gpsim-0.30.0/0000775000076400007640000000000013117466031007726 500000000000000gpsim-0.30.0/config.h.in0000664000076400007640000001421113041764004011665 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* gtk version */ #undef GTK_VERSION /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define if your host uses a DOS based file system. */ #undef HAVE_DOS_BASED_FILE_SYSTEM /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `floor' function. */ #undef HAVE_FLOOR /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* True if GUI is being used */ #undef HAVE_GUI /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `popt' library (-lpopt). */ #undef HAVE_LIBPOPT /* Readline */ #undef HAVE_LIBREADLINE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* True if gpsim socket interface is being used */ #undef HAVE_SOCKETS /* Define to 1 if you have the `sqrt' function. */ #undef HAVE_SQRT /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `strndup' function. */ #undef HAVE_STRNDUP /* Define to 1 if you have the `strpbrk' function. */ #undef HAVE_STRPBRK /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* printf modifier define for GINT64 */ #undef PRINTF_GINT64_MODIFIER /* printf modifier define for long long */ #undef PRINTF_INT64_MODIFIER /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define to the type of arg 1 for `select'. */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for `select'. */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg 5 for `select'. */ #undef SELECT_TYPE_ARG5 /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Version number of package */ #undef VERSION /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `unsigned int' if does not define. */ #undef size_t gpsim-0.30.0/install-sh0000755000076400007640000003452312734477075011675 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2013-12-25.23; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gpsim-0.30.0/gpsim/0000775000076400007640000000000013117465764011061 500000000000000gpsim-0.30.0/gpsim/gpsim.h.in0000664000076400007640000000157513041763577012705 00000000000000/* Common definitions for gpsim Copyright (C) 2013 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GPSIM_H__ #define __GPSIM_H__ #define GPSIM_VERSION_STRING ("gpsim-" VERSION " #" @REVISION@ " (" __DATE__ ")") #endif gpsim-0.30.0/gpsim/main.cc0000664000076400007640000002777613041763577012256 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Portions of this files are (C) by Ian King: /* picdis.c - pic disassembler */ /* version 0.1 */ /* (c) I.King 1994 */ #include #include #include #include #include #include using namespace std; #include "../config.h" #include "gpsim.h" #include "../cli/input.h" #include "../src/interface.h" #include "../src/gpsim_interface.h" #include "../src/fopen-path.h" #include "../src/breakpoints.h" #include "../cli/ui_gpsim.h" int quit_state; extern "C" { #include } extern int gui_init (int argc, char **argv); extern void gui_main(void); extern void cli_main(void); // os_dependent.cc' extern void AddModulePathFromFilePath(char *arg); void initialize_gpsim(); int parse_string(const char *cmd_string); extern void initialize_commands(); extern int yydebug; extern int quit_parse; extern int abort_gpsim; #if _DEBUG char szBuild[] = "Debug"; #else char szBuild[] = "Release"; #endif void gpsim_version(void) { printf("%s %s\n", szBuild, VERSION); } // from ui_gpsim.cc void initialize_ConsoleUI(); #define FILE_STRING_LENGTH 50 //---------------------------------------------------------- // Here are the variables that popt (the command line invocation parsing // library) will assign values to: static const char *startup_name = NULL; static const char *include_startup_name = NULL; static const char *processor_name = NULL; static const char *cod_name = NULL; static const char *search_path = NULL; static const char *icd_port = NULL; static const char *defineSymbol = NULL; static const char *sExitOn = NULL; static const char *sourceEnabled = NULL; struct poptOption myHelpOptions[] = { POPT_TABLEEND } ; #define POPT_MYEXAMPLES { NULL, '\0', POPT_ARG_INCLUDE_TABLE, myHelpOptions, \ 0, "Examples:\n\ gpsim myprog.cod <-- loads a symbol file\n\ gpsim -p p16f877 myprog.hex <-- select processor and load hex\n\ gpsim myscript.stc <-- loads a script\n", NULL }, //------------------------------------------------------------------------ // see popt documentation about how the poptOption structure is defined. // In general, we define legal invocation arguments in this structure. // Both the long name (like --processor) and the short name (like -p) // are defined. The popt library will assign values to variables if // a pointer to a variable is supplied. Some options like the 'echo' // option have no associated varaible. After the variable name, the // poptOption structure contains a 'val' field. If this is 0 then popt // will assign an option to a variable when poptGetNextOpt is called. // Otherwise, poptGetNextOpt will return the value of 'val' and allow // gpsim to interpret and further parse the option. struct poptOption optionsTable[] = { { "cli", 'i', POPT_ARG_NONE, 0, 'i', "command line mode only", NULL }, { "command", 'c', POPT_ARG_STRING, &startup_name, 0, "startup command file (-c optional)", NULL }, { "define", 'D', POPT_ARG_STRING, &defineSymbol, 'D', "define symbol with value that is added to the gpsim symbol table. " "Define any number of symbols.", NULL }, { "echo", 'E', POPT_ARG_NONE, 0, 'E', "Echo lines from a command file to the console.", NULL }, { "help", 'h', 0, 0, 'h', "display this help and exit" }, { "icd", 'd', POPT_ARG_STRING, &icd_port, 0, "use ICD (e.g. -d /dev/ttyS0).", NULL }, { "include", 'I', POPT_ARG_STRING, &include_startup_name, 0, "startup command file - does not change directories", NULL }, { "processor", 'p', POPT_ARG_STRING, &processor_name, 0, "processor (e.g. -pp16c84 for the 'c84)","" }, { "source", 'S', POPT_ARG_STRING, &sourceEnabled, 'S', "'enable' or 'disable' the loading of source code. Default is 'enable'. " "Useful for running faster regression tests.", NULL }, { "sourcepath", 'L', POPT_ARG_STRING, &search_path, 'L', "colon separated list of directories to search.", NULL }, { "symbol", 's', POPT_ARG_STRING, &cod_name, 0, ".cod symbol file (-s optional)", 0 } , { "version", 'v', 0, 0, 'v', "gpsim version", NULL }, /* POPT_AUTOHELP generates error: invalid conversion from `const void*' to `void*' [-fpermis sive] on i686-pc-mingw32-c++ (GCC) 4.7.3 */ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ 0, "Help options:", NULL }, POPT_MYEXAMPLES POPT_TABLEEND }; String *scope[8]; bool bUseGUI = true; // assume that we want to use the gui void welcome(void) { printf("\ngpsim - the GNUPIC simulator\nversion: %s %s\n", szBuild, VERSION); printf("\n\ntype help for help\n"); } void exit_gpsim(int ret) { exit_cli(); #ifdef HAVE_GUI if(!bUseGUI) #endif { for(int i = 0; i < 8; i++) { delete scope[i]; } } exit(ret); } int main (int argc, char *argv[]) { bool bEcho = false; bool bSourceEnabled = true; int c, usage = 0; char command_str[256]; char *hex_name = NULL; poptContext optCon; // context for parsing command-line options // Perform basic initialization before parsing invocation arguments InitSourceSearchAsSymbol(); initialize_ConsoleUI(); initialize_gpsim_core(); initialize_gpsim(); initialize_commands(); // If last arg ends in unprintable character such as \r, strip it int len = strlen(argv[argc-1]); if (!isprint(*(argv[argc-1]+len-1))) *(argv[argc-1]+len-1) = 0; optCon = poptGetContext(0, argc, (const char **)argv, optionsTable, 0); if (argc >= 2) { while ((c = poptGetNextOpt(optCon)) >= 0 && !usage) { switch (c) { default: printf("'%c' is an unrecognized option\n",c); case '?': case 'h': usage = 1; break; case 'L': set_search_path (search_path); #ifndef _WIN32 free((char *)search_path); #endif break; case 'd': printf("Use ICD with serial port \"%s\".\n", icd_port); break; case 'v': fprintf(stderr, "%s\n", GPSIM_VERSION_STRING); return 0; break; case 'i': bUseGUI = false; printf("not using gui\n"); break; case 'D': // add symbols defined with '-D' to the symbol table. snprintf(command_str, sizeof(command_str), "symbol %s\n",defineSymbol); parse_string(command_str); #ifndef _WIN32 free((char *)defineSymbol); #endif break; case 'S': if(strcmp(sourceEnabled, "enable") == 0) { bSourceEnabled = true; } else if(strcmp(sourceEnabled, "disable") == 0) { bSourceEnabled = false; } else { usage = 1; } #ifndef _WIN32 free ((char *)sourceEnabled); #endif break; case 'E': bEcho = true; EnableSTCEcho(true); break; case 'e': if(strcmp(sExitOn, "onbreak") == 0) { get_bp().EnableExitOnBreak(true); } else { printf("%s is invalid exit condition for -e option.\n", sExitOn); } #ifndef _WIN32 free ((char *)sExitOn); #endif break; } if (usage) break; } if (c < -1) { /* an error occurred during option processing */ fprintf(stderr, "Gpsim %s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(c)); usage = 1; } } if (usage) { poptPrintHelp(optCon, stdout, 0); exit (1); } welcome(); if(bEcho) { for(int index = 0; index < argc; index++) { printf("%s ", argv[index]); } printf("\n"); } if(poptPeekArg(optCon)) // unprocessed argument, does not have to be a hex file { hex_name=strdup(poptGetArg(optCon)); if (strstr(hex_name, ".cod") && cod_name == NULL) { cod_name = hex_name; hex_name = NULL; } } if(poptPeekArg(optCon)) // unexpected unprocessed argument { char *arg; fprintf(stderr, "Gpsim Unexpected arguments not used: \""); while ((arg=(char *)poptGetArg(optCon))) { fprintf(stderr, "%s ", arg); } fprintf(stderr, "\"\n"); } poptFreeContext(optCon); initialize_readline(); // must be done after initialize_gpsim_core() Boolean *bEnableSourceLoad = dynamic_cast( globalSymbolTable().find("EnableSourceLoad")); if (bEnableSourceLoad) *bEnableSourceLoad = bSourceEnabled; // initialize the gui #ifdef HAVE_GUI if(bUseGUI) { if (gui_init (argc,argv) != 0) { std::cerr << "Error initialising GUI, reverting to cmd-line mode." << std::endl; bUseGUI = false; } // Move this from above to accurately report whether the GUI // has initialized. With out this, gpsim would generate a segmentation // fault on exit under Linux when executed in a telnet session // and with out the -i option. get_interface().setGUImode(bUseGUI); } else #endif { // so scope setup does not cause error when -i is used for(int i = 0; i < 8; i++) { char buf[10]; sprintf(buf, "scope.ch%d", i); scope[i] = new String(buf, ""); globalSymbolTable().addSymbol(scope[i]); } } AddModulePathFromFilePath(argv[0]); initialization_is_complete(); yydebug = 0; quit_parse = 0; abort_gpsim = 0; try { // Convert the remaining command line options into gpsim commands if(cod_name) { if(processor_name) cout << "WARNING: command line processor named \"" << processor_name << "\" is being ignored\nsince the .cod file specifies the processor\n"; if (hex_name) { cout << "WARNING: Ignoring the file \"" << hex_name << "\" "; cout << "since \"" << cod_name <<"\" already specified\n"; free((void *)hex_name); hex_name = NULL; } snprintf(command_str, sizeof(command_str), "load s \"%s\"\n",cod_name); parse_string(command_str); } else if(processor_name) { if(hex_name){ snprintf(command_str, sizeof(command_str), "load %s \"%s\"\n",processor_name, hex_name); parse_string(command_str); free((void *)hex_name); hex_name = NULL; } else { snprintf(command_str, sizeof(command_str), "processor %s \n",processor_name); parse_string(command_str); } } if(icd_port) { snprintf(command_str, sizeof(command_str), "icd open \"%s\"\n",icd_port); parse_string(command_str); } if(startup_name) { snprintf(command_str, sizeof(command_str), "load c \"%s\"\n",startup_name); parse_string(command_str); } if(include_startup_name) { snprintf(command_str, sizeof(command_str), "load i \"%s\"\n",include_startup_name); parse_string(command_str); } // otherwise see if load will work if (hex_name) { snprintf(command_str, sizeof(command_str), "load \"%s\"\n", hex_name); parse_string(command_str); } if(abort_gpsim) exit_gpsim(0); // Now enter the event loop and start processing user // commands. #ifdef HAVE_GUI gui_main(); #else cli_main(); #endif } catch (char * err_message) { cout << "FATAL ERROR: " << err_message << endl; } catch (FatalError *err) { if(err) { cout << err->toString() << endl; delete err; exit_gpsim(1); } } exit_gpsim(0); return 0; } gpsim-0.30.0/gpsim/Makefile.in0000664000076400007640000005113713117441635013044 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # gpsim executable Makefile # # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = gpsim$(EXEEXT) subdir = gpsim ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_gpsim_OBJECTS = main.$(OBJEXT) gpsim_OBJECTS = $(am_gpsim_OBJECTS) gpsim_DEPENDENCIES = ../src/libgpsim.la ../cli/libgpsimcli.la \ ../gui/libgpsimgui.la ../eXdbm/libgpsim_eXdbm.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(gpsim_SOURCES) DIST_SOURCES = $(gpsim_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ @Y_CFLAGS@ gpsim_SOURCES = main.cc \ gpsim.h.in #gpsim_LDFLAGS = $(shell gtk-config --cflags) gpsim_LDADD = ../src/libgpsim.la ../cli/libgpsimcli.la ../gui/libgpsimgui.la \ ../eXdbm/libgpsim_eXdbm.la @GTK@ @GDK@ @GLIB@ -lstdc++ -lpopt @LIBDL@ \ @X_LDFLAGS@ @Y_LDFLAGS@ @LIBREADLINE@ # Make sure we have parse.h when compiling other sources BUILT_SOURCES = gpsim.h CLEANFILES = gpsim.h EXTRA_DIST = makefile.mingw all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gpsim/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu gpsim/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list gpsim$(EXEEXT): $(gpsim_OBJECTS) $(gpsim_DEPENDENCIES) $(EXTRA_gpsim_DEPENDENCIES) @rm -f gpsim$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(gpsim_OBJECTS) $(gpsim_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile gpsim.h: gpsim.h.in sed -e "s/@REVISION@/$$(${top_srcdir}\/get_cl_revision.sh -s ${top_srcdir}\/ChangeLog)/g" "$<" > "$@" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/gpsim/Makefile.am0000664000076400007640000000116513041763577013037 00000000000000# gpsim executable Makefile # # AM_CPPFLAGS = @X_CFLAGS@ @Y_CFLAGS@ bin_PROGRAMS = gpsim gpsim_SOURCES = main.cc \ gpsim.h.in #gpsim_LDFLAGS = $(shell gtk-config --cflags) gpsim_LDADD = ../src/libgpsim.la ../cli/libgpsimcli.la ../gui/libgpsimgui.la \ ../eXdbm/libgpsim_eXdbm.la @GTK@ @GDK@ @GLIB@ -lstdc++ -lpopt @LIBDL@ \ @X_LDFLAGS@ @Y_LDFLAGS@ @LIBREADLINE@ # Make sure we have parse.h when compiling other sources BUILT_SOURCES = gpsim.h CLEANFILES = gpsim.h EXTRA_DIST = makefile.mingw gpsim.h: gpsim.h.in sed -e "s/@REVISION@/$$(${top_srcdir}\/get_cl_revision.sh -s ${top_srcdir}\/ChangeLog)/g" "$<" > "$@" gpsim-0.30.0/gpsim/makefile.mingw0000664000076400007640000000336113113676423013614 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw TOP = ../.. include ../plat/win32/make.mingw ################################################################ # Nothing much configurable below LIBS = -l wsock32 \ -L $(READLINE_PATH)/lib -l readline.dll \ -L $(POPT_PATH)/lib -l popt \ -L $(PANGO_PATH)/lib -l pango-1.0 -l pangocairo-1.0 \ -L $(CAIRO_PATH)/lib -l cairo \ -L $(GDK_PIXBUF_PATH)/lib -l gdk_pixbuf-2.0 \ -L $(GTK_PATH)/lib -l gtk-win32-2.0 -l gdk_pixbuf-2.0 -l gdk-win32-2.0 \ -L $(GLIB_PATH)/lib -l gobject-2.0 -l gthread-2.0 -l glib-2.0 gpsim_LIBS = ../gui/libgui.a ../cli/libcli.a libgpsim_LIBS = ../src/libgpsim.a INCLUDES = -I ../plat/win32 \ -I $(GLIB_PATH)/include/glib-2.0 -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GDK_PIXBUF_PATH)/include/gdk-pixbuf-2.0 \ -I $(POPT_PATH)/include DEFINES += -DHAVE_GUI all : \ ../config.h \ gpsim.exe gpsim_OBJECTS = \ main.o ../config.h : ../config_win32.h.in (cd .. ; $(AWK) -f plat/win32/configure_win32.awk config_win32.h.in > config.h) ################ The gpsim libraries ../gui/libgui.a : cd ../gui && $(MAKE) -f makefile.mingw all ../cli/libcli.a : cd ../cli && $(MAKE) -f makefile.mingw all ../src/libgpsim.a : cd ../src && $(MAKE) -f makefile.mingw all ################ The gpsim EXE gpsim.exe : $(gpsim_OBJECTS) $(gpsim_LIBS) $(CXX) $(CFLAGS) $(CLDFLAGS) \ -Wl,--export-all-symbols -Wl,--out-implib,gpsim.lib \ -o gpsim.exe $(gpsim_OBJECTS) -Wl,--whole-archive $(gpsim_LIBS) -Wl,--no-whole-archive $(libgpsim_LIBS) $(LIBS) gpsim.h : gpsim.h.in sed -e "s/@REVISION@/$$(${top_srcdir}\/get_cl_revision.sh -s ${top_srcdir}\/ChangeLog)/g" "$<" > "$@" main.o : main.cc gpsim.h gpsim-0.30.0/AUTHORS0000664000076400007640000000236613041763613010727 00000000000000Scott Dattalo Ralf Forsberg Daniel Schudel Roy Rankin Borut Razem Additional Contributors: NOTE there have been many, many people who have contributed to gpsim in the way of providing comments and suggestions. The following (incomplete) list is for those who have submitted patches. If your name should be here, let me know... I know there are many more contributors out there who I've not kept track of. Mike Durian Bradley McLean Alex Holden Steve Tell Paco Moya Joerg Wunsch Erik Thiele Daniel Christian Rudy Moore Salvador Eduardo Tropea Berndt Josef Wulf Carlos Nieves Ónega Wojciech Zabolotny Robert Pearce Craig Franklin John Sutton Tom Oram Jack Twilley John Steele Scott Brian Behlendorf gpsim-0.30.0/config.sub0000755000076400007640000010624612734477075011656 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gpsim-0.30.0/PROCESSORS0000664000076400007640000000275513116724453011310 00000000000000gpsim-0.30.0 12bit: ------ pic10f200 pic10f202 pic10f204 pic10f220 pic10f222 pic12c508 pic12c509 pic12ce518 pic12ce519 pic12f508 pic12f509 pic12f510 pic12f629 pic12f675 pic12f683 14bit: ------ pic12f1840 pic12f1822 pic16c54 pic16c55 pic16c56 pic16c61 pic16c62 pic16c62a pic16cr62 pic16c63 pic16c64 pic16c65 pic16c65a pic16c71 pic16c712 pic16c716 pic16c72 pic16c73 pic16c74 pic16c84 pic16cr83 pic16cr84 pic16f505 pic16f73 pic16f74 pic16f716 pic16f83 pic16f84 pic16f87 pic16f88 pic16f882 pic16f883 pic16f884 pic16f886 pic16f887 pic16f627 pic16f627a pic16f628 pic16f628a pic16f630 pic16f631 pic16f648 pic16f648a pic16f676 pic16f677 pic16f684 pic16f685 pic16f687 pic16f689 pic16f690 pic16f818 pic16f819 pic16f871 pic16f873 pic16f874 pic16f876 pic16f877 pic16f873a pic16f874a pic16f876a pic16f877a pic16f913 pic16f914 pic16f916 pic16f917 pic16f1788 pic16f1823 pic16f1825 16bit: ------ pic18c242 pic18c252 pic18c442 pic18c452 pic18f242 pic18f248 pic18f258 pic18f252 pic18f442 pic18f448 pic18f458 pic18f452 pic18f1220 pic18f1320 pic18f14k22 pic18f2221 pic18f2321 pic18f2420 pic18f2455* pic18f2520 pic18f2525 pic18f2550 pic18f2620 pic18f26k22 pic18f4221 pic18f4321 pic18f4420 pic18f4520 pic18f4550 pic18f4455* pic18f4620 pic18f6520 * USB functionality not supported gpsim-0.30.0/README.MODULES0000664000076400007640000001347113041763624011647 00000000000000 INTRODUCTION ------------ Starting with version gpsim-0.20.0, support for external modules has been added. This allows gpsim to create a full simulation environment that extends beyond just a PIC. It also provides for users to create their own simulation modules without having to be aware of the detailed internals of gpsim. The module approach attempts to leverage off the gpsim infrastructure. The definition of a pic processor is now derived from a `module'. A module can have pins just like a PIC. The node infrastructure for connecting stimuli to gpsim I/O pins has been extended to now include the module I/O pins. Break points and internal module events can be traced just like they are in a real pic. A stimulus can be connected to a module. In fact, although I haven't tried it, gpsim can almost simulate a module with no PIC present! Several example modules have been created and serve as example templates. These are found in the ./modules/ subdirectory. In addition, examples may also be found in the ./examples/14bit/ subdirectory that illustrate how the modules can be used. HOW DO I LOAD A MODULE? ----------------------- A new command called 'module' has been added to gpsim. Straight from gpsim: gpsim> help module module [ [load module_type [module_name]] | [lib lib_name] | [list] | [[dump | pins] module_name] ] If no options are specified, then the currently defined module(s) will be displayed. This is the same as the `module list' command. The `module load lib_name' tells gpsim to search for the module library called `lib_name' and to load it. (Note that the format of module libraries is exactly the same as a Linux shared library. This means that the module library should reside in a path available to dlopen(). Please see the README.MODULES in the gpsim distribution. To instantiate a new module, then type module module_type module_name where module_type refers to a specific module in a module library and module_name is the user name assigned to it. Information about a module can be displayed by the commad module module_name [dump | pins] where module_name is the name that you assigned when the module was instantiated. The optional dump and pins identifiers specify the information you wish to display (dump is the default). examples: module // Display the modules you've already defined. module lib my_mods.so // Load the module library called my_mods. module list // Display the list of modules supported. module load lcd my_lcd // Create an instance of an 'lcd' module pins my_lcd // Display the pin states of an instantiated module module load lcd lcd2x20 // Create a new module. module load led start_light // and another. As you can see, there's a whole lot of stuff packed into this new command. HOW DO I CREATE MY OWN MODULE? ------------------------------ Probably the best place to begin is to find a pre-existing module that is close to the one you wish to create and then make copy it and make changes. (basic structure of modules) HOW DO I CREATE A LIBRARY FOR MY MODULES? ----------------------------------------- Without a doubt, the best thing to do is copy the way gpsim does it. The distributions for the LED and the Logic modules is probably the best place to begin. There are many details that I can't satisfactory cover in the scope of this document. In the example module libraries you'll find two major sections. First there's something I've called the `module manager'. This is a necessary managerial layer that provides the dynamic interface. Second is the module section that defines a module's behavior. Module Manager -------------- The module manager provides the dynamic link support. There are several mandatory functions: get_mod_list() ------------ This function returns a pointer to the list of modules that are supported in the library. /********************************************************* * mod_list - Display all of the modules in this library. * * This is a required function for gpsim compliant libraries. */ Module_Types * get_mod_list(void) { return available_modules; } For this to work of course, a list called `available_modules' of type Module_Types must be declared. From the Led library, the list is only one deep and looks like so: /* class Module_Types { public: char *names[2]; Module * (*module_constructor) (void); }; */ Module_Types available_modules[] = { { "led_7Segments", "led", Led_7Segments::construct}, { 0,0,0} // indicates there are no more modules }; The first two parameters are names that the module may be called. The last parameter is a pointer to a static member function of the module. gpsim will call this function to create a new module. Note the all 0's module. This marks the end of the list. more... Shared Libraries ---------------- The link between modules and gpsim is `dynamic'. Which is to say, when gpsim is compiled it knows nothing about a specific module. Similarly, when a module is compiled it is done so indepently of gpsim. The module compilation depends on gpsim only to the degree of using the include files provided. The module compilation however does not include a step at which it is linked with gpsim. Is that clear? I guess the point to understand, is that gpsim and the modules are built separately. Now, when gpsim loads a module, it will open the `shared library' in which it is contained. The infrastructure of shared libraries is defined by the OS and not by gpsim. Consequently, there are a few details that have to be managed before the shared libraries will work properly. (ldconfig) $ more /etc/ld.so.conf /usr/X11R6/lib /usr/i486-linux-libc5/lib /usr/local/lib /usr/lib gpsim-0.30.0/doc/0000775000076400007640000000000013117466025010476 500000000000000gpsim-0.30.0/doc/gpsim.pdf0000664000076400007640000134245013117466021012235 00000000000000%PDF-1.4 %Ç쏢 113 0 obj <> stream xś]ŹAK1 …ďý=´‡Ć&“´ŤGŃ‹7Ą7ń ®.".ë˙Çé8ŇArč—×ä˝ö RŻí|ťÝŐ#‘ÂńěV>ÝÉŃÖ¤m nÚ: 2©@{w´-pTŃ‚ĆĐf÷äŹ!Ö"Ĺü×/f&î8Iań!&¬dŮü"c6‘úÜî˙RMĎ%%NڤV!–Š…Ě –„Ë-!WŰ˝˛U!˙'MężCś0i2őo«Ć*ţz“ Uö<śŇ@XĆ@X˛Č~2˙żć)ď×wţÇűűŻďš{XęšSfendstream endobj 114 0 obj 225 endobj 123 0 obj <> stream xśíZKoÜ6zÜ_ˇ#U@ ‡äđqlÓZ¤h,CĐăW‚Äo§Źßá®V3ÚŐÚ»ŤQ+¶ŕąÔäđűćEęŞ2*SţÚ˙‡głŻ°:˝™-ú+¨>ήfĐţ0­TőýĽZ¬¬×1E¨ć'3h_çtŞ0˘F[ÍĎfoŐËÚč€!«.jĐmręĽnŚŽ u[7 ŤGăÔqişě,t!$)qCCDţ˙Ü®"k;ř˛Šŕiňů«ŮüŰ· ę&g§1%uZ7¨S˘źę’ŢĎڧ‘č!fďŐZa4ëYÝX¤ąBPMiFmÁ©ďĘZBÎÁaY—u©L©~­ŻłĹŕÔźuĐ„Ą !꺣]pž/b;—3¤ä_ eŤIaˇ—Ł H!SÍŹhĂâĺLČ´:C:7Î:CŐr y`m5-V“Š´nę%­ióPýRzť3>©^ĂG~MlČ9÷žÍ qtH§ĹűN5ŇÇz«ŃgjÍSĚę9\6Kęs÷şS¬ę]÷üSoç’'¨ Ń$ťĐ–¦ĎAGŇpkóŃd÷Śv±ëuŰ›Br.t[ă‹%ТmXĚńŽla¤ mŢĘÂ8IŇúa”…UoĘhY»¸4FŹş¸‹veQ˝`ŮCě˘ÓĹ^bĎ7ťÝźv}źYđş˛ĹlŇBHÚgŰŽTD/Yô–ŤC,›EĎY”@4ťű™SüIçJwf‹e¶Ľ®=EYýÖíľ`PŮS~¤˙swž¸ńÇ>„dóÉŔÁŃ1ŽojOáϢ—„gÓ:ęZßL”ń¬ŔMÔ`ăčÚ°;ż3Ú[ŽöK+¤IV±¶2z"Ŕo ű>EB3ŚjGźěŰŤ× ÝĆ[¤¬ëj-Ú­˝ |ĐÉ(}Ć™­čeŇÜö‚t RĆú†~ZOůűeNłňë”QݱKW`ąây)*– ţŚâpĘжĽ]$rěVaú¨­Č—żęhŐóţ+É’.!IdŻ~*U0!.Ű„ą”n"±Zeý×LŞ&ŕAÇ/‘Íń[›•Q޵2Z…Áv—î.ŹŘzD®'šBŕ›T%°´ś8V>>UŁ)Ý4pâm¶$˛ĂŘ‹`ůŽZĎhśt§ýz9‡¬}ú’ä~ÂűAđ†z=ë]Tşw.§0âOlĺè+ŚËöcÝŰçC·—Á{Ćţh0+âłA=wrKDäLŰ­(Ęé×óč‰ ÍW[¤ď±űŔ oËáşŁŚ†,ślWNM~ţŃńĆŤ˛xéČHźtyÜ`Fw5hí›Uo^Ü[”kŤLĄĘ?äĚ“ŃŢŽ`cź+ú;ůőÄDxżďZĆGŽ=ÚDĄ¬¨ŕ&›ę÷řřĚ€‹„Nřx ď>˘NśG‹ł« 𱾋™‹ĂŃRű;ú¬´íÁäľ|W`]ÖS3ţ÷Ľ€ˇçź=709űńa6l˙Ţ“AËĺřćy­ăó˝rđĚ—÷ĺ“5†;Šô‰ ŹB…ÝÝ€dp|c-RţţŃ_¶Yź®<ú´áöÉ<ăνř—EˇF2€1áßżŘŰĂô‘ˇżä^.ü 6ďK€:äĺđp]><ŚÚ}üŤ~âl°Ě†µŰĽ=˝A`J źő|—ĽM*7đQ¨8ą±`ww{öýĎ ˘†4ť|Đďiű‰ń—U˙ĐďeqíY?Ő#Ć˝öľjś-7đ©÷dŠEâÇůěwúű!Kendstream endobj 124 0 obj 1353 endobj 157 0 obj <> stream xśí[IoÜ6rś_ˇŁT`X’Źk/EE‹´i“)r(zplgibÇIśĄ˙ľŹÚŢÓ6Łi<® >C‘Ĺď{+źŢfR¨L¦żú˙ńŮęŰGJŮěůűUŮź©ěŐęíJŐ?d=*»»):ěJJ—mž­¤ÁQŐýśń*fmź!sÁá•ls¶ú3żWaµ‰.X¬Ąp1:°ůݬ˝)Ö t4>ä÷©92ÂI•?.” ¤ůkós˝¶(˘ÓΤµ©úeŚ×ÂÎ:t±¶"D|ë4s „wŮZ{ś-u¶9iÇ„!ĹZ‹h >]QoÄ&ŕ§ó÷kqDţ]?+ÖFDŤťO©ó 5_ă]׫}znŠđŢöšV¬ž°ĎŘ+˝ŮŤY¤‰Ô ÓM6VĄn|± †µ! ĂćÁjóÍ XŻ#Áe2ŕ¬Ő*IÍšÖAţł ŔzßcÓJ\¤»Q{}k a©fłBí`ÓU3řüSˇ”b~„KÎYĺř¤ăŞpŇ‹Îę*Íçx Ąćs ŔĆp•.S‰z68 ăš—˛u;aˇ×aéŐ3@Ţ ťřµNšgÚř°^M cy—pÖN§Đ15OÓşĽH*¨]­ą©}{Ř6ĚŇ0@ř,’cĽ ŇÄR@/GĐ9Ţßâę`! #Ân!:|ĆçY5"ăŐ+©Eňo,ŕhµĺ†yÝ8kŤ®c2éĄuŔY:ô˙HNĺ;’ţŁÖ©¸H!’ŽAŁĎPK\ćô"“?XäUj'ťoŤžŞ-:Ńä?µ×Ď˧Ń8%=dŁ ˝IŤ+ó¬RTĘ[5suhVÚ!ŔŇk ë•,7ŇŚxD|#A%˛vC›}ńp—”@¬I˝Ň„Ć ¦%±ýKĘÓ ÖĐ}ŁťŞF€ôĺúĄNÚÖ›WŁqŐ8ÇaĐ)Ý—â"^“âŐe…F„UŚäeMâ?Á śĐ‘łâ”XqNŹýĐ"Ťqr[äüđÁî…iűŔ« Ţ»e’Ę©ČpĽ$fÍ7íősޏC˘u^důja¶˙a „÷La ć0=hľ¦ëĚ0 |ęr˝É,€ťnv[˘Ë =M| B.¸Źŕn»a2)ptý6-®ÉŠÜ,ěaÉ6Š•şˇ˛6ZXĂÂ;rVJ®‚u•á÷R§&]¤ĆB퀏AůE%\%5fšöÉś~Łę^k}#ď @Bő,±oˇÝU°Ââ˛UĽ1@~m Ď2÷“ˇsůC%cŹ ¨ľÚN­¤ ĺçcţ±ídĆä´@hŤĆhűSb ŢJŞ|]‘GyÇ-Č‹ÎM1”rUŇżá!3+Oۡău nđđq2ö–ŻŠnĘRlŐ@FâQ{4yZ()íKţś&1;?šŃď¦ŢJÝ j0hÖ K˙â:·ţöhßáÇ´ş0cnĂđP7ąsÓ§şI2ŁźTN(µ@~ČĂ^A%ŕźď«¶ÄĄŢ”<˙8Ş,:p{ă…U[r= ň‡@~Ž›ŕĆäľÂÜččxôÇŕU§˙âô[]Ď’FÉV%@-©öC“"îĄ<ńánëP ČĚ=ÓämCčD,$ÄIŢĄ\ÁBk¦Ŕ˝›4F~fÎ){™:Ŕ%}Z°cøpâś c·˛€kľZD‡ßZ3щ»ażÓĽ˝îD MRiŹŘ K p|IÍŕ†™l•bf€ŁžQâ‚&Uµ^N†Yµ^ăsçÔ˙żÇ·‡[ë˙vrBŤq‚Yaý_¬Žş»ń¤0R8mÍ>GÉÁ–ť ®ŚÝ2˝ąĺ†Ę3FŃg…Ě)¸`ĘŁµ'ťRćúó:č4Ŕ‹6čúIJN1,ąÇĚ?­lĘ3îđ›ÖW?pĂÖ8¬S aŰÓ­Í`»8(r™S›a¦d¬±żěó€ń¤ĚéŔ1O˝ÝŁ·Fɦ-CÓ뢮żQHůTÚ0öÖdţüh¦łÂF˝HŮV)ëňcşťdÂ죜*c´î•ă—G9*Ś`Ęâü^¸†¤RŠŕÔ ÄďkĂ:Ó}ŕŐŁđŽžŐlŮ^˝N-ý^ú}©`ŤOźř,H‘žŞŮŘoĹ{ôdv×Éűe]Ó{cěľÚ@Üź‰üDŐĆ8 vUmtrŻ#eď—ü®4żno_B¨ëˇA÷°~‡óÜ~viÉyţˇ_{\ş˝çR×Ţł„Éď^ĄâL7đŁKç8™«„T€Îfă~n- sÓ;e ä†77ę9šÉ7ÇČŽÜ7'Îläíä«öž}ˇčćŹÎÇb|MeQEäč¸>:˝OÂp:NąÝĺ”ďYŤK– !k‹+ËU'ČŔ ˝Ĺ”—ŮŞ ŔÚ‘!tě9í;Ăë¬dY 6`¦gÓ{Ü9o­uHĺPúď(˝Hĺ&Ü©&ü58ŰŰŘ‹±©‰Máŕ^Ť|Ál° KPÓ‘s)ń6Đžú)ŢÍżCrIÜÎ`ň'#.6%čč‹#®&Şr8¸ÜR:i!ďĆŻ_Ś˙¨ľů~^4Ţ=˝żYýŽ˙ ~żđendstream endobj 158 0 obj 1934 endobj 196 0 obj <> stream xśí[[sÝ4~ĎŻ8OŚÍ`ˇű…7h --¤úŔ0LHBŇiB›ů÷¬dŮ»˛uni(!Í䡧˛,­´ßî~»’˙Xp&<ţĺ_í}ş/„YśĽŮKí ±x±÷ÇžČ˙áą×â‹eęhˇ‰ ÎíbůŰgÁ[ĄE?žŐN„ĹŘ&”b~a˝…'‹ĺ«˝źš{­fFę`›'mÇ™ Á*Ó<&ż—m§ Úůćţ¬ô°\4O[Á‚\˙Ľü:ËX°Ňę(›Č‹ŃN2­ 9TŰć¬:ż) }łSĘ3řŮIŤ\.–Gđ’k»3ŢăÄÍó–k5ČÓĽ‚FŚÍŰńńK||ćôŢ5m§™´Â¨üş1R4găK'm'Ťg^«ˇ+WÍi|,˝ Í1<Ö’ăšý¸/ŽsoElĚZTž*.褂ĄÉćYëâKB5żŹ’Ľîß±ĘgI“$GăTźÁ^sĂ”×dÉuńűŐkég«WÜ Ň3î¸d8 ÚI«Q\1UL©ŇN‰¸/‹Nh+őŁbâz@9 岠µJC ‚9Ó<$đů˝…!$‡ý+î#,źbî‡:nçĘqß\Ć=ÔĚ)›čAvą‰Ă~Ľ€žAGyŁ$€sć`zři8Ľf¦­»t¸ }wLlU«’ľ"6Ă+1!Aż"„šŘf+€!ŔČý‘¨ó gľ@xŁĄśC®ŕ;•8ËČŃ:Úä`žŻ"`‚4VMúćaŁýĂ2-훎ĺ¶2WúI†z;ľOLůyŰyn·ţVCDé ŚlpÝÄŁŃŮ~Š;ř$:cĹ, ĺ»š×Gµ˝i;{°zwŁ6řĂq% F˙đÍŢňăUÚW¨ýĎIHfg Kôý…_Hö¶l„ĄŁŹ&@Ĩš5i|KA#Dő4ÂÖüĘĚÖs€§Ć‘ď(%ýŰĹ[¨MĺsÂČPőUžEq‚‚Ž€î˙˛†¨CŚ)§řüĘ8ä‘˝çŕú–ŕE·W/ ÉgţĆľsŽÝ q6G”’Žú>ă®E_޶ť×¸s+[ÂduĐ1‰ouŤ¦Ar€Hą z\ÁA‰Ť+Ç”¦t÷·ČŚ%…Ďéř|Č6áĄwidQ˛ů6îŚR\{ đCt™( !Ńg8ˇÜ^Ę(Ś !&ä7R)Ç«UŇáí|óĚí|Ů´Ř’\!rŽRśÔ˘Ű Ť #Er%!­¶ ëűőÚ©É. ä@ Č«®QY˙oÇc¦U“i9Ë1ż3f¶‡‰ÇJÖ·ëŔ­”Ô‡ś©–#—ÔŚIś ĘÚŞŽ˝JUÇoŞęś`‡sü‰”©ôLŃÉyĄ©·AXŐ(Ń|Ĺá?§Dň—˙66>»Ő„|,ń¬ÄĂzßöq3Ŕ(ÉŢo-)ăSiنĄÓwş˝6Ýú+ÚE“5™ą’2f’9e{%öäÁɢ¦ßăvÝét;ť*Ôé#ärTä˝Č -S`†Pçä'ň•ýV›0ÁőJ٢ÁÇH@ĂťkzD¶ĐđBŹŕnMô»ąb¶‹J5Şťě_D%„ ^v:'ů„ Ž‹l>ŠuXŕ1\ěŹUű˘ëŔü«éŔE57"ĄJCž#Ô´RţABL!Ń3˛Ý!a?¶(“ó–P®—S@L)˙ DJA=…¬V±HúBjcU”|ˇ%Ő˙Kx˘3™( Z‘żĆZŽőxA¤H×zţE83®IÖE¶`-…ëFX"n&74‘ÝkÝđúŐyź­˛9hŇů˔ƭB€‘·ľ*cË?ŹIŹ%6?Ťé®†IV•.ęW lĄcüvş—]}ŠŰž9`XT ·ĐŇćĎ6ŢQÂFďbpŇNڧWLŞŽ¨Č%,Ő!1)ŇJ¦"?‹ęF6ĺ|”şî@. ]>K4omčYwŠ»ÁSÜŤeö¬:®hu` ĺk¨XÝŃ=ąË8ŢŰŮ­„Ćú Á˛µěŰR;%Ąl}Ź7Ů?q UR}ŤđL{ą9 !&eóŮÉ@ľ°U«…a.ű%ŽxĹę…$-yH°A]ĎÁăÁ ¤ëÁOŚCŔ/â%Ľ˙?ëăM%¤ú`ÇŐ謣˘I?!Ţřńyä{ZĄLŮŮnâăźW™/ ĂXÚn xU[?xîp¨e«$óҨ·Šîm5á¦/k$“đѸC+ #¦6ÇâăŻxé’Öľ”č+ˇ„Ô3ÖS^ĚeĐŞ‰Şç/ół° ŐźVş+G-Ńć…#–H&}–J'@}čë›ćÁÝß´Şzv0ç=Š:ÓMž5ăP‰â&C‰ÎŠë-“HTżôÁŹmD"Ö·)‰¨Lgî` _öůŽńL¦ËĎ)ţc«űib‚— é~%ĘĂ_=Ę‘˛ Zďě8uâ”Hëá6ű«JŇüçşźoĎ)A=µŞ M}ě<7óÔ?€$Ś‹M^á˙Mzć vQ>)ŔжÎ\Î'jJ&Ł˘93ĘmĄčlhŐlšjśŘś%(â@şOí¦TúÖŞÜĽ“ĘëőŹBK“ňGޱĂô”°ÄëďÁ¤Bś3’Y˙ľîßi´Zń¨Ö>_ÎÂmöćŢG*˙.»q§Ó-uşSĄ‚Ü8~6Ţ˝Ŕ’Ä,KWżŠĎ„ĆQOšíH wśJ\ŔĆď[¸q°ˇ¤1 óoŕąęóÖ˘÷›Ź‘ŮĄ—ÉĄśXö\Đ{9ˇö…Ů%*ż±úuâ ŇăâJgąc}Sä+WůŠ;ąÄók+-ăńÖĂ[ú ÚŞöŽłIOx<żDvŁ<1îr?˛vRđ…¨Ż˝Aąžt€ĎÉőű×)JYmé>Ś·÷×JvH DgŮG”ăo4Ĺ/«W:ɇ€łC¦Ş¤źÉ)ízI%Jş?¶<Ąe ŹĆoîXPdĆ.`¬ÇĹt¤ŞÚS=CŁ‚č|üđ|ŠWüř°O.jioşăěű+RAJyDQÄ') Vb7dČP±ú«SŢ’ŇCvÚžÓ‚‹¨=ćCŞ­ÉWžgăâŹPâňvŁ>#«­ţuüšĂB  “ŹáúłY… x0‚€Ăqjô(¨ˇ57ý6BU­„ŞۡUŁ űußtBŕ’ľÇ ş*UýŢęY“Ń`‚C.ęç˝íüwí˘Ë4íÁrď{řűőŕU™endstream endobj 197 0 obj 2422 endobj 235 0 obj <> stream xśí™Ko7 €ďű+ć8SdTQÔóšŔ-8 âĚ!@P~%-»IlÉż5;#r×ZcŰÂđÂ1|°LQ/ę’˘ż4ZAŁóĎôűř|ńë€k>^.FyÍŮâ˦?ô¤Ő<FEO"Zűfř°Đ*EŹ–óy 5E*6>zęi†óĹűöYg•36ůöu×kĺSňčÚW˘=t=*“lí7+^Cű¶•´ýcx1í-©äŤ·yo0Ć٬]هíz§b˘SO#Ť“#{Ĩ¨Ů›@Bmšá„Á8(¦„­ëzí(Đvć#ý5ď¦=ízPŢ;đí?<č+Kżw˝±^/>d©ŁMfëX•ŚóŘ~^źŐcś§Bt¸C{•Űż;şďśiţ|ÔöBš ér‚!Ťgó¬ĺÖmłjŐ!ŞH¶!b*f™›ŠÎ˘’µtaYIîMű´ëŤq̇9ă >®.Lăl,:ěµ<Ö,<™VŠ>ŻO˨Üć¦Ótgţ‡Â.čţëÉlb)nn ]ČbZb#%`Éčša1ü˛†‘x^.÷‚U/;TΑ.A]Hf ®Yó9Ş›řźAąěú ¸Ż;řiAq[3‚ĚČďÂý ßĘ÷)„L‰p1źhZ$'f±ý­řÓ%$¨Pá…¦2Î*ĐŚŢĘC"!Ĺ<Ś!Ín‰ÖĂG\˝öabpž˛[űĘž™Čن˛äÄw‹ťEhŚR†Ro†©ÜŮĎ˝}ń?[$Ëd• ‚âlQ=˝›rSř” Yhw€,›h.Ę‹v„–AÖ¶YŽc¨DâúŤu4ç2˝+ k¨ VŽâ§<%=4ó\™€‹9•L’ę* l®‹¦ČĂ„ęĆPŠ@ń«Ű° ·8,Ęţ·dË3[C‡FEcëqN¸+B(9TnÉ…ď×Ôž‡ňµÄ ¶Ę~BíŃÄw.B”¸ţłň- ·Â¤ę®d°é]˘‡oLŹDěQ:`řůô2«"j»R99(đŔ(˘ťűŃą)@Ť{şZ‰?˘Ô@ ¸¤Ł€ćűsdy3WçësíÉ~E«2ţ‘“[9IëŵBŐśřŇŐŇ,•JÍ5WŞö ĎËóú™xYí•ţWKi´S‰Í¤hD÷ŰÍu$Žw­^ßúöu$_ýDI>…«ă\g‰˘5i%Ů“‰dë{!ôŰl,¸|8ăA)™ŃŤ2Ať óź©pHKĄőwřÎŘö§ V"Şß˝(ísČ/–#VÍ—Y(ĐĎë\­Á@QŐLcýItħŕ÷;‡Ľe3#LJô$Ď“ýÝĚ˙'RÎOjÁůS5ŕŻ(oZ஦"6-®â]ţ¸ÖŃm;bĐçŇL‘çh娜r7ňŘ»BvoXĽˇźyŕendstream endobj 236 0 obj 1059 endobj 255 0 obj <> stream xśĹZKs·ľóWě)žIyaĽÇŘĄr)Ą$Žł>Ů9PK‰r‰\ŇUŽňëÝ ŤÇpiÇ®”Ď=ÝŤţľ~€?í8;Ž˙–˙o/ľřVł»ţpßďÄîýĹObůľ¬Ú}yŔ…Ňě¤fÎ;±;Ľ˝Ëˇó;ă 3rw¸˝ř~z9 ć¸0ÓiŢsć´°ÖOŹó^0®µŃÓĂ, ÎůéV*Ł”ś®ČŇŹäůŰTPN¬¸™~ś%űfĆŕ‘Ú0 Á}¸ŠŃĽ*ő,ô° "XM$[ďm¨‚ş’·§ôhAnt‘ăZĘ ă`z3ôƨÄ÷ă"K¨‚Të÷ë.tŔ>y`/dňÁcŮň°†m’Łe°ÓëYx&BőŹťvFXÔCđś7tí©<^­'Dv=ŕ.Ĺ”T컲 ”Kŕ¦0}‰€sV˙ť<KPś]B°s*>z3„ ĺĐČÍ cF° ׋EQŔëę Í ż‚GćłJäpO«Ř‚Ĺl{¨°FŚANŕŽqˇźă˘ůpů\őát7Ö3î3pžđKÉÇ€5‹&^Ű´ Á"9Ć ŢÎ1Qn jňű…E˝ ‘•LŮ/zĎE:ö¤–Ěčő(5¤¶—+Nľš5¤F 0y‘~¶|qľ pŘfú×ę¨(J3±čh‚ÖÇ!•çuś‚‘ňĂ\"!mŚC+!ó˙¶tČ-ă¦rÂeŃ2ł¨öşňR^PC.…¦é_‡Ćőşň4ÚC½N8J„¨ökşK , ,…N6@WIP79Ú„x/ËÚšă×´jżĆä?‘]ď«ŚÝ ĎxŔ9Ž!ŃÉÉŮnú üqhذş¸LŘ6ň]ĆöqĘ2řőÓBčVŇ#"p$â â?VôTÓnÄăęÝĂ.ŻŤŢ4‚Ś ‡üBN©…|˛°†|!±şP +m0oJ(€©üJ†Ľ+ᨑhNx"IĹ™™á"T„Zq x±p© <7’ľ}Gc=nr†šňEQćhU€ł$»3MąD“Ő°©3Ž”@â|C‰>µ%úĆŐ ůŔ5jZ5I]ŻĐ2ÖtĄ”|‹jAŹç\4Tű‘",bĹLŮŇ” ÂÄ{ßUMĺF¬&kß ‘˛lÓ"-ľ˝)łđŇż Ř{M‡’\‰ŘŹ-ď@–\Á!KAHô#áüŮl ĆĆîHJ=“Łů„DsËjézVkş§5î+Z˝[‚­$ČĄd\PHČp“—8­şüz®×YxTqŕ@ů0RÜŽxfÜ "4K˝MÁě”kY :C˙ßX Čf`6¨DR`q{t`8«|äe‰Ůáe ˙•—ĂvÎH)IPóÍ'!ußăŇO«Ô„ŹhđŠŹOĂ ˙¸P´^e‚%őď¨G÷i ±kČ0˝=_•Ž' 3) ĄbkŐçý„­K˝Ö•“A×˙mв]YâĚE„çU–ÖA`Řß·˛D™˛«,ń­ Me‰3!+ÚZĎCyápč<Á±H˝l€™ú÷K¦uW™˘”ýŁjEëCdźocÓbÁÓcúĽ)úŤ™¬†RňEíőÔ1‚B™':vmŰÄ1}oö?é¬,z—wŰ6ňŠú2ů4śź-m"ężÂ^–¨äĺ1Ť­$ĐŤë˙–‚ŹŁźk-/•bóUŠË`ďŇíďpĎZýëa- »«L"v •9hQ‚i`- ¬vń°.{ćЬ59Öř,2„ [íńTa‘s™ű! ! ¤óĚćĎ›ş*°IËǧ‰ť”+%• ŘĄVϨ|GŁ1¤3çŤ^ŰEĺ!J»¸",«Ë#™¸ýëzµ>ż,'@ÇźŁQµhm”g·†«„UČ#©”›ň,&U±1ťęG„k÷ UČdş9Š '7ęÂu¦®jÉś3»Żš0ő(tşNqĂ”7MG©„cş"€Oyz!š:l±QBŢm„JÖö~ßeS }]Xµ0`(sP9fČĄ\(‘Ë­µŰh;G"ľF$&ůF‰ĐNµ}†inAźŞŽ±Cő@šÂŐ÷;é~óJÇo»čÁ”¸Çm„ęűŮ2ápŢE&%dü:„Đű>­Ĺ[ âŐ»ˇÇc—’x?O Žrą^XÁ2ě lŠŻoĘĄC.ćM űÇ»oâŁMµý§đ•:¬ăŁŮV⓸í̤ś`ćÜÁilY)Hőu‰µ Ęö´,"ř8pÜčë˛Úý‚Ě SĽ®ýîźŇ Ěyßß·E ă†řşžZäbs–˛IŔŰĺ0ăASuÝŰ,KŻOiĄő†V3T‹ő©ë\R9$cť"M Őűsx!ëĂ´©>ëžjż8 žM–+†\AYMó Ú«†¬Čä&b©«ˇ› OŞé°5ś\‚HLŻJ-ś{`Ú˙,Şz˙‘.äoüN©ŢÔFż’k­€D©6Zqm*čžŐt;˸÷Ďę d€˘Hm”ş$`Ź `@ˇµüÚňUs¸ĘŤ{ŃŤżQ0?u‘Q§˙@ăü­řxLîĘĎ~·…tܶ@+şjÍE¤éf¤qA˝o:źĐ.0íz‚ĹXdzAłQw7Ň$>rŰ~*ü6¬Ŕ·†‘ŃDvśÓ¶3Ĩ`čŮ)6ž&.Č=h…= ]Ť÷'?ăď ‚W‘&Y@“UŻšá—v­Ľě¨¸©ŰVűG0u;8&bM’F::ŚÉrqÁ‹ĂĹ?áß/˝©çSendstream endobj 256 0 obj 2321 endobj 262 0 obj <> stream xś˝Z[s[·îô‘ż‚o>ě„î—ĽĹvfęNÜ6®fúôÁ’(Z5-É”•ÚůőÝ€Ĺ!Žez¬Lf,ÄY,{ůvď—ś‰%Ç˙Ćżçď'Ż„0ËíÝ"Î/ĹňíâýBŚ˙ĂÇU˧§¸PšĄäĚZi—§— 1~ ”b~iĺĹj v˝ÁÂB3|Z­ ó>5ÜÔá=.đĚ=\t\§ˇwĂ“•c.ĹĐ×Âć¤ΑGkŤ°pAe¸/ Ŕ$·LKĽ*ŽŚ)ľp" ±(eUţ\Áž‰“Še4S6Śß+îŞĹČÔ¸“0…iĽ/ŁmĄ„Şä-3Ćć“Âď›´©Už˛÷şÎ^ŐŮ]Ý˙nĄ±Üşá;<ČEČ>Wô#X*đ!K Ďú¦rH$p[g _›ş`ź/Öf­©0âän…Ú#ÁŢT`{§`lI,hö›ž\vu˙ŰĽTdm‚Ą7•>Q¦m{…EĆ °vŢ›°MÄ}]g ±;ĽĹŔ„ ô`…1EďŽP5ĘrXg¬…LB¨ { ú­$µ –LnëJ¶Z+®…=…!·vE˛¸-ěŐrIěôďčrlM1ÿХIo@PŚ{ĆŃ%qî­~Jd•18”Ć2iĺiĎ-Ťg^„áŐJ3đ40ú± tź“ńKřĚ’kŹ«ăR FΔŕšÚQJÔp‹O€]WbÄvÔś`1 şí›łeÂ*ľ±cMŤ Kn^9tÍdg,ő„&.Ő"B >‚ŘÚ:.5ˇčgÜę&™Ť7$ŠŮĄ&<ń'…Ă0Łŕ—•1§}ť%ëoqŐ8×Lˇn‘Ô~Îuě(é¬7Ęł#k?/ž/˙´řńĹ)á÷‘ $„ஏ"4— ·>ަÂöG‡lÇTôć h‚@Í’„ĎPr)95§?Yčp: ŽÁ6ÇëfbŐjĎŤÎ`âm'| ÁŇ99lu_yËsŠgĄÂżß‚¤MßD…MG˛ôU*lŕŢŇ÷C:(mdą.ćý±Şíouř{Ĺ"ę%řş8ľ®qňcUŤŠ§ Ż…Ü ¸§sżW-$łýzÁ>†.P†,%ůk=ĚćřŘ7•ͱ^E4ťěh>Ĺ„č„î‡x’sőc8ąžn"Ř$ůzMęF)[i`ůëŽŔĽâÁ\öA'qüíĚ™¶vGSę›¶vç±Mţ•:)̨ăZ™á¤ÖE®yZM©˛ßŔ‰PŃlđ4—Ç>}6rügĄ¤ňYü=A·Ä ^ʵ ČźT }¨ývšd¨,ÉX+Úuţ“Ńa¦âÜh[Äx‰—|ßÔń&µn¦‰®¶Ěů0[¬f÷W’Řî'ZÎËfÉ;®‹EGpZEń A˙s©ĚŃ”ú©ĚĄ-xŞŁę¨ŕý1öôŘĚg{"Üú5ER Üö"ŘÄďŹĐ±ăe2§cfI©ŻcRBzýř:&ĐÓ}±ŽĹKň°ÚYAZLűذ)w˛Ľľľ>¶ ˛ľI´EZÖßQÍŤťÄ~ôQÔőx‘Ě©«ŕŹ­eŘVś—Ř:ß<ÁŘi Ő˘;T·’pťě+©%ÜŽń,¸Tň1˝żŇ·—6ôß÷:o„Ô¤1ZJ·ŹYGxéŘL«äj% ăCş­’ŕ"ÂwŽ·4ĆfŢÝ3śÚTbć `XjJĚÚú\bvJĎφ`b“đ%0¦ťńÂĺ/®}» ř#RňĚ€SyžîĹký*!X_*KżľB˝áÄŽ7Ą°gLjN(†…ĄuęSg(W'uíy¤¸ ĺźÉ¦Ę·“ WmëĎ÷erż‚dH ź `ÖcŰžş-++ű„çî–Č=ÓVŇW ´Â-ŕŐz©3Đ& Xóí]ĹěÓ$+ZKu ë¸×Ľ•Îśˇĺ'jp—ř” H¨é’€jľ÷LH9S «ž7ap`4á>¨R˘ÁôůlÝH:ΰÓđEMMtbÂĘoĐÔ´–Yí‘YĹeDŰŰľoI{BđëP·Ú>pđĘ_ż˙NjoMô*]Űű6äM“ń}*¨ŐK ęÝ€Ů/Í¦Ł¶xŁö {ÄýşJeB-˘ Ó |ř¬¦^ŰI˝< 64‡%·y(ŮX$‹ű0µö†SI=É t]?[ł`#Ŕ ×ňŇRĺ3ż÷ă]ÍŻ“huCE‹GŃ‚¬5iG)Ŕřšˇ |ćÍDH&9şnô—Qń  9Λkî‡1˛ŕě¦ďw¸ť4M'·­Eo'ťT{źŽ|ĎöÂ{k1Á•^â be›©ÖLŔ^~śă˝dGúpelľK ěé0ü·J‡řŽtg*ľ^*şŢ>Ô‚OŔÜm˙«˘ť_jce8bĐ ±ĺł™Ť5‡Ř/ĂD§fŢ5T ¨.÷ÓX=Ô3 «ű‰¦•WŔ'>ěkŧŚ-¨jVđűžóß5q€¶`ÇŃéńçz´ŁcéĽtŮu­µiçĆ'|™^S˝- g}4Oźs v˙)ŽQPʆóP·xZ$P‰ĺn†‘Ů'i©ęÝ€ŤiîVűŃ©˛E.¨í_žĽ¨HÁP÷ Đîr čÎEtw‘ ®†A2¦%"Vú‹ňäM™Ľ®“—eňŞNnËä}ťÜ×!Z;Č=ŞJž$Ă‹4´ÁQŞwuřşĎęÚ]łC‡î¶®%ŚŐ-şxŤŹ<đ,ř]4\źź6ć[&^âl%-ăĘpL36¸t7Żo7LůĎĽľMîU÷;ßM$O!súŽV ČĚŤśÚŃĺĆymGtĘQE>€1Űä!î&ňdç‰ĆýmřB< w‹ťî<ť'Ďş}Ş.:ČáY¸9 ‹E|3YD\çŮ \¸ˇ°´7 ž©¶şNňn|B9,‰ímÉ€ú ÉsŽćťJŻ(‘Ú–RÇGrńý©´ÎŢĘ?ęśě=Ň<,vdß5> ÄÄ·!.¸üHćAĹ• LDLE Tq§/wb>ĽÍĂwRé ť'_őźU÷±ÓEâ›¶±0î@t‹> stream xśí[Yo$·ň¨_ˇ·ĚžŢćM‰ŤŘń8N˛â‡őÂĐęŽuYÇůő©âY ‹°Ć­Ţ®ň‚i*~Trń>ĎD¦' z5ę(®¤m8—ČP"Ë]űĎř,ś§”žµY˝+Ű&j)‹]­H\Љq`°‡K§•Ľk1OŠ9Ú{™g:.fŁ(ř¦t’ĺ÷‹Zü䮊ÔäÜŔ*đÉIŘV?W» €ŻDđű]lDÜĂe¬AíM¨='Ś ˝|˝qNM €ö’( ÖĺJŽmä!±»8j×qzg@BItE^J-P«Ô°đđłĚ¸« OqwfšĆÄGŐěN˝ľĐşXî1sĎsňśđě0jΫ¨š<'o]—Ţ2ô´ŮŞ|‡J·Äw?|ťčśjµ¨'ť/™8wMwVÔor\FUzîÓhĹ+Ĺ-ź ź`ś:;2íyk‰}sH`”~Äß-mŽđa'p=ŚĆNĘEd{»md çčC‚Áz‰ÔŚÖĽĂ4WčC@# Ł­ÂžŁ&k‹Ĺ$aE×;|ńÄ̽ðµ?Ěbł .O…^¶ ë°¸řč.ΉŽA`ř"hxzŚłĂkFŽcŇ´şćOd†ˇ¤^ cĹßTçU[‘~ýŁŠ0}gďxJ~ĐZ!@—€đvŤ¦0š`#{… ÔDzZ”`Ŕí—¬Ŕ›°“b%˝|GC’ ŤCayĆ„¤V,źeŇŃu9,iXf–Đ$”©ľIŘ0ţP’wÔ Ö#d`C€ç€.Yş4Wzm+틾ĎGžlżµn żŃr1ôoO —8’"ÖađIÄ;§ÄL±ÝBŢUöw‚ě5’lĺU2§nĚÇ1ň?ν!LŚi=Hĺ4ü‰“c&ž…4ŰČÇţÇĺůłałĘ&Ňű%Ä%ü'L#¤8ÓÍÚ€8dĘCSQĐ=¶w­¨^a×#©ĘŮţs¨Úᬅ~DSU[ŐDTňţo|řȢN*¶Îđž’ťô) »Nč# ]2Ń4ćĎúĘY›´ŽÝ49gÄăOÜöľ™Č§ŐsžV2×5ŚÓiž˛ż%ž“ŘÉĘ›…Ľ`98O‰ŮŁj®~3%7iÖ˝$śUsšjMLŇ^ĺĘP±ď'I.Ě—/áĽÍVŁ Â=“4cËé`Ú"% ÖĄŔ›ů  ‹˙şâÁ8 %»ş˘Z¬¤:Áa%VŹ<"ëĐ–” hâCĘa!ůî9 ±O9SçqąŤf‰Á艋&8cÉŔań' n!8íĘîŁ Â¦2 ~EŇSŁÍIZąÍ'ü•("U˛ Rc!ôB‰ńçÜůž‰śf#†DHu®–włŻ%–ŤÔ… 1ĎS4ć9[C6< H:ÝEöp ‘ĐÂW˛$ýô0ŕ>‘s?ľ¤ř‚C=—‚ÝÄ’*MĺNLB˘© áŞ#ź¨Ď­ótčIüë0Že1Řé÷ąÚןđý.MĆ©N‹O¨Î±Žqh`CŘg]ŠůŕUt —CÜ2uĆŽ&€OOŞRLPň…:&ďů˙™Č˙d&ŇÖp›Ěý:m7~l‰štvÄľü„o+eŮĐř’ yďHô[[3§G×U6}Şß–r…7ٸ/ťĎ*‚„ʤĽIŐżÉ.ë@ÜáUŠřm–ş·oźČŸ°r>\fď®bŐĚŽĽ%ŐĆ—l’«vfí3`Çs™dmíÇďŔ¨íŐ“í_D|ÉőŘ]˛mĎ˝PšŐžË†~; #9űc±@‹I±µ Qß] )Gr&-â·QW‰Ĺ&©‰źç·Y˙UE­Éab'0D‘”ą­›EöÄđĎ Z;ĽĂ!ډE&[ťk6YQ`Ň5‘ÎqUv˛.>@úćaBtȰ5PxŕŠE›}D –=˝­ĘG­ň[ĘŤńłpŻ<‹A¬Ŕ@ă}Ş[ľJ‹lYyî«VLŹ›ČŁ8Ő®V”3ëJŹŢ{ŹJŹS0…\H’)<ĄöŤ¬cŔĺŐF•\W‰čt]Á€@»)WňĹńv‚Đ*ÝNĐ–›pČŔ!r0 „Ç›>÷ţ&‚5:ŢNpŢ˝ĄÖUÚ:EúNňěă»ArÜr7h±–6ńĐ3´ś$Ůh/ˇĐĎĚřś¤uČŤ… Cô·ůhÝaŮÔ5”TYę.Ĺ0Ĺ|•7G : /BŚŤQ÷Í|Pc-Öh#g‹p}?'ź’JčÝ+÷aëÂIĘŻ?ě'¦`=őÄs!˙$–xu/hś¸Ĺćś?ßzŹß8śLr*×8ňÍ{¬B‘ë!?·^äk‚аĂ\SęŻ $ßĹ» şÍźŃďÓřşzܤZÍÍ·9ËŰhĂßšXŠŽ†^ýIŘň_,…XđĘ Á[Ęłžl#V»±ŰGC%źG4’™ÝĚW?®†§=•Ţ“Ş7áőş ČJŻîƦ đ÷7Íüe˛2•Ť¸*SÝóF¸zZ%‰Őo‡d¶ĄW–Ţ×5¦ŁXŮ—¸<ÎCĺ_ ›űe, ±Ű¸ß—±{Ą÷yi~Sšße8µŢX«ěÄÜŔâ5"Ü _ţ\GqŮďŇ+”`›X¤~—ńÇ8O˛HŃRč’• ďJďŮĐ^E;/ô < ć¶v^vע< ­)·E¶ŘTÂ΀0͢E˝MóW5†FiMň‹Żţw^é—OQď†VéUuŕ@ÔŃqˇs yč€ňăÝ?Ĺů=pPQý#KńívKÁ4–Ýŕ¬HDÔËd…+ĎGě?Qé~m:«ŢVçőĎă·jş­g*%Š>Ž;N»n†Š>h%9€j˛ÁQůČĐ_§Ě@(“Ďl¬Ć±=$'E~pX€WbŔŻíC^·›lŁ>Łčá¸Rz4‰Ĺ/ Ć^•CÎĆm´őĘĎ·Ę7ťčOsŞçŐűLjłLĄÎµÁXíu“sŁ˙˛>”ţ‹vó~ěápěب‘ŐŢU:k´uřhm‘9čŢ˙UaE qôiČ i€ĐP*Ćld†ĎKóOeŔSĂŃÎ1ŽËó¬îííÜëŇKĆ޵Í6Ç"ššËâ˘ŔňÉ ÜÝ1ĘVŮoĘáY•NÎ gkÎřýqî]äá§ŹFÖ8߯wÁ$2i«±„o /î†c ŠoËŘN‚–C×%6ëR­Ö‹#FěţÉčµt˘Ć™‹†z6ŘĘ┟ÔcŐIжő\¨wÝâőPŮdÚwĹz‘ŔÍĐH]2Ý?N-‰L)%üĐ:ţboçďđ÷o ÷ü|endstream endobj 275 0 obj 3787 endobj 283 0 obj <> stream xśµ[YŹ·ň8żbpw࡚7™7Ëvbv¬c?Č~V{(ÚK«Uâý÷©âYěf‡],ÖńŐAöűíÄřvÂ?éßăËÍŁçśëíهMßňí»Íű O˙™Ň¬íăŁ0ŃŔăÓd¶G§›‰yg¤â‘žQ–űmăR2·5ÎŔ/ŰŁËÍËá«Q1-”7Ă·ănbĆ{#őđ%y~:rć%źÔp4î$^Y7|ÍćçăN(Ç”pwš9ç˝<*ëęáo]b/ĘÓ“q§0\Ëá{ Ą5V;$«·&rc§É>ügHf¤~•eĘŮáźä÷ÄÔsŽ9)|3¬FćţbPž;÷ËŃß“L=óF…2ĺI Ę ¦T#?¶ěA[řćNJÇŕťť°đö$¶Go`ÎŃč8›8÷Ă}ĐM}|;‚‚ŚÖ‚ÇăŽ3c$ŚľŠŹš›á˘NŹ DŹÄ„T tÖ%űa”L›ÉXşŔe«“jř‘Jś!'ËŰĹ@Ř &LJב.Hű)¦­˘o]Ťr±Šáß#wLL“®Ë+ďFtĆŕËyo€ŽĚ€…\T:„Őđ–ť4§oýĄLŤšĆQM [ó ^"'|ňJ …áŁQqpWżŞ×eđ˛Ţ”ÁŹuđ®>žÄGăíp[G©ŹźůÁxËŮ‚,>~¨ŢÖQ`OÂÇPnîfŻ/ö8›{»Ř/>ÎnëÜW ;ů‘-VĂą× ;Ď­W¨ćô{×µvTcá!hěç!ş)AťójÜ'Ĺ;’8ÝŘşlŇ=xöJę9xŞ{şŻ®µ+ëT$Ľ®Ë\ě"®ő±ö]5]bĄ·aQ'PőŮ ?Ëďtĺ` ÷>sÝt—VŠáW˛*ř@ őŔ8¦™śD†ääŞzY$ä¬'„ŇL„ÓK”„Úß/ší‰Éţiâ٧HŔ-’€š Ęý}™Z‰¦—x‡¬ îp K˝î±Z‘íée3)ž©Uöö‹r ŕ PÇ —ťáŐ< „—Ţä ĹRĹ.б¸*nęŔç<ĐöăËéhaÖ9Ę ‘ÜIőţ Żčq/%zRz˛čçŁÖĚkÍŘJ¦¬^)°+_g´4A"M—_"űÝÍĹPVĆ0řĎ\Ç«ŇäZwí 9ńAXÇěîb!—ꦙ‡ąKj¶ä‚¬ĹV  Ćy*źLmrDĽÎ–»ůâAÂ`äů8“Ž­¸P®Ľ&®ŁŐ@$“­žX'ć~yë΀ZkŢ;5ÄŤ<ą·ž:]Śž&i<Ŕš[I‚f<Ǹ2‡úČ|€zëmÜĂi±őŰňÔŻBJůz=—'©P"@“«)©SÍ*ô–+&•XłJ%(x¶GßmŽţü»Čś„ĺ›—Ć ;Čqç˝ YĆóJ5e=f` ÖqČjßĂî=”Ą">ů` ¸[ŹÁ-ŕ!ßř†•PR]b¬RZ:xU^ľC>@ś&äŮ ´ %ďÝP.‹Ěý§őĐ$(T(K…Iŕ–•PÂŘZżÎ¤Ýş3TŚ»&ŽÔÜ)‡ž“nÖ·,€¦äęPGz­awó~ QRňľ«őO4*Ń_+QĐľµ ˇi·Ô" ‰¶őë¶:®DĂ NÜŠ’Ś+BÍŮj]ŃÁ̱Ą+M"€ ~Żhħ˛ŠĐá)ó_•ţÇ™‡ň$ďÔĄ’,d|m¸”F†ťĽżĐJH {jé¸3Ő;ĚM.‘±Än溜ūW F ŚIńl.ö &Bě×ÔWŘFʨ·˝KöE´ŃÄÔ ykű-¸·=Ϩ֊ÁźßŇŇrÎݬż–˛š(FËNĘHŚ ëA(ǰŐó#‰Á=îgLÄF¸łmko"’2,ˇ¤„biol\@&Q*¤ËŘŔ˛Ďk¦Ů„ćĐm^RŹĆî§­“nr—Ű•^PVIX%9c?©Ě]ĽF„™­tť(‹6Úâá“ S7|9JÍ .ZŇ5ţ"ž]9«čĚţŮN·PŤĺĄw‚şç)IgSMµěV”ÉË«šA–R1˙ŞÇqDŘKĄío{úFŞĆbŢ°Žą!Űz\˛ĆĘMfYĄ•NŃ$‡Í€^$@hIŃA&7=+%"W×'\u›a¤;wç;G=G[Vđ ŠPżč~ÍZŠý×rŻÓ­™pÓG‰¦bE§éŤjS:Eа)ŽSİơŘł¤F ФŘńÁ$şv“Hôčw Č„ŐzIBÎé4_+aZqHÉźÖPéŮU!Ó˙¤Ô&$Q𶻦Oř÷Š_JkÓô•ÉJYÎÍFgĹY;zQŕĎD‘u ±±,^bńłt EţzÖŰŕ»ô;”ß´˘\ĺ°cháÔ&â¤«ź›ž-îwbH6©(*şËsŕŤóÎCBńšŐĘpl)`-§RS0ă/z6óśÚÖ'5 ÉŻšŇ-ŻUsŞă}Č}CĎÝŚüźSô{›ŢFżrÉg| ýÚ0čśMŤ«ĺóFkW{ay­ZUç¶śżu”8Ŕ!_wư¬ŐąŠŔ RdŻYîjŠşłpkIQ¦ Ë–ła»~J™ëŘ÷BŠ!…y«J›ôĆIb7ogDQ´ťëëƦĂ!`6NÓ`0ćg“Ô)0,M^äîíjőńvÔü†Ľ`ĺřˇ9$Kgź ufő÷Sy:ÜËÁ]/ě\Wu°-­Ó`Â57ÝâA\l©ě»ą1C.,·„›śä÷Äl›ś}sŔŰ/HŰĂ6ś+ąŁ8–»eÎő+ž$tĆ\T8żúů}SŮŕü­ĺ!O{ŠK4J*µţˇÂJß#VLŇ~Ú)fćŞTźëg  ›S‘éTÎâuąćŇKç” x˝RmΕŽţŐJQI=LWű•ôc „řxV1‘ĚýS1Žt0öµĂ¤©Ŕ[żĂ8ĎIŇîŃ”XŇ9(čěb}t¶€±vÉŐKxŹŃs·7KígŽýsÜ&6{>$”żaDF©…×Rg–ÖöN…´ž gúŤWâ)÷©©‰šŚŁsߥÎ$«ł’(·Ľ˘q€ÇIc€cyŘuÎŘ—ôY×Ç݉XŰN‚÷M»łWş’iµďËfWII¬»Ć{FF…˘,4ôâÚKp›E"HŻf¨Nű-ßX˛†MNĎÓ  ;SłT5ő3jk˘ßúČ+Ř9§c°¦­.Z4”ň•Śű˛ýj$#Hüš’\Ú_{/MÚţ±ŔëxĚEí¨łÚěęŐŤphĺV×ě€3ÝňX© bÓśË5ĎĂ.3frŔ…–fÇ}¨% ?I9+&F”č·ýOŇilëőçăÚ$‰Ç5"ůhíˇ×3-‹wďdĽ«E0^Ł•ĚD‚MA;°Îîč{»+“÷űR<>7n%đě-K±^„ÚúćÝřŁËÍ=7ýŢ4~™÷]ĽŔlE€m±răŻÜpŕ]ČëS' fa®'ŹéBL˙Ô|ő>şqSĹ÷/ú¦iśęžh¤›#řĄGçâHiN:Š4ś)1oŇQ±VőbmşĆZ’Sµz5–›Ĺ'Ë ‘IŐpBşóOGYʇ~ńR[Ńuj×פžůšŘçkx^ΉżočáW &aŠŕš5“ë‘ßmžmŢoą´xÚŤ×@a‡źYl_q5MxćřróřÉćŃ“ď·w·O6Ź~ÚňÍŁońŻÇOż‚ž|˝ýĂć›'Űg~¤AV;úŃ $î°[.s*~3“. €ÝS©‚9R…ŕ@ľ…M¸đq1\áÁ†Ş`šĂy°KĆźUp0Ž^HÇ‚ ü ÁŮ 'ě7 íd§ X•oAăÖ(ëLrŚĆ ľ‰öt_ÖIľ<ąĐ>†D<Ąâ"6Ŕ”1Ťş+?ž2ŻŇ´  Ľ|«Ă••‘JŘd›ËČ·Á›:I<ĆŇ=ĹJ–ô“ĺ—|©3ÜWČŰşO"…ÄS I÷…ɻŮâQUśđ•×<ÍĚྥ•ź«B3i?I}f°Í©ŕMŁ%Ü­ŃáÎHä7é Rµf_i Ý}}Ź×GŔÄ$†ť,”V~¸‰ŞŕüŰyˇŢs Ă9o“ĄšÉ ~ľĐb»lHÁ‚9ő ëŤĎHVř::ĽŔ #ć)/ŞćOëŚI<ŰxQ QAžË"ü~<352±Ľ÷V(źúćM™őůhđ6´Sa5ČŔ´ů“ľ`ĎDq&Ź­^,LřvÄ RÖş Ę™‚~Ď6˙‰ęÂendstream endobj 284 0 obj 3842 endobj 297 0 obj <> stream xś­VÉnÜ0 ˝ĎWřh°*Q˘–kŠZäŇ·˘‡$3YĐĚ’Ą-ŇŻď“7Ń™)P Ĺ¬±(ňńń‘ňCĄ•©tţŤĎ«íęígc¸şyZőď+S}[=¬ĚřGŹVŐY— ‰+ŇĘ{ňUw˝2ăc­ŠG­ś«şíęKý®1*˛ŹTß6­Qlµˇú˘ŃŠÇhęCyű Óä=V›†”'rˇ~lZbRÉŘšćC_»Ź§B &C€UH hÎWÝ›čŘ'Oő~-S´ő/­Ž”Äę˘ßµ–ę]Ójśń>Öë!®ĂˇóŚP'm]}\Ú%ěKŰ l]„;Ş?ŔYĐF›…ÁsďÁ±¶ŮáĘ©MËëb0Ŕ!»*űĺÔşńUWä]źşSŃišRďšÖ*J.ÄĚ9«Sę#“öʙѳ÷l<¸™ ¶MëT"ç¦ű g6ÝS°cRTßČä™É€ťyą[Ć5QąDŁŐa6äĚ/7C0‹SŹyĂä™Ý &ďŹ)xçqŕ)ż ž{Qk$.SKdó÷Sc{í`Ĺ©ÓnoćoO%Űöç9éË?ąÚϦÂ˙ĎĆ üÎzIěŻçC*Ë–Uš4`™Çč ­ Ş˛~M<úµ[ŁA$áýrvyż¨OĎt`±ż)•ěˇç˘"„ü™eÇĘńȢE{/„ÔŽT Ĺ1Mv&H}ýZ”˛ťjnăUo»Č:–yhG"Z°Ł6 ŞîMýŁĎAëE"]apY¤/ 2u Á†ë>ľ.ůa˘đĂ‘úY'„‘¤DîP&î <‹âŘ脆Ä~ń/úí±W¨ýpJăwR3ę’J.X°ĘaFá_gŞ,ôž¤«Ű×ř˛J{|©źżi‚š÷÷'´Ţöˇř«ˇw0čKď\Vv5Üú$ťŢË4qąMőrˇÍ>d$Á`éźCŮ?Ö`ó2x-%ßßiw©#÷e^=1$Ř’ăaš“ZeyzęĎĂo¸°(˛Ľ°(`Ť k¤qyKMŠ©–Ţ^]&ebéUQ˛‹ç<ńQčx Ě—“#|VüŮŕÚVť,ű=reydŁ&Ě}r†0‹Ş$p:ä“dňď»Ő'ü~žŞxendstream endobj 298 0 obj 870 endobj 303 0 obj <> stream xśÍ\[ŹÝ¶.Ň·ý}hĎ)rdńNE€$vąw‹>$A°Ů]_{w{“řßw†şp( -éX*Š^EG˘fČo†sĺ«]]‰]Ť˙µ/_ž=řNł{úú,Ţ߉Ý/gŻÎDű?uűÔî“óř …[•¨k»;rVWÁ[ĄE3žŐN„]O(Uůťő~Ůťż<ű~˙éAWFę`÷źŽueC°Ęě?&×ßD”¨őţüpT• ÚůýŁćŇÖb˙Ýá(µŻ´ô{y8šĘűÔľ‚K­á»†|âkÖŐµ·b˙%ĽV)Ukß^J_«ćĂí_‘ë‡đQ•5f˙Eói—ŹG]I+ŚĘ~„éJ]zâ<Ťń(]~ µ"ě?;8x fR¦Ň:ř– ü5˝ňăů?ŰU°Ňj\Ń.™¶^Čf[Ä °¶űşżÄAťź}{öj']•ŽďÝ~'¬…u€ł^TÚ#2>y|öŕń—»7żŢ_ź=řĎNś=ř˙ůä›OáĎㇻ?ť=zĽĂ±đý8@Ť5ľ’8s°BKz즅łŔ€5ţŤ,_Ž˘˛Ö»żMđx‰ë`•ş+cŐţ˘yÔ*żżiőnĹÍSĆ›”řµ˙oJ8\IÂÜ몌­­Űß§•%Ť™SŔüŻ ”o;>KĚiŔމ̕ŃdĚŠc)Źß™uÓ–Čô0é;«Młt —o  aR¤ —ä‚ágóá¸5CŇĐš‰#Ş;>Tí8–PŔ.źˇş´•sšŕ™ đ<]<ß÷ú"}ŕ9ŞiŘ.ňnŰř@äú6 ĚUó:Ř“2)Ë繌f-LUŻf [˛ÜÍ@((Z%+Ű*Łź“zm5 l¨× şDý2Ĺ[3˘j9dä_˝ĹAđđ¦–FF¤ŃŚÔń Đ!Jő:1JSČOŰÎÇź1•t†7¨±Qą„Qw&8&ŃĂ)8aÉĘ2ŕ‚[ĹS„ÔĆű†mľSWľu°žôî!ë(ľb…„×P—đzTĘę%gkŽĄŹ¦'ĺxĘĄĽă¬›ŇËôŇő`+‰˛—6•ŘJUBęnľqL˘ý %Żú·î‡’—GCLwŹúĺÓ]F˝u‹ÇâQomŘXó;4`QŢg#, ü»ţIoMľTŤ±GČ?? ă*”HKO-Nű7ÖޡśĎn'ř >`TŠq"®‰©>Že+á§ő8Ş7U)Eˇ?ŤÜáý‹nK™ĂÔČ[żIśW杬֎ Ű;!=ŐzÓI‰^ú–#Ą,}0«řÔ0Ý8:‰7wń3­& qŻŻć‹ÜÖ4K×Ě ˇ™doZxIÄx"zťlI›?§9†>HNŤ:˛±4AjŢďź&đ=ĺ$EJ‚~pŽOJÝq:c(s‘|bŰUhZ :ećËW§ s-ŹĹĂ\KąyđaŢ$ "d˛dă’OG9zŔoM=Ěq‹$ÔŻéd¤—’˝ç´<ŃÇťÂ÷٨ąć킦„‚ŃTŁ)FĚ»zóŹŤi¤—&qľ|QĘ8ÇÔÇ*n´ aăicL‚1r„s’Öż8IłoMľ´ĚđŚ|RDBĐI ×˙•{o™ôQ´ä­Ňű?ҧX·x®e6¨2Č,3 °uÂM Â$ü—/UţÂ-‹‡żpf[ÔĽüÔˇ/äáá˙t>ć·¦YzE–ĐĚc>YO|`’6¬µŢá Ţ?”ožU`śDqĂۦRBk`™˝ŚI—Îx_/źý2Śkłx,Ć5lVŰşÄ1ŃĄ­Úíţ&A— +ÇÄóÖÄKëńĺ¤mk€l–´ms[ď[,C¬sÄ>Błž“ ^ś×=aqŠp×A-ν±p×AúŤ}PQÉťöşŇ­;7Ž6äp'ÁΓR_›łÔ*uĘŘ'­%_h+řxłEë*“˛¦őĎFvHh(¬E>Ü'LzÜľ^ś$ăÁík˝­çéÜN7 áş$!}ňÜĹęlôAR8kůÎ> ü­Ů•ÁĹ­‹p\T˙Â93ÇSlĹa›D@7Đ|T/źŃ2Ş­_śöâQŤUčŰú™Đ&šŰq•ůTTL›OŮśz%ŞeJţ·¤ĂX`ëEöČK†ř5 :d±†Ĺ$Ś–ó\†‘±r•°Ć7ö×,®€ÖQiÄ…`óśŁJfkś ¨­ůÖeL°Ĺ\Iă\çű»ŐU-Ýž‰|‘pÇšÉI Ű—ŁíŞ€HIăÉOfÔ ´!‘ ó–ÂĹpÁ†ĘťĎ˝E=)-Ë´,-zĄľh뾆ye†˘B4nň'Ąbkz±H5ČD/)ůŁ ĽťBÔ"AéMft6ĺŽa˛¬ĺŽSá—Üď¬ń@r8D”€-PěËgą UµRÓ ´qÓC‹§XĂjĆ:|k’QËÁ:Q’W ALćHřŘń '’·”„ľq‘‚Úß+ZMJ<ŃgdwÁHˇ’z˙7+ůŢ„ůM¸üsďň’Iy:$I‰ÉdÎ ‹_"±Rdž›wlřI©˙KORyş›ÚA{qÚšxŮTSPâWÔ˙YáSXĂšJsjXÚrz‚ě$‚l‘Ľźľ<Ĺ號Ű5@°%áżdţ~«ĄÍŐ“—ňľŕ‰"·»›ł,ťĹR^Ę29?‚ďB–A•Ő2ŻL `;oUxŢž!ó÷ű¸˘k,ě*Éd85O:Sźź°*eéđ+µ|(żyˇŔ(śr}çDŽ·I"RËi›ľ(&„Ä$ö·fő¶§ülůNňň–­2IČç¦iľŇ>aÂʰ´+uaŔ@K›'%ß•M= D¦SĚ…?ub~rsFđÔ Ü}#Ů(7©Íž ±đ)p[ÎúÔo .ĺâcXNŢ2xÍJÍĘŘĄ±Ćĺ:ö]ĄS7ÂhĂB&'ť;rOr÷jĎ[ó†ÍBp‡ň¶fü”¬Îţo&žŻ- ®ł&—[ä(ÓSŢc|ů”—1®WjY€6nY±¶B)‹µ˘ĚzoNpu?ěłĘ»q*ßuv9ĂÓ#ő°Ý`?ÚX\´Ś±ŠŐ»ĐMVž1"ć›ţŻ›N!íe9–™•'2aAě$R…8 !›đ$Óü]ńmnđł‡%púvľ`-GIY°Ôâ&‰…ňŹ ˙ŞęűĎúÓ˙ňNş¸[ćh’AŞž8űťŮ)ÝŤÚŘm$ šöđ­¦ărÝšéBV§ÓĆlŕşP°+\eVšŹÁ>*4'1¨˘bĎs˝1njÇ?:ęSD%;÷X9ţ÷¬ŻŹë‰8=żJ9Dü•o\ŔTŢ„x•f'tĄ´•×cóá#&ÉńÓ?❲ńMZY0‡c_AÚVŃ4OĽ‰íŹ^ć—äK Î:đX°«RÁ`ÁІ BHÄF‚ś¨ŕw0ë•!4Ä\ ˘:zZxéű+ĽyŃ߼L7ň:xđÉt3 ÍÝŰtyŐ\‚ďËÔÝĹł%AŹŐ\ĂĎâĺóôÚËt÷>]ľÝĹg_gźĐ}­ĺţűtwü5|íyşűÎŻáł÷ě`°’ÚÁ´:îë0ôSşü*]ţŘ?ËžďyLk ĘĆÖ˛YkzfęÂüUťoQŻńn¨lá­ÁÖÜ G˙ş»¬2J%ô™ĐcO’ Ó‰Ă|äZg(Ž#{ kÖ ŻĄ§”Ή<úA¸Ş 2łŇ9ˇŽâwÔ‘¸w÷J˛\ °Ý*KoćQ\ŘP Tˇ7™É4޶6t¶*,ÜŰTvĆxIŰÂ˙cK÷Q Z ®!Fó@&Šű›ěIP”UťŇŘM(ú¨@ľŔ&cŞÉŃ[}ýV;˙Í[Ć—'J„uóŤŚJËż•…Ů:ú2„G˘”ą–ąÂĹ#ÂôWűťŕC_×`‘9öÔ8¤IČ öŞÁŻ&Š<ßg|ĂÝĚ"5č&Öčô@‡yއĹ`M&Â6ĺřÍvQ&…«´dŽ `śšNqőŮ˙ąÉ;ŢęŠGŽ-+G!ű-}î@Ą`-.ÖmÝýr¨,X2Ýą×§mŹ9ńś7×®WěźägČ‹äjĎ[Ż)/ÁčŰ®;?ë2ëU—đ˘ĘŢă»äY«ňiÇÎ*'Ńb¤V|đŹ7™îg¬ţzPŘI¶ě‡č«€‡oĺĽFřkŰa?˛e®m14G™w ©qh”µŻ‡Žw7ÓÎä93¸«*m&ć˘ß€Ń¸+řZ4üţN€LľĚÖß"ţÁżC ń/5Ü_+÷ŢĘ_ßU•…ńâ]ĺ˛@Úéť˝m:ĺŇÓU˙nO­W…DOm’éęUČů$çóuú*[°Ř% KýĆ[%ő; ¨7€’ÜŹCFx K3çńě•Ö lÓKÇf#ěžVŻ`w€ů©'Dq3Ąx—|á+ gń&<ýBn˙tĄyŁ"¸ŕ‡p¶Č*V%ŤŞ–ćT]·˛çňdâÄfŹĆs%­žëďZĄqA¦”ç–°­DËó‹łóżgíNüštÁQP8˙@čˇ= ďŚ˙#)ÎA°)鮏šˇ°ŹAP ëak˘‚žť)˝%&“1ňôŽěĐvi ÄÚ‚H`:Ăđ 0¦jĂ$|4/w@cćÁŘBqĐön–hFPa°w‡ÁESTTíÁô'a|Őó7 HKű¬4U­śćŹŇ-ě˝<ĺa®fˇ°/pŃ:˙¨ ·­ ;âIđdť†–‹XĚôôoĎţ ąS^Iendstream endobj 304 0 obj 4039 endobj 310 0 obj <> stream xśŐko·čGýŠňeŻčm–o˛h8‰Š¦Čõ´@˛–j[Nô- ?ľ3\rgČĺŢé'MaŔ¦ąäóÎĚý¸z±đOú÷äŐÁ‡O„0«ç7q~%V/~<é?CZµúř(.´0Ő‹a°«ŁóˇŢ*-FxV;VÓśPŞ÷+ë-|Y˝:ř¦űd­{#u°Ýß×›ˇ·!XeşGlüx-ú Ä »ŁőFő2hç»ĂqhŃ=Yo¤ö˝–ľ“ëŤé˝Au= µ†s ;â+ë†Á[Ń}ŰzĄíÓPúAŤ§_˛ń§°Ä¨ŢÓ}>­`řŮzŁ{i…QĹâCĽ‘îEĐK+ŽĆ! źÄ‹Zşż­lŠÂ…”éµ>ˇ_iËwG˙H}°Ňjä€H,ÓÖÁ†‚Ú"(oŮl¤W}«Ťth«ŁSXţ$ŚÚ«îf­zcëş{"ň+Ä.HcU÷lśő®{MgĽ\çfRt(…rĐ]ĆI58@PˇWÎvÇëŤč­Uő gmďBŕkݦniňl ’§ś’ÝóéóŮÉ*ß]㡠DÓÍîď·ĺţ8z Ű>Čî cŢE U‚†×—˝ń˘űi-<˛Qqô^ŇőďřĄă&§—éčĐý0í*ɉRw3T—Q.›ŠV r& >ĘëWעp2n2Â2Z]‘T°á-=! Ü’XŚhĐä6,mŕJĺď8‹|Ő¤z‘iňŰŽôoŽ˘=;uE˛ťŃ­Ů¦ńبŹĆCť ݷ낉Ŕ¦F3űvѤa2´ćňÂÔáÍZ^Ů!˘%ŤďÁúťč‚×4ÉtĹM90ŠË+[‹§ݡ᧒äpy:®ůťvš=%‰Őػнť®xL f˘A1ărŹ×˝ĺd . íJ÷&=e0¤Ą@ä(<Ҹ^ ĹŮÜ#K6Ćql`V 0´`Šv]ˇ–Ů“ą$´‘ (4h†ŕĘ >Řůa†D66p`YfXV|Âá†Íx-ÜčĆC7"9†ŮĹŁ¤>§av;¨L/­˘Ł÷ýËçG|łň‹µ2@µÓ”ÚmnIbcŮ.FV˛çL8™Î & 3Ër0®TŰŃîÉÉÂŤé_ĄŕE‰eßęŁÜC®Ĺ$>éň™ůŮÄóňpáŃ*ą|82ł ! ’ú!§{ŚÚ$· ĄGXĆ2‡žwÁ˙iů^Î`đx˘w°rI‰#$© ą*n@kżhˇ…‡Ĺf٤ĺ«P`Hˇň׉ęő`0ĎLďŘĄX&CĘ.Ë”oÎEPŁń)!­çO ©Ás<x씂–yčS>Nţ0MŢĐäĺ4ůŠ&1Ľ…ńńRÓěkŹCFCx3Z—´ŕІ7´ö–fŻixGĂ“ćÚËć®h-Ăç{ jZűŚĂµ ÓÁ~XŹ“F‚źđcó$†G<·ŐÝđ]B /Ü}¨Äp× ‘Euś=›fŁgžśňŻÂßWÍ›łŰ0î0,ńކ ř,cÔ3‚p=ŁH%÷ăuw'°9ľLĆŘ6\Ëpcb1Ç83h.ŹĆ$nÚ€€îćZ÷¸ ŞÝčéfË2pGł/ ÉŚćł—´öŮ:;ýßż°,*JD; ŘMs-ˇŰt„ŹšY+ě-×U¦Ö×ĺç,»mŇţkš}J´DłOhöhšŤĘ,ŔÖâWŐč«&‰+ű’lŃUA+ˇř1Á‰u:ŁĎká« 2#Ö1c ~–ďé$K:•Ű*I:oZł«bíH§ŔĺúŠĂ,É-Í^Ô$Ëę0šQ·7Ą±dKďgƸrĚŚ/ÉvŃěżhřAřkÉĄA;ŮË÷Ë%ĚÜagXÔĽ{Iúđ¦i¸™ˇą řSm”j‡ŔÜD6˛^Śův˛9ż®Í­ee8Ůfz/ŻĄg=÷îmůľ/ cŠ#Ńz/;Ĺ !+ ŻW¨~Ű]Ü6”ČBő m{L ý:™źÁf<*™©ŕdŞŮ۶I9%¸Ą ü߉Hééó°'¸Ohöß4|LĂĎhí—ëŤĂTˇV ĚeÖ“Eóó …!DAJVň1Ô[8ŠĽÓŠSçu<Ťł[üćÖű˝˛P6µśýë¦11ĽŁŽď”f"1Üč4ýŕąôśĚ°#]l8™j[Bdä"Ă|úŚTé0Í2R2…’ŁÖ}Sâ‡EµŹŇÓZ›rT›%™ÜH1_ĺwZ¬:Źźr=˙ł(Ohë=Źzü‹& ߸.@eL™-h?ĺ/n mţđ‰f%tŻ´•ěŮLŮe±Š”¨…Nĺ´IY‘źDAt˝´¨/ Ł‹Ą áz-^qč­ó¤čŕE^Ů,\KÓO!Äb-LI ·Ő9ż¨B5µ2– µ™ÖÎ4Š ¬Ž BĆfłÂHJô©ÁĄ$/(ĄŔ]›:­lĽ”UŃK)ü0<­űzśĽ/ëČTŮ€ďČa8Z,ç™ÁĘ]Ą4†_;§Š™đ"° zYläÝ' óÄ8Ë&·Ďb"VnÜpeĆŮ^BZ,rĆd˛óýT{F0·#‹«zž`Ţď® „N[·yđkŽWť¬KĎR=—ŘÎŽgő´vMýtŞň˛ő]sűăġ»jîZŘÖ?P¶J0a¸^Lě±އ^ ÍŰ\.šÎ·°˝kaË©c Ýčĺ‚P¤P!ΫµŔ@˙uŤŰµŞÔ5αkZÖĺI¦9÷©LçEU0®!c‘DaÓN첄ĐŔ÷ŰrW”?/лڂá÷Ő’Eő®ZR–7 Ż Ć.¸˝Ź§Î¬m&‡/°žĺ{;^ČxÝ”ďşS(v— ¤ `!ăţ„ťŔŠ"·¸Ěą×˵· {=™ŢîŞÇďíÖ†ŁóUB\š…¤łRغݝ×fĘRž5Żg]rş<ě˛Ř<Áp$Í"j±Mě.—śFQHĹdćogu+Äú´M!«ÔŚH"cć4âş›|Ą¶!Ö& É[—)ÔÜ 0TŰ©“Ô+§¤††7éŤä\É»«‚S˝6ˡč˛੹ E•ůt %Ş2” ˙fűÖóÜĽbŰŠV¬lרëy^»‰Yą=eÔi<Ő˘Řţt*Ű2FâńŇí LŘŽ›çĎĹ<»:´ô`Č ˝D łÔ;06 )âłî4ËÖUkWdz@n©©§;cý=Ý zrźNŚĎ€a›ĺ Ž×˝űz¤Ĺć¤čfJOüŐČRRşŻń­Äź*BşôT9śĽXY„Oŕ_hř€íÉĹéY^X$M>c?`KžĽŽś ¦ö‘ůHôŮ ŢĘ}dŢ´ä˛ó÷[ ůí­Š…ÝE"Ĺé…ăi™—ŞfßĐ÷gÓwöŠgTö¤fŮŻv&˙lv~WäfÎM»żaݰD»ÄzýËĂ’“ć Wă npU l€Č{xîqcť\#ťtź&µçvó~úľŰV6¶_ĚqfĎ×f¦I;ahĎôôtN‘ÎXŞEѰš€{¶¬dNď‡SiËÇ6ÚÔ°1üÚm°jĺańv–äŰąŃ!5‡Ę,ë¦l÷Î8Mˇ“Fv?Lvă„Ţ‹űebňŇÜ iěÉOď%vk|Ţăíuą9ĆľG­+‰OÝ”ä ć4¬zOŮçĹ“o—v ő[z†SęžÚ‘°Ú+»@tä⣀ݑU/ß,°Í…n‘z9ůíÇ”÷#Ç ęóBŘú,—'Ü.ýŘqk¸4ŽîŘÁˇ2Pěç!¬‹őpjĐ{»Kî*ßZ‡·EC˛”Ř&·yyÂ/úbZYůë:™*ĐMďJ¦`„B#8 A!3¬Ä_s‰}¨Ąµ‚ăcm`OIĆ]6ě)Éń˛¦řů&íđ17Ô­Ó1hEáIńSJŘE—Ž|ű8FęJţxóÜ‹öř{ő\îÍősŹV%†Ł´ŘĆ o]$PŠd)Ň]Nżň€›Śf/0ö+˘pŚőoéa±ŐÂÚ©±—•zްÎSĂBqsĚŘRýS-é…,%féí<×Vř&]$©Č'ÎĚXýň)#7<̉°ăܵ´ütÄ6f±Cö*9oćŘo„vů,•ĺ“NwčYť|”–eĆ @§bLéËWwvëŽǗ˛Ăß>’/{^÷ˇ ÓěvYq—mĽ’ó Ôôřł#)ł¦{mŰů¬ôVލ–oe*C°ßvÖĎ•x ĎŢ&„e•Ë ţ»{ ĎßŇG˙„?˙—·”endstream endobj 311 0 obj 3483 endobj 320 0 obj <> stream xśÝ\YoÇňČ_±yqvs2}w IÇ–/8±#mŰ0(ń° ^¦HIü/’śękŞúî®HˡŤz{ş««ëřęý´¶ýźô÷ół˝?=aL-N^í…ń[ĽÜűiŹĄŚiÖâoë0QĂĐŔĆQ/ÖÇ{ă଒Ĺő´4Ě-¦1&Ä`Újře±>ŰűvůńJŠK§—źŻöÇA;§…Z~DžżY±Á 6Ęĺzµ/ËÇńQŹlůdµĎĄ$·KľÚWµÎ‰ĺŹRÂľŠlńµ_ÖŚŁŐlůwxmb”6=r;Џqšńňü LQbĐJ-żŠ[ xübµ/®™ĹäÇž"90'çf¬qŤÇřř$Ş™[~ş2đpjŇŮt ˙+ľňýúËtnpškéo€Ą+“ÚŔ ·Y`»MĽňŹ~‘}7cřbźXhä‹ő!L' ˙Y{´Úg&—ŻVbPĘIą|±‚;îp¶<óGv\i±ĽÁ—NqÂĽ?h­^^ă(Yá_;‡ąŔ Ĺ8Ą€¬@ÖŤ‹‰Ń0 Ht3zů†°=-aM8¬ … [‹”Ňt…rŞ?.—y_$"'§©WxŰG85pIŹÚ˛Ś3鸙X>˛†·@“„5nůvĺoMŔ ÉJĎ‘ę›iSBôQMź˙ýCż) öéëźĘżfAâń>â™…Űřęĺ† ;h âä…¬˙˘{/äľËHëÖrLJ„ś¨ČŹHŐ${¬PŐOfžŁF #łÎX©—O'ňVsă`ÁŠÖÔ”BD%I§ÝgI?žJÁµŔŢů÷ą±!ęq‹“zŔ yű‚* X PK:zĺ—w{xvŇ‚0îYDôďY-ď",ĄÔŕĚh=·…† ł–Ú©ă´•Vłúʇbq‰»7ŢĆ©ç8•Čť?´\ˇ*ĐY?Šr@>‘ Şbůin{®ě`ÁYThÄ yý˛şV‰„˙n’¨Ł¨j›ťµ˘PEnŕ–Ď›š´Q&´ÜčÚ/ ‡Ń¨ÖĚR#ý‚qś «rî‘ëĺëłŕ–€·DƉ˝i.ÇOč*mÔ‡xÎI® Î… Mb,\(ÉlU)T¶ńÇÓ[3¦–Ăą¤rt«Ňaq1'ŇŹÖcÁ§ř;TrmŤĂ |;Oç ŮŤđ›= A˙jČĆ^mG9řÇY#ÎË\GŚ‹‚aµźS–S.“Ăś$‡ˇĂ 7SěT1+Ńç…תҥ{ŐĽs4Ś^Ž@Ť坬D ¨11(fUÉÜĂąGçŻ4Ě0^+€Ôq,IuEMr(*:śYd A7čAĄÄ+<Ç™„´>ľ"út转ô€1˛2íĆeg=öKV­vMŇNÔKüłő¬†gűKęó%ŕw}—Ď(ľ€ GłšŽžÎî 1Ú\Ž<ŕ’¤ÝW§˛·±˘˙;ŃúŰîq.““a×'Mşě®[<ěuAT5fćF/zţ$3¨ľ;&oőŠ×şaÉZřtŃ]jú=y™pĐž—éÇ×ɬB„B4„L8Oşi SVNHÜŚ—)ůtlD[3q şĚ,8ŃÄąŤ>źŽÇ{R…&Ř=E!°ÄĎ\ö´%ë¤ËbBě™·_ ě—›1ěd´_·+%Á÷ü™R&…¦\ŃĐ”CL¦ś]¬żÚ[˙ń[şOևا“÷Ń^wŤŔU˛ţĘÇó°Ü¨‹EĎŁY§«`uţý–Úë ç®uŤąÉ×#Ŕ rń°1`/äô>ĎîŐŐ‰é`/M%ň´»,‘Ă~ó,˙Ĺ·rFQŠ;˘‹}”„ľP·`‘\ě{#A3#żçÝ}‘ˇ·SúH[–%׿î:á·‘µvÔí-yłţhÚ?b'Á&@2,/ŮDŢ OltŃWúGÂmHĐAIŹóčc|ü WřGźâăşyÍυŤŐő-żĹ âăÎ}‹Ł—ĹÉ3eýÎp›WÝÇś{ŇĐŕżoanOÂ…V†‡ ĄÁ`*§Éč_°V3˛ă@çÓYŞh±U­&&I¶EtÁ@ Í?éÖŘ>#[¤÷Ói·őéËă]7źľČŰ–Ö-”Ő¦`iëĘ‹ŕPŞÚ-E±©¸’×ծ̣ fÉ ó×xĐ:ŤrRßN•|)}a€řŐýÖy7rśčY ő”<ô¸ł-Τ¬N #ě|’ŠćÝ I))&1Ů6_&mcřŐ ¶µŚj˛MuĘůŐ*[Ö2’·I)~ŔEŻ'ŔŰO¨ŢÔ$Ďfř§ÔŞŕuö(äNŠ|ąÍ›†ëŮcb€ůĘćľ&h6…O1O€ýúZí-k3ö–@H/(ëdD;Qdö·>ĺ¬äv€˝Döń˛îÄ4ąŕ &Ćlß7PʦşĐˇńBż-ĐđśŕŤÂŃęăřÇS\á¦çÜ7ąq ˝f}y.“˝_žÓ‹;úrŹçĺČîíËIXűkřro˘ëÎs°rP›ë˛ęE^:ˇz×2á0YS#ç‹í©¦u˙Ňtł«ÝĹ_÷}[0°€˝f l‰ ±ňŁÉŁ÷Ł&ŕwţ[5!$»Ám*»ń _ ç`ôó}ZžM„šř(ŢŹŃ‘L ›˝¶)‡żňoŮ­ěM\ýˇU)ŻŠ Á ˇ ěŁâUö+,Ŕ Énc䪮Ȧ—–…`LČy//A®xŮÖÖ·f!)ˇÁNd«X[µşŇ>qEÎăń¸»!‰Šć2řßí2Š´[ ąĚ(7ö®Ş”})łč5.Ńëçý*VîýŕBó•ďóÁáčt¬ :>Q®EU:É.kÍ›ŻXc¸wrŠ=p1$­żsyÝS¨ŃnMj´•r»Úç`öMŁE¬§ťgDś±ÜĘŠ»lk׾P‚€¸®đ7xčđ˘p/<÷aÓuÓĐĽ+Iײ]Â-ăL¤])Á"íĚCţ\of” }9Ťľ@Ĺ&¶P…´¶¬ýĽC ą_%ąM…5««TN¬“ęwDDÇ(ý~mŔ¦±*©‘÷%ŁÄha‚Ło^űJuŐîËçĘ7Eu¦ă ¶ččŚEyIZz·k5HĄLďhŤFŁi'`?‹SµFŽ W»ôF€ŞjëŔĚ,?]1Q`U±>Q đ˛hć˝ţ¨?ÄŽŐmŇ{›bÇŮLÝí6'–YŮč_bŕĚšCR¦ołwýv©R­rÂűa˝CĆ]źTôßŔÔ1”Z«şŻ¨éôSú}u•ś.WS™rr8¤0c@Z~¬ř[}ł›ŐuG@ LćŠ/5Č]‘ŚQ'ß[ęĽÓ·ËŻ|JÉ”=‡HÂÔĎN*őýŢ@/v`¸y/U\5]%#P#Ž ÖEd„BO6şśfî Ą1š\@ŕنe;ůŇÁ <´€+˙/Ţŕelä› đ·1í Eŕ{~RŐ7˛©—]iąžwzŇŞŁ¤Î>OŢbZʢ*ĎPĐŻ°IëG µ*i,¬ťĎ©ŠÇu©q?ť­DôÉŤ(M‘’ŻÇ81iß·ËHŢ n˝ĺ”*_b3űqFŃ‹”›äw‹HsÇőNýŚűÜZŹ‚gjjÝ„ňI#_¨’©Ť–UUm•ëXüMľ’ˇ˙{1ąŚss =ň*dy’RűÚeçĽ5÷K©‹Mťď‡şmÄCNn˘[Đ% rŇꂵˇ˙š3ÚĺK¸©Śd]ś®ŠŁľˇ‹U˝@S墔ő\Ém>¬R”źdF^ű‚źosĎ•Ňţ—U]šVf;•ŞčW­ŕůqŻ~ŞMLđÓ`7łu@®.'F‘-ýú¸.Ď~…rW(¦—9wźÓ4Ý„˝m+Ę…)(ßPű…ëÖŘýÚľwąó݇Éd_ńńu•Q/˙ŠŁ¤®rŚŁ¤‚rŽ;“šŃřHZ»®qîAÆ4A°1†‡’Pýi¨čMŁFöĽ#‘GÝą‡řřÝjzî ălŤ:R”řkHʞ%śű‚ű5“¨ý‹iDĎMTC€*Uč (p‘Ł!m!ÄHĄďÉ řyśQĚ® hn6 ţŽîžcźrŔ'9Ű˝ť÷B[ŐôńoLáTacŐ2yó"šÍřg5M@Í7r)Ę+ŢęEŽŹéžşí=ĘŁ÷dÁßoîé~ÝëîöŢҲA°Ý:Óćb‚ ~T€A+Vvóâݤ6ůť´w÷sÂďR¨Ü`ţŹX˘˘˙ź ÁĂCÎĽÁ‡Wdá«ëŔý5ví8IťrŃ,çj5ń«/łă–·đšąC×RÄL P$VRcý.]rĺ71±ˇďč€çę@?/LŐfů¨e®Ó÷˛C5c›ďYCë\!Ţö*30«IČ;űYIl‚*2™›`{›ętż”:fNôËXäÔďf?űÝ‹ĄéÉ-ZďÔij᳀~­ä˙ ä}Ü`"ż]놲¶ç¦ÓŞ3â\ň]ŔŻݦVťßw!%YáYs"żÂŘ=gc©‚őx˝÷Ořó?ľńˇendstream endobj 321 0 obj 4024 endobj 327 0 obj <> stream xśµ[YŹ·’·ůóĎŠ÷Ŕ‘­Ŕ ěÄvČ{čXh5»ZíĘÖżOĎb7{wF¶!@j±ŮĹbť_9ďÖś‰5Ç?ůßó·«'ß aÖŻŢŻâřZ¬ß¬Ţ­DţĎłÖOOâD CLpn×'/Wśo•‰žŐN„uJ1ż¶Ţ›őÉŰŐ›/¶š©Ý|µÝqfC°ĘlţNžżÝ ”ŕzs˛Ý)&v~ó,=Z.6ßowR{¦ĄßČíÎ0ďCPŹZĂş†,ńo$ë8÷VlľĎR\űü(=Wiá<ă_äůKbłĆlľNK+x|ľÝi&­0Ş›ü 9ŇL˝4ă¤ŃxÖżŹŚZ6˙Ř:ř $ )Ă´>oß¶OţwňϬŔ‚•VŁDV™¶>č¤-˘€čvŁę#Ů)ĐŚ“ëťt@ËőÉLĎÜ\^–‚b ĂÍÝÔ ‚bóşÉűđÄ%saóÇŞŻŰ¶ů·ř@*›ź·B °Ăćt»ĚZ#l™É#@NĘÁĚf„Ôe[?±˘¸řSŔĘ{$[·ŽN¸FăBÓŃĽďꀱ[áQúްTgÄďÉ„łJęŞcK:ĎÜ«Y,ĆŞÍMý\ ˙hşv‘Óňýľljyj‘ćű­‘p aź¬?bźlŹĐżÜ˘ÉHíŔ0ÁҢ©\7ËÚgţ­L*Ě6O–˝j*Ľ‚ Ҷ™íH"Żk•§s÷LHIŤŕ%ĘŔ0ĺőÜ4#±jšÝÂרdáUĎä‹¶pR¸ ÜGÉŰ݉ěűfű„™ł6:µ á**DqfŔ¤ŻŰTô.mŔKI¬şoŻ›wśl˝m‹Îy˘fMßzt,Řp'môr¶0 <}ˇXÄI-ë]{ß,ŁSKţhęd‰°1ő+†á5hŻ(Hˇa”‹őÉ׫“żü@cúëˇD‘{ĺ2(<Č3ĘCŚůĄM%‚hA榽'*/ÂďőÔĹžBŠěôMݲ" Ds]ÇöMNdĄŹY!PE5ąě­Z2ŁC7›†ě‰›ŽDťŢ\Ôׄü«Ń`Q.¬ůY‹`-—|Öx› őŽGŁđ]'ě"Á}3ˉ­ĎĽ\Ś])ĘX(a¦ŮâMüÍ44f÷•Ór@*Sg®GφJ¬ľ¨·T%†…ÝÎbzüŚdŢżŐĎRú–ÖÓô 6& TLđiß‘CÁ–¸1|ôŃ]ËŕiDs¸0ŐîŚTŚÁţ¸isďÚc¦`C¶ËčM{¶{#zóçFŤ· gÝÜBLĚF'ŹĽÍĺłŃÉăŹ[`ÂaŘŘ|ŢF?Ďě({;®v;rIÓë ŘS ,Č|ŕX\%­}Ű‚ŰmtăžCâţy 8~)ńĽ=‘Źn[ !ë—UşvSaŮ] x—ť7¶&Ąe=¤!ąÂ=áó´™ô›:ł-Ó(’eöS.0–Th2„łŕ PC„’0ţC(Ô´Jp ‘iI‡čżŚ}¨O/FđóO„ýâPJř+ą—BaE-.ÄŚ<|ň3ŇD îč.zš%z&ě É`Íż1ŐTň • H¸ŘŐ€F˘ŮJ#ĐqÉ0€1Ď;ă„ÂöÍ6š^·ĽŮÁ24 M‡†3…‘Lű’(†Yő0 <Íd}ń‰¬zě[3ě1Ć-…yÇlŠó1t|zśßŢ_—÷jÉâ4ż–ě}GVtî“SS~QßßŐ(|@Ť!EF{-´µ§Űćç]ö‡Ç%°·AH*FcÜći…ä·öH±‚ß4 N̥{?Nö4)%(yÉgď9ťˇ…N=e1|9Lľ÷mîn´,ÚGúť¬ç‚Kاv!^5 \?őĺµ¤ŠĽ+®h5A2Şô2Nm÷łĄ*ŇŚ}.Qý®ÎeĂF*ýITśE ¤Ţâ É®m}ŚtVcŮG¬ée5śl.ľóˇ4ł 6źb°oGń,UČĆvÁ~ŢÚh….ěČ…Y„ “íĹŃ©‹DE‘@z7Uź—r]'¦8 ˙P÷OŰzăre\Úś•,˝$ÚsrŠi+zFEZ\Ň­źQÂé°H«9!łÁ9®Ą¤Ł™‚®Öo¶+RĆ –»®´¤™3M óźŕĚUJę¤]rQúCa^EÖ’?6đ,Ý˙uGaŢś¸ZTŚ7Ěp3oôUd3ĂfeEkŐ Źm%ŢŹ‰‰mU3I1«—[ë­xPŔc´ö,µ—…Ďľ&ľ›Űhn(¨±MŢdäßŮâkc= tde;•ąč„.ŕč1 ŤÄŰ"jíČ ă©Ä(v“&`Úimf@î 5uB”#Ż[ľö±ćY¦ f&‚8jŽń «ÎÂZŚ*łČÔ1aŤö^O"ö řŽ3ďh¸ź xŃ˙şÔšrźV]šˇauPqĽ™Đź4<ŹK3ĘY¦¤ˇg6݇´Ş°<¸eô ĺ¬ň9«“ęí~aŇZś<íĎaT“äĚľG«Ę¨"C}‹ČpLwŇăD !c‘¨ŻŢá:×IÂčÓĘCáťT™Ë}ÜÁ4'© ú‚ż´—•šÜ9¸)…¶žĐu$¸šŽe¤fřdPZO‚ö¬ôťt.G–ú6ő;ť÷öNűˇ 5řMo÷-ß´üô޵¤ëh ăH(ĺ<ä*NŹ—ĘÁÂcpşµ#ĂÄŁ ¨˝˝W ŕ¨rn ¤ŁBđ+Ů7f¨,ŐÖÝšµqź}Mű1ëŹÍΧޫgJČ®ëš_ÄźZ…;+<űSŹŰLÉ‹‡ŞŢßł÷÷;T˝ąăpţp¬!,aé™í­ÍNňOŹç­Ş˝Uµ›źÚăľÍ˝o٤Ë~6ŁĐWÖărÂLJäń)ZÁT Ł(qnN“9c^›d64§˘\ęă¬ô€řôtIńŔ€{rfEŔcmşĎ¶Ă‚ç¶ćAŃť¨-¶1ÓY8XŤLZĺΓpQ§†äK®wÜá¦x<†Ęó.Ö đ˸ă:ŚkixŕI‚čNR0Ĺ#ŔĐ ”LK#ćíđ 3j•K¨iĄIÜ˝źquh5­ëŠéš §´®†P§ďěŠ"ü@?Äm0iQŽLyç+xd ćËeç7C_í®śHŘ”Őn :”ŽîşL‘/gŽÄÂq­Ą>1»9lŔׂ´'~1ćQOĐ#´ůU»9 ŮĂGđ=­âÓ& 4Ŕö>—¶ţ'>YpšŹŁˇíÎ=Ţî› ±đG+ŢŰl‘@ěC*í\ ďÉW„VŰM®măVkm;Ľź˛xů«ŔĽ#Í#¸ĺ D“BVŚÎ|ęř o uż•±Ń µT9ąř=©6ÖYe=µÝ…ĹŠĹ„Ź¶ć…Á„/°e…-•:vÚÜÖч XśśAŚ«‡QĚmC14ÜÔ÷?5ř°oďD8—¬őęhě„:”ň ±¬÷É5›śt€°IׄXC»Ý3.X»8čŽń0`ĂÎČÇJü\CĄ¤ĺ$\@éĎ$—s>m›ô®™¶ud”Ă ů[ô/L€˝żĐż@m¬[ÜoĘ`Śť€U5%xöY#ĘĐ’ĐD4|Ö ¬ţL] Ç´Xj R\đ±Â?ëöÝżĚkŤ~­óvÓ™öŕšQGĽű*źÚS!ę°F1ůkŃy2ŮᱎU© â¤*ÇQńčEOÖŠ´2:ľca¸zRýüj¤]ČşĄ¸ň^¸_őgúĄ€cĺ­Ĺ4âdRę>š8ćň÷jBrş•#ţ{¬ŤwŁm×—ęâJ)VH˘§éŹ$î€×zŕvIÁ®đĘÍôîä`KÇ:čÍ`#Ľ© ~ °<Ž[„d‰®íƇ„Łű~ŢĹČ’ÉŤđýĐ—.Rh…˛öĐ{™*ž¶'Ĺ«Qď|r‰ô€0i„“Ĺ0Ů·y‹îď»(€őĐ˨©I?řy߾Σ®“A#0żô5D™Ó[Ý}©šä)Ëĺ ăŔÁ‘™"ęV—Ă"«ISüěÁ}z¦ČĐÄ{Č`D1gĐ‚Ěëćvp†Ľśtę^Ë.BŠl2"®‚gcM]´M|ś+ÄĘQ›ą+> stream xśÍ[[o·ú¨_ˇ‡Ţ-ĽěđN¦p€^4EzsôÁ5‚µ%ŮBeÉ‘­:.úă{‡śs8äě®d9ü†Ë!Ďő;R?Bř/˙÷ŐŰŁ_?“Ňż~”ćŹĺńżŹ~8’ů†Ľęřw'iˇ)!‡Áźś "§Ť÷sĆËx<ÍI­E8vÁÁ/Ç'oŹžŻ~ż6Â*ÝęŹëÍ \ŚNŰŐoŮřok)˘–Yť¬7Z¨h|X=‡n«gëŤ2AVj˝±"„őJŔĐ8ײ#ţŠŰúaN®ţ ź ­ňP…AŹçaă?Ŕ«…łvőÝx´†á·ëŤĘI««ĹO‘"#d4K+Nhʧ4|–u2®ľY{ř $ i+ډ!łżŇ'/Nţ”5EtĘÔ€Ě*3ÎĂ•´ePÝ®Ě4Ě›({,ŤĐĆ)ÜdŁAU^o”‡ť;…ďAŔRŻťEZµ Ęă^1zŕS­N×f#đxzs!ÚŐ{¨&·´Až5ĆńáŮď#iőŮ4ÖéŐËiÓËiÓqˇ×éW.p!(#‚ŽčŐĘGúO‘i9DŁ€Ľ4 O/“ŰŢäűiňŚ&ßN“/iň’†°Ô€CX=§I6Ě_ąčů®ŻúpxEkżŞN-Ŕá)­}‘I°«˙Á¤ŇbP5ŻhxM_Ýv·ý@ĂŐ y¶kR L1"ćĆoČaĺđŇŤ<Śł ĺ^§$¨A kŁ1Ł9§áwš¤ŃŮřł…ťŢ˘aE5ÚPÚ4xĐîi=ҡĽR{”FŮôšĽ„mŔ†Ś€«iŰSd`LűtšĚ´8h–Ž\ÁV`ű`đ±zđ˛k\ZČ~7MŢÔ\O“Żé¤ńwÁł¶DpĄčlđśAF ›˝înö)óíůąďhéťřF;ÂÝ”†¨1šËIੵ˙@†qŤŇ}äłoh-Sł§üLî«Ńvś–ŠoŔ„t5§ŃňL§®n 3™­źÉóŞ˛ţE§W]źxE¦NöČ앬ăźk(©¬áŐB2ČŔyfČ×e˛ŻOö9S -eÂĺ:ŔîŹaO©Ŕ˘ă˘Egţ3š[…4ëŠAé°óé¨mď|ťU¶?Eä9<¤MçTÍđÍ*1„AşA´Ź`đ űy¬0uI:<ă[m€ VĚĚĄŃçĚOíß6^ŹŰ6SĽ¶¬íťśGBRůŮř-ąCĆ˝ŹăÜÎ 3Mö# [¸© ©µ2…+Ł„5‘;! C泹޳KAš‚¬ęÁs%!ŚĆ{śËcîÓŚBFÁW“îɶň ©‹e3ďz‰Ą`oiňk84łÚlŤĄcl›ŮŮđŚÖ˛#3¶ĽYD“űîčäWĎyšt;|C“7˝ôđjšüůqşˇä^‘Č>ˇäl ?ŇPDK ”\ŇiÄ $pöý0 iReZt.•ޤ—}…GiÂćXu›Š˛ôמÓÚ›F ,Ż-űćŮÇ4”>GôŮ}ô D3Ţkţç~`b˙Ř˝¦!ylŃwŘÇa ĺ>e×Ć®÷i 1‹=łźYŮĺ°ĺ»57B€},oďŔ˛úň,«{łĽI’íúŕÉÄő׬ ď“Ę«;HĄ6*•>î"•;ĂěqÎh‘5Ý-±°Ä`öżEâzőKšÝtĹŘ Ž9QCł˙ZíŰ"°ĹëĂNU“E 1}Wç]!0•nď'„Bńwă|očPÝ3)µý¬bÚ~ČEZ*°Sž§śĂ쌥‹ lżÝaŤpŐJ–J÷;, ¬KĎ”{óŮeâc$˦ô÷^švP3üüŞCř§X*ㄏQk"ŤqÉŞşK´ÚR2™d˛¬NąX+ ‰n Ż`'š‰.÷V” ŕU›ĺ¶+˘ÍTňŚĺađB+ŠX/É’Yű<ŕxŇ^ä(­…TK 9XSëb…ÉĽ†Ő»J]ŢĆ >őř4Đ$I›™˙¶ë€lAKöX*m„0Y0’° čͲߕ·iÂŤ,tčfÄR©ÉŚżĎAÝ H,hĎe€%˛•"zł—Vş0˘+‘:‹Ň–”îĚ JD™(ÍV¶ŕă–vP|_çĄĘîFU°¤Ö@gę­fĘyď ‰„;?<|ĐFY2\šĂ 0!µú‚PŘŠ"]fěň›/ŰFë‘”k“˝mvn˙¶-ˇúżVĎ2ă-AaÝmK]ßÍ´í¸I/˝nn bÉkĆÎ]X´tłýÓGŽIľV^vÜ*… 9i`9Ëy%NýÄ€ŘĆŚsÚ•i°v' pŢÝ07€iĆZß˝†”Ë,]¸¶˝KáŰ4 ޱŰÝwĺ×ű]äRSŽuIŢ•ŠÂđĎ›őÔucW˘ďiČf±rÓřˇĺ;´Ť,Zj{‹«ď»U޶9"ß ĽEšÓŔze´¶=­ĬĘÖľh†wľăťZż¬ÁŢŤ„  m· €ÔAćŽ'JeVŢe«ĂRěë[îV×yŇ„¸ńbbJ6‹L¸h4ű"#沋âź`•.ä«‘˘y×Z¬PÉ\°wr™N^±Ż‚¨#¸49M;\é@¦OS:ĘĚ,ݱŢKë‹ŕ¤aĄZ((H?}©uG‡´RÍÓľÔ+ŘźJíąľe†R={©Š ”bßL‰¨çoŮŇ·g©Şµµç/µ Ľ[źť^Ţ”×âmwBgkÄ` 8weţ®g¨Ą)hoőßßÔuE˛6Éźâ°Ą,Wżíşý¶ë€ěÜů«ś‘ż xY §Ű¬iK'›®*úŤŁbAU5 dGɬËJěg®Á=tů•FÜ(WŹÖňfYż—[tfĚorÄÎ ěż3˘D¤‘ôÜľďa1 Îm75ńąÁ¸÷ }Śů(Ŕò­M’mŤčč—µä—^żÝš$Ř„Á­F/Ťô*ęś`˘–ŐXË‚Á¸<v‡Ś ű¸űŻëX%JłŮáÔŢ#¸¶—&ۧJčOß7^ŠĂEăÓo =÷óşUˇŁ„Ú¶Ęšb±—ř$HYŐ˝(tĹĂâ÷ř»”\ÝőKÎ.UuP*gni§V°Á3đcŮKíÓÍö78!Oq_(¦iďˇâŠ3«JfŔŚŤ¬ßňçŽxÔ›¬3Ueŕm®Ť5“řý`”ĘňMUŔͲµř.`;ŁĘEć‰{¦p˛ç§ÝżLX Ě9…Ęwî7KÖvâ2Şď†˙ă»Âôyo¶;=p§ĄÜý‹.•‘ť‚ng$ÁŮGd˘ňôŇyŔVŮŹ€ě{r‡b+a!Š_~N÷ r 0źR4¶é ’¶;Áž?ffnč—ä¬h~´¶V` Ż~˘™Éx8OŔ‹Ź !ÚY~UŢc~;%M ůűep©ă‡Z+Xk9mđĆ?ĄĘňďşw}űa§f˛ý`ű­a¦ŕŇnŇËáЮ˝^űR^z¦Îş7mg=›e’›”‡D®ň•*‹ÉjŮźAŐ Eâ_˘‹{ĐvqYpÝ`DÎđG˘ćŮć-…‰]‘ěľ}űĎ‹3»YL0J)Ű&”ł{ăŮÍ5Öťł{Ă”Ŕk˱ľůăÍ®]Tś[_ş!žőě¦Ď¶í»ţ%W‡ŁćŚÂÔx]6ôTM.¤Ů·‰±ć²q©ýÉö.uKŢSߦcž˙ Ńö°ÄbüwJ÷›V„š99wžD”ýŚ„?w >ô|.›~âdáĺĹř.hŇyýHźŮwsµZ·.öXc#˙ů´ôĎz·é3WĘíŞ`ŞV@-÷â!Ý[şîÍ[÷:°“ŹÄł.ćmŇ÷ŹÉ GE˘Î¶:źDžŢÝ8Ä»,˝é÷GGúmJŰ(GÉoąwO}ż0“@ĽËQ6řXY ý–ĐîFŃ0/rD§ţo{Kˇş˙UůÔk ÔŻŠşżóÎĹĐΖ]Ľ¬°+ýIţ]ŢM%‚!đ¸wĂxV¨SĂ­6ǧ'G‡˙újendstream endobj 342 0 obj 3279 endobj 349 0 obj <> stream xśĹ[[o\·ú¨_±čKĎŮŢ/@Q i]$›¦©Š>$FaK–­F–dŮnę˘?ľ3ĽyxvW¶ŇÂaÎň2äĚ|óÍzła3ß0ü—ţ{öúäóď8×›—oOÂ÷ ßüxňć„§˙a©×ć‹ÓĐŃŔ§™3f6§'löÎHĹă|FYî7ĺ—rvă ü˛9}}ňýô»­šµPŢL_nwl6Ţ©§ß’ö·[>{É™šN·;9 ݬ›Ǧa|ún»ĘÍJ¸IlwzvÎ{9ÍĐT ÖŐd‰?á´–1gřôG6KÉ”KMጠ§ßö–łŃzz—–Đüj»Sł0\˦óc”HÍÜ«µ§uŽÇµů]Ôp?ýakaś($ő¬”wiřkňôôë¤?{#ŚB đ¤2e, hN›‡ň ŰI—fšDč WłTFŕ$; Ş˛błffđíĆĂóŮYi40¨U'ěd¶;ď-ěSL/¶ 8븶ÓYmľÚJč묙nĘ CŮ…ž™c|súääôŃ÷T㯪n_ŕůŠY/p:c47°\i¦ľÎârB»Ů)Iż©s˝FyPWni#§gµëu™ę¦’j¶ZM—°3°Mfůôeńł„­˝/]ßÂvµvBdů$¬t^EąŞăăTZ >ý¸EY¦yŘ V3 Š"ŚÁ)¦Ű2˙]µ*"JőŠ §ŞEĹ0KĎgU*ň•ČJÎ"}5Ňu hpKǧźYaŢŐ}˝ŞFGv{˝Đ .|SűÖŐ~Qŕeýůý DśX{°Nr,ă’ĺŰ…„°‡´Ě ˘Š,SE‡–ŔÄÓ”\ ůKâEמąr.ŕ˙¨k˝ŻkŐ °«Q3c>™CčJN›ś`…[ŢĹ=ďxňÉŐ‰]żOÖ †}^ż^vsjżW»Š‚(ŔUz€ĐÄÍlťěô—g˝çÎîĘÇdL’»$„4.ŕ *ľ(ăCÂfť±Łťđbkg >ćé.’ŁC"H®ÝöhÁé2˘9ř®pÎ_Ç#pR ­Yo@¸DéÉ"l› ďK®ţŐ©˝§ŽY!ú¬˙e  }†ćŮČ´w[­ńłďüy—6]đ|•óHé`§nP za{DŔčKY;ăolČú¬Ą%Đ^ńśřΛ 4˝ťä~fVw´Ě·¸®}Ď“Zµ;ŔşC$$eÁśęI ĄżĂ…ś®^npG$ó3Zí?·ÜaJŐ„‰«ĹRÉ×HěŐ PĐLî%Ŕ¸©ŇnŇţA‹Ąp&‚ýŤ«HÔÓóŢŚ“~Ěůo0Q„2°Rţ™ b6FAŹQŘŹC[·|8´5j´Ď,Bß6iÂeíĘVVŇ—`ëÔKďłµ©ÖbłVä4§R“¨Dbç8ŚcFcŔî­/ [``h.ç5L/°¦Ń‡´íGBĺmÜý7¤ Bđź8rffŐ â ę÷„ď†W}×JVHÉ1~43Aş¤z6D˛zk‘Ă÷đHťşON‰uTG9ŇĄýĚÚČź‰:í¸3łV+ž4fvż á_9ΔC„×!·¤P€ż˝a#d&r(ŤÎ#kJJr`îÍ –Búj°‰óu^›ŮĂkń@‚EYűů\«Ť9áxJĚ9˘?ń)bj?6őÄCIŞ ÎJćjöŞ$Y$óşBo4ÎkËôs\MץSS>pÎ9m+(“3ŻW¦C•Źľ€( bÖ÷ĺkś\JN'—|›–qVç¸)żŽ-ămnâďĎjóş6ĎKßá^€> ¬řĄĺžvÂu‰ä‚‰ĆLÔ ĽÓ^őE)ńbębZ0E‡ľ–Ňç€Ä*ăý §‚µ{>t›&©b=,!ő‚‰§&Ěk€)Ş›ř›Q‘¤Jcˉ÷+Tă*U™D’ą'ÍM5LJ 5±ŠI˝Đ+Â6Ĺź<ęeÝâQĄĆ¨}Z7}ž¨s(V j…d*Âüđ4ř*—cB5„Gc)o+J˝«_×nWôąA´/G™üMŕ™X˝!'“xvÜlA˝1%x0XF©ńY4`Ŕ )mC4jö×b"$ŐŔ¦żm,(JiĽwşV/©„ň ä2UäÉďhf0LČqńüŮP]äë˛ř˝^('eÄW#+a„y8V_řYsn7ŁéóĄ Đ–ŞöE×0á†QSé7zMý8[ţĺďkla‚iLXG‹erŰ#٢śśă{Áj쫇š;ô<:n*ĐčpŁ´·¶’Bz´ąO,L¶ÖK<áYCnr Ś—5PÜTŰzŞý|ĚŮ/¨Ĺěě˙Sí“îEVQ‘9~}ŽĘCžSN "ěwZ’ŮK wi¶]á†{nP}e†—zGďOĎs!ţ ”rǰŇeĄ`g…¸ˇusbŠŇ@BěnG4”Ł<Öíôë–Q¶ă‘ŢŐŻďjó7µů´Ł=Á«›‘Xq‡ń]zę‚·ĂJÎu Aá¸!D»®j"śjŹąŽ’´LárţÔűE{uŁ}—Psy|Âŕ< —Ç ÂÔňTvws­/ěŔë1˛ôącC˛yĚÖň\«dԺَK©wŃo­€}eż%JyFFdÝNSIŰÄ”^㦻YĘ9ÇѨM]QVă5nXŚQQîÂŇľ*,«ľYAµY;[aŰÂfÎbEcˇňňĂ4ŞŃ'RRçKĚÝś›ĄµÓ/Ă} d­Š—uWs«»zŮçcę‚•#ˇ9á8źńšś_Íç§ż”r+ă“ř çŰŞ ܨ[*ą §{Ţ'ôa&żu@cŕ|Ľű#BÍ€đžĘř˘«îÚ¸Eź e†#N(ˇ«A°T‡Č^[†”]4ćÎ5ďĽ^.šXý!5!Rą&}“7Áq‰>Čě€ÁÄâgy”IŞĽ—…łżmyř˘ô››©+ţÎěôhJü¬é¬HŮ!9óŕd‚G‹Tů˙ŮrkÖ]J‹ĂH˝řEmţ˝6Żkß÷ő+)>?_ĚĐĄ#2Jx•K¤ůl!Žş\¬;¬“|Ż`Ř—Ě@µCLŽ8ľ*|ş5` ňŹËŽ(Ée@jź ö±ĎŰÇŃaGK†ăäk»şg&}I) FÉgë›×p LĆ”Š`ňJexţ—Ź RzĂ·]GĽT¶?â˘W™qĄĚîťŐ÷€Ýý}*Ë|: Ť·†• x‹7IáÇW Î#I€ş3{Ŕ—Şc㹪\L´%Żćďą%ůÔ "M–O-}#@Éa]–p¤ŇyŘý^–˘˛u}Hzu ş˙ąşC×÷Vw2ÎN݉B˘Ťa56×%a ÷ÓŔ±ÇžŠžŹ†°{–.ó!Đ§Ś Şü$mäÂq˘Td‹”{y¬ý]ŠPÇŘ;vµÎuţ˛żŞ!|–ĘěÇĹřmĆ0Űjsz¬rë=µ.„.ČĂśšwĄ7€ř7T¸ ¸Ţç>•bJÍ~ęŮ’@5ĄŹstgvĐáŰňgqóŇŞ–ÂÖGďËÓíř¬&óđŃęĹčă°çuăU¸»ÚZPC^â?©Iç¸$@Ň ň•P°šT>oF-…ÎŹŠT“t6›ęÎ$ĺ6ôsíŻ0§VVtŻľŇ¬ă<óPŕ<Ćůr׾_Hoă-0v#޴ǧ'†˙ošmendstream endobj 350 0 obj 3303 endobj 360 0 obj <> stream xśµ[Ys·®ň#Ĺľi7ĺEp~sĺp9N˘bžl•K”(Š1Y˘óß§gá.şř Ń ŽFŁŹŻ?`Ţp&6˙ňżŻŻO~˙BłąřxßoÄć§“źODţĎ­68Ť -Ľb‚s»9}{ÂYđVi‘ĆłÚ‰°©ď„RĚo¬·đesz}ňýöŹ;ÍŚÔÁn˙şŰsfC°Ęlż&Ď˙Ü ”ŕz{şŰ+&v~ű<=Z.¶/v{©=ÓŇoĺno÷!¨-G­a^C¦řë8÷Vl˙ÝR\űü(=WiâÜâ;ňü'hbłĆlżMS+xüŰnŻ™´Â¨®ńs”H3ôZ‹Ó6Ćóöř" jEŘţyç hR†i|^~m]^ž~“w °`ĄŐ¸"o™¶:tÚQAövkëcDšŤĐLi+q˝‚­rrł—Fćđî ô 杲 ŰŞ¬—‡-Żá1K–Ű+Ü8 ’ß¶ĎŻÚ㛝‚ţÁŠé"¤aJ„°9ýöäôwßÓ­×6ů-™Ń®v lŹ8]i§łÖ ÓíĄŇĚŮíëö’4˝Ćť °oĺÉŘ®˙Mję]ÉčíeśUq'¶Q–ŔLđ©6ýk4ĆK‰˘âH fÂţÚ2»{×úߦ·Î‡Ľ–ň6őj1€ ßF č°}_›~hF×ú_´­OßMྌj•ÇeK)řëö‹ęrD˛‚/Ń <Š%Ťf°mEŻŘŕ¶MF´ąT,¶í+%HŕŽ’@C,Q¨"4 é¸ Ř}´ÓřŮ€ŮWĹă ÉcRvŐ††YoŰ[Ôz€ (VY Q×]38ň–a( Ú‡BíłT{p,ďąHµ€öŔFE›Ěßyg ™˛śA.´¤!"â*•wLČlťQD°NPH&ŠuâřŃ<-·Ž,Y ń)˛ ÷0” V8ÂĐcKxě ]Ţ­žÂd8ťŕ] ¨˘›ę]ő~"?Q1čN+ Î4—dPňťJ„Ăp$¬ŻQ*ÉŇs±˘ĂÎňjĆç;H¬Ę)ąý5©RĄ-Eĺ-w\'ť§-7ŰťÝî0 ż´ďdĄÄĉ“ Ń!If'Ť n»Ä±ĎďENI“âčý,¸žµ—$řKëőŹŁ[×˝˝iÝŢV˙¸ť9Í2Ţ Ž{9 ´d©°=šĂV«@węuë¶‹]^âlcf oᦟ5ö«–,ŔĺHźµ–ÄĄŕ†|'šč"oY3FV‡‰Xç·řý¶J·â˛h^ ‚Ó/ő3Ńí›dÚÚÁV†fŰisµ'ač~š7ÎfĆ·°™ä ŐfĚŇfb··Ô+fľr¤Ő¨GčÍm”<$/ĽşČA0C¬ůfę$÷Ě4k?o)‚d‹¦Ű~ĐŘ]ş.Üdă™ ˝ŘŁ|¦KúÔđ0XĚÇ`‡Wëy»CXP˙%PyjŮ7,­»Kń6b¦äíłâ,/pZĺţ⌅ă˙ČĹľÚşŃŇ`ń}„.“›@Ä媺 ‰4=«Ó/CĚ †ä1{rĐ §ˇüf?ˇÁýÚlk-@PÇp´ÔŃ~‹§}U_¦ŇFZß•6° *x(­ ÎxČ  ´LR i÷U{‰ş‚qČüß··ďkÓ‹ţ6D“-oĎŰăÇÖŕă˘>’ÁîZŰűżø/Ał<×Ú`.ŮĹ´Yđukű¶˝˝lŹWť ÚˇmSÝ\-†Ĺ±Î¦’_u‹Čm§…éžnź×Ą2ţ a,ŢĎöeCč×)/‡čr/báđ†t ËędĂß-ś¬}^i‘PąDąč¤-±ü!ď8Ž<çÓ,y>EÄD0â:7t¬YDÎŢ&…).×Ń‘óěŚŘI/Ň ˘0™ŇYěŢÁq‚ ŹË÷4d”Ą ŕZË ţ@ÍV‘ý›6ҡh T@Ţ€z+GlŻm/_FR!…Ŕc°K2'¤'FcŢPGđŃŃ}YQWxę’αŻFS’’®"ÂȜϠKKD]")/ď:-Ýߏ /§ ŮČ–U %ł vľuHTCý««Ů«Ř˛˛0#ŹQ đŇ1V§­żnß0 ăÜ öťÄw-§\M¨q® ŹaˇXs ş=ÇŰľi3¬Öěö 5@Ü«K̽ŠlíAľŇ‚e“™řLQ*@܌ˬdĽZ{-ŤÝĽ4Ć´‰,ęjši¤LîŔˇF€ś" ®‰‰Ů5XšeŰ—B‚(Ěa6ă¤éđIfĹ‘’\uŐ­tF Ú $z;Ľ[@eřl±ŇžźšSČX°¶‘ßŕ!úŕ\m@¦G 6 ±XWćNĘŹj3âÔŁ÷ąĘÖ¤ąL<±{”<S:Đ,Ý:e%MiCšĹ,Ę)Eq“őç׺˛¤łaIQ%ç p‚ŹYäiçÜŔśŽ+I7ô$HŞş8ˇŹË®;M[&őAž/ ŚißrŮÝÁ§gFHęHÓ˘˝ůu)ˇŚ˘tŞI*Ś…ŰśPÉ…nÝI(Ą´íŚďČš3ăĹ5〠ɩ×ŰTVĺM)Şj;'‡Ŕ«ĺ Wp3¬ĄD߸Ż ť)i  †MýĄňU˝§b-i˝9Č)Ô­ëV]w˝p_Ľq_OšŇ˘zĄ<*ĄE©T`NRĄÎnŰV[ϲD@X¨ŽZÚŻłh•řâ‘ř„v[ď 22ZT<$í†ţ®ŐWź•śh/2Öý”2˘äR­Ěᢾž—~^QY›ľĚßyWÉ“BťÉ×Ó*ú¦źěuiËĽˇđńőc fUřŽv*ż<„=xX2ŇŚIxɸ—s0BŘŕq¶mÓI4pę5GkŐ’ű[h!^6Vü±T Ďx0OrJşś 7Iba®éÝ‚ľH\†ąŇĆržLŐ3¦ 9C#r=ŕÓÓRYs𕬅Ľł6)K'şś̤;‰=źŔc9(“%`şŐŕ¤älei¨=5ć w(™D`Ľ;/ȧżq"ĚńürÁ"t!îbńXOTĆ30ř.‚gVx:čÍ"˝4J—™!Ć62ŤË}ëĎ‹Ŕű… ń®Ŕ4v¤SLš#ő‰k \6ĺCÉ*AAú¨k9;ÍŤqA ”×ÝÖ4Tß™-fRZ° ł‘ÝźVYćž}•o,ÄŔ¸ăŮGŐăëd9•ŻOĚňLă`8ŠP /čł„kgÓąSƸÎęS$Üŕëâz´ăŢú˘¬4Ţi$µôUMb âă1€ËCánG†Ý"˝ý‰{$%…¤c‘0>çT.FË.§ÁA¤wŕz"”ęĘ9"ËOł6gŻŠµż‘.(ĆŇŹsđ†\ô ʨnńnj᥇X4ż°QL Ý>Č4f6Ő_Ž(Osöš<Î/OĚďQÜÖÜL‚ śÄŰőФc 4)źU·"“<+—˘Âö‡í¬ÁX™d¨e.C­˙°ËőHM˝„Cz€Y»}AŘ«§GÜq%R|žbçŰľmÁźBÉřřckK ÷ň8«?­z‡ăXm†Ç`ë9ż7ř ‚›ŕáÇ\†,0\Bë˝Ĺńpaž˘2$wý-©ž6ř^® ć)d_oĂwR4“CFŢ@Ćqšö'ÖyÄÄ+»Bé˙6ô\(]^Đ>ÝĐ’±?˝GLŰ]Ă™ç‚R_–€:܇†Ě`{GĐu#Ç "Hp˘çíHjś6";LřLyyůo\çű QŞŠ –ücč‰CW]M¤'ĽÁč^'Ş3ÝźU\"©¶z´‚ź}xڮޞlşbµ~Ż«0ĄM«÷QÓ˘Ä0U"5ĺçą–UśÇ›´kW}pP[Ş®ÁҢ_"6f • 7€EěózAFŘ «„›‚{yć] ŢRV NS3m°äĄ .2­1l=Żś—W}m9:śU1ź/f÷‹[pÁ“)YZ­»öYl*ĺL ľÎ~*gwö ´đěÍzżí9ßr Éë\ż6Ť·—|ý%>ťYi fú7™µŁEČŽ*(ď¤])^lvk—Ţ›Wý§őjőkűüzęŔkČ(ž¬F<źD““ëŢ:˘üĆ>`Čqł<¤>-–G=cQřľČBď×gÎ# ŐăŐĎŽçĹ&\ĂM±ž°Ň®ßŹź”P«c•·Ď2}$ő“Rx_â°Pu¬»tŕ OŚ‚rĹÔŁ ¶b9˘»ŕ˙_P¬ÖfŃ’!ńUC>ëŤ3ň“v%b¬ÍWĆ2Đ=˘âK&Ą«ůlŔvő/ąGŰčŹ7Ę…Ň>č¦âŤrGĐÎŘÉ«±/ż4šÓ ÇÝ0O)‘("®±X~N¦,¨0ß>8ü#2Ů~D†Ě9ÓŐ“Ň÷×;¤±Ľ*D§äRŃ_™}D˝ ĄÖ[&‹0äg€D$3N7ąü…Z˙ËśŽĚ*¤‰#k4ÝÁQbŘ?ˇá:n:o/ž‚ëľxş,WýX­¦—ó*<˙<×HżŚ]}hĄ-¨S6ăčŮ׫i[rYT´Ç/óFOşáăEAvÝ ŕW¨YčŮÖň»•)T8<ĹwííË®lßăąDT<)pŽQ“—TKäćꜤ¸f…_r5äbÂYÜÔYŢ,x áĐXú{ÝžČ?SX¬ĺL‰\0O0D:3řÖr¸·†‡˘O»OOś4şňvĽ©WNůHÎËżî=ŕBŤoyRz?lyEz8ňÜÂ[¤o&c Ž5'¨zg‰ögĹQÎ’¸5űą7BM=?=ůüýÎm+rendstream endobj 361 0 obj 3678 endobj 368 0 obj <> stream xśÍ[Io\ą’›ţ@® Hş“i†ű2˛8H‚'1ä0 dË– [Ëh[ůő©âňXäăS«ekč`šÍÇĄXőŐWEň‡gbĹń/˙űęěŕw/„0«“ëXż«w?üž[­ţxZ¨b‚s»:|sŔYđVi‘úłÚ‰°šę„RĚŻ¬·đËęđěŕŰőź6š©]˙ułĺ̆`•Y˙”˙ą,(ÁőúpłULíüúY*Z.Ö/6[©=ÓŇŻĺfk÷!¨5˘Ö0®!Cü»uś{+ÖßŔgL)®}.JĎU8·xNʆ&F1kĚúë4´‚âß6[ͤF5ŤźáŚ4A/µ8¬}<«Ĺq˘V„ő_6>‰Â„”aZź—żÖOţsř÷Ľ+­ĆyË´uđA#m`o×n*b'[;ăäj+tÄĺęđšm¶‚Y«@´ŻRŃ»ľJËÁ]TŃ_ĂWN1DůŞmú~ ĺđwĹ%saýa# ĺ ýć[â&ÚŇżwë7X©ŇˇĚ'uQWö~ú;%E.*îŽÚ-Ŕ*żľ©mßÖ¶çÓ`'0— –r˝QĚXnô$%Ó ¶äÇ ŠVÁLIďWuˉĐŢŁP,ăŢŻ/§ŢŹęDŇW&pOkϰ6Hcáf¸*2îŰşŞ˙ÖÎHŰcś ‡I,ŚKŠd9çÔi@4”-jËqýUŔ ’‹•¬ŕ"ď1č™Ŕy-uýN{ „\źÖßóW–›"D-p„$oGw{ĽÂí$úh yQ[‘Ť`.TÍş–ăt¬F5¦PuZ‡Ą(«‡ń6ˇŮ·Şc0}ĺP˨ “mmĺ“:Ő­‘(kQĹßöńŐPˇ&…(«ó®¨6­“Żb ű<6Ş:ąóÜ=|_W|٬h0?˛ú:>™Ô5öęó’Ş×)ť?Ŕ h„ÝWe^żŢŔ¬TľNę ™Ő˙|dÖ­+órš6 yŚĺT–Jä2“k,Ž­& áxŨAŽk)“~§YOúÝ`4üäŔa ­ĹĽ=ÉťXB€)Î*n¬ Đ”ˇ%˘{ŇËV‘űJîLzCݨ1°íÄŚ5ć<9ת>C÷(uéŠ(g,0˘ŰiÓĽ”=tjËP :3žyi[ŔSL[‚Łýą"Vđť‡ň6: ŤXÖ\©%3€€ŹÔ\†~V3ě–PŹÓdq«iżIp°“i2·C }M]ĂĺQľLŢ·ÝOČWĆ7’*Ńë Kĺ`-©€¨Áţť$ţ€|D$0Ě“´ś:1.ÂŽ’ukřÉ…˘,ŻzGж•©HXîŚ÷\¤öDÁ 7"ŁĚµeIŤ•Íű7p@¸5cűÁU¦ĄEOČ@ë÷UšÔCX0ŹG©71ž"ď/ K@˝Ä˛Ňçů?=a*ęĚ=ú™gÓşÎ7Çbµ•ó~‹qŠÇY»-&Pű@ŕkěHO3Ŕh5×dÁq†ľ•Z°!ťÔ¦÷™pôçÔÚZHŹÖ†$Ŕ˛ĎNܬeA'Š<őUk‡čľÍ‚ÜŃeŹď±xµŔf¸‘´ňŚD‰˘zů`ˇ-łţ‚ J ř5tҦśMZěşý,Ş>÷CÝ'¦u4ÔÂE÷ żF&GhyKp˛°/ZósĹŔß/FČ]Uô” 5ŚŽ!»ěx¤ L^ľ)ó"Â*°m®oRÝie}űMęÓ™ÎďŇmď”KJĐŹÉČŽ¦nŻ6 ‡7‚¨ˇń5ćD÷hĐ@&~Ž(úődPFS ’ţ÷a}ŮŘŚq‰ęA¤}çIX"¦łŔąg"[:‡[lÚxđˇkËhŰeŠD*Ţ€{®‰:…ťÔéÉxŤqjŐş… ~fB'É\cŚD*Ł¸Ű€+sťFł:üúŕđ7ߖď늽µŚ€e¶oFůžYľ%+hÄEç’sË0=Ă‹Ř22`z6 )đ®Lů–㩡–ý*Ă$.”WPázěčß5îĺÂX…¶_hJ­ źgL5־Ċxµ GűťŮŻăčzĚÄѧśŤ«*~őü~Şü9Ů/ ~słŐĽ&đ˘+lŽ]Ęt€Ŕîé}˘B­«‹ąI$¸­)Ą<Óú¦ÖŞÓJ3Ž$’ÚŮĆü[ · {GŘPznh&g¸Y,† µ4sńsb{] jxOdĽ’‹§BĐ̆ÚJÎ=řńőĆÉp—\o’u6Ł.ú9¸&16‰JnŢíH?(¦ł!Úw9Rő­06Îö>'ŞÔÄ}´6běľ>'ęd1Ašs­˛‹¶rWS#‹.śc «mĆÂt:Nűǡ…ůS45đt ÄŰ‚úONićwSO°K—€rA–ŁŽVúwUÎíQGv&Kiř!Ů2•Ç$ÂĽwcµŁőČ‹Ź÷ĽIŕ–¨`4ůă1áÓşßäú@˘`ş01r¬u†ß tŽ&÷Ń›–Ęď§Ę×µňăT ŃÁă´=a1weC¤Ąö"¦m{<+âgŔ] ( vaëÚöÝTgZsŮ™ÂĂWü¦Vľź*Źęh'Í´·,pąţ=Ô°qp‚ß­k‹ů°ŘĹ|\,ζˇ‘ÔÉlőXüí°í\ŞXün3¶T¬UgĽ§„·UÄYź–śO2;ž‰ÁŹąĎ¶QR…Řésš‰çn¨ŕ۸Qü$AZě$ůcŽ~Ü´mÁ˝sé{ć<YÓ P2¦é•ÎŇe=µwĐFHx>úÎÜř#ٵńĘ>1“łĘ‘Ř*”»:ű/'±2†ŻBFĺóúó#¤¨ż‘M\ݵ/k‘W“ăłÚ®(j[1«ÍEí`MN®YmýíĚT—›,ílV‹mI7 ojíiű":pŁ÷ŤO(ŵ_20NGŕőMG{;~–ŠBDgßwĹ}Đg9I„Á§ôOΨĆG`$¨Łm8СÓÎxŔ2?¶Ě6ńßRô‡¦Ąčya&~Ť}–S–E˛žŁüаăřj·@7Žh¸A›Ď2¸?uîâU=:©˛ŔaŇaśiĐlGžaź JŘŞÝ®H*>Ű®ćltwg7}Úö´?2¤Ëé' ˛Ć„||V?Ąx‘Ž_><Ň9sđ» RÉ&şćµ Ňź$Ěg•]qREzSmXŮ˙N!ډj[&¶Ó±?Ô?ţdgEŐনć9Ńţ¤şŇtqţśq•S[ż; ^ó5$ \g)Ďŕ•zü-±2 Ýw«FťzlĚv_Câ˙˙Ŕö2…*’F*? m"±Ř•ěŹk ]xęćÁ Źć>Ű{#ŠOtëo¦‹ Ä©7M1ˇ`µĄ±Đ”ĺ\:±łĺ´ců:ŻĹÂ%żWĂĐoÇip8ŞÁL2/z“ląąçD° Ż ŹmlW€Ő"C>nL°wyÚf?P€Â.ݵ}ŕĺě€SÍ•lAŠŔiÔ%¦¶_ŐáńUm k%˛S1ž“za§ö~´«ź¸S·CdľüIvęÓÁř& ČŃ2 ¬Â<)Eť˛,řXOÉf üżĚµ˝Í—xÍ=O𹢋áRáo{Ľ·—ÇňÓĆ&Wśn·Çę—‡„(ďŽ-źđg©Őů-\§Uä:íŐ$Űf îKľ[|(Ń?©ř\!Ą†Ë‚íÇG>hŐ1RsgâŰ8z?ť(Ţs=„gď6ý';ĽÁNtz~ŞJď\7›jŮ‹ĄgV3ąőIÝń“¬ťÁMű:ŁĽ9Ů#/1ŽşŢçEšĄü^)Ńh ˛|C!łü”$íňŇböSą˘<z™‰ă¶ŹFňÓYŕ<ÍÓŮra~G¸86L…˝ŹRâdfw6ă•­ü–¬ćcý˝f…ĆŹ)|˝Á¶gú"E¬ŞUöś6Io©x~ ByýĂGŠV÷ÔrÚş$Ć{vxđ/řű^ݦ„endstream endobj 369 0 obj 3458 endobj 375 0 obj <> stream xśŐZYo]·ň¨_qźšsŰ\–ŰáR ŇÚAZ(]\-V[°6ËRTýűÎp9ňđHW˛\¤ĐŹyIÎÂYľňĂŠ3±âř—ţ=<ßůő!ĆŐŰŹ;a|%Vďw>ěôžf­~ż&b‚słÚ;ŮáĚ;Ł´űm…_McB)ćVĆřeµwľóýđ‡µfŁÔŢ ß®7śďŤ‡ŻÉ÷_ׂy%¸öÖŤ×Ö Żă§ábxłŢHí–nëÍČśó^ >µş#!ńÜÖreL)®]ú”Ž«H8Íř3ů~SFĹĚ8»‘´‚Ď?®7šI#FUM~Ťi&Ľ^š±Wöx]>ßFŤđĂ7k Ë@ŁŔ™ÖŢ%1đײäß{J'ŕ™7Ňh<‘ŽL *m‹  g;¸é3m"GşÉFÁQYąÚH \®öŽ`ý+r.§k8VPĂǵbăčµ®¦Ă:+?ď—cą/źdýĹ´ę-ŞÎ0ë}Eëx˝ĚQá‹inY•~6Ę GxP‚q…'¬™v^«Ě€łĂaś©€ţő¬VY—ÓĎQ'eW±–®övwö~ů}eˇDÔ3 o ă`˘‡…çŰ"őu4Nżt+7aS 6N÷żGń«>*{.h'ďÔj–ť#y/GÔ“•rXćFţFĎ]RP0›Ź°`‘†ęrż,»@ p=”i3…oŚ ¸Md¸±`@©Ú‚ňţ÷­\H?Ë1 ˝OśX•”H•őW=NŠÚŢv—ż«d2¨u‰¦#Çť‡GŻYTjŢźh’¨šě:;,+¤KĽ†ąGŮoÄpGâ ń±›ňů®¬#änËg™‹Âl’4!@r.˘PűHQ˛Qű¬3_ M1ń¬{†©c¶¤ě RŹšč˘ëµeÖBČBőç™Ä}ŞM‰ÉUNÓÔo¦ÁčŐҸʫ5sĘ;t:J( &"¸“h÷yđt6¦Ý@őw= ’"±«0§p ŞźÓć9X$oAňÁ -‘†Q%™AíŐąsˇQŇL&•ŚÜ@f@lj<ńó”V+pŮ ĄDp’Ľ.ă(w.I–GÓVűőÂ3nÄśÁ ÂćCŁşđű1…ÄSµr_V  ˇ<ĆŻ6Ńö×_´Ľb˘>ĂM%“pJDŻ—T™5ÁÁł.)ġ`ĚŁŃ!xdPł>ˇřŕµ QS¨ţď‡Rą,×Ó|DržM@Ž Ą‹¨.ćŇaYń¨™ č ˇŕ9đŁmČŹÉŘ}ÔŐb¨Q3°âşpš¦žLS»ëçvŚ&O@!Ů•l€h^i~•ů´˛1©›X„Aů’aś«}ÁfÄgÎq‘•Ľ€mäíCđN QQŤ`|`Ń_#táČÇgÓŠ€¶)bĐCXő§Ň [Ůw ®Ón˝s–ĚĐbźě°[ąô7ÍUŠĄyU- ¶,Q˙žÍXČÝ,V)S•{¤ ™LÔ-d٬ÂâM’Deb­hŚNËřyLBc˝é%:VK'!ł)Z]\•ĎÖ.ĂVç‘*!Ö‰1îk˛Ş_Ľˇ^<G˛I+óęöz D%‡6¬5ÔŃuv»-¤W¤řű2,ĂěI‚ĺbŽČš-ŇĚ É 9 ý¤n}×2ާܧK˛Ff.™uť­SŃÜUô¨ťő”Ćç ÓGŹ4޵~ŻOu"MÖFSžÚ15—„Qü'ź í!F㎜NĆÝő[Ŕ© q„&S/jôÂ~UZçÁűÔĄŻ›xÔĐrŔ…ücáB•\Śţ gCčs~I\ű©ßZ¬âłB$Ř|ň>-,ő„--ę ^ý0pDó°’jˇ hÝŚíçˇ:¨ ‡XĆ7ĄGSG‘î•O±… &ą™×lí…Tő1ˇŽ±tßŮÓüšŚ8/”ś  ˝|ŁĆ d`÷9ciVSłű°¦ťALŕE/\cnsŕI8Ş´…–r¦ńz ›ŕNĐ\*ż[8#Űaä«»č" ›°ŮEşY]® Ŕ;ŕzŹž}7ńw–ĚŘďŰş5©•pN´ń*(ŢęĎďQŃŤ˘2HÓ˝Ó1čľa¸Á@Pʦ•¦,ŕRm·ňĺŕGż0ă“IË0Q÷ś%n„ŢĆ ”…ŚăLżýZ†Ŕ@Ý“čÁÁ¬ męű|P%ăŢ=łÁőĹÂŰŤŔżń4Zu1&±7(ş”±LŞŢŐ7éXL*ňŘĹŞm>xŹłÓíCˇ‹ń–ŤÂtú}›ţ±ë+űUĂhâ˝u˙ Ă"vť8E ®ekjk…ýÚvk8Lâ8ĺŘcSšŃąŞLj-ă["&ţS׉ćŹR2€…z|÷á*ŕIm—)¦úf+ÓÁâŢqCĄ8ˇY@˘ź‚MßáT Ç_âžăg𦷥RČĄ?Ó·eô©µş˘~´¶źËĐÜäž–ą„_ŇKsç Ś™€S¤µšëż“+zĎť¤˙őCąýPppĎź&÷Üď.ź‘ &xа2•ŰčgáĄŘB++¬ ­,ŽľńŇź_Ó‰\Îß<Ňš9Ósďł%ąjîăŠ;čťČĽ#“¨˙ ˇđęLĆWŮhÄ^âkĆѸüěg{ůY`?·gZU ÄްD Ě2Fµ`9/rťŚĎŐBCxĆËM€ \^@†k&ŮĽ€Ä{8˝ŐŤ~G•`ąˇâ›é 4¤;B–TĚYU\6ec¸!q®'A¸&°yln/ňŞ{™©ÍÓ˝+‰°ÜAµi Î ¶9ő˙źx=— Ş~^€’dn):@ŃŹ‰Äy6MG(ĽĂ%—źď~â˙5­/F×ňfî»O 뻏ÁňRŽô˙Éč}yCřMw3ňŠěx&y×Hž:ÍŐá&¦Č4×0®">˝űz3Í%ĆÁÖhp:ŘĽAmH’™w=®o¦AňFď]µ'މH÷ћ̸ŕőŢÎßŕďż Ć«”endstream endobj 376 0 obj 2991 endobj 386 0 obj <> stream xśĹZËn\ą˛ÔW4ĽIwfř~l$±‚qŕ‰=N‘<’0RË–[™č;’NyI/y-ů^®&‹ĹzžŞë+ÎÄŠăźéďł›Ł?Ľ¬.>EúJ¬~9úp$¦đi×ęĎ»¸Ń‰ Îíj÷ógÁ[ĄEâgµaUhB)ćWÖ[řeµ»9z»ţËF3#u°ëď6[ÎlV™őźČúőF° ×ëÝf« ÚůőqZZ.Öo6[©=ÓŇŻĺfk÷!¨5ĄÖpŻ!WĽB¶ŽsoĹú{8Ć”âÚOKéąJO;ţNÖĎa‹QĚł~™®V°|±Ůj&­0ŞŮ|Śi&‚^Ú±«<ŽëňMÔŠ°ţëĆÁ1Đ(¤ Ó:řéřk=ňăîo“ VZŤ“É´up Ń¶ `Űu(ËÄDZO™l?ŰJD.W»s8‹‡Z®ďŇŇˤőHDN¶ľ<Úýîíú_uómŮ|W‰2ńŘŹZîěËEľâşžxWNśWâI!şJüزÁ­/*ő¦Ű€Ë}Ý{1k˙d·ĽŻ'îË "ëe!žTâOݡ™|‡N§í[Z©_?b˛C!ţcxĹU•ᦓ —×Cy[%.*ăşăăćď?[˝CŽçC•ýZĹÝ·÷ȧ^ń±‰[ż{·t2?î¬|ÎFö:ď8’xÍ&o•s?ňt쇅·ďęć]Ůü˛Ő(]ˬ•éĹ S@,Äm!ŐĺëŞÍ7•úŞ.żď.Ŕ˝ż,<đ)ލ{mĄ¶’ýUd*uQ<¨JŇ4Esf°@ea\ź*ĘËRśŁ§â}š–Ţ/Cń—ÁcjőW đ˙Ś.°ŇZć|<—N +fLĐ"2ď„HĚZ#,M^¦ż)[ϰÖkf…‡$>Zܶ"ĹŤ÷Q8oyá3]¤‚ÖU©™ÇÇo…gŤBŇI–Ă8¦¸ p FS*IY§ŐdČ â‹Ă›ű»py^÷ŽÓ5I%'ĂJó0JÄQHŔ2ŢŻßVb/B–ń“äGR÷Ýɸ—HţăÜG[ä´-Ö‘ŕA’«dťWŤî«—žKă Ş'?TŕęBRŻ ŽöSĺp—Đ!ʧ˛OVârĺt^6Á‘·B®–Ň4™«wŮ­ňÄQn)%Ľ"‹Ą¸Ä«OëÖh‡ßÍ©¸ő÷(V`. …Am]2ywč¬Ę˛j¨·č•€ÖĄ±Ş µÂôľ‰řä&T…T¬»śÖű'8îZ]Ec)7ÉŮîËďő}‡úó)Ő*ú‘Ô :`îč-‡ąŐç‡Ă·Bď"„$©rŁŕAC—ť†áYSŽńMŞŐ†)Ě´Ľ$—ŇxÜV&ťr曤]ǵ”Ó-N@ö;©{ÉóŞv{óáş§aţ›Z âhC§ŃV ąŢ÷«5ô€ëßnŚÁu’Đ!1 ť×S͵4´9ţő|kĄXe‚ ^„qę8ó®±íĺ<"kIhÍYЏOo­'FÖ,xĄv÷Ríľ«ó$ &â;$Zɲ Śäŕ× P€š6Ŕ­_Kk:T}úűˇď]Ť’Řľn%˛\cĂ Áčź›erEOş PV•ěMąC ŮGŚ©Çr#ÉăĹxh±­0#$‚ž+IÔřt+J­%3:´0«l¨aCBTÍMŔUćękaęŔ”ł ‰šh~śęgĹ5Ă ß‘¸!›ďę†P§Ś Cq”cJš™ű¦0p J°ň.¤y-–3ŰĎ3ĘLîOĂA’žđ}A~dpUIý±ÂÁ/‡x_(Ç 7ŔŁ8äç]głŘ$T}&ĘŘé9ńđ…džŁćşńĎěżÉžž[şˇď8BtŻAĎ€y_yôëz‚6”?ŮŘŻk ń Z6ąűˇşňýHwuIŠăb_¦4s2,«+vu÷#Ă-«kV«¤H@gjŃ©›ÜW ‡!zU‹~M^#úAĄ &ü{É)6÷}YĚđ+µ®â3*öĄ^Tď^Â9˝ĎĐáÝ”ś˝]HŮu+AµĽ<Śşú3áůôĽ9+ŻU:Ř -ŰÔ0š)m%zŹ Ů‚ËŢ#ń(`8Ë pTÖK‡+“őf‚j‚M§‚ !a´üűy$z‡ĄLkÜ#Y_˛)Ĺ gßłI^Ě·š6ŇuH2/™TŽŰäqĎM8Ŕ›µ·,đ@Ź}Áł˛C8Či.´ť©ýŹ}N×nu.äkQ u¦cń| ú&€9Ł>5ŇXD¸MžÝÓ!¬:ź2“p˝čě6îG?ç¶dá;$‚bÁť?ĚňÚĽŹ'(ęjlF)ąţ÷0F‡p{žčc§ýźĘ' Z1ě~+2Ży±ďËf)đѸg^Ú…>¦*k?”ŠśÂ,†ß†€pÜŇ'­™ŔýBăpťĆâşôµm šľ‹L8Ĺf‚´íÄÖ‡ë$Uřľ´í€  <‘/‚E´E»ˇaT‰7÷i:[Sž~é%źMëgOV˝áE™‘ýŚŽ§łÚ”yŇp’†<‘¦©U8yŔÜYsĹF]tĄ1ú}řęYX[ş"|*ýÖâ@ˇĚőü¬ĺ-§r÷k$yj 2o]·E ÓsXń©ZŇ °1t/Ň#öQ\ŽŮźÂę’úu´”SënđŰupŕ¤ĐĺńÝĚiig˝ŻčłO6%[‚OéAŘWč€ó° ÓëJÇ=śÖ”őígOSBţw–qčOŰP0ŽA¤śN_0¤ý¶ţŹ.!Ă4üĆţŹÉJ„'ů˙Ô©±Đ«¬†¬*šÇ^Ѱ S†-¦ŕŕĹl2?‰…Ńř° źOŃ {kĆÁór´uŤŮ1čČç´ŮydŰ}f¨u„äÝ<ăř?Ç@Dq§Ĺ«D|i¬Iăźáُň ăÚ~„DÜťŔµgé™Ęą. d Ć#ĎçöńŢľl)á)ŕ!Š$ÔĘëYŠp­ä7‹–NŃÍť%>ŚV–™©¦‰oő Ű äH <EžNéń7Śq'6^Máa›ĽÝÎŐrâ{> stream xśÍŰn·裾âĽyO‘Ă,ďdßÚÄAS$MăęÍ1YŠ-#ň‘,K¶ôă;Ă%9Ă]®.Adz0Íĺeî7Îy·…ÜŚř—˙=~{đő3)íćőű4ż‘›ßŢČüź1ŻÚüă0-t0%ä8şÍá«QÄŕ´‘ÓyÎx7uNj-ÂĆ_6‡ožßlŤ°ĘD7üs»…‹Ńi;üťŤ˙ł•"j9šáp»ÓBEăĂđtşQ϶;e‚0* j»ł"„ő `h ÜkŮ?á±~“ĂŹ°Mh=š‡*Śzş8Żř7 K¬ÎÚá‡éj Ăď·;#”“V7‹ź"DFČhÖVŇOiř,ędľŰzŘ€´ĆÄŃŔŻ´ĺĹáż2˘N9™eĆyŘĐP{"PŢcN‡(ř!;= ĺf§ěińy]|B“xwJ8=|Mł8TZŚÚńµo»č;0âˇsÜęEe†+š=maŔیĂş ÖA”#ż­ŮUC“űRCJ1JĂ—J˘›UÝY˝Ý’ŞĆzÓěe{q†šQîŞYđ¶†/Ř·4BĐAÚŹ”›-ĐPöý~|Gí†Ó>mËČ_Ѷ‰˙R_©ťŃ‚7´`ÁSśÍZ«ěFˇŤSIá”AGĐ8í„›Ô %EđÚY´gŔí‚ňČŐ2m·»=XÔ8ŤÂÖĺr+˝0Ň{D ¬<Ţ‚EőAZ„‡LQÂ[€U†]yhµäŰ.ëÚ®™  Á^M@_,Ä$4 8ľÝĽď úeVÄQ Ď»2Ĥđ#ÍţJĂ%T¸v ÖLś˙–€Í4áWÎkVzp7´ Ś ŞX.t8_2:hůĽo ĘQĹáí\Ź’ĽżŔďĆ„Łť±ŕđśţGJű|‹b¤‚ł qÁ$1g´˙ÍŔ4Ë”ďY?lßUÉuŘu¤;-•0>nŞn&pYrJÇo¨3ÎY鲢Ű8ĺ 4şŃ‘)É´ńrkĄđĚî9M×ÓĘÁfߊ[ ôeŁs~LşŃő±1 Ňa”v;â-¨¬k†GÂ~Z tCŞü(‰7`$ V}˛"€9Ä~¸®K'hRÜŞ đ·îX€´"zĎײ ŘÚÓz[z‰ÇJ¬›L=˙îtţRĂÉ=˙¬|‚Ĺ#ĽÄVűć»A@m•ŢŞÂBř|IAŢyť<¦+çD1šśó”‹Bi7›ĚM¸[«ťâđn[şkN—z J7ÁgÁ# 9B¦YK+÷|SROá´)‚Â.=Ą•G„-ŔÍ;¤’›ťĚţ€éČÉ\•>yFWešŽ\±řRâíM–#­‡—=uääß“Ě=D8ĘgÚîŘ€źţ5qýyO&úŠtFrĚĐ.ČuA/7°Ů'[kEĘ› …Ąbȱ ®ŹáĂôŇ>@?ŐŁ.HBVL}ŹąR'a3QxŐ6F ›˛­(@ŇdgVD¸,0ę¬+b#¦" eNz5)3*&ŤÎ{G%˝ČV˝ ţ†ŔŰ/\€ž„í“Ă•"íi;ôfaÔa’)3úghv ÄĚ’Q’‘żʬp_ŹY*TÉ(DË1\ٱ;ęúZŠÂîµ0.ôő†íżÂĄNŚ!ôŹzŐłćKuÖ2ôŤ ?•`‚ ¶CZY^hsR `Ih#úq )ˇ*ŁS]e\ş 2aźíGSý$ýŤk@ ko8ÚL]ަ$¬šÄVáĘľ}˝#ëFÂu'sŚ’PfÖţ—-j´€ ]× ŮT°ňŹęŔŚixŚ×*T]čhÂčŃdĄ86˛ŇcD¶öś™âUĄP[0^Q@‹[<Ő8ę :ëŞŘËz~k-BlqťřâŮ&â–/,hA˝Ćď>+¸¨4Č–8éŃŠbô¶uCIE¬ÁŇVV‘ó-ş4ˇ:ęűK6d|=i$5Érő}ß1‰›ţLÎc´ă<.(Ȳčža¬»Ša‡|Ő3!OłńŹc”°&.ô-ÁĎ‚ž—3äj§”‡µjŐĺřĐ\Jŕ§VĂ/1îżuŰo­ŁD¨ÂťyB?I3žĹ"g=Ý<âůOS@ťĄ[j„Đ+ĆYş5óuL·@«Q$[K‘¸’çIçátLV ëĂ"ů5 śĚŕđnVZ ©TW°’ĹI÷[~Ŕm2”|»ŚvR y‹2¤$sÉ2*&‹€ĘňĘ•„ůš ČĐËĄĽ{}›ťÁý”ąĐ¨oe±,qĽ 謝L*łhz’źśJĺ‡Ű€Ą_™,łÖRHÉ‹m.¤5ˇSŢĄ•ĂűWś€®˛=6.ó!ćşĹFć 'W.ϨŰĂRaşťŮęůIÉj_u-ĐIvA–۲›< ~ëuď|‚„ą5&Ń_Á~3&wÍn˝™•…#ŃŃcvWîÚ/•ŢŠä¬Č”PL5¦ĆßBôDjB u÷ –š[eƵµŠ®yÔ6Öđö ń_îR»őčI¬-ןî˝ý ”E_7łĐ3DÁŞëŢÎ9$QŁóăQĂŘ,ŰŐŞÍTäą%”-ŰľŻäkZú~·4ůÇŃ+ŤA88ćŻĐäit¸‡„&A,îP‰†GĐ”ĄÇ_Éó9}ń ŹP±”°Já$Ëh żŰJ I“ťWër ŹGéŐ#ŰoŃ2×Âç6¬=íÁŚ™—“ÂtŁeV*ÉĂ)»µňOŃ„JßRAI’jůaÝTiҵ˛›Ąy¬äq}GľÖő˛HŕęĚ‹—]'äĐW®,'Q˛BzÇ7ćVßč@+żĘńnŕęׯoô}Pލo‡A´ĺĄâ3<×NNČc˝ýI7®żóKłźáť‰"o»őĺmY˙ĺ _b=0Ô+ţ|ČÖ^Ó OhöÍ.ßÜq–˝ł]6kË,[ËžÉoňaÎ,ĎÓ¶W4Ëžľ÷óµů\Ś|tM´Dý<= L«K~äĺű4cHđ2–/AďŐ<’ZA§2IbwGxĆ!Ş÷!٬˝&é¸S'ÍöŁÎ‰V’ęPlŰÖˇG–‹.ö ö_’Ä<˘ÉJv޸˙Ç´í÷î‚×K“ĺ“ĹŢíYž™ÁÉwŰnřąW“oij4J˛•ß1ÓÇ6Xů|’%ičşśb¬ 44…ڞĺő~­“U1͆⛻N¸WÇWîŃXď×jąúfITa(}u_Cý’‹Öđţf*X·ŮŰFł&†Ş†®7ŕeĹé/`Ä\76-‰Ú%Tü¨íhhŃŽŤJ@HţXzpŢĄ+łŃ}6ĎşłWźq&ąź“l^żM«Ť¸ţ¤^DG˝ďj/âuŹ©&1¤x ;'ÜJáÜŠęČf}ŕ,9dY&VvŰR…ĂďěMd^†K›XŽj¬]JLřOŔÜMO¸¤vËëJŚ}!Ćâ_ ňuôŔqEŐk–'R|•ßďµ®/$mĄ¶%¬\iűšżął˛^ş–ľ3.°´ËÓ)Y¶jAńyá“ÚÂúŹŹ,˙e,ë6”ZŚÔ«/é©ŘŹ/ ź¬ÔŘÂÚŁć¬L,“ń!]Me%=€jlp) ˇPđ–M6ĺŢ tJą~MŠ•{š>ě<L?ńóá~_Č`_ŇlŰ,PŞL¬ŕô;ś•úőŇŇĽ-Ą Üš Xîd\„űť7LG®ęcS»ł7ë„¶ý©f'ŮÉMÜ&=Ę3›ľ“1Ş]â÷1AO©Óő>uy,+2š1crÝł (0ŔŚ\V\ľ÷ź^Ď4±>Űĺ÷·ľtËjŚŕń˛5X°ŐRř0Żö˘Ůs)öJ*×> stream xśĹ[[o\·.ú¸żb>x·đŢÉÇ:vIšňŕ†,ɶPÝ,Kv…ţŚöw†‡<ňĚŃj)Fšˇx†Ăą~3ä~\öťXöřżôďÁéâŮĎBĺűO‹8żË->.DúŹ>­Z>ß‹ -Lu˘ďírďݢJ‹žŐN„ĺ8'”ęüŇz Yîť.^ŻľYëÎHěęŰő¦ďlV™ŐßČřǵč‚˝^í­7Ş“A;żz9 m/V?Ż7RűNKż’ëŤéĽA­:j ű˛Ĺ?‘¬ë{oĹę{ř¬SŞ×> ĄďŐ°qZńż€%FuÖŐwĂÖ †ŻÖÝI+ŚŞżDŽt'‚ž[±WhĽ,Ăź#ŁV„Őß×>‰CĘtZźŽ-źü¶÷ʤĐ+­F ¤2m|PI{PÝ®Ä8D"šqrą‘őrąwËYkP4zuĽÂéĄX]•á8h!Ă‚ł"úó4 ˘ß_oDg­vuąvťsŔĚę}Yz]†§(©r[•ŹU˛í§µęŚí­[=…­ÝĄż«ŢE¶đ+ď”ęeç| ‘•i+ô/2×vuPfĎ‹ŔĆ*:Ü/kĎĆm–—]ĐvßPޅտר§"»¦­¬ňY~ŽÁOxVŐiëW¸ô¬đw„ ÓY[‘@aŠŔe±Ď˛?9?YJLŕ|Ť6#Ťčz ¦mĺ,ťYÂŢ;äIuJ‡©~j¦7N˛Ď-Ř<üŮvčćDRD)‡ĂĐö&‹ €ók 6“ ˝YQ.ë VFÓOçŘ9žä®ö™ÄcŽn‘S%tçŐŮ´ °d ¨’jl":.Hâý¸ôx-M×+égÎäÉ€ű(đp9zuă>üNĹ.*E26MlćĎc'ŠĘTA?ű8ôŃ~ĘŇč3®7•#âJPÄÄ"źkÖQßŇHżżDý¸NX*KU2€w‰9ďLŢw`&ÉäwöŁ(ĘŹF¦‰VP(}ŁôłsÔ•ufOVBRZäÔD'eA±zJ¶öŚYƸäń¬Ł[ěűˇ-:°ę!Ďř-Ŕ‚/Şż7vvÝÚ… ^âߥ–ťqjőe-şęK ·äl_•îřňi¬cQŢZŢţß € ÎĐřŤVą¬ę¨.µí\¨foFażßb‚ĎKŢ,{€BÂS#:O[Ý1[ˇ¬YpRfOhć„B§™ľ/¨éĺm‰śâ^ŕ¤Úxf/“oH ÔŮ9Šśm­Ą¤ţřBj4bÝ„±đ9^ŃI‚ŽJŕÁ„b@ÂĎ»OL l†…ÚDNŞD7dM6#˘+Ć@|¤5ŃťłHá(%ëyoŁb&át;ÄŘ|FD1ąkL€WŘßÍńsg“SŐĹ`űX}ŹP)'[ő]‘źĹ.‡ÔSIs' v(w©±–ÍF Ö·jôEµ4K@ńJ[‰Eő&ť|µłĂ™$néť‚dÓˇ!e˝tXXçé°Ţ„qXý„Ű ĄÁáoĘ‚S °§FűS@!Ř(Éü÷GÖ‡TčKëiˇ/±ČŠvŮÉQΦ=Vž7Ă€Ői™|;Nž—Éŕ-řXĆż.łSR68†kbyí›2{V†űexZÖ‚ţ´óGcájB ‡5 V(S€8v Ýë2{T†żM†°–íŃlŠî°Ű1vŠ“É Ľ©ú=nŔ!Ł«ĺĽSâëé)˝9Đ…±»‡%R˛ü€r"„Ľ â„F)aďŇ Łu˘­1cpöY8#f éG[đĹŔM˘lĎGá´ŕ°­'1Ţ”rµNXUŃ’`Z¶F-!ô„ %Ž*Ȯ׊¶±ŻˇÁÔŚ¬QR.h\ć őq™rTJVi(¶ŞCoĚBFć*ŮŽĆ8é8•âŇŕy:DhĹбÄąŔ‘y°€z€?WZˇÇΨ>S»ÓÔŇçĽ 0üGťŘy˝ĺTMŇyăT ćwĚ6_÷ßpíRŢD Ăv*8éÇjż*3ş|żabnąB„p`}Ű;ÄÜż“_&°aÎA3 1–´+§ sXęo÷ÚŢeF»äńfv×B2]Ë·qâ¬ëµ”3 ›10^ŘlŽ]W«Ľł0|j1SHÔŽŚŘ]ŤEkńRľŽ \m÷l“{"4|'”˙Ó0ůž´PŢq?[•ł[Á7ńqňBÎ… VbW<şć‘z–Ľl:™7Hžo>áVwŃ]b~Íî˛ŰĺG>ŐŻë"‚„Ż}Żfđő°ßv|M¦{__á± „ř9ř ´c!”qö®É\"Ł¬ŘŠ¸âˇt_Ťřúxsa’ŔĆn·÷¤§( ~=ˇŹt b§h4Âú &k 1Â-Y{Vq–×”»ÚzÝokß m}'ěd[ZuPS<é©§'łŁźń€×@dčĺťď]ŻcYÜ7sÖ×&¤š–Öâ‡|  ´yI´!ž¤jz®ĹPža)ÄÖ–YLăĆCęÖÚÄLʎIh®ďĽU-¬G˛ŇŇÓ˛-Á*ýÇčěEŇŤëDŰĘĎHžo»‘ôüvl€k_÷ż[´]_·ŕ囏j®)‘Eo©ÂĘôµ ü‚}‰I’«—Ű:€qA݉ŠßÖW–¤]5šîwËĂ`űmí­ŰoaŞKŽdÇ“ŤgÇîTN°šćüÝşvI™©ćę)z¨¬­Ă”ËÁgĆ›úÇ«číá°ĺFaÓHh>gm4?PnËÄPäńzR6 ëř„ĂUçLČŹśíz7ĘŞ~4 »7ŚŐM?2ŢĚ›IŐćM¬”řČÎFëć–ş7řt¤Ť…ń÷.ŔPĚÎÇZkżHü÷Ú$q´|r(ą‹OÔUn~“SyýPŁŮNކÚř?ľ.3¸ŞÜ4łRwâY-s+׼Dá_šÜ–ëcSă¬MCĺćd8U]‚‘ĆÁMnnĆÜ[pť_¸ˇĂi7yą·řińq) ”Ě2>ýR€»Ţ/-řźö=µxöęűĺŐĺőŃâŮ/K±xö-ţßóż^˝XţińňŐňˇiá÷‘=ÂR $¸ˇ[Ţ 2/ŕ„Ź={ĽzÄTy:ą§e*_>kNnŁ©˝©űw.ÚŇ,Ń[%¨Ľe'˙ů –Â}|îW}6(QÁ^jţI^ţjŰ^$¬eŞFnż*ă!ë¶ž˝őă_QśŹŻ’¶<4™S°VR$OÚUÁó^iTTćעĹ{¸Q1ń#z¸Ĺ®Ôýx7],¸-YTKţţ¦XŇÁřbł@žÖý0żŐ“[R+¬&rxěatą2wYľůBŢC°ÍşłőÖú`zýý ř[źŇTłˇ€”Ď´äEiŘ\|Ď?WÚv7›yźÖ;ě_Ťtďv„;Ƈ`P€JAi>¸Ĺ´jm®łŘŠĂ­:]ý±Ź¤z“ôHŹcüśKţ~9Ť¶˝»śćíQ˙~-ZĽmK@ź»%Ń]mŰ(Ůăëőhg“ęuĆ>FÝjĆŹÍ˝ô=źr˙°ďĘsôëdŽR±ÝWŁźě®yŰÖŮťÖŽć+†ŢJú1ö7dňÉu°ÚŃvD]QÇ~BŞ_čpĹwąë'©ŁA4Ř“vŞą„K?|yĽ. ţČŢ›"(6Ëî hp±’äę Ćd·f…ůR›NőěđŘö±Ď’J6!,Iďd˛€ŘVŢm*éwEŇäíQc‡)&˛ ČOŞĹShGmkźýěŞp¶_1q–¨Á[Í g?łń›IWŮjúŇĘKjĺÇă$9öaQ“(łýd»ß€ţSŽ<%TER|,=ś¸ÚóiM˝ď4ľĎѤĽ;Ń~–čč)ę!Xħ~Áe’ú> ŽöO‹˙{s®endstream endobj 407 0 obj 3637 endobj 415 0 obj <> stream xśĹ[éo\·/Đoú+č‡îYš÷ âĆm\$i!Ľ’,#˛$ë°˘ýß;Ăăqřȧ#ŤQ°i>3Ă9äľ[q&V˙äwo÷ž}+„Y˝ľÚ‹ý+±úyďÝžČ˙áyÔęů~hˇ‹ Îíj˙xŹłŕ­Ň"­gµa5ő Ą_YoáËj˙íŢŹëżl43R»ţ|łĺ̆`•YJÚ_o Jp˝Ţßl“A;ż~‘š–‹ő·›­Ôžié×rł5ĚűÔšASkŘ×-ţË:νë/aSŠkź›Ňs•6Î#ľ"íĎ`QĚłţ"m­ ůrłŐLZaT3řR¤™ziÄ~]ăEm~ µ"¬˙şq0 $ )Ă´>ł_ë”í˙=ź@`ÁJ«ńD>2mLh¤ťŕlI3-"­§‹l÷ ĘŐV:čärµó˙“Zâ$˝_ěí˙éÇő _*Ćá ţ6 YżIM/×ďkç4…`\čőuí=iŕZZ­Żjďu·¬ ný¶öŢÔći׋ca1 ˘đÁ¬*ąguěAmľ­ÓŽjďÇ ÷Čw?ŰKJÔŮŰičyíü©nyqW™şC»6/‡ô_ §Ô±× @¸÷\”3&SÎ&›ť*‚0ŻŞآFTŁOŃ@łŔbĆŤâ'ć%śďÔ|‹ć¤±*I"Ůöi@zŻpŃŔ4¸„Ýf «[#,rWšg8Ŕ2çĹúUťv„˝’§×ďRŻwyŮh'GiC/«1ó«ÖiJŕÉ´V™ĄC,Î:Ż"";&١ŇU$$\>Ÿ‘ćŮIšŔŚ/Ő…ÁÇÓ¤±×Š˘’"ę›×Ĺm˝îlT—QuTÄv˙ ¬Z;˛]lžWĂůihd˙Wăť|ó#Ź‘îgz5uţÖ„kˇŃꂯ»&Ž%v‹Ń#Ź=¬ź,vž}ż˛żÁQťŐ±D˘‡ŁińP8„rPĘ­ČŠů}Ǥo¸ůdęäµ& ] ţźCyťTŞ>©˝˛6Mmň¬ĺŕ^·}Ű#m¬ yüĆHşŔPC^+hlÓĐŮ‹n¦BßÇ’"4 yÝťC¦LCv‰ˇ«ßYý®k3Ħľ4Iolú:€ě°­M^¸ÚűýÔ[⬠®ŘëgťAůÉCaçűQgŤČŻ—Îm!đF;/;ÓŢw˝d"WűÝPz3žčŚ2+™—ţI”őŮ6ż{H%®»‚Šä¤މáúâťlÖjGë˛űĽ×ŹnńUŤW¸…Â~CL=; YŘvĘíĐ ‰ÖV«ĂÁÔrѬĘfđn†zŇłÔS?i»*ÇEĆfβ¤v‰-¦ĹIͬW‰¶ł–$€ŽÜů€Ý>bú‘Eř‘çôŤq‰®gMĐŧ)`uLDók"ABóݨó´cp2ĹóŐH<ż´ç˘ëŐäqňófŠR=ů$ßŔ±=ý3§&ć6>ŕę±ĹŇ‹ŠzĽß@)ď¸™ŠŽRÖx ®=ĐŞ §ďaĘÔc3—K©¬(ť0T:˙Y˙¦­5ĽaśőѤĄ p%ŃßSuÔ‡¤üXTXˬ#4ĄjĐKI3~Ü28¨˛Ź#˙¸1†Et¨P$d_pÄâ+ޤ@vÉďź\Ë»óiä%~LNŇG’Wĺ’Îĺ@DJz?ÂY’Pş!ş¬Ş5-ąČąL˛śq]ʤA*ő–m‘5ítM YQ’‚–T¤d©¨(J/’ě`¨'‰RŮŔG!ćó€ ÖyCJ4Ču”,fđWé”çbtbgş«˝‹ş+ŤŹiěA1^b&Ź„·ćŰŢ´‡îÓNŃĹÎg&“$Ѧw-'ˇŃĐ^˛iV żÚĎDŽSăC¦UQˇâ^ކ°_괋ƶŤ¨oFĽ7şźü97˧–âWjH/6–ă…âÝÝ˙=Çqţ‰qî(F7ËýËan)N¶iśJćIQěg±ĘizuOą!gUÖ—–\Tś ă@¶0Ësôq\O‚wBúI†ŕI]QX›ĹetŢxŐ$oM­©Đ«V6–Ä÷`ržČy4¸sů^[ť–Ć‘gĘUnf“eŔaE¨»`ZÇýüŠfPŇ€ď#jzŚ;™¨ĆC…$qĄÇŕ§ť?‹C^¤mŚË ®4+P 5&¸ ň˝’ÄK¤Ď;e ΂”őŇŃnČö$~ҦҖ Ą5ú*– ÎëŘ ŕ!(±n7’YíBFţÓg2iÔZ8¨ĂI™Tłq,xńŤüô dd‚sIAäfá˛ĚY–®ĘtrňGącęď®ú[˘Zäĺ"ä¸~'UŢe®m¸Ą ‘ěKÔÁbýŘčI¨QĚ’‡•śÝCä\w/ăy§ťÄ”!×wgÂzśkޱßYŹ ŁüVT qPąîw´zrß©)% ěŃnP–Ď0“`ż…X–á-˛B{řńÜxTIMś vޤ BK˝÷ąíń /ă{64›^{gM˘$ x FĄ8÷Ër÷a#jśA»«ŽîTBh$˘?îzg°ëU>kžd‚d@ŹŔâŘËzÓňľ“îlÝ›n…ţt!¨s äŇHórH(QŮĆ­—ť©?ž-děŰ >äŮf„ěŠÉSłF¶Ĺ‘7_ęíš”uŢ16Ůä(7~Ă>Šč*Á OŢË%%9Ěń- ýb˝‡+÷oO<¶ÁYIż®&9Ó˘ě˙Çář¦á¸ß¸T]r1.Řhȵ¤iŇáÇB”!?LP°ŹŇmľl! úËË ×2tQŐ˝€©”,řŁY ĺ$e„ʤĺ%î ˛çşAn§˛č`úLćěRÂńz*Ú†ÂÖ2Äy˙[ňŞŚdâ$??ÍXl\+?2´r0†>HŃqWë“E0Ôh8s»đRdN<ং8¦Śť0Ć1–ëÝBĘSŽR&uělą«˝'I őc; 6†Ŕł3®«•fj&f·­–Í€$"WÂĂvŞwc‘«ŔÜťť!B·Ó‹Čˇ±ě¦âłÚčPĄ+¶— Jk¶zKŢqń¤l@',QD‚-Ť*p.ÂrşçŘ©Ŕ7ňşŠé!Šíń3Ą;$rć°€«Žß_‘^˛ÖřuÓż[ŔDáÝŁl×…^ËW3eŤ„ĎŁö^µ}¬®G)™g‘.Ž@ěě9›P˛J ß…Ç÷¦j…jWç˛(d UČVg҆9ŠĆü<żĚĘ0XÄVYŢČzm)Ž„űK°;k)¨vÔfA—˙‘żič@Ľl­F:IťĘ _Ž ŕżĚĐő8ĎÜŁCľp«ň‘r※|Kç$y[Xŕs+ď}y7gü˘9Ż5_‘>,XĹű?"_ÉB¤fyŹ·šŕ’.ÇŔł‚Ę=<›…\Áę'›|ÜěípčůŔv$$şąčŮ Íäľ›¦úł‰yvˇ-Ń`ű$!‡¨qę1yŔĐŃp­Ú$ń°WčluÚ ˘ąŐää_ b~1ŢO÷Ş«˘)XEmýĽk.^v´±tŇšć]űčáýđÎDo…—XÉÂżA«Ö`éFÜ® qhüsLb˝gšËE—‡ŽŐÄqZ|8Ő_|€°¤ů®×üßą÷ěĺ—«ëË›Ł˝g?¬ÄŢłĎńŻç_˙ţyůŮęw{/^®ľą÷'XV;ăéŕ„׬€ËďßđNP[â ¦="Ţů)°rP«0ác#ž Ä#¬ČŚŤ7†B¦ßÄxfň‹¦­}q/ q¤Ž·ÝĄ'¦ČÓ Ç”őFĺX*ď°Ďń„˙Ä}Ú$\9~ľJÇĄ9Ţ ©iĽ~Çe\^=b[ËXÓ–Ĺ2Í.¤ÍbxFâLóą±u4‘TĆWrßL;śOBAíx“ĺHçqń„´ť×ÓÜşŢÄTe9ú‰ĎÍ´ZťZÇhÂU䪬6qëČŞâoŁĘ•éňLŚĎ„Áih+ţ¬Nęí$Ťî]6dXłJĚé×Ďň˘Lć©Pˇ‚D'Óçm«mż"úWµĄôĄr—Çš¬ô%ij‘é÷!?…EŚŽ7ť´Ëu†„:ş0Ugí­'źŘWÂQu8-k&‰ŕĎŇpG ŽNŇimđ”ŢeŃ!/É%rÍ„€Ň;dcŚâßMS-«”˘­}ËŔłi`ÖŻd'`üL­1ľđăV5,ÇăĂpNťđůxtwĘńMz‘řŐ,]•e×™đÍ@‘Ęb‡)Á†Ă<hD2%ˇŞř}0ÚŰÉ-ł÷_¨îendstream endobj 416 0 obj 3795 endobj 425 0 obj <> stream xśÝYÝo·ú¨żâЇz7đ±Ëo2@ ´Ť¦H“Ö¸·Ä5N:}ˇŇI9éëżď —\—<ť -`čÁc.9ßó›!ď—ĹŔřbŔżřďŮíÉďßs®—'a}Á˙>ůĺ„Ç˙ q×âĎ«°ŃŔăĂ`«‹“yg¤â#?Ł,÷‹iŤKÉÜÂ8_«Ű“źşżôŠiˇĽéţÚ/fĽ7Rw"ô?zÎĽäęVýR2á•uÝ»‘4ďŢ÷KˇSÂu˘_jćś÷˛c@*r5ń#˛µĂŕ ďţÇ”r‘nŁŕ¸ăB[´dFëîűQ´ň»~©0\Ëbó;ÔH1îŐˇ«Ěă]&ßE ÷Ý·˝…cŕQPHj¦”wŃ üšŹ|Xý-FŔ3o„QC¦Ś……·Gym''22zÁ“Ęd˛”*+Kaók›ńL‹×UËqS›™Ę ďˆ‚DúMü›ĹUG«"Ä˝HńÝeŢKŽĺhŢôZ3o}ÁBĹóŃ˙ÜȢŹŃÂ3 yu×ÂWĚ‚  éđ•·’ş"˘Ë,íöTd3lĺ 4§%H0ŹŘJČő-d6·8âůWÖŢšW¤eO+„F±ą`o2˙稌ڗc€JÖ§@:čă(ß µď}KŔş‚hä5ž˛IčWő)Aď”f\RxŘ6W ¬Ó„šÁźvPĐ'>rÂöM\ÎöŽ](zcjC¦§˛!`›p0ČmąîH…ŤEÜ©!8ĐÔî¦ń‹ĚWr7ëd_;ŁÖÍZűąG\Ś'©Únő$úG ůu¬2$šVŰ­f"A=ą$6[wsä†<°Ć1Ń?ÍvĎÄYfgÚM¦ Žąşđă‘¶BÖ•n†-á9ą™wBô|łîŰŁo»>Ż,b7ećčäHÎŚ€­Í¨žč$q×RŞť#°AšÁ킌'y=bůţkĎ9\ŐKŕLň•Ł(Ťó, 8FóŕĆ'ťőηşĂ @Á,`{…×aĂ&Ę*C|G7Śc´c9Y¬‹ JĎ(˲›†łOÔ;ĘŔi>«˝YĘeĐ:X +°yÍ#ŁďEk1ďlžŮ$ű¦`Z=$$ŚŢŻ‚©$>"‘M6ü5Ý9U˝ńŕPFĐÂJD$gtáČ‚al«łíľ)ŐŚÔŻźiňN|â’j^Ľ']•Ś%^µ„ ˙}LU¨G‘Rő…˛FCÚ@Şg›ç1 %Ć "Đî(ą d°8 {ÚÄ[&)“v»nŽÉ_O‹G&~úšY"$„K?ŽôźZĎX·­áKß¶ĚApáH^ł÷¨ŰćŐşâźÄłe^]Ćç3ďŇ›ą©—2±kn8«ĎŢÄÎ Čmä*ôÚ™ďZNxČ‹ŹÔ33ˇ®°řč"†CŞÔU©>É’÷="ö:›EüyŮOŹëń‡ĘsÄČá¬â; Ě˙ e/ţ»A,™E—ÔÚ|ĺ<ŕďÜHž'}-=¶ÍÇ6Qš’Tő»rC\˝Î«yőy"CÚŕĽčmš ź*µË öu«đN§Ĺ›Â’FôßFűOFĽů&sx©}ďľtwÉ7í­á´H„™Źqbj‡qÓd¶kÚvÖ´â¦pw’V?ąň°ĎbÚiŐ¨9r,%XôŮ~îťvÚ…ŐË(B©ńbÜpź7W_‡(¸ ňč™>żi‰ }#™Ş‰ç÷•ĂK€Ę/<…J­ôŘć\#\ו€Ăů3¨¸—ĺ~ŰĽËřJDCÜMíŢKÜĎ‘Ö6“4I‚ĂO™Ă:çÄn€°J¤ťfň&o }]@Ѳja—•s\«—8A űc.˛úśÉŹYîH^ĚşU x#…Ö šÖň]ńŮS MsÚ×-Í˝ [Y›ýÝn¨ŇíyŐfňCöÚrŕk„/22Ţ´Źť<Î9µ‡Ń;‚nĽă ¸wsľaµ=íěú/¶\Ú‰ş«ś^ŞĐÄÂËóőőí›±í$#"öM/={_ľšÎ®ońJŢžŽŽ^ÉŹúˇ9yp¶ˇ(÷$*ţČ2ł8ećÖ2i“˙‚U‰ëúłŇžÜˇđç—ÄíwýëÇ—Üĺ1HďV'˙„ż˙Äô[Tendstream endobj 426 0 obj 2348 endobj 435 0 obj <> stream xśĹYKoG–8úWlN™A٦ߏr‘(QPYD$ČŰk@Řk†ŔżOU÷ôTől/q,Áx¦őúľzřÍJ µ’ř3ýrqtç‘RnőâÝQ~żR«×GoŽÔô‹śV­înpˇv+-…÷ÚŻ6gGjÚ Śq墄7GO‡{ŁŃů¨‡—ăZ g¤ŇĂóQ g]Śj¸˘·×°4yOŰQ ݵ ĂŰq­ťI™ÁĚ›ţŮüV%°"Ä PXeM‚[?ÚÜ~:ü‚çZĄÁ3”0ÉhĂ“3Fă˝R«ĽŹ(Ůüü ®–6ÁÓI٦ž¶ic‡sÇ&ác<ŢąÂ𾩤ÉçM(şŤB§4ü:ß±«®q­´Dl·ŐÇ3Z@0±h×dĺW L¨˝Í±Âx©«E~Fó%-ł¶B{ĺĚđ7ĘăS´jxň c¤ŤĂýqm@pâđ#Ľ5p¨žŚ1ŠĆ{5÷iĽwĘ—ăÚ‰S2ĂűňŘK‚@ÎíOń$đx•ľżŤp.j]uÉ‚˛`9 ÎNh‚**¸ĺ˙—á ş Ď72(~Ő9˝í]uM+ßŇůĎ‹*(Ó‚Ľ˙­- &€şq>u­µ:GŃôn[NBůĘů.ÉČß~7żEÇ)0%‹ÜdÇ+zĚŇ{é—čüä=\n«ôčf˘s˛…7!ĺĄěÔI}°ËŃ ĺ l˙@ź_5ŢŰ×”7ÖKŢo‚2řŞ@ ¬{Ev$›1GžĐR¶ëu•n==uá[\č„W‰JcÎmwUQĎƬâlsý i˝Ĺ ڞ9‹Ti ¬Q«ížó¦ Ľ5içg_ĎYFß­cq#Píćȕɏ®đIDËobËnÚN®*QQśMf“‰ăă%-¨Ű€Né- đ÷ô–-(ŃĽtpńi^‹ ®' × ňF”Ş(ʢ›Bz©gYFHĚxl?SnKo+9™€ě‚”püÖ(ÚzĄ?l*m [A*;áĽđk~`VŘmŚ—ŮąßŹÎ‰äĽĘ\c‚0Ú±ha.$0Ç˝«˘‚{X0_ ¤ąËy×UŁ`Őj‡é2D¶\2zŐ‡Ţ)“ZAj„“řž™KĂRtŤÓ•šZşŘ`0’®ŔŔ aAB©Z aɢ¤5§űf<ÝSřz/¸(±4±đä7Í×Óą—„˘k4G@yF¸żßÓ¶ OV…˘bŤµŇŧôÇčEů?\u„‚ h€­ÜŤ` Čąö@vŕydţľŁÇ–}Xč®VJa­6c„H™đž-K/Ť;@lPFĆĂţL2ă›ÉB±Í‹ů$úĽđĘŢ÷3<Ţ˧2)eaUJéŘϨK—Ŕ×K.]Ä˙ŽŻÔ*ďČ ÉÖD2.Â2{…žČ<ôzŔ Ľń`4ćČ©ÚÁÍÁÉĘ!ŐȨ»®ÁŻ—2RÖ(ş|UÖ`ńÍbâ˘öĽI™tĹb^Đ-yŃĂÂTëWÇŤă5řŰB3p€;űY‡â€qňs^ Ôhľ(†gC7˝tŇ–ě†]/ŠŮµĚż'¤NWnTmúEĂłq˛rs“uî6ěz± Ŕ [pS éYüďIźŮˇ‚i’-¤Őz¶Ü °íJÖąŔkĚË}ML‚Z8đ -Ç–łŠ‚ŇáFé ¨ÝśšZ>bł}°č+K,®· Śe‘NÔŞC—c¬×Ř7´4<ŹŞOÜB!Ő¸N)€@[S¬č¦ /k_ĺqAĘ\ŔH‰*’źľĆ„˝š#“Ǧ>a·c“tl“v‚™PRí{’b€O’H‰ęĐŰ”\îg€ĺmpQ…<Ů€,aă$VĐźő €Ź ©ŰĐkśPŁH }q­ŐÉwŔXôÂ;”2`…?XĄËâ Éűk¦u~dC™ŻAľ&äßÍ6p&0ă3xmüô¤LîĂëA…˘ö• ô<đÜcmiĽWÓ;xqCă»—]X“ëY~cŐe6ęű‚ SîS¨S»9“,އEš†î1ČĐ– yĘj˘^Ďs©í¨püx‰˝×C±ůˢb8Ą>ő¸Ďe-‹&4Á—¦íIµyľ)ś»Łš¦”¬´Äć ._‡25ŠljôĹŔČUT®§s v’H©÷×Lł×DłŚ[1<–jbËĄKbż˘·ŰTÍÝĎ‘ě|fD˛,3ç—{;9†§Đ,T9”Ľ”w_Ł}+׋Rro’qĹŐˆ –/ĹhőJXe9ŘΖmAg4ŞŤÜĐ‹ë#›«AĚ˙ęśÎź;Xöß-ż 0ĨMP—ëáŃś˝_†KËůÔw¦Í¶«CÚ;p1·ś6$ążkYµs?´Zˇ¨a“ç \čŤNŔú7©É<ŃýëGß=Ý–±;L!ÉYĄ÷‰»•č2L3—ôĘCľ>±feEe“ŹKŘ.ĆýďoĐösLɰĆ#y˘Ű2±—$"ĐŠeîé–żM•–.ňÂëĎŮʉęłlPÓ#Ź;15‡zVŇ6•ű›Ł‡đó{Ňaiendstream endobj 436 0 obj 2133 endobj 444 0 obj <> stream xś˝[Ys·®ň#Ĺľi6ĄEpzł|ÄIŮN˘Đ•JŮy ąĄH"i[‡•_źnC.I9Ą gp4úüşűó†3±ář/˙öćčŹĎ„0›‹_ŹâűŤŘĽ:úůHä?xµyzZxĹçvsüüłŕ­Ň"­gµa3żJ1ż±Ţ—Íń›Ł§/¶š©ťľŮî8ł!Xe¦ĎÉóß¶‚%¸žŽ·;ĹdĐÎO_ĄGËĹôl»“Ú3-ý¤¶;ĂĽAM µ†}Íô'˛Řł¸ť!má8÷V-ľ!o˙ĽÝicŤĘTöÓľ…ťŤeR‰éňúój™JeĚL%Đ@ÖýžL;®›ye篷¦—eÖÁşę”˙%K%°`ĄŐ(‘Ũ­ ŤddZyOf~Ě‹HłpS`‘ťń9ąŮI+sx·‡ůŔtÁĽÓÖ#ÓAÔĘ)=‰á[‚a&hŕ’—RO/‘t®Qjop¨ŔQ7˝›Ľ®NҲÖÉé-°ŮY]ćĚtUw˝D†»˛˘V–~Üǵ¨ĚůV2eřkv!lŽż=:ţĂŹT˙^TM{ą…ÓY`‘~…=•őět†›YkDÜ·Ś˝LŹŢőó¬_Ş>\Íß_ÇďT<®* SBĐmݶÂ3)¬ś>ŕIa3°…‹yţu•ęŻpXcąu™TĹť@ľH #”ZýÖę­@-QńűI:źJŢÖ·çőm\Őx)§Ç¸Ř˝¶tÖe%pŹ,s~> ě•Ďgâńd 5Ý©<ÇŮ’’Ągsúˇµdi¬FsÝ_f­ňTBĂcZK´1uGJf=EUľ'>TL‚{2bzżEłS çU=@ü†;Ăäô%!ąjaÔŁ­c.H€¸ť –8Ń Ë#Á°Ľňł÷>» ­˛?~77q_ p.Ęr~Ý,Q6†Ăj®ňňSŞ%1QÂÍj, Jç@CEă…_Ôˇ­ŤknŔ'Ž^ ëČçČÁŔQ?ߢş(p-< O>”°>[ 9PŔů{TŔřÝq-%®M(°Ů‰ě ŻŞ6íš Ż0Z‚p%§m-ýë$`µR‚q8T‚D.Ż+­č­DĹĆšO˘’*X QR%-~§˛‚]x @DÚďU‰ UżŹ®\U^]¦˝ŘŰéĽÖÇJŔőü’xóˇŰčIĄZiyÔʸ<¦č®ś^F ¸Og‰ 0íęŰ/pÉśęwHlEfF‡eĐ)|±P е¤ViÜ´×G‡ĂĎęÉ“ĂÉăÂçg5”J3g4•ČŘN‹·šJ·Ą}ü!rxŽnÓÝĐrVMŞ5âÔw€¸ŕ5žPADxúßrĽÁśµ€·Źü±†fű_Ż‘ťF4Á—:Ęë‘•®ÚČăg!…•łÜ@ą Ć3Ř &„˝K$?QŤ ëĺa„đ°•*ČŇ—8}{lĆ“óćŕw“9Śń!r6:ćU9Ăw¬‡€ź»ÉyMĹ‘.CwĂ™„·?MͲ3Ľ#Á%nQ„óĆ: îD˙Ň;T¶ ýČEĆăä"~).’8§ç‰Ą0ŐÇ:‰xÂwŮ6¤˘ž5A§2ůŤ!Ëé3Ě|Mű˝ű9^$Í“şFţčć6˛Ľ;ňç[´­Ś˘­8 O9=©ś$1č§í,…WĂ6 U_É/.üacceAOŐr“ ÁĐČ4ĐČ$łÚĄňťcQŃyáJNqś3?Öă"$€äW/j Ľ®ŹĂ”ň ĆH1¤ C«űąšÔűatÝ×·mć˘ fSŠęRR › «Ä‘÷#ĂŞŽj(®ęE¬TµyŽpŔİ‘«aě–Á++ÖF–xÖxy|CaSđŞÓŁ:¶×?éMS\÷¨vµ”“7«9˙rÖGłKst.»Âв`ZŔČáTJP2QKN•Ń$ ˙§ĘôQŕ– Śhy©ÓĽC$]ĽŮ8(×ďX“ЎRĺŕ†ä¶Nˇ sđv•§…  C&8žĘ´Ť°H Âťď ­ť®FÔ@«#§c{kř‘kĂIG‚Ö*• ôŽÓEp€Ć`ÔHvÉúĆ}†×}xÉÂ)ËŽa˙ĂíkĐÝŹ,şZ‰O«ŔŻx˙ĆĚ#UR`ćq¤’$&”śU®<Ô d-ň\ aJÄZfńĘă\ë‹•y{RǢ™¶€ç›ÔŘáĂžĆR QH;zPd×ŐÖň¶1€GŤňZ”éX}-­-śrpŹëź°‘ÜÚk"Pµ mđjügvass¬Źű>›»Ł¤Ĺ5—ÇGČe~ÄLËş{Ë"|¬°6z $Bđ×cCń¸„^Ťăq¬î1łŢ0YI?‘(AĂ9ńvM˝d`f3‡‰7Îk¶ňq˝ö|RiÁ$"S×Ĺy6•“Ľy[ÁŤb rĄ'Ňú¶ČüZÚX  ŕ5/N4m‘Ťeę[_]ŞSŕ—ŹÁžŞč_‰ţ’<Ó÷ORŠ6Kł·}ŁňĹŮ-ś<=ë9Ţ'zmŽRÖ"zxz‹vĽÍ$†q᫦k%°‚ę~‚jh¨Ăbć* ˙ÇŤSŚw"ЬŘ.FőĄ8|"•¤ľŚknîË˸hV1ľT?‹/ßUť"ĘňŤ×řElßÉÂůή:Ěą–Ďě%…7ěő:…ŁăŐĹ‘"÷đ`řÝdţöö-Ar…ÓRŹ“uâ|ŞÇęď?ĚžrĎí4n®­4ß’ÇšW@N&÷}$©áËZí:sĆ0áWüŮĚrOťÔ¸ęp1@ĽXeOö]xŽa® µU°¤jşl%'U ăŤ7QĨłĽ.kU© 4ĘF -ă~ŢŰέ—K"‰ż‹ÎŞBź¬FP«>H]ę¶—d5Ćş°r_xŕÓ‘:#ť˙ +•“ŇvĚľÁc˘rJ!J¬VľfhčĘ,¤µjĹ[t8(úB·Îç«“bă– u¬ćCĆ· AĄ sş© ·…lLJJĹ@sB‹ď#ć2Ő*Z=Aľ|U4[ZBĐWîH¨ÎđRWĹQËlăIl ‰@qÂŇü‘ßµEslĽš´–5¸řľ·‹ŰV’Żl—Sb',„zĄßÓ*pj”u‹eB‹_rçZëľ:ś—jnľÔ2A1Ą9ž{  Äˇ–F†l.ć„čş>${.=żEů™txKżb`¤¸aš«™ě6,Ôˬ_ä;§ÜP=-Ü;Mą´R9v`|¨¦Y]fkthłpDzź r8¬4ds˛©Ź$@ !ˇŇX…y7ŚŽ 7V®mJ/‘U+}~BB[íͰI®đbň ¨KŔú÷/fJç!MQc®×—hĺŢ0¬4VžhN 6S2Î/Ş"‡”<°÷¶T~«|/p>ÂI°V˛ĺçŠ-ÓŰ«F%Ď]“Ň! #zźeg›’ăĐ@W×#äě±r×)›u:A4k'ĽbI3ź>e–T[{5éˇç »k­!2«kÍ Čł¬{ĺË‘¶µ«ĆFÚzY$Ŕ™%Ýñˇ%±:ˇďo8‡Ń7ĽXI`_sŤ%Ży?Ř=WŞéץ«|X5ÍÉ÷ĹeçvâĺŃ%Ü^w/‹†4ÚżđłqÚ J8¨"hY° ňćbőľa:ĚŚŰîď˛ó}­Ě.g(+Őt¸KÇŻF·Ä†7ÍšĘĹ“¦šęÉ´Ű^˙n®Á6ö[ÂzĽ\$@:űc-6˘&Y˘Gb żTU ;\ĎĽ­'[+Xĺˇk˝Ł@JÎ_Ď뾬¸»˝* ŔÓ˙Ú¨oĄ>ěę6Qýaa µFy" \-Yw*°XëÖúw‡s“ĺ¶ëś-ĽS–){Óď*ňip´źvŃ{÷ś˙Q]ÁzͤyăÉČĐÓbšá$é9¦Ăqk.{6ڱDů|Wú@D )Łéë,÷Ž&™ ·7ÂËĎwĆŮĚmAv%–đf\5»l7VŠ[—EĺZa¤Đ‹<ŰߡµWnv™~˘ńOçĐpŰí×…ł˝µZ[ę;ţ0ęëđřă(€1őgÚMäŘ3üeÍëw x€$Îű…‹q“ô«ăŁżĂż˙*z¸endstream endobj 445 0 obj 3760 endobj 453 0 obj <> stream xśĹ[Is·®ň‘—üŢÝX †ä#)ĄtđkăëîŻÍ_9‡˙ĺ˙ľ|wđ›BĂł±ýPľ9řĺ@ä˙áą×á·G±Ł…&&8·‡GŻ8 Ţ*-Ň|V;ç6ˇó‡Ö[řĺđčÝÁż¦ßm43R;}żŮrfC°ĘLßďżn Jp=m¶ŠÉ ťźž§OËĹôbł•Ú3-ý¤6[ĂĽAM >µ†uÍô2Ů‹¸ś!-á8÷V%ľ'­?l¶šA_Łň.űa?ÂĘĆ2©ÄôŇü÷y¶ĽKeĚĽKŘ™÷ĎdŘQíÜŚ++·q0 ¤ {P†i<ŮWňďŁ?ć[ ,Xi5ŢŠČר­Í Č(´÷=Ůů'Ů*¸-'·ŇÁD\í {•Őe=ÇyĽwÓWřł ^No7píÖ)¦S<ĽdF‡éĂF1c‚ÖÓÇúűńf+µFŘ2)Wđ;H&ó~úąŢëé¨+4ZÜdpDřą§U~žĘj\ŞŮŠĺÖĺ­(îć­(XŠśoŢKŢak€{W+}ßlP¶ 6xÚü.AšBęéŐHlĺ÷±PŻć/˛Ó×őóýü;JZqf„ś.čäkĺM 5śó çÔ€„P."-T¤{ąA´HW ë &äwPEÉ‚6ĆET•Ž[Ŕ|6LťWĚ\`WËŔă>HňžI)Ť¤ş˙yý‡ŁÇíĘ2HĆĄť~šę¨Ĺ^U: 4šYáé¶š+\€śőeťj;"âh9Ţç#zqľWw‚;…SQÔFXéŔ”™aőPüJ @Nź˝%y_˛«źçH°©OĐK ‚ĺé§M<¨Ń"ă:ďqDiĂ‹›AĽµ0.­/ë' Ô$‚í› ÝŚ"h<©Ťđd~ذPŘ@ĚĎő”D   Ý Á)A‘ÓşŘ@…ţqq0L¦@”ô‹ôĹŐ$tQÜ*Yâ7ćÉoŕ*5čŕt݇óF“Čüo‡Fýd^Šü~ŠÔĚì!Ck÷ľěE­!šĐJNq J(ěO7Ŕ–”SrúoB¸‘ëđʏÉ?ýÍDYŮĽ(ôˇ›ZŞ*°2ǵ,Ăbëkl}§ ±Ő(zź2u‰|Ó\đH >ňA†'®Ž Ć ćŔř,•2ŽÚQ^ŢĂÇăŃ( 1ý‘öA+ryÇÔŽm%Răm‹ÚŘę^uŃóĹyq‚ŘUělel~Ĺ’ŽM=±Ż°Y 2‚ă¬HÚR¦°m‚fÂĂőâa kĚď+Ü`ŞĽ‚ö¤“@Un%žN‰Ľ>Űy¸§˛şÄťZäű«ŕ)laĆüCšRŘ´ÎVdňúiUĘv®©ÜH˝ýg(Ĺáy<´»äTw(gm0˛ÇĐSzĚ(› cŹy5˛‰»Ś×OŹÎBş•ů‡ĽMľ˝Ď' °«d°u¶±ŐČuźiéĂđ—1mžĆ»ú{2W†%„hÎ\^ô& "lĽÔvÖ†LâD3đV‰Iôˇ˛SŐ ŇŤÓ¸ˇd’5Ŕúኦŕóˇ’v–Í:ÝĹ+ü?íX­\ţÚŮóŐf”[±“ĺśm‡·ęĢ0´äďGű†4ëřKëďâ4±TÇ ˝é=~Xł~ d#â€ŮËŮÎĐtyŐ­4˘ő¶÷ˇ-QCµ~Ľ9ëÝY Ž+ź(Ł˝”˝Ť‰ó‡;G.şBH*x(¶˘…iíŇoç1)áB“‹É6Ťyr ü«2ç0ź€ę‚’BB{q·đ C—# °¦sj1<ňMë®·rť«l8Q‘ve!ĹZ}«ů(ëŁOÓ·„© díLR—팞Ź6M¸Óş+ONuHčŻFÇ'‹âţ¸e@9݇z~š"–č„*FĘ]hJYŚ.šrV˘ĄÄ>Üd."Đ'7ƉQYgîą_kJžmâgˇŰę-úö'Q„÷š%öu̢,|+ŕĘ<Íâ4+KőSŻGgL’.7 %’ŕ7ż%óń–O’bp=:ÇĐź4ĘV>ÚYYk{»ŕÚ^ֹƋµyŤűcK—äő–ĹÜŹ46RŐŁĐř­WńÎ\‘]Â?±éÎý,l“‚ą‘LŐůŽÂ]Ö°“,EüMçs¶¶M¦Ä\]Ăçö‹<Ł‘dIßć»KŠDĹĎ9‚”¤ńĚKżÎ2Űś¦ź#‡rŚ Ő)Í2ë·Ţ”ăćLçws¦3- %°ŕf"•&Ka5g†BJŇ(ëŔźŮ{Ą,ă]=&ăä%‰ŤŻč¨’ĄGŵÇ="ź“»©Ë8Ž©'8«{eŤłLpOźŻń™ŔqÓ+YŮËM>ŚÓ+Ä˝ ZĘ;ÁÍHă®*±uäqěÖ”Ź7ëË×UŤ{ŕ¬ô–•,fľ1Ą\ąÂŢ6.ž‚ĹŤźĎşg)2`˝*Üš·Âěąę«ˇi›ŰĆŠo•öAEtä|xĽ‘’“AopRđۆNÂĎşc0®D(ŔDąýRRH¸ ˝NŻAťă+ům"Ý›{gšĐžcN`ăŠz- '2Á{p‘źSł±ZD_ƱŐŔ( ŽGŚ=á)ukąu=Oő·§CĎÝ™\آD†|ŹÇĄ± mňY5şp÷@Y€·`y(ĚĆĹŤW1¤+n§˝•b)Ç9 2li`qŤU›•ÓdąVň`ŮNŰA sŁB%Ąył*S˝…Ž,Łc’f¨€ę TŇ«úŹGż¦Ĺ5äq°_8b˘ľ€ŹźŃ4¸A2˘Caő4De‰¬&ę>oQOĄľ“Ź+4†Lf-Ý—2ëQr†qG“Gd&r–z1ăĆűĽ•,™Z94Yj\-Đ“¶LiĘ®Ž ž+%„,gť‹v,Ŕyý ^Ł!ĹĘ;ŕMş¸ąYlžvx;°‰ä„ÉR^8.޵Ÿ»ů@‹2˘bü ¤ĚZ:Ü‚Ô0,ÜŞĄĐĺ)ˇZ KźÖ@ł'¸˛ ®řž?mŔ ]Q‡ÂB|ŕh«]ËyŚĆcDţ˛IÂŐtÂł+_ărGâë­eĆŹ5•9Ő0€".†•EzwIüŮE%0Ă2–9żµrĂĚ a»ŐüíYŹ•GµDBÄM$ňR%Kšż›kď||hŕŕů÷“IA÷őu‘˙éd”u‚KĘÝ:ÝHáĹL¤†p x^đBžW ĺ*{ť±fÖ÷.˛ă„ťÜl ľW¦OäP-y^Ť_U˘ŁÄ̵/ĐÂ80ĄcH,J _‚_­b˙Ől˘›‹šcŔÇ»;ŻŻ­ď,ď‘ăhźôƱ¤hâɲ·ĺś˘îžUŹbţÁâ áÚ\$± _Č-ÎŮÔLÎc«#&Tt;7Ć‹ čß;iyK=ŰŇ9·W&Ń!)|ÁW¤m · FĆĆęh łi¬Ä· ę hŁcÝ'PŁ üC'‰Ő":–l”ń»řł—6ůĎ ěńşţţŐťĐAÁxÜ©&ňUlS^U8ĚD ¬1QřKYsžÔĐť’őOć®˙ÁIŃ“úéۨ\Xčq_ Đęźo<ĆĘś+°Áëă–^äÝqL®ĄŹˇżÇÚČ"Ű1Ť—ą~"Noană¸]ýĚÓĆq†—†.qL™b\ďŚŕ&UźŮT\K,ťY‰lO–ŹŇ"9’˘ä¬3InjZb«˛÷KĽ”ÚO˘ë„X¶i‘ŇwÔ“ÖńSÍM.lń¶{:ľňÍ%° ŁJ[«4«ÔÚŽ+$›ľ1–€\ČK´©!š»Äz"ą6Őjdi‡>‹ÄÜzž:EËiŻsnš@mY^cćüšBţbˇŚÚ-^˝ _ zZ"m·.¦AłhÁ‹VłHÎ< C ĆŹMZ!ĹËqí÷Ű‘ż=ÍO9ÚŻ§§ĄC­ękFÖ˘ďAy ©ŤĚIÉ/ëăâÁTBŞ­őřz;ČP˙ßţ}ŽňÚ8Ý[w˝(IkŽŰŠ˙ö]rPŃ_ZKlŽÚ‚Ŕ2đësµÝm…±®WŘ\ý›$1¨•[ýqRúÎđý˘¶“¨g˝záM7¦SĆlD˙&·Źm%¶ ɢ/ĘĹQ•+™[ ŮŢMshb>uUűIł®KşŽH@WĹłöŹpDąÚíލIĚ窎‹‘•(Ą şű6|Łô&úăň¦˛n†Hőd×]ŃâW3}%/ĆĂ`cĺO`R *rJÁ±Ü|ý7Ă?jMŹ X=ńĂśTĂOi0•/čóÜůP÷I´J®+ËßŮÚŤçG˙<έendstream endobj 454 0 obj 3422 endobj 462 0 obj <> stream xśĹ\Is·®ň‘—ü–/š—ň;›ăرSv™®$eç@‰ÔR’HZ"­čß§ky ĹrJŹça°ôňő ţr:3~:ăżôß§oN>Ěą>}ţî$Ľ?ĺ§ŻN~9áéć4ęôŹga WŚĎł9={v23ďŚT<Îg”ĺţ´ĽăR2wjś_NĎŢśü4}ąQL ĺÍôÍf;3㽑zú‚<˙}Ă™—|VÓŮf+™đĘşé«řhf>=Ţl…rL 7ÉÍV3缗GĄ`]=ý™Lö8,g¸ŹKŘyv†“%ľ!ożÝl±Z¦]öź}+kĂ„äÓŹäőe¶´K©uŮ%ěĚűWňŮYÜ|—Wţzcá3 2ěAj¦”wd_ő“˙śý%qĹ3o„QČžŘ¨Ś…@4üžlyL“M'ŮJ`ź§[aáĺ,NĎ.ŕűłÂÁĺŕ—HĹ w +ßm$ÓÚ+źĚl,ĺĚÍÍôľwů¤ĚôzÂc´|ú€“:ćÄt)8ËéĽrü ü,îFr‡¤’ÓuüÝŮé.ýěĚô4.)}ţ>ţެů‡Â HĄ2p3ÎČŔH·Źdř]ŮÉř8Ă«9ŽţˇĘu=Ă]Ůî“ú’é*g†ŹO+ÝČ€—ő1 0ŇMŻĺ4ˇÇNĄÉ;OÜy*9ŰfŞ«J%ÜŔ;\(cŻ3kL÷6-öĽ{ S Î%ËÁačŰŞ'— ÇȱŇĐ›ňt]çŕ¶ľŤâč„@´ĚźíăŰĚ˝-‡§{˛üqѲ±ç•Í/ę#Č·tŠ)íf3zHϙҴ\oą$l¸¬TĚ‹ą@[é,ă0ô ߼5Ä'tQ•Öüôž Ř‹Ń‘“ÚĎßJ«Ů CÉ›ŻÂďÖü’°•ffj"äYŻęź4Í€ľ Ëäô8M7đg˛Ě(CŐ˛Q!ałĽśŻŃ/ż˝HŰł’.u•Ř-QŃhpš—ÜĆ5·<ˇy…čˡäúÉ»] Ŕ·†ąyMvŻŞČ“s ŚÚ[•QĚň>Ęř#Á_˛‹‹^zńoń쥟ĂŚĽđ`ŚEnű9żá`ŁG’q‰&l Çw ł;«‹·ŽÓ„ůçC]np!1«ęŕ_ůéYUĘĆŞ¤'ňyĎĐŢ­`PA Á zX9Łëżâo nĘďD$Ż)Wé÷¸}Ç×|pfĺ}Ţ3řkCqÓîÓw'gż˙©q\[±I ŕŞĆ Ů—*™…?¸©oëä,ĎG H¸ú& «“jÂÉŰ 2Â|H2D ’űŢ: ±„Űd Íى[YHÉĆq+™2Ťč’-ą«oÉqŞěá\Ę3éŮě3$2ŔĄ4DăČ ˙;]B¸ËVÍě ;Ї9 »A“ŃgLmb.‡Fâ5u]"µl–ÚháiµŁóON@MíDBăöđŢ,"č!40´µ–YOżĆú5'ńý·ČVËś`ěĂŢŚ°ô’ĘvQ^řú©ČŰ—Ť<“Đ/žÂcŔ)…Ď8µĎúzA%î + ˘áxK©O’zŐ;Űt-×ń(˙ŢđŮB¸.»p;ĆŔÔqh­s§đ-Ń›…;EmtV¬äO=ëĚůB@a$xB4ž" ěT'yÖűxtH —•hĽXË”gčń¨rüę_ „đľľpžżeínłlhú¤ńĂ:&ăF_ŐˇÄů"R2Xn[cl8S°˙u·Üú@Rxŕłëä<3®}ëq /™TŤQz=tX …ĘJŃľä Żľäp×Ju»rbKŤ]b[řÄüçiä>ŽÝÚçÉărn]ŕÓ´o’ĂĄ™)@Ö¤YËŘż¦\˝NLł>ńŹ7vĚČŰČËE` pŕ·»Çú <îľ8[}Ćayăfţó&G®Ô.FáîPIştmź@±—dŃX!Tr/b XdĘÝ^4 )ŹôŠ:ÍĺCAÇ´Ö(ŠçJ*#0"”¦F„§rVFg v Ť)€×Ţ7˙xöWYŹü„ŕ,Ś8?{‰jBŽ 6ČĄRôđ3Č«Ńé#ŹŮ  ^Z÷5†'dŕű˛dšSK>Žm5XTL«ěńÇnŕó]żSÁxżá€fvEá2 y#@xEŘJ$źŕEÁIтꙴ€w5ŚnbÜ ĂăŔÜŠŔW›VU+/D‰~S—Q\GRe@É Ń Hë0ĺ’v%€Ćqőë{44Kjł’Z±9®uf3g›¶°­EĽ¸×ÉÉh^rAËŕ“rX¨ÔÁ žD[{Űí{TR)Ü,KĐęGy ‚p—‰”Ţĺč3Ô.ÉpďIšg©9FžćŮ0v‚Ô2עČb/‡ČMT7alŰ»O•‹‚ )@ĚCoç.ČĂ!ęŹÖÓý6¦(:˛şY5(Ă}/Ë=Ň GáµŢ‘µL‡&Vŕnh‰ÇqX[6m‘ĐűâźeB§„tá°ŐˇÚ¬5 ěC[R5¶×çÚR_Cßä¶]ž¸DĎkŇcş)Α ˇŮZb*aOó+/;Ź$¸O$Wµ”{śôCI:NĂ[2QÓG‘TĽ8"@H§6Îl­<úg "M@`MwOj‹Ł5«ô"YQB’ŮvGÍ3ŕâcBşÍ˛€!TsďAQ”ÄY%­A-K<òŕ62ŠYŃŮł™ó‡5”U_‰ˇ^„•r0.ZÇLŻ-]ůˇ/S+áM 39Ü\ĐĽËP·iÍ<€hYmw(¶mŢ×ý(îÝ ·(Ä$îK0ÄĎŇ>îŠ[R1Áa'˙o˝…Ęf!řüqĘŞc×SŁQµšŕô€Ô(3¬:N‹3-žÄš;ˇcÔ¸dđęLD3Wě•ËŇB‚F›, ŤJßTť?ĎćbĄ¶¸Hňí Ë·AáţôOWĺŔ„öëYôëÁívh¦ŻíŞ>ôžíZy)§1v*C×6 1 °µĽ±/cÁ{\y ˝G skFŠ Ź Úőwĺ3c$yě´N¬í%Č®ô¤‚Ţn*d2 ­—€–8ĚŃXC˘ě "VS5(^[<ɨŐŐČ#1ÇÉęl]çYMź†RxnY· VnµŚ’ę˙äi×p>a€FfMÔ_?W R2{–öe,W3žHu8_ÝŐ‘á‡"eÎ-ębß?–¦±óH“’bä]€ó!ĺG„űmµŞ$5ńňZ×*¶ í8.n9Ż)ŽĺľúÜí8%)p*­měm­‘&·3l»u;‡©Prb"Ëdź”Ű OkâŔ˛Eźő†ďyč`\u¦˛'Ű5Ď&űôd$Á·TŁ}3@ä@Ow$ 9sŢ%_˛;y>Şˇ,{© ŤM[‰ú¤‡ˇÜR˝ˇeŁsŰĎůŞÁĚPčGFb5NPśÍ«ĘŠűw,aL L!ŹZÉB=Ű‚;é›J˙ŘFď«6¤şB8I±Ąźt7@łWŚ–¶ى4'˘ÇGľ)yXsfR„OEEĺÖow…â¶XĹŔ\TíĐËç˛Rٵy«ýůŃÍřÖxž“é{%QŚŠwLÓą›LQ'—$„~MÁ,Őu»‹ čYHO|·jĄnFČN>O”ÜŃŁ4eŽA9˘®ÄR…µ,÷kZ‚Ť¦ ßŘ!{Ö\Ľ ĺ2’Ľî•+Č5^Ď˝*˙ŢčNńTŘt‹ď]Ő,vëŃ;Ó}‡9^ú¶xŚĄÁ|ĄżĎ1 -ČZ%ó°ă¦;Ö˙¸ő;˛©aşmtE­µ‡9ůVňö>T§:÷D*ɢÍc?›ćM Pw"ët*‡/.„§/Ó•Đ™ |dĽVÜÎŁ´´=rĄ™îşŕA‚ö{€zş5íoDc—[/ěD[Ěl–ŢÝÇ«ŻŇMT⦹„’eŐ=›aYŞî‰u+›o|•ä¦4j,·rPÍ8]SÂţÖ!IËĐ˝Ƶ~ú|żcU/Ň}˙ş“q_ňřÂÔۨ łÖm$ák˙ŐŃŁüĽčçX6ş•Ňy^éJÄ1éh1´b{Ş„·Iöa·+˛ŹŽýÇýi€Ż Ć“BO×_e›g˙Âji*uHJĚ›Żôĺ¶ŻŁĘůZîřŹB4ÎR¨+hÓ|'\@R 屝ŕˇëpí2ę«UˇN׼[ˇN›Ů§J¤‚şjCo—˙ŠĆţµ˘xâđ”UÝ˝ýQ…˙˘ÚÓ‡UˇĎÚ¦ĂÚt— Ňß3ěČľ·Y dz͟ÚéúŁL鮾¤Î×cpźFĹq]q3tżg‡ĽÓ¨q‹|ągşâ ­Ůľ˝icí?Ť/ĐîÓťëŃÁčȨ\!NfB“Ů> stream xś˝\YoÇüČ—ü……_´h'}~ rX±'HdçEI DJiYż#ůÁ©ęcşş§{wą˘?x4;ÓGőWU_Ăw+6ńĂ˙Ň˙ź˝9ůÍSÎőęĹű“pĹWW'ďNxúKO­~4pk⌙Őéĺ ›Ľ3Rń8žQ–űŐ|ŹK9ą•q~Yťľ9ů×ú5iˇĽYłŮ˛Éxo¤^˙Ž\˙mĂ'/9SëÓÍVNÂ+ëÖ_ÇKĂřúéf+”›”pkąŮęÉ9ďĺz‚KĄ`^˝ţěiÎp§°Ś9ĂÉß»ßn¶j‚gµL«l_űfÖf’Ż˙An?Ź–V)µžW k ăţ•ĽvZ®ŢË3?ŮXx ¤ kzRĘ;˛®ňĘżO˙śNĹOŢŁđTx:Fe,ĽPť€BópŢk7_â [ §eĹj+, ÄÄęô'‡đ˛ű9nOLÚčőłÍ–OĆhnđnľ|˝­§—ďń5?)8F2ŘŮFŘ_˙ĽÁeĘ8’lŇ\¬/ĘŻĘH—î''­„«YĽi~ ŹţÔ˝{Çrv} ŕ>×çó­łřś‘.ď _ą*âz1?GמąőMůýnţýşÜ„ĺsď&핼EÄCî’PhŇNRů, áyYěŰŢͲÓňNźd–“ź_  Äd@qnčú…T“’—.˙vâÎř1B±IZ@ĘK˛0ŇYżţ’vp"o™Ňßqď7P&ń¦ĺÂQńŢé}…—–)!˘J(­©JŔ6A‹ŔŔ&˝‹‹ţŐŚ®®á%ăóźĚŞŢŔ$ŃDŘj5žôí\Ć‹.’ĂŠîĄF˛PôB¬\we¶OL¶kÓA2pW25áÁő­ŕ_đ5 ϸőŹ›·ŻđČ`ßpdŻËŮ““9^Vú„oi0'§żÔ­˝˛îţeá>?ćÄŠq~[YŻl§ő"[<ن,‰C‘Óż+c,ýľíJŽč÷uQŚr: ¨ÔJuK‡ďŰ.ăźç1'“d۬ĚßQ2€Ń1‘WĹ^ŠľĎął®죫(?9Ř­”|âđh:R&6¬ŘeEvcC „ą? ´ÄűśLM=ŚkđzÄsţH®źŕÓ€k¨m)~‡h9łĄ]Ä»(%8%˛;ŁŠ˛3“ä’Ţ˝¨üńĐáŕŁEď3›_úĄeOx“ĄĄW«kdTł—J˘‹žs† J«ÉiNśŮý\¦â–)Ą ¦ůŚşH*üC*©—eˇůŚ|c€ČďÉłk›@Ë\0”>b9ĎZĂübŤhŐ:IÁŹ>C˝°‚Ţ=ö¬Đ˝K¦űgĹčY ŚŤpnâR,h^•lńcĹš»6D{k?ɆÍľŢŕ€s‡Üob."«łđŔCš,Ť,-ž‰>Y=+0˝Şü>:0ýÄf »uÁ!a_GĘî¬&K%úö !#˝ő×ě8ř °˛‚|*ď~9Ř9Ýpî0©páPzňÖ ž/wÚ¬?ŕűąY*‹ź˘é‚Ž%UóŔ%^’wҡăä˘/š*Ç<Řńłq…şŽ™ÂFAиQpKÚ¨%ÁF{žmŃu.±E™}˘ŠG}IĹ áâÉ ˇ’ďhý•¶ŢI Bl î«’Ř@GÝ:#ŇÎ’›%[‹ĐnrJÖ‘Ţâ¬<ůťDÄÝ sőůĂ}Ö3 %$nŞ2„˝¨/ŠČ Ś’×eFŃ˙ĹŇ…¤N&˛dÚbĘUÍ=Ě~ä@šĎjÝŚý…0ß,t]q†×]ÂíˇŹÔ @vE〚mŃ0^ ťUÎ Č’ŘŞ5ÍailÓtÎÇ6Š"\ŃMGĆZňŽqľ f€SCr3o{üb'ŰŚTc+Ťźśđcl5DŰćły”0ż®Ü+Ţu\˘Ü»Ş®Ë$.ę{ňC"Ziý„`vŔÍ;^°}úŇM7´˝Ŕ i¸ŚśÖVĺŔYkşôĘ –¨łmAĐĘ\Z*‰8‡-o9śČĚű\«”g›“Ä»DŁkßGűîę·Đλé˛Ąä ťŞ$Q'KŁ˝0ˇ=™ž—ăĎéD?V©ěOέ—ä ®^ŔňZ(Xăä×»n†uM9…ĎĄ;QO|V’:ëç…BĽěâ|‘šk3Ě{źĆÚ1śťŁ÷yFFR_č̨@Ő.gÂDHßnőSď•6Cnâćŕ}ź*ëzđ,µŁv–ËŠřÝÉ鯨źÔń}žţšB6r =Đ˙B“‡‡Ů;¶&¦›BZ  A…ť(çĐźwUzäĄÎ¤«BËE5bÄKÉTo"ŰtŞ‚Ye(Ĺ’ś_]—‰Ů>H0]wXÚüb®’H¬ő>SvI=a0 ELI¨‡Ő]-Ó¶˛$mp|)zh”ĘX 3m1=6—÷$ŽüÁ„×aéŇ8:Őfë˝ Qä÷0«—Ţ6•źEB7)ÄěůüóMůůu¬~zI‹ůî+LďĆPaÇ  ńٞŢtc(pb·&U^X–qUś·!˛ÖWѡŔçĂFł˘`â׼Ő§if€ĺüÓKJ»Lć ŕÄ–Y˘vw=tKÝM~Č•›¸ cŘQ·Xž|۵tdŃ g —÷K>ŚnďĽŃÄĆ;–×vбIq[U§šÄf›xË€úFN×8ŇZńPČýíi.şĚÔÇ*F—6{Ł`zČy- AŤń‚, Y­Ę¤ŹWäđ·óďÄ›R®yżĚArʞb¨5Ul•Ҥ‡đŕ>­Ą„ßx6äŘfąŕ®@Ó36ąž2uTăq¶ÔžçaÇBóĘQUˇúT$â›ĂĂ5ŮN/Á6Ź]˘ÂëT0mŻqÁéV6/jŘÎŮÍĽČ´ěC`[q‘zýÚo^ED„R;uEů Ëâ p¤äHšý‡ÚálţąđżM[ť‰ć˘¶@íżłKŞ mç)†ąî ÄbjżŞpŻB­ö‹ą|úşRJ9ńŮR jĄĄÁťŃo*µqĎ!@R;0Ę̤ćÔRCáĘnŻ{?“ΙFď‘­×]:çűŘú˘Ł'ęKL¨Ű©¤iiQč1®@ĂkU\ü®‚éá!pÖMôĚXEŻ“ű˝–!G‡]ÔĹĽałĎ@ďYibfЍ“ŚO€Äs?ď*h7Ř&ŁÜ¶đĚ.č‡Ô!І]A›™dﮋ=jU (ă°3F2ŤĹţNŚ—Ë!#ě‰>Üt}@—Ťă.şËŢmŃšď~ NIaÔ>Żw>§ŤĘđärŮV*¦×Fz@ŔÁŘÚ˝ÓWăÇ8mXVł·Ĺ­ 8ݨś„ă«‘W¸^(It,ŕ “ >ŘßĚŹťi"ÁĄ’E´Çĺׄ‹d°¸Ł”̸çÖ…*x_ć.nSŚîd#s"!wŚ*‰łśrCȡ`Sä ±¬ôBŤ«„]#:Lžˇś©ŃŰ$vô’0a¸ßß*y×UÍë"ůO‡?ÄżŚŔ~źĎ@Ô›  7ś€ľ!µi‚~1¦oůÇV!¨ĄJą,¶Ű»ĚXp"}?*®ĺqcůă®f†őhc'ÇŻ‚ ˘ËÖ;&†źH®”$ľrb.ĄeͱŹÍíďÉWŹĘ“Éé‡ëťŮĽˇ{ ™âŢ ˘ÜŹWźË‰C-ωßb0îçť°s‹÷QĽ;"¨4é‡ =)Ťdµë¬YĚAźµO •ŤĘc.˘Ĺ]-©ó”%r~h#˛âHäćTău2/;“ ĺn޵î!ÎwźFw["®± 3ěčË•â/q\-<×UĘ…ĐĘbr’ó‹«˝™ç&A\ŘŚ[Ą«ÉŁuA,Ľ%Őń »ňÚ—qJúNN˝ˇŘ$%|HR:†=ŐXŞ•! °ýZ Zx´“’ʎɫZ˘†m‹yÁű”µßµö&¦á]Űń©Qd.á űO˘b IĎ5˘nŹ&­ŇíŚo°˘a=˛E@Ýdó°aHčĹu1űSI-¶f?ŘÚćÖĄhĹ‹xŹćóĚxďoőë×|›­“y@mő^¶=č«9Ҷgň]űŘťe2©Ńđące úę0ËösąůŠjůŢ4,@†$NÓŮ °GĎŮ˙D‚Xš+Ěó(§Ú~XěKĽ%˘ŇŘIěHiiA|űčIR' ;Đ˝LÚAţÄ$goŔK xňɆK8 Mą/ÎiôdBĄ*·ă—öĚ~=¤ÄČUî+˛hěĘćă1ŽFÁU"żŚsjďÇ)E©dčd{ÖuĽËŁÔźET%áë|€Šě&qă°ÖÚS ŢČÚĆô8 ě«yĺÝöĹś ů”/źľť ře¬Ń6 ,÷r·ŤśÉ:»–jɇďÝ÷Młj’‡î¶]*A[ěŤ'Ó¤lÔN«gHŘÚQá¸Ë»’ý“YóżOu‚ô>@E°,ąĽPâÜ-yTf?ŮůŇ žRźÔ€żď$N!·!”Ďu:Ľ˘ŽQÜ`ďô—?ŮK­ŔÇÖÄR·˛şÔ˛’,ęůŁ—±jĹéLFüM‹¬E Rl€ M:›ŇA….M˙ÜŘ8ž×Yyö6„aN„ʍ±!Âqmcm'ĆÔ˙»w-µ_Řo”2Żşĺ›Ć{4ű±N™#Q6~·řz’ÇëÇë‹O–†đ1áěh~“»ëľÚ°o1î«Í{=¤Í#„ÝŰćŃýĽsŃĽÔ,«×¨•0+–]HĂ=廿-—´r†2â ZđĂüÍhSß ŔQ®ŐkÉ2´BuÓ˘Ą ĐRTö2GeP¤ŐŚ‹1ŃŠĽĽM^äéć î‰ý]łä.˛lđdŇÉę#Ę›žňt?Ä"0ÚvQŇŹ^şmŤ2`áKUÖüń€ÜśˇähN˛Ę Ŕo 0Ü&%%ŠŃwŹgÂÉaŕÔ,cY‘ş­Ľ@ĽçCô.ŮĂjÂwŔ0ŽźYO]ôď¨Ę޶\}"Ő+NŐqô˛ń' |„ ă‘2o©Ćźő¸ę*V­±¶¤örrl(” "eß -ĆlAĐůCăĄ4ů«čŁ)M`Hőă·ÜGSžđ=3»˙Ů8p÷lţ2i›Ľ[<9w@N'†ŐŘŠR“ö°č˙憫^·ţ=ÁC„39đuÖ5“}ü®\4Äüç0E˛#Ő×:ő‚ÂE @Ź€ź×íü1ä;SřŔU¤Ć‹šµÓ‡Î]śc°]őű^ŁpǸW}.![h @ů«ŮŘâ=‰ďŢ{ä$Řżcb/ú·SfW_łŢąţ Z v&4 sřúôäďđß˙¸‹Úďendstream endobj 472 0 obj 4134 endobj 479 0 obj <> stream xśĺZKoÇrä%a‘‹gŚL»ßŹ9D~D1 ÖׇŔÎ"EJą–-Ň2˙‡°«ú1]=Ół+a ĐAŁŢéîz_Őč§gbÇńOţűâćěŁ'BÝő본ľ»—g?ť‰üžßÚ=ÚÇ-,1ÁąÝíŻÎ8 Ţ*-ŇyV;vóšPŠůťő~ŮíoÎľ>53R;<'ÎlV™áäů«Q° ×Ă~ś“A;?|š-Ă“q’Ú3-ý ĆÉ0ďCPG­á^3ü“ö$^gEHW8νäŠÇdő_㤼kT–rąí ¸ŮX&•ľ%Ëß̧e)•1ł” 9÷K˛m__nö•›?l+ Ę0­'rŐ-˙Ůž˝X°ŇjôŠČnÔÖÁ†Ć2-€ż‡0?¦C´1ôI ĎĽŢMŇÁ"—»ý%ě˙ólôîÍřČa‰§·«qžŤ“`Öa‡[4$¬[=üśŚĂüQĄś®«W_ŚJÖ)†×ŁbĆ­a÷ĽHÎü n@Ëá—ÄĂ©á<ý¬ŕ¤â&ĹťîŇůŢ•íVůľţE—IŔ“Ꮰü]ąĎ[Śc"¸áŃĽ‹¨·éeuç«Y±ç§UďĂĽx[ŁY-·îá,p*žVS˝ĘJĄ™Ó¦¨»čzË\ĺ̵gu9áňDČ7 K®Ţw…ߊB”'‰Cś]Mň˙ăíňîTÉWÁżďVzבZBĄuďm%Z’’zWWoPÉP­HÍ«řTA2xhÎŹ¨m]EiŔ€|y“”Däż ˘Fqĺ×ňŔo+®“'=ÚŔ”˙ýP{‰ÚŻę#‰űCE‚×čEŘî,ńě’Ž3ď˘CĄóĚ5±Ń…ŠK‚)př SĹŔŰÍöçťpČńf÷1˛¬eVűá~TQć;<ř›‹U2ăYŇĚŁdE-z×_q•ś…ůe5ă"lN,@¶=Żv«®ľÂłpAL[Śi&”pm¬‘l}UmAÔ&R“ÇdlîzŠ/g_çTgWtن#„é<;ÁşZĹI±źU™„¸H]ž eŻi ®ÓĘq_÷˙mŢß­B§kŰÜ{·rQ ÔLöđ÷ŁVW÷'’ôáęă—¤ë!ôź˙…´‘#S«H˛kÍO'ă'DF©ďbž?(Ź›«±ßń. ż.ÎxĄk>üšë¬ľfjń´›Ü·4Ďe8¦LżWsÓőf„bˇNµľ®đý8ŻÚqs˘=D°™Ő®8kŃ ň íÉţʤ ,[Şâó&a%`íšúĽ*{^ĘxôÇ>,Ŕ¬Ä.ç6p¦ď&5@hőőě$¸ŕ/•Ě‚/şÜ¬Źd/Ź·…×Ĺľžčr¨‹Dě޲©ČM}€»««-)Á3đhX(gĄ-äÖŚ´qŇ—Ŕn$m¸z U@ÓéLge§(ÜELŇSoC.Ĺ@PM.Ć …Â(!©­]ş]ľš&Ş?‰<ŹŮŽ`äń:Ťŕ4Oéµç˝ĘX"_H‘mAÔv„‘SŚT˙ĘÖ*ßÎ5Kš ˝ŇVbÍRŔLvű/Îö~‡ł=śËFV b+ëĄě8…ŕŕ =”‚Ő`1.–{i3ôĄm#–/€ÜżL)]Íü dÖĚ7|5€ë@-‰ eZtŠŁZĺ÷n­•ŕ‘"7Z>ďULhoá&L†U Qŕ 1Ą"˙Ĺ‘€[é·$eË<$Üđž$Í,qř]78ű(N¤PmE˝O2™ĂUޡ0ŕr Ń>]·ĘoÉő{9ŢÖ:l&´¤˛”ClŞ5ELpźwɦ¬5-şeBy‹1•*z.`ĹîĘmŘuEąŤ›Iżĺ¦ô6¦ç©ľ4 9¶¤m¶ˇdV0p}wg±†Mslä… Î%ŠPáubٸĎ3Ścxl4|ëŹCn—łŔűC>ß4uí] j â5¶€Pź«U@"ąSˇ›€jĄ83mÇűß@ń<ůé¶É R‡cYTÁ‹§'lqŢKŘĺěůxňĄfÄt€L÷3 “ÉŐf>dIűň‘]w UbńšASU.» •·iQLč„ô$îëÓ h›˛’SÂ8Ttá\E¸Gx¦°ÚbŘ Ç4fčł kě.g0|ź\‘X~&oV,Ë›ŕŐ-TS‘'`{Üo›š|TM/iÜňwe [˘·Éß;/¬2~„ëďA¸úQ]%EyU6iDf4 Ň ę¶Y 9 H»ę弣ú)¦S>޶¶bľ¶&¨Ň@)úĄ§ ÉŽI^OňmćÝ“‚ćLjMőďz—'`śi’Ĺu‚í¨ĺş¸ĎĘGĺ Ą+} ‰b5ĐNĐ9Îu@ť^u\Ă⡦îk›(3ş˘H’©ő”İ™×łw°{smđ—[űeK›±Ë˛w† oĂMŔf_Ä˘ä Ąˇ;%ź›[ŰG’®źý {’g‘4;deí±‚úd…ďGކÖ+.Şrb’݇Փ„L?`p&ÜrĚIQBľ Cڤ7ôg( Î=Ľ1'9AE;xµč“eĺb˛Ţ!°ës1k 8Đô“‘T­ň¦bŽ™öő[ˇâ]kh‘ďÔifIQłyxľ?ťě‚WéłldÚH’AV?`$a ¨c‘‚Ä,č“íÓâŰ]fÉe´‡Š]źŕsýVçď‘{íFšŚŰ‹RcţŠ ~őĆůŐ\ůL'8©0?>c±E•ą–29\‡^iç?)đ Kž[bč[ë黟UÍWĐ?vŤ]ëďniÂĺ•Űf3PĎťßfIIFO˝ŮžPřܲOĘÎuy=¤hcô˛ţŹ‚ţěđĐTŘr:žWnh‡îąD_-Y o2ó&Ux¬#çŐä =ťąSn+<„ĆźćAQŰc—pokƧűłŻáĎďt:§Ăendstream endobj 480 0 obj 2374 endobj 487 0 obj <> stream xś˝\YoÇüČ_±Ń‹wsÜ÷‘7'pbNŕ( ‚  š¤D[)SRţűTőYÝÓ˝»¤dCÎöY]ÇWGĎ϶đ Ăé˙‹W'ź?ĺ\ožż9 ď7|óâäçžţ`©Őć÷gˇˇW gĚlΞť°Ĺ;#Źăeąß”w\ĘĹmŚ3đËćěŐÉż·Ř©E ĺÍö«Ý)[Ś÷FęíäůŰ_ĽäLmĎv§r^Y·ý2>Ć·Ow§BąE ·•»S˝8ç˝Ü.đ¨Ě«·"= Óîă–1g8™â+ňöëÝ©Z ­–i•}·o`fm!ůöäőßËhi•Rë˛JX÷ݤŰYmÜôË3˙qgˇPÖ ő˘”wd]µËÎţśNĹ/ŢŁđTx:Fe,thN ÍĂyoYyÄAN%ś–›Saa &6g—Đü_;ÎěbąÜŢVjż«Źw°¦ „żŘťňĹÍÍöĽ>Ţ@É.čďw‘&LnŻVť$ŚúvoźŕLZFJ•ź…Ţjű!2ň»‚K‹Ń vĎrQ93hIVD›Ĺ§'”*ÁgŐö»meă/vČ/xË—6Ůł8ŕ%]NQÉDE­Ç$`ŐŇl? ĂkĎňA Ž1Ű×u0ŇŤlő˘>ć)€jd ĎʸÇă˘Oyâî÷DW †ěů)Šż]@řŢÖ–0“°@!Łš±®«€a‰\§~V [ć¶dÝďp6·8ŽđâyÝîͰá¦;ĐđňŞ6˝ âcs~ł“‹6Ě4lB˙’Ƥő˛îń]ť«|$Ż´¶ŰďvpL°E·Â|yßŔó}#ĺ<ťŕŞaaĚŇn ‘ĽđłH~âIT;! `s-*›×u>Ăq<fťwUHČ’Čęßąř2mZHzVSI"ZLé"áŘŢőçľ§Ű]'aE$Č #Ů”X´ňYa±xŤÔ‡¦—MŻĚđő¬ ż VM©ľ¦ vz…łÂ`Jtş7RËĚŹ8­µ˛(Ń$ŻG:ónúNÝlOëľžVU)Ap8 &UZ Ü3¦V b÷ŤUeţ|´DBŁ*Px„¨ő㛳oNÎ~;7ŮRÉ…KµÇNrDtóxC­Y€`d€Ç*¤‘hÇĘ6DąÎš6Ë'€Ý¬îQŽÄ?:jǡ;Ô¦B*ęőţQ>VÖ,09’Vţq@îUVfF-˛hłëž©{\™ĄĆ•HÂÚ aCKMÖňxöÔćŽůgżÂsü¸Ůě5ĘaŁ–~t#ĚeoĐĆůÎŤŽücTçÚç<ŚĄáűzŻ°ŞžÖľÁR;ěŹ×`çŘG&s‹6ćçŰ˙â“ÁNEÁé_&Nő$®T‰Ź8%ţ9˘bTžÝEUČĺóśc‹jŢď@ Kiőä3xÝů?q>±Ü—u†óŞRš#iŐH6q uł" G®mo˘Ăs›g˛Üž3 żŻâGĐđK«2Ńä'%ŐCD†rb¤»k±Wĺ{×ńq’ě—KĚÓT‘\uđ×˝&ĺÜhB˛ĎˇR<0S\˝ŮŃgN>ŃzwM~`żzµ·Őú*Ť“KĚ.ÄA,A¶GÄb¬R1Ň&Ő©=ađó@=š˙A<Áä«)OI &Ýř,ĚFNb8mÔĎ*`~ÍŽ=ś62Ł\¤ó­ŞŠt•SQLűŻ*{Ş5ÂV¬™,ĺaüĄĽě" Ír¤*ędî­§Ú{_°§„`’őX…îiŃ@Śń 쉢Ç5F'‘ڱ¨ĺĽjň: 3×—÷)ţĂ Mš&¶Ěsyioíů˘¶~^· oÁ—ŃĺjÝá´k¨‡ôŻřâ2˙ľ´\ [çŻÍ„mŤYČžęôdĚş%ĚHeţË!פęo xŹ´´ÁÉśÚŠ–SsJśř‹ +‡ „ŢŁÎ=¬\Ńhßy5ť˝Ç±”ŘKw˘ĺ‚çÖh™‚˘:[J*ńč.~hś6?ÂÉŔä!”] .~‡µOT>[ ?KfČ^1ŽŐř´öz®ń1¬®í?¬TZęD%IF}…ŁŠ…Űy¶3ďęŘiśŐvÉŹ”¦¸śěJÓcďGŃ$iµ†áŁ<€^?ń¸„JÉ/`É…îM9ż0V _ 0_®ÔÔ8eŽŇţR!Ăk"݉óĂ^ZĚs„ŽŽµ ůČYýq6nEş=Ü›ęIÖÜë[=e_&4§Fb¬cڬÍ9Ą&‚Žčłsą™s„×ň,E÷7ĂYí†đćĹ„C÷qOb ™H?Ś˘0p±â(3dĄ F†ň&¦Ű­ ’ĹdüĆűÍ€)ˇ3Ią§ĘĹJŤşÚ݉!ˇ\ADŽ0y%@ëč•d@&lĎ˝NU ˝!ŠýőĐYí->‘ş+žĆňb`×îOÉ˙ßÇć)}ÔC =ČÜ_+HÉ”›F!Ň7p[§«j—ŇT¬ÄA Nş2ű1şH0ňŽťłŤˇg®š¨ŕ* Ý!đĽ.!ç§D´łî5«vrž›„îŹČĚä`öÁh÷‡Ă ŮŇG†Ăă¶Z-?Ć UŁ“}—o ˛˛¶ľbv%uŽ05yŞ\“9Ź%y ¸ź„tä.W"ő€Ôa˛˝¬·^i˛­Wšj)Ď«A:˘‚×9ňĘ›=*?3ŰYuY^Ö5™¬„ŇáWľ·2éЦâR›z'RĚúŘŚZ41€WĽĎ˘8Í­Q˙!šîP0 ýsÜ+D–ôÔx{Z+Ěł'°‚$đś:(¤í8FĐÖy¦y“AŠŰ*é|(Pä1GyŰš“tˆޫĆÁHq2x=ť!f"š¨lť j…äYĚ,Ź=rĆdúĚĺ|ô%†Ô´ŚErťÄMŃ…€2ySi˛÷<Č"[÷űIÄ–­Ş˛FźĄ”űř°ż­%FçV6)í—T’řáryc{˝,UÖ5Ç©W©V[ \žű:î‡î± :é‡E[ŻqR/Hć$ÇE‚Ç×ŐţXMáEfŇ ·Í"˙ ÍYő€ÄM N¦Ô˘â^ŹŁĄ˙Ż™aţMĄmBčhőЬɱôŞ&mĄ\x+LäŘC„mš€CL6öчňY;şł‹c,(ĂTĚę†ĐŽpVőĹIňdĽŤű”p~Ćř{ŤűóZjŃ1Śëu ÂĂ4ű Gy˘LeĚł®ˇ1¦Á}Ó@¬ÜmÎxÎ*1šŠďhäá LJ‡ÝčI¨Ľ/ŚLÄhéŘKjŠz3ÍŞŃ#.ˇ™R˘ÇÁéa Ú -öä“lŔ~Łxo[˝uLŢ5&×çP9%̇{%áÝŚ¸ŠM1kšu^j‘Tśz ŐŘ„őrŢÇ­iĘęŕXkô}µzˇşŐ·Š~ }knöyCÇ‘]Ě1GbV0~]da? #E@¶đbaĚOŁ;ń¤5°kµúĄîHJ b2OQĚíJ`ŰËÚv<î 2¨ČÉ´4ÇËŹŠrÁ6NÝŞ„Ć\BÔ y\…Sś?Ă·q„˘u±bÔvÖ¶‰fäíp ť».ŵˇŘóÎŚ™©úŻrúĘŁź]X,—´Ć{źC|™ÖL˛i«‚­PMdű¤8‹m¨Çąŕ˝ \×j-'X'‚­îhâţ°“ÖVĂ6´KU•wő[U‡űV޶=čo^5”«|“FN¬Zaaܰru}8ű_RŐ•ônx ;‘粗CÚĽđR”üĺC&î§Ú«‹¶7e5ö[Gâ‘Đ“‹7Ą>QT06µ«CŐ#§ąHHcu¨aÇőŚMń,ąnĐf°»zF dÚß5ŐçO…qôb8XhŔCXđRďxÉ&‚_ÇG"9ůĺŹĺ%lJsŔ) űĺßߤ·>°r~{_/âŁń‰âŰËúxU—Úö˘ľm»)¬“yÚN!䤙¬á¦ŽKf{Űîb˝†7öueĂë÷H^°ÂnSöŢĄĎ*az1ʏjÖ8ár?&…Ž1Úy‚qŔ© ^dV>Tˇ×łgJ"Sö Mą;¨Ô—¶‘…Üé3•µůnq µ>AÉš®éĽ#ĄÝY·ęĚ®\ ‚ao'ÔŮÚücN´GFĚm[m–bÍw6–ÂĚÁAÖkłkL,nżŕÖ©¬€»çkľţčK¬ˇ\ŮľbŮĎ´dĚ·ć4ßaÇŘÇ c.qÂ+‚Ď3sµWhÉL[şTö őőQRlÝb`ŮS)ĹeöÁĹeŻr29F?ß÷¬¸â˙­u#? ­óř:ŃűÎ|ŹÂÂěH×÷»›'©Ľę¨ ^a~ ź›śGÜ÷( ß”W•2đrr.­…(k÷hp X `W6¨­]&AŔ9axđă Ö[Ş×_•8t†O˘ÝP®Íťď  áÍÍç6]x9\đ˝ţęÄ-é3ŇĆęԼ^7Oиk˙®q&’čE›¸-!%°äŰÂbĄznOU"Ť\î&!‘—#4wďHô!R^őµ)€4Îőźb€đGöAŞ,kÜą+™ Ý^[BEd­ęŞéňw%©JóË_P’j&¦ŕ,ô†PF p–ŔÂ9r+q0ť&X X<0·;őŚ›ŰłťE Ă1.މj‡Ő•çµŰE}HĎ —ĆŚCnđ#ž’AŁ}šz0Ź`(Ú˙đĄ•̤ đ÷!ŕÇŰłÜűĽtňĺ˛9§ŕ]Ĺ|Ápý ˘VĺÖ¸r¨4€˝c%˛đ  iäţşkÉ}k÷*vا`8wko-*p’L˙í–ßMز™G$\jwhÁ;•lÖ˙F±ÂŞĂ»^+č–oxaů¬UŹLżö˘¶¦ĚąěËôľ2ý·»°®±Óő,FÇr·O€®^zŃ änď ó+÷K1żxç;"kŔůˇ˙0ăçZýd€)«uľFç«X”)eÖQřŃ ~üF…pî¶&hz,ˇŻ"zÁűäÄ0Ě*FÝďč78ĺr´Ä‰kůÇě↉€?23aAöŕ†VÔKg:0]€Möi&Ž9ŻÓţšŹ_ßo¬9t}c±­Ž-Ü@Żţä 6ýuóű ^ŰĹô=•ÇÖ$'/ŘŤŐ4a†»!†^‹sĘ&‡čWľŢ‰ŠÚŞ11ĆAßQ:óÍľüfp˛RZ+JI÷ă+;R•d§CÁ íźUŐd¶jwë™hż÷ŢFţ6]ř€ÂţŹŇ„˝ŽÄ˘©„ˇđp_ą Xë,Uş~yvň7ř÷ ëP´endstream endobj 488 0 obj 4703 endobj 496 0 obj <> stream xśĺ[KŹ·|Ü_1đE3A¦Ő|“ą%;0GŢ ěF»+­ Ç®VÚHú÷©âłČ&ç!ŻŕC fŮl˛X¬çWŐoWóÄV3ţ‹˙_Ľ>{ü„1µzţîĚŹŻŘęĺŮŰ3˙ă¬ŐźÎýD C›g˝:v6OÎj!YXOKĂÜ*Ź1!&»ŇVĂ“Őůëłź×ŢČIqéôú»Ívž´sZ¨őÉď7lr‚Ír}ľŮЉ;iěú›đSĎlýdłĺŇN’۵ŘlŐd­sb=ÁO)a_µţ Yě‰ßN3¶0ól5#[|GFżßlĺs•T¶Żý;+=qÁÖ˙$Ă?ĺŐ"•B©L%Đ@ÖýyíĽL®ŢK;»1đphj’ŇYBWyĺ?獷â&§ą–x+,^ŁÔ^¨n 0ÍÁ}ŻYţáŠ.˛p}†Ż¶ÜŔŕĚWç—đţ÷1)ĺ¤\żÉ—ÇއĂÎb}·Ů˛IkĹôú>OĽ(eć‹ ŚVŠłőMąŃ7ŔAa'§äú6ż·ŃXIf~•ż*+]…ť´°]q6¤şŐůgçżű™ŠÚuYö©1“Pš–L˝Ů0;1řńH_z‰+8m^ŠĽu…%' Ź›FďË ˝F&9:±~&X“Ž&śg2‡ŁĚ6ń?CŃSpß<î*fĂčYȢ…KžXé&a4Ý`W&\”Ńk<Ůpq]żĹ›L‚g‘žµˇÜ=¸Ď3ɢ}bo 3ŢÄ]…IdE¤e‘ť’OJ:ř‰‚bŤ[Ü ě V뢫ĐB S/7(@ČQś9čX>9igŃWś8{ËݤĽ”ýFŠC–ÚŃ iŐçµ("ďĚ^u.ymăVąÓ´M'UŁv˙ŞĐw—OEnńU0Ş^dĹ–]ů‰z2–Ń–nşşv[–%2E$­Č÷óň‘Ô ®&>PĆßFSş»’nݎúMu>.fczT2X6B÷§ Ř5ˇXRĄ J{-nş{­Ču‘3’ë$o˝GƛɚJ x’Č„—ńčđÚŇ$6§Ľ/"E.˘fů’ąDxÜţňcom€eÄ;=ÉAQBň š8á¬]˙—»pośp˛Ö‘ÄľçÔłp>+Řś"„!‹=­Öý=kµń¬s#A`Vř,khäxYŽt@źvřôĽl™~b ?Ĺ –üď$»mW@Ż‚‡vŔ+íp_1sŻa—yę‹®ĽŞô˛ż”ŐhM{Âą”Ë®?Ĺ Â\‘HâuŹD˛^śŮ`Ą>ĺ©7µôÇÓéßUÇާ™IzśË˛ÂeÍ&'«Ř‰v– Ş{†ű*pô’ę8‘­wÁ{;3I›Ľ÷BŢ<' ŃÁű®Yč}Ük ~qR *„5AÇăHČ–3°S«-‹ÁôS“­q“¶3­\´%¸ßAuŮuíç+ŚSÁí…!ŁdîÓĘ„×â,!o ŃĄdŔ‰*Ą* qYŽßW¤AŔYXŕËĘŚˇ±Ś.@–]ÄŇxQäd)p—1)B¶úł„dîë YÉ"‰q"ľ-Łe™*Y¸CGE&ůyGWzŐ á}&‡´ä(;' ÇÄśőÚš‰1QŮž®ă»$V'|ú€+ńiVęa»p;8OĚRš‹#č_îmˇäşşŠô„1ö;J_ey…QÓ JVNżëZ2:űehs˛_ßú\ł§*ɲQÔłwL%řŞeÚééŻóZaŮ„U}HaŞ› ök†´†Á h[<5źy×s#-Çţ¦Žđ—ţ&…c}kQt_ŮÉ MwီŤbŢńËşŔmC`ŽŰ”ĺś2¸ š‰,®Y" ü˛Ác‹‰qIöş+ÄmOD~6–ä9Ů«öË 6»Ź*…}ŇĎÝž7ę-~Élh†Nˇ d·˛żßí˙Źńť».gűX"VđľpQ=îKm!śŮ˝Ä"D( J˛ŰwŰuÚJŽ•ć˛gKú¤Ň\×[X ŃZ–LlĹXIlkĹĽ14ď¢lđ40ěŞ\"Á«śOqZ•«p‹¤]8ČC<ÜYN­Ú—QłÓ€Ě2„ŮěXŕ‘ŕ{€ť8ˇh)Ů몤Z]`Ą/K‡n“<ż¨… Ň ĄÍ2˛ô‚WDěžš{Hc4Dö×B”cäÇĚđ‡Ě­‘Žp4ݬ rI´n»rs…CýĐ™ŚVUQ1H:Va¬!;TôÖ2°Ëâř¨ş‡Ři+ąôůŘż×<oŁ ”&%\ŮQÝÍŮáË”żĘALU# ŰxÔśč]UB\"í6Ą›1ŁŰ Á|LÚ‡,.ă^‰PĎ«˝Ç™zâŔ¸Ű®Ćő“ć*¨Ů TriŹ„'&Ç0âŇ\ŐŃąŽetCdßçfWYI —ó\g]q˝CÂLRęA¤×ÂÖ>&Gč‰rę Ĺ!‹’ ŹŁf@x’Ë Ý• !$zÄ1Ý–@µŞ*9bZ‚˛Ř‹Q’ŕ†k1k˝ď F_r®¶#˘‰'–.iJTî¬&6[Č“˘ŹćSËiUä}ŤžîąÄ…äÜűŤű˛líŁ0Za–Hî([Đ=Áô ńmo*Ůţ4(ä8j‰F4ĐČăQĄ źťőҢÔŃNâ?׋Ľ¨Í,Gö$%IżÇMq14ĺ$IG O:2Ě‘Ěq{>(µ­ˇCśęXă˝s^¤y”óŔ}IÜ\?Ďš€µvĚ­Ť3áuU/ ¬);Bę-®OÉińýOzká4ö^2Ö_µ™!—d¬2Ë 0A|‚ń‰×(2Y‚Zë.îv™¸T…REčşń1ű`ů„ć EŃ Úě»śĆ T·sHëö|Ë"wô¸đű¬J{řëj3ŠôFťCU…+ž4«(q FL6dz©¸ÚIHC|Ó˘sŁuc ´0Ą‹¸2H$ž)3ś‰ěvó’‡$¨Ů@ »ŕíă…”‹PŞHŰ~ěMÝíxý:ŐăŠěÎa.*“¨p4ąM˛cćî+ÔÉOnlÎůĎľŻżHGn v@Čjł'Wwˇ]7~řhľ„B[ŔŁ,–}ŐL’›GYŚĚđܲŃ{,ŕYA |ëlcŰX'‚#3ꆬŘĂúR›é磄@Wđn·kč¶+LѸjç›BůąU#†ý¬¦ßHQ„P˛¬WăM}ę˝_;4_ďß´›«#1ÔŽĘŚ—p†9/ÝĂł‚nď÷ ü´Ş"D`ĆÁRG‘cÜ@™:EŃt ‹‰ńÔť‚bÄ‘ű漊zĽp„úE¨)ňhüŇEĹú\¸«ť)uWŔĘŕľZŁźzKĚJĚĄĆŮ48Ŕ—.5–Ŕä.ÚK ţbĎ%%OÝďU)¶ń&”ů»q Yµ„0ČĎ. Y ÇŃÁ«¶¨~®IŚŔ‹ž˝Řîěš3„^üŔ‚ö˝t×tŐ q×!të&ON¬)9v{3ę\7>„¬tĽčeC±/;ŇńPmšĘqT9ßÄŁ‚|p2XĺCŠĺ(±U[í CY ldĽÖđ?±v¤;¦8—›“:*zŻK?ó ?ÍżĆLZ5ú°ěiş˘^gË-$ęŔ#jőjKËb´Ú­4¤ĆĆ?˛íŰźküŢ«Rgű< Ň[H$Q,_wů¤JŮW¤ÜšYPuEx‰ct*¨ÄLTb¤\I61‡‡ŮíGWS/M, ń„×Ý2ç&Jř¬52ýtu:ÄH™ŕŽ÷µüGT§ăµť!öipgëjqbą,Đ5NŰ;šŚöľ&a2_ͱĆ.t©± |ˡ}72l&´…p•áyłur#0Ő?»AP=ľĎ•ĺÚßkšzëź[°Ä6×t´Éá1yéb¨€Ł\§EűýjŰnĐ›háˇěn"C^t7GnÝşŹŇ‘h!µçIÓ‰%ŹkDyÄ^ć¶Ó2jmĘuFŘÓů¦ć]iô»Č¸nŃŃ‹®j$žp9č~,V®oŻj)ó(KݙРŘ˙č$%¶/śŰžíęŁý˛g cŞ:—·háďÜtłďŕmŻőľfÚöA&Éň‡–VęđBoI)j˙†×TUůăj?NDq‰Wĺ l-R]Á 0˘kł+ÍŕHűşÍb®QôŠhKăT}ó]%"¤ÁyčÜâĂo…⪵˛%¬ŕĐŞźßvŐ‚Uƶăm€Â&,˛ăü¤Şž ZůîćUóP€ş$&‰ ÖµČ"h™i˙—G$ˇÖföPŢxČű4‚DŇô3…ÄŤ-ć…ČŹńwaV©¦Ń} ÔĆşÜ(Ą4Źľ?8dˇsĂXUÝ$µ˝aęµhi«đ#ŞÔijímŕč8·_j=DĚi®-ÖŔµĄbŠĘťé:î{žć Ú1–Lčë|»äŃŇĘ?ÔTŹÝúU2!ő·I·(Ţ&NTŰpâ÷ŚĂ@5}ë+Č×>řĂĎÝ襑z–ýĆĄ÷Ŕ˙ë° Ţż–^ÜPą•ô ë8…D ot¬ęÖ˙«Ŕ%— +¤ĺ菰˘:K<94č4-áučńá/"rL?m{qI~ŘźÚ_ä/Ă-\ýĎŹ0N-i#×Ćţ›ółŔż˙Ż'vendstream endobj 497 0 obj 3748 endobj 507 0 obj <> stream xśŐZÉn]Dzä*ů·Ó}†_«çÁ@$ĺNśČ4$Ę‚")ŠIŃ’›úŽ|pŞz¬ľ·/éĐ‹€ ]ő멺NUťŞî6ś‰ ÇżüďńĺÁÓçBÍŮűŘľ›7?üž{mţp;Zhb‚s»9|uŔYđVi‘ćłÚ‰°©mB)ć7Ö[řesxyđĎéŹ[ÍŚÔÁN_nwśŮ¬2ÓďÉ÷_¶‚%¸ž·;ĹdĐÎOź§OËĹô|»“Ú3-ý¤¶;ĂĽAM >µ†uÍô™ěy\Ί–pś{+Č_’ÖŻ¶;Í ŻQy—óaßŔĘĆ2©Äô=iţ®Î–w©Ś©»„=y˙L†¶Îݸ˛ňł­apʰeÖÁ“}µ!˙:ü:k%°`ĄŐ¨‘Ő¨­ťҡĐ÷$ë'N˛S -'7;é`".7‡'Đť(áu;îSO2cÍtÓZŻŰçÓ-€Ŕ#Ĺt’Z˝›Ţn…g"7ýHttsIÉÜtŢĆ\µ™NÚ'épĽÝ f­‚ÖŁôi•ź>´o›ď`MpGörÚF]‘ ÖAdŞÓ¶Ö{Ü«aŠ—Š;Q&ÍĎE˛Ôyëů®aĚJ„!łž…ÁÓRš9ĺöî€LK&¸©]ŻöI[¶6Gj[DËxĘ÷[PáÖˇ™J´ç*"GîŔńěAšµ V.‡ÇËâďm™ z`xÇŤţŤ_V [3đ‰‚Ptđ;`̬â'3Ý,·˘=‘čşIĽÔ(˘‹¨ńWŐSô!¤śbÚ«u…:ćA°sÔVjŕ=ëvwzFâ”Ç[đäĘ»0ÝÖÉÖ/:TŮVńô×Ě1î'JN/3Â,Ó.”ĺý[pöĶę¨0˝şłŠÂÂv.±5€ďv~2śźI˛;®ĄÄľŇxće§×…ěqŘťÂă°¤E¸ź^lÓ·Ő0ŚqŮ0’Ŕ;!ŕPąHr?Ű ›2–ž¦6,Ľhó§ö3Au_kę¨/»Ä®ź˘ĺ 悤ř}UGe{ÝĂÎhA‚őmEĆESÖýlµ E ĆýŔVU Nzłđ‚NS„ ©YÁ´ĐŹiŔ'ۨ.çµ¶  l‹×ĆźÚtmlˇąčÂñ¬Xs2É4qĂqqeS¤Í”ŁóËčwş…0¬•ÔY¸LŹÜ¤łOýĘ;W‡‡®„¤Ťd.ňIĽÁ˶¬Đ! Šż™µ7(S™ű¨Ř¸4Ó!” LAÂůťńa}Ü*v ,Ô-ě׺U Ţ9¶ĐjÁ˛ťë´y>´¦‹Ü9čǵÁxvqŕź`rúŘúŽ}ń–ŕę¬p@ŁĄĆŻđŐőĄ¬zŚŕ“¬% ŐÍćŇ».ÎůźKźÎ[ܸjaá¬)–„›Č‡Ą˝•^u¦Ż¬fJ¬[\oĆ•Ëg«AP½Di&‘XjC=Ţl…ÄBşG±DžŁDź Žp•ˇ(ÎŚťÂř‰e‰oŢĹýaľB:™„ ŇJ(ň˝ěIđúŕÝ_.¶$|ŹE‹÷Ňaަg¸ŹáŰHÂÁzĽĹě¨K^ú| 7>Ůn­—>Š€V€ĹŹ[` -gÁ3rŁ9ÉĽ›T&Ôq|Ľ©ŽŁś*2+Ő7­b¤şÄ#B­^‹$IUa˙\ÉF’Ô=ÇzÜ$#ĆKűĐ$#B«ó*•M8t‚ÂlO‡o¦Ő3ć–; Ę,𽋡ůĽpyÎ9ťŤHDO_ź>Ňl8.m%–#d›Ăo?‰ő8o§l´XKYK´fř „•Ów ,z‹™ř/ŕX&Ę]ş^Çß˝ł‰|p3ým+$şŕ˘¬h%ež“ú…ęÓŢhôľ :Đm;¬Ą Ë!”ý?«Xńß“{őZLÂŁPŠëZµÂŚöłâG÷T˘‚Mšľd1~ÎW#Vä*1hžUaŔ?ŕ !‹jCďą×!^Ť @đGBq$÷pr$ŽxŻ&?a5ojc«+(ÎP x„ÜČ=®ęA9ø‘¤®7f“×ý(ď> HĽżśEˇśOá‰uŤÓ}˘ýfŇHZl_Öa’”ŕľĹý‹2>KG  4©FŃVCÄz ŢÍ%J* ëlWkĹ5b äsX,rqµÂŘ®:üIpAŔßć¬1# ę(ˇ€m+ű#"vkAű‰Uß/.`âĚ+b•;Ýy€,e¶l#Ąë¸Ô0NÎ'ůR˝Ú qôÄ^ú ]’Í.˘·«€ŮĆٰuYI\1ŃĘ–=yN.Ç5GWň W«±BĹŔ­ĆŠvbL×aćŠÉG9‚ćáoć®pFjć‘>jvwżčC}Šď\¸!’ç|eBv;ČšlęšU•»÷$g‘—ţg’3đ¦TĉCj';÷C d}â]x|;ńEŃz@#“X¤đń÷q㏠)$ĎŢéĺü÷Y-•LuÖÂÁ AW‰Č˝Ć‹|ÄŽ倇(ÚŞ¶ąř™”¨ĹJyR-ˇE%šę‡•â?©ňô®u¦žY­sV@@‚Öčű&łQ¨ęż†~‚˙ňřfţ­3•ťçn€©őáşŔ’ꦜ`&ŘÉŐňë1‚ߌꏽˇkŹe*KoĐ×Ę °»"¬_4Ą-jbD‹˝»O]gő|ŸAě+Î Ś8Ő/‰%ăvťlÄŮWk‘Łë@ZŚ…śh6> čî€ńňŤÚ<ě#Wĺ{Ľ3©ŕeÔ‘ ®Â¸¬A2·F˘‡MOôĺ›q¨–.‰ďLň}ŽŃŻ+ę~ÖT˛Đh]˛†ĎAHTo®ç2Ý´; ŃÍ[Ť‰kľ5Ś–ááAâčÄŠ14×NÜţË€X­ZżnčëFčşbÚ>»}„ꉩ€^ŹÖ/;ő4rIňŰŐí “±i2Ü•7d^+W95•ę÷‡±Z˘–+UĐ;Ě<†âÖKÜ·'C¸O‰Oˇs8«PâŮŘ5#>ÉĽ6Ę\Ă żXż‹ődöFŕŰâJo™x1ě|ăZI»z^:Şţ2Gx'öżoyŇ ýźfOjnŠjÓi~ŻJU´efő;ďp‡%q¤ąžo€® H^±´^3q3:=iXžÁ‹­ó“ÎGtĄYi}WÝ笂ßŔڬ˝úú·+xв|‚]žµĆëÚřľ5ž×ĆËÖř;Ś×pŞh×ăöů6}ÚŕʬŘzÚ>Ůbö}ÝZyZ"€ŃţZĄbH÷Ż»ť­ö®µ~îLµľż©­±’X"NŞ$ţ_–ř…KŻÖ˘žľë gŕ#BîŰţI`ńÄśjaŘßá±rÂKxŔŃ0Îĺľ]šÝń„2Ő>&Ł%"ă‡~-z”{/sÇCÂĽţĂąx‰ ˙×ű€áăĹá›™e=·w›ť0ď13˝-Á'ÜĂ7—¤­ŇŐűřč¨ÜNed«{ßfÍŇ3\ˇçyuÝîĘŢw-ĂŐj7gł]Ť‚ÔaQ8h~PĺiŐ Ę92ŮJą÷"ą¨w×ő˘-TŘßńŘ1oý—#¬ń±1Í3—Ź Iiký‰b~ô5¤űë2źu„ öČeăG8Ç릴ű*B¬zŽUrrâUô¸B7;L©ńŢĘúÍŢÔŃńŮN θF2‘ş€…śÄ \|{źß0Îî˘7pÓđ‰CżĐL"´)%Ú·Póő‹šěěz­!5kČ—ĺ:;VŤ<Ž«Ő/ľ®{8EžÝÚ`ŤßĘř8Ť×j_@÷)Öč Ö™Čs-’q4˝ŽŻŢ:+\$©ăâŕIîţżĘ!ß'ÖŞHIÖ5f]NŢĚ€¬ÚŇ ’ř9ĚţŇHáÜř\9vşĐm^Ýéţuq*±`ů·Ä¬“ˇ Ř·wśD)“¦ő×^ŘTŚąĹ-$­Zbžş|őÚ?ă Ś_e΋óńÉ[®ËD±÷Ü<–ÜGë‡ŐÔËď$%=˝sµňĆź@ @ĐŇ”<.Ät·Ţ$ĹúüđŕŻđ÷_űw? endstream endobj 508 0 obj 3210 endobj 515 0 obj <> stream xśÍZ[o·ň¨_qŕ>xOáĂň~IЇĆM-z‰€<EˇHG–Đ#ÉŃ%®˙}g¸ärxYÉrŚ˘Đi.—śË73ßpĎĎÎĆă_ú÷ôęčw˙ÂlŢŢĹůŤŘüűčç#‘ţĂÓŞÍ×ǸPšŤäĚZi7ÇçG"˝ ”b~c<<ń›ă«Ł§×[ÁĽ±^NŰť`Fq!§“-gFďĹô®ĚŢĂŇ`-Śö[ɬ”ÚM·Űť4’ˇ&˝ĽôĎă?e4sŢ VYĎařçŁăßţ8}żÝqć´°ÖO§x† ŇI܇JŠéá:Ŕówdí=.ŕZM\“oA"m@jŔ^F*ťpëŐt6‹¬˝ĺÁĆ禛¸V)YmöEµqŢíě–vbUž´q˛Š°›f”VG«hfłI@rĂĽAˇĆyx·UĚXněĎáEcŔ6W ¸Ň‡ęäĄ7e¸G±¬UqXë@‹r ÖŢăIÄ@ž=ŮJ0’ ~úek™°JXÜU*đr„X„—Ë® Oµ ý´ v1Ś+§Ç;OËë`Vͤ Ü'µw"›Nş/“Ä,ł$˘$Â@ú”›eíI1K‘úmyëˇUW’ç(¶đL;CdŮWb#ř„ÖD-ňśmw = Öw#ś{+|žIÎŐôžĚ`7Ź4śIăă3[â`еsţ—nü1—ęµ@*ŕ'oíËŇÓ! Ö7Ć $˝śOŞ\—1p9ň"…ĐŚ6esđFč—˘–çČ>DN’´sU˛‰íŞ~4•€ř‚DCCň<Ä @ ”~˝ŐĚ€zaú’§ÓT*±ë-¤ H˘®Ş%sÄ`P.GBŽF â‚WHYÁÝH ołmÜ)ÁŚ;5˝ŚŞynspKHE$ĂWZ,ŃQŇbWăóD ´Č0ŤŃs_bę˛*=Í 0śŁ,˛Ŕy#EĂ´éXË`[ţ„%2LGŹ´sšÎű9"2gÚo!—+ďÂôJÄhEÔ€ˇá[Âh¦š`uJ5đČX:ČáĆĐlK$(ţW%YčBśîˇĽ‘4]eß49”M(!aÁjŃłÜP Â"Ĺ8Q }hŕĽf+©Ŕ§E»C)tL)şŻ9Äu-şK˛ŠŹ ß]#ŃŹÇlqgéľ„fJ[‰"î„• *ĆNYčQRŤGy§l|PĐşIlw!8°žśľÁm…ŐÖb€+¦±Śüî *DŠŠŚÄ }N"Ů;k;ĹíÜu™Ř…ĽĆîQ»KH>żě^F'ĺńő˛gŮým& ·c›Ňpľ™Á#ŹPÂ1 Vű0l J^nµŠŤŃíň6qŽnŞrZŠpWŐR‰PqmzŰ4ăy „)ťŇśA4Ä_IÖ64 šj&ťKËűă®%tĽ&\”*Ŕת)ŚJa;⦙Yé!öé‚×ë/‹đHĄ¨sÍ “­ E,“`EąÄď5z„µaE˘Kß8ŚÉŰl⤨+“äB$N‡é€Đ· [ %jŐý¨.ÎĹpÖ»®‡OĹé  ’Ýô·ĹoŠÍ_ăs ä8P:Y¤kŚńqŹ–¤~Čđ°d›'Üßó9BŞÓ»2żŇł ®9,đaĚž¬ÉçôžäýwŁýĂ´_ÇJD¨Ńă”č}żłJ×ÎŔ1k}iUúÚB©”Ię™ó-p.śN#Ľ6$äă1Öȇ’@Ç‚mÎ]§–„$ęxYfÉÚě1r˙‘ş`¶3Ů#viîŞH(NśCÍA›]š¶ń…Ăéż”zźé4”Î1Ă${ĺű'Ź3_Ĺanődx”ĺ“fŇŻ]°­%\ę |E÷ y¶ľĂ;Ë7-+€j.e°łň^bľ^:Żż’+¸o—řv6'WKÄĺ~&n+Vöú#î bă‰HÓÇŞä ËÚ†Ż?ÁmŔŞ‘ŕĄŐP ¬Řť¶>ł;§4’»ńl€4ťEĽ1`>^(ĽÝN—FLú]áZ!¤ĘM™ww O0-ŔCGř…ëÁą)‘X_'ćDC„řČégľűJĚ?@ĂF^‡^âůyňa™<”É“eň~ŮŞĆüŁĚ[¸Ä˛•gÉ‚«ňÚU·-ŻËđlY‹.5u¦ź¬¬»[„ş¬"Ňźţ Ź&ĄBSU ‘„ćcî#ă‚x:‡ć”“{SÖÉYź»LîËä)5źž!í~Qž“Ą/ŠPݞ*¶ í°ďLç‰ÁýřsÉNáeX8ë•*¸vľé´SF›·BZµ›ŔţI\=é"P[Ťňđ%­ŚëĽ¤ž#h:tðď+iŁKL˘Áóě»NܡÖ'ľ¦ě¦s ľvŢĹÉieíí0<î»…ŕ4H0¬6ÓŻŔhl á&Ąeçę7ŻÝçYźŃYNŠGł6Í’ÓÎÖĚ2TşĎs;ťŇCäŢxő‘.éY/Ş€ÄxâH¸—ço–çŻËó»Î†~qRŤ?bm’ ’-€júˇĄqâˇÚ!cęˇxč'n&&Λ‘ĐIőÄqʤĽCJKc\“#&yU„콓͇2h•.Ź8č g‰n×­šqÁÝ#đQŔ›ĘGRŰ.ĘűËøK{Ś*Ä˙:öí¤[:6uâžh«‘g 9¶zúC™=j‡ŰĎuŔÄxµź´iíeeÔśó>2ČôĐěö*ń%éÝÇC„rDąÁ}2*ŞwJ#)) îqS'ĐL¬Ą…ZWöđ© ¦|LÖÉ•˛óĚô‡/ű ±âóTĚŮźš‚ă˛[»ŻëÎ"pč5ľ®˝ďlžI:Ő·çF›ŞG˘ŚÄÓíŚ9ˇIVăň˝Ä±x2ÁÎwfqvFeÚżľX{ßi×Ă,µOŻL“ü˛‚Č4YrÍřtâřÉ#ő+ńç)6@oşÜŇâý@už'çď}V»ĺS©4ͧäů‡ nüÝ뤻źĐšţşŁůĄ ~c“’\‹ś§_ÝXzÉFISÝŽŹľö^`oîĘÝçüţ"<ţ¸¬ÜÝŞ`żżţĄ;Ý<ă Í5`ş¬Yż“¨?܆;ő}ú™…CW~Ů|°khÂNJ ťiéßľ*PýMI“é2[ť¦‡ÍţľĐ‡q2#<~Ü­ÜvŻ5 Šđë/«púôn˙E=[‘˘†ř"ߨýhŽÚJuyrłGkYcCR‰ţ5¬pĎÔ8Ż˝Ű‚ćýó˘ö‡ü˙qĹ:×Jĺ”ěýĐz¤.’"pQđN.ÇHß&ĘŤurĎůkLôý˛ô‡rŽ(Ďű]’0ľ& Ńöű˛öĽłacú‰?—é/ĄVKž˛±Â+ő9©%Ź©% â«ßýţţ ś”’endstream endobj 516 0 obj 2879 endobj 523 0 obj <> stream xś˝[Ys·®Ę#ĹV’Ůw28HJ¶b;vĄâDfĘQ¨]^%^Z’~GňÓŤ¦Ç’-«ř 4ĐŤ>?`ß-†^,ü‹˙®/öţřJł8ąŮ ý ±x»÷nOÄ˙ qÔâë0ĐBW/†Á.Ž÷†Ţ;«´čY= żű„R˝[XgáËâŕbďßÝËĄîŤÔŢv]®†Ţzo•éľbí,Eď•tw°\©^z=şî›©iŃ˝Z®¤v˝–®ÓË•éťó^u=4µ†uM÷ÓL`ZĚ “RëűĺJ÷Đ2Ş^IĂż˙w5ł˘űV5Ş·:n6vó!‰C”c ˙¸cđ·óÚlÁďŘ€±vą{ăWî.µ˙sđC<$ß{+­ĆCńTµPv *ČĐĂńGqbs""­ăDVjî+9Bß Žr]đZv7SÓÉîŚ:/ )D?Ýý–zš‡ţ<µ¬;AßŐÔĽ¦±Wٲřńě^@ŻTýŞ!iŁk‰[b &íE €Éżíüá °ůńyl2bćŮl~_QóŠĆ^Sď5/×Q÷nÜĹkÍcÜ.^+Ó­î…đôVTŢMzÍ|Ď)y™ł%¸6kŚ(%ĄM?Şîś:Żhčár%zkŤ°Ýfęuăv.5Y z×ŐaŃjaŔmµőśnEŕ©ú˝V˛<”ŕ!Ą‰'Ó®uD“˛'Q®3×Ć@¨đuŃ—Ľo**cí”dʶÍ(×Y.ôš.ŰřŤÝm1­>krqÓ\m[-Q¨Y{gWŐ±ń^öppčÖ ĺ+,覩|łOpśc¦|LuŽ©÷.älŁöł ź“!7–¤4oš<‡źuµ˙¦z@çIĹ^îUO(R˛ů·%UÍD”%Ťy÷ڊѧ&Ö$Gs¦ş I倥ŘJ*ß #~ťôÓNĚý™ÜáW•WĘ˝řŃÜą­ÝeJQűˇ‡ĐťĂÖb´Zsy"ůɉn ?yN’Ŕ*Ä}†l7d?†g»l“OÉv?GŠËŕ–OMqĄ3EŠkedXŃi(D‰UŞÔbµřv±ąqé&+$;Nh+Zלđ ë˘!ŔA[!Ô3ů úŽp¬‚ů÷óg†L|DE9ޤp`‘:´lŻCo*oXp×Z“í©zÝc“ő2٦Ą8˙Lš ­8ť'µ1Ž JĂ3p2čŽp¦G˙8“1 H˙$Żä™T*Đ€Z.[Bč‚ié*ĸb×[bŕššWś­ ‚˘}öůmL OĐš~M÷ş#(mâK ÉůBą›Ô¶!â@÷ ¶ŻŐLvqü08Ü­´q&hC¶ôz9Ă/hlÇ Zd—7—$Uf… ňS‹‹EŞä§Ą·đčg‚±K€ű°¦Đ5 ˇČ:ł`Žrć>ĚGÍÄÄ€ĚĚÂŇVKP6,JJy‰Jka„ĺË“R7Ť’YÚCŕ&?ÜÔ†äű Ž™ŕĽ ü|P P6ÚAۆŁ2+­KĘLxă::©ÚÖ„z™…‘_Z—l—Xt }bup ő »Ă\eP˝Ş>M4+:öů!Ř94™`xhŽ–ń'@®“­MB›‹…Ú_ak×X„¬}äe„S–ÝiÖ÷ł˝“™V0nŠ )6TF@WźË 0Č *×âpŁłüd)6´­řËŞSضDŔĚUBŽ{Ź€˛rV–OK6cO;NßfbCËVžÁĆšńşöŞÍ‡eéß`€Ź2 KiHś ˝žŹM×z•üĹäOFfYí+«;šuŢ´§¶Áí2yëˇ8ţ—]PÔ—Őý)Ë.őX}ń˛Ş}sH4Oů#2ůhˇČj†*jň>7› HúşY0łZ‚%ďwŐÎyŮ/wUľlŚŘus‰uĹPkµ‘±uĹE¬0evőîU‚Šú÷Ô{Fc˘qNĺĚI^&SHłD4ĚáŽM(p»bŞŕËú#8Ü·iŽ=/Ąz?Rďźćć„H‘*KQ†)8»o1ë2»B×D”˝Ř'±ľ¬ÓXAĘ^[0U]ŃX›.Ăażz‰8–YCjŠŞY Ü«l“fäKťŠ`UűŮ„$ş#ť5S`öH©ây“ů›Z¨`ÓěµÂŠX’ąĎ´Ö f7¤YŰR$aŔ;꽣ޤćšÝ^·çߤSËžYô4Ŕd™$v@˝ëylDPu]ü’Ű©]ŢšŐŻT°ůč3vlm×–ŁŞ őeúÂ4Ł-“¬AKĹč5Pň+ŇöÂx–I^6‰’ĎN8 óOô±ĄżČ0±śVÄ Ôq˝! orąŐ·zLĆ\BĄÓM"ڦüLŢD&äIy‡f~2.°ëú†«ýúŘ»/ÔmMŃüwt¶Š^’`™Ë~A˝ě Ř>őľ~ÝRľd6¸·ź3Á5.ÍjM§K™ŇV6Ů&’€v§"Ń3ž–˘*=ă&w\a“š`ÓXÎąÝ Ąćł­°?­ť^Zäoͨž»LuÁ®z.€6ŐK¶]Ú1ü%fă öÔ켪WphŞ8Ĺ#  hb˛XŹCéP`˛ĆŚW Şń‚Ľ}8ŹČźEMťMáj|jĽť- Vě^EHE» Ra•eő¬©ńä,…Ve‘§t?ął4«1™O}ťÔĺŮ/ˇé1–±¬Čl#îř Ě5—@•۬Ćk€*GEáVâěř‚Ú»˘n‚»ěEX8É3Bc¦'aÎ ^~書~öš˝„ó¦µ^Â1+Ş6¤Ép)‹#ădw˘Ů«n¶AŮćm±7qBÝnµăJ˘ ńlËŔ[QŞ9ÚO1Ą+Ť6˛H ŮFhŐźDxŐě€âő>$l’±Ňdš`%†3\§ŁĐżJ Îśa?ŘÄŮűČńôC‚ťŽŁşđy˛ă7ŚlóŮLÍIlŇň7ÁéÖČ9N¸z Ć–vî){Šz˝Îj’ŰlaĎ˝änäWż´4>ďn0ÝR°)ŠÜŞGCÇ}ËŇŘéĆŕ’ÍGCµJł Ő~Yü5mŻ´ß"ĘYŰ ¸Šß2OźcŮé–˘)ĘBęřă–G­î‘ű$<Ö<|M—)ŽŇ”ĆĹŽfĆ’‡Ň6Î,ŐĐ›ň:5&†ęˇ€lÜědx˛WYAě7 xXRXHŹé·S?˛ëżWK‹ Ϩ¸ŃŇOľň7×ßěýţţ©c(endstream endobj 524 0 obj 3160 endobj 533 0 obj <> stream xśŤVKo9ľĎŻčŁ{Ą6®˛ËŹ#°Y´–NCC‚Âd ů÷”»ÝíęNŹ„FJ<ĺz×÷•ç[c44&Ę˙óýćÉ;j.ď6˝Ľćzómĺ‹)ZÍłmŻčY¤Áßl?mŚNŃ[?ď¤f’µ:6>zľi¶űÍőĽušĐ%Żţn;Ł}JŢ’z*Îo[ĐÉ‚qjŰvVcr!Ş“áč ¨wm‡.j‡Qą¶#cJVi>:ÇqIý79‚yHl4ž^¶ťÓ|"ű8’%’÷ŻsVÁčA˝ŕ¨dµw%Ů"–*Eŕ7G”˙šb‹€/„Â{q^fOÉÄevăůăöURŇÉŁwyHP¦ę|`GłŘľ‡‰ÇŻh:'H 8mťÇ줳<Í€M‡=–]°=Ďt ÖSžOŢúAaŰĄ¸.äyX–&NóPuĎ[x@A]·€ÜüÔ® ďł*EdŐ»\3#éHmHÚBJÍöźÍöŹę˛bâk=ŢqäŤę3ÇHžAíyęĆkC0ÜSrN}dôt¨ÇŰarĆr¶“SÎ#i2¤NŮ?÷/Žţűř‡Úďó\Ł÷–]]·<‘3ŮUá}Î/“ KÖÖP7SV÷U(¬n+ž>µA‡HÎćTĆű5ĂTXńě\@ćঠW5ŮĎł­I:ăQä5JÍ‘lݦ“¸>[Šnîj˛ÜŘäňÜ…ŐC´źď‹PőHČŘ:m3zĐ1™ =tż×ęľÔ˘«ą)ŃéŔŽ$ék¤˙[ýŘŕóf9á×*á¬D D,`Qí­†a’Đ‹Eڎ}–&dm÷aFßn(µţ ˙{v6ĐýW˛I›@r ŚYkA›„޸śąx<š čÄS:¬©î Q¨sčôąĐl&WË13z‡˝Ŕ´›í<¦6ŽŁŢµüd°«źó§µů{1ŢJű/««\~"Ń? żn[§×üşĆßÉ|uĹů¤m^¸ĄKŔ§râb•´b-ě-aŰLŮ&_Âęˇ%—7팿µ+C—±ÄśŁŔ Ó–ň»VK8·$Ą#•WbÝ/ŰŃ?¤Bő¬çł łÎ]G’mxç{¦[yO+äofGËťcúĚKäk7ŐŐë 3±ťЇĽqFH[Č+Ł ˙Â\(ś9:ÔäŇ‚‰č> stream xś˝ZYo]·~×SónP ¸·Č=ĺľp8Č桭€pó ËÚ`[r"ÉËżď Éňđhq\æx‡äĚp–o†ç·ŤäFŕżü˙ńŰżýKJ»9»>Hóąy}đŰĚLµyv„Ęn”śSnsxz ó©ő66ČÉl߼Řţ°“S°.¨íůn/'«…TŰŁť¬±!Čí;š˝ŇčŚNvjrJżý}·WVMQę­­‹~=ü©p`&ĽD,śŁcŘţăŕđŻ/¶ßµł.:µ˝†}˝–'x¨ŽZI<  op(ڱf{ ]Ř^Ám•6ŰËÝ^LŢHł×Č–˛t½}5óm‚Űţ¶Ť(>&Z­U9Ë ]Q^5GĽbcF¦Q *N!Y¤~–¶ 1XLú)zą´G•×yéŢŽ•ł:Ë‹ł‚oäb|gmŠrŇm"Üźr&]‡n;Űí-LĨń´2ĽŢéÉ:á<&`­µŔă[PŘO4nţÝFc¶·‹őŔŰ銆pŁfRN łuSĽ0Ż'Ę<‚a´ß~H’ śĚhá%ę8źpB´ďw2LJŔ¶G¨ç4ť%Aqlý ÜĐě'” LYÇÂ-p: «Áč_ÖI¶+Ű*ëtŔËkUŁyĎĚ•yIłť6¸¨t\FűŞđŞ8Á|A)vq'ÄŐ̶Ť"p±3ŚĹËĘ÷ő.ٱ‘“‚rř bĆi„íĎŔȤ5ŘaË©›¤–”Ş,ß˝j• }Nż3¦gIt :ó]Çp» X‰ł±ôŰî+)J·źĹŰK™ťĄ$ă>ž×Y¸2^¦·—dÜĚęé™_AăÍĺ·Â«h¦±mˇ’˛q±ôǢňÄ·E]ť1©ä-î·ă4.ŚcŠD=!6îözRQ[Ë/đ˘µĺ`'+ěŘ*Ź‡Î¸j•IK.®…†7´î &™Bĺ ÎŢ2s/>Äîéůł›Nú‘` ×(@Ź‚ő° ®ĘĄăá¶čIŔ°±Ť'3ˇ5íí$|_$®‚»/Ę3V'w$—sĽĘ¬ÂpjÖŽ] 5É  Čq¬Şđ… *č¬ÍâI~ŔČT|ęÓQ˛ěÄľF•úČKS%UµúÇ ŠPÍh{o52[ybş­ľ$bÁfđCňŰ…+bą2'(ĺB“ ĚÜ}ŮCl‚řg¶“ńKŤBëÇaHuV™<Ş“5šÂ• ¬ĺ÷«úűĺŇđ”öE|üđ)<ÍLƵB»˝"!˝íCu»ˇĐ e .uŔ™vŢŻŃvbâđ͇4d;ĚŘWJ0ëoiö›:»±8ĎFńĽĆÓŇhqk)˘íµC9ůä5©“ěcî$'R©6aů͢ęCR¸ ‰NµšąçF„˝/^b÷ÂČôеd¬ź|Ë CČoík} ŤÖűGŘžą…,ea1á§äMějE‡’ŤVŐ©íćąĐ§YUÚ·ŚŚĺ{rĐ)Ôß@ű>ÖÝ\Ĺ8vK1s ˇk|,ŃVĹUľŹűĽNęX°”·×Nz´›gW»sĺqAaw˛ą˙ÔŹĆO'Lgő †řf‡ßzł¦&꬀ ĺ;PĆ% uŐ„;Ŕk`V˙śfB4şµt&`Ză:4Ď€čK Ř(ă!vE‰}ö |–.žAă;’řÁaskŠVTDŕ‡M¶×Fö‚X_ń’˝_©N!<°±ś\ëIegMh™„‡µ¶rżő«Ľć)ˇ§Ŕ›mÎś#}ךJM)sţčŠÂńËÉĹ0¤–F´XýúŞűjĹ‚Ťľ7q<˛}•ßŕżäG+O*ß÷vČł9°–ę»Y÷ő˘N˛žíßËä°M­=x<¶­ścµ¦YU‡ăěN«ŻqË…Ŕyq¨RĚżËú{ ÉÓ:ihŇ6›b4‚˘b kQw]p¦Đ{K¸ÇčR+÷NßвŰ!żOr¬ňb‡>Ňt9¦áŻ´Ă«¬qöé}±Ź*ë„…d×üy!dkÎ×uňľg…d5«%úç´ €ń6ţ_Jôî4ö<őmŁŻe‚H௠IGáFµBůR)AéÁ§XM21‘µ,ŰŻk»€şÂśŐđ‹'“;ľĂęq|ĄĘcřáÓ8ť „WvRÁá\Ŕ <‚ÝhšŢĆ  cőęí˙u]ĺÄ·řśd®ĽF­”ZűI+[ZźPťYŰ;ęKINÝ÷)hŮěn?…ĄreŃě®ßűáVVuݡąČ2ĽYĽ{ÝŃĺlqB!ČOk“í=ľgE˝ŮŁ5°Ě“„tuŇţxxđOř÷?|-MNendstream endobj 542 0 obj 2999 endobj 548 0 obj <> stream xś˝[[o·ú¨§öśćˇŮSä°Ë;Y I›˘×4M¤@܇cI–Ë’-ŰIôď;ĂëpwV’“´0‚Đ\r8śo.é×»YČÝŚĘ˙Ď^žüîK)íîňÍIęßÉÝ‹“×'˛üe.Łvźž¦ş„śg·;}v2‹ś62Ď猗q×ú¤Ö"ě\pđewúňä›é{#¬2ŃMŢfábtÚNźö{)˘–ł™N÷-T4>Lźĺ¦›ĺôĺţ LF…ÉîV„Łž4ŤuÇÉľj“őV™K[ s9#ĽnKaß_ö#”“VO˙Ä™ü<'§ĎIű+ÁJČ‹1CţC´p:ĐőţMF%ÉĹ­M€S«(¬—Ó§I›NFŘIm‘ɨp#í®bşC˛ńĎy9›˙sú×b QD§śAKĹtŚó Ępę:T›|k–I”ÝI#´q '9h0ŻvĺaćúÎá÷pĐRŻťĹóŇ.(?Éý!F2+ŘŞ`|`WopR34/ö`>Hë§ŰŢ|‹óÚ `Ţoqo.D;ÝôĹ®÷ÖŠ …7hut"§#÷ý<ŹÁă(D‚sÓKÔť±NOOŰČ,‰×`<çäçěçr  ‰šŻß»ś}ňwíë~ő3F¤|x—`«Vhݧłľz`uۆˇ­c˙ś´`¤®ŰđQVŐ[-Y[Q°śŚqwú÷“Óß~3]v żęÍ70›ułó 6śąłVI”`®pŰîAęčŁÁŐôĚŠnżżÍ=kP*ëś•Enç4|Á®zÓ›dŮënÁ NĺťA‚ó<˝¬€x_Š­g@ęeyŤ˛z1KCżăĚ #J¨•ĂÁU,řŐÍ^ˇ`őď 4/ú^n;xźőć»öű+:!Aú¶ć ™ťŚÓĚ7F:ňyűNÔ÷¶=ë˝Ç®˛S~Ŕۮ߳ŢűçŤb6­}­ňV˛3 "\ďÁÇčH»ëkuĄeĄŘ8‡˛Ăt~O{óŞ @X:K€ŽBżQK„YUŹĎű\(hüÇĄ1€ž¦C÷t¨›:H€QeŢ[^/ÂÖ‰Év;& #¶I,öş¸)oŞmb/™‹ĹÔĺj‚0ŁË„0ŻŹÓýűŰ•Ćň945tH Ëś«Ŕ[Ňhü€rďgńĘXp´ z•‚„ŔĘé;4P·[H§4Äyř=‹ ‚˛˝ńhűŞčs `SŕyňÓ8KN€j·Ł~Äâˇ] Gś€±ŃT$ŻD€Ď«ňŠťéjČĎ6éRY“ść±7 :TDVbÜŮB¶ĺÜŇĎÔ¶¨„ż@čŕő=¸„”蝬ˇ*C)©ĺ K˛Ŕţ/ZÎs˝úŽ't^ŚÄ,ĄNJV~-jťA%¬‰4†tÄl^˛š=~·’“j%D›¬ĹĎZe ’öŢpŘġzNŽ@â†.ŔĺŰxµ ŮnjYhđcŃYbŹ‘ľ&) !ć‘Ůęń8CQ«>kFΚ;js˛8să- pŻXžuÄ’őÉ®®Šó°šĆé‹ű]-ůýĺ€"Őh‚՚Ȥuna— ʇśŤpd5A4ÖzšétĽˇ÷h ˝ÄQŚQiţi/!ßöÖ- ‰äśÖ_đ¸D}Ż8\^d°ČŞX>‚źG+ úÂŚkČ«‹J*™=ťž,zW6jGŹń돿ˎŐě„Ia4ůŞŃćW~±„.Aş°TDÉHČ»“0ŢÓ»e’ ÄÖŻűŻşGĘň¨áůŐČ,–őX†Y7pźŹŐ<”s8fš±™Sąđt0=tRň źřňNs ’ÄAZ›(c•ĺý|Ąőb¬(~z–D]yÍŽ6‹“¤¶hyµ±8–zÄ ­*$žé®oô2›q€Ý9ŢăęťC‹ żf ś¨ă®&ťŽęŕNDÔűóÚ†ĽŻX·ţŽ­Ö±˘&G ąCd»)ÂĆu¶>V;dŇkîJž¦¶T8V¨JGd$ާá{7=|Éţx+cí¸ĚŤnÄ@ Á)i—é0ŕrŽFáüŘ “Öů¦u^ôÎŰÖ‰Đ,îţýÉ´šŔĹäka“ôľëc‘č‰|ˇś~˝J‹ň”ąŹýˇ7]˙đd_¦0~ú¸w\f* ţ¨÷>yһɞ>í‹áŻ{óEYΚ4q‘řĺjwŚR L€łĂČ.Ş<šŽÍG e&TŢł•˛Î{ďŻ{łl9Ťř wĐzY˛íĐ, ťT%ôúXĐhŤ‡!I®v7-\ćg_8nm …7‹‚ z­đv@5_©ńŢŽ/(ĆÄPbT´ÓČqi¨ŘŐ¬6ś¶«,›.ńaĄ;Fçź,«IlŮL,Ç|˝ĎEjµYKk…a`«ć#iŘ:#ÓĂ’šD´@gá@.´W˛—Ş?řüC˙Lňľ`YĆ|¤Ę6CşÖŔ¸4,Č#|` ô­gLNř|ôCGă»á,ťŘ)Yześ)·ë™xă—P"Ąěbo*zЉŁgËóRgÔŽ Şš`Ü:s+g{Đ!@PŁ7>+)ô=8Q>ľ¨xÜ!§0Č&ŁÎ0+KůO'ő śçÁlIVÖslž[ů5żzá$TPx…z€¤tFąäzkt®ŕЦLd˙OLĄh°ĄEJJâšr=˛e‚¨p8UĹHvë%˝›˘Î€§ Iü÷KĐ: ŰŢ (f™ąd‡6šĚĐňçY˝_§‡Ü1´ŠsŰÉqKę+˝ţüŔO0őňÎä'ňł ?”a¬ŞĎ‘ŚK ¤RA"1´Ź}H~ĺ•Éł|»˘Ç©PőÂ8écmBéő†Đx!z[oŮŕ ŃBĘ8Űą?›×(łĚžç_ĐŐÇNź`Ú ÁˇŞŤÂł >;ŞEjÇ8*Ěç|Ó…zJ«ÖOţŃ1íá×J%[/öü¨ŔW„b" ń%ߞދ/ů*ăÇ—$dŠi° tc˙—{洞6±^Q[%}ęaäř˘ŢN\ĐŠVż˛Xw+'H\ŁKĹ'„1?.iLÉĆńÖąÄ9íM!aŇîšëöşľhčĚŮ<Ü×*Ńč ­9üŽ,şEs¶Űô'ËݧbËëšBݞďĆłJćLb÷ÖăĽDâ¶^c¤˘i ¨üťÇŞĽčLŻČŘäFKŤůt©ĚňPŻÁ"]ŕ‚+ün±ć‚ßąíĺßXBŃ y”# §H´ĺWŞż$q›O2 äO—i =ŕęn2KąŽűµĐ+›ó×ďINą6HĆŕđ±a`nÁ‰R4őx䇋·ÇĽŁ#.…-ÓŮJ§°|0Ă3ą+öĐnFđG×x‡^~ľ_’A`D˙9hó,€Űľj®Z%˙ĄÝ#ň„(ý”!H WÖ_xďl‡•*ŠDâ}[]eç CÎ2ń”Ĺ#röMëšFŻ6+ ˝ …ţë‘›ĆS =đ(ôvŻ}1])*8,{7yRŚo›j˛őšH«ŇŻŤYí~Y©÷§µ›ń<íĽ/żÚz˘^Zë´SÄ•A©±‰˘ü„ěśa)ş„>ĺc˘vĘ›'=¸ęú\Ń66ŢBÝ÷ę)ĺ/W˝r#lÄď[/{QźĚ&ş]»_]^Ô—[ŢPĐÜů˛u’+ç~ĄO.ŞA& pőôËŢűUo~ť›x,{/€Ľ ×ĚüťţE^-‚ǨWď*PÁ_ cëdDŢ_µćOż†^\áűHëň/›OÚ·©KROus†±C­@µ˘_ב/?‰7ąéŚĹC>†MńWUN]–9°*ťzź˘ë” RxżĽß™¤ňîţČI}o‘µ,ŚžďŰkyÖ·ž7˘4^][M5Y#9O÷ ĺ©bćńRÝň5+&­3Ş˛‡9ČĎNOţţ /<Wendstream endobj 549 0 obj 3549 endobj 557 0 obj <> stream xśÝ[KoÇrÜ_±7ÍŢVżľ‘cŔ $č`ç@“"e")Š´ĂüúTÍôŁz¶‡»CîA`Ŕ\ÍtWWW}őę®ůĽćL¬9ţ˙ž}Z˝ţ‡f}ůe5<_‹őÇŐç•˙ŕqÔúÍ ”f-9łVÚőÉĹJÄ B)ć×Ćs¦őúäÓęÇî›^0o¬—݇~#Q\Čî´çĚhă˝čnËÓ{¬…_ď{ɬ”ÚuwýFÉ‚PťÍ“ţyň—Ä‚fÎ;,Ŕ(póýęä?v'˝şRJ$! J X~Ądw6>”ŰH­6&ľ—Jw×ý†3§ąőŞ;yĐŢvßă48ڏɴ.ó¬ŻűŤśyçşw0‰ ĄUŔŤ#-a­'+Ü㲎íěřĺ¸ŕĂve`Ţs‘vמqKž¦ßÂYÜa’Ŕ5ňÇÄK”§°ë VňÔĚk.ÓŠoűŤfŇr…$ 0‚3&hŤËáCďĆŬ5ÂŽBŢň‚5XřĄü$¤.A´$űˇ Ô$Ň}(îMŕ>ţ´Â¨Äě>®ăđĄ‰q–[×UÜ!Pň,ňY±€„@űiżđP/¤îóĂ›˛ÔC~xGŽš*«…će™Nv™˛ĘwꀇQś_PD)PyŮaĺŇ ŇŘJ,dD5Űcq]\A9†`#ë^÷DU`΂89»/ <.z8–!tżG[[ŃI™Hť,OÖĽÎbIZsŠbäwmÁřZjZЏo’%‚%{Ýg"&x0ć-pNVCIl˘(6|ź n”Aíé€awĹÔ­I@|g )śźláç^x&9ŘĺCeLé'—Ä5ă6tCŰ·ŕ#j"Ă®-žk\ Ľ«‘ĎHL˛Ä«ŢŚÍhŐ\l ÁKIJ-#ŻúAĚ(/Â`ÝÇ<”hňĹ%€ćoĄ2®¦ nlPąIqČ 1¦K‚:"ź¶ÔšľŚö|Kťě§ÉTĺ–Ćí+”őPiŔy”„łÔoŁZó¶§&4‹ďpFR{}hş)ňsËŠŁóMKŚĆ2î{#$ń¦čuŕĺ´JH¬Aś Ö!)úo'±jpH5ѦŔFéĐ»ënz ip÷kyMćźOĂ^˛i f0Ô1Š+ŹÝ>%ŕđ§\ý^jVFÚĹ$”Öq,Ň‚ô Ňiě:íź «ć*űć^«A‚Űé˝Yň›c ă>ŮČYswmT&Ąřn:qLŠÁ @6Äą·3ŢüIwď„ô9¨K…Ý Ť˙â@Řżő”˛Šęe’•‹Án;’b.نŘ2d„(‰› ĽŁivEŢ'™Bę°‰Cťm:Iö•,íŞ ˝MCÓćÉbőć51‚ ˘k’ó¬xV!yć9ĎťhÖ“ŔÁ­šOMź¤)MűÍ)‚kďtL}¤.ÍÔ‡Ć56GUÉ©{H!ŽŹŔ<˝Š‘V”ÉjŠÍţ»v ČľlduBZdĘ°Ä P#9\äۓիĎk î‚١áůµnŔ«ň`}Úc™ůćíęőŰż®ďďŢŻ^ż[‹Őëďđoţţ üyűçőďVßľ]#-ś?’#!tH‘ż„Đ\ [<©†•7˝UárCű®×Ŕ{ĐjÎMeĺŚéŤöž¦7 }3‰ŕQčDľ•L$Ľx=¶L ëJ&S#ť„ö: F+™Ű‡*dé>ćµóÁhY?`ďĺŕµÎĽś)»V7ę逥f;.^˘™ăµ3‡ť>¶ ” LuÚ˛<âĚۇ %4K—TAôߣn ěţŐĘŞšÁŕ~.µßď´§ĺRś·ČÉńďËmŔ@ –Ç´É™—ĺĐe ŞmćˇÍÜű®Ujž5]ýîŞ.âa'ÖŹ-¬Rě˙¶°Ţ6ď­ŢďÄÝňÍăN«%śeN|©ďőxęŁ áMA˛ňhţNĺútŹJ°vť©¶LTôĆNd˛ănÉÍÜ"Ł!×/O˘wąPćŃË­>LUČM8nUČÁéʵ ŽEE7ü±y{AŇ­«Ýt»0\é˙őäúزEoď*Ů»<€îöőőË…7k-2ŕҬEeŹ[?Âcé‡>±•ťô"sĽ‹÷ö°ÉŃžÎ˙řB {|¨ś ÂŰľ×myO.— „ŻšîřŹęĆ9ßZ%ßißŮ6ŹćŰšŢá vYÖ3ô3oYňCTČ@hé1çŇ“Í3°š÷OśĚě?U±¸Űfę´w xĆćgTű BłŞµA¤(”Ö/=˝[ę4,‚7HŁbŢîHmň±\cżih;=Ţ_ÇÇ–‚‚4ra*ćÇ V—Ą®Ď`~WĆń^ŕV—žÎ-Ä•’ĂÚ3a‡ Ťü©}}ż?HŽ˝Ą˛ĄĂd9óó ŃÚ¤ľBęE©_VÍK e1=Ь”|SYLJ„Ĺń,¦—ĘbzˇY1‰°”Ö2ł{ĎEŕůÔí¤ß(u‡ó­FbkşW˝cžsQµš•î/ŇtFš7I+Ě«ńn”űji¶‰ągť…nťëĹ„4Ô3˝&ä@é*6 yŃNşëôókÇçŰ]R‡Ú®>ÇvZÖ|_ş­š fłśÄ®´g6łµ:WĆľěÔş acl‹ ,÷+ßĺĆŤŘÖbŚ‹í‰8j#Ě8îOđâ°ËőČ´=ń.cę˛Ćśó`äšĺ—čÚÍísk3‚)!–ě˝:k‡é6ýSWFlwĹ=ŐŠŰBpMŰ+ĺŐ FŠËˇĹtұ¤‘n»łfŇ…âńK}ď)q~yřS_6»×ĺäYUł†4bj8Ś jV7DÍ5Łń*áź<Ŕo”žŇxćł¶©‘¨m¨&”l|a‘›|~˛í gěN[ßGÔ­ďÍ&őNť«.ĂĘ5ÔŤŘď7ôaž»Ýš2 > stream xśí[[o·ú¨_q t·őa—wŇZ8¶Ú˘0šÖ‡¤˛.¶Yr,ŮŽóë;ĂËr¸Ë=GG‘ 0ü†‡’Ă™ůľ™Ą~\ ŚŻü—ţ{ôvďĎ/8׫W—{ˇĹW?ěý¸ÇÓ˙ iÔę«0Đ@ăĂ`V§{óÎHĹŁ<Ł,÷«±ŹKÉÜĘ8ż¬Ţî}×=íÓByÓýł_Ěxo¤îžözÎĽäęúµdÂ+ëşýŘ4ď^ôkˇSÂu¦_kćś÷˛cĐT ÖŐtÚ‹°šáVš)îҰ d m2®o‡ÁŢý›´źáÉŚtÝó(UjÝ}MFü´Ăhé™WŞűVQÎ+Ź™<éů`áś÷×®”ö7(Í1oÄ⢪ŇÚ/ű¤'ů[żćĚ8É˙ţ•nŃŁpŁđyşve,h§ş1”ěÁ>:?6Ła˛–ëX­……ÎA¬Žaţ+śÄŻD÷.6ťč.Kç›±óméükżVŻUwUzß—ćal˘.ŹJďÉŘÄ rŘÁó˝?~× eČOăr¤s¸•NŇÄ}m€MQĆšŇű÷Ţ€ yë±Si¸Ac˛ćđw^š®8-˝Ş4uµXĐ(ŘÂ\Ë;'«=-wŇ–Ŕ·ť] oJďĹě‚QÂ§Ň gă€y’wÍąłŮİW–ŢG3aŘ|T”kŃĚŠA®Ö<î‹™]ąŃî°óxě|śÎĄěőtË9¸ˇwö~¦ű¶Ś}?Ű 6g˝ßwMí˙´iĘ2öűľr*h 1ôÄÁŮ•őíě,®şŮ«±“l˙ń6‹Ú/۰EWµ˛„d4t  ů…Dk-ç4P€‚€čA­’XÂeÚŰ`®wŽ˘M NwŁ:^źeŁę.g‹MB,éýP{˘ń‰qmÔ8Ž}6 fŁĆŤ`0ţ†źźŘ/pĄśjű}aďBěďŕĎśž‡î,KxYzĎKóg`Ešá»ßaëVPO ‡^^)2˘‰ęţB˘\·M„ëŃ|$÷L ŕJÁjrlL˛NżŽň0­ĘÝ«ŞŐ6[«ýĄł7x±ŞŁćH|űąHŘJAĂ8ťö’c※ćÄßT7Ľc3ŮŘŐ4§ő‘ ÝoAĚß@-Ę*PÁ-0â§<|ĐAË߯ őd›µ=Ű&ˇ …u Ü€Â?•čÓĆ1ƵÁb7ü«Ž P(f2–F±V‘˛ [}ť–{ů€ ÓD`Đ´ 0{ĘWź$+łŁ•.“XÂÄĘB/Ńn-ÉCĐçwĂŻî’ŐĚ67Ô×8{–@ęSl>VŠ®Ĺwb łęÄF–@đn¨AżIÄ}a ˛$1Řó/Ő‰YŘ•÷Ő‰ Oď lM!·–®ůÝ—® ‹¸źĄkyG¸@.ęJ×ä*ż”®o'tĄÍňuí Düš1űv»–Á®ůj ÚpÖŰhÖűĺ3řaüř«AGĄůhěP=ČÓZâŞ0\W(ŤÄ†5'ĽĹN/4ŚÄ öňXçF@:Łb}oÂ&ä`y,Í…NĐ“TŢL0ŕńs6KöŽ'2–Á˛¸Üć9YQ¦¤"ánÍAşdÚ ¦ZśěýĂ8ý¬üžŽ)!¦_•Ţ7eÁôăóó˘ăŁpd¸źîó(őhü*źóOJ/ë×Fq&•éz‡. 9™˙®¬DÖ'RÉ^ĎBŇ.´e欝,ú9îTpNOőşą^Šń`ÝŞq)aÄmÂ`<ą§΋ŕ¶>”ÇĄ9“ĘGK/Öé`#†«Őř¬:żZ43 &|5»Ôâ1ľĘP°źź&+ë6ťŠ,{Ô\kŃŽŇ•EÖ ÷Dź…-¦Ĺ¸–´÷=Ünx`s‰G°L M/ęĚĂŢ×řŘĆ0aębÜÂ)v‚Q17•čjđ»`Zůîwă»”“ć-“«-ľřxü˝ůĚDĚŻÖâ›ĘĎL U#ެKç˱“đ·«Bó)Ř|[˘0ÁŤłfHż*cŰńÇÝüEĐśi) wâ}`ZbL ľ&Żk6’CýI ő°_)L+iťYŤĐ+®°¨ «‰+¬‘*hČ«ÂB߀t/±ä~Ř#Ůx?˘pgĄA”‚ĽÎx„Â<îžV0DZT”Ž Ža}Óqťî-Î> ˝|"č C¤0B¤ ![(đf2ň(–C2™×: Ë;ŹÁ2‹j26ˇ#óO•Jň§!µ«E’°ł/Â#y97qĹÓđŘŤ:mAU¦Y5]!¶‹€.(ř*p7Käţ‰€Ú9P .µĹĐťźÔč y4ś×E‚Čsů$¤äůsUüťÚ2®Ůľ]ĐŐMúDÖzUPU#?Q"O _‹w NI ¦eÂSaM1-Ż^ ‰ç0¶¦a5Ńł\dŠŁϬ=ôľ®°|ąd6l§L›ó%nŽW“łÝ,>Ç«ÂÔC U“$&ŹkÚ~»ČF\§"wĎřbů·&¨Ëóń9ٱ=ŕł6( ţiŮb”ÖŠ±3ĹĘJ…‡ŕ!:*ť©‹x,ľÚÓE†[_UŇG¸Ü‰ŇÎvĘl ˘—‚™~Č‹ZŠOś5˝wŠ?Ó?Ŕ`ťš|ľřµ˙lŚă-Ve@RÚ#o|ÂŘř-Š,LŠx¤65_TůHŤDzŇKj¤îVJíÚ„P©,*TN4ŔN` Ňo/6ĽiĹ`łul IÖ¦YÜbaĚq"˛eŚ‘‹ľ‰‡1rgßÄ#ÜŘ3ŤgBWQ¦ÎYň¦šŐ6śĎ†ćŻ v@Ö´ăŻwőţ‘Z–Ľk8­Ózý–ëĐ1&Ŕ­WśĂĽ ĐQµŚ]ŃĚlş‡pźDaä–ç¬ĎPŚ+ĺ]ń°5ü»?klĎČnšő´™X·}±›×¸0/ä>5ĺ “°u*}Ź×ňşe˝çé˘őÁfZBŠZó/l(ęó’ÉŁ|­¦™BűRRHÔŐv/˘Ż6‡¬J~!™ăvüfŞA»ľć…SŠąďfůV’2®ńď¤_ôËşŢĐLéSücwaý5“ŞĐ{Rš—xX.µäMÔŘ%N ítőăŽ)GK6\C tş(âSţ[˙öźś»n7âˇX “ŤN2/-6Dp@áÜÔ BEgŮÄnX\Üě5Ń&íőÎÜ Cz`TUĺ«§6XX>6qśf­|ţ†BňyéšÖ•Çâ n/TŰŹVáBDŰŻň¤|..v‚„%đJl¶aiZ­Ćü-‹µ,ĺV#‡ť<™Ŕ –ŹĄ¨:Ńi?R ößÚř 4u…’§ŐwŽĄ>hjt…uĺOTÖ×9ÄĽ–^ÍHČÔ¸Ő-ćG7łO\“Ô좵P róHMüéłÄűö¤<°4=V(˛nÜčq™Sӡ˨ʟ‘¶eCŹ˘9E1e1â`…É×Q&”‡řŽIhÖ`#›KŘqٶiťą$ŢRs©ý˝˙Âż˙•> stream xśŤVYoEFyś_1oĚHŮvWwőĹ ŠCŚÄfĄ !Ś˝Ć>đ%”OUwOw­˝Š”-×ÔýŐŃwŁV0jţWO݇˝c7ţţ0dţăĂÝő]ĄĆýuôÄR µ×çV)z‹Pěy ĆĆkU}ôôe\_żLogTÎ`ňÓűyĄ•OÉ[7˝ôÇT˛ qZĎ+«L§Bz ÓńĽ2š8ůyĺTŚ)ŮI‰H~ťT;ÎŢ<$ň`ťB5f‘MăĽ2Ć˙AëčaúAĐďXÄ*oăô}±jť›~ß ú+’¶I%ÄéyÁĐ–4«Ŕ›t <ǸřŢčôOl-ŞäÍ?ŠôRuę Ç)3ůz^ňž2ůuý]E1±qŹŚ"TŘŃŞÎb‹ś¨?&ÝH6˛˛„n0ăĘ2¤Í¸>#ńłŽÉ¦řtŕ§ÓBZâŢvݲg °WĘtŇąŹÄ ^iXpŻfę5ďśIR3X’µ8Î+TĆk;ݰľVŃă˘o[9ąL Óe¶duňÚŚ îm˝éúŻRfŰŞ•E/š(ehĽgżÓźŤy_âg…ŃÓ†ŐRőa¶ĘyíCˇ\4FčC_ÎFÂI*™ŇÔtmś(„ŕr !Ş­:°Ą`¦é/ŃTÂée/ÔăÎňmfîC˝˘ó˛ČͲ€’śÔş] úďJľj}µ•Ŕ’ÖŇ .,k!˘Ż¦2jOťä=(´^Ć-dEŽ%s—tĚíꢊ¸ŕšeO:†BVŘýĽ=KKaVPçHЉ¤čwŽÜeŤ[z‡gCŚÉM©Óo[3gĐ(lAµ.ŕű63/@$Ň6^*ÍY Ď ĚÜ$W€č•(ŮVßÔ QZŘ‚mGg÷Á¸f}˘!ĘďáV8XÜRÇĎđmŹĺÔuxj„}őXÁزzSTGş2x`.zgwnjË»–X«¦@=nhŢťËöÖĂŃpG—78eňV's‘/q pé7ŃäDľůű‡ĂŢá‡ńńţi3ě}aŘ{Ď˙í|K?‡ďĆ/†Ăńč_ß´gBpQ^ +LkT˝Ŕ5‹}”é§ J>i›ĐˇđČ9}ĂJ:‚Zá ‚7Tčźk“&4Ó*ŻŹŕč:ňÇ@·ÔO«r‰ÍăNsŻO»U@ĎW@ŤTÜ@SËL$Đ?7ę¦ žĚĎÍCo c/COŻ‹oŁGĎź&vŐľe*i:ë4ß&.¶*xŢŃś ˝6•±č?6­ĺËYŐFW>făMŃ[ ç…Hý@źştÉË% V•`AşŚ=ź›&xž}˝mĽűĆĹxx7×Uoj&ŇnZőz®Ü ÉrĘRµ)‰Śx™8jË[ě9¦ôZ¨§ 0Ř^«X¶›\bŕPééCŘíŻ3/Zz—ÍžöUnÜi—®@h!†%„Z%N P‘âçceŚĂĎGjoZ@5|„®yŃ仍§Fń3ÉŁŇv¨ľćM•F_nĐëśo=Bň©”^,ÇťhywfÍu3Ô?źĎ–¦=âR‰<Â}bz W[nBR:ÁłÚg@Ň ´˘ł[Wöíń~¸h±ő^­‚/çŻÇwQÝĆô˙ćnŃ;ëÓľ«á6}źÚËŰb\Q…´áňĂU”WůŃđ7 Ţ> stream xś˝[Ys·N%oű+öM»)í÷‘7K¶ËLʼnĄ°Ę®<¬HIT‰"iŠ”Ěźnś †KIąĘÍb€FŁű뿯ŮÄ× ˙KOŢŻžĽŕ\Żß|X…÷kľ~·ú}ĹÓ?Xµ~zŚ…^ 6#ĚúřőЧ¸”“[kÇ&/ÖÇďWżmžmůä´qbs¶ÝńIKĆĹfże“VÚ9ľąŞoo`¨7ž^mĹd„Pvs˝Ý -&ĎĺĆ–Źţsü÷L‚š¬łI€Q’{ż>ţÇęřŻżmţ˝Ý±É*nŚŰĽ…éňđôćĚ żą%żź—ß÷@‚ÔR"1@SšIňůůč R¦'!éĐ32ŕ PnÎo^Ŕ˛Fko-ľ…%Ľ°"-&¤`¨ź,ă›_·–MĘo.ËŹ×ő‹Jči\H-7‹ë+¦‘1ÂOÎ1>âC"Ti5c‰µŢžpkČRehb;7kç$Ś lW@¦wu98CÉ™‚Ĺ@ŚŢŔ ř¨µŕ°ÚNlh#q5 ¤: k‘ˇ;aÍÄśöµĆhnjŚLµnB>r ŰYżů#Îă˝Lk†…šOňp ‚ư ÄřdĘ «´ KÜŇÓ"ň{UöG^ľ,/ÉZçý÷gu‡t}ä̀ȰPÂ^±Ś|ô¦Ś˘âi\‰Ă["—¸’űěÉň5Üao‡Bř2Wü U:¦©µ6Í…Űü9˘ap 2’őß®n „„oĄĐt•ÔÓĽmłů Úba• Ň,˙1Ä˝—őíůvđ4ĐŇgŮvĘ´ śÇF¸‹űkŃŽ'»™ r*>DßHÚe´Ô°_.;  Z€\Í/Ĺ99ŞÚýl ş Ź~óh Rä\pM+'e5ů¤Î˙/4ŹŔĘ•!Űâ’ďďclIɉśŕťĆe¤K»zҸĂf é]2…ÝyęśTR›·\ŚjÓąp*‰sG­—÷Q`/Öd}¨,%(ÓŞPhH>gN1ŢČ=ptŃąęĹŐ˘B^ ©nrŞÁˡFŚ•ăd —#řĘ7»ă"n—H3m2UĺGó{´_Ž~‘< ]iŐ%éĐM’ ć7ߡWę1’"Gř:y€$űětP ^>6ĺ©ţę*CTuÔĆv÷áŔľ‚SW)şžÉ]:? ó”Ę_&Â=1$ŕcđţ$ŔK‘ŹĆ¸CČĺŔŠ€ ÚjT+äĐ\Ăţ3Z|)™rc—wf“ĂŰ%YÎë/áKĐ ŁćZ1šŔ“ ZÚQL!LÍî1 ÚËVWŕpŤs ^EkiĂ FŹ%=Šw¤z$Ţij̮š¶Ôc˝ m1ę\'áađą!.ŇeU…ńMR|ÁC~e%k'Ůg•ö}pŇŁŰCŕD(đwâ&«rd5¨‚2Ä °[ ±TÔ|°ëťçÓ)"N ę󆲣R9ç#J$“ÔÖ|ă…ß·˙Ia‰_r㇎r ¸îa[°I&yMtXĆľŹ,vŠžňnŞÍÓ€uvŐF»´˝ÖZ ‚Iź˘UÄ«ąćI‘ąVSġ§U(9Q•µł îPŕźCŚŔypĄşţ9®xv­ĽjBÇł‘śfĂčuµf_»UB’b8řS ŮÄ#;ë3•ŠÂť5‚ŹhHj`#$©‘ĚhüQĺ_6˛JPŃžeçßa}ŕÜźĐ)ĺP¦ĺń\78ń†ľERŘĺbóąąÉžN7v˘B8ę›D'ŹwiŔRaƱď}É–ŔÎqŃÄÄB˛IK»hĆ2…äűlN¬ůB1K`çL©•ó ߡZ0RS^7±IIýVŔ´D'–ą˙Ź4 ĎBUb”®<ଧşŃfG?˘Ó(kvE¸;ΉľěđdÄR/BČFD‚«jăciCF`hř»ěpČ©ÎB˙ŠLaş—_4ËÎS»7üś‹uĐŹ儝X±ű—#ZĆ’Ř §€#PKđëáŰůX’ľE¶CD‚Ed6D»bőMé— #.ńČiÜÖqR욌 +̢í’Aެ*8Ů:9Xě7Í“p>ś— #‘bJŮÚ?pf¤3&x)ýüîţ,ĘiőnŰ5%ţgŮŢ ŘC<’Z%Ť®€ŇŻÎ‘>NŤäô˘sm­ĄŹQ[IŮ®e ¸QEú!ÉĂX?éŁČQ·l![}YU%¬f™‚VX9Gç† ŹÜD§4‹Ü8ěśF”š j¸đßĆ8ˇTš>s=“Ą±›0wĐ$) IńíŃ'ŕÝŇô˝ăŰŐh´¤ÂZď$,Ó }OĽ|R $‰™q^“ô[o‹ ŤŠ‚i?włű.ŤŰEďÇţ“ř6ŤóŘ;q(`čórfÁŇ`-$śâĂ'2Ů+â[ Ă> Q¤g 'ĺ^C`é–áŕđŢPÓyŐéř Č ^ţdÁ>CjDè$áqWŘĆő•^đ'Ç®ĺůČ^:ůF§‘«¶Ţ“ś}őó•îĎÓüz©Kŕ`˛ć: ĂňÓÜ»!ęŃĄü™“oJ©­ŁžéÇĆd˛Ě#iĆ =¦żÇĐ„yA“p3 ¨–ť˘„ŮI™"_ RźTéć7nfdáďmĹZxÔž Á[žëQţ´Śy4–Ů·÷CL©\ů…©şvĐc –ű1Ľ ^ţBY1gć?ŁxRÜŽ»” €éŞđmö¤ ‚ł4\hť Ôbě6-•cł"ů’ ąíĎrÖ‡úAŁý íšđb+uŘąŞŢĆyőARlj¶(8‘oöëŐl×U‰â¦ŰśáŘĎč @!uJ5éb Č'´TąÖ× úP'O4n›·‰,™ĐŘŻćS*#°qLj†Ú8fqbgĄŃř!L' Ć3|»óŢqbó,Â<śv Ó@t ¶Ĺ5›şěĄ2X™w[Â`  «µ’Ąpě7xáżn-vú›ĺuŻëĐwůűaĎv’nŹŁÂ>-@Eć–,2ö$ňP¤FĐk^vÔĽMÖŔ˛Ľ!Mˇ”VJpŕq*áš0T˘Ű$ô8ôĹIQ)‚´,hw#6@śŚ[ fBwúßÖ«%Čt— T áŽiŁŇxtŢ-—ü%¸¬ŢřĹJNŔąlŚA¬ăńI•pl_e Ż§†,ß3ZEh+aő@Ęľ˘v˘]Ž Á&÷…sL+)” ¶§z^ ľXë»aNô¶˘ęÜء8ŢŐ)·z!»I¦ŻäH°vL‹Egőá‰Ô• ¢ÀüH¤é|d㉠ż«ŰZnČ™3flŐŤ …‰e"„pă>kś¦%¸q.yč»ZÍІĎzs#ođ8‰»Í˛žB3p]6/ŠXłú-H¸f×Ń]a"“1vß¶[f~ŇŢÓSéyJ»wöµ"n‡y®.—Ş_ö“·ÉGTŚw›Šžă Úľ#Ăn_–Ú-´Řtńq$ţ˘ô}°”óŃcÇoX+ĆđEXx-Á6ÍŮVŔSŐřÉĂ9O*OۆĹx&72k°´Yľ‡ Y3ČčÁř´Q`ׄc»Ę\ŘJNŞôýKťNFĎEkP¦»:t|N•7ÜIë`Vhw%)FŁc”Ą^ǰď~†˝ˇŕ“síitţůÚuoU“z9¦´dmˇ=R¤ĎęĎ4±xe?CóG‡HůĆUëČźq« ™*µé),4G¦‹˘ áŢM†É{%mu~‘ /ůl©ßn'R}ň# Ç,÷ډ[­¬Ę,ź6[ěBuó»FPˇ„oîşÔDJ87°?pţ›BDßűšZŰv›nkęËą”÷€Ce)šł%¸Ő¶ż«q4ĚxÓďţjćňµ­ż@ĆE§Çą4j{˘ăh$ކíI?,mÄś…´M58H¨wĺ'ç&SÝE9÷Ĺ–»iď ňw¤Á˙żÇ Ť 2˙ v" E­G[Đ1†lbb“čŠčĆ Ůţ(%·ôúµyěĽüľ'5Îě#űÁť—ľżeěß‹J@ěn›'5m“LÜ(řBk Q˝ýzÔ(ąŘK_°¦ć2Ř,`!ć2640±†Ř;’Á‘xËŇs…â=Ćő®|€wŚžŘîďđ~ x3MéŠ0±Ť4ÂťŤ—ŤF•1Ś+±:ÓFäžÉ>Üů âFü¨6ýN ţŕáMÉ/ČÄw^%9ľ|‰Â/ßd¦ ;gżÚáőBÁřŇN›H2,t;ʵ€¨I«słž ;{Ë®­€ôęÔ4‰Ą,ě#{EÓĄ8ůÇ«ç«ß×·/ d Éá%d4ţđ× o6?=Z=9úy}s}űjőä×5_=ů ˙÷ô—gđçčűőźV?­ź/ßvĐx.Ú5·ťAy ,·ămgł‰Š^–µčźs•G`ş5ŘN[r—6âť{gCä‹Oh‹1™ K…“ČO·ĺéMyŞăÂ$ÄBµ/żĽ*Oč÷Mʇb×{“ÜJňüN.Gj„ĚNŁ=jÇf¨pEź^4Š. át܆gB’­ˇĘZCŢ˝-ăš.·üň¦ ĚKś&˝×ŽüxY_>Ę4]Z*UaËŮěĘ&®ĘĆęecu ´µx;Ŕ" u>9ĺ¸SšßUâ3ë2é±Ă“C ‹3Ť™Ľ™¦°E3-zHXĆć =k·cbjdÝBäÖ(Ěh7•p" 9¬=€Z†đ—«±Tě #ÉLä1J‹ó6«Ä6ĂĘý|™ÁŠ“]ŐąÂű$ĎÍnęo»ŁĆuË^ŁŐßôĎăU6°bÉ äĆî+d$V~ăěÂŮŘáÇ#Îĺ_?ÄüúNűńËP•@!9)żWíM"®şŞüsČnť‚’Q™öşl}w=xWĹ˝ `p´¬±i’†{×1…!U·ł˘ˇ3]˘SA¸g~ Ťä1ÁfŁpGť‚~x7n˝:DÁ9Qůüóľ Ă@şQżŔuQÎ ÝnĐNÁęSňĆT1ĄĽńŰ‚Íyľú/2Ź;-endstream endobj 581 0 obj 4212 endobj 589 0 obj <> stream xśí\K“ĹŽŕ¨_±7Ď8V×» źĚĂ6llÍđaAŇJ´Áú÷άgVuÖ̬]Ô[S]ʬ|~™Ő?\­‹¸Zń_ţ˙Ű—~!„ąşůńAlżWß=řáȬą×Ő‡ŹbG M‹XW{őčéu Ţ*-ŇxV;®j›PjńWÖ[řĺęŃË_ď>ÚëĹHěî/űúج2»?’çěĹ”XőîŃţ ´ó»OŇŁ]Ĺî‹ýAjżhéwn0‹÷!¨ÝŹZĂĽf÷eŕÓýA/Ň Łv·ĄVíw˙ÂÉÜşz+vźĄq•Á5ŐA»)ób#áďäµ?ăÄbWO;˙…ôř{čE¸ Ć-[Ę.ŇlÝ"J߯öÂ.Ʊűśth#ő~L:|#X˝¬ĐăË‘|Ă6N"u6aő˙yô×|ŕa fŔ™C´u°¨îpu<ʬ´“ő9(`'ŻŇÁ@«Ľzôşß¶ăűľ=>NŹŢížě@ck„ÝŇVµ{±î˛ĆH±{5°ĹîÇ˝ZŚ]­Űýű3@h|ŢşŢb«_Ľt»›6Ő«öŘ o˝Ä·ÜKąNKQĐó¶m–*Ý ßR«»gtŇč(GĆŐŢ'S}›&°ĘÇ·¬]l%Îú˘ŤOZ_"Y‚4V•Vŕ¶.€¬ęGd˛°(Ę\ŞŇ=.ću=öüŮ…L·`Ľ”…n0Á÷ői ‹Ň‹SÝľĎÄ‚µN‰…۶82 ĘÄę×"łwž·GB€»:RÇ"I04=a˛éô°dÝż.Č é)Y ť.ěĐ]÷™¬ăR2yíqkmt]P6†5FˇÉ8,/D>kśKW(  ě–p9Ł[N¶^WŮşnŤ/`¨”7<’ÖW١ÚűŰ­"ßÖ†e ĐFzr¤ďw{Đ&Ę[Ű3^Ú–˛ôčQĐAťř°aÇFŐxÜŤľ„Tß ÜR$K®vŃjä[)'4^DČ˙ÔćÂaX¬HĘřäĚîç=<Čuí¶OF}Î ¶-~ž|h˘Ŕ{NLŤHZ‰DŃĎ<úý×Ů»ü_¦i“˘'{`'­‚=Š®¶v˘Ś ůV@3ő›©ßĚ'ž_'~^ŻÔŰőő6âru§?9ýzŽúC˝µ8ăč`‡Ö›ńč˘ďgçâöĐ@„6?ŁŔś‹3ÄŹA˙˙ŽĂ$(ÚŃßx\[ů1ÜÁ}ZĎ™Dęy÷am `“΂¸~Łłb‡wOń‹jpŮíW1XS>*Ć<ĐK>)¬č=řň;!î3Ž˘dg?Ôßďčô1’úwMeĽÎźéŐ m§!´ŘČóp 7í/áĘ%%@^Şa´ĄâVZ˝ĺéB6ŰĹÖ1rśŐyXOqßÚň?¨o'?MZôňÎđÓ>ćă…÷Şš˝Ý2ˇîXgŕŇ ôv”˝ŰúńślŮČĘ bíÚÇVSGě-‰FB«3‘AŚ·kbýŠ0“Ó!Ź×3Ź.™ÓďţP›¸đ>á)ڱÉ01´gm˘j RÜ1V‹”ŁGS±€Ţćßyőy{Šž×}ßč$ó;#ďżŹŁŞăŘbć˛w#y,•7 ß>^wŢcÜľŃ](ţśŐ„/rÔěĹ1ôvDo(ç2 ٸ_7ľ—Ce Ż]ËŁžĎ~!¤ą°JX2¦yŚŃ?KC9|ß;m#ź®Ä€C*f­!č\|”i¤ŤD"–η°oč+‘ßđ˘ŕ.ʬfóŁĆݱš5~” XUÖ©ő%N)„V¶ô•V“AoÍśMömŃVzÁNEFş‹ŻéńLËď­+›“‘0˘\U Ź?'Ęnе°k7R^,J#ÎůĹQtÄ|că©Ć¨šČ-’ŤđvżéQ39^şçÂ?HwJ¨¶ČŽŐÔ#!yš ÖÝű&S¬;ĘÎĆ[Ć­¨oCl‰Oţlś˙Ř÷&Ď%ÎŃoQxŤ•_„wjŤś]V?ˇď†YĆÇOe€ö%Że€µŤ*(ŃG,?"ř çÝ`ů±ç‹ŤŃ•$ź/íř PL«(ů–Ť_'Y—‚A†HjjăJW>xîÇB{čWKűÖ\Ćńb·Ř…ÝŻ<Ă3Ç RYŘ÷»?í¨gěŕÚ°$M¸ýš•ŘSqš`<ε[ŢÓ<•í¤ AÓ6!˙qٰŇyôh čw:z„ž`Gä,ŁBڧ1‰dá (Ë"$÷ •3Îe@ÍvÖ ĹĚŻ™dókCňăYk%Ú¶„ÉłćÓ•ůµśmŚ»­©’ÇťDd1yľ—fYőřů qShŕ†QęcÖ&ź6ńČfű6ަföpTCMa#ŢgâĎyšaŚ"ŢĎÝŇă|zžß‡JĽO†DCďOr:Ďżěďť“ĺCúEÔh»˝“ŐŹZ+㻲‡YB5ęŹc,Ş~˛B‰í)Űiţ+hjš·Ň7HÔ“Vp9I}‰L¶ľfô©ő qËx‹ř,gRŤˇqŻRˇ$¦PŔśč)ݱF¨f¸=AxIW˘đÉăÔéh.śť—´Ä‰hť!S“ĹęҡŘ*˘Í>äĚwŔřߎ~a/"řĹ 1š,|ßÍ‚µä¶Űę-şr‡Ű†ź±vŞéŻ;ĘZľRU ČFšĘ¸îy÷,Ĺdz˛Ő”U¦ Ž1íţds@ŮmZśvś$Îśř}×tޱW˝µa€Zń’ť4$Î/{A÷qí়eMś<ĆE?ŐŁ¤ĘqĐŕ€?9Č—ó BGÓŃOśW{ĐĽEçPDł)‰šSâ"śU­2‚D­®„O‰¤‘ĄŢt¦#¬'©y‹ĚŘNË>OÂÖ|&}3ví‹â¨ Ą^ ´~•ąř꧱敬ŹĐęNĹĐ×nů-˛†¤"üŠaZTZ ŢďQąĽ­j>ަpQĐ®lęcĺĆ!f'U0ŮE!U¦ť:@Í‹Đ×Ló–žo˝ć p1‚˘‚Š9«{šąŔRlîi"°ˇĎ-ůeÇÉ‹ÁĆE‚e*WÚ˘oFɸ˛WçĹz]˘ttë`đ§Ęˇ{mG€{‚SÍZ™ć‘ł ;٢ńCČŇ:T ¤şkĂ5!¨ăăŁ,ôĂi÷ZÍX1ÔbŤ%ę9—ő1ËĂçhŽâIńůŘ9gb–|wšĎĹ-—K‰đąÂSh?Yë]-’tŐĹ:YóÜń^J ű‰ăĘWLV9RhTa_=%›;7{š¸SD¨`^Ţ@BCV&™Ö”Á·¸vE䲊 €¶§şyôA”ă}rjcôáSŕ÷8ŻX. D-őE  °9ç}»~ŤHPĚî!.lŤąŘ{lçC$‚]LčrľŘř»LRřđ‚ßϡ±üˇX»’äÎýőÄ&¦Ă 5Ľ7) ű;ńëFA˛d”lěţţ iSoëPW)©(´š}‰Ś?ęDÝWWô’^{(P¦6ţg1˙z^âŮĘčÁ?‡Ž ŐďĐ× Ŕ~7˛6®mĐxsŔÎK#:eđcťZ´ßŘͨ•\ Ć­'ĄŔĎ6´ÖTąĚd­F–} b‘pŇMëĘcăLá(ŹvF¤}ô1uźe/¬Y ·Ö´ă’^[żv܉µb`ŮĎăÎś:"ŃDĽ;îĚw8zîT NZ—:"h4mжErdŤ§îLďÔťňxα}…™ű÷"sż;žÚ?Ë"IÖN'–ŔÉŰMnžäýîîÂŐ̬`b˘Őx’ŐbĎŤL¸f7(Ţš±´lÝ<u·Ő1!¨é‘ ĐąB›‘g ; îqFŘžô“¬6’OŔšf7:t)fmD(Y›Yí¦ŤY0Ý`§!~‚’ĹĄ1€‚ÉÎ"w¤šÓÂA˙b /°`źI·±Řdţ!FŠ«ń óĆ ˇx“–Ś5(Ť=Zĺ 5RD# Ş[MT#S ĐôjžÇY·×‡$ĹÖ>őiŽCăţŞ0đaďr™.(ý1Ę]˛¤8şMŽçX-g=‹EťđÇ_Íň‚żT/[óĹ [„Wő®]¤‹$2Úô"nH* ­§żöĹÝ=$7É%fĂ0ŐQńö‘2›ĽÎń3–o&)Î'Ęz9‰)yÁnf™Ż颤@*[v¦Áw´ąě,oâ ŔËěŠÎ”5ĄĽĚâeq‰őe)S}‚PÇC,ěł`k>OäŐ?[Łfa°®+˙ś*Ár… ľl”ŕë·@ą—â­{F%dm™j˘é]ú˝GWXĎ/ `´ŕϸĺ˘ĺF¤&"ĺîHPíŠ 89ăĺÄňÜm–%†lEąeü¦öÜŢv=§A¬Ŕ;F•OŇ ÎgćuwŞ+Y$ĎÖnµşޱ}?ë8kt5a!’|řaŕ‚«đź.(#HîÂ&NŃ.ťf‹ăS%V69ßt‘BŮěô7Ă^ç×“Č Ŕ»ÁvŚ ±mČX6ĄßguS9˝hÝT±<Ť{Ó^ ťůuŘśÚbŻüöfD˘ĚX–”ây˝ĺŰB,…b/ľ+â*L‹¸z:ŞF˛ÂČQ¸ äF™izË.Ććłš§{PqřR@B,'·ľ#úŕV# ÓFćű¸•ľ‘¨x6˙†?`±†:‰ľ }‹Sä íđ*ŁlNň7Ţ›Tm€‡A«±Ĺ„|ťëőľ/> ~ĆŹŘÄrĄs‹3ň¬x6VľC(ă0„ĐKô Ľ€ ŢŞ°éšő±řY_ÖčŁ}ĺäGČ^fÉźÚ÷MĆúšG¤Nć˘6·DLĎĚÍL±ż5.ˇ?™^€$>ĺ˝î«ó<ÇĐFuuZŰ,†RëôžmvD° h¤–˙ĺ|Ý÷E“NËDC˝vĽÉŢĄÂîůń’ŢĂ ľč‡¬†,cşF9µj»¤€Ćv×ĺÖiŁ~ÉeyśkuŐŇŇßůçˇ+Ă( ž'C±i"ůr.}Ě^>TľÉ’ xÓiĆţ0e&é»3gVęĆ˝VŃ8+)ŇÇŃN–ÎŻÁĺće»9gwDĎÍů–|ŹĎóp0:oE¬p‰5§:wÚ:©«Ĺel2âTaoç•'çD_ Ş$šÇýů8žfů°˝|lőż˙Rď% ˝gQťÎpş®vk”ć*†0=ß÷X)j‰0>yôŕźđďżŔ{%endstream endobj 590 0 obj 4234 endobj 605 0 obj <> stream xśĹ\Yo7^ěŁ~ĹyđĚ"˘›7`âc7^$ÎĄE°pĂ‘dË,;˛ťDűë·Šl’Ĺnö´z4“E€¨Íaó(ÖńŐÁţuŐ1ľęđżţď難űßq®WŻŢ…ö_ýrôëď˙Ńő˝VNBGMŚwťYťĽ<ęwF*Ç3ĘrżĘm\JćVĆřeuňćčŮúáF1-”7ë/6Ç3ީן“ço6śyÉ;µ>ŮK&Ľ˛ný8>šŽŻżŰ ĺnm7Çš9ç˝\3xT ćŐëďóO6ÇŠ õ\o1);ĺÖ˙ĆÉl×9Ă×_ĆqĄĆ5đÎB»Nób#á)yퟸÎLçhç/HŹÇŘC1n=,·l¸O»łU‹H}ŘpĂ´ć|ý5éPF ë}D:|#Ĺ:čńý|mĚ"vÖľs?ťü«?pĎĽđŔyĎ!ĘXXTu¸*ś‡VZËüK`+VÇÂÂ@ťXťśA÷`ٵŕë‹r’ç°@Ů1ÍĹú]i}[Żăf:  Ńy»ľ*żżŘĂŃÍÍú vő@Ü<*Ěő;a¶×e őj„T°`ß·ĘÎć5:S‚iĺ×?çĆץgZ—Ői đűŰBś÷É´éĚोLMĘ€O´c,đÉĆq0ĹṟŠçů@ «ť 0<‘„ŢąTČ:Őć˙‘7G¸©SĘŁ!tzŰxkjźJůŔ";ěs’í´×†™}ŤŞ, ‰…‹ZČÂβćq¨é‡\ü´ ®)ř#Hńy>j @źVHŃKÖ˝ţOiśăä\Ł”týW-śqS€Q˛Ä f'v¦¨V"Ůřř6x*/±J8ĂÉőŹë˘ŰG65ŚőËp¶Ö.Ŕd~ ŹŽ•CŰCy§Lď8 NůqSˇúmâ¸ĂaM‹ă‹Çj‹ë<˛řáDČš°`Ř‡Š ô »ŞE–žňUé0röĐe}G>Y°Áµ¨IP†Rء‹Řż7+j‡&”°ž E U¶Gä誗.O}¤[˘Č%..†XŹŹ°DŁ–ČŕĐu\“ŕޤÜ)˛Ôł˛T*‡Ď•×( ŇëéA6€ĄpÔř×IíJđx—éňžSăŹŐSă Ö NŇeĽr!Ĺ—$¤ýÂá6Mî¬šŽ˛h)))ŰŘŕďhb8ÇXČ7l8°§ÄnŐžH.0\µ˙’¤Ż iúZM9§[XGĎ  %s¬-ă‘eT|¨îp*Ó"§Íâ±Ú"§ ÇhCIT!Đj„(‰,QČYĺĂLóŻŰRCI¨” ¦¦ŐĆ´ŁŁłBuhJ ‡jÎ2VŃ˝$1DŽnJ׳–=|˝°8Ś˙ÂC0!†ĆO+ĂÇăN ĆŘ5Żd§ŞŇT’ŢÁZÓŞZve}Ř€m^"]ËŹgZş”:°P„̆暙‘lEĘjŘ 2zU´’)Ďi4űmXŠ„ŐŢŤ& ® ÎE†­Â’97ěÂąô-Ân\q޶ÄBµ~Ö– .Śź8„´6ŃŮ«Čb®3[âv @mgçâÖ‘jNÁÖŃU<^™°GQŃŔÓ*—í+F´ŃIç)°F¶¸Äeˇť˘GL"{xHĆ CŚC“CE3J>„ÇwÍľ1Ľďá<ţJ'†§CŰq×9¶}»ô hRŻUŇzČč¤ď«fë‡ĎŁ$ŕ‘:Ç:ďÇŕ;Ś@d©Ŕš8–kF đŹRŽi_Ą/ŞĐž]fő–hłě@1‰élKŘ9ŕš3*l‰¶ÍĆöŞőúmRH"žB/ݩĬµKľTájéß7ś3)M%Ý7ÔźmX šř~HoBg¤´hÜŽf9-HZB$˛‡WMwkĚI#îp®¶öLaŞyßQZ$ő&°ť‚Ç"Ź9ý›>ćhł:÷NxřcaQ2s!oňV[¦‰‘¨¤¤•°Bř!0~Ł×ż”%TĆ Q…—;‘Lmľh1tJŻ(u‡üL•íËḠ[ާ©ýé3Ŕ;)ç:(BčWL*#E`\Y•ŚśĹŐ8+AS3¤—Ćo)7ÇÄH€Ä|ľcP6¨# — |›ňÚp™—Ţŕů‚voK[ xjĽŢ ŻĐu!a;~‡4~ĚŤHC čŇÚő÷ąńönČ‘„óÁşl‰Ć%uĽÄ_mGű5« żZo%h!H;7T%Ţ#ŚLđVYoG›“đTŮűŕ‚źkŔ Uć˛%=·ÉńYoKŢ΂s¶D€¦†`Ëx&¤Ů¦›¦"tŤÜC€@ĄŚ†4ŽéJŕŚ\mŞB+ד&]bRĎĆH„¸oş’Áv¦.Ρ3Óës–qŽj'·­tJĄ ľ„Ř‚0k3Ä}Ő\˙yS…ôuxkaąÖˇ]ôHJq‰ ÝJËFČIY;Vť„Š»%dĐqZ0D¦°(E÷R{ěvaÂd~8Y˙ZŹŽtĹůÍB•¶GL`| FTV´(c´5(ÉéíĽ’4/#¤tUPŽ#uŇÉ;–D8§1L‡sč’ÄŞ&Ôműšíň®ŃIH˘ăj¶žŚÝ)0męOز$+Tµk⦠Eu ő·P:D—7`hď˛Ďi~üµ8‘;5Öyî…wڶ¦ŕ u†ÜfÚ•đésrŇ t>Q][úĐt@·ITdZ„`¤ZRś©f Ý.t uyU0 ýţ˛h‘v9&.„SMŰćq"y7ĚJ`qb›ŁŽ¸‡Ó•HĚéÎJürF–RmîXn‘¤Äĺ°Uťâ®¤ Eä=wä®t8ĎŠ˙4›DĎRxđ}z‰ö„îóóş0©QDôy¬cm©*ő*2>É]űŞ_Ix–‹—rš‹•ÚNRň° A€S#uĆ Ĺo»’¤őYŃ?Ý|Kó€ŐžĘ•’vÍçlvˇˇWÁĚéŐ2&?™oBÖŹńľÔuźf;óůrúOó9xűŃÖ’8±ÝiÄB¤ÄvłźÂ& >›EÁ™Ëľ!‹KwôG“ŚŤ·jÚ•iuzâJÄÝ$łýň™f{ŽÄű`{xXh'–şˇśTzMÚa·Ů\;°[<Śeşpîţ@’˘CÓĄH×ô™Łf:eýâÝĄv´ »{!Ş˛ŽKl|W†ťÇ§Yî–á´Üu‘-\ů Ń+Ő6Š)ŹY vI cŤeBUAřşŻ4aí­iďĺ4‘@§ů cZ…%Ivľ«ş_‰µĎ’ď—[xęż…H¬¬pݧ5‘ăĂ+a]\Ý2ąßo˘ 6ë„ZTmF. öLđ*»ô¶?b9¸KCԆɜěÇé-¦ńÚ!™´•–Es‡4¬süŇ`đ›ÔY/IůÜĂuYf”ÄÉÓbÎŇMňĂśúe®čŰuężán'ůkňpgȭɆ0µ/{‚™S§˘Cl[[â.ń5Öq"˝‡ęťŁúͨš˘x›:¦śąóĆO—r őýu+J»đžZ˘Ű2 d“Îě%ąĂž­oň` §Qp„c\$Á© mÉ™Ebš-—Řű*tmŢS¤$ $,z˛ÎópŹ5R.ť+łr׎ Ýá ‹E á\T*ŁYp]a÷DËy$Zkđ˛uµş–LÚÉ+ËíşÔÔB SIűÖ'I‡X_e" 2«—Ƈ˛ČŔˇ¸*ŐSš ÜS¨-čIŁ™áb" źrĂJC_%4š;L˛z6ňö5sÉÔ>%©`Óg)Űkp9ÉĂ˝”xn莡Ć—˘aő‡lOęJW ¶Ń.ąó0Ö%ĹvšEŁŕ­1,ŃŃę‡ $Ą,ĽżÖ/;Ťrş…Űń5OĹĄ˘ňD~ľ©ËtŔóÓŇLYÖdż˙˝śćdę2uťdćXŞé' Qj[ŠÂq ?2°g}٦ĐC`ŐYÖńéO¤Ć'śE6;ňzş вş`÷2 †čgÜľŠ€§§`a™s‰hC3ŇJžľş&T˘j?a42_U;Čl+.[©ń×i‹;‰5™ćPa0Ćę}…€ň±Ě»ÄQqiÜţqł’˛„ş™L;¸"h°ź¦O˝T ĹË9-Č«µVbČŰ8 ągCÓ¬hŞ­Ĺ $Ěe@Gv>\FxŃlť®†n`!µ%h,ŤTë?"÷kE kš/ßRL‡E2Ĺ.¤Ő‰©âţvíEUťĆę9Đ‚Ťąť1űËĆŕ^6Ş”‰¬ŚaCQshKžĺjóż$—…‹=«„fĆč§T×­ę’ű[‹sIçťŐĆ}˝WŐţô‘ŕ”ćĐbb#Y«b_Ý–Íô“Y‚Ë"DťDaźĹöŇguŔKëÍR¸i8Ă9$NĐí¨üÇ‘ÁŚ„rć­ß7KŠgOa­Ž‚ľfę†Í üľm2Ď©•"F‡-~mOt8ótŔ7ę/ó§¸unůVR"x»6íEk˛ć÷jźĐĹ„µ«Ź_‚qĺÝ Ŕ5ŠdNŤ˝ŚYWí=Ś×h7A =\=a°yzűrĐ#%˛á™ĽQJčë ,űą,Pż4}Y ż[˛çz#ôm¸®Ë NŔ°Ś*Ý©jGŽjĺčÖÝ9Y8¸N„Łâˇ˛¬›~­|ÇČI…–Ó¬€VÄa+ČuJ,±wÓ6®ż4FôÜ6tĽëš>áš…©ĽV9ů Q˛˙AUř°¨h3^ű«~ŻZx5#–sůŕ‚*'ÖҶd¤Ţ˝y­Ťl¶„,ł˘BôjK¨¤żä7%›ä­ôiöb›Ş+aQAü˛ęă\I }–ăe4aMd 0g }R÷ś-2ĚČ;ŢĺĚŤorăÇŇxŮjÄ«{-o`0ŇšoâŁIßłŤ­§ĺń˘<^—ľoK+yŤ´~,}ÉlĎ›křPúV›4 ¤¤Ú$4ă«á&5(Z+CAˇŔ|˘Ł‹ąî[c¶,µž—ÖÓą=\–Ö3ôm,ÍRÚęţV^Ă)8mDÎ#GĄÖłŇ÷Eło9Ş Ş쏪Šlüdtx®l6ÄW‡gW¸ §üP~ÝÜŕed*ĐPŤS$}b€08…yÔú´<>ę)ĐúÚĹ`„Řaljw—PçÍ?đŤ9?Jź¦#ĽO|ç7bëE“)®rk.Űřöč‡ĚzAendstream endobj 606 0 obj 4581 endobj 612 0 obj <> stream xśÍ[mo·ÚoúôďZßšďKćK‘ć=HŇÔQŃIČ’,‘tŠtŽ+ýďť!ą;Ă—ŐŮq‚ţ Źgžyf†»úq%ąř/˙÷ôęčÉS)íęâî(ŽŻäꇣŹdţ‘g­ţr':¤nuüüH Á;md’çĚ(Ăj“Z~ĺĽ_VÇWGß®?ŘÁ*ÜúÓÍV .§íú}öüőFAKaÖÇ›­T0Ł_”ťë§›­2~0ĘŻÇÍÖއ ×<űÚő7ł€Ď6[3('­^ «­…ńëżăfŁŢÉőI®¶¨#ŚŰi_dľbË>Aäŕ„ç“?e3>Âfc…ńČN†éi·B‰iî?6Ň ÖJąţ+›@ľ˛ ďg3ľ©ÍWă°!Ňd„˙×ńçŮáav@‡ËŚăFPŞp®‰ţ%ö„(çą­<·ÚŞ…ZźÁú?Ŕ"Ą®}‰ëĄF­÷yT»ő-ŤîŇŁWëKĚŹ.Śë;x”D3MĹ ?Ńă9Í%±¨¬mľ8:ţă·\‰ëy»Jłfđ¤§Ř÷óŕ]łś-Beö…ŠĆ©VÉBCÔŤŮę¤1@Ţ7†K|9˙~E;žÓď ť ~€ăRoK«E±zýşË…r_da:Ôh·iîMwÂi!7 ¬˛óělôE)LĘČŠ c»˝"uíŔ–Ý7šá˛Ëj·:6!áOJ?ňÝ®itßř‚P‰"*%Ä‹4[yŐq™/PF(lU–g2ŁÍעyŤËŕam]ă’ ×űnţýľ6UŤÍiÉŘÍ—,eż˙¶YY-â./űŤęż§Ŕa5đčTíNľóxŠqSŹ’H8«1B‘Őô› •‹BçĚm~ Kşpż¨‚­|Ď>ËMČXT%2`W˘$Żţ·¸%Ć06Řţ¤ă*¦ł=~łtÄÚTF&¬věß]ľ×·]MźŐaş‚ÂÁď*«°©TÉ|ńqĎ]ťŰ+îň‚ěq&”Q.hw°–;xeşëš˙ŞŃ¶Ę=SńŻĚĎ˝CaÂÚ{Ňś{¦ÇçŤ:U]}NIŻřŞ´Ěę4©°şôŞúÓDîfę«K–랰Ŧ­Í|Łűo°U¸1źPŢ<+¦=y*•]ľÁZ_)č\tđ+Hȉş"cŤ›-q“°žµA˛ěچ`ĚüVÍXTAăc{Zv‰Żą„Á7†;˝Ŕpj˝śŢDz/0Ô`ś‚Ń{šKbO7jĐVX0ö4t»Q°D.ś°ÁWó îâ4,ˇ·ť÷9ŚN騰ť#,Fiů%ýž¦Zl÷˝ť‘2„ bü•kôVzŹm圆ÇË XŘň  ÷>ÖfÚ‚CCůŇö˛1?OeRO“T ˇô‚FoÓ[Iˇłüřâđz^Ď_Í`.­5l«Ů›Î}ÔT‹Ť€Ź®h/ÄcťÎ루Kš€sbĐ©ŁśŽ}KďJĐz´]–·8›•9§U×´Ăžď0Ż:Ąąy3§Q…‘źa‡ă 4›{ß3ú‚~żť_ŕ>dX?˝ŽJ?gĂ" >ĘňÚů ZŻ:řHÚŽ™T±ÝŢç)ÍB‰p=Uv]ňľ9%űb4Ć……čĘ:i"&'ďIÖb»˘¶$Öő"/ ¨®©Bp×[”ťšŘ"Âë(}ťv™#´T Yö*…«¬†1&¨,U6ó#°€łďÎőŐ8Žű’×Ň$0ľňU rVpţ{â·Ó^…ÁôyV¬WZ ŘŁ,&•,«˛ŕS…—Hâ –=ňo g$uCh«&Ç6¬řúJIéĐ]ˇR?d컎ˇ™BIz=myý âŔ)±s]ä”·Í`±Lßóő­ ?łD.J€Y Á©h¸Çfjłń™6*ŠAl‘-¬bíkĘŔxSź?Ćä%%Şű÷4Ęş<64Ő.¨ĹŇvÝ壅) ęĚ·->mÝJ#±Ë˘”´\r ůMKš×ÜHmh˛âş=Ą‡GÖh°X˘Uum&@wYĂ ţ5…âDă›tD†Ť—<íô8ý˘đ70śyş 9ce§ ×B|·¦ÉW_iÇĘăźě,ěCeöÝôc<řťľźŢÔş·~ČOň¶ĘĽJŤ0{Ń?lÜ µ‡vä<×q°ŻŁ×IĚ,tŠĘŢ',GVˇ†*bJŽĽňjDŐí,Ót‚@‡Ű»_L@XąŽGšń˙łë˘"MĹ’íĎ4řÝf†uK=Ł;Đ0Zjż †15jÁł~nb}ßI·Ż¤npGżS‡y—YEHţűóüŃľă’^Ě‹bËďˇĺ7ďÖľšŰŰ»ÔÓâŕ—(GćxnzOă㨅czśôND›cŰ ×N’{]öwe-/9„b(x趨†ŃÁ[Éëd^oů ş †i{d?VĹoçj˘·ĽˇSĚ\ŃB§{^ź^ťŐ-fK„) 1 ĹĐÜ OôłŰE>(T#DÎ,« •˝:b˙n]}üĂł”ëĎHżôŇÂ̇»bf™&ąMĘVŚápĘď3fÓ÷ÎĄ˛®fâQÄϧNz”Yy((4HUKbÔtü…Š"mdŘß8±‹LŢŘ Ă¨„wfQ¦}N‚Ł=xóŘöxÎgX&ČŔÝQ ŻE÷u5ź0-¨lěÂţ>ăHĄAżfŤ%;čˇîŹú4Z‘Řżj®XŞĂNŠ+·ŕNü]T úôa´¶ vĹď–b hČ˝Š}ť!?ňfŐLŮGůZĎŃĹ‹đî•wŞf3ő~N&MUه,§öűôÍč§ß˙n†w}Ľ÷ÍÇ/?T`f2ŐÂőŁúöĽ|Ď”Šö^Ŕ'v‹öÖ†Vş:sŐí·Ä ńG®¬ŤMćGÇG˙ŤĘ@endstream endobj 613 0 obj 3316 endobj 621 0 obj <> stream xśµXIs\5¦8ÎŻx7ŢŁ2˛ö…I 1•@–ˇrHqŔK<©8¶3¶“řßÓ­ĺ©5#cs ¨Â/šV«—ďënéóŔ™8ţ—˙}Zě˝ §W‹¸>áăâóBäđ,5<^EA KLpn‡ŐűgÁ[ĄEŇgµaׄRĚÖ[řeX}ZĽźLš©źMKÎlV™ńgňýr,(Áő¸š–ŠÉ ť÷Ó§ĺb|=-ĄöLK?şii÷!¨‘Á§Öp®ßĚ ¦ĄfŇ ŁĆ°‹)ŵ˙ÄĂçŢŠńyŇ« Ú ¸uSÎĹE˘áw˛íW´A0Ë=~F$öQB3áŚ.[Šé´Ć"űv–#Äř¨˝O‰ŔO ÁjĆAâÍvř¶Ü¸?IŘî˙Zý–X°p&\d„hëŔ¨&ą:ć#”F3f%Ň ,3°”, ĂÉa)hć°v ű!ź‚y§­Ç|Š”SUuVĹ´ Á04 ¤wĆŤ›IJ¦…ĐăEÝu9)Ü$őřw]<­źdő˘ç¬ÖăŚ7<Şé3ĺRčmđZŚ'DÓhÎę˘ď¶~^aŕµĺÎuĂ*á`°zľXýřÍ+Đľ¬źWŕ‰±Ü:°a!šbüŠ=„V[üHcU2ÂZ#ěřq‚©ŕ=X;/˘9â§,zU_p‘FY‚ŐëxâNĐĎ“*@ÎÍÖz˘]˸÷tW9ÁąoâďDŐͬę¬ţŢ7뵕#l*ę/ćĹËŠQ˘ętţ=/ZU¬Ž1ţĐ8E Ć3•čx^<©űĎę~˘ővĹ8ĹD?h…żŔeM\“?Ň(¦$1ç¨zB4˙‰@Ť*Áq8¦!H-)YJȬ€DĐ ™ťu\KIýľ-x ôuŐ@lŔp¨)V¶«ů\ôz™Ý^B)ńž‹ä}‹ßň‰đóú”E3•ĐĚAÉ”ĂĂ›]‡[ÓĐtî@:Ęrtż©ü“đLrPű•¬žÄÂ$Á‚/ČFp¨Q»™zäřŁ —¶Ůżîě"“űěôîĽU&ş]hć"™ ”[-\ě–9<í@Fđ}ŢkK7˝! ݵ–Á)»ŁbEçíjä ]Ň ÉńsÇ1ö}žě2ńDRSĆőp72Ły;–l¤>_Ž(Óu^©~ĄľnP٦·ďy©śC[§/]Ir~q%•ç‡Ď]éމŃΑNZ3­é0fXG !{ĘňˇwŸ©ĎÁă1f¶´ŢĄŻÉŇĐÁřŚ7*` ».Ĺ—ř’üź›ĎÝPĎU®;lUlŹčqęşníÇ"+ÍŹ·©“8}w pş¦ş…¶fî´© é‰ĂasTé倗7Ĺlň]˘6ă­QÝ…/C°´ś7°&–ű«Ĺ«ĹçA(]3>J:ŹoŽĚżkľn>>X켮77'‹˝·Xě=Ă˙=~ůţ<ľ[ě ŻţőĹÓŕ‹…ńôL@*í $–Čôţ%ç×ę?LýB$‡´‡8ŕLv6$§VÓŇ2Ĺa\CV…¸ĺۢ6)=äˇJ7ůðr^çxuĹí:ó×BÔboĆ-/îáR~: ®çŻëů×G‰“P)Č–¦"U+‹—íšEP੠‚Č—ęqč-‹çŮUîČ® ßâZ„0ë;Ęof˝ŐâhfŕRm© ž,lĘË^ĎţÍ®iŹRĹÁ+uľĐNĺ@á±5&Ĺ$śĹ,@ÎŃ_Ą·!ÍCyřâ­ÇłS5äřf^ŞaőčlţŞ6â 7Śž.¨üŻ˙x¬·endstream endobj 622 0 obj 1869 endobj 632 0 obj <> stream xś˝[IoÇräŻ CzO»ö%@8N;°łČĚÉČÔ”Ф(R˙}Ţ«őUW5g(S*U×ň–ď­5zĚf~ĚđOúűő»ŁŻ_q®Ź/?…ůc~üźŁ÷G<ýĄUÇ<Á…B 6#ĚńÉĹO¸”ł;ÖŽÍćßý<}»áłÓƉéÍfËg-Óé(íźnëě=,őĆŔč|#f#„˛ÓÝf+´=—“+›ţ}ň×L‚š­łI€UĆ1ţptňŰź§7[63Ť“Ó ,µ”bÚá¬UÜ7=¤1·fş‚ ™ň0{ŽôH/-ź>Ŕ6Ë8Ë÷qsě@aT¸OÍ&_vąŮęŮ9ď%ň“‡6ÄŔŚťŢéŢh-řônł•ĆĚÂ)H^zŠ·Łą][©-°%¦łşŕĽ.HC qşĆĂě,´AÎp­łů»‘®Ł@2`벬ĽíŮáýzć0{_7ݤ›¤ßt¶ánć@ŇCůz™¶(ŹL«Ů™’ňş2r‡ „á••¸-Łáç×őv"’Ęri'ŮCŞ çÍÖ(PşPÓwŚ9,K‚19ý—Ě4Ŭ„ćÓÇŤ™ą‘­Fî6’ŁĘÄôŐa#Ś@S`Ç';0†'倌Dú´g.íÁ"“ ÂpĽ …ĺ"k_‚=ŐŃÍđ(ÄX®ń.#qALŐ42µM\mą|ř^m¸ś¤ĆA¨Ňjúů‘šÇV* HÓŘŮ’tz¸G2Í,yÖ(®Ľ@Ľ{VćcŞf+·u’ š(ލńŔŃŞěô Ń|µ–d"‚sŞĆëŤd@§`dŕśNögĺř«úýqnFŘľBaÁń\QúßPS”çE4Ĺp}c‹UEě7 OľăIŇÍ^R»ą¨ÔŹĹw]˝Ćy>¸f‘Ýa70>Ô!Y{_ýćů—ČŚŔyľÜ(—ć°7őŠ›%Dd?ŮÜ/îÝIKČV qśE,"ň“Ţšď5 óJeF|(áMoQWRaLµ-:ó÷± >/6~´jđK\ ‰fDWčîÁ÷ô¨»$´R“JÎ\ *€°[íńT…Ń_€ďaĘÁě–p«Â\B¬ŕJ®Eˇěű?–Ďo#îYpßÄJ)Ěě,5ˢzx+nł_¶ä^¨ć=BŐŮ I ä1-•–PM!˘>r˛ĺĐ0±B†Î7fťőÓ§ŠüŢLşŤż5‘ŤçeJ™÷–ZŃuÝ…Ç*PĺăD‡@c©ďĄóm±%Ŕ‘릂 Íć%° hśqÁ_0Bz 9[“— ŻRNÂÎRŐ‘3oGL‘ë!fîg«íjĚHKc‚+ś¦ ®€0ÂTFr#€>ż\@í0‡~fŇ»AzDtó˛ Ŕ?Ł´ Iäî§i¨Ĺ—K”8ćôaVŘ‘˛°±É” #SżÇś’ůŕ:%äVLSëx¨Câ­®đ$LE]p›“nűDQĘ7őyěří믖Bˇďçô"‡Ś/§ÝÖ.;kφB÷Ö›†ăJ3ĽZĎ 29;âËťY“Ś^rGu>¶š¦_Bń“ żůëÓĄ© $pXł;<ŤŔdtů”'ÁŰqř¬f›^y©\ć7äISťŔĄeJ,ź6şŽś±žO·Ś“(b_]™˘Äő …IĆ›,éRQ,ú\3*m|ăͱ®X-š6'K5Tó˘+Á°±Ďő}…ë×őĐż#U:Ľ’ÝŽś]En~JPmč"Ű6ä>4¤VBX ÔJt©$ôQ].ă+hÜY©˘Ë›żä!-«¶ńT!ůÉ-ó%*Ѥ-űcś~±ś|“P˙Źr´`łł"9{áJíl­.]ć?‘ú¶eö"–˛—l¤ Z{źĹ:‚Ä= ÷ČkG§iűj\(”¤wč¦ öâ¦é»iđ6mÓ• ® ™ÄÜRaOŁéyč‰'˝ÜVÓYWŐk7;ؿςąŽ~…05ŹVżÔcWE^P&ô ĄD«zS şSü5ÍÇş´KŰKO/<{uď- -úű.śŐ{ “ÇŇÇBB07ÎüL^ĆŻ5¤w;nşŤź6«y‘ĄMĺ‘đ&HĘÖ7^bçkt>BEŚÍεç !˙ÂĎ…¨o¶îäŃ…á›řżH ű ű0{ęôÇ2Ż6ř› ‰č VŚ,źź‹ÇřĽg{ŰÎŕĐó—+VŇĆLj¦Á;˝+Ďöj\‡GU:żžä†fµ_ÖsůŇţ•(öé }`Zé”udVé:je„~’Ňí’óPr…×a3»<ěÓöŤdXáŢT ˇ Č›5FsöęŔN0:29zIż Ĺź÷ăBxź+ýUÁëĺymuŇWĚż+ĐHAҸćE’F|Ńrb´¬ďŕTĘ9sčĘäŰ2ů®Nţ(ńüŻB{ËłĽç84>tĐňě§:<«ĂÓşöˇÎ[Ę0y1ýó(1{ľ.0uČę 0äăfϧ_×m„źó:ĽO ”¤Dľi×BJÄBl,łwCŇŻë,ąí]'Č$ä-Ůĺâ°LYZéĺ܅ʤ$häÇ˝_Ry„Ľg*2Q §Zx_óďvÔzŇ= ­kŐD‰q]9Ń4őת‰čďG.b–›C’ćXBžQ«Ž}ésŰďčBPĆkř Ç ˛ô±ó‘hPıÜÔáŐ ôęđUž¸›ëáa óEÂÍ~s;ô1ÄCĽ޶+C”3ú†H«44Ä‘?y~S'_Ő;OęěŹÝő¸ ^O=îŐČń ˘K/lW‚ń°®ářzŚ›2ŮŢ#Ľ§ě_ âUĺiË[˙{8áwÝ0y‘đfFgŁ(ł˘ëŽŽ«‘«¬n_‚Žgęô®L~ŞÜÎ>SäíąmáU?”ÉĎOü[oĄóţYüw±›+übŕ6őś*U<±)Q ·ţůäčźđçéŢ“endstream endobj 633 0 obj 3191 endobj 638 0 obj <> stream xśí\mo·îçű×O˝+r4ß_´€íŤZ»NĄ)Đ…l˝Ř°-ɲ”Ř˙ľ3»\rv—«˝=ÝşFW\.93śgf8Ţű%gbÉńżřďËw‹‡Bĺů‡EŐľË7‹÷ ˙ŕ±×ňŃQŐŃBśŰĺŃŮ‚łŕ­Ň˘Ďj'Â2µ Ą_ZoáÍňčÝâ_«ÇkÍŚÔÁ®ľ]o8ł!XeVÉówkÁ‚\ŻŽÖĹdĐÎŻžÔŹ–‹Őáz#µgZú•_o ó>µbđ¨5ĚkVĎ SŠkżzŽă:ν«oČóŹäůi=´2¦™h¨ř÷Ń_#Ó+­F¦E”’¶¸i1¨+šsĺŇc=´ž˛QÜőËŤtĐČĺňčľ˙?DÍ®Z_e{#(›`Ä€&…­0çpm%4Ăa™óG”·k +…Í0|›±…Ór !P›’}‘>úĂÚ1çpôüq%QڰҲ2}Ë# É$·đâBĺ]¨#€ębąsW|ČŔ+ËQ´ µą6{Úú{D pb|QF;{ą3-9Řvj}O×RBä\ý’,ţi¶(×k…¸ Öş6=´hzŽ»2©–„B´â¦ç§"ŠIńş‘DšóXw ©Ąĺ¸–2­:DŇÄ×ë ‚äo"ýM×eÖŐ‹–ÚJĹ™3O:śˇť@ŮaeoěřDe¦”Šz*˘ä‘,8Q츲"‡ŢŃoČjfOĹ0ŔÚW´óÔ2|AvžżÄúőĂ~|<Î}‰áÎö·q5&»˙űR„燣˙-|ŤŔ˝ n|M;ä=)ŇÜv6Ť4‰ßş.rMY$˛4Ż‹ŇĽiÍF¦Đ´ÂDL¶V8ÖI^Ĺ>adě{ÚZpQŇ,Á˘(meŰE)Ë,çşVDŹ*흲5䩬—%ń«DUmz\Ҭ¨6L(­Ń@(m¨¬ Ź\\0Bt^Öź‹€Á~î‚›Ţâ׎[´u€hç·ÍčĘŠ˘·…h\ôť9ĎvÄßى $ `ËŮŰ…ęřš|Oö -[°ΡÚáŇ€łb:Ĺš•Ý #ăN,ĐqŃÁĆBŔÎÚxAö˛["ĆKq3!ë¬fKŐríđąsiwŽ(Ű>€Ľť*u)őľ·ŐPdţâTeNdIbô† 9vˇ’ĎQíg,xăf_µ}k|8KăţŰâú\gţHÜ*Ŕ#™čü‰¬:«šĽč0+ŐŞ;;° ";/@ÂOÚLĆ]JÇ{WRIÎ{Ô źڤ÷ĺP6FGÎŐŃQôŇ=^ŞpCQ“+(#ľž¤ŤŤŠ}ťŢ#§OŽß/Ţ/• ’ů*łyL: _TĐqŹiĘG‹Ď–7×·§‹?-ĹâÁ·řżGß=†ľYţnńä`‰céf !9d®ŞţÝy ę±—Ŕŕ;di—ĹäĺÇ )÷!rؤN$ꎴs!+Śť\*3f`‰Ű¸-9‚ž:–ôZÓžĺ0ľ;í-+Ętöe‡Âf÷±¸ ŕ€ó-®uúQ(ֶ̻läH‡´ß]°ąY’VUkYz;"Ų ęú°˘g¦đÔŘrěőîMd̲7ľčş"š;ěxvŇá¤v Ö›ŐĎ«Lw7Cá ÷<.zKâC>Ą®?ŻqZ·}—ń:)V˙ Űý“’ĂRµé*0 5cö二Ń ňT¨ _iÁX#Qw[ ćŃŘb‚Íś›Uř[¬ţ†Áý`O ¤ma0ÇŇ­čöNN×€ajużP-!P+>ŃkND ă•Ći*µě†/&čÖOŢ×ë e°Łđš›i€<Ýâᥡ•‹ňAS9ŃG}‹ş%ŞcQ{Ëđ P>ĂĚ·7Z śŹ‘(Í“ÉÚŰŻJÓëŃší×_ę °·‹8„bBfĄt3ÖE)€TÜ™ĹÝý(q„Ń<JÉgŁś®4ĂTŐáŐ ‚śč\§úDÉ8 0±Jné©~c†OĹIö‹2]l“Nçs`whp…÷űŮ! ŻćÝ!jÍě9ľ«Wń ŮM™—&W&mŇë'Ĺ ¤\ˇt¸Ö€ L%>'±N]Ď‚łqü x‡[Zńąe"µb˘-bŁe˛7&“oKuźhzŤžxUĆTąFŇhŰň¨Źc—¸Ź;PŐ´d‹˛şÓ6OW–aTs«÷“ŕVĚk›Aćr)ń¤ŕscZ´@Ő` şç–ŤÔ8/‘MŰorŇ6€ŽĺE€V–ˇbß;ľű,€Ž€ÝĐŘ8†çžNTŹŹŇű pž®p-ź•8ďŃ×)]}ŐíP•¦D0j1îÖ¦ëĹ0Ť›îĺúr˝LŽŃ¶‚ÚÜÔC(‚ĺ”úěv6Ů|“ďą›8ÝÄô´WÔëuŐpqťL7Ť˛.)Žý{űj_ăló¸ÇEíÎ:?ŞÇÓ…>¬ÇZO«¬Ç¬×¬y§*=†éBĚy“Ę—ë¦lTyç&ąNtPŠżDÝĄ»ĂĽŹÚŁľN—ó°ľ*9y¬˛ľ*ćM€ÝEË%1Ć®W˙#­EVÝń—ى—AW»yBüTWŔÚěQu˙ITw~5ž.ôa5–|ň±eYŤE0óîŠÁěB‹„Č/Ú°‹˘Źo„’ňÎM2ŢŐ‚7„äZ‚;MĽš0pĎ*u<Ż*L¬j¶´*“Îo©ÓMţ oŰ·˘‡çk\d ;hĽś¤’ŢNPčŞ&nTG•{ú˘ +7w÷;NĘÍťśwwj8žŁ‹€ů„ZUĘ÷¸IŮ’ü]©&®Kz¶NŠ'z7xÚĄ[Ł0š[8˝8Ů©Fs%wĐ­1°J}í‹!^Oµ2µ‹PC?}Łiă-٬hń–e;ŠéÄŔiňŮg"€#›wXĄ’đÚöŰa`L5g§˘@\0J3QÍbIäE'Ҩ t›Ńć$ńޤF9«8Şś÷OŕÜűgCx˝–†qĚͶşńX¤"júWž?¨đÄGÓ´ Iâ)G=ť$jU„jBďţŹđJN)ŰA߆ëeŘKjUŕ­—y‹ŔV W…ęČďĺǧąUeźă ~lŘsó$–%·x*úr–oô“űęŞË\ýÔÔ$ëŁsqçęŠ/yĽÁÜ V¦ł|Y$Ą|{±ˇĹlqÓ±maĚv vXŢaą=]Ô‚fľ¨qdóE­Q‰ŚŁ\ic¶ÇŃÜÂŕotlą™ŰA˝†qlöt'OŮďäŐ8ÖéŰ(Ś3bëßś ăąYŠ0ÖĄ+yŰŁ8×…Š÷‰ˇâÝň~V‹ń˙†âÉÚőýâżÎ#;endstream endobj 639 0 obj 3456 endobj 645 0 obj <> stream xśí[KoąrÔŻăL°ĂĺűqL˛^ÄłŢő*Č‹dI–Ű’,Ë+ż>U|4‹löĚŘ– |p«§ÉfU}UőU‘ýnĹ™Xqü—˙?}{ôí !ĚęâýQĽż«×GďŽDţç§V<ŽZ¸Ĺçvuüęłŕ­Ň"Ígµa5ÝJ1ż˛ŢÂ/«ă·Gż®˙´ŃĚHěúĎ›-g6«ĚúäúÇŤ`A ®×Ç›­b2hç×OŇĄĺbýbł•Ú3-ýÚo¶†y‚Z3¸ÔŢkÖ…R\űősś×qî­XG®˙F®źĄ©•1ĺ-xůsYĹ?Ž˙’…,Xi5 -˛–´u M# Žk  ÎĽ<ĽĚ“Hł0­!0ÉVvś\mĄ™9Ü;ń0H0ď´ő(hR9Ą×bén†™ '‰´‘°v…H=éU+Ô› L[)AŻhŁÜP6)Ř0¬Žź˙ţWj„ËŞîsбµĚŞŢśm7i­±č‹ŤŐ̧p2é9ÇŻßn¶`.i¬ZßÔyĎŇĄwëUŹo6 °U܉ř^ŁŁÄWőî{¸ëÓa}‚Wžąő+ś^ZaTž ç$˝A4ăZŚßy;tľŕ+Ďíú#®Ă3@Ű)ZĆ‚"Šqřő4üw“J.ęĎuIwuť'u¦—ă·đ%3ľĹo§ó|7ëxĽ±žg8ҡ}X?­o˝Ć»śżć.Żę¶ pąAěH?yđ„\b¬ vFŰčZ s“Ç©Îęĺyć¸ö7h𠽾ŹÓ‚Ď Ŕňh 5seŔÂőzE0ZD”oóR·ŕŢs‘V<i„¨±LJłţ'ůůŞ®â ˝„‡áŤľ€1L}žh¬z†' ÁŚęöŐd™óŠęńžN †ž|3,yôv´{ʆ;ú‚ëŚc®a`/¦“XBÉM'V|˙yµ>`N Ž=⢨*ŕ¬GN:Vą[ß]Ç#vŘ™ű<*>z9=zľ_Ňnp6]Ŕ˝_äč›Ö&Ôd8^Ń€3GŤ( @Uťö—Ń.o©±ABpexŻ7{Ht‚äőPź|Y/ł€–úÚäę&pOL\&Ęż’şwŕş‚ý¶^R¬MÇ ëÔŠä@šl %•LC˝ń>Á…+ru—m„Ąkyą‘–q ÄŕĂď+ŘΫ'g\J{¶¬¤.šŠň±ŕV`p‘Ć1)Ôr~ĚkM/“ľ[Ů”c3¸ß——>ć ’¦č{RµC\…\ŢMŠl´'<A¸™őš”8ëŇ-†"ˇ÷ú×§%Şyť–ŕ“ ¶‹E–[GÓK7˛łšŐ’Ż8%IŇk$,“¶Ę(PşŰĂ"P§Gé% kd< °4FU]ő†ë#ßyŁ‚Ćű&–xŢäÍĎ”fşËÖSjÁí4Uń.EsÄ׌Ľ iB„„ÇyR-ó¦0äŮ©°/ÍtGREĽ;Č9ÚOÂđwˇ 0ö2žĽ¶fřü*HŞ„ü˝Ą&Ţ‘Ö> ħłKŐBť4ü§š9oB¤(7!\ =óoúxŃv0^Ŕ°jŞm"öĽ:ŞŤÓ>v”¦¨čŐÖ†ůߕıRq|FKČ›1ĆÓ‘*‰ůAz, ÁĹ”ĘŇÔ˘-´kZF¤f…ßMlSÎúU8×0Ş9Ůě|-¤Ţ˛ˇqÜzH ±AJ[‚<Đť|° óÖ¶Éx»UDLż°°ÉŽřqĘ›i‹Ň•âʶw›X5€_4nŤĐ‡Aó>ŹŔłwmź˘Ô HÜ5i±N §p*! ÁmY‚˘Uč!î…{aGĘÄÍčYĐnÚöô ×h66Ň—ĹşS}eĽ<Ţh2sd‹ĆÍJĺ$Iô€©•K<ŕcöŽź‡0ŮF A]ŕrřěp§â_łZ|Úuę· ç;Śŕedó«ß[ŤAůÓN‡TŹOżUtŚ}é¤ őm/«]ßČĄ°Y.d÷ÔÁ‘(hŃYą# źgÓ=Űżăó¤č謗jÂŮţo˝ŢzŁăp†ś˝~:ĺo«†ž'»ˇŘ?Ö¦h“=q(xůy'ŢŽëQű_†ÇňźNŔř—Y8HЦG<=Cvĺk,i}w}übúč`&QÔÓL"K÷PŞÄ;ú ÎväÖěR‘¨{s€8ť őĂ b źźŕ˛1@}t^ŔtîZZ ¶Łűɱ,¦­É.Ân˘$A2g|¦ipn č…:žś}k‰5&`§»ŁeR$\I7>±Żé9¬‘É qcç¬AëhëŻůR˘¸v1˛jbvĹ4±ltĄç§ô¸P‰Ó; ß·±[Ăg^u€áA:ĎUŤxä#%b čâSľ~‘őë—g勡<ÉqZŃsIĄ•ôŰÂA©StâĺryQ^µoýô|I*Ŕ°ş?Ë3/ĆŰšcÎ+v5V.‰jܲß}0ăYůXÇćş‘\Ü^Č­±áĘ–óĂP¸˛‡/[Yě¬)ş/uČÂ0Ď>$YŘw ŰÎsSocý¶Dť[ćJ8¶f§z»śRÇ·$đÉńŃOGr(‡|¶š_Ü]ěüsđU"ö”]aÔűôUâđäě/„Ę’Ź&ź KáŔRÜňńă…R=·Ł«¨—ŁX3ű´/*­lŔ9ě–}­MyşY„ .eűŞ?·đ>o×žŽ‡Ú™ŰÝͤ´…˝=’Č{ÇtŞ=ÎśÚż®–š†ş°Ű™Źß ÝĹCÄ:ťˇĚ:N]6%±·°o#qohřĹÜŢŞs·Cí˙Žą%"ĹyŇ'Ë@Ý™ÖÉwN*ʏžľ¬=›®ä&Ęö"spÜŢÁ*Ę=ň<€Ęjŕ‰^Ą' !©sŢĆ« ±áWîĹŽ!dšňu”‡"ňň­ďw‰Z€-á;dÉ÷ŕůÎ"¬Ď‘ůŕføô$Ěg_Ýy;E“«˙®§›»ËÎŽň63Wŕ•^’BěűŃkk: :·YíÜůjmBŃOG˙lĂQ|endstream endobj 646 0 obj 3499 endobj 657 0 obj <> stream xśÝYÉn7˝ë+ćŘdîË1‰Äo @ś=ÖË’¬%Ž˙>Ul6YěćH#K dCÓl.ĹŞÇŞ÷8ś‰ÇżôďúýÎw/„0‹‹ťŘż‹w;vDúOŁ?¬â@ ]Lpn«ý΂·J‹a=«ť‹Ü'”b~a˝…/‹Őűť?»{ÍŚÔÁv?÷KÎlV™î{Ň~Ö ”ŕş[őKĹdĐÎwʇ¦ĺ˘{Ń/ĄöLKßů~i÷!¨ŽASkŘ×tżÂ¦׾{Šë:νÝ#Ňţť´w‡Ą•1ă.Ř|9Zń×ę—tčŔ‚•VăˇEň’¶NSPG›¸ł ą‰‹,8ĂÉĹR:XËĹę- ghlĐ~Ô߬†Sv'ĂÁĽë|Wć…n MăŞű)űL:ď—šIËUwŃ+f,·®»Ä90>#Ť‘b\ývVšWyÓËĽ(.4ă*řĹjwgőMeńél26qO8Łwššü”„¸ś­Ú„4 ‚‹ľlnl=x@`¸é$Ú ™2šŁζxŐóĐ}ěSZą€łĄ–Đ+ŔY€®Ń–pfPNj0pl]ĹVF&ń|?i¬Š§[e»bĐëŇĽ„đ9+áű^´Rš6Ě$x¬íů&VřĂŔŠ.ńřĐý!MţOÍ&tGĚúmĐťîÁ5čFL_後î?†Łz-¦@ׂXçÎ@§×ř ú-®ćş€ J®l7Ĺ›”§KŢéOđÚJŹîŔ˝łÝß˝gÂXpv„ťšÜ &«Źłđ-rZśOrTżÚ⻊ÔÎ(—ZhänîS%’®jŇ⌹F„1Ĺh`gëŁ7’`Ž ,d«fZŹń?óÜ6%—PĐĂâˇ=čUâ č€UᨻĄW•i.;Öá‚ńŕ»÷%ť’ľ-,˛„ă8†Cq'˘ŇÂC˛ÄQůNVmÎŹ.˛pŇăŞcďl  úŽŽ=Á^ĹDÖçe—´…QÝ›ÜIląÄĂZ&ˇDťĺďiQ«|Jx&pO{Ź 6Ź›Ł-bzóąÖĄ÷0ťŔ@e, ˛6ď‹cŤaÂŹ‘»ŻJ`.{D„Ŕęů@çĎZqCH8˘ÖŁýxŔ“2t°Ú ¨˝oJ/ń™Ŕr0*”S˘ă’ŹťDśIµ.˝‡e/˛AÄ“ńRFŃ’Ž·IݤEŤ°u„†šaR©Čţ, Kč´$3:rÜŞS]ζ”ô»W:O[ÁČÇŁ‹~ُc&•ëtZ.)ÁŇáÂÖ–JHJ X#űűNfNǡë&ngµ>NŞ©SÖôj&k7 u’ë ĺ¨ŕ%µ`ô÷Ó˝D`Ľľ9'Ă}€"¬U¨/ÄĚ–č. ¶Ś! Ô:(\÷(§•°5,Á> Ćëd$Pk8CjLz4á&Ę…±’DŃť—Y0ç)y—ٞôD8…˝L>Ě-2i?o8ľÁ†/Ę{PŢ‘<•3\ ť;7{ "Vn|2[h1éŔËĵ(ÓlĆ FÎě[ů~K)&­úţß)1é ËÂ6—×H˝˝ťĆÄ}ë0él¤wŘÄă$ę´v•?jşę¸°ŐÓT:!-fv;Ţ pę)D‘<´_é-ô$˛íŠ‘ŤQZÍ Ul×ăóÔtĚÄôśŃ~Şňmm­š*wtÄŇ›÷\T,śTNŽC&9ľ­ĹškŐ˛*;čE÷íçůŐV©Üąń;B»p±süĄÉŞ˙Iv%–Z ¤XLc#ťËż’_3ź¤â =k©6ćËĐąZßLľÉMĹšnÝo„[źüÇë%ĐdćIÖGˇ˘ĂAž)||/“7”k´Ë`(jvŕ’ ¶ťtsíBµEjń93l‹ŮWqf Ů–…$˙Îň;ÔCB<ÜźÁY´‘«S0N€?Pä1í[4[żŢîŹŔHĄfzMgW3Ô§2t™Íš˝íL2|؛ᥠšdŐúE ŮťçvËÁ:ĘK¸7•"Š TÉę] c™ţ Ň*Ed%¬šĘ1%M˝@˝öî˘w¸6 ďôxm>_ýFGO˛JdĚaKR1}źhżýŤ‚ś~o(bRľŃLiHSE9¸j™ĺŰý+Ę›ŞÜ,AĆ«ÚGă$(˝á~l 5ăĐëŐ=ěTcé/6÷” pŇáMKť$VŻź·dcńçI§oE+_müť‹ŞzWrÍ=hiş˙dS"9§űÇjŻh¬*WB~‡řMx ĆEľç\0;Ň–\vtţ¶âľ~›Hçą­¶GŹhÓÝíE\ŹŻůEbs¨"”ÁKÔ±*)ŤŐ}çĽD¶Ú|]!•°¦Ç«ťçđ÷/+&}"endstream endobj 658 0 obj 2171 endobj 668 0 obj <> stream xśÝ[[o9–ö1żâ<ŚDź§ń˝í•vĄY@Zf` lVűŔ B!É@2Ŕżß*·í*w»sB`%„ň€qŰĺŞňW—}ţX‰^®ţĄŢíÜy*Ą]˝ţ°űWrőv珙ţ#ҨŐ?öâ@]˝­öŽvDĽÓFŽôśdX•>©uďWÎ;ř˛Ú{·ó¬»»6˝U&¸îźëŤč]NŰîÖŢ]Ë>h)L··Ţč^3řîţŘtBvO×e|o”ďüzc{ďCĐ]Mc`]Ű=‚˝ÖÂřî1Ň„đNv÷Xű?¬ýp$­­Í«`óß™‹ç{ż&ˇCśr…–IKĆ M% Ť<Pg'J3Qv%¬…)@dŁA;ZmÔ”ôÂü˝¨ «‡Ô2 ’‡Ą¨ËŢĆů.Pz•U˝—ŞŰ`3ôJA2Ý«5(Ä Ű˝Ç†  ™7(*¨(Čnźť na–3Ý(`pJ»îڍď®}?!Ë'˝ĎÔkB™üŘ´"Xâ#Żc4ăň¸´sG…Ť‹,™B \Ľ‘Dň5-ţ†Vü€X0N ¨V4š{¬`¸ aµ÷pgďçgŚÇ»W@ťHÇěZRŻĄialú¸ˇĘ«$}·Ţ~•u5žGś.ˤ“5XÓb‘çz7€¨ş·N@ë }fD›Óă–9§aĄ‹ŠhîEzŰ#öŘŘSč hm.Ű ÝŕZĘI«»—Ą“ń‚č}/§i!§E8Űáů¶ćIš®,pZV:/­KŇ®9¸^đĎűÍEY侮R9Ńt•ł5‚G0a.!špµ~!uŢÚIäĎ™^€ą’VŽiäšDĽ&MŠPIđj nYĐzÝ$0. Á~WŐX‹Ýť©Ń®·ŕ'T«j>´¨˘6IpsŢ 9ęăśŕś´lÁ^FΝМFř€†^¶7MZěűgĐhvŚüÚ` ßĐŁ2żZjŁĐ5xŽÚgeďŢăwŮ °­"uFş'lžR'[ő i|LlÚë$Ś«Ć˘kÖ\˛Bm(Ł`ĎĹ.Kŕg QJ1KŘj~4ô¸)Á{ŇKe©…@ŹřFHt˙b!÷Śá?šŹ €ˇl>Śţm”ü0ř™ă2çl-=„Ű}d$Á§ŁWVv®1kéjF5"ř@’b€¸;pÜ1ń#¸ŕĂŇXôľZôš4ŤA€ůß™‡ř`ŮŹö3jb#ŐĚtă ř3; V”™Ő–Ł Śj¦f:3uôPźi覰Ĺ4pÜr¶m`/Ă6”G5ćU™ÔÇČľë˝p×t ¬¸±b=Ř pr Z%:‰_Dż*%Śšzču«°×XÁ1×ŔŔ’ąâë_΀9.5šŤí•ÉfS‡çb_-N™ÝfEOĽ čtđášIEdoî™Gâˇ&z(PzŰXŞÂZ{Ф[ą|k ÁwŽňKk‡dWQU8äDeĄĎ\?agQ(ň˘Ő ÉáęîDĂÝÜŕfľ1ZéÉ, 㬓m¸•~QJ‘7 %—&â1‹eRÝcrgĽZ7 đŻŤPYKő¦Š˙3ÓŽ˘śOĄ"¦Q-‘iŰŕ÷ÉV~ż‘ĂIÇŰHť&»‘î+ŇY Ńy0,~Ő6ah¨í1SŰ}„¬éĄç໷,6gË{é{JŽÇéLm(ęËfúFţhqËc"Ł‚W¬lđęMĂD.!•mÜÜő ćůůn3®6X”y›=˘é~ďČÍ·7ąé3É%ż¦Ĺ\2;ç‘ógxú}]ÖşÚ¬źMÍu¦Â7Ýřv.ÎÔAÔ Ŕý`ę sĐI‹±YEďň{Ń{ ¦¬ŕ„Ĺ)89éÁrÇÄ&SÔ4źAˇÎ'âVît_Mćs÷\ÇĹfÍ ˛`c°Ô4 á©hŇŁźýN6{őz‚íaÁxčŤS°-ŠĆŢE~p3ą\E­]‡V8<>]C’kÔ Đ7e˝<ľÍ`˝ľŞ3ŹRŘ9@Z'b3~÷°}Ę,ś8ihs¦ąÖ4´ĆőA ĺŘaI r•Vp­`Ŕ Ę¬»ČµOîxŃ’5é䀅3 ݆2Ě~Ŕµ†^Š…l›Ü DgR… •m2űk zY.…xq2đbŇő4ębVlXÉŠ™ś´ĚŰŇşŤ˛Kµć•EŹip[ú>çČ‘FŽ€ĺŠŁ©Ć•řH:˙9Zę-5oO˛×Q¤r*ÜźÁ/• cnjLV®(şĹď(ĺąß,±Ďt«}•G4•jK‹ÉôS@ť’O"Řry«›:păd+yVąíckőP (Ä zkŤuhIÇß: cTĎ»ľ÷Î\őmÔlaú5J¶Ů4^´*D,sbôËé}čţR¶§Mő:´rď-Ôpč±,>;@F *đD2¦[맦·÷+“Ź“ýŐşŠ&=8čČ&ýbZa›–mZZ ŁÖ˘yFú0J%M RůkŃĘ˝·Ş¤`“ř+öɰZc1kňĺâfŘZĄÉŽGQcľkÔ(ńßF_’p¤ľĘi+· ôýĎńęשnż.+bgśĽM¨(Áá%•TÚÇ»|ď_RLsÚ9Uű=Jë1†ťÇ„ĺě;ĺÎv| “B…$čąTě®_äËŘa AŤ]S˘»Ňş§úxýů5uŮcöËŰqľVóŕQ҇”ÉÔ×îŤ\¤®Ü[~ŢRaşHmć•ĂO7ŠW¤)ó?eťčItđţX–2ąŃş‘Ť4/g4!Ă˙¸ÇĄu}lÎGMH1ąu˝źF!†§ô®?‰íşFvç©rľ*CF2­6Ř0ůÉčĎ8]Š`Tnú”¬ŹťçĄóuľ)ťď¨óďŔ?8'?ćą÷Śš‡cÓ…ŇĆŢj‚TL#Ś?ö‰3ŕ?‚ŽŐŕ<@Qó.ŤÝPďýfs—Ć>ĄŢÇÔ|DMIcődŤSpÔ‹B̸‰ÇrsňMu>vâßśtŢΦHńŐtRŔš÷šw1ëĹćłm ĆĽ`ŔśÖcř·J÷óO4@SS QﲺŢţ‘5ÔDŰś7_Xcüřgľbá˘ŐÉřú‰ř’łÝČ›­äF›Č*ţ˙' Ż<™ĎÜÓ pđÁKDtšJ­ôůäÇcňŹŐž]J«–_$”Zëâ}ĄşqYüKýÜ(—fŘ˝<ÝÓ´3śÓUzó…NóŤ?E^ä[¸­ŹľŞühśÜňëîtµ'Áf‰čW/Ń›8ńđŕ”[ČK逵­b]ę‹·ř|c䏹1ň»ßĹgL|wÔŹą;ę»ßťëľŃz ¸^™ęˇŮÂĄty0săç†ńťúÂwEcçŐo©H¶{kmńÍŠG ŽŻ\®#ţNMŞ›K–RŇ~m«Ý,nÓasŚÇ\펵őđ_ă5ßɰëóńDd—F˛’l±śĐĽUáżhÝ 6_ŁBîďí<ż˙yjĺ=endstream endobj 669 0 obj 3236 endobj 677 0 obj <> stream xśÝZKsÇ ®Ę‘żbOÉL*Űî÷ăhË*Ç)9rd&;•âK$ËŇR¦H+ú÷zúžéŮĄ(Ë®¸xĐhv¦@>óÓ†3±ář—ţ={}ôŮ !ĚćňíQĽż›Ź~:é?<=µůâ8>háśŰÍńË#΂·J‹i=«ť›rO(ĹüĆz żlŽ_}?<53R;üuÜrfC°Ę ź“ëoGÁ‚\ÇăV1´óĂÓéŇr1Ľ·R{¦Ąü¸5ĚűÔŔŕRkŘ× ßŔL)®ýđ×uś{+†/Éő?ÉőłiieLŢ/żËRüűřoIéŔ‚•VŁŇ"YI[Ú4 š(Ss˘\¦E¤ŮXÖŔ+°ČVuśÜlĄ•9Ü;‡÷A'ÁĽÓÖŁN`Iĺ”ĆĄ:wő¸ Á04Č«đ¦ÔĂ»¤›6r¸F…¸FÝBÎJe‡łĚŁç*ľäĄ.đžáfx Ć3ŠéáŹx!‡U^L§ăµhźcÚJ/Ň&†‡r—;Gö»©˛ßÎ^‡»ö•đ®asüěčřĎßS \Ő#żŔu­5ÂNkHoš3ňĚÂ!EŁľE ­“ńw=‚-ś…YËĺŮŘ;’Ťúz¦P´Áëq ŕ“Ć*T7Kx>]z7Ü×›ŻâfŠ;´ćV8,ëşŢŰ( b8Kˇ™7˘ł,{^Á–¬ˇâ[é=J’G_⪆)¸$«FĂXn€lő¦ĽßŠ­¸d·dąx÷ÝŘV–{Üî0.4ýťx‹H+Ś˘{‘Ů•mO¦·¬ň¨–âcL bż#žLT űžŐ}ŻĘ˛ŕDÚk¨ľ®Âܡa$ ‘‹đ ŁLNÓG{„˛>{SŘŤ!é8ó:#&J踖2™ĂŢĽôŞš\^Ô Î›đ’;Đgł…Sđž‹i—ę#+xďúJa˘„GÜ yx95Ţ@ü5b cšZ_5b\ąlÜ€čI,˝4:žÚŽÂ=Ń ÇnšCŁŞNPôj[aA„=Ą/e€ źĚ­/OşŔG]Ś'ľZIL ĺ’ÉEŽ…Ł®zŢߍ…RLP4&ďÁhhEXőť •¬6zT4Ś2’`5…CHzé '?”p2űźFc`ů Ą|䚥ŢĚ5Ź/í‹’Ń„ŤÝBŘ6zŚ„ě­=xLJ˝źÄăŘ«áŻŕAJ ůQ!ż×ÜC€ZoŻ9©/U̡ťŠ3Ěź}L儤QŻ DyYrČ ?ó Žz:,Ä { 㪠"ŢuÁEö%č;!q xéľ'+Ů2ˇÜdďPjĹ;ęR'iś2K6ÖZ‹Ş( ĆoxZúŚń_"ťI·•_‰0óÜ\cUš@4ŞŠhĄ’ć˘Ö˘ZzžÂ˘1T8ěĽŰrn“Mf)^tŃő˘™Ăh éŇQÄăÉčü$‚[jÉŚ q«%Âu+‹]•ŕşHJó|‡šäÎ3Ąq–>űj*!Dµ9ę}];żjuBâC7ŤÂ3żóxn‡† Ś6‰á“[‹xHgĽűĂXť Ý…mŚ«e Ťĺ|˘roZšÝ•řvGYA‡aśŽŇ2.ˇ\»/ĺÜÝ:Ęń„× ›%IrkäEań$:żéR™Św‹¸•Ú0—ĄşŰ+ çŚ?FXu"=şV—L×›$Ę,ŘM<$˛ÓErß°Ú]ňś†ÓX×E*8• En¨Î"$čuVd43ůâwóB';Ů@ąu•Âç>ÂěĹĘĂň{Ś6ýpő t ć˙ž DCúă 4…ô>‚>$ÖĆl® ¦0аń\M©Mc=ĄI=EpuÂÝ5ÉňRΡ !ÄRŔ^fĽ‹` t° ‚vf˝âBýţřĂŠ2J}Ľ­ŚĘĆť]yöÇűlj˘ÂŐe¶Ę@éÖkşĽęĎČ-%çŞMęĺĄű´q}pz§MŰMIŢŰŻ·4á^ŹmýŔ ťŐn÷Ë|Ś7uÍD:{¤±’JRMťËŕ±–=ţVňPÂ)śt·ë1"Ä}˝Ľ¬ĺáŐLŠ™’±Ćו|ľlü mąÍ Żyű°Ç ’^®‘ˤգŮkŞÁgqÚ`¤#ń€ř›ž‹Ě‘Ék?¤ĺfŠôµŞµ*ÁéŤ1E€Z jáô«ínµúę\Ŕ]{#ÂýęçýM)(ŕ°·É9ÓĘćřîµí4‹ LćÁK:5٤V ýÚó¤®ŰfĽ}HÜ*)™’Őoűy“\VÂÝ*ö DÓ_oĄČ¬Ł)ˇiđMâíîĐOí§ÝĐҦXÂ#•X_—ôY]íůÄ5q8óm4M p¶ňq%Ô績`&ČHk!J(nźěšP é(ç ˛ś÷˘Ţ*#˙"M𸡌zuČw¶†FŮ˝ ě䥱FćţˇW¨¶S:%Ŕ“ h&5>d‰@ˇŐyŁäęcçŤë„7 X ˙ćCťűXďłSŇő2!€ůŻĘ¸§ó[‹¤š!óü`·WnÍ™\•¶ĚJgú}çĚ%övÁÓç7OV[]$oôP{ä{„µĺ:©8&¶´żčĘáoR†öPÚnI1wÓ3ĺVű”ĄmÓÜ˝ľĎ§ë^w·8Ż2v›Ö±Ö†:Y=_â¤ÂČDj·›®;ő3őeăľq-N»Ę7 /­…lŐ_ň%~k ąX{pGO –UůŚ,tiÁŢ/~/{Ĺ)–]Vă—1żJC)_¦mUëí¤Mi0‘q„ú¶m¨éwşׂ/ĎXúuęápŕ5ĹŃĽ˛Ş‹’˛„Z"ňÜęLżĐôGŽň‰f§Ýg‹6EŹřŔuo…Ô®âÍ<ó“‘ęf´qô6S bšüŇąŹ1Ó­a¶_uź$î EÔĂ"ÚCÂ@dÚąMąĐjO`xäXítšť¦Z˙2Ăđ_§ż}Ú‹­Dš‡Éł6Ŕĺž/KŇ …|×1Ż÷D,Ö"fˇ¬†ÜIs±.A*†NŃS‘ď‘›‰&ĽÓľÎ˛§‡A2EF-r@ŤMFbĚ„XX!ł(Ý+ČYçťde‚MBf‰¬gÝPB:ëËŤB'~‰Ü>Z(ď•aOÚęq¸A=™ąő—Łcž#Łíg3r—0íßťL¨ŘYJ¨®P˝íőIŐÓ|eÖ-˛Ú6íµ-é ·üMş9ü-uĎgB »ţť^ $íş™©|ĺłgßtTń 2ďÂđßý=޵nr{ Áh»4`łGuilíŇ<‹ĺ,şŮÓih –ÍÉ[+1ü§.ŕ¦Kë$iČ<-ď5ĄĹŕ7` Ũ3ä÷ż“Ź´ŹËÝďĆřM÷a˝Y˘ÝBLĽú˛.8}«Ĺ~R>Ůtš.Ę×ßçeÝĄ^ĘZÚŞ/‘žÔkÜR©„«ťŁ*lm•oĘ·SçU€)Ţ“Ě ąŘ—ůmŇšŞv…núo§kÝv­v“QËËÄňĄĄtŐëąUű]L ʬś 6۬3äť~_­v»^Ő߉DďËĺÁčp°źJGa褬@¸,aJ‹aĺĽ&ČźŐ…&6 0—]/ř’˝™hYѩʔ@曩Jůڦă¶á)ę>UčÎ’=j¦©ątXéŮT˝/“ŘĂJsŮkő•náÓăŁŔß˙ľ‹íźendstream endobj 678 0 obj 2902 endobj 691 0 obj <> stream xśÍZŮŽ·}źŻ¸ŹÝ/Ĺ}É[l °IäIü`Á,ŇHĐh®–‘ ů§üb޸4‹ÝälňL÷p©*ž:µđľßq&v˙ĺ˙ž˝=zň\ł»řxżďÄîÍŃű#‘˙‡çY»ŻŹăD źŕÜîŽ_qĽUZ¤ý¬v"ě–oB)ćwÖ[řËîříŃOÓ7łfFę`§ďć=g6«Ěô2ţË,XP‚ëéxŢ+&v~zš†–‹éůĽ—Ú3-ýäç˝aއ &C­á\3ý &0Ą¸öÓźq_Çą·bú–Ś˙FĆĎŇÖĘr (RüăřŹYéŔ‚•VŁŇ"[I[Ú4 š(SsNr¦M¤őt“=ś„ËöŇÁG.wÇç°ţź¸Hđ ezI>âN{a“\íö"/ÂCĄblňo*śl&Ţ~ÍCŃěµŮę~ç 0?iĄî a»BČ/Â0é‚ +T3îMšĆä.D6ĚŇŞďgĹŚ ZOOfŔ®5F ÄŽÄéŇ$ ľ®®"2€dËú.X¤`.őěčřw?!R%ąőły/µFXJ-™±fÚ§…łt¡býíĽ¤K7ŹŚUôďW°Ň`Ň@78©ĂëŞÄ« ׼wÓů2z‘Yĺă=élęŤ&‹`rrş¨ń,ŤşǤP›%@t Q- ˇ’jeÂ5l…žĂmzúšĐtoĹ# (ď%š|dŃdk;¸aÜ˝ ¨YJőĄ7¬Y@˝1ăCĹ<˛”ćKÍhY@Űř>W!•*Á´ĆH™Ä~“ ٧ äë!˙<ÉĹ•HD€H1ś+çNj pŕr®ł`˛©„›Ţ-.ë„)Ő0Ţ“Łž.Ł’Qh#ďBü$ťyU•Ç3Śf˙‰I”!Ö{WW]Ö eSĎş Ó·8AŮó¶Š;gíĄk ŤAZ‹×’$°Ü::őj‰5Xt˘Hč×ëĄń 2łm¸Z‚MÜôÓňń˛.ÇíÇhÝęş™ZŕőŹ Ť"SOęßÉD•Ďxá–ą č¶Ż]s<Ś@sśA˘K粲pD"8™űŠ„YÔŕË”|H@M'éj˝˘r…˛X3ÚpYf›eÄĘdýŢ7}a­ś^ŚNN¦Í_ÎLéW1(~üÔĹFÍ4bâ5ls¶M6RüBxpjđČ!¬…L™@/č#~ź7ŞMŐ٬/3˘ ŢđŇ]ŕ"š-Ü ."x†’·pP<«;·µňŽź§(¤ ÜçŚ'~¦ë~ža?  Ô†JŐ\~<ĐX*FuĽ®ß Q`ŠxíUŢđň+€BzQý*›I„úÁ4ši>$čBËâ+*ă‚Áµ»=^ĎŇ0náô_f¬Ó”°ké¬dÚJš “K$¬÷Şë:ßfáÁůŔ7¨Y <Á H!‰@Č Eř0C`míôŐ˛kň—¤óRťVp~ÎDŁt{9>ö}â"SÄąˇ3–AKőłîq7ŘÁ+kéM k‘´š"‹'Ŕ8ˇv[‚|íçĂ0k-Ö$ž©ý’~Ĺ«őŕ9żÎ&`CÄű˛ŔiFˇ] ×ď3,ÁY­!íÓ÷ y)H&˝(~rĎŕC—żGđ3ôľu‡mČRB’%33&3iLj®÷jÉ,79ş$Őw!˘}Ş`îr=X\ÉhźU%­´bBe–˸_…©Ę˛ üX´×ÎUĘ#4‡‰RÜ@¬± ˘ v_z+R‰€nĂ2a4‚U"Éşż’6ĆIUŠEhps-SâoX®˙+Ô›ÇügäZE†ć•Ń],‹»PŇ&Čż¤CËCÚ!©?Ľî˛-  Űŕi€uő‡ 1ÇUo ţÜ*ĹË®“`źUhłŞž7qś€xIµyCí]ש#s(CĹ’Î{ŮâvMŰĚ’JAE©Ç ŠŤ1}‡čŢ÷©ZĽ¤Ňµq„ľÝˡv”ÝÎ*ľ_•ň!PHř\'Ż/gpP/¤/¶ZyĐŤb©TŢV%űĹŠWÝ:{µA śIÝɤΪ­GÁäň]‚!3Ů*{Içě±Ď€'Ť ŕÜůׯZ@®ýĐË&U ®÷«ň N8]¦’[éu>·őŽZ\i[ďäűésaÝđlL1N‘‹%çÔ=q°#AożŤ‚Qf/"Ĺ”N“2ńM­ >Cöě d=‰z%±dŢFŔC×(]ęĘĺĄŘt›őK‹>µOhây˝0É5e—‚ rá§3Äő·Ľ+]wďćÖ&ľ-’< …¤aöŰâkëR. D‚LZÓ b{Ú9(¦o,5hľ ˘fż,0íg’źz0ASŽ)%ďă=˘'‹ÚꍬS¸;[Q.×áĽ&BQ«6©GŁňŐMIú•ućVĐVű­h>Ř_[żÂD¬9dßć=C&>M{/|zçRL‰-uăĚK¬K±ŐNä}ęV źl˘ŘŞÄKbŰ©‘°„ˇŠYBH'46PÍ}ĐŰňA%‚š˙#§)gţvň¨+ŮĎ=ŞŁÔă<öĘi31cnP,YN˙á4o÷›ľ›v‰vő‘Öi y‚ç˝ěôÜVŇ~ŚŕâYŁwĐŰ—€ŕqkďĐÍ®„° Łč~uó>ĂŔj`ľ}ě;B˛Îý&yO’2˙™ĽIś¤S0  Ś•!ĺí0]ł•ʦ°.1Ż„{đP?r“›‚éśřd‚©>ů–ĎčçˇáÁ¤Çśy™(:hEŢKť-“7Ľ‡ăk˙­Ď"Ř8QMw·>VR“‹BcKK|ť z¸KXéŔBx7ĄvÚs7ĚźśE`QwŢ´ÖÇkŰĽńľŻS«&'ńˇéáŻ&Ŕ†łmM».<9¦§«~ś±ă®Ąď˙ľ ;)Ľi»ŻAOë^­l,aÉ?µÚ–M­OŤT4Řäţç:®şĎÁĹîÇżşIw{żYˇa÷&ű@;fD;×ď*TFÔ°ŕý°¦ż8$Č~·™`yžŕ¸–ri±{uGď…ŇJŮÚ[>6ŹNŹý÷™¶W†Uą<d¶éîÉ*ÖÄ|uëđĄ‚ÇzTЦ뽲t»ig]80l1ŰXäŇ\ŢÔBX1ΠíZU Úq–˙~{€YZ+ýßC ['VCĄ˛˛ńňßΔ€{f{]¶zóUÔÄI>y7‡@ä89~ I)łíô1×}éää]=")ضť·XL w[ĆĹ|ľó §młŚZ,†Đ<ęw×ĘôÓď×-đuŘ­3K™`,ńţK%ůZúú¨ćęöáPŤ=L;Č2ŰÜ´4˝‡ż(E‘¶˙°JPĚE[6zę@QRܢČgšî?éHŢfÂ-ŢjŤď*#î3—ŰUËúéńŃ_áßUęµendstream endobj 692 0 obj 2775 endobj 702 0 obj <> stream xśí\ëŹÜ¶ďçý+ôĄ€6čŇ|?>úřФNÜ-R ( ?.¶‘óť}ąKí˙ľ3”DŽ$jµ:ŻÜ Ř4%‘ś×o†CÎ~¬8Ç?íżŻŢoî=ÂTo~ÝÄţJTżl>nDűŢľU=ŘÇ-t1Áą­ö?o8 Ţ*-šń¬v"T©O(Ĺ|e˝…'Őţýć§úáV3#u°ő“íŽ3‚U¦ľOÚßo Jp]ď·;ĹdĐÎ׏›¦ĺ˘~¶ÝIí™–ľöŰťaއ jM­a^S/0Ą¸öőS×qî­¨‘öżHűŰfheL7 6˙Ů­â?űż·D¬´‰-—´u@MŹ@×€ťµJÍvič ;Üq˛ÚIť\Vű×đ=eĹÍv§™´\‘Öőv'µFŘúÝmŤ‘˘~ą•–q ěąMěkżFŐçÍG őëV1c‚.&†j˙íf˙ÍOČUÉŕ]Ő2D/ë‹<í‹­” #ęß¶Č«:Ď |žĺӒ嵨_ç^ŇĽN’Ňbˇµ“„cę´Ścđżú,S(›‘Ľ ŰIe™rşv¨*–9hľLĎ®)îrÖJş•ŔóóH“ h*|ó*łňgâĚ(ŚH˝ŻłäAݧeaąu-ˇ^ʢ¦ČŔ ‘ĘYâĘ˝,ЧH+Ě&-XP˛˘"—I€ł*` ň˙EĹ{f×˝Đ6Ťq‘ďŔDëuAZ áá˛3AŇzËN˝‰]¸n€«CJúh« h&°ŕ~3ŤK gÉRdţa ,‚p*cÖĐwÔŇó T`¤ŇDđís«0„ž'$č&–›“٠ﲱćă–rŽšDędĐáNx’Gm4á(™ôÇ- —•FOd1şĚ:¸đGsTőňůĄŤŇE›ĺ·˛;QBĽ"Q^üFů§aĚB>»Ą)úÍÂĚru™†©ŹU†™ŁYf4Ó°Gg&—ăL~>Fścök“‡žĎöÉ;r˛} Áç×Jčł:i-úŇţDź?.ú,W—iô°%¸VšKx¶}¤ąQxp ř¬M‚<ˇÔ >ů âNŕł:i-řŇţź?.ř,W—IđQ!č“„>*ř°nŃ0 ţ5ěY_ŚźÎ@‡÷$ňů$Ťś‡|>¦VçT ü1†7m2t‘#¶ N˙&†rČZťLĄEźLréěaJŚjGFdRTÎ(§B˛YC^›ŽöVý!:†ZR¬ź5Öµ Q2ŕÝťhąFâ)—‹1vâ–.9đ*ßěËĐPşsO&ä-ż:®Îj×çčÎŃW=HWřĘe“sgMíÉĆQŢ|ąü¦­•ű41ÖJ‚Ť‘ýŔËčĄ7X.Uˇ-›ÔÖwe“NĹ{0…^µ”†™€őî JPt<ěăL©–ŻĹšH©›çxyÝ5^äÁo@ťŐş­śÄ÷Ż›JpKč¤ő ÄD?ąLoĆâ-<‘í:ň t)ďĐ7qĂsĄ¦Ô´3­Żxyۉ3mĄyýyâö)w®+Ĺ…]7Uż¦9Ą…] ¸;Óĺ"°\ýIöhű¨źXď-ňąyLE=ůMR.Ń;ÇŰ)ŹH* ű•Ł·EXţ+‡A[2íA Ôíx”ͬ[lëŠő8Żw >Ő‹ŕiţmźăŤ^U ‚©%ĂBÎQů Pł\ G ÷Ú»wI=:9ż-5G*D@3`¨Pý ©ĺ WM©¨qX×ŃVŠ^#g!9-ÄČźŚŠĺă’Ţ´lŤV؆ÖCL~t8Ś"Wł˙;şť@|Ŕ€ĂMÉgCTŞř,ůŹ•Ż_©ţóFńşŤQś~ácéWtg–ż«_Ý(ł`lmQë1U<±¦|TĹĂsOďçÚ""í ó+áO^E„÷]D˙78Ć;‹ňťĽţôó ˘ţ&mVgTűż#Ađ kK¶îîëDN«÷cç D Ď čĎ_ä¬aj9śîUđ'¸ˇ†©ţÄ Éü°ů“@–endstream endobj 703 0 obj 3137 endobj 714 0 obj <> stream xśÍZ[sTGŢĘăüŠy<ł•9ôýň0[x‹l€uÂC˛•"6Ř.° Ć^Âż_©/GꙏÇ`˛•޸9Ó­–Ôź¤Żu·ąĺ\ŕĺďáŮěÁ )íüřă,=źËůŰه™,˙eÖüáAščŕŃ(…pó731Ćŕ´‘Yž3^ĆůôLj=†ą ~™śÍ~-Ěh•‰nx˛XŠŃĹč´~`ăg 9F-…K=Şh|çˇrx±X*FŁÂK;†ŁFűÚáG0j-L~Bą^ŕä°ÇĆ?łńÓ,Z[[wÁáż«˙9řg1:ŽŃ)gĐhYĽdśkmŇ)‚;3 ‹eçÄZXB–ĽăŐ|©·Ă>úÜ8{2Uĺ N;<5<á`$íÔ—şĎ{gđř•ť°ľh’~=C9R*-=JH°ÁăNU<uAÖMßâ"»Ŕź8JĐ}ŹÖ’;$-Ő44ôÓ°‹FČçOg˙•Ců„@{ş€“t9|Ěúh8J0€¬¬Óh@ť{”‡`ë5=|GĐZŚeNwV:.ëzŔV˝ĘSťĂU#«>­ząX&háeµ!ä3°pLĘ5VäęIÇ´Ś ŮÜÂÉŃŔnSÔq Ěa‡$ŕ‚Bî|Rě’ĺlłćbúýT“ˇ1†´’$TO‹Ä4ňč,7úď県ŐÜ“y›ťÁrRVŹZAVIYŕ`ˇ!láY19éÉń:Ǹu¦Ú´"”ů„M@đŰ‚őđ‰xB“×=ŚëN˛aAČ 6|„Ŕ˝ Ď\4IoYĚZBŢ °<[ÇBŕaq =dnU’hšŕŞO}Ęf8ôłY2´łá{~¦fTN4Ńt†{é”#[ŻÖŁZ Âäť,ËFČg”` S5X>§ąGe‚1[±ĘV1ú`­^Rvřď$ŕ´ ¬„ WôŞČÜĎţ€-5 ŔL­Ý¨Áźů(…ó<™á§Ý ~—S},d•<ĺ$ˇ6(…ĺKŤŃXë©(ňĽGËňć~ZÁ‡l?ˇ1 rÎ3Ę« ąç°*Uö…ő·IŇE5ŁKůOöÚŮ€ ~ČeÓĺÚaˇv¸ő„…Ř#Äť®eZü˝ú*ÔŇ“x›pŐ,«ÇÉ ;ó&ăTŔ4;ăżA8B˛đč‰BgĽÉ-Ä㞢T7B%ţ*ŽŃp>F3ůkI-0 Ž·„íoě"SrÚ ~zÎNřea®•~¬zę™wÝÍäżZí!áľ\ČčŔ´a¦Ђ̀„Tç”Xë3'Ă™,µĹ×”‹]«%& U}° {ŐÄ^źälk@łÂ:ŃňcZv2łL!YaěËQ…`#rV°\Gâ–‡ű‘H*{ĘH"fIďájă9˙Ł_.$äH­9!Í[«ś.A›±e”l&3‡m5Ioé°ňfDî{ÁjĎ|°ÎŐ9-f•ÇF;ZsUů5“˛Ô0$lÂĄŹŕŐ­¬ť4;^ŕB*BX7ü#Ń­ŕ*­yŐU-;Xh•L_JŘ1ef\Ĺ ńކźo&ŕKmst.!˻ʪz,ü5§ µÜŕaFww:ÎyMś ŰaćZm·ˇćY/µ™Źă­6L«úůű|–đľ(úą ^r°ĘI8W pËŘa«‡Çn· @™ű EËŕÇÓTrZaŕŢ2¨¦67•űY‘—*pv|ÚăÁéˇFM”®˛)Ă zFq“–Ä®^. „ěĆĄ2öEś,KÖy)K÷€ &ŕ¸{缺±+ż=^¨ őŁ¤Ď­pŮÓK*ČDA‰-Ve°¶łű @@¸tŁ”xÉwuËiŹÔ׌¸őµĹf÷¬˘äLÎěP1˘Ă†k'ŹžKVŘěz;hĄźô~-#¬ äŐjÄ>"<¶lđjš«ŐÁÂĽOú Uó}7 Ü´BôÚţ™NGÖ z“{xĎ—e‘ö:Ĺüv‘˘TB-˙Ô ˇOřëC,– „ &ąËzˇď‚§Ň2I–ëćĆT[rrC;€%«7ĺÄŔş?Ăl“´ú§ÄžRˮǦBőęV·ýNö3@ź”ÖŚö·|đťşŢđpA<éÁ¨!)ť6Sż‘Ę68ŁIł­#ܽ۠9őzÔŰ*@‹čŻy4Č>”G^ĎÁý× ór´ P>•.ř˙;6`XłşDUţ»©GA{ł3á©') ×ô>Ť¤KSżf`S]ÄQH~˘ż€P @”ű^Ľć'š3”_ÉÍ%ëlk®~7‘ƶşGßG ł´•ŹIŘ ˙uĎłVśß’JŐ‡ět!Â7Š‹Bńuc%€ěĆb÷3=ým1ĚM .ÉkÜ_Ő·}ßEčyńcÁ/mQîOS; DŘjŁ.ÔAěµÓ\ÜĄťf¨ťö¨T]cë±ćËeçě፠"|mä ZźNí(ľÉ˝če/VźP‚fÝ$ÓĽ©^ťĘŤ¦÷­q „ľů%+.ŐŁˇ-Í˝ˇ“ôşŐë3Š‚¬s I,U2¬^ÓŞµš¸Ťěf©@»—ÖoÍ{WÝ’Ô˝đ}D©řPĂöč˛fňÍ<Űs&hx'ţŃ”•Ú©QΨ»ůń}׬%†Gá Žub U•‹^Z?ËiôZiDňT__Â'?XŰ˝íŻEqŇ︀"ĆŠÉn'ÚéQŐô¤xŁ‹ľáCO}Ł@O©C—;@Ů®©´­ě3/{Ž{GWµő–D>y°6]3(ď˘&ŹfĎgćŇŕ›ëô} Hř GTAn ř±ŃĂýŮýçW—ׯg^ÎĺěÁüßĂgŹŕĎţŢüołÇűs”eŞ © ˛(@W‡ËĎ.‚nř’©óQŹ„L¦Ő9‹ ůŁžőßÓuŰ[Ě­ţ01;âžőWPO@>ׯ #hv#›žäŐjî[ůâĽhĎĘCčŠ;ąb3ľ„MżŽ,vŐ«ŹUˇőŽJíU#đe´ů ×«FéÔDđűtLG]zBdž•­ţ­îó4a+äďÝ 1ŕ—t“é.čípżbNýn\U?*iRcçę·©ĽŐ(ŰŠüÝ=˛­2J‹2ż­ (ˇéŃjŇ15â;¶=Ô:ü“††Së›đx˙†<2CďIóí y§l†¤Ź_§ŘKîąŘźq1ŐĘ»ĄPV%=u4dOŮ덭H˝wű R™Zýo‹Tů ‘ş»S6#ŐąiĂóŮ˙VîÍHendstream endobj 715 0 obj 2683 endobj 726 0 obj <> stream xśŐZYoG–ňč_±/‘f˘lÓ÷ń‚Äa%D qL$ń‰kcL˘üřTőY3Ű‹qŘh5\˘–Ňr~«żľšmžß’–FrŐQt_¤™đÔ·ń•ĚÜYmŇ_5Ç•?ŤGŐ_7.ŹZŕóýA"5ß LÇ‚¨uąlń 7™y[.«t®€ÍRçßDÓWŁđLr¸ëC{ŞÚ·Ë âŞČęń~ď´ő(6ǰVzÝ]  {‡ďr8ECęxĐžş¨ qW^ÚL †8BĚ·‡čF9¤h}m$?şÝŞd6Č“ĺÖÝúÔ}ň”Hů ¬EŐ–Ľ.7Ń•!Ű”pÖlKĐě§Ŕež[Ę*„uŽ*«çLCKř©Á MîúĐpúf-R0"Żşqšs^âYĺ ău˘JĂ۵ĽnţBĐŻę.@AiÇSËć뎎”°$ @ÖĄ˛ś)8zZ"E좉rÖ»źPj 'i4ĺx+"A9Í8PÚ«zÓ5J‡çŽPR‡YŞř ZĺMH,sFAF„Źtp2s̤Uă˛9H¤iЧh7%;CB¦ }Rl~ŘD=oVí±Ä%F ‡2-“PK‘Íb_ŐQ ĆƆ}Ąç©PZOł‹ćFěş1=b#ŚŃ÷/> stream xśĺ[[o\·~ׯX¤Ý5ĽÇ‡w2˝Iě˘ií&uĺE˛îŤ,)±[(ň+ô÷v†—ĂáĺěJŞŇ‡~0Íĺ!g†sůf†ţv1l1âźř÷ţŰť'/S‹ăw;~~Áßě|»Ăâ?Ƹjńé®_¨aj`㨻G;ă଒…ý´4Ě-¦9&Ä`Újře±űvç«ĺg+9(.ť^ţ~µíśjů ąbl”ËÝŐZ ÜIc—ĎÂPŹlůrµćŇ’ŰĄ]­Ő`­sb9ŔPJ8W-_Ŕ‚AQÚ帯G«Ůň)ż"ăçakˇT:‡IT|˝ű‡Č´śćZ"Ó,JIjÜ *O“q.ő4Ś›pE7Y Žá‹5709ňĹî|˙ůJ J9)—OV G­gČ—°× žI(§yÁ9’ËťĺËwéű.áś pAn±ű|g÷ŃW(5>ŔZű_ÉL{,/˛„Ď`­€­Ôr¨aFg1•+'şöVk6h­^~żRŻX Î(M?φYANÍ´XłĽÎ2ľĘg]ćŮëié|Źň pȰo5Ů)*FĂâN~¸—Ď?ž–F˘´°(Y&avdA~ň?/ČýĽ+ŮČ’Wn´q¨‘BBÁyď0/KµEßdŽźW=9~:ů—bĺÄ"E‚G±ĽÁ­ô`ܤ.öçU—/'Ëý.ݨSjŕ¦`-;Ć뮊de;Äďĺ>71Âż¨·8¨oÂłqY·ŽşĐĚüAO-ZŽ©”Oóy«sT&®ČŞő¨ ]yLW¦C÷¨2§ĄłúóŃź?"glPŽ{y*3p&<[ÉŰB^ďđ{7đą‡];#¤˝Éź5ş† :QÔCHÍŃC =čÄŽĹŻ¬@Ř€ě8ˇ-7K±Z;¨üWm¨ţ ‚ő% röšĘ%”tô3˛–8âÖ‚“Ů› Ë”++ř&Ć%ő–Y7:ŽÂ«ŻăĂ(Y\ĐZ„Ś0Ť9{k9ŻLG+‡Ţ“ŤPµŰTvźIábăÔÓ5r©ÝýVąZÓ-Go!Ú­Ý}Ú‡fĎń;J$á;Ô"®Aĺ@iƛΠŃzç2*đ$D- ôGľ#|~HTz™Äh®Hç¤öJ†ń‰yÉŇĄúŮŇŢ׉î5c1$ ů·TCŚP{ý°ţŚyQ0.[?ź4 ü>™Ś«‘Fő»QY µ<ÇyąDgú>™Żě+ůU7b®ĎJm٤°Äď&|BékÝÇć0ćwGVG=H©č÷yił–ót¤µE űźôř'&’Ž”»Léă č`#Fł¤čoĽaŹŁč`łĘ)xVĽ J’âëQÍG.±ă™ôöf#idNÜş?ŘKÝŚd™ &XIdzÍbZD(čäM&]Ěr©‚BÂżÜĐ ö›ˇ(M$ŞäX€Č‹ /f)üÜE7DDż\Úpv̬đAD˙”AĘçŮز»LŘŇ8“Âç¬Ő \Č ĺnŻb”PZCä,Đ6(E€¨ßŻŔ‹ aÝégĂčLĄÖB ¬!‰¤ äÜ«Â×"Š˝8´–„Ľŕx›÷ř3HóŢfďÄ\®|–^"ĺ‹ČˇµDlý„€đĺĆá+â8‰Ĺ{AĽvÎF1©“(2= ű1pÜâÉť$¶ĄH€ßZnôiíQťěm`  ÂÄe ŽţśwŤˇŇS:ů€Ć÷$ÍćnôččpĹĆA€1`Oż0ëp/ŢDŹŘŘrÔ˘[‚P‚ř“>%Č7†+¨+LţnJÝ/č]ÚęZVr´Ă "4]Îhs:ýqśBhľěů­LSţ­C:pCpf_ç¸e éds˘‡yót)ާ`×Ăhćv R'uîZyëŮqkt¸šëđˇÎ«$ŻO»ŕc‹e‡8FrăĎüpť7ˇ‘ßű ˛{ő1Ręl!Ą.ÇŔ”CH®5¤t%Ř·»¶ 쎖׉Ă2µş )V“łs®Řŕ:ęŕ…¶ŕŠ¶P–|üZ)ęTŘ[Q"™m58˘ ®8E[›«çA„wč3éÍ,ŠáîZű§W ¬…gSÜžQ¸(}/ćôVž˛Tűó0…2LF±R›!Ŕ}«<`}‡ÝŻ~$>xQĽ‰7b TAvř¦>ö'_ĄÉgAű=#S(č»őË•\ŻwĘ©¨D~?Šĺf˝lEWHě&ăŞVgFAü÷˝5Ć'—n&>l÷ßä«Pb[i!ň'pťŤXeŇJ-kű‹őâ ´—vý&®rB´>—đ°|ŤÍĎŮPŠ4üĎk¦Q© OBjÁ Ętrť~]OM \´»Dféc łÚëŔ›Ňó9‰žť˛ Ş†E YTp_g}×⬎8uâi0üX”îűV÷Ő>O«ŕýŕ\Ţ·' ´ŕNĹfpm+…bŽůäö+%Żf`¬Và ש ÷ňץ+¶{a–;nQ 0Ü ź« Ó2%zZĹ‹rlö°‘+©ą‰2µä0éf™ńŤÁ˘řЧJŃ(ĽŮ+oë™íyۢhZZ2°’Üé ĐŃ‚/uOѬXň,4hÄ …ŮX@ľ}˝>‚’–UŔ V:BRV2Ę46öŘŠ–EĐ qŞă|ßóýîqHc°»Lt«$Ř‚|۵4‰”zÎË0€Ţ“i´X#»ł(`Ą‹Zw>7!`J‡ ‘ űrZś RŤËşB;IęFD©×‘ożq9ë„cčąF«đŚNfń¬űX…X@¤Ó‡ŃÁµŮą#znŚż`Z‰]‹‡±H]ŕĂŰôĚĘ™6Ńĺ~îUľź˝Ě&ůőýó;FŢ˙*ŘtSRÝĄĂÂ=L-„¨*ľ»Ŕ"j˛‹~Ł´i‰¬şAą¨¸…–ŞIM«1’Z¶ŁbŞ€éÄ,âVX=Ąí ß㕱¦Źęž`C™·ľ'úĄ¤“ąL€¸ýN^·‘{µM*Ŕ‘.}żç „Ý×ÓďE‚Ł"îň˛ ąh N€G×Űí%›imQŚľ6‘(ŐŞsyTň=#«ěµGşĺřŘĄRzŮdňS3/Xd‘SÚzËÇ.†Ó¦ţĽ%-]Z‚§¬K÷•O§DŽč˝ăi˛ńŮŽyŕu *?f˝=n*/Yđž×yÁĆ:_WZ\C´Zwüď?ĺc± hű;´GT6Ő‰C·­Ý”Ŕx ină·ÄŔÓb[jŞľ’ÎnC9˙Ac`«Čů˝qî/G·âFpk¦3ä&%'Mú^îŕřßWl4jyť§Çę9€Hú<,p3­¸PĽ#YN°Ŕđ-eńaD7Gů¶(nńÝ«z÷ŁdâEOŤ,h;Uý—­•Ç$ÄަYęÝ[Y}éÖďďfvŃgŢĄĂJc†gpÁżrugK?ŚŘbó¤°2kGg“¬X5ŁĎŇBÉ⪙Ę?Űdö#e ‹÷2Ó~ńľď@rR˙S$Jtšôw}'2=2ŞőŇpX,ŠVKh•ë•ý´€„b?„ϲöBł E€UU€~Ď€<íî?´)wHĄĚm7ŘÖš[äś4ô!ţ5oŃÜl»Ű›éËɲ/ćQB¸¨z~„¨T\çbk4Ůôđ2őOâsÍŘ’<’x<­L‘yM=&Ţ6{’§dE;TČR3r&OË×ŐÍ‚Ŕß1îÝ$KšŰZí˙J°Ĺó«ż+ŔGQ†3ú.tżĽX¬]ý9ăĆÖkŮ{îY·V€?‘}­ĘąZPI@ě7Üá!ńÇEcôÉK®mńŕZŇřĹ: Ľ<ÁťŘč$_>‚!Ă(4>;Kł CËĂm‡ÉÓäyňiľ Cí ľáMłĎ@XV¨ő)[š=ÉĂ‹üŮuž=ËCŕ[:;8%s ł‡™đr6Źňľ§yöĽ»ö  ^ᨡ ‡ŕ6–qô0§łŕ`ä´w‘!Đ„Gy6_ŠęÇÓ+ż_4‡Řź–wŘ +Ăa˘sÁ8|ť)‘gďxĹ„ňŠćÓ‰"úýi’Hčzš,/oĆ‚)üş`^e’šS«KňZ˘€ż-źŕC#ýź…“ă<ĽĚÔ˝ërB4ďI^»Q 5¸vVď$ˇžj>śp>j$R çmCnĺQ>šÖv.ôE#.Ű“–íoéw§É›.ɇĹ}JŘGçôű÷y¸×őUgÍľŮvť„Ä·yíFݧˇD`ŘWŤŻđw)á} Ü(fZ/3Ł˙,çÇAĘ‘€üYŕŐąn[HńmOô­ĄWVsąIЏ–\ˇŕqä í]ÔPö]~Čk_7ôĎ]Q¶ß˝Ô‘ üő$·ţ´{p+¨J›şA}ś×~Ü9Ń1/Ŕť®EűWâ¨Cθ$§/Óä>]éÁąÔź°ů“>. |VůÄĎżŽŻ #R aď"Ďö=(ˇďŁ?{ čOOĆ­řjR|jźO“ŹódűQ É°ý ׾ę®%ĂJ‰7ýC^ú«DâmŁéQ#Çŕ$üGě ‰Úôíţş'ý»¬-ťˇíĂDđU/Zopžą ¶üYiá¨RÔŢsV†ů óž O»2ě˙˙şd}<´·ŔÁ·G=I†ČÂĆ›Ö&_VO*ÉĹöÉj'ôv˙ż;eáú@B? ŹŰĚ ÍÔUnd>ďNv÷ÜöŃ˝vJżÇw|`Ž<›HČ-Ͳ]ŻňzšÜűk@´ š®3-/»‘‹`…6Nâđ*{™˝. 8Śi4Ůá(»!ÂďIIĂĎ‘}W 3D5ţ+}Úě$_o…3#8Ëł§y-čßĺŮ˝z–Qż '_¨,Ďvwţ ţ ·•óendstream endobj 739 0 obj 3998 endobj 746 0 obj <> stream xśÍZYo\·~ׯ /wR}ą^ŇA ´uŠşc7QЦ&Z,ˇÚ,Kv"ż"ůÁ=‡ëá2Ždnŕ‡0É{vžďľ^ÍŚŻfü˙{x±÷řÎőęŐ›=?żâ«í˝Ţăńć¸jő‡}żĐŔăólVű'{3sÖHĹĂyF-Ü­ň—’Ů•±ţ˛ÚżŘűÇôǵbZ(g¦?Ż733Ω§ß“ńË5gNňYMűëŤd©ĹN_†ˇ™ůôÍz#”eJŘÉ®7šYëśś •‚ďęé9,`RÎĘN/đÜež­áÓS2ţŽ–Z§ŻŕđŰ$Ĺ?÷˙•vĚa*ÍŁ•”Y@›JAíer`ÎiÉĂp0–˛‘łdfµ ĚÍbµŰ?Ç=|vJŕł_ííć…d3h˝ź—L§ahĹtV&ßŔs6sŐÎâŇLŰrÖMYp\†ŻĂиeş+łä°~®=ZoXÂ:=ť”ä„˲ö°ĚŢ?qUÖ^Ď˝ŞĹAŤg3˝*ł×µňń0ň‰ ܆±Ş¨8Wő‚¸Ťv>”w[É›†·At7çmEÎí2}_foĘě¶ťm·«ÝŘ&…KěqŠüŚ ‡ čŔ\ÖÎ<ÝóN{¨ŁÎ…¶Ňý8O Hlţ0ôD-¸ZŚ%ÁýŞ[JBwtîiśv4\;v±‰Âď¦2~;ŚČł5ř”/NQ+}·®rÝđź:›g¦µłŤńű\˛UNă“•Î2§UŠ•FŘ-vd˛ŤÄ`ď_ö6ǵ˝Í›t?G+‰eQô¬78©…PÓ•q6Ĺ:±ţŘý])(“ůďźu.ťtBŮJ•“b¸ˇ‚‡ż”ówT—YëC!E@¨îµŞĄęÖąĂć*Z«x6Tńq™M9ő˙“+îÓÜŠRT¸»_á†gVb0ŕ@ĄË‘4ţć W˙Ůj¸ŃZpü–0ś)ÉiÂ0gĆhnPIJ=/۶eäbÂĚŐ.rěmŮED ÜâZw‘‹kĺĽäµv‰ŇúIáČ_}Bj¦ ´f>\Š!®‹(DÔFÔÎ=›Mµ˝ŹVLÂMď5‘ś-ÎQO’ŹŽĎ"V'kÉ,1űíp[±¶Ż–ŃąX~_‚CEf íG3úU ¦!0K»ţěŞ9WVúˇś}Ż}XśOĹ9š$ińÇŽyŕ€UüŁüˇ9Âát&lîOëćs°+ ţŁŰ2뿯­41Ţ$1Lrrě)nSl1•Z]lěN“>4pv(#…ĄסăŕDÍńN÷ącŕ‚M©sŻ,N!č h«*pWv·Iî›`ÇÚ* H E ĺ|[ţNŇč¨öŰlâ÷ů^ŹřÁkNUÁ^ŐëČľŠHFŮRµ˛Qy“ a˙ŞL󮱂7M÷“:WĂM¤śU•vµˇç'?*ôp¶1mzËnőţi˛÷h— ZÓj‚ĺý|Óé:ý;Üç [xně°Ç»+CĽúT™v”nb“@6ŤzgpDü„ôˇî…ŽdV˛jĽrsQá€đú6P¶X7nÍĆMRi9›îŰ .Ć ÝŢ ńĂY.W™®ŘöJJVťŮŔ„bĐ’=+Ű—/BC €*xUt)¨©Ť´”ěŞ4ôצ𱠫@Sshé(‹šl‘ăŠň*w’Ţ~[1Q¸1şJ€N `}vöĂZTl„ź‰%6ž…¤ ×6áÚ†TüťĂ…Wvŕ÷ĂŇë2,AT“&Üj€n âĆüĘ8Ó*‹0 ăüIľŠK“в káH‚ô§ÇÂw<+`÷k˛ŕŞ*žzV%l ŽÂTNp ŚĎ†Ŕ±Źçá ?KÂ`;4Ę­@,łKnź%°٦,ůŐhŕw”’‘pAŐş"ôHŞ“®†‡ŤY<˛ŤčCNč(Ď–ń›śpłFNU›@Á͡ő’88$ߎĎr¦b‘ V˘9E’› 7Ągś9\ŇFT,ŕú;n&}&G¦ÔÖü Ü*ˇ4ĺŐ» 4ŇB‰Ĺ&ápłĆcđIiÄehÉ}ÜEí–ęx8ÍuËaŁä°Şť”Ĺë¶ł@hŰëä^¸łë„÷:[ Íf Í^­ SLÍ|§.ĺ†ä3OŽ ýćYV &§ů°šçsWgn„\Ďg—Eş@;8h;ú›°âěŞD9 ›ćŮîľ¶ü FôÝ`ČHěZ(B§Ă*’o»üZ4××ýz/ 5ÜŇř'¨w·ŕ‰ Kţ#aě#Ă}®šôőMZĹYu÷}Ón•zG,4dÎ ‘¶“3C޳Ъ^p±5¸Nď`ÉëÂzÓ÷ČŐ±Ž$ŠŞ ómĐĽĂVD-2Kô®űĐäYV˛`\^µJŐą”~†2Q˛©ÔCÔ.qZ Q@±Ś 'ż@"śÖygžɓţˇQx?C8”ó6ż x”Ѝ{ďY›[Çfí×8ů¤r‰?–ü÷Ĺ+ˇ›í˙"\=#őIYuę«H“^×>ÄWŹâS6Ŕ—ý“>"dóäčŐpířŐŕY™%\÷m4ź’4±ańá}Ťń[şźňAľ^UŰNË‚Š¸Ç¸‘p—»ŚďIč“lËţűPń©îě&o7ń«9Čł®ňĐé¦s’­j ńňyń\˙śŤśšč4˙xÔĐ ?Ĺ#±zÓFJŰîđúvxn_(Éţ}~ŠwEuKDĺyů±f÷/¬ăëß E ń±C°ž­j-A?vKíČÉńc(ldôZşę5/Ë´ŞřÄ.śÝ‡˙Č]śđ–ÉŘşmä,<çřŃĎ’ü[#eÇ $A$ÉFĐf­¦üąěl6“ĐżD–ďž?Ř7}gÍsŰěŽI]‡ŤškřYk*[†°(Ő®ăˇ%ČpĚĹÔś/íÖńA jů°HE¦ô¶4¦ô~~[˝ÍĎ?Ć”IKEzýr•Ě/öŁ}•p¦ďö)‰‚!ţsâďü‹aR=čťa3ëßóqúÜjüútôwu4eśĂ˝˘)`Đ ‚’‹eô< cd†ÜĂ8¬»Ą1ZŇó†{üě@±«–YffŤLŞ3{çU9Hűď…(1F9ľĂLď›–ś§Ý÷kČLÂŽĽU"Hď> stream xś}RMoÔ@ ˝çWĚq‚3¶ÇŹTqŕジąUhY¶»-e‹P˙=ž4›DBBs3~~~~ă‡Cjgţ^»—ź%ěOÝt0üč:śŇŚ ŻÇ$ ”@•4Śß;ś ,%Č9ŚÇî2ľéLÔ(Ţô‚pBŠ_ű’Ĺ ăĎőöѡUŐŁ]O DąÄ_ý@BP‘c]ŠľŚďĎ2+Ř$8ŞÔęj>tă‹Ëřą”ŚŞźś…™âŃ98ŐxµÉß/ů7NąúÝíY‰×MrŽo˝ZEj)®ĐesĄB΄ćjkŽż7śű…ó9"Żż]ŘďţAz~ 5T÷4Oce°śč<ÖľĚjĺćÜ9<ő ˘I‹·H^+BčłäĎQjia†J˘ěÖ»pUAÝbďV®ÇőöżX·ćÔ:ŕ\”\Ş«ŢyšŐ—j«ŕj©ż_˘—Sq,Íý9•Ą?×mŃaÍďÖ<8Ôl‰›‹č¦YÂłi-‰ŤăźfĽúž°´ÝĘ@šx;Ýf|§§L †[ů»Ő”WĎĽ¬ÓFúcúî¬äÍĂřÍ—_Ő¶XŃ ďĆżąľĽÁendstream endobj 754 0 obj 438 endobj 760 0 obj <> stream xśEQ»N1 ěó)łHküťDB h;DŽă!t‚ăř}śeďN)vÖĎŚťmD ý,ßŐ&śŢi|Ý…ą)~„m ĺVĽ:‘52‚[ś^- $5jEČ9N›đ.‚ŞV9˝ # §§AłÖJéëXýqj3s´Ś9—ô=ڬ Ť$ѱ đqşŢ§ÉPjˇžĆJkě&L'év0ŁTqgQN«n,Ť » wÖôy¸Ý9*ȋ⮽-3¨ŹłéÔĆjŇ«ä[U˛tţŻ+6IfľŮQJâ“=űjuj­%µ5˝N˝šÂťź?bŹcÂendstream endobj 761 0 obj 293 endobj 767 0 obj <> stream xśµXKŹE–8úWř–1Š›îŞ~!!‚oĂ&ël"v×I6 ŮOU?¦«íń*€˘2iO×óűľŞÉ»µVf­ůOýűĺÍę«gƸőŐÝ*źŻÍúĎŐ»•©˙Đő­ő7;~Ü´ňüz÷jeę¨âÚE­¬]ďnVϧo7FEç#LŻ7[ŁjÓĹF+g]ŚfzŰO?Đ«É{zÚo@y¦÷›-8PÉŕdúĄţřÇî§ŤU!ĂŃĐ…öój÷ĺóéva1j$Ăô ÁLɲud§ďɱÖÎŘé 9Ö6ů8]ĎOőîčĹ ŤnnŤ_' ĽÍn­ŠVCs»ŰlQA˛!ręNĹRŽ,(çĺ«é˛sĚűđŢOµ¦`®†[í÷\*TrÓË~zčď^–Çf_T±» *ç’ĺgŻ7›­U śÇé~ľtťG樨^5Ö|şď§—ěŔs±§ł0Şľe@‡oóS"|•PĽöˇ†’ŤŢ”nDÄ–ŰŻxŚÓmµj¤+NŞîŤVﻫ·KţŻ{Ţ<–UÔ~9«‹ę|klĹh…m%Řé F4meU÷F¸¤€8ł»$’<Ą+>(nĎa¶ˇ”ˇâŠFz"ďů”ěč8wÚA-‹DÎ%»` ¶ňrMz¤â÷‹~+Ç´ő{=pJŰ’ÓÖăŁ6%5ln!KýôcŽÜ!o;nÜŻé#¨šÄcR"6şZîR.7[ĹpRn ÉËĆ*b¤¶Š›đďIŞ’—|UxÝ÷Ó=Ať;NĆ)Ô O_xF’6jŢ«R"ăp„D;hZ«ĺÄ­W%ö,^S„ü^:÷Ęśüô×üł¨Î 6-w&Y§:ŽüÉÍçÚđ¨¨MŮŃŠ„9nöB8Ň„v벚·YNÍňµÁl{•°‰$źt· w´Ťß‚Bl bťĂß( ź+KĂë#ă-Mwš$4ɵ:ňý4%jAń‚§—ś9Húl‰ô ŕ˙÷’¦FlĹ-_ÇHŢZRV𥠬iď~ŁBáţ%% Ć$Oo%„?… h˘lô‡EĄď~¨ý6˛ŠÄ&NlVx˛qN%ç3‰Q§,˙"‚ý‰6`îO†şMÄ>ÓŔ.*$÷˛Ř-ÂË%üe°G^Š@Fřzě&…ĚŁy B“Hc(%cĄŘ‹Á1–‚˙šSVűBIMŕQ tś4Ý€†Ž¶yŻ3÷ý´ď,GĂ9çäřb‰‹´ĄżL7đű†íŇL˘ńp„Ĺ\†űMrËűC?<™ĄÇťfĺ ^éĎJ{{u5`<Űę>o¬yŐ`2âYun‡/š›˛NĐ«ó ZG?đb„R®Ëů\ DĹ–¨űă zhĘšJKŤs*U4źE˙ a^ü} É:­íăG‹#‰Öë«EîTÎ{=ś Ëú1˛o\zrNó$°f©¤µŽżc5ű^ö˝ŁM6ÉŤ©3 #QěF§R{Ķ1Ăěü¨ Ĺ+Ś˘µ$ć3Źú˘Ŕ§_Öžń1­Đôł1ć(†@ÜOg9*˘Ą©K“{yI8©Q…ýé8:6Gâńł•(“€nćŐ_ÔJýợËÉő$/vłÔۨđsażľÄ?ľ˛Üâ#¤hi˙<żŤ˝dĽ“Qo:Ó×bëµěŻ OOąVˇ9 ĄHXţôíPjĄDüo–Ě|4Ęč¬Sčř‡ł‹Y;ßÇ5Éţ{x#> stream xśÍZKsEŢŕ8—ý sŁgi×űÁ Ů^а‹ŘěÁÖÓaY˛% đżß/«•ŐSŁÖȱA€ŠšŞ¬Ě/ź•Ő–˘•KA˙ôß-žü,Ą]ž^/ŇüR.ß.>,d˙?˘_µÜ; …Ę.•hťSnyp˛ý©u–6ÖbţÝâ×ćéJ¶Áş šłŐZ¶V ©šW+,06ŮĽĎł±4:‡ŃńJµN)㛫ŐZYŐF©™7©qřß ÜÖ/‰lpA`řýâŕż6t„1XâA´ŢHçY+ZułŹ“˝ÜB&kŁ÷Íł4tŃ©fÝ1á±ňÇĽŕ›´ŐšďwÍKvŔ żß2ÎD®K•OôŔ°±B“4«˝lŽ_Őˇš7ŔGXá|sŃŃRÎj‚BĹ60É_IŇ!Śt”ä]r'‚& ]06ŻIB%˛iҦi‰7Z;(dŘ%k?‹n»ŽŞ~ďé t’ šŕšó‘•Ľtâ> Ň[tË RÎ$+€AČ,NWk p"”ř>ŻW¦JHľf#T „Ţ­ÖZĂ/prúÝFcH›“ýÁsJ—yĆL«¸ý‰B O&ŐüÖŚ :~q!Žs:v   ŕ<ű4rđŰ tĄoˇ'ľöl\pL„6*Ű|A¦Ą0ü€ŚPÖpm= ǵŇiĐ<®r5…-ťy9žyAgBc1°É ¶ĆÉYF÷óIOW¦µF8$~÷m´j0Řbc[Ż=;–!śőv™'ŻWÉq`}JG±#D-&őá˛}IGi`dzfmˇgV{C̸…Ž˘UżÖڧĹĚ6Î2;„‚rmp®Ç;­eüŢäáEuC',IłÄYKŐ tV5ÔĂ,ć[ҸV‚ W >VF+׋M“7#ž=! y‹a ­“9;žéë}!6\×z XXTe)˙`ý8Á…Đśa¬ő9? F€M‘¦©Ydx 6a•CĂ2¶ÂB2 L4–ľÖ™‚7Rçą°+0,˝ě~×PâĹHň‹qtš·ßŚ“WéDe §N)Ń;…Úźęôűťîâ#ź=!#Ôi3&6AC<Äd»Ź& €Ąj|Ą`6@řs2|DíA;d Ż6uô¦Ů'«8î’›5±ů”‡ř _Śë{_EăCó ą–‹pDŰěu9Üł5fv›_Gľé>ďčjk{h×—+kŰD˙şCŇŮ|ËösZě\îôŚpiŤŇ)ú;& Ă.§6Ůó…˛řB,ÔĘÎăYőÂěYĘR˝áévš™á뼔%S ąŢR}1¬µ)™®u0­±q˛–8ĘÄC‡Ą¸6ľĆaŢ·JŽçf´ DTZ¨>€˙Ů ĄN‡]ŠG?ó‰-O`ąAđ.u\}¬ňĘ=Kb ®ËiV!˛_(˘é!čő ľ%jzâ[X ¬đ÷QĚ5ŰĂe°ťąß!ľĄ\Ĺj<ÍŚ˛üř*‹úŽfQD8Ťa—ÚŮÂ`-Lff¦§CŠVśT™_“Z´ă aś÷悬u\ú ÍÓ'ëÄŕZRŽľă“ĄŮěˇ,uoꙌvCĎFE·©ç줉(ŻÂŇ}^yÂ+=XćNNGŮVă2ٍ×ŐĘöuÍ:>ĺ’!›.Ą<"Ó lRŚá–Đz«řěMŤż‹ž€žT¦JŃŃo­Lî7Ó?čF…+MQǰMLgSÝg©zCNś‰$ I;w")‡ZA…LYŞ’D#źq{q©ŕ§·×.ËŞ«JYđŚY6 ¸|ĂbeY\ŻQ˝Ď»ťAw ŽĹç/,Çm¤^„rV>”)ÎÉÖ@®oŮţ»Ą^eđźÔ,“z ÎÎCĹF>¤-LďĚ.¸ÝT©“=}-‹ĹT3—=§uě${®1¦VĆ˝˙>ął¨ËS–eňŠWTH™dš™6ţÍĆ/­@GMîdTA!Ol÷­ţŚůë)EĘd]|ĺř3Ł´q[Ů1ŢA ZRF×~Ú]Ďž,Řg&ľ\ůÖGiÝž˝áĹ6±†E•R¬„‡ĺ‚woąîněÄ_p­¦äXŰâď…Đ˝Ěő~đ0 rUxÜ4Ć·ÄĘŢ0Ď«Ő˦ezS7B¶‰Őo‡;‘ä'7$'¨álĺ˙Ż=ŢđÍzzĐ‚ťfjQx­X˝P)%l»ÉŚ)¦Ą˛đëüĺA*S*3<|&—ŐÄqTµ„Dy“z~°řińa©"®IÍwlKiQŹ«°T¸ÔCéÔÔßŰ_<Ů˙aůńęćxńä?KąxňýgďĹSüٶüŰâůţ’hŃţDH*A„p#"BĆÓßm{1( m|1pČ*f©”ş'µĹh˛OňÝSÖ&Ő09덏-&Äž¸”YŠ?ł=ćGäÉŻ(5ŕÎ.]}Ó^ĄXZgĂf”ţ·ç•˙˘ŕ¬+?6F:RŹg$—‡¬űÉÄĽMxs ŁřÝÂƬÓďÄvGÁĐßĎwTá“–ĎQ=ţŤq|pźóR]sHsg‡|lq”´Đč[ŁI~óď=ңƬîĘÁč¤Ţ: (—˝—uĚ®ďîÓŮ”'ÁNrł¬˛3_ßÍ—h—,ŹWÁĆ|ĐlHyl-ëhÉ»fŐĚdž{S»„”JŮ!˘ěŽĂÖ"Ö¤$—ŃÚk{D”ŕŰ;¦}W (ţ®ĺŃĄQ6pivKďäˇ:>¶‡˛NčɸiÎG8e2·ěäíqN䔾ÎU?›Ý őůn{h¶»mĐuQ*?B(?™“Öµ} dßä/ Ž*ß(\u­˘ŕřë}ţ¶`öŃľlý,{#:Żö'OüŕÇç+]Ë…ŁÜďÚx„›|‹Uďť±Ţ×ůĐ .§ něĆ÷?őjňM{ăˇŢŰ´ř#ĆFWË2±{śžo ř•ýÜZĽőApÇîÓÖF|ßáŻĂµÂŐUiĘwŰü¬Ńő˙BůžÍÔS¶ýH¬ ć_ř$5Gś63†O„ňŁAŃD{ŤěS±Î!P  ą2ĺëđŤ čaPÂШ=í›…ÚÜ#źŞýßâUłŃź0•=RryT%{CŢđsÔ-–Ś·—«ňqü,=ÖQŕZm˙V—łyŽĆcĽýiń?Z='öendstream endobj 775 0 obj 2564 endobj 782 0 obj <> stream xśµZIo\Çrä%aŕ‹ć žvHNhq¤±ŔČA\­)Š´ÂüúTőňşş_I9tPł_/µ×WŐóqĹ™Xqü—˙?xż÷Ýk!ĚęäÓ^ś_‰ŐéŢÇ=‘˙ŕyŐęń6.´0Ĺçvµ=Ţă,x«´HçYíDXÍsB)ćWÖ[ř˛Úľßűyý—I3#u°ëżMÎlV™őźÉř‡I° ×ëí´QLíüúiZ.ÖŻ§ŤäśI˝ÓĆ0ďCPkY‡lÚh'™ăŽosś{+đ0,ăjý Ö2i…Q™0+Âú YşÁËb^’ŮW“2Lëŕń 0|3Óý#YZą©ŁWäűëÉjćÔ̬2¦0‹Ă'xľbZyJëK¤ (°fýSËWŮ÷z榒E PĆŢŕuđ—Ókž$ę T˛ =źĹ “bôö‡‡¤ŃÁ O2éfýVF·ncĺlBđL1?굆ËhJ˛±Ë‹Ń†` ¨Gux9 1ÚČ1aÄŢ>dĹB&ú÷­@čh‘š¸Tť] T'o˘tţţ bË`ű罝ż–Čă-č} ¶ë‘—GˇaŞ®Hn;đ9§çűBLÜŕĺŽKzD ˘ZÁ•l®÷kĺ•ď&w9AěqF7+Ib'ĂFI)gIÓÇb+š™©ď+.óówWż»i‰G^Źů6—üPŹWu{'ŃŮ ިž$v2|4#7fh=2G6parńˇ‹ć0€UAş ő†Zś‹V§h>FRź·#âŢŹ!XXIóíI&Ę6ÎzľŕĐ7YşŐ§TśuđmN¨žd“lzmćLţé…“IbëW]°ęáF›rîă·=ŤÉ˝U qŽÉe>Oŕ…Jú0@˸’śôkď€ÝŇîŽčČ«©@hÄ’Á8Đł"8âíˇÔ‹ÍťQqBŽĎůJbŘ&z”Âńl»ŐЉďĽOžíěŕŕ>ś˙•¤˝ÉřYęP×;IŚm20Ĺ| NgĂčŐ‚ŽEsH TEÄwt…¶“¨‰ îUNL© űPqťNÂŐŁ¬ş‘@wůxľČĂ8ä0•Íô’¨Ŕ•=é@>ݍ‡¶^#Ýžin¨Š{ÎÉAâl)wćQT–YĄ‘µá®Š«ŔÍ#Äkä68ő„*ť„*)a…§]Ţh»66"@qäzâ>䨏r€|®<Ä8ŕ › ĤLڍ2¶9ÝW?Šű@Ď€k@ĹRHřLWďzEŽĹšŽö‘ŞhIZ«´Ë&ĽiĂ˙w–[ /ß 6"7\šę$GŇ[č#iß=«ł(xxW;’U±Ť*˛ÚŤCŢüq”jHlČ“Fąű|PěYȶűMÂ]˛O5ĺ˛W®i°d‹¶Ńf»Z ,'|S }Ë2p—!…cľ[É@ŠTËcQ ĘďŽÂYrż˝/&ŕ0‹őYĘÇŔĹčvuČ€VużčË”ÎH'ÎÚcŤ‡]ÓÜ8Vłóm1ŻżŚxîIŻf8+§ŮČŐěíöÔúr_Ř'/öŮ­K6›ŕ\Łřńĺ ‡<şuyŠ^Dëd·‘+0.a”KR!V“¸ĘäĐöŞK€ĐÄp %VĐEl”X>$Ş”Bo†ÝÉJÉ9ˇ ‡8Y;ލ›{.ő >Ć˝H`­µŚň]b>$ÄŽ…iö  ksý›I3~nđm©™)ĄK®¬ż%XGórnGâ®·µmŚÔáň˘µ¤›tŢqŰ,A#&@ôÁŚC•,jÂĐ´Ň›~źsj7†<‰Üő4ń•VŐmog‘’qˤX±]˘„ľWÚ#0öÔ‹&Öď ŹăŢ;Iść•¦uŮô^ă4őřqqř)çËćpWŠOĄ2zŚ–×şABŻúŰŤú+şľÔ%O#> .q©‰(‚ ]†JĚČ1nËéźĚďkë_=ż<ţ*¤Ây{€Bŕšô+‡\ÚĽHO ˛ÉDpµÝp12ča×k'Ź‘Ü˙‡G’† ŕwÜŹŔńňÁ6—Yůáłž4~·Şł_ŹÇďgŤnţ“=TÜăQyGŹ`h7FpW§ÇeÖRô‹hZ–cěŃ3ď÷ď~pZ»áă08 ®Ą˛ M^vů8LB˘ŘrjŃ|ǦˇW «Žť…}¬±üâń˘GÍţTśBž‘ĹXćÇ‘ćW*‹źd]Ö.¨îž„× Â,74©íâĄ#H+SOě·űÁăů-µyüUÝ‹]†íěmݸŇgo~l2˛2;ţ=Ĺâ·űm+=ç°x¤î*[˘řů§HŞAž·ŁŁz'ÍH©RTľ­…ŁöJX[Ą—?úuÁŽž±XäßqÜŐ–lÚZéyD1gB} ąo«{J‹Ď· ”>_Fß@—ëˇS íä63 0Ň ™˝Îq-ežn÷ţ˙ţ%ďendstream endobj 783 0 obj 2751 endobj 791 0 obj <> stream xśŐZ[o\·~ׯŘ>u·ČŇĽň)ČĹ R´@ęlЇ dÝcI+K+Çú÷ňśáe%Yq ~0Ĺĺe8óÍ73äyżŕL,xř—ţ?ş:xőFł8»;ý ±xwđţ@¤?xµřzJłśY+íbsz ҡs ă8Óz±ą:řeůÍJ0g¬“ËóŐZ0ُËĂgFçÄň{w0Ô[ ­“•dVJ=-oWki$óB-NRĄůźÍßł4šMnA0y‚ýă`ó·_–ŻĂÜyg–a e” "äÖ,¦ř4ů)Ă٤…µny 2píˇuć+/'ąĽY<ď+ěÂĚŇ긯fNs™÷ݬ֊IŻ'ÎnsŢ«y5kŤ°óŇş†pĚ)ď@››cPhB2-ŤŃó<˝¬v$¶Ţé¨ÉÜ{ GňÖ)Čv ĽbĆx­—ŻĘďĂshÍ8‘çÝÇ-< důvŢÍMËcěĽŔ}ÁpšI+L9±Áްą‹cAńbą-k‘Y`yŻ™7šÎÚâf×eYę‡^`/˝›Ha’:,·SR2śxůae™° ”E„&B‘ĺ/a%!™đĆ €›|0RÚ(Ť´ĘÁ9¤±*Ű~żDéČV(‘`)ÁH“`OŹ“öŔČ0aü^…ÍqµىsgE'#Ń$¤K2ÂŮ ŚŇ¤¸ÖíĘ€“Amő[Č #lîpŔhý!L'Ǵ㢂iś×ÁÔ[n–ëhFŁĹVXf„_¬TX&.rŚNÔ™SďÍ҇&‘~‹ ŕ,Ŕ2ʉâ- d€‹‘ů×ŘDÜ ]ěpčW'a[ř Ŕú4`*«çůťěŠ~űŰÍűě RMˇ©¬ç­çĚgY«)·âr‚ë áĤ•;—ßgaŤçɵ•ł6‹îDr©U_pµ €Ä”ĚxŞlŻ!čVéô§(Ü–şHg üé€ä@ŔßĂďšLătٵ^ćv@=qµ1łŁ¤SŻ…śĎýCőu˘hp‡e‚đă˘"âLóžZzK{{Üì/` <ŢW.öü`ju€„ü,¸ź©_áďtt ďźłŞqRŽ ĎTąŠđżŽË’­>s\Ű1ĂÍgËr˛ďągĆe>eú‹a"fâZĘ:čÁŞŠi[Ņ˦9O»ÇĹĐ©:Ţ(IwŘádBgĄÝRhH˛çč©ëŚâŰd’RXC:’ă&N GPÖq&$‡<Úů´qüý¦ÍDÄ%ĺŻ+xŢq[l ZřĄâĽ˛±ăĹ|÷JÔDwzą§ĺLKkÇ‚ąľ \ŹAJ°ÓZ~ú°‚@MćRŇčúA~?ÁľˇFÂĚ(ÔŃ0†©Ţ¶óŐĚ·3!űú1xA&` w×%I%•Ä–Ý0Š XX®R’I’ś}‰Ë}Yá¸#ąĐäĐ•&E pg t*]ˇĚůČłíĹaÔľ¤:%GZWG‚ÁIŕ#~0LŃzčF{#śtˇŞťĘ­Kµ:qšĺ·ŹqĐY©Ďdý|bę(!żžxĺiděuI§Ňa¤!A3ŃŹ ěSBâ»O±Iťv x`\Ú±§Ľ ë O§śµT‰yGăÇgÂĆIÚŘ;®G«ľźť ŕŽ™áýŘ·áD™{NÚ+Ošę÷:VV’4Pl©ëÎÁpĘ…)P$ÂL’Ä”dĐbóˇŽJIĹgH2HđOôK‚q…6ťđ®9//P'®%IĎŚä*_ĎܲGo;¬\Ë»ěíżâﱸô.0ĐZĘ ˛¦'ř“ˤ«p/ć5(ţ¦Č1ŚTC’ Wäz+_3‘,śT§çˇŠňLőůÇjŞ®B÷Ţ%Íő ŁË3÷OĽ’±Ľ1Ş_yĎŞ4vś ŚoBŔ쪄“7x™ň›_aó[ÂW˙,6±ă 3~ăÉmKźwŢ ‰dă¤oo*ď|•¨45¶B9ÂÉÄ—Iü»i‰ŁŤ¶÷š¸€~%X}R˘­\!Ń´® ͤš] oI˝!Đr]9őE`ĂgC¬$îŇ!'˝A‡Iv…„#c ô~;_Ş‚ZM€šÇŽ1 «Ű¨ÓÂőŤÔ`·é…ő¬„ ŐŚđ‡ÄkQ˙×Q¬ÄuJă†üřÇ/=Ąâá®a©m¬:†Aň‰[Oîů©˙÷őľ$ő~{›űôzľ%€ż)Í&ĺiŐŃôŃCI‘JJW’x“±ĄöM¦‚âzĄ”*<˝çKŤxÄM.8pîltÁ]äy̆Ëď'ĺ÷;ěÜŃNídťt^χâ™Cađ3öţ„ÍŻć¦őS`ŚÜ$ŕ{§ősď›Ç8í{/«ŤŁdF‡ä8÷^t‡+ś'!ç$äńS|Ź˝ä@?ŕ€Óánq7VzÉ}ČzÔ*Gť"\Ń=1Ŕęt¨łŰĽÖ잡 °8Ŕbóĺ%˝›őűc­‡ÔüUBôp—6V–Úí®VuÚśŤ!Îz5ĺiél˝žŔdkŠ}ƺűłdBÄd+É )vnqŔ!ö^cďö^aó˘Z—증ežKj!˛Â.ÖA* &B·Ăeݱ÷ mµĹŢÓ2v~©I‹–~Ô)ÚÉ|F˘Ąşó¨tIävhó{L@PŽşęygš t#Tâ^ŞĆk‰qŻ;fĹŽV¸ďÖŚ%ën»-˛E­dN(:m‹^đ$á<é&·•"łJŞĘn®%˝•ž¤Ă€źp@Gұw3Q˛JćUo›Fvl{/+—lŘş±@ě=/˝3„gQę·Ćžý](.3č-\Ńt¶kŞćĘ©¦e)c5ś—dż©÷MM߇š¦Ľ2/40 Öön×(Ů)î[•ćčá÷0,±Ŕ臒 ÉĆd{R­e°~P ĂîPŢý N‡¨#’!IŇ%Ü Ýß?¬ 6y 9ď 8ö=~ HĎćQ”ÂĹ˝ç×dŠČ&XşD§"Ŕ$víąr¬MÍźd_š“”?×Eń¦¨´iO’B”Ö0_"¶q21v‹ýäZ#ăą9iÎAžLÇ)'‰ ÇĂĂ“i_d_@LěŘDŇŰE¬âő´ěy!O†‚â§Ý ±|śÍ"hbqťĽ)\foz2đĽn@čđ-ö’˝:-4ń&ySĄxÓ0‰!™öĐŰHްfÚÄ DŔ«Ő3j‹?†Ć&O¦íDMäđÇ(ďţ- Ęáo» =–H·©x—H·('ëÖpť“1Gë˛qe·€řGđ *}Ű"· ďÚ8P#÷ম™öS+ďa ěOprŠŰ×!'m‰Ű˙^ ÝçďjJoĐŚBIă9dŔ6;Ň*ÉTňś0+‰Q €űü'hfVą'(,¸¤˘öóĺ— IJŻ+íś_ş^=żnřü\’)| ˇqěšä~d‡Z µŔ¸˛=ú.N+É”˛čD„Ĺže=ô'ďˇĆŃ˝/cC“\–ŐÄĚëĽyšÓÇ<ÝĄ˛-ë: ‚IVww}ŰŘzŚxÂÓ¤r$ Ő Ń$9üv8í˘ŐdpV."NSmë/Yévçq˝JŞĄÝH¬TşĆť F{:r’z÷MŃÚ˘®Ąîţ±&_ÇFü>lúÝ*| ÍyőAĹÇę岼شo(íÓ©ť?JŞ[‡o&&…š?UŔE¤–Ěh?ţÖĽšî}Ź/žĽtvď壝pĂ%«7ŹmúFˇú‚\ĘwOčůE#Ľş(Q}×Bźe×R@Ű6źĚ•mĂwF@ŢěÉĆiz¶˛rąďU&+ëĎřţ/ŐŻP>~•ľ3ůÝŔ–ĹTQFüzsđ/ř÷_öâ¸Ěendstream endobj 792 0 obj 2939 endobj 799 0 obj <> stream xśµWMo7˝ëWlOŮ-"–źCňÚ˘—˘—¦zzp%Y "ŰJ­4Éżď ąKW«Úř šä g†ď˝á~ě¤Pť¤żńw{·úáŤR®;<®Ň|§ş«Ź+5ţ#Ç]ÝŹÚ¨]§ĄĐĐmnWj4PĆĐą …µÝćnő¶˙iP"8ş7¬•pF*Ýß R8ëBPý©ÎžqkŔŃ~Đ´¶ľ˙{Xk§ET¦WŐČ–áź›_¦h¬đÁ+Š |ŚŘŻ«Í÷oű7¸D Çxš‰F«ţ€§gŚĆ3”ŃűŔ—qŮK=ţ*©ú÷”´Á÷Ĺň>GgCě7C”"Di&'Úsă3MJëp˝Lޱ+č"ć­Á¦Ř­Vę)öß©&FI‹$î˛:–ť` T+4 [¶ţ> ťĂ40B'B¸ő0¬ŤôB*ŰÖX,‘q|óąń˛ŚŠBBč˙@(0 rf‡őÜÇÁüč ĎPX˘t,ë~:zY&ÖMDĐ\—I˝´\m^“#+ČűˇLžŇ("l—㸣4‚Ńő»bÄÖ«ŃąNŽą)gxqţĐ‘–Ţ÷źŠ'f´ŻwňH‘FŞqµ”Ć#jjřÍ2łÇ \ĐúZm 8Z2Mv›’Śp­Î^ i!Ď:‰w†X¦Çk#t4Φâî)%dť•üSćL\”oČ0 §ë1‰ÜŮWś`’¶ŢҬ&X‚·ˇě"÷:&&ôë2K…XçJ¬ęL*äPa_‘Ęŕ[SĎĹŽÖň»~¨ć„_đxpzĚ]%Čq _Xą/BCŔŘŔqx‚ńQhOüJŔÂŻŹőšŘŐW ł­íŤď#Đo놇ĹkZĆ޶–ů˘°7ŽoŤŽsaNF§ą&yĄ ٬â˘ô:ż'°l™9ŐÔ1|ôOp#ßGÓFR#×˙o“IuSţM¦é,ôÎĐpĄsÔ¦çź\Ö¨t&,ĂěusS_Ëo&¦wďęëł ë’XĚkb%ĆËňfđ“ăE}™÷H:ťáůô'bX'śžqµ«]iJcynK=ĺdźŁöYë,'»Ŕ›Ĺľ˝ü@»Đl=™9ŐŇ/ž§Öé¤ ]őŃ&]5Ů^^ß™SÄv«–?,.ČÎŹo{+5ť¤đb\Čß6^ĘęŠJé« ?«Bó©d¨ű€[-Đ×$VxBŘç•ĂVé† ~‚¶§VAnźÉiĆ©QřŰ|*°ÎÂÓńď®\oŻ6ŢĚ r3ńâvđ"Hb7łiĘ?Ö<^©DmwL¶UŘ”Ööś,ecŔwíČ[ˇ\Dí7f Ęą¶8 ­?oVżáßż„<ˇendstream endobj 800 0 obj 1275 endobj 806 0 obj <> stream xśĹ[[o·ň¨_ˇ7źÓölyż¤@‹&hŃ-ж*ú…,Çr`[Vd)‰úë;ĂËrČť4p‚x‰ŇŔ#ö—ł‹_|ľ»ŔOEÄâŤt.ŔGൎZÉÝ;ř˛¶Z+üľT^íáÓĆ.ÖęňwĄÍîe–ÇGµű5:ŤJŚËâ e1í%h\żpź¤1¦} j aRűŔM[Şč&Ýy»(g’nf F(˘›^T4> nv !F\XŔ kAµ÷ °C9ńQ6Ń,ŁsVşÝU~)A˛uV^Ŕ¨č@´´lđ(šňb đrř€×‹‰˛E nÚă›6ö±¬ŕ“Éʲ`%ł€ŚÉÎn‘NX߮ΟҌřb}Yp:ŕKeě˝ÄÍi+‘ĺ•ő‹’UÁ´Ô«őďmd¶OPč`4·8żű.m‡Á sŞoń›QY§aŹWSEźSˇÓŞ&PĄnÖżńľjKó·IV'ÜlÖ‹=zʞ óâ ±˙f„¦JÉf˛¨łr´·»ëô×aˇlXzl†Jkzaŕń-ÎG­n0NĘÂy©BQÉé‹ÍŇŰű¶›ŐřŔ 茪˛n á%™UäŃ«i`ޤ~K<´řŤĐÔďÖ—Ű-FŕlĐ’{hťĎ`zmí˘„"¦'î\lEXĺ–tţ{śďÁÝăîYó "âŕĎŁŹôh¬›Kiăőâ«& mö˛Ť%–! Űç„]d »?PeŻ`f 5Hj1ĘJ5$tиí„…ćP ŽĽ¤čČFбx0šă¶@Â,VUL41µQđŐXĺP@N}¤îMŚ™ĺ$(DK ]Đďߦ´´yKě÷jÄ.[Ü?éq*kň˘ówĆI‰yHtÓr-"ä]G˝°ˇĄGlĺZŃ%!)ÁLTqޱ®óö‹4٬ß5äĺ&śŚňrĚfiC7řL+´Ŕ ® Yx ÂďţEś°9GŐQ;>‡°‘}–řj9ĂYµĎÇćO>™M“ëř‹L>&V\`pJ¤XI*?:”‚T´ GęŃd[HžyŐĽá $DŞ˛@k#38Ц);řč©Âcđ'VľăňÖC{üe“)í“ôqÓ}ˇV0“b‘µ~ę| ·_ěÚî÷át•ö MĄ!c+OŐ!!Y…<’ĹžŞ]P3Ř7‰ţă6ŕËć8_ěq·í˘»tEDxŕ›H[Ť$á]µh¤úÁ.ŮčqłÂD¬UÓÔäřUyčlĂ.ľ%ţׅݡŔŤn] DmśÂĘ˙P;h¨!…0Y>‰ëCťé,tEëă‚›5´]GİS»Ođ YŇ||Â8đ>p°× LÔŃ%Dâß-„Ľ»=báS$®“Ö‘7ëÓ‹ôQ€í\lłŚ±v.× ·íqLČÉD…[„•Că‘ĂKvuź¶Ădčýř Ú;2ȆmŮ‘R*ˇń~ÜÄäŹeľ·c­‡oAîO÷®ťŚ»_¦=j‚ňčUÄ ł*÷V˙†ˇ&DCkóÇőéw« +•†°hąçřÖŕ+*„'łßĹ Ş¤¨l& IW}UcuA0™Â…±Ĺ’C¨˝ †bÚ C®.Ă0ŤH_áćŻęÁťŞ˛¤ č’Íú…mÜĂ·7mZó‡śy˛ÔkYvY3ă¤='ĹQóÜKîĺU{ٶ$ś«Í^Ř”BA$„çŘ-˝Ť%Ő:m,ÉJ¬®jZzŤ%Â`qĺ0ýĹÝgÍsG‰bqí>ě×Úu]¶Ęz “‚B©7>ďjě2ôn Ě‚Ň^ZŞ1ŻÖWŇńi”Í’wĄ‘‹´±z9ßZđ)¬ë”óK´jóžíˇłŽ”řf¨ŢlmXśRs>É:ÔvMS±´1Ů}ĚUŰöŤě b‘˙¶żŻ둦[opĄoו/ŘŇśÖqŮäR>]dÝP(“Á'€í1ťܦyćŃPúi7ó®ćł$@”vÖ‹.łđ #‘ Ž?­tt ¶ÁąK'qYŕÄĆťJĹ©FĹĄ^Xjc!ĐŢ·—隤X‡éxĺç*ĂVH»‘Ťý:]ˇŮU‚ÍúPöł ÝüB[)’—ąĂ4!G¦€üTJT•_z΢ľ?`ÉýŘŐ1DöěRi­0wĚX*_1ĺżJ»/×—¦ąČˇ…Čç¬ăTę@Ť¬e ÇX‚Ś‚ÍqÂIçVŐÖP@Pć˙łŞ·!‡Ŕ¤O´ő°ĄD•ěk9ł4^F#“ĐLNŹx‰Ĺđ ŕ˝mÝËfmľ}ęX4U ABĂh'ÉëEŃ«Ç<_ŚĆ”–őîy ţ:ú•Ĺe”ÇS €C­=Ž~b‚›‡Ńn1đ˝F=Ööł[-|ăçq ĽÔ]®út'#Ô” ¬\ĘĎ…’|Ďq¤ĹCđč]Béňną|Ážđtĺäˇ!AÓ» •Ý‹q- IţÂsŻ:ąp[, AzŹfH޲hŕůěˉ„}•yňDz±N‘´Ç«ÓîhŰTtĺjľďö€đ‘°–8ŢĐC–˛ŘaëńĐx…­9ĐÇ5 2rC>’Ń«+č×}ÓŮ„‚î®”ćĚ ´SîîÜ:^íŽK 6˝Ů†ôs 3\ŮyŐjŔź‚J›Ĺkß§śšG¤¤ĐHCMŞ˙keÉ:ó±˝Ö˙VŃLŇ_8I­}ôĂ.‹! x¤OĘŘÉfHÔŽPć+ÎĘşk&AÍéQőä«ÍŁî‹ŻćŐ퉿Öp]ö™P,9HŘ"e&¶»Éň@µwŹoŻl;'Ś…¤µJ! ‘yH÷ů.ß˙Ź)Ľ”'Ĺ$}°›:ů X?IŇ#Í üĂöľÚ}hR @E®L{Ć^®A::™§ÍŞyaÚ§Á׌P”×eÎçÜaqü¤I_A57&ů€€ť ‚řîGŘ樓ŃçÄÁcI>ńČ©O%‘yP}đ8IlÚ\‚?Ž‘4ŻŕĚÂłB9ż°ĺÎIŐÁ»ě¦,"źňÁ ]™Ĺú1×—F+Sבř?îĹSúłbĂ-ňÖk˛Ow¬Ô¤ÜÚž_4 l¸§ÜÝô˛ŹL—"ęMRZ†ÍĆÖ#[`ÍÓx_+«ăÜcĹÔ˛ÄöňŰ©· ËÖ"ŁâcŞ’ţąžVńˇ»ĘęLŇŹăŽPREAö×w´¸>rWď?(Ź÷ź>TĆ[™Ş)W•yFßJĄV»ďąkŃW1éç/2Mhľ†˘ČtCdŮr=‘rJ*ŮŇĂÍ TGÍ×Z™ Í#@»·h˙ýú®@&› Ď5­^—“B˝–H*ŮÁ˘Ý-ăďUoBâxU”ŚmŁcDj\o!8BdŻř]ŮÖ‡őâ{şP5çIěŘíĺźĆš‚ˇ ČźČňÝÁô±’[Ű®;Gš’:’5[ öĚ{%׸K˘Śĺ{xţ§äę< DOŢâéÍŃ#'Y`M6¤*coG_s6ŕĎţÓfmĂ…-nȲŹ{(´ÖqmŔ!ćm‚ÓiëX—¦ĹK !Đ&}_:¦Ig0đŁÎ/Oş{â «™oóf{,”Ôt±)űŰ/ş0~Ô[{N1ýzF $Ň|EľË`q†€ĺŤ~öŞŘŚű™H·eB ŽZŞm}2˛ĆÇ’ňüŠM@Öj{ÜÁ6ßŰčŻ»Ş OĄ…YĐ.{$ü¤Ś”Ëž .Ü$÷ĄôĘWőŁöIĺŕ_çlňt y—Ü*¸í˘Ó.Îţ˙ý6†{Cendstream endobj 807 0 obj 3686 endobj 814 0 obj <> stream xśĹ\[Ź\ÇqňČ_±oś 8'§ďÝ Ŕ$G; °ärI†K.E‰’÷wÄ?ŘU}­îS=3K.-ěĎśľU×ĺ«K÷ë".VüË˙>űŕź a.^ţř ľżoüđ@ä˙¬ů«‹ŻžÄ-ĽZÄşÚ‹'WÖ%x«´HýYíD¸¨ď„R‹ż°ŢÂ/OŢ>řăîë˝^ŚÔÁîţmX‚Uf÷ňü‡˝X‚«Ţ=ŮÔ"v~÷Mz´«Ř=ޤö‹–~'öłx‚Ú™ö¸ŔŁÖK°ˇô ŚIĂąuőV”ŢđőďÉëÇ{«gMŘýŽ!Ž~đ-Ľ6°¸ş×mƤăÇqˇVXśXÝb˝ŁÓůnĐ ülT×Ő¶ç˙}ňď™ÚÖ"­Fj‹Ľ=Ú:轣¬Ť°Źä;9(Ř'/ŇAG«Ľxr ź˙BHţŞďőÖgŤ‘b÷|X#,~ ´Z„Ň»÷j1&h˝{Ú~żMŔŰĎŹ Ťł 4yŮşŃÚü„}úE)ŹuĐWmđ­R~ ŇäY©Ő‰Ý»~(»Z—ŰÇź?4ş~¬_ć•(ů”,ő¦Ťú./Ő”őĄVi®†¶Uű'3%C}lť¦Y™°z:ÁíŰwí[KY`ł{_G ­nęË—ěyÚVůÝ[čJře  ^’€H+ŮÝ_öČ3 ˇ‹N‹¬ň§]ý=GÔCűý_AD!´W»ź÷0¶ŇŇ)]7˘ě¶ş|đ§=NÚ-Zwí.óYI·đÝ^­H“ĆÁş­oö )ʇm¬(iĄ‘ĹâgV`"j• tąaŐÂÖůwľ}ŢľUŃöۧD”®±+Ф …®j+ňé»q:¤W˛ŃŤS ‘ôr "o´‡™ţ)b IřôŮćđ<ů”rnZá?PżÚ‚jŃťú%rMčň#Ě+€&&Ňöľ}{Bž˛3•W+;ľn«¸¦4BfńĆ&…Őpť—î%]«Pdă´›ę›8Y%wφĹFrŃ âđąÄ-+ôE¨uĂąÓ-é˝YŚęŢŢ đ…e*?ăÄ3‰L&A˘Ő '7ýL&“HŻÁ”ŁŃR‚a¤FĄ3µŐ‚ËŐËjŃš¤@ăgH«÷ C6űęeą)#č ÖŐŚFúęi/'`]Ť;Ď |J˙˝Ť™~±˝aęŐ*î[gënK$BĂ‹´’«Ĺ=XÉ(5ĚĐ*ÔH;íLݤĂĹß˝śLkä­8T3gÇ^_ćŤ÷(R@¸9 IsuTÔ„Ţt#ś´Č“UI’2YBŔÄá!R§}DĹĽ˝á•ÂfyÚSÜŚX%L Ĺěţ««5V‘Ú‚± »‡tsPO:PcźkXâBč NTP_©H9aĺëQÉŚý^¶yĎPśÔr1`¸î¨ ¸ M ť«ŕzyD.q®^ąĽH˘d$0c5@«#X”׺RNIČ[K-Ęe›2Ŕ´1.;ŇPÇăP†E/«ŕÓčh.ڇȡŮgÔĆúčZŢľE龆Ľ7ĘôëĄŰ˶«ŰÎŐŮřKrÍrő»OţńŹÉ˝ĘNéŹ>2´ź@="<¸‰\?'G…â`XŔS°X† ťs{[e ěýĎT”$ě®’WsM!˛’Ö~NFÓK97ąÍ#ś§YŽH‹µ¸ [źÇ>4ý—}'CÁćjĚ>vÝăz••€‹z"Wě[ň-ʬ.3´CąYő RÂ/ľíX˛Ai2RÍ)”÷ů˙ŰPçÚ»Ö´(H× mDŹ )Ż\.©ÚŽ~ťĄ\ßýµM¦úC&@oŤ~Odťcë)Źđ¶rfYAK“ŕŚlʇj…ž l1aq´µŁ˛ń®µżĚ3P˘ č¶8ÂvD˘ťš+ßÂ6$ó5ö[m=ŐĚ7ě¦^PĆľ–Ć›(Š@ßKH÷}XeTŚ7) ’~mŮ mpďmŢXÓeż°‰MҶy_FćĹĄŔX©Ď˛!ÄI>¤éýʨ7* ˝«ĆÔdňÓ‰\ Ž3şś*Đ€o›Ó6îĐ3ʎ˙Ü#ć7%FúSUCOYâçp›ŢĚň,‚8ŤläŐ9@ö°nĽe ńK׻ۢÂN;Nx¨ř0Ť×#ČśFúÄu6±żJ3–Ęň’8‰‡§X…dźß‚'L1xđ k–ŢkK5Zď6EÇ_11˘2vô®¤;ÇG’@‚§¶T+ű!—A¬ń3[ yF(ŃÍóˇ—Oíý:ů…#‡WďlNÁS :µTP1Ś_µ1@V"ťźPĘQĺ6(TFŽ=Ž»Ńłq~y*¦Ü¨ţu®`Y‡(V  7ąďfš\íë>¶!ŞÎȰő¨÷‰źąő 0ŞDä0jʬŐI«ß%ťĎ…•AŮ+me +§‰µ0+®K`{ďŔľa]Oy\C€$ĐgjŕVb°ű·0…5Ŕ"W¤!:µ^Ä >öÎć—aŤĹőńiëř:íPr÷í“˝@RLßchwŤżĂ“ő! 6řŐČşŹ÷@J˙NĽlť¶ć?"˝ŕŽ|Ŕ·Ňší¬bů[5)˙‘čT63ůřFO˙Cĺ.’a}ż Ř4M¬dć3IcócĽd´űÄbG«X\{ŔyŻě§ŞXÖ&’|F‘gęK@Áę{ śßMÝĄ°’‡¤©F:ŤŘůĎpČ5i9Ńdl~~V&€žÔbń„h‘ú6Č(óX-0ŢĄ|Gj&"WhbÇÜZÚ=71“µŮé8„ŕËwzż/v«;<U8ŚtPKu`UŐR>¬<wL¶dvII0ŢF‚ţ IH=aĆŇ€6}Ö˙Źĺµłb°Ëjě¸Yx ô-_E9x§›U»śU"ś‡{ řA41ż)=µOłîě3Ŕd€AČ‘nNM<ľ;`p&(Ij%žeqR ‘‹8ݶŃq*ƦĎNäfĂ2|@űz_dbI~eôßqúĽ)Ďú/+‹ÎŇŹ©¸ťň=I]R‹PíXý˛™,¶˘®ĂJr„ÉMx1y˝ŢÝ×Gľqzâ0ąă‘ÄÖĽó’ĄdžŃĘ3ŤÝÉ>–ZŤ@ä ÔB·šYíż‚®UIűŕř\Ř*A4tI°Ph0źąîŕT…Aä&č˘pStď’U°h@­ĂzŁ\¶ĺŕ«ú;ŐŢ´G~ł^ŞŰ pj)×´ĐjiřZšŤŽ Ź¸ë˛„Ű:É ±&sĨìć8í÷čĚś*·ižr)§Fáb˝ćę,'7𴻬›»ü}ô‹Á_…×{ČŃm~Ţ_W·wđ•A¨ńs|eP1Ú˙zľ˛Á:µD¤ď«şÝ #W-.…ůyręl1!ďÇ×ކT”afúTeĚŠŢa~@¨íăW1‹pÇE ęŚĚľ$¦;5áž †ěT†;qÓô”lIo kyň̂Į4Ť°I µôuçĘ"1Lö\m±ŚnEţެ4¤ˇ#áé%«—Yü‚sű™U[ó™áG †3}LńˇëË‘p ŞÔnçJ:BĚsŇ÷ŃJ ńĹŘ1MŐź… â¤Ůîy»A‹8“iĹ„°<ĐzŻ÷”…‡ôsLń†˛§xZK&+ąćČwS]ŞóËHy¦ĺŐ›őYâ+'ŻKÁ®űŇrUË) đą©?ŽD¶gkTčęÂ>ä„QäŔX_LV‚S'둿iľylžĘă˝ĆR¤ŕşC«˙:D©U§pżÁŽŐż±•Ő„GŢŹ{8ßÁ턾¦.ä­ĎqCOČ˝‹žşH„°·áíâX]Í[.tYŔ« ‘BľŔĺmb ĎTëvNžěXcÓ˘O|ŽQKGćF-Ëau p­˝Ó|ŻiŠÔQ©żPg”łgrUŹŞ:E—JuĎDlMMż±Ą}ď¦ÉÍËđqrĎpU¬ q3@5‹ ´sF1†šťí&PLŚöääX¬WrłšęYAf,GZÝÄ‘ýôüNĆ/P¤“–]­Ç}JFÚÁXRś¦‡fZ¤ĹĄ\@†*ŢĂ:"sŢ+Kîăwź?™H "[ËÉzů-LÔ›\Ń  XuľĘ“'ô »ĚŠzĚU”Á„ˇKšĎëm}ň$®U[ŁʰH˘ď«Ş.úË«8Câë=öŔ÷ä\ {Ě‘†UYc«^Áę×$ź×YV[——÷x|ÉjG!ú¶m4Őضś|Ű`Ĺ1]2Çö]R]Ô< ¶™Ó[]‹´jíý§:%ëü0çąW ¦ŐÎ’4źX@]Žw'OJxĽbjŐulÉÔ§9ŐťµLŰáÍV]ß±|ąOÂĄâľŮaăĎ)TN´ŕ2z|lsîu•/‘Ť©xxµ9—Ś„şm…aC<<†›Ă9ş¶¬ó ][bűÓĂčńče¸ăiřňv[ęŞZ\’^}Ôĺ'sh^ÚSÍÂĚxśÍ™ąkSLŮçšÜ^< ďŞ|ұ®ąâC“ü3§ŤČŚ7ŻŚÇę®óÁ@i¨‹Ë‡S®gDTšYH1h“z¤ĆQôX|2î+MŃm»71ä’ĐLˇ鞍T’I?lú¦‚3©€í~Č~•ăŰĂ4Í•n“©˝;™­~\lU^wdt5óĺŢ—­¦űĺ”¶÷ń±’­“ŰśÁ#.[µ5ÍŇNŃx_‚€ů2ŢâjëÓz¶c"ô}Ó>%ٶvłë‰Š€`2´Ôľ ~WĽ©čYȇĺfÁA%m e߯©5 ŞĄăI=O2ĺŰżî¸ÖxţM ­6XÄGżńgíî~ž"ç°µGUˇcÉW©­±A ń¨Üůtě¸|ÖÉÓŠŁąIělüב›lăE}9)–CýľâůóΡ.Á;UşR7ľŢ/_VÂ:^V& ő]|>\±ŕc[Îçš?©:yPŮĘĹ8ßp‘š#)Łn©˝ ş”QůĂŞf^čP?•rŹĘ˝jű|OW'ÁĄ¤´Zť‡×z˛jGçř*ů†©M9Ú×âs"MÁ=g Ľtvc˛R“Ëź4p ťGmŤˇ¶†ŢW„đr^~M_Úó(—Ą­‘úĹĂhuޤ’@îń¬«ťŘ®ÄčNÝßy˘lň*÷oď9—±ýćhRĚ[IiqňÔp,MśëdÖqTʇ˝Sč*$‚uťľVg#ŚÔŹq wbi÷ŚqćŽ,ô˘Z.Jn0Ś·ąĎ-mö,~Gšť˛WŮwq_z•đ岯×~W{Ża‹‰Ű2 c^_wŐO©¶fT8š+ d;U?Ż><éĐÖć%Ä ZçöpžőÉsBĹU›ł‰Ű†;^ ZëˇJ ő-'‰T¤`eh—‰ś*,d !©®=?ĹxĽr3•‹ĹP™‘ĂuF JX­‘•;Ą ›8ţĽ[7žé‰D9V9ť™|8ĐNµžQśÝtřAq9yí&(¬ ë ËKw˝]±‘ś_']b—l*`3V‡€/Ýě҇ƏĄVÍŞ§.7sń‚W?p еĂMˇ9˘:€ĂÝ}¶ßéšó2Ku]Xöš%Ďm“ŕcÇŘP&©µ-‘ßĆA$âźë©bUZßß±((X1Ko5‹XÎů(±z™˘ťéĺu} űŽ×b•÷Oí÷íńuz´!fÄĘۧ­Ůż´·żmŹ/Z3čWo' CĽęż•jYuľĺ1˝˝ÜjwWV)ÍNÎ÷5Ű/Ůčç[ 쌏·Ýć}óäÁÁßßeÖlendstream endobj 815 0 obj 5269 endobj 823 0 obj <> stream xśÍ[ms·ţ®_ÁOŻc^î—Ś=ă¦yq“8­˘¦Ó8ʬW&éH–Ąýń]ŕěŘ#i9n2ţ\,‹g_úyÖÔí¬±˙üŹŻö>8hŰnv~łçćgíě§˝ź÷Z˙?Ť§šýĺĐjŞŰ¦ŃłĂł˝¦Ś–ŞůiŐ·Ă,εRÖf¦Ť†_f‡W{ĎćWŞî„ôüójŃÔz´ěćŹÉřďU[˛mÔü°ZČZ Ş7óOơnÚůAµĘÔJy[-şÚaó‡5 •Ş=˛ëĆíú¦1ş Üěô×dú ŇŞîu7Ě˙m÷hk»%ř¦;8Ü0$Ó(1a|ŕŞŰ×6}­MOĹyR-T ?w2aőÇ?ţÍk{€ł­¬¶[=J÷Ŕ=Ѭvŕç}z&˘›µŞ–J Ëd!áZz1[870wëA™mmz©;«Ě0¬­@ÔFôvzzZŘ {ŰZĎAâ#^ŮŁŞNËůËJwiő¤ÍĐÍOGýÂ}Í׸ćĚŞWŔą(Ł•%Ő s1_Ćő«ČóĆę`ĂWvQg,ş®N}/=żŤ¤ÇnrĺRRdş¦›úEě%®nLÓÎżÜ;üółȧ–‡Ö]«AwĂŤ¤“űU×#Ő[Á(ł áďpZ `iZË ¬Lš~°Ř&¤W–˙ ” Çß/áŚî:Ń:&Řk=­Š H@–vkçń÷S»ż¨{¸ăq+ \×­“‚th-×fÜęÚo%ş­[ůŁX´¬+‹h ç{Í ˝DN«řű ÜV§ÝÓŤ®Q¦ŰHIÎDH—¨4rR <#¬XĽüG”×B¶`C"ŕeeŃľ®6 ŚÖŮ%ţ|›Ęh~#' ‘˙•ÚŁJKXó7Ä™\ŕaŽŘ Ű€«7ÇDnýüíĆaß‚^%žfá»h­m[ ±g>AxMʇľäRn‘Ç1¤“Ń-ôCOmâ®w@­¶¤)˛üščÁ¦{1˙&şorű’§•µ˛ż—Ęő@š/­§$!›ş“}Z'6€ţ<2x‰Ű"”ɢ+»(¤ś´$ˇŔoŞťŚÖIŐĐ­Č~Ž”·ĹŐ[¦«Ü”î÷Ł|ŁçÚ$žSÁ)‘GÖÚ@ÜůŰfPÂ*ĐŤĹ'Ďăä5NĹÉ+ś|ÎMžâĐĎꡧü ×;>CZ"ŕ1€iPxĺN>˛“ťjtZAŔ0y‰“·T,ËI~ŔÉE\ô(Łt“ż°§:ŽśűWqˇü~gżŻpúŁ8dăÝ‚^[^nĽ¶ÄÇśÂن-ĆîŽqđUµ‰Ó”N4µŃjţ%&…„–pCl7ćR8d°GwgĄnëVěäŕA BęéX&´‡`ÄY2ÉŐîÖí§ň8wˇ©”cV+©SÜgřó˛"j WĽDr'Ś Š~§Ôx3¨Ž $W»FOW‚‡@ŮîwW3ĂÉšµN/ŰßW”ö‚Ĺ‘!© ł‹ËqDPP{áęsÖ0Č}“eŻYfřĚ—…;ňŠâOśáŢÓ’VĂŢýjçE*şó;†ú®.[ĺÇtłÇĹáGR[Ř©7ą0äZ\J‹Ú4’Ň.Y Ž9(Ź 7Ť©Ü6Ľ^ÄI«˛”ˇńś% ľě Qs\pČDŻXÔŚ®# Ç7)řD´­RO…Ł\·n8X„çś%ąČKÖ"Ž“c:ítŃ‚-íëŔn ŃĂ<\I€ `)ŕćf‰d‰#\•ýĺášbtډťŤ69!JÇz3(Ď p¤HĹÉkVżő¦aHÔěץˇyG‰#lr‡č'3m¤°›ůe’ŃľI mOü×±›Xú÷ř»kL&î}{ ĐeČ6>EŰ/Žmî•^fŮÍ´•ۡ0ô¬kVo;ůď ˛€[îFNyĆîvÉnńś˝}Bp^0›N`Ë j‡Vg”“Ý@˝ó 4ÄóŤó¨Eě7Fz•ghm›{$ď{Ť;'őˇě†ŕE–ůFąw;Ę•üĘ}Ţč_ü®› IbcćĄňÄŞŚezťetç,”ř|Ś@©Ü8‹¬%&ś3(]ł´űľP1… _‡05ާ¬ÉeŇlLŇN_´Lń*+¬:CĹ… Â.‡i'ب׸§38$Ç" n°vY§Ňx;Ř9 Ú­6Ł´DIr÷}Ľč%{%$w 1ŁŚp™łąeiIĺBŢf?˛2ćĺá‹#rí[çB—ç–¦wá[­‘ŐGąNÜeŢ&j WP8vG{Žł|JV±# ĚjÔęa,&“úU·č*e•*‹{¬jGF«ZŻż›B'fŞB;©bń»YűXËĐĎĂŻ¬ć¦Ý,qa/+® ¸ÁŤů řuş¬Ś'ŰRľpŢZd—Çô ¤A[]c(Gđţđ"ĽŠ@ÜȉWGXv%Mâ<ЦIc˙!ĚJ;ßQrŃäŘÉk.ľŻ0ü¬r±cü‚2†ś7Đŕ÷í.ßëĺüżUĚOß˝Éó'¤=ŔYRÝ~†CŇ~‚Wţg§¬9ĚżÁßcMs€“˙ÄEŹßꌩe¬L)ű°ükś|'‰ _!ĎÇQ±D/â˘pňŁÔsz1±2šöś˙JµěgË\ČÉgâŔ‰ă#ž†˙Ap{äMÔü řNŮqJŕÝ7źaÂ2q®Ń™˝aU˛µÎ·kîXq2/ZvXHפhřđíĽ’;öo÷u„í6“ŚrYÜĘ®•I¸â˛‹ÝĘĆ–[vŻ+t_P$78e… %šę©×[&ň†eá{ćřZťArÖĹN9řA#ő’6~=MÍmŞ%´XMÄÝ”š(¶ 3Ň^’şßd3˘yŇý•a?”GWÜÓŰ#q3Ś’ŰKEr9ä"ĎsuE\mü@Ç7* ®ĽY;ľ4¸oćě'ď˙1ßú~ľôÝź,ö«ÓT»ž–656w˛IÓźGĐśÝ)úxXđé4ßÂĺËÚ˘Z›đG~™ďçńr’v>ŘĺÄÍů¤qšÖ ˙5/}Ář×ňýď‹ŃÍ…BŇ$SÄ—„WŁ':É|}[vwíđűßKlfë´5÷§ß{[{ŰgłŇµ‹&QńF(f×±ń9 qVˇmeëS+˛ ůąst”3Ő)vĆţ°ÖY†Łp=ŢŠŠ ž·hHş–ćŰLőAh}O»‘·oÓE"¦•őIîI:î”&Y"?‚/ýffËv…I°ŤÝ ;ü+Ň’nĹ78<Ä!ů¨E>f<Ž•Bš3ĆdŃóŘCř*ăä‘ýżŕ>µú·]7VXyVĂUŘć·…ęoĆ?˛ ĐŠj<>ʰ˒7^qö29zŔý9+dňö†ű «Łw±=Šüx}o× Â¬Ś˙¨ń6o»î_A™3żě:N±¨á»ŕĆÉsĽe–nőU–˝vóeźťLuöĘÜb|źD#ŢIęŞ ć»$ţbĘF`š!d9Ň®đű˝‚ëUÁŔËW}4q•:o:GÜîđĐ%[]6tł‘e÷’O§OŘä…sČÍË&ŮxÚyžTÜc˘™7śfĘ7OĺČĄŻŞ^@”N‰}Ľ•VąďÍ˝˙Ą˙ŞDřŽÚér‰Ä73z×r‰äíĐ;ý9ë;>ë"™PÖ±Ű)W¬‰»;Cw÷ĄďÝÄŰtŢřᄂ=ű]?3ŇDö×m'’ążXÜúpó˛ő•É{˙ĘźĘÜďeCěë­/a˛:Âż×ÚęR·´č »Ś´(J¸dá—Č›9ÄôÝjů©;íý-âäŁT:o”A'3>rµu±kFKř’·Źß±ďV›čËâäCşođeÉ%†Eą˙Ě˙Ęžě˙:rJ.“qĘ»<‹ýäpďđď¸Ägendstream endobj 824 0 obj 3853 endobj 830 0 obj <> stream xś˝\[o·ú¨_ˇ·>ĚňNşh€:pQAÚşŠ") Ů’/µ#+ŽÇúß;ĂËrČť=Y1üŕ5Ď.—Î7óÍeýăé$äé„ĘßO8ůň±”öôůO'iüTžľ:ůńD–Lĺ®ÓçéFCBN“;=v2‰ś62Ď猗ńt“Z‹pę‚_NĎ8ůnóő™V™č6:ŰNÂĹč´Ýü\˙őLЍĺd6çg[-T4>lćK7ÉÍăł­2A6ňlkE1ęŤm—.ŤŃĹ:¶6żÎOSp˛Î†Ă!ĂŹĎśŢٸů'ľC |˝áŹ0las1vĂmĹdâÇiŁNFŘśśĽpÁÓĺ<:Ű?[ÝMőm»ţ×ůź‹´#ěE9Ň–ĺxŚó0{'Y—$á7aľĚ“(č$[A~ćt«qpR§ç—đü—řś˘QéRi1i‡[®Ł/óeP›ë6x‘/]ô›×m”\~l7Ü=Ă‚C´ő1Ľá˛]ţÜî%7·=m—W0l#‚Đ޵ŃÝ VJjşąég([{Ň/˛Śľa_|ŐV&ćQ®é}srţŰďčÚnfI˝oŰyđ+îΧí ŰöűW ń“…á˝ä­oËĹËÚ˝Wt'˘‰>Rá}żÁQ«”Ů|Ö†×mx Ř7”f  a’Y{ţ×Ýz«ě©4B§˛Ęt § ÂĺG˝RŻťEôÖKÚĺQĄcôĐńZH%lL…Ň&%©Ź=mŁWéŇëɱRVĚgö°YźaďŇOV˘úÎJ‡"E”N:«q¶/ď`ţč¬U2«[}ŮFŻŰčs°lQ°+Ź]´—ÁIh“҆NöŽÂ-:ÂĄÖMΗßőä%ž/ĚŻ¬ÓYŮBĹů÷ň=/<Ť^µQŔź–QL$2-ľŚ·—–>–ĺaăęĽNÔÁ:?ďv6vĹŰ5ϰkI-.¸]´KŢ,˘›)Ďż™ź†˘‹Â$1Oőbţý wxM'˛'˛˝jŰE ŔGRţ˘™ß:ŻÓÇĘNd¨ŕ“3„š¦z¦iÚgg NĐp…«S‘u˝Ĺç˝0`Ä8ý)¦-Ďu˝Xm¤; o}ž/ÝdÉ»˛!đ6yYČÓ¦Ęäý Bä÷÷ ŻŰ­đ@¬`>ÂBé©" SDÓ÷°Ő“P÷†>3ŹEżžŐˇX9íµ*Ű/ÚB$]ĺź0iR¨&0Ž:÷kŞŤu°©čŰ6X”MËN?Ő ‹nŔü* 2Ş˝Ĺh°ďú˘]öMĆ ĚíÂIČĽ˝ ËđNË­Š»¦ď¨0`ŘQUśš?)áC¤´•żBŰě4ś,Yí5>äĹŁD^D±/Ë j\7Ń|ňXŢŤ±3Eacµ˝Z*:Ô[’—ŰV l%ş­čł zϡü–츋+Ľ!On#"`ĂgśC©ÝKÖ‚z…d÷´wB+Ki* !i ˛+ľ†w;ĶŢÂR śéč‹Ŕcßőô©‹NqÉ™¦ÍúA“˛X»§t›c%'JôóĺwšŽ ‹ô«ž&Ź%˘1d?eÔ"Ż é WÝÔîwęđrÖ›uE"E<Î)hť ! #Úţš“@JŢôěZÖÁ`”°¦ŔÓFcVÜ÷^‡ł@u±J#íNa`3ľöF¶ŕŹŐű˘Ńđ:‘]eÁ~(GNâiľžNrFž'(mYMó\§îĎp˝U•‡$ďńw–›R4"AjĂóNÜ ŘlĆ›u%.GLÜ×Ĺěž?ŚB F.9ߤ·*P7L¬Q=é˛Ë´·a›¸xXĆŇ3ŽşüşîÉŻqŐc rŐ«ě[HÚń ňz˛¨W\Lsfš‚°cN”#x"ŢĎŃTEŘxçYąj˘&ŃĎŇÄUY'n§6żG j’΂›±Ö3—ÎňŢ ®ˇSŻÖ\“»\šC^ö‘™^4FtäR%H~¦ĺeKNŮ9ąŠDŢ_ÎR‹ý¤ó ˝?ĚQ§egę•> ÇČún6P]CÚ€ď0D\ŃÜ4…źŚR39Śn>Í-ßLF뜣‹ IĽ^{¬Đ´śC–6'8hşňÍla>Ń«3Ą„čç\ĺ«™Hi/‚Ń.ú1ŸâŘđͬ$g[ŃO‹**·ćŁŠÎP Č© pŚ7Ô›. ž{tÔ,ÍÔHźZčYžO!đ,o™¦bąw¬Źî)Wz/l«g7Ů aş$’4F“v–† Äł‘ßo8{Ö'Ěh9¸Îőřä!Żp1&2K¦Ëâuňg·Ă'˛ĆýT˛Vż^Ś6_3řZů„ŘňѬßDgżH1‰uŤ‹é@đšâ§2´x˝O{›ĘQ<á¨\qĺN†•pc`ZU‘—!Ę Ţ¤¦iřŚĹŻ—R@˛cÍŢM]sžöMq9ŘBEĂ*ą+ŚöŘÔ&ĄďěžĆřś¬™®ĹřÁf¦ČEŹ©\€­@É˝{Ó o¶–eŃ;”gđO­}—Łj±<Şö)FxZOľ2=5”ť]t«4˝‚gg7ĺVpNMĺů„ĺ«¶÷Ľ7u¦—hâ%ôşQ‰ $ţ¨„@//9l6•˙âĚ(ń<0tPđl;«Š>XÇĐűŕC8”4x8^oV¬“ŐčSUŚę ¶ĽŕÇŚ«…›SÚIÚż—>far¸D_oZ)Ůä5lµ;Ľbă[ĹćN/ťqH}0/-•+µ™±xó t"j%ČŻbN+Őź_b¸ë'‡zPo|‡?94Ü s©őJÉTYž-֒ϹݰvĹ‚ćçĆęxBöŽúĐP+RĐ Š:MҬx©×ĺTíJ`°Ă Ę+ÚĚŔĽÍ<ßiCx>źé|Éb !ü>&îÖ7ˤjţÂ%s l¦žĎްfm:Đoý-#–:dő#č˛!CętřĽž:ŠŘ»ÁfŠ‡čş§»lökE2(»Ň}^#XNĐâIçĄ>śuú–Zu•Ŕ’ŠíGU˙…pÓó×s’é~˝“Ç—DóÁőÇ3 őÖ >M°Š)DZŐ‚!i=jqíFE×ÓéŔč]VďH—ŕF9/ŔÝ+ů.Vl†_N-2(źhÔ’Éjţ’ĺ1`d”Â÷¨é9dŤ?jÚz–±Ç‘ô BRQ­&[Řı?wIó/ˇ;C‰|SýĆV»b±:óÉMv‰çâ„…‰Ô»ĚiRľdłĐ"šDgú˛e)x-ůw}ÔŢFîm¶’d<ČÂĎRđRzďN¶‹kĚ[·F–ÜF:„9€ăÓÚ‡»pÔt+Ar¨$&Ú<ĐŠÎú»ŚÔ·ň™y>CPg0c€ľôoębÜzRęc{ôü9ë‰ĆüylĐkLŚň.ő#›&'«éŇŕó ˇÜ\MŰ·q6y˙´PQIą#ăH\“vëSŽ˙B±Ü;*©=,óyj–»ŚwNËǡ=˘dŕ3:ň^gx ڍ˙¬Ň*첤N’FíL’Ćơś…)v«ůĽěůČBíż &âv—˛bź×٤lA˙V41XG=ĺJČĆ䲇âgJ~í(¸˘,µ'[˝šßDóa˝ĎIĄlݱäµt{Îrxx¸wj\p—fU$˘Ţ™ĂçĘáJŽWLxB˛\CĹi—Ă9:˝˛H¦' ő-˙'l"Ft/X„áńÂYą°«°ńöPŇWJb*—!ݡNH˙B™1¶śşĚ2OEČąîj©‘Ěä1Íş®ŮzJ\ŤÍů‘˛AĎš‘H´Ó|nÚ™ŽŁ/9—¶˛Ô\±:˛f×DE1NžNEŽ‚¬ }ř…cŠ3ł×JŞçŹöZi™<$ä(hJbářˇWlŽŻ4C¦· ă% ¤˝+¬®Äľ;YÝ ĆŢ8@š;$ů^¦VTö” IŽÜ„€Ńűą 0)mĺ`~Ą­ˇů·]ý’KWaˇżnpjĹč˝ĘÚ Í´ÖqL -ŇÜ3Ń;ݤrËŇAĚÝýŁNŕüŔą=Š˙ÝWááŃB&T˛ÁŇ"ev‹î3ü;ŁNu«őÎŕ´—»ěĺ^5®i«vđYé,Běxz¦ůU®—€öc“y˙ľF0ž<ô9U'¬MZ+$W/î-,>mĄ/·Gę­Çe~ÁÂcđçǰÚDˇ}Î`‚‡Ć•E?ÍŘ Ľ‡ž’–Č=)EĚ$’üř㮣a^đČ%RÄßüů®Şúüޢ'kXŤŹŘ¬D˘CŞ+÷ż—coľr‹–bҰC ŰdŤ ŮĘë{ęţ7sĺăi™Ę„OŢAßUś: ÓGb8"íąŮ$÷ŤÜv‡ąMIÂ?w·UěŮqżŃÝ|“Í7ö“ yjFµSl]3*ě±Jz©ŤĘَ©pQ7L9ďíóÎ[ćşÉ×#ĄŔ%ąĎBz»’řń= Č-śĆzČÂűŠšácrĂ]”ŞR˙ĹgqB);áĚÝöÓÖ™Đ_IĐX;×#¸î ‘Uż…~Ń­™&¶Qd5ţM‡’«%5ąłÜ駸# J§ĐĺHňâ?ěc|Á ٤ŹÉŁţ=Ő’ť4dÚ ¸,ŔpÔ§, ]ˇ69ź»žďËMŔÔ5¸ôçZżň[ü>¤9Ęç]nJ< ~v¬M®Ď}*†‰üţ#¦w…_8Nc>Y†~3ÍĎ˙Ň–˘ćÁ©ä¶ĺz3bjúV}íż!jţ|CĎťłG´[‘Főz‚±ZIůűÄkô$SđČ´]ő*ź’¶+;ěąq ÄÍ,Á8´pTNĆ0Óka˘üŞ·LŹKáä{˛Ĺk}ÖÜW~«©»}ą&Ô¨ĚĐ ‹_}L·í Z‡˛>ĺ#î˛FŰŐ`kÜć{ŮŰa÷C™d ´U°ť+5!˝ž›ÉóŔĺšźâż–ŰŽ]łiűłąĹ7|…¶ĄŢR·rëŇgâ K#Ä4÷a«¨˛Ă{3tüŠłç?B ˝ç)v6Ó]}zŁ©ÔZˇ˙¶ŞU2Ő‡«Vm “;š1J@~”CÍ F±5Ý.ÉŃvw =ę˛Ăw!{?|ŇĂ$}IĐíkˇ8‰Ť-!Ĺ~jx9{ŻŇüĹ=˘‚ÄűľĹáöµ‡J|©=äśŃZqřĺĄćöŇś^\ůź Ţ´šŘZq"7”«ŠOżFq˘–'{”ię?Î/ ÷Ëśý°‚jLęx®ŐµD×.#+6Ł[“ĺI§—‹7ĂZëcd|'ýŢNţ}˙Ä€‘‡ç'?˙ĘL`xendstream endobj 831 0 obj 4184 endobj 840 0 obj <> stream xś˝\YoÇňČ_±oŢ ´ăé»Űo¶˘$JbÇ– AQMJi™ůő©ęłş§›ä2F ĎöYçWÇđĂf™ŮfÁ˙ĹŹ:řücjóćăża›wXüŹ%ŽÚ|učjx5łeћóevV ÉÂzZć6ůb¶m5ü˛9üéŕŰ瓜—No˙4í–Y;§…Ú~IžżťŘě[äöpÚ‰™;iěöExÔ Űľšv\ÚYr»eÓNÍÖ:'¶Ş<Îđ(ĺě´K+ĄÂvfY¬fi5|ý7ňúŐ¤ĺl´rŰżălĆíč€?Ŕk—s®z]NL~ĺ/ޙ˱ĹĚÚzś—ÓNÎđłŐRß”çţ9RŰÁ]¸–HmŮ#µŐ+ĘjO|ÜşüáŠ.˛ŔĂ7;nŕĺÂ7‡'ž3…w…šÇÓˇ<^Lpw- ŰÓňö‹|“î‰9›A$Üć𯇿ŁüĚ\,ł‚óĽ.cŻĂv‹HgPLoŹĘďĘĐ÷ĺńŞ<ľő;(ĹŮö˛Ľ˝)o?Âľ ›™utÝp0±FŻ&fa¤ŇŰO0‹»Yią}–†ż/<ů8 řqŃ&ŔO˙ ŻĽ€ŰŢĐEá-H˘â±„×(´jfI*¬qŰ_&”Á*–Ezka··ů¬dQB˘«r ‡eáäT7xm#|Ç%ź•täŞäţýíÉNżťP~¸°ł]PĚ˝P'¨Čv™]¶"Çż.şU®wLĎü›rzČaš§¤J:á'¸( ś–·`‚¸ăó"DŇy+őöĽ¬đ¶7afÜ®ŢâĹăH”]˘ĘŽ1¸ .AkŹ]›xŮčy A-K?4$ źă>{V+JĽvv8}¨EĽLW1îCţ÷änNĘ€‘óP¶‚d…`U•.é\®\îŠö0üˇ(#lŮXëT(Š)†Ę@ckŁŔj!+…†ŐáY vT¨łŁŁ}lq’rçfOŐiţ˝Âç„ĎxažGđ°`ŽHaî,TgĘXBŢ&í2 F ¬(˘XpU´Ć‡µżT5Z§%tQŁÁt†Vy5ęBÁDěĺă]8Ý'R$#>›¤€ÓUk›ĎŚ9Ş5ÝŠ,„ą>“ŕńűśóľ*Č࡬ćU¶×ĺ仸â¨V)ŘŽ$źvôšĽ‡$š°§ĄRQNśńQŰsŹE–±˘'ú<&­źNxÝŚ! Dř!ŻŰŐĄ±đ˛äÚP!r¸,’Ôď×Ôú•‰®>G7b‚&D7‚ą-á~\Ľ$âś«ŞEčW™Ě>6"h ‘?óežŹ | ®dCVapxbśľ‡7ĘÍ2Ô©„Áę‚î‘ţźTa!`Ó8Gç„Ę÷Ge`$—ŹŠĘ`Köëe^ňµ ’OVŇÝ4^ż„×·ÚMĘJPrÝÉ*¶â<Vz°Ć{¸Uü=CĚ28˝_F7ä4LAxCÖäĘ|Đcź¨1d>*‘&zźě¸¸Ĺ2ŰĂ((ćföLâÇí÷5ÍRĆΛN3ÖĂúúźsĂÁî/p×ÜjńtÚ ;ŚA§xL\ÄŔĘ‘—}ĺ]»Đµú¤ FU ¬,g| 'mm,ŢşFH]Ĺ8ë˝ěŽ\Ç%1më IVŚ[-bĂΡĄžš‡%×wáü*VqhťÝ=f Âp©9樆ęTb8ôW+lÓKŹ3š@'´ĺfk§ť&b6é×eZ‚đŢŽ )5–[!(tJa‹]úýŐÄ! Âć)6yŕ»ŔąČďż”Ínđ şFyŔ&¶®‹iČeAşNG+&]„NCçó^UµuŠŚ|źźnóSŮ§ß §fAšáĆŮL.·vcŤZ0Y´vÝ6’Ň«®‹}AU…UÉÍŔŹ_&7A»]F,v ş¶ňs>Üw:Éő0ŃÔÇEE-*ň ˘ÉWÖ‡jp-!5†Tŕzť0Mµ#şˇ.&¨™âHwşîED3«H°ÎÓ…Ń8@Ň-ŕ”‘ł7FŇ÷±T1ëxôăŰPbň‚ŕ˝ďŽëYo’†íáú0gžs¤÷·ąuČ›TOŻŘY—ßĐYŤŞoM%Ó8Ňö,¶¦­ÝäHu¨~`“Ěo’ ŕUuö„㡟Ű‹»ap´ÎvÝ`L9;ô"w T˝M]ď睏D‹™‚÷#jDĽ‚ĐŹv_—ůĹ+V–ŤŽzćhŘUĚ‘.P‡Wľ?Ş­-ĄN…=ú¸ŠE%‚Quä†fťĹöł‘wŤŕ’>Ő±řXŚKëŞä]ÇzqyDĽUĺŢ}sߊĽďe”¶&˙NşËmĽ!a m°˙O9^‡[źJď'4VőâĆ4ú¦´e ć,-× }l–˛ÎĄßĺĆlE91öµąLéŇéŔĘXÚŢ_2^ĎsÓŘ‹2ëÜL׍·%ˇ>ęEĹN©é<±ęO“NÓď%žçĎľGvŔYm¨’4†"^ÔĂĄ¤n3vS«°`Чťt„TáPVËö›nÝl4­ă/U<âm×Ô¦„”’µ¬Ą–ÇU5Ë;1˛VmW%ÖĂŐöŹä„ď;ÂXă5L$âg#n˘&1‚QŇ=Ą'"ĄAôŞľŹi®‚%©@Ä+K«c˙á’şhű}děE[G™!«Ę‰óď×>»JŁɇ‹Ô•Ô'Ce¬włĄj|#CG8CH‘¬Ą™oš#ôÎY°ľsNµmÝt®‡n”a3 śÔúÖˇăJĄH úJGÎ&ě$Şř~6·ÍŻËôˢmpá ÁtČA™żď·Î#Q…Gę¦éM@˛Ś2›GLK•$űµKY+ÖIě‚p)ĺč©BTă~0ł3ë´ŞäF7Ď7ÓéwÂkťMżĆ0U­¶Ż« w¸U¶˙%ËĐÍR|(˛z»ö¦:Z±3}0AT$đťˇŘ‡D±ý\Ý›Fz«‡ăüẆ”ôa˙©ŰŐ$#‰§8{D?îôÄ.9ŞAäć ‹śv?ÜU2•¬V ?BDDŮü1¸/ IĐO“ľól¬ Gd"ôÄQ˙«<ödeAüŘ^Î~—ŹąËá ž¶`¦ę+Łô’@‘Nxĺůםďóú9Éż_SłĎX°µý†G‰îF#ţĂ&ÝéÚËąžEĎ2Őرmݤß|#‰ó9‡´éä•«ŠŤńý@€…\VM%@ž; ‹ŮĂW`z/Ě×2>Ĺđä#ěxhĽËľ âH©›¤¨Ŕ‚Ż Y¤ĐC8…"K®:˝î-tÓĄú¨JľťłżJüá/Mó6+ ŤŃÇi«Ň긋í˘b%C[éýź]-€ť,Z}Ú& űFS^ňľP…ťev#ˇ}b‚g±y¤ţ^¸)PĹcÝ_ÖyH@i¸ý2&ä´'b«y÷óI S)ęu{$mŐ“ŇO—Ą*ÔŻHęÜĆČDă'éu)¶—ĂÇ]ęuDT {HŰyióčgDIµěnĘ]Öel 8üů˛,ÓôŐÇ*ÉÇp>Ô’Đ˙`±–űôX»Ř‡ß|Ř0lŕţOŔJ˙,čţ –C[ü_˝<řüĺ×››ëŰÓĎذĎ˙„˙÷Ő·Ďáź—żßüćŕĹËÍw÷ţQl{5ĘŇ?SŔŔˇk؆ĎńŹÄRÔ–6CSóUŁY‚)“!•żD.á%V¶Ě,@‘Ř>Ť®űbBĂgĽ˝đů$杀¬¤ô±jšrś§Ľ ĺBĂC˙}h“¦\槲ßMŢĺm~şňă” ‰nÁÎIňóÇTŠĺl9#&±¬L/s.ó»˛á©?„ óđ¸%?^Ĺ«şG¸ÍmŢě2?2> stream xśµZ[s5®ÚG˙ ?Îlq&ş_–§›­,°Á) `+…'qá8Á…üúÝŻ5ş´fćŰŕ-?XG#µZ}Ó×-ý|,&y,č/˙ţćčŢ)íń«_ŽR˙±<ţéčç#™<ęřÁ TöX‰É9ĺŽO^ÉůGáĆL>xIÜ`‚ŹŚ=>:ůë÷ĂcZB„ěđKx!-ŘóÖE§†‡ésÚ _¤^˝ľwbňF¸ ůÜ-ť mii&mś˘Ąľ*ˇËŇ’fŻťϵ9‘¨!O#bô“#źcuť´BC,#đcřeÜ™IjcÜpžĂđfÜéÉX§ )ď|.čłXŕC[ë÷ÚĚüJwAE9Cü*;icá÷“ŃLV™č†·ăÎN!ÄHĽ80C şĄóŠŘR¬ží©)9Ľjß_·ćŻu±`ěd‚€ÁLÚAĐŇ ÉsbÓ9+Ý̦±–łąF1Úďúi?\6ĆŔj6·GMš&ćáŞ1%VÍŕs+ †]ÚźŤ"”YýwąŃI,ě`|Žö·Uj¤•OF X44¦ ĽD“ŤAaZ öĎ߇ćNiěó)©ÜÁľµ…#ŐyÝŕÚd.Z/[ăŁĆΓ¤|'c™Ąń}žĄ…—ĂKňE*|ńłQÂ>˝­ě_,BZ ›Ő“uÂůá´I쬽=ôT(éÄŚđ­ČiÔ÷ŞkV _U±ć‘Nľ%6éyëeT‰Ť@Üđ`6˙}í,Ëď“ă7ů3’Í(˘Š‘˛I—mŇ Ň“O˛<Ói(÷Cţě]ţ¬˝)”hűŚŇOsÓ ;»®F©2˝ÉŠ3K;śŮ~qT43ĚłĎhUUŰYĺ6ĂŤëýRfBsS§é‘ś°Idf˝IłEYĽů…†Ć áŹä“—z۶ĘÔűľőľ!^"4¸\vŞ”h»˛V˛~¶V3ÚwŤjły6)/•#5Î1Ä5Ď=ńC#đ{ĄÚ†’.j™Cô¶&Bw«‹PhđJ*©—±zÖTÔIEF8… ËĹč IoĹ-®Zđd&uË0ÁÁ›¬˛^¶Iż6 ţ6J9i ®¶=9ÓÇMo¶¬á=}Gčô\˝Ź(…Fř= 4ëě˘ě…qÍŔ†žŽŘľ@žC„¶–Ňú¬ëĂ^3ä˛q]}ľ+óY”*ŇlűĎn”üLzF‰0 _í!íće|VĹłí¦ěXië&yŹuH6Žâ~)Ć á -qfádűĚ˝XĚa–wľÄgKG˘ř&4Ą6\相Żw¤µËĚŢ1o¶:Ç*śX[«Đě_±šü岨ăě‚/;`{UŹř†JľĂ˛3˛<ăXI¸5rb­X$c§ňJľI×m(ď#Ů%=ßGZJ~‚cËpłgCűPÎ 'íbYÉwaX›b“×!Üh„‚Ťw ´Ř–\.Q:së33 ‚QşţĚda©ě$\§ęËÜk÷Ç­\:ľZ'3µwÝHA•…=”:KQlF»ĹIžzaKżĄ2‚ˇg–Ă‹<ŢvÚ±@pt›4Z´eÂxÉs”9Ç8 K`cü-&il‘µXä5e+ß ±0!W>jô¤ť5g›ú’µź˛6 —Ŕ8Ţ÷Y÷¬ý]kçT$q^ŁÔ7ŁTÉ$g ůĐ}R+­uĎ©Í|ĺ»1Z©Q]5VÂfgí䱝ţ¶ÂkóĎ^hRM2EjuFÁü6˝˙˛íućąťV4űÜ>‹˘©u-¨ŢF(—[ř!oŔsIĽ$®ăd°«R¤ŇZ mxŘLĄĄ°źÔ7ź}¶q2F:*ńjĆűh¶ő&_ói††ÖvŚ#ÓČabUfŇëmĚCurŕŃĐefĹ{ĹJEł˝Î«ď âV˙áć÷°™_Â'ŕBQaQk$ReąZľě öiR{×VLT3ýj"WT4áy2:Ś$€r˛Ü|Rj:÷M&¨žX^Ř3`ú´P¨}Ősžż7–wL[±ö˝OiŹTŠÝë:¤0đůcyJC|"Á‡śm¦QŰ'rŹĎá1“ ńyj^l‚şçĹ•‹ qĽó<Ů.ČbSĹvW@ť•t*”ĎRšŁÚŢŠąmfę5–®Áľ¶Ë . g©-KŤşÂMsY4üá‹Ń©ŘD5¦ą¶ńÝ(…Gb E¤”vŠČ(Ľ^A€c-[¦eÁ¸ n˛ˇKî~LqŮ,ĂrÄ'd/˘íę|DěÇçf€/«Ď帒ß3RÖKŚ~ČłLěŁjJ™AjoŠ”ép %ěděy„ôęŠ[ý©űě}wÔęđíiŰMX/ÄľŰR"Ă&XpżřČvô3h7>ëŁ0űiĐ«+Ł`aQNŔ…ôyÖfjOĺS/¦Zo_8w+¸ô…?r,‰ôç‹P)¶ęTĺSA%Ţß2@¦N[Ŕe”š$×%ĘR.Ł \Ź|”‹©±' Ď1‚óA ŹŕgŐZ íł˛®ZęÇUí‘k Dşón™ôá/íˇFżÇÍŢדl_©˝\;$ZJąŔ+Y>CpÍS/[¸CóŘąśŚ´·PÔÂ9Ľ¦ŰŔ;đŤäý‡îőČdS»RZš„Íje[ĹśĹ%|¦Ô—“C:˝nĐRŽ'ŢXŞą*yĄ[Ť÷›ö]äd4ź6§\ÚëXý¶™˙Ľ—j˙Űc2Éć Ů“MŻ«vĐ=e’2ěAĐ}["Lŕ(:x8@˝, `W’ýáŔ8OŹTzś,Io{öŕä”gąh÷Ú—D¦Ęĺ]3DJ«ýľ”R%ŕŐÓđĺ[ů’ôđ†ţ™LŢ«·|l׬ů.×µ«k˙­}ľ×öŹ#óć}›ŻtżÓ`šeŚ3“gc»š‹Іp÷6čA%Şú”ó§u˛¶óR¶ě®ťeŞůň4Ć Â€ Äć_“×*Ţ1ďaĆ}1"ž+í—×S+DąËJŰÍĐ’w=°Ô X>&ň’^ý5yZ&= tŢk‘‹3)Ö{^ßIžµNň÷¨ü2żŁt!Z6˛‘ŐhΠ–.„2¨Ő©jPć´WšÍ5Ěq÷Äźµ9­ómë|Q©żŻ$/ö ¬“2D˛1źö*3śZ‰a#ueŘj·fŘjÉćdŢűźµ9iő@Žů-=ů5>ŇK®TuęŐŻŰ‚•ĚfްËÓvsÎpđĺšvz{qŮéVĐg hóý+Rt $Śą~•żöAů|ÓŰ "#ÄdöF}=—ÖnB˙Y›~ŕąĐ˘\q±’…« ‚R şlônj/W׏™4ÎGdŃ˙÷MĺśÁIÖrű·ěDhű;í$ˇ»ŕëĘNyî†8 î4Ě“\p,Şţ!ăMYu7Sófďň˝á^ŻřŹVۧ žDÓM{Y2ÄŤŐšÍl=€dł¬rĽip}meĂQ'”s7ep›€D¸ ŽíşxŁ:řu·Ęg¨ÁHŔm¤ źnď‘A©ŐŐM~Ť0§rň5«¦¬ §°uf‘őĺśP—iF­‰\źßÄA’ˇHĹg-2żhŇŤÉúýxÉ9z#ăVŚ=ĚŰl•´ţu˙Ă“Łáď°ś˝áendstream endobj 854 0 obj 3332 endobj 863 0 obj <> stream xśuUKŹÔ0 –8öWôH4çá$Ü­xÁ˛ô‚‡egggĹ<ö §MĎî Ćă8¶żĎźŰŰV+hu~ĘďŶYśřöęľü-´ż›ŰĘ]˘Ú7ýäR 5¶ýŞŃ*E´Ć|č¤vöµ*¶‘NÚ~ŰüoĄS޸„â˝ě´Â”ĐzńšŮ§T˛ ťčeg•I.Dq2š¨AśÉθ¨ś‰dçUŚ)YŐTd:§&ńiĽf˝dç”Ađ¶ô€¦´ůüsn!hÄ·ą0;ö ‰Št™(Ľ9 ”űrZKDpi8›9Ig‰ž`ÚÎJ¤MŰ/)|56Ş­ŘWLŹŐÜŤf bIÍé 4%ľ–Ä9zo ź[HJ{#Şw]\R€Áś‚MăËŃ |g¤09WďMĚ•ś÷3ŚĂç—ŃZCm+^Ěç›…ąóäĹ_Vv=3r]c/d Ńŕua„BďĄU5†riĘ~ľ˙Xť›ĘÝrşY©siŚr6EńGćY[Ŕˇ?p*úňűšt›9LĆŁťcI… Cp8=kvΓ7KÇD“•ŁGÉ0,3Eâ¦:ď†Ńů¤#oćęhŔůŘ8ÚČ»Í;ĄŁŠ¦Č`]Íć ćŇSEČ»*9¦d†ę%É…P…čţŻT㝢ăă`Z/,ű‘űÉd…ëĽs.g”÷‘ßbhw9©żć)O·‚›ö2ë˙©`˛µ«l’^ ‰#č0ĺ·pC˘¦TUEOÇ=7óů«ę\TŘ‹ęĺÚ9´}R„0ňĄdßP"ŁćďdPQkpĺvö±úl;źĎ%ÓzY¨5ďG[ťß•EÄ,°NíxĄÚIeŠwuR†K´?hŇôŐ8ĽÎKěňKI‘-ŔFzKŮŕźĂIß|Ąçç%„Hendstream endobj 864 0 obj 687 endobj 870 0 obj <> stream xś­YÉrÜ6˝ĎWđH¦2öĺ8J┲)ă\\©T˘‘-•µÚ’—ż0\úg¤ÄĄ(Dwż~ýşAÝ5ś‰†§źá÷éŐę«!LóúÝjwżÍ›ŐÝJ đaUóÍ&-”¦‘š9ďDłyµĂ B)ćË“Íćjő˛}Ţ ć¸0íu·ćĚia­o·Ăµp¶=ëÖ‚© ¤h?ƵĘ(%˙Üü¸óĹ6+­N& g\ßlŽW›/^¶®[ć}Şý=ľ”ŕş=ęÖŠÉ ťożO6lV™ö§n-™R\{\ń3¬ŘĐíÝn2xŮ~_SŃý [CÖÄî2D¤’›R0Żą˝ú;Ec­6<ľ˛í/˝k%Ýv÷q©¦»~şL»‹řÜWŮýľăc"lp Néň|2źlę!m‡0v6yfsŃ?´îm·ÖLZ®ú¤ő›&cŰ7Ep şĚe"ćĐOŽ(‡ĎE<ř <“<~ Ĺď:ĹŚ ZSTzoTN„0îř¬ÓĚH,Bv;áTÇń˘ŠůM  Üą%•‘‚µK2Q‡űm—čcM¨T`íďźĂ‚@ł­ÚĎ·P?Ôˤš6ňÄ,Y˘X·´%ä TşIWĘUÂ=HcŐH×Ă?-—* ¦7u®T÷ŇYÍĎ"ý©â‹»»¬E`Î ÄJçXE$=µ¬Tm’x Đđr”jŰ~× Ĺ‚3ëvŰ˝şŠbtŐEâ|¶©ŻVËČ «öÔČ”–ó왌’ľŹIçO’Ě‚ůó‰ PzĎ’Ë”38xÄ„űI§#Z&býK1ąČÉ˝ŰĚŃ*ëJY"Ý&\ä”"ČBß]LÔÉ1 2Ë‚,&ÁÎ6OgŠ $öú!bĎLBQQŹ€6MĄúPĹ–^T›űőXŃÜŹě#Ĺăx@C–Ę_E·ČgÜłI2^—*–ç¨Ä†Éă*!ŃĘ×#&—Ë*~ŐTŚŐĹ˙f&oަąűżĽÝÇ˝şő2'ÎďKEŤőíęĺ5µäĹ3ÄL§ Ý—S®˘!VD‚Ý,S~6ŮĎr6ŠvŁUô8¸]efi×í$^cQNs›âNÔć¶ a,ëóçŕ`ăpjó ÚÇÁGů‚3¸UľĂrë(ĹÚšÍĚFřcaM¶IEnČ ń¬Ś{g!őc€·–¦"ŹCqNŘŞéYY& Ą†`Bڎ38ˇ¤ˇĆň¸ Qok’•SBçlv8ŘĄŁg©—2ó,•‡’4@,şS!đ}áßMËĐâ¸c2lľDßťüEŰÉ €Ňw§ä(ń… ˛GÜWË vĘŮ<äË.°yF©“]ł"ůŘeˇhéfqtŢÁÖ;d÷°tä¸WpâČżżPUCHTŔ×52~žě_ť”f^Çą·ďUesd&­4ű€§¤b”-–Ü(Ă!ä(HČeńU)™¦Â0C\‹>çŽÖ‰x›Ł0dű€Ä/ehŶ“Đ“ŞĂݲJ”U["e5|¨ÓÂ…Y×ŮëÁ*ťA.9¸Ä&đ’$rôˇ‹Ż*é~ť—`Ž8Ď3›¦ďpíÉdýµŢsR".ťý«J-)MÔ'Š®úőéf–Í© bŠ.P~n†Źŕ€<(Ô+äc6L=•@j!÷Uä!h˛@­@†ä/ Ź2CÂęČŚ{Š™YQ´h*űÔ3ňžŽňM4˙îžtV3—ĺ›”#ˤTźs´&h|‘÷‰V {pޏ¨‰ČuĄÝůĺć”çâŹN cvµ® U K4ťĄTHfś®÷:Bâ©—N.¨-IĆ,żź2Ś*Ŕ Úş>SÉ}gĂb%¬ÓżÝ¸°ÍZ©áđÎpTMą8mVżĹź#"ŐŐendstream endobj 871 0 obj 1535 endobj 4 0 obj <> /Contents 113 0 R >> endobj 120 0 obj <> /Annots[127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R 134 0 R 135 0 R 136 0 R 137 0 R 138 0 R 139 0 R 140 0 R 141 0 R 142 0 R 143 0 R 144 0 R 145 0 R 146 0 R 147 0 R 148 0 R 149 0 R 150 0 R 151 0 R 152 0 R]/Contents 123 0 R >> endobj 155 0 obj <> /Annots[159 0 R 160 0 R 161 0 R 162 0 R 163 0 R 164 0 R 165 0 R 166 0 R 167 0 R 168 0 R 169 0 R 170 0 R 171 0 R 172 0 R 173 0 R 174 0 R 175 0 R 176 0 R 177 0 R 178 0 R 179 0 R 180 0 R 181 0 R 182 0 R 183 0 R 184 0 R 185 0 R 186 0 R 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R]/Contents 157 0 R >> endobj 194 0 obj <> /Annots[198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R 215 0 R 216 0 R 217 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R 225 0 R 226 0 R 227 0 R 228 0 R 229 0 R 230 0 R]/Contents 196 0 R >> endobj 233 0 obj <> /Annots[237 0 R 238 0 R 239 0 R 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R]/Contents 235 0 R >> endobj 252 0 obj <> /Contents 255 0 R >> endobj 259 0 obj <> /Contents 262 0 R >> endobj 272 0 obj <> /Contents 274 0 R >> endobj 281 0 obj <> /Annots[288 0 R 289 0 R]/Contents 283 0 R >> endobj 294 0 obj <> /Contents 297 0 R >> endobj 301 0 obj <> /Contents 303 0 R >> endobj 308 0 obj <> /Annots[313 0 R]/Contents 310 0 R >> endobj 318 0 obj <> /Contents 320 0 R >> endobj 325 0 obj <> /Annots[335 0 R]/Contents 327 0 R >> endobj 339 0 obj <> /Contents 341 0 R >> endobj 347 0 obj <> /Contents 349 0 R >> endobj 358 0 obj <> /Contents 360 0 R >> endobj 366 0 obj <> /Contents 368 0 R >> endobj 373 0 obj <> /Annots[379 0 R]/Contents 375 0 R >> endobj 384 0 obj <> /Contents 386 0 R >> endobj 394 0 obj <> /Contents 396 0 R >> endobj 404 0 obj <> /Contents 406 0 R >> endobj 413 0 obj <> /Annots[417 0 R 419 0 R]/Contents 415 0 R >> endobj 423 0 obj <> /Contents 425 0 R >> endobj 432 0 obj <> /Contents 435 0 R >> endobj 442 0 obj <> /Contents 444 0 R >> endobj 451 0 obj <> /Contents 453 0 R >> endobj 460 0 obj <> /Contents 462 0 R >> endobj 469 0 obj <> /Contents 471 0 R >> endobj 477 0 obj <> /Contents 479 0 R >> endobj 485 0 obj <> /Annots[490 0 R]/Contents 487 0 R >> endobj 494 0 obj <> /Contents 496 0 R >> endobj 505 0 obj <> /Contents 507 0 R >> endobj 512 0 obj <> /Contents 515 0 R >> endobj 521 0 obj <> /Annots[527 0 R 528 0 R]/Contents 523 0 R >> endobj 531 0 obj <> /Contents 533 0 R >> endobj 538 0 obj <> /Contents 541 0 R >> endobj 546 0 obj <> /Contents 548 0 R >> endobj 554 0 obj <> /Contents 557 0 R >> endobj 561 0 obj <> /Contents 563 0 R >> endobj 569 0 obj <> /Annots[573 0 R]/Contents 571 0 R >> endobj 577 0 obj <> /Annots[583 0 R]/Contents 580 0 R >> endobj 587 0 obj <> /Contents 589 0 R >> endobj 603 0 obj <> /Contents 605 0 R >> endobj 610 0 obj <> /Contents 612 0 R >> endobj 619 0 obj <> /Annots[624 0 R 625 0 R]/Contents 621 0 R >> endobj 629 0 obj <> /Contents 632 0 R >> endobj 636 0 obj <> /Contents 638 0 R >> endobj 643 0 obj <> /Contents 645 0 R >> endobj 655 0 obj <> /Contents 657 0 R >> endobj 666 0 obj <> /Contents 668 0 R >> endobj 675 0 obj <> /Contents 677 0 R >> endobj 689 0 obj <> /Contents 691 0 R >> endobj 700 0 obj <> /Contents 702 0 R >> endobj 712 0 obj <> /Contents 714 0 R >> endobj 724 0 obj <> /Contents 726 0 R >> endobj 736 0 obj <> /Contents 738 0 R >> endobj 744 0 obj <> /Contents 746 0 R >> endobj 750 0 obj <> /Contents 753 0 R >> endobj 757 0 obj <> /Contents 760 0 R >> endobj 764 0 obj <> /Contents 767 0 R >> endobj 771 0 obj <> /Contents 774 0 R >> endobj 780 0 obj <> /Contents 782 0 R >> endobj 788 0 obj <> /Contents 791 0 R >> endobj 796 0 obj <> /Contents 799 0 R >> endobj 803 0 obj <> /Contents 806 0 R >> endobj 812 0 obj <> /Contents 814 0 R >> endobj 821 0 obj <> /Contents 823 0 R >> endobj 828 0 obj <> /Contents 830 0 R >> endobj 838 0 obj <> /Annots[843 0 R]/Contents 840 0 R >> endobj 850 0 obj <> /Annots[857 0 R]/Contents 853 0 R >> endobj 861 0 obj <> /Annots[865 0 R]/Contents 863 0 R >> endobj 868 0 obj <> /Annots[872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 897 0 R 898 0 R 899 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R 919 0 R 920 0 R 921 0 R 922 0 R 923 0 R 924 0 R 925 0 R 926 0 R 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 933 0 R 934 0 R 935 0 R 936 0 R 937 0 R 938 0 R 939 0 R 940 0 R 941 0 R 942 0 R 943 0 R 944 0 R 945 0 R 946 0 R 947 0 R]/Contents 870 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 120 0 R 155 0 R 194 0 R 233 0 R 252 0 R 259 0 R 272 0 R 281 0 R 294 0 R 301 0 R 308 0 R 318 0 R 325 0 R 339 0 R 347 0 R 358 0 R 366 0 R 373 0 R 384 0 R 394 0 R 404 0 R 413 0 R 423 0 R 432 0 R 442 0 R 451 0 R 460 0 R 469 0 R 477 0 R 485 0 R 494 0 R 505 0 R 512 0 R 521 0 R 531 0 R 538 0 R 546 0 R 554 0 R 561 0 R 569 0 R 577 0 R 587 0 R 603 0 R 610 0 R 619 0 R 629 0 R 636 0 R 643 0 R 655 0 R 666 0 R 675 0 R 689 0 R 700 0 R 712 0 R 724 0 R 736 0 R 744 0 R 750 0 R 757 0 R 764 0 R 771 0 R 780 0 R 788 0 R 796 0 R 803 0 R 812 0 R 821 0 R 828 0 R 838 0 R 850 0 R 861 0 R 868 0 R ] /Count 73 >> endobj 7 0 obj << /Count 16 /First 8 0 R /Last 108 0 R >> endobj 1 0 obj <> >> /OpenAction [4 0 R /Fit] /PageMode/UseOutlines /PageLabels<< /Nums [0 << /S /D >> 1 << /S /D >>] >> /Metadata 963 0 R >> endobj 6 0 obj <>endobj 10 0 obj << /Title(\376\377\000M\000a\000k\000e\000 \000D\000e\000t\000a\000i\000l\000s\000 \000-\000 \000.\000/\000c\000o\000n\000f\000i\000g\000u\000r\000e\000 \000o\000p\000t\000i\000o\000n\000s) /Dest(subsection.1.1.1) /Parent 9 0 R /Next 11 0 R >> endobj 11 0 obj << /Title(\376\377\000R\000P\000M\000s) /Dest(subsection.1.1.2) /Parent 9 0 R /Prev 10 0 R /Next 12 0 R >> endobj 12 0 obj << /Title(\376\377\000W\000i\000n\000d\000o\000w\000s) /Dest(subsection.1.1.3) /Parent 9 0 R /Prev 11 0 R >> endobj 9 0 obj << /Title(\376\377\000M\000a\000k\000i\000n\000g\000 \000t\000h\000e\000 \000e\000x\000e\000c\000u\000t\000a\000b\000l\000e) /Dest(section.1.1) /Count -3 /Parent 8 0 R /Next 13 0 R /First 10 0 R /Last 12 0 R >> endobj 13 0 obj << /Title(\376\377\000R\000u\000n\000n\000i\000n\000g) /Dest(section.1.2) /Parent 8 0 R /Prev 9 0 R /Next 14 0 R >> endobj 14 0 obj << /Title(\376\377\000R\000e\000q\000u\000i\000r\000e\000m\000e\000n\000t\000s) /Dest(section.1.3) /Parent 8 0 R /Prev 13 0 R >> endobj 8 0 obj << /Title(\376\377\000g\000p\000s\000i\000m\000 \000-\000 \000A\000n\000 \000O\000v\000e\000r\000v\000i\000e\000w) /Dest(chapter.1) /Count -3 /Parent 7 0 R /Next 15 0 R /First 9 0 R /Last 14 0 R >> endobj 16 0 obj << /Title(\376\377\000a\000t\000t\000a\000c\000h) /Dest(section.2.1) /Parent 15 0 R /Next 17 0 R >> endobj 17 0 obj << /Title(\376\377\000b\000r\000e\000a\000k) /Dest(section.2.2) /Parent 15 0 R /Prev 16 0 R /Next 18 0 R >> endobj 18 0 obj << /Title(\376\377\000c\000l\000e\000a\000r) /Dest(section.2.3) /Parent 15 0 R /Prev 17 0 R /Next 19 0 R >> endobj 19 0 obj << /Title(\376\377\000d\000i\000s\000a\000s\000s\000e\000m\000b\000l\000e) /Dest(section.2.4) /Parent 15 0 R /Prev 18 0 R /Next 20 0 R >> endobj 20 0 obj << /Title(\376\377\000d\000u\000m\000p) /Dest(section.2.5) /Parent 15 0 R /Prev 19 0 R /Next 21 0 R >> endobj 21 0 obj << /Title(\376\377\000e\000c\000h\000o) /Dest(section.2.6) /Parent 15 0 R /Prev 20 0 R /Next 22 0 R >> endobj 22 0 obj << /Title(\376\377\000f\000r\000e\000q\000u\000e\000n\000c\000y) /Dest(section.2.7) /Parent 15 0 R /Prev 21 0 R /Next 23 0 R >> endobj 23 0 obj << /Title(\376\377\000h\000e\000l\000p) /Dest(section.2.8) /Parent 15 0 R /Prev 22 0 R /Next 24 0 R >> endobj 24 0 obj << /Title(\376\377\000i\000c\000d) /Dest(section.2.9) /Parent 15 0 R /Prev 23 0 R /Next 25 0 R >> endobj 25 0 obj << /Title(\376\377\000l\000i\000s\000t\000 ) /Dest(section.2.10) /Parent 15 0 R /Prev 24 0 R /Next 26 0 R >> endobj 26 0 obj << /Title(\376\377\000l\000o\000a\000d) /Dest(section.2.11) /Parent 15 0 R /Prev 25 0 R /Next 27 0 R >> endobj 27 0 obj << /Title(\376\377\000m\000a\000c\000r\000o\000s) /Dest(section.2.12) /Parent 15 0 R /Prev 26 0 R /Next 28 0 R >> endobj 28 0 obj << /Title(\376\377\000m\000o\000d\000u\000l\000e) /Dest(section.2.13) /Parent 15 0 R /Prev 27 0 R /Next 29 0 R >> endobj 29 0 obj << /Title(\376\377\000n\000o\000d\000e) /Dest(section.2.14) /Parent 15 0 R /Prev 28 0 R /Next 30 0 R >> endobj 30 0 obj << /Title(\376\377\000p\000r\000o\000c\000e\000s\000s\000o\000r) /Dest(section.2.15) /Parent 15 0 R /Prev 29 0 R /Next 31 0 R >> endobj 31 0 obj << /Title(\376\377\000q\000u\000i\000t) /Dest(section.2.16) /Parent 15 0 R /Prev 30 0 R /Next 32 0 R >> endobj 32 0 obj << /Title(\376\377\000r\000u\000n) /Dest(section.2.17) /Parent 15 0 R /Prev 31 0 R /Next 33 0 R >> endobj 33 0 obj << /Title(\376\377\000s\000t\000e\000p) /Dest(section.2.18) /Parent 15 0 R /Prev 32 0 R /Next 34 0 R >> endobj 34 0 obj << /Title(\376\377\000s\000y\000m\000b\000o\000l) /Dest(section.2.19) /Parent 15 0 R /Prev 33 0 R /Next 35 0 R >> endobj 35 0 obj << /Title(\376\377\000s\000t\000i\000m\000u\000l\000u\000s) /Dest(section.2.20) /Parent 15 0 R /Prev 34 0 R /Next 36 0 R >> endobj 36 0 obj << /Title(\376\377\000s\000t\000o\000p\000w\000a\000t\000c\000h\000T\000h\000e\000 \000s\000t\000o\000p\000w\000a\000t\000c\000h\000 \000i\000s\000 \000r\000e\000a\000l\000l\000y\000 \000a\000 \000c\000o\000l\000l\000e\000c\000t\000i\000o\000n\000 \000o\000f\000 \000a\000t\000t\000r\000i\000b\000u\000t\000e\000s\000 \000a\000n\000d\000 \000n\000o\000t\000 \000a\000 \000c\000o\000m\000m\000a\000n\000d\000.\000 \000B\000u\000t\000 \000t\000h\000e\000 \000b\000e\000h\000a\000v\000i\000o\000r\000 \000i\000s\000 \000s\000o\000 \000s\000i\000m\000i\000l\000a\000r\000 \000t\000o\000 \000a\000 \000c\000o\000m\000m\000a\000n\000d\000 \000t\000h\000a\000t\000 \000i\000t\000 \000h\000a\000s\000 \000b\000e\000e\000n\000 \000i\000n\000c\000l\000u\000d\000e\000d\000 \000h\000e\000r\000e\000.) /Dest(section.2.21) /Parent 15 0 R /Prev 35 0 R /Next 37 0 R >> endobj 37 0 obj << /Title(\376\377\000t\000r\000a\000c\000e) /Dest(section.2.22) /Parent 15 0 R /Prev 36 0 R /Next 38 0 R >> endobj 38 0 obj << /Title(\376\377\000v\000e\000r\000s\000i\000o\000n) /Dest(section.2.23) /Parent 15 0 R /Prev 37 0 R /Next 39 0 R >> endobj 39 0 obj << /Title(\376\377\000x) /Dest(section.2.24) /Parent 15 0 R /Prev 38 0 R >> endobj 15 0 obj << /Title(\376\377\000C\000o\000m\000m\000a\000n\000d\000 \000L\000i\000n\000e\000 \000I\000n\000t\000e\000r\000f\000a\000c\000e) /Dest(chapter.2) /Count -24 /Parent 7 0 R /Prev 8 0 R /Next 40 0 R /First 16 0 R /Last 39 0 R >> endobj 42 0 obj << /Title(\376\377\000M\000e\000n\000u\000s) /Dest(subsection.3.1.1) /Parent 41 0 R /Next 43 0 R >> endobj 43 0 obj << /Title(\376\377\000B\000u\000t\000t\000o\000n\000s) /Dest(subsection.3.1.2) /Parent 41 0 R /Prev 42 0 R /Next 44 0 R >> endobj 44 0 obj << /Title(\376\377\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000 \000m\000o\000d\000e) /Dest(subsection.3.1.3) /Parent 41 0 R /Prev 43 0 R >> endobj 41 0 obj << /Title(\376\377\000M\000a\000i\000n\000 \000w\000i\000n\000d\000o\000w) /Dest(section.3.1) /Count -3 /Parent 40 0 R /Next 45 0 R /First 42 0 R /Last 44 0 R >> endobj 46 0 obj << /Title(\376\377\000.\000a\000s\000m\000 \000B\000r\000o\000w\000s\000e\000r) /Dest(subsection.3.2.1) /Parent 45 0 R /Next 47 0 R >> endobj 47 0 obj << /Title(\376\377\000O\000p\000c\000o\000d\000e\000 \000v\000i\000e\000w\000 \000-\000 \000t\000h\000e\000 \000.\000o\000b\000j\000 \000B\000r\000o\000w\000s\000e\000r) /Dest(subsection.3.2.2) /Parent 45 0 R /Prev 46 0 R >> endobj 45 0 obj << /Title(\376\377\000S\000o\000u\000r\000c\000e\000 \000B\000r\000o\000w\000s\000e\000r\000s) /Dest(section.3.2) /Count -2 /Parent 40 0 R /Prev 41 0 R /Next 48 0 R /First 46 0 R /Last 47 0 R >> endobj 48 0 obj << /Title(\376\377\000R\000e\000g\000i\000s\000t\000e\000r\000 \000v\000i\000e\000w\000s) /Dest(section.3.3) /Parent 40 0 R /Prev 45 0 R /Next 49 0 R >> endobj 49 0 obj << /Title(\376\377\000S\000y\000m\000b\000o\000l\000 \000v\000i\000e\000w) /Dest(section.3.4) /Parent 40 0 R /Prev 48 0 R /Next 50 0 R >> endobj 50 0 obj << /Title(\376\377\000W\000a\000t\000c\000h\000 \000v\000i\000e\000w) /Dest(section.3.5) /Parent 40 0 R /Prev 49 0 R /Next 51 0 R >> endobj 51 0 obj << /Title(\376\377\000S\000t\000a\000c\000k\000 \000v\000i\000e\000w\000e\000r) /Dest(section.3.6) /Parent 40 0 R /Prev 50 0 R /Next 52 0 R >> endobj 52 0 obj << /Title(\376\377\000B\000r\000e\000a\000d\000b\000o\000a\000r\000d) /Dest(section.3.7) /Parent 40 0 R /Prev 51 0 R /Next 53 0 R >> endobj 53 0 obj << /Title(\376\377\000T\000r\000a\000c\000e\000 \000v\000i\000e\000w\000e\000r) /Dest(section.3.8) /Parent 40 0 R /Prev 52 0 R /Next 54 0 R >> endobj 54 0 obj << /Title(\376\377\000P\000r\000o\000f\000i\000l\000e\000 \000v\000i\000e\000w\000e\000r) /Dest(section.3.9) /Parent 40 0 R /Prev 53 0 R /Next 55 0 R >> endobj 55 0 obj << /Title(\376\377\000S\000t\000o\000p\000w\000a\000t\000c\000h) /Dest(section.3.10) /Parent 40 0 R /Prev 54 0 R /Next 56 0 R >> endobj 56 0 obj << /Title(\376\377\000S\000c\000o\000p\000e\000 \000W\000i\000n\000d\000o\000w) /Dest(section.3.11) /Parent 40 0 R /Prev 55 0 R >> endobj 40 0 obj << /Title(\376\377\000G\000r\000a\000p\000h\000i\000c\000a\000l\000 \000U\000s\000e\000r\000 \000I\000n\000t\000e\000r\000f\000a\000c\000e) /Dest(chapter.3) /Count -11 /Parent 7 0 R /Prev 15 0 R /Next 57 0 R /First 41 0 R /Last 56 0 R >> endobj 59 0 obj << /Title(\376\377\000.\000s\000i\000m\000 \000m\000a\000c\000r\000o) /Dest(subsection.4.1.1) /Parent 58 0 R /Next 60 0 R >> endobj 60 0 obj << /Title(\376\377\000.\000c\000o\000m\000m\000a\000n\000d\000 \000m\000a\000c\000r\000o) /Dest(subsection.4.1.2) /Parent 58 0 R /Prev 59 0 R /Next 61 0 R >> endobj 61 0 obj << /Title(\376\377\000.\000a\000s\000s\000e\000r\000t\000 \000m\000a\000c\000r\000o) /Dest(subsection.4.1.3) /Parent 58 0 R /Prev 60 0 R >> endobj 58 0 obj << /Title(\376\377\000E\000m\000b\000e\000d\000d\000e\000d\000 \000C\000o\000m\000m\000a\000n\000d\000s) /Dest(section.4.1) /Count -3 /Parent 57 0 R /Next 62 0 R /First 59 0 R /Last 61 0 R >> endobj 62 0 obj << /Title(\376\377\000S\000o\000c\000k\000e\000t\000s) /Dest(section.4.2) /Parent 57 0 R /Prev 58 0 R >> endobj 57 0 obj << /Title(\376\377\000S\000c\000r\000i\000p\000t\000i\000n\000g\000 \000a\000n\000d\000 \000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g) /Dest(chapter.4) /Count -2 /Parent 7 0 R /Prev 40 0 R /Next 63 0 R /First 58 0 R /Last 62 0 R >> endobj 64 0 obj << /Title(\376\377\000A\000s\000s\000e\000r\000t\000i\000o\000n\000s\000 \000a\000n\000d\000 \000E\000m\000b\000e\000d\000d\000e\000d\000 \000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000 \000c\000o\000m\000m\000a\000n\000d\000s) /Dest(section.5.1) /Parent 63 0 R >> endobj 63 0 obj << /Title(\376\377\000A\000s\000s\000e\000r\000t\000i\000o\000n\000s\000 \000a\000n\000d\000 \000E\000x\000t\000e\000n\000d\000e\000d\000 \000B\000r\000e\000a\000k\000p\000o\000i\000n\000t\000s) /Dest(chapter.5) /Count -1 /Parent 7 0 R /Prev 57 0 R /Next 65 0 R /First 64 0 R /Last 64 0 R >> endobj 65 0 obj << /Title(\376\377\000T\000r\000a\000c\000e\000 \000a\000n\000d\000 \000L\000o\000g\000:\000 \000W\000h\000a\000t\000 \000h\000a\000s\000 \000h\000a\000p\000p\000e\000n\000?) /Dest(chapter.6) /Parent 7 0 R /Prev 63 0 R /Next 66 0 R >> endobj 68 0 obj << /Title(\376\377\000C\000o\000n\000t\000e\000n\000t\000i\000o\000n\000 \000a\000m\000o\000n\000g\000 \000s\000t\000i\000m\000u\000l\000i) /Dest(subsection.7.1.1) /Parent 67 0 R >> endobj 67 0 obj << /Title(\376\377\000H\000o\000w\000 \000T\000h\000e\000y\000 \000W\000o\000r\000k) /Dest(section.7.1) /Count -1 /Parent 66 0 R /Next 69 0 R /First 68 0 R /Last 68 0 R >> endobj 69 0 obj << /Title(\376\377\000I\000/\000O\000 \000P\000i\000n\000s) /Dest(section.7.2) /Parent 66 0 R /Prev 67 0 R /Next 70 0 R >> endobj 71 0 obj << /Title(\376\377\000A\000n\000a\000l\000o\000g\000 \000A\000s\000y\000n\000c\000h\000r\000o\000n\000o\000u\000s\000 \000S\000t\000i\000m\000u\000l\000i) /Dest(subsection.7.3.1) /Parent 70 0 R >> endobj 70 0 obj << /Title(\376\377\000A\000s\000y\000n\000c\000h\000r\000o\000n\000o\000u\000s\000 \000S\000t\000i\000m\000u\000l\000i) /Dest(section.7.3) /Count -1 /Parent 66 0 R /Prev 69 0 R /Next 72 0 R /First 71 0 R /Last 71 0 R >> endobj 72 0 obj << /Title(\376\377\000E\000x\000t\000e\000n\000d\000e\000d\000 \000S\000t\000i\000m\000u\000l\000i) /Dest(section.7.4) /Parent 66 0 R /Prev 70 0 R /Next 73 0 R >> endobj 74 0 obj << /Title(\376\377\000P\000r\000o\000p\000a\000g\000a\000t\000i\000o\000n\000 \000D\000e\000l\000a\000y\000s) /Dest(subsection.7.5.1) /Parent 73 0 R >> endobj 73 0 obj << /Title(\376\377\000L\000i\000m\000i\000t\000a\000t\000i\000o\000n\000s\000 \000o\000f\000 \000t\000h\000e\000 \000S\000t\000i\000m\000u\000l\000u\000s\000 \000M\000e\000c\000h\000a\000n\000i\000s\000m) /Dest(section.7.5) /Count -1 /Parent 66 0 R /Prev 72 0 R /First 74 0 R /Last 74 0 R >> endobj 66 0 obj << /Title(\376\377\000S\000i\000m\000u\000l\000a\000t\000i\000n\000g\000 \000t\000h\000e\000 \000R\000e\000a\000l\000 \000W\000o\000r\000l\000d\000:\000 \000S\000t\000i\000m\000u\000l\000i) /Dest(chapter.7) /Count -5 /Parent 7 0 R /Prev 65 0 R /Next 75 0 R /First 67 0 R /Last 73 0 R >> endobj 77 0 obj << /Title(\376\377\000U\000S\000A\000R\000T) /Dest(subsection.8.1.1) /Parent 76 0 R /Next 78 0 R >> endobj 78 0 obj << /Title(\376\377\000L\000o\000g\000i\000c) /Dest(subsection.8.1.2) /Parent 76 0 R /Prev 77 0 R /Next 79 0 R >> endobj 79 0 obj << /Title(\376\377\000I\0002\000C\000 \000E\000E\000P\000R\000O\000M) /Dest(subsection.8.1.3) /Parent 76 0 R /Prev 78 0 R /Next 80 0 R >> endobj 80 0 obj << /Title(\376\377\000S\000w\000i\000t\000c\000h\000e\000s\000 \000&\000 \000R\000e\000s\000i\000s\000t\000o\000r\000s) /Dest(subsection.8.1.4) /Parent 76 0 R /Prev 79 0 R /Next 81 0 R >> endobj 81 0 obj << /Title(\376\377\000V\000o\000l\000t\000a\000g\000e\000 \000S\000o\000u\000r\000c\000e\000s\000,\000 \000R\000e\000s\000i\000s\000t\000o\000r\000s\000,\000 \000a\000n\000d\000 \000C\000a\000p\000a\000c\000i\000t\000o\000r\000s) /Dest(subsection.8.1.5) /Parent 76 0 R /Prev 80 0 R /Next 82 0 R >> endobj 82 0 obj << /Title(\376\377\000L\000E\000D\000_\0007\000S\000E\000G\000M\000E\000N\000T\000S\000 \000a\000n\000d\000 \000L\000E\000D) /Dest(subsection.8.1.6) /Parent 76 0 R /Prev 81 0 R /Next 83 0 R >> endobj 83 0 obj << /Title(\376\377\000I\0002\000C\000 \000s\000l\000a\000v\000e\000 \000t\000o\000 \000P\000a\000r\000a\000l\000l\000e\000l\000 \000p\000o\000r\000t) /Dest(subsection.8.1.7) /Parent 76 0 R /Prev 82 0 R >> endobj 76 0 obj << /Title(\376\377\000g\000p\000s\000i\000m\000 \000M\000o\000d\000u\000l\000e\000s) /Dest(section.8.1) /Count -7 /Parent 75 0 R /Next 84 0 R /First 77 0 R /Last 83 0 R >> endobj 85 0 obj << /Title(\376\377\000T\000e\000m\000p\000e\000r\000a\000t\000u\000r\000e\000 \000a\000n\000d\000 \000h\000u\000m\000i\000d\000i\000t\000y\000 \000s\000e\000n\000s\000o\000r\000 \000-\000 \000D\000H\000T\0001\0001) /Dest(subsection.8.2.1) /Parent 84 0 R /Next 86 0 R >> endobj 86 0 obj << /Title(\376\377\0006\0004\000 \000x\000 \0008\000,\000 \000S\000e\000r\000i\000a\000l\000,\000 \000I\0002\000C\000 \000R\000e\000a\000l\000-\000T\000i\000m\000e\000 \000C\000l\000o\000c\000k\000 \000-\000 \000D\000S\0001\0003\0000\0007) /Dest(subsection.8.2.2) /Parent 84 0 R /Prev 85 0 R /Next 87 0 R >> endobj 87 0 obj << /Title(\376\377\000H\000i\000g\000h\000-\000P\000r\000e\000c\000i\000s\000i\000o\000n\000 \0001\000-\000W\000i\000r\000e\000 \000D\000i\000g\000i\000t\000a\000l\000 \000T\000h\000e\000r\000m\000o\000m\000e\000t\000e\000r\000 \000-\000 \000D\000S\0001\0008\0002\0000\000 \000F\000a\000m\000i\000l\000y) /Dest(subsection.8.2.3) /Parent 84 0 R /Prev 86 0 R /Next 88 0 R >> endobj 88 0 obj << /Title(\376\377\000C\000h\000a\000r\000a\000c\000t\000e\000r\000 \000L\000C\000D\000 \000-\000 \000H\000D\0004\0004\0007\0008\0000) /Dest(subsection.8.2.4) /Parent 84 0 R /Prev 87 0 R /Next 89 0 R >> endobj 89 0 obj << /Title(\376\377\000G\000r\000a\000p\000h\000i\000c\000 \000L\000C\000D\000 \000-\000 \000S\000E\000D\0001\0005\0003\0000) /Dest(subsection.8.2.5) /Parent 84 0 R /Prev 88 0 R /Next 90 0 R >> endobj 90 0 obj << /Title(\376\377\000L\000C\000D\000_\0007\000S\000e\000g) /Dest(subsection.8.2.6) /Parent 84 0 R /Prev 89 0 R /Next 91 0 R >> endobj 91 0 obj << /Title(\376\377\000S\000o\000l\000a\000r) /Dest(subsection.8.2.7) /Parent 84 0 R /Prev 90 0 R >> endobj 84 0 obj << /Title(\376\377\000E\000x\000t\000r\000a\000s\000 \000M\000o\000d\000u\000l\000e\000s) /Dest(section.8.2) /Count -7 /Parent 75 0 R /Prev 76 0 R /Next 92 0 R /First 85 0 R /Last 91 0 R >> endobj 92 0 obj << /Title(\376\377\000W\000r\000i\000t\000i\000n\000g\000 \000n\000e\000w\000 \000m\000o\000d\000u\000l\000e\000s) /Dest(section.8.3) /Parent 75 0 R /Prev 84 0 R >> endobj 75 0 obj << /Title(\376\377\000M\000o\000d\000u\000l\000e\000s) /Dest(chapter.8) /Count -3 /Parent 7 0 R /Prev 66 0 R /Next 93 0 R /First 76 0 R /Last 92 0 R >> endobj 93 0 obj << /Title(\376\377\000S\000y\000m\000b\000o\000l\000i\000c\000 \000D\000e\000b\000u\000g\000g\000i\000n\000g) /Dest(chapter.9) /Parent 7 0 R /Prev 75 0 R /Next 94 0 R >> endobj 94 0 obj << /Title(\376\377\000M\000a\000c\000r\000o\000s) /Dest(chapter.10) /Parent 7 0 R /Prev 93 0 R /Next 95 0 R >> endobj 95 0 obj << /Title(\376\377\000H\000e\000x\000 \000F\000i\000l\000e\000s) /Dest(chapter.11) /Parent 7 0 R /Prev 94 0 R /Next 96 0 R >> endobj 96 0 obj << /Title(\376\377\000T\000h\000e\000 \000I\000C\000D\000-\000 \000N\000o\000t\000 \000S\000u\000p\000p\000o\000r\000t\000e\000d\000 \000i\000n\000 \000v\000e\000r\000s\000i\000o\000n\000s\000 \0000\000.\0002\0001\000.\0000\000 \000a\000n\000d\000 \000l\000a\000t\000e\000r) /Dest(chapter.12) /Parent 7 0 R /Prev 95 0 R /Next 97 0 R >> endobj 97 0 obj << /Title(\376\377\000E\000x\000a\000m\000p\000l\000e\000s) /Dest(chapter.13) /Parent 7 0 R /Prev 96 0 R /Next 98 0 R >> endobj 98 0 obj << /Title(\376\377\000R\000e\000g\000r\000e\000s\000s\000i\000o\000n\000 \000T\000e\000s\000t\000s) /Dest(chapter.14) /Parent 7 0 R /Prev 97 0 R /Next 99 0 R >> endobj 100 0 obj << /Title(\376\377\000B\000a\000c\000k\000g\000r\000o\000u\000n\000d) /Dest(section.15.1) /Parent 99 0 R /Next 101 0 R >> endobj 101 0 obj << /Title(\376\377\000I\000n\000s\000t\000r\000u\000c\000t\000i\000o\000n\000s) /Dest(section.15.2) /Parent 99 0 R /Prev 100 0 R /Next 102 0 R >> endobj 102 0 obj << /Title(\376\377\000G\000e\000n\000e\000r\000a\000l\000 \000F\000i\000l\000e\000 \000R\000e\000g\000i\000s\000t\000e\000r\000s) /Dest(section.15.3) /Parent 99 0 R /Prev 101 0 R /Next 103 0 R >> endobj 103 0 obj << /Title(\376\377\000S\000p\000e\000c\000i\000a\000l\000 \000F\000i\000l\000e\000 \000R\000e\000g\000i\000s\000t\000e\000r\000s) /Dest(section.15.4) /Parent 99 0 R /Prev 102 0 R /Next 104 0 R >> endobj 104 0 obj << /Title(\376\377\000E\000x\000a\000m\000p\000l\000e\000 \000o\000f\000 \000a\000n\000 \000i\000n\000s\000t\000r\000u\000c\000t\000i\000o\000n) /Dest(section.15.5) /Parent 99 0 R /Prev 103 0 R /Next 105 0 R >> endobj 105 0 obj << /Title(\376\377\000T\000r\000a\000c\000e) /Dest(section.15.6) /Parent 99 0 R /Prev 104 0 R /Next 106 0 R >> endobj 106 0 obj << /Title(\376\377\000B\000r\000e\000a\000k\000p\000o\000i\000n\000t\000s) /Dest(section.15.7) /Parent 99 0 R /Prev 105 0 R /Next 107 0 R >> endobj 107 0 obj << /Title(\376\377\000T\000I\000M\000E\000R\0001\000 \000E\000x\000t\000e\000r\000n\000a\000l\000 \000i\000n\000p\000u\000t) /Dest(section.15.8) /Parent 99 0 R /Prev 106 0 R >> endobj 99 0 obj << /Title(\376\377\000T\000h\000e\000o\000r\000y\000 \000o\000f\000 \000O\000p\000e\000r\000a\000t\000i\000o\000n) /Dest(chapter.15) /Count -8 /Parent 7 0 R /Prev 98 0 R /Next 108 0 R /First 100 0 R /Last 107 0 R >> endobj 109 0 obj << /Title(\376\377\000G\000p\000s\000i\000m\000.\000l\000y\000x) /Dest(section.16.1) /Parent 108 0 R /Next 110 0 R >> endobj 110 0 obj << /Title(\376\377\000G\000p\000s\000i\000m) /Dest(section.16.2) /Parent 108 0 R /Prev 109 0 R /Next 111 0 R >> endobj 111 0 obj << /Title(\376\377\000L\000i\000b\000r\000a\000r\000i\000e\000s\000 \000l\000i\000b\000g\000p\000s\000i\000m\000,\000 \000l\000i\000b\000g\000p\000s\000i\000m\000_\000m\000o\000d\000u\000l\000e\000s\000,\000 \000l\000i\000b\000g\000p\000s\000i\000m\000_\000e\000X\000d\000b\000m\000 ) /Dest(section.16.3) /Parent 108 0 R /Prev 110 0 R >> endobj 112 0 obj <>endobj 115 0 obj <>endobj 118 0 obj <> endobj 119 0 obj <> endobj 121 0 obj <>endobj 122 0 obj <>endobj 127 0 obj <>endobj 128 0 obj <>endobj 129 0 obj <>endobj 130 0 obj <>endobj 131 0 obj <>endobj 132 0 obj <>endobj 133 0 obj <>endobj 134 0 obj <>endobj 135 0 obj <>endobj 136 0 obj <>endobj 137 0 obj <>endobj 138 0 obj <>endobj 139 0 obj <>endobj 140 0 obj <>endobj 141 0 obj <>endobj 142 0 obj <>endobj 143 0 obj <>endobj 144 0 obj <>endobj 145 0 obj <>endobj 146 0 obj <>endobj 147 0 obj <>endobj 148 0 obj <>endobj 149 0 obj <>endobj 150 0 obj <>endobj 151 0 obj <>endobj 152 0 obj <>endobj 153 0 obj <> endobj 154 0 obj <> endobj 156 0 obj <>endobj 159 0 obj <>endobj 160 0 obj <>endobj 161 0 obj <>endobj 162 0 obj <>endobj 163 0 obj <>endobj 164 0 obj <>endobj 165 0 obj <>endobj 166 0 obj <>endobj 167 0 obj <>endobj 168 0 obj <>endobj 169 0 obj <>endobj 170 0 obj <>endobj 171 0 obj <>endobj 172 0 obj <>endobj 173 0 obj <>endobj 174 0 obj <>endobj 175 0 obj <>endobj 176 0 obj <>endobj 177 0 obj <>endobj 178 0 obj <>endobj 179 0 obj <>endobj 180 0 obj <>endobj 181 0 obj <>endobj 182 0 obj <>endobj 183 0 obj <>endobj 184 0 obj <>endobj 185 0 obj <>endobj 186 0 obj <>endobj 187 0 obj <>endobj 188 0 obj <>endobj 189 0 obj <>endobj 190 0 obj <>endobj 191 0 obj <>endobj 192 0 obj <> endobj 193 0 obj <> endobj 195 0 obj <>endobj 198 0 obj <>endobj 199 0 obj <>endobj 200 0 obj <>endobj 201 0 obj <>endobj 202 0 obj <>endobj 203 0 obj <>endobj 204 0 obj <>endobj 205 0 obj <>endobj 206 0 obj <>endobj 207 0 obj <>endobj 208 0 obj <>endobj 209 0 obj <>endobj 210 0 obj <>endobj 211 0 obj <>endobj 212 0 obj <>endobj 213 0 obj <>endobj 214 0 obj <>endobj 215 0 obj <>endobj 216 0 obj <>endobj 217 0 obj <>endobj 218 0 obj <>endobj 219 0 obj <>endobj 220 0 obj <>endobj 221 0 obj <>endobj 222 0 obj <>endobj 223 0 obj <>endobj 224 0 obj <>endobj 225 0 obj <>endobj 226 0 obj <>endobj 227 0 obj <>endobj 228 0 obj <>endobj 229 0 obj <>endobj 230 0 obj <>endobj 231 0 obj <> endobj 232 0 obj <> endobj 234 0 obj <>endobj 237 0 obj <>endobj 238 0 obj <>endobj 239 0 obj <>endobj 240 0 obj <>endobj 241 0 obj <>endobj 242 0 obj <>endobj 243 0 obj <>endobj 244 0 obj <>endobj 245 0 obj <>endobj 246 0 obj <>endobj 247 0 obj <>endobj 248 0 obj <>endobj 249 0 obj <>endobj 250 0 obj <> endobj 251 0 obj <> endobj 253 0 obj <>endobj 254 0 obj <>endobj 257 0 obj <> endobj 258 0 obj <> endobj 260 0 obj <>endobj 261 0 obj <>endobj 264 0 obj <>endobj 265 0 obj <>endobj 266 0 obj <>endobj 267 0 obj <>endobj 270 0 obj <> endobj 271 0 obj <> endobj 273 0 obj <>endobj 276 0 obj <>endobj 277 0 obj <>endobj 278 0 obj <>endobj 279 0 obj <> endobj 280 0 obj <> endobj 282 0 obj <>endobj 287 0 obj <>endobj 288 0 obj <>endobj 289 0 obj <>endobj 290 0 obj <>endobj 291 0 obj <>endobj 292 0 obj <> endobj 293 0 obj <> endobj 295 0 obj <>endobj 296 0 obj <>endobj 299 0 obj <> endobj 300 0 obj <> endobj 302 0 obj <>endobj 305 0 obj <>endobj 306 0 obj <> endobj 307 0 obj <> endobj 309 0 obj <>endobj 312 0 obj <>endobj 313 0 obj <>endobj 314 0 obj <>endobj 315 0 obj <>endobj 316 0 obj <> endobj 317 0 obj <> endobj 319 0 obj <>endobj 322 0 obj <>endobj 323 0 obj <> endobj 324 0 obj <> endobj 326 0 obj <>endobj 329 0 obj <>endobj 330 0 obj <>endobj 333 0 obj <>endobj 334 0 obj <>endobj 335 0 obj <>endobj 336 0 obj <>endobj 337 0 obj <> endobj 338 0 obj <> endobj 340 0 obj <>endobj 343 0 obj <>endobj 344 0 obj <>endobj 345 0 obj <> endobj 346 0 obj <> endobj 348 0 obj <>endobj 351 0 obj <>endobj 352 0 obj <>endobj 353 0 obj <>endobj 354 0 obj <>endobj 355 0 obj <>endobj 356 0 obj <> endobj 357 0 obj <> endobj 359 0 obj <>endobj 362 0 obj <>endobj 363 0 obj <>endobj 364 0 obj <> endobj 365 0 obj <> endobj 367 0 obj <>endobj 370 0 obj <>endobj 371 0 obj <> endobj 372 0 obj <> endobj 374 0 obj <>endobj 377 0 obj <>endobj 378 0 obj <>endobj 379 0 obj <>endobj 380 0 obj <>endobj 381 0 obj <>endobj 382 0 obj <> endobj 383 0 obj <> endobj 385 0 obj <>endobj 388 0 obj <>endobj 389 0 obj <>endobj 390 0 obj <>endobj 391 0 obj <>endobj 392 0 obj <> endobj 393 0 obj <> endobj 395 0 obj <>endobj 398 0 obj <>endobj 399 0 obj <>endobj 400 0 obj <>endobj 401 0 obj <>endobj 402 0 obj <> endobj 403 0 obj <> endobj 405 0 obj <>endobj 408 0 obj <>endobj 409 0 obj <>endobj 410 0 obj <>endobj 411 0 obj <> endobj 412 0 obj <> endobj 414 0 obj <>endobj 417 0 obj <>endobj 418 0 obj <>endobj 419 0 obj <>endobj 420 0 obj <>endobj 421 0 obj <> endobj 422 0 obj <> endobj 424 0 obj <>endobj 427 0 obj <>endobj 428 0 obj <>endobj 429 0 obj <>endobj 430 0 obj <> endobj 431 0 obj <> endobj 433 0 obj <>endobj 434 0 obj <>endobj 437 0 obj <>endobj 438 0 obj <>endobj 439 0 obj <>endobj 440 0 obj <> endobj 441 0 obj <> endobj 443 0 obj <>endobj 446 0 obj <>endobj 447 0 obj <>endobj 448 0 obj <>endobj 449 0 obj <> endobj 450 0 obj <> endobj 452 0 obj <>endobj 457 0 obj <>endobj 458 0 obj <> endobj 459 0 obj <> endobj 461 0 obj <>endobj 464 0 obj <>endobj 465 0 obj <>endobj 466 0 obj <>endobj 467 0 obj <> endobj 468 0 obj <> endobj 470 0 obj <>endobj 473 0 obj <>endobj 474 0 obj <>endobj 475 0 obj <> endobj 476 0 obj <> endobj 478 0 obj <>endobj 481 0 obj <>endobj 482 0 obj <>endobj 483 0 obj <> endobj 484 0 obj <> endobj 486 0 obj <>endobj 489 0 obj <>endobj 490 0 obj <>endobj 491 0 obj <>endobj 492 0 obj <> endobj 493 0 obj <> endobj 495 0 obj <>endobj 498 0 obj <>endobj 499 0 obj <>endobj 500 0 obj <>endobj 501 0 obj <>endobj 502 0 obj <>endobj 503 0 obj <> endobj 504 0 obj <> endobj 506 0 obj <>endobj 509 0 obj <>endobj 510 0 obj <> endobj 511 0 obj <> endobj 513 0 obj <>endobj 514 0 obj <>endobj 517 0 obj <>endobj 518 0 obj <>endobj 519 0 obj <> endobj 520 0 obj <> endobj 522 0 obj <>endobj 525 0 obj <>endobj 526 0 obj <>endobj 527 0 obj <>endobj 528 0 obj <>endobj 529 0 obj <> endobj 530 0 obj <> endobj 532 0 obj <>endobj 535 0 obj <>endobj 536 0 obj <> endobj 537 0 obj <> endobj 539 0 obj <>endobj 540 0 obj <>endobj 543 0 obj <>endobj 544 0 obj <> endobj 545 0 obj <> endobj 547 0 obj <>endobj 550 0 obj <>endobj 551 0 obj <>endobj 552 0 obj <> endobj 553 0 obj <> endobj 555 0 obj <>endobj 556 0 obj <>endobj 559 0 obj <> endobj 560 0 obj <> endobj 562 0 obj <>endobj 565 0 obj <>endobj 566 0 obj <>endobj 567 0 obj <> endobj 568 0 obj <> endobj 570 0 obj <>endobj 573 0 obj <>endobj 574 0 obj <>endobj 575 0 obj <> endobj 576 0 obj <> endobj 578 0 obj <>endobj 579 0 obj <>endobj 582 0 obj <>endobj 583 0 obj <>endobj 584 0 obj <>endobj 585 0 obj <> endobj 586 0 obj <> endobj 588 0 obj <>endobj 591 0 obj <>endobj 592 0 obj <>endobj 593 0 obj <>endobj 594 0 obj <>endobj 595 0 obj <>endobj 596 0 obj <>endobj 597 0 obj <>endobj 598 0 obj <>endobj 599 0 obj <>endobj 600 0 obj <>endobj 601 0 obj <> endobj 602 0 obj <> endobj 604 0 obj <>endobj 607 0 obj <>endobj 608 0 obj <> endobj 609 0 obj <> endobj 611 0 obj <>endobj 614 0 obj <>endobj 615 0 obj <>endobj 616 0 obj <>endobj 617 0 obj <> endobj 618 0 obj <> endobj 620 0 obj <>endobj 623 0 obj <>endobj 624 0 obj <>endobj 625 0 obj <>endobj 626 0 obj <>endobj 627 0 obj <> endobj 628 0 obj <> endobj 630 0 obj <>endobj 631 0 obj <>endobj 634 0 obj <> endobj 635 0 obj <> endobj 637 0 obj <>endobj 640 0 obj <>endobj 641 0 obj <> endobj 642 0 obj <> endobj 644 0 obj <>endobj 647 0 obj <>endobj 648 0 obj <>endobj 649 0 obj <>endobj 650 0 obj <>endobj 651 0 obj <>endobj 652 0 obj <>endobj 653 0 obj <> endobj 654 0 obj <> endobj 656 0 obj <>endobj 659 0 obj <>endobj 660 0 obj <>endobj 661 0 obj <>endobj 662 0 obj <>endobj 663 0 obj <>endobj 664 0 obj <> endobj 665 0 obj <> endobj 667 0 obj <>endobj 670 0 obj <>endobj 671 0 obj <>endobj 672 0 obj <>endobj 673 0 obj <> endobj 674 0 obj <> endobj 676 0 obj <>endobj 679 0 obj <>endobj 680 0 obj <>endobj 681 0 obj <>endobj 682 0 obj <>endobj 683 0 obj <>endobj 684 0 obj <>endobj 685 0 obj <>endobj 686 0 obj <>endobj 687 0 obj <> endobj 688 0 obj <> endobj 690 0 obj <>endobj 693 0 obj <>endobj 694 0 obj <>endobj 695 0 obj <>endobj 696 0 obj <>endobj 697 0 obj <>endobj 698 0 obj <> endobj 699 0 obj <> endobj 701 0 obj <>endobj 704 0 obj <>endobj 705 0 obj <>endobj 706 0 obj <>endobj 707 0 obj <>endobj 708 0 obj <>endobj 709 0 obj <>endobj 710 0 obj <> endobj 711 0 obj <> endobj 713 0 obj <>endobj 716 0 obj <>endobj 717 0 obj <>endobj 718 0 obj <>endobj 719 0 obj <>endobj 720 0 obj <>endobj 721 0 obj <>endobj 722 0 obj <> endobj 723 0 obj <> endobj 725 0 obj <>endobj 728 0 obj <>endobj 729 0 obj <>endobj 730 0 obj <>endobj 731 0 obj <>endobj 732 0 obj <>endobj 733 0 obj <>endobj 734 0 obj <> endobj 735 0 obj <> endobj 737 0 obj <>endobj 740 0 obj <>endobj 741 0 obj <>endobj 742 0 obj <> endobj 743 0 obj <> endobj 745 0 obj <>endobj 748 0 obj <> endobj 749 0 obj <> endobj 751 0 obj <>endobj 752 0 obj <>endobj 755 0 obj <> endobj 756 0 obj <> endobj 758 0 obj <>endobj 759 0 obj <>endobj 762 0 obj <> endobj 763 0 obj <> endobj 765 0 obj <>endobj 766 0 obj <>endobj 769 0 obj <> endobj 770 0 obj <> endobj 772 0 obj <>endobj 773 0 obj <>endobj 776 0 obj <>endobj 777 0 obj <>endobj 778 0 obj <> endobj 779 0 obj <> endobj 781 0 obj <>endobj 784 0 obj <>endobj 785 0 obj <>endobj 786 0 obj <> endobj 787 0 obj <> endobj 789 0 obj <>endobj 790 0 obj <>endobj 793 0 obj <>endobj 794 0 obj <> endobj 795 0 obj <> endobj 797 0 obj <>endobj 798 0 obj <>endobj 801 0 obj <> endobj 802 0 obj <> endobj 804 0 obj <>endobj 805 0 obj <>endobj 808 0 obj <>endobj 809 0 obj <>endobj 810 0 obj <> endobj 811 0 obj <> endobj 813 0 obj <>endobj 816 0 obj <>endobj 817 0 obj <>endobj 818 0 obj <>endobj 819 0 obj <> endobj 820 0 obj <> endobj 822 0 obj <>endobj 825 0 obj <>endobj 826 0 obj <> endobj 827 0 obj <> endobj 829 0 obj <>endobj 832 0 obj <>endobj 833 0 obj <>endobj 834 0 obj <>endobj 835 0 obj <>endobj 836 0 obj <> endobj 837 0 obj <> endobj 839 0 obj <>endobj 842 0 obj <>endobj 843 0 obj <>endobj 844 0 obj <>endobj 845 0 obj <>endobj 846 0 obj <>endobj 847 0 obj <>endobj 848 0 obj <> endobj 849 0 obj <> endobj 851 0 obj <>endobj 852 0 obj <>endobj 855 0 obj <>endobj 856 0 obj <>endobj 857 0 obj <> /Subtype/Link>>endobj 858 0 obj <>endobj 859 0 obj <> endobj 860 0 obj <> endobj 862 0 obj <>endobj 865 0 obj <> /Subtype/Link>>endobj 866 0 obj <> endobj 867 0 obj <> endobj 869 0 obj <>endobj 872 0 obj <>endobj 873 0 obj <>endobj 874 0 obj <>endobj 875 0 obj <>endobj 876 0 obj <>endobj 877 0 obj <>endobj 878 0 obj <>endobj 879 0 obj <>endobj 880 0 obj <>endobj 881 0 obj <>endobj 882 0 obj <>endobj 883 0 obj <>endobj 884 0 obj <>endobj 885 0 obj <>endobj 886 0 obj <>endobj 887 0 obj <>endobj 888 0 obj <>endobj 889 0 obj <>endobj 890 0 obj <>endobj 891 0 obj <>endobj 892 0 obj <>endobj 893 0 obj <>endobj 894 0 obj <>endobj 895 0 obj <>endobj 896 0 obj <>endobj 897 0 obj <>endobj 898 0 obj <>endobj 899 0 obj <>endobj 900 0 obj <>endobj 901 0 obj <>endobj 902 0 obj <>endobj 903 0 obj <>endobj 904 0 obj <>endobj 905 0 obj <>endobj 906 0 obj <>endobj 907 0 obj <>endobj 908 0 obj <>endobj 909 0 obj <>endobj 910 0 obj <>endobj 911 0 obj <>endobj 912 0 obj <>endobj 913 0 obj <>endobj 914 0 obj <>endobj 915 0 obj <>endobj 916 0 obj <>endobj 917 0 obj <>endobj 918 0 obj <>endobj 919 0 obj <>endobj 920 0 obj <>endobj 921 0 obj <>endobj 922 0 obj <>endobj 923 0 obj <>endobj 924 0 obj <>endobj 925 0 obj <>endobj 926 0 obj <>endobj 927 0 obj <>endobj 928 0 obj <>endobj 929 0 obj <>endobj 930 0 obj <>endobj 931 0 obj <>endobj 932 0 obj <>endobj 933 0 obj <>endobj 934 0 obj <>endobj 935 0 obj <>endobj 936 0 obj <>endobj 937 0 obj <>endobj 938 0 obj <>endobj 939 0 obj <>endobj 940 0 obj <>endobj 941 0 obj <>endobj 942 0 obj <>endobj 943 0 obj <>endobj 944 0 obj <>endobj 945 0 obj <>endobj 946 0 obj <>endobj 947 0 obj <>endobj 948 0 obj <> endobj 949 0 obj <> endobj 125 0 obj <> endobj 956 0 obj <> endobj 957 0 obj <>stream xś]O10 Üó ˙ ©Ş*!ş0´ŞÚ~ 8Ę€…0ô÷%:t8K结ϲëŻ=»ň=ľ(ul"Í~‰H0ĐčXÔ ŚĂ´ł2qŇAČî¦ĂűVŮŤßőDňy9ťËŞŢBč ÍA#EÍ#‰¦ŞÚĆÚV›?i öpÚ¶@UJ˙ˇäh.qÜ\b$NĄii’ 8¦ß3Á‡ś‚â S"S• endstream endobj 455 0 obj <> endobj 958 0 obj <> endobj 116 0 obj <> endobj 959 0 obj <> endobj 331 0 obj <> endobj 285 0 obj <> endobj 960 0 obj <> endobj 961 0 obj <>stream xś]ŐÍnÚPŕ=Oá7Ŕöů Rt7é&‹VUŰ0ćR± B}űÎL’.şKõ->ŽtŘ>=y>źîĂöűí˛ţě÷áx:nýőňv[ű°ďżOçÍ4‡Óz˙hş®/Ëuł}úş\ýąö7ôă{˙¶ĽôíŹ]Núhzh˝úëuYűm9˙î›ÇqlŹÇcŰôóΰÝřţÄţřqë„[™yśÖ†:5őŔZM™Ç‘§3OqÄun ęĚjMA5Vo ŞłfSP“•oŐ›§ëCSpúŔşk ŞN—¦ .¬ű¦ îYצ ęKš‚JÂÜ›‚ÚYŹMAĹôh 3ă+*p& hŔ™€F gś hZ45Xa5yŤ^•A-VXM^Ł×`5yŤ^Őä5z V“×č5XM^Ł×`5yŤ^Őä5z V“×čuŕ\@'Đsť@Ît8Đ tŕ\@'Đsť@Ît8Đ tŕ\@'Сq‰ś"‡Ć%rŠ—Č)rh\"§Čˇq‰ś˘ŔôB N0  ‰‚˘€&$ Šš(( hB˘ (  ‰‚˘€&$ Šš(( Ě'4ŁŕŚš(( hB˘ (  ‰‚˘€&$ Šš((JĚ'5ŁäŚš”()JhR˘¤(ˇI‰’˘„&%JŠš”()JhR˘¤(ˇI‰’˘Ä|R3JÎ(K“Ŕ.L¸0 LŕRŔ$0K“Ŕ.L ă*Ť¬8˛‚µä-z Ö’·č-XKޢ·`-y‹Ţ‚µä-z Ö’·č-XKޢ·`-y‹Ţ‚µä-z Ö’·č-XKޢ·`-y‹Ţ‚µäĹ•{ösˇrĺryîęa}»Ýúů® Ż ÎĹ}:÷×Ë•O Čć/–ŮwÍ endstream endobj 268 0 obj <> endobj 962 0 obj <> endobj 126 0 obj <> endobj 950 0 obj <>stream xśťxy\S׺öŽ@öV)UŇ"6I­UŰÚZŰZ­CťqD”H $„ća1Ď$@(ó$ j±N§jëĐ:ťÎ¶¶µµ§í©=çÝtqďď® µç|ßwßýýî?˛kŻ÷}ź÷yžwó(ÇiŹÇx+˘Căt{4ŃŢš5^Ďď”…+¸Ż—°R&•+T2éĆ]>~ŰĽ·H=·xď—n‘©eÚ•Ô'.TĄ“z)Âdjťl±T®ŃJUSHĂ4ęp…^ˇQë–KßŇIC¤şY‚ü“Ě&‹á–IcdÚh…NG>K:i„6D­—…Kő©B¦Š çOľ—kÔziŚVCÖŁÉ 9ĘGŁÓë´Š˝”<ŃgÓŰSwÔG†čąçędYŞ‘“ťáš°8.š?×ô! µNŞ—ôÜsBeŇp….F’HžKŽŠŃ*&ݧS¨#ţőôeR­,"D®’é&Ďĺ˛ňŻř¤˙uHLŚ*qň5“»ţ|ľBŻ“©ä˧ +%• QKIqĄ^R®şqŃ˙ďÂżĘőż+ EQßRÜ Ůł)vłömÝýÖ¸mń !; ˇ^‰a;Ă˝e»ä>»#÷(ö*÷EíWö}ů•ŐŻ®ymáşiËž_´bĺ /ľ´Š˘ćQ»¨5Ôs”5źÚM- öP ©˝Ô"jĺIí§S¨%”/uÚ@-Łü¨ŤÔóÔ!jµśÚL­ Ţ¦VR[¨¨­Ô‹Ô6ę%j;µŠÚA˝LyQŻP;©Ő”7ő*ő4ĺFąS"jĺAŃ””Цž \¨'©őÔ,j6ĺJ ¨§(!µ‰ šr¤TÔ=^Ć´™ÓöL»čŕĺ0ęřśc˝#ëęô?śoŁ=čz„yŠ©ťľ|úé‡fźIϬśyßy·óĺ'=‘űÄ.\†žÔ?‰gEĎÂł˝gçęëÚ$ gžrę’pݰçéçžözúŽ›·[†ű÷ë˘(Q—č‚čžč×9ÓçDĚéöxx܆"—q9˛Ăú~ĐYaŻ•7ľŮ.ĚᇣäF?ulł»†Źµ#˛ĺ©ĆĂé"-Ůiźb}jA5ĺöĆwëúÝ!Žßµ¶:šxSZd^62ĺ§ä1Z¸KOä‚Yř=äü‚sś\Ř3ČĆş^Ť°ąŢ Aâ&H6D÷ęřĂ™i(„ÁŁ4 ÉHLgteŁĺ%©u¨—+ŤŠË*++ÁÝć&[ułGw}Ě^ Φ‘Ü”¬Č!›SmtxQZ5:Î@1}ďŔŮ5»4>r1śu| kÓř«B\¤ĺWä—Ł˘üĽęt¤Cńćx˙iú(mäXân˛ć• jÔX]ŢSH>Ô0vü“–îÉ­Ik„CxŘoıŃrťÉ/‹¤˘ČN{—&T";j˛vÜúąď÷_đ+Ő† 2‹PRRzd^2ç›ňI.ŘiE±ćđGx;ô¸_sKĂ­2‘Ëř d×v°żÓÚ]Á*X k°Ö» –XČ•uZúzNC2:ČLhtĐş!(µp›†µŕxśF ‘í’ČcŠşÍuŚ@L×Đŕť9ż.?Ź_{ă{Âc|ň×Óűń´%ˇ~Ż%ŐKŘÇžşš~±@uŁ#řůyJ ~2WâÂ榴łkŰyvX/Ŕ"(fŁ…Xŕ9ĎĹĎý0Ü@řđ)śté#,”¨„öáWńňßÝ> ďŔBŘtdě’„$Üpr|z'ďlv_Ë„>;Łt‡ ęTe–mC^Ýę1ő™”ŹĐĎ „]iŕ<:”(…7+»×1v0ĹđS"ÍfJGĆâ¸JŰáŞĂÁ‡ńbĽăPX„B؇ë{ĎJ:šš¬#§‚,ŇoÓAé,;ăúÝ*‰ŔŁ0@Ę*,Ő5Ö¦ćę&ÄŚŮva7ę"…ü‘<˝6¸ ~üV‚´ »óHm´pťĚ'ŕP,…Ů8Y‚/đsµô•¬# ŕ řJł°ŮZÝ˙Ń;Ę·»Ä­j7 ŐhYÂËQŠ€Ăúí 4ŐŚH&c¶éěđÚ»ě‚×.’˙W¸Žň‚–ŃÎŚôí©Śŕ”¬6: "˝ 0ěwFzíŢCŞZ?$ÂOŻG2úĚťĄŔí¶ JÎ9¦Éµń ÄěT˝OjíŃqăň@kÔaÉ>ŰYčšÄç+nOö̉[|AÍ˙Mßó[$«‘Zö3zÂť4|ŐÖM„:@ľ/ybvj†$M †Wc†iocůFĚŹŔTFşŻ¦b VźR`‘]lç»°>„/^°eX]?ç"»j®’»uüˇ¬* ›äŠĐ4sPi˙í]śZ.1°›kę,ŻČL®7ÄÔĄ· ¦·Ą­_"X9˘čô÷“Ĺlő»°€ěěü’ű Ňľ w2$#ňý·´0a§W'VŁł ¤ĐĎë•×’űŰá[-?ó##!îúźŢšĘwľ»Ů.nŇVĹÔz16…(Ą‹}µ“×ú3:ŔřX âč,cVv*ĘBi…É%Ę*}qbVnŰązŰ`Ŕ/Á’kŃmZĹ„GÇnů*^¬ÁkěüŞĆҲ T‚Ęó*sZSĎŰóíĺKß|>äy\˛ĺ¨ĆŽşÎ6{_K«9ľIÜP•XĸŚ7:ÇÝ;y˝°Ć`ĄĂx ńC-˙^vťígćŃŐq[˝B†”â sń÷83 » đÄ Ň™Ăâ!YłâîĚPŇ™ ń|˙ <[ß hôQUőírĆîĄ~żó>‰\ 5|ÖjůŢ/‡nßÇÄŚá»ôöˇ°ëWŽ}6(ÖV%Č’Sâ‘Hc®Ŕ»ßÓ$"OďŽB»ť÷‚ń,xĹ-%YÄI4:””˛!cŠ]7V$× S KŞvÚjąVBű–ľ‘mMF~ ĂY6ąr[ůFK_Í:b$+\•M›ÓÉ)ßŘé ĺIµäH˘IĄĽŻjfĹ6×÷Ë•š„Cu¶â÷Ë.•ą7ÓA…rC Lŕ}:§:3¸‡Ś(•ńfŤG¨ŃúŽľĂ>:z0Ł<ť“·úĄÓľźŹu[N_ !ű8ßÎ'8="żÄ”ő™ä&żÚéu%†Z46ĎXŁĺVąőŻZúŁěF#i7ެ­ě+ŹMäzb)鉼ęL"hćśäĚÄŤx»ű”ŮWŠJE¨®˛Ě^XĘ Ę .ŇŃÍąĄąĄé…Ł‹,ˇŕŚOą·đa+m./o/"‚$ź:{Ü—;ŰCÇďÍ©Ę@z”j’«Ţ0†għ*Ňs«ăo%\ĎlCČRYŇWDN6éčţś‚ü†mĄ÷-xťîJzcfCv­HsĂÜjȶň¶b˛M«Ł[˛‹łZ·çÄ wfĂĺżăËNÍ|XÁ.°ô–—·”ţ°ĂŐNÍÄřx†P}E––›››źŤD)™ ÔŇ_¬;]°ÓşëCmÚÁ6[WmVMŞEś^™KâgŰ,ÝbÁ -1Ţ’ 4žq(A® Ž&TĚxŹ^9Âzú¬¸ę`“áBí–ľAFđ ö=/ŚQ%¤ęß:pářńO%“Pś,ŘtR°ńJ»P[`.1Őá ¬‹;řŔűŹĺ¤Nǵt}~m~I~O^MJ@ÉŮ*ŽĆjwPŇčĂ:Ë-ßrLsä1Óaß1…Á? éV;lÇ ş’tÎPR˛•śąB)śˇ¸Oš‹¬ěM\’YśY…=Áŕţ ¸64[«ÚKD6ü†Ž&†'ż5ç—g!#2¦%i˘˛˛Śc|VYNinqÔńŘ!RśęÚŇÎ?ĐŃ’SšmŤ†§°ź»ZŁLOŮűVB’<ŹěZQR†ęP]Ëńľ…Eeĺe ęzmizł˛Ň€RQjJ–ŠŰ™5Ů>ě‚wa‹Ťk|XÍ9ŠÎĐńO¤W¤źxTM|îDhOňi$ŃG°Äo>ćĺIárÉÇú!«Ą1—Ú·ĄGoßÓ~ň±"ŤSv×ß8ňŽw…ˇšŻ\› ŠŚ •ďM|1ŢśÚ°*Ý®­ůޤűďZúZΑ?´JP‚šĚŇŹ–˝Íe‡śgďYyéŔę˙ŻžĘKO×nÁűÜ7Â΄wBĺ"T[]a/´¸˙[?ˇ‘Ĺő!¤źNş'Hň‹ŤŇ#QzFyE*,(’”” bć¨ÎŞÇÄĘ”绎V76Š›­ÝßĂböY÷úă••íE¤ą}R®˛"Ή=ëŔ®žP›ŠUűľ‚ążv\łÔeK%…:˘ďEĚń[˙Ą­'_Âs=‹çcń7ž0ëîąö[$.żošBíoÇŮ6Xá0ţűáD)Ťö¦¤N’Í—vzmeZúa˝ i×ŐÝäŕYBc˙ ögUN¸TËż™e1qPŐĐh—)u-U“ť^Sjh@·VICÉÄ·N­|®ěçâšŮçHáIóz’Ââ4Âw&á‰{ÉĄ˛Kĺ„8ŠL5ÄŞłá(}5»"“8Ľ>m ’2mŤ/:ńÜ;žżťé´śçţE˛Ň’RM úx3ËÚż€„­/t¶ëdµśűJ´ćqqş>f7sdťÄÁ-BË·˘zăÉ=Ě„šF{Ś)8ŞO°ÓoV$6p1/$|ÍîťtjcďńŃůšš÷+IřQZúVfC<ÚÄŕ 4W‘Ź`W/¬jç± a¶0ě*1…#ő‘řîÄŽŚÎśë ”đłľ0ŽFő)ű¬űHłW{â…xágKaÖ§§:Ľ/Áu°NXÎGNˇ6Ô\®*1j 2FúO•î&*ýOâśŮgĆ·±ŚH«'ÇaÄô."–‘ü& `Ľ–âIľRÓ®ŕ'Č–ťx¦1˝“Xę@P]¦Kô őĚ0nç}HÔ÷Cöe!ľGŁ`sj@6iÓv˝ą0µ˝ĎŔŐŻ†W }¶®©űHUfjNnfVš8ÝcFiŚŞE×Ők·÷^ô\˝ŐW#Ž‹Ě E/3{‚řSNj˘›8©ź‰:żĆ .ˇÎ ÁŁ «hřȧíĂ 0Ë>  ľÍŚYÎŞMF›™ ‚·ť¦˙¬\”–gćFĆŻěô•Ä®ŢdŮÇćúęÎĎ;0ĺ•*‹Ő‹u ĘĚMS?ÚAdÁů«VPťIowműú xÜÁCţ±›Ŕ•băŮyÂ3řiZđe Ň”†yŕ™«·-SÔ(›5’&]i4áŤ0ňEˇGŻčÁŹfŻtĄ6tÎîŰ p…׾űéîÎ ÄŰůŻ'”µkkŚäŹ"{i—U$¸AŤ´4ž™RŹiÚ7'7Íď¶$)öĹzľĐ<ÜXVŐÖ,,ĄîłéÂŃŮňĺ†˙É=ľočĺTooűW±ÇŐxş0*=9×€üQŕE—ˇ!­.±÷Ó–nëЉ÷Ţ'~d śpűbbł‚ńĽ ‡Żl_}a‡x0 #Ꭶ1¨ÚЬ?·÷‹¨ŻŃ{h¨üv+‚ăěL°:… Ćxň+Dľř’Çă8GĐ×§ Ž„słŹ#č˛ ĘL”ý§ń¦f2Š#ćż›Ĺ#ŠLuÜ,^09‹'ěöťśĹ˙0ÝŔ'XŮëÜwÇěÂDd*M«ÁĐç~±Á^Óf?Új@# Đž—ńŽÇ ą•]kD'Ał!-m-×ĆßţI]p°•†0ü„đ'v°? Qiq]QiiĄĄÄŽďzçí0†GĹKb“™ëň‰-mź/nà ׿Ŕ 2Tžzá÷“ s:5cdfIX6:˛$µő°™ý§0822$°S9<ÜŐ9<¤čćRJşxN»Áę:LRť3ÝݞV#„čh:36##‰xgsQ\9#¸kńŹ*•y๯ľ‰]_ó‚™{$WŁľ±Ĺ"_ŃۇßÜíg?%Çô¦t&Ý`Ôĺ—ÚË+,¨Uĺ6ežNęÍ"S‡çĎ_‚ëí€Ű;:$xŃÍ×âěč¤čŇńľk#Ç ňqW¤EmÝÎYpÔÎţc2X H´ó¦˘­á˘ Ôńß™ň®„!őJ©¬˛¤¨¬´R\i)®B•̱[”\«ŤđąúŮő3­§ÚÄ ĺ}č"IÄúńÍÂ`ID‡rd¨»kh(’K§Đă3­<(ĺśm)L˘·Ěć—9µ·Ó«JÍ•čĂÚhx2g, ĎdŽňó ŔiâG~.p:ĘŻ‡™c'`V13‰ŇqĆĆ»AŕÉVr×UęůUy•ůEů¶ÜŞLâ†ŇÓÍfü~ĘťÝwéč®ÜÚ$$›Än¸1Q™;U9˙˛ěR4Ęźn¶ý€çÔkËRQ†3,š|˛ĂdŁÍ(»(˝€F÷źk9r™L.ărĂ©qžť÷7x n;Ś;°—…čb­ĺ §1ZúŻYÖ´Sěą÷mń‰=N?đąËuŚ?uÔµ žŔÓ@H"`Çŕm¸+ÜcĐ›bµjŤQ†‚_n!öMňŕ˘áÁ—¤×Ä‚›»ŻĚążîž‰=^Üú­¸»®µ¦©ąŠŚź‚ߎŮRŤůůąůą’lsžĄ2Q-q}}­öîó[şń´ {#äâ°0ŁŢ‹ÄźÇdŚN3űg‘ăsČń%ćÔOŔQ”eM„—\aĹ57AđyĽUĚŐÓ {ĚőĐŃ]~JĄźXĐp,j¨¤”ŠÁ„ž =ŞĘÓM2EČz_ÎÍĂ:`xĂăÜ[ĽĚ@źśl"R;űżCg•gźćq?…§'rýh"2ëř‹d˙Y2aĽŔÇć˙8äôÍdó¶Ť‹Úx6x‘Ć‹PDhe;Úş1j_ÜóčU‡~O†’1=ü—D(ľ6!"źŚµé1furŠ1~†‹ŕ)D–6\8yĘş/âAĘŇŇrź<Ö<ŕÇY%çKW•¶VÚËjcŻŠó—Li´&!É“č2;ÓFŻ,LŞ#{uň…ŘťŔçÁëŔj!B¨ă«7¦f- ×RÎT.˙řv÷UtGôĎ7ď`ĘďpBD¤8<u…X¸řn‚//°Vaß{ťÍcąÜćµ-2rY´$‰ţ\ݙԣ`×ŰŐGĎŮ( ŘĄ3Tu(ĹáýŃ–hÄČbtŠýďE|ݓɄ O‡ÔÝ’x[RuŘFđĺ•ţ†ŁçÜó~gçzżůű&“d…YŕŔľ`u+,ŔĎÁsn‚_Ř•P.d7żNűĽI\ÎëŰVěZ&"Ü^€çÓ„YŔüËŕŔ<ŔˇOcdpÚÉ%ÁʆXÁ×ĘďśŇ™ťťÎÎ mv~‚˘ţ }E› endstream endobj 456 0 obj <> endobj 951 0 obj <>stream xś%ŽAKQ…ßs¦¤š´‚jQŮ+BÍ‚0˘%0ÄVDĂřĘDZń•A•­ iQŃŞő,[úO¤E»6ŃťńşČhq8çłř(‘=„RęM¤6·f˘sʡΨǓŞXh&ÝťŽŞ"Uů Ü(öîŢGdJÍó»„Y:˛ô˝Ľ`A-Äfâńůi‹FălĹŕ–®©E–REžŞhCmššÎĹ .ć…(-D"•J%¬ĺ°ií-…¦YEy–áenň[5‹‚m¨g˙vá˙JFé@p‹ĄĚ·Ššni®ý‰BÇßK 7D˘T]8W>çŞţ _O´î KNnbŤI$s±É‰Ć,ďŹĆOŔ×<Ć‚í~Ú´n»ď¶ÔL¶PĂmPńŻ1‹>` ¶Q…K¸†,hđhĄ[K(p 2p g°iŘkÁS<ĂuLăţ¸Żüę.żtâČ˝×î¶{ÝňĐî‰Ňe?*J;mŰ_óy˘W endstream endobj 117 0 obj <> endobj 952 0 obj <>stream xśĹxiXS×ÚöŽěÝ:´%Ť&jęP­SŐjĹy•QD@ c ! $L‹1Ś 0Ďó(Šâ„C«Ő:Ôˇ¶jOçٶ§ksç{ßµá´=×Űóýxż?ßu9$Y{Żő ÷s?÷łXÄäI‹Ĺâ ‹<+w“F”®s^ć&‰e~^LĎfŃs&ŃŻŮíDQ˙pŤ`Ó©j¦N®śłxý?XŻŚ:˝DöňÄ>٬Ö kt‘§Ű‘7—,YşC*K U8¬\·nťĂń‡­88‰ĺa!Qoŕqb‰T)ŽR,wp‹ˇb‡ŕ0‰ŘaÇ!ď˝w;,Ú}ĐÓa·8J(qp‰=. rp GÉĹo:Kc$_‚¤Q'ÂaŇ(ůr‡mr‡@ąL†_+Ä2fa©L&—ăĎar‡Ŕ(…ř„Bę$‰=ÁŹ–F)d1RĽ‰WđV.RąB&S8ŕ]śvMب T0çĘĂđ˛4?yBËxóÇš"0,Jî +Ě9ÇĹ'Âä2I`>o%‹ 7!VňçéKbÄ!1'$bůřľLTţôĎá߼”É$ ăďJÇźúăü0…\, ^>‘XśŮŔ(ś\g&»’Ŕż®ü™Ż˙· ql[”×v©÷™ŹSôÎ]ňÝŠ=±{ăöĹîWwN: :qP|(Ř%Ä5Ô-Ě=Ü#ÂSr8ňČšÂwÖľî8wÝĽőó7,ŘřƦ…›ulys±ď’IG—Úů-űŻâĺţo­XąęíŐ1—8D¬#ć.Äzb>áJl nÄ„;±đ žÄ›Äab1q„XBxۉĄ„7±XFřNÄr—ŘIĽEě"V»‰•Äb±—x›ŘG¬&ökgââ±–8H83xb&Á'&ÂŽEL&flbÁ!^#HBHPD!"^ t„ń"1…ŘHL%"‰MÄ4"ŠŘLL'ţFH‰—­ÄËÄ+„=Á%^%x„?®Ľ‘¸Ď’MzuRŔ¤»vűě®Ož19ŹM± Ř?s8L%ż¦ü©[/LyAňBď‹ű^ünJâTöÔŔ©ýÓŢ™–3 Mß<ýĚKK_/“/źxůń+=öNö§¸NÜęWwĽ:Ŕ›Ě+›1eĆž•3]f~Ä÷ä – |ÖYŻĎňźu}öúŮŇ9ě9Ç_Ű˙Zp™pżĐ |.zEtX,zćđĆë/ľľúuďם;mîą?Ě›9oÉĽOć}?źš/żb~ţüÇ V-8µŕ73}4Ř W/ýşŤ5zŘĘ;–Ł/ ˝‡˛éëüx:1–´˝‘”č›!PB+é_ÚP’cÎ+ ÂŘĐÂé]R"3EŤÄ¨RgRJX@Žia’°R¨=ťNzÖÖGO Ó»2z./?§(«P …jĘ"›Nă•F©a¨…ôĘU—€ ¶‘§OV•´j¨F˛W„Ä$pÖŞĽ™‡NXHźĽ¤0DÁňk˙‹Űü$Şý»…ŹHC¶OBÎ#Q0îŇč$ěŹóčbJVrÎg”€¨u Q!Ť„üŔËźĘűA•Ř,­Y Y|+ş $ݧW¨żG"ČB«ůh%ň\őzjšWv]c%]s @5°Xj;á¸˙ rhő©jHHÔ‡e¦]f3Vňpľş(`yŔz>|î»ţĐVň^.6ě-`UvŇO;•V{Č~SźŻ‡äLîârl'ע$ꤖčŔ6jĚ…Ű´ZÇtŠ®„ź’ÁíĘζŽŰIp $ôH#ëe%űʆK+‹j*)®¤¶ĘŇŮ; N^5‚¶ סĎxßÁÔ5~ý’Ľ>ČyđŚ;¤H8ž˛P>šÂ음ĂWi*´8\ $Żú®ÚtŘ™§Kß@Żj`5~ÍźŰÁ:€‡f¬X‚„höWo@{h˙íߡÎ|ëôŞH+ĺ=ąĽ˝†ŘÇvo=\Ó'’'~nSßśşv[Č$Â:jgcÁ›ĎíFÝ™dH•śáĚň úÔ¤d5š‡âřhŚŃ•ËA±T [˛sA(΢¬¨UIžÎ0k~DŻĂ™Čʶ“`µ^ż" ů˛•\•­)÷)x„‹`ÜŐżŐUťʱf€ţą‡…Ńg7JЇyÉ0ŽÇ1Ć%&Ĺd ÎQçű”y뀣ä€ÇÎâĺM˛֜u»˛ďKń˛ÁWS ŰśöF:3p·ty I>ĐŽ‚{ż‚/Ŕ—†ă‚z„-©u…ن"ËU 0RßBOżb˙áűl&7µ~ŤWe…€j3鏊ĆBIpD§s1RÜ7T0•ä« ·fi‹Á»\I¶‡×čű_üN† ŕË;?[ěîăé/z@ł=ăBµ*\Ľ•×t±cđŢĐD!;ź­;Žşu4 §ÓtŃźt±čŰЉ§r×ÇĹÇĘcü5n€BEÚ‰ţ;Ű2VMĆŁ-ě:NáP­Ľ˛şń¤ů>-š3¶wěďl5}•¬Něń¬ýŽŇ_žÓČšÉÍú˛x`G’vK*Ć›v’ż¶^»xýrçgŕ;đyäCŹ »o!Vz źXÍáÎQ’Ź …ÉÎ\ÉóV^sqAďłë‰a§…={×DôâńµëŹzEą&­TPĺxÍšrčv•¶o°ŻyźĚäŞá˝‰çWYxďüĘ4ÍGö7V}=rˇîô€ábqOP;a»†TPg&=JR @EŁ#·ŁOx@ž¦Ő§Ä*Ă“$@dEń¶Ć¸ëŕŽňą{OŻ5‡ďŹöö÷ÂÂ.ěôĎgrô×pOĘńFD€Í”Śăó ¦ÔśŚbPNA—“‹¶Ô‘ކjÇpý‰3^ŇphvZYż=‡źŰA1D<ĚśŕNqń¦Úf%ůŔP¬;ĆóşVź´‰Ékł•ÜšŻ-Ĺ„ŹĂ‹čČZˇ]ţÓ.č0É´’7˝ľ\c¶żýî¾͡ĺgx©?]ń ~‹V‘ÜVy-˝DĽ)”DiŞFŁ“ĹJ’"u"˘­OÄ-‡ŹĐňtşY ü(”Gn<íu·ł»¬ľ^ŘßĎv$ąÎąglĹgͦx¬Ł“­,HbI†±¶j“Ö¦Oôäu9‰fpwÜÜ»ćŇ'ąŘÜ3JňéDËŶjlôF‹ŽĆ±G"5§%ݢJ ĎЧéˇţXh4§›A!nRŦöĘ‚ĽÔdW†I?8NE=ülcŽ!'%?!?%äS©Ąľ ďńo曚rZĐtŃ˙…ms¶5Ógxŕnqńă|lEŹ’üضť "Ź%ĹEkڵˇľ=±,óN¬BŘ9‰«wŕ+"Ľ†ŢĆŞÉ6C‘¨€Ú(×ÉV˘ţZ¨P J ŞŘtĘ„ÍôW“ťi%:›§IiRć'¬@ľüEĐśV”QŠ ˛¤ -?µGMVg諼ŕlô ż$˛@“ň@AiIîEţHgÎ5ć ä–ő` đż˘/'φŹŔ©vŃ_rˇů5ö?‹Ď䞤Ţŕ©4I©j@) ćÄŕNmT×ÄvX]µl›ŹłÂ_]Si«ĘÍĚË4‰2 3 €‰Şo©ęŞŹň$ŃňŞ”qlĽ& „S\/ç˙«˝•ĂW…ÜŇ#yq˝łŰ°ýí]x ˝…©^’š—$×H“ă*mëĺâ"ëí€Ó¨ -Â`ăĺçvôĘŃ™Ľ’Ě" š2JR@4–hÓďd·‘~»•ÜÄ(Đ»ńÂĂ“»Ou ?<ł MGvľű×9V]űŻĆÚM˙4Ńkdôp;O%Ö(ÔŞĐ Ž€ÚĂŮ®ÍoŃ‘$¸m6?ĘĂAo˙÷ćČÍű˝=ş(évň4ÜÎ (ę }—€”©ŐٸVË’Ó2ŤéŃbÔHo4§•ŽËI‹©?踆¬K+ר eňsR,‘ Ţe!ŚtW+śU‘ščXĄAr¶>OiRĺŞ0făăĺá-1}ďźľçźÁĺôŇҖ⢚ő;4»‘UűŔŽž Wđ|w†Č±ĚZ±˙#Hţ|áöăŽR]p‘(?¶@Z‘P uUÖę‹;O­őńŠ9.ňö—î)4ăŃrhw˛§¬ąCX_ó}™šţŹi˙B(k€®Ŕ‚ůúŢ7Ć]Ňîp“Ýž‡›ěĺŢ.-˝Ç`Ô—DŃcŮ(‘Îf#%çăÔŇ$†I“`ľFéhÄď%1ÍYU ~˘č…$Ě;Ĺ6s° ‰žŐĢ߳y ązoc˘V%Ш’˝pçr`ý&Ű‚~$ÓŃ‹ě Ná]‹ĺ ÖŠB˛Ž˝‰µâ´qzeô‹ ¬úg0ţ‰üNĎ ‡ŮedBfHTH fyú=,?|Uˇúý*A"Y• ŐY¨?.B+Hq‹¬8źG.ÇcŮ\ôꇫᤋ]¶Sm˘ýľ'!IŻKŹŃGĘŃă#řdÝ»nčča†u¶d&`öLŔŢ`8‡Öńčj\)ę´–š‹Ěą] Ë')É®tsš%٦) (ô99ĆŁ•l´EÉé攞ŁÔŘ’ëőź6‡ä–ŇqȬ߂Q-ě`ŃKˇ#ĎwK@Ô~ŕŁ.%tZ3®Rđ*'ĺşľ1¦%˛ĂŻňđGÄaGŹËśŔ:Ň;k ů͇—!Ń'DáR^ńöΫŕ*¨‘–®fčIÓA˙źVÖ$›!ÇţsÔ‘‡ÜŃ,vý–µ¬8ď*qţěÄßpĽáčý~zęqEä|kmÇęÉ`0ˇ#âĽOó2€¦í®ř#É1Ş…"4ôXÂaŕŽU„6 ˙ Ď0ŕyĂw}§¨îţˇŞ €šĐś [``ëgśĆkLU˝„Ĺǵą«Ň¬ŹŞ–E—čËUm­¨îđŻ;tŕ°Ě/Zíź’ąZń1zź¶ë’v0óy©wZ]1ř‚ďĂéä„â¬ęgqâÇç0‘'$đŕŐe”gÖ‡ŕ|QÍ•–Ž«ŕčÓtÉV7,è(çpË1¤é—%)ú-†‰JŘŁfş9WBÇM®7™ęáěkGç/vńFdĽ&+[!g‰KđmśY Ă»óX ŔÄő vt8Íçuo&ăń,oŠ-ŕËŠdy¸Ń.ß¶c…s˝řF¸H™ 2¦†Giăqg+IęŤw:" ÁÔá‡ţß|ř°®oXŘŐ\ŢşŔµŁ}Űr/ź8;¦”[k{}Aa¦)3X3J3óA'č±4×·6XÚÁĐZ­iˇalŻŐđ‘qP_´jC\·ś@ě·]ŞMĄ}gDyđ+Ţĺ†öÁć:Ud™°"´Äś ÜŁBý^˙–Ń®ŁŻţ‰’QWô6qr6 ¬˙őfiGů`Ď˝]_ŚO©~hśŹ4!˙7›Ö]Ţ/ěl‰ż-?ĺÁżąN €o žLń¨ťĎAźŹŽđúÁ ˛]rŢ·e @l°(jA_đń# ŕ üËCZźŠřŔŔ·Ťß÷öśŞÔÄőÎěó¬»OŕA ž•đ[^ß`Sy7 ÎÔ†ě!ěÖk]Ť÷;žEĆp‹‚ľäŻç×»Ęů á%25',)&Ĺ=Q cNnV–TAJ€h,HĆd×üľÄBşćëKđűă7)ôĎ ¤ž?‡ZRFZyâśř˘¨6tćóß/m*i­o©łöS _ŰÝ(îu¬c`ŐČážT’¦é~oěú¤­LÝ7áşĎĂšO1ŢäĹlŚ®˛á×kĚ—~Ćk(.诌,óŽ Q ý˘CŤK2őŽýźbi·ÁiĎí>‹Ü_áćÖä-¶^IviV!ÔŚŹpjěĐëv1…˘·{óRŠÓ ÉĄ˝`O¦PHĄUІĆęŞĆEužĎi:bm4ę łŮß~5?1ÚSC'MˇÓ©đÄŰUĹm5DĚţŞđ¨PIB 86 ¸ĂÉ.wÄĂÇkĹ…ÚĽ8 §öxűm_ĺ|N÷*8M(”]Ĺá:[łJĚ–ŮxŞMłđNꮞ”žŮüěŃĎ{\Güۢą#ŕeH»°9Â]ć‚ÇBě>Šjť<îý—ăŢ=i?^jŽ‹B¬uIŔśź—eɶdAuˇ 'ô%lIŹŃĹőš P˝IU™P­)LÄM7AŃŁ8']ľ犸?yŤnůOAÁŞ‚ţľŹMXJ›F ŢX: ŢŃé™.y+ý\M)Łô ΓŞŞŃ$ކc„›ŮcW9F´™]Ă©¬j+śü;~-¬ŹńŔ=jÇù¦R­EZ_ŃX ޤ§ď`n­…ŚĎ ĘƤÓ.€Î$t@‡rҲӳÓsŇú#HĄ’“ŤIBĄFY8ţ9kŕY´ ć7Ößľqm°±@`É5gc-°  §;ł8 «ş”dŤ& ˝†¦óiG2-[ś•âš(La.a4ô¨•őËsřĎ;Ň%<đĽ¤ěă"ÜĐÔŚ,-‹ )„›Ýn81Rć»_˛8źŮ©„C'sźtw|.ű™Ë:”䣉]'ѶÇëŕfČú°ýf·°¦Żp<€1ëű'vV|NqVInÓ-EšŁ˘±hxj´Î©8 : éś›T.Pô×ŘŢ#*±~—J0ŢŠG§ŮXŁ;ľ@%çBz…HA˘A–‰ŽŮńŃřEřÝ”j`«ąąă+Î23w|V%9”aÖôŻ‚™c| ĆĐ#­ŹŠ‹OcĄ5jĹąymőě tfţŘY鹼Ҝćö¸®0ŃW„ňŰÔî™Ř¶ y8[] ş)ŘN‚ě‚"“©¶şżĽPUˇ°Ät×éÜŇSXH·,u9¸FÁ<˛©żµbP—*dŽ"B·”W~Hj!Łł#łµ [Ź“đĹW6»zE»z .…Ő{ Ő8:S’†l/eÎC-ţ§‰8üĂ‘‰VcgSqd έ—˘WĐ—|ć_gä%Weć’+ŤVP jŞ‹Î3q°)ÉK™EÉmZ×ńP;šOO5T¤Ť_ŠV™Mgsđ#JňlŞ%ˇsôkcBµśŢWŹm`[8Oˇą¨˛ŕ)ëpqṢńy¶“ľôG?°{éŹxĐ‹SrłsL]źń“Mę8}j 1±˵L!HÍM/hé1h{… >w,˘–Üş)^eŞŠFT+ŠđTĄIŠź’řäNýŮ3˘Á“•—Ŕ}pG9č}ĆŔ­˝X‰Ovˇoý‚3şˇg·Ý%z'ďýÖ“WÁęLh÷±Pą",˘JŮ™oĘĘĘš˛Č‘oL‰{‹ Qůżxšń±ž<Čjű ć~nG»ŤnĹ˝PďŞÜî…Í.Đ,°şţí~ď.˙óňkX9˝üě<·ľşý1"ýă bgQ=\‚§[®¬ŁĐqÔÍ{vfNÓ¤wľíů5|ëlAÍ"Ş,k.lgŠ}÷‹öÄŮăp\ĐÂň”ţ›Ą€FrĎŘWěë::—Ť%Uňoô şB'ŢIš‹ë©Ăʆ°đřČŁŠÂuĹ;„…‡ňÝ€ľi/R!—DVĹ6µTW55Ék#'ÜťŢ`ńţÎ{PzËă>nr°ź&y?śkď7©Źw\YXë÷¬ŘgŤúő-!÷3D¬‹•ěžµřŃnȆSÜřůAŘšöą0a>ďŕNí;vl߯‘Oß«ę9%ä>zŔ[52.R#'{ß˝ŮďżËMzĚM,LM -»Ľ”Ţ3XpŢÁ3ő”Ý/ĽUĘ …\™ H´ĽYľRÍřż¬` ľźžÜŔjúŇîr,N.˝`˝9ôËý«đegSpÝ[đÄCSV˝fŁéwÖCâB_Yď9áq´Ů9 ĄŃĽ Gy >-Y—,•kCµĹ÷C8ĺRŮ•Ę:Qą­¶¸Pźž\6ŠĆjčuÎş÷áŃ0Öđrlpű× ‹9MđŰ•‰Ž±‘€Ó<ţEÂ|yŃNâġYlDyüĆ Gö§JŘp^gľ43_X$„®ĽxćąYśJĽ'¦K´YĐŽçĐţĽČhITmLcs]mcst]¤ˇÉů ›8|ď,ÝŮŃ›čt´#Ă,k‹¨wĂśIg49<:LŔѲОŕFi•úv…ÚÉeY‡OÉĄÔhçJpźîI:µşíSň^IsIGckµśm)I¶^™ Mű€‚™äýÉŔňw(´w9Ďńb|-ÚÚn™©vôď+×J8ö†oR3Ěo´%ţ3ˇťých—Ô=“»ç7ô:ďV[˙•?ę06LČM˙ŁąˇŮ&\Śł˙¬Ĺ.ú!Ź+ű«ËŁ÷´6C,i+kˇµ5MF›ýŐű0¦öú}]7“ëűtt%4b; Đ+›N{Ý9ŮYÖŢ.:wľő1xHÝwďš"x]-!ţn1»ĹGEAQ*Ś‚ş®s w‹ę{*š?çťŕxz©€  0Ém·íiU´6O2qĐÄÝyÎíz˙I[{«hř\Ë#p3JR+* éŤ`Ô™zŞŃ/˙äđOs¸óžţDŹňňăsÔ@C!ö:D®•×vôŮnÖźrŮOĎ7vµ5ĎÎŮ™ů©fmIjc ®”«zŚşV=ď9ćÝiü—Ť?ć!{/‰™vřČmú“űľ/o>‚+ĎĺBÉLîŮQ_z3Iâ8gRÍz džűßqżqÖ˙ŮÍ–Úň†ćĘęŇvĐJÝv?łqÍîÝkÄő[…âŘ×z9µ‚Ą×ÝţţřJ퍅\íľw‡˘Gfż.ő5ÝVó#‚bqµ¸#Í~W.×v6źŻä×ôÚJÎäScłŠy‘ďę»ŔIętsŰŕ`[Ź{hŔ:!׺k;ď â´{\Úér4kHj§Ë{Ţkî˙ô"FďU8őśuE7Ó3xcY{é,š5yâ&ĽqÖßÝm÷÷˙@ůŐĘŽżx¸4dśÄ]čťżŔ)6V˙xĂ€oaq»'üŘApňjźlŻ©nkQXCچĚLŁĐp§˘RŚů­ ç;EPný_<=‘Ą=ŹÎ*ö śüß’vDîcř/CŰŁóm¬ÓĎěŕilĆ6ßČč`?§Őˇ z nç›[Đë[;QRĆßđ®´]öˇü}Ý}đ#řµôăúk ך:îŚ0ă4=pžULĎó„ďťgîFS~?ŰŕÎ&ÖÍł×kţҦCG^ńűĺ=ť§/`®l*í˝ Kۡ¨mw©öÔ[;8•Ç6×”—׍%ęrQ’9µP-MCWNŢă§ő{Ąű•>zźLAŃ>¦…DDýŢBbj±Ržđú>łëB;y÷N7ŐuŢţ´}|ŠŻ÷öóă§Ł«Ž´$%ň?r®mŘZł§x XćieĄÎ‘!;\™ľ7ľ‰ŃjŤ´'/K•gŚŇ† i* ŁâËTÖĘ ke~zij©PŰnčÂĚDšŇ«’+ęõ’ň¤ @Uš-Uuęb“čD~DItYJ¨Áj0uĺ—ZŞZ]§ViĄraLdLll’!Ť_G‚šü†âć|kn(¦*ËâăŐęř¤Ü„ü8aQxžČ(-)®T–…wÄ×$ŕ B©NŚ—Ű4§“Eť†&˝U[lŕŹI4ú%KQ%*Ö¬­*+Ěł– [óň LE…¦Ľö*&ghEíha-ëo÷íŕ0šÉ[Ă O,oŤ®&›KK[„ź×˘^†! !ÜgŽŢ`Áěv0vót/”"Ů (ŇH e{9ĚĄ‡…~ŁUo>µö?<‡đ\t˝™^Ă»‰îsŔ~ťÖ=+L™…tĎŐš±š†?#żÍK?,B匠O>úŻĺ<])xŹ‚TęěswiZ›{Ôŕ•4­ě瀜ćĽrswÓIЬښ0«¬”ą«©´”Wőy7lŢâí"Š<® 6n v1›Ć6*´±’1Ŕˇňź»Ř79(atĆ~Óěá Ü>Áŕ±[ůgsţgđya śu/ŁŢţ§'Đűü] ýďşÁÇŚ1šd˝Aź•ń/žŻ)üş OIŕŁN<ÂHó 陫/Ăý™šť’©KK2 ”ÉšÔd ô9ę<Š{´X•/ź}řÉĄ'"ô'Ňަś8đëČeóK噪’Y…+‘ZK“«g›°ěÍËű·ĂM÷íÚpŽc`ČčeóŚl-S…Šţąš”h´!~~—Ő 3íşaĎfľKţqéloţáÇfrĎý˙ą{ć®@ďÂCĽ…"ZZ[ßP]U_ݍ–Š ďŚżüĆČ/ż!Ě™ěC§‘8ż:\ĹŻüřW±Â8÷Ęó/ďĚXş7ůH`ĂĆ ă8aiݨ}«ć[Xú-3z;ň<@ *8ÔŐ]ŚČq’dµ˘Nąwúź•Ź€ł żĽŁ}äB¤śFÁŔđu4SÍ{r±‘‰ýÖ¬ń˙ ž€ˇ'ˇÝ3ŃÄ0~Î|ź†Ix€ąÝł‚­!KňŠssł+Lĺąx8Ż,TG›ńđEb˛:Y“Č €ŤrcVb8Í@‡Ůę>]}ŹżxfGKákÜü`&÷+Zy hWzĚ•˝¶ˇ $÷§pĂsÚó8ĐżeOʷчmĐĂĆizń锦‚©SźVLťF˙ Ëóm± endstream endobj 332 0 obj <> endobj 953 0 obj <>stream xśť–ypTיşĽľ,@§‡–ĺy/;¶gŚĂę`ŁšŘ¤1B–,h´Łµ[˝ďűv{ß÷E­µ%B „‘A¬–1űâ%ŕL(W&3OĎÜÎ<§2Ż1„Şü7S·ÔU­ęŞwŢążď|§›;+((˙nŮ–ęŐ«V­Ęy6W<'÷t!¤ÄąoţT8.*„‹ćfž^˛aŞXŠ%hî±9˙°zSg{—€ßŔűqyg}ŻăÇŐ’®Ż%˙ź-|N[KÝßüĂ0vGgŻ›/ŕě—ÔŐ745·T·¶µ˙´vÍZ «ŔŢÁ*±w±jl;¶{Ű„˝‡mĆJ±2ě-l ö6ö ¶+ǶaK°70&ö#¬VŽ1°ł˙XpgNíś˙)ĚĚĺĚó’ř^üĂÇř Ě{ţźčV-Ľ˛¨oŃ­,ůÁÄâ-™łč>¶řá§•˘}3ąuW Q<Çd©¶%ŔÍ÷šz§Ő`1@$MŃAG<í&<ýÁ“16ˇ†´H ٤‚2°-z‹ęl’°"' <M‘üęÔĺDoßA2>±`gÇ&q©ĺ޸°Ô7żrüúL„°»mnčQu@¸×ű~}7ˇW©¤rô·w šőő“‰s™_‹ Ŕ0ť®«;a˝ Ą<’>“[**@ĚkH{­}›Ű¢Šä+©ç!5”\ńßDGěŕô˘ë ¸Óřŕâ&µĄ_·gĹęvťEkŐB°K|ń`¸nąűËńX ĺKBŕĆŹ“µöúGʎ¸3ąáŮ‚Ü[× PëX{pˇF&E´i­Ĺ3á`"¦ ÉřIT“âfYX„žú•sµő˵µÍ\îR5Ň’hŕőşgöuÓ^¸ă'I{y" AŘ-Së-:‹Ô·éZumë¨ßłM2“Ü,čëÜ&–ţő: Ťo˛Ň‚ĺ©ĂźN 97‘^§ßé‡ŕPxW“ę­ň{µQ!ŠŁRj=Z_>»Ś9Ť.ä–°´‡jÓŤđ°­BşË¤2(ˇđhÓuF€gŠ#AĄDGkĐ“Ő×ČWµCQ‘4&ŹNŘ?9 ˘łńŮÁó=“٧.Ŕ4<¦łË€•µJ”fJöŤ$†˛·7ôo«áÇ—nÎ,˕̖ß[ÎümşËňůÝ!˝˘° Ev ëT ş4uĘÓŚ8Ňsđ< ü bP%âÚAť[ç~`gx/ÜńŹÁ ŚSZ#} t')‚yuFúm˝ŕó—ý»Ţ\ݵRNXŤV4BĄKîVO– 0<Íńé=Z¨Ą+Ä5ŤŽxóiźĚ  ť ÚŕÂy*ĄXR¤Ý.t“—qWĎ3p›¨çŘF±Al3ŁňtÓôgW.}g_ŃŻpp«‚T8ś©‚|r=n»ÂŽpâ6Űt…`$Ą!Y·ZÂ3ÜgĚJ“ʢ,ú«Đ}¨¬­ąV›;Ć tŚ(†ŕeŘóqř¤#ofô ˛6‹@l$ \ĺn ´@3´ŘMN¶Ń˝Đk‹»®řE¤bŰźµąěnč=|‡‚`NVőRŚ=Ĺ C$Dşö¤'éJžF l‡Ďáłů@BËZąŕ%ʼnz¨âjëło Żű’ôâŽáL¶ !ţ˙c`rKg>S€žľŠ¸× ‘0w’eQ›UfuĄek8Ş}p(;Ľîw>˝5K$Ž'áqp»á×+šëä‚NÂ˙AčDđ„g€msŰ]tšeşť2✯PŠĹaMŠDęK·łîź›uć|ěÔ@ůë8üő©oď y^»>ßŃ ‡«ţ‘,JLŰ÷ł™|Ä-CŻ-gNćć'XʲJ ĽPî6FC^OFSśGŤňćÎŞ“śł˙őé|5BzF}Ł×ŃŰqEěz”â´]:!×@(ßă=ßJ•˝‹ęTCg{Î$N“ţľ@/Ćśáýß~u«‘03Äamšţ”›đ¦‘PŇăa{\/mbŔĄUqEuęvR¶Oö>|lřpĎ'CľHćńĺ„„huů¬•V˙÷´úPnńĂ|VPĹ‚ÔrXŮSq©e@1dÉÂkđ–űܤĎăő ŚKăR;°ŕr¨QŞtśŽw 5T4M] ™_}†–|é׫ujŤEE0g:"’ľŃČp˙ĺmĂU3d4ZŤĹŹáËiglôĂ—^{ČŢ݇ľÖęeAş+~QO—PU?)}í7Łý˝Y2Ň:Hcy|>Gc颱L‹\ŇďgKĎSżÇ‡@aŚĽvźÝC",Węą#¶ps2! ć]=ŤTńF\"Ń ¤AeŠP#˙g łč©´”f‘¸Ž4ôRk@U¬ÓřŃKQÄś­>VFS éż§Vťy-¸r×=1Mú˝«qq\˘0hujb÷¦íÔîH< ă˙Ę:řŃéŹď@Đ—Uxb6?á •ä° 7˙0«ëŐsJˇĚ&µŮܶüűgřaQ§ŰµížéĆă‹;“®Äć^¤Ă‹N HČŁ©D%¶ÝM±Fz.‹VP«©Ą¤ŠáŘ<µů38F˛)piYú’ÝÔâ—Ôۡü´őříMÄĽO¸đqS¬ÖŢüx§Ď˘§1÷<ýúíôť™ĄF‰QJÍů®śmÖ5PL »$ŞŽÂčθ#há8ęD?‚`Ř+ŕm®Y)/%­FzŔîŃĆ7&o^ŚÓEN7 i‚J;ŕő&7UX ×Ů-tNÂáÔX`$:•ś†SŕNÍpĺţf9ż…pÄ\Qgl-řëhóéŃ^…‹ejˇ(ŞŤ?I?‹R˘ü¶ť !/Óď¨n5çK‘Âşt¦R>"22xôˇV*–µi¤lżtżŚŁ¨…–nPůAË)‡äš:ŢwÚô'aÄ•~a»E)1Zˇ˘Łłą)ŢX*:čë!ŁG"ôńĄC{xßÚEümbńͱ…OŻ,AR’îK÷ôĚTZ’Ěi‹Ůjy4¶™‰Vn›YĆLˇ^ÚäßâÔâďójp‘R!‡4t·Y§bžLJáă“­8ZśSĚű 7 µb‹Ěi:RÎXÜEÄ®Ű.—˘Ţn»Ś îâÝĐ 3JĹ?g?ęŹü”)Ň=´gÜ“°'Ŕ“čťEóhÜ…ß_´Ô”żč_°Íj“ Şl’¨2űˇ·Ç™E$Űć„n—řđńËŇąAĺdĺ‡ Ó„ż`;—r=QzbŞ€k44Şm‡´¶ ©2ޏé¨$áĄíŮ]ˇłSgî]s=ĘTĐ 6čR%ŚłÄ3:B7‘#Ňńšç*©Ĺ;_%R·cww˘—ŘvŻ#}Ŕ۵>•P…¸X`n—úŐiňńşŢ†JsKhS÷ˇĎóKDaT?ýŽ‘/t2ş-•Ţâťľ5vó|:ĎcľE8ć°ÚŻ€@‹€«Ń…ŞS-ć(ć·…zĽŽ|—@tó´ű\č/ŕŰ%őw¸T`×=O Ü–‡0·ý|Őżuś_Î<Šr/˛L]P[ˇuŻ®“ű,ŰŔÓňt> endobj 954 0 obj <>stream xśťxw|מďGň‰…°\II!tBB€K'tc0î&ŰÂ’,«XŐęýH˛š›$[˛q·±M1Ĺ`J0Z˝¤@BBîÍÍnĘ&÷Ś3ľűŢěŰěľ÷ßűčc{Fgć”_ůS°†a %u=_#—¦ ×Ď];5ťW _%Ë$†&c)ĸaÄ_’Č·ÉÜ?ŘĹT‚ý2^N/żÇţ"e°ĺµÁi#‰ź_}>™‡ŇE93 ›‘ľőťÉ“§,-«$ü‚BwćÜąsą9*îŽp—ń¤üwş(ĺ ŠĹBžH6Ť»‰ÇăĘ yÜ|ľ€Ç]ş!mŰŞő+ąW®Ďŕ®ä‰x’l7Mž#ŕçr×ňsy")ďn~±„+x~ĂÍ-ĺńeüb‘tw±”›Í•Šyą|ôO™Ë'¦pĹ<‰/•˘k._Ę-d‹dĽ<®¬Ëĺ äy‰ĺŃ÷ůĹ"W,)FăB4‚¦J+–ʤąľXĆE+¦-[ń|ʞÂlYb]) s‹óŃ“yĹąňÄiţkL–ÍIą2žR–X'‡ÇÍăKĹ‚lZM%–đźmA.ĺ‹ ţ\} WÂ+Č–ä xŇgó&˘ňçů¸˙íÔŮb±@őěÝâgOý×ú|™”'Čźö<»\”Ţle»–›H± [ÂM¤™źű˙>đgÚţ˙‰aŘüŢâĄâeË%+¤+eňUĄŠleŽ*w]/?­ 0ťżiďć˘ ÁáÖ÷g0çŤyăß^8iGŇ®©ÓöLź1óÝYö¶KĂĆc±·° Ř&ěml36ËŔ¶`“°­X&¶ۆ-Ŷc˰iŘrl¶›‰}„­Âfa«±÷°5ŘűŘZl6¶ű[ŹÍÁFc©caIŘXŚŠá{ ›Ź‰°…Řl$¶{{ KÁčŘ(l*bě,űŤ˛†r`Řöaw“J’nĽ°ĺ…GTő ­”Ö—üNň—xéđńĂ^ś÷bčĄq/ť|™ýrË+ÓF`##ÇŤ¬|ő˝W{^ŁľćLII¤ôÓ-ٍŁrFÝőŚăÖč”Ń˝Łź¦ŇRżf2YŁX«Y{X*–‹Ő8fŘś1çĆ®Ţ1ÓMŚŽQO"Śtź5¨»=•¸Ě,ˇ‘G†óI–Ńkfiŕ†Hr¦Ď썠Ίî€T&ÓbdŞŰä63 đĘLk¬¸ş’‡X0Ě€“`őQ˛š:‚púŕo§Rࡻ®/R鏉,8śQZ"ĘWiĘËlÔśă Ŕ*ý3_ĽĽľfL·¸1oÍÚ ä{ăŮźB‘Ă“a(µż§ai’OąŞ­@¬.«Ë6™ü•y—Öß Ő˝~ńűSý=‡ *˝uŻYŔŮCÎĄŇë2eĆ1ĽM籦ř÷ź±Ńn qbZśŇü6=J‚u r9‘śNÎ|˙\ĆÓkWÚÎs®]=ôÜĹżÚ80›­/eiÉO_˛÷í=«9ů[x’,€ďt|§őÉÉ›śçzŰŽ|ÄŕtŐ1â§nĘ5řBŇ —ŕ1zŕj)ͬ1ZŔ ôžRßîĘ\ŔI>™Aî"%äT‘śúëçGűŽŁ®™9kŁp.`‘IkîA|é|ĺÁś'/·\ßS$†'6_GĚŚ)c)‹`6ô|—JżŽČh ŕnwµżI ´ŔT@ľQH2ĹoK§XD†]:}– Ą%;śĽSŠ×DÄîpuµö€Ă pśg=ŘÓ·lőŽ˘y9­?yC¸Ü.Ëé¦Ňç¸]°é÷ť.ršś #(Îş°¬˝źµ.;m‡`+Ŕ‹áúýÝ0µő§ůúů“ýŽ|ĐF|×F1C6±&%ÁŃŻ1.YĂf Z»Ô"!G­gŞ6Z¬›Śhoţd8üŁýţąoŔaâ8śCŇ~#W°Év\“Ćđׇ‡Ŕč×uHO4Żó‰e“/¬\™¶ažđM€ďRV6UűęŁ9‰Šî$uR\ť48bđuĆUCűϵ ÖB›ęŮÚętł%±6Qž| ÎÖw®))ÉR°ňŐ+Ť‹ľIZ±Ż˛˛Żń §úh¨łâ@—łÝUş[¬•FźÍcj vęlňŤyjUĺĽŮ&ë ;KŠ\…®k°ŚéŻŻ,?‡<łK·AçŇşÔś¸µ Ä·břĘčÓpaôČń{ťçZÚŁŔ|vź1¨ÚboŤÖ¶·+ăĹ2±V\ÂÉÉÎMÓä–0Ď@ˇĂłDgr.ŃłÔÉű|^x}µQU€f%gyŚú¬™‰;)¬Ä±mÚUk•PČ%éóo°XÓÍ(äľHňFŻŞ´ 7쯿ĄĚg˝«WČ6t¨Ď4N˝Uµ1ďAťĘ·{¦ĂEÎw˛Đůü±˙aŔ‚ó»uë¬ŔćŇq\VŕréăN&:¤.¦ŠSP™BĘíă÷Réîn8ˇ gQ#´`Äď«• ÖłátĄ>ęŚ}tń콥Gwžçđú4í ďŚÇ»N·ĺ/¨`Ghôq1ȡ–ŃĚef{°ŁGéCo%ZŹfě’YĹłz383Ł…@„ďíŮ,8ü†ŤŠPŐC î§ś†Ă`¬KĚśÄĐ–«Ąjc `Ţ+l‹dsPS›Éť¤xeëňľśS™·Ĺ߀'ŕVÝý#'áfä\¤ęj9!ë4ÉU®jg9čtDŚ@äÖbůbůR‡YŻ—ËyúÝh"Ć’;0Ž< éqŽő]jľ®‚ŹĹm»"%RßžZsl7ś„tPŕIbăCZËŻnO˘}Y‡×fu¸ĚVv^ćşmE&‰ŮbŕN·żC[J¶8M.‡ĂÄ2 Í…ŔŚËăšćăť-˝ĚÖ¶ŻŐh4€e˛«Ü Ľś'đkę#Z1ÎdöôXJď}¸đA*=“ČFđ»uµ¶Lp‹Ý_é îç!w‹§ÂŕUĄW˝îť_>‹éÉóCh/ŃĆîĎ|•±®¶3ßÂĚVň–Gěq+**š;Ýîr_ąŽÜ)ŕ Ţ&ŻJŃÎt>sDËŽhý¨:A?L%?(‚ż1éi•NŻŐćpšmlT©Ž†ß 7Xô— Π~,*‡În°Kí{mv`tęťĎ¸âäŽ1=–}3o§ŇŹypC«µÚ,fˇ@g4Ülőb˝đ_úŕ"Ž·Âíń„,^ćz‹ĂaŘaîĹł1ÉiäňÝĺr®Ü8Ň _}ÂQ,pč€ĺTTĄo9ÔX÷ô›^M~o1ö;률|°Ť|qĹb©ŻĽPÖzüě_Ź\â:ß×qȑȝá<|zŽBL€I łÉf5éeB˝Ń`®jK‹3čň»Ľ’ź ÇAřčýŽ [•%ŕ <^ŽÇŐé^wÇđqŮuCL XrŔ7­WěĚríPȬFŕ7Őlh%G2ç’ĂB…ĘXV`ôýş€Ák¸R«U”Ä4míUˇOú9ÍńćŢómäËĚęĚjM8šöť˙îYWORćă$8l0•qÁéw909ôVąÓâ´¸lN “7ä¤Ú“e÷…çŕd8.…3olď˙hůÖrŘ2öih>˙Ĺćcn3X?2ă0ŹŚ3Ž4ďݲ*“›¶Ž“ĎË*E˛B ­l¸ŘöcďÎŃűÇś‰XsQ•Ź>”&Ć3Ş˝w%bÁ°ä8ą(şz9ńĆŞŃŞ9ŠľT®7ë€XĽ† ¶Ęŕ3\®VË%őĘÖ+”&Áíă\‡#[n“x›¤Q(ÓhĺÚ !¦c×&PróĚ&_W@ś©}˛ ÎŐÜNsąěŔL®ë#BzG™óY» NśŇö54ŢJ‚żţÎŘś–'ßđtţ‘›Ź»ľ=wÓÚv¨ö ŔÂf˝Íił›8ťÓL¸4\¶Ż9k:ľ»kR^\r9cĘŮÍ˝óqű˝‹´ď„3oj[ňs;Ň©ĺŠ*„)ĺMľ(|‘XÎüdč5J#^!Î“Śˇ˝š- íj ’´M‘ä•~“´¨§:Ôţ~.ú|B‰Ľ#;AŚŠĄ„żë‡)‰\TŻë &5ŔŤćPeMŃ ‡qšżŹ~ îDÉÝb(°" ¬NţŘp€R sYË2÷sć^U$‘Ăhr6™FNZv(ëęőŁ?]ç2ťZ ĂéŐ⨪±÷ôáۧŮôLrĽÁhs†• '§ĽI.šÎ—6üŞâ×n°[Z{ęZžgŕ1ŞŇţ T^K‚@ ciš@Ş(=żűlŘvpZĘá¤řď÷Ŕ׬^aÓ6r<9“śKNšwvÓ›÷zMŠŕtĆţoďÜ?•č+ŤL ,9ů…<ŐűĄ8˘)27N<ě€Ęz ůö§ÄĘĎ’ş.ă;Ú¬ˇ9rîŢÍŮ€Ą7B^·×ëă”űÝĺŔŹÇUŃŇRŤJĆďýöĆżÁµ‡Ů·ŕm*¤ĐüTŁµÂ™=7‘.ŞŮ,—ÓaăŘMN„µ¨*4ő uµő=ů-Ű·çÉw°…yŠ]ÂÉřtÚs‹r îoŁ®_“ŕ¤%,5&P‚ˇT·›|qhÁźÂĆI^˛yÁ~P婨č>3ŤÖ&çađ%ř4z¤˝ż§őcp˙ű˘3ä86é¦ÁeţxU ±Çc¬¬IU);ÁjŮ®=%užyj1ł[\ž¨2§>‰Ă-kęS‚w>€“/î}J˙B@ĽĂXOs›Çě×î­ŕˇ\'Í\8uk˝p „“–«R)ĐőueWŁë]řŠk»†)Ź.|syÇŃ)Ťě=•%ĆĂ MŐpyŮAgŤ+pú/O˙öĹ#fŤqúiô?ČűäS†‘ŻÇĺuU8"¶ß÷öŁé26ć.üpç+űüŃH»:Úۉ’ţ;śHŚeôÔIwę÷(ůyŽ@Î8OŢŇ÷ýŔçW9˙Ç™Qŕá‡ŢI Ś•z&K(Tą=Íiýˇî؇7ç­^¶Š|kľLl¶ů6ęň,,,mS2ŇHqÔř÷©€”!1 rąeV99v(„üŮ!8­z˙ˇON?Ľ~© ůłj˝ÎޏJĂŮLćę¶[@Ď*‰jšOu5ş˙™€ý ĺYń[q%ÂŘăUD•§§A'ó~´ł¦»ŁłaĘ1üŻ‹O‘cPö4´^«ĎUa Úüz¤”ô6©Eü\'¤!ť`BŐŕ$ŻZ| Tx«C]ç ŹyŐG’÷©p"Ť¬"ľGÉŻtü«ĂĽĹ×d’Żi îr)'!ŇúF fÄ('ď&A ¤1¤EłŃ VkźQ§9¨đ†uŕőÎá‡$í{Er…Xí7Ô©Ů5eţó”ČÄ[ ¸~`ŚQ„ީג‡–&sČMCč'ń˙iba îDŢ" P_ŻÚlňVJĽA)•ë´“Ç(eWď.—¬ĽzE´¨[Ń` ť¤@R67sz,Ć}Ú* 3«DeŮeζ¨uHŘ+"ęşh´2a7ﯩjŻ ůĽŻ×Ł`r›´,ߢpč‘+’‡5±†H´!č ZkŮÚ^{˝ëLŔÎěT6(šŠę¤Uć0’čŃh}şjO€Sě“´Áü:ć‘ćh /ŘW‚&Ľ^–ëĚvµ–ťąŮfϡrb‘S›˝ÍbÔૌ@3•\L#·ýs€ Óhčn­HŞóPáŔ÷çů›ŞB­  dV#\x u@iĚPźBľţ)A˝›J/%^BŔĚsäłůdŞn-ăÂ:Ekoűľ/.°5ˇÝ[•ę2dłm>?Ç]ńŻÄ´“0¸Y>gąĂ‰äľŤŤĚšKkčđ,Đ{Ę<8˝«\!őŞÇn›$yŮY;Ks„ń4kő[š.ÍaWî%× H–x™ĂlE„¤S•Y”×ZË‘óđ$śâ<ŕĂcި\ˇQÉ :KŽ}wóg¸±—ýĽL t0|±n8ˇ˙Ú-ŔŞŹ N—ĂaçŘĚ 2ĘvŹĹk-·x¬ČG:äxęź!«#S1.¦ÁmTr# Ý Đ:˘&•¸€%ß˙ç<‹Čd˘ÁŻáćËŘ ˛V¶– Ĺ´Đ‹ČôËźÂçÝ×ŇŃ„şŻu_"ŔŻőSżýCŽmÉw 0Q ^śĆńĎEÔŰ4bÄŕ˘DuZZ“[(áŇIđosČĆM!•¤žd^™őă‘Ţp{/ç§;÷á<ÇăđÝ´&±-ĹŚłm»>$Çä’sÓßâđVĺđw<ٍ˙ńď§áŽÓßsşŻl?ú /Ax$îhŘÖж—VÔ‡ĘkŤOĐăO=ľIDĘĂžđ±Ęť^p—‹=_;Sĺf§ÁÉŇ&xÜa=P°€Ői´©Hö©Ď/5η<›˙±áń°Ż“ńĂn+Őe w”îŁÁÍč3ďč×X_vgF!Ϩ˛3‹Ĺ|ŃҸ…ŮsőHëE€ß<»uy©CiŐq¤»×®ZNć“2¦Âä~Č|žÄO˝)đáçb¤”?++Ś®ă]ń^€źéÎĎČ.-Ř#âd‹˛´ďjq$ÉAµ«ÉÓRÚąyţP`.(“Ęrwç")"«Ö‹âš*ŻbM™„w¸ôć@UăÎĂăýŹŔ·ŕ–čřGí¸7­ňJ_Wçő1·7śýpĹşÜ5{Ů#1bY îŠŃ^|đRCčĺ—1ěŇi endstream endobj 269 0 obj <> endobj 955 0 obj <>stream xś­zxŐşö„™ˇ¨í–@tEé˘ ‚ô¦”@ `(´ťěŢköŢk÷ŢKIH H?ˇŮA@"ŠôčQ±ËÚüĂą÷_łĹ{˙sĎýď˙?ŮOɬ™µľďýľ÷}ך,¬{7,++«ÇÂ7-znÔ¨Qě¦ó»ĄË60˘ôÖ[łr@ďlĐ»{Ýc/<‘›Î{®y}°ě¬¬ü!/L)/­ŕWóĚ.§W6`‘¸˘XČŰ€~óţR´vÆ—ž{éĄ1 [öZŮ’ÉĺS*–˝^9•÷FŐ´ęéü7¢™˘ŐłÄkfKŢ™SĽôáSąë8ŹqŹŚ~dwĐŁSíěëÍë™×ĐoX?g˙MýÓůŻćőŘéÇë¨ç¨˝ôxşmŔ€{žXüÄ·OžřŘ śAe>yę˧<VĺťÇ˙Jđ%˙+ő^Ă•wśd)ľč„úʵĚđŤĚČbfxŤX/2‰IÇrwÁůµ07ÇŠ×2ą»ů9w'ť‚©Ô˘T®ŽśÚuőĺ\€ăŇ\®ŹkB•Ô‹¸X¦ Â4áÓÔbśłS¨PH!u’†cđÚ°;—űDôbř ţç}ç® Ľł’b¤„@%“VGuq­,ň&"Š€]UŽ ţŚé^°LT˛žş7…Ő‚tGʂ–€ă:ą_ŔEß2‹r8_­*t oôůc |»”–á2` ÖxVť_{靏ŚN8I+ś§Őńś›gsŰ|@&đ„/i !CqŽCŻ·čóER•€ć$„AuŚ ŕS™Aá ^‡îMsq™ODqz˝Yź?—ńkŞĘâ5Q:„Ç@dY/ŽŻŤ‡*ň¬Fk ¨!M„IgĐuLSšWŁ1Ę(׸@ĄW$Ť!6Ű«śNł3?öĹŃCŁĘ˙·CA ¦rżč‚’®e(ć?‘îŕŢ–—‰®JäWŐŃP…o›-ŤľÎú]§Áp~Áą)>’“>R{¤ír˙o_<>‚bř8_%—d‚üým9 —‚¨9Ş%9?ď7®XŮĚ~»hdž€;¸°>@pP¤+§­lŘ$¤KE%` ďLĘ‚§˛Žźu]ŮĐ’žĹez©¦ H5ag˛®? {ŇŹĂ^Ţ ?_HQłG˙Čô$“ÇąŔnv;ůŃ‘«ąÔ1ĺu7Ą!^]>ôŞŐYpN{ĺîCÔ©´;•µŁ+;=2ý!w}óŠŘ2@Şpf¨z<30Oćń«ĚD8TOşńo~ývO*}UĹÎŇ*­Z¸ h! u8ó€k ľ&= CâěáYs\”}S@źdł=ĄáłDBđ%†»g*Spd žýéöűrľFHďÇu­‹Ź %ÚjaHŤ đĹÁŰŤé—˙ Ň‹đ¶ŤŰĹű ‰żţ‰__8Ó§°P\ş†vf6W÷Ú’×ĆrZáĺă~‹řiŕ3Łä©÷Ľw}ďsÓ  Ćlř iy*ëdlCaˇşńĘUĄkĘ‹Ć3=^a‰LOťRĄRŕ‘5RÁŁ K+ý3Ń$uŠD]Â5ę sz˘awóŽÍ».ĂW q ötů}^!šPĹÜÄĹš2úE˘ÚŻLĆ‚®íŹĹ—{µ F÷^ͱ’‰µ|š# Šł×ĺD=ŽŔ9"ZJ>ŐÇĂţ3ÎdFÓĚZ\ S …„[ÎŢ›ŠiůçĚí`ž4j C3ÝUôňpˇÓ,ĚÝqÖ˘'^M?t„Ë”,$Dr•Pę“Çhř&ŢŕóĹbJż€^>Ž7Ë\BˇL[N‰ Î7mV% ň™^Ăždz2YW™lřĐ‘˝µŰ¶ŃLeahG0Ľvöҵ33g»¨yÄäiłçLXüÁUő} †;Rpe*÷f|ôĂÝ]hofÖ]BđĄÔ"°­űę˝®ü4…G­î(ÔĽ‹ĽB$Uţj±ČP®·€Ĺ>ů°/ôf-Đ‘ĄQ}4qn¦n ¦da4‰ś±X_ŞCt §ľp%Î9ŤóđŇ!Vëó×S—‰dMd#u»Γkř™Šľo¶×™–z+•ŰNESő@ĽĹÝFÔ«•ó.’i‚€…Ţő&5çĽS­TŠ%~Y‚ćÔ;śG>\Š~ ›ĂůÍ1G#ͱDU~ĹŔ?ß»Á)N}Đ\řn~2ičX*ž>ż¤ đ·ŔöÚóŹ]°?ŠW_Îw?f˘µž¨FŃ(găń:– ”>=–Ŕ|üżŤ|tµĺN(’~’ú†ŕ|­‘ą¤ůśď;ęň™żăśOô:Ôľ/ iÎwü°¶–ş×´ćŔ7`8dvgîůڦúr"nĺ¶—ďUŁúĽţkó°/3LŃ客 h{/¸[¬ŕ±xA 8˘s­!9­•.ł´5żÉ‹Ń—‰¸*€¨Q¨ ÁRW1 Ç29ü!ĚKđňE0€63ŐđQ[[ ‚Ł$gS„JóKkÄbT]hŃĂIľ_«sĆŁ.ę^ŰϧŕŢTV{¬=źť~hWOݲ†HĚŃ@Á©"đÇjĹ.!Íd᨞‘ «•r±Ř§LĐpĂ‚Ęá“t$/C~üsü‹÷ŽŇÉxS¨ ś»ŢpÍło ™b¨ůŮb¨ů=“i~ŐŞ*ŽÚX·>± Fśř3šĹäźc^Oii/ľěoŮň{ď?›‚ łŕ°.řjDĂŇS¸Łđ*ĄR$ نř7&€»&/ú3 ?şşďí'Ĺv1_©¬¦tÄŠBţş…¶}TŔ±D4ikD•˧™Iźá™%Ő•Ý_z;YćC`şŃ×#(íľ‘RÁCÄIsď‘čŮírنsç2‚)bÓî¸Ě˧ĘÍ­geř{@ZŢ„ÇQ÷¦9[cň@5şáJźŹ*e+‚•.ź/S ąµµţ$ŐÄ2ëaa+Yâěbm4@wo€ ŕˇĚ°‚hŔ˝.buŰQX µ÷fç2&”Yř‘˛ĆŐ‡4űŔN°Ç×Ö@rDBDďÔ'hFž$šź^ŻăI}¨„šKř¦r±O‘¤1E8gďřĄóÖľăHQ°–H˘eÔËŁ4|¤Ć˘ôýě…(eÂL™‚‡T“Ě#›h؉'˝ÁHTéŻB=8-‡9x˝7 i‚R+Ít"}%—ýĘş»7‹ Ň=2*ěpš`çŹ1çsL8Áó9Í8sm\áăŃqNBÇFˇZĆVăaADŁęń °ČmŞč[yŤcÇ4żâ®ôV7҉GAÄą=VżÝ·ĺ‡öď[ż·y-Á ëńXÄZT".óŁśÎÔú`ś§P ďë™9eťEÓ±•ąĘeÍ̤<ß\óÂý`přZaž=l["¤+fű Ý%1}č ĺ=Ú 'ĺ9š\›mMdO„<ɤč ě)rU‚>/a°!lő“Őş¬5뵊"E‘zŐbx(ďžđg¨ĎD ĎiôoÝç,üđdîŃ.(FYÁ é^ܨ-nEĹřŢąęń4Ó›™VĆ<0âË5uüÉS»ť¶Z¬V ­¸eĂfu;hdť7Ąm„9"÷Hń"ˇ5ć° "Łá |=9ő¬“\‡ż=F?˝,)©­ŹĹëlčl4śÍ<Ç}‰ŕěťńšriѬŘáă‹îpQ[­¶-÷dÝďâşÎ`zďË©˙ě.ĹsšŘőX|ŽsÖß)ś [8Ml¤¨J‡ {Â'[Ž.ăhÎzaHCtádAž xă ©WJkp ¨‰ę|•Ę+>[|víYŁCçFÂÜBXť.§ÍńĚÍ „Ł­Q@zđ(bˇĆ*«”Ž‹$H7 [Ň.śYÇÄr`¬Í+q'c,jźĂ9;5*gk´žŃĆď.ř]×đZ'÷|čŻĚC9ŇLv!dXŕ#îţXŁĐ.bM“žÖá PăŇy y‚AŁ AP‡”>4Iź×ôř7·u\Šłt"¦w2š°7ĆÔ~›z–eQ«IĐA|ňŕ‰ßç„đ¤/E®!)ń)¶$P‡€ŚŞ m~•L%¨LP(nVB¸ń0đ}Š÷_És«"RDČ=hÄbŤ’_.(ç—‹«ótcŤ qľ\-ŕĹ aúgÖA¸GĽ™B‘űŞë7đB ⩬›¬’Íα1¬Ź×{u”‹řçu6Ń&± ¨‘¸Ü¨R) (cTş'óý˙Ąl˝#!ÖulÇXU+Z&Eµ±:$3«O÷úWJ—–wH E3Yg¦âŤ\*őĘîU#LĄ[ďô¦oQ/°Ş»şe\ëř–W§ĺŮŐn9ĐĄVaT‰—ŠĆ˝l.+ű Fa¤ŞL^Í/ŘY˛ç‡°×•j+Ķ˙Úţ«3â ;"ź)a­b,fkI úIÔÝ2€«V˛ěr5ëzކ9ÄŕđPâ… 7ž”yôöJ}ćJyćĘ úwUÂZ© ČĺtC ÍF`$Ëę¤ÉxÔßŕ .Ť±ĎóoĘ2Š·VQV’O^ezŔÇĎ}Đp¦…˛ąlŕ&ŁrŹRă`čŇ’52äÓžăâőOO}üM"a2Ý ŚĄ3-íĚę:ëŽgwe2@čŇJČŠ˘d¸ä+ÖßFcŠ9[T–tµc}`˝ż¤_äíČ[Ń·]Â<ßą±´çWŇĎ«żP÷Qň‚=čZC–ŰŐy˙ęŽi9ÁVŚI UŞéyx™¤+Ĺ óřoTOL3ŞŤjłš4áĆŐfm˝ěčäřXžtŹĚZČyx5˘s±_‘tş,Ŕů»öÔĂGć¤Řď…ňţňË/N=vÝú5ĺ ‚¸ĺ T:ŹĹm-ô˘^ć‰ä:‰‘ZÄÄ›7üú‡/Łá°Ô“pUR’UrM9˝@´ĺ7Őű}Ť¨t˝fݧ˙}<~–­,„µmç “U(đˇŔ2Ďë‹c«‘ß}č…AL/&ëâS°›)©°'ľu+)#8e|Ꞗú ‹ş“ ™WH/Mń¸:ČC "ł«0K`ö+4łśůŽ Č®8ČK'Ż\ĄśřAcGˇk9ą„*‹(É)s§Ďś°ňĘ9ÝÚ'ůňëËiýňÚiÓ)ÔšŮ0ú Żőű٤–á(ĺŵK˘Kűíb] ą›!üŮv€lvł-ĄÓž&‚eH$ŞQWćD25pGç´ftNÓíj\ď7jüEDźU,ů7Z“ ±K\jFlA 6Ëׂq`öQÁUŇr’;˝»ó¸vĎ·żń‡]†“§aŇEĺ·˛ąă5ÓJf|M!X É)gťYÜ0ţ#ăY@ţ eđ°­­uçNŰ—ŕ ł pŔ|Pۡ=,ďŮč.ŃźľÝ“‹8­Í=Ř ö:öŘí[˘ÉÚĆÖ6@đV°4Tµ”Ůfů$Ó‹sÁËĽuüőĆbôĎ…Vů ]»u[MűoÄŚ#ĚEęm&šĺL$¸_ÁďîV)B~TĄbR/ăě¦ űK•üž¬ŰŹÇ}H\áŻÖęŘÍŔ10…¨:DŞíRšyř~`w|gB§Q:)·<¤ ˛!ś¨?<ÍQţú‹k^ü˝şfĄ 1C"Ć®ěű0˘ä iś%b„äjş΂đ_Ľ\7']~ĆE2F–Ş„ü°&I˙ť1rˇö&Ţ3ś.Ż‚Ť+W+T üžaD'áäcGOÂĺ'ťÂܦBV)·ż×—ó“ ~’Ę5ăŐÉŐîM€óň¬aĺ®ŇPm­q,ŇŚęA´đA™O¨$9ߪÖK/é?ö_ůuG‡3ľ‡Ú›čŘf?Bş ř0“DÍÁ –‹ÁBjžlHx­^›—®W4¨›LXׯžţşAWݬĄMVŁاݵŮEYÄ@,`K’bűę膵˥B!Ĺn«ąŔf¶yôDÓ>źĎ ĽÔA<ľ2¸^#őXWTUŞ*Q¬«YÖ‚µÎőˇJ߆±…DkŰ!×MÚÝq˛áĆw‹ťKH-±xUÁŰ”/°˝ł]đwV&¦ZuV-Đ’5(DŚ ­ŇđĚýř‡ L©§gÔ2ř•Đ„‰DÖĄŃđGAúD*Śđ61Á9 D!śá2Ü L`f‘*Â*ËŁě¦YÜ‚Ľ@‚ Ö¤ĄÖ–ŚÁŃápH@Âç ąQ“‹iČä]D(ŕŰĂ•ůŐrMňz¬Ó‹±'wÜę†Wdş˙Ŕ>ŇŤ BY ŻÚ\ Ô PŰ&äY_wNŻ“:˘‰)ŞŹŘžtcŇ,7ŕ÷·şq&±Ě$@`°čmyÖŐÖŐöŐVž~í@6YvDi7ÁůÔ~ĚzÔ~ …%=aL"TA3ÍÜ€Źü ň4¶Â<Îi[‘µČVd©2Ü?ţ‚ý¨őýhćdȉT÷Ýń÷ …ˇ©ÜC]°îň”óžéA°k5—é=@…Â!,t„ŕµyíäĆ÷®Ř¸.á:Ű[šC~gĢ$ş‘D\!VH©âM•‹ÁR˛ uńˇ­ŤŤŰZůu”סbÓ›X­ń?w?jÓ“\!Ó)Ôrí¸%c—Ť[ŠÄŞ™Fi@ ů}.?őóŮ_N˙z*ŕöŁňaĄGápę‰3OžQş”¨{‘…LĘOhCúÚҫˮ. jęîîSf nĹPmLîĘN?ykWa’*TZ¦çóo2ů€HJ'óäEfěóšÇŕ1xYäC‰K饟¸0ćř€Ü÷ fäsúÝ DF~±ŃĚĆßôCú02=k®dCQú߸oęóÁ(’ďŻhEú¨žBőę}Űa{ÄłFA8[“\i5X—‚uKe<ńŚ•…‹Đ(9ÄNYÔHFđdÄŃBo%śÇ·ďíhÚQ·»'eňc/SĆۡ˙č¬Y[Ť<5¸7§»ËnE¶Z¶Ü¤QĹ4!őOŽ2˝“ Î|ća›$×(´@Šâ­ ż{ö=[©ÎË-ßď0>Îô¸!÷IB"[Ó}hĚąĂRÔżĄđ6·4¶)RCůđĘQ+DRI@ÖŃŤ˛:Eť´AÝĎDTŞ«¤UŠ YžT§P zš(ô{Qv›c-‘ć™e@F–fš¨‚Tü "VďND¨¶™ÚÁ¶fQ‹¤Yt·Aűp‰s]Ş T…+˝ý¬D·.\h ĺ…]’gaELx§ń•Š6IJE`›݇ ČđDrźRěÓ, ô` ł°3¸łŔ±¨®oelO%ŇfMpŹ€{k |@“ŽŃś@=ß)ˇ8M™3>d_bă&úk›Ć% ‹sÖg6˘qg=ÍiŠ)ü‚»ąA"kq ľŤÂ'K!úźs™—q±Y®b›"Ď- ›C€„Ă™—p‰O‹‚Q ľ ‡!¶¸Ă¶@Ęýb ÉĽGăUX$VČĹż“k„ÝÎáţĄýN‹2źÂ©đW*•ß2Kľd n2KÝ2—$f&Ů-b¶Ztá7ß,ż9rçBî Č!9‰^çs›LfSţo”ĆvÔ…žÎţźŮ ®<\ů­ą˙ČĽ@”ěˇîz^ŇFŃÍĽÁÇŕ‰¨­…ľµ†0zt…Uú1ăŘS`ö•±@ĎCŃů•÷|ś“9TÁ,hćĘŤZ9“ŘŻLRp+žôűŁAm}×!‚s^ÍĚ"gÖßĂuz®©ą™dúWl¬’‹ÔUJžŞJY­Ę“ę5¶eű*~żÇáĄÚŁ[ăۢv«ÝŠě6g•®áŻo¶ĺ;;$Q«ŞÝäz‹ck˘Ĺ1˝MoŐßăĂżI)ű/ĽÂđ®¬ë<45"k˛:˘Ş§ŕĽ!D0"B+ą“m¬äD@z2‚€Ř¨édC™…/0K†2 äe˛Ry©^ˇB¨ %y„˛âI‹3á‰ěűbĎW{ţÖ }>z >ę x¨×qayPJýęTúś0k|uňJĚSŇ…Ě4ŔZ.’čË©˙”ËíH¬,“—‚e$˛8gZÍ[5łŘ®5yJÂ]í7ĹĂ?p~ç ~IB”ſ¼ŠdŔëpú€ŹlÚĄ”/3<’¶@‚‡D=óű‰­LoJ  ±Ä§Óü°áłIeQiV"§±&±j»üţÂÜôĂ]«»X‘5<ÝȵmőíÎ]€üÓUóć/Y±DKŻ3Ló"ŇHXDMďâśsÝX;rĘÄ‚)+Ţö·n˘M6Ăě.ŻÍ “(Ć+QňŞVÖ—G$Ôž˘ĺ'Ŕb{°'ű $úę*85c3Éąľżuëˇ÷úßÜ1j CđGđ•ÍőńhŁÇčŃ»îknb*ý8BŰ…ăě«Á‰\›N°ďyf“áQëó–üĽ±Ţ¶™ćěMČĽęMťĹŔÉžĚ'™“y>ýüŹšĄÔZĽhERSČtĺ©%j ŕ!żż1fŚS-).¬„?ä0?>¨öĄ'{ŕ«>ś:‰ď{čEőĚöMęÝĂţ7red endstream endobj 108 0 obj << /Title(\376\377\000L\000I\000C\000E\000N\000S\000E\000S) /Dest(chapter.16) /Count -3 /Parent 7 0 R /Prev 99 0 R /First 109 0 R /Last 111 0 R >> endobj 5 0 obj << /Limits [ (Doc-Start) (table.2.1) ] /Names [ (Doc-Start) 112 0 R (Hfootnote.2) 290 0 R (Hfootnote.3) 291 0 R (Hfootnote.4) 336 0 R (Hfootnote.5) 420 0 R (Hfootnote.6) 574 0 R (Hfootnote.7) 584 0 R (Hfootnote.8) 626 0 R (Hfootnote.9) 847 0 R (Item.1) 591 0 R (Item.2) 592 0 R (Item.3) 593 0 R (Item.4) 594 0 R (Item.5) 595 0 R (Item.6) 596 0 R (Item.7) 597 0 R (Item.8) 598 0 R (chapter*.1) 122 0 R (chapter*.2) 254 0 R (chapter.1) 261 0 R (chapter.10) 759 0 R (chapter.11) 766 0 R (chapter.12) 773 0 R (chapter.13) 790 0 R (chapter.14) 798 0 R (chapter.15) 805 0 R (chapter.16) 852 0 R (chapter.2) 296 0 R (chapter.3) 434 0 R (chapter.4) 514 0 R (chapter.5) 540 0 R (chapter.6) 556 0 R (chapter.7) 579 0 R (chapter.8) 631 0 R (chapter.9) 752 0 R (page.1) 121 0 R (page.10) 302 0 R (page.11) 309 0 R (page.12) 319 0 R (page.13) 326 0 R (page.14) 340 0 R (page.15) 348 0 R (page.16) 359 0 R (page.17) 367 0 R (page.18) 374 0 R (page.19) 385 0 R (page.2) 156 0 R (page.20) 395 0 R (page.21) 405 0 R (page.22) 414 0 R (page.23) 424 0 R (page.24) 433 0 R (page.25) 443 0 R (page.26) 452 0 R (page.27) 461 0 R (page.28) 470 0 R (page.29) 478 0 R (page.3) 195 0 R (page.30) 486 0 R (page.31) 495 0 R (page.32) 506 0 R (page.33) 513 0 R (page.34) 522 0 R (page.35) 532 0 R (page.36) 539 0 R (page.37) 547 0 R (page.38) 555 0 R (page.39) 562 0 R (page.4) 234 0 R (page.40) 570 0 R (page.41) 578 0 R (page.42) 588 0 R (page.43) 604 0 R (page.44) 611 0 R (page.45) 620 0 R (page.46) 630 0 R (page.47) 637 0 R (page.48) 644 0 R (page.49) 656 0 R (page.5) 253 0 R (page.50) 667 0 R (page.51) 676 0 R (page.52) 690 0 R (page.53) 701 0 R (page.54) 713 0 R (page.55) 725 0 R (page.56) 737 0 R (page.57) 745 0 R (page.58) 751 0 R (page.59) 758 0 R (page.6) 260 0 R (page.60) 765 0 R (page.61) 772 0 R (page.62) 781 0 R (page.63) 789 0 R (page.64) 797 0 R (page.65) 804 0 R (page.66) 813 0 R (page.67) 822 0 R (page.68) 829 0 R (page.69) 839 0 R (page.7) 273 0 R (page.70) 851 0 R (page.71) 862 0 R (page.72) 869 0 R (page.8) 282 0 R (page.9) 295 0 R (section*.10) 333 0 R (section*.11) 370 0 R (section*.12) 377 0 R (section*.13) 380 0 R (section*.14) 381 0 R (section*.15) 388 0 R (section*.16) 389 0 R (section*.17) 390 0 R (section*.18) 464 0 R (section*.19) 465 0 R (section*.20) 498 0 R (section*.21) 499 0 R (section*.22) 500 0 R (section*.23) 501 0 R (section*.24) 543 0 R (section*.25) 551 0 R (section*.26) 565 0 R (section*.27) 566 0 R (section*.28) 648 0 R (section*.29) 649 0 R (section*.3) 266 0 R (section*.30) 651 0 R (section*.31) 652 0 R (section*.32) 659 0 R (section*.33) 660 0 R (section*.34) 661 0 R (section*.35) 662 0 R (section*.36) 663 0 R (section*.37) 670 0 R (section*.38) 672 0 R (section*.39) 680 0 R (section*.4) 267 0 R (section*.40) 681 0 R (section*.41) 683 0 R (section*.42) 684 0 R (section*.43) 686 0 R (section*.44) 693 0 R (section*.45) 694 0 R (section*.46) 695 0 R (section*.47) 696 0 R (section*.48) 704 0 R (section*.49) 705 0 R (section*.5) 314 0 R (section*.50) 708 0 R (section*.51) 709 0 R (section*.52) 717 0 R (section*.53) 719 0 R (section*.54) 720 0 R (section*.55) 728 0 R (section*.56) 731 0 R (section*.57) 733 0 R (section*.58) 740 0 R (section*.59) 776 0 R (section*.6) 315 0 R (section*.60) 777 0 R (section*.61) 784 0 R (section*.62) 785 0 R (section*.63) 793 0 R (section*.64) 816 0 R (section*.65) 834 0 R (section*.66) 835 0 R (section*.67) 842 0 R (section*.68) 845 0 R (section*.69) 846 0 R (section*.7) 322 0 R (section*.8) 329 0 R (section*.9) 330 0 R (section.1.1) 264 0 R (section.1.2) 278 0 R (section.1.3) 287 0 R (section.15.1) 808 0 R (section.15.2) 809 0 R (section.15.3) 817 0 R (section.15.4) 818 0 R (section.15.5) 825 0 R (section.15.6) 832 0 R (section.15.7) 833 0 R (section.15.8) 844 0 R (section.16.1) 855 0 R (section.16.2) 856 0 R (section.16.3) 858 0 R (section.2.1) 305 0 R (section.2.10) 355 0 R (section.2.11) 362 0 R (section.2.12) 363 0 R (section.2.13) 378 0 R (section.2.14) 391 0 R (section.2.15) 398 0 R (section.2.16) 399 0 R (section.2.17) 400 0 R (section.2.18) 401 0 R (section.2.19) 408 0 R (section.2.2) 312 0 R (section.2.20) 409 0 R (section.2.21) 418 0 R (section.2.22) 427 0 R (section.2.23) 428 0 R (section.2.24) 429 0 R (section.2.3) 334 0 R (section.2.4) 343 0 R (section.2.5) 344 0 R (section.2.6) 351 0 R (section.2.7) 352 0 R (section.2.8) 353 0 R (section.2.9) 354 0 R (section.3.1) 437 0 R (section.3.10) 502 0 R (section.3.11) 509 0 R (section.3.2) 447 0 R (section.3.3) 466 0 R (section.3.4) 473 0 R (section.3.5) 474 0 R (section.3.6) 481 0 R (section.3.7) 482 0 R (section.3.8) 489 0 R (section.3.9) 491 0 R (section.4.1) 517 0 R (section.4.2) 535 0 R (section.5.1) 550 0 R (section.7.1) 582 0 R (section.7.2) 600 0 R (section.7.3) 607 0 R (section.7.4) 615 0 R (section.7.5) 616 0 R (section.8.1) 640 0 R (section.8.2) 706 0 R (section.8.3) 741 0 R (subsection.1.1.1) 265 0 R (subsection.1.1.2) 276 0 R (subsection.1.1.3) 277 0 R (subsection.3.1.1) 438 0 R (subsection.3.1.2) 439 0 R (subsection.3.1.3) 446 0 R (subsection.3.2.1) 448 0 R (subsection.3.2.2) 457 0 R (subsection.4.1.1) 518 0 R (subsection.4.1.2) 525 0 R (subsection.4.1.3) 526 0 R (subsection.7.1.1) 599 0 R (subsection.7.3.1) 614 0 R (subsection.7.5.1) 623 0 R (subsection.8.1.1) 647 0 R (subsection.8.1.2) 650 0 R (subsection.8.1.3) 671 0 R (subsection.8.1.4) 679 0 R (subsection.8.1.5) 682 0 R (subsection.8.1.6) 685 0 R (subsection.8.1.7) 697 0 R (subsection.8.2.1) 707 0 R (subsection.8.2.2) 716 0 R (subsection.8.2.3) 718 0 R (subsection.8.2.4) 721 0 R (subsection.8.2.5) 729 0 R (subsection.8.2.6) 730 0 R (subsection.8.2.7) 732 0 R (table.2.1) 410 0 R] >> endobj 963 0 obj <>stream dvips + GPL Ghostscript 9.20 2017-06-12T20:25:20+10:00 2017-06-12T20:25:20+10:00 LaTeX with hyperref package endstream endobj 2 0 obj <>endobj xref 0 964 0000000000 65535 f 0000235440 00000 n 0000358504 00000 n 0000234746 00000 n 0000220774 00000 n 0000351215 00000 n 0000235660 00000 n 0000235382 00000 n 0000236732 00000 n 0000236229 00000 n 0000235721 00000 n 0000235981 00000 n 0000236104 00000 n 0000236455 00000 n 0000236587 00000 n 0000240695 00000 n 0000236945 00000 n 0000237061 00000 n 0000237185 00000 n 0000237309 00000 n 0000237463 00000 n 0000237582 00000 n 0000237701 00000 n 0000237845 00000 n 0000237964 00000 n 0000238078 00000 n 0000238203 00000 n 0000238323 00000 n 0000238453 00000 n 0000238583 00000 n 0000238703 00000 n 0000238848 00000 n 0000238968 00000 n 0000239083 00000 n 0000239203 00000 n 0000239333 00000 n 0000239473 00000 n 0000240343 00000 n 0000240468 00000 n 0000240603 00000 n 0000243540 00000 n 0000241359 00000 n 0000240938 00000 n 0000241054 00000 n 0000241193 00000 n 0000241929 00000 n 0000241537 00000 n 0000241688 00000 n 0000242140 00000 n 0000242309 00000 n 0000242463 00000 n 0000242612 00000 n 0000242771 00000 n 0000242920 00000 n 0000243079 00000 n 0000243248 00000 n 0000243393 00000 n 0000244594 00000 n 0000244265 00000 n 0000243794 00000 n 0000243935 00000 n 0000244109 00000 n 0000244473 00000 n 0000245140 00000 n 0000244852 00000 n 0000245448 00000 n 0000247328 00000 n 0000245897 00000 n 0000245699 00000 n 0000246085 00000 n 0000246437 00000 n 0000246224 00000 n 0000246673 00000 n 0000247020 00000 n 0000246852 00000 n 0000251240 00000 n 0000248978 00000 n 0000247631 00000 n 0000247747 00000 n 0000247876 00000 n 0000248030 00000 n 0000248234 00000 n 0000248548 00000 n 0000248757 00000 n 0000250853 00000 n 0000249166 00000 n 0000249452 00000 n 0000249776 00000 n 0000250165 00000 n 0000250384 00000 n 0000250593 00000 n 0000250737 00000 n 0000251059 00000 n 0000251408 00000 n 0000251594 00000 n 0000251721 00000 n 0000251863 00000 n 0000252215 00000 n 0000252352 00000 n 0000253965 00000 n 0000252529 00000 n 0000252668 00000 n 0000252831 00000 n 0000253044 00000 n 0000253257 00000 n 0000253485 00000 n 0000253613 00000 n 0000253771 00000 n 0000351051 00000 n 0000254197 00000 n 0000254332 00000 n 0000254461 00000 n 0000254816 00000 n 0000000015 00000 n 0000000314 00000 n 0000254879 00000 n 0000306961 00000 n 0000318532 00000 n 0000254922 00000 n 0000254957 00000 n 0000220938 00000 n 0000254992 00000 n 0000255057 00000 n 0000000335 00000 n 0000001762 00000 n 0000305835 00000 n 0000310334 00000 n 0000255122 00000 n 0000255256 00000 n 0000255392 00000 n 0000255533 00000 n 0000255674 00000 n 0000255814 00000 n 0000255950 00000 n 0000256086 00000 n 0000256219 00000 n 0000256355 00000 n 0000256491 00000 n 0000256627 00000 n 0000256763 00000 n 0000256899 00000 n 0000257035 00000 n 0000257171 00000 n 0000257307 00000 n 0000257443 00000 n 0000257580 00000 n 0000257717 00000 n 0000257854 00000 n 0000257991 00000 n 0000258128 00000 n 0000258262 00000 n 0000258398 00000 n 0000258535 00000 n 0000258672 00000 n 0000258707 00000 n 0000221320 00000 n 0000258755 00000 n 0000001784 00000 n 0000003792 00000 n 0000258820 00000 n 0000258957 00000 n 0000259094 00000 n 0000259230 00000 n 0000259366 00000 n 0000259503 00000 n 0000259637 00000 n 0000259774 00000 n 0000259908 00000 n 0000260044 00000 n 0000260185 00000 n 0000260325 00000 n 0000260466 00000 n 0000260602 00000 n 0000260743 00000 n 0000260884 00000 n 0000261020 00000 n 0000261156 00000 n 0000261292 00000 n 0000261427 00000 n 0000261562 00000 n 0000261698 00000 n 0000261834 00000 n 0000261971 00000 n 0000262108 00000 n 0000262242 00000 n 0000262378 00000 n 0000262519 00000 n 0000262660 00000 n 0000262800 00000 n 0000262936 00000 n 0000263070 00000 n 0000263205 00000 n 0000263339 00000 n 0000263374 00000 n 0000221758 00000 n 0000263422 00000 n 0000003814 00000 n 0000006310 00000 n 0000263487 00000 n 0000263621 00000 n 0000263757 00000 n 0000263898 00000 n 0000264033 00000 n 0000264169 00000 n 0000264310 00000 n 0000264445 00000 n 0000264581 00000 n 0000264722 00000 n 0000264856 00000 n 0000264992 00000 n 0000265133 00000 n 0000265274 00000 n 0000265412 00000 n 0000265553 00000 n 0000265694 00000 n 0000265835 00000 n 0000265976 00000 n 0000266111 00000 n 0000266252 00000 n 0000266392 00000 n 0000266533 00000 n 0000266673 00000 n 0000266814 00000 n 0000266954 00000 n 0000267095 00000 n 0000267231 00000 n 0000267364 00000 n 0000267499 00000 n 0000267634 00000 n 0000267769 00000 n 0000267903 00000 n 0000268038 00000 n 0000268073 00000 n 0000222196 00000 n 0000268121 00000 n 0000006332 00000 n 0000007465 00000 n 0000268186 00000 n 0000268321 00000 n 0000268458 00000 n 0000268595 00000 n 0000268732 00000 n 0000268869 00000 n 0000269006 00000 n 0000269143 00000 n 0000269280 00000 n 0000269414 00000 n 0000269549 00000 n 0000269685 00000 n 0000269822 00000 n 0000269958 00000 n 0000269993 00000 n 0000222474 00000 n 0000270041 00000 n 0000270106 00000 n 0000007487 00000 n 0000009882 00000 n 0000270171 00000 n 0000270206 00000 n 0000222640 00000 n 0000270254 00000 n 0000270319 00000 n 0000009904 00000 n 0000013024 00000 n 0000270384 00000 n 0000270449 00000 n 0000270514 00000 n 0000270579 00000 n 0000309634 00000 n 0000339982 00000 n 0000270644 00000 n 0000270679 00000 n 0000222814 00000 n 0000270740 00000 n 0000013046 00000 n 0000016907 00000 n 0000270805 00000 n 0000270870 00000 n 0000270935 00000 n 0000271000 00000 n 0000271035 00000 n 0000222980 00000 n 0000271096 00000 n 0000016929 00000 n 0000020845 00000 n 0000308271 00000 n 0000332313 00000 n 0000271161 00000 n 0000271226 00000 n 0000271361 00000 n 0000271497 00000 n 0000271562 00000 n 0000271627 00000 n 0000271662 00000 n 0000223178 00000 n 0000271736 00000 n 0000271801 00000 n 0000020867 00000 n 0000021811 00000 n 0000271866 00000 n 0000271901 00000 n 0000223344 00000 n 0000271962 00000 n 0000021832 00000 n 0000025945 00000 n 0000272027 00000 n 0000272092 00000 n 0000272127 00000 n 0000223518 00000 n 0000272188 00000 n 0000025967 00000 n 0000029524 00000 n 0000272253 00000 n 0000272318 00000 n 0000272453 00000 n 0000272518 00000 n 0000272583 00000 n 0000272618 00000 n 0000223700 00000 n 0000272679 00000 n 0000029546 00000 n 0000033644 00000 n 0000272744 00000 n 0000272809 00000 n 0000272844 00000 n 0000223866 00000 n 0000272918 00000 n 0000033666 00000 n 0000037265 00000 n 0000272983 00000 n 0000273048 00000 n 0000307915 00000 n 0000328520 00000 n 0000273113 00000 n 0000273178 00000 n 0000273243 00000 n 0000273379 00000 n 0000273444 00000 n 0000273479 00000 n 0000224056 00000 n 0000273566 00000 n 0000037287 00000 n 0000040640 00000 n 0000273631 00000 n 0000273696 00000 n 0000273760 00000 n 0000273795 00000 n 0000224222 00000 n 0000273869 00000 n 0000040662 00000 n 0000044039 00000 n 0000273934 00000 n 0000273999 00000 n 0000274061 00000 n 0000274126 00000 n 0000274191 00000 n 0000274256 00000 n 0000274291 00000 n 0000224388 00000 n 0000274365 00000 n 0000044061 00000 n 0000047813 00000 n 0000274430 00000 n 0000274495 00000 n 0000274559 00000 n 0000274594 00000 n 0000224554 00000 n 0000274681 00000 n 0000047835 00000 n 0000051367 00000 n 0000274746 00000 n 0000274808 00000 n 0000274843 00000 n 0000224720 00000 n 0000274917 00000 n 0000051389 00000 n 0000054454 00000 n 0000274982 00000 n 0000275047 00000 n 0000275112 00000 n 0000275247 00000 n 0000275312 00000 n 0000275377 00000 n 0000275412 00000 n 0000224902 00000 n 0000275499 00000 n 0000054476 00000 n 0000056908 00000 n 0000275564 00000 n 0000275629 00000 n 0000275694 00000 n 0000275759 00000 n 0000275824 00000 n 0000275859 00000 n 0000225068 00000 n 0000275933 00000 n 0000056930 00000 n 0000060098 00000 n 0000275998 00000 n 0000276063 00000 n 0000276128 00000 n 0000276193 00000 n 0000276258 00000 n 0000276293 00000 n 0000225234 00000 n 0000276367 00000 n 0000060120 00000 n 0000063831 00000 n 0000276432 00000 n 0000276496 00000 n 0000276558 00000 n 0000276623 00000 n 0000276658 00000 n 0000225408 00000 n 0000276732 00000 n 0000063853 00000 n 0000067722 00000 n 0000276797 00000 n 0000276932 00000 n 0000276997 00000 n 0000277132 00000 n 0000277197 00000 n 0000277232 00000 n 0000225606 00000 n 0000277306 00000 n 0000067744 00000 n 0000070166 00000 n 0000277371 00000 n 0000277436 00000 n 0000277501 00000 n 0000277563 00000 n 0000277598 00000 n 0000225772 00000 n 0000277672 00000 n 0000277737 00000 n 0000070188 00000 n 0000072395 00000 n 0000277802 00000 n 0000277867 00000 n 0000277932 00000 n 0000277997 00000 n 0000278032 00000 n 0000225938 00000 n 0000278080 00000 n 0000072417 00000 n 0000076251 00000 n 0000278145 00000 n 0000278210 00000 n 0000278275 00000 n 0000278340 00000 n 0000278375 00000 n 0000226104 00000 n 0000278436 00000 n 0000076273 00000 n 0000079769 00000 n 0000306682 00000 n 0000317836 00000 n 0000278501 00000 n 0000278566 00000 n 0000278601 00000 n 0000226270 00000 n 0000278662 00000 n 0000079791 00000 n 0000084059 00000 n 0000278727 00000 n 0000278792 00000 n 0000278857 00000 n 0000278922 00000 n 0000278957 00000 n 0000226436 00000 n 0000279018 00000 n 0000084081 00000 n 0000088289 00000 n 0000279083 00000 n 0000279148 00000 n 0000279213 00000 n 0000279248 00000 n 0000226602 00000 n 0000279309 00000 n 0000088311 00000 n 0000090759 00000 n 0000279374 00000 n 0000279439 00000 n 0000279504 00000 n 0000279539 00000 n 0000226768 00000 n 0000279600 00000 n 0000090781 00000 n 0000095558 00000 n 0000279665 00000 n 0000279730 00000 n 0000279865 00000 n 0000279930 00000 n 0000279965 00000 n 0000226950 00000 n 0000280026 00000 n 0000095580 00000 n 0000099402 00000 n 0000280091 00000 n 0000280156 00000 n 0000280221 00000 n 0000280286 00000 n 0000280351 00000 n 0000280416 00000 n 0000280451 00000 n 0000227116 00000 n 0000280499 00000 n 0000099424 00000 n 0000102708 00000 n 0000280564 00000 n 0000280629 00000 n 0000280664 00000 n 0000227282 00000 n 0000280725 00000 n 0000280790 00000 n 0000102730 00000 n 0000105683 00000 n 0000280855 00000 n 0000280920 00000 n 0000280985 00000 n 0000281020 00000 n 0000227448 00000 n 0000281107 00000 n 0000105705 00000 n 0000108939 00000 n 0000281172 00000 n 0000281235 00000 n 0000281300 00000 n 0000281435 00000 n 0000281577 00000 n 0000281612 00000 n 0000227638 00000 n 0000281699 00000 n 0000108961 00000 n 0000110000 00000 n 0000281764 00000 n 0000281829 00000 n 0000281864 00000 n 0000227804 00000 n 0000281925 00000 n 0000281990 00000 n 0000110021 00000 n 0000113094 00000 n 0000282055 00000 n 0000282120 00000 n 0000282155 00000 n 0000227970 00000 n 0000282229 00000 n 0000113116 00000 n 0000116739 00000 n 0000282294 00000 n 0000282359 00000 n 0000282424 00000 n 0000282459 00000 n 0000228136 00000 n 0000282533 00000 n 0000282598 00000 n 0000116761 00000 n 0000119655 00000 n 0000282663 00000 n 0000282698 00000 n 0000228310 00000 n 0000282746 00000 n 0000119677 00000 n 0000123077 00000 n 0000282811 00000 n 0000282876 00000 n 0000282941 00000 n 0000282976 00000 n 0000228476 00000 n 0000283050 00000 n 0000123099 00000 n 0000124427 00000 n 0000283115 00000 n 0000283248 00000 n 0000283312 00000 n 0000283347 00000 n 0000228666 00000 n 0000283382 00000 n 0000283447 00000 n 0000124449 00000 n 0000128735 00000 n 0000283512 00000 n 0000283577 00000 n 0000283713 00000 n 0000283778 00000 n 0000283813 00000 n 0000228856 00000 n 0000283861 00000 n 0000128757 00000 n 0000133065 00000 n 0000283926 00000 n 0000283988 00000 n 0000284052 00000 n 0000284117 00000 n 0000284178 00000 n 0000284243 00000 n 0000284308 00000 n 0000284373 00000 n 0000284438 00000 n 0000284503 00000 n 0000284568 00000 n 0000284603 00000 n 0000229022 00000 n 0000284651 00000 n 0000133087 00000 n 0000137742 00000 n 0000284716 00000 n 0000284781 00000 n 0000284816 00000 n 0000229196 00000 n 0000284877 00000 n 0000137764 00000 n 0000141154 00000 n 0000284942 00000 n 0000285007 00000 n 0000285072 00000 n 0000285137 00000 n 0000285172 00000 n 0000229362 00000 n 0000285246 00000 n 0000141176 00000 n 0000143119 00000 n 0000285311 00000 n 0000285376 00000 n 0000285511 00000 n 0000285647 00000 n 0000285712 00000 n 0000285747 00000 n 0000229560 00000 n 0000285795 00000 n 0000285860 00000 n 0000143141 00000 n 0000146406 00000 n 0000285925 00000 n 0000285960 00000 n 0000229726 00000 n 0000286034 00000 n 0000146428 00000 n 0000149958 00000 n 0000286099 00000 n 0000286164 00000 n 0000286199 00000 n 0000229900 00000 n 0000286260 00000 n 0000149980 00000 n 0000153553 00000 n 0000286325 00000 n 0000286390 00000 n 0000286452 00000 n 0000286517 00000 n 0000286582 00000 n 0000286647 00000 n 0000286712 00000 n 0000286747 00000 n 0000230066 00000 n 0000286808 00000 n 0000153575 00000 n 0000155820 00000 n 0000286873 00000 n 0000286935 00000 n 0000286999 00000 n 0000287064 00000 n 0000287129 00000 n 0000287194 00000 n 0000287229 00000 n 0000230232 00000 n 0000287277 00000 n 0000155842 00000 n 0000159152 00000 n 0000287342 00000 n 0000287407 00000 n 0000287472 00000 n 0000287536 00000 n 0000287571 00000 n 0000230398 00000 n 0000287632 00000 n 0000159174 00000 n 0000162150 00000 n 0000287697 00000 n 0000287762 00000 n 0000287827 00000 n 0000287892 00000 n 0000287957 00000 n 0000288022 00000 n 0000288087 00000 n 0000288152 00000 n 0000288217 00000 n 0000288252 00000 n 0000230564 00000 n 0000288313 00000 n 0000162172 00000 n 0000165021 00000 n 0000288378 00000 n 0000288443 00000 n 0000288508 00000 n 0000288572 00000 n 0000288636 00000 n 0000288701 00000 n 0000288736 00000 n 0000230730 00000 n 0000288810 00000 n 0000165043 00000 n 0000168254 00000 n 0000288875 00000 n 0000288940 00000 n 0000289005 00000 n 0000289070 00000 n 0000289134 00000 n 0000289199 00000 n 0000289264 00000 n 0000289299 00000 n 0000230904 00000 n 0000289347 00000 n 0000168276 00000 n 0000171033 00000 n 0000289412 00000 n 0000289477 00000 n 0000289542 00000 n 0000289605 00000 n 0000289670 00000 n 0000289735 00000 n 0000289800 00000 n 0000289835 00000 n 0000231078 00000 n 0000289883 00000 n 0000171055 00000 n 0000173387 00000 n 0000289948 00000 n 0000290013 00000 n 0000290078 00000 n 0000290143 00000 n 0000290208 00000 n 0000290273 00000 n 0000290337 00000 n 0000290372 00000 n 0000231244 00000 n 0000290433 00000 n 0000173409 00000 n 0000177481 00000 n 0000290498 00000 n 0000290563 00000 n 0000290628 00000 n 0000290663 00000 n 0000231410 00000 n 0000290724 00000 n 0000177503 00000 n 0000180609 00000 n 0000290789 00000 n 0000290824 00000 n 0000231576 00000 n 0000290872 00000 n 0000290937 00000 n 0000180631 00000 n 0000181143 00000 n 0000291002 00000 n 0000291037 00000 n 0000231742 00000 n 0000291085 00000 n 0000291150 00000 n 0000181164 00000 n 0000181531 00000 n 0000291215 00000 n 0000291250 00000 n 0000231908 00000 n 0000291298 00000 n 0000291363 00000 n 0000181552 00000 n 0000183100 00000 n 0000291428 00000 n 0000291463 00000 n 0000232074 00000 n 0000291511 00000 n 0000291576 00000 n 0000183122 00000 n 0000185760 00000 n 0000291641 00000 n 0000291706 00000 n 0000291771 00000 n 0000291806 00000 n 0000232248 00000 n 0000291880 00000 n 0000185782 00000 n 0000188607 00000 n 0000291945 00000 n 0000292010 00000 n 0000292075 00000 n 0000292110 00000 n 0000232414 00000 n 0000292184 00000 n 0000292249 00000 n 0000188629 00000 n 0000191642 00000 n 0000292314 00000 n 0000292379 00000 n 0000292414 00000 n 0000232580 00000 n 0000292488 00000 n 0000292553 00000 n 0000191664 00000 n 0000193013 00000 n 0000292618 00000 n 0000292653 00000 n 0000232746 00000 n 0000292701 00000 n 0000292766 00000 n 0000193035 00000 n 0000196795 00000 n 0000292831 00000 n 0000292896 00000 n 0000292961 00000 n 0000292996 00000 n 0000232912 00000 n 0000293044 00000 n 0000196817 00000 n 0000202160 00000 n 0000293109 00000 n 0000293174 00000 n 0000293239 00000 n 0000293304 00000 n 0000293339 00000 n 0000233078 00000 n 0000293400 00000 n 0000202182 00000 n 0000206109 00000 n 0000293465 00000 n 0000293530 00000 n 0000293565 00000 n 0000233244 00000 n 0000293626 00000 n 0000206131 00000 n 0000210389 00000 n 0000293691 00000 n 0000293754 00000 n 0000293819 00000 n 0000293884 00000 n 0000293949 00000 n 0000293984 00000 n 0000233410 00000 n 0000294058 00000 n 0000210411 00000 n 0000214911 00000 n 0000294123 00000 n 0000294188 00000 n 0000294324 00000 n 0000294389 00000 n 0000294454 00000 n 0000294518 00000 n 0000294583 00000 n 0000294618 00000 n 0000233600 00000 n 0000294666 00000 n 0000294731 00000 n 0000214933 00000 n 0000218339 00000 n 0000294796 00000 n 0000294861 00000 n 0000294926 00000 n 0000295104 00000 n 0000295169 00000 n 0000295204 00000 n 0000233782 00000 n 0000295265 00000 n 0000218361 00000 n 0000219122 00000 n 0000295330 00000 n 0000295509 00000 n 0000295544 00000 n 0000233964 00000 n 0000295579 00000 n 0000219143 00000 n 0000220752 00000 n 0000295644 00000 n 0000295777 00000 n 0000295910 00000 n 0000296043 00000 n 0000296176 00000 n 0000296309 00000 n 0000296442 00000 n 0000296575 00000 n 0000296708 00000 n 0000296841 00000 n 0000296974 00000 n 0000297107 00000 n 0000297240 00000 n 0000297373 00000 n 0000297506 00000 n 0000297639 00000 n 0000297772 00000 n 0000297905 00000 n 0000298038 00000 n 0000298171 00000 n 0000298304 00000 n 0000298437 00000 n 0000298570 00000 n 0000298703 00000 n 0000298836 00000 n 0000298969 00000 n 0000299102 00000 n 0000299235 00000 n 0000299368 00000 n 0000299501 00000 n 0000299634 00000 n 0000299767 00000 n 0000299900 00000 n 0000300033 00000 n 0000300166 00000 n 0000300299 00000 n 0000300432 00000 n 0000300565 00000 n 0000300698 00000 n 0000300831 00000 n 0000300964 00000 n 0000301097 00000 n 0000301230 00000 n 0000301363 00000 n 0000301496 00000 n 0000301629 00000 n 0000301762 00000 n 0000301895 00000 n 0000302028 00000 n 0000302161 00000 n 0000302294 00000 n 0000302427 00000 n 0000302560 00000 n 0000302693 00000 n 0000302826 00000 n 0000302959 00000 n 0000303092 00000 n 0000303225 00000 n 0000303358 00000 n 0000303491 00000 n 0000303624 00000 n 0000303757 00000 n 0000303890 00000 n 0000304023 00000 n 0000304156 00000 n 0000304289 00000 n 0000304422 00000 n 0000304555 00000 n 0000304688 00000 n 0000304821 00000 n 0000304954 00000 n 0000305087 00000 n 0000305220 00000 n 0000305353 00000 n 0000305486 00000 n 0000305619 00000 n 0000305752 00000 n 0000305787 00000 n 0000310784 00000 n 0000318068 00000 n 0000319183 00000 n 0000328815 00000 n 0000332787 00000 n 0000340624 00000 n 0000306367 00000 n 0000306451 00000 n 0000306856 00000 n 0000307814 00000 n 0000308790 00000 n 0000308888 00000 n 0000310198 00000 n 0000356861 00000 n trailer << /Size 964 /Root 1 0 R /Info 2 0 R /ID [<9DE5F6CA1B4D620C1B2DB899AD108E72><9DE5F6CA1B4D620C1B2DB899AD108E72>] >> startxref 358715 %%EOF gpsim-0.30.0/doc/gpsim.lyx0000644000076400007640000057544413117450177012315 00000000000000#LyX 2.2 created this file. For more info see http://www.lyx.org/ \lyxformat 508 \begin_document \begin_header \save_transient_properties true \origin unavailable \textclass book \begin_preamble % added by lyx2lyx for converted index entries \@ifundefined{textmu} {\usepackage{textcomp}}{} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding default \fontencoding global \font_roman "times" "default" \font_sans "default" "default" \font_typewriter "default" "default" \font_math "auto" "auto" \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 100 \font_tt_scale 100 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize 10 \spacing single \use_hyperref false \papersize default \use_geometry false \use_package amsmath 1 \use_package amssymb 1 \use_package cancel 1 \use_package esint 0 \use_package mathdots 0 \use_package mathtools 1 \use_package mhchem 1 \use_package stackrel 1 \use_package stmaryrd 1 \use_package undertilde 1 \cite_engine basic \cite_engine_type default \biblio_style plain \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \justification true \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \leftmargin -0.5cm \topmargin 0.5cm \rightmargin 0.5cm \bottommargin 0.5cm \secnumdepth 2 \tocdepth 2 \paragraph_separation skip \defskip smallskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title gpsim \end_layout \begin_layout Date $Date:: 2017-06-12#$ \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Chapter* Introduction \end_layout \begin_layout Standard gpsim is a full-featured software simulator for Microchip PIC microcontrollers distributed under the GNU General Public License and GNU Lesser Public License \begin_inset Note Note status collapsed \begin_layout Plain Layout scott2 Wed Sep 30 13:25:58 1998 \end_layout \end_inset (see the LICENSE section). \end_layout \begin_layout Standard gpsim has been designed to be as accurate as possible. Accuracy includes the entire PIC - from the core to the I/O pins and including ALL of the internal peripherals. Thus it's possible to create stimuli and tie them to the I/O pins and test the PIC the same way you would in the real world. \end_layout \begin_layout Standard gpsim has been designed to be as fast as possible. Real time simulation speeds of 20Mhz pics are possible. \end_layout \begin_layout Standard gpsim can be controlled from either a graphical user interface (GUI), a command line interface (CLI) or by a remote process. Typical debugging features like breakpoints, single stepping, disassembling, memory inspect & change, and so on are all supported. In addition, complex debugging features like real time tracing, assertions, conditional breaks, and plugin modules to name a few are also supported. \end_layout \begin_layout Chapter gpsim - An Overview \end_layout \begin_layout Standard If you don't care to wade through details, this chapter should help you get things up and running. The INSTALL and README files will provide more up-to-date information than this document, so please refer to those first. \end_layout \begin_layout Section Making the executable \end_layout \begin_layout Standard gpsim's executable is created in a manner that's consistent with much of the other open source software: \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout tar -xvzf gpsim-x.y.z.tar.gz \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout expand the compressed tar file \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ./configure \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Create a 'makefile' unique to your system \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout make \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout compile gpsim \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout make install \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout install gpsim \end_layout \end_inset \end_inset \end_layout \begin_layout Standard The last step will require root privileges. \end_layout \begin_layout Subsection Make Details - ./configure options \end_layout \begin_layout Subsubsection* gui-less \end_layout \begin_layout Standard The default configuration will provide a gui (graphical user interface). The cli (command line interface) is still available, however many people prefer just to use the cli. These hardy souls may build a command-line only interface by configuring gpsim: \end_layout \begin_layout LyX-Code ./configure --disable-gui \end_layout \begin_layout Subsubsection* debugging \end_layout \begin_layout Standard If you want to debug gpsim then you will probably use gdb. Consequently, you will want to disable shared libraries: \end_layout \begin_layout LyX-Code ./configure --disable-shared \end_layout \begin_layout Standard This will create one, huge monolithic executable with symbolic information. \end_layout \begin_layout Subsection RPMs \end_layout \begin_layout Standard gpsim is also available in RPM form from linux distributions such as Fedora. \end_layout \begin_layout Subsection Windows \end_layout \begin_layout Standard Gpsim runs on Windows too. Both release and snapshot gpsim apps can be installed and run on windows machines. \end_layout \begin_layout Standard The release version of the gpsim apps are generated on each new release of gpsim. These can be downloaded from the following web site: \end_layout \begin_layout Quote https://sourceforge.net/projects/gpsim/files/gpsim-win32/ \end_layout \begin_layout Standard The snapshot versions are generated from time to time from the then current source code and will contain bug fixes and new features added since the last release. These versions should work, but are not given the extra testing of a new release. Snapshots can be downloaded from: \end_layout \begin_layout Quote https://sourceforge.net/projects/gpsim/files/snapshot_builds/gpsim-win32/ \end_layout \begin_layout Standard If you wish to build your own windows version of gpsim, the late Borut Razem has documented the process which can be found at this location: \end_layout \begin_layout Quote http://gpsim.sourceforge.net/gpsimWin32/gpsimWin32.html \end_layout \begin_layout Section Running \end_layout \begin_layout Standard The executable created above is called: gpsim. The following command line options may be specified when gpsim is invoked. \end_layout \begin_layout LyX-Code gpsim [-?] [-p []] [[-c] ] [[-s] ] \end_layout \begin_layout LyX-Code -p, --processor= processor (e.g. -pp16c84 for the 'c84) \end_layout \begin_layout LyX-Code -c, --command=STRING startup command file (optional .stc files) \end_layout \begin_layout LyX-Code -s .cod symbol file (optional .cod files) \end_layout \begin_layout LyX-Code -L, -- colon separated list of directories to \end_layout \begin_layout LyX-Code search. \end_layout \begin_layout LyX-Code -v, --version gpsim version \end_layout \begin_layout LyX-Code -i, --cli command line mode only \end_layout \begin_layout LyX-Code -d, --icd=STRING use ICD (e.g. -d /dev/ttyS0). \end_layout \begin_layout LyX-Code Help options: \end_layout \begin_layout LyX-Code -?, --help Show this help message \end_layout \begin_layout LyX-Code --usage Display brief usage message \end_layout \begin_layout Standard Typically gpsim will be invoked like: \end_layout \begin_layout LyX-Code [My-Computer]$ gpsim mypic-program.cod \end_layout \begin_layout Standard (The \emph on [My-Computer]$ \emph default text is an example of a typical bash command prompt - you will only type the text after this prompt). This loads the .cod file generated by gputils. \end_layout \begin_layout Standard Under Windows, gpsim can also be invoked by navigating through the Start/Program menu. This will open a DOS window to provide access to the command line interface. It's also possible to open a DOS window (or CygWin bash session) and invoke gpsim from there. \end_layout \begin_layout Section Requirements \end_layout \begin_layout Standard gpsim has been developed under Linux. It should build and run just fine under the popular Linux distributions like Fedora, Ubuntu, etc. gpsim has also been ported to the MAC, MicroSoft Windows, Solaris, and BSD. Two packages gpsim requires that may not be available with all Linux distribut ions are readline and gtk (the gimp tool kit). The ./configure script should tell you if these packages are not installed on your system or if the revisions that are installed are too old. \end_layout \begin_layout Standard There are no minimum hardware requirements to run gpsim. Faster is better though! \end_layout \begin_layout Standard gputils, the gnupic utilities package, is also very useful. gpsim will accept straight hex files, but if you want to do any symbolic debugging then you will want to use the .cod \begin_inset Foot status collapsed \begin_layout Plain Layout .cod files are symbol files that were created by ByteCraft and are used by Microchip. \end_layout \end_inset files that gputils produces. The .cod files are in the same format as the .cod files MPASM \begin_inset Foot status collapsed \begin_layout Plain Layout MPASM is Microchip's Assembler. \end_layout \end_inset produces. \end_layout \begin_layout Chapter Command Line Interface \end_layout \begin_layout Standard The command line interface is fairly straight-forward. The table below summarizes the available commands. Brief descriptions of these commands can also be displayed by typing \emph on help \emph default at the command line. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout summary \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout attach \begin_inset Index idx status collapsed \begin_layout Plain Layout attach \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attach stimuli to nodes \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout break \begin_inset Index idx status collapsed \begin_layout Plain Layout break \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Set a break point \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout bus \begin_inset Index idx status collapsed \begin_layout Plain Layout bus \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add or display node busses \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout clear \begin_inset Index idx status collapsed \begin_layout Plain Layout clear \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Remove a break point \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout disassemble \begin_inset Index idx status collapsed \begin_layout Plain Layout disassemble \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Disassemble the current cpu \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dump \begin_inset Index idx status collapsed \begin_layout Plain Layout dump \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Display either the RAM or EEPROM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout frequency \begin_inset Index idx status collapsed \begin_layout Plain Layout frequency \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Set processor frequency \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout help \begin_inset Index idx status collapsed \begin_layout Plain Layout help \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Type help "command" for more help on a command \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout icd \begin_inset Index idx status collapsed \begin_layout Plain Layout icd \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout In Circuit Debugger support. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout list \begin_inset Index idx status collapsed \begin_layout Plain Layout list \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Display source and list files \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout load \begin_inset Index idx status collapsed \begin_layout Plain Layout load \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Load either a hex or command file \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout log \begin_inset Index idx status collapsed \begin_layout Plain Layout log \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Log/record events to a file \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout node \begin_inset Index idx status collapsed \begin_layout Plain Layout node \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add or display stimulus nodes \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout module \begin_inset Index idx status collapsed \begin_layout Plain Layout module \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none Select & Display modules \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout processor \begin_inset Index idx status collapsed \begin_layout Plain Layout processor \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add/list processors \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout quit \begin_inset Index idx status collapsed \begin_layout Plain Layout quit \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Quit gpsim \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout reset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none Reset all or parts of the simulation \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout run \begin_inset Index idx status collapsed \begin_layout Plain Layout run \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Execute the pic program \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout set \begin_inset Index idx status collapsed \begin_layout Plain Layout set \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none display and control gpsim behavior flags \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout step \begin_inset Index idx status collapsed \begin_layout Plain Layout step \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Execute one or more instructions \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout stimulus \begin_inset Index idx status collapsed \begin_layout Plain Layout stimulus \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Create a stimulus \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout stopwatch \begin_inset Index idx status collapsed \begin_layout Plain Layout stopwatch \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none Measure time between events \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout symbol \begin_inset Index idx status collapsed \begin_layout Plain Layout symbol \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Add/list symbols \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout trace \begin_inset Index idx status collapsed \begin_layout Plain Layout trace \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Dump the trace history \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout version \begin_inset Index idx status collapsed \begin_layout Plain Layout version \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Display gpsim's version \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout x \begin_inset Index idx status collapsed \begin_layout Plain Layout x \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout (deprecated) examine and/or modify memory \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The built in 'help' command provides additional online information. \end_layout \begin_layout Section attach \begin_inset Index idx status collapsed \begin_layout Plain Layout attach \end_layout \end_inset \end_layout \begin_layout LyX-Code attach node1 stimulus1 [stimulus2 stimulus_N] \end_layout \begin_layout Standard Attach is used to define connections between one or more stimulus and a node. One node and at least one stimulus must be specified, but in general two or more stimuli are used. Attach can be viewed as wiring stimuli together, with the node acting as the wire. A stimulus is either a CPU or module I/O pin or a stimulus name. \end_layout \begin_layout Standard Attach_pointN can have one of the following formats \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 pin() or pin() \begin_inset Separator latexpar \end_inset \end_layout \begin_deeper \begin_layout Standard This refers to a pin of the current active CPU. \end_layout \begin_layout Standard is the pin number \end_layout \begin_layout Standard is an integer symbol whose value is a pin number \end_layout \end_deeper \begin_layout Labeling \labelwidthstring 00.00.0000 or pin() \begin_inset Separator latexpar \end_inset \end_layout \begin_deeper \begin_layout Standard These two forms are treated exactly the same ( i.e. the pin() has no meaning). \end_layout \begin_layout Standard is a stimulus name or an I/O pin name. \end_layout \begin_layout Standard I/O pin name can be just the pin name for the CPU or .pin_name for a module or CPU \end_layout \end_deeper \begin_layout Standard Example \end_layout \begin_layout LyX-Code **gpsim> load instructions_14bit.cod # load code \end_layout \begin_layout LyX-Code **gpsim> module library libgpsim_modules #load module lib \end_layout \begin_layout LyX-Code **gpsim> module load usart U1 # create USART \end_layout \begin_layout LyX-Code **gpsim> node n1 # define a node \end_layout \begin_layout LyX-Code **gpsim> node n2 #define another node \end_layout \begin_layout LyX-Code **gpsim> symbol TWO=2 #define symbol with value 2 \end_layout \begin_layout LyX-Code **gpsim> attach n1 pin(1) pin(TWO) #attach CPU pins 1 and 2 \end_layout \begin_layout LyX-Code **gpsim> attach n1 U1.RXPIN #add usart pin to n1 \end_layout \begin_layout LyX-Code **gpsim> attach n2 portb0 pin(U1.TXPIN) #connect portb0 to UASRT TX pin \end_layout \begin_layout LyX-Code **gpsim> node # show results \end_layout \begin_layout LyX-Code \end_layout \begin_layout Section break \begin_inset Index idx status collapsed \begin_layout Plain Layout break \end_layout \end_inset \end_layout \begin_layout Standard The break command is used to set and examine break points. New break points are assigned a unique number. This number can be used to query or clear the break point. Break points halt the simulation when the condition associated with them is true. Break points are ignored during single stepping. See chapter \begin_inset CommandInset ref LatexCommand ref reference "cha:Assertions-and-Extended" \end_inset for more examples of breakpoints. \end_layout \begin_layout Subsubsection* Examining break points \end_layout \begin_layout LyX-Code break [bp_number] \end_layout \begin_layout Standard Break points can be examined by typing the break command without any options. Specific breaks can be queried by specifying the break point number. \end_layout \begin_layout Subsubsection* Program Memory/Execution breaks \end_layout \begin_layout Standard The most common break point is an execution break point. This one halts execution whenever the program counter reaches the address at which the break point is set. The syntax is: \end_layout \begin_layout LyX-Code break e|r|w ADDRESS [,expr [,message]] \end_layout \begin_layout Standard The simulation halts when the address is executed, read, or written. The ADDRESS can be a symbol or a number. If the optional expression is specified, then it must evaluate to true before the simulation will halt. The optional message allows a description to be associated with the break. The read and write options only apply to those processors that can manipulate their own program memory. \end_layout \begin_layout Subsubsection* Register Memory breaks \end_layout \begin_layout Standard gpsim can also associate break points with register accesses. This is useful for capturing bugs that stomp on RAM. E.g. you can say something like \begin_inset Quotes eld \end_inset halt execution whenever bit 4 of register 42 is cleared \begin_inset Quotes erd \end_inset . The command line syntax is: \end_layout \begin_layout LyX-Code break r|w|ch REGISTER [,expr [,message]] \end_layout \begin_layout Standard The simulation halts when \emph on REGISTER \emph default is read, written, or changed on write, and the optional expression evaluates to true. \end_layout \begin_layout Standard Other syntaxes with a boolean expression are: \end_layout \begin_layout LyX-Code break r|w|ch REGISTER == value \end_layout \begin_layout Standard The simulation halts when \emph on REGISTER \emph default is assigned the specified value, and: \end_layout \begin_layout LyX-Code break r|w|ch REGISTER & mask == value \end_layout \begin_layout Standard The simulation halts when specified bits in REGISTER are assigned the specified value. \end_layout \begin_layout Standard Here's an example of a register write break. This one will halt the simulation if any value is written to the variable named \emph on temp1 \emph default . \end_layout \begin_layout LyX-Code break w temp1 \end_layout \begin_layout Standard Sometimes it's necessary to specify an auxiliary condition with a break point. For example, there may be a temporary variable that is shared throughout the code. You may wish to trap writes to that variable only while executing a specific subroutine. For example, the following break point triggers when temp1 is written and while the program counter is in between the labels \emph on func_start \emph default and \emph on func_end \emph default : \end_layout \begin_layout LyX-Code break w temp1, (pc >= func_start && pc < func_end) \end_layout \begin_layout Standard \emph on TIP: \emph default Use this type of break point if you suspect an interrupt routine is over writing a variable. \end_layout \begin_layout Standard Another situation is one where you wish to trap writes to a variable only if some other variable is a certain value: \end_layout \begin_layout LyX-Code break w temp1, (CurTask & 0x0f != 0b101) \end_layout \begin_layout Standard If the firmware writes to the variable temp1 then the simulation will halt if the lower nibble of CurTask is not equal to 5. \end_layout \begin_layout Standard This example breaks only if the hex digit 'C' is written to the upper nibble of temp1: \end_layout \begin_layout LyX-Code break w (temp1 & 0b11110000) == 0b11000000 \end_layout \begin_layout Subsubsection Processor exception breakpoints \end_layout \begin_layout Standard Stack overflow, underflow and watchdog timeout can also halt the simulation. \end_layout \begin_layout LyX-Code break so \end_layout \begin_layout LyX-Code break su \end_layout \begin_layout LyX-Code break wdt \end_layout \begin_layout Subsubsection* Attribute Breakpoints \end_layout \begin_layout LyX-Code break \emph on attribute \end_layout \begin_layout Standard gpsim also supports a concept of \emph on attribute breakpoints. \emph default Attributes are parameters that gpsim and its modules expose to the user interface. For example, the simulator stopwatch exposes attributes which support breakpoints. This feature is intend mainly for module writers to provide a mechanism for allowing the user to control the module. \end_layout \begin_layout Subsubsection* Cycle counter Breakpoints \end_layout \begin_layout LyX-Code break c \emph on cycle_number \end_layout \begin_layout Standard The cycle counter is gpsim's time keeper. It increments once every instruction cycle. The 'c' option to the break command allows a break point to be set at a particular value of the cycle counter. \end_layout \begin_layout Section clear \begin_inset Index idx status collapsed \begin_layout Plain Layout clear \end_layout \end_inset \end_layout \begin_layout LyX-Code clear bp_number \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard The clear command is used to clear break points. The break point number must be specified. The \emph on break \emph default command without any arguments displays all of the currently defined break points. This can be used to ascertain the break point number. Once cleared, a break point is deleted. \begin_inset Foot status collapsed \begin_layout Plain Layout A break point disable/enable feature has been discussed and may be added a future date. \end_layout \end_inset \end_layout \begin_layout Section disassemble \begin_inset Index idx status collapsed \begin_layout Plain Layout disassemble \end_layout \end_inset \end_layout \begin_layout LyX-Code disassemble [[begin:end] | [count]] \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard The disassemble command decodes the program memory opcodes into their standard mnemonics. With no options, the \emph on disassemble \emph default command disassembles instructions surrounding the current program counter: \end_layout \begin_layout LyX-Code gpsim> disassemble \end_layout \begin_layout LyX-Code current pc = 0x1c \end_layout \begin_layout LyX-Code 0012 2a03 incf reg3,f,0 \end_layout \begin_layout LyX-Code 0014 0004 clrwdt \end_layout \begin_layout LyX-Code 0016 5000 movf reg,w,0 \end_layout \begin_layout LyX-Code 0018 1001 iorwf reg1,w,0 \end_layout \begin_layout LyX-Code 001a 1002 iorwf reg2,w,0 \end_layout \begin_layout LyX-Code ==> 001c 1003 iorwf reg3,w,0 \end_layout \begin_layout LyX-Code 001e e1f4 bnz $-0x16 ;(0x8) \end_layout \begin_layout LyX-Code 0020 d7ff bra $-0x0 ;(0x00020) \end_layout \begin_layout Standard With a single numeric option, the \emph on disassemble \emph default command will disassemble given number of instructions starting with the instruction at the PC. \end_layout \begin_layout Standard With a two numbers, the \emph on disassemble \emph default command will disassemble instructions starting and ending given number of instructions from the PC. \end_layout \begin_layout Section dump \begin_inset Index idx status collapsed \begin_layout Plain Layout dump \end_layout \end_inset \end_layout \begin_layout LyX-Code dump [r | s | e [module_name [filename]]] \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard dump r or dump with no options will display all of the file registers and special function registers. \end_layout \begin_layout Standard dump s will display only special function registers. \end_layout \begin_layout Standard dump e will display the contents of the processor EEPROM (if the pic being simulated contains any). \end_layout \begin_layout Standard The 'dump e module_name' command will display the contents of an EEPROM where module_name can either be the name of a module or processor which contains an EEPROM. \end_layout \begin_layout Standard The 'dump e module_name filename' command dumps the contents of a module's EEPROM, in Intel hex format, into the file with the given name. The 'load e' command can later be used to read the dumped file thus allowing the contents of the EEPROM to be preserved between runs of gpsim. \end_layout \begin_layout Standard See the 'x' command for examining and modifying individual registers. \end_layout \begin_layout Section echo \begin_inset Index idx status collapsed \begin_layout Plain Layout echo \end_layout \end_inset \end_layout \begin_layout Standard The echo command is used like a print statement within configuration files. It just lets you display information about your configuration file. \end_layout \begin_layout Section frequency \begin_inset Index idx status collapsed \begin_layout Plain Layout frequency \end_layout \end_inset \end_layout \begin_layout Standard This command sets the oscillator frequency. By default gpsim uses 20 MHz oscillator. The oscillator frequency is used to compute time in seconds. Use this command to adjust this value. If no value is provided this command prints the current frequency. Note that PICs have an instruction frequency that's a quarter of the oscillator frequency clock. \end_layout \begin_layout Section help \begin_inset Index idx status collapsed \begin_layout Plain Layout help \end_layout \end_inset \end_layout \begin_layout LyX-Code help [ \emph on command \emph default ] \end_layout \begin_layout Standard By itself, help will display all of the commands along with a brief description on how they work. With a command as a parameter help provides more extensive online help. The help command can also display information about attributes. \end_layout \begin_layout Section icd \begin_inset Index idx status collapsed \begin_layout Plain Layout icd \end_layout \end_inset \end_layout \begin_layout LyX-Code icd [open ] \end_layout \begin_layout Standard The open command is used to enable ICD mode and specify the serial port where the ICD is. (e.g. "icd open /dev/ttyS0"). Without options (and after the icd is enabled), it will print some information about the ICD. \end_layout \begin_layout Section list \begin_inset Index idx status collapsed \begin_layout Plain Layout list \end_layout \end_inset \end_layout \begin_layout Standard The list command allows you to view the source code while you are debugging. \end_layout \begin_layout LyX-Code list [[s | l] [*pc] [line_number1 [,line_number2]]] \end_layout \begin_layout Standard Without any options, list will use the last specified options. \end_layout \begin_layout Standard list s will display lines in the source (or .asm) file. \end_layout \begin_layout Standard list l will display lines in the .lst file. \end_layout \begin_layout Standard list *pc will display either .asm or .lst lines around the PC. Without *pc use current PC as a reference. \end_layout \begin_layout Standard Line numbers are relative to the line of the PC. \end_layout \begin_layout Section load \begin_inset Index idx status collapsed \begin_layout Plain Layout load \end_layout \end_inset \end_layout \begin_layout Standard The load command is used to load a program file, a command file, or eeprom data. \end_layout \begin_layout Standard Program file is usually used to program the physical part. A .hex file provides no symbolic information. .cod files on the other hand, do provide symbolic information. The only reason to use a hex file is when there's no .cod file available. \end_layout \begin_layout Standard The syntax for loading program files is: \end_layout \begin_layout LyX-Code load [processortype] programfile [label] \end_layout \begin_layout Standard Gpsim will automatically determine if the file is a .hex or .cod file. The optional \emph on processortype \emph default is needed if a .hex file is being loaded and the processor type is not yet defined. \end_layout \begin_layout Standard The optional \emph on label \emph default is used to identify the processor module on the breadboard and as the prefix in the symbol table. If a label is not given then the processor type is used for this functionality. \end_layout \begin_layout LyX-Code load [i] commandfile.stc \end_layout \begin_layout Standard Command files contain gpsim commands. These are extremely useful for creating a debugging environment that will be used repeatedly. Normally loading a command file residing in other directories changes working directory. This can be overridden with the 'i' (include) option. \end_layout \begin_layout LyX-Code load e module_name file \end_layout \begin_layout Standard This command loads the contents of either a processor's EEPROM or an EEPROM module from a file containing the data in Intel hex format. In either case the address of the first cell of the EEPROM is 0x0000. Used in conjunction with the 'dump e module_name filename' command, the contents of an EEPROM can be carried over from one run of gpsim to another. \end_layout \begin_layout Section macros \begin_inset Index idx status collapsed \begin_layout Plain Layout macros \end_layout \end_inset \end_layout \begin_layout Standard Macros are defined like: \end_layout \begin_layout LyX-Code \emph on name \emph default macro [arg1, arg2, ..., argN] \end_layout \begin_layout LyX-Code macro body \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Standard And they're invoked by: \end_layout \begin_layout LyX-Code \emph on name \emph default param1, param2, ..., paramN \end_layout \begin_layout Standard Macros are a way of collecting several parameterized commands into one short command. The first line of a macro definition specifies the macro's name and optional arguments. The \emph on name \emph default is used to invoke the macro. The arguments are text string place holders. When a macro is invoked, the parameters are aligned with the arguments. I.e. \emph on param1 \emph default in the invocation can be thought of being assigned to \emph on arg1 \emph default in the definition. The parameters replace the arguments in the macro body. \end_layout \begin_layout Standard In the following example, a variable or attribute called \emph on mac_flags \emph default is being manipulated in an expression. The arguments \emph on add \emph default and \emph on mask \emph default appear in the macro body and provide a parameterized way of manipulating this expression. \end_layout \begin_layout LyX-Code mac_exp macro add, mask \end_layout \begin_layout LyX-Code mac_flags = (mac_flags+add) & mask \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Standard Note that the indentation is arbitrary. The macro is invoked by: \end_layout \begin_layout LyX-Code mac_exp 1, 0b00001111 # increment the lower nibble \end_layout \begin_layout Standard The parameter \emph on add \emph default is replaced by the number \emph on 1 \emph default while \emph on mask \emph default is replaced with the binary number \emph on 0b00001111. \emph default The invocation turns into the gpsim command: \end_layout \begin_layout LyX-Code mac_flags = (mac_flags+1) & 0b00001111 \end_layout \begin_layout Subsubsection* Nested Macros \end_layout \begin_layout Standard The macro body can contain any gpsim command. Of particular interest are macro invocations within other macros. Here's another macro that invokes the one defined above. \end_layout \begin_layout LyX-Code # Nested macro example \end_layout \begin_layout LyX-Code mac1 macro p1, p2 \end_layout \begin_layout LyX-Code run \end_layout \begin_layout LyX-Code mac_exp p1, p2 \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Standard And it could be used like: \end_layout \begin_layout LyX-Code mac1 1, 0b00001111 # test lower nibble \end_layout \begin_layout LyX-Code mac1 (1<<4), 0b11110000 # test upper nibble \end_layout \begin_layout Standard The first invocation starts the simulator by executing a \emph on run \emph default command. When a break point is encountered, control returns to the command line and the \emph on mac_exp \emph default macro is invoked. \end_layout \begin_layout Subsubsection* Displaying Defined Macros \end_layout \begin_layout Standard All currently defined macros can be displayed by typing the macro command without a name or arguments: \end_layout \begin_layout LyX-Code gpsim> macro \end_layout \begin_layout LyX-Code mac1 macro p1 p2 \end_layout \begin_layout LyX-Code run \end_layout \begin_layout LyX-Code mac_exp p1, p2 \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout LyX-Code mac_exp macro add mask \end_layout \begin_layout LyX-Code mac_flags = (mac_flags+add) & mask \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Section module \begin_inset Index idx status collapsed \begin_layout Plain Layout module \end_layout \end_inset \end_layout \begin_layout Standard The \emph on module \emph default command is used to load and query external modules (see section \begin_inset CommandInset ref LatexCommand ref reference "cha:Modules" \end_inset for more information about gpsim modules). A module is a special piece of software that can extend gpsim in some manner. LED's and switches are examples of modules. A module library is collection of modules. \end_layout \begin_layout Subsubsection* Loading module libraries \end_layout \begin_layout LyX-Code module lib \emph on lib_name \end_layout \begin_layout Standard The \emph on lib \emph default option is used to load a module library. Module libraries are system dependent shared libraries, i.e. on Windows they're DLL's and UNIX they're shared libraries. This means that either the libraries should reside in a path where the OS knows libraries exist or that the full path name must be specified along with the \emph on lib_name \emph default . gpsim provides a module library with a few modules: \end_layout \begin_layout LyX-Code gpsim> module lib libgpsim_modules \end_layout \begin_layout Subsubsection* Displaying available modules \end_layout \begin_layout LyX-Code module list \end_layout \begin_layout Standard The \emph on list \emph default option will display all of the modules that can be loaded. Here is an example of gpsim's built-in modules. \end_layout \begin_layout LyX-Code gpsim> module list \end_layout \begin_layout LyX-Code Module Library Files \end_layout \begin_layout LyX-Code libgpsim_modules.so \end_layout \begin_layout LyX-Code switch \end_layout \begin_layout LyX-Code and2 \end_layout \begin_layout LyX-Code or2 \end_layout \begin_layout LyX-Code xor2 \end_layout \begin_layout LyX-Code not \end_layout \begin_layout LyX-Code led_7segments \end_layout \begin_layout LyX-Code led \end_layout \begin_layout LyX-Code push_button \end_layout \begin_layout LyX-Code PortStimulus \end_layout \begin_layout LyX-Code pullup \end_layout \begin_layout LyX-Code pulldown \end_layout \begin_layout LyX-Code pulsegen \end_layout \begin_layout LyX-Code Encoder \end_layout \begin_layout LyX-Code usart \end_layout \begin_layout LyX-Code TTL377 \end_layout \begin_layout LyX-Code I2C-EEPROM2k \end_layout \begin_layout LyX-Code I2C-EEPROM16k \end_layout \begin_layout LyX-Code I2C-EEPROM256k \end_layout \begin_layout Subsubsection* Loading a specific module \end_layout \begin_layout LyX-Code module load module_type [module_name] \end_layout \begin_layout Standard Once a library has been loaded, specific modules can be instantiated. The \emph on module_type \emph default is what's displayed by the \emph on module list \emph default command. The optional module name specifies what the instance is called. Here's an example \end_layout \begin_layout LyX-Code gpsim> module load led D1 \end_layout \begin_layout Subsubsection* Display loaded modules \end_layout \begin_layout LyX-Code module \end_layout \begin_layout Subsubsection* Querying modules \end_layout \begin_layout Standard Dumping modules and listing the pins is not yet implemented. \end_layout \begin_layout LyX-Code \end_layout \begin_layout Section node \begin_inset Index idx status collapsed \begin_layout Plain Layout node \end_layout \end_inset \end_layout \begin_layout LyX-Code node [new_node1 new_node2 ...] \end_layout \begin_layout Standard The \shape italic node \shape default command defines or queries \begin_inset Quotes eld \end_inset nodes \begin_inset Quotes erd \end_inset , used to connect external signals to the simulated PIC. If no new_node is specified then all of the nodes that have been defined are displayed. If a new_node is specified then it will be added to the node list. See the "attach" and "stimulus" commands to see how stimuli are added to the nodes. \end_layout \begin_layout LyX-Code examples: \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code node // display the node list \end_layout \begin_layout LyX-Code node n1 n2 n3 // create and add 3 new nodes to the list \end_layout \begin_layout Section processor \begin_inset Index idx status collapsed \begin_layout Plain Layout processor \end_layout \end_inset \end_layout \begin_layout LyX-Code processor [new_processor_type [new_processor_name]] | [list] | [pins] \end_layout \begin_layout Standard The \emph on processor \emph default command is used to either define a new processor or to query one that has already been defined. Normally there's no need to explicitly define the processor since the symbol file already contains that information. The two exceptions are when a) the symbolic information is not available or b) you wish to override the processor specified in the symbol file. (See the \emph on load \emph default command on how the processor in a symbol file can be overridden.) \end_layout \begin_layout Standard To see a list of the processors supported by gpsim, type ' \emph on processor list \emph default '. To display the state of the I/O processor, type ' \emph on processor pins \emph default '. For now, this will display the pin numbers and their current state. \end_layout \begin_layout LyX-Code examples: \end_layout \begin_layout LyX-Code processor // Display the processors you've already defined. \end_layout \begin_layout LyX-Code processor list // Display the list of processors supported. \end_layout \begin_layout LyX-Code processor pins // Display the processor package and pin state \end_layout \begin_layout LyX-Code processor p16cr84 fred // Create a new processor. \end_layout \begin_layout LyX-Code processor p16c74 wilma // and another. \end_layout \begin_layout LyX-Code processor p16c65 // Create one with no name. \end_layout \begin_layout Section quit \begin_inset Index idx status collapsed \begin_layout Plain Layout quit \end_layout \end_inset \end_layout \begin_layout Standard Quit gpsim. \end_layout \begin_layout Section run \begin_inset Index idx status collapsed \begin_layout Plain Layout run \end_layout \end_inset \end_layout \begin_layout Standard Start (or continue) simulation. The simulation will continue until the next break point is encountered. \end_layout \begin_layout Section step \begin_inset Index idx status collapsed \begin_layout Plain Layout step \end_layout \end_inset \end_layout \begin_layout Standard Execute a single instruction, or a specified number of instructions. \end_layout \begin_layout LyX-Code step [over | n] \end_layout \begin_layout Standard With no arguments, the step command executes one instruction of the PIC code. If a numeric argument is given, this specifies a fixed number of instructions to simulate. The specific word \begin_inset Quotes eld \end_inset over \begin_inset Quotes erd \end_inset as an argument to step tells gpsim to run everything involved in the current instruction. This would normally be used on a CALL instruction, in which case the whole subroutine runs and the simulation stops after it returns. \end_layout \begin_layout Section symbol \begin_inset Index idx status collapsed \begin_layout Plain Layout symbol \end_layout \end_inset \end_layout \begin_layout LyX-Code symbol [symbol_name [symbol_type value]] \end_layout \begin_layout Standard The \emph on symbol \emph default command is used to query and define symbols. If no options are specified, the whole symbol table is displayed. The creation of user defined symbols is limited at this time (see the online help for the current state of this command). \end_layout \begin_layout Section stimulus \begin_inset Index idx status collapsed \begin_layout Plain Layout stimulus \end_layout \end_inset \end_layout \begin_layout LyX-Code stimulus [[type] options] \end_layout \begin_layout Standard The \emph on stimulus \emph default command creates a signal that can be tied to a node or an attribute. If no options are specified then all currently defined stimuli are displayed. \end_layout \begin_layout Standard Note that in most cases it is easier to create a stimulus file then to type the command by hand. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout option \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout initial_state \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout state at the start and at the rollover \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout start_cycle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout simulation cycle when the stimulus will begin \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout stimulus period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout specifies the stimulus name \end_layout \end_inset \end_inset \end_layout \begin_layout Standard Here's an example of a stimulus that will generate two pulses and repeat this in 1000 cycles. \end_layout \begin_layout LyX-Code stimulus asynchronous_stimulus \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code # The initial state AND the state the stimulus is when \end_layout \begin_layout LyX-Code # it rolls over \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code initial_state 0 \end_layout \begin_layout LyX-Code start_cycle 0 \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code # the asynchronous stimulus will roll over in 'period' \end_layout \begin_layout LyX-Code # cycles. Delete this line if you don't want a roll over. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code period 1000 \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code { 100, 1, \end_layout \begin_layout LyX-Code 200, 0, \end_layout \begin_layout LyX-Code 300, 1, \end_layout \begin_layout LyX-Code 400, 0 \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code # Give the stimulus a name: \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code name two_pulse_repeat \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code end \end_layout \begin_layout Standard A stimulus can be queried by typing its name at the command line: \end_layout \begin_layout LyX-Code gpsim> two_pulse_repeat \end_layout \begin_layout LyX-Code two_pulse_repeat attached to pulse_node \end_layout \begin_layout LyX-Code Vth=0V Zth=250 ohms Cth=0 F nodeVoltage= 7.49998e-07V \end_layout \begin_layout LyX-Code Driving=0 drivingState=0 drivenState=0 bitState=0 \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code states = 5 \end_layout \begin_layout LyX-Code 100 1 \end_layout \begin_layout LyX-Code 200 0 \end_layout \begin_layout LyX-Code 300 1 \end_layout \begin_layout LyX-Code 400 0 \end_layout \begin_layout LyX-Code 1000 0 \end_layout \begin_layout LyX-Code initial=0 \end_layout \begin_layout LyX-Code period=1000 \end_layout \begin_layout LyX-Code start_cycle=0 \end_layout \begin_layout LyX-Code Next break cycle=100 \end_layout \begin_layout Standard Even though this example uses 1's and 0's for the data, one can use integers, floating point numbers, or expressions instead. Integers are useful for supplying a stimulus to an attribute. Expressions are useful for abstracting the data. See Chapter \begin_inset CommandInset ref LatexCommand ref reference "cha:Simulating-the-Real" \end_inset for more discussion and examples of stimuli. \end_layout \begin_layout Section stopwatch \begin_inset Index idx status collapsed \begin_layout Plain Layout stopwatch \end_layout \end_inset \begin_inset Foot status collapsed \begin_layout Plain Layout The stopwatch is really a collection of attributes and not a command. But the behavior is so similar to a command that it has been included here. \end_layout \end_inset \end_layout \begin_layout LyX-Code A timer for monitoring and controlling the simulation. \end_layout \begin_layout LyX-Code The units are in simulation cycles. \end_layout \begin_layout LyX-Code stopwatch.rollover - specifies rollover value. \end_layout \begin_layout LyX-Code stopwatch.direction - specifies count direction. \end_layout \begin_layout LyX-Code stopwatch.enable - enables counting if true. \end_layout \begin_layout Standard Without any options, \emph on stopwatch \emph default will display the contents of the stopwatch timer. \emph on stopwatch \emph default is writable, so you may initialize it to whatever value you like. The behavior of the timer may be manipulated via the three attributes. The \emph on .rollover \emph default attribute is the number of cycles at which the stopwatch timer rolls over. The \emph on .direction \emph default and \emph on .enable \emph default attributes are boolean types. When true, the \emph on .direction \emph default attribute will instruction the stopwatch to count up. \end_layout \begin_layout Section trace \begin_inset Index idx status collapsed \begin_layout Plain Layout trace \end_layout \end_inset \end_layout \begin_layout LyX-Code trace [dump_amount] \end_layout \begin_layout Standard \emph on trace \emph default will print out the most recent "dump_amount" traces. If no dump_amount is specified, then the entire trace buffer will be displayed. \end_layout \begin_layout Section version \end_layout \begin_layout LyX-Code version \end_layout \begin_layout Standard Display gpsim's version. Note, this command will probably get replaced by an attribute with the same (or similar) name. \end_layout \begin_layout Section x \begin_inset Index idx status collapsed \begin_layout Plain Layout x \end_layout \end_inset \end_layout \begin_layout Standard The \emph on x \emph default command is deprecated. It's former use was to examine and modify memory. The preferred way to do this now is with expressions. The help for \emph on x \emph default now indicates this: \end_layout \begin_layout LyX-Code x examine command -- deprecated \end_layout \begin_layout LyX-Code Instead of the using a special command to examine and modify \end_layout \begin_layout LyX-Code variables, it's possible to directly access them using gpsim's \end_layout \begin_layout LyX-Code expression parsing. For example, to examine a variable: \end_layout \begin_layout LyX-Code gpsim> my_variable \end_layout \begin_layout LyX-Code my_variable [0x27] = 0x00 = 0b00000000 \end_layout \begin_layout LyX-Code To modify a variable \end_layout \begin_layout LyX-Code gpsim> my_variable = 10 \end_layout \begin_layout LyX-Code It's also possible to assign the value of register to another \end_layout \begin_layout LyX-Code gpsim> my_variable = porta \end_layout \begin_layout LyX-Code Or to assign the results of an expression: \end_layout \begin_layout LyX-Code gpsim> my_variable = (porta ^ portc) & 0x0f \end_layout \begin_layout LyX-Code \end_layout \begin_layout Chapter \begin_inset CommandInset label LatexCommand label name "cha:Graphical-User-Interface" \end_inset Graphical User Interface \end_layout \begin_layout Standard FIXME: We could use a few illustrations here! \end_layout \begin_layout Standard gpsim also provides a graphical user interface that simplifies some of the drudgery associated with the cli. It's possible to open windows to view all the details about your debug environment. To get the most out of your debugging session, you will want to assemble your code with gpasm (the gnupic assembler) and use the symbolic .cod files it produces. \end_layout \begin_layout Section Main window \end_layout \begin_layout Subsection Menus \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 File->Open .stc or .cod files. \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 File->Quit Quit gpsim \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Windows->* Open/Close the windows. \end_layout \begin_layout Subsection Buttons \end_layout \begin_layout Standard (These are also found as keyboard bindings in the source windows.) \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Step Step one instruction \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Over Step until pc is after next instruction \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Finish Run to return address \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Run Run continuously \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Stop Stop execution \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Reset Reset CPU \end_layout \begin_layout Subsection Simulation mode \end_layout \begin_layout Standard This controls how gpsim simulates, and how the GUI updates. \end_layout \begin_layout Labeling \labelwidthstring 0000000.00.0000 Never Don't ever update the GUI when simulating. This is the fastest mode. You will have to stop simulation by pressing Ctrl-C in the command line interface. \end_layout \begin_layout Labeling \labelwidthstring 0000000.00.0000 x \begin_inset space ~ \end_inset cycles Update the GUI every x cycles simulated. \end_layout \begin_layout Labeling \labelwidthstring 0000000.00.0000 every \begin_inset space ~ \end_inset cycle Update the GUI every cycle. (you see everything, if you have filled up on coffee :-) \end_layout \begin_layout Labeling \labelwidthstring 0000000.00.0000 x \begin_inset space ~ \end_inset ms \begin_inset space ~ \end_inset animate Here you can slow down simulation with a delay between every cycle. \end_layout \begin_layout Labeling \labelwidthstring 0000000.00.0000 realtime This will make gpsim try to synchronize simulation speed with wall clock time. \end_layout \begin_layout Section Source Browsers \end_layout \begin_layout Standard gpsim provides two views of your source: '. \emph on asm' \emph default and '. \emph on obj' \emph default browsers. The '. \emph on asm' \emph default browser is a color coded display of your pic source. \end_layout \begin_layout Subsection .asm Browser \end_layout \begin_layout Standard When a .cod file with source is loaded, there should be something in this display. (TODO: add section about high level debugging). \end_layout \begin_layout Standard There is an area to the left of the source, where symbols representing the program counter, breakpoints, etc are displayed. Double clicking in this area toggles breakpoints. You can drag these symbols up or down in order to move them and change the PC or move a breakpoint. \end_layout \begin_layout Standard A right button click on the source pops up a menu with six items (the word 'here' in some menu items denote the line in source the mouse pointer was on when right mouse button was clicked.): \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 \series bold Menu \begin_inset space ~ \end_inset item Description \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Find \begin_inset space ~ \end_inset PC This menu item will find the PC and changed page tab and scroll the source view to the current PC. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Run \begin_inset space ~ \end_inset here This sets a breakpoint 'here' and starts running until a breakpoint is hit. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Move \begin_inset space ~ \end_inset PC \begin_inset space ~ \end_inset here This simply changes PC to the address that line 'here' in source has. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Breakpoint \begin_inset space ~ \end_inset here Set a breakpoint 'here'. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Profile \begin_inset space ~ \end_inset start \begin_inset space ~ \end_inset here Set a start marker for routine profiling here. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Profile \begin_inset space ~ \end_inset stop \begin_inset space ~ \end_inset here Set a stop marker. (See the section for the profiling window.) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Select \begin_inset space ~ \end_inset symbol. This menu item is only available when some text is selected in the text widget. What it does is search the list of symbols for the selected word, and if it is found it is selected in the symbol window. Depending of type of symbol other things are also done, the same thing as when selecting a symbol in the symbol window: \begin_inset Separator latexpar \end_inset \end_layout \begin_deeper \begin_layout Itemize If it is an address, then the opcode and source views display the address. \end_layout \begin_layout Itemize If it's a register, the register viewer selects the cell. \end_layout \begin_layout Itemize If it's a constant, address, register or ioport, it is selected in the symbol window. \end_layout \end_deeper \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Find \begin_inset space ~ \end_inset text This opens up a search dialog. Every time you hit the 'Find' button, the current notebook page is found and the source in that page is used. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Settings A dialog with which you can change the fonts used. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000.0000 Controls A submenu containing the simulation commands. (these are also found as keyboard bindings (recommended), or in the main window.) \end_layout \begin_layout Standard These are the keyboard bindings: \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 \series bold Key command \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 s,S,F7 Step one instruction. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 o,O,F8 Step over instruction \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 r,R,F9 Run continuously. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 Escape Stop simulation. \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 f,F Run to return address \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 1..9 Step n instructions \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 ctrl-f Find text \end_layout \begin_layout Subsection Opcode view - the .obj Browser \end_layout \begin_layout Standard This window has two tabs. One with each memory cell on one line and information about address, hexadecima l value and decoded instruction (i.e. disassembly), and one with the program memory \end_layout \begin_layout Standard displayed with sixteen memory cells per row and a configurable ASCII column. \end_layout \begin_layout Subsubsection* The Assembly tab you can: \end_layout \begin_layout Itemize Double click on a line to toggle breakpoints. \end_layout \begin_layout Itemize Right click to get a menu where the breakpoint can be set or cleared on the selected line. \end_layout \begin_layout Itemize Under 'Settings' you can change the font. \end_layout \begin_layout Subsubsection* The Opcode tab. \end_layout \begin_layout Standard Here the program memory is ordered as columns of sixteen memory cells per column and as many row as needed to contain all memory. \end_layout \begin_layout Standard The seventeenth column contains an ASCII representation of the program memory. \end_layout \begin_layout Standard You can change font with the menu item 'Settings'. \end_layout \begin_layout Standard The breakpoints can be set or cleared on one or more (drag the mouse to select more cells) addresses with the right click menu. \end_layout \begin_layout Section Register views \end_layout \begin_layout Standard There are two similar register windows. One for the RAM and one for the EEPROM data, when available. \end_layout \begin_layout Standard Here you see all registers in the current processor. Clicking on a cell displays it's name and value above the sheet of registers. You can change values by entering it in the entry (or in the spreadsheet cell). \end_layout \begin_layout Standard The following things can be done on one register, or a range of registers. (Selecting a range of registers is done by holding down left mouse button, moving cursor, and releasing button.) \end_layout \begin_layout Itemize Set and clear breakpoints. Use the right mousebutton menu to pop up a menu where you can select set read, write, read value and write value breakpoints. You can also "clear breakpoints", notice the s in "clear breakpoints", every breakpoint on the registers are cleared. \end_layout \begin_layout Itemize Set and clear logging of registers. You can log reads, writes, reads/writes of specific values and to bits selected by a specified mask. You can select a different file name with 'set log filename...'. Default is "gpsim.log". You can choose LXT or ASCII format. LXT can be read with the program gtkwave. ASCII is default. \end_layout \begin_layout Itemize Copy cells. You copy cells by dragging the border of the selected cell(s). \end_layout \begin_layout Itemize Fill cells. Move mouse to lower right corner of the frame of the selected cell(s), and drag it. The one cell's contents will be copied to the other cells. \end_layout \begin_layout Itemize Watch them. Select the "Add Watch" menu item. \end_layout \begin_layout Standard The cells have different background colors depending on if they represent: \end_layout \begin_layout Itemize File Register (e.g. RAM): light cyan. \end_layout \begin_layout Itemize Special Function Registers (e.g. STATUS,TMR0): dark cyan \end_layout \begin_layout Itemize aliased register (e.g. the INDF located at address 0x80 is the same as the one located at address 0x00): gray \end_layout \begin_layout Itemize invalid register: black. If all sixteen registers in a row are invalid, then the row is not shown. \end_layout \begin_layout Itemize a register with one or more breakpoints: red. Logged registers are also red. \end_layout \begin_layout Standard gpsim dynamically updates the registers as the simulation proceeds. Registers that change value between updates of the window during simulation are highlighted with a blue foreground color. \end_layout \begin_layout Standard The menu also has a 'settings' item where you can change the font used. \end_layout \begin_layout Section Symbol view \end_layout \begin_layout Standard This window, as its name suggests, displays symbols. All of the special function registers will have entries in the symbol viewer. If you are using .cod files then you will additionally have file registers (that are defined in cblocks), equates, and address labels. \end_layout \begin_layout Standard You can filter out some symbol types using the buttons in the top of the window, and you can sort the rows by clicking on the column buttons (the ones reading 'symbol', 'type' and 'address'). \end_layout \begin_layout Standard You can add the symbol to the watch window by right-clicking and selecting the "Add to watch window" menu item. This will add the ram register with address equal to the symbols value to the watch window. \end_layout \begin_layout Standard The symbol viewer is linked to the other windows. For example, if you click on a symbol and: \end_layout \begin_layout Itemize If it is an address, then the opcode and source views display the address. \end_layout \begin_layout Itemize If it's a register, the register viewer selects the cell. \end_layout \begin_layout Section Watch view \end_layout \begin_layout Standard This is not a output-only window as the name suggests (change name?). You can both view and change data. Double-clicking on a bit toggles the bit. You add variables here by marking them in a register viewer and select \begin_inset Quotes eld \end_inset Add watch \begin_inset Quotes erd \end_inset from menu. The right-click menu has the following items: \end_layout \begin_layout Itemize Remove watch \end_layout \begin_layout Itemize Set register value \end_layout \begin_layout Itemize Clear Breakpoints \end_layout \begin_layout Itemize Set break on read \end_layout \begin_layout Itemize Set break on write \end_layout \begin_layout Itemize Set break on read value \end_layout \begin_layout Itemize Set break on write value \end_layout \begin_layout Itemize Columns... \end_layout \begin_layout Standard "Columns... \begin_inset Quotes erd \end_inset opens up a window where you can select which of the following data to display: \end_layout \begin_layout Itemize BP \end_layout \begin_layout Itemize Type \end_layout \begin_layout Itemize Name \end_layout \begin_layout Itemize Address \end_layout \begin_layout Itemize Dec \end_layout \begin_layout Itemize Hex \end_layout \begin_layout Itemize Bx (bits of word) \end_layout \begin_layout Standard You can sort the list of watches by clicking on the column buttons. Clicking twice sorts the list backwards. \end_layout \begin_layout Section Stack viewer \end_layout \begin_layout Standard This window displays current stack. Selecting an entry makes the code windows display the return address. Double clicking sets a breakpoint on the return address. \end_layout \begin_layout Section Breadboard \end_layout \begin_layout Standard Here you can create/modify and examine the environment around the pic. Pins are displayed as an arrow. The direction of the arrow indicates if its an input or output pin. The color of the arrow indicates its state (green=low, red=high). \end_layout \begin_layout Standard You can't instantiate pic processors from here, you will have to do that from the command line, or from a .stc file. \end_layout \begin_layout Standard Your can create nodes by clicking on the "new node" button. (A node is 'a piece of wire' to which you can connect stimulus.) You can see the list of created nodes under the "nodes" item in the upper-left tree widget. \end_layout \begin_layout Standard You can create connections to nodes by clicking on a pin, and then clicking on the button "Connect stimulus to node". This will bring up a list of nodes. Choose one by double-clicking on the one you like. \end_layout \begin_layout Standard If you click on a pin that is already connected to a node, then you will see the node and its connections in the lower left part of the window. You can disconnect a stimulus by clicking on it and pressing the "remove stimulus" button. \end_layout \begin_layout Standard When you want to add a module to the simulation, you first have to specify the library which contains the module you want. Click on the "add library" button and enter the library name (e.g. "libgpsim_modules.so"). Now you can click the "add module" button. Select the module you want from the list by double-clicking on it. Enter a name for the module (this has to be unique, and not used before). You now have to position the module. Move the mouse pointer to where you would like the module, and left-click. \end_layout \begin_layout Standard If you middle-click on a pin, you will see how the pin is connected. Press the "trace all" to see all at \end_layout \begin_layout Standard once, and "clear traces" to remove all (you will only remove the graphical trace, not the connection!). If the tracing doesn't work, try moving the packages so that there are more space around the pins. \end_layout \begin_layout Standard When you are done, you can save by clicking the "save configuration" button. You can then load this file from the command line like this (assuming the .cod file with your source is called "mycode.cod", and the file you just saved was called "mynets.stc": \end_layout \begin_layout LyX-Code gpsim -s mycode.cod -c mynets.stc \end_layout \begin_layout Standard You can't load only the .stc file since this doesn't contain the processor type and code. You can create (with an editor) your own .stc file (e.g. my_project.stc) and in that file put a command "load c mynets.stc" after you have loaded the .cod file. You then only have to load this file (gpsim -c my_project.stc). \end_layout \begin_layout Section Trace viewer \end_layout \begin_layout Standard This window shows the trace of instructions executed. See \begin_inset CommandInset ref LatexCommand ref reference "trace" \end_inset . \end_layout \begin_layout Section Profile viewer \end_layout \begin_layout Standard This window show execution count for program memory addresses. The profile window must be opened before starting simulation, because the tracing is not enabled by default. \end_layout \begin_layout Subsubsection Instruction profile \end_layout \begin_layout Standard This shows the number of times each instruction are executed. \end_layout \begin_layout Subsubsection Instruction range profile \end_layout \begin_layout Standard Here you can group ranges of instruction into one entry. \end_layout \begin_layout Standard The right click menu contains: \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Remove \begin_inset space ~ \end_inset range Remove an entry. \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Add \begin_inset space ~ \end_inset range... Open a dialog from where you can add a range of instructions as an entry. \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Add \begin_inset space ~ \end_inset all \begin_inset space ~ \end_inset labels Add all code labels as ranges. \end_layout \begin_layout Labeling \labelwidthstring 00000000.00.0000 Snapshot \begin_inset space ~ \end_inset to \begin_inset space ~ \end_inset plot Open a window containing a graph of the data. From this new window you can also save (postscript) or print it. \end_layout \begin_layout Subsubsection* Register profile \end_layout \begin_layout Standard This shows the number of reads or writes the simulator does on register. \end_layout \begin_layout Subsubsection* Routine profile \end_layout \begin_layout Standard Here you can see statistics about execution time for a selected routine. You mark the entry and exit points from the source browser (profile start/stop). If the routine you want to measure have multiple entry and/or exit points, then you have to put a marker on every entry point as well as (and especially) every exit point. Otherwise you will get bad data. \end_layout \begin_layout Standard When you have done that, gpsim will (as simulation goes by) store the execution times of that routine and calculate min/max/average/etc. You can also use the menu item 'Plot distribution' to open a window displaying a histogram of the data. From this new window you can also save (in postscript) or print it. \end_layout \begin_layout Standard You can also measure call period by switching the 'entry' and 'exit' points. If also want the time from reset (or some equal point) to the first 'entry', then you must also put an 'entry' point there. \end_layout \begin_layout Section Stopwatch \end_layout \begin_layout Standard The stopwatch window shows a cycle counter and a re-settable counter. The cycle counter is the same as the one in the register window. It basically counts instructions. \end_layout \begin_layout Standard The other counter counts at the same rate as the cycle counter, but can be cleared by clicking the "clear" button (or preset by entering a number in the entry box). \end_layout \begin_layout Standard The up/down indicator denotes the direction the counter counts. \end_layout \begin_layout Standard The rollover value specifies the range the cycle counter can be in (a modulo counter). For example, if the rollover value is specified to be 0x42, then whenever the resettable counter reaches 0x42 it will rollover to zero. If the counter is counting down, then when it reaches 0 the next state will be 0x41. If you don't want is like this, then set the rollover value to something large. \end_layout \begin_layout Section Scope Window \end_layout \begin_layout Standard FIXME: The scope window still needs some work... \end_layout \begin_layout Standard The Scope Window graphs I/O pin states. It is similar to an oscilloscope or logic analyzer. It can be controlled either from the command line or from the GUI. Currently only the digital state of I/O pins are supported. \end_layout \begin_layout Standard To use the scope window, each scope channel being used must first be connected to the stimulus being tracked. This can only be done on the command line (or via the .sim directive in the .asm file). The following example shows how this is done, but note that in the .sim command the ' \begin_inset Quotes erd \end_inset 's need to be escaped with a ' \backslash '. \end_layout \begin_layout LyX-Code **gpsim> scope.ch0 = \begin_inset Quotes eld \end_inset portc3 \begin_inset Quotes erd \end_inset \end_layout \begin_layout LyX-Code **gpsim> scope.ch1 = \begin_inset Quotes eld \end_inset portc4 \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard Once the data are captured, the scope window display may need to be altered to better see the data. In the GUI, the following keys can be used: \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 z Zoom In \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 Z Zoom out \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 l Pan left \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 r Pan right \end_layout \begin_layout Standard In the command line, zooming and panning can be achieved by modifying the scope.start and scope.end variables. \end_layout \begin_layout Chapter Scripting and Configuring \end_layout \begin_layout Standard gpsim does not have a native scripting language per se. However it is possible to place gpsim commands into a file and load them later. This is useful for loading modules and stimuli and connecting various devices together. By convention, gpsim's configuration files have the extension \emph on .stc \emph default , for \emph on st \emph default artup \emph on c \emph default onfiguration. \end_layout \begin_layout Section Embedded Commands \end_layout \begin_layout Standard If you're using gputils, it is possible to embed configuration commands directly into your PIC assembly source. The gputils supplied include file \emph on coff.inc \emph default contains several macros that embed simulation command into a COFF and COD files. \end_layout \begin_layout Subsection .sim macro \end_layout \begin_layout LyX-Code ; Simulator Command \end_layout \begin_layout LyX-Code .sim macro x \end_layout \begin_layout LyX-Code .direct "e", x \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Standard The \family typewriter \emph on .sim \family default \emph default \family typewriter macro allows gpsim configuration commands to be embedded in the PIC source. While gpsim loads a .cod file, the commands in the \family default \family typewriter \emph on .sim \family default \emph default \family typewriter macros are collected. After the .cod file is loaded, the commands are redirected to gpsim's command line interpreter in the order they were received. \end_layout \begin_layout Standard Here's an example of switch module being loaded and configured: \end_layout \begin_layout LyX-Code ;# Module libraries: \end_layout \begin_layout LyX-Code .sim "module library libgpsim_modules" \end_layout \begin_layout LyX-Code .sim "module load switch SW1" \end_layout \begin_layout LyX-Code .sim "SW1.state=false" \end_layout \begin_layout LyX-Code .sim "SW1.xpos = 216.0" \end_layout \begin_layout LyX-Code .sim "SW1.ypos = 156.0" \end_layout \begin_layout LyX-Code .sim "SW1.Ropen = 1.0e8" \end_layout \begin_layout Standard This loads gpsim's module library, instantiates a switch module, and configures the switch's attributes. \end_layout \begin_layout Subsection .command macro \end_layout \begin_layout LyX-Code .command macro x \end_layout \begin_layout LyX-Code .direct "c", x \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Standard The \family typewriter \emph on .command \family default \emph default \family typewriter macro is similar to a \family default \family typewriter \emph on .sim \family default \emph default \family typewriter macro except that it associates a gpsim command with a particular instruction. This is useful for changing attribute values at different points of the program. \end_layout \begin_layout Subsection .assert macro \end_layout \begin_layout LyX-Code ; Assertion \end_layout \begin_layout LyX-Code .assert macro x \end_layout \begin_layout LyX-Code .direct "a", x \end_layout \begin_layout LyX-Code endm \end_layout \begin_layout Standard The \emph on .assert \emph default macro provides a source code mechanism for setting breakpoints (see chapter \begin_inset CommandInset ref LatexCommand ref reference "cha:Assertions-and-Extended" \end_inset ). An assertion is an expression associated with a specific instruction. It essentially means, \begin_inset Quotes eld \end_inset If the expression at this instruction evaluates to false, then halt the simulation. \begin_inset Quotes erd \end_inset \end_layout \begin_layout LyX-Code ; Close the switch. Because of capacitance, portc1 will go high after a delay: \end_layout \begin_layout LyX-Code ; R=145, C=4.2e-6 TC=6.11e-4 or 1527 cycles, 0-2 volts requires 0.51 Tc \end_layout \begin_layout LyX-Code .command "SW1.state=closed" \end_layout \begin_layout LyX-Code nop \end_layout \begin_layout LyX-Code ; portc0 should be same as portc1 \end_layout \begin_layout LyX-Code .assert "(portc & 3) == 0, \backslash "SW1 closed, cap holds low \backslash "" \end_layout \begin_layout LyX-Code nop \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard In this example, the \emph on .command \emph default macro writes to the switch module's \emph on .state \emph default attribute (see section \begin_inset CommandInset ref LatexCommand ref reference "subsec:Switches-&-Resistors" \end_inset ). Just prior to executing the first nop instruction, the switch will be closed. The \emph on .assert \emph default macro at the very next instruction makes sure that the expected state is seen on PORTC. \end_layout \begin_layout Section Sockets \end_layout \begin_layout Standard gpsim supports a socket interface. This is inhibited by default. Advanced users may wish to study code in the \emph on examples/scripts \emph default subdirectory. This code is not distributed and is only available in the subversion repository. \end_layout \begin_layout Chapter \begin_inset CommandInset label LatexCommand label name "cha:Assertions-and-Extended" \end_inset Assertions and Extended Breakpoints \end_layout \begin_layout Standard gpsim supports a wide variety of breakpoints and assertions. Many of these were described with the break command. This section will illustrate how to extend the break command even further and introduce simulation assertions. \end_layout \begin_layout Subsection* Breakpoint Messages \end_layout \begin_layout Standard A breakpoint message is an ASCII string that is displayed whenever a breakpoint is encountered. Any break point can have an associated message. The syntax at the command line is \end_layout \begin_layout LyX-Code break conditions, \begin_inset Quotes eld \end_inset \emph on This is a breakpoint message \emph default \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard The conditions are described above in the break command and are the conditions under which the break occurs. \end_layout \begin_layout Standard Breakpoint messages are useful for distinguishing among many different breakpoin ts. \end_layout \begin_layout LyX-Code break w counter & 0xf0 == 0x80, \begin_inset Quotes eld \end_inset Counter overflowed! \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard In this example, the user is monitoring the upper nibble of the variable counter and breaking whenever it is equal to 8. When the command is entered, gpsim will display: \end_layout \begin_layout LyX-Code break when bit pattern 1000XXXX is written to register counter(0x26). break #: 0x20 \end_layout \begin_layout Standard The breakpoint can be queried with the break command: \end_layout \begin_layout LyX-Code gpsim> \emph on break 32 \end_layout \begin_layout LyX-Code 32: p18f452 register write value: [0x26] & 0xf0 == 0x8 \end_layout \begin_layout LyX-Code Message:Counter overflowed! \end_layout \begin_layout Standard When the simulation encounters the break, execution halts and the message is printed. \end_layout \begin_layout Section Assertions and Embedded Simulation commands \end_layout \begin_layout Standard gpsim's breakpoint design is a powerful tool that can catch many problems. The assertion design extends this power even further. An assertion is like a breakpoint that is defined in the program source code for a particular instruction. gpsim reads the breakpoint from a special message area in the .cod file. For example, you may have a routine that requires BANK 0 be selected. A gpsim assertion can be placed at the entry of the routine to verify that this is the case. \end_layout \begin_layout LyX-Code .assert "(status & 0x60) == 0, \backslash "Bank 0 must be selected! \backslash "" \end_layout \begin_layout Standard The syntax is identical to the extended breakpoint command. The expression is the condition that is checked. If the expression evaluates to false, then the code halts and prints the message. The \emph on .assert \emph default is a macro that is part of gputils. It requires a string as its input argument. Notice that the assertion message is embedded in the argument. gpasm and MPASM copy C's method of placing a backslash in front of quotations that are part of a string. \end_layout \begin_layout Subsection* Command Assertions \end_layout \begin_layout Standard A command assertion is a gpsim associated with a particular instruction in your PIC source code. These are useful for changing the behavior of the simulation based on where the code executes. Almost any gpsim command can be placed in a command assertion. However, the most useful ones are assignment commands. For example: \end_layout \begin_layout LyX-Code .command \begin_inset Quotes eld \end_inset SW1.state = open \begin_inset Quotes erd \end_inset \end_layout \begin_layout Standard This assignment writes to the state attribute of a switch module named SW1. \end_layout \begin_layout Chapter Trace and Log: What has happen? \begin_inset CommandInset label LatexCommand label name "trace" \end_inset \end_layout \begin_layout Standard Inspecting the current state of your program is sometimes insufficient to determine the cause of a bug. Often times it's useful to know the conditions that led up to the current state. gpsim provides a history or trace of everything that occurs - whether you want it or not - to help you diagnose these otherwise difficult to analyze bugs. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout What's traced \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout notes \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout program counter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout addresses executed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout instructions \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout opcode \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout register read \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout value and location \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout register write \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout value and location \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout cycle counter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout current value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout skipped instructions \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout addresses skipped \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout status register \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout during implicit modification \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout interrupts \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout break points \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout resets \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The 'trace' command will dump the contents of the trace buffer. \end_layout \begin_layout Standard A large circular buffer (whose size is hard coded) stores the information for the trace buffer. When it fills, it will wrap around and write over the old history. The contents of the trace buffer are parsed into frames, where one frame corresponds to a simulation cycle. \end_layout \begin_layout Standard Here's an example of a trace output: \end_layout \begin_layout LyX-Code gpsim> trace \end_layout \begin_layout LyX-Code 0x00000000000026F6 p18f452 0x001C 0x1003 iorwf reg3,w,0 \end_layout \begin_layout LyX-Code Read: 0x00 from reg3(0x0003) \end_layout \begin_layout LyX-Code Wrote: 0xE7 to W(0x0FE8) was 0xE7 \end_layout \begin_layout LyX-Code Wrote: 0x18 to status(0x0FD8) was 0x18 \end_layout \begin_layout LyX-Code 0x00000000000026F7 p18f452 0x001E 0xE1F4 bnz $-0x16 ;(0x8) \end_layout \begin_layout LyX-Code 0x00000000000026F8 p18f452 0x0008 0x3E00 incfsz reg,f,0 \end_layout \begin_layout LyX-Code Read: 0xE4 from reg(0x0000) \end_layout \begin_layout LyX-Code Wrote: 0xE5 to reg(0x0000) was 0xE4 \end_layout \begin_layout LyX-Code 0x00000000000026F9 p18f452 0x000A 0xD004 bra $+0xa ;(0x00014) 0x00000000000 026FA p18f452 0x0014 0x0004 clrwdt \end_layout \begin_layout LyX-Code 0x00000000000026FB p18f452 0x0016 0x5000 movf reg,w,0 \end_layout \begin_layout LyX-Code Read: 0xE5 from reg(0x0000) \end_layout \begin_layout LyX-Code Wrote: 0xE5 to W(0x0FE8) was 0xE7 \end_layout \begin_layout LyX-Code Wrote: 0x18 to status(0x0FD8) was 0x18 \end_layout \begin_layout LyX-Code 0x00000000000026FC p18f452 0x0018 0x1001 iorwf reg1,w,0 \end_layout \begin_layout LyX-Code Read: 0x03 from reg1(0x0001) \end_layout \begin_layout LyX-Code Wrote: 0xE7 to W(0x0FE8) was 0xE5 \end_layout \begin_layout LyX-Code Wrote: 0x18 to status(0x0FD8) was 0x18 \end_layout \begin_layout Standard Each trace frame begins with a new simulation cycle. Typically this will include a simulated instruction. Here's each of the fields: \end_layout \begin_layout LyX-Code \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout 64-bit simulation cycle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout processor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PC \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout opcode \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout instruction \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x00000000000026F6 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout p18f452 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x001C \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x1003 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout iorwf reg3,w,0 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard Other events that occur during the trace frame are indented. Typically these will be register read or write traces. The read traces show the value read. Write traces show the value written and the value that was previously in the register. \end_layout \begin_layout Section* Saving Trace to a file \end_layout \begin_layout Standard The trace buffer may contain thousands of entries making it difficult to search. The trace save feature will allow the trace buffer to be written to a file. \end_layout \begin_layout LyX-Code gpsim> trace save mytrace.log \end_layout \begin_layout Standard The entire contents of the trace buffer are decoded and written to the file. The format of the trace is the same as it is when displayed at the command line. \end_layout \begin_layout Section* Raw Traces \end_layout \begin_layout Standard The \emph on raw \emph default trace buffer is the trace buffer displayed in a minimally decoded form. This is primarily used for gpsim development. When saved to a file, the raw trace is not decoded at all. In addition, the processor's state is written to the file. Thus third party tools can be written to create custom trace reports \begin_inset Foot status collapsed \begin_layout Plain Layout FIXME - The dynamically created trace type information needs to be written to this file too. Without it, it is difficult to tell what each traced item is. \end_layout \end_inset . \end_layout \begin_layout Chapter \begin_inset CommandInset label LatexCommand label name "cha:Simulating-the-Real" \end_inset Simulating the Real World: Stimuli \begin_inset Index idx status collapsed \begin_layout Plain Layout Stimulus \end_layout \end_inset \end_layout \begin_layout Standard Stimuli are extremely useful, if not necessary, for simulations. They provide a means for simulating interactions with the real world. \end_layout \begin_layout Standard The gpsim stimuli capability is designed to be accurate, efficient and flexible. The models for the PIC's I/O pins mimic the real devices. For example, the open collector output on port A of a PIC16C84 can only drive low. Multiple I/O pins may be tied to one another so that the open collector on port A can get a pull up resistor from port B. The overhead for stimuli only occurs when a stimulus changes states. In other words, stimuli are not polled to determine their state. \end_layout \begin_layout Standard Analog stimuli are also available. It's possible to create voltage references and sources to simulate almost any kind of real world thing. For example, it's possible to combine two analog stimuli together to create signals like DTMF tones. \end_layout \begin_layout Standard Note, however, that gpsim does not attempt to be a full electronic circuit simulator, and certain approximations made for efficiency will cause inaccuracy in complex simulation environments. \end_layout \begin_layout Section How They Work \end_layout \begin_layout Standard In the simplest case, a stimulus acts a source for an I/O pin on a PIC. For example, you may want to simulate a clock and measure its period using TMR0. In this case, the stimulus is the source and the TMR0 input pin on the pic is the load. In gpsim you would create a stimulus for the clock using the stimulus command and connect it to the I/O pin using the node command. \end_layout \begin_layout Standard In general, you can have several 'sources' and several 'loads' that are interconnected with nodes \begin_inset Foot status collapsed \begin_layout Plain Layout Although, gpsim is currently limited to 'one-port' devices. In other words, it is assumed that ground serves as a common reference for the sources and the loads. \end_layout \end_inset . A good analogy is a spice circuit. The spice netlist corresponds to a node-list in gpsim and the spice elements correspond to the stimuli sources and loads. This general approach makes it possible to create a variety of simulation environments. Here's a list of different ways in which stimuli may be connected: \end_layout \begin_layout Enumerate Stimulus connected to one I/O pin \end_layout \begin_layout Enumerate Stimulus connected to several I/O pins \end_layout \begin_layout Enumerate Several stimuli connected to one I/O pin \end_layout \begin_layout Enumerate Several stimuli connected to several I/O pins \end_layout \begin_layout Enumerate I/O pins connected to I/O pins \end_layout \begin_layout Standard The general technique for implementing stimuli is as follows: \end_layout \begin_layout Enumerate Define the stimulus or stimuli. \end_layout \begin_layout Enumerate Define a node. \end_layout \begin_layout Enumerate Attach the stimuli to the node. \end_layout \begin_layout Standard More often than not, the stimulus definition will reside in a file. \end_layout \begin_layout Subsection Contention among stimuli \end_layout \begin_layout Standard One of the problems with this nodal approach to modeling stimuli is that it's possible for contention to exist. For example, if two I/O pins are connected to one another and driving in the opposite directions, there will be contention. gpsim resolves contention with attribute summing. Each stimulus - even if it's an input - has an effect on the node. This effect is characterised by a voltage and an impedance. When a node is updated, gpsim performs a Thevenin voltage summing of all the stimuli together. The resultant voltage is then propagated to all connected stimuli as the current state of the node. \end_layout \begin_layout Standard For example, in the port A open collector / port B weak pull-up connection example, gpsim assigns a voltage of 5V with an impedance of 20kohms to the pull up resistor, and a voltage of 0V with an impedance of 150ohms to the open collector if it is active, or 100Mohms if it's not driving. The Thevenin sum will be roughly 0.05V if the output is driving, or 5V otherwise. Capacitive effects are not currently supported. \end_layout \begin_layout Section I/O Pins \end_layout \begin_layout Standard gpsim models I/O pins as stimuli. Thus anywhere a stimulus is used, an I/O pin may be substituted. For example, you may want to tie two I/O pins to one another; like a port B pull up resistor to a port A open collector. gpsim automatically creates the I/O pin stimuli whenever a processor is created. All you need to do is to specify a node and then attach the stimuli to it. The names of these stimuli are formed by concatenating the port name with the bit position of the I/O pin. For example, bit 3 in port B is called portb3. \end_layout \begin_layout Standard Here's a list of the types of I/O pin stimuli that are supported: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout I/O Pin Type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Function \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout INPUT_ONLY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Only accepts input (like MCLR) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout BI_DIRECTIONAL \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Can be a source or a load (most I/O pins) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout BI_DIRECTIONAL_PU \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PU=Pullup resistor (PORTB) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout OPEN_COLLECTOR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Can only drive low (RA4 on c84) \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard There is no special pin type for analog I/O pins. All pic analog inputs are multiplexed with digital inputs. The I/O pin definition will always be for the digital input. gpsim automatically knows when I/O pin is analog input. \end_layout \begin_layout Section Asynchronous Stimuli \end_layout \begin_layout Standard Asynchronous stimuli are analog or digital stimuli that can change states at any given instant (limited to the resolution of the cycle counter). They can be defined to be repetitive too. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout function \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout start_cycle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The # of cycles before the stimulus starts \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout cycles[] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout An array of cycle #'s \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout data[] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Stimulus state for a cycle \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The # of cycles for one period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout initial_state \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The initial state before data[0] \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard When the stimulus is first initialized, it will be driven to the 'initial state' and will remain there until the cpu's instruction cycle counter matches the specified 'start' cycle. After that, the two arrays 'cycles[]' and 'data[]' define the stimulus' outputs. The size of the arrays are the same and correspond to the number of events that are to be created. So the event number, if you will, serves as the index into these arrays. The 'cycles[]' array define when the events occur while the 'data[]' array defines the states the stimulus will enter. The 'cycles[]' are measured with respect to the 'start' cycle. The asynchronous stimulus can be made periodic by specifying the number of cycles in the 'period' parameter. \end_layout \begin_layout Standard Here's an example that generates three pulses and then repeats: \end_layout \begin_layout LyX-Code stimulus asynchronous_stimulus # or we could have used asy \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code # The initial state AND the state the stimulus is when \end_layout \begin_layout LyX-Code # it rolls over \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code initial_state 1 \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code # all times are with respect to the cpu's cycle counter \end_layout \begin_layout LyX-Code start_cycle 100 \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code # the asynchronous stimulus will roll over in 'period' \begin_inset Newline newline \end_inset # cycles. Delete this line if you don't want a roll over. \end_layout \begin_layout LyX-Code period 5000 \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code # Now the cycles at which stimulus changes states are \end_layout \begin_layout LyX-Code # specified. The initial cycle was specified above. So \begin_inset Newline newline \end_inset # the first cycle specified below will toggle this state. \end_layout \begin_layout LyX-Code # In this example, the stimulus will start high. \end_layout \begin_layout LyX-Code # At cycle 100 the stimulus 'begins'. However nothing happens \end_layout \begin_layout LyX-Code # until cycle 200+100. \end_layout \begin_layout LyX-Code { 200, 0, \end_layout \begin_layout LyX-Code 300, 1, \end_layout \begin_layout LyX-Code 400, 0, \end_layout \begin_layout LyX-Code 600, 1, \end_layout \begin_layout LyX-Code 1000, 0, \end_layout \begin_layout LyX-Code 3000, 1 } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code # Give the stimulus a name: \end_layout \begin_layout LyX-Code name asy_test \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code # Finally, tell the command line interface that we're done \end_layout \begin_layout LyX-Code # with the stimulus \end_layout \begin_layout LyX-Code end \end_layout \begin_layout Subsection Analog Asynchronous Stimuli \end_layout \begin_layout Standard Analog Asynchronous Stimuli are identical to Synchronous Stimuli except the data points are floating point numbers. \end_layout \begin_layout Section Extended Stimuli \end_layout \begin_layout Standard Discuss the extended stimuli in the modules/ directory. In particular, describe the \emph on PulseGen \emph default module and how it can complete replace the asynchronous stimuli. Also describe the \emph on PullUp \emph default and \emph on PullDown \emph default modules and how they can be manipulated into being general purpose DC voltage sources (FIXME, would it make sense to rename these modules?). \end_layout \begin_layout Section Limitations of the Stimulus Mechanism \end_layout \begin_layout Standard The simulation of external devices using gpsim stimuli and nodes is intended to assist in PIC software debugging, not electronic circuit design. As such it takes a simplified approach to certain things. \end_layout \begin_layout Subsection Propagation Delays \end_layout \begin_layout Standard gpsim makes no attempt to simulate propagation delays in the circuit. Usually this is not a problem. However, when using modules \begin_inset CommandInset ref LatexCommand ref reference "cha:Modules" \end_inset to expand gpsim's environment, it is possible to create situations where it matters. For example, daisy-chaining two or more shift registers with a shared clock relies on the propagation delay of the first register to ensure the second shifts the correct data in. Since gpsim does not simulate this delay, the results may be wrong \begin_inset Foot status collapsed \begin_layout Plain Layout They may be right, it depends on execution order, which is subtle. \end_layout \end_inset . \end_layout \begin_layout Chapter Modules \begin_inset Index idx status collapsed \begin_layout Plain Layout Modules \end_layout \end_inset \begin_inset CommandInset label LatexCommand label name "cha:Modules" \end_inset \end_layout \begin_layout Standard gpsim has been designed to debug microprocessors. However, microprocessors are always a part of a system. And invariably, the bugs one often encounters are those that are a result of interfacing with a system. Modules provide users with a way to extend gpsim and simulate a system. For example, the \emph on system \emph default may be a processor with a few pull up resistors and switches or it may be a processor and an LCD display. gpsim provides a few modules that one may use either for debugging or as templates for creating new modules. \end_layout \begin_layout Standard Note that gpsim's modules are provided to facilitate debugging of the PIC code, not the hardware. gpsim does not attempt to be a circuit simulator by itself. If you need that functionality, the gpsim core can be embedded into third party simulators. \end_layout \begin_layout Standard Modules reside in a library and are dynamically loaded with the \emph on module \emph default command. All modules have I/O pins which can connect to other modules or processors. Most modules provide \emph on attributes \emph default that allow the user to control a module's behavior or query its internal state. For example, the USART module has transmit and receive baud rate attributes that may be configured: \end_layout \begin_layout LyX-Code gpsim> U1.txbaud = 9600 # set the transmit rate \end_layout \begin_layout LyX-Code gpsim> U1.rxbaud # query the receiver rate \end_layout \begin_layout LyX-Code 9600 \end_layout \begin_layout Standard The symbol command can be used to query all attributes of a module. \end_layout \begin_layout LyX-Code gpsim> symbol U1. # note the period \end_layout \begin_layout LyX-Code U1 = USARTModule \end_layout \begin_layout LyX-Code U1.console = false \end_layout \begin_layout LyX-Code U1.crlf = true \end_layout \begin_layout LyX-Code U1.loop = true \end_layout \begin_layout LyX-Code U1.rx = 0 \end_layout \begin_layout LyX-Code U1.rxbaud = 9600 \end_layout \begin_layout LyX-Code U1.tx = 0 \end_layout \begin_layout LyX-Code U1.txbaud = 9600 \end_layout \begin_layout LyX-Code U1.xpos = 72.00000000000000 \end_layout \begin_layout LyX-Code U1.ypos = 276.0000000000000 \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard Modules may provide help which can be accessed using the help command: \end_layout \begin_layout LyX-Code gpsim> help U1 \end_layout \begin_layout LyX-Code USARTModule \end_layout \begin_layout LyX-Code no description \end_layout \begin_layout Standard Well, the USART module isn't the best example here! However, a better example is one of the USART attributes. \end_layout \begin_layout LyX-Code gpsim> help U1.txbaud \end_layout \begin_layout LyX-Code 9600 \end_layout \begin_layout LyX-Code USART Module Transmitter baud rate \end_layout \begin_layout LyX-Code \end_layout \begin_layout Section gpsim Modules \end_layout \begin_layout Standard gpsim provides a library of useful modules for simulation. The current version includes the following modules: \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout pushbutton \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout pullup \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A resistor connected (nominally) to Vdd \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout pulldown \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A resistor connected (nominally) to Vss \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout usart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A serial interface with a GUI terminal window \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout pulsegen \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout I2C-EEPROM2K \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 256 byte I2C serial EEPROM like the 24LC024. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout I2C-EEPROM16K \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 2k byte I2C serial EEPROM like the 24LC16B. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout I2C-EEPROM256K \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 32k byte I2C serial EEPROM like the 24LC256. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout i2c2par \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A slave I2C device with an 8 bit I/O port \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout switch \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Switch, which connects two nodes together \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2-input logical AND gate \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2-input logical OR gate \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout xor2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2-input logical XOR gate \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout not \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Inverter (logical NOT gate) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout led_7segments \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 7-segment LED digit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout led \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A single pin LED which can be active either high or low \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TTL377 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 74xx377 style 8-bit tristate latch \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TTL165 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 74xx165 parallel-in-serial-out shift register \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TTL595 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout A 74xx595 serial-in-parallel-out shift register \end_layout \end_inset \end_inset \end_layout \begin_layout Subsection USART \begin_inset Index idx status collapsed \begin_layout Plain Layout USART module \end_layout \end_inset \end_layout \begin_layout Standard The USART module is a full duplex configurable USART. In graphics mode, the USART will display its output in a console. In addition, the console will accept keyboard input. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard .tx - The \emph on .tx \emph default attribute is the USART transmit register. Data written to this attribute will initiate a transmission. The USART supports a transmit FIFO, making it possible to stuff several bytes into the transmit queue while the program under test is paused. \end_layout \begin_layout Standard .rx - The \emph on .rx \emph default attribute is the USART receiver register. Data received by the USART is available for querying through here. \end_layout \begin_layout Standard .txbaud - The \emph on .txbaud \emph default attribute specifies the transmitter baud rate. \end_layout \begin_layout Standard .rxbaud - The .rxbaud attribute specifies the receiver baud rate. \end_layout \begin_layout Standard .console - When set to \emph on true \emph default , the console window will display received data and will accept keyboard entries for the transmitter. \end_layout \begin_layout Standard .crlf - When set to \emph on true \emph default , carriage returns and line feeds generate new lines in the console window. \end_layout \begin_layout Standard .hex - When set to \emph on true \emph default , the data is assumed to be binary and all bytes are shown in hex. \end_layout \begin_layout Standard .loop - When set to true, received characters are looped back to the transmitter. \end_layout \begin_layout Standard .xpos - horizontal position in breadboard window. \end_layout \begin_layout Standard .ypos - vertical position in breadboard window. \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .TXPIN - transmit pin \end_layout \begin_layout Standard .RXPIN - receiver pin \end_layout \begin_layout Standard .CTS - Clear to send pin. This can be left unconnected \end_layout \begin_layout Standard .RTS - Request to send pin. \end_layout \begin_layout Subsection Logic \begin_inset Index idx status collapsed \begin_layout Plain Layout Logic \end_layout \end_inset \end_layout \begin_layout Standard The only attributes supported be the logic devices are the standard \emph on .xpos \emph default and \emph on .ypos \emph default breadboard positions. \begin_inset Note Greyedout status collapsed \begin_layout Plain Layout FIXME There should be attributes to specify the switching characteristics. \end_layout \end_inset \end_layout \begin_layout Subsection* and2 \begin_inset Index idx status collapsed \begin_layout Plain Layout and2 \end_layout \end_inset - Two input AND gate \end_layout \begin_layout Subsubsection* I/O pins \end_layout \begin_layout Standard .in0 - First input \end_layout \begin_layout Standard .in1 - First input \end_layout \begin_layout Standard .out - Output \end_layout \begin_layout Subsection* or2 \begin_inset Index idx status collapsed \begin_layout Plain Layout or2 \end_layout \end_inset - Two input OR gate \end_layout \begin_layout Standard .in0 - First input \end_layout \begin_layout Standard .in1 - First input \end_layout \begin_layout Standard .out - Output \end_layout \begin_layout Subsection* xor2 \begin_inset Index idx status collapsed \begin_layout Plain Layout xor2 \end_layout \end_inset - Two input XOR gate \end_layout \begin_layout Standard .in0 - First input \end_layout \begin_layout Standard .in1 - First input \end_layout \begin_layout Standard .out - Output \end_layout \begin_layout Subsection* not \begin_inset Index idx status collapsed \begin_layout Plain Layout not \end_layout \end_inset - Inverter \end_layout \begin_layout Standard .in0 - Input \end_layout \begin_layout Standard .out - Output \end_layout \begin_layout Subsection* TTL377 \begin_inset Index idx status collapsed \begin_layout Plain Layout ttl377 \end_layout \end_inset - Octal Latch \end_layout \begin_layout Standard The TTL377 module simulates an 8-bit parallel latch with output enable. It latches all bits simultaneously so that connecting an output to an input gives correct results. However, this is not guaranteed where multiple modules are so connected. \end_layout \begin_layout Standard .D0..7 - Input \end_layout \begin_layout Standard .Q0..7 - Output \end_layout \begin_layout Standard .E - output enable \end_layout \begin_layout Standard .CP - clock (rising edge) \end_layout \begin_layout Subsection* TTL165 \begin_inset Index idx status collapsed \begin_layout Plain Layout ttl165 \end_layout \end_inset - Parallel to Serial Shift Register \end_layout \begin_layout Standard The TTL165 module simulates an 8-bit parallel input serial output shift register. It is particularly useful for connecting to a SPI peripheral. Note, however, that the common practice of daisy-chaining such shift registers is not guaranteed to simulate correctly. \end_layout \begin_layout Standard .D0..7 - parallel input \end_layout \begin_layout Standard .Ds - daisy-chain serial input \end_layout \begin_layout Standard .Q7 - output \end_layout \begin_layout Standard .nQ7 - inverted output \end_layout \begin_layout Standard .CE - clock enable \end_layout \begin_layout Standard .CP - clock (rising edge) \end_layout \begin_layout Standard .PL - parallel load \end_layout \begin_layout Subsection* TTL595 \begin_inset Index idx status collapsed \begin_layout Plain Layout ttl595 \end_layout \end_inset - Serial to Parallel Shift Register \end_layout \begin_layout Standard The TTL595 module simulates an 8-bit serial input parallel output shift register. It is particularly useful for connecting to a SPI peripheral. Note, however, that the common practice of daisy-chaining such shift registers is not guaranteed to simulate correctly. \end_layout \begin_layout Standard .Q0..7 - parallel output \end_layout \begin_layout Standard .Ds - serial input \end_layout \begin_layout Standard .Qs - daisy-chain serial output \end_layout \begin_layout Standard .OE - output enable \end_layout \begin_layout Standard .SCK - shift clock (rising edge) \end_layout \begin_layout Standard .RCK - output latch clock (rising edge) \end_layout \begin_layout Standard .MR - master reset \end_layout \begin_layout Subsection I2C EEPROM \begin_inset Index idx status collapsed \begin_layout Plain Layout I2C EEPROM \end_layout \end_inset \end_layout \begin_layout Standard There are currently three I2C EEPROMs supported: I2C-EEPROM2k, I2C-EEPROM16k, and I2C-EEPROM256K. \end_layout \begin_layout Standard The commands 'dump e module_name filename' and 'load e module_name filename' can be used to save and restore the contents of the EEPROM module. This allows the contents of the EEPROM to be preserved between runs of gpsim. \end_layout \begin_layout Standard The cells of the EEPROM can be examined and modified using the command interface with the commands 'module_name.eeData[index]' and 'module_name.eeData[index] = new_value'. The following example shows loading an EEPROM module, setting cell 16 to '0' (0x30) and checking that the new value was written. \end_layout \begin_layout LyX-Code **gpsim> module load I2C-EEPROM16k e2 \end_layout \begin_layout LyX-Code **gpsim> \end_layout \begin_layout LyX-Code **gpsim> e2.eeData[16] = $30 \end_layout \begin_layout LyX-Code **gpsim> e2.eeData[16] \end_layout \begin_layout LyX-Code e2.eeData[$10] = $30 \end_layout \begin_layout LyX-Code **gpsim> \end_layout \begin_layout Standard \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .A0 - Chip select to set bit 0 of slave address \end_layout \begin_layout Standard .A1 - Chip select to set bit 1 of slave address \end_layout \begin_layout Standard .A2 - Chip select to set bit 2 of slave address \end_layout \begin_layout Standard .SCL - I2C serial clock \end_layout \begin_layout Standard .SDA - I2C serial data \end_layout \begin_layout Standard .WP - Hardware write protect \end_layout \begin_layout Subsection \begin_inset CommandInset label LatexCommand label name "subsec:Switches-&-Resistors" \end_inset Switches \begin_inset Index idx status collapsed \begin_layout Plain Layout Switches \end_layout \end_inset & Resistors \begin_inset Index idx status collapsed \begin_layout Plain Layout Resistors \end_layout \end_inset \end_layout \begin_layout Standard The \emph on switch \emph default module is a model of a simple two terminal switch. It may be controlled either from the command line or the breadboard GUI. The \emph on switch \emph default module's open and closed resistance are controlled by attributes. Thus a two terminal resistor can be modeled as a switch that is always closed (or open). \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard .Ropen - Switch resistance in ohms when the switch is opened. \end_layout \begin_layout Standard .Rclosed - Switch resistance in ohms when the switch is closed. \end_layout \begin_layout Standard .state - Switch state. The switch state takes the values of \emph on open \emph default or \emph on closed \emph default , although \emph on false \emph default for open and \emph on true \emph default for closed is supported for backward compatibility. The \emph on .state \emph default attribute is writable. \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .A - One side \end_layout \begin_layout Standard .B - The other side \end_layout \begin_layout Subsection Voltage Sources \begin_inset Index idx status collapsed \begin_layout Plain Layout Voltage Sources \end_layout \end_inset , Resistors \begin_inset Index idx status collapsed \begin_layout Plain Layout Resistors \end_layout \end_inset , and Capacitors \begin_inset Index idx status collapsed \begin_layout Plain Layout Capacitors \end_layout \end_inset \end_layout \begin_layout Standard The \emph on pullup \emph default and \emph on pulldown \emph default modules are two terminal devices with one terminal tied to a voltage source. Their voltage, resistance, and pin capacitance are controllable via attributes. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard .voltage - DC voltage \end_layout \begin_layout Standard .resistance - resistance in ohms between the I/O pin and the voltage source. \end_layout \begin_layout Standard .capacitance - capacitance in farads between the I/O pin and ground. \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .pin - the only pin exposed. \end_layout \begin_layout Subsection LED_7SEGMENTS \begin_inset Index idx status collapsed \begin_layout Plain Layout 7SEGMENTS \end_layout \end_inset and LED \begin_inset Index idx status collapsed \begin_layout Plain Layout LED \end_layout \end_inset \end_layout \begin_layout Subsection* led_7segments - 7 segment common cathode LED display \end_layout \begin_layout Standard The segments are numbered as per the following figure. \end_layout \begin_layout LyX-Code ___ \end_layout \begin_layout LyX-Code 5 | 0 | 1 \end_layout \begin_layout LyX-Code ___ \end_layout \begin_layout LyX-Code 4 | 6 | 2 \end_layout \begin_layout LyX-Code ___ \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .cc - common cathode \end_layout \begin_layout Standard .seg0 - segment 0 \end_layout \begin_layout Standard .seg1 - segment 1 \end_layout \begin_layout Standard .seg2 - segment 2 \end_layout \begin_layout Standard .seg3 - segment 3 \end_layout \begin_layout Standard .seg4 - segment 4 \end_layout \begin_layout Standard .seg5 - segment 5 \end_layout \begin_layout Standard .seg6 - segment 6 \end_layout \begin_layout Subsection* Led - Simple LED \end_layout \begin_layout Standard The simple LED is a single pin module internally tied to either Vss or Vdd.By default the LED is internally tied to Vdd(0V) and turns on when the pin is driven high.However, by setting the ActiveState parameter to low, the LED is internally tied to Vss(5V) and turns on when the pin is driven low.Like a real LED, the module will either sink or source current from the driving line which may affect its logic level. \end_layout \begin_layout Standard The LED color is by default red, but can be set to other colors. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard color - LED color, possible values red, green, yellow, orange or blue \end_layout \begin_layout Standard ActiveState - LED active state mode, possible values: high or low \end_layout \begin_layout Subsubsection* I/O Pin \end_layout \begin_layout Standard .in - drives LED \end_layout \begin_layout Subsection I2C slave to Parallel port \begin_inset Index idx status collapsed \begin_layout Plain Layout i2c2par \end_layout \end_inset \end_layout \begin_layout Standard The i2c2par is a 7 bit address I2C module with an 8 bit I/O port. The direction of the I/O port is determined from I2C R/ \begin_inset Formula $\bar{W}$ \end_inset bit. When R/ \begin_inset Formula $\bar{W}$ \end_inset is zero the I/O port outputs the data sent by the master device. Otherwise the port is set as an input port and when the master device requests data, the port is read and transmitted to the master. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard .Slave_Address - I2C 7 bit device address \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .p0..7 - I/O pins \end_layout \begin_layout Standard .SDA - I2C serial data \end_layout \begin_layout Standard .SCL - I2c serial clock \end_layout \begin_layout Section Extras Modules \end_layout \begin_layout Standard In addition to the standard modules, modules largely supplied by third parties are supplied in the libgpsim_extras library. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Alias \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dht11 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dht11 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Temperature and humidity sensor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DS1307 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ds1307 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 64 x 8, Serial, I2C Real-Time Clock \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DS1820 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ds1820 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout High-Precision 1-Wire Digital Thermometer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DS18S20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ds18s20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout High-Precision 1-Wire Digital Thermometer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DS18B20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ds18b20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout High-Precision 1-Wire Digital Thermometer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_display \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_2X20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD - HD44780 2X20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_20x4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_20x4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD - HD44780 4x20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_dt161A \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_2X8 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD - HD44780 2x8 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD100X32 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD100X32 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD - SED1530 100x32 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout OSRAM128X64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout OSRAM128X64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD - SSD0323 128x64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_7Seg \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_7seg \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LCD - 7 segment no controler \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Solar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Solar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Solar Panel, Controler, Battery \end_layout \end_inset \end_inset \end_layout \begin_layout Subsection Temperature and humidity sensor - DHT11 \begin_inset Index idx status collapsed \begin_layout Plain Layout DHT11 \end_layout \end_inset \end_layout \begin_layout Standard This module emulates the DHT11 temperature/humidity sensor using a single-wire interface. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard temperature - Temperature degree C * 100 \end_layout \begin_layout Standard humidity - Relative humidity % * 100 \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .pin - Serial I/O pin \end_layout \begin_layout Subsection 64 x 8, Serial, I2C Real-Time Clock - DS1307 \begin_inset Index idx status collapsed \begin_layout Plain Layout DS1307 \end_layout \end_inset \end_layout \begin_layout Standard This module emulates the Dallas Semiconductor DS1307 Real-Time clock which also has 56 x 8 eeprom memory and connects via an I2C serial bus. \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .SDA - Serial Data Line I/O pin \end_layout \begin_layout Standard .SCL - Serial Clock Line I/O pin \end_layout \begin_layout Standard .SQW - Square Wave Output \end_layout \begin_layout Subsection High-Precision 1-Wire Digital Thermometer - DS1820 Family \begin_inset Index idx status collapsed \begin_layout Plain Layout DS1820 Family \end_layout \end_inset \end_layout \begin_layout Standard These modules emulate the DS1820, DS18S20 and DS18B20 High-Precision 1-Wire Digital Thermometers.These devices uses a single-wire bus interface. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard ROMCode - Device ROM code \end_layout \begin_layout Standard temperature - Temperature of device \end_layout \begin_layout Standard powered - Device is self powered \end_layout \begin_layout Standard alarm_th - Temperature high alarm register \end_layout \begin_layout Standard alarm_tl - Temperature low alarm register \end_layout \begin_layout Standard config_register - Value of configuration register (ds18B20 only) \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .pin - Serial I/O pin \end_layout \begin_layout Subsection Character LCD - HD44780 \begin_inset Index idx status collapsed \begin_layout Plain Layout HD44780 \end_layout \end_inset \end_layout \begin_layout Standard The library libgpsim_lcd contains several LCD display formats using the HD44780 controller. \end_layout \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_display \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 20 col 2 row LCD \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_20x4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 20 col 4 row LCD \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lcd_dt161A \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 16 col 1 row LCD \end_layout \end_inset \end_inset \end_layout \begin_layout Subsection* I/O Pins \end_layout \begin_layout Standard .DC - Data / command select \end_layout \begin_layout Standard .RW - Read/Write select \end_layout \begin_layout Standard .E - start data read/write \end_layout \begin_layout Standard .d0-7 - data bus \end_layout \begin_layout Subsection Graphic LCD - SED1530 \begin_inset Index idx status collapsed \begin_layout Plain Layout SED1530 \end_layout \end_inset \end_layout \begin_layout Standard This module emulates a 100X32 pixel graphics LCD based on dual SED1350 controllers. \end_layout \begin_layout Subsection LCD_7Seg \begin_inset Index idx status collapsed \begin_layout Plain Layout LCD_7Seg \end_layout \end_inset \end_layout \begin_layout Standard A 7 segment LCD display without a controller. If common > 2.5V, (cc- segn) > 1.4V segment is on otherwise segment is off. \end_layout \begin_layout Standard The segments are numbered as per the following figure. \end_layout \begin_layout LyX-Code ___ \end_layout \begin_layout LyX-Code 5 | 0 | 1 \end_layout \begin_layout LyX-Code ___ \end_layout \begin_layout LyX-Code 4 | 6 | 2 \end_layout \begin_layout LyX-Code ___ \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .cc - common \end_layout \begin_layout Standard .seg0-6 - 7 segment drives \end_layout \begin_layout Subsection Solar \begin_inset Index idx status collapsed \begin_layout Plain Layout Solar \end_layout \end_inset \end_layout \begin_layout Standard This module emulates a 20 Watt solar panel, a 20mah battery, and a PWM controler for testing control strategies for the controler. \end_layout \begin_layout Subsubsection* Attributes \end_layout \begin_layout Standard Aoffset - Voltage on Asol pin for zero panel current \end_layout \begin_layout Standard Ascale - Voltage/Amp panel current scale factor for Asol \end_layout \begin_layout Standard VSscale - scale factor for Vsol pin \end_layout \begin_layout Standard VBscale - scale factor for Vbat pin \end_layout \begin_layout Standard inductor - controler inductor size in Henries \end_layout \begin_layout Standard BDOC - Battery degree of charge % \end_layout \begin_layout Subsubsection* I/O Pins \end_layout \begin_layout Standard .Vsol - Solar Panel output Voltage \end_layout \begin_layout Standard .Asol - Solar Panel output current \end_layout \begin_layout Standard .Vbat - Battery Voltage \end_layout \begin_layout Standard .PWM - Pulse Width Modulation signal \end_layout \begin_layout Standard .OK - PWM is enabled \end_layout \begin_layout Section Writing new modules \end_layout \begin_layout Standard A module is a library of code. On Windows the library is a .DLL and on Unix a shared library. There are a few details that a module must adhere to, but in general the module has full access to gpsim's API. \end_layout \begin_layout Standard The easiest way to write a new module is to start from the source code from one of the existing modules. For example, suppose your project produces a serial bit-stream in PPM coding and you want to display the output during the simulation. The external module you need is similar to the usart module but not the same, so start by making a copy of the usart module and then modify it to work how you need. \end_layout \begin_layout Standard To be able to load your module into gpsim it needs to be in a library. Usually you will be creating a new library just for one device, but sometimes you will have a few devices. Either way, the library must declare to gpsim what devices it contains. This is achieved with an array of Module_Types class instances, returned to gpsim by a function named \begin_inset Quotes eld \end_inset get_mod_list \begin_inset Quotes erd \end_inset . All gpsim module libraries must declare this function. You can copy the required template from the gpsim source – probably one of the \begin_inset Quotes eld \end_inset extras \begin_inset Quotes erd \end_inset modules is slightly cleaner than the main library. For our PPM decoder example, we might have a module_manager.cc containing the following code: \end_layout \begin_layout LyX-Code /* IN_MODULE should be defined for modules */ \end_layout \begin_layout LyX-Code #define IN_MODULE \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code #include \end_layout \begin_layout LyX-Code #include \end_layout \begin_layout LyX-Code #include "ppm.h" \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code Module_Types available_modules[] = \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code { "ppm_display", "ppm_rx_iface", PpmDisplay::construct}, \end_layout \begin_layout LyX-Code // No more modules \end_layout \begin_layout LyX-Code { NULL,NULL,NULL} \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code #ifdef __cplusplus \end_layout \begin_layout LyX-Code extern "C" { \end_layout \begin_layout LyX-Code #endif /* __cplusplus */ \end_layout \begin_layout LyX-Code /***************************************************************** \end_layout \begin_layout LyX-Code * get_mod_list - Report all of the modules in this library. \end_layout \begin_layout LyX-Code * \end_layout \begin_layout LyX-Code * This is a required function for gpsim compliant libraries. \end_layout \begin_layout LyX-Code */ \end_layout \begin_layout LyX-Code Module_Types * get_mod_list(void) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code return available_modules; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code #ifdef __cplusplus \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code #endif /* __cplusplus */ \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard This declares that this library provides one module, called ppm_display, implemented by the C++ class PpmDisplay. The class which implements the module must provide a static method \begin_inset Quotes eld \end_inset construct \begin_inset Quotes erd \end_inset to create a new instance of the class. For example: \end_layout \begin_layout LyX-Code Module * PpmDisplay::construct(const char *_new_name=0) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code PpmDisplay *ppmd = new PpmDisplay(_new_name); \end_layout \begin_layout LyX-Code ppmd->create_iopin_map(); \end_layout \begin_layout LyX-Code ppmd->create_window(_new_name); \end_layout \begin_layout LyX-Code return ppmd; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard Your module will need to include stimuli for its I/O connections. You can use the standard gpsim stimulus classes: IOPIN, io_bidirectional, io_bidirectional_pu, io_open_collector. In many cases, however, you will want to derive your own class from one of them. This will allow you to customise the actions when the node state changes. For example: \end_layout \begin_layout LyX-Code class DecoderPin : public IOPIN \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code private: \end_layout \begin_layout LyX-Code PpmDisplay * Parent; \end_layout \begin_layout LyX-Code public: \end_layout \begin_layout LyX-Code DecoderPin ( PpmDisplay * parent, unsigned int b, const char * name=0 ); \end_layout \begin_layout LyX-Code virtual void setDrivenState(bool new_state); \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout Standard The only methods we provide here are the constructor and an overridden \begin_inset Quotes eld \end_inset setDrivenState \begin_inset Quotes erd \end_inset . This is because our PPM decoder needs to be told when the input pin changes state. \end_layout \begin_layout Chapter Symbolic Debugging \end_layout \begin_layout Standard gpsim maintains a symbol table. \end_layout \begin_layout Standard \end_layout \begin_layout Chapter Macros \end_layout \begin_layout Standard \end_layout \begin_layout Chapter Hex Files \end_layout \begin_layout Standard The target code simulated by gpsim can be supplied by a hex file, or more specifically an Intel Hex file. gpsim accepts the format of hex provided by gpasm and mpasm. The hex file does not provide any symbolic information. It's recommended that hex files only be used if 1) you suspect there's a problem with the way .cod files are generated by your assembler or compiler OR 2) your assembler or compiler doesn't generate .cod files. Also, you must supply a processor when loading hex files. See the load command. \end_layout \begin_layout Chapter The ICD- Not Supported in versions 0.21.0 and later \end_layout \begin_layout Standard gpsim supports (partly) the first version of the ICD (as opposed to ICD2 (the round hockey-puck shaped one)). \end_layout \begin_layout Subsection* Special configuration of the code \end_layout \begin_layout Standard Read the MPLAB ICD USER's GUIDE. \end_layout \begin_layout Standard Here's the short version: \end_layout \begin_layout Itemize disable at least: brown out detection, low voltage programming and all code protection. It is probably good to turn of the watchdog too. see the MPLAB ICD USER's GUIDE for more information. \end_layout \begin_layout Itemize have a NOP as the first instruction. \end_layout \begin_layout Itemize Don't touch RB6 or RB7. \end_layout \begin_layout Itemize Don't use the last stack level. \end_layout \begin_layout Itemize Don't use these registers and program words: \begin_inset Newline newline \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Processor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Register \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Program \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -870/1/2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x70, 0xBB-0xBF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x6E0-0x7FF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -873/4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x6D, 0x1fD, 0xEB-0xF0, 0x1Eb-0x1F0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0xEE0-0xFFF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -876/7 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x70, 0x1Eb-0x1Ef \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0x1F00-0x1FFF \end_layout \end_inset \end_inset \end_layout \begin_layout Subsection* icdprog \end_layout \begin_layout Standard Download and install icdprog. \end_layout \begin_layout Standard Use icdprog to program the target with the hex file ( \emph on icdprog mycode.hex \emph default ). \end_layout \begin_layout Subsection* ICD usage \end_layout \begin_layout Standard Start gpsim like this: \end_layout \begin_layout Standard \emph on gpsim -d /dev/ttyS0 -s mycode.cod \end_layout \begin_layout Standard , assuming the ICD is connected to the first serial port. \end_layout \begin_layout Standard Now you can type 'icd' to see some information: \end_layout \begin_layout Standard \emph on **gpsim> icd \begin_inset Newline newline \end_inset ICD version "2.31.00" was found. \begin_inset Newline newline \end_inset Target controller is 16F877 rev 13. \begin_inset Newline newline \end_inset Vdd: 5.2 Vpp: 13.3 \begin_inset Newline newline \end_inset Debug module is present \end_layout \begin_layout Standard 2.31 is the firmware version. I have only tried this particular version... \end_layout \begin_layout Standard You can step, reset, run, halt, set the breakpoint and read file registers. It works both from the GUI and the cli. \end_layout \begin_layout Subsection* ICD TODO \end_layout \begin_layout Itemize MPLAB has a setting for target CPU frequency, I have only tried with a 20MHz crystal, so there may be adjustments to be made to the serial port timeout settings in gpsim. \end_layout \begin_layout Itemize The source, disassembly, watch, symbol and RAM windows works. And the rest doesn't. I guess the breadboard should be able to work at least for the pic, but it doesn't. \end_layout \begin_layout Itemize EEPROM support \end_layout \begin_layout Itemize modifying data \end_layout \begin_layout Itemize Fix the UI to give more feedback about what's happening during long delays. \end_layout \begin_layout Itemize Better error detection. gpsim doesn't always see that the target is not functional. \end_layout \begin_layout Chapter Examples \end_layout \begin_layout Standard The \emph on examples/ \emph default subdirectory contains several examples. The \emph on examples/projects/ \emph default subdirectory demonstrate sample projects that can serve as templates for new projects. In addition, the \emph on examples/modules \emph default subdirectory contains several examples illustrating how to use gpsim's various modules. Finally, as described in chapter \begin_inset CommandInset ref LatexCommand ref reference "Regression-Tests" \end_inset , gpsim's regression tests illustrate many powerful debugging techniques that have not been fully documented. \end_layout \begin_layout Subsubsection* usart_gui example \end_layout \begin_layout Standard Each example contains a brief \emph on README \emph default explaining its purpose. For example, the \emph on README \emph default for the \emph on usart_gui \emph default example in the \emph on examples/modules \emph default directory contains \end_layout \begin_layout LyX-Code The tests the USART module with the GUI fix. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code The code for a 16f628 PIC is used. The code first transmits a string of \end_layout \begin_layout LyX-Code characters, which are instructions to the user, to the USART module which \end_layout \begin_layout LyX-Code will then be displayed on its GUI. This verifies that the USART can receive \end_layout \begin_layout LyX-Code serial data. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code When the focus is on the USART GUI window, characters typed on the keyboard \end_layout \begin_layout LyX-Code are sent from the USART to the PIC and then retransmitted from the PIC back \end_layout \begin_layout LyX-Code to the USART. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code If all works, the typed characters will be displayed in the GUI text window \end_layout \begin_layout LyX-Code of the USART. Both transmit and receive must be functioning for this to \end_layout \begin_layout LyX-Code happen. \end_layout \begin_layout Standard \emph on Fixme \emph default - we really need to document all of the examples! \end_layout \begin_layout Chapter Regression Tests \begin_inset CommandInset label LatexCommand label name "cha:Regression-Tests" \end_inset \end_layout \begin_layout Standard Starting with version 0.22.0, gpsim distributes regression tests. The purpose of a regression test is to validate correctness. The tests are designed to exercise many of the aspects of gpsim and gpsim's modules. While designed primarily for developers, the regression tests also serve as a rich source of examples. There are many features gpsim's developers will tuck away into a regression test and fail to document! \end_layout \begin_layout Chapter Theory of Operation \end_layout \begin_layout Standard This section is only provided for those who may be interested in how gpsim operates. The information in here is 'mostly' accurate. However, as gpsim evolves so do the details of the theory of operation. Use the information provided here as a high level introduction and use the (well commented :]) source to learn the details. \end_layout \begin_layout Section Background \end_layout \begin_layout Standard gpsim is written mostly in C++. Why? Well the main reason is to easily implement a hierarchical model of a pic. If you think about a microcontroller, it's really easy to modularize the various components. C++ lends itself well to this conceptualization. Furthermore Microchip, like other microcontroller manufacturers, has created families of devices that are quite similar to one another. Again, the C++ provides 'inheritance' that allows the relationships to be shared among the various models of pics. \end_layout \begin_layout Section Instructions \begin_inset Index idx status collapsed \begin_layout Plain Layout instructions \end_layout \end_inset \end_layout \begin_layout Standard There's a base class for the 14-bit instructions (I plan to go one step further and create a base class from which all pic instructions can be derived). It primarily serves two purposes: storage that is common for each instruction and a means for generically accessing virtual functions. The common information consists of a name - or more specifically the instructi on mnemonic, the opcode, and a pointer to the processor owning the instruction. Some of the virtual functions are 'execute' and 'name'. As the hex file is decoded, instances of the instructions are created and stored in an array called program_memory. The index into this array is the address at which the instruction resides. To execute an instruction the following code sequence is invoked: \end_layout \begin_layout Quotation program_memory[pc->value]->execute(); \end_layout \begin_layout Standard which says, get the instruction at the current program index (pc->value) and invoke via the virtual function execute(). This approach allows execution break points to be easily set. A special break point instruction can replace the one residing in the program memory array. When 'execute' is called the break point can be invoked. \end_layout \begin_layout Subsubsection Program memory \end_layout \begin_layout Standard Note that in the above discussion, the pc->value is referred to as the \begin_inset Quotes eld \end_inset program index \begin_inset Quotes erd \end_inset . On the 12-bit and 14-bit PIC cores this is unambiguous as the program memory is instruction-word-wide and the program counter increments by one for each instruction. On the PIC17 and PIC18 cores, however, the program memory is accessible through the TBLPTR in byte-wide form. The program counter increments by two for each instruction. \end_layout \begin_layout Standard The program_memory array in gpsim is always an array of instructions. Thus the pc->value on a PIC18 is an index whose value is half of the PC register-triple value. \end_layout \begin_layout Section General File Registers \begin_inset Index idx status collapsed \begin_layout Plain Layout registers \end_layout \end_inset \end_layout \begin_layout Standard A file register is simulated by the 'file_register' class. There is one instance of a 'file_register' object for each file register in the PIC. All of the registers are collected together into an array called 'registers' which is indexed by the registers' corresponding PIC addresses. The array is linear and not banked like it is in the PIC. (Banking is handled during the simulation.) \end_layout \begin_layout Section Special File Registers \end_layout \begin_layout Standard Special file registers are all of the other registers that are not general file registers. This includes the core registers like status and option and also the peripheral registers like eeadr for the EEPROM. The special file registers are derived from the general file registers and are also stored in the 'registers' array. There is one instance for each register - even if the register is accessible in more than one bank. So for example, there's only one instance for the 'status' register, however it may be accessed through the 'registers' array in more than one place. \end_layout \begin_layout Standard All file registers are accessed by the virtual functions 'put' and 'get'. This is done for two main reasons. First, it conveniently encapsulates the breakpoint overhead (for register breakpoints) in the file register and not in the instruction. Second, and more important, it allows derived classes to implement the put and get more specifically. For example, a 'put' to the indf register is a whole lot different than a put to the intcon register. In each case, the 'put' initiates an action beyond simply storing a byte of data in an array. It also allows the following code sequence to be easily implemented: \end_layout \begin_layout LyX-Code movlw trisa ;Get the address of tris \end_layout \begin_layout LyX-Code movwf fsr \end_layout \begin_layout LyX-Code movf indf,w ;Read trisa indirectly \end_layout \begin_layout Section Example of an instruction \end_layout \begin_layout Standard Here's an example of the code for the movf instruction that illustrates what has been discussed above. Somewhere in gpsim the code sequence: \end_layout \begin_layout LyX-Code program_memory[pc->value]->execute(); \end_layout \begin_layout Standard is executed. Let's say that the pc is pointing to a movf instruction. The ->execute() virtual function will invoke MOVF::execute. I've added extra comments (that aren't in the main code) to illustrate in detail what's happening. \end_layout \begin_layout LyX-Code void MOVF::execute(void) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code unsigned int source_value; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // All instructions are 'traced' (discussed below). It's sufficient \end_layout \begin_layout LyX-Code //to only store the opcode. However, even this may be unnecessary since \end_layout \begin_layout LyX-Code //the program counter is also traced. Expect this to disappear in the \end_layout \begin_layout LyX-Code //future... \end_layout \begin_layout LyX-Code trace.instruction(opcode); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // 'source' is a pointer to a 'file_register' object. It is initialized \end_layout \begin_layout LyX-Code //by reading the 'registers' array. Note that the index depends on the \end_layout \begin_layout LyX-Code //'rp' bits (actually just one bit) in the status register. Time is \end_layout \begin_layout LyX-Code // saved by caching rp as opposed to decoding the status register. \end_layout \begin_layout LyX-Code source = cpu->registers[cpu->rp | opcode®_IN_INSTRUCTION_MASK]; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // We have no idea which register we are trying to access and how it \end_layout \begin_layout LyX-Code //should be accessed or if there's a breakpoint set on it. No problem, \end_layout \begin_layout LyX-Code //the virtual function 'get' will resolve all of those details \end_layout \begin_layout LyX-Code // and 'do the right thing'. \end_layout \begin_layout LyX-Code source_value = source->get(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // If the destination is W, then the constructor has already initialized \end_layout \begin_layout LyX-Code //'destination'. Otherwise the destination and source are the same. \end_layout \begin_layout LyX-Code if(opcode&DESTINATION_MASK) \end_layout \begin_layout LyX-Code destination = source; // Result goes to source \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // Write the source value to the destination. Again, we have no idea \end_layout \begin_layout LyX-Code // where the destination may be or \end_layout \begin_layout LyX-Code // or how the data should be written there. \end_layout \begin_layout LyX-Code destination->put(source_value); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // The movf instruction will set Z (zero) bit in the status register \end_layout \begin_layout LyX-Code //if the source value was zero. \end_layout \begin_layout LyX-Code cpu->status.put_Z(0==source_value); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // Finally, advance the pc by one. \end_layout \begin_layout LyX-Code cpu->pc->increment(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout Section Trace \end_layout \begin_layout Standard Everything that is simulated is traced - \emph on all \emph default \emph toggle of the time. The trace buffer is one huge circular buffer of integers. Information is or'ed with a trace token and then is stored in the trace buffer. No attempt is made to associate the items in the trace buffer while the simulator is simulating a PIC. Thus, if you look at the raw buffer you will see stuff like: cycle counter = ..., opcode fetch = ..., register read = ..., register write = ..., etc. However, this information is post processed to ascertain what happened and when it happened. It's also possible to use this information to undo the simulation, or in other words you can step backwards. I don't have this implemented yet though. \end_layout \begin_layout Section Breakpoints \end_layout \begin_layout Standard Breakpoints fall into three categories: execution, register, and cycle. \end_layout \begin_layout Subsubsection Execution: \end_layout \begin_layout Standard For execution breakpoints a special instruction appropriately called 'Breakpoint _Instruction' is created and placed into the program memory array at the location the break point is desired. The original instruction is saved in the newly created breakpoint instruction. When the break point is cleared, the original instruction is fetched from the break point instruction and placed back into the program memory array. \end_layout \begin_layout Standard Note that this scheme has zero overhead. The simulation is only affected when the breakpoint is encountered. \end_layout \begin_layout Subsubsection Register: \end_layout \begin_layout Standard There are at least four different breakpoint types that can be set on a register: read any value, write any value, read a specific value, or write a specific value. Like the execution breakpoints, there are special breakpoint registers that replace a register object. So when the user sets a write breakpoint at register 0x20 for example, a new breakpoint object is created and insert into the file register array at location 0x20. When the simulator attempts to access register location 0x20, the breakpoint object will be accessed instead. \end_layout \begin_layout Standard Note that this scheme too has zero overhead, accept when a breakpoint is encountered. \end_layout \begin_layout Subsubsection Cycle: \end_layout \begin_layout Standard Cycle breakpoints allow gpsim to alter execution at a specific instruction cycle. This is useful for running your simulation for a very specific amount of time. Internally, gpsim makes extensive use of the cycle breakpoints. For example, the TMR0 object can be programmed to generate a periodic cycle break point. \end_layout \begin_layout Standard Cycle break points are implemented with a sorted doubly-linked list. The linked list contains two pieces of information (besides the links): the cycle at which the break is to occur and the call back function \begin_inset Foot status collapsed \begin_layout Plain Layout A call back function is a pointer to a function. In this context, gpsim is given a pointer to the function that's to be invoked (called) whenever a cycle break occurs. \end_layout \end_inset that's to be invoked when the cycle does occur. The break logic is extremely simple. Whenever the cycle counter is advanced (that is, incremented), it's compared to the next desired cycle break point. If there's NO match, then we're done. So the overhead for cycle breaks is the time required to implement a comparison. If there IS a match, then the call back function associated with this break point is invoked and the next break point in the doubly-linked list serves as the reference for the next cycle break. \end_layout \begin_layout Section TIMER1 External input \end_layout \begin_layout Standard The timer1 module can support external input, on some processors, as either a crystal using two pins or a single pin drive. \end_layout \begin_layout Subsubsection* External Crystal \end_layout \begin_layout Standard If an external crystal, typically 32,768 KHz, is being used, then both T1OSCEN and TMR1CS in register T1CON should be true. Gpsim will then automatically simulate timer1 being driven at the crystal frequency which can be changed from the default frequency by changing the value of the processor symbol called tmr1_freq. \end_layout \begin_layout Subsubsection Single pin drive \end_layout \begin_layout Standard If the single pin drive is being used, then the T1CON register bits for T1OSCEN should be false and TMR1CS true, and the T1CKI pin must be driven manually such as by a stimuli command. \end_layout \begin_layout Chapter LICENSES \end_layout \begin_layout Section Gpsim.lyx \end_layout \begin_layout Standard Copyright \begin_inset ERT status open \begin_layout Plain Layout \backslash copyright \end_layout \end_inset 2000-2010 \end_layout \begin_layout Standard T. Scott Dattalo, Ralf Forsberg, Robert Pearce, Borut RaĹľem and Roy Rankin \end_layout \begin_layout Standard The source of this document is gpsim.lyx. \end_layout \begin_layout Standard This document is free software; you can redistribute it and/or modify it under the terms of the \begin_inset Index idx status collapsed \begin_layout Plain Layout GNU GPL \end_layout \end_inset GNU General Public License published by the Free Software Foundation; either version 2, or (at your option) any later version. \end_layout \begin_layout Standard This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. \end_layout \begin_layout Standard You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \end_layout \begin_layout Section Gpsim \end_layout \begin_layout Standard The Gpsim program is licensed under version 2 or higher of the GNU General Public License. Details of this license can be found in the COPYING file which should have come with this program. If not the license can be found at \begin_inset CommandInset href LatexCommand href target "http://www.gnu.org/licenses/gpl-2.0.html" \end_inset . \end_layout \begin_layout Section Libraries libgpsim, libgpsim_modules, libgpsim_eXdbm \end_layout \begin_layout Standard The libraries libgpsim, libgpsim_modules, and libgpsim_eXdbm are licensed under version 2.1 of the GNU Lesser General Public License. Details of this license can be found in the COPYING.LESSER file which should have come with the program. If not, the license can be found at \begin_inset CommandInset href LatexCommand href target "http://www.gnu.org/licenses/lgpl-2.1.html" \end_inset . \end_layout \begin_layout Standard \start_of_appendix \begin_inset CommandInset index_print LatexCommand printindex type "idx" \end_inset \end_layout \end_body \end_document gpsim-0.30.0/doc/Makefile.in0000664000076400007640000003214013117441634012462 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ screenshots/breadboard.png \ screenshots/registerview.png \ screenshots/scope1.png \ screenshots/scope2.png \ screenshots/source_browser.png \ screenshots/control_source.png \ screenshots/breadboard_register.png \ metadata/gpsim.desktop \ metadata/gpsim.appdata.xml \ metadata/gpsim.png \ makefile.mingw \ gpsim.lyx \ gpsim.pdf \ gpsim.ps MOSTLYCLEANFILES = *~ CLEANFILES = *~ DISTCLEANFILES = *~ MAINTAINERCLEANFILES = gpsim.ps gpsim.pdf *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile gpsim.ps: gpsim.lyx lyx -e ps gpsim.lyx gpsim.pdf: gpsim.lyx lyx -e pdf gpsim.lyx # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/doc/Makefile.am0000664000076400007640000000106413041763626012456 00000000000000 gpsim.ps: gpsim.lyx lyx -e ps gpsim.lyx gpsim.pdf: gpsim.lyx lyx -e pdf gpsim.lyx EXTRA_DIST = \ screenshots/breadboard.png \ screenshots/registerview.png \ screenshots/scope1.png \ screenshots/scope2.png \ screenshots/source_browser.png \ screenshots/control_source.png \ screenshots/breadboard_register.png \ metadata/gpsim.desktop \ metadata/gpsim.appdata.xml \ metadata/gpsim.png \ makefile.mingw \ gpsim.lyx \ gpsim.pdf \ gpsim.ps MOSTLYCLEANFILES = *~ CLEANFILES = *~ DISTCLEANFILES = *~ MAINTAINERCLEANFILES = gpsim.ps gpsim.pdf *~ gpsim-0.30.0/doc/screenshots/0000775000076400007640000000000013117466025013036 500000000000000gpsim-0.30.0/doc/screenshots/scope2.png0000664000076400007640000001402613041763626014665 00000000000000‰PNG  IHDR5t•; ;ÝIDATxśíÝ{T•UţÇń Éqiż@ŔDCsZ˘€?/•żÓtĎĽ4)Š© ",/é¤SjŁN+ś,k&KÓ\Ž—”©f¦Ľ&6e™ĺ%¤x×BA„tlyPĆóűĂxŇ‘›xçśçĽ_k=ęzžgoľ›łöłŹßµ÷~|öäŮŕa|]@}ÔLčó/¶(cÖlő{t ľüjë×l6›¦Lť¦čŘxőĽón­ĘÎ1®9rT=®Žťş(qČp?~˘Nĺ¸gô˙ö˘®:¸źšú}ź Ś˙€gpF˙÷”ńż‘«ŕx}ôÝzk{ĺĺĺëâĹ‹W\›ýęë*(اĎ?űT‡ŹQâáŠWüíqšř‡Éş˙ľ{µlÉ"=5ůMzjŠŢ[¶¸Ör܇3úż$}“Ą-Z4pk\‹šú}ź Ś˙€gpF˙—7Sź¬Y§¦‹ž|rĽřť$ić‹Ę|?KŤ7Ö€Ç~§§źšhddk*Ŕ}8Ł˙÷Ľónť9sFÍ›7Sď‡Ҥ‰ż7ÜGMýżľĎĆŔ38Ł˙{Ęřoę¤FjÚX-|g®«Ă<‚Ůú‹™ÚC[Ümq_fjmqO´Ĺ}™©=´Ĺ=Ń÷Ăňŕ‘L?S“{n_ę ąąą®8 ËO€ëd7Ůa®ţ=ňŮŔ“X­VW‡€¸úŮĂł¬j®ţ=ňą¸^V«ŐĺĎG$5đ1Áq· ˙Săęß©#ŢÍŐĎ žeUsőďÓ‡Ç×ĆŐϡë=HjŹä˛¤†ÍfÓ”©ÓŻžwŢ­UŮ9® x ‡nşnýĹĆĆ($8¸Ö{gżúş öéóĎ>Őá#G”8d¸""Â{ś#C&ĺĐ™cĆNС‡k˝Ďfłief–FŹNÓŤ76WtçNzđű´tŮ{Ž Ż$µďĄŐ9ę±u[ÇŤ™¦˛˛2IŇáĂG”ś2JѱńęÖă.eĚš­ .¨˛Ü»‹«{Ď^jß!J’”’š®fľ,IZ˛tąîąď!uŠŽS÷ž˝Ś%&{öě•ÍfSLL´HttgíرłáZ<š1Săµ9o()i˛łVčŕÁCĘ5[JIMWxXľÝ¶E9ŮďkÝú zsî<Ł‚UŮ9š?o®vnß*IZ´pľ¦O›*Ij×.R™+–i÷®o”ś4\ŻH’ŠOž”$µ 4ę TqńIç·‚‘Ô4q‚úöé­¨¨ŽJś O7mÖöí;tôč1Ť“®ĆŤ+4´•Đ꜌ ĆŹŁčÎjÖ¬ŮU•ßŃł‡‚‚ZČf+Wdd[ýtú´$ÉĎׯšĚĚŘ(4´U¨q288XgÎś1fT]v-芗Ͷřo+3ł”••­¶m#tö矍óAÁ—ę+--Sđ/˙.++SHHíŚHŐĽý¤°đ¸Z·5ŢbRRR˘–-[J’Š‹‹ë”|Řł·@Ó¦?«M×*,¬Ť¶nݦŤ7I’nűMY,íÚőťî˝÷·’¤Ý»óÔĄK¬CĚĎX~rÎvNŇĄŤAWffiđ ęÚµ‹""ÂőÖĽި¨Paáqef®ŇŁýűUYYÓ¦MUrŞDv»]ĄĄĄ’¤'N¨¨¨H˛Ć¨żI“&’8HoĎ{GgĎžU~ţ÷Złv­† âěö“0fj¤Ž-ܤÄÁ ™’,???-\đ¶fĚx^]âşËb±¨ż>zbÜč*+KO©ÉS¦©ĽüĽúő}D}űôÖ°¤‘jÓ¦µ&?=IyůßkČăIÚňE®&>9^Ď>7SwöşGM-ÍţGĹß×` žÍgAž˝}‡(-_şXݺŻ:‡Ş|Í,ŕLvI>®Â¬V«6ĺ暢-’y>—JfkÜ‹ŐjUnn®«Ă@5ĚÔ˙i‹ű1Űř îĚŇ˙}kżŔýřJŇK/>§["Űş8€şk$I ¸:§°»:ŔŃoÜź ś†Ą'h@<ËÜź ŕ…L2ţWůJWłđôµA@CŁĎ¸/>8{j ˇđ,sO|.€w2Ëřďłż Ď´‰ŮÔ´±®8‰©fj´»µŁ$éŔľ|I2EÖ TÍto?9°/źWąő`µZe—8ÜřśĹjµş:x W?G9cüĘ,ăż©fjĐ®ëjÝ_8ăŚ{±Z­ÚÄěfĚTI IÚ_çę@pŮň“ϿآŚYłŐďŃúň«­® x(‡&5Ö­ß â“'ëtďGýC-Z*//_/^tČĎowkGcłP`nMjŚ;A‡®Ó˝žő’FĄ¦8ňÇKb_ Ľ…Ż$µďĄŐ9ę±u[ÇŤ™¦˛˛2IŇáĂG”ś2JѱńęÖă.eĚš­ .¨˛Ü»‹«{Ď^F"!%5]/Ě|Y’´dérÝsßCę§î={iUvŽSCBďaĚÔxmÎJJ¦ě¬:xđ2fÍVEE…RRÓ¦o·mQNöűZ·~Ţś;Ϩ`UvŽćĎ›«ťŰ/틱há|Mź6U’Ô®]¤2W,Óî]ß(9i¸22^qzöä±Y(^ŔHjLš8A}űôVTTG%NЧ›6kűö:zôĆŽIWăĆŤÚJ huÎFăÇŤQLtg5kÖěŞĘďčŮCAA-dł•+2˛­~:}şaZLĎxĄkh«Pădpp°Îś9clútٵ ˙şh```µ•ŻĚĚRVV¶Ú¶ŤĐŮźvhŕU©Ü$ôŔľ|§˙,ŕZŤŞ:YXx\­[‡*$8X’TRR˘–-[J’Š‹‹\kĹ{öhÚôgµiăZ……µŃÖ­Ű´qă&†^µĘ}5X‚€ąËOÎŮÎIş´1čĘĚ, 4P]»vQDD¸Ţš·@*,<®ĚĚUz´ż*+kÚ´©JN•Čn·«´´T’tâÄ éăOÖő; …ŕ=Ś™©ŁFËßß_7)qp‚F¦$ËĎĎO Ľ­3žW—¸î˛X,ęßŻŹž7şĘĘŇÓFjň”i*/?Ż~}Qß>˝5,i¤Ú´i­ÉOOR^ţ÷ňx’¶|‘«{ďXEEĹ’¤Qicäçç§ţ=Gááa×Ő fhŕ|öäŮŰwŇňĄ‹Ő­[Ľ«ăq(fmugµZµ)7W>®U˛K|6p«ŐŞÜÜ\W‡/ŔłĚý0ţŢË,ăżoí·xŽv·v46 ćć+I/˝řśn‰lëâP}5đ>ű ň쮑*ű ňÔŽäpÍ~ęžLő ŕŐgÜKĺňđTUľŇŐ“]ľQ(&PwfYSgV<ĎŕLôŔ»1ĆŢÉ,ăżéfj\.5m¬«CNbŞ™•›„Ř—/I¦Č:€Ş™ęí'…őeµZ]j`çŕŕŕŕŕpâŔűĺűż©fjĐ`f¬y†łeM-€kÇFˇ<ť©’Ň•…órÉň“łgĎjÂď˙ ˙í~—:EÇičđúáÇ] đPMj¬[żAĹ'OÖzźÍV®řř8m\˙±¶mýBMnh˘gž™qÝ?żÝ­ŤÍB€ą94©1fě:x¸Öű‚‚Zhčă‰jŢĽą,=üđÚöÍ·‰}5đľ’ÔľC”Vç|¨Ç Ömc4bdšĘĘĘ$I‡QrĘ(EÇĆ«[Ź»”1k¶.\¸ Ęrď.Z¬î={‰„”Ôt˝0óeIŇ’ĄËuĎ}©Stśş÷ěĄUŮ9UQTT¤›núźën Ľ‡1Săµ9o()i˛łVčŕÁCĘ5[JIMWxXľÝ¶E9ŮďkÝú zsî<Ł‚UŮ9š?o®vnß*IZ´pľ¦O›*Ij×.R™+–i÷®o”ś4\Ż\Ŕż˙ýo-/S)#’Ň ýyl €0’“&NPß>˝ŐQ‰ôé¦ÍÚľ}‡Ž=¦±cŇŐ¸qc…†¶RÂŔZťóQÁřqcÝYÍš5»Şň;zöPPP Ůl劌l«źNźľâzyyąĆŽű˝îčŮ]#S’ť×J`:Ć+]C[…'ućĚcÓĎ   Ë®©¸ř×Í@«­|ef–˛˛˛Ő¶m„Îţüó×ţóź˙h“Pxxžn†|}Ż{ŹĘMBě˿{kTŐÉÂÂăjÝ:T!ÁÁ’¤’’µlŮR’T\\¬ŕZ+Ţł·@Ó¦?«M×*,¬Ť¶nݦŤ7×_™=G?•ý¤ą}Ý! ŤJ•űj°s3˛ çlç$]Útef–¨®]»(""\oÍ[ ŠŠ Wfć*=Úż_••5mÚT%§Jd·ŰUZZ*I:qâ„ŠŠŠôń'kŚú÷čÝE‹•0@'O–čĉ"ť8QtÝŤaŁPĽ‡1S#uÔhůűű+ ŕ&%NĐČ”důůůiá‚·5cĆóę×]‹EýűőŃăFWYYzÚHMž2MĺĺçŐŻď#ęۧ·†%ŤT›6­5ůéIĘË˙^COŇä§'Én·ëéÉĎ\QŢł+ˇ€wđŮ_goß!JË—.V·nń®ŽÇˇµÔťŐjUnn®«Ă@5ě’|\L‹ţx/«ŐŞMąąŚ1€2Ëřď¸Í,Ż$˝ôâsş%˛­‹C¨»F’”0p€«ăp »«<‰ ¦ž€úá{3ŕ…LňýżĘWşškş3Ëš:pmřÎ x'ł|˙÷Ů_gÚÄljÚXW‡śÄÔ35ĚuU3uRh¦™ęÄ;CÝź ŔÉfďSůJgOGRp3|°˙ň‡Źc2|6p6ł¬©píĚňźőçé_1}]@}¸,©ałŮ4eę4EÇĆ«çťwkUvŽ«BȡËOÖ­ß ŘŘ…×zďěW_WAÁ>}ţ٧:|ä‡ WDD¸âoŹsdHŔ¤:ScĚŘ :tđp­÷Ůl6­ĚĚŇčŃişńĆćŠîÜI>pź–.{Ď‘áó•¤ö˘´:çC=6`°nëŁ#ÓTVV&I:|ř’SF):6^ÝzÜĄŚYłuáÂU–{wŃbuďŮKí;DI’RRÓőÂĚ—%IRJjş:ÇÄ)ŞsW%Ź%IÚłgŻl6›bb˘Ť@˘Ł;kÇŽť ×rŕŃŚ™ŻÍyCIIĂ”ťµBRƬ٪¨¨PJjşÂĂÂôí¶-ĘÉ~_ëÖoĐ›sç¬ĘÎŃüysµsűVIҢ…ó5}ÚTŮl6%ŹHU#??mܰF»v|­3ž‘$ź<)IjhÔ¨ââ“ Ňhŕůڤä‰Ô·OoEEuTâŕ}şił¶oߡŁGŹiět5nÜXˇˇ­”0p€Vç|`T0~ÜĹDwVłfÍ®¨řËŻ¶ęřńšöÇ© VŁFŤyË-’$?_żj0+#©Ú*Ô8¬3gÎ3*‚‚‚.»tĹŚŠŔËf[\îä/e[·˝ęZPđĄúJKËŚseee ©}Q©šŤB Ź«uëPă-&%%%Ƶâââ:%Z¶l)I:zěŘU×nűMY,íÚőťqn÷î}F[ľüJ’Ô¤I I¤·ç˝ŁłgĎ*?˙{­Y»VÆi€&3hTůŹÔQŁĺď﯀€›”88A#S’ĺçç§… ŢÖŚĎ«K\wY,őď×GOŚ]eeéi#5yĘ4•—ź×ďí§E‹ćkĆźž×ý>˘n¸Ań·Ç©gŹî’¤‰OŽ×łĎÍÔť˝îQS‹E3¦˙Qń·Ç5L«€ÇóŮ_goß!JË—.V·nń®ŽÇˇ*_3 8“]’Ź«p»ýŇß>fhŚÉđŮŔ٬V«rss]°Z­Ú”›kŠď2®ŤYú•{j¸;_IzéĹçtKd[‡PwŤ$)aŕWÇávWxľ7^Č$KOŐ~‹çňôµA@CşűnÖÔ»+öŇ8Ă ŕťĚ˛§–Ďţ‚<Ó&fSÓĆş:ŕ$¦ž©a†¬¨o? éŇô3މţx/ú?ŕ˝ĚŇ˙IjŹDRx$’Ŕ#ůĚžőĽiß~ĚiÂÄ)—Ţ~2ééé×\ŘÇÇGv;ů .|||ôůg]¸ť;îúí5—ńńńů5©!Iöĺ׹đgąŚ_K9Ŕ]Ţ_W«oN‚=5€GŞ1©qńâEÍ|1َbĐĚ3tńâĹZď«6©ałŮôÄř'µřoK@M˙m©ž˙¤l6[Ť÷U™Ô(++ÓĐá)Z»Ž˝@Ă[»n†OQYYYµ÷T™ÔôÔíÜąËiÔfçÎ]šôÔ”jŻW™Ôxő• ĹĆĆ8-(€ÚÄĆĆčŐWŞßëłĘ¤F@@€–-Y¤îż×iTçűďŐ˛%‹Pí=ŐnęďﯿţeŽ’“†9%8€Ş$' Ó_˙2Gţţţ5Ţר¦‹ľľľšöÇę×®8Z]sŐÎÔpgĆLŤĎrë÷úÖú–ęź[h$I>>>ő*\ßrŇőĺ|.\8ow`, â˙H¸0ÝÁĎ´IEND®B`‚gpsim-0.30.0/doc/screenshots/control_source.png0000664000076400007640000026324213041763626016540 00000000000000‰PNG  IHDRp_AcfŠ pHYs  šśtIMEŢ káÉ IDATxÚě]gxEŰž™-§źôŇč‚RP° * zéJAEDE^z Hµ˝úˇŻ…"JPP@ !ĺäô-3óýäp8I0 "{_ą¸ÂfwÚÎÎ=O™çÖC @RJ(ĎCBáčM;´®)+hĐ A JŻűiJ)DčßP„yÄŇc:‘óH* \2@AČAka ϡaOß=4őŚôĽÎ(…B˙n•ôZ¬A ţQ@éôzŻÇówéŔG ·;4<Üăv__ —Óéqą®»§Ăĺľî tÚíF“‰"9ňOś/~eí/6O Ą€D€G˘™Äz5ëńř= ŕ!!Ş˘ mv{QQ•"H ‡PhH¨Ĺbˇ„hłP nwPBH–UEąnBUUUą‘PUU˝cĺĆJPU«*@g oŃ(tîîÝ-'˙Ěrr¤„R¬r‚Ŕ ĄŹ:¶®)D°ÂŘŘíőfdeEĹ&Z©ę!ËYyy‰ ˝/?Ůů˛Í ýyv•ń=‚(>L×¶Ž^–$ç5ĹŻ 4ü;8•bL ąî5ťRňs%+`Ln BJÁĄ®E„@$ľĐĄACŢs˛@99‚1c>bÔ lpĄzJ5®ewËŕ ‹ŇRŃýµÁÂ`âP1!Dł¤j¸Í– J1Á”R Çqe•Bľ 2B•ěÜ1¦€„ˇŠź%ţjĐp»€PŠ)Ĺ„\·Ę—RŠ ąî@©Ś{í „×໩J"¤Č2{BČ %DUŐrşquů:qDUdIôŚ%ůRޤcßÝB‚1‡Đŕ§šPŮ!đzÝűöP1fśŞMD · Ň3Ď_ČÉ‚bŚăcâj&&űuˇK—/ĺĺç;ÜUĹăđаÚɵ‚ç2Ďç\Ęĺ"”"k'×ŠŽ (*ş“]»„J±2Ć×(Ag0 ŹËĺőzËm -ÓJ)ÇóFŁ@(‚Űé„ÍfŽç‰Ş:ڱQlgěĎ߀R$„b,{%Äs<„"Ę8č˛˙*Š‚8®’±,«@‘&ˇj¸]€ĘÉË=uć÷zµę¦$$ed]8qę¤Ń`‹Žő}<”REUkÄĆY­Ŕ¬K9‡~9ŚŠ<őçﵓk6¨S_Q”Ý?í=öëńömő}„B»ÓqęĚyăf6»í§Łu˘®VRŠ6ňnĺ €B*–EťŽ`¬TěďĂŚÜ€„JJQ® Óé°Şr‚€ťNXž˘¨äů«m¨ŞŞĘ˛Śx`´X@© •*ËLB˝Jk[VP¤q<ây Çq”PžR bÜ{•„JĄTQTD*u B¨bµt I¨nB…čŇĺË*ơáăȰp hN^n\ÔBĹÇDFJ1&˝NđJ^ŽC:QTTc,É2ĄÔ¨7řó!‡Ăaw:âj CCDQĚĘÍŞ™¬} nBő1"-K‡”ęŤFŁŃ1&‡˘(°¬E™<**ˇrŤ(żJyž×Ť!!&„çyłŐŠ1–<â'ŚÂRů’bP‚Ón7L˘ Ś„BŮëő¸Ý”Ri–R˛?ç! °Ş(’A/č„<Ĺ*!jýB™%TĹ2$•2ů@Uˇc“¶^h¸Ö D%ŮK A2.¤”zĽ^ ®Rď`ŚŮ$w»ÝGNÓëô q5¬fk˝šuţH?“s)‡RŞuM4öWĎ@UQAD)EA=^Żöh¸˝8µ„K®¦CJ©ÉlÖŤ’$!„Ś‹Ëáeą|7¦/˝1j@ ”R«Ů $„H’D™!ť BŽśú$Ô€(XUUt:¬($ŠŞŞŞLŮKŻr*Gĺ Á**E@„‘ÇŞ¤z úä2˝·˘(•÷ˇŔŞJ)ˇPm˝Đp›€,đó%E±ŰlŚkŮy3·ÓéqąŘŇýÍw†;Pa €Ł¸+s„ŚÂ\¨ź(y /_»ÍĆqśŞŞ„RXŢ÷Un ŞŞÚívXÚ €Çĺ’<Fa[ˆX`KăS %°Ô¸ęÇ˝BöÍ+ŠRÉXľĚËP‚)ŔÚ\Ăm ŮhňE*Á#„BB(ĄěŰf˝ęł@UU‘˙ě{ ¶Q@U|ĺ`¸A§7ęôľÂµ×p›I¨ĺĹÂľse~˙‚2ż—pją%€â'TLę׎µD0öEúŁŮĺĆZ˘W÷˘lżüKđ˙x!„ůşN€€BB b*_˙‡9Ž+ĘĎ'r•1­LĘ’dw8˘‚5 UĂmą/ó _ăŻ×z°Ľ{µďAĂíú]Bo$ÎQ©¶öF#%Ýp 7ކ€P ůíÉň@,îďőz«(îŘşM–«ŞŞ‚K ž0~†…Ră8ŽŢ 7ÔŹÓëtÚ\ ţ%€°$ÔŃőę•`I7ŘáşK¸rőFJ¸ZŔ…0K1„°”OĎÔă¬ĹţĎ+„D„‡G†‡cBTŚ1 ąVÚ+¦&fIyžçyžă8! €rµw– 4h¸]ĹSB´Ľs¨WĆ˝Ńnŕ$+dÁńo°„«;P(E%ÔR…ďűK‰Ĺă+Á{a©fR‡ĺ®:ëĘîÂŞJ0V4­– 4üŰ$T Cx#Y®)Ą.§‹|C%8ś7T.§“ŕi%ćĄK!BÇůyMA!€ĹňĺăĐđ„Z)DSŘjĐ A ĺn0 ,.˛ť;ý'Ĺ«ö”đĄ˘(`ů¸Ę…Â× A îLBE•u4, ŽOŻ–¬5] 4hĐ ˇ"řź˛Ą„RB¤XUxJ0 ¸DJ”TšP)Ą‹Ůétýúf±XśNç?g¸ÍfłĂá¸n˙l 4hĐPť$bµZYôÁJÝJ8“v)9‰N ĐG¶%ÎI×®Řd2©Ş*ÂŕÁĂŢyç-“ÉTÝcµČň_‡j2™Lýú=łhŃ|ţ“·ąwďľëׯ“eYŻ×kĚŞA ˙d‚Đ˝{Ďőë×I’ô—7Cý$T BQĎ#އđŠÝ”‰¨ĎŤFßď:ťnĚî˝÷ŢáÇ8p@–ŁńzTĢ(bŚ}'Vu:ťŻ'<Ď[­–1c^lҤqŻ^=˙’S9ŽűńÇ1ĆŐcö €˘(Ji„öîÝ'ÂîÝ{–-Kűřă-^Ż—˘V.& 4h¸˘XvÉ5 n·»\ńBřĂ{b VRŞň…€…J¤A‚|€\XÖ†J±ZCÂĂĂŹgřđˇ .°Űí^Ż–fyóµ ”—y§,Ěfó¸qă[´hŃĄËÓcžçűő{fÝşEá8nË–-š7o®ŞŞ’$±N–[8;¶ĂţJČUy*o ®|łŮF&,,2((ý×ívŹ3ęµ×&»\.˙˘XdăćÍ›µląc<~ü„ĆŤ8 2Ű 4hĐpÝ0›MăĆM¨[·Î!}K®,ËwÝŐčâĹŚâââ˛4AiI.d_ßż J/Ć>!€Ŕq”žBÓńB@Y*Ą422ňŇĄKn·B¨(ĘáÇ-KíÚµ| !ĽpáBNN.ĎóII‰aaa×Ö˲ܼyóÓ§ĎËË ĎÍÍÝ˝{wNNNdddvvÎéÓ<ôĐCééé<ĎÇÄÄ>|$&&úÂ…‹Š"‡††Ö¬Y“”(..NO?ďńxęׯWb¦”Ršžž~ůrľŃhLJJ =}ú÷ĐĐŕŕ`„PQQQHH!¤¨¨Čf+®Y3%3óBNN FŤŃŃQ©›Ą”šÍćË—/ąÝ% ęőzĎóąąą™™! ěeŘl¶K—.EEEĺĺ奧§ďÜąłI“&A›ń4hĐPE „ň<_’„ÔĎ{H§Ó1b’$éüůŚ˘˘"«ŐZ«VMAX$J©Çăa”‘ťťcµZSR’ CąůYK°ŘĘSJ®D. UŢ“ĄÝĐét .ľďľőęŐóęŃŁÇV­Zíp8CCCžyf@LLĚ58U’¤G}äëŻw\Ľµgϱ±±{öěíŐ«GffFVVÖ”)“ÇŤ›pď˝÷Ś;fřđmÚ´±X,ăK—.uěء{÷®ąą—>üpýŮłgCCĂľřâ˙śN‹Ł±gĎë×oHJJ,,,JLL9ňůŤ7%%%őěŮťçů©Sß\ĽxˇÇăŮşőËÜÜK;vX·nťÉdâ8^Q”I“&ţ%۱ŃŔXeĘ–f!”‘‘ąxńb„8ťNW\\,<„đĉ“‹/yë­é™Š˘:ťÎZµjëőzmĆkĐ AC±’N§7›M>ÇA(ĄP·Űýĺ—_8p ,,ěâŬvííر ěŃ‹łştéúĚ3xžĎÉÉyŕRSźŕzˇ2í)Ly„¨T@”Đ"¤”:ťÎ¶mĆK’4`Ŕ€°°0AXđ_Vî‚‹&LצÍv»cáÂEß~űÝ AĎz˝Ţkô944´^˝şGŹkÔ¨áÎť»^|qě®]»ž~ú©#GŽ6hpWpp°(Š‚ `Lôz}۶mÚ·L…}űöĎť;˙™gěß 7÷ҤI/'$$ěŰ·ď˙ţo+ĄTUŐĺËWŚű´ľpáÂâĹKwîÜաÓ[·~)IŇŢ˝űľűîű&'§¤§§§¦¦=zĚf+?~\­Zµ~ýő7Aţ2ŻÓË?üđŁěNŻWęŐ«Ç /Śž1cfrrJ˙ţýL&ăÖ­[wîÜE)ĺ8$Â<Řşu«»ďnôĚ3ýív‡–şK ŞRB%&“é?˙™»yóX—™Á`€ž>ýű‘#G_{mrÝşuĎž=űâ‹ă[·nĹ\kY ßŘŘľ}{ß}÷ÝżţúŰĽyó›4ą»Ayf®ÔKbRćAi¤$Pš÷®¬„j4?ř`•Ó餔†‡‡O™2•:öí<Řż˙@¦/-**zéĄqiĹôx<]»¦Nť:íé§źĘ̼СĂk×®-,,Ü»÷Ç™3ßńxĽ>‰YUq‹- „ŞŠkÔ/..†ćĺĺY,ÖřřxŻ×ŰŞUkťNdjzúůÖ­[K’rńâŧžę8wî­˛¬<ýt*ĄŔívoŮňńöíŰ™yéŇĄ7ßśĆŘŠ‘HHHČÝw7öxÜwÝu—,Ëv»–G‹%$ŠD,é …ăË´ű(ÝÇöÂ`žç®4Ď*%1€qíÚµV­ZEUUcěrýĹ©PU%µjĄmܸ©QنÁ»îŞ˙Ákbb˘RR’EöĺygÔ_ĘOJj6›%ٍ¨Ŕb±¦§źUUĚn?wîLBBBaa×ë1›k˘’’ĽmŰ6JI§N6oŢňÝwߥ¤¤g±GŚ:~üŘS§N ö\‹Í|ŢFżŞ’ŃĐëuľ!SU%""âŇĄIň ‚pćĚ!–R— )„>uşF¨4hĐPĄ„JÁFŁ1$$Řß)‰%pCöěŮmúô©Fىâ»Î¤”şÝžěě‹aaaąąŮ˘(čt"!´)%đJu „đ”,{}ńË›ˇ”˛*K90ʤ”*ŠĚ"ę:äµ×¦¦¦vń—_Ž×«W÷É'źřËă.ʧ˙>C† űíé”ŇćÍ›O›6}íÚUŹG§}µČ˛â«ť"ËŠ˘¨÷ŢŰäđá#«V­iÜřîíŰ˙WTd#„rěÖ­ë;ďĚěÝ»ç‰'gÓ¦÷şÝ®öíŰżřâK“'O§¦v™=ű? Ě%„îŰ÷ăŃŁG›6mZPPĎŚŘą÷‘$ißľŮ{ÂÇÇÇשS»[·Ô•+WɲüńÇź˛}ĆXQTŚq\\Üüńż˙}sß}-4Ş 4T©„ʲŁů»1"ĂתU+66vćĚŮ>ŘZ’ä]»vŹ˙bTT$Ł9AvvvZÚŠÖ­[íÜą;11)>>ŽÉu”P+–f@†ÓG5Ő‹|Ďvőe‹z˝Éjȡj6›AhÝş%Bś(ŠŻ×›śś.IŇ˝÷ŢĂq\ť:µÂĂĂ>zţ|FýúőZµjÉqÜ5ȉ9\étbbb"Ďóť:u´X,±±1ˇˇ!]ş<Ť¤x˝žäääpŻWşçž&̶L)ˇQنV«µfÍäĚĚ ż˙ţGűöíkÔkŢĽÇq Ü…:zôXPPPϞݓ’eY €véŇY„řř8„ĐăŹ?F) uąÜ‡öxĽC† Ž˙Ë÷d6›BţůçĹ‹Y/fedd„‡‡'''EGGĹĆĆś<ůkVVNĎžÝĂĂĂš5kŞŞŞŮl®S§vLLL~~ÁO?ý|ď˝÷h^ľ4hĐPul*‚N'Ö®]+>>žçyŃ÷Ý×Zż~=ŻW:räXAAAÇŽâââŘAÇ-šççěÝ»wŔ€ţ{÷îMJJěŢ˝khhh@†oJ©"ÉÎb»Nŕ~ü˝(ý’!H)@kĂa!A†Źß~Ęá–-ÁÖ¸˙l3˘(ôěŮĎ`ĐłS§’$uîüÔóĎŹpą\cťNWĘęă8Wąí\[Ô3ŤË–-ß¶íkťN'Š˘˘(¬A$I–e©sçNĎ?˙\@-ˇ( ’$X*VćgËqśŻ%>‡iUU™ÍB(Š˘ď˙ßŮÍ”Ý×~UˇOźţá#Ç!;uzcĚq<[9Ž“$‰µP–eö BH’$-T˛ 4Tt:q۶í+W®Ňë «ţn1‚ DEE.\8ßĺrůŻüLeDsî\úË/żşsç7‡ĂźDü!t;\ą™YŁ0ű‹sßţRŔs%1“xŠUźĘ—)ýW|YV,ëkĄTŻ7ŘívvŹĎŹ—;Ë Şn·»{÷®ť:u(× RŞ×ëËÖÂţäő–čÄý-ůŞfr}Ůý›ę˙{eBúŕńxćĚy/ŕ"!Ôl6I’L)UŐż=ľú7U 4T$InÝşUăĆŤ‚eđ<ÇĽkË®üLh$„x˝E‘Ż}J…^•j†–\ˇ„/=CSZăŐ6TJiHHp ąQĎć{mĺç?Đ!–R|»´V î4PJEQ ŻY(Ą))É_ýeaaѵO|z@± ä!Ç#NšR 4Üń|,ËňßJgB!€AÄy @!tą\îĚóÚjĐ A ’(¦!!„i sʡXˇg!ćMFsxL$„¨ÚŇŤ‚)ĄW}i×0V€Ő“—¦ĽÚ1UŐ_vň!®Ú^3 ߪÁôM!Ś5}» Ş ŹÓ}9;°5”B!B<‚ ŁÄěšÖ ŕ“'Žĺç_F%ŃŞt)$uëÖ7›-ÇŽŞ$B¨QŁ{Ľ^Ďożť¨~ „ÔŻßĐ`0=zđ¦űúBăââccăOźţŐ鬎 ¬”Ň îćyáđáźnUÂWBHť:őjÔH„ şÍ<Ď3wîŰh-0ô˛¬h.rwB:ťŽ…uÓpGŐĆć]Ě@ıó'ă<ŕäJ#„¸óçĎĹÇ'>üđăŐЬÜÜěźţŃn·őë7¸$žpăÔ©î îŮs@őż†¬¬ ţčrąúő|Ó w8ŠúißîÝßvěŘ5<<˘ş“‘qîСŠ˘ôî=đVÍěÜܬ}űvGFFëő†żÜT–ş˛—đ.;¬ĄÓé®osŁÓéÖ®]÷óĎW®\îp8ţŞvčv»u:]5ěSŻŕŕŕ‡zřµ×^»˙ţű4NýGŠ>WMQڱ˘(ĺf;©di§Nť9rÔ‘#‡‹ŠŠ*şÇw"Ńëőrç‹&}ŤŘs»\.&÷ß„«Q$ŢD0`|«ú¸$„ !@aL8VĂdĄ”"„ţVÔ›Ý_X™xL×Q8ĆľÂIu˝>Âj¬ţÁôë5)qSŻÇĺääćääx˝ŽăBCĂâăă¬Vë–-[ç1ŁŻo˙^šü€/·ďB‡ĂqńbVÆ X|Źçž9aÂřZµjÝŇČTD„PőKó®9EQAAáĹ‹Y.— B\ŁFĽŮl>qâÄš5kW¬řëŰ5ľQ+šră'N4kÖLUUÁ0ţ‚š5kvíšú·˛ZŠ‹‹Źű…çyžç)%ŚŐ‡~¸K—®»wďü»ŢfŰ ¶äĄ°Ľ]sUGť…»Šĺ«#Č-ŞÎ–íoŐŐaIÓjx}·p0ýÚđÄ ŠâîÝ»·nýŠă/×^JJĘóĎ?7tčP–"×l6ł,÷,3ۧł `˛,ł fłŮăńřâ„L&M/[¶A€¨*f%dddĽňĘä˝{÷ş\›Í¶yóf§ÓÎ(ëőzžç™?!”Ů2„Çq„_]ľ×p×ëeÚ<˘¨ľ€!‚ ˘ČÂľřŇ!„ôz=ÇqňAßţ‡ĹŽńuS#¶[AŽ?ţÉ'źz<žçŮ zíµÉÍš5kÓćˇüü<“ÉdoźRâńľ}BŃhT…Ą•X,§Ó? :EA„ĆŘăń°<Ý»÷,((đzÝN§sÚ´7dYq:ť,M'Ëh曂 ° h<ĎłčSr@ ?˙üóŕŕŕíŰwÄĹĹÝuW}—ËŐ¬YłC‡ćsÇš'ŠĄ@–eB(ŠÇaŚ˝^/›í¬Sl†K’t(Q(A„Ą"@%űL ˇV#»WKu˝Ľµ…nníeĂLVsďţ±§® Ăś9sGŽ|ţá‡2 ˛,ĺää „¶lŮârą‡ńŇKă›6˝÷»ďľËĚĽP«V­_{řđ‘Í›7C{÷îýÄŹ[,–‘#GMšôrXXŔápĽđÂŘuëÖů ëëÖ}řÍ7߸\î–-ď;vlnnî°a#G«V­ zvذácÇľ0xđ ksőęvěŘaµőíŰç‘G,\¸Čl6ź:uúôéÓµkל8qbHHo“d4ÓŇ–#322~ůĺDllě¤IĎťK_łf­ÇăyňÉÇűőëÇXóűďwnܸÉn/~üńÇ|FQ„P~~ţ˛eiÇŹźčرCAA!S*čőúĎ>űď˙ű‘dX IDAT9´{÷O?ÝŮëŐ,m·:ťnăĆMqqqC‡1™LŞŞćĺ]ÎČ8O9yň×˙ţ÷żď˝7kńâEŠ˘dee;öKLL̤IĎźĎXłf­Űízüńö 0›ÍłfÍľ˙ţűZ´hÁv‡=zôܸqź2–nŰöőgź}VPPx÷ÝŤĆŹŃ`0>ńDa۶mďż˙ľ÷Ţ›µ`ÁĽ„„„Ç{ŚçůŹ?ţäóĎż€¤¦¦vëÖUUŐ;ţwěŘ1A~řaollĚřńăXů„”””ĄK— &§sŘ>ĐŻ__¶MMí˛~ý‡YYŮÓ§OôŃG>účcž† »nÝş?ţřŁNťÚ“&M˛X,!›Í¶víşýű¤¤$?˙üóńńń,fý?śT Vâ!€P„V@ľŐđS}Ő•Ń{Đj˙©ŇÚoá»»%I+Ł·$×­[çłĎ>;~ü¸˘(z˝!!!ˇaÆ”’ŚŚĚłgĎŽ?±xńŇnݺϝ;×d2ué’şwďŢéÓß:tŘ˙ýß˙íÚµKtű÷`TŠ˘îݻϷäyqúô·Š‹‹§L™2gάěěśŮłçÄĹĹMźţf­Z5?ű쓞€((č»ďľOKKëÚ5uęÔ7¶nÝşrĺű˘(-\¸c2oŢŠŠ ˙řă„ ›7oYż~Ă„ /Ťůüçź˙÷‹/ľĐét˝U?!‰‰‰ű÷ďß»wźÇăE1&&şYłf„âbŰŃŁÇéééiiË﹧ɢE ëÔ©Ýłgď 6Lś8áŐW_=~üÄš5kEQňäÉË—KśIB;wîňó»D›7oůᇽ/˝4~Ѣ”Ň÷Ţ› HK[j4?úhóȑϫŞüűďdee †M›6Ż_żáĹ_3fĚÚµk?ţřcŁŃxéŇĄ5kÖFEE-Z´°A“'żîŻŐ`2«ŞĘĚîëőz™eçÎ]!Iňţ÷żźź>ýÇěŮłű÷ď7oŢü &>ňČ#óćÍ yůĺIz˝ľ¨¨héŇe…sćĚŽ‹‹]ĽxńĄKą·Ę۱ňRQ"+>ná) ´<ŰŞ–9*Ý_Őňů-ŞŞ´ż"i5H¨·âőýEŻý,CŞOŐétşfÎ|wÆŤoż=ăôéÓŃŃQť;w>|K5ĚľVŹÇ3eĘk-[¶¤”Žű† gĚxBX·ní={öś;—( cĆÜ7€T3E‘¦OÓ§ž4é原š>ýÍž˘˘"m¶bJ){„çů>ř`Ó¦M 5’’’ňóó·ný˛C‡NŹgÄíÚµŁ”Nś8ˇnÝúů+Ő©Çă6lhÇŽ !ăĆ˝8oŢüożýźÉdBť?ßöűďwAČ}ůĺÖNť:µmŰF„ŮłgőíŰÔ¨‘—/_>}ú÷5k>°XĚĎ?˙üŽß`ŚEQ\˛dé’%‹!ť;w޶m[ŹÝ=Ź–ađ¦,´LĄ_ŃźŮń9f¬ńx<#F OHHX˝ú^d}ě±ÇĆŽ}©CŘőz˝C† ~ę©§ŘŰź;wŢ7ßě`‰:}ôŃm۶•Ţ ýÍ~_ îŰ·S®^~yâC=2mÚÔđđp„Pdd¤Ífc±Í!„'¬]»vęÔ© 6Lś8á˝÷f0P–ĺŽ;ôë×cuěŘŇŇ–WF%ËšAMNN~ýőÉ„:ujoÚ´95µËŁŹ>B)7îņ ďćyţŇĄK'NśX´hˇŃh4hĐСĂňňň˘˘˘TU˝ĺ&˙kt„"ž‡ĄÁy@@»ZĹ«!­ÎęĘk©ŢíOY‰üföĄ„0$$D’$–’ÄÉś­g>ÇRżYÇť={víÚuÇŹw:]ÂĚĚĚr©—ˇ¨¨(""ś]Ź(,,Ą†|ťNçt*,żČßžç-KQQĎóA«ŐŠRUU§™;Ąt˙ţ˝{÷!„9AFىă¸ÜBĹ/„čŇĄśÔÔ^ŞŞ”w¶“BÄQL°"#žňXńbŚ>{J)!Uí&zŐKŻęę@I<¨ů†Vă‹©Âţ""0WĂëó'3BnÁ–BZ®ŘӮݓ„ŹÇ ýꫯâăăëׯo2™BCCďş«ţ©S§ĘŰ‘řŹ_`ÉÇŽMNNrąÜź|ň© řG …Ë–-oذÁÂ… t:ý_|1rä(źáŠůwř $„´hŃbýúŤĂ† ÉËËŰ·ďÇ řÚ@ią{MŕwĂ|żŰ([4¸ëÇ´hŃ"22rŐŞŐĚśf6›żýö»öíŰ˝{÷ůóçŮBÖŞUë‡j;`@AĐefžĎĚĚtą\µk×kذ‰ć|#ŔőŐËîĄüa2™{¬#!X–eE‘8@)mҤIppŮlmܸÉ'ź|@Ćţy=Ţ>«($$äĎ?Ď(ŠÂqÜG}@“۶}]XX´eËćČČČďżßŮ­[w›ŞŞj4ýg]óćÍ?ůäłŃŁGRJ?ýôł-š¬™Lś˝>!* ýľjŤFc§N‡ úŕm {öě Sĺá‡ŰßB˝/BÜöí˙wm¦€„J|‰â V·„ZĄ[ŻŢR™¸ %ň29áAµK¨·d ¦×Ť˘˘ć4¨Şęš5k3331&FŁ!..nÚ´©Ş*{˝^ŹÇ p8>ĺĄÔf+f‹„ŔăńH’D2aÂKË–-űŕ5FŁ)%%‰c$Ůívzöěľyó–Îť»čtş† 0ˇ3**Ęb±6oŢbÄáC‡·ŰcY–§LyýÝwgîرBÔ¨QĂ~ýú@\.—,+ľEĘfł]˝`A·Ű-IriĂ Ífó-˛¬¸\.Hż~ý–.]6jÔJ‰Ůl™2ĺuI’˘ŁŁűőëł`ÁÂąsç%''Űl6ڱ$IŻ˝öę˛eiÝşőp»Ý±±1©©©<Ď{˝ŹÇ­‘⍀ĘjkŠŠ B˘(B¶nýrÁ‚…’$ úĐĐĐąs˙ăńxT;ť€Űíöy•Cý•ʲâr9ýű÷_şti×®ÝôzCăĆŤŘ4ĆŘíŔýëcŹu(,Ěg0;$Ŕ– Ä zf@u»Ýěł°dY–$ÉjµRJ\.·Çă…Í&§Ó®ŞŞĂá`)˛Kg]Ée%¸Ýn—ËĄÓé‚Çq쀖Űív»=ŁŃ`4ʇ)†ń•ĨB[aŃ™_łšőď}úű7GóD‘§„Jů 4TłˇŢn*­čż˙V µ’{ŽăĄ<ËBHpp˙ŠęÓJ™LFź‚‹1^Ż'„čt:¦ÎEü•=â«7 “Éäc;V—Ĺbńoct˙+¬_ĂüoĐéDť®äđ>kRŮýVPPPŮŃÓëőľŤ†›·qżž ±ŃhdĽ°š „łŮđö}÷°ĂÄ”R ˙ĽŇéôě¤ipp0‹Áâ˙řŢ»Ż^B{–Őâź^“]aŹřÚZî'YîDĺ8.$$ŘwŃ˙cř&s@#oPäx% â8XîbXőn˘·Ňç¶úk °gßěÚi5÷®Lwč-rJŞđO.—S–Ąęo•†;›MˇŃh‚Ú¤»C@DĄî9yJ1(ŠŚĹ#¬âi"%Uý,DŐ,…—é/ő dqsűë˙aőĽľ€ S®‹PUiąoŮ]ŇÓĎZ,VŞ%úŐPŤlšźźÇ˘iŁqÇĽő’ä§ś ByąŠÓWéZTÖq¦ę—>z …Ş˛˝ŁUé–T-ŻďVJüרBčt:ŤFÓ=÷4׾w Ő‰ß˙őčŃCfłEŠ;GH-•/ Ą”‡Ńr†´Ş·öeTľŐoCĄ·°ş›];ĽÓ^ßµ+őYÇo‡Đeţ‰@űí·ă‚ Ö®]Ż’łĹ‚ÖÄÓ;„–0”ň”pkň3kş¸Ď`^ßą´j赦ńŐpÝPUµ4™R%żmĚîHŔ+qŞxPľâ“Ą+©Â%ňΓPI™˙Â*ęNµH¨¤Ś_ń-`ńż¬Włˇj¸±oęo¤zÔ&Ű˦”PŠ1ä8žŇröůlĄŞb7ZFÄůwKuă›=ĽŐ<ž˙ÜŔÄŻą\j¸Áp%g‘Ƨw ›RB%B ,fR9Ň­jŻ–2)<˙ÝjÜÜúýb—śC­§$XAďŞmH+3Í´ď^ĂßBľĂ”•ťEšńôޤTCxÄóńţ«!‹—­ťC˝éý HSĄŰjx}WwçźuőV‹Îţ 2Şß/ôo>˘áŽ™%„0U#ű‡‡Ë›˙úP;˙žXľŢ!‘’*3K5ł–†ë!ľŮE5ކ %T„Jó`PJŹPľ¬ôFHŐúmŢň„š·6ęM^-jEˢfCŐp]ł‹ú’˙TrUCĘ, ˙4-DBH(xĹ¸ŚľŽV~_v˝ó5 ăX5Ý 8¬IŞ7°,űÁŢĽâ¸Ę]›Vőxt§ZdâżŇŠFŤQ5\'ˇ–xTvi„zgJ©AH!ňĄrý»{˙źŻw„ZĄý ´hVűëű'ÚPKĎŐhËś†ëޤúöľ=‹* 9§á_Ϩ,€G<yˇĽ­ÖdCe)“8Žs:ť×˝¸›L&–€©âęŞ-˙+˝“óˇV™@ĂBŘäeÎ#\둿ÇŘq§ÍĐ.OB€wmQˇdz@vĺ)eŤyŐl„+Ő«Ü •çů?˙üóĹÇ:t(33C–ˇÂśVŹÇ—ŐČ!!ˇ 4ܰa}RRRąź_ŔV©HwçŘP+GşšĘWC•îŰ®s ţŰo'23Ó9Ž×†řź ŚqrrÍk宆€L)€@<%*-'R%˝FşPŽăţřăŹČČH«Őr+é-qË?c0čgÍš=zô¨®]S].×ăŹ?ţăŹűÜnwŮŚF㣏¶Űµëű˛é»)%˘(@ •éo^ •”P9Ž;qâD­Zµ| ~o†\UŻŹă¸ŁGŹ6jÔ¨ĽŮHŻÎ×ç[§­ ®đoßĆň‰VnI©,Ľ^Onnöý÷?Čqś¦Gůg‚çů_=îpŘ+~ű<ěń˝fžçu:„c,I’Őüę«“'Lx©}űö6›Í—ŮXJ©,ËŠ˘0(Ćçyˇ˘(’$•)ĽÂŘuÇét:„ĆŘëő˛ĽµN§Ë÷(ŠBŻ×+‚(Š!UU˝^/(ÉÖkPUEŻ×«(JĹň Ą”ňĽ••Ő Á]Ápřđ–IŻ×«ŞĘ:%I’ŞŞN§óČ‘#……ůV/„PUUY–™µŽçyÁČŠ5»˘ú_çy6ÎN§Ód2ů4Ď!˝^ďtşôzÇqld(Ą^Ż7€Ôý:@IĺßTöúúőđý÷ß…††:„PŻ×sG‘$ cĚ\QQ(Š˘lÓ®9Ň—»›i´X:ťŽő‘MP˘f9Ž÷ÍÖv'k‰ŞŞ!!a:tĘËËÁápřĎlÍ†Şˇ* ůbWÚvđ·l¨`0Ł˘b´ŃţÇ"33#''űÓq<@Wt < ”ń ’ú믿-[–vůr^ăĆŤ‡¶qă¦ăÇOL™2őÍ7§oŢĽÉd2q·aĂĆíŰ·[,–ţýűµlŮ’çů©S§Ő­[wçÎť‡ŁC‡ýű÷óx1bXçÎť¸ÜżFłŮ<}ú›§Nť>ü9AO)ŠŠZµjĺożťZąreăĆŤ·ný2((hřđˇŤ52 =zt_ąr…ŞŞ?˙|đý÷WŮl¶V­ZöęŐ+88XřÇŹĚ™37/ďŇÝw73f”Ńhô™TËsJ˘lg°cÇ˙~ůĺ„Đ7ß|»zőűďĽ3cöěY‚ @333WŻţ`ŢĽąk×®ËÍÍu:ť‡®QŁĆ¸qcŁ˘˘®M%%{fB>˛jŐęâââh=dČŕÉ“_u8Ď>;BřĹ˙%„¸ÝîE‹;0%%EĹ‘#G=öŘcź|ň)„ 5555µ‹żÔ~ B5Ť‹-6™Ś§Nť>vě—Ź?Ţb2™¶lůh۶mz˝ľOźŢ=ô,ËĹĹĹk×®űé§źM&ăŔĎ´jŐ ŕv»W®|ďŢ˝ńń5† z÷ÝŤ† ¬Óé:w~ZĹO?ý$` UNµ¦‰¨nP;[9†üűÁD5Ůôö~÷W J@)E”bJ®eg˘”Ž=şcÇsćĚNIIůî»ď|¦QŁFŁGŹ\˝z•Á`€®[÷áöí_żúę+O<ńÄÚµîß@Ż7;öËŇĄKűöí;a„O?ýôĂ×WFÇČqÜŮłç,XőÖ[Ó˙üóĚâĹK8ń<˙ŃGó<ŹşpáÂO?ýqčĐá ¶mŰćÍ7§;öˢE‹EQtąś}ôq^ŢĺE‹´iÓ¶b 8e+řČ‘Ď'$$Lžüę˘E —,Y´}űvžçťNǦM›óóógÎ|÷ˇ‡ÚÎť;ďâĹ‹‚ |űíwÂâââÉ“'÷îÝköě÷ôzýÉ“'@˘¨[·n]ďŢ˝Ţ~ű-—Ë5mÚ›ĺZ[t¤ˇěěě>X·|ů˛¤¤¤ďľ»˘Rv:ťű÷€ËĚĚ|˙ý÷SRRćĚ™÷Ę+Ż^s\ů˝°°đŤ7ŢčׯĎěŮďqwčĐá—_ž1}ú´eË–0IzѢĹéééo˝5=<<|ţü…ééé:ťîÇ÷ŻX±â…F>lÝşuźţ…N§«¤žäôéÓ+VĽ˙Č#ʤĄ-Őëő6lüüóĎ'Nśššşaæ]»v‡„„Ěś9Ó땦OsěŘ>űěsŽă\.׊+Ďž=űÖ[ÓSR’—-[vęÔ©3ŢEqŢĽąsçţ‡i ţÖÇŔ\Kţ5 „ŤFß–÷vŰf‘Űęe”:%•č{*÷F@w „1—$ Dq”’>eÓĂ7QdY)..†véňt×®©˘(čtşŕŕਨ(#bőęŢ|óÍřřř¶mŰÔ­[çŔĚH0n܋͚5­_żŢ´iSß•(ŠźY€L̲€ýöŰoÇ=űěłÉÉIÓ¦Mýî»ďťNçřń/.Y˛”Ý|ňäŻEE¶Ž;nŮňŃ#Ź<Ňşő‘‘QS¦Ľ¶qăFŽă0ĆuęÔ=zT||Ľ^Żó˙ŚŻ2wJ)Ĺó< !¤”ŞŞÚ°aĂ1cĆÄÇÇ=ó̧ÓU\\L)EůŤ‰MĹgźضmU•=÷kŻ˝Ö¬YÓ„„„ŃŁGîŮóSĎúŐNj/-J~ňÉÇ»uëËqBĐ˙!¦äôz˝Ý»÷HMMŤ‰‰?~ÜáĂGĘ]¶Ę 'Ą”J’lł‹˘8dČŕ–-ď7›ÍÇ………EFFRJÝn÷Îť»¦N}#))iđŕAÂS§NAeYzăŤ) 4hҤɨQ#Ů~¨˘ Ż×;tč6mÚDGG#„–/_1}ú› ÷ß_łfM÷ěŮ Â8v·Ű•8{ö{Š˘ýđĂމ'DFFőë××n·ź?>""BQvEľ¦:×wěßóś’Rł¨¨°ęňz=7«(›­(99988ř¶mâ·÷ý»Źh¸“8•Ą$ŔCÄAË®KěP3cŕőë×-^ĽäÖÄĹĹ>÷ÜvíÚůËş”‚¬¬¬gžyÖ'Ź5’)#""XBÁččč‚‚‚ĘŔ „’äZ,I’"##Ć8))©E‹ćë×očرĂáĂGÚµ{Ô`0*ŠźxJiPPĐŇĄ‹—-K[˛dYíÚµFŹu˙ý÷BCB‚‹˘(I’ż%űšJ©Ĺb1 .—Ë·é%A•ŻTj6›DQđxTVř5ŢŻ]aaa‹-HK[ľxń’zőęŽ5ŞyófŕŞÜÔétFDDx˝^«Ő őz% !4**Š lxxxaaáŐŻďZň1!$44TxEQ „ąąą öMŞgź}ÖívN›6uÓ¦MÓ§żív;»tI6l(ĄôČ‘#={öbC !°X,Ś5Ëő ¨„şě í#„~úég€ÉdjÔ¨!Ó ÄŰ233˝^ottt||<»ź’‘‘QPPhµZőz=Ą”㸜śś¬¬,„P||ŤČČUŇGFF¦ÇăŽŚŚ¬QنŻâĚĚĚË—óÍfsbb‚Éd"7G~ˇĚ¨˙·T…”ŇË—/cLââb+Ů łŮÜ®]ű;ľľ)é˛)Ą‚ ^ĂůË/żÜsĎ˝˙¨lđľíS TOşßüüüŚŚ JiŤ5®iÓYYYYYY˘(&%%ł‹6›íüůó˛,ÇĹĹĹĹű‹ŞŞ¦§§„„„$''űÔ„ŮŮŮLë–Ę.ÚíöôôtŻ×ë›Ě„ôôôË—/Ą¤¤ř4Uąąą.\ŕ8.!!!<<ܧTKOOw»ÝŃŃщ‰‰ľÁ<ţ|^^žŮlNIIń©îňňň233‰‰‰ě˘ŰíNOOw:ť‘‘‘IIIľ‘ĎČČČÍÍ5™LÉÉÉ&“é#ćőzÓÓÓ‹‹‹#""’““}s8333''Ç`0$''[,˙ń<~ü¸ŞŞ÷Ţ{ďő1ęýĄBTÖçÖű˙çźÎź?!8eĘÔO?ý¬]»öq˛,Ť‡ĂA)x衶={öHMíÂóÂÉ“'%IÂXEÝ_ü_ýúőŚFăG}ܢEsEQü"ř «ť’J®cŚ#""ťNçŃŁGď˝÷ŢĎ?˙"))‰ç9EQ†6nÜř5j\ş”űÄ].gJJJ˙ţ}‡ źčpŘöěůů±Ż L´ XV ÷UÍ$r_c|6żr|Ë•eůŇĄĽ÷ß_áńxFŽ˝k×îűďoĹf^éł„ŃˇŻ Gü>WźÔE(%„ŕđÇŹ<üpۢ˘˘/żüĘ÷°ŘO)×R? PY˝P’Ľ«Wżďt:GŚx~ßľ}-ZÜÇqś×ë5™LN§çąÄÄ„­[·>őÔS‡rąÜ‘‘”bA¶lŮ2jÔHYV·műşiÓ{UUńďÎŐévŠú·cܦͩ©]şwď&şÓ§OŰUU=yňdçÎť_ziâŢ˝{RS»=÷ÜpQž|ň‰ˇC?úh;Bđ?EDD`¬rďőzŁ˘˘ÇŐő˘ż0přBűřăŹeYޱă99YEE6„Ýn_ştŮąsé&“ńŇĄĽ7ŢR·nŚńľ}?¦Ą-ŹŽŽ.**lßľ}×®] Ă… ßxă łŮBAM™ňzd™  IDATd¤ĂáXµjő‰',knnľŇ°aJéˇC‡çĎź]\loŐŞUż~}+űmĎýĘë•xžʲĚnA F—ËĺóŇÂX•$É?˙ (ńĽĘ« !ÎĎŐKRBÄ:věXUUEQ„Ȳ¬ÓéěvÇqŢét±Ie4eY..¶V>pŕŔ[o˝µ}űö˛Ç7*7Wü–$xČqĺáhiŢ"zčĐá^˝útéŇ-//ŻS§Ž’äißţ±+V>ôĐ#‡“R2qâ„;ľIMíţÄOÎź?ż¨¨!ĘĎĎ5jLź>ý>ňĘ+“Ľ^Ź.¤˛ág)ŞŞ6iҸuëV3fĽŰŁGŹ 6<˙ü˝Ţ@)MLL¬[·îÔ©ÓşvMŃăńôęŐĂh4Ť7áńÇŰ8řĉ“AUŇŁôDöU?e÷ ” ‚ŮŔŘl6 ŞŞN§Ł”ˇĂáPUB`łŮ(l’Ą¦vëŐ«Ź^ŻoŐŞ%Řn·cŚY™„Đâââ€6TP;$‰ůÚP <Ď+ŻLZĽxI·n=^|q|NN¶Űíx<ŹÇ[:h9WWT¸ßź¨ŞâďżßůôÓ]űôégµZ[´hîőşSS»ĽňĘ«O<ń$BČh4>÷Ü?\ߣGŹ™3ß{đÁ5j¤Ş*BčâŬ48++{ôčQn·§âŻşîrądYń˝ĐW^™´sçînÝz<ńÄď˝7«°°@„üüü7ŢöřăŹĎš5{ěŘ1Š˘‡<űěŔµk?ěСS§Nť7mÚäńxEíŢ˝Ű!Cşvíf0*ĎŠfzÉNE–Ą ć3o/¶ďţ˙ű_QQŃëŻO^´haűöí.\„r86lčßżď˛eKFʵ˙ß?m4-ZÔ¨QŁ˙ügÎĚ™3˘Ł#׬Yc6›öîý!33sҤ——,YôÔSť–.]Ćü“ßUŹÝ—.]2~ü‹'OžűäćrE v»}Äá§Ó1oŢĽÔÔ®ďĽón^Ţe_\3J BpÆ ˝{÷>|ÄţýŰÎńnjjęŔĎîŰ·!!ČÉÉ...nŮň~žç~řaĎСC{ôčąm۶>}úétbvvÖK/M4›M”“É8cĆŚ'NX,ć>}z‚}máË/ż\ż~^Żcw4HQdUUúöí÷ŮgźĄ¦¦ŽűÂŻżţ*Š"ĄÄ`0|ńĹýű÷ëßŔ®]»yľäPŮľ}űFŚxîé§ź~ůĺW._ÎÓëuO>ŮÁb±´o˙Ř1c,ł( oĽńF×®ÝgĚx‡Ť‰˙n˛ş~؆•)ś„Ď?˙ĽWŻŢ}úôőýtďŢsěر§Nťâ8Îď‘ëÇ’%K/^ś––v÷ÝwĎ›7Ďn·/_ľ<;;Ű'Ř,Z´ňî»ď¶k×nůňĺłf͢”~ôŃG€Ź>úc<{öěĺË—·k×nćĚ™Ś¤7oŢé¤ljD"D4|ř°Ůłż“Ďç‰(ŽÄă1×uKĄâ˙ýż_6lçÉh4’H$Şů×4’ŕóp8tŢyçžrĘÉžç†Bˇd2©=µŚáŤ7^_(ęęęJĄ˘Žt¸řâĎś}öYŽă Á‰DąěŚ7ćwżűM:ݶë| "ŇQyétŰ3Ďü.™L)ĄÔ;ďĚĎdŇ“'O~ňÉÇÓé4ĄÓmO=ő+-ľóÎ|ĎsĂáЬYWçr9-ŃÇb±m۶=÷ÜźR©”Öá‰řĽyŻtěC÷y¨ĄRé’K.–Rćóy­űÎqÜÁěşç<‰”ËĺíŰ[®ąć*DÔ‡K6›yűí˙Ľ_6˙×H$2kÖ5ů|N'2EŁŃl6óĹ/^ö©O]ŕyž”’1<üđĂ&L_.—-ËJ$–e©rąŞ5Ë3füřÇw#ň•+W555Ť9˛\.źuÖ™wß}ŹvŔ/Z´čŢ{R*•&L‰DÖŻ__mŔ—R>řŕCoż˝ŕ{ßűî’%K,X0iŇÄ믟3nÜř±cÇÁďąç§C† -‹?ýé˝étćć›ozůĺ—ׯ_7f̨Tä™;÷ńżýíoßůÎuË—Żx챹pŇI'^sÍ5#GŽşůć›sąěÜąO}ôŃRĘM›6oßľ}úôé/ľřâC=|á…Ś5ę?¸óĹ_Ô˘ý«ŻľŞýý:líĐC§ !^xáE­‹ľŐ«×lÝşM‡pÎuô"ţéOÖŃň˙řÇĽ{ďýŮŐW_=uę”gžyfîÜąßřĆ×-ËşńĆ›lŰF/żüĘ3Ďü÷ĺ—±¶¶ö׿~ęÇ?ľ{öěďýä'w}ô1>ř€ă8ĹbqŐŞU?űŮŤ?ţâ‹?űŔŢsĎOľńŤŻń.B˙ţ×PU6ă8Î)§śüěłĎţéOÖ=QJĄRÉkŻ˝věرžçUVvݬúóćÍ»í¶ŰÂá0ś{îąźůĚgîĽóÎÜ~űí·ÜrK6›˝á†ľő­o1Ć^~ůĺ»îş ššš¦M›6oŢĽË.»lţüůG}tSS|úÓźľűî»5;ܸqăÉ'ź Ç{ě=÷ÜłcÇÍůćĚ™©Tę裏~â‰'`ńâĹcĆŚŃ–Ţ‹.şčŽ;îĐÔ˛eËÎ8ă 8ě°Ăîż˙ţ-[¶Lť:őĺ—_ţă˙Ńhôä“Oľí¶Ű`ٲe =z4\pÁß˙ţ÷µÍyÁ‚Ź>ú(L™2%Ť®[·î裏~ĺ•W~řaťMwć™g^yĺ•Ú®ŹÇ:č 8çśsn˝őVť{ůĆo<ňČ#0věئ¦¦ĺË—źzę©óćÍ»ů曵ůĽóλđ `óćÍp衇ŔgśqŰm·iŮĽyóîż˙~:tčČ‘#—,Y˘§}Îś9§ťvÚرc÷Ś›’RJI ®e|±s7Xűu(ˇP8 WÔafwMK‘H4‰v °´íP}}vŰt©ËµÓÚ¶:1¦¶¶¶ë_·AaŐÔT?Iś‹ššZ)UOL:ÚnS[[´ŮĐШ ŃŢ”JżB)jhhÔŹ…Ă‘p8Rmü©nëëŞűĐÉuŚH‹ 秲çÉh4ODRşA˙ůË_ÎťűXccĂŕÁV­ZůĎţó¤“Nń<•ÍfËĺâčŃŁďşëörąT*•V®\1fĚX,ńüóĎüń'žx‚eY7ß|ăK/˝¤{Ĺ "k™cő‡ţÔ!j¨Ňźk1‰Äőׯ®®nĐ k×®}óÍ7?üđąsź¸úę+§M;o¸áú/}éËR:Çwě±ÇŁý2łf]}Úig”JĹ~ýš`Ŕ€ţą\Ž1|ăŤ7âńř…žoŰöwľóíO|âĚYł®âĽ÷ËäV‡JÎŮĎ~_±X|ůĺW4úęWݏüň/t[fĎÉdR)ÖŐŐéłÎ:kÓ¦M—^zikkë÷ľ÷˝iÓ¦@:ťŽßh4Ş5°|>lóşşşt:­ą\Nr×uµk ş…D"ˇ“Ĺ …BŕM$ş"*‹\Ą”Ňyét:8˘S©T&“ŃÜWůő±Ł?Ô}ÓŚSKf:\?“É'@mm­~]ą\ŢeŰv6›Őâo6› ú&„Đ-dłŮ®3VńúůOj5Oż.°ńÚ¶­néŇĄożýöC=´4‚‰ů>Ôîc9öÎ|áşŢ1ŁĂá°ŽĚ|?’Ĺ^q“ĐľănBí–vµ7ŁŰűˇyž7qâ­‹ě|8ť|¨}P|×ĂějÖr€R@RR4+•JĄRYŃÜĽµ¶¶V)`±Xtűö‘H$“É2Ć,ËVJŐÔÔn۶-™LJI;v´ęł ‰¦ÓéBˇ(„hiŮšJĄ”L$â۶mŹFŁů|A) …«÷RÔÚÚÚŻ_?}6A>_¸üň/}á _<őÔ™·ßţn €®ë‹…şşúR©„Ř^TVŹkÝş _|I`ířęWżšĎgďĽósç>>{ö ĺrůüóĎżôŇ˙ÓÖÖ˛|ůŠÓO?ťHf2ŮX,fY¶”˛©©_ő®ŠNN™*ÉĎw7ˇ~RĎ$cŔkhht'Ť a ܱcG]]#˘ţýű+ĄŮćÍÍsç>ţĎľžÉduőâ‹/Ý|óÍ·ßţ˲Z[w¬YłćĐC§‹Ĺ±cÇľýöŰ---B§źţŤV8ăśóĺËWDŁ‘ýëŤ5kÖ0†Úsˇ” ú¬'pűömŰ·o·műĎ~¶T*i»h©TŇiĘďľűnsó–ÁyžsČ!Óž{î9Ç)+Ąž~úi˲coĽńĆŰoĎ˙ĺ/ńź˙Ľq˙ý˙USSŁOOÎyą\ŽFŁžç566śţyŹ?ţŘ‚ ţůĎ×ćĚą‘1VŐŤŢűW Ż€ŠčG?şkÎś9_ůĘů|ľăüĐ^އzâ‰'ţö·ż- RĘG}ôÔSO€U«V=ţřăłfÍ:ňČ#ď»ď>­Jžzę©?˙ůϵyóµ×^;üđõ=öµ×^۸q#<đŔúëÉdrČ!Ď<ó üď˙ţoMMŤÇ=í´Ó|đAÍ ˙ú׿sĚ10mÚ´… ®\ą|đÁ“N: Âáđĉźzę)xĺ•WcšÎś9ó‘GŃý™gž9á„`âĉëÖ­[´h<ňČ#Ç{¬V=ôĐąsçŔoĽ‘ÍfGŽ 'ź|ňăŹ?î8Ž#:ĺ”S`äČ‘mmmÚÉúŘcŹvŘaÚĆţńŹ\›|.\¸iÓ¦ &Ŕ 'śđ»ßýN/ÄŁŹ>:sćL2dýă˙€§žzę ŇŔ‰'ž¨‡ĽbĹŠwß}węÔ©z&·nÝúë_˙Z[¤ő«_í +¦d(‘ş9((ĺłÇČ岻L±Ŕ nél]$‰>ŐP±;´ż†¶÷óHš=N•|ÁîzŇ9[Ű»tą%Ďó6mÚtňÉ'rČ!sćÜpâ‰ÇŻ]»föěŮJ©xóé±cGçóůŻ|ĺË7ÝtóĹGŹýąĎ}6›Íyä«WŻľőÖ[ĄTŃhtöěďe‰/~ń wÜqçsĎ=Ç9?çśł§Nť¬=ĘşcśłYł®ůŮĎţë÷ż˙C<»řâĎŽ;¦T*wÜ1?üđÓO˙Ęu]ŞŻŻ»ä’Ď=öŘ܇~¸ľľî+_ą‚1L§3J)Ąäµ×~ăÁž;÷qÇqtŃEź˛,±eË–Gť›N·…BˇYł®.ňď˝÷ŢŔëęjóůüůçź÷óź?pĺ•WsΆ Ć#R őźřÄi_úŇ—˘ŃŘČ‘#¶oßîy^%:Ż=·ŇuťŹü¨ĄK—|îs—D"‘‰'´¶¶ÁđŻ˝öęOů¤â˛Ë.?~<\{íµßüć7?ń‰O â„ .żür1cĆĘ•+żýíoK)ăńřwܶmĎš5köěŮ• ő™éÓ§Ŕ¬Yłľýíoź}öŮšŹjęa‡¶bĹŠ9sćH)#‘Č­·ŢŞkĆ]{íµ×]wťŢPgź}¶–®¸âŠŮłg_xá…D4xđ`íWž4iŇé§ź~ÇwÜvŰmˇPč†nĐĘču×]÷Ío~sćĚ™śóSO=UsßK.ąDŹî˝÷ŢŰoż]«¶»uřb%Ď€05劚¸ýŰɗű XRĺT˛¦©©.—ÝŻ©WX,–,y'“IęSźonŢĽß÷bkëö… ßN&S§ťöÉ Öí“»žż˝PČ/Z´ PČ_tŃç7mÚ°§]×Y±â˝Ťן~úŮ:Śb'—Ë.\ř¶çą^řąŤ×cݎ×$ôöŰ˙9ňČct(ärąeË–Ž?iË–M“&Mikk ’z7oŢڎR*×ŐŐé*Í™LVJ/Ť%“ńŔ7źÉdJĄ’mŰÉdRť]†ů|>—Ë!b<ŹĹ˘:ÎŔqśL&ăy^4­JnŁL&[,-ËJ&“:y´S˙łŮl±XBčW$“Éoś“HÄ/»ě˛ G)•ÍfKĄR(J&BX---őőuÚaS(ňůĽR‰„u˝×ułŮ¬ă8BT*ĺ8Î]wýđcűŘąçž­Ó]<ĎÓ%J2™Ěç?éoüłT*é<Ąd4u]7‘‡Báććć 50@ˇPĐ;][»©©Áu˝C=lá›7oB$‰P(T5]yDĹb…B±©©QJY(rą<Äă±BˇĐĐPŹČ …B6›Bh3¦çyŮlV»Ó‰d8ę}vĘ9_ľüÝúúĆçóŮž0KDÜľ}ëÂ…oGٱ3Î8wÇŽmÝn "zĺ•fÎüäóĎ˙÷QG׿˙ŔęéŐ‚l"‘Ĺbş~x<×HťJĄ1›Íćr9Îy2™ żT*é\x<^ý ÚÚÚ´Ĺ5•J¤•Ëĺ˛Ů,c,™LÎ×rąśN§Ą”±X,z%˘¶¶¶b± …R©Tŕ Ő-č]ŔK»0Óé´ëş±X,ppjĂrˇP°m;•J~Ö|>Żuîę\×M§ÓŽăDŁQ=Xýy:ťÎçó–eĄR© ™°ÓŚ«¶¶¶®-d2™|>Ď9Ż©©éZ¶oË–-ýű÷ďôáëŻ˙cůňwĎ;ďÓžç9ÜضŁuĹâ%ÉxřŽßż÷×ů͡…Ś€€n2öĘ…š°ű&űüŤ}XHsŢ0ŢCëęűrWWĆĐÁ/tĚąeYőőuk3řk2™ ˝‘´ď'8ztÄ™ « Đko!‘HTj]»ŹÇµě¬˝/ţ󳯿ţĎűîűYµëZźVAO¤”ÚQ¤čn¦ôa|R*•/^üµŻÍ*—?˙ŘcŹtФÜrË÷?ůÉłt„ŞeY őť&§ˇˇˇ«PýĆJé *_şłéŇž<íf ŽÎ ŚbđdĄŕ Î⾲~´Łí˝˝#.VOŽ6–VŻf(ŞęTš@›gć€1Đg·äWŤP(¬cµ P[[[%ş‹lŰî*‡i'hőX4tú@§-Ë ĘDT#•JUSE·3Ě[·-ToĄ®čĘM{D'J‘”¤r]]Ë—čäË^¦á^x]×ňô}Xz_żşŹ‡ö.ńý!(>ŤĆľ˙ýŰţú×nşéĆúúş}ŘçşşÚgźýS>ź×E<Ď›6mę>¸iÓć3f\}ő•:€y/Ý “&M”Ň;ŕnőˇŞěASÂŢ`'š„ç‘”ŕ Ruôdv$¦ýJFť+%í»(U˝ Öó+Kwźźa—(ßý=ꬓ°‚Řű…Lß·R}(îCÍfłßţö·Żż~v±Xt]w/c[:ÍNď©ôś)S¦<üđĂŚˇçyĹbqď%!Îů˙řŚ.cr ”ÚiW÷d˘ĚÍ»Ařőđ‘·s­ˇĘťčsű•@h™”űgäЧjíżéíT×0Něů˝ťĄ~ µĎ‡nQ,Ş.¦ŰŹđ<7—s÷­qBgxjPj”hO®f3ř€¸â–Íc$€ůwĎt&Ą^ć6˝m4¤ľc/Ť·Ó㽵|Ŕ‡Ě}“{y"U*răţ NŢáËűPp'đŻňPN™€""ă©r ­ď;đ´wőľ`ap@é§DűO»D˘C† {ńĹżžú…”rô豩TÍÎ +IĘD¤Q ă]ĎÂŢŇŢökĺ ÷=jU_X)÷Óx©Ú†Ü'†>b]†_|P„ÔÝÝcÇN8q˛™ę28çÍÍ[vů2ÎlK–Ë‚”¤îŻ!¤Ţ¤× X|ď˛4ęÝýIűsz;_0ľ_çs'e§>@GbPź™sÁ`w¨Ş ;쏠$Ą”®¬kđ®vń'dśůWůĺyJŠťh<ű•^÷łÎÖ­(ŃëcĄś IDATŻÜŮx÷ő«±«¬°_××e§–ůľ;z=śŰŕa©UuŚ{xÁ¸ óýč±ZDdŚ”‹Â čŽVz'¶Ó}¨˝,hPź¬ěŰW#övČ4twťíŽÚ Ś Ő`/É›Ld›Á®$(@Ć9(EČăwš‡Ú›®÷ 38•’:Ú“±/bnűj2i—ÄN}u ŽÁ‡ş>ěNh›aĽE "r`@ąŐŐÉÔ ˘}ďkT]6Lݦę) ޸ĎÇŰËúb×ĺë“ ¶zrĆ™ B=;!´ňa*%ěBh'"†:yP tµAű[Ëé¤ëë˘zA?ŻbÔ+/­/u/îÓˇu JR˝;ś^ťĚnI¨[nŞcÚÍĆ7Ř}ęň‹Číż $N¤c’ P]ŹÂJţŐţ%^öˇvŃT(jßę‹ú†«>™Ćśb†ˇěĺéÔŁů>LĂ3čCÉ !Ş[* ^ĎcˇŢÜ!Đ÷Ĺ}ö±µ»ŰË{y8¸’¦ Dŕ‰H@ĺ¶ń^VqşŢýŇűhoľ´Ć[í íýĺ다÷]bĄToŢzkp1Tµ_+%0”b€ Dź*}ĺ Ř}¨]W˝›÷­ĺk2g öJŕ&BCB»<ú) Č™ %U—JI}T]˝—_xǧ.…™zc6?Xr#b%rʇ{˘ˇĆăq"*—‹†„ vÁOµiP'Öť*Ó •’°O*ôňU$]Ăb÷ç|öÁňőEĄ¤]©mm­™Lz×Ďěât¨­­SŠŠĹBuŐ¤]sîyž™˝Ź”ŕE@H¤”$YÇëcŘ+ńH‹ ôţ} ڱľ;giżN/c¬wŚ˝dFŐŻ_˙ĺË—ľůćëĆjĐ»Ç+Lž|đęŐ+zĆ}c&0ř !¬]פ€tB@ARVťżÄ9_·nMSSż^P88ç(„xçť·zŤ§"˘ă8K—.RJ)Ő«©“zĽś‹E‹ćďóŠíšsa-_ľ4‹÷Îp´Yuńâ Ąě}r×SÚqpëÖć˙ţďßčmĐ'˝2ř(ă˝÷–Dٱ]?ăşîoűšÄŐ\×Ůąˇ‹™ĎMQ@•łM)5dř°B>żjŐň^¸ŁCJ9jÔx<ľdɢ^ăm‡vd©T^¶liď«ĹRʱcLJÑ%KîsyE)Őż˙€Ź|ÜŠ˶nmî%U)yĐAS„‹/쫣AOi(dź$É‹.úĽ9 úŽSŢ…Lá…ź3Sô!‚RĘuŰv˘Ę c@D˘úvq" ١)S¦őÚů(Ą cŽ9ľ7Ź` 3fśÔ‡´.ĄŞŽŞ“RîرÍ}Ž]lCC˘Îj’Ö]´˙R d¬C° ôzŰJÖ˦×>ycŻ˝˝÷c"úv2wë 300$j°Ď@šŁęůŚ€Hš # vK2ŇuÓ‰”Ô^<ťŤčd`````Đ%•t¸‘tDDJ«¬:üµ­m‡2 «A·z)bˇ ěö¤€ZaŐšią\jii&sÝ•A÷ Ľ˛‹•wdś#2XÉ,VD55uă'd*}t ĆŘö–­‹Ţš C΀”T“‘Ň+ň&ŢŔŔŔŔŔ`'*–ťR`ń­ż'PRtľ»ÍÄ$ě’«¶˙@@:‘!" ©wj`````°»P¤<’‘1AF+500000Ř}=U_´… ‰H™Ë öH?ué”Hę;g€‘ą€ŮŔŔŔŔŔ`÷Á¸ŕÜ"R …PŞÖaÍĽ…`–MĘSJ2a ˙Şh]•°X(‹S»ŮŔŔŔŔŔ +¢öA! ĄD ‘"cmm­Ż(¸ećĚŔŔŔŔŔ ”’ét[$ἢŽ"r+¤” €ŔPóŮl63|@żÉlfÍŔŔŔŔŔ ¤ôŢz덵«W7&ë€ApŽ HűP+J*˘6˙îâşyŹ,C%"†¨Ů&!"%€ ęzDú ]m`````đ`¨ŞŞĽ (  €‰ uA"Ą”‰K20Ř-0ĆtYl"ÚuAlĄÔâĹ‹>ř`ĄcĚóĽ}»Ýcóçż}đÁS‰LJśÁľDÇ=E¨K!"€ť3e”RFC50Ř-&Ą|íµ×–-[&Ą1bÄŚÇY–µł}äyŢC=ôĐC˝űî»Ë—/?őÔSÇهý±,ëţűď˙ůĎď7]ě[(ĄŞ&… 2.°S}|-_ ŐŔ '@DĄÔś97µµµNš4‰1öüóĎýĎ˙üńÇ?ţ1"†B!D,‹HD©TM&“fŚ=ôĐĂĄRqőę5Ź>úŘ™gžĄ”*—ËŐ›ŁŃ(çB) ®ë‹ĹT*ĺş®mŰčşNˇPDýŰ€ë:ĄR)—Ë=öŘcétc,‘H:NY˙µ\.I)Ăá0cśHĺóy#:ě.Cíđ«ç’”Ŕ-P@J "Y­Ă"‘Ş\:n``đ>D"Ź?ţD[[ë¬Y× 2Z[[o»íö|đÚkŻ˝ďľűŇéô׿ţµb±H$>ö±Cź{î9:ě°“|î\‰Dnżý¶Ď}îâR©4ë8Îwľóť^xiúôC˘ŃČ”)S®şęęóÎ;÷¨ŁŽúýď˙P(>ýé‹®ąćęrą\(}ôŃGů…ă8źýěg.˝ô˙466N™2ĺµ×ćµ´´śxâI_üŮx1vőŐWŽ7îg?»ďí·ß7nÜŹ~tWż~ýŚYŘŔ ç ęŔPçŚH˘\”$=َě8ç/˝ô·™3O0`€–^“ÉäůçźwÇw]{í·Ňét[[‘č·qă&)%mذaܸqŹ=öčSO=ő›ß<ÝÖÖV(Ş÷ŕí·ßQ,_~ůĹ×^{}Ö¬YŁFŤ€;vüö·ż{ŕűŁŃč¬Y_B\}ő•/ĽđÂłĎ>÷řăs›šď˝÷ŢÖÖÖ††† 6(Ą<Ď[ĽxńćÍ›_|ń˙˝÷޲ٳŻ/—Ë·Ţzó!‡ňŘcsŻĽňŞgžůCąlBú z®ˇV»Q…ĹlŔSž‹(˘j?ŞRd‚’ zĽÁT6›‰ĹâÚö«?LĄR™LZłFÍMĄTÚŁlHĄ¤çyJ)×u:9;•RĎ?˙üK/˝ …fĚ8öÜsĎ-‹ĎnĽńúA!âM7Íąüň/ĎšuM4łműµ×^;vĚ—żüĺp8ěyžnDJ9hР믟]*•Ž8â°ˇC‡wÜq‡~¸çy_üânżýŽ€ÓôRŞęËP•çzĺDR 2`XU őö7 ŐŔ 'đ5gÎM‰D⬳ÎBĽüňß~ř‘›oľ)źĎ§RÉĹ‹oÚ´©ˇˇáˇ‡) DJsYĄ$"H)‰”m[ĄR)ŘtD4}úôxŕ«_˝bÁ‚w^xáĹsÎů$€ ‡C=ôĐm·ÝGîż˙ç'ś0ĂóÜU«V®_żţ–[nÚ°aĂyç]°uëÖaÆ‚®/‰HJŹH)ĄH)©­ćŁúgł=DÇ(_DDDÎu-ßNQľĘřP z)ĺرcľűÝë~ń‹_ţä'÷ćóůšššţđŽ)S&çrąăŹź±rĺŞ3Îř$çěśsÎ) RJ"ĘĺrRzĂ‡Ź ‚‡Ý|óśOúSŐAIßúÖ7nľůűżřĹŁŁGŹJ&“:;śjjR\đ©Bˇxä‘G|÷»×ĺóy۶_yĺď·Üň}ËgźýÉH)sąś6ůćóyĄHJ©”*‹ŽăčĎ•jĆ,˘AŹ5Ôy¨Ě˛x8ŠĚ"Ą¦¦\Q·űý3ňE/WĘ ;fř°­­; C50Ř-0ĆŃóĽóλŕë_˙ÚńÇĎp]7aőVd ĄTúa­ęoifٵMÎy±XüéOď8pĐ׾vÍG}Ď=?=zUP-%CĹe śłN/Ň?W‹sn¸©Áî2ÔććÍëVŻ®KÔEmvçW˙żwZm΀”ň<ˇá8Ž”ž”žçyď›ëŇműťS茱×Ŕ`o4T’Š”$Fśë(_Uő€ďC5Ůi{†ŃŁG=ůäÜl6§Łm÷ śóC=ô÷ż˙C]]Ý—żüĄ ĆgłŮ™3gĆăqm46ól`Đ',µ#U =ŕD&lý !c ”bĚ| ö®ë¸îŢ–d O>ůÄ™3O%"ĎsËĺ]uŐWÇ1qą}§ˇBuÔ")E @‘Žňešë"âÖ­ÍáPXJOJĂP ú–1wVpsąś™>˘— Ëâ#÷(JŚ "DP¤ššú—ÉyóÍ׍ŐŔŔŔŔŔ +˘Ńظq[6n°c‚ "ĎÓ÷¤†BáIžvđˇfĘ şUS·oÝÚĽ~#é;Ü‘‚ €Ŕä @RzŇ3îŘ)b{T C@Ô±żŔHIRŞóť¨»!2B9eéézI€~"Ť™$î4TĆc>IŔtüŻôóccŰ[¶non1óe`````°s¦ŠB]ý^)Ď@Ƹŕ–Ĺ„ŕ 9ŻŽěÝ…–Š ŽwüI>P7ía—WaÇ/V·LÝĽąÇ#ďŘí}¨#mŢŔŔŕĂęىÖóŁmgObĎ޸‹/ví3îäçžÇťúÓíŻô~=é Α!’ô”NH@PvĽ?ľ˛¬ě*"…€Čuy‹fx¤€őżJQRúc""%@Bdčçá´·HJ2ŽúÎ8R’¤W —bČxĹ׫ťŔ@Ę@äÜź9"đ+˙u™""IJ×/%@dL`{R¶łüjv®Î>Q¤Č·•k A)RQ[Ď!řˇ‹°đ.ëíĎg‡·ú#Áť¬+‘.}囨}~üŽő€pű¬3]aőŠé© ň¬k¨ç ˇîQp‘ď˝ÇöácUÝhDż™J7+  ôŞźYÍhZ%"E ë‘@Q‡FŞjŢú4Ş$ gŚ|BňK•'‰yR;B’ŔKE ut”"ý‰v«€ĐÍęwxXĎ0ľŹ «é Po4d Pźi˘×Ű»ĂË| !Rz±Ň´ŻWŐEŹÝ µŹśHC‡ł©2Ď>)`…ć}ĘÄ€B‰*äK @RhßTMýJůťD揪SŐš`°JÉŕ@ Î"ŇŁő{ND˛éfű V­{ĺÔ ţH@# č éé“GŹ őâmVÓ“^Y’ÔÂ…"Ą€rś‘"’’ #%őv® Ś·KR’RȢT» ô'XáeĚDäßšLŔ”ň@äÜŞ÷«OŤ¨¤ŁÜ2p;ŚB ¦h×F@IŹ”‡Ŕôńęďjé8Jş $p‹‡"Ěפ”ŇÓ‹Š‚#LS*ă‘U¤á*Á‘@‹EHD$%I-‹ˇ ô'RŠH""BŹBK)Ô~((幤$2†ÜbŔ€!2Ôą’ň"ľęěkŇŚ1®ŞŇ r˝‘~+\µ"vUÉš¨) }1B)`Z–çďg\`5+­(€6•€HţąY%)SeĐú<‚ŕę’*-€ČSÄ,Q¶‚íŚRiéR/8Iś1†Ňő|Ł" #ôoY©RmŘçۤ”’""·ÚĹpR %=é–ą°®rAhnJţt~ą©ČZĚFĺę˝čÓI…ZłđÉJKÍLOG"…ČýݏH"‘’ŠHâ8ă@źM¤|}Z)`Ś(źa»ÉĎ/«ä ß–Ł<ĺI}^ŁeˇĎ˛•Ö*ç¨<©%h&„/çUÔ6źD}ă/RµV%ž$řv¦ŠxXĄ*’ňôęp;Ň®’dČ‘ň+„3Ć|ó’†-)éaeŻ‘ô”ôtŃĆ-mľňmWZĽđ•[Ą<Ż"čű!”XŃ!*ź€(Ą<$Ąü>Z‘nTk-mIÓ­ň<@`ÂŇ‚` aC†Ś(©”ä–Ąw‘f{đC>í)IJ!ů=bŚCR„€¤$‘dLd•]Ü®]#’oqQšŮ ÷÷1çĚç¸ĐÝm`ŐŇŞ ßţcŇ b\hu?Đ˙¤çyĄ2(b!›q Tź´”"-ńh#"#éI×e¶Ĺ-KK}$ĄtDĆC¶o¶óĎU_m­d”č3ł]”J)×őY¸R 0Ćl_ćS®[Ů‹ľl‡ČĄSFÔ\źcšŰq_Ź’RScŚ@)Ć”ă"ăL0Đ<ŃçNľ$ŁĄ7ŽLKŠ„Ĺ,”˛úëD$ÇW.\ą ‰`JIéşLXŔ¨¨Ďڎ’D  sEç©[Ďj¬Ť7ˇÁGŔ“Š=řë.<‘=idţÎ]{OˇŁýßo8;󒾯ź¸Óç ;CÄfżxiăŻ˙±É‚CΔ”x™6g€t‹RR,˙Ѭ“×IŐ3Ć;ú{ľbć6 ‰…#µĄŢťrYضmY®çíY ®ë2ĆÂá°ă8{vi·ľý0‹9ĺňžµ Ą,—J‘X¬”M UĽő7Ëž{«€d©$gÚę-ih˙šľtüчޓŔ•”RyÎdrů|ŹßM–°jjj,ËĂV ĹÖs])ĄÜ3†ŠčyžVĎĽ=e¨žë2Î]×Ýó_p0üű7Úr…Ž 2v6 # Î'ő'Ďó¬ęš‡;ç<u]÷ŢOĎó¸Ž }ż†gVđŁÍMU%\n79Rĺë{Ć’ý*ˇR{ĆÔýxă=n!x{%˝Ga8őđ•ńľwDËAČc»&Ş„>Ü’b{̰ú|±ÔÎP©›‚úś‹¦”D,¨=ťw›ÜZ X˙T„®&Ý=sô ,ËzőÍni٢ŻZüä)gPüŰen©=‡ˇ×ű)¬7ügůę•gžtÚĽ7_+•ËD˛Cź8ićY0ŘW›KUţíŮ÷U€˝hĺŢőşmÁ˛,m Öż2Î9çžëvR U%YÖ˙śëWňJyQťäčçTĺŐjn\›ŚśsĆôž÷yý† ď-Y*•äŠ*k¨kvĐTŻĘĽŃ-“ëPfˇCNHg¦X•#Ř…MR7UŻ×ůźż>…Ł‘¨"Ĺ1dřĐ]ŞÓ+vÚ~ĺ÷ö*d-ďth»rW^Řy‹J@®çžyŇé‘HÄuÝÖ¶¶ĹË—:ĺ2 ©qŁĆ4Äâą—ţ·-“9ďôOvÉŠĹhňD×Î÷|] JNůÔăNF†Ď<˙?€ ¤4ŇóGˇ’”ZżÜĹC;/NÁ—¤„= µą”RRv+V"b4cŚňyéy]ߢĚHĘN-X¶O$¤RĺR©T(ضŽĹ„…\®T,vÖP‰d•‰A:eágµk•´ëvn¬ btîÉ€cRJ_1öŢś±…ď.ÚşcŰIGźL$Ú2él.+=©yFŮ)·ĄÓĄrIQ“LŢ1"*—Ë›[¶Ô¤jjS5¸ĄĄąX.01¶văz] II™L$›Çiˤ ĹÔÖÔĆŁ1Čćs™lF*ŹĆRÉÎX§˝,„h¬o8ţ¨ăň…ü[‹,zoImަ6Uł~Óť•/• Ůö×IgÓąB!&Éd<Ąr©eű¶x4ÖPWźÍĺ¶íŘV_WźŚ'¶·îČćsŤu ‘pŘqÝÖ¶Ö’SfÉx"O0Ćb±\jK§KNٶěÚT*Ž@6—ÝŃÖŠJ))ĺđ!Ă65o€!w[ý\Jp\—sNDó—,PRÔ±!Űn޶•së6mPD!Ű^µn c8|đ0}ľ¤ł™\>ÉX<™HęcbÝĆőZš˘P(T—Ş …B¸ąe‹ă8D¤HYÂJ%SÉXB’dČ\ĎKgŇůBžsžJ¤ń8Uöţ޶Ö|±Ŕó㉷=ĚR‘Ůě u&_Ć·¬®*]»0]­ˇîÁ jÇg±c-ŰćBč×IĄş2]ĺ:˘N-x®ëş.Y–%’IMö®ăx®ŰiĽ•t.Ó%ě ""‰€¤*ťě¬ˇ‘’ŇseŹb˘8ăRJĺۨŤĐzŔB1V(˛kWŐĄj“‰Ä€¦ţRI( ď­\^,ű7ö۲µeőş5ÇN¨MŐdóŮ7ügâŘ u©Zd¸lőŠ–m[ű7ö·„żčmÁECm}Sc" …ĺkVnoÝŃŻˇ1 ŻÝ°nÂčq[·o}oŐŠD,‹ÄÖmÜĐż±iŘ ˇšÓ´Ëž€D ”Ô=ačůZřîbĎóRÉÔŕţ5ż_µnMó¶–¦ú†b©´jÝš±#F754J©,^ŘX___S·~Ó†Eď-™4vüÄ1–­ZѲ­ĺřŁŽ“R.|wQ[:=xŔ p(´a˦ƺ†~ M™\vÉŠ÷<×Đ4`ĂÖ ë6®›4vB2žÜşcűüE â±Řŕ"ˇ0"ţçťů0tŕÝĂ`‹jŰ®>®¨X* Η­^Q“LŐ$S‘PDJYIn÷săI‘ëą6oܰyc}]˝”rőş5#‡ďßÔŹ3>ńÎxc}CM2µfĂÚşTíŁă±ř˛UË[ŰÚjS5ú\łeL71™H–JĄ•ëVooÝŢżˇ_®PXµnÍÄ1ăkS5J©ő›6®^ż¦ˇ®s…"Să[ĹĽeü; µÂ»ţ  ‡Ăˇp¸X,óyꢪ"@»ÉwŹ4TÍJb×@X– 1Îuˇ ;ćB8ĺ˛çşÔ±ŕ׍éĐ‚R*›NGăq†¨´%I©b±č”;Cvń IDATË´“Qt´ß– ň<`Lz¤§÷FµuH)E®çx=»x\r)•Ôś™ŚÜzŕÂóĽq#G/Z¶tÍúµ6o´„H%kĆŤťŚ'77oŮÔĽyʄɚú7ÔŐĎ{óőkV6őcD „ĹS¤P!gLp®÷(ç"ŽL™09˛˛5֮ݰnÜČ1C áś—GJůîĘĺDjŇŘIáí˝'W®]]›Ş­I¦S¤bkşőĎ/üE‘r]wÔđ‘ŃHTIĄŐľ©§Ä"DÜŃÖşzýęýŽ6RzŢëoýkŮęĺőµu¶eőkl,‹;ÚvdóŮúÚş\!żŁmGŮ)554…l›š·¶„ĂáţMMńhL*EŠh͆u-ŰZŽśvxC]]S}ăß^˙űęőkž8Eů>xŘ!Ă´ô„ŁŹ×s»Řô^őĹĐńŁĆĽ»bŮŠ5+-a Îô0bȰMý–®xŹJĄ!€T˛X*®X»Ş6U3fř(EęÍo-_˝˘ľ¶žŮLpa[öAă&Ú–MD+×®©Ż«ŹĹbşŘÍıăk’5‰Dâ_óß\»aýÁ“&okݱvĂşŃĂGŤ>’˝đęßŢ[ąüC>ć¸Îʵ«˘‘čřQcˇ\.ç ů®b·a¨ 1z' •1ŤÇ™ĄRɲmČçrť,ĂX‰ňÝc Őg‡šˇvlc‰„f^ZŃdŚq!â¶ÝşcGu‡µÉWv×ÇqBžÇlŰs!8Ž#» V©@ż­rŁ·„.ŻJ HzAHsGc”"ť÷Ó#K âRJŞą ¨J5Ö5Ä1­™ô¶Ű67oiŮÖ ‡'Ź›X(]Ď‹†Ă T$€\® ‹áů‚®”P©+IR*M”‘PČő\äĽT*9žŹĆt†´Ĺą’2WČ3Ä_ý›ĎŃĄt§úd×?×$RGN?,›Ë.^¶t݆őMu ¶°ô±pXIÉ]Ç)–Ę!Ëć€Ü¶8çą|^ë˛ýú-[˝ĽeŰÖR©<°ß€­Ű·6omq]wŘŔˇz+Ž1zŮÚUŻýű_Řż±ßča#¶ťËç˛7üŰßśgsY¨lĄ°më@Ř@§­ARúQHŐţ6 hM·6okiٶmÍúµµ‰T,ě×ů“•Ň}žçŠ…~őŤ‚1@&8oK”ô”äţ”Ú!E˛CŽ[vü’Ş E””ŃPX)Ę @T.—¤’+Ö¬\±fĄîU&—Ń»¸P*¦IK"‚űĘŠTA˝sĄ$†úQ0ůV\;qÓX<ÎSžg۶ë8²b±X.›íß ZÁŐvŁ=é@Ĺ ŰŐŹK…|>Ť˛JÍQ]¦±Ď+);Żş.}wžŕx2i á–ˡPČs]@ŚĆbąl¶ónŐ µZ¦¬\‘"¤[FÎýň­č«ÂŐ˝EĘőÜFńqĹĄňČżhÁ¨§2Jĺ’%¬ÚdŞ.US—Ş}ăť˙hZ۶%DľOÄâů|ⱨ’ ‚'ĄRTrňRJ}HµŠ¸9mËĘ䲩dŠ3ć8Ž"‰Á‘‡f۶RJdGŮłr‰‰˘p( G¶lkńx¨ëą–őu Ű[·ż·zy6źĎćsJÉŠKEĘĘĎJ©úÚş!ýonŮ⺎ •KĄŃĂGŤ6rőúµ –.Ş«©‘JŠĹ!ýĆcńęÍ&•,”Š«×Ż)•Ë­™tż†&K©Ű×o ‘pdč€Á[[·/_»Ş\.qÎF®EWPWS»±yó€†~‰X<‰ljŮ<¨ß†¨M=+Ö®Š†ŁŚ1×s“ńd8v\gđ€AeÇY˛rYżúDt\Ź16vř(Ą¤'ĄÔŰ—çüďoĽ §Ď8Ą:JPIÜ„€žôć/y§6Y‡•Rm™¶Mb‘çą©D2_,¬X»* î?ĐÖ°AC7·lY¶jĄTžRräá:J+ń‹—-IÄ[·oĐo@"÷ÔŹŽ†ę—D¨âR®ăčŕťB>ďyž[.Găq‡Č«\¶ÓA·SJi µcU!„ůG—BtmAűP;·TĄÔÎQ%%TÄŮ®-P§<×uJ%R*“ɸŽS"‹Y–ĺ:N7}čBđúú$ŚŹąí0 s]ďÔÇßxů±Žě°Ł­ŤÂö”É\×}ßě7ŕŚmŰÖşií†T4fŰ–‘[T0Ķl¦ě”µüdYV<Ź†ÂŠ1V.—ł…\Ůq‰X,‰jú+•K™\Γ"jăLż†&ĆŘć­Í‚ó¦úFýCćI/WČK%HĹ“ŃHŠĄb6źó¤äŚÇc±H8ÂŞ˛G¨y[K%-K$ă ۲cÍŰZ”˘ţŤMA–Ž”2›ĎË%†‹Ć  ĹB¶OĆâńhy÷»í0!(RR‘ľo¦SP’bŽëx=3ů*îűP•’JqĂPT(€D,ž¨RµJ¤ NQ›¬©ŢľuČ5Ö…:‰˝RĘ~őŤŐŹ)P%±D° ô×Cv¨ZTě´łű54uĄ~ĄTCm}ĐOŰ€ÉxBgËtúS$‰„#ŕzn8 ‡BŐ¶eKXő5uŐíë˙9ă5ÉTőŔ<Ď ‡ÂĂAű Tc]x˛CD‚ă8ăFŚ=t¤ÖSĄ”5‰T×@łŔúšÚNłZ˝Dś±Mý‚Ç´ŁçĽ©ľ1H:ŞŹč´¦Á´¤âÉTŃD »3Wč{R•ľćRĘN䢤|ŁeeĆôMp;#¸ň.cw¨ÖÔµŮq;sôšz5ŁD %"˘Rϡ]kí`&bŚíhmłxQŹŞ4p΋ĹÇuˇbw28€M@»ű§žî_Űă7î~ű´ł;¦:gîĹĐzřu"˛„e‰ö_÷ň- T`L®Ţ†ľZŚ T÷őÍ{ţŢp•dcvúGbżkńt/ŞUĘřâž×9"b{SkIűPÁż|ĎĄ = U¶1@„˘ŻţÍ˝Š:±ĺD,¶műö_?ö¤'Ąçůţ 廵őŚ!"ăŚ!‚ ÎS©äČáĂc&đĎŔ ŻÎľ;ŠשfśNąkÁOÜéĆĘ€2Ś!0T® Ż”ľJBçń€ŞÜ~'ąe‘ÚDD:űĆLFDD’Rv±Ź|ŘáęL°=˝éE»QA©˝j\wŹ[ĐŞ¶·- Í“’´&Za¨(¤9˘´9ąŽsč‘Gľłxqkkë‡čľŽ} ۲węa3000řhbďíŽËĺŢű;¤’Ň€¨ ‘‘1Ś‘ç2d˲ţ1oޱ'śđ˙Ů»î¸(®µ}ÎĚl_zŻŇE¤(Šě vE±aĂFlŃXٱ›Ť)56ŚF±ÄŠŘŔŠ ¤J—^v—eű”ďŹcöňa‰ÉŐ››ËźŹâ µZ-€Ăáŕ8Á0 *¬ĆáppŁiF§Óńx<}YE’lţ äÝmłçW­Ö ˇ%ťNÇ04A¤!4mó‹˙yÔÖT_ŠŹ÷lăőFp.ú$I–—˝RkUýBĂTż[ˇ FpC3Ň4ĹP$ź–ô–˙Ŕ0 Baxmm]lllff–““ăĚ™3ŚŤMH’ĽwďţÉ“§Ôjuhč€Ţ˝{óů|>źáÂE‚ † ÖŻ__ĄRŮb‡¦P(~SúäŁŔÔÔ<33ŰŔŔČĹĹí]ç<ž‘““ëĺŐV(}`ł{÷îĺńx¦¦¦ ’H¤ ×ĘËËCCC_ľ|YVV†¸ĐÜÜ"4t€řw9¬¬¬ÔÔ4•JimmÝąsg+++€L&»v-±ŞŞŠĎçűůůůúúBăă㫪ŞFŚajjJÓôŽ;Ĺb‘ąąůŕÁÉÉÉYYYBˇpäČ‘ŕúőë%%% ˙ţü* 5Ť‘‘QŻ^˝¬­­555IIIőőő¶¶¶={ö,**ľ}ű6AHÎŚa@0yňäíŰ·;;;8BřřńăGŹétş vędÁâ­„jmcŰ«o?¤ěO˙04EÓŚŽÔq8śĽ—ŮÍ-PšĆpbÇ ‰O‰“••Ő˝{÷ü-6yóćK$Ň9s>‰ÄsćĚçóůóć}>pŕŔ¨¨©§Nťľ˙@ ¸qăĆŢ˝űĆŚ‰$$$'''$$dčС˙·ß~C¦çť;wRRRşt   …_ýµJĄŞ©©Ůľ}»ĄĄe˙ţý?~|ńâEš¦űöí[XXřóĎ?“$‰aXż~}333űôé^ÚŰŰ»şşşm۶|>СC‡ěěě^˝z™8;;kµÚ1cĆŘÚÚž>}Z.—×××ďßżßĂĂŁ_ż~R©ôŔmÚ´!ÂŇŇrÔ¨QC‡Ť¸qă`Ŕ€çÎť;sć Ŕ××WŁŃxxx™™±ó& oµ÷|-@!“IĄR‰DR__W[W[S[S]]UYUYYYQ^[S­·V›Z° M¤Nh qÓ+µ|l,X°`ÝşuhŞúÇA&“>|ýŢşuëýűc „îîîÜ›đů<Ź·cÇŽ > ¤iZŁŃîßżż{÷nXĄ‡ĹźŽă………[¶l‘Éd3fĚpttĽuëV||Ľ±±qdd¤T*=zô(ŔĚ̬}űöئ‡‡‡««kaaˇŹŹŹ\.W«Őľľľ(6ŤĂáXZZšššš››/_ľP^^ž››;lŘ0SSS€˝˝=bÇ={ö :ÔÇǵieeuńâĹĚĚLooo‡ÓŞU«FEEY[[s8@€N311ńńń©©©Ńét\.7//Ż]»v–––SSÓúúz“=zÜ»wŹ˘¨“'O2ÄËË ĐŞU+ý˛ĎČČHż€8tčzuʧŃh’’’şwď.‰ĚĚĚ0 cÇ ýÂýu~(ŕm~\ă i15Wú˙ôëׯuëÖÍ …WŻ^­]»¶S§N>>>+V¬@>ĎgĎžéŮ´˘˘băĆŤť;wööö^şticc#ŕĺË—ááá~~~=zôŤŤŐ·öăŹ?˘¦fĎž­R©ţŢnĹqüŇĄËóćÍE‰a؉'ű÷ŕĺŐ¦C‡ Ăą»»Ł9;;—č÷ŢZ$çGŽůŔ2şZ­vţüůcĆŚ9qâĂ0çĎźź;wî!C.\¸Đ®]»±cÇN0áĂ١oßľ‰‰‰/ëę꼽˝Ńq ĂŞŞŞĘĘĘ®_żîďďP*•ŤŤŤM›âĺË—ęLMMq—H$č†#""”JĺĺË—ßdµnÝşeff* @bbbż~ýôOˇPÔ××ßşuËŘŘX(ľző*==}íÚµkÖ¬9|řp}}=@ ś8qbٲeK—.]°`ľŰMLLú÷ď˙ôéÓŇŇŇOägÁâAÔÔÔĚŠţěÉ“§č^…FĽ¶oÁż¤ß´‚Ź=ęçç—’’bddŚvq†IHH@O¬ţäššš;v™™Ą¤¤bcc9ÎŻżţŞR©<(‹ °k×.@đđáCŔńăÇQřĎgź}6nܸɓ'WVVîÜąóâĹ‹K«ŐÎś9óÇDĄ©š^hjjjhhXPP@„©©©Ţ1‹ăřË—/Oť:%‹‡Îĺru:ťŻŻ/ęŰk×®ť={6**J©TFFF6{G4M›™™ÝĽył¬¬ĚĎĎŹť%Y°řđxĽ—/_®Xą255-'7wÝš5]‚H%ůî@#cdhšˇč·îy1 3~üřm۶i4šlÝşµĽĽĽ©!Ü™™™ąąą$IN›6mË–-#FŚŕp8z%%Çóňňž>}Šăř´iÓľýöŰA^Ľx1yňd€µµµźźß˝{÷7nÜ2d­­-`ٲeh+¨)8pöěYĄR©ÓéöďßäČdŻX±˘˘˘‚¦ésçÎĺĺĺ.\¸jŐŞĘĘJ…B3kÖ¬cÇŽétşgĎžmŢĽą´´ôý¶)Ă0űöígzĹŠ/gÎś%đ_˝zµpá"©TJ„JĄÖjuĄ80tĎž˝4M)•ĘŁGŹöíŰG§Ó¶`WÉ'l\  O­¤¤ÄŘŘÇńŚŚŚ°°0‡sřđaD-“¸Oź>±±±ĹĹĹÁÁÁŕ÷xoŤF3wîÜčččţýű8p`kkkffvíÚ5tUAAA||ß××744ÔÜÜ|˙ţýeee .üá‡,,,"##Ź?^VVvďŢ˝QŁFˇWG«ććć8EEE;wî¤(ĘĆƦk×®čŕ#Îź?îÜ9š¦[·n=fĚÔÔÔ .Ĺ⸸8d4—––FFF.\¸°ˇˇa˙ţýQQQ!!!ąąąl‘5,>Đćčč¸ůŰM:ťŽ¦h¤Ő ŢŻQů.cĐ/Z­6¬›çŞ™=JmZÝ˝gO䶢iÚÚÚşşş]°iÓ&‚ -ZÔ”nŃzpńâĹS§Nˇ%<Ă0AAAçĎźGŃh§çĆŤ{÷îE#€nÝşĹĆĆ:88Ô××Ďť;÷öíŰmÚ´±°°XłfÍ„ """P^A}}}@@@~~~ӻݩ©ůöŰo/\¸P]]Í0 źĎݍ¨Đjµ—/_ŢşukqqńäÉ“,X`llěääôüůsd ż|ůrܸqČ)Ť¦§ąsç"wńďËĹ­[׆Ő××¶ŘDŇĄRůőë×'NśŘĚ·ÉA§Ó=xđ@§ÓőęŐ‹í ,ţv0 S\\đ8%uř¨ŃĺeŻhšFŐÔ)}UŠ")’@&‘ľ|™Ó»_•J[^TÄÁq>Ž©Ç~wó2@á[˝ľ$Ifff¤R©L&CÁ‡o…ąąą˝˝˝\.Găx3B255mŐŞUCC@"‘ŕ8Ž|P:ťîČ‘#Ż^˝:räH$ęر#ŔÇÇçůóçčä«WŻę÷‡‘µşnÝ:@––V__ź——§Ńh†…„„$%%egg?yň$99™(‹yúâĹ‹aƱlú.( µZͲ) ˙mxĎű.kęm,  )’€öZ‚Ă…ŘŰ8´Zí¶mŰÚµkWPPŔ0Ś>yîĉ*•JˇP8p€ĎçŹ;ÖŰŰűůóçëׯwwwżsçÎ#QbžžžëÖ­kÝşő˝{÷ÂÂÂPLÓ† <==)Š*,,´··4h 22rĹŠß˙˝‘‘QBB¦M›P#ńńń±±±ńńń^^^/^Ľ8xđ MÓ/^Ľ@aŔµµµ7nôňňŇétfffh ¶©ŔMÓM˙T«Őź.µĹBŁŃ„……±ýđ÷íŰ—í,ţ«ČTGędR©FŁe†¦hš¦Ph!"ZÆ˝Ełbp¤-âS@7Ó˙V:’Ňd+gg”cÎ0ĚŹ?ţř믿ľzőĘÍÍmôčѢŤŤŤjµšËĺúřřpą\ÇGŤ…6˘\]]Qf‡Ăqwwçrąrą<00pôčŃBˇŕĺĺUUUĹăńzô莖ţţţ*•ŠĂáLś8Q hddäăăăčččëëkhh(—ËE"ŃčŃŁ|||ř|ľ““S]]źĎ÷ńń:99y{{Ł0t¨5›¶mŰ"âGĐétEEîîž*•RN%‰—ËĄ( mSńx<±XÄçó1 Ó;Öq …BˇP­V·pw1kü-ggg9rÄĚĚě= /^ärąof¶ĽËŰŁ˙Ľ>şž×{Ô?¨ěLĆ‚Ĺߎ™4=-­˘Ľ¬¬´´ěŐ«ňň˛ŠŠňĘĘŠŞŞĘꪪšęęÚššÚÚšşş:’Ňą¸ą‘:J.•âĆÁalŠŠŰLĄ4*€’Ć:5=Dˇjľ‡jccSUUŐrú´Ů*AEEĹß}·5--­ukŹőë×ÚŮŮk4š«WŻîÜů‹JĄ7něرc „%%ÍŘ‘ IDAT%;wîĘČxqýú5˝]ŢÁ0Ś‘‘1Ž/I’trręÝ»÷»ÎąyófUUŐ°aĂĐşđC°bĹ .—kooU]]}üřń‚‚‚)S¦<{ö,''‡$IO‰2Ł(ŠJIIąyó¦BˇpttěÝ»·««+„°˘˘"..®¤¤D$wëÖŤ ˝{÷Ěž=ŰŢŢž$É%K–D˘V­ZM›6 pöěهÎť;×ŔŔŕرc/^Ľ066ž0a¦M›Äb±FŁ …Æ óőőĹ0lٲe@©Tâ8Ţ®]»Áë5"X°`ń—g­šęĘŇ’R€Ç1DZߢ<9ôŔuZ]ć‹g­śťµZíˇ 8pČÎrڎ)Đ`BaĚ»Ń-b±xÁ‚îîî×®]íßż˙äÉQ|>ż  pýú ;vl?sćôť;÷îŢ˝G„@ :5ŞM›6/_ľdó>‚066~˙°T(†††Φ€Ĺ‹+•ʨ¨(€ĄĄeÇŽ»wďîëë;aÂôßM›6ěßżą1óóóçÎť»fÍ˙~řA­Vďر#$$dŐŞU3gÎ|őęŐ©S§4ÍôéÓÁöíŰ A«Wݦ( ±)`čСVVVcĆŚAž’đđpÇ.\hee5zôhŹÍ›7O0áĘ•+(pÓ¦M("oůňĺ4MŁŚp,Xü›€&‰D"‘P$‹Ĺb±ŘŔ@l```ddhddllbhhÄár›Í@Ă ‚/$8\ša( Λű­†ˇÚë•’H$—.]D%e† öÓOۆńňňĚĚ|QQQ‘ššfoogccÍ0LcccrrI’ë×o`‡&„T*522ú#‡ üüüĚĚĚÚÚÚ¶mŰž;w.--M „††˘*˝ ŕÂŘظuëÖ÷ďß ’H$UUUH÷J˙ @ýýýăââeee%%%ăÇŹG{€ŘŘب¨(gggźĎ9rä™3g233Ű·oOQTPPJnÖ'†µmŰ6##ĂÎÎŽÇă%''űűű7Ő<¸ąąŃ4ÝlżßŔŔŔŮŮ9''‡o,XüÍ3ŽaĂ ‡‹ 'ŕű&Ç–»Ç´ßP-¶~őŐJ­VKQtccăŁG©[·~oiiŃŞU+š¦!„*•ŠďŐ“DJJ ý'ő,?Ü9ĂĺrçÎť;mÚ´sçÎ1 óŕÁ!C† :´¤¤¤M›6#FŚ5jÔ‡ł)Bßľ}oÝş(//ohhĐ‹r8ś{÷îÝşuëüůó h4•J…Ř´)ĘĘĘôúşˇPaŇ×ÔjµˇˇˇÇŽ{óĄ»víš››+—Ë‘ěľŢ›Ťăxiiéýű÷Ďž=ëéé©ßě§(ęŢ˝{ ………(*ž  Ä0 „Ä s^kŰ@¨#IśÍvř˙Ü!ܶm»ŤŤÍ1cI’ÄqÜŔŔ 4t@||\~~ÁÇ)¬Pj3$ŮŻ_żOÔ-E9::Be2I’óçĎŻŻŻĎĘĘB|¦ŐjQ©Ń?;;;“ÔÔÔââbww÷¦~{TË);;ŰÓÓQ,‡ĂysńdffVSSŁ˙ĘŐkDh4šQŁFiµÚ3gÎ4r …ŽŽŽŮŮŮwďŢuss‰DM_ša‚‚KK˦Nlš¦Qń™?ÔÎdÁ‚ŧµ»` ôŹ+ĂPHD_§ÓuíŇ%7'íÖ´4ÓĂđîÍ,T­V»aĂĆ#†‡„„těŘńîÝ䌌Ś/ľX|đ੢¤R˘ †aŚŚŚĐ%Á‰DŤŤŤ-Ö¸˙ÔŇyyy¨°šĄĄ%A;wî\°`AQQQBBB»ví¸\î_ŕraďŢ˝÷îÝëćć†,Q´ŮAQTź>}x<žťťÝľ}űVŻ^moooeeuöěŮ‘#Gâ8ţôéÓGŹMš4)<<|ďŢ˝S¦L±łłS©TW®\a¦uëÖ¨q@€ăř1c¶mŰÖ”/Ń 0`ŔîÝ»ëęęPA‚ \\\‚===÷îÝëčččÇń®]»˘­ÜóçĎŹ7ŽťÔX°ř;-TšÔĐ$Eju4©…B(Š|UVŕçëßCišŽ‹‹‹˙e=Lž<őüůřC‡~C„ĐŇŇ288¨k×î\.gÖ¬™ÁÁA$I:9976*†144 čxM*•¶Tł_±bĹš5k>şôŕýű÷Ź9Ňż˙­[·Ęĺň3f@{öěą~ýz##ŁńăÇ?}úô/”oCśggggkk«7O!„»víŞ¨¨ŽŽţĺ—_<<<:uęôůçźĎ1cčС‰‰‰Ë—/×h4®®®cĆŚáp8>>>†††GŽ)--‰D!!!hOw۶mµµµłfÍÚ˝{·H$ŠŠŠúí·ß^ľ|™śśQĐĘÇ˝[•JŐ´+bYŤFÄ›G˛‹MŹ´Đő„R©4,,ěźľµüQ>Á·6‚{><žč­Ť°lʂŠ! Bě_Oĺ$uB¨ŐęŽ92tč°—/ó?nľć¦'˛řĎ@§Ó‹Ĺb¶+ޱXĚFç˛`ńżdE`0„8ÁĹpâßä6ÇŤŤŤŤŤŤy<^SVĂqL$‰Ĺb‚ ¸\î•+—ÓŇGGGŰŮŮŇ4ŤačC±^KťĂá6u;ŁŠ’ú¦ŢÄIŹÖúý§Ź$=hhh(‹‘É!ärąH=-I‚‹Ĺ†††"‘¨… ;@)ęS)$§¦¦Îť;÷ńăÇď?­ĽĽ|Ë–-EEEzˇů±×dďií°“ ˙t$I0€8  Ŕ_waöřqz˙ţË–-]±âK$Ľ‡aXVVΊ+=JussݰaChh˙ěěGGÇŢ˝{iµZÇsrrW¬XńđaŠ“S«Ť7ôęŐK«Ő?~â»ď¶–—WDDŚZ·n-*zÚĐĐ0kVô… ĽĽÚ®_ż¶k×®MS#8âáè:ÍG‡ĂyúôŮĆŤ_§§§»»»}űí&///ĄRłk×n•J5vlDtt´µµurrňşu üýŰýőFggç÷Ďcń×бcÇââbTđ=HJJęÔ©“““Ó6;wî\š¦===çÎť[YYą˙ţśśśĎ?˙üńăÇŹ=Âqśa++«©S§˘8[µZťśś|óćMą\îččاO??? Ă^ľ|yöěŮ’’ˇPŘĄK—Ţ˝{‹D˘m۶=}útńâĹ­[·¦(jćĚ™ÇËËkŢĽy€ŁGŹ&&&ZXX|ůĺ—†††xř𡭭íŚ3–.]*‰Pu‘#G1{ölDƆůůůŤ=úS¬#Y°`ń'ě. Ă Ł_'S˛RĆ0¬¶¶®¦¦ćŐ«Wůůů55Ż+†Ň4íďßžaoľŮ(•ĘĐÉżx‘9iҤĎ?˙ĽĽüŐž=»?~Üب(++«®®ÎÍÍ#I2++{âÄIłgĎ.//=tčPjjŞP(¸téňéÓgvîüą˘â•‰‰éÎť»†!Iň‡~$˘˘˘lćĚ»wďÉČČhj§2 S\\Śă¸JĄ*++«­­ÍĎĎ/..ÖoBëëë KJJ>\Ľ^ üđĂzů2wŢĽyS§NeeegÎśKH¸’žž–““űŕÁCˇPĽzőšĹ‹ĺçç >,:zvÓTBÝ&IR.—×ÖÖęW-R©´ŞŞJ"‘ B†‰äOmŇ˙ý÷ĆĆĆsçÎX[[÷îÝ{ܸqţţţÓ¦Mł¶¶ţî»ďvíÚ5|řđ€JĄşzőŞL&[ż~ýöíŰ tňäIťN—‘‘±}űöŐ«Wëtş3gÎ444Ě›7ĎŮŮ9&&¦ŞŞŠ ]»v™™™Í›7=tcÇŽíСìYł ‘‘‘ŽŽŽ«V­˛¶¶ž?~×®]wíÚµ|ůň[·nˇd¶;v@wîÜąmŰ6sssVz‹żRâŕdh†aÉĐlN‰Ĺâąsçgdd¸ąą*•*­V»jŐJooo†a(ŠjhŞTj=Ońů‚µk×Nź>­¶¶666Ö××oĺĘ•.Ä_ż~ĂČČčŮłç»wďÚ°aĂÔ©“%É‘#G}|ĽW®üJ­Vçĺĺµoß.88XŁŃ¬Ył*00pţüy$I&&&ž>} ljĂRR>žáăăŁc#I200˘tW®\ť1cć1ĺĺĺ‰4$¤[tt´X,ÎĚĚÜĽů;†ˇq0`@d䄦ˇFď‚L&;z4Ivę`bbBQ”‡‡Grň­´´ÇüęééééŮZ&“Ü»w)%uîÜůäÉÓ-Ü•‡ăxVVVëÖ­?…÷Çńüüüúúú˛˛˛ŕŕŕŕŕବ¬;wî Ú|–––ůůůíŰ··˛˛ú@W„źźßµk×úöí[SSSZZŞOąˇił˝˝˝Z­TTTTTTDEEˇ-€6mÚ|ýő×€“'O"w@(2äřńăąąą;vÔh4 :tčĐĚ™31 kVgĆĎĎ/%%ĹÚÚšĎç_ĽxQ_ýWřfii©żŞé×ÜÜĽ¸¸ťÎX°řŰA@€a†Ář†áńx­Z9~ýőF[[Ű#Gެ^˝6.îě[őöpĎĘĘ655őőőQ*U/^š:uęČ‘#’“ď¬\ą‚$ɬ¬,ˇPčçç§Ń¨/\¸8eĘä!CŰŘŘ\»–““Ó¦M›#GŽäĺĺŁI­ŞŞşU«V*•ĘČČĂđ†††fV&źĎgš p[[ŰéÓ§ůřř”––6<""ÂŘŘxőę5Æ ‹Śś —ËKJJ>P#BŘŘŘXa۶íß|óµV«ĄiZ&k I˛ľ^Âá(©ĄÓ¨Őš~]ż~]ÓŞ«-sĹöé<Ţ4M›››GDDH$’ź~ú)((čäÉ“3f̰±±)))‘Éd­[·n×®ť——ײ)BŻ^˝věŘŃ·oßňňrŤFăćć¦W@YR‘‘‘ťN§ŐjßL±­««ł´´lJ҆ˇ‘@’d@@MÓű÷ďź2eJłˇ¸uëV©TjbbňäÉ“/żüňw7‘žž®T*5MPPŞ…n`ßľ}:ťÎÄÄä=UwX°`ńĂ`†¦iš4 >̢Ňé´=z„X[[kµÚŃŁG§¦¦ľÇˇ(jÖ¬™ŃŃŃź>äČ‘{öě…G˛prąś¦iťŽś>}Ztô¬yóćŤ?nçÎ]8Ž4°}{żČȉ^^ŢĎž=˙]1X%Ĺqě­ŐÓ)Švrrjßľ˝BˇpuuŐéHŠ˘0 {ř0eܸ±E …Â6mÚ|x]qÇIR·té˛!C†tďŢŤ˘(ÇĹbq۶m7múZ"‘<žŇ• ŲeË&LĐ©SÇ^·ś˘HooďOśEÓ4*†jbb‚Ü 2™ĚĆĆŕčč$|)Šúłę¦¦¦®®®7nÜ(**jެŐj{÷îV[[‹ŢŹÇăńxoVčłłł+))Ń˙©R©Pv2Z™étş—}űö5“ÄqÜÇÇçůóç×®]ëŘ±ŁžŞ)Šrqq9r¤@ Đjµúţ$bذa;v¬©©ae/Y°řűg<­chi†ôş(1 «®®Q«Ő†•””XYY˝ëBŠ˘Ú¶ő˛´´DѦ¦&Í\¬EzyµA6†a¦¦¦hŃŃŃ7oŢxň䱟źoĎž=]\śÓÓÓą\nEEE‘4ýöúĚM ŰcĆĆĆş¸¸ůÍ>Ü‹aD"‰Žž3eĘäüÍÍ- 23łÚ¶ő),,ĚÎÎ©Ż— °ŢĘĘĘiÓf,_ľĚÂÂÜĹĹÝÄÄ„dźĘµBYYYrąüţýűHÔ·m۶7nÜĐjµ.\8qâ6Mð¸¸¸ŞŞ*}A{ÄßÖÖÖQQQ‡R*•ööö§Nť’Ëĺ$IŢ˝{÷ÇÔjµcÇŽÝżnn®FŁ©««;{ö,‡ĂiÓ¦MS‡ÇŕÁQ]3ôîÝ;--íÖ­[}úôiz\,›Ś?>===//Oď+677ďĐˇŻŻďůóçŮđ7,ţ^`1 ŤL?áŕĂTř|Áoż>>ţńăô/ľX4sć ô0k4šěěěšššúúúěěl䤚;wîŞU«?NOJJÚąsרQáĄC:ăµZ3gÎśuëÖ§ĄĄˇ)ĭa®\ąúóĎ;23łŽ?ńÓOŰ—,YŚa‡Ă5jÔÚµëSRRbbPݡC’$MLL¬¬lÔj ˘p Ă0E7™ )†EÍ™3{Á‚EŹ=JHHŘż?ću D"Ń·ßnyńâĹ„ ‘>>~(v·U+ÇččY'NŠŽŽ:tpppŹÇ[´hqiiiXŘ žžžž˙ýšź†K–,ů őGŹ%&&:88üúëŻÉÉÉŁGʆFFFŻ[·®ˇˇ!<<<))éŮłg±±±6mĆŇҲC‡íÚµÓ‰‰‰ˇizíÚµZ­ÖÚÚzĐ A_ýuAAAXX››Ű?ü°zőęśśś¨¨(.—ëää4ţüÄÄÄ5kÖěÚµËŢŢ><<śÇăíŮłðU«V!÷Ć”)S233÷íۧ!.—ۦM›nÝşéé¶°°đčŃŁOź>MJJâńxcĆŚ9zôčť;w–,Ybff¶qăF Ă:věČăńvďŢý‡aĎ,X°ř„“mŁ0ś T«ÔýťVL n«Ţ#=h``0sf´‘‘!„°  °gĎ“'OBŐüüüůóXXC««k6nÜĐ®ťŹÇ‹‹;úôiI4|ř0Ŕńă'D"áŔµZ­P(ĽpáÂÉ“§ ÄBC„‡ŹÔétµµµÇŽ{ř0ĹÁÁaÚ´i..Îśhš>xđĐ­[·ÜÜ\§L™âââ‚Z5+zóćo!„‹-Ţ»wĎÇ“’’żřbˇR©‰D‹/ť3ç3sss‚ Nž¬ôŕ[ˇ(*!!ˇU«Vú"qď-Vz‹Oý°˙;ŇvV@q›©ÁahJŁÖčâú!„5­K—ŕéÓ§ët:’$őQ†5-©R©ĺĘĺrцŠă@aM Ăčc‚8ÚOB' ¦Pµ¤đ§wgAy<Žă4MkµZtśa±XŚvłP‚ ®!˘C‘H¤V«%óx\‚ŕ4köý„ĘŽłżäý€ŐŐuŽŽŽoőm˛@ë°ĘĘĘO“eÁ‚Ĺ3ˇţąŚŔ Ä0@ś1üŹk ę…mU*U3%[š¦Q!ĺfhV™UCkz‚N§kpKÓ4JNxó żyGż+ Tl‹˘(Ä…¦ѶŤVŁŃ˛CçS˘(WW×.ő~đů|–MY°řźÄp âŔpăÇ>D)©ˇˇá—_vEFF6cÓ˙ýÎúoyëAvtˇíůOű÷ďŹ3ćîÝ»ď9§¬¬lýúő(OČ‚ ‡ šf!PBę‡QK‹ę&ŹwĺĘ•_~ŮSRRbii±pá‚Ţ˝{×××ďرóęŐťNŰ­[·yóćşşşž8qâСßJK_ŮÚÚL™29<<ĽĄ-;ţ3 Ş©©yż(ÇÓ§O;věčďď˙áÍ.Y˛¤®®.((hÚ´iŐŐŐűöíËÎÎ^´hJe133Ă0L,Ź9ŇŰŰ ‘H’““źű,00˘¨Ď?˙Ľ±±±k×®Ó¦MÓßŔË—/oŢĽ‰˘¨ýüüd2YrrňĺË—###7mÚ”““ăăăłpáB•JµoßľGŹEDDÄÄÄˇŞ‚C‡íÔ©Sccă˘E‹(Š255E˘ŮĄĄĄß˙ýÁłłłżřâ oooTĎ\«Ő†‡‡4],Xüe4MahЦčůBHŃŽc-0ż BŘ,Ú™ ‡EGĎ }đŕÁ¤ISrsłĺrąT*MLLŕr9“&Myöěą——×Í›·W­ZŐ˝{Čůóq«WŻž0aBK&ÔOŞE’¤R©|ńâ…FŁi۶-ŹÇ«««ËËËăóůmÚ´Q©Tyyy8ŽKĄR˝ÂbóćÍkÖ¬Aĺľ---{ôččëëëëë›››»lŮ2@PPP°wďŢoľů¦ˇˇ!11ŃŘŘxŐŞU€ŇŇŇK—.őěŮóÁééé“'O633#IňÖ­[—/_ ›6mZeeĺ… ŚŚŚĽĽĽ~řá‡5kÖL›6MU”•••””ćŕŕ€XůŮłg~~~őőőŔËË ť¶lٲőë×Ďś9 BCCÍĚĚČÉÉ ńđ𨪪ڲeK§NťÄbńĆŤcbb/^ŚŢăµk× „K—.ýüóĎĎť;'‰śťťW®\yţüůA±!N,XüĹé!`†&u”VGSŻ72)’ôői———KÓ-.ąŤa@łeDccăÚµ«I’Ôjµćć>>ŢE988ěرýňĺ+żü˛;((¨S§™L¶{÷.ą\Áĺrľůćë®”DDbbbĎž=?Ų Çń˘˘"##ŁüüüňňňAĹÄÄřúú>yňdôčŃHúăĎfgvęÔ)..nÄĹĹĹÝ»wGÇőP($P]]]SSŽŽ;88 ’»xńâ’%KP 2A˝ző:zôhAA………Z­7nÜ™3gŚŤŤ ›I&%%!6řűűűűű3 ăěěěěě\QQˇż‡.]şÄĹĹŤ7NĄRÝż__ź\§ÓˇÖPŽ:¨V«‹‹‹cbb(ŠR«Őááá(훢¨ŁGŹFGGët:ÔQ,›˛hက A8A8ń:éőwă(¬ĂŢÂ1B§V@ś`(’Ö‘ E"·/†cĹů…¶¶ö\.·ĄéŃ2 ýâEV3›UĄRa¦Ó‘ß˙ý–-›5 Ă0 …Ň××wÄ<¨ŞŞ˛°°@±Qź}6+.îü˝{÷zôčńę†˙“ iş}űöź(.‰˘(''§ŔŔŔ 6 Jć%%%]»vµ±± …­[·Ćq©)}8şwďľyóć!C†”••ěěěĐqˇP¸zőjÇÍÍÍçĚ™n€$É7¨±±é"!`¦ŹÂŁişU«V#GŽÜ˝{÷ěŮł›]«T*ů|ţŰü%hXţë9 YąrĄR©¬®®–H$č¸H$Ú±cźĎ744ŚŽŽÖ_hff6tčPT'@oŻ3 ăîîŢŻ_ż˝{÷<ĄR,*µ:ůÖM†a !€@ÚÚä;!†ă$Ąłµ·×ĎđČ4% 8N0N@#¸ `ŔĆĆF@řŇ˙c4đćĂ0™L¶lŮňU«VŮŘX#[Bhll<~ü¸»wďúúú"Ź™ŻŻŻµµőđá#׬Yó!âű˙ĂK“?Ëg¦q%äđx<’$I’\¸pannîÍ›7ŤŚŚĆŚCÓô_ ˇPŘľ}ű .$Ů´ú·R©\şt©‘‘ŃO?ýTTTdii) …Ba]]]ł÷čęęšťťÝ¶m[ô§D"aFŻ™EÓt›6mzőęµ}űöf Eööö...oú}Ó:ďҥ˵k×4ŤŢ†F79uęT__ßźţą  Őđůüw}íÚµ«©©‰‰‰qwwg'S,(Š4441ć]RzB•R™|űVQQ~ó°#ŠÁ0‚ qăp1‚˙¦$!ĘőŃ˙ţ_•nAD^^Ţĉ“ÇŽK’:3ÜÜĽ’“ď\ąrU.—[ZZņÁ{öěÍËËűí·Ă;vlájp¨Xާ(ąJĘäää_ľ|ŮÓÓ“ËĺΞ=›$ÉvíÚŐÖÖäryCCĂź«Â0,88řĆŤ zŽŃjµHl„ iÓ¦ĹĹĹYXX¸»»ÇĹĹ”——_˝zuÇŽZ­vܸqçÎťKII)--ÍÍÍŤŹŹ766öňňBŤTWW#ÓĹĹőŚľ|ohhhFFĆÝ»wËĘĘ Ž;vôčQ€Z­–JĄJĄR&“ékŐőęŐëÎť;………zE'Š˘T**î6cĆŚÄÄÄěělµZ][[‹tł«««ĺrůW_Tç8 IDAT}•źźŻT*i𮩩!˘gĎžööö-YŐ‹‹fĂ0eĄ%Ą%E…ůůyą9Y™™Ďź=I’–účÁýŚçO‰7Şb0@Çy–p‚ $IŇÍθ[;{Ť–´°¶.Ż(ł¶¶yłĆ§¸{ą\~éŇĺôô'íŰ·+,,<>^­Ö89µB9RfřŹůN†yőŞŚËĹ]]=T*%„ĎçÇĆU*•©©©‰‰×»t îßżźP(tss=uęT^^޸qc;wîLQdŹ=’““¬¬,—,YÜÂ%„ئM›BBB>újVVÖóçĎ;vě““ŁP(†ĘăńZ·nť””¤T*‡ V^^ţěŮ3…Bannnjjú§çńx\.×ÇÇÇÜÜąté—Ë}ńâEÇŽ…BˇµµőÍ›7mmmýüü8ÎÝ»w333 FŽÉăńD"‘żżzzzzzzeeeűöí»uë!ŚŹŹ …†yyyi4ĄRyóćMDŠ\.·]»vyyyŚÝÝÝCCCEEE±±±@"‘¤¤¤x{{óů|TÄůBĐM¦¤¤ÔÖÖ–––zxx899]»vŤĎç'''›››?zô(33óÉ“']şt9uę”­­í“'O:uęD„««+„°U«Vědʢ…C&“T”•·i۶±QŽa†á„Cß0ĵĂ4*u}}ť‹«IRr©Ç0‡Çꍠ‘ď,á `´]˙@çĺŢŻ”ôŃÁăńV­ZŐبhÝşő¨Qá«V­‰DaaˇÝ»wG;OBˇpâÄÉ;wţüź1[ß*=Čçó›:âP57‡Ăápäâ{Çą\.†a¨ÎIK^ős8Äýű Ťüsßȧ“T«ŐWŻ^íС˝˝=;‘±`ńßđ°jtUeEaAAyŮ+D Í0 ôđhMŇ”L"}ů2§wżţ*•VŻ”4,¦ž Iă@†¦tZEj?4őcÎĽś'NÝ˝›ljjš““›••uăĆuR‹NĐh4sçÎţ'eˇFŁišş¸™”ŢíĆŽK€NGvčĐŃČČčź.–ôQ˘uŢÚ‡ĂéŮłgÓ&,Xü—€$IOO_żvM·¬šÎÉĘ„ř[ć4Aj”äbÄ|ě$˝fPÓriúp8Ž×ŐŐˇ<ąĽQ,ŐŐŐ7e)t2ŞĽöf›o}!ďZĎČČ­Óůŕ8β) ˙ťŕp8驏^ćĺ5ťÄ0褣ŢQčb8Cihg0bmúCµ”wîÜuî\śL&ŤŚŚ\˛d±FŁIMMýúëMĹĹĹK—.0`@@@'’¤<<<w* ă3¦oܸ)ńů˘˛˛RŤFăââöĹ Ź=FÓô¨Qáź}mnn®R©ľ˙ţ‡Ë—ݍTĘiӦ͛7÷­:Ŕ˙ć{©««W«U\.ׂ †a …D"ˇiĆČČĐĐĐPżP€Ęd˛ĆĆF6Ö ,ţ‰Đét:w éŮÔBch:3ăů[-TçrŠ`č>¦y* żůfS^ŢË'ŽŮŮŮýöŰa†aĘË+¶műyҤČČČČŁGŹîÚµŰĆĆćůó ‡SUUČÉÉ ťťť-—KĺrůďF'ŕrązťaGG‡ěěĺĺ ~qýúŤ3¦Ż]»®ľ^rńbĽ‘‘щ'>:‡ ‚}űbnßľMIęúôé5µ¬¬eĹ@Ĺbńś9łŰ´iJ]VTT,_ţĺÇ)eeĄ(ę’ ,Xü€ăxaA~mM †Á¦Ö•ą™9ő6•rC #¸8‡‹s¸8ÁAŃIË^ľqăĆĉ,--µZmdä’$duuµcÇŽU*•ŁF…+•Šúz‰FŁbF"‘H$™¬¦)­V­TŞŢşíd` ž1c†JĄvpp°µµ•Éd÷Ę•«sć|fhhHÓôرc?zEkŠ˘¬¬,żürylěáoľůzË–ď¸\.‡CôčrčĐÁýű÷©Tęââ Ă‚¨­­ýâ‹Eb±u>ł`Á‚Ĺ?—Są<.—ËkúőžYťˇiBŚ4Eę~D—/Ă0BˇP©T˘—GîP Ă‚ŁR)9®R©Âq·íŚŞś"M˘¦ë Ě‹EúňmM7Y?4ÍСC†!I˛ˇAŢ·o’$MMM'Lpôč±uëÖĎ›7·{÷nE)•Ę™3gÍžýYĎž=~ůe7„8+Žú)••%—Ë;uęÄv ,>(Оwppusojd24“—“°·%aŻŐQ­ÁÇ›ú5Í1c~úi{FF†BˇXşt—Ë533sttŘĽy‹JĄüńÇźĚĚL­­­ßEřĆĆĆC† ˝qăf3á˙:Ôh4“&Múę«ŐůůůR©ô«ŻV …‚OŃą€úzÉ®]»ľůćkDóZ­6<|äÁż¦§§?žadd9éŃŁÔ)S˘śś\kkk{÷ČańáééŔö ,>8NzZęáŽţM˙uęřQ‡űÖó_K2Ĺ9H~Ěú jµ:"b4`Ѣ%µµµK—.ˇ(ĘŇŇrůňeë×oěÜ9ŘßżýĘ•+ěěě(ŠŇk¤q8„ŤŤÍďz´™™9źĎŁiÚŃŃB!Ô‡ůĐ4mbbb` V©TS§NNź>SˇP¬\ą‚˘>~†aůů;vüĽyóćššGGGŤFS]]mkkŘéŔUUUŤŤ /ĆŁ0…BŃľ}‡ë×o LVvt~\°]Ę‚‹O ­VÔµ[źţˇMŇ4ýřQĘ»‚’hŠ"ŔšaóáőP?*•jÔ¨đČČńb*• ĺq:::9rÇ ä Ą(J.—ggg˘ŕ—+W.KĄRˇLÖđëŻ1ŤF"‘Ľxń\"‘ …Âôô4‰D!T(«V}… h@'Ož4sć ˇJĄÔh>ň*ŹÇ»téŇW_­ž81ňŇĄKÓ¦M×é4ůůS§FEDŚFĆ«łłM3úň2ű÷ÇH$’K—.„„„|ô=]UUUZ­V_… ,>şUW[[UYI‘$Ş„AQM’8ŽÓo‹4bŔqŚŔp‚ft@ŔćcÇÇ6ÓCP%—76ł6ôˇ°E544č•ýQÚ „P"‘†A\‹"öBŞŐꏛ*Ó¬Ż ÄfÍš©ŐjkkkwîܡR©~ţy[ZZ†ásćĚvsskŞÜ«Őj×­[SUUý˙"ÄX| PőäɆaXBeÁ‚ĹÇŇMĹ0D:MgpI‘ouĺB  Í@ c@iU ©€%€7—Úľ}ű4u3’$‰ă¸ŹŹŹźźň4ËŐ™7oÆaÔj Ű•••$I6­˛Â‚ ‡LT*/óÔj5^K}ýD ‚ Äđ·dÄPj- €g( ]ĘŇ黬˘7ľÉŁzčt$Űiźvvv¶¶¶ě6* ,>…u*•J®_Kx˙i ĂĽYfńuÚ Ă Śŕâç5ëBŁ×ókiú|­’üűšĄ©[@ϬMuŞšgń©?Ł Ôjucc#„đß/Ë0ŚR©T(BˇP,łĹ_MÓŤŤŤ*•ĘČČčÍ*÷µµµď稪 MÓ2Ôkjjř|ţűŐ:‘€ťR©‹ĹBˇđ/Üł@(6Á'‚Ŕ_Çqôŕ8NŤFťňđIţżh8—C ů 0 „h˘˛kccW[[Ťa-N‹•afźhżöńăÇ••U¦¦&AAA€˘¨˛˛˛'Ož’$ééééîîF‡CÄÇ_D.†177 Ŕ%ýł>ý'Ož´oßľŮńçĎź{yy=yň¤C‡ďşV§Ó•””HĄRý9 ĂTTT”••ˇ_+++ ĂbccE"QTTTMMMqq1EQ¶¶¶¶¶¶8ŽWUUafgggccć”fjjęęęÚt]¬T*cbb´Z­żżĎž=˙‡?—ŞŞŞňňrôąh4šüü|™Lfffćęꊖ°Ż^˝*++#ÂÉÉ Í૫Ť …ÂĘĘĘĹŵSTTTYY)śťťŃÔ,‘H µZ­ťťÚ•§iş   ¦¦ĆĐĐĐĹĹĺý·ĘĘĘp·˛˛B‹Ľ´´44„$Iff&‡Ă!IRoÓ âKĹĹĹ|>ßĘĘ 5‚^N«Ő >Ł(ęŢ˝{<ĎŘŘŘÄÄ$//Çq˝źŚËĺvčĐáîÝ»|>_«Őâ8.‰ß$†aŠŠŠLMMő1jµş   ˇˇA(şşşŠD˘ŇŇŇsçÎi4šáÇ»¸¸Ľ|ůR"‘đx<777ŤF“——×ŘŘhhhčěěŚ:¤ŞŞŞ¤¤„aGGG} Áf8{öěť;w<řÖ˙ĆÇÇŁGcţüů8´Zí®]» „«V­BźŁÁ›T][[«ÓézôčѱcÇż6ŘH’@¦%ÚąŁišA?h†Ćq†atZMÓhçôuW@pąŘk;Š˘hšţWP‚C’¤N§my_Í ŻŠĹâ 6;v˘¦¦ćňĺ+ß~»™ËĺľzU6{öśÜÜÜňňňüńéÓgAÂ3fJĄR$ü$—ËŮ ¤OÍÝöÝłgĎ›Ç>¬V«wíÚőžkOź>ýčŃŁ;včď-33óęŐ«‰¤¤¤dĎž=555€ÔÔÔyóćEEEť;w®®®®˘˘â·ß~+))IMM˝uëV}}˝T*MJJ*))ˇ(ęţýűwîÜihh¸qăĆăÇŹ›î>`V[[űĹ_|6ýŻöŞŞŞ:|řpLL šXďÝ»wďŢ˝†††ÄÄÄôôt†a^˝zuúôéşşşâââóçĎËd2µZťřěŮ3™Lźťť ČËË;wîśT*ÍĚĚLHHP©TrąüÂ… őőő§OźF ńěŮł+W®444¤¤¤$''7 «l†‚‚‚ääd> رcĂ0{÷îE¦¤¤ÜĽySŁŃ( Š˘~üńG,şoßľ3gÎ4mçÔ©SůůůMŹ QĆäµk×?~¬R© …FŁŮ˛e „°ŞŞęŕÁ:ť®®®îĹ‹±±±yyyÍnO&“=zôňĺËÉÉÉúeßéÓ§ŃŠ$55ußľ}č4SSÓ%K–¸ąąĹĹĹeff644<ţüçź\ştééÓ§ …"'''%%EŁŃÔÖÖž9s¦˛˛˛şşúôéÓŐŐŐoíśéÓ§‹D˘wŤ´´´´Ůłgż‡M›HŹ7oŢ<˝kęöíŰ………o]Ô2 łhѢżĆ¦ČůďŚU‚˘HŔ0 E2Ą^Âp¬¤¤¨}űŽBˇ°ĄéçŃ4]^^ŮôR©ś6-ĘČČČÂÂB&“uůöŰM––ß}·Ąm۶R©lÉ’%HyaŹ·xń" #hšT*•*•šÝíű¤ľß„„„XXX >ÜÚÚZ«Ő&'''''{{{8°ˇˇáěŮł555Æ óńńQ(‡®®®îÜąsż~ý®_żŢ­[·śś™L¶nÝşĄK—B7oŢ|8 )))99ŮĐĐ022ŇŘŘxéŇĄ666Ýşu‹‹‹k۶mXXŕćÍ›÷ďßçńx}údffzxx  ÝÝÝő$öíŰ7===$$U©©©·oß633355mj Ś92##Ł˘˘IHH°µµE·DQTMMMyyůîÝ»išöđđ iZ(öéÓ9BĘĘĘžxđ --­®®®WŻ^—JĄß|ó I’ |>˙âŋݺuËÍÍ•JĄ«WŻÖjµ‡®¨¨ E¬|ëÖ­ÇŹ×ŐŐLMMgLŹúëKR†ÔP *č×QľĚk®n[€ Ă4 u¦(ĘŮŮýž‘ńběŘ1$Iňů|OOĎĄK—oÚôMHHwäŘárą“ţŹ˝ëŽ‹ęXŰď©[aé(U$V¬],ŃhD°+ŠĹ^0ÖŘ[l‰Š»˘Ř{Kě(j° ô.JgŮľ§} Y –/ą7š{oöůů‡{ť3;sÎĽó¶ç ~ăĆĎíŰ·_şt±ŤŤŤŮŤúYŃĄK—.]şŔüůó—,YRZZzďŢ˝đđđłgĎ>|ř0==˝~ýúË–-ŰĽyó‘#GÚ·oďîî~çÎť_~ůĄK—.ééé,ˆ‡‡Oź>ťă8$SgÍšUĺązőjÇŃq^"‘Lź>}íÚµőęŐ»víš……E­ZµŞľt:]rrryyyRR’ťť]PPCDDÄ„ ľ˙ţ{•JőęŐ+–e7oެP(ľůć[[[ggçGŹŮŰŰńđáĂüü|˝^o0mĐĹĹE©Tš,(4M÷Ýw›6męßż?4oŢ\­VŹ3fţüů†íßżß××wđŕÁŹ=:wîÜW_}˘Óé.]ş4wî\{{ű°°0°µµ;vě•+WŕţýűZ­vęÔ©ůůůGŹ3f̢E‹fĚѡC‡™3gž9s&666 ŕĘ•+ĺĺĺ“'ONMMÝ´iSXXŘŤ7şuëçççW…ÝĹ˝^?hĐ Îť;Ż_ż>))ÉTŁIww÷ĘŤ5ÍĆŤ‡ R«V-ôi4ŁŃčŕŕ®®®ĄĄĄÇeddŚ9͉łłóýű÷ …D"Q(HüěÚµ ˛łł˝ĽĽ±´´,))),,¬[·.cőęŐŰ·oĎó………5jÔ@3*•ꏟĄĄĄ\.ĎÍÍuqq!b÷îÝ8ŽoٲŴF'OžĽté:—oܸ‰´1cĆ$&&ţüóĎÆ 3ýü*‘Ź•?J$’­[·ŠD"dńFpĺ$I¶lŮňÖ­[jµş˛@%IŇŢŢž¦iÓóś‘‘ˇP(ćÎť«×ë}||(‘H† –ТE‹Ă‡«ŐęĄK—–——{zz2„ ą\ţčŃŁ¦M›fff&$$4mÚ4''§S§NhíęÔ©~  —.]ŇétÓ¦M{ţü9ş˘R©._ľ¨P(®^˝*“ÉFŚ‘śś<{öld±GË—xäČ‘ÁŁfĎž=qâÄ*sŢşuëÔÔÔÚµkűůůUľnee5iҤӧOŁ ˝_'Nś>}:†a‡ň÷÷ŻYłć˝{÷nŢĽicc“‘‘1~üř·oߦĄĄ­]»–˘¨©S§b˙jýf €g9ĂpT^ŕxě Ę­’’’ňňrWW×÷ĂĄţep—źź˙9ę¦a–’’zęÔ©µk×ܢŁGŹîرăŇĄË<=kµmŰ–çyggçnÝşmŢüSdddDÄśC‡˘'ĂŚĎ´´´óçĎż~ýšçy”—ŚśI§Nťj×®ť§§§\.GćA¤ĆÇÇ'%%ńxđ ˛ÄĆĆĆľ|ů=uëÖ­üŕÝąsçÚµkjµZŻ×ŁÓţ˙I5S@hTžŽă*żÚOź>5˝űoŢĽqqqqppppp‰D8Ž˙›Ĺ›ś$HŔ0ŕŔ0 ű7Í»A ăžÁ`@›éwŇ4Ťž{ŁŃH’Äýű±Ű¶mĎĘĘ>xpżťť]•čő I’˘( –eŤFĆ4•4MQąee§´źźyyYIIÉűĂC|ý˙ÂďÂqüÖ­[qqqëÖ­;yňdďŢ˝JJJîÝ»ŕî•)1 3 ß}7§yóf$IÖŻ_˙âĹKf{ďgĹąsçš4i2iŇ$“&D’dÓ¦Me2ŮéÓ§}}}kÔ¨śžžľdÉ’Ő«WŰŘŘ shYYňŤ˝˙"aƲljj*Ňf>ÁŔ0 Žă ĂĽ/ůvâĺĺ…ÔVdĹ­üF mI¸ęŐ«‹Ĺb–e…öĚ™3Ť5‹Ĺb±833łFŤÉÉÉÖÖÖ•ďEÓ´é#˘ň#•J§M›¦P(4ŤJĄzýúµÁ`@2Ţt$Âh4Ň4ťźźŹµ‚ ôéÓ§}űöh[Ä0L$™n⑆WTTäîî®R©2224hжmŰŁGŹ6mÚS*ů>M0Ť;vlҤɅ rrr*k¨ŽŽŽ ¨|ć5j”éă”)S¦M›–““CQTvv¶››[bb˘ťťI’uëÖŤ‹‹k۶­^ŻOKKsssłµµÍĚĚ,**˛łł{ňä Ň8====zÔ¬YłŇŇҢ˘"ooo±Xś••ĺĺĺ%“ÉâââęÔ©ăxőęŐ|||ĐA ©ąź€ŹŹĎĺË—•Jĺű1AEU1u\ż~ÝÎÎ.** Çq›ÇŹ#u Çq“éňńăÇľľľ•`6u‚ s‰IâŢĽyÓÁÁáA°$IšćŮŮŮŮËË ­cÝşuďßżŹĆ‰888T«V íáŢŢŢ.\@fväéLKK‹ŤŤU(žžžĎž=CˇXńńńULâ2™ YP+oµjŐš9s&ę ťŐĐNŃŃŃóćÍsppxüřń“'OĐlčt:dĹ5íđ•'!))ÉÝÝ˝rX2"¦Ç»ň«mee5gΉD˘T*9Ž{ňä *©‚ű>v¤űłZ")đś<&ŕNŽĂżQľŤ$‰'OâWŻ^-“ÉÇŽݢE dž"˘¸¸xĎž¨ôôôš5k8ŔË«nLĚ ˙ýűÇ D–´gOTjjjŤîruu!âŢ˝űgÎśQ*Ë»víŇ»w/†a0 Óëő{öDĹĹĹy{{4ĐÁÁˇŠäV(ôűR5iŇä~Xű~Řѧ!“ÉÖŻßđĂëÚ´ńź8qbTÔ^†1¨ŐšÝ»÷ś:u Ă0›Żľňáyž¦éăÇŹďßż_ˇPđq@Öétׯ_OMM­^˝:ęüرc(dĎž=R©´˙ţ>>>GŽAŤ6lX­Z5äFÚ»woHHżż˙ńăÇ‘l®^˝z­ZµÎž={íÚ5ą\.‰äry§NťĐÉěěŮłR©TŁŃtčĐÁĘĘ****$$„ă¸]»vĺĺĺÝľ}ŰÝÝýţýű‰Ädy qâ„••Žă—.]:räČîÝ»_ż~}÷î]gg礦¦"“I’çĎźŹŽŽŢ±cGaaáľ}űP$ŽL&ëÔ©SńŹ‚’Š‹‹U*•JĄęÖ­[Ź=nܸ‡ÂŁ‚‚‚ĘĘĘP¬VóćÍ;věřóĎ?#Ó·Á`Öëő7nܸwďžL&#Â×××ĆƦK—.ÇŽCG%AúőëWů¦íŰ·żzőjBB‚›››V«=xđŕŕÁ›5k¶uëV‚ D"QĎž=oܸQPP°cÇŽđđđ-Z?~ÜĆĆĆh4>}úôŐ«WM›6˝uëVbbbť:uôzýž={BBB˘˘˘rrrîÜąăďďďććvďŢ=Á0~üx“@Őh4ĚÎÎŽŹŹ§iúĹ‹………'N´˛˛€^˝zíŮłG$ń<ďç燎t[·nőôô4IV­ZU–&˙‚DĹdµ‡Ž ‚ŔpB÷ÖžsGř•«tő5Ś{ň°aĂ& Gá hiq7Ťč4aR©|ý:oŐŞUm۶ ŹvKJJű÷ĐŻ_pýú_%%%étú ĐżgĎžC† .***-- îÔ·Aú©©iĄĄĄóçĎ;sćě®]»»uëâáQsÇŽťöĐétűöíżsçî¸qcNť:maa>ÁĘĘĘ$A ;wî’ťťYVV&‰L^˝^ďččę©étĄRů1Ý‘çůŘ؇r9ĐQŰ‘™™‰R¦A (ş^=o–eKJJ ňŃlee…,!Ť&77—aX++…łłó?Vć ‚ PXů9:W©T,ËZ[[ł,[\\l0¬¬¬59•JĄT*µ¶¶ćyľ¸¸a™L†Č§Âó<Çq–––Ó¦Mwww92ÇńŇŇŇáĂGś?îőë×(¦ŁqăĆ)))Ë—/9rd‹-L:;¨ąąŮééé[·FFEE±,7zôčąsçÔ¨QE·×¨Q#)镉@ř˙¨fŤđ?M ţ˝Đjµaaa$Iúůů…††ţw >22ňńăÇ,ËFFFV¶ţ;Q cĆŚqrr:t(Š>ý_ĹÁ»wď^9ä§Ęľ˙«ń,füŤXµjJXÚľ}» EE˙š@•PXďÝEzÇ 70°|ޤvűöí}űö:;»Ś?îűď/[¶ô [$I^»vÝŢŢľAFAôîÝkҤIË–-MIIéŮłÇŕÁŤFăµk×mll5j‚ăXŹ=¦M›jeeE’¤Á`ŕ8Ž ŤFóěŮ3 ĂŚFăë×y 64ŤµjŐŇë ČyůŢM©K—.ÇÇÇßżĎŃŃqőę5ĺĺĄ8N §ŃhJJJĚ’ň_ZÇ ‚4yT*2q˙C&A*•FEE˝o˘üŻ8ĺŚ7îŻí“ Cű?ŹÁâŻfiú_zîź={ö_ŐŻgp–1//đ‚ üÁnZ­fćĚ™"˝v횣GŹ™,fďK_µZíŕŕđěYüĄKŠ‹‹·lŮ€3 ŁÓéËËËA@ˇŢżţúřęŐ+jµzýú $IôěŮóŮłgë×oŘ·o˙şuëQP’ Ër( 9üyž{CŢÍÍUˇPěÝ»÷đáĂC‡±±±)/W@yy9"~űsł. R© •  ĐtE%v‚d˛w×+»h]‘čĂÇŠ$A*Äâwőß B‹×ŽřhHÉGŹA$ůî&g;Žż»…iÉ0ěw6MÎď{ŔqÜ`0<ţkRRĎs¦ČÉ Â333˙BƲ˙®†y´fa~J,&çx`p ±Š(ß?”„”AŔqB>ŞťđĽŕäT}ĚŃ,ËÚŰŰwéŇ%::şŠđ«^˝Úرcxž·±±éŮłGdävŽăÚ´ń·¶¶şsç.Çqľľľ /A IÂÚÚ*//ĎŢŢľ¨¨˘(©TŠŘˇK őÉ0Śżżż‹‹Ë˝{÷’’’Îś9»nÝČŁů/Äq 2™xÓŹÄÓ§ÁŔŰÚq-›űô'’“ūׂŔIňnnĆŢ˝ąşuÇš¦Oť˘®]ÇÔ¶Ťż~ěhL«ű]Ź4MŢşEź>)•ÜW_ú ®®†))ôńDJ2oooěó-ëçGdeI,çťťŤ=zp ęIb CďŰG<}&ŘÚj—,ĆŢ ]ÄbňŢ=ŃÉSXQW§Ž1¨/çé‰ –ť#މ!…•±w/¶m`ŕ8ęüyęę5Śĺ˙ÖLŻo™L iňa}âžźĎլɩ]ťS’Ž;^­š#Ďóőę5 Q+”––Îťű]@@§*µůĚ0Ă 3ţ)â™$p pcAŔ0Ç˙¨ÇK*•nܸ1;;‡ăřyóćőéó- Ž˘(J&ł iZ"‘(ÖA0 3dČ%K–b†ňí5jT9–Řhd† ˛té2áÍ›7‡ńőmBä‘#G‹‹‹ÇŹçç×*2rŰÜąß±,+—Ëë×o°~ý ŁGŁ)ŠrwwGŢő¦M››„%I’<ŚŤŤ5jÔčŃŁP¶ŚX,.**ŞÄô‡ Ń'O‘OźŔ8V:iŠdŃbA&ĂSÓčłgŤ˝z© ä}ńÂB ŃŃhYřdÁÎN°±˘÷í‘¤ŠŤŚüĺ¦,doee "ůE6cVP@dgËÂ&/Śc‚ <”|đ+)ˇŁŁ™.] ú“±±}‰”Á¢KW<1I´{}č O €H$XZAIR÷cĺC† i<|öL6‘ČÉÁň d3f’wîű r™,d8yóđ<}ä¨ô»ą\ÆL»¶âý´ ňÉůˇŔ°†ˇC¨”lčЧ)‰dqqń·oß~đŕ2x’$ůâĹ‹3fîßŕKP´˙Áµű‡1|™a†3'ERŚŔ?¬˙r×°aĂÖ®]‡$©ďż_¤×ë)Šşpá†a‘‘ۦNť†aŘ‹ ÇMś8Ă0ŹZ]»v÷ńń ÓëuÇ#˝Öh4NFÓt­Zu:uę\«V­)S¦¨Őęš5k®ZµÚĆĆ.,lÂňĺËZ·öC1ńS§NINN±łs‰‰7nś‡G đâĹ Ă8ŽÁŮŮ96öˇ˝˝cçΓ'OvttdYvĆŚéŢŢőęÖőţXdÁGŹ:­nNÓˇnéLĄ˘cbĂ.ĄŮ™Lď^H1 Ŕ’oÚFŁ~ÖLíš5Ş+—±˛ßE? %Yş W*őÓ¦2ť:űRçĎ“·ďPgÎ’÷î† cÚřë¦OÇßľ•¬XÁúú–Ľ5q^^E€aFŁ:~L·d1I™ÔhQä6E˝Żř§‚L&^ą űV?cÓ¦Ť~Ř0ňî]ęĚ9ňömęÂc` Ó©Łnút\©”,] +Yµš·ł7ŚeĐźkĐ@Ľy ^X(^·ĎÍŐO›ÂúůĎźiaÄ…‡”JíÚµkÎś9}ôčÉÄĤ«W/ b) Ă^ż~˝`Á˘Ť7˝ź.ö—›i`ĎŔ01şuą¶l•–š M›‚­-,YÓ¦†ÁÜąPŁ4j99ćWŢ 3Ěř| yŕ1śřŠę©đk:ťľOźo·m‹äyža”ŮĆ0L÷îݵZµ©ş™Z­F±*K–,^µj%b‡1Ťeeeě3ĺó<żhŃÂĺË— Cýú_ť?8čőzÇ+‚łłÓ‰ÇQĽ¸^ŻgYT*•FŁR©TŽŽ™™é………NNŐ7oţqűöHAP>˲ӦMť3'Bř?”„•”(Äböć đ®®Ŕó€ă‚……xÍZéÜy|µjšŰy{Ŕ0üU" ™ó}ô(ëßF»j%ďQLéM8N$& 8.X[c`cxQţć ÖV€a‚ť-‰I@’‚……čČŮ‘‚ťťć§M\ť:Ŕq‚­mU L‰D°±’Dćhŕ­­1ŽlmĎËÁJ8!ŘÚ8NĽz… <ž“Ă»ş r9°¬ —cĺĺ`0©© ŘŘp{7íUV^ţë×111%%EđôéÓĆŤĎš5ő—_®˘( }ĹŠ•eeĘ ÂÄbŃçzfFŚ€ś¸Ž’đóáĂA,†QŁ`ölčŇ""ŕ§ź`Ý:HKµ22`Ď:~ůĹüΛa†źËčËs,A@ŕËýaC(f0P …*i°,Ë~iµŻ¤c`(uőc ”ý «‘ Uľ‹:D”›(Ä 9wőz}^$ŞáĎú˘1 Óé‘HI‘N™Ć5l ]ĽÓëń·oń´týěŮĆ,úô•\ţ0–óđš@ĐÍźÇtč 2Tô•ŹvĹr¬#¨ •bz= °XŽ (1ŕ Źčô •bJ%uăgĂŕÁL—.˛a!ňĐ‘ĺżÜŕęUѬňµZèPýř0\]' .ľRo"ş" é÷·@gxŕy„ŠQa8ę8Ž ¨n-ÚHí3¦O™YVVA}˘T–ţú믠×kMń˝8Žł,»aÆ˘˘Â3¦+ÖźKCĄŔĘ ¬¬@«Ee–ŕéS@y÷Í›ĂÇ*†Ah(ĽG j†fńX–cYç–ů#Qľ:ť.,l|ť:uŞPqţďNŽ‹wě”,úž č¬:u’>w^‹‰§ĎdăĂđŚtËŠÂÔjŕ8ŚăNť0­NÉ€$@ŔńĘÚ$ƲƠ LŻ'=ňQś`mÍúřp-šE‘M“±÷Ŕ„§ĄËB†‰‰ń·, V ÁĘ ŤŤ\É€¦©«×¤s"đ¬,`Ycß@ bc¦©Ř@Ó\‹ć¬ŹŹ`eM>~Śî‹éőĆ~Á@’Ćž=ńě<=/*"ŮfÍ+…±×7@ŢŹ±˘ŹB@›÷ZaeC’$MÓ …µÁ /--6ŤUN'‚Ť–eŮĎe÷E“)‘€)‰ÇU‰ru…ÇŹA 9«EÁ˝{7oÂoE1Í0Ă 3>ĂÎÄ“8Eb‰cNŽ˙‘(_ÁĐłgäŞüGL“ĄĄlh}ö,±Ä۶ă99šő€$ńśEł‚T b‘făŢŢF»l ¦×[¶jŤi4Ć>}ŚC‡b•e†Ńφ+K冀 ¶¶ÚU+8ß&ś hW,EíoŮ®7V?1ŚHKĂ4ËÖmK  (íŇĄ|mOA&SÔ«ŹiÔ€gdŘ8;3]Ô{˘ČÇOÄ[·±ť;ónnú‰đâ"ůŘńŔq‚ĄĄvů2¦CŔ0íŞĺâČmtô10„ ÓOźˇ[´Pş`eűŽŔyzęż_$X[FŹ"ňßʦN–dRíÜď 4%5--­@§ÓĽĎŞśŮăĆŤś/pLEW*˙ś*ż."?†Ž!5~«hk†fń9Ŕ±FRŕ9¤ <'ü]Â0Śż»¸¸Ř˛ ţĎĂĚ"ö‰Ş$U™hăŘzőĽ"""ľý¶˘Łú+¬\ +WšWÍ 3ĚřŔ#…ßĘę <_™đa_ßć˙ŔIáyţĆŤźČßëo„X,Fą::ťŽă8TĚO$a FTl˛réfžçËËË+ě‚ ‹#ąŃhD>HÇ% *Q˘ÓéP ±XLĘ BE7Ĺb1MS‚ čtú÷ËĎaFQ”D"Öéô¦j—•űA=‹D"”$Š2‘†ˇ(J,Łč\SnҧĄ©……‚çy•Jiň űűű/]ş¸qăF_Hš"ôçhüe†ôţ·áŹR~~biŞMÓ©©©Ă‡ŹhÚ´yHHHJJ MÓ*•zÓ¦źZµňď޽ǽ{÷«ĐĐŁÂćgĎžíÜąëĄK—©2EQOź>8pPÓ¦ÍFŹťžžÎ˛ěŢ˝{;u đőmÖ·o0*äű믿öíÔ´ióiÓ¦çĺĺ}‚—Q’¤,-­ŚF đVVÖh›ć8nëÖÍ>>>Z­îK=¶DG‹ xy»;xx@›6pófĹ_KKaŢ<¸x±âĆ0 „şu!1@ٍWÂĂáĚpuGGxřž<??pw‡[· - ľýĽĽ }{8|`äHđńš5ˇFŤŠÁÁ”ŽŽŕć;w~Lš^I¸Ňy]gĎąžť×uľöęşXP^0l×0ź>Í—5ßpmJŻÂÓ5Ë/,oĽ¸±÷ď±űÇ&˝MBŤŻżşŢń‡ŽµçÖţză×çžž3°x«|;zßhďŢŤ7šzľJŻÂ0lÍĺ5Ő¦W;÷윆aućÖi˛¤‰ďR_ł45ĂŚ/¦Ťá <Ď f6u~“&Mvqq>uęD›6mBCGJ$’ôôŚůó®Zµj˙ţ}7oŢĽ{÷APżţćĚ©7®őďßßŢŢľ˛äŁiúňĺˇZ±bŮŽŰÎś9sR­VďرĂĆĆćÜą3ÖÖÖ;věd¦Oźľť:u:{öt÷îÝ'Nś$—[^¸páňĺË{öěžpŕŕčŃŁęÖ­ëęę:ţüť;w–––¦¤¤Nś8ÁÚÚ:<|bJJJbbRjjrPPßüüüââŇfÍš şÁ]¸pÖŮŮ©cÇŽ"Íq,UD 3 Óąsç“'Oy{{3 ‹îµtéŇGÇj:ť><|â™3§1 ł¶¶...ÎĎĎW*•µk×a¦¨(żM˙¬¬l–ĺęŐ«÷1“/E!ijĐhÔ¨Žzyy)Ë2VV68Nü=«BQPVůůđö-”–‚·7€^ŃŃ0{6PÜľý®1ĂŔŔĐŻpÜ»bA÷nÝ‚9sŕâE¨U @­†ęŐA­†Zµŕî]4©˘e~>äĺA^°,”” S|ÄÝ^X^¸űÎî}#÷5óhf%µjYłĺţ‘ű·üĽEĎč•:Ą«Ť«Ú¨¶•ŰîľűČ#?ÝřÉŐĆ5ĽC¸­ÜÖNn7łëL~ŻÔ)×_]ż+d—§˝§L$űşţ×…ë ýkűŹÝ7veß•Z r°tp·uźÝmvŰÚm7]ß„¤xźĆ}ćś“W–÷oÚÍ0ĂŚ? m.8I@baž”™1­V‹aŽăš;÷;†a‘Óť;wVŻ^Ű«×7žžµxž×h48ŽÇĹĹQĺë뫪Ď„ăŘŰ·ůŽŽŐpçyŢÍÍ5/ď ˲ŤÖÁÁA«Ő:88h4Z†a´Z­FŁ™={MÓóçĎ5ŤČMQÔŮłçmllH’ܵk7*€ě® cŕyî71§ĄĄ_˝zőŔ ĂŘÚÚŽ9˘U+żgĎžŻ\ą’˘(˝^?}útŠ˘T*őŰ·ogÍš]łfÍŮłgšüŻU~>ËňŃŃG›7÷%Rˇ°ŔŠ‹ UŞňŰ·ďőë×_Łů;‘¤RŘą>–…˘"?  î߇k×`ëV8wÚ´©h¬×òe0z4Lž 3gľ¨"\ąQQpŕTŻŽ, °kĚ›ŕî;B»v L3f€T ‚––púô§Gg` ąĄąµěk™®xW÷Î(ĘPéU'ĂN.>·Ŕ 7·fÍ4W–g!¶ĐżKQăx.µ ŐĂ®jpňÓܧÍj43}‘"W×Ë —@gÔÍě:óF⍙Çfî Ýc~sÍ0ă‹ TŁÇ0Ă0ŔĚ'ÚOժ۶m»Ba9tč0†a‚Ëĺ˝zőşrĺRrrrll,I’ ‰¶lŮV…÷€çKK •ŞőVZZ¦PXâ8.Ńjµš$IµZMÓ4Aŕ–––gĎžž2eŇĚ™łd2)†aA\¸p1;;{ŕŔ–– Ă,Z´đc†V-Ôżż÷8°ŻM›Ö›7o˝}űV~~~tôŃ Îoßľíűďż7Ś …ÂÝÝýĘ•Kţţ­×­[˙Á´cAĘĘJ.^Ľ8{ö¬ŚŚĄR™ź˙&++mÔ¨QŹĹ•——ý=K˘RÁwßÁµkđË/pő*„‡ěŘOžŔرׯCRŇ»ö DFBn.,\řŽb‰ă fMčŃ.„”t|€ŽáÜ9Xľ6„ČH¸| ĽÎź‡7ŕçź? MßË-# ŇZj]¦}79EŞ"{ {„FnŤN„ťŘ8`c‡ş®ľĽşéú&gkgŁă_Çp;ą]ĺ\¬]2‹2+ŻN©¦ÔŃŇ}Tę” żYH“ô¬ăłĚ|>6ĂŚ/©z‚ŔóŚ3xž5OĘGT4vÉ’eMš4 ç#ó' IDATmÓĆ_&“Ą¦¦öčŃł°°PĄR)•ĺČýŚăxjjZfff×®]ŞÄâŤĆ^˝zíŮł§¤¤Ä`0¬Zµ:88XˇP899í߀¦é}űö;;;yxx´oßńîÝ{ťťa8&BLLLAAÁŚÓĂĂ'çääÂďs{(Š˘(MÓR©D*•ó<ߣÇ×Ďźżŕ8Ţ`0dddÚÚÚ`ţöm~aa!†aIIÉ,ËŇ4Ő´ióWŻyžóćÍ'’…¬¬¬Ö®]S»¶÷ŞUkÓÓ“ŢĽÉ™…áĂaçNčŢ˝‚tp¬¬@,†-[ .®ruđő…  o_čŰbbĽĽ 1<< gĎ ˘%Ô˛ň/íŘ@.ݍť‡a0`dľ“svr»ľľ}CŁBß*ß@^YްÝĂBZ…8X8xÍ÷ş›v×ÉĘ©GĂÎVÎ/߼ nś—°çN…Nu7*dw•Ô*Ô?tÄž*˝ ¤?Ť M/J_Ľ6üpří”ŰŔňlÔ˝¨ Ď/Śi;h’–‹ä°mč¶—y/˙xmc3Ě0ăßÝ–HZ„Nŕ…nJú,--¦NťľmŰö  ~66¶/^$`fggß A??˙Ž;µnÝĘĎŻ˲4MďÚµ;((č}1Ł×ëШQŁ.]şůú6sqq=z”Bˇ92ôüů NN./^9r¤••Ő1Ł#""jÖôtč°X,µµu°łs´´´zűö-đ©TşbĹĘ.]ş$''Ž?nÄ‘‰$77÷ŔCçĎź{ôčáË—/cccĺrË1cĆőěŮăŐ«„§OmҤɴiÓe2ęD,?~ü—_~9sćÔýűwž={µW©Tnßľ˝ukżĚĚt?żVŰ·ďÔh4“'O ĎĚL ?sć,DHäíŰ·ŹŤ...F˘,Ç“’’Îť;íÚŐű÷ďÝľ}çůó‰dçÎťŻ^˝zř0öřńčëׯźŢK—ŕČ8wJK!- Ö¬Ľ<ČÍ…ŇRP«!#YA 1x¶n…ţýJKaĺJhÖ ŚFčÓÖ­űC3Ă 3ţ˛“3‰SĎó<Ëđ,fęÁˇ¬¬,&ćŠßiÝşµ\.ăyľnÝşÜöěŮńă1uęÔ©]»¶Ń¨ ĚĚĚ<|ř0Ď %%%ß|óŤ)‰¦éăÇcĆŽS­Z5 ĂćĎź>©]»¶99ą‹/ćy~Ô¨Qˇˇ#SRRź=‹W*•űöíĎĘĘ2dÁ` "..nßľÓ§OKLLB1ŔwîÜiÝş5ÇqÍš5űůçŹ?ązőZăĆŤÝÜ\)ŠÜż˙ŔîÝ»¤R©łłsHȰ#GŽ=­×ku:͡C‡zöě!“Ép?räčŮł§ ‚lܸq«V­nŢĽŐľ}ű÷#­¤R©H$Ńëuz˝Qj4jĚŇRˇŐŞ˙†÷ďC׮г'ŕ8DPż>ś;őęÁîÝ ÓÁž=př0ŕ8ôí żţ QQĐŁ¬X @Ë–p˙>: Ŕµk:ŔşuСܺǎUĐó^żţ׎÷řq8||¶l–-áŘ1‹E‹€$aáB8yňýđ?T$Ä–”ŔÓ§đóĎ&@` dełłůŤ4ĂŚ˙<ý'HścŚ<ËËő<ÇĂ?dŽĂT*•Ńhřé§ÍË—/C9'JĄ˛ĽĽ<%%‰ŽăĽĽĽŇÓÓł˛˛333łłł===Mě¸8Ž•––)VŔóĽ˝˝}qq Ërz˝Aˇ°dYÖĘJ ¨)•JÁ“““™™U­Z5‚ ž<ů5,lÂÓ§O·oßžź˙vÖ¬˝^_XXÁĺ˲¬JU®T*“““‘˙+..±··Gľ^…BQV¦äy–e™çĎźł,ëăă˛wŠ‹KíěěݎD"ţ`ě.†a…“&…gd$$EÓtnnvzzRhhčßcÖ€ąsÁË Nť‚‡Áß~ůČË!&.]‚ 8:w†M›ŔŰÜÝßüęőĐą3Ě™łgĂĐ®ěŘ‹—×_.M ¬ ,,*ţ_˝:”•ÁǰbäĺIBj*|óMĹ_Ż]jŐ*D/Ë‚FSAYAŔ0đ‘l,3Ě0ă?BTË&`†á„ąÚĚÇ@˲ .ęÝűŰNť:–””$)“É7nܸqă ÂăăźÖ«÷ŐŇĄKwíÚééé)ÂÇq+W®ěÖ­+Rřx^°łł-..B$ yyoH’HÄĹĹ%EE%(ŰŐŇŇR«ŐĚš5311qüř ô«QĂ}۶HA*•ÝĽy+(¨/A}PĽJBmٲE‹ÍCBF$'§xzz:::Ľyó¦víÚÇ—ŘŮŮň|ôĘ•« ýß“?ŁŐ‚ÓoÄ5k‚X\Á«Ŕ0`0€€D~~píDж-ż·QׯŮŮpü8üř#Ś.@ëÖźc°vvPVVg”ť]1đŕ`đ÷‡Ŕ@¨Qă]Ë•+aĘ”Š˙SXX€V R) Uđ2™a†˙q€çXăăĚ1…Žăĺĺĺ'N2d°żż_µjNŻ^˝Ş_żaVVvjjjII‰T*ŕ]\\Oś8©ŃhĘĘĘÎź?ďěěb’OaŔ€۶mĎĘĘ*..^ĽxqHHµµµ‡‡ÇÖ­‘aëÖ­5ëÖ­ăéYçÜą FŁńćÍ[ŽŽŽÇ+І 4lذyób±¸I“&A P^‚ bcc[´hőúu^bb˘Z­‹E!44tţü%%%iii{÷î bY67÷uFFF ,,,Aŕy~Č!sćĚU«Ő<ŤŤíرĂ})Š;vĚđá#ćÎ]”šúŞ  oČ{öDuëÖőoËFE…bL’ÇąŞW‡K—ŕŮ3P©Ŕކ…7 2ĆŤ{× »[7¸t lmÁŐú÷‡ŃŁ+8˙j ‡ĂăÇ RÁ10y2h40{6= ¶¶°fMEł¬,((€€€ŠŹ¶¶Đ´),Z<ëף#xx_G3Ěř©ŚşśÄ xĂÇ 3˙çűËĺ3gÎ~řđappžçíííxžwuu LQtXŘx?żVJĄróćMK–,íСAť;w^ąrą‰NČ`0ôęőMqqńđáˇ!$dŘ A†=zÔ’%Ë7ömŐŞĺüůóÄbń–-›W®\9oŢüćÍ›mÚ´A­® tP(,CB†•––¶mŰîŐ«„)S¦íÜąŤaX//ŻŔŔ>˝{+‘H¦L™Ü AťN7t袢ÂnÝľ–JĄaaăżţş;˲ńńńµjŐDbžă¸QŁB üýŰ:9Uź6mZË–-t:ý'aQŁFŤĚŽQ99ą{÷îkŢĽ™ńď2Aîß7ËBË–Đ 89ËBőęŕîYY°`Ś Z-,_-[V¨­Z-řůää@Ë–`i S§ÂúőP·.´j2Ś §NAÆźcĽíŰCQŚ……0z4Ś­[ ŔŮłđô)ŘŘŔČ‘pâ„„ĽSC 5 &O;;hÝÖŻ‡jŐĚŻŁfü§‚ă1Eq <ĂA×5ć kf¦|źzP.—S•Ô ŇŇRÇĹb±HD čőzŁŃlą‰„˘HA–e´Z]•9‰Db±ĺˇ"Ş#‚ Ąĺ­"B`‰D‚ă8˲Z­Ö¤ă˘a (ÜŇŇRą\Žd-†aďŹ$‰é˘^ŻGą4Eęő†Ęv]©TjĘCý´€DÔëÖ­«S§N@@çŹ˙š®0ŕOghţ©ŚNž‡/’*öG’JżÔXĚ0ĂŚŹîZ˙2ő „&z-‰%1’žÇ€ŔĂÍVßiňV…·IYťNW…5•DýDWďÓ"żĘ=Ś ĂÔżé[ Tľh*Eţ~ĎZ­öÓ˘±ňJJŠÇŤ‹jÁţŤëńçţú‰ö_J‚ý»¸YššaĆ·< çY†çXÁśjĆ«đOxVĚ/fńgŔ ¸Ŕó†/<‚9őŁR„$IŠ˘H’4…á ‚3EU.Ö† $I~°Ľčű_yżçOß áŹ Ť„˘(ÓHLWLĂŁŢĂ'Ş˘"ęD‰D&—[ľ?†˙¬\ $ šcôĚ0ĂŚ?'&päŢxŽgYÁLěđ!D˘Ű·ďôíÜ AŁŻżîq÷î]‚ T*ŐęŐkZ´hŐ¸q“·oßR•››;~|XÓ¦Í;tč¸aĂF”j’y†ýđĂş-Z5iŇtîÜyÇcöěŮłŔŔľ>>őű>{ö\$]¸pˇWŻŢőë7üć›^W®\‰D2™lÆŤ66vŢŢ>^^ő\\Ü*–1 {ňäÉ·ßöńń©üňĺKT &"bNăĆľ-[úmܸ‰$É‚‚‚Ĺ‹—´léWż~ĂÎť»DGGQ»v]»ző|ĽĽęy{ű(Ö[·F"n¦÷!K¤RąZ­ŇëuŠ˙M™şh°,<}ú—k¨żf˙:xç`§NöSí»nčz#ń¨ôŞuWÖyĎ÷¶›b×ryËźnü¤ctĽŔźŠ?ŐfuŰ)¶5çÔ·Ü‹×/ŕYîłá{†;ĎtvćĐ}C÷cŹŹ@©¶tõ > }¬&Yů,ôŮpmC™® ě¦Úa#±‡ŕ—¤_°Á6Ű}g·ůu6ĂŚĎžçqś˘€çY3źĘ?Š˘®_ż>jÔČWŻ-Z8qâ$±X\VV–ťť}ăƵ¸¸‡yyoâăăĺrËđđI;v|ü8îęŐ+ÖÖÖ?ý´Y"‘ü&ŤÄű÷ďĎÎÎľxń|lě=˝^żeË–˛˛˛¨¨˝ýű÷KOOé×/xďŢ˝%%%§Nťţţűď322&M _˝z­X,AŻ×ŻYł:'''77·¬¬Ěť„ăxnnîţý†š––Ň»wďÝ»÷¨Őęü‘㸸¸gĎžNKK;~üř˝{÷SSÓ.^<ź‘‘±fÍęeËVh4šśś,[[ŰěěśÜÜÜśśśččŁ...,&#‘HĄR™FŁ2 ŤZ§ÓĘĺ–"‘řď±ý¦ĄÁţýđř1\ĽII’11•Uńײ28Nź†ÂB¸˘ŁáôiČχ“'áČ8zNꆗ/!3ŇŇ - Nź†ýűăŕŘ10ŕňetNů Çű ăÁw'ż ň Ę[›W¸ľpQŻEóOĎżśpůqÖăżžx4ďQц˘căŽ]N¸¬3ęÄŘ~k{Ěřâ ĹO<±·´ż™|3ńmâ’óKú7ë˙zÍë‚uă;Śßu{l¸¶á×ě_oÍĽU¶©ěćĚ›2lşľIgÔ­/&ž”ô6©}Ýö{'îťŢgz¨¨9Śß 3>’"žG>1Ś0OĘűP©T«V­dYÖh4:;;{yŐĺ8ÎÝÝ}ĎžÝWŻ^ÝąswăĆŤ|}}Óë –––†ˇ˛3·oßY° BŤŁiúâĹËS§NF &Mš4bÄ>}ľ}ű6?88H«Őź}@,{{ص V®WW¨V ”˙ÇŢuÇGQôýßlą’KîŇ ˝’)´„„PC‘"R-ĺyÁÓÓł¨¨Vssó||ĽY–µµµ˝{÷.˲EEwíělĄR ˲ ĂFGGO™2e÷î=R©D§ÓÍť;'.îPĎž=ß|óŤäädłŮ@ŇĘdryII ˲………*•’aďÜÜ\ĚZ\\ěăă•’’lk«8qBTTÔŇĄK<`Í\Ő±cÇNť"===¬É‡Ůyaěîî6oŢĽ—^šP\\źűęŐŤ¦şWŻţűöí'5c,–{éq1''@HĎyx$@8†S§ŕ«Ż`ÄčĐv쀰0čжm{© áŻrî uÍ-Ď5 mJĚKŚöŹoGď!†Ľ7ü˝“łOn>˝ąZWÝÉŻSÂÍ„FglXVW¦5=°}‘2R?g?ba%H-H r ’2ż¤(ś3ÁÓŃsîľą yW„>źŇ4…!D!Xŕ0D…PS0 sçÎťńă'Ž˙˛T*Q©ěělsrrÚ·»|ůňéÓgęę4ÎÎN¶¶ĘŽ#ľür[YYŮŮłg÷ěŮ3cĆ­‘ $;ŇŽ__şt9##ă>6mšcHHČúőrssׯ_Úşuë6mÚíŘńuAAÁŢ˝{Ű·oÇqĽŤŤÍĆŤ›&Mšś››űí·»‚‚‚†©©©!á°^^ž­ZµÚ´éă›7s׬Yngg÷ꫯľ÷Ţű™™™.\Ř»wď1cťť[Üą“äČOwďŢݰac@@ MÓ%%%<Ď—••QŹŚ‚aŔ€ţ+V¬ZştĺµkéwîÜz啉‰I>>>Oě©ÔÖBuő= ş¸řŢÁş:ptµľüââŔboo;Îś/ľ€I“T* }ű`ŔŤ…ăÇÁßZ´€{EÜ4š?˝łsĚMş•ôáńÓ Ó®_űôě§›NmÚ4nS|VĽúőą›çŠk‹Oß8ídëÄ ü§/}:kטּ«q·+oĎ:>zËč/ľxłď›×KŻo<ąńzéőkĹ×ćě›óü'Ď»Ş\_éńĘëßľ~"ëÄͲ›Ç®{ýŰ×ßčő†ŤC™¦ XcĐ8(^Ź}ÝĎŮŹÇĽř.‹ń×rŞ}Řkd]6™Ěý:ů,%fJj”)IˇP¬\ą*55Íh4ň<çěěüĺ—źk4ő'Nśüî»ď†7nL÷îÝ%INNΖ-[‹Šîµž2e˛··wĂÜC666qqGvďŢc6›‡6zô(“ÉTYYąuëçiiiaaaS¦LvqqąvíÚÖ­ź—””¶oßvúôé …!TSSłgĎŢ„„ónnîoĽń†ŹŹ÷ňĺď/Z´ă8š¦ËĘʶnýüęŐ«;vś2e˛D"ٵk÷ĺrŮرc čŻÓéÎź?żoßw555~~ţŻ˝öާ§ç°aĎ988(6źľµa~‰faggwŕŔÁ;ľŇju~řˇZ­~DfĄż0SÄĹÁŠŔó°u+ěÜ ńńpé GŽŔŤ°|9čőđć›Đ­Ŕüůp÷.ěŘqďçůů°kĽý6Ŕ† ĐŻÄĆ‚J‚ţé]ć~㩍ǯ·đ–čVŃóΗKä&Îź˙uŇ×őŢNŢsúÍ uEŐ-;´ěFů {Źń1ăű…ôg"g`(¦OHźY}ďU*ż|çňúë‹jŠĽ˝göťć˝>쥔+y'vŮs7Î׏é4F\ňDxÄŞő»3%É$Ô3‘}řë€1ĆŘd4÷Źň]đ‘P›I=H Z•‚őőőEI$–e°Ůl!ÔBĽ‡B‚Ŕ›Lć¦ęSň’‰¤L˘(J*•Ň4Íó<1ÍZOb=BšI$†aA ĹăärąUüĄ(J&“RÝđ'R©”eYڱŮl& ’X–•H$!ëIěěě@x­V÷«>ŢcĄRyřpś››[۶ĽGQ IDATm]őŻ%ÔG^ř˙‘zđaÍ~ăOţ¶ë`«ó1O4=.B„?—Pź[ťÎż?„˘(1ő`óRY‘MEřKß<€D¦Ý‹›‡DÄŁŃTě!B„§ťKA`@ŔÄQ!˘ŹďĂYDŁŃÍf–eU*UĂÄÇ‘L 2™ ´Z­N§@¶¶ …B!ćGţÇAŁŃ(•ĘFëëëmmm5ŤJĄz؉Áb±XŰ};Q-Čd2˘o?pŕŔůóçmll–-[FľĹKĄR˘ç7 fł!DŽÜW?č9ŽcYÖĆƦˇÄi0ľýöŰäääŘŘŘ‘#GţűžĆÜ;0 CŞ05; FŁŃd2‘ĘK$ç )ßÄóĽD"±&˙2 &“ÉZâ ,‹Á` Ź€ĽÂ¤Ú„Ůl&WlX´)H'éý’{uuu*•ŠL!‹Ĺ˘Őj)Šj¸¨T*ň”‰­§aŻ0Ć*•ЏbŚkkkIÂQ†aŐ˘@©T*RóЍôIŕ;Ă4ca±X,FŁ‘eYrwd5#…­hš¶±±!N»wďľvíÚ´iÓ:vě¨Óé, EQ666Ä̤×ëyž'ăFÄd2Y'¶ôŻ,|ŻÓé Ĺ˙÷…}20±€…łž×Ó¦Ëĺ[·~~ôč1žç(Š2äŮ^x¤8ŔÇÇÇżöÚ׬ůhôčQeeeďľ»¤´´ !đóó[¸p5TÄ?sćĚٲeKŁK—.]şté›oľąm۶‡ý0)))''çěٳ۷o'GîŢ˝{öěŮęęj˝^ŻP(^|ńE{{űăÇŹüńÇPYYyâĉĘĘJ˝^/•JGŹm6›Ož<©Ńh†qqqéׯźR©ĚČČ8uę” 4M4(00ĐĘ©‹Ą  `óćÍ˙Ögqůňĺ´´4Bx666íŰ·ŹŠŠJOO?sć Áh4šÝ»wkµZ„··÷!ChšNHHHMMA"‘Ś9ŇŐŐµ˘˘bĎž=&“‰˘¨6mÚôîÝ[„ź~ú)//ŹřIŚ;ÖŢŢ>??˙ŔÇQŐĄK—GřŔź={V«Ő8pöoĽ±m۶ąsç~öŮgĹĹĹk×®ĄiÚÓÓ“ô611ń›oľafÆ îîî/˝ô9ÉĄK—vîÜéää4ţ| ‹eÝşuEEEŁFŤňőő]ż~˝˝˝˝łł3©yńâĹÝ»woܸ±   M›6<ĎKĄRŹ®]»¶ ţę÷ˇ×ëŹ=š’’ü /Ş>{öě­[·4 ÇqÇ/..¶··'Ó>)));;»®®Îl6{yyŤ7.)))99™ Qddd»ví,Ëľ}ű*++1ĆŽŽŽŁGʶ¦„űÓqćĚ™gžyć fÎśůĹ_ü9R&B p,x,‚ÉyA´˛4»M–ÉdożýVDDDNÎŤÁźť0aŃ|ĆĹůůçźX–‘ÉdëÖ­÷őő]·n­Ůl^»vÝ–-[.\đ$+ť=HMMÍÉÉQ*•]»vU*•<ĎggggddřúúFDD †¤¤¤şşşOOOłŮ|úôéÚÚÚ   öíۧ¦¦fdd„††šL¦ŃŁGo۶M"‘8p K—.ÎÎÎĽi÷˙šÍćoľůĆÓÓÓÉÉ)//ŻS§NľľľäŰA]ąrĹ*¬$%%…††včĐÎť;'—Ë÷ďߏ1Ţ˝{÷¨QŁÎť;çéé9f̲¤ÚŘŘěÜąłOź>íŰ·€¬¬¬<899ů™gžQ«ŐWŻ^=ţĽ««+Ys9ŽŰąsgmmmRR’››Ű™3g‚+++ëęęFŚ!‘HNź>]^^îëëŰąsgČËË»rĺŠZ­.//ݍ¨Ŕ+Šçž{®ľľ~ďŢ˝m۶íÔ©ąnff¦ŤŤMďŢ˝ĺrůöíŰťťť‚‚.^ĽčăăÓ±cG"čdfffggK$’Nť:ť8qBˇPřřřŘŰŰź={¶K—.­[·ţŐwŞYł}Łă'OžěÖ­[×®] 11ńÔ©S­[·NMM}öŮgłzyy>>#FŚĐh4V>g&//ŹaĘĘĘššŚqŹ=ŇŇ҆n•´$Éś9sÖ¬YÓżčŃŁ‡Z­ ł ĽőÖ[ďż˙ţ›oľI&ۉ'âăăź}öYâihOwwwą\^[[kÝöUVVŽ?ž$JKMM­ŻŻ?věX]]]^^žŃh,((xţůç•JĄ^ŻOHHĐétńńńłfÍR*•:ť...ÎĹĹ%99Y©TŽ7Ž˘¨Ă‡9rd ňľżÉ(** ËĚĚŚŽŽ®©©ÉÍÍíÚµkË–-ŕÎť;W®\ˇişsçÎnnn;wî”JĄÎÎÎ!!!GŽQ«Ő111ÖS}˙ý÷VxçÎť>>>®®®éééAAAm۶eYöđáĂ$«kŹ=Ľ˝˝ëęęÎť;g4;věčďď_YYzýúu‰D2xđŕ;vřůů9;;gdd„„„„††’śä ………-[¶ ďđű™Bŕ)ŕ-fŢb …DełZť1cF·oßžă8“ÉŰ“çyŚńąsç~úé§wŢY.•ʢϜ93jÔH„D"yć™A ?˙k«˛üm V«ccc»víúĺ—_@uuőáÇ۵k—žž~ůňĺź~ú Ö¬YqqqÎÎÎŃŃŃ©©©ˇˇˇ%%%ąąąíÚµ‹‹‹ăy>::š¦é¨¨([ŰŇ Ě1C.—/^Ľčúé'„››Y> &&ĆŐŐµˇ–řĆŤYYYďż˙ţgź}¦V«ĄR)!­Îť; †ôôôŇŇŇ+VlÚ´ÉŮŮY©TĘd˛˛˛2ň󲲲۷oëőzŁŃ¨V« ]»vUUUVß4š¦###ĺryHH»»»Á`ČĚĚ 9sćŚĹb9tčBˇčÖ­›Ůl>ţ|IIIBB‚——ÇqqqqÁÁÁÝşu;věŘŘŘxyy%%%@FFFQQQTT”——×áÇ1Ć‘‘‘‡®¬¬l×®]NNNrr2ˇ˙ĚĚĚ6mÚČd˛˙ýď-Z´ČÉÉi۶meeĄÁ`h8đîxűí·B_~ůĺ˘E‹¬Ç/^üé§ź6bŮ©S§fee‘™™™ŻľújyyąĹb €öíŰWTTp—™™Ů­[7˘L ľuëVEE…JĄ"=éŇĄKnn.\ż~ť4svvnٲeIIÉť;wZµjE¨{÷î×®]ăyľ¨¨(""|}})ŠŞ&áÎAË–-I<7Ńë.Y˛„˘¨ X÷aGŽY˛dÉ»ďľűÖ[oa7..nÄmÚ´!ĽHn™8Ţ7Zv¬şb–ewěŘAÎ3ţüŢ˝{E±µJĄ2dHqq±•8  EçÎťU*•UO–žžNQÔĆŤW­ZuîÜąŘŘX™LěâââďďíÚ5‹Ĺ˛}űö+VÄĹĹőíŰ—ČÖDŢ%¤›ťťI’¸uîÜ9++«áE;tč™™YTTäééą}űv˝^okk{ŕŔň­»»{÷îÝűöí{ŕŔŁŃyéŇ%[[ŰÂÂÂşşşŕŕŕ†§Š‰‰9räŕŕุ8“É|áÂ…ĽĽ<@EGG;99 †S§NůúúvěŘ1++«   S§NW®\©¬¬lßľý÷ßĎ0ŚZ­Ž‹‹ă8.(((!!!˙~đvíÚĹĆĆvěŘńŹř D1 B<šfE‹fÔfAô?Mý¦M›V­Zi±Xňóó'Nśl0Ź=†1޲eKr˛?Ď ‰„Ěr–e›­.âODEEĹľ}űrrr¬ŻD"‘H$—.]zć™gĽĽĽNž @.—GEE@qqqyy9\ĽxqŕŔAAA˝ző2™LwďŢ­ŻŻodf~÷Ýw›Q¬L0ˇ‘‡AS™őüůóŁFŤ€ăÇŹź={¶m۶M„ă8«ůD  ¤*ĺ}ÜOŇÉ[•·Ä+‚őĂ0¤Y#ÍŻşA„„„Üľ};88ŘÖÖ–Ěoooň•ŮlîŢ˝;Qć“ÉYTTDÓ´ŻŻŻBˇŘ±cÇŻ­ä:tčĐ=z}:żJĄrĘ”)·nÝÚłgO×®]{÷î–°zőę%K–ČĺňuëÖY ĎúpÉzÔpY˙Ő•ÎşH=L{IöÔm۶€ČČČÓ§O7 |˘(Ęßßź¬mÚ´ąxńb]]ť‹‹ËřńăÉŮýýýY–•JĄŐŐŐŽŽŽĺĺĺvvv O]·áŤ`Ś7lŘ`mś””Ô°Ă ŰYÇęÚóňË/޵X,č>¬\E~K‚¤ÉÂj4mll˘ŁŁżţúëĐĐĐčččFă0kÖ¬†ý4ŤŁFŤŠŤŤÝ´iÓÍ›7­ë˛ ŢŢŢłgĎnřŰ´´´iÓ¦ŮŰ۵ç'ź|#‘H˛´¬¬Śxzyyĺĺĺ[,–˛˛˛–-[*•ĘŇŇRň \\\ltűöm???˝^ŻŐjÝÜÜ0ĆUUUfłY"‘äĺĺyxxPĺääTRRâććF–ě_%ĽöíŰ'$$hµÚFZ 2Pä +@|||QQŃ›oľ‰R*•)))Dhnř4‰—MهKJ“óŤ,»©©©öööżÚ[{{űž={’!ŤŤŤ%šëµČţ’čfűöí»páB2nďĽó±ú˙ôÓO …ÂÝÝ˝   E‹ˇ;wîxxx4};¬· ÷ă ŕĘ•+őőő«WŻffţüůÖyĺěě\[[[[[K:ö0§ő–C¸MaŚ}||Ţ~űíF»"ňČ{a}" Oňů矏=:44*ĘK· U° áŢaÔCm¨Ť!•JOś8ąpá;“&Müůç„1cĆ™ÍFâÍKÓôÍ›7łłŻÓ4Ý­[×3f¬ZµŞ˘˘Ňb±ś={öí·ßn<*âOAyyąÉdňňňrww/--˝|ů2 ±ÍĘĘruu]»víŔ[´h!—Ëżůć"שk×®»wďöőő˝~ýz@@@»ví***®]»`őTT©Tű÷ﯬ¬ś2eĘ#ŢmŤFsńâĹęęjŠ˘Č‚’™™ÉóĽŮlNKKŁi:((Č××÷đáĂÄžçáááŕŕťťM´oß>""b˙ţý>>>ĄĄĄ‰ÄĎĎďóĎ?wppP«Ő:ť.''ç…^JĄ>>>‡ NOOo×®ťCJJJxx¸ ÄV\\¬T*‹ŠŠ´ZmDD1ćőęŐk÷îÝjµ:77WĄREEEĺćć;vL©TZŹŐjőÁ===ł˛˛I/,,ěÂ… <Ď×ŐŐĺççOź>ýĘ•+áÎť;®®®yyyz˝Ţ`0tëÖíĘ•+uuuEEEeeeŻľújHHH||ĽJĄjş [w0ŤÜ˙ţ÷żżjCŤŠŠ:zôhPPB(;;;**ĘŮŮŮĂĂăđáĂ­[·&ůĹměŕÁ555z˝ţöíŰÇ·±±ÉÉÉ9v쇇ÇĹ‹űôé 8xđ`TTTyyąN§ ć8n˙ţý§NťR©T.\´hŃâÖ­[-Z´hč¬ÓérssµZ-qý%ű´´´éÓ§óĎ?˙|ňäÉÖ­[Ó4]UU•ťť­Ńhhš^µjŐ®]»RSS5MII I÷ÍóĽ­­-Ďó,Ë®\ąr×®]))):ť.33łľľľ˘˘âöíŰ}úôqttl$ÚfffŢľ}»¬¬,555  oßľIII^^^păĆ Rcăúőë%%%uuu]»v˝páBmm-ÉűÖłgOÁ°bĹŠž={:88ܸqĂĎĎĎĹĹĄoßľ?üđ^ݧ(*55uřđá /z÷î]ŤF“ššÚŻ_?‹Ĺ’‘‘áééYSSSVVćäätóćÍK—.IĄR­V›––F ¦Nťš––¶nÝşI“&‘ľ\ż~Ýd2Ą¤¤„……Ą¦¦ÖŐŐ•––ÚŘŘ=­\.wss;qâDbbâ’%KÔjőţýűťťťłłł{őę%—˵ZmrrrŹ=HDFzzzMMMyyąT*---˝~ýzxx¸··wnn.qR˙^ *Đ,KK]"_Ď ^ÝĂĽMf‹c˲żĚkëoŚq~~D´jĄ6ô$ ţŐ«^^ž:ť®ĽĽ|Čg;tč@v@ Ă\»–%‘H¤R©ZB6Ë‚ Ś=ŞC‡öOłÖW&“=:Eđ!Ôúúú–-[úúúšL¦ŞŞ*ŹÚÚÚ¶mŰzyy·jŐ*44400Đh4j4šţýű+•J˝^_SSqűömwATC„)ÝÜÜL&SŻ^˝VhťHf)))±±±Ä·‚*Q‹ˇ' ŔĹĹE§ÓUTTŘŰŰ÷čŃĂÖÖ655µm۶555jµš\¨¬¬LˇPÄÄÄ888„„„X,–ęęj[[Űľ}űÚŮŮŃ4íîîÎó|eee`` ńj!+#Ć8###888˛Z,Biţţţ‹Ą˛˛Ň××·[·n …ÂÉÉ©ĽĽ<(((--­WŻ^,ËTVVň}=Ś‚« ‚U*@UUŃ×®Q•UXaÇ„Ţި¶–=yŠ€ÇJßşµŕ↡rnĐ7o"“Ipuić* CŇYYH§śťřĐPě䣺:úZUV†ĺ2>8XđńžŚé7¨Ü<Áׇ –šFwď2ײV+8:ˇm,öŞĽYçĎźS(l_ßVâÔ!B„{M3€1˘(Ś11ďló[[;ů‚…ôŤ›ćqc©kYtaaî\óř—ÁdÂR)“ś¬<…ľqłţč.:(Jńętŕ8É÷?đ!!u×2QÍáEçܰyu:vs||čäd.˛“qÁŰŔqňĹďRwňůđ0:;Őku[?CµµŠ˙L0˝ř"¶W±'N`…­îó­B@+:%UńętÁŐ•Đymy9Ş®™ K%H§Ś©ŰwŻĽ‚U*A­¦“SřVţ†÷ßš‘­ţINć;†Sy·PEąţ“Í|«VěŮs˛%K…`ĘčôtăÔ)ćQ#©’›W¦LƇË®$›쯾żäřáĂ·nÔ××#„ôz}›6íź@bĹßQŽM„"ţúµ‰0F‚€ <Śú°­‡FcXň®iÂxŞ´L"űhŤiÚd±PŐŐ’ý?Ňwň‰Ü ŔóćŃŁx/oÉ÷?`…˘ih/fYŮňĺLjjíîlܲĄô“Om-ćztGŇŻżŃn˙Ę2|•wK.[ůţ㍚Ó'ůŽÁh˘Żç°'N úz,“É˙÷?:+K{đGÁĹ…şqi5X.“ěű^ňĂĆ… ą°˛>`’.Ô]M|Ľ%ß˙ 8‰‹‰ÁNN˛O?ŐŻ\aš6—؇„Ę–żŻŰú™lé2ÄYtÖM+ĆOŻ\ĹőŠ•®[Ďž;Wwů’ 4¦Ą]ą”xćűďSS2¶lŮb0čGŽ%“Éęë5]şôxtĹşżŕa řî;xă ?®^…ädXşžy( **ŕő×áÎxĺ0ŢľřćÎ…˝{ÁŮ>˙žÚ^„"~˙˛ X,”Ŕ™8ł EŃ⎾ů‘Ş­©?sÚôâ €“¨ą0MłGʎęóŔż´KĎžřÁŐ€¦Ů¤$,‘ŢŢ@Q‚·7X,Ta!}ó&ŢŢ ‚ż°’°ť-%ٽǡĄ ť–®Ýő-ß&˘/_Ů˙>´÷ô–Ż^ŤĘĘ•PĹĹĚĄ+ Őð.€ŕëóľ>@߼IÇ žž€ŕëŤ%61IOÇööŘŮŰŮa—–Ta!čôěĺ+ä śŮt¬¤ŕ\}ý™çöď˙^ˇ°qvvľp!iéŇUůůůGŹzľ9Ď?ăĆÁ0o¬] łgɂӧCL lß đí·°p!@r2ěÚíŰĂÔ©âd!BÄ_DŘbaĐŠfx,:|?LŽÇX*Š‹Eľě=¬T_ ,ęĆ öŕAË AĚ•+€*+á˙ŢGĘú"§} ĺ˝Ý ¶~…G›^ÇEu˛ť4YńĆŚúĂąČHŇŔ4á?–ŘXŰ1c±˝J·i“鿯gĎBđ<¶z5ěnpĂ‹’>Đg|˙+†f÷4zđeKÖ8"ťNGb«ëëë·„z˙ˇ@˙ţPZ ‚ĂéÓ°o@t4$&¸qŔq0v,¸şÂ;ď@¤á"Dń犨&ť–˘š–ĘÍÂéĂG !Ł‘ľša3UTXř ŕé‰éőTy…ä»ďŘźŽ€|Ń»TE`ąËä…–mHlç-=z Ł‘şu0¦oÝÂR)ďçËť—4MÝ’ ý˙ IDATĽ \ĎtF¦ŞcUU%¨Ő|«V¨˘´:x>< xµZđöT«†ĄňňŘźŽ˘šZŕy®{7 rs¦é›ąŔóľ>X"ˇnߌéĽ4ô—<Źĺ2ÎZn·áţFwwÁÝý#-[BË–Ö+b''ÎÉ©áŮËĺ|pPŁëB‚§§ŕé čľ!•śÁÁ‘sp´6F<Źęë5Oţ‰¸ą›Ű˝ĎááżgY¸_„`öl8zŽ…Ľş7t"›Š!âŻ^ržŠ˘0…‘€@tômE‘üř‚ p×0›EQ,ËrGĘł,Kęó‘\ůâĐ=11`"Dxś4AŠÖŢL— ‡±immísss===ĆŚŁT* Y2 SQQ±oßwÝ»wk۶mIIÉ÷ß˙P\\ŘjäČ‘2™LäT"DřÇěĂ–Ä€JL§ ţ24ð LQÔ:=ŚhšÁD'&`ŔÂŻDO>­°łł›8q˛««ë€ý.\¸8wî[۶}i2™hšÖh4Ű·ďX˝úĂĎ?ßÝeܸŢ čŰ·Ď™3gŢ}wÉĆŤt:ť8€"DńŹ€ŃhL<ꀱ€(„B€!ë'ň™B˘i“Ůčîái­xŤE3€1ľď™ ЍÍ@ŁŃlÚ´a†a˘˘˘"#Łhš&Él?űl‹Ůl6lĎó:]ýű% MÓjuŕČ‘ŁŃ,-B„˙pŮüÎ;‹kjj,‹\.'í/^Ľ4iŇ$“É$Žž"Dü@QƸ´¤řžÇ Ďó}Hz sçΧĄĄÍť;Çb±TUUź;wžaŘiÓ^ąpᆠoŢĽIÓ4ĆřäÉS·oßž1ă Á ť"Dü×|˛ě?š¦hŠ˘é‡EOP$JRM¨ŹŮ={öÜ˝[ôŢ{Ë/~—eY÷žËť:uj÷îÝ<*ěß­ÂizwOä~ËËËżúꫬ¬,qeřÝr꤉lll~őń!„(ŠfĂ ŠÂ‹BęĂŘ´¸¸xÖ¬ŮÝ»÷ś2ejii©uď!‘H 'LxîÜ9™LVP?}úkÝşuź4irnîMZ,öŘ·“ź|ňÉoÜ^ştéÜąsżĄ%BčŕÁż/éUvvvZZÚ_}ăµµµ·nÝz<ăÜ®]»¤¤¤?îp‡Z·nÝźK3aßľ}ď˝÷Ţ7ß|SSSóDćˇ^Ż?xđ`ÓyZłfÍc˝˝T*MMMׇ˙ÇĽĽ0CB<Ś&Ółô!3P˘ď­,zů6;;»×_˙ŻŁŁăŽ_…‡‡żôŇxb+Ą(ް°đÓO?Űłg_MM­ŤŤí°a#:vě¸sç7}úôž˘X ËĐŚŃh´X, …Âl6óGÓ4+‘ôú§¶ć z" .„$‰ÉdúŐAÇD'ĎqÜżŕ a–a0ĆĎŁÇr9©Tb6[ţ`i? “J˙Ě„bŃ4Ť8ŽŁp<˙·¨?€eX@H&•{5š¦)Šz´{ęż~92[~ĂtEȠן9yň7(˘!¦[7ŁÁB ŚË$Ôóe3@ŞÍ`üKR_EUT”ť={ŇĹĹUxHÝu„Ŕbáęëë*Ë+Uv […čŐ+B„FBŹÁ /+-ícwżJ•Ç˝ž#*ţŘQ_ßGMuĂ0§ľň[Ι—wĂd25ŇĂ1gˇiÂ"ˇ6Ü>cěëëŐőmt:í•ä ĄÝzôt÷ô4›Í˘Z„ż,ĺ4]VZrúä D!D!ŃŞö„Čĺňg‡=g2ćc®¦ĄŢĽń[uňÇ59f@ŕ1Í(šˇVů†›K"› ú†Ű–e,( ŤFR]€çůšę*1yďS –eÍf3Q8KĄ2łŮȲŽăhšć8Nô zWrŠŇët€1)¨)J¨OJO@FľĽĽŚ˘(ňÂbŚąĂ`ţ `h‰ `„0j3r*ĎóÖŇ4}öÜéč®<Ď „_ľâyˇaKO›žŚ?>ôąç÷íţöĺ “¶±uĚ /9|0*:&';;2ŞsEEąČ©OíB–ršfx„z•ć1Ć,Ëž8yŇÖVů'š–±Ŕ3ĽĹŚcâî©ŃcŚ«„a6›OśŠ/(ČŹíŮWŁ©Ą(ę— ^ŕEYä©•BČŁçÉ_ž'@ŔŮ“}±§ ‚ ÷U”PźäJ>Ą‰#úv×îŐ«VFwîŚČ·üŃ8 ˘(Š˘‘ ơ6ű>`žçh𮍍8ućduu5Ă0…xžĂ*4$đĽ J¨OçëŠĐĂßF$`ç8,ęÓ*aAŔ"ˇţ=$TăcžăX†)).ž1ăÍY3g>Ěš>ö÷_ C3,˘YŚl6ŠŐfš‘â±ŔóB¨NSŰPá~źPy§€ˇGě)]4˛P"AxŽDB}şçMÓb¦—'N¨ĎSs'BČÂóE…&“‰˙Ł%F P´ đł`Ăfš“PžçAđňôR)U/],,*$Ş˘ňE÷NUľ"ˇ6÷– yŤĹzZ7ĺX”Pź$©|9Ž3MööösfĎĐż˲÷dˇ?¶zcŔ ˘h$đ&ˇ¨µľ.•‚đ‹ ŐĆƦG÷™™ÖÓĐ+LŕQĺűÔŞ Bd>‚€( !„0QĺűTOŠŔM3 +ę“•PyŽŚÍ&S+ż÷–/ëÖĄ Q ý Ű&Ša€h†•Ó2!Šł6Ů] <˙€GI»¶mjk«1x[m¨č”ôÔ‚ăąđŽ™WÓ#;E%_ĽĐ)ŞsFZŞşuëŇâb{•ęVîMŠ˘Dđ§4Bp_ĺ+ę—P@Ż×wďÖ Ěóź*C"„ɷɦ8Îb4šxž0Y_UUyBdOÖô‚ qźNđŹ(Ä <˘)ňYŔ÷ć˘8+žzń1 CbĹy"„Š1Öiµ÷^FüýdžďćqĹG€xł‰î©yEŃHÔJ5x$iiińý(Ą‡e¤ ˝„•¤\ľlŁP©"Że4ôZ]˝D*ę“"TN;JŃÔ#6·Ľ Pč·’ MÓ ó`Ě`ž6CÓ%:ˇÝCyyYBÂiA_TTđkJ\ÄHhŁEg¨Ń‰ă&B„¦`¤tZúJôň}rŮJŞë~˝ş”D"‰ŹŹűŐ”I!Ť¦®M›ö bM1Ű xX$&ň˝żÉ©T6|řs‚8 "D!â!\AQtzzú//†˘h /ÜO‘ő;pßöďČŽ˙ßđ/†ˇűöíűăŹ?ţîP_Axţq¤"†aí Ĺó<ĎóŹça 4M‰YÖDńŻEQš Ů{)†˘YŚy,đÄąć÷ť4''«ĽĽěo)n *•}ppŰß^c\__×§OŻß·˝ (ęúőkĄĄĹŹmÇŔ˛´ż+ŻfýHB&“1;;ł¶¶ćńx ‚`g§nŁPŘŠ#"Dü‹Á°LVęŐşššbî'΄¨ßÖŠ*(¸Ó©S´ŁŁłđ7Ë̲lbâYA/—ËűâŽúÝ“)Šľy3'""ĘŮąĺc „Puue^Ţ 77Źfó4!„´ZmeeEDD´­­ícčË2W®\¬©©–Éä˘Ú\„˙b`ڏ—zP`€˘ žűýkMÓ˝˝ăßđ†e2ůcÖE“„Źm4{š=„w%Écë’\nF®i"DřÇ+ĎSXŕď…˘Úů×-‚˙z­#Ćż©ŞÁă±Đ‚"ž. š¦¬ů{1É>(."D!BÄ˙źRŠa›g$‰ő_Ťę¨żY’ś$ޞňŮďóµˇiš˘¨GŰJÉm>¶2żď^W-Ă0Ö{aYÖú™({Eí«"Dü儊H)Çrą\ľ}űŽë×s°R© ëŰ·IT‹JMM;ţ|UU•““Sßľ}ÔjuÓçççďßżż˛˛˛{÷îýúő{DRRRŽ9"€:uęDHĄ˛˛r˙ţý·oߎ:t(‰{ąsçN\\ÜÝ»w[´hѧOź¶mŰÂX»víÝ»w•JĺâĹ‹;›fdd:Äd25ۆa‹/jµÚľ}űšÍć?2ĚĹĹĹű÷ď/..މ‰yć™gú4Z·n]QQQŁ{ÉËË;xđ`eeĄ»»ű#\]]ÝKvv¶FcčßżźÉd’H$?ýt´{÷n$ě§ľ^űĺ—_DE…7şVrrň‘#G0ĆŚŚŚ|DçOž'''&&fçÎť{÷î%2âĽyóB=zôpqqůôÓOOť:ENŇĄK—çž{nĺƕʔáh;;;{{{ĄRɲ¬T*ÍĎ/8yň¤ŤŤ­D"ÁSeccŁR©T*•ŤŤ ŘŘČłłł“’.(v,Ë`ŚU*•uăANHŘE.—“Ęd˛¦fyyůęŐ«ËËË;wîĽyóćC‡=Âś3bÄU«VYŹÜĽysůňĺă>}úTUUÍź?żŞŞŞáO( •••?_VVFÄî+VTTT€ ?˙śŘ(¦öęŐ«‹-ňóó \´hŃŐ«WÁ¦+W®Ś (jůňĺ………ˇ[·n-Y˛ÄÖÖ¶C‡Ë–-űůçźĹ×I„"¨fx0PęÜąs÷îÝôöŰóvěŘ.—ۤ§§_ĽxięÔÉăÇż;|řĐŐ«Wˇ&ÉŹ=ęęę:eĘ”ˇC‡Îź?Æ 0{öě3gÎXE®Ĺ‹çççoÝşuäČ‘cÇŽ=zôĉׯ_ééé•••oĽńĆŕÁçĎźżwď^Á_~ůĺ´iÓú÷ď?nܸ€€€„„r¶Nť:ĹÄÄ|¬™““3dČ//ź.]şť>}ćňĺË/ż<~˙ţĄRéţýűĺrymmí›oÎ Q«Ţ~{>Ë2‡ÇÍś9űóĎżH$§Nťqtt5ŤD”ĚÎľ>`Ŕ GGÇšššĹ‹ß P«ŐA›7ŇT?|ţüy†a¦OźţěłĎ.X°`Ë–-d4Ž?N-_ľ<))‰ÜKtt´\.·ţĽ¨¨H§ÓÍš5+66vńâĹYYYőőő Ď/BPPCRŇą\–••UQQyéŇe˘ß·ď»˙üç?FăRřÇ…B1uę+ŁFŤĘĘĘܶí‹ÄÄÄ®]»~őŐ¶#ž3™LC† aYfćĚٸ|ůbBÂ9AŢĹСĂ?účĂ)S&›Íćž={§ŐjĐŻ×ë¨]»v———ź9sęâŤŇŇRŽă›Ęë¶¶¶...DÍĘĘaĺĘ•›7o>~üxiiéÚµkýýýŁŁŁ›íĽ‡‡‡R©Ü·o_eeĺÖ­[Ű´icgg×P˝ĽĽ<==2228ŽżpáR×®]._ľŚ1ľs'??ż _żľË*ëôôôČČH†a(ŠęÔ©Srr˛‹‹Kź>}Ö¬Y“———¸~ýú·Ţz !”ššÚ˝{wP©T^^^ąąą““hkk ÝşuKNN_$"D<í€ů…Ť0ß0h†a™„„ź[´hˇŃh88~üxž·X,„@.—Aía°X, sďĚ,Ë’Ć*•jőęŐ/ľř˘R©|ţůç‰)Ńd2YsŮŘŘ–Ť2ţÍf+YVUUőë׏¦éNť:uîÜů7Ţ&ĎsaaaYY×á;__żyóŢŇét&“‰ăxŽ3ó<__ŻÝąóë«WŻž={Žă,mڴٱăkriŽăĚfcŁ.5Ě*ĺĺĺuýzÎŹ?đńń™9s¦T*mtuŽűĄś*Bl%Égź}6tčP''§ŘŘŘ^xáať÷ňňęСÊ+ÖŻ_ŻŐjß~űmĄRŮäůČČČ7n\ż~=%%ůŐW_]´h1EQ_|ńĹäÉ“š€»őiĆĆĆOť:Ől6oŢĽ™ěL&“őŽX–%§2›ÍV˛ő©‰!BÄS Čb2ˇbL’(Yż5 łgĎZ¶léś9łűôéM˛«‡‡‡©TĘŐ«?,**˛µµ­­­Y¶ě˝¦Ůěbbb.]ş”’’‹/1bhµÚE‹Í1cůňĺ§Oź&.E#FŚXż~}MMŤ^Ż_µjŐ1c 00PŻ×:t>üđĂ"N}đÁ„ç JKKU*4ĐôZiŻ©îW&“nŢĽ922réŇĄ 8|ř0B4MÓ ‡’JĄ‰d÷î=ŃŃťW®\1sćLDĆd23 #‘HAđőőÝż˙G™LV^^ľ~ýąÜ!úÜąóUU•óćÍ{íµéçĎźojCíСC^^Ţąsç`ٲe$|#FŚrwwojCíŢ˝ű¨Q٦OźîááÁ0Ěś9sxžź={öČ‘# :qâÄďż˙>##ă?˙ůOTTTTTT۶m۵k7uęT š2eʦM›ÜÜÜnÝş5kÖ,B¨®®®]»vőôô?~|÷îÝ'L@şÚłgĎ-Zčtş–-[†„„4 ĺ!00ॗĆ{zzňɧk×®5tíŰ·ŻŻŻ—Ëß˙Ďó+WľżeËVooßÁźuvv&Ěť——+•ĘOžěýŮňjßY?1óϵ.Wc] fĚ1ă˙ś~`ß BÖµý=;=5÷›šCâ‡?xőŃ?<|đîóVŰxůĺď#ůäääH Ä䫯üčý?=zďŃŹá ·oßzýőź<ţ÷ĎŘy÷›ßţÝo~}Ç""^zé{˝÷ź<~úŰßuŮĺđ3»÷½ăů1§Ă‡üĺx2ź1cĆŚ/’ą·± aĹÜ!“ˇvĹżv»7â‚!Ô5CŢ1Áeýŕżt™ő?”^»Ůí~y»Ű…ËËsđó{e×%uŐĺÝľnŢ˝čúi†ť4~ ÜÉ~ńłóŕvk”Oç\ZÝ‹có}\Î2Ža¨öÖ2Ps¤ IŘâoc{vűęii“fOb$ KçĆM§+Ĺv×RóÜÝ$ŃÁZ\Č’[¤g°{Ę·{P[WHđsKĂőż*ĂţG¸fá:/&ŃŐbÓőą ®Ň˘ ěhE!%q˛üźfwęönµËäí陼&mŘąăúŃ­2ě•ç@PĽ­Ęń†‚âž5×ÄbîPsŹcŽŰ5żµp|á§ż  evËŲ/ĘÜωq}Í(zrÜÍ$Đ|;áÚFz¦0†áÚ}ˇ™«!ë#ÍĽtć>‘bş˸mšÇ†ŢřBŁbJcŔQiF´l6…ŔúMnôoËxSPµĚQääĚ Jô(VjZ)hĂŁjĄ»5­´Í¶ŹTbşĚÜ7ŮlĹ$eŚaČeŮ›ŮX¶¬PŽ °#4Łu~š§O”iîȬ«•—ÎúnăhR1îz®Z÷8ĘdŽÚM3cfĆę©j(ł,o[W5km¦0Łzż hĹA‹ŐÓ\=őĹÂşn8?_ťś(j÷•ŻŇ<ęPúEYŢ"ŮěaFŤ§gYŁ,—ô~4Y Ě;!•SvrżkťśŤZĎO)xż”™lÝŹ±ž?ŤŐYÖććž‘Šhj¬te±dq7ď”­k0š ©łĘ˙v†µĂŘŰ1IEND®B`‚gpsim-0.30.0/doc/screenshots/breadboard.png0000664000076400007640000015247713041763626015574 00000000000000‰PNG  IHDR9S† IDATxśě˝w\G™ď˙í鉚 ŃhrÎ9眣&h$9¬ÍÂÂ’Ăâ%Ř^Ŕ^[$/Ë.,yw“.Ń`°—hlś-i¤ŃäÎ9çîé<Ý÷ŹÓ}úÔé#Éđc—ç^ŐcÁĚgę¤:Uďű}«ęTń@™*y<ÜL7ÓÍt3ÝL7ÓÍt3ÝL7ÓÍt3ýe&$2©äń½ýýxâ{?@~AÁźíŞ÷ś˙ ŢvׇČ;ŕ<ŹúťP?ńâň ĚuŰ7ÓÍt3ÝL7ÓÍt3ÝL7ÓÍôqŠjŕpě×čOa„ůápČóő/~Ź?řˇ˙źoö˙\2čőřÜg˙9|ńő×FÔ@9•<^řs_ú*ęţGn`gűjěx<Ŕă rxĽčźén97ÓÍt3ÝL7ÓÍt3ÝL7Ó˙{).ȡ~ bš0ÂT„p8ŚÂĚ(č˙©”_P€G?ů8x˙{ŢEG w€siăâźôďZIŻ–!÷D&ŽB!…< A.ÜEEa.Á#‚AřAěnĽŚúĘ"ř#żűAl_xőEÔď‘;_B]9Év/˝ŚşňB’mĽŚÚ2’í]~µeq¬ş”dűW^CuI>É6_G‹\˝€Şâ<‚ ®^De1™O°u •¬|Âí TĺL´}ĺ…,¶se…' &Ţ˝‚˛’Iö6QÇ®˘$?‡`Ňý-çť ě`;ž vP”›M0ąp…'Ůl'ŹL!ÚG~N™O´‡Ľ$Sźs<ޱó)%‚8¦’ q2;“d2NĎ Z.F‹iäd±™Ů™éÓ*eČÎłA‡´Ôd’őHK!™Ĺd@jJ‹‘šL2«Ů”8fBrR"Áls<łš‘”Č'Ýj‰g6+ů$sŘmŕóâYÉś;x$s:Ŕ#™Ë鏒ąśHvčrĹłĂC„Ăa‚ąÝn„YůÜnw|>Ź!óx˝…Hćőúp ‘ĚçCđÍüŹćóâ? mđ˙/ţXź?ţş^źźăţâďŮăőĆ=›‡Ł\Üw9łŘááa\ŮrĽ7ŽwérĹ×®úât8âë•ĂW˙¸ę)W}¶Ű¬o¨-جńíČj‰ooVł)®]rµ_‹É×ÎąěŮ¨Źł\öĹdĐĹŰ+˝6.źQ§‰ËÇe˙ ZuĽťÔ¨âě©^ŁŚł»\ö™ËŽsŮ{Š‘~AŁŕD‹É%q~F-Çů#•Lď·¤B䲗Ďăô—˘ý¸|rŃ^ś˙Uâý´\¸çĎe‚]˛ü>—>r0ÉţVśŢŕŇ âÝÍ8ý"ŢŤ×9˘=´}9N7 9ô§»z1.ßÁć…8]Ç©˙®Ľ§÷.żŠ6Űx%NwréÓťKń:vç"KďŘąđę+‹ái»z°ůŞŠó Q˙ŽBĐ*$Č;‘…ŁPčšZüĎ­í˙ŇÎWßĐ€Ď}é«@$ÜăŔŔĐpřücź .ňÁ÷ß}Í›¸^ú—Ďýzş{ vĎůĎ`iő ´&[$ ĺÁ c`p2Ť Ńń6éî%ś^?-ˇ’>Vtőuś˝ĺV\Či&ŢzgÎÝ‚«ÁNź9‡mQěXÉöE¬­ź!ŮÎE¬®­cG¬˘™t÷–WOc—`8µ˛Š=‰šf˛˝ËX:µ‚=iŚÉ÷Ż`aéöĄš;ŘÄÂâÁ‚«›_ÄŚdłó Č´4S ·13;<ĆT˘mLMĎB¨Đ1Ř&§g b0µxă“S+ő1&ŮĂřÄ$Á4Ň}ŚŚŽCŞ6ĐL+=ŔđčÉd Ź@¦1ŇL'``pr­)ĆBô AÁ`z…}ýPčĚë퀒ɔbôöőĚ ’ »§*=“IŃŐÓµŢB3ŁZ†Î®n¨ 1fŇČŃŢŃ ŤŃJ°¶ŽNh̬U Ą­:“-Ćt*4·´@o¶Ó̢Wˇ±© Ôhll‚Áâ ™Ő¨A}}#ŚÖłµ¨«o ™I‡ÚÚ:lN‚ŐÔÔÂlwŃĚnÖŁŞş‚PU]M0‡Ĺ€ŠĘ*X‡ fڰX>§Ő„ňŠ "źÓfFYY9lÎsŮĚ()+ÝéŽ1»%%Ą°»běĐaEQq1.ŮPXTçaŚąť6ÂyčŤ1—ůůpącĚăr /?źd‡äććáĐăc0'NžĚ…Űc^· 999p{ý4óy‘ť}ÉŽggĂë 0ÇŹ‡×c~Ż™YYđ1™ĎĚŚLřAš|^¤gPâ…f~Ž;†@đfÁ€ÇŽ#ň~¤ĄĄůŽ‚¤¤¦"Čf)©ĹXččIÉI8:Š9˛PčI‰I„s ‡Bŕ'ň 1&8„CHHŕSSb<á?©0ţX®kpÝ ×=s=Wp•W™r•=×;âz—\ďÜďő ++‹¨/>ŹÇłŹłęW]‹Ż“TÝ=IÔgϡąąą¬zĎŃ8ÚŚŰeGAAŮŢś6’íňĐaCQq«ýZQ\\B´s—Ý‚’ŇRŇŘĚ(eŮ §ÍŚňňrŇľXM(ݍ$ěe›*Yö*ކqŮ:»YŹęęÂNÚL:ÔÔÖÁ̲§q6–Ă[ Ô76›˛íͤ˝×«ĐÔLúłN…–ÖVŇpř.ßcŇČŃŢŮ Ť!Ƹ|—Ď3¨$čéí‹óˇ=˝ý„żäôµ ú ?­S100DúsąC¤ßçŇ\šA#ÝÇčŘ8$ŞăŇ \ZE%ÚÁÔô KçlcjfBůő5ҵôŐüÂbś6›_X"ňqi8ŮŢe,-ŻúOş»ĺ•Uě,^;riLÉö¬­ź%´¨xëu¬ź˝[ÂŽ]}-˘w™ěuś»őVlÄ4°dç"u]‰ ‡ˇWŠŃŐÓ ŤÁ‚0€+Żü>nşÚź[Ű˙%źďÁŹ}Ż˝ň2Ź üőď|EEĹÄEtĘßĚP˙QÓĚX‹N5“‹vńě /»çügĐ60AcŇ*ĐÝÝ ąĆŚ0@8 Ĺţ,Ż®bK¨¤Gć¤[ŻcýÜmŘČčsI·/`ýÜ-Ä —î\Äú™sŘdB˛ť‹X]?KT ůîVNŻ“lď2–W×Ę§ŘżŚĄĺU˘’*®`qi%R©¨¤<ŘÄÂŇ)˘Ň+W1ż°DB*ÁćI&ÜĆěüöL-ÚÁôěŃŐâLĎL#ŮĹÄÔ Ńđ5’=LLNB+ÝÇŘř$DĘÓÉ02:±JĎ` ŹŽ†I/`px”0`z…C#3(Ĺč$ŚźA)F_˙a8 J1zűkPIĐŰŰGBF•Ý˝˝„q6ŞĄčîî…’aÄM:»zĂnÖ*ĐŢŃI8 łV¶ö"č±č”hik'ŹUŻBsK+´ e5¨ŃŘÔL87›A†¦&’µ¨oh$#—Sµ›t¨­«'™YŹššZÂ!;,TU׎Űa1 ŞŞšpđN«•°°„EEEÁ\63Ę+*ÁಙQV^A—Ý‚ŇŇ2BĽÚ-(f‰·ĂŠ˘’’9m(,,‚pě‘'Ć<‘ÇÉ fňóň ć=tâ$Kčq2‘čó"űÄ xnôř˝nd'Ĺ)W€đy‘‘‘A8~/ŇÓăśôcÇŕgŠlżÇŇÓ‰|G?RÓŽ!d°`y9C‡Ă°»Ü8 ‘’’ p‚HJNţ pÂHHH@ƱT„Ăa¸ÜŢ˙ONč(ä䔸'55• 9Ę”3¸Ś8ĚwÄů.9ŢąßçAf&+řőzu< I‰‰ôó^+ŔŽ«“nN°ęî­÷\mĆăr ?źd\mł­FÚ´ÇëDZÔ€Őlĉ“yd'‡Ťŕ´%6‡Ë6qŮ0.[ÇiÍzTłl'§Ťĺ`ś6›Ă¶sů._ÁĺS,:%ZŰÚ ßĂĺŁL9:»ş _fRËĐŐÝCř<ŁJŠžľ>‡#AÓ‡růZŁJ‚Ţľţ8źç»" “~_.Äŕđ‹ 04Bj.mÁĄA´Ň}ŚOLZE#ŮĹäÔ ¸hÄ»š™%ő—FmcfŽÔR*áććIÍĹĄÍ”‚M,,’ŽKëqiB.íČĄ1e»—°¶~†\d;qšĄYą´­dűuś9ÓŔ1Eô&čd›Äَę匎ŤĆŔ bhdŚ^ BˇáQ†Ä¨¤ŚÁTbô Á–I%Ao˙1ÂdRKŃÓ×1›őö=9&Ť ==}0Y#CWw/$ ĂiÖRNAĘ`ťí]1 ±E§D[{ä #nŐ«ĐŇÖ“Ôhni%ś‚Í FSs+T ça3jĐĐŘL0»‰r–j=“éPWß Ă‘9Ě:ÔÔՓ̢GMMáŞkj c0§ĹĘęj˘‡Đi5ˇ˛˛’pľ.ŐsJ2JlčÇşěf”—WŔ`ޱC%^Ś §č°˘¤´&Ć•ŰaEq ‹9m(,*&ÇeGAa,lVPHϡůůó:‘›—CřxÝ.äććĚçv!çäIŘ‚Ëç9ĉ'ŕpşńř‡ßŠYéxó=źFvö üË˝oŐq{ţůt€ădôdű}T/˝‹!ţ>/223‰ŢňhŻ˙!E¦ŤŠěhľÇ?üVdgĄă®‡ż·'vlT´î#爛ŐŔmď é™đ0p4Ŕń2„r4XđúH– #x‹8Á “…‘đçp‚Á#|ĺS€ŮćÄ;î˙W$§¤÷ÂyĎ‘Çëőăíçfáöřđťź˙ÉÉ)DHMMŰĂd¤¦¦eĘ,űh=xëG>K1ƱŃçő~ăß9ŕ0ëF´ľ8]üđł÷Âlsâoîýrrrá`چ0ë$ÁrrČş©ĎD˝çj vŁvD·7Fäj«n§ EEĹ0YěoĹ{ď8ří+WđĹď=>źút7ja· ´¬Ś°%QűBŘś¨ş˝rZŤ¨¬bŮş¨ýă°“¤íÔŁ¦¶.ÎîÖÖ‘¶8jź ›mÔ˘ľ±)ÎŢ76‘ö>ęľÂjPŁĄµ•ô)zZŰÚ ßCů¨NŇGiččę"|™Y+GWWéó42tőôrřĐ~҇^Ă×ööő“>Y%AßŔ ợţśéă J††FHơôrFXÚB/`t|‚Đ :ŮĆ'&YZe“ÓŘahš¨Î!őĐ.¦gćĆ­Ą¶1;żČŇa[gk3áć— §^ĹâŇ2©ő"úŹ© •›X^YeiÇ+X^=ÍŇťX=}—v,˘O™šUľ{ ëgo!´­l÷"Ξ#5°b÷ÖÎśĂĆ®4˘ÁyĐEÉhpÉăQ:űzéĎ©í˙RĎŤkăţň?tÓá0e ZZۨ^‡ČJZé>fć°)”ÓAŹrwëçnĹEFe‘ď^™s·ŕŇł˛PÎŁ˘)ö7°vú,6ö•/ŕ\aTÜh…ĽÂ¨ô*Á&N-ŻѵJpKË+¸ĘhXjá–Na‹Ń(ŁŤŐkDŰ[X"ňiÄ;ť_ŔŽŃ %»žťĂĂh%»š™#ztŇ=LNĎ=zŮ>Ć&¦°Ď0BúH€Ăěí0Č›ŔèB ŹŽ=*ĄĂĂŁ2z^¨g"†15ŞÄ"zmLj úú!ań¨•˛XOo¤ `ÖČĐÝŰ©ĆŔ`rtőô@¦eä‹8Ě)‹NŽŽ.(tL¦D{G'ŃF8íP1†˙m‘‡Ůłf3¨ŃÔŇ µ‘áŤ445CkŠ9Őh€ĂěŃst¨­o€Žáôf=jëęgî°PSS =C08-TŐÔÓŕśV#ŞŞŞ‰^HJTÁČ*QÁ`",vh§z]IfAiY9Ńsꎦhr;­(..…ĹÁd6=»§ßxü>äç3ŹŽ ×ńť_<ŹÍĽ‡äĺÓcĽ‡Näĺĺ˝Ě^·ąą$‹ BfݵĎsśś¸""6+# Ç3Ó!ŢzŤ}“8ž™Ż×‹ýK/˘chŠŢđy™u<Žedf=ňQĚś®đűžžN°¨Čf˛Ěô4dg¦ăĘKżFS˙€@OKŁG ľóĂźâü§?‡>-łČ=‘…ő™tÔW"/ç8ů|zĽĐ™¬řŇ÷žRoA€9Ň ‚ŚŃh€CŚôDśŁ9ŞóFWyáń@ŚĚ4T•ŕxĆ1Ľľ%d”‚ËŻ ±o"îţâî9)‰™Yí†ŃlĹgżüuä—ŐĐůŽŽ‚HMI!FWbĺ XZZ]öŃz Řx Ťý“±ű‹¦^ö¨]f&ëťSŽ›ÍXő%đA¶łĆóú##8.9Ň““CQśőŮíÂÉÜ\˛-pµŽväq9PPPÁě(,,"ÚŞŰiĂř`x<.l‹đěk[řŢŚňźĐ«dĐČ(©nâ´TÇi7¸ě —â´WV*Ş*ăl]śýă°“´=eÚŘÝ%l1‡}¶›´hhh"m{ÄŢ3Ga¸ü‚Í FskáS˘á{tJ´ut#.QżEř2­ťÝݤĎÓČŃÝÓCڏpůKÚŻrř_Ň'S~šé»ąüąQ)Ćŕđ0ˇh}ŔÔ Á…ˇő‡.!µĘ>Ć'§ MĂĄs(6§‘ffçI-%ŢÁĚüÂŤuhs‹$‹ę:¦ÖăŇQťČÔŽĘ+XY=MjĚýËX=˝ŽËŚŕKźFu,SŰFő.ˇw.áĚ-·`cŹ pÂ<@+ÚĆÔě„2MT¤Ă¦Sˇą­ EěXfúź Hţäă`ś‰Hßď}>đ€G>ń8üč˝ôßúřă8˙±{ßđý]3ČąŢE˘{č±Oăüý÷Ć č:ײThiiJo¦ľ SCŁc“ÓŘ)é"”ű#3‘(— Gó]Ú%™µő3DĐŁ:¸Ś•ÓgЦDÖhÍ©•U\aŽĚŻFFpŘl™zÔ¶0żxŠř–H#ŢĆüÂ1l©•ě`vnŰŚ|:É.¦gç±#"™©™Y˘·C/ŰÇÄÔ vĹd€319MĚ%ŐË0>1E0\€‘qŇŕBŚŚŽß•" ŤŚĆʨaph$®¨pzhĂIŚÂP=MĚ!íhO“TMěžŢ>HU‚u÷ôAĆČgŃĘŃŮÝą†ŕt’Ž‚v(L¦Wˇ­˝=®W®…ĺ lF šš[yĐöHŹs5ŕ™Á ŐCČě…¤­‰ĚčQ]C=N‹Ő5µ0ă<Ó™»¬FTTUĂh!CEE%LV2)Ż -@¬d€SVVNöěFŤŮF3ĹĹ%dO±Ó†ÂâbXíŚ'"¤˘řÝüx’’’ĐÓن·ŢqÇÎĽë#(Ż©'¦ĽEśÝĹŕ0ĎCMQc~wŽLť–đű‚<ŚĐQěÍ÷y•uśřĽČĚĚ$¦ü^dd, p|ü´ť ü…Â1ÎČąE(¨l@iA.»űMČ8–Šg_ş€/<˙"l6ňNć Łµ FĄN©éYc*V8BźOL‹Ž¸qM[űS†uÂřřÝ “Őß<÷2Oä1ţ¦Ë> !11‘¸?úž1vú˝Źbďőg‘ś‚Ü’jŞü˘Žź#Ŕńâ—Ţţ?ŐÎ÷ć÷!=##îťgfdĆżěúB?ăyý^7˛łOŔĺŽĺóGFpČşËQźŁ«-äĺ˛Úǡyůůd;r9_X›3>Ŕa~÷mżyç-0Yříó/#11 uMť± .›%Ţ8¬(--#ě·}‰·C\öĘe3ˇ˘˛Š°k\öĎi5˘şş†´“ŰIÚSjT‡iw9íłI‡ş†"±µhlj"í˝QF–_v‘>%ŕčťkJ´µłü‘N‰öÎθκÎÎnÂ癵rtw÷ŢŘ_ŞĄčfůU:Ŕaĺëí`ŤţHĐ?Ŕňç*1‡!”“ťťqú@)Äđ©# ŠřÇŐak•‰‰)â».ťĂĄ‡tŇ=jTGDvĎÎ-úJ+ŢÁÜÂ"ˇĂ4âmб4ÜÂŇ)B×qëżM,-“:Q%ؤf1őäÁ¬ś^ÇĆ^ŚqéS.Ë©ww/býÜmô=ji»b˝‹UG}Ƭ§qéOp®G°ÎÇŕDÉ{ľG>ń8Îüq<ôŃ{đĐÇ€?*ö¸ÎH÷E<řاńđý÷ŃË@_+5·´Ae°ĐŁ5fµC#Ř“Şčő˝•‚+X]?‹‹»z<ĺŢF\D«ÜßŔúŮsSí_ĆęúY\"ś+X=˝NT*µŕ –WÉčZ-Řĩյ¸giy…ŐŃD*Ő&Ł!h#Á 3Ň׊©ž&ÓIv0;ż-“íbfnŰŚž˝tS3sÄÜO˝l“SłÄ¨Ž^v€‰©)ě2§žÉÔ5b:šc¬‡2LăĨŽQ)Â0Ë€™Tb Ť˝6&•ýĂ„A4«©ˇof/PÔ2{Ět€C3=˝}D>‹V†®˛—ʢU «»›čͲę”ččb8z%ÚŰ;‰Qťh€Łŕp”Ä”…H€c`8-P3§E¨© ÄNÄ2™Ó¬Gm}=tqη>n§š5ŞăŠLŰ00ĹŐDŤŕpć¨ÎˇÍŚňJv€cAYy9ŃsęvP#8&;G€Ă fŠŠKOd‡MQ!ĺřEŽŽč{Y{ďcŕ'ňńµówádv&žxę9Ě uŕ=Ź|…}5eExç-ł¨-+‚ÝĺĆ÷žˇĘ~öůŹŔlsâ«?ü5Ţq˲ŇÓđÄSĎáĎ_ŔÝo^äžČÂożőĽűüc>ü¶uŚt5âS˙ő$^ľĽxËÚ$Ćş›pף_%žŁ#üü‹÷Ăl»űŔż#ăgź˙,vľň_Ń×ţćO‡_żr•(żč€ëÖęâ\ĽçÎeÔ”ŇĎůĚsŻáţ»îŔPG>ů?Á+›ř˝xëŮyĚ uâíü;ŞË ńŽł3¨«(&ĘÇďŤS×čo©ÂmK¨(ÎŹÇTĄÇů<¶ĹZ8Ý^ş<źřéońîż:‹Í…Çľú#hŚřÜ.üň?ŮćÄ·ń<Ţş>ŤD~žxę9…BxËęů ř·'žÄ®T»ËÍj3^|÷é?ďÎępáËߏ•ßţč—xm[‚·¬MďîŢĎ<YĚ|^•”ÄŤň––•±ěFÄ–°FË+*H;™¶Ć…®¬dٵ­#íźUŐ5q¶ł¦–="NŮXÂîFl1Űf×׳Gâµhhl&ěýµüBSK Ąi"‰©I1ßĂňQť¬Ž9:şČś¨Ď#ý Őů'áđˇR_Ëöż},?-AßŔP|€3DŽŕDµ€ N3ڱt„#Łă¬UJěł‚ž±‰IBżčeśšféśČSE4S7é$»ť_`é+Jsqił-"˘4Ü&+čY<µLč?µđ*5‚ĂÔ‰íx™1‚ŐěÎöŐÓ,}şkgÎ’ÚvoëçÎű3·ÜŠ ;bZa«„T`uU¨ŹÇCBŞť=˝TĐ}Ń˙§8×ÓöJ€óFĎ÷ŕGďĹůh`ůŕ\ď| ׹}‘hzčăŹxxCj'ÂaXő ôôöA¨Đ" # C-ŘÄĘň6vćB‡BPî\Ŕé3çpa[D3ĹîEś^?‹‹ŰŚ|{—°ş~» ¶ż•ČüČ(Sí_Ć©•5\Ţ‹1őÁŞâîIcLp…š—ą/c°M,,,áęAŚi„ÔŠWňma62G4Ę´˘mĚĚΓLL}@·-TĐL'ŮĹäô vD,69]±’fz)µZÉžXĹ`űÇľ$Ć ˛ŚŽŽc_˘Ž1ůAä{›3ĘŠ|oC3…CĘL)B˙ŔÄ -ÍL*1zű VčÖÓۉ2žIUz“ »»‡`fµ·Ă¨ IDAT]]=±Xg'ő˝M”Y42´wt@ÎdZÚÚÚˇĐifŐ)ĐÚÚĄÖÄ`J4·´@Ą‹1›^…¦¦f¨őć3¨ŃĐŘŤ!Ćě ęë 5Xb̨A]]=tF+iQS[K0‡I‡ęęZčM fÖˇşşłŤfNłžrú;Á**+ć˛P^^“ŐcV#ĘĘË`bćłšPVV3‘τҒÚĚÔhŤÍcv3 ‹Š`µÇŰa‰0YQ_›bŃ4ÜßÎŽvĚŤáüŢ ·×‡>ţ/EŽ‹¦‰žFüî…×a‘măü{oGNV:ŢýˇqáŇÜőW‹ČJ ě÷bK Ă;?řOxŰűîCNć1ÜuŰxˇ\‡Üyj 3íxňéßâě[Ţ›=&|nJ¤ť<‘ŤĺąI\٢´đ$ţúÔl6 ¦ú[qßŰϡ#üýGĹ»ţá#úܸďíg0ĐX‚ăY™xmsďb\ű}o:ł^K<ÇXgž}ńÄW^˘ďçgż|gX÷“š’źĎO—_Đëí‡ĂHLࡽľđ­ď˙'‹+P\ÓŠŚě\dç"+·EUMH=– €š*µá9â^ö_˙ŽÄH[~˙ň.żÇĚRŞÜOfeŕ|7ĺ9gVznźëÇsŻl %9 ·Í¢UŕŰ?{`¶Ř°ňWoÇKżţaű˙ę& «*łIüĚwâOý {Ż?ŹPčáPGÁůôó/ýGj%óX*qíŰG WHň‹–éőęÁ±d>ý‡· '3ťxÎüŚDüîUj/·ŢÚ|XőJd¤§c´« ż|î%„8×íČ=‘I—7˛23‰çď¬ÇÇţîŻńŢű¦ëŇÇţîtÖŇĺy<# -•¸˛CŐĹŰf:á´““C˙}¶·Ďľř:ŇÓRńÖµIĚ ´áŮ—.ŕXZ ÎÍ@)#ëX*Őf2Óńî? —.ÓďÎă |FY~oZ™„ä`ß~Š|wĎüä;t[€céé¤=ŘŇnÄŰ’¨Í!íPÄ61óElaë,†8[µ‰l;Y]] ˝)Ć8m¬)ŢŰŤZÔŐŐCkdŘńmgÚű¨ üBÔWčbŚË§XuĘ8ßCű(Ť‘Á¨A™ľĚ¬‘Ĺů<łZŠ®î^–żŚ÷ˇ\ľÖY €í§)ßÍđç/’ǧP#š©-Ĺ”Á84^ŻUôŇ=LLN:G'ÝŁ´ŹÁ¸4RDKÝHsqi3. Őz¤ţŁ4á•}†NäĐŽ\SµżŐµő8}şş~—vH{ú ©m»Ô¶DŚ|XY^‹ÜĄźŤJ!µ…ÖHď™sÍôg p¸Î÷ĐGďÁC»ç?v/ľ˙^śż˙^:ŇůSĎÇřÓŕ×ÉI`ŔC»=F͵{č±OÓ7üČ÷ѸÁ´8şĐíF ÚÚ;!Qé©ĎrÂah%»_ZÁĄ})=·@ąëçnĹĆGWŞ+X_?‡ Ś©lęÍ¸Ź¸Ô‚M¬®­s5«X^Y#˘kŤp §VV‰ů‘ZŃ6–N­s+µ˘m,,-s0µâťHôc:É.Ő`ś=ĚÍ/L/ÝÇĚě1„Ş—íczš~5Č09=CôXäLL’˝F…că“Ä !F…ŁcĨŽI)Šëe1©$”ab-044LôÚŐR A¨`2ú•S,9zűú‰Ţ"‹VŽžÓČŃÝÓËÁQ ‡Ĺ¬:%:»zŢ,«^…ŽŽ.bTǦWŁ˝˝čłÔhm%{ŃěF ZZZ‰évŁÍ--¬Q-šZš‰Ţ;‡I‡†ĆFrTǬG=kşÓlë5tZ qóĂ]V#Şkj‰G—Ő„ŞęjrTÇfŠ›¶qh3Ł˘˛F+WĎ)“YQ^QNô’şV”••Ăhc2JËJafôÎzśv—”˛¦¨ŮQ\RĚúŔŮ¢ÂČ•˘ Ť|ă ŹÓ, âs_ű6ž}áUT6"Ä0Ćoąëðzń–;nEzZ*~üÔc_ Ħ¨óS<4–žÄ±ßzęwČN棰¸ Vç!J r!ŰßDuç(Ć{›˙öĄŻ!śś‰ 㛑¬ăÔ÷AŻ÷ˇű‘—_„ßţč?Đ×Ő ĂC˙ŚŰ¨Uh>ô±‡ˇĐ‘WZ‹Ď~ógřÚÇ?„;צń–}˛“ůČ˧zň‹ňOB+ÝEuç(˘#WŃçHĎÎĹXu?źýÂWâîÇKŚ@PÓGS@JR"(Łj˛XQŢRŹ`0ädöt´ŘĎ9bĹţťyolĆ,wP„M‘†.÷çw([ăřqç»î†ËŔĚpr˛ŹĂ¨’ŕx~) x„DˇBICqűR8\nLŤáăź˙:Fş¦ś”o}ďČ.(A8 …‚HN"ź ““Ék{îFNv=x "--•.ÓëŐ©Á¤§ĄŕÇO=P„ËJĚOńP[|/]ڄõŚÉŃA|ü ßDia.Šósđă'•ĺ%¤KĹŹN–OKe!]>ĺĎî\›|đŁçˇĐ‘ť_†/~÷iüűů»qűň8ž~ö%±ş_X‚ßüŕ«čďjËüŻp? đůýxó{>đ“qfqˇpwľó}ë ă8ž• “VŽŰÖO!=-?yęż±@¶w¤šEËĎéöĹ•_ô݉*”6tź«‹^€®CQ{`&Fpl(-+cŮ’}!F’­¶É™ĘFŽBWVU‘St#öŹé¦ě$i;ŤT0cfŰ]–-ŽŘg ËŽ744°FěuhljbŤŕP~í+Ř>ĹfĐ µµŤđ=6˝míí¤ŹŇ«¨ĹX3:»Č«N·ĺ/Ył 4rj1–˙ííí‹óż˝}¤ď¦üů ËÇK188Ěšá!ÁĐđ©”b ŹŚ’Ú"˘7äZZe||Š­‰ęb–‹ěÓÓł„FŇËö13ĂŇRŇ=ĚĚ.°t—6ŰĹÜ<©á´â,,˛´žh‹Kńšpi™ÔŽáVśĆT ®bumť™‰ęS¦fĄ´íYBŰŞö/cýě-„ÖlbőĚ\Š|—Ă‹”ŐčŘÄ*ŔCaŘ ±wĂN„¶gŚŽ?Ź>đŹş¶gžŹĘĎý=OďŤĹ ¬ŕ+{DáŹ}úŹŠ=®=’ø<úَë8×űÇăÁiŇRS„t¦HAđ`R0·°€mˇ <x„÷ýőiäE6üŕ'$ ç8ŐŁnłŰ‘[\ /fޢß^¸=řü~ś¬¨¤;ŹÓŽ‚Ül€X*GQU3ŇŹç@g¦ÄWYq 3ékŕooENv}íă{›čsäWâd6ű~HźŔă!|Dú±4⛄ÅĂt XT‡D~RR’ …éc!9)™4´ar¸Ć5Ł÷VP^Ç*«j®Yîn%ü\‡nŘě.T4ő qˇŁ q iÇČ‘Ť`đ/ně!))ă}mX›ęÇŻţđěv;˛óŠp)ɱg‹&EĘ%zíÚ¶>„#~'t¤Ë/†˙ÎŹ~†óźú70Ó·żöyćfcţ–·A©Rá§ßů*jŞAź>)ÉI8™“cÄw0Ńű>? i©©ťÁŁŁŚ; sO ¦Ş‰™úhi Î­Tkq÷»ß‚ÂÜl,ÜúvČrüě»_ŁŻť™• ćř źĎGZdeµÔČý¤¦$#Ť1Z“ŔO@(@zµ‡óţůđ‚Ř<ˇ«©÷Ö;ńí__DńáŁ#¤¤¦ĐÁQB$XĚËÉƱ´ŘuxŃîľHJNMŁFĎXĚâp^łÜOWÄî;‘ʤ”âř~´çŤšgŔ|–č︴‹Să=xď;ŢŚ‚Ľ\Üóŕ'p<݉I‰HŚě—CĎ üÄD 1‰¸6»üBÁG=‚×{Îś‚2Ľ¶-ÂĘd?ή. Ľ¬ßţńÓHMK‡Ĺĺ}CĺFzł Ĺy9¨©Ş@VqÜ>?*KňPu)-0Ŕăó‘‘JŐÓh]Ś–gô’ŕe,Ň€pţČŻ7ş·Ä¤$x‚!˘üJ"ť Ńwçw»PRV»~ľCgś=đ8ě(ݬ ě—}qŰmńvČfŤłW‡6 ŞŘvŤÓţ™ăě¤ËbŠ·§–x»ËeźťfCśwôqöžË/Ř Z4·¶Ac"ŰĎŘô´·“ţȦçđ[::»{ˇ`ř7«VÉáăýetd†íkąüośźćđçfőÍ´XÍ`úŔ¤”`Ą#L qśŢ0*DźÂ‚Á8ô‹A.äĐ9zHv@é&iL7éĄű›_$ô•NŻąt’]Ě/ś"—®ăŇŃvśNÔ·°ĽşŽM!“ĹëNN}z°§cUűWpúÜ­, ĽÓ·Ü†ËűŠń­hs KT$P:ÝjPŁ­­ťXťmO@Vľ7¨íŮç{đŃO˙ŮÎ÷đý÷âÁG?M8Źá0 ]ĹÚésŘČé V 6±~öVlHi¦nâô™s¸z #ŘÚé3¸*ÓL#şŠŐÓëŘ"ŘVV×°%TÄx++kŘĹVBM[Ű+,:‚Ł˘™Nş‹……%ěJL¶Çô˛}ĚÍ-bOĘdťťÇľTM3\€™™9ěËH655\C3ŁB©É)ÚSŠ01IŤŕÄăăEĘ 6XĄ§™I-‰lĘ`‘ž©Ú@3łF†Aj±“Ł`rmŚY4 ô÷S›ŹĹň)Đ×ß….Ć,Z%ú"Ł:LÖÓÓĄ>Ƭ:ş{¨ Óh¦WQŁ:†ŁśNhŚ–3¨#=kVšŮŤ´µµAkb0“Í--Đ›m4sthnn†ŢbŹ1łMMMsZ Ô¨ÁŚhhl ËjŚô$:Ě„şş:¬ f3٦–ę­Ś˛C›5µŐ$ł[P]MŤę0YUu,Ś|n‡•UTĎiŚŮPQAőşF™ÇiGyŐ;K3—ĄeT/n”y]””•ŔátÇء%%Ĺp¸Ü´ŤXžźFcgŽ‚!t7SŁ:.›ŻźO[XŹ?\ŘÁúT?n__ơ7ĂPR’’ŕöúp,ťę…źźƱ“E¨*§ÄŘřP?'±-T §ĄŹ|ôČ9™‡Ô不ŢcJr2j«qëü0ŕé_˙É)iřńŻ_Á{ď<…OţÓ˝řöĎźCVvţęÔŕK_˙ή.ć&qěäâÚöPxŽĚĚLAě0î'· )IŚ +BZF‚ }oĚ”Äçă[O=‡š˛ÜşľŚúú:l Őpzž–‚ĆęRĽtyŻn pčń!ďdîýűw`nzɉ1łž’’LÜ[b ‰Kâ'ŕő«Üľ0‚Ű×—áń‡`< áxĆ1¸˝>ĽvU@çĺ‡$>ź8>91ÎCNdÇp_ü‘’™_,WCo˛˘ /Ż]ÚÄöö6ę:‡š’ŠPZ `Ë.ćµĂˇ0ťç(@ZFQNć拼¶)Ŕí ĂqĎéŢ@×]>/^¸JÜó“ży•®Kß{ćE$§ĄăÍk“t]JIĄGHINFCM5ţćě<Ş.&%§"ě÷çc–A8 â÷~žż°ŤÓS}T›ńáć%#™ź÷î˘Ç2ËďĐíŁßÝPo'ŽűŃ„‚x{ŕ´Ł˘˘ś°n‡ŤĂľXQU]IŘ!Ę6UĆŮ«ęšj2‡ýsŲ̊­«%í¤Ő„şz–íä°±N‹1Ţ>›ăm¶Ă¬G3˶;8ü‚ݤCkk+tLĆáSl5::HßcÓ«ŃŮImJú˛n—Q>݇đy­2˛6é/{űúˇÔÝŔ×jč ü´Y#çđç2 Cމů}“FЎ‘B ÔŚŽŽ:¨’`t|śÖuŔ54RŮĽśˇUBLMM:Ç `zšÚôzI/;ŔÜÜK_ícaa1N›Í/,bO;V'ÝĹââ)"źV˛Ăˇ˙¶±ĽĽ‚mQŚqiGJcž&4¦Zx5NźŞ…›X;s–б*Áś>{ŽĹ6qćěm¸ÂĐŔń–N­`W˘DbźQÓÉŃŮŮ ŤÁLĎŕL m­ď[ţm˙?y> 6‚=g€sťó]ł$nô×E®O¬v$ňůŕóů8´čŃÝÓ ĄÎÄD>ů|äX:µJ˝´D>ůĐ‹w°˛¶Ž±‚f:É.VÖÖ±+fä“îayő4v%Ş“íáÔň*öĚ ßÇŇ©ěIŐ43ʰ¸´Ś=)_<…ą†f&Ąs ‹8kL„™ů1fV‰13;Ǧfg!TĆE-ĆÔĚ DJ]Śi$ž‚HcVŤăSS¨ő &ĂčÄ$$ÍlZFÇĆ!e2ťŁcciŤ4łëä\gŠ1˝CC#P0™A‰ÁÁ!(őfš9 *ô Be°ĐĚiTŁŻżj#™Ôčéë…Úh%Xo_/4&&Ó »§‡`.łÝ==Đš™L‡Îînč̶łčŃŃŮť…Á¬z´uvRu-­z´¶wŔ`uÄÍ€ć¶vm1ć¶ŃÜŇłÝc››av¸hćqšŃŘŘÇę`a0ŻÓ‚şúz’଍­«ŐqČ`6ÔÔŐÂćŚ1ߡŐµŐ°»Ü«Şa3*«Şŕ8ôÄ;Âůü'**+ádäŁXśnóşPV^—ŰKł€÷ĄĄĄ8ô0ĎŤ’ŇR¸=>š}nĂíĄXÔ|ö±űńî[p×Kči©ĆćÎţᣏ )%•ţČ<šĽţĽţúÂ÷đÜKŻăŽőEüĂ›WqŰâ0Ă~|ĺŰ?‚R­ĹŢó·h¬(Äýŕç‚x÷Űî„QŻÁwźţä* ú»;đĚož…Ů›‡>˘¦«eĎÂOľůďęŔ3ĎľĎ}ĺë8‘_„/ďá‘ϡPŕmřđŰÖđűqĎůÇńä/~…ď?ý<Śk˙ç˙zŠľöˇĂLý˛ŇČóóś’Ś—®P+«}óý'NâDN.xt$đxH;–J›Ŕr)ÔµĂÄďŃň‹–)łÜńëßĺîr»ńŘW~H>çÂ0Rů€Ĺ¨źĎÇË‘ű|íŇ&T*5r‹JáőđŔż~Ďżô:n[ťŁË'!čA(ŕ!îń÷Ż^Ć'ľđ-„B!<řţ7ă#ď<‡€Ď‡űţg<ů‹_ˇ¨‚š.}< O>ńLöµâż˙>÷•ŻăřÉ<äćçç;bŚü°Ë?ŮfÎ,âî7­Đď΢SÄfLiLLŚ˝»/>~aż›¨‹™„=ÚÂnx\”-‰ł/•„ňąťńöę0Ţ^qŰ:Ę&v’ĂvrŰXkĽ-vZPßHÚl.ŰNű¦_ř qů”C›!Î÷D}”Ţb'Xś/łpř<łÝ˝=ś>Tkş±ŻĄ|rĽďfús‡‘ňńJÓďÇk»A‰ˇˇx1<29Copi.­bŐČ069ÉŇ9”ö«bŚK#Y4LÍĚúʬ¦4—6*bÇšTń.¦őbú/Ş ÷e ơą4¦A¶Źĺ•µ8}şĽzšĄcw±zú ÁtJo34°^ş‡ĄS«8«‘ČŹ”©^îž^čĚ6đů|zş8Wúskűżüóá_>ű< .m\Äß7¬NĎ Ř˝Šg_x=Ý˝ô9ď9˙ôŚÎěfę 7ÚđBząŁcăô®ş<Já6ć5ÔŐ˘mĚĚ-»ęŞĹ;‰Ś†D“FĽi6‹l®yŔ`Ń]u™ËiĄűš&vřŐE6Üd`tl‚Ř?FŻ`xtśŘmXŮŹFÄÚpspxÖ&[C#ć…FĄýCĂÄnČF•}CÄ®ÉFµ}}ÄÇ‹ĆČůĚ—Mzzz‰ÍZ9:»»ˇÔšIÖŐM|HiŃ)ĐŢŮEě `‰¬˙ŻÖ“{´´u;L[ő*4·µCËf­mÄŽŐV Í-íĐ›­©ĐŘÜť‰Ü”­±ą…ŘďŔfÔ ˇ±z3“Q{٬ÚM:ÔÖS˝|43ëQ[[G|(ë0Sű,Ěb@Uu ±7„ĂjŚĚ#w1 •‘)`Ńä´™P^QAě)ă´›P^VA,Ăě´›Q^VN0WdWqć®ç.‡Ą%%Ä^‡+ŠKJ=36—“ĚiCq1ÉÜ.; ‰}9Ü. ŕd0ŹËü‚8›zťČÍËǡ›ą§‡ ›ŻÁs+€ęyNĎĚFeCŇ3łáő¸°wéeřĽ Ξ@íy“’’ÁÖŘ­FŹ”ś‚š¦V$&h{^ď!Näŕd^ÄűW‘™•ćŢQ8m&Hö®Âď󠢮*É>ü>/&NÝź?€W[ů‹Ďç#§ • íŕóůđű˝đ8mPŠŕv9𖑉˛ęFdçŔe·Ň×Î-,EzĆq(Ä;ČĚĘA}G?®ľúüľŘs„CAě\zż—şń>üßP7Ţ IDAT~/ť HNIÁ×}~ň‹_â›?ţ2rK‘śś‚ŁĐ|74r!l&µ\1/ڤ¤T¤ĎFiu2łr – ˇď!)9ĺu- ¶á÷Ĺ®łń¯߯żîC(„;tą'§¤˘´şů%xő·?CrJ*şÇ„±ńÂŻ‰ă *䢄Ca´öŤăękżGrJ*zÇ ‡ńžŰQ]’‡É•ŰP×Ö‡ěĽBúşˇŁ#$&%Ńß!˝úŰź!99}“§p:˘ŻÝ14ä”\xîúÚTůĄâč(¶‡ŽËnxw#®Ś.žC0Ľîsü>5r(D{8ž“‹¦îü^¤§gŔa·ÇĄ¤¦˘¤*V>IÉ)ž]…Ď€YŻV.ġËx8–™…˘ňZś,(Ćź¸zŁ c§nŁëâńÜ´v™Ž=ßčÂix<>ş ZzG‘ť“ß˙üôűđz\HKIÁÁÖeF›IFmS;ŽçÓÇ6u#7//üę§tůyť¸ť8ŘąŚ”¤dôŽÎŕ?>ţ|ç‡?Ĺ—żűsT5¶_Ó¸ťv‘vËľpÚ!{ĺrXPZʲuöŹËN:í&”—łlld‰}¦-ć˛Ď‹U‘iu1f ¦3Fŕň öČ^h„O1Q[ 0}壚ý|l #ßţÄŤÍ­,ź§BcK1ĘFůPŇ_^Ë×¶´µł|˛­,ßÍĺĎÍ::;»-ŔĄLş{z‰˝€Ljik9K—DżŠ1jŹ=BÓpé%µ´5S#qk)!†FĆX:L€‘ŃqRŻÉ#™N~€±ńIRëqč?­t“SÓ,íH-w}@čÎLĎÜXźŞE;™#™J´Ťąy¶ŽĺŁ´7Fµ=˝ýPéL´8·›uímăń?DűçÖöéç€Ĺé *ČyöĄ×ŔLŻĽň"¦ÇFń§¤g_xCCä±wô1 N-Ŕa¦6A4Úŕ…©;4¨%q•^#ŢĹÄô Q©(6MlNĄďbbjšŘÇE+ŮĂŘäQqµŇ=ŚŽOA¬d±±IbĹťl#Ł,v€á‘1b˝L€ÁáQbő˝\€ÁˇHĎa‹004D2…$3*Ĺčí ‚NY’ążQ-Ą>TdlţdTËĐŐÝMlriŇČŃŮŐĎ:»µţÍZÚ;: fl„fÖ*ŃÖŃNlŽfŃ)ŃŇÖFl†iŃ«ĐŇÚJ0«AŤĆćf蛲Y j455Ćž+źŐ¨FCCsśŁ¨ohb1-ęęHÇcҢ¶ŽĹĚ:ÔÔÔ{9ŘÍzÔÔÔĚaÖŁŞ¦6ÎáUVU“‹•ÚµŰę`±ň bĄ1—ÍŚ˛˛ň8VZZFěH~h3ُ´ŚŘąüĐnAqq 쌠âĐnAQq ±ëąŰaŁ‚ĆŽén‡ …EED>ŹÓŽü‚B8ÝlV@ě¶îq9—źOěĘî9t"//—ŘÜĐ{čDnn.±Ł»×íÄÉ“ąÄ†›>·'Nć(úÜ.śČÉ!6Zôy\Č>‘ClČčóâxv6±qŁĎëĆńăÇ ć÷ş‘™uśŘ;Ĺďó 33“ŘD’‹Q}¦ĂçŹM— ĽHO;0Ä`>¤§ĄĹ±cii0X0ŕGZZ*‹šš‚ c‘Ł@)öµ‡î˘ĘĎëĂ{ýcÓí¨ ‘±©i„%&ß?…BGHä“,!ÇGůýSúČź\‹-ŚëĎ#%@Kť/uŤŘu[jËń˝‚/~ăűřň׿…ţ©%Úq…B‘ç`=[Rő­]VÁ#¤¤$]łü,5-%ţ}¤¦"pÄ|o~c˝#î÷ëEú±t:ř®Q_üddܸ®ů˝n|ó“†ŢhÂ왿Áŕě2g}ć¬÷\í«q´7®vÉnżĂťŤxŰ:µ:Üw~řS|íűĎ ®µ“۸ČĎĎ'í‡}á˛CÜöʊ¢b"§ýă°“\ö”ËîrŮg§Ő„Џ 'ŢŢsů.˙a7ëP[SGěÄ司ü—łŐhhl†áţňZ~•Z@‘ŹĂOsůsłN‰¶vŇďsé“FÎÎNBGpé ŁZ†îîn–V‘Ffő04 —Ή,wÍÖH}„v4(ÄĽˇÓË…&‡®ăŇ\:ńš“Í8ô)—ŽŐ©Ą˛™«Ú©E»ś!5°A!DO˙P¤ó9Ś0Źú^¸ş¶żxň‡ř·Ź ĚôçÖöéç› |Ő‹ŻĆđüsżů“.419ÇŢóˇűŃŃÝ‹ĘJĘhD]©E§B[{ő‘TÚq[#=ŔčرKŻF˛ŹŃńq;ŔČř±ëŻFz€áŃ1"ú×H%V&Äŕđ0ŃĂ • 188D4"ťBţ!˘wB§ˇżXRݎ݀h”zĄ}}ý3D/łA"A Ó"Ć€m ¨9»$ëěę&–¸4©ĺhďě‚ĆČ48 ´µw@k"—–¶v˘·Č˘ŁFWâXK+±,§E1¦ŇŔ66’‰Ő A}C#aÄ­ ęab1v>›Q‹Úú"ł›t¨®«ŮJ:ž˙ÍŢťÇ7Q­}˙•tZvhKŮJŔĘľŻ*p‘UDdPvP”U@Żr]U\PĽ úşA\ą®,J *ČÖ–hKÓBÓĽ”„Éd’Ě$3É$ů}?V’™É™“IÚś'ç9ç4ĺfˇ¨ćJn¶u–˛›Ű.˘~}ŰŢ•ĽKËf |0ć]ľşµëÚ|¨ć_ÎA»Ú˛ŐÂm>Ż”}™gĚ\F\­8ŃüeÄÖŠłé5ązĺ2bâbmWó.#&Öv[áŤĆFAˇQ´-Ćö¸‚<Ô¬QFŰĆKő5lCĆ«ů¨^­:®Ů6ŞV«ŽB›m¨R­ŚE¶ÁL媢mĆ«¨Tą*ŠŠ…Ű Q©rŰmE…¨T±2Šă®Q1ş’ĶŠ6S3_/.*kt^·ÝuË-¸výfŁłäZ1*DE‰¶]Ců¨ ¸.ÜvcOá4Çe ęH»m‘‘(Ś/±Lms\I """lŽűâĂ­ĘŮwď{_Ůq&ÂĂÂaL]j*˝ôÜlŚ—––Ţpnn3—šË&u1‹śrĺDk)”ýýu¶Ľ‚cöŹźŁsËĆ(VK—ŻDLťDÔOjä°Î¦Žđą™L%e=[Âkj*ADx„Ýu_SGŻ‘śm%ׯˇ|Ńű@âýr˝¸Ř: ÂÍmŇďżččh4iX‡ľŰ‹Ż÷˙îči÷~..2˘REń¶BTŞTĹőďLáUT®ZŐĺď ôďo>®ć_ĆŹË¦ą®“Śú‰)¨^Ý682䡆čď†ä߉żCWó® &6Ćĺß0G˙Ä'Ąţž\ą„řřx›ż»RźĄ¶Iţ˝żtńĆřśۤ??$>g¤>Źr2Ń )Éösëâ$&§¸üĚ“ Žä~®^Ę*ëMĘ}v7n$ú<Ď<[o}îKµÎźÁ­Ml·ĺś;ŤŰD퍋çNŁéŤ±˛ÖmgOˇY‹6íGíń—¶Rm$ÉöŐ?'ŃZÔËĽ±Mx\Yζ]'Őţ“j'žż0 Ű“çţNGÇNťEmQ‰ö©T;V˛˝ű;:w˝Ă¦ëü© ´mۧ3so|ădĆ•ś h„‹— đíîO°ćůĄSłmŻ÷ň:·nZäüp$Ă­Bĺ7efÓÝ|9ű6l¬Ků°|'yęÚ¶ď`óF;÷g::vędłđůżŇË‚áíďt´kßŃć±çOe ];Űň.śĘ@ŰvímŢôN•)Âąď3O—-¨%üeËüç$Z¶jcóK™uć$Z´hc3›Eö™?ŃĽEkѶżĐĽE+—Ű.ž=…fÍ›ŰĚ×ńÜ)4iÖĚö[–ó§p[“f6ó˙çś?ŤŰš4mű©·Ýfłž@Îů3e)Ôr.śÁ­·¦ŠţĐťEŁĆŤmÖ,ČÍ<‡†Ťě˙p¦4lhłŢÁĺ¬seŘ/eťCrJ . R».gźGRrŠÍ7a—łĎ#1)Ůf•íË/ 11ÉfŰ•śL$4h€\Az•ś¬˛a’“…ú˘můąŮei ˘oôęÔ©‡ËÎ{\ ®ä >^ôMâ•ÜŞ˘o!í¶]B\|-Ű´°+—S«–͇yaŢeÔ´ \.ßh0¶ŐŚuÝŘPĚ4E…ů¨Z­ Ť×Ű PUf/LĺĘU`,$ĆBTŞ\Ův[Q!*U¬ٰ¦ČJ+Ún“ f®á–[n±ď™‰şĹ6ŤÓ˘ŤSA#öZ1*T¨€kÂĆîµb”Ż`űmľéz1"#ËŰô®_C¤¨wŔTr ‘6= Ą%%Źw˝ÍT‚°đp›é¤Í¦„Š·•–"4̓ɶ×Ä`0Řô†Íf ĺl·áFŹ‹(š ›ŽýcĄÎa6›qćď¸ZP€Ä†© —®łÔs“¸R×Jîu–zŤ$_K©×üZ1Ę‹Ţ/eAOŃűĘţ˝&~Ož=ý'`6#1ą‘ÍűůZ±•˘+şţ](*DĄJ•]ţnŻ˘r•*˘ßËT©bűű[TX€ŞŐŞÚüžKý=Ü&ôÜčé± zjĆţ^9ř»&Ţ–w1q¶AOá•K­%îý±˙+ő·XúďxjÇŰ÷Ő®]×ćsA˛GHâ3EęłçJNVŮÄ06ź[öźeRźyr?/%?kłÎ!Yô9-ĺfžCĂĆŤlŇď¤ÚRm†śógz[ި˝!Ő‘j«ś* Žíś‹çNÝŽí!‰6’Üö•TŰLŞ —ůĎI´j%j˙ť>‰VmÚâL¦ó¶ŁTóüße ŞÚ´OĄÚ¬GűŽťlÚ¶çţLGÇÎťlz¬.üťÖmÚ៬e€/eźG¤$kĐ˝çóʰń•çĚÚŢ–\äü’ńŹË=1jüôčsŹÍ¶ÜČąłäÝÝřźËŐP‰‚fÜřďƆ˛…µ…ßSĄ}˛omxŵӏćÉuʦŢňźlí⩚ź(%¶éá•¶˝Ţ…0źH?ęëzQÚąă·;mú8ő—íĐ›¤”T'‹yÁŚŮ ?&$$Ó¦?!ąO2ČŮ·7MńIU×;zřş DDDDďdĆ1ŮÇşŠWö䌝8M~Ť”ŮlVô GDDDDľç4]ŤcuČŰ’RRmî‹?‹’RRůůDDDN•óuÄN¤µţqDDD+77cÇOBnn®ëEü6Č)..¶Y›{p‚‡ŃX„ “¦`ßľo1aŇ Ëá·ANj“–8tčG_WĽ„Qp0™LxlúLüúëo€_ý ŹMź “É$» YSHËIŕ‡©EřąĂĎ"˘ŕňô’eŘ˝{ŹÍ¶Ý»÷ŕé%˰x‘Ľ©¦eŻ“ST⸋(24Rn1DDD.YĆâ0Ŕ!" >‹-Ě8âVşš'AMRJ*>ýôsŚ; 7ĹÄI“­]O˙} ŁÇN@ÓćmĐ®C,_± ׯ_;ö;î9ý B—ۻ۔ůëo‡1hđp´ëĐ]nďŽw·ľ lúßŐ˙y;Ý&ÍZˇU›ضÍýU‰Č{Ä“É%»'GM«ţý"ćĎ{S§<ŚaĂGáŘď qن;~:węők_EvöEŚ|` """0qÂXŚ7ÓꆎCîp3•áĘ•<Ś7óç=÷ÜŤôŚ ¸g0Z´hŽॗ×ŕóO?Bbb\˝zUń %""ňöč‘;9ÂËmgilŽLťňşÝy»uv´ĽĽ<üôÓĎ8}úLŮ2 aaa¨U+C߇-+†)ÉČËËÇ {ď±+kď×űPTTŚ:µăńăO?bcc±˙űčŐ«' ¶ľż C¤DDEE)®/ůžÔTŇ ~HŠ˘ ÇĐD†FÚ7ÎR ÄBµâjĘ•»™-—•ť ¨^˝şu[ŤŐ‘••ŤsçĎŁrĺJ µŻ®eŢě··lµnkÖ´ âjĹ!..›__ʵk7 ßÝ÷"!ˇ>žYş­Z¶ńl‰ČÄź–ű hŰľ˝iŞ•ĄZşš§>5kÔ\Ľx111€¬¬,Ô¬Y·Ür ňňňa2™`0péŇ%ëăj׎GII –.Yččh»r;´o‡íŰ!??ËW¬Â#ŹNÇ÷ßî±;Ž|#$$DŐňÜšxŔť5WZ¶lzőęâŐ×ÖŁ¤¤çÎťÇ{ďmÇŔ{ c‡ö¸~ý:>Üő1ňóó1kö<ëănďÚµkÇcţ‚EČÉÉ…ŮlFff&Nť:Ťóç/ŕŔpíÚ5DEEˇNťÚŞ×›ÔzżOź^ÖŰńńµđĘË«%·ăżď{R]"""""ň3nĄ«é""""" ( r( 0Č!""""˘€Â ‡ """"" (^rľýî{,_± Ćţmö]¸‰©Ź<†Öm;!µIK 6‡Ź”M1˝műŃŞMôí7Đć1}ü ’RR‘žžaÝ–”’j÷öŘL´mß·5m…‘ŚÁ™łg5~ĆDDDDDäM˛Öɱ ÎČ]Kg׮ʑśś„ŁGʎ´´Ôfß#Ó¦cŘĐÁXýâó¸ví:ţóŇ+úČcřzĎ—Xőü xbÎ,ôď×Çz|ff&ž[őoÉó|¸cŞU«fł­¨¨mÚ´ÂŇ% †©Ź<†yóžÂ›ol”Uw""ň9ź;@Íučč&Ů=9E%E”Xąb&Ś+ąďđá#¸˝k ”/‰>}z!??““‹¸¸XDFFĚf3ćĚ}“ž$YVÍš5cý€ęŐ«aäᎎ¶–č?*Ş?é›[éj‘ˇ‘j×pűí]0fě>r—.]²e+0cúcčzGŔÄIS°ćµu€wŢŮ :ä>ɲüÁe*Zff&*W®¤â3 ""5™Íć€ü!""méjâĺË–ŕÜůóxďÜ~gOtíÚ#î†}{Óë×˝Š‡šż˙>…WÖ¬ĂňeKbWÎí]»ŕťwßCď>wăÁŃă‘››kwL~~>¶ĽóĆŽyPóçEDDDDDŢŁ(ȉ Ť´öâo«eĹĘçŃŞe ¬yő?¨^˝^zy ľůć;›cL&fΞ‹™3ł¦ˇ‰mÜđŢÝňöíMCNNžZ´Äfqq1¦L} ť:¶Ç¸±ŁU}DDDDDä[˛&°°Śż‰ Ť´‹ăl¨ś•gΞĹövŕ›Żw#..ť;u”G¦aŃÓK±űËO­ÇĄ§gŕ—_~Ĺ/żüŠŮsćY·÷éwćĎ›1ٰn«RĄ FŚŽeĎ®´n3™LöřLÔ­[O/~ ĺĘéŞ3‹<¤(ČqĆÓb23łŔ:F¦|ůH t/fĚzÂ渔”düöË!›mM›·ÁŰ·âÖĆŤěĘ-))AhčͧůÜŞpůŇeĽňŇ‹ p[­|Ą3ŞÉŃ0%+Fă?/˝Šk×®áň•+xoŰvÜ޵‹Íq*T°ů€ň‘‘ ś8qfłgÎśÁ›onAď^wާ§că¦Í2ä>dg_Ä… ™¸p!SőçBDDÚ ±ů‘ÚODDÁMvOŽZăozôěcíµ™0q2 ţ[·^߸K—­@ËÖîÝďÄĽąsźăŃă‘——‡čč[Đ·OoĚţŕŹßŹĂl6ۤą\§€Č[’VŢLm>1Űýż˝ÂĘBBB¬÷Ő p„呑䨤}ń‰Ă}Íš5Ŷ÷¶(®xß÷ßî‘ĺ–Ő­ŰčÖíŹĘ ""˙ĆżóDDä ÝL!MDDDDD¤9DDDDDPäQ@aCDDDDD…A9DDDDDPÜZ ÔI)©6÷ĂÂÂĐĽYS,^´))ÉÖíß~÷=ľýö{ě?pOĚ™‰íŰy»ŞDDDDDä‡d9âŔDŠ’5 ž_µýúöFII Nť:ŤYsćaćěąŘµs»ő]»>FrrŽ=†ŇŇRŮeQp“ť®VTRäđG)ˇ """’’Ś!ářńt›cV®X† ăÇ*.›‚›[cr"C#U­DNN.jÖ¬ˇj™DDDDDśĽ>&L¦R”””Ŕh4b˙xăÍ·0cúcľ¨ EAްÇrŰťtµ3ç`ĆĚ9Öű‹-ŔýÇ*.‡HLQc h"C#í‚g“'%xń…çĐŻoL& :ź}ö†‚rĺ8Ł5‘š’RRN$üě¶#ţŽUĎżcÇ~W­\"""’Ź ŮANdh¤ĂO=0jZµjǧςŃX@őčŮMšµL8MšµĆéÓ˙x|.""""" l˛ŇŐÔüvGެrĺĘaË[›m¶Ą}ń‰jç$""""˘ŕÁ‘ţDDDDDPäQ@aCDDDN—‚ "ň7ŞM!MDDDú$µöŤeŞhá6á±–9ëů#9DDDĚY"µŹA ¦«Q@ńzOޏË<,, Í›5ĹâE ’’ (((Ŕü'a˙(,,DóćM±üŮĄ¨ďíꑟ‘äČڍ¤{űůU+ĐŻoo”””ŕÔ©Ó5gfΞ‹];·ŠŠŠŃ¦M+,]˛ˇˇaúČc7ď)ĽůĆFŮç "ő%Ą¤Úý®Kĺô‹÷Iý}–%ő7FjÓhHŮ=9E%E÷E†F*:©ÁP))É2xž^˛Ěşżzőj9b¸ő~ź>˝đä‚EŠÎA¤wžĚdäíYÄ”…őâŔEę¶łsČ-źł@y—ż\oÁDDdáÖĄAŤ+99ą¨Ył†Ăý™™™¨\ą’Şç$"ůä)Î8ëý!"""R›O&0™JQRR‚üü||ńeŢxó-<üĐDÉcóóó±ĺť÷0vĚ^®%Y¨ů ął€))%•éiDDDä1E{p,·ťĄ±92cćĚ9Çzń˘¸řP»ăŠ‹‹1eęcčÔ±=ĆŤ­řŽĺ+Vˇc‡ö¸őÖĆ8žžŽŤ›6cĹňgť}ŃzlllŚjç%Ň+9é7ľ]MíräĚľćl;yŹŢ®7^""rEvŁöŚjBŚ/Óvăńéł°sÇvüńűqÍfĚž3Ďć8~°ů†¸÷€MZš…»żŁÎĘ7°ůw€\‘ä¨Ů¨*«\ąrŘňÖfëýúcŔ€ţŞť“ÔçhÝWÇČŮďěqzëU """ýQmL©ĎQŹ{3Hkz{ż1¸%""%8˘źl$Ą¤âă˙űÄáţď÷ŔqѢU{$7Ľ ­ÚtŔ}CîÇ7ß|gS†ĺ§a㦸ăΞxjáÓČĚĚ”]ŹożűËW¬Â€±˙ŔA›}EEExbî“hÚĽ :vľŰ?Ř!ąŹ‚{rH¶ť;waÖśy4q–<˝Ő«UĂŮsçńÇbsěó«V Oď»pőęU>|Ď®xĆÎ˙n“5™Đ®]#99 GŹCii©ÍľUĎżôô |»ď+ü}ę†ß˙ęŐ«‹6­[Ůě#˘ŕÄž"""’Ĺh4bń’e9b8fÎxµăă‰Ä >l:wîhsĽÁPaaa¨\ą2şté„77oDqń5Ľôň«˛Î·rĹ2L?Ön{QQ¶ľ· ?<+FŁi“ŰĐë®á­·ß±ŰGDÁ‰AQJOĎŔČĆ wßčŘé$Ą¤âË´ÝNsđ‡CČĎĎÇСÝ:gőęŐpWĎŘ÷Í·n=ŢâŹ?ŽŁ¨¨Íš5µnkÚ´ ~ţůÉ}D|䙢˘"Ś;Ý?ţ߇řţ»˝ŽvÝëqćĚY@Býznź;!!™™Yn?˛˛łŐŞVµn«Zµ*˛˛˛%÷Qđá""˘¶oošÍý1ņők••…aĂ”őČÍf›ÝQZjBxx¸ŰŹC9[ű(x0Č!"" pc&>qâ$šÜćŢ´Ţţů7’’Ýz¬EőŐąą—PăĆíK—.ˇfÍ’ű(ř0]Ť(śĚ8†“Ç•*UBqq1._ľ 8ţŚFŁË2ÚµmŤ *`óć7ÝęÍÉÉÉEÚîŻĐ·O/ĹŹjÔ0ĺË—ÇŻżţfÝvřđQ´hŃ\r9DDDA¦]ŰÖŔš×Ö#==Ź=>‚›S@›LĄ0™L6?QQQ7w6>Üő1ć<1ÇŽýŽK—.!==k×mć»>¶9ŹĄŚ‚‚|űÝ÷xpô84h€FŤđ¨ţ¸řP¬ym pěŘďřěóĎ1jäývű(81Č!"" 2UŞTÁŇ% ńîÖ÷qßű1bÄpDDD ""ÂzĚŚ™sаqSëO“f­ÆĆş×^Á™łç0tř(´iף‹#GŹ˘qن6籔ѪMG,ZĽ=ztĂŰoľnsgzôěc=“ѤYkś>ý`úăŹ"%%ť»vÇř ă©óѦu+»}Dś8&‡dIJq/˙ŢŰN¤•Üî/ősô|<5𞸻?ŔŐ«…(,,DLLM®ßwÝşÝnÝîpzŚś÷®%€‘˛~í«Hűâ‡ű#""đě˛%xvŮEű(80Č!˘€b4íSËk@Lާ§#?żMnK…ŃhÄň«P·nŹ'PęđŻ˙óęů(x0]Ť1›ÍşüéŃŁ`ďŢ}vu¶lëŃŁ‡Ďë)÷‡HKyWň°hŃ´nŰ ÝzôÂĹ‹9ذ~ Ę•cł€{r( <üđĂHKKĂĽ'"ż =şw¤íţ Ď._e=†€6mZăăŹvřşDDšaCDaŕŔ0aÖŻ_ŹyóbŢü…6ű'L€ú¨vDęQ:ľlÓşŐ€ ?˝ĄEuÜ2ľĺ(MËgż4„¬[·iiičŰ·/jÔ¨5j oßľHKKĂşuëâş """ň{ěÉ!˘€Ň˝{wtďÎic‰‚""•…„„HN Ő“ÄIH)ĄÓŠďŰ›¦QMô‹A‘4RÄÇą“>—´ňćxŚłą†‘ŽÉ!"ň%Á‘#€‡nbOqŠ0Řîłl·$–}ÂíÂ]•Ł…¤•©v=:Jgßry•Ëó”Łú(­§Ň´/""ňěÉ!˘ $\xS¬Hmď5R x:*GX–;¤RÔŘŁCDDd‹=9DAßx+' JĽ=Y€ś †ŃM rĽHŤ±8®¨” a=ąŽęŁ´žzK˝#çÖ>·0iÖ$MnQŕbCDAI‹13Ţ`Č59DAHßĚűšT0"?#'`‘ٍDŮM, ‘šĆé¤) {[´¸MD‹A‘€ŁŕGÉcśŻĹ´Ń p‚‹Ň”»MëVkTĎč!ťLuTZ_[¦&’+ś]ŤČŹ1Ŕ!""˛Çž"ň{JÇÂʸ8äĎôN¦‡:*­Ż-SÉ9DANţ¤‡FłŇ€E¸P§^‚guńt¬Ž^#ň-ĄcęöíMÓ¨&ĘůcúżÔYëô-µĘ÷¤>jť‹)sÁéjDdĺok­ ©E7˝U%Ç:[$Tޤ•©Ö"""’Ŕ,ţVhßŢ4Śť8Ť30QĐKLľ'3ŽiR¶Ňu?´Z·Dî@vËůĄzÄŤuWłŚ {_ÄŰÝ)GxŚ·{s¤Îé¨Jęgyľâ×ZüziŐł ëäčáyyĂľ˝i3áQĚ}o®Ż«BDd5ľĺ(ëíť;>ŔŚŮ µą,ńĘőë×pęŻ ›}I)©LW# v'fµk8'­LUÜx– 6ś!R·ťĄť©̨”i=…´3RŻ•Ú ^újÍ` B‘iEzH Ň[’ŻRĹ´ ´ţZźKi9Z§*­ZuÖĂűÜ] r‚śT'­Çęţr‚µSŃ|”©1&GŤ ”(1]ŤČ‰@MWS:žăÄěŁ.ÓŐ” ®ć»J˙’”8ăő¦«)łAŮázĄĹďÓŐôéjDä´HĎr@ĎŁÇŮŐ|MŤĆ»Ż‚_ĄĆ‘çÔš)K‹t­Óoô°€©Öĺh}Ý•ď/©SZĎަô\J·Ë©žŻż9DAČn ‡ĚÉśq”˛Ą4ř‘ű"Ţć(ĐQÂ[AyÓŐśÔt5›z¨4»š?5î•®căęůy:Kśł2Ą^k5‚RWôĐ“Ăt5u0]ŤôéjDäUÁ>€ÝŐ$răěxOAo8¤oJSú6­[­QM^Hî„ReJ˝ÖRékîŽÉŃŰâłLWSÎŐď.ÓŐHŹ®FD^q2ý¨ß­“ŁW“ČyŚłăŐ\'Ç‚“”Qšz篩zrŢAÂßĺ}ëV»už`HQó÷&o¦™é5%ÉÁ6Ăž?>G5”óuH?ÜMsń§^ś@ÇČÓŐś¦t5WśĄ«ů’ckô@Îb j8z{ży’®,”ľË__·šéjD¤;LW#"M©Ýhö”’ń=žN%­9őp·®zxŤôDićë/ ÔpRtßĺÄ!{ÓÜ:ÓŐ´Ł·Ĺ1-]MČSą®&ÓŐČJńz,äő)­“V¦ZÔ‘(1]ŤČ‰`HW“;ÝŐějB®f.˛)Ţ®¤©zx»'GÎb RŹÜ›]MüzyÚłăďéjj•ďŻÄAŽT€ĂŮŐHŹ®FDš:1ű¨]Ă9ieŞâĆłTÚłt2©ŰRŹqVľŇ47ge‹·» ʤ‚GA™¸,OI˝VîŽSqô8GŰ!H$j÷ŕCşšŻčˇBLWóŻT.µŐC}´Ä ‡(ÉIuŇz¬Ž°á/'8q¸Óăë Ě]jĄšFD$ŤéjDNjşšŇń'fU´¨« ÁŐbś®zirůŞľJę-LWS<ţf˛ĂÝĄĹgÓŐ”‘óeÓŐHŹ®FD~A‹©śÎöëť7ꯤńÎ)›‡=zjĄÁčí¶žéˇžLWcşšŻęŁ%9DAČn ‡ĚÉśq”˛Ą4ř‘ű"Ţ&\ŐCŠ·‚2!=NwM…©‹DDe®FäD ¦«ŮśOĄŮŐü©Áî*ýĚBij™śYâäÔAX†Ôk­FPj-Ëž¦«é«÷ÓŐHŹ®FD^ěß»šD@ÎcäöXąCÍÇ_©•2ç·©wă]"|źlj»ZvŃLWó>_ĄŠi±`¨´~M™®ćŰúh‰‹‘•»ŤeęĹ 4ÁŕÉÁt5"'‚!]M.géjľ"5­´žęç 9‹ŞŕřcşZГѓ#´©íj¦«‘î0]Ť4Ąőz8J)ßălć5_rôÔĘôđů‚Z•Żż,Đ‚ś19r©•vÂ5ůô®¦ĹńZĐúý©=ÔŮßSţÜĹ ‡¬üyf&_M~ŕí LoA)ůÇhIcş‘Á®¦ÖějBâ©’ĹŰ…‹cŠ·+)G¸ĎWijr•ű8ń~ŔyşŕyÖ_ŇŐüĄ|o“ó~ŕějD¤GLW#"Mť}Ô®ˇäNŹŽÔ0↼đľÔm©Ç8+ßr[ĽÍµ2ńvGĺHŐßSRŻ•»ăW=NévĄ!ŘĐ5zpô®ćIůţČ›éjtÍý%­Q‹×ÎWupT¦ŢRä!©ŢgÇh‘ţ"läËiđ;JírwM Ę„Ô J)0đu'"’Ćt5"'5]MN#tböQE‹ş \-ĆéŞçĂŮŔ~ą“Ţë+LWSúza˛Ă}-ŇáĽMΗLW#"=bşůgéYž”él°ľ/Çâč™’Ć»ŻĆäpJhő©ŃŁç«4˝¦»xéjZ¤ińőrO0¤«é˘ d7†C…šĄl) ~¤Ćľ·IÝ–[ľ…·‚2%ű‰<ĹÔE"˘2 r‚śÖSĐşŻâÎc”ŽçQr5‚2@:r7(Ó"(ĄŔ ö-o~++<—žż Öšśç®ôú8ş¶ž\gľ^îQëZ©őÚ©ĹŢ rČF°7–ŐĘśďiOŽ/­gWÓş|ĄçŐ˝ń®ľO6µ]-»h¦«yźŇt5_ÍĚŻ‘'ô®¦˝ŐGJ9_W€ôĂÝĆ2S°|'ŘR""")ěÉ! rŇHvwúh(ŻéÓŐĽOişšŇŰj ć×ČzHWÓ‚Ţę#…AQÓz=Ąapľś©ˇ÷‚-o˝FŽfNÓbv5N!íW)Śűö¦É.ËW)(ţú˘•`~îDZbşY)^ŹE'-Ş·s OB WŇĘTë'ˇ "’Ćž"˛áÎĚLâĆş«YĆ„‹lŠ· ˙uUŽTYÁ„Ó“§ď_ő&s/F0?w"-1Č! rjMAë(đÚîč¶Ôcś•ď._eZ¤áI˝VîΦôqţ2»Z ¤Ąą˘FŔ«‡Ô)oΦúĽ|ŤAQ’“ę¤őXĄkÝHőÔxěř:(s·îjŻ‹BţŤŻ;‘49D¤{RÁ‡ŁŰZMZ Ć¤Jë©4(Ąŕˇö—zčMđćŚaz¨Ď‹Č×ä‘*<ť5ĚQ™R= Rçń—YŮĽQO%éYJgó—ŮŐüvˇO¨Ý٧ç4*9ilzN{ÓC˘ d7†C…šĄl) ~¤Ćľ·©1É€·‚2%ű‰<ĹÔE"˘2 r‚śÖSĐşŻâÎcÜ)Sî9ÔĘç=N®ę!¦EPJAË1Zzîe“Ʀç´7=Ô(Đ1Č!"ÁŢXV#(stĽ˝8z pDDnßr”őöÎ`ĆěŠÚ\–xĺúők8őW†Íľ¤”T¦«;­×ĂQJéŕ|=5ZN@ ‡×ȵ‚%=Ďަ'®R÷íMs«\_§š8Ł4UFoé4ľJ‹RëůjQoľ.jĄ„yň˝Y7o¦Ŕ)­–®FDV\kE9Ą3˝y:3\ŇĘTë‘^ÇhůÓŐś†t5ąŤ$géjÎf “šeĚŇ“!ž•L­rĽÉŃZ>Ž®“Ąľ®ę*'] đĽA«Eş{rĽGÎűaßŢ4¦«‘î0]Ť4ĄÖ´R sŠóÂűR·ťJĘqEí LîŇZaRŻ•»ăc”>N­YËü}v5˝KZöŕč-uM‹t5_ĄHÉ9^­T4-ŇŐ´(Gë×ĹW×Ó›çŐúý ĹsW›Ă GŹyîD¤9©NZŹŐqµîŤÚ“ ř*(ó”–ë˘˙áëND$M2]-1ůVßÔF'¸*ąű‚ĺÚi™ÂćŤ4Ąă9NĚ>ę2]MIĐŕě}"'ýËU:+ľ®ŻŇt5Ĺăo6(;ś<Ł—žG®FDzäłt5oŹCĐ á,4Áz ÜĹkܤҳÔ(S*€p¶ź”5ş9&ÇóňŤR×ü%]Í›é@Ţ,SëYÚ´8—Ň2µ¨›ŢRŃ}v5ŽÉ! Bvc8TˇÉQĘ–ŇŕGjě‹x›Ômąĺ[x+(#"""ďs®¬ßÄ[şľĚfsĐ^wńÚ©Ă_gWó§Ć˝«ô3 ąČť%Nɸ"Gł«ęNĚžuË×#¦«‘qv5"ňŞ`Čěj9ŹqtĽ ×E!Ą©r›Ö­VőüLWsŻžŢ|¬ÖőńfÝ´8ŻZifZĽÇÔZDUëĹXő0cˇ+\ ”¬Üm,űS/N a€CDDdŹéj"LąrŻť:ôşˇłt5_ó·t99ä,ŞF€Ăt5uË÷wzr®FDză÷éjĹĹĹ CąröťFÎöyăüŢâëkŕÎ9 qęÔi4nÜČkő’âεsVw=ĽôNëőq\Q°Č™ćŮŰäŚáq·®ěą!ĄA•pćKµů*EĎéjz+G­ňőP=§«i}.9Ç{ó5őćëĺ.·Zzk^[‡¤”TüvřËcS›´ÄˇC?*ާ­ÎáO×Ŕťs>|ý ŇäüZ_;aÝú?4mr›őŇ5^÷yűÚ5jÔolćĘrxŇhv4›xźx¶2Gł’‰·;*ÇßHež<—¤•©ěŮ!źňŐ7´Âójq[­şéˇµĘ×C}|umŻEť=9Ţ›Ż©7_/w)rŽűgϞãFŕă˙űOĚ™ Á EÝt‹×Ŕ}Ţľv•*UD§Ž4+ßW<]ĐŮ8ë1¬“ă(…Lx_ę¶Ł†żłrÜHA™T ăîűCéăď«rôVľ#zźrÚ]ŢLMŃ[şšÖłŤy2»—ZuÖĂloLWs~ĽŻŇŐĽ93žŠÓŐ>Üő1zţ«;Fچěě‹8pđ›ýÇŽýŽűGŽF˙Đĺöî˛÷‰%Ą¤âÓO?Çč±аqSLś4&“ đ÷ß§0zě4mŢí:tÁň«pýúu—çřő·Ă4x8Úuč‚.·wÇ»[ßWúô˝~ >řďNôĽ«š4kŤw·ľŹożű­ŰvB«6đŮg_XŹu÷š$Ą¤âŕÁCď[ř۵ł§«ŔéÓ§ŃŻ˙@¤6i‰…‹—˘´´@Ůs߸i3ÚwěŠ}űľĹ›omA÷őĆmM[ˇ}Ç®ŘţÁ·žł Sžőŕhť%lřË BBB¬?jť_XYÎ!µ]ĽOj±R©i¤ĄĘń”äFL]#""˛ˇ¨'Çd2áăŹ?Áňg—˘ABš5m‚]»>¶~S~őęUŚ7ÓꆎCîpó.gűYőď1Ţ:ĺa > Ç~˙Ť5ÄŘń“ĐąSG¬_ű*˛ł/bäc‰Ć:<Ç•+y;n"ćĎ{ďąépĎ`´hŃŤ¦čöĽýö;xéĄăóϿIJgW çżzŕĂŰđď˙5kףWŻž())qëšČĺŻ×ΑW^]‹ĄKĆŤ­[µD˙~}Ű?ŘµŻ˝‚Ä 0„đŢ»oŁZµŞX»n#–/÷ čÖ9ÉsľNQS”©INĂ@'8ůz˘!o~C«·t5-ž»śşyň\ô®ć«:0]ͽ㕞W‹tP%9ţ€Rs):u*k”8«ž‹-@dd$ľţúäĺĺcĐ˝÷Ř=ÖŮ>G¦NyÝîĽÝúM{^^~úégś>ý¦l™„°°0ÔŞ‡!ďĂ–wŢEĂ”d‡çŘűő>ŁNíxüřÓĎ€ŘŘXě˙ţ€˘†ş·ŻÁäÉ“Đ0%ŮŮa4aáSO˘bĹh´lŃ?˙ü ¸}Mäň×kçČcÓ¦˘s§Ž€–-[ŕë}ßXśG§NFł¦MŔ|ŤEhĐ >._ąâńą=ˇfŠ‹ b-ŇłĄĄIĄ·éiv5_Sň^áŇę–/çx­čiŚ–ŻŇT´NQÓĂóň䵎÷fڞϫĹ5÷Çt5­Ďĺ.EA·~„‹sаqS›í{żţ˝îúÎť?ŹĘ•+!4ÔľXgű©W l¦űÍĘÎTŻ^Ýş­FŤęČĘĘvzŽÜÜ\ŔŰ[¶Z·5kÚqµâd×đţ5¨]ŔÍdĹŠŃ6÷÷݉\ţz퉋»Yďš5j OĽT­ZŐz{ë{۰mۨ_ż ®^őřĽzb7†Cĺ19ÂmJGé`ŽĘq7ŔńfP&<2Ň’ž""_’Ýb4‹đŮç_âăŹvŘ|{?nüCصëcôşë_¸ĺ–[——“ÉÁ€K—.YŹs¶O‰š5j.^Ľ@VVjÖ¬áôµkÇŁ¤¤K—,Dtt´[çÖË5s÷šXXZgĎž“,?Ż]nn.ęׯg·ýŹăéxrÁ"ěŮý9ęÔ©Ťa÷î=ŞśSŹNĚ>jč¨ŐXrü¨ůw‚-2ŔqĺN€ŁEPJAËß]Oř*MEë5=ůô3e<*_7ŠôB8a€p›śÇH•áNç ˙—”’ęŮŹ&q×ÚçÖZÓV´._ém_ŐYµę©ôąk}.µ^#Ą”ÖGi9žďI™z{xrĽd9~řz÷şËn– őčŽŇŇR|ţů¨[·-|KźywőęŹ{°çlꎎˇŘ°~ ţ<ů'Z´jŹ{={ŕ‘©;=Gxx8ŢÜĽ¦’tëŃ MšµĆý#GăŹăé˛Ď­—k ćî5€IÇáĹŐ/aĆĚ95sşdůví¦=>î†iÓfŕ™%‹ĐşUK»cÚµm»ű÷ŨÇaĨ1čÜą#š7o†űG<čöyý»Ťe¦]ů"""{!ĚâA“‰É·âdĆ1ßÔČZôs IDATÇöíMĂ؉Ó`6›ö¸‹×Nj ŚV›Ą^z hq|‹ĺ gk©ŕpâuË—sĽÇĆ+;|SŰŐ3áQĚ}o®zu "ňĐř–٬·wîř3f/PÔ~´´;Ż_ż†SeŘěKJIUľ(6_OI«4`Qs Ŕž˙¤ĺ®R÷íMÓěÜžĐbQNGĺűŞjQk¦8µfźÓş>ZÓb¶=µŽ÷Ő,yžĽ´¨§/JDKoůű®b‘ŁED$Ťéj"LąrŻť:|•®ćޱä,]MÜ›âj–1á4ĘâíJĘî ´`ÇQşšÚ®¦nůŢ&ţ˝• pöíMcşéÓŐ€ş9ýÎĆyXŹń`ťGkÁďKÝv4˝˛łr¨L öŕx’Ză/©hD¤ 9DAHNZšÖcs”LŃ ßŘ"91°!"R"ň ÁÜsŁ´OOłň‘¶|=QÖá6á>WŰ•Ă^"[ pʸLWó×€ °°§NťFăĆŤlnPuLޏl"59ú’ÁÓ/Äďµ×ɱ¤Ť9K'“ş-őń±R÷m# & pn’=&ÇYŁjŇÄq5sşŞóÔáĂG1bÔhśH?jsP¸}ż˙ÖoŘ„_~ů ¨X1 öČtéŇÉ®l" §×Fë±9€DNpâl‘Y8¬ŘI“Ý“sü÷߬Ű6nŠçW­@żľ˝µ«™†äöäěÜą łćĚä‰ă°äé…¨^­Ξ;Ź~8ä´ÁĄ…/ľLCóćÍPłF Żž—H/1Áŕ(íąă—.ÁĂ×…é•ěžÁ`łÝ`(g·Í_ČiŤF,^˛ #G ÇĚŹ[·'6H@b-«'iň”iŘňÖf9AŔŃűSŘĐő´«ĹZŚ•qŔ8J‡# fI+SčÝ ęějI)©Ř¸i3ÚwěŠ}űľĹ›omA÷őĆmM[ˇ}Ç®ŘţÁë±'˙ü cÇOB“f­Ú¤%FŹ™`Ý÷ëo‡1hđp´ëĐ]nďŽw·ľďđśÎÎᬞ®üáňóó1tč`—Ç 9«»łşŠŻťĐQŁcÇOÂ’ĄĎJŻöµ6›ÍXýź—ѱÓhҬZµé€mŰ>Pt-HżNĚ>jóăę9,cjÄih ä$ÂÇXŽwVŽłI‚ gH$"*Łhť9¶°k_{‰ `5ŕ˝wßFµjU±vÝF,_ţî4EEE=f<7jÝiźˇj•*8ýĎ?€+Wň0vÜDĚź÷Ţs7Ň320ŕžÁhѢ95L±;_bbÉs8#çůś9sPżžěçîŞî®ę*ĽvB[ŢÚŚ¤”TlÚ°íÚµ‘<^íkĽôň|ţéGHLl€«WŻÂh,’}-Čżś}Ô®q¤Ö·ÂRŤ«`Gîc‚Ą‡égä–ż»DDţLőŮŐť:Íš6tęŘ`4ˇAú¸|ĺ `˙8ţ‚MúU„˛†ýŢŻ÷ˇ¨¨ujÇăÇź~ÄĆĆb˙÷$GçpFNŕ&üY.WuwUWᵓCËkÝ«WO l}†Ü7II‰ŠŠ’]7ň?RŤ%˘@ Ő,…>3Ţő!«CDÁNőžśŞU«Zoo}o¶műőë×CÁŐ«ÖíŮŮŮ€řřZvŹĎÍÍĽ˝e«u[ł¦MW+Nň|ŽÎጜçČ8qMn“÷AčŞî®ę*Ľvrhy­ăâb±ůőőX»vúÝ}/ę㙥‹ŃŞe Eu$˙ân ,=*DDDä4['çŹăéxrÁ"ěŮý9ęÔ©Ťa÷î=€ŔéţABýú6Ź«];%%%Xşd!˘ŁŁÝ>‡3r·vm[ŁB… ŘĽůM¬zną¬\guw·®rhu­;´o‡íŰ!??ËW¬Â#ŹNÇ÷ߪSgŇ/~ëKDDDţNőž K/Á… †O>ý đ÷ߧС};ÔŽŹÇÂ…K°tÉ"TŞT GŹCÇíq{×.¨];ó,ÂÂóQµjdeeˇ¨¨őęŐ•}gä<ꍍ(Ě›;O.XÁ€ŃŽB\\,˛ł/bĎŢ}ŤŤÁ€»űŮ<ĆYÝťŐµľŚq?*TŔĹś‹ÖŘrŻ»×:<<§NťFË–Í…:uj»¬#IÎ'Ć^0mxc–B˝Pc1_"˘@ŁęějBíÚ¶ÁÝýűbÔă0bÔtîÜÍ›7Ăý#Dxx86mZ‹Rs)zöę‡.·wÇĆŤ›áááxsóFJJĐ­G/4iÖ÷ŹŤ?ާ+:‡3ró°‡ ŚuŻ˝‚3gĎačđQhÓ®3F=8GŽEăF íŽwVwwëj1iâ8ĚyâIěŘąKŃup÷ZaĹĘUhݶšµh‹Ď?˙«_\%«®DÁDÉŚnÂčÔ n’V¦Z(ř0Ŕ!"’Ŕ,d“oĹÉŚcÜďÉńűö¦aěÄi0›ÍÖçKĘX®a ľGôÄ×ß@[ÎĎž[r¦Ć–:ĆŐă,Á“ł×ZÜŔu§q«ô}ĺčx_•Ł”ŻŹÔ¦Ć{€Č×vîř3f/PÔ·´AŻ_ż†SeŘěKJIŐ®'GĎüvF"R…łµu¤¶[nËÝî¨5±ç†ÄŕݤŮ= ´çC¤”Ň@?gÄ ŠZĆĚHmwt[ę1âc-÷ťíWŠ)JdÁםHšfł«éY nD¤-aPâí”=9˝6\%8ńu'"’ć2]-S»ŕ‘ŻxÚ‹CäS‰n’5&ÇčÚżDÁęDúQE?H8fF­ C«ń7Dr1Đ!"*ă2] ¸Ůóh˙Qđ’ lÄkŮČ ~„ʱďhMw‰Ó8&‡,NĚ>j÷~HZ™Ę÷=‡AÎľ˝iެ‡ĎŰó%"iŽ‚µŁFŻQ 5lő®kÝëî·˝úă]±:Dě$ś`Ką¶çKDţO*Đ!""˘2’AÓą(ĘŔ:DDDŇdŤÉ!""÷‰×رP+uÍ9ú2MB¦ĹnZ—ď ŁEDdŹA‘”ĚÎćl±QwqěEpc€CD$ÍĺŇDD¤ 5"€‘{r(č'÷®·[z\ÄSE[î‹·KťCm pHŚŃMŠ‚ńt›aaahެ)/Z€””d@AAć?ąűDaa!š7oŠĺĎ.EířxőjíÂÁ‡0bÔč€É·&R›Ň©sńwI*mĚY:™Ôm©ÇʵܗşínOS”Č‚Ż;‘4ĹéjĎŻZăż˙†Ł‡‡;¶ˇĐhÄĚŮs­ű‹ŠŠŃ¦M+ěţň:ř"Â#0oŢSŞVľř2 YŮŮ’÷5j76oPýśDĽ„‰'if–ŕHÉ‚ˇI+Sm~\CÁŻ;‘4ĹAŽÁPHIIĆÁpüxşuőęŐ0rÄpDGGŁ|ůHôéÓ ‡ţ÷ŁŞ•€ÉS¦áŻ?˙–Ľ_©REtęŘAősé"˘›<““““‹š5k8Üź™™‰Ę•+Iî3›ÍřĎKŻŕ˝÷¶#ż áááxböL <đëo‡ńô’e8sć ÂĂĂ1ůáI>lFŚ ;~† Ś?Ž·ąßó_=lŇŐ’RRńŇęă˝m۱˙AÜ޵3ÖĽú ŇÓ3đôŇeČÉÉĹ•ËW•ťŤ5Żţ=şwsZ7 .‰É·NfóqMÔégJ©=•łĄĚ@Y‡üSŇĘT¦°ÁŤ Çd*EII ŚF#ö87Ţ| 3¦?&yl~~>¶ĽóĆŽyPrzF^zy >˙ô#$&6ŔŐ«Wa4®\ÉĂŘq1ŢxĎÝHĎČŔ€{ŁE‹ćŘňÖf$Ą¤bÓ†µh×® ŘÜ?xđÝąVýűEĚź÷¦NyÆŹÂ±ß˙@rR"FŹť ăĆ`Ě-ZµwY7 N'3Ž!)%•B€ FÄ)dr© Ą˘ąS>`?î‚crČBjAX:DD‚ś}{Ólđ¨őě3ç`ĆĚ9Ö}‹-ŔýÇڕQ\\Ś)SC§Ží1něhÉ“WŚ®Á€­ďoĂű!))QQQ€˝_ďCQQ1ęÔŽÇŹ?ý ŤŤĹţď QĂĹOtꔇĐíÎŰQZZ ČËËĂţ‘••…aĂ+Ş[bň­x}ý×üŹĺ˝o p(đ9 ~ÔzŚZ €ęˇaëčwB­ß­çüöwzĽëC¸~;‡=9c&vü÷}‡űăăká•—WKî›2ů!L™üĂűÂşŠë-Ľ?𞸻?ŔŐ«…(,,DLLM—uŁŕ‰HŹŞFb pĘxÜ“ăĎŽ§§#?żMnK…ŃhÄň«P·n$%%úşj¤CěÁ â´1aďŠÔĎât3áv῎Ęqt~Ozuŕ"˘›‚:ČÉ»’‡ĹO?S§˙AXX(Z¶h ë׸ś,Čß)í• ÄOX‚©íŽnK=F|¬ĺľ«2•`ŠYđu'"’ÔAN›6­ńńG;|] ňśx€„Á»=0î>NNŻ Çć'ľîDDŇś9âEA‰‚' "=óĹ‚°DDzĺ˛'gěÄiި‘®Íf›Ĺ@mâjŇcoÔ(ÓYYÉĹ@‡¨Ś¬tµMë¤g8# D]ďč!ąťA`‘ 6ÄkŮČ H¤&$p¶&Ž;Á•¸ŃĘ19d!µ ,""crŘŁCÁŔl6sÜMsü¨ő5zr´jŘŞŐ[©·r|UľfĆ»>„cu(Ř)šx€iČś7śx€ôF*Đ!""˘2ś+™H¦@—(BBB¬?rĘ6ü†žHZPO!M$W 8zKkQ28ßŮş6z"g-wyúš©5ÖLřűáI™j•ă«ň}c´ě1Č!’)PDÎřű€e_8ľ¬ô¤’w1Ŕ!"’ćqşš0U$$$čÚµ+Ž9b=&//Æ CÍš5QˇBtëÖ ˙ý·§§vjďŢ˝ŠŇWüŮ—_~‰YłfˇU«VřꫯlöŤFŚ;ŃŃŃŹŹÇ믿®é>ňîŚó˙p´O¸M¸ĎŐvGĺř+µžÇä"˘2ŞŚÉyűí·qýúuŤFüř㏸ző*xŕë~ŁŃ.]ş ##/^Ddd$ĆŹ—1=Śš5k†/żüRÖ±;věŔůóç5­Ź–¶lŮ‚š5kâ§ź~Bii©ÍľąsçâČ‘#řçź°sçNLž<ß|óŤfűUbň­ÖÉŤTŁČťĆłŮl¶ţ©íâ}RS0‹{Gś•Ł4řńeP¦VĎc€CDt“*éjˇˇˇ Ĺm·Ý†ńăÇă‘G±îʉ‰Á”)S¬÷‡ ‚I“&©qj‡ŞT©‚=¤×;»÷Ţ{±gĎÄĹĹiZ'­lŢĽ0{öl›íFŁëÖ­Ă;ďĽĘ•+ŁM›64h^~ůe´nÝZő}]ştńÁł÷˸ś@H[“Ó@Ö: JŘĐ—Óčwĸ;&GęqÎĆřHÝ–zŚT=Ôî}bŠYđu'"’¦ÉějYYY¨U«–ĂýgĎžEŐŞUî ÁóĎ?ŹŘŘX|öŮgřá‡Đľ}{ÄÄÄ nÝşX»v-€˛FĘÂ… Q«V-DEEˇjժظq#Űt5gÇÝy着޽{cÚ´˛µ€^zé%$''ŁB… ŤŤµIÇ Á¶mŰp×]w!,, ýű÷‡ÉdüńÇčÝ»7˘˘˘Pľ|yôěŮÓú8GĎAKżţú+ŚF#ÚµkgÝÖ¶m[ěßż_“},'đâ!_P”Iq·'ieŞÍŹ«c(xđu'"’¦JOŽÉdÂőë×QXXŻľú «WŻĆ˛eË$Ź˝rĺ Ö¬YéÓ§;-óő×_Ç®]»-Zŕ…^Ŕ<€#GŽ U«VčСBBBđôÓOăرchܸ1ňóóQXXhWÖ‘#G·gĎ„„„ŕÓO?ĹwÜhܸ1ľýö[Ô¬Y+V¬ŔĚ™31fĚkyóćÍĂ /Ľ€  K—.řůçź‘ššŠž={˘Yłf8qâŞWŻŽ?˙üpéŇ%ôęŐKň94mÚÔ¦®;věŔ¨QŁěžCDDrrrś^31K ^Ť5¬ŰjÔ¨sçÎi˛/ĐBŽ–„˝j"ŽzIü™TĘ‘ü}â""5©äŚ9#GŽ´ŢőŐWńĐCŮWTT„AˇGŹ1c†Ó2.\¶mŰbË–-0ŤHHHŔwß}¨]»6vďŢŤűˇˇXż~=ĆŤ‡[o˝ŃŃŃveU®\YÖq–4·ÂÂB4lŘąąą6ű,X€~ýúYÇż\ľ|_}őţůç›´·† >ůä‡ĎAä 8NŻŤ\€}Ł0$$D“}ä?Ä !5Ňź¤ëâń3rôŽĆč·IÝ–[ľ…·‚2!îšü"˘2Ş9ďľű.† †’’tęÔ Ű·oǤI“P®ÜÍl¸’’ 6 ‰‰‰XłfŤÍ>)–ž‚ěěle“E۶mQ·n]Ô©Sźţ9–/_ŽćÍ›#%%ëÖ­C§NťlĘ’{śĹşuë°qăF$''#??ßnÝşuŔć9Xz8ęŐ«gwĽłç ĄŘŘXëů-·/^Ľ¸¸8Mö2ˤ'3Žů¸&ęÓz|‡ŁŕǓǨ‘:ć­ L ZĄNĚ>j÷~` CD¤ň:9ˇˇˇxăŤ7ТE üűß˙ĆĚ™3­űćÎť‹śś|đÁ.ˇúő룤¤k×®EĄJ•ěöwëÖ ÝşuĂ•+W0kÖ, 2gĎžuű¸ß~ű “&MÂÉ“'Ń AěÝ»»vírYĎřřxŔźţ‰””EĎAHÍtµ¦M›"** Ä€˙űß˙¬irjď t4ń€3ÁŢ8Ň"(“űą‚Ąa«ő88żg'crR®źDDÁNő‰5j„ĺË—cŢĽyřů矇ĆóĎ?ŹńăÇăüůó8sć Îś9c}ĚC=„­[·J–×»woÔŻ_'NDVVĚf3Ξ=‹'NXÓĂŠ‹‹Ť„„É2\wË-· 33fłŮÚërćĚś={ďż˙> ##ĂéóîÖ­ęׯŹÉ“'ăäÉ“¸tévďŢíň9YŇŐÄ?JŚŚÄC=„eË–!//?˙ü3¶oߎ©S§j˛/ËÄî6†vĺ}l¸9¦ÉějŹ<ň:uę„űďż………řő×_a6›1zôhÔ©SÇúc±ví˙·wçqU•‰Çż"fš n¨‰¨iąT®ą!.Śf.e„Kj¦™ĺ®i›{3Z挆[éhYiXSÓ2fj™š©Řbcî"h®( ÷÷‡?npą÷r{ą ź÷ëu_qĎsÎsžsĐ™óőYNĽ¶nÝj¶.???mܸQYYY UٲeŐ±cGíŰ·Oéééš0a‚*Uޤ;î¸Cü±Ů°”ß~'NÔСCµjŐ*učĐAŃŃŃŠP§NťÔµkWµjŐJ:t°zÍ~~~úňË/uëÖ-5lŘP!!!š7o^ľ×`aaa ”$őěŮS:rä$iĆŚjܸ±jÖ¬©=zháÂ…ĆĄžQćÉ’đČ^śä ŚwUСažĘÜůw€#yI2>¸mŮĽQCź~Nď,}KĂbGkĹ’;Úc sŽţEuëÝcüď;KßŇЧźs™y89{’ě¶lÖ’}~G˙ď@A'ä[zÇŤ+2Ć,µ9{_w ÖŽúóioîŇ΂`Žw·!a˝ĆNV g®-›7jXěheffč÷˙ĺqÖČ1=9€§©[ďăâžĚÝ޵‘3ŘŘ{˛AÚ`«śďú±W ă=)%Ě#ä6*)ór ó°ěĺĺ•ëc©,ç¶śeům·TŹ;łGĎÁ¦8p!°'sE…yxÎŮC‘3¬ŰnZfn fsď”1WOaxB(#ŕŔţd×%¤Oć)ă÷%Ű˝mQŢucʎ^ćB”iďJÎďć~¶4ČZ=ćľC”Ťß;GČ83”ąB(…kâ÷ć1\ €]äžeŻIő–†zĺŢf:4ÎŐąK;á~¢'(L˙Ĺ×ĂźĚ=¸›Îź±ĺáŢŇKővůč‚¶ËÖ:ÍŐE°Aq }˝=: ;ôäNŕőóóSűöí•””dÜçŇĄKŠŠŠR•*U đđp=z´¨§v¸Í›7{ĚJNŇí—˘6LĺĘ•SőęŐőÎ;ď8»IpŽžßanÉäüřÍ-±lméĺÂKí*hŹTÎcLC™˝z¶rľ°ŐŇďĆ^ꊂł×Â!ŕiěŇ“łzőj=ţřăĘĘĘRrr˛ž|ňI ¨~ýúéď˙»ł›R؇!†b?\°Ě! ¤¤¤¨ZµjËOž<©Š+Z,?xđ "##U¶lY•)SF]»v5–-\¸PőęŐS@@€‚s ąňňňŇĘ•+Ő˛eKůúúŞ{÷îJMMÍ÷8KçË9\­S§N’¤ČČHŤ=Ú¦¶|ôŃGęÖ­›J—.­‡~X7oŢĚ÷ú~üńGµjŐJAAA Q|||>wŰ6{÷îUzzşZ¶liÜÖ˘E }˙ý÷v©îˆ9tX©§„2wţťŕHv®vóćMeffęÚµkúć›o´`ÁÍš5Ëěľ/^ÔâĹ‹5fĚłĺéééęÚµ«š4i˘äädUŞTIżýö›±ĽaÆںu«ŞT©˘ąsçjܸq:t¨±|ęÔ©š;w®4h ľ}űjüřńzçťw,—ßů˛%&&ĘËËK_|ń…:věhS[¦L™˘7ŢxCÓ¦MS»ví´gĎ5jÔČâů.\¸ îÝ»ëŤ7ŢĐŕÁ•””¤űďż_­[·Ö}÷Ý—«= 4hPžvúůů)---ĎöÓ§OK’*W®lÜVąreť:uĘěď%‡« k)čw›7gď\áwćN<é}WŮxoäe—3pŕ@ 8Đř}ѢE>|xžý®_ż®~ýú)""BcÇĘiŤµ IDATŽ5[×7ß|ŁăÇŹ+11Ń8÷Ą~ýúĆňěác×®]Sýúőuţüů\ÇĎś9SŃŃŃ’¤¸¸8Íź?ßęqůťĎšüÚ2mÚ4őěŮS·nÝ’$ýńÇVĎ÷ď˙[éééŞS§Ž¶mŰ&IŞQن6mÚ”'äôéÓGW®\±©ťŇí!…RŢBw{@„cąŰĽŽś/ńtv łŻ=%pµŠâEŔóěrŢ˙}EEE)++Km۶պuë§RĄţ —••Ą¨¨(Ő­[W‹/ÎU–SvŹC­ZµĚ–/Y˛DË—/W˝zőtůňĺ<ĺ!!!Ćź«V­Ş?ţřĂęqůťĎ[Ű’óZ­ťďÜąs’n‡Äl-Z´ČuM…lČ›n7 '9·çüo~ő¸ű°łâxI(JÜf×÷äřřřhĺĘ•jÖ¬™ćĎźŻqăĆË&Ož¬´´4­_żŢbŔ‘¤ęŐ«K’~űí7………ĺ*Ű·oźâââtäČÝ}÷ÝÚĽył>ýôS‹u;vLµjŐ˛zśµóYSжŘr}µk×VVV–âăăUľ|y«őt¸Ú}÷ݧ˛eËjÇŽzä‘G$I»víRëÖ­óm3<›˝Vę2×Ca­çÂÜĎ–Ţycďg…2{"ŕŔţd÷…4h 9sćhĘ”)ÚłgŹ$i˙ţýš7ožbbbtúôiť8qB'Nś03|řp­]»V’®ÚµkkÄ:rä.\¸ M›6Iúł§ăĉ:yň¤>üđCIŇáÇŤu]»v͸mÉ’%ŠŤŤµzśµó™ ÔŮłge0lj‹9ÖΩڵk+66V)))2 :yň¤’““óÔ“=\Íôc.ŕH’żżż†®YłféŇĄKÚłgŹÖ­[§gź}Öj{á™B_o”ë“ß>ŽP÷ćX;¶(çϬ¤ÜaËtśiËŮÓ÷íäWOö§°˘„lž°p8‚CVW5j”Ú¶m«ččh]»vM{÷î•Á`Đ!CTłfMă'[||Ľ¶nÝ*évOÄ—_~©[·n©aÆ ŃĽyó$I:tPtt´"""Ô©S'uíÚU­ZµR‡ŚuőčŃCęÜąłâââ4věX«ÇY;ꩉ'jčСZµj•Mm1ÇÚůüüü´qăFeee)44TeË–UÇŽs-Ç]3fĚPăĆŤUłfMőčŃC .ä9€ŤěĘ,…k\!”ŕNŠ<\ÍÜ˙Ů—*UJ‰‰‰Ćď¦ äWGýúőőÍ7ßäŮĎÇÇGk֬њ5kŚŰz÷îťkźÄÄDăęg9Y;ÎŇů:vě«mS§NŐÔ©SmŞÓÜŰÚó;źt{®ÎúőëÍ–•żżż–/_®ĺË—;¤~”lŽžeiXš=&ěĎe×99ÜéĐ{ 2:L{+l &–†Yš+“ÍÜĽkex.Ź 9K—.µyůg·9z~‡ĄđcŹcŠśĘ SżäP €'ó¨ăě&nݤ?,;2”ŮR—-ěµ"ÜShXÁć]yâ P ?Yx€{*ěC2C±ŠË<Ş'@ÁąűĂra†yJ(3ף9@‰—ó!ŮOA&éŰű%ˇŽfnÉ袶×~g(^ ?€üyĚpµ+W®čçźvv3·FŻ@ÁôĄž9ß“cŹ@ĆűqČ«Č!'çŰ»˝ĽĽäçç§öíŰ+))ɸϥK—Ą*UŞ( @ááá:zôhQOťË®]»Ô¬Y3»Öéh¦÷®(o@ěĄ0ËÖţ›Űžýł­Ű-ŐăĘ˝6Ĺ`€yvéÉY˝zµ233•žž®Ý»wëęŐ«|XÝşuSąrĺ¤ńăÇ+###Wť:u’$EFFëZ¸pˇęŐ«§€€ëťwŢ1îź””¤đđp5nÜXŐŞU“———6lŘ IúńÇŐŞU+)$$Dńńń…¸#–%&&Ú}čP’×böe…ť‡“sŢŤĄ€ĘÜţd—sóćMeffęâĹ‹JHHĐ‚ 4eĘłű^ĽxQ‹/Ö1cĚ–GGGë>ĐÍ›7%I۶mÓŤ7Ô©S'eff*22Rwß}·ŇŇŇ´sçN%$$húôéąęHLL”$}ńĹZ°`$©aÆںu«®^˝Şçź^ăĆŤ“t{(]·nÝôđĂ+))I§NťRůňĺ%I.\P÷îÝőĚ3ĎčĚ™3úüóĎ5jÔ(íŰ·/O»çs×]wYĽo‘‘‘zűí·Ő¨Q#uéŇEçÎťłv›—–sx–˝B‡Ą!]¦Ăár˛ËpµjŕŔĆď‹-ŇđáĂóěwýúuőë×O;v¬Ůşzőꥧź~Z‰‰‰ŠĐ»ďľ«'ź|RŢŢŢÚşu«Ž9˘ożýVľľľ QLLŚ-Z¤Îť;[mcDD„$éÚµkŞ_żľÎź?/Iúć›otęÔ)ĹĆĆć9ćß˙ţ·ŇÓÓU§Nm۶M’TŁF mÚ´I÷Ýw_®}űôéŁ+W®Xmąú%)55Uť;wÖ#ôŃG¨ 0L‡6Ůcř“ą°a:Ć–@biŽŽĄzLPAćĺô[ę4W—ĄápŕO[6o´[]v 9ďż˙ľ˘˘˘”••Ą¶mŰjÝşuŠ‹‹S©Rveee)**JuëÖŐâĹ‹s•ĺ¨^˝zé˝÷ŢS›6môŃGi×®]’d\H ç–ŕŕ`›X˛d‰–/_®zőęéňĺËĆí§Nť’żżżĘ–-›çěž•E‹·µhŃB!!!ůžŻ *Uޤ#FX ~€#9z~‡ĄđcŹcŠśĘ SżäP €+±÷*Ăv}¨ŹŹŹV®\©fÍšiţüůĆ!a’4yňdĄĄĄiýúőN¶ččh 4Hm۶ս÷Ţ«zőęI’q3gΨzőę’n‡”üŘ·oźâââtäČÝ}÷ÝÚĽył>ýôSIRĹŠuýúuĄĄĄé®»îŇńăÇuíÚ5IRíÚµ•••Ąřřxă6K4hĐ <Űýüü”––főXIĘĚĚ”Źďf…ó•ô‡eG†2[ę˛Eň„y‚NčëŤJüﮤ +ŘĽ+^ ŔlݲɮőŮ}á hÎś9š2eŠöěŮ#IÚżżćÍ›§ť>}Z'NśĐ‰'ŚÇ >\k×®5~ďÖ­›J•*ĄqăĆiČ!ĆímÚ´Qhh¨fÍšĄĚĚL;vLK—.͵\u¶ŔŔ@ť={VÁŘ#sâÄ ťä%‘-ČŽž«“óÁż ˝0–Ž-ě|žâ eöŔ{r°Ž6°G(+lŘq…P €;aâ »Č9gĆ^˝–†t™s'9çącűpôä%éżôŰcř“ą`c:÷Ä–đcnz S¶Â—_ťćęĘ9Ľ-ż}@Ńą'ÇtU%???µoß^IIIĆ}.]ş¤¨¨(U©RE ×ŃŁG‹zj—`íÚň»î'NčŃGUĄJ•T¦L=ôĐCÚµk—s.%–Łçwd?Üd¸—éţ–ę±¶˝°í*hŹTÎcLĂ—˝z¶rľ°ŐŇďĆť_ę €˝Ůe¸ÚęŐ«•™™©ôôtíŢ˝[WŻ^ŐŕÁŤĺéééj×®ť>¬ÔÔTůűű+&&Ƨv:k×–ßu÷ďß_={öÔ™3g”––¦6mÚčŃGuÖĄ’ĎáčPfkťÖű±Ú˛KČńöö–ŹŹŹüýýŐ¸qcĹÄÄhßľ}Ćň   Ť9RĺË—W@@€ú÷ďŻďľűΧv:k×–ßuďÚµK‘‘‘ňńń1–_ĽxŃY—:ŕ0ěŞř•ô0 €5Yx %%EŐŞUłX~ňäIU¬XŃlŮâĹ‹Uľ|yť8qB’ôŮgź©~ýúşqㆤŰĂăV®\©–-[Ę××WÝ»wWjjŞ$éđáĂęÖ­›Ę•+§   Ť?^2 zůĺ—U­Z5•-[V+VÔňĺËí|Őů_›iYdd¤şuë¦]»v)55UcƌѬYłŇ.ŔwćdîEˇá)ˇĚť~g'»,şrĺJžO~ÇÚµY*›0a‚Ú¶m«„„éµ×^ÓW_}eő<€#ąŰĽs“ýťŃ[ĺś§cŻ@úz#ăÜf—óţűďË`0(33S-Z´ĐşuëtëÖ­\űdee)**JuëÖŐŠ+TŞ”ĺS‡††ęÁÔwß}§ &ä) 1ţ\µjUýńÇ:}ú´$)88ŘX¬Ó§O«fÍšúꫯ”””¤¦M›ŞqăĆÚ¶m[Q/ۦkłTvôčQ˝óÎ;Z´h‘z÷î­}űö©S§NzöŮgíÖ. 0 ó°lşĘ˘Ą˛śŰr–ĺ·ÝR=îĚ=OĚłëś­\ąRŰ·o×üůós•Mž­ĄK—jđŕÁ:~ü¸’““Ő¦M•+WNuęÔ±Řţěáj¶˛vmÖĘî˝÷^ÝyçťzőŐW5}út]˝zUË–-Sdd¤Íç Ë–dGĎŐ)ČÍŽ`.D™†ŹśßÍýli.ązL.JĐqô»Ťpwv9’4jÔ(mذAŃŃŃÚ˝{·öîÝ+Á !C†äÚ/ű˙ŕăăăĺă㣨¨(Íž=[m۶Uűöí%ÝžóěłĎ*<<\•+W–$őčŃCeĘ”QĄJ•§±cÇĘŰŰ[źţąžyćU¨PA4h^zé%=zT&LĐÁe0Ô°aC­]»Ö.×jíÚ¬•ÝqÇúňË/ő /¨B… *S¦Śzőę•§ €k°W(ł˘¬q…P €;)rČ1÷ĐĄJ•Rbb˘ńűŔ5pŕ@›ę>}z®˛1cĆäY­,11Q;vĚSOXX6mÚdvűÎť;-žż(¬][~×ݲeKmßľÝ!íŠ[ÎŢ {őĚärö¤¸ňęj x9¤'€k3ý—~{ 20LçáŘB,Íѱ´ŕ@aŽ3BA €âáv!géŇĄŞ_żľł›x GĎď°~ěyLa‚3BYaę—Jđdv]]­8ÄÄÄWL`%ýaŮÜ*n¶„2Ó},˝Ç«ÄŮkE<<•Ű…ŽS؀ìâWŇĂ(Ö¸Ýp5öĺŽËÖ–z¶…§„˛ä čÁŔ BPÂąÚŇĂ ,–$p%¦ďŘÉfŹ°ĺ ż3\ ĂŐą[Ż€+¬VV•ó%˘ÖVŚ+Đ×?ŕ¶"‡//Ż\???µoß^IIIĆ}.]ş¤¨¨(U©RE ×ŃŁG‹zj—ѡCÝqÇ*[¶¬îż˙~mÝşU’”śśśçţxyy©RĄJOŕľ ó°lúgÜRYÎm9ËňŰn©gg#Ř`ž]zrVŻ^­ĚĚLĄ§§k÷îÝşzőŞl,OOOW»vítřđaĄ¦¦Ęßß_111ö8µK3fŚÎž=« .¨U«V4h$©fÍšÚłgO®Ď°aĂôŔxü=ű°×J]ćz(¬ő\ä,3·łą97E]•,g}îĘ8Xf—99ŢŢŢňńń‘ŹŹŹ7n¬Ť5ĘX¤‘#Gż÷ďß_qqqö8µKxä‘GŚ??üđĂZ±b…$ÉĎĎOM›65–ť:uJź|ň‰ľ˙ţ{Źż'pm¶< ;z®NA–hvs!ĘÚ‚ć~¶ô"Rső*ĘP;Ţ“€u™““’’˘jŐŞY,?yň¤*V¬h¶¬gĎž=z´ń»Á`PýúőµiÓ&I· V®\©–-[Ę××WÝ»wWjjŞ$éđáĂęÖ­›Ę•+§   Ť?^2 zůĺ—U­Z5•-[V+VÔňĺËíxŷݸqCË–-łŘ#3iŇ$ĹĆĆŞ^˝zyʬÝÎgĎPVĐ€“sŢŤĄ€ĘÜţd—sóćMeffęâĹ‹JHHĐ‚ 4eĘłű^ĽxQ‹/Ö1cĚ–GGGë>PVV–$i۶mĘČČP§NťŚűLť:UŁGŹÖ?ü jüřńĘĚĚTdd¤îľűnĄĄĄiçÎťJHHĐôéÓ•””¤×^{M›6mŇŐ«Wőűďż«gĎžfĎź ŔŔŔ<ź»îşËâő:tH:tPµjŐTŁF -X° Ď>ß˙˝ľúę+Mš4©Ŕ÷p9‡gŮ«gĆVN+(WX,Og—ájÔŔŤß-Z¤áÇçŮďúőëęׯź"""4věXłuőęŐKO?ý´ŐĄK­X±BC‡U©Rć±™3g*::Z’§ůóçkűöí:räľýö[ůúú*$$D111Z´h‘bccĺă㣥K—ę©§žŇ=÷ÜŁrĺĘ™=ź>}tĺĘ•]HHŢ~űmíرC/Ľđ‚ŞV­Ş‰'ËoÝşĄçž{N&LĐwÜQŕ{Ř›éĐ&{ 2÷ŕn:Ç–‡{Kst, ů2ýŮÖáą2ůĹĂ.=9ďż˙ľ 233Ő˘E ­[·N·nÝʵOVV–˘˘˘T·n]­X±"WhÉ)00P˝zőŇ{ď˝§Ë—/kÝşuzňÉ'síbüąjŐŞúăŹ?túôiIRpp°±,88X§OźVÍš5őŐW_)))IM›6UăĆŤµmŰ6{\ş$Éßß_ 6Ô!C4qâDÍť;7Wů{ď˝§äääűě3ݸqCçϟ׊+ô—żüĹXöÝwß)99YO<ńD®cň»'€36ŕ0«ř•ô0 €5v™“cjÔ¨QÚ°a˘ŁŁµ{÷níÝ»WAC† ɵ_öQ||Ľ|||%IňőőŐcŹ=¦?üP˝{÷ÎSŹ=T¦LUŞTIqqq;v¬Ľ˝˝őůçźë™gžQ…  A饗^ŇŃŁG5aÂřŕíرĂŮMŕf\r¶űŃŁG5uęT5kÖ,OŮŇĄKUż~}'´ €;pÉžś6mÚ¨M›6fËbbbŠą5rňÄtĎâ’=9PX.Ů“Ŕő$b‚;pôäđ(„…áj·–ű…¨9‡Vć,cČ%”„€Ű3 6ɇ˙kşŕů®ŔŁr‰^(ą®p{ůÍ˝a¨”,ôäÜ^v€!ŕ$BŔCd/6J&BŔcä :(ą“đXÖޡđ\„€[3 .ÖćçJ†«đ(„…ŔŁrxBŹBČŕQ9< !€G!äđ(„…ŔŁř8»UhX#g7ˇX$:ŕě&€[ '€Gˇ'ŕ1 ł›ŕ^^^În¸zrxBŹBČŕQ9< <šé¤ýś‹ä,óÔE  $"ä\Včëľ˙&yBáßcl ńż¦Ű «¨Çě‡áj·3đ¸"¸zr7TRŢî÷TÔ?źÉ‡,÷Ř„ľŢ¨H=:94”Ř2ěÍRŹQaÎ(c¶q?Á đîÚ¶ýű|ĎoĘ푤_~ůŻ˘ŃĂŹôS»ťóścÇŽťżŰrßXWčsóć-eeeéňĺËúú?µrŐ?őĚđXcůĹ‹—4ě©X ŽŇŰ·hŮŇĹzőµ™:Ł·gőę÷´pá|=3TłfĎUBÂ'ú$á#uěŘA‹ă—J’˛˛˛4,&N!5kj÷ÎíJX˙ˇľţĎFýýoëá‡{čóˇ›7oJ’v˙´GjŐ˛…Mç7UÔö\˝zUCźŠŐ#˝zę_ź¬×wßn*đ}-L»ü©Đ!g츉jpO5»ż•FŚ­1/ŚVôŹË7»EׯßPÍŐµű§=ş|ůŠ‚őýöŚűڧúaajŢĽ™ŇÓŻëĺ—¦Şzőjjެ©._ľ,Iúé§=:vě¸FŽSéŇĄU­ZUőěQ}ś°Ať;éęŐ«úaÇŹ’¤őoPß>˝ĺíímÓůMµ=ß~űť.]ş¬~}{ö¶ŞÝţäSŘß|ăŻęŮă/şyó¦ú?>@_~ůµžęŻRĄnç¦óçĎK’VŻYk<¦É}÷ŞjµŞĆďw”»C’äĺĺuűűĺr}—¤”sç$I•*U2n«\ą’RRÎ) @ťĂĂőŻ}®ćÍšé‹/ľŇ†Ź?´ůü¦ŠÚžS§OëÎ;ËËǧзµPíđ§Â?Ť˙?ooo˝ţúlőz¤źVĽłR1O •$Ő¨Q]YYYš1ýe•+W®ĐőW©|{žOjjŞ‚‚‚$I)))Ćů?˝ă'éţćÍT?¬žj×®e×ó¤=şté˛nŢĽ)ooo]¸p!ĎńA’tňä)łő;ŞÝ@Ia—…ęŢ]GăÇ˝ żÍ{Sżüň_IR‡öíTŁFu˝8íĄĄť—Á`ĐŮłgőűďÇ TwóćÍT«V˝˝TYYY:uę´>ř`ťúô~D’Ô®][•*ĺĄŮs˙Ş~ýţ&fŻó¤=mZ·Rff¦>ůô3]ľ|Yă'LÉulٲeµwß~%%ĐÄÉ/š­ßQíJ »­®6xĐÝ3˝0fĽŇÓŻË××W«Ţ]®›YY Źč®{›< čC <ŢÇÇGË–.ÖoG~Słű[©wßţęÚ5BŁž}F’TştiEv歷ŚLEvďf<Î^ç/H{BBję•—§jĆĚŮęÖýaőíóH®căbźŇ› j츉?nŚŮúŐn ¤đ’dH>t ×Ć-›7jčÓĎI’ŽţĹ ÍB~¶lިa±Łeú»ýd˙=ŕď€ălHXŻV­ŰęŘ–­Űé÷˙ε-4¬‘ýzrŔrxBŹRä%¤ (Ú¶ /đ1^^^ĘĚĚ0[FČŕtYěiËćŤVË®ŔŁäŰ““_JWb5äxyyW;Ŕ.,†św–ľĄKg[Pô´Ŕ“ĽüĘt­yomží˘Łôę+ÓlŞĂlČúôsEkÂKÓ¦čĚŮłÚ´)Ѹ­sçNziÚ›ë`áŔ †l/ooo˝9˙ojŇä>IR“&÷éÍů“···ÍuX®V%ÜOÄP@ç(SĆ_Kă˙ˇq&ëoŻĎV™2ţ:ž÷äp9+VÔŠeń…:–áj< !€Ga¸§łç|hB§˛÷ж Wŕ4ŁÇLRffFˇ>–¸|OÎ?ü¨oý]~ůŻŇÓÓU®\ ęÔ®­±cźW›Ö­Šµ-Űż˙AK—­ĐĎ?ďÓ•+WtÇĺT§NŤ5RíÚµ-RÝ­űXsćţUÁAÁziÚ 4DɇŘ©ĺłcÇN§ž%Çď˙;l÷:]:䤜;§a1qőě3ZĽč-ůűű+%ĺśöěůYľľľĹÚ– >Őř‰Sű”¦żö˛*Ýu—Nž:­Üi—Í{C“&Ž×Ă=˙˘72´ňÝevhµíľţĎF5mÚDU*WVő‹ýü€˝¸tČůőŕ!eddhčÁň÷żý š ©Y¬íHOO׫Ógiŕ€'4ně Ćíuﮣşw×±Ë9ŇŇΫjŐ`ůűűËßß_mŰ´¶K˝¶1r´Öüó]U©\YĺËßQěçěĹĄCN˝zˇňńńŃ´—^Ó¸±ŁdvżU˙\Ł•«VëěŮ–Ő¸±/čŃ~}ôtě…„ÔÔ´©“%IAť»Djúk/«m›ÖÚ»oż^›>K'NśŻŻŻF<§'˘úç©ÇŹ;uůňe=ţřců¶ůčŃßőĘk3ôÓO?«LőéýĆŽ­ŇĄK+4¬‘.Ż>Z§ďżßˇíŇâE Ő©s7IRlÜHŤzö5oÖ,×p±C‡ëµł”–v^˙¸¨”sç´xŃ[ęŃYˇaŤ´ćźďŞeË%)×÷аFšŁ¨'é—˙Ô–ÍÖHK—,RŰ6­µcÇNcť×Ż_×a±zú©ˇ:t°$©Ůý¶ĎEZ·>Ańo˙Cuď®#ooł÷iÍ?ßUhX#­XŻ–-ĚuţÂ^Ó˝ŤŮÜFw5v´ăĺĺ%Áŕ€Ö`;///mݲÉŮÍ€›kŰ.ĽŔÇxyyiôIhMn.r$)""\=ÔF›7oŃ—_ýGo.X¨·.Ň‚7˙¦ŽÚK’qhUzúuÝ}wmýqńâíc;wŇ‹S_Ň;~TŰ6­µţă ęۧ·Ľ˝˝µůŰ-ş~ý†jÖ¨®Ý?í‘$ëűí?ä 9ŮĄů=śţôÓ;v\#×Ä©téŇŞV­Şú?ö¨ÖĽ÷ľ1<;r¸Â;uĐ­[·$I—.]˛Zç÷?ěPJJŠ˘˘ňďE2çągG¨É}÷J˛|źŠűš<ɑÿؼo뵧 rödĎw‘…}r4—9’äďďŻîÝ»Ş{÷®şxń’žőĽ^zů5ăŤZűÁGúčŁőŞ]»–®\˝j<. @ťĂĂőŻ}®ćÍšé‹/ľŇ†Ź?”$ť?^’´zÍZăţMî»WU«UÍsţęŐ«K’'±ÚC‘rîś$©RĄJĆm•+WRJĘ9ă÷jU«I’J•˛mőî””sňóóS™2elÚßTĹŠŤ?[şOVĎď€kÉ-BNNĺËߡČČnš1sŽ$éே4uÚ+JÜô•jÖ¬ˇ;vjÓ¦Dăţ˝ă'éţćÍT?¬žj˙˙ł5Ş+++K3¦ż¬rĺĘY=gË( @ďľ»Jűë‹«©U©\Y’”ššjś?”’’˘*U*ázËëĆŤúăŹ?tçťwęôé3JOOϵOvÓÉ“§,Ö“ß}˛Ä×äénÝşĄYł_×Ôß ŕJfĚśŁ)“'8ýż]úźŢwěŘ©—_ťˇ­Ű¶ëüůóĘČČĐ˙ŽŐÇ ź(<ĽŁ¤?{dÎś9ŁłgĎęß_|)éödyIj×®­J•ňŇěąUż~˝ŤuwhßN5jT׋Ó^QZÚy ť={Vż˙~,O;Ę–-«)“'č“O?ÓÄI/ę—_ţ« .čСÊ_˛\ź|ú™$©yófŞU+D‹Ţ^ެ¬,ť:uZ|°N}z?Rč{вĹňóóÓâ·—ęСĂzţ…q’$/y۶wß~%%ĐÄÉ/Z¬'żű Ô´Ôc¶Úwě˘F÷6Wô€'Ő¸Ń=š3kş$©e‹ŐëáôäS0h¨z¨Ťš6m˘čOJ’J—.­ČîÝ”‘‘©ČîÝŚuűúújŐ»Ëu3+KáÝuo“=pţzČl[˘LKŢţ‡Nś<ĄÇź¤[>¤AOSŇjŘ ľ$ÉÇÇGË–.ÖoG~Słű[©wßţęÚ5BŁž}¦Đ÷ B… š1ýe˝żöC=Ú?Zü‘‡ââbŤ÷bcißľý^¬ @K˝·ű˙.[Ú&5=®ó€ďquL3ŢßÂ=°ŽŇŇR]sÍ÷$™ă>néIŤ˛ňrIR÷㽕••{«$-ôź#nŃ«su÷=Ł•š–ˇĘĘJIMŹkĆ<ŕ{\ÓŚwŔwpO¬ăË/żÔ†Ws•>%U’9îă–žÔđ÷ó÷v \ôĘŞÚ¸áOz»p»>űě3e?ąXRÓăš1řWÇ4ăđÜÓk¨©©QÖ¬‡uÓđ$MMO“dŽű¸Ą'5BĂB%I••UĆ{UUU óVIZ)88X>˘·Ţú_IMŹkĆ<ŕ{\ÓŚwŔ÷pO|×7ß|Ł9ŹüLQQ‘Ęyv‰üü.N%á>néIŤëż?@AAA:pŕ_Ć{iđŕx/V µjkkpńËšš׌yŔ÷¸:¦ď€oâžř¦ç–˝¨Ď«>ע'’9îă–žÔčÜął&¤< —VüQŐŐŐ:tčC˝±e‹&MśŕíŇ4ăčŃŹĺt:őé§źjíÚ şű®;%5=®ó€ďquL3ŢßÁ=đmë•Ők”śÂxÄäđáŹäp8k;Hűöíożžźf¬ÔxáĹß(5u’ňó6ęرăĘYşLµµµJĎ®¨ČH}°g— ň˙¬­Ű¶ë÷ËW lÎ/ĐĘ˵ďnIŇęU+µpÁă’¤~ýú*wăz<đľŇR'+'ç9IRYyą$©{HŃNHHĘĘĘ=ßc` ƤĆÜGçhô¨{3P)ă“őćη´wď>ť:ő‰˛fNW§Nťq­’ÇŤŐk1=k¦âb©k×®W4~Óđa í.‡ŁF}űFëó/ľ$ůűů·C×€•…F\aĽ¦łgĎ+*BCCëĺB/[QRoµĹwmĘÍS^^ľ˘Ł{«ú«ŻŚ÷CĂ.¶WYYĄ°K?WUU)<Ľů F¤Fľýäôé3ęŮ3Âř“ŠŠ őčŃC’TVV֢ɇĂkÁÂ'µsÇEFöŇîÝ{´cÇNIŇőß    8đ/ÝvŰ%Iiđŕx·t XźńřÉ9Ç9I7Ý”›§ńŚÓ!Ő»w”ţ°âeŐÖÖęôé3ĘÍݬűďÓ`c]ştQĹgr:ťŞ¬¬”$•””¨´´T˙ÇFűť;wÖ„”ôŇŠ?ŞşşZ‡}¨7¶lѤ‰<Ý_`ĆJŤŚi3¨ŕŕk”2>YSÓÓäďďŻU/ż¤ěě§48!IAAAşoĚ(=4kFŤMĎśŞyó¨¦ćkŤý#ŤuŻ&ĄNUŻ^=5ﱹ*:ôˇ&<Ş]ďęŃGfëÉEKtó[Ő%(HŮ ˇÄÚ­ăŔ·ŮŽ9űцuk4th˘·ëq«ŚĚ,6{śS’­ ú*§óŰźm6 ǶK_Ä&–Y®=b/ĹöKAˇ×ŻEâ¶Ĺ#ívíÜYŘĘóíC[ˇ ®EbSÄ&¸–‰ůw±b\‹=ví>ŢúŘxüŔ—řIŇ3O/RźľŃ^. ĺlG‹‹śÍć›ú iń±ßY©ÖęŘ'Ő_¦GLlĄŘLµ{!¶_Š MRqűĆvţ;zl¦Z‰‰=7ř•®V1ŇnoŃžulmŚ}N[;LLěĺŘn·«P…WćMP±7ăB“ŐCějl·ŰUŘężĎÂ&rÄÄÄfŠ˝Ź·56A߉‰]˝Ź·>¶ôJŤŚĚ,o—<ÄR+5ú]7P’ôń‘C’ÔŞUŔ·XîŰO>>rHý/íĄa·Ű[u®łWkňľč»ý &¶Jl¦Z‰‰]‹ëîă­űN]öő~fé 11qűĆfŞ…¸ŁĆ®ÜÇ]‰-µRŁţ„†«ę?˘ăt!Ú‡Ą&5$éhq‘·KíŔkŹźĽóî.ĺ,]¦1÷ŹÓ?ßŰí­2€Źrë¤ĆÖmŰUV^ޢc˙ú×˙V÷î!**:¤ .¸ĺóű]7ĐŘ,X›['5ffÍŃńc'Zt쯖>ŁiéîüxIîŮWźź$őŁ× ^×OĆŽ×őă4ej¦ŞŞŞ$I'NśTZú4ĹĆ'jč°[”łt™Îź?Żşó^Y˝FIĂG éÓµxÉł’¤µë6čÖŰďÖ ± J>B›ó <Ú&4č8Ś•/ĽřĄ¦NR~ŢF;v\9K—©¶¶VéÓ©öěRAţźµuŰvý~ů ŁÍůZąbąöク/ĆęU+µpÁă’¤~ýú*wăz<đľŇR'+'ç9Źwčhq›…Đ“sťŁŃŁîULĚ@ĄŚOÖ›;ßŇŢ˝űtęÔ'Ęš9]ť:uRDĵJ7VŻüĹh`ö¬™Š‹¤®]»^ŃřMÇ)4´»Žőí­Ďżř˘}z,ĎřJ×k#Ś7ĂÂÂtöěYcÓĎĐĐĐząP••}»hHHHŁŤoĘÍS^^ľ˘Ł{«ú«ŻÜZxCę6 ýřČ!Ź𮀆Ţ<}úŚzöŚPxX$©˘˘B=zô$•••)<<¬Ů†T¬ źÔÎ[ŮK»wďŃŽ;ÝXzĂęöŐŕ¬Íxüäśăś¤‹nĘÍÓřĆiČÁęÝ;JXń˛jkkuúôĺćnÖý÷Ťi°±.]ş¨âł 9ťNUVVJ’JJJTZZŞż˙ă Ł}OaŁP:cĄFĆ´ Tpđ5Jꬩéiň÷÷ת—_RvöSś¤   Ý7f”š5ŁÁƦgNŐĽů TSóµĆŚţ‘FŹşW“R§ŞWŻžš÷Ř\úPLŐ®w uŰ÷¨´´L’4-s¦üýýő?+PTTd›:Ä :ŰŃâ"g˙1Ú°nŤ†Môv=n•‘™ĄÂÂÂď”dkC시—ţ´[,6S-ÄÄÄ®Ĺ#ív¶ně_ l6ső…¸}c3ŐBLÜQcWîă®ÄĆă'VĐďşĆfˇŔÚü$é™§©Oßh/—âě«@Ç`;Z\älţ0ßQ7ˇq´¸Hý\ܰŐűąˇ˙0Íĺ€9uůÍXZ_éęËęoZ÷ Ź«šű7˙fĽËŢĆ1ŔÜ\ăÜśźÁ}°¶öă–[©Q_Ff–·Kb©•u›„~|ä$1ó €…YęŰO¤Ë7 µŰímjËŮ‚—4×/ňäÍš·ŰíMćÍ\;yňä=—7smäÉ“o߼™k#OŢęůúżŹ{ňó-5©á‰o>±5ń˛’ćúEžĽŻćÍ\yňä›ÎŹ´ŰűäÉ[8?˛‘˙é®ö=Ů6yňäÍ“·Ôă'Ňĺ…ëňĘJŤęęjÍyřgúAŇ-ş!6A'Oѧ˙ţ·7J>Ę­“[·mWYyyłÇ95JLLĐŽmמÝďŞóUťőÄŮmţü~× 46 ÖćÖIŤ™Ystü؉fŹ í®‰¦¨[·n Ô=÷ÜĄ=ďŕ–<±Ż0?Ię? FŻĽ®źŚŻëĆiĘÔLUUUI’Nś8©´ôiŠŤOÔĐa·(gé2ť?^u署zŤ’†Ź0&Ň3¦kń’g%Ik×mĐ­·ß­b”4|„6ç4XDii©®ąć{mî tĆJŤ^üŤRS')?oŁŽ;®śĄËT[[«ôŚéŠŠŚÔ{v© ˙ĎÚşm»~ż|…ŃŔćü­\±\ű÷î–$­^µR <.IęׯŻr7®×Áď+-u˛rrž»˘€/żüR^ÍUú”T·tčhq›…Đ“sťŁŃŁîULĚ@ĄŚOÖ›;ßŇŢ˝űtęÔ'Ęš9]ť:uRDĵJ7VŻüĹh`ö¬™Š‹¤®]»^ŃřMÇ)4´»Žőí­Ďżřâ˛|MMŤ˛f=¬›†'ijzšçz ,ÇřJ×k#Ś7ĂÂÂtöěYcÓĎĐĐĐząP••}»hHHHŁŤoĘÍS^^ľ˘Ł{«ú«Ż.Ë}óÍ7šóČĎ©§eËĎŻíŰ{Ômúń‘Cmn [@Což>}F={F(<,L’TQQˇ=zH’ĘĘĘÖlÇ?*Ö‚…OjçŽ-ŠŚěĄÝ»÷hÇŽťFţąe/ęóŞĎµüwżvË„Fťş}5xk3fÎ9ÎIş¸1č¦Ü<Ť`ś† ¬Ţ˝Łô‡/«¶¶V§OźQnîfÝßëŇĄ‹*>«ÓéTeeĄ$©¤¤DĄĄĄúű?Ţ0Ú˙¨¸Xݬ^Łää±*/ŻPII©JJJŰÜ6  ă0VjdL›ˇŔŔ@_Ł”ńÉššž&­zů%eg?ĄÁ I Ň}cFéˇY3llzćTÍ›ż@55_kĚčiô¨{5)uŞzőę©yŹÍUѡ5áÁTÍ{l®śN§›÷Äeç»cu+4čŚIŤ ëÖhčĐÄ+č­ukW7xňw'˛fţTY3jÄ/<˙+˝đüŻŚřöŰn5~3f”ëU€Ď}›Y´#?IzćéEęÓ7ÚËĄ´\€$%Źëí:ůöÎ_̵őÚ!ďŰy×®ňmĎŰíövů|KOj´šó;Ďë8~–§ˇgz|šł™~‘'ď«y3×Fž<ůfóőźĹmŐůN§×k'Ož|óů‘ ýH7¶ďɶɓ'ož<“Ŕ'ymRĂáphţă ź¨á7ŹÔćüo•|[7 Ýşm»âăăÖě±Ëž˙µŠ‹Źčť·ßÔ‰“'•2a˛z÷ŽR⍠î, X”[WjĚĚšŁăÇN4{śĂáЦÜ<Í‘©«Żî¦ŘA7č®;o׺őŻşł`a~’Ô@Ś^+x]?;^׌Ӕ©™ŞŞŞ’$ť8qRiéÓꍎĂnQÎŇe:ţĽęÎ{eő% ˇţb$IéÓµxÉł’¤ŹŹWzĆt ŠKPĚ !J›2M’třđGr8Š‹‹5 ‰Ť¤}űö·_Ď€O3VjĽđâo”š:IůyuěŘqĺ,]¦ÚÚZĄgLWTd¤>ŘłKůÖÖmŰőűĺ+Ś6çhĺŠĺÚżw·$iőŞ•Z¸ŕq9ĄMÉP€żżvlCöýź˛łź$••—K’ş‡„í„„„¨¬¬Ľ]: |ź1©1÷Ń9=ę^ĹÄ TĘřd˝ąó-íÝ»O§N}˘¬™ÓŐ©S'ED\«äqcőZÁ_ŚfĎš©¸ŘAęÚµëe ˙ó˝Ý:s¦D ~ń¸ÂĂ ľ}úH’üýüŰ©{ŔŞŚIŤk#Ś7ĂÂÂtöěYcEEhhh˝\če+*Bę­¶¨ŻüŇą={F\‘ »Ř^ee•ń^UU•ÂĂ›ß`@jdŁĐӧϨgĎă[L***Ś\YYY‹&zôč!I:őÉ'Wä®˙ţéŔďZżöż<·sçÎzö™Ĺzö™Ĺ.:¶÷Ô0;?IzćéEęÓ7ÚËĄ´\€$%Źëí:śÔÖúµ«uç·y¬0€ĆÜyÇmZżvµ‚=¦ŃŤBő»ßľ¨´ÔI) !i©“ô»ßľ¨ŔŔŔ&Ź h*éçç§żhüŮwké\DŁ+5ĚĚX©ńvˇk_ßęęy’ës ’dłŮ\:ŮŐó¤¶Í-ŘÎź˙ÚéĆZÚĹ˙ _Őć…ëCSIEND®B`‚gpsim-0.30.0/doc/screenshots/registerview.png0000664000076400007640000005453713041763626016224 00000000000000‰PNG  IHDR»%}L- IDATxśěťy\ő˙Çź Č)âÁˇWži&ZjhĄY jú-Ă2~^]šW—w‰i–™Gj–Yž©ĺy›fy`Ć%š‚‚7* ¬óűc9vvaˇ÷óńĚ{f_óţĚ~vŢóąu x{{“€··7€‚ ‚ ”Ab˘"uymv9wĽ˝˝•Îťü:e"5kz—śg‚ ‚`ÎźOŕ˙W~۵;WĐÓe•ěeÝšoyčˇfĄçĄ ‚ '"éŰď…쀗U˛Sľ˙v%M7"3#€łgOéµk×3‹Ł‚ ‚ĺ0÷3ŢÚôš4nÄ÷ß®¤AŁfJLT¤Î “_G5nHF¦čÎá۲M‘.ôןżSĂۧHźA,Źąźń֪רqC:ůu@([6ŻĂ§fÍě‹´đm]¤‹dqôŻCđÁ¤¦Ą C‡ŁŁC©ůˇ×ëąsŻČÎÖ– *”š/‚iűoízçÎźçŮž}Őj̬@wéŚ)”‡˙…˝}Z>ůÇÓş8;sëömÎ'$R˙ş$%_ÂÖFă˝X(“XşdWÜsóžó\źŔ\1'§˝°×.°d÷\źűíęŔ싪 Ŕ´¨.”âNźˇv­š¤§ßaÇÎ=ÜNM剮~¸W«Ęď‡˙äúŤ222ر›k×ođĚÓţ<ß?gggŁş{÷˙Îő7čěמîÝşňH«¸¸8ă{Ż:ŃŃŃgžöÇĆĆFóş†üĚK˝şµłŹZň9–şukĺ«Ţ3–F/O’“.”” ŔĄËWP… “¨îĺiTŁ0ţă|B"gΞcĎľ(ŠBÓç;':&Ž:ujáăăŤ{µŞ$^¸ČÍ[·ňťWن':ťŽs÷J~˙ţ›`0( eË—ěžëoÓľvÁţĺŚEYú…÷Żmv}{°ný¬]÷Ă}{źißűăßŐ'''˘˘ă¸sçÔk€[%W||Ľů÷\‰‰±·Ż@zú4¨GĄJ®ŘÚä›É'Š˘ ×ß%!ń" ę×Í÷ŕ·±±ˇre7Ł×u»w­ś~ćĹ»†ö$$\ =ý7oŢ"%ĺfvĚÉ™łç4ŻŐ°A=lll¸t‰Úµ}HMMĂĹĹ™K—Ż’r“ÔÔ4ĽŞ{Ő(ŚżĆŘůŰľě˙[ú>”/ŘÝľťĘůó‰tŞ+6iČî˝‰ŽŽŁĄoó\çV¨P/O/˘×ë9>‘6mZg’O‚ő’÷ąťő|7Dß>w„ĘŤś–˝ =ňű¸vÝ…ň- ÁÎPděۧW®‹őÍŽŞÂ•¬rjj*§ţ‰áÔ?1ŮÇo§¦fW§9ŘŰZ·ëă~üuô˙DĹpęźhÜÝ«Ńú‘T­Z%×yĆ®kČĎĽŘŘŘP§¶QŃqśý÷ׯßŔÍ­•+»ĺ;×صlmm©Vµ É—.“xá"U«VĆŐŐ•ÄÄ \ĽŚ«kE\śť‹íŻ1^|ˇ/—.]ć×mżw†ĆŤćŞzŚŤ‹GQ~ţe{®ĎĹĆĹópófŘÚć®ä©Ył:.&ń÷©hîdÜÉ.˝ ĺŃ©ĐçVĎX‰Í4˝Ľ±'kÝúŤ…x%;ĂÎôéÝ‹ő6ѧw/Ís„˙ÎÎęĂąaĂhóhË\Ǣ˘c¸uë6wîÜ!ýÎŁzU«V¦k—ŽÜşu›“GË®=ěő4p?»na©W·QŃqÄĆĹsóć-š>Ř8_fa®ĺĺĺAňĄËDEÇá]Ă gNź>Cl\<Ő˝<ÍćŻ1ÜݫѸQ}NýĂŃŁ'hŐňaŕ~Ç”‡š5Éö .ţ qqgř÷ÜyęÖ©•K˧¦79Ɖăăăť/ eSžß…9×Đ9ZĄĹ˘čĺŤ=E‰E%;múôîeęG„rNíZ>;~’ŘŘxś©ZĄ2éwîPˇBĽkTG§Óqößó8˙uś ’ĐëőFőŽüyŚę^ž8;;áá^•¨čŘěAˤ§ßáÂ…$jT÷ÂŃŃÁŕuk˛Ť©Zµ*T¬čÂĺËWŃétÔ©cx2ci¬ĺ㍧‡; vĆiéűŽę€ďËW®Ň´iăBi?ÄŮ8őO >÷ü:>‘ôô;4i܇ű%l{ű ÄĹť!:&._°«XŃ·J®\ż‘"íu˙Ěý\·DśČ«ię5L*Ů ‚!ěyň‰Îüu4’żOE“™™‰““#Í›=HĹŠ.´y´%;AÜé3´jů0GŹErëÖml4Úî®\˝Fl\r”Ë—Ż’‘™‰ŁŁőęٍ֦°‘Ę‚PjűoÍzʶőSÝďű+’¨ ‚ X;mÚuÖšAEAĘv))7JŰAA°vuę>PÚ~B.víÜVÚ.‚PFéô¸>›Éʡ¤:˛´]ˇŚˇ( ±Ń'óŮ%Ř VŤLp Ba1ä˛*‚ BąG‚ť ‚Pî‘`'‚ ”{$Ř ‚ ĺ v‚ BąG‚ť~ÝşŤ¤ääŇvC¸Gjj*ÁÁÁ¸şşRłfM–-[V¨c‚ 2ôŔŻ˝>’oV.ÇÓĂŁ´]€ńăÇsâÄ ţý÷_˘ŁŁéÔ© 4ŔĎĎĎč1A)ŮiđâŔAĆ”©ÓůfŐj|[µĺÂu&îżńäSĎpçÎ4jĆŇ/—óXűNěÚµ‡ŁÇŽÓ·ß ´mç‡_ç'řvő÷ŮÚQQŃ˝ô O?@űŹÓ Q3¶nŰ^âi,K¤¦¦˛hŃ"Ţyç*W®LëÖ­éŰ·/ź~ú©Ńc‚  ÁN“oV.ŕË%_đţ{ăyáůţ<ř`Ţ}oéééLť6ť ŢĹŢţţęĎk×mŕ‹…źQżţ˙ßP^đ<öíbÉâĎ™4y§ţ‰"--ŤAÁCy˘K~ţńöí݉«««†BGŹ%55•¶mŰfŰÚ´iĂţýűŤA v…ĆĆƆéÓ&sŕŕď zeÍš5Ąc‡öąÎńĆk´x¸9‡˙8BZZ:µ|jňÇ‘?IIąIőęŐŮżďű$))‰çźďWJ))›$&&ŕ‘ŁJŮĂĂ„„ŁÇA@ÚěL˘NťÚ<Üü!ţ ëżĎwĽjŐŞ\ąr€ŻżYť}¬ĹĂÍ©á]¤¤dprr*§Ë ¶¶¶čtş\vťNgô H°3‰íŰ#HIIˇU+_,ř‚źÍ3ř@őń©Iff&S§LČWEţËVŇÓÓąví•+W&1ń©©©%•„2KőęŐHNNÎţ˙ŇĄKÔ¨QĂč1AjLŁ8;;séň%E!55Ť©Óf0áw™1}*»vď᧟à ~®s'?||jňîűą|ů Š˘pńâEÎś9KŰ6ŹâŕŕŔç Í[ŁBĐ!Ąc<üđø¸¸pđŕÁlŰáÇi×®ťŃc‚  ÁÎ(ÆţcǽdžŤ›XřĹby¤%­[?ĘőęňöH&Nš–]e™{{{ľZľ}f&]ý»ÓĽĹŁ Ä©˘¨RĄ S§LŕŰŐßó\˙Ľřâ 888ŕŕŕP ),;8::2|řp>üđCnܸÁźţÉÚµkyăŤ7ŚAĐJLTdiűńźCŻ×pëÖmiÝŽ7o QنĄě•ő°kç6‚‡ŽĚµÄOZZŻżţ:k×®ĹĹĹ…©S§\ŕ1AţÄFź¤~æů–úiШ™´Ů•4˙DE‘’r“ć5#55•3gS»v-4¨_Ú®Y=ŽŽŽ,]ş”ĄK—štLA‚] săú &MžĆ™ł˙Rˇ‚­Z¶dÉâϱ±‘eAK!Á®„iÝúQ¶lŢPÚn‚ ü§â„ ‚Pî‘`'‚ ”{¤S°jňöŞA( ě«%ç°A„â ăěA„rŤć8»ú ›[\§Ói6-sĽĺ‹ŽčŽaťŮ3'['/!cŢ/¶†µÝ+Áräl˛Ř¸a]‘uFľ=Ž3§ŁóŮ5«1‹ÓV˛kç6‹h‰ŽčŽĺtBÇ~PdťĽdd¨‹[[Ą Ř:ٵsť÷Ďe+ĘË’N§cäŰă “6;A˛Ůłk{i» Ůňr’·•z ‚ ”{$Ř ‚ ĺ v‚ B™ŕĘ•+fpiµ‚`'VĘ·«żçý&•¶šLšü!ăßů€ŚŚĚŇv%›5k×ا?Á‡2ÚpGˇl’ššĆaŻłk׆ {ťÔÔ4“>_âT’’“ ‡­ť-.ÎÎ|4k:NNNšvSt*T¨ŔˇĂ°}{üq„ ëż/’?żý¶›ĺ+VR©’+çĎ'2dđ+ö*Rşűô§ZŐŞŘŘŘ”śĚ°!˙GŹÝMÖÉbÉŇe,[ľ’˝»wÉźA8~üD®sŹ=l˛Njj*'MĺÂ…‹čltthߎ!µ×Ź3¤sěŘ ^8(×yŻ˝:Ś·GŤ0ŮźC‡˙`Áç_`ooĎŐ«Wyĺĺ—xúén&ëś<ů7ł>š:uŮ °Źfŕââb˛Ž©Ňéö”?ď0‰)“'K§(ţ\ľ|™ÉSg`gk‹““ď˝;GGÇěă>x‡Žťž@Qî–¨oĆt>ž;źŐ«ľ˘víZŚ|+ÔdíŇbé—Ëů~Í:~ůys¶í§źÂůjĺ7Tr«ÄĄäK<˙|?ú÷{ŽÔÔ4&Oýřř38;9q;5•ożYÁ»ďM 99™żáďß///&MxOÓ^–ĐëőĽőv(GŹŕčŃcĽőv( >ť‡­­mˇ4JĽd7}ú,üý»˛lé"|||řlÁFí¦č9ň'QQŃ<ţx'ţý÷\‘ý9üÇ&|đ.‹ľXŔĽąły÷ý‰¤§§)]6:K—,dń˘|8uăß5Ţ˝ŰŘ}8Ďńă…›ŔÎńهsmEŃ™:m5kÖdĹň%|ţŮ|*T¨`˛N›6ŹňĎßDz·˙őާž|˘HţŚółf|ČźĘgóç1iĘ´"鄌ÇŃołüËĹ<ؤ1ó>ů¬H:¦bHÇXµ´?ó?[_Çö„ÍžAŤŐYńŐ7EÖ2§oĆt’’’đôô`ŢÜŮĹň·$9räO.]şÄŮł˙fŰ>0™O>™Ă˘…ź1kć‡DEĹ0ëŁ0232Yőőr–.Y‹ł3Ó¦Nbţ'°pÁü쀦e/KLžň!Ű·Gä˛mßÁä)ZŁDť^Żgë¶<ѵ ţţ]ůő×mšvSuÚ´iÍË/ѸQŁbůĐ“şuëŕááAzz:&ë¬_÷]öywîÜÁĂĂ˝H:wďŢeúŚŹx÷ť1EN—©h餧§łń‡Í4iŇ7Ţ|‹™łf-ůjéčt:lmm±µµĺŕď‡đđp硇š)].ÎÎ|÷ýZôz=˙DEѰA"Ą+::†ĆŤŐüóxçNlݦÝß?_.[Á+˙7”ľĎ=ĎëoŚÔÔ(H`GÄo<ŐíY:vęĘá?ŽI'6î4_ fđWy¶goÂŮjÔ§»wď˛{÷^:vh€_Çü¶k7ÇŽť`@Đ ‚˙oQŤÂú¶}{A/˝ÂĐaŻôŇ+\ĽxŃdťíŰ#4€W‚‡2 hű,´ĄÉőë7pvvÁŻcGvDěĽ@§#1!€ ęóŢ»ă¸{÷.ŘLpđËčt:–,ţĽĽ.Y&M|ź¨Č|ۤ‰…‹W˘ŐW®\%-- //OĽ<=9űďżšvSur˘Pđl Z:ÍsôôtţřăOfÍüĄ_®PßB熙ě¨/ź|ňËľ\Tät}ňÉz÷éĎ/żü :+WhŻX®Ącooʇ‡;QŃ1<ؤ1űüN½‡MQҵdŃçčőzš>Ô˝^ŻYÝRNTT4á?obý†6m†főĽ1ť‘#ßfđ˙©ŐńżüşŤ¤¤$Ít\»vŤôôtÜÝ«ŕî^-ű^„Í™KȨ<ňH+:v2^/Č· .ňÎ{đKř*»ąńŢĄ|ľp15JZ:O<Ń…'žčBFÍXľl1…ňËص{ť:uDź™Éú ?0čĺĚ˙dŁBĆđč#­xýµáÔ©S›«WŻ‘’’Býꕲ×eŹ-Ůĺ]Ť[§S'űŐ˛›Şc.˛X˛tgÎţˇSŤw0¦Ó¨QCFŚxť7ß|ŤÚµ|X¶bĄÉ:çÎťcßľ<÷\źb§kě/ZŔÚ5ßâčäČ[Ł´Ű5´tô™j‡„áĂăěěL˙~}ŘąsW‘ü5wîěW`űŤ1ťőë70|Ř`žľ?gÎśeý†LÖŃétL™4·CĆ0třë\ľ|;;í÷Acţtďö‹—,cĆĚ‚«Ň ş?C‡cccC»ÇÚň÷©LÖąví§ţ‰˘[·'xĽł˝ hÖéňj©ÓmĄ¦¦wÚh Üߎů“ĚĚLĆŤŹáŻ˝ÉĎáżg˛NYć·]»ńóë@§N9üÇnŢĽ @»ÇÚňËĎ›iÝúQ^4Ą_.ç^aN(%ěŞT©Ś““/Şo•“’©UËGÓnŞNN ó0¦óńÜů\ĽÄĽŹgř–hL'))™Ęnn4nÔ±cBYłF{Î7-ťŁÇŽć =ž äég¸téO? Ů©0÷ÇÖÖ–—ľČÁ‡Lö§zőęŘŰŰŕŕŕ`ô~óGŻ×óĺ˛ô Đü|A:wďŢeĹWßđĘ —xqŔó|±đS>ž;żHţ´jĺËĎ?ţŔ˘…źŃ¬é<`ä ZKGŻ×ó\˙xyyđĆëĂ‹ś®,˛đw2îŕââl˛ŽŤŤZ˘ĚĽ÷’âŕŕ`´¦ŔÍÍ GGG.]ş ŔĄK—¨QŁ:wî¨Ó€ŮŮŮ™d´|«X±"5ŞWgá‚ů,\0źŤëżgĺW_š¬SVŃëőśúűăĆżÇ;ďM ˛›»wďŕĎ?˙˘B… ô{®Ë—-&lÎ<ŞT©Be77bbbKŮó˛G‰—ěžzň‰ězéť<ő¤ż¦ÝTsůłfÍ:ţ‰Šâťńcň˝IšęχÓgfźwäČźFZ:Ďôxšźü!{swwççŔÉÉŃ$€…_,Î>oëÖ´lék˛?•*ąŇˇ};6ţ ö;tř:thW¤űł˙ŔAśťś¨^ÝKóóéčt:*Vt!>ţ öT«V­HţĽűŢD233Ńëő¬ţn ýŚ”¦µtRnŢ$))‰'ýźČEIW^~ţůďÜÉdťJ•\iŐĘ—_}˘((ŠBJJJ>éčä×˝űö°wß:wę«k%*V¬H\Üivţ¶»Ŕ´ä[ëÖŹrĺĘUöě٨/©ĆÚěĚőŰ·ţřă}űöÎö/ż<í÷Ҷfí†ěŠ))Ôň©‰N§Ł_żľ|úŮBôz= ¶Ç–WvíÜVč­ J|čÁ¸±Ł =Ž;qpp ěŁFí¦čěÚµ‡U«ż#==ť[·n3üµ7}ű-“t† {ť?˙ü‹‡}[gź±ý—ěö SŇőďąó öiiéddf2OŁ]« €ťżńÝ÷kąző*!ŁÇ˝GZ:±±§2ô5n§ŢĆŐŐ•ŹĂfjjÓ™6mŁÇĽĂŽ;±µłeĘ$ă˝Lµtöď?@ť:µŤ~¶ ťNÇěY3x÷˝ ¸»W#ĺć-f4˝Hţ4iŇAÁCHMMŁMëGyqŔó&븸¸Đ«ç3<Ű«/ť;űáččȤÉÓläűŢ»úwÇŢŢžZ>>Ěś1µHéš6‹ńăßgă›ptp`ذ!ô|¶‡Q­7^Îä©ÓŮ·ďöööĽ˙Ţ8lltżňo˝=†!_ÔZ±cBŚjiůćääČ’Ĺź3aŇT¦Mź‰ŤÎ†đü˙ú™¤“őŰxsÄ(śśśËDoĚO>]€Ł#Ż z ˝^Ďö;8u*ЍÁÁÜľ}›ĽDĄJ®ÜĽu›ŮłŐß꨷Ţdę´ô čKŐŞU¨Q˝Íú0{Ŕđ×ŢĚ7ô ŻÝÚŃ™ąÎÖŕzvő6-ö,ăÁCGf/ńc-EQDGtDÇB:łgN&těf›şm;?ěě*XU‹«#XŽĽ«lܰŽÇÚu(’VŰv~ů–řiШ™Ě "‚ ”$Ř ‚ ĺ v‚ BąG‚ť ‚Pî‘`'‚ ”{$Ř ‚ ĺ v‚ BąG‚ť ‚Pî‘`'‚ ”{4§ +Ě\c…Ĺ\Z˘#:˘c9K`mi´ć{%XÁÎśs’™KKtDGt,§‘qÇlZ`}i4÷\‹‚yÉ;mĄą1ěĚuŃŤL[óJ„Ň!t섎5>™wy`ÇŽĄí‚PJ vő6-¶pÖ[TĽV¬«Ó‰ŽčŽ•ëXBÓ:us”čştéR\— aéIş5ŰěŠ;˸ ‚ X ŇSA(÷H°AĘ=ěA„rŹf›ťąIJLdÔŔŘÚŮáR±"a+Vŕěâ˘iŃť’×±fß,‘FáżŃ’Ýšµë ěÓźŕÁĂ=®Xš“|N­zőřtÚ4ŁvŃŃ)yköÍiţ[(1Q‘ą6EQ”¨HĹÓÓSٱ-\‰‰ŠTžéń´©´iÓZqrrʵĹDE*űöîTÚ·{Lńóë <ŇŞ…(€Ż(Jlf¦âčä¤ěŤŹWâEYł{·ň@ăĆšöxEɵ‰ŽčŽĺurnÖć[qt˛žE€"X/9cĐ왓•=»¶iËȸ“/¦ŠŃj̤¤$<==7wv¶ýřŃĂůÎť>}ţţ]yiŕ‹ĽńĆ›ąŽ]IN&-5/ooĽĽ˝9§i×BtDGt,§cÍľY"ŤÂ Ő›6mb@Đ ^ Ę€ Aě?pPSDŻ×łuŰžčŞŘléŰ<÷Elr_F§Ó˘hÚ5ťŃ‹éXło–HŁđßÂ`°ëŐ««ľ^Ŕňe‹YőőrÚ=Ö€7gČĐ×čݧ?ď0‰kׯsĺĘUŇŇŇđňň ˛›[.˝*îî8»¸p1!€‹ ÔŞWOÓ®…čŽčXNÇš}łD…˙&=;&„Ĺ‹°vÍ·8:9ňÖ¨PoWy.bcĂSlŰĽ€í[¶Đ­woM»¦ł˘#:˘c1köÍiXµjAAAb/%{I˘Cí ’ËXżaSbŁOŇ Q3"ŹÁÁÁÁŕ‡Ďť;Ǔݞ%ňřZ´lCřO›¨YÓ›ĄK1}Ö<ŕţÜÉ.0jŕ@llmqptdîĘ•¸¸şjÚs’s~<ŃѱśNN¬Í·˘ęäśSÉ“ÎĐĐPÂÂÂÄ^Jöśäś˘ră†u<Ö®ćąĆhŰÎŹ3§ŁsŮ4jfz°[řĹb†Ŕ˛e_±uűV}˝śĐ±řú¶``ĐFŚÉOáęü†~D¦bM“ĘŠŽčNÉiš{"hc[ˇt±t°3Ř3<<ś°°ŹxsÄ(śśśł{cĆĆžfČĐ׸ťzWW”#%G IDATW>› Ŕ¸±Ł =Ž;ą™rŁHN ‚ ‚%0ěşwďNĂúµ ~ŕŁY´{x¸łbů@]ő xčH3ą(‚ ĹCćĆAĘ=ěA„rŹ;AˇÜŁ9]¬6.‚ ” ;]ŢQáĹ ®™´DGtDÇúu,ˇiNß"""̦%—Ú>^Ő7ěĚ1%+`ZËXŃѱ¬Ž%4Í=ήK—.ĹuI°9ÇŮYÍjĚâ\XŞ@AkB:¨‚ ĺ v‚ BąG‚ť ‚Pî)±`—”Č‹ţţĽÔ˝;Ż>÷·oÝ2j/Ełá1źűűżď†—şĂčŰ~\S8żňęüďqhZ1÷VťÔŰ0v0ôď z¨KKçüÜ ęę`H şĺĽF^~Z ýüŕ˙zB÷‡aýJŐž™űvŔä· WëÂůa®ď]tJFÇš}łDó˛lŮ2t:DDD ÓéXĽx1Ď?˙<:ťŽž={H`` AAAŇ8y3÷VťcŐŕđÝNXţ¸"hZJ§fX¸^ýńFu{ěqíĎŢ“ćĂŇÍ05Ś éiđÇ>řçtyÎĆěď{ť’ѱfß,‘ĆĽ 8P{mfőÜ8p «WŻ`Íš5lܸ‘Ť7âăăC۶mYż^ýqmܸwwwMűŇĄK9tč;věŕ—_~!%%…éÓ§Ů_Á4”¨Č\›˘(JLT¤âéé©ěŘ®ÄDE*ĎôxZ‰‰ŠTŽ=¬ôí¨thßNéر˝2vL©ěŰ»Sißî1ĹĎŻňH«  JĽ˘(±™™ŠŁ““˛7>^‰WeÍîÝĘŤkÚă%×–ĄŻ(Jś^Qü{*ĘÁóŠR˝ćýsš4W”·'+Jl¦˘¬üUQÚwUФӶsţĎ™Ş§WW7Eůů/ëЉW%&CQ p:›)ĘÉ›Şíčős'®ß?ďP˘˘T®Z°ŽąľwŃ)ťś›µůVť¬g DFFF®ó%555×˙)))Ę_ýĄůcö–-[*áááŮűÇŽSjÔ¨ˇÜ˝{WQEůő×_ ĺgy$g š=s˛˛g×ö"mwňĹ4@Ńz””„§§@ö?S§Í f͚̜1ŤÔÔ4ľű^­/ś>}ţţ]yiŕ‹ĽńFîbŐ•ädŇRSńňöŔËŰ›łqqšvc¬\O€—wnűgß«Uk?ŻSWJ˙¦€ŃZ:ľm řY¸tzĆ|•«š¦ső¤\‡úMŚűPR:yůúsč=P»”řđŁ÷˙_8 zAĹJąĎ)ĚĐ's}ď˘S2:Öě›%ŇhŚŔŔ@ö~ýúqűömęŐ«Ç’%KLÖ=qâ 4ČŢoÔ¨‰‰‰\ąr…jŐŞe—óc°sÓ¦M Ŕ+ÁC4ý’žžÎĆ6Ó¤I#Ţxó-fΚM``/ôz=[·íŕ‰®j±żĄoóܱÉ}ťNŠ˘i×âßÓ°w;ôÎlírxuĽ8 ÎÄŔşÚ‰6¦3~|ą6'gxóÓuL­r·´NN†Ââ0Đg¬·h6śŤ…‹Mó# s}ď˘S2:Öě›%ŇhڬŞĘĽ¬Ył†eË–ńŕI7ŻżYÜ˝{@‚ť1xç{őęĹŞŻ—°|ŮbV}˝śvʵĺÜůŇÓÓůăŹ?™5óCŞU«Ć&sĺĘUŇŇŇđňň ˛›[.˝*îî8»¸p1!€‹ ÔŞWOÓ®ĹŃß!>ş5‡§‚ä ęß[7aŮ'ü˝Ş¶ŰÍů@;ŃZ:©·ďźck Ţ„;M×qtVK…—oiťśéZĽ–lgăZaďĂ…ój›ťcţă…yžë{ť’ѱfß,‘ƢR»vmBBBŤŤ5x\«Ä·dÉš7oNLLL¶-..//Żě çîîN·nÝĚď´`ZoL}¦Z>l0ÎÎÎôďׇť;wx»Ęsž dŰćÍl߲…n˝{kÚµxöđë‰ű›GuőŻł‹ZÍo%vG¨ć©ť-'gXŁ­ř׍Ъťé:Î.đż˙O¦Ŕ˝[Fě©ŇÓqrÎ}^æ`WA[绥pę8Ľ?4^D …ąľwŃ)köÍiXµjAAA…>?'ďľű®AűÎť;5íŻľú* ,Č.É-Z´W_}5»fZZ'N,´źeÝ^’čP;¨ä2ÖoŘ”Řč“4hÔŚČăGpppŕĆŤZ=úG˙ü®]»†_gŽţů;-Z¶!ü§MÔ¬éÍŇ%‹>kpnĚä 5p 6¶¶88:2wĺJ\\]5í9É;?ŢŽáŰĹđ[8<Ó>^ »…Ůﻤ܀ŃÓ uGLÖ y®^†Ű·ŔŐ ¦|Őkš®s'&˝Ąöl¬ę޵ lEéč„NU{§n۬¶ç Ź´'Y:˙{Žě‡ 9â®Xüľ^¨öĚÜ·]í• j»fæ†ý1×÷.:%Ł“kó­¨:9çĆTň¤344”°°°lűüůó1b?ţř#Ď<ó sćĚáŕÁ|÷ÝwřůůeżÜWŻ^ťQŁF1mÚ46oŢLçÎ긠ż˙ţ›M›6´_¸piÓ¦±cÇ*T¨@Ó¦Mů裏°łS»Olٲ…ž={čgy±ç$ç•7¬ă±v4Ď5FŰv~ś9ťËÖ Q3Ó‚ŔËóÔSţĽ8ŕy¶nŰÎşőY¸`>!ˇcńőmÁŔ Ś1’źÂŐ"†~D¦bM“ĘŠŽčNÉiš{"hc[ˇt±t°3Ř3<<ś°°ŹxsÄ(śśśł{cN›6‰ŃcŢaÇŽťŘÚŮ2e’Ú86něhBGŹcGÄNn¦Ü(’“‚ ‚` »îݻӰ~mđ©Y“ożÉßŐŃĂĂťËŐ†Ů];·žíoZş†ŤVW1ĐŁĚ] .®¦é\»źĎ€.=ŕr’şbůäOŐŐ´HJLdÔŔŘÚŮáR±"a+Vŕěâ˘iťŇŐI˘ţ++#vKűcÍ÷Ęi4'Ë–-ŁFŤ%~]ˇp-Ů­Y»žŔ>ý <ŚŃăŠuˇ)ŁŔ§.|˝m€ öж3ÄdÜß^ÝŚ,Eeěü©!ęň5_…C­zđé´˘éŘŘŔňźÔŐĘg,†±MO¨wÜLXů 4mO4]g콵ő®ŤUß&0ĺčÔž ŕ«đpjիǧӦµ‹Néę„@8PV€ÝŇţXBÓÚt,Ĺ Aps3ň&*”:JLTd®MQ%&*RńôôTvl Wb˘"•gz<­|łrąäÚ^{u©ěŰ»Sißî1ĹĎŻňH«ŮÇăEů'UQĺ‹őŠňt_EyéuEů벢Ä+÷·o¶)Ę÷s۲¶,­óc3ĹŃIQöĆ«űkv+ĘŤM×É»­ß§(őjëhĄëźTEŐŻxEQ6P”Ú®ŁžŁŹWĺ×j:c2 ëÄff*ŽNNĘŢřř{÷a·ň@ăĆšv-DÇň: (™ 8o7(ŤŤŘ•<›ąÓ•sł¦{U\ťśĎ«,¶nÝŞ´oß^éŃŁ‡RµjUĄnÝşJ@@€ňěłĎ*€˛yófĄqăĆŠŹŹŹ˛{÷nEQĺăŹ?V:tč ôěŮSéСňÉ'ź(Š˘(˝{÷Vzöě™­żuëVĹĆĆFY°`R«V-eÄĘ˙ţ÷?ĄgĎžŠ MÎ4{ćdeĎ®íEÚ22îä‹i€b´3)) OOćÍťŤ˘(üó÷±ěăLĚSO>Ŕôéłđ÷ďĘK_äŤ7ŢĚĄs.^]đóđ^˝–Ě÷^…OżSŹßI‡ąaExá˘sŢóŻ$CZ*xy«ű^Ţp6Ît€G`ír¸gbá˵?Ż•®ů«ŐUÂŁNŔ-`$ś5]'ëţdQݎšÎk—ŐEjór%9™´ÔTĽĽ˝ďÝoÎĆĹiÚµť’ŃIR{Ůo ÎÝŇţXBÓÚt˛ â—_~ˇE‹ÄÇÇăççÇĆŤIKKĂÉɉ'NpňäIV¬XÁ¨QŁ8tčăÇŹçÂ… ¸ąąqáÂfĚŔúőëÉĚ̤½Վýýý©RĄ ÉÉÉś:u 777öíŰGŹ= ôK°«17mÚÄ€ AĽ<”AŘŕ :ť[[[lmm9řű!<<Üyčˇfčőz¶nŰÁ]Ő†°–ľÍséefŞ_§¶§ýď˙ â§űÇżţZ»Ť-/yĎ·É“ ť 3j×Đu?oM„‘ öđĺ\íĎkĄK§ÂČap/Hľ¨¶%šŞ“˝^ýkW!˙1 {ĺ,t:(Ц] Ń)!ť<űYŮVËni,ˇim:Ydffâä䀝ť]ľYŁĆŚŤŤ ]»vĺčŃŁŕççÇĉ‰ŽŽfÎś9FŻ1nÜ8śťťquuĄuëÖ(˛pl©b0ŘőęŐ‹U_/`ů˛Ĺ¬úz9ík›}üÎť;|ňÉg Ş6h]ąr•´´4ĽĽ<¨ś§Ţş†Źú7kÁsÇűů13Ď>/ÎaCçWqWÖĹu˙b‚ÚngިťR*W…&Íaü,řn©¶†±t=Ň~=K6ÁC­ÔÎ%EŃÉIôIµÔęVŰNwwś]\¸ Ţ‹ ÔŞWOÓ®…蔌Ž;j§“{Ů–Ôö9-»Ąý±„¦µéd1mÚ4ÚµkGŻ^˝µt§…±tŤ ™jPývô.šNz=,ś / Íł°±±á©Ŕ@¶mVoÄö-[čÖ»·¦] Ń)! ¸—mŮô6b·´?IŁ•édńăŹ?ΦM›§C‡Ď[łfMvPëׯľľľ„„„°iÓ&öíŰWŕu´XµjAAA˙y{I˘Cí ’ËXżaSbŁOŇ Q3"ŹÁ!«Ččőzďúkľ[EőęjĂŃÝ»wiѲ á?m˘fMo–.YÄôYó€űs÷ť‹‡·_VŚťLýŞ×„™ă *–nF“śóăiťź|Aíic«–Ś uő/ŚÎ3­TżŇR!#&χ&këhĄëă đűnH˝ m;Áé`kkšÎŠOŐˇ]źQKśŹv€÷ÂňWcćÔIľpQbck‹Ł#sW®ÄĹŐUÓ.:ĄŁ“Upż€:ÄŔpV®Fě9É97¦ąŇ•kąWĹŐÉ97fVUbPPű÷ďÇőŢy...ôë׏áÇăääDýúőqpp ^˝z,[¶ ž}öY._ľŚ‡‡iiiĽňĘ+Ľđ ôéÓ‡ĚĚL6oŢL@@‡"99™ 0xđ`ěííů믿đőőeďŢ˝´nÝšĐĐPÂÂÂňUmţ×ě9É9EĺĆ ëx¬ťá‚hŰÎŹ3§ŁsŮ4jfz°ŰłwS¦|Č/á[r}&$t,ľľ-4€#FňS¸:?¦ˇ‘©XÓ¤˛˘#:ćĐ‘‰ KNÇP°ëÜą3+V¬ nÝş(ŠÂáÇéÚµ+ÉÉÉ899IűZ)`é`g°ŰDxx8aađćQ8993oîlöď?@ť:µó}fÜŘŃ„ŽÇŽťÜLąQ$'AJ‚FŤ1`ŔÜÝÝŃétÜşu‹ĺË—óńÇČ#čÚµk){* Á®{÷î4¬ź? Ś}Ű ÝĂÝ˗ęŞÁC ý,‚PJ,^ĽXóŘřńăKС¤nB‚ BąG‚ť ‚Pî‘`'‚ ”{4çőŐĆA„ň‚Á`—węśâP×LZ˘#:ĺIÇ\ż0kK—%4Íé[DD„Ů´óRŰÇŔ„żfÄ`°3Ç“ě€iŽń*&Ěé÷źŐŚcmßWyÔÉ«i…téŇĄŕ“„R!ç8;K YŤYś K¨ ‚`MHAˇÜ#ÁNA(÷H°AĘ=%ěÁßşw‡çž[·`íZđóž=áá‡aĺJăgÎ@Ż^jăw` şůřhŰMőÇ˝¬čĆ‘|X¸űd)MA(%Ś»5k×ا?Á‡2z\ń®őęÁ´i°gĚź›7ĂęŐ0t(¤ĄikÔ©ë׫˙oܨnŹ?®m7Őcö˛˘#GňaAwȲš‚PŠ(1Q‘ą6EQ”¨HĹÓÓSٱ-\‰‰ŠTžéń´©|»ę+ĹĎŻňÄ]”V­|•ůóć(1Q‘Ęľ˝;•öíSüü:(Ź´jˇę¦( ™™ NN ńńęţîÝ Ť+:¤pó¦j»rE=˙úuu?ç–ĄŁ( ą÷ ˛ŇŃňGË^td3ľI>,X'çVNó¤`˝äŚAłgNVöěÚ^¤-#ăNľ(FKvIIIxzzd/ń3zĚ;Ěšń!_|ţ)źÍźÇ¤)ę[Ýôéłđ÷ďʲĄ‹đpŻ–[(9RSÁŰ[Ý÷ö†¸8xôQpqQmłfAPTŞdĚĄÜ|ţ9ÜĽYx{AţhŮËŠŽ`ɇ…Ď?’'…r†Á`·iÓ& ŕ•ࡠÄţpqvć»ďע×ëů'*І  ×ëŮşmOtUl¶ômžç*y.“wëěŮ F–ÝČG` „…Affáě…ń§ ?­]G0ŽäĂÂçÉ“B9Ăŕ ň^˝zŃěÁ4hÔŚĺËçZ©ü“OćĐ»O~ůĺWĐéXąb)W®\%-- //O*»ąĺtwWßśÔvŤ„µ®ŕý÷Ő·ßŐ«ó˙ڱq#śl0Ď?ßź3gβ~ĂŘäy8ä›)ČĆF}ÓÝĽYÝ߲z÷†ĄKářq3Ç´LM›B… …·䏖˝¬čĆ‘|XřüóÉ“«V­"((HěĄd/i4;¨Jäń#Ůö¨SÇGGGĺřŃĂJLT¤˛ň«/'''%ęÔqĹÉÉIů-b«©Ś32wÇEQHLTđ÷WčÖM! @áĆ …Îťěí\\îo.h7 ÇÇ+ôě©î(ěÝkÜ®ĄŁĺŹ1»µëČf|“|X8ťś[9Ě“y {)Úsbé*:@‰‰Š$'ő6%6ú$ 5#ňř‘ějLEQhס3Ë–.âÁ›päČ_Ľ:–ť;~!$t,ľľ-4€#FňSř˝ů1ÍQźomŢZŁŽ`kűľĘŁN^M+D‘öE«%ç|Ě7¬ă±vФӶťgNGç˛5hÔĚp›]xx8aađćQ8993oîlt:łgÍŕÝ÷&ŕî^Ť”›·ýŃtĆŤMččqěŘÉÍ”ErRA,Á`×˝{wÖŻmđ;¶§cÇöůěî¬XľPW=:ŇŚn ‚ BŃ‘ą1A„rŹ;AˇÜ#ÁNA(÷h®T.«Ť ‚ ĺÁNgÎnĂćҡ8XŰ÷U^u¬śŇvAĐ ¶Ź—Eő ;sŚE1kŔ4'Ö4.©<ëe KŚłł–<™#?véŇĄ –"ç8;K YŤYś K¨ ‚`MHAˇÜ#ÁNA(÷H°A(_~ů%Ď?˙<ÇŽ+mW„"đß v;wŞŤÖ9·÷ŢńăŐ˙źyZ·†áúuăZ‰‰ŕďÝ»ĂsĎÁ­[Ćí†8szőRݍn>>ÚvKë+]BŮĆ\yŔÚtŠHpp0cÇŽµŠĄjÓ1ěÖ¬]O`źţFČčq%ĺ“ĺéÜ22îoC†¨krMW'µfÝ:8xP]»kds|†„@@„‡«‹XN›fÜn:u`ýző˙ŤŐíńǵí–Ö1Wş„˛Ťąň€µé___âââ,¦/XŁKü´ďŘ…Ő«ľ˘víZŚ|+”ysgsňäßĚúhčŔŃŃ‘°ŹfŕââBRr2ˇˇă°µłĺö­›üqäh館 ňvcŢľ~ű &OV÷u:HMGGŚTKx7n€]ŽŽ«Yݡőzpu…ż˙VĘž=0x°ú9CöS§r_;g·ęĚLuˇĎĽţiŮ-©cŽt e‹ĽůÂ\yŰträGs «rssăzA5>‚ÉXz‰Ł%»¤¤$<==7w6!ŁÇ1fôŰ,˙r16iĚĽO>`úôYřűweŮŇEx¸W+’“%Nz:LścÇ>ްˇř._6|<9Y=îí­î{{C\ś¶˝°|ţ9ÜĽYx»ąu,•.ˇě`®<`m:f fÍš\ąrŢ×ĚŹÁ`·iÓ& ŕ•ࡠÄţIOO'::†ĆŤđxçNlݶ˝^ĎÖm;x˘«:`łĄoó’ńľ¸|ţ9<ý4¸¸>®×«+T0|Ü&ĎíËz Ő˛†Ŕ@ SKb…±[BÇéĘćĘÖ¦c^ýu:tčŔęŐ«-zÁĽTŢ«W/š=Ř€Ťš±|Ůâ\+•{x¸ĂMł˙Ŕď$$$rĺĘUŇŇŇđňň ˛›[ÉĄ ¨dfÂś9°oźö9'OŞoŠUŞ>îî®Ę„µ %!Am3в†ŤŐëć ŔZvKčX"]BŮÂ\yŔÚtĚ@XXÇŹÇĄ°żEÁ*0©7¦N§cʤ Ľ2†ˇĂ_çňĺËŘŮŮa“çíŞL4ŮDD¨?­^‰z=Ěś C‡j'ČĆF-)mެîo٢vtѲ–¦M —&µěćÖ±Tş„˛ąň€µéäaŐŞU{WjŮ._ľś/Đ™Ş#ö’Ç䡭ZůňóŹ?°hág4kú ÷´iŐ«Ă;ď×™=~řAíöü÷ßęcvCś9}ú¨˙Ţ/mjŮ-­c®t esĺkÓÉÁ‘#Gřć›o mW}VóF1tÄ^ňíŤŮ Q3"ŹÉ®ĆxőµĚ˙d:ťŽŃŁGw^ř"!ˇcńőmÁŔ Ś1’źÂ­t~Lk™ś¶Ľëe‹˙ČDĐĹ鍙––ĆöíŰ™4iż˙ţ{ń|ňaéŢŰěÂĂĂ ű€7GŚÂÉÉ9»7f“&Ť<„ÔÔ4Ú´~”<Ŕ¸±Ł =Ž;ą™rŁHN ‚ X+kÖ¬á÷ßçűďż/mW„"`´dWTvíÜFđĐc—Öň¶YŢu„˛…”ě„R¦TÇŮ ‚ By@‚ť ‚Pî‘`'‚ ”{4W*—Őơü“݆eîvVEťť´‘ V‚Á`§+Ď Ě•6ŃĘ–J÷^±1cžŚ0›–`^jűxYTß`°›=s˛YÄCÇ~`==˛Ě­S^±¶űlm:ćÂZŇ•Ąaˇ’ťŮü+®Ć=ştéR<-Ábg@aĐ¬Ć űA±„32î[C„’Ă\UŽJy~Ę,šÁ`Ď®í%ĺ‡ ‚ X ŁÁN„˙KfŇů‡Ľn!OÁ|ČĐAˇÜSr%»ÄD8ěě bEX±B]bGË^VtĘ+Övź­MÇ\X2]?˙ óćAĺĘęĘŁG«ç‚ëׯłdéWŘŘÚŕčŕ@đ+/áŕ`oĐ^Şi”߬PHŚ–ě~üńgţoČ«„ŚÇ”©Ó‹wĄ€đpuqĹiÓŚŰËŠNyĹÚîłµé K¦kĎ?_]ëmőjumĆ´´BąőÝš řú>̨‘Żăî^Ť 7j/µ4EGřOb4Ř-^şŚÉß'ěŁdffş|ů2#GŤ&$tď˝?‰[·nÝ?¨×«+d÷ęĄîŔúőÚv-¬M§Ľbm÷ŮÚtĚ…ĄÓ ޶5Ô@wçNnÝ˝{—żţ<Šo‹ćřú>Ě‘?ŹjÚK5Ťň› ‰Ń`wéŇeÜÝ«0iâűF…ć¶żŽí ›=5Ş3}úŚű““!5Ľ˝Ő}oo‹Ó¶kam:ĺk»ĎÖ¦c.,ť®G˝_ť7k–ü*U*Đ­”›7ą“‘AĺĘnTvs#9ů’¦˝TÓ(żYˇlł‹žOLLĚý*… ÔîÁ¶¶ęćĘ•ŕęŞmĎĺĄÎútĘ+Övź­MÇ\”Dşzö„ýűˇB…űź‰ŤŻűî*9ćĆĚš.lÉâϸ~ăK—®@gcC… üŽŽŽíoĽ’;iy5Kű»3˛Ryhh(aaab/%{N,˝RąIÁîĆŤz<Č/?oćbŇE^zy0żEüŠ­­-“§|HłfMéŰ'…_,ˇzŤšĚž=Űz&Ľ5·NyĹÚîłµé +I—V°3…Ľ3¨Ň,2fžşŔ6FˇÔ°t°3X·qęźű'ľ÷Á$&Lś@ĄJ®<é˙‚‡°aăfřxî|Ţx}8»÷ě%$tgÎśĺťwĆÉQAA07{c6i¬ŽÍ14ô„ŢÉţ?dÔě˙«V­ĘÜ9eď»ć­ŽA„RB&‚!2±łP‘`'‚YŃ™káVA0#ěA0Ů ·ćXýÜ\‹Â Bq`'PüĆ%¨ ÖŚf°ËČ(xÂŘBa®îÚÖ¦S^±¶űlm:ćÂZŇ• ,1"ë˙âúhĆď.""ÂlZ‚y©íăUđIĹŔ`° c|Ňç 3÷ĂĹJĆ%™]G([X[ţ1×86säĹś:y˙/®Ĺ!GÚştéR<-Ábägg 4KvĹąđ®ťŰŠüYAJéL"X+üşšüťN§Y+)mv‚ ]ÎŞK  B11ĄĐUP!Ë䉠Aˇ¬!ÁNA(÷”˝jĚÄDu†s;;¨XV¬P׳Ҳ—ˇlamůÇůĐÚ|“ßšP Ś–ěÖ¬]O`źţFČčq|»ú{Ţ˙`RIůf€đpu‘ĆiÓŚŰËŠŽP¶°¶üc‰|hmľÉoM(&JLTd®MQ%&*RńôôTvl Wb˘"•gz<­ü~`·bčü¨HeßŢťJűvŹ)~~”GZµPónŠ˘™©ŕ䤯îďޭи±¶]QroÖ¨#[ŮÚ¬-˙S'çfmľG'Ç÷'X/9ăÉ왓óŮ Úľ\4O”ŚŚ;ůŽŠŃ’]RRžžĚ›;#UÓ§ĎÂßż+Ë–.ÂĂ˝š1٢“ś ©©ŕí­î{{C\ś¶˝¬če kË?–ȇÖć›üÖ„bb0ŘmÚ´‰Ax%x(‚±˙ŔÁěă;"~ă©nĎұSW˙q˝^ĎÖm;x˘«:`łĄos y›ÇݬîÍZö˛˘#”-¬-˙X"Z›oň[ЉÁ`׫W/V}˝€ĺËłęëĺ´{¬möń¨¨hÂŢÄ[#ßdÚ´\ąr•´´4ĽĽ<¨ěćfoÝÝŐ†ç„u?!A­Ł×˛—ˇlamůÇůĐÚ|“ßšPLŠ4ô`č`lllh÷X[ţ>ő6yŢ®,6 –Ť ÂćÍęţ–-Đ»·¶˝¬če kË?–ȇÖć›…~k«V­"((HěĄd/i4;¨Jäń#ŮöČăG”śçoýőGĹÍ­’uę¸âää¤ü±U‰‰ŠTĆŹi™ŽŠ˘¨ŕďŻĐ­›B@€ÂŤĆíŠb¸!ŢZtd+[›µĺsëäܬͷ˘ęäřţň"öR´çÄŇTt€INę7lJlôI4jFäń#888žžNłć­Č:Áç_GŘ완„ŽĹ×·0bÄH~ 7óü樇·¦ xłt„˛…µĺkұ„¦™'‚V¤=ĎjÉ95ŘĆ ëóľÉÓ…IFĆÎśŽÎu¬AŁf†•‡‡‡öoŽ…““3óćÎÎ>ŢŐż;öööÔňńa挩Ś;šĐŃăر“›)7 źBAA°0]÷îÝiXżv>»yKYxx¸łbůŕ~„Ak@ćĆAĘ=ěA„rŹ;AˇÜŁąę¬6.‚ ” ;ť5v‰7—OÖ¦#”-¬-˙X›Ž%4Íč[DD„Ů´óRŰÇ+źÍś….ÁÎcQĚ0­eĚŽčü{wUą?pü3`ČrÍD·ŇáĄ$ ®ârŻši™–^E%E,ď­_îKeZ¸…¸äŻ\ĘkţüQšš,ŠšI¨)KîK˘¦2¸pî“(03ĚŔŚ3Śß÷ë5Ż—ç9ç|Ďó<3Ηsć9ç‘8çńĹ4ń}v;v¬`…„ą”Ľ§ÎÔ9DçeLcnć+I. !„¨Ôť?š4ž PBaó$Ů !„°y’ě„BŘ<ťżŮY­óçađ`¨Rţö7Xľ\3ź•®r‰#q¬5ΩS0j”fzšČHMŮľ}–¦˝üĚó·ËZűĘ\mV+4¬“Ńű¨T*îŢ˝ŁuťŢ3»µëľˇWź~DNěř‰FŘ,bc5_ÉÉšI§NŐ_.q$޵ĆiĐľůFóď 4Żt—?Žv™#¦µĹ•FnÎa_Ë–|Zf<ťóŮą»»+۶&+Dz)/˝ŘCď\Béi;”6­•°°P%(Đß<óÝ»§ŕä¤pň¤f9%EÁÇGwą˘cn,‰#q¬!Ž˘(Ü˝«}>9]ĺć®Ď—µőUEâč™ĎNXsĎg§÷ĚîŇĄK¸»»›âG›éÓgŃąs'–}±·Z5Ḛ̈ĺrů2äçCÝşšĺşuářqÝĺGâXsś’ŕćMĂËÍYkë+sőąxbhMv7ndŕ (^ŹĆŔAQěÚť@îń ~-šˇoľÍË˝Iţ~ ÷ďßgËÖm„wŇܰŮ< ™™j[˘şn8ŐU.q$Ž5ÇyTŻ^0w.Ü»gXąąëcm}eŽ6Š'ŠÖd׳gOVŻJ iŮVŻJ˘MëVÄÄŚŁoź^,]’Ŕ¨Q#ą|ů2WŻćˇV«ńđpŕ™ęŐÍSŰZµ4?<ź;§Y>wNsŤ^WąÄ‘8ÖçQ6ŔĆŤĄVč*7w}¬­ŻĚŃFQiüűýńňö-őú÷űè[®]»Ć‘ŁŮtëÖ€íĂčÝ«'v%ţş2Űc#íě4é~÷ťfyÓ&čÝ[wąÄ‘8Ö§¤¦Má©§ /7g}¬­ŻĚÔç«WŻfĐ ARnˇrCýkň$ÂĂ‹?ę-<Ľ#˙š<ɨ8:¨Ęˇ¬ýEĺű÷íVĺ—źwŰ>űH–âää¤ü´}‹r,ű?!Ć<TEáüy…ÎťşuSŚT¸qCůŁ/‰#q¬)ÎÉ“ šĺČH…´4ý口]Źľ¬©Ż*GĎ•ŘŘX)·`ůŁĘ ’•ůłâďď§Šżżź’•ůłQTT%»bŮĎłqSrsăĺíˡ¬ýT­Zµh]żŻŇ.,Ś‘#†póćMŞU«Fě;qř3xĐ@FŹŽas˛‰źŹiŠëđÖôpZ‰#ql-Ž9bšřAĐŠüžgµ}ó†o×;ar©g4_˝z•w&Ä3gÖt\]]‹­Űąc+ŃĂb¸{÷§Nä[çĺí«ý2frr2oŤŔ¨Ńc‰óNŃşŹćÎ"#c]ş˝DDĎ>ěř)€‰qăŮşuŻż1Śó.V ÉB!Di®®®$.]T*ŃBëTşwďNcĎç´îPż^=V®H,UîćV‹ĺIK‡V!„°ňlL!„6Żň=S!ÄÁě3• !„–ôŘf*—ŮĆ…BXB̸‰ÄŚ3íäZo=B!l…Î[„B["ÉN!„ÍÓú›Ý†o×?îz!„xBĹŚ›Xę©'¦¦s€Jě„ÉFS©Tň8!ÄKĄR‘şóGKWĂbBĂ:˝ŹJĄ2ů`môŢzPňądú<:zÓý„ÂČvŤňć s“ßě„BŘ<Ł“]aa!S¦Î0G]„BŘ)SgPXXhéj—ěÔj5ŁFŹ%iůJsŐG!„ IZľ’QŁÇ˘V«-Z“]^^^‹ćűäş´BĂ}˙ĂV˝M^^žĹę`p˛‹?‘2ÍY!„6ęŔLbǛԥ.'»ąłgŕoÎş!„°QţĚťmąń'»5j°jE"Ýşv6g}„BŘn];łjE"5jÔ°XŚ âččČüO?&jČ`sŐG!„ ‰2ůź~ŚŁŁŁEëaô|vvvvĽ÷®ĺ®» !„¨<¬%_ČMĺB!lžŢ3»ň>ĘE›#„O&kýţ×™ěĘ;%ş©§RBQ9Xó÷żÖ™Ę<ßŘ2µBńD2ç?^ŢľÚĎěĚ=ŻBń8=ÓXÖzýÖXí:X×ý…ÖÖŻĺé[h6¶Ú.!*3ł';€ča1Źă0fŁ(ŠUÎŃg-ýZ‘ţ±…6hc«í˘˛z,ɨ´3[ű…ĄűŐýc mĐĆVŰ%De$÷Ů !„°y’ě„BŘL›6­Ô˛±>ű|'ŽgŃÂ|őŐţos˛AďĹşő߲hág&k—ľýŚů˙ „(#ŮŤ;ľhpĘ+_ŁfMWVŻZŽ““SŃÓ!Ś}JÄůóçpss+*sssăÜąs >ś€€† †Z­fĚ1,X°€ŞU«ęÝďQׯ_'!!qăĆ•:vÉuůůůtíÚ•*UŞpěŘ1nܸÁüůóµÖűéjOcooĎWkÖ’“s gggjŐŞ©łťˇ!m¨U«&juŤ5äÚőëöPůŽYŢ~-Kvv6íŰ·§nÝşÔŻ_źyóćéܶUËděŮËýű÷IKK§}»0Zµ ĆŢŢž´ôݤĄď˘UË`ŞTŃţŕžň¶áÔ©S€&QLš4©Ô˛±ĆÄü“¶ˇ!´ !0°9?íL1č˝ýĎZą9>ó†ţBhč}\ŘěYÓx±GwěííK}AŐ«W€ścą4{Á×ŕÚŰŰĄç=R©TŘŮٱtéRüüüčÚµ+téŇĄĚýP«ŐôíŰ—Îť;;më¶mŰĆéÓ§Ůľ};uęÔŔÇÇGk˝ëÔ©MҲ%,Z´”—{öáůç2uĘ6׺ýW_ŻeíÚő4lŘ€›·nĐ3;fyűµ,Ď=÷ .$##±cÇR§Nâââ´nÜ‚ź-$5-||Ľ±łł#Ŕߏ´´t Ńý{ťąÚ`¬źw77n\żnĐ{ˇëj‚9>ó†üB<¤÷Ěî©§ž˘jŐŞZ˙oŐ˛ÎÎÎ$%­0ęě®víÚ\~d4â•+WŠľ`ĽĽĽ&%%… &Ľß˝{÷0`žžž$&&bg÷°işÖ=řëřÁeݞ´iÝŠ¤eKŘ·'Ť ŔćŚ]úěŕČŃlŢ›ü>ź|<‡ąsf5¤ĚŘúđěŮâ™zĚňökYiҤ QQQÄĹĹ1sćLťŰ6đÇÎÎŽŹ?™O»°¶EýBZú.ŇwíÖ›ěĚŐ†Š¸ző*€áďEIćřĚ—SQ\ąo*wqqaRüţłqqßĺđáßČËË#;;‡E‹żŕ?7iÝĎĎĎ—bŁäöíŰG›6šA 7näúőë„„„0uęÔ˘$PÖ~ńńńüńÇ|ţůçĹťľuÎNŹ?^f{ĎźżŔîÝ{¸sç...<űlýbëťťťąňÇEáęŐ«\¸p‹/˛ů˙“8yňT©môećŻY¦)úŐîîî¨ŐjťëťśśđókĆÁ‡h×®mQyXŰ®\ůďĆş'~m0Ćń'Ř˙Ë"##Śz/J2Çgľ¬Bâ*4ëÁ€ţ˙ŔÝÍŤĄ‰Iôe0ůůůÔ¬éJË–ÁtěPzThÎŢzë-¦M›FÇŽÉÍÍeÝşu$''sűömĆŚĂňĺËńđđ €5kÖĐż˝űeee1wî\–-[Vt¶Pż~}˝ë:uęDÆ 1b‹-ÂŐŐ•ýű÷^ŞŢę53gÍ!÷ř EÁËłó>™S´~ř°7›řwěů2=#^bđ7¨_żqb9tř7ľ:„ô´ŶíÓ;’áĂŢŕ“yóůć›o™5k:}˙>Ŕ cš˘_˲iÓ&şté­[·HLLäĹ_Ô»}Ëŕ ȤmčĂ[OüüšQ­Z5BÚ´Ö{™Í\m0VĚŘXęŐ­Ëť;wúáű´ äÄÉ“ż¦j—ľýô­B”¦”cهĚv€ť;¶=,¦Ř_ájµš‘#G˛nÝ:\\\2e ŃŃŃLž<™'N°jŐ*>úč#¦OźÎáÇqssӹߪU«´Ţ˙Ą(ŠŢuGŹĺí·ß&55•ŞU«ĆćÍ›‹¶ËÍ9Śgă¦V7]Š)űŐŰŰ›sçÎqëÖ­˘ËÖ™™™xzz@nn.*•ŠîÝ»“@ÍšfT¤LŮ•JĹ–-[čÜY3QiÉe}Lý?ŽĎĽľćj—••—·Że’]eb­_ÖŇŻ¦Nv–đ8’ť%XëgWÇÍËŰW-„ÂöI˛Baó$Ů !„°y’ě„BŘĽ Ýz` ů‘ÜB!DĄ‘ššÎ¶í? PQEý¦$0ÄTŁ»÷IEND®B`‚gpsim-0.30.0/doc/screenshots/breadboard_register.png0000664000076400007640000120001713041763626017461 00000000000000‰PNG  IHDR‘„>Äá pHYs  šśtIMEŢ 9'zĚű IDATxÚě˝yś\Wu.şÖŢűś:5öÜjµćŃ–YƲăbž16Ű<&g$÷ć‘Ü$7yď’űă»árBŕţBŕ>±ÁĆb°1Ë“ŮZS­'Rb­á @{O Ć&&Ł™ !QJ`F@ 2&1ZŁ@B‰B˘df `&b"”Ň>wĐ$”!Čh†LŔÂó¤ @š€5 ÁÄl ©…PŇľ<`٤fŇšŤff2Čĺ ĺ!"Ř.‘™)‰™YĄ” íë·Ź] ´&0SmJŐ‹("JŞ5ßÖ'űě kD!Č@”öuŰ*Z«b\űŮÄ‘ŽŁZK¶»1€(¤Ź B‘ŽBJ"áů*Č©jĎ\k6†HŁTR*@ lăZ¶Ź”Ş5ˇz_ŐG×ĐfH'LFJLíáŘn‡l3'Ł@Qł‚ŔĆŘÖR Űr­­ŮnQöqbcě7€Ş}±NĄ@D@¶BDJbŇ €(¤@ÉŔ(jťaµű"2¤ŇG ˛ýł©vLµQ{SŐ”k˝+ŁÂZ¤$aJ„ô@ ¬ö<Ěö–ěĂ´5¤VdffL¶‡Bd4łA@fbmP*ˇ ŁQH`‡@T}Ył]ćú˙°Înć«óĽę(ËŤç2suÖřŤ§ë*µ;q@.źŹÂp)v˘(’R¦3™8Š–d' ™Ů ‚łÖ/;o]K!?Ô?V9<f|d Ŕa:ŽV¬Nşş‘Ěâ$i±ç>=ď#/ś Î; ŹmíDďo±©ů‰”öX¦ć•™Ź}0źŘSz±‚źd]?v±çQÉS-Ŕ‚1˙lťó‚Éđ1HŔńŕ ÜëRĚ‹? |ń:|Ľ§˝đn±>­žCţŹYôă­FĚ™óŇjž|;XzŤĹĽń†jŔsĎšÇĎqÁ+ăľe^´ŐÎ{Ź|ÜG‹ó˙c^•Źń%‹/´ćŇž´ž.ś[ ăÝgĂ=°b|čhˇĄ]z3·wĹăYDěon_&¤<§UŤť!ŕŘ`ë˛ĺł®Îą|óDÚ¶˝Ă±Á~“n€Tń'¬Ę ·nîüă\¬Ňy»ÔjO(—ËqźDÁľç§R)7Źrpppxč$ŃZźúÔŃhMD/‰@ÔZżv—nGFkˇ|Á•ŰTďPńk÷©$, îČsł.?;Zvä¸ó­˙\`ŠĂ‰¨{e[.€ĄDőIŹ>‘Ůr~K±#$}ä±ěąz>,Ą3úŮ‘ŰúF)–ôlˇ˙‘GâÎ3Á›1ó´Bűń_ ň-Fë†ÇH=GŽ ŹŽžä°Ł­mÓúő®:888Ľ”Ť¨šʡ܀%Ű©i v°V"X˛ťÚN&"2†Dę}W¬ď«üË/†2ž„&®l8»˛|+ęĂ©F|*Ł«ĂÉ ^qTHXT7ťé“ ăJ†SK±#¤I9 cÔb)Ś …I9 M —lI“2Lťńvl›SĄJBvČo¨ŠĄŇLźsţ›´9‰K ý=¦ŠĹB>ď6Â9888Ľ¨Ęśj—‹U˛öRŘ©˛¤ĄŘ©Y° ^;őŃŤ™™ŁÄÄ1e[¸ĽykÔ¶“í¦|! 4.Çz1.źc¦TŽ:ÖBrŁžĂ‰¶„Ř#Ř,%^Ikfc´ŕ%tÁĚH:!H˝Â&H Ń zIl IŁŃő}Č“[®QţÁ‹ MÍ4wăYĹ,ýžź.Ĺ8wL^Ü0ć3jCsG1gÝŔĺpZt¬”BjťŃěçWfąŮó3žŠŹă]¶»L–(Hp¬č \Ýć%Ä=Ó‰Ŕ_IŹ…+Ű<PM=ÓÉ‚ććČ"RMF^,řRŕ~ŞŃ˛ć”čnń 1”,iáĽŰ§ß ‡Ń†čÔ=ch=cd .ÉT‰8¶§Ž“hcP¶’ŚAžźâC M 5IL‰€X]|ßNHŁ™ă{T@ …ř‰ÓwÍĺgťxD(Ó#Źě ¸Â/§WÄáµ Ďóöí=p°ç”’™…ąlvĂęő]ťËâËQźH é{CRHëé"bzůłS‘’ŇS^թ회Ă)Ő˘Ą† Ö¸ÓĹBęyĄŹoSA ”*—JuQâyKtD‘JĄRAh]!JâXů~:ťVž‡ˇŐşśc§ća›MżSÓ G“ EČzVíš4uw¶*™§NÉ‹/2€ď{í- N'ŔYkĹŻŰńKŕŢ[Ö—Ę}n—wlöŔÄ ň‹˝D]ò¬·÷–ő‡¦âő_Ú#}ńĘ?mřĽ®ě/n^݉•Ŕ‡űËoů§ýš“ôĽ1ë mEµ,‚sňĎńlRëú\Ů“šŻÚÔ|۵«‰A üëž©÷}÷° ¤«„§ŮM¬Ů%xŘÖĆX‚‡ ˇJ´ ëă‡V’MGwĚ›5Źź^HŘVf”'ŕŕTő~™ayNJ„ŢłČ@hôěU'l É•m*žp2M žŃ6‡S›5QEgm>sĺňSÓS‡űzôLĄRm-­Q Qź7icČ®Ż×M5Ät D!e}-ß3ű“6Í R^=Ç|m˙ Ř{$dbC‹śĽŕZBH!«yzÎRJaCľ×DkKDĄ€čŐ~µIt]“q8µV3/đoŃcŽ“TłN^Ô΋ x5§óqě(Ą<ßGDĺyÇĚ‹Íܸ#n±´ąg žď"3ŹŐHZYÍkŚ@„ +˛ d€yűYËßÖŢ­µY@Í'lž§&㡣` 㨍ßt2Ăjśú:8śt@„|6×ŮÖžĎć†ÇFűúĘ•ň˛öŽŢŁ}“h´Ö«W¬ęhm/‡ĺŃń±éâ4 ¶65·µ´)ĄH1S) ”+%e.›ëlďR)"–RN§GĆFËaE 9=3Ť(jé>Y*y¨÷đŔĐ"ň…eíťžçYG\©\ť)ÍH)[šZÚZZ…–€MĎŹ Äq¤¤Ęgóťžň„/>X + @Ćhc6ŻßËćĆ'ĆG'ĆÂ(”BUÂ\“q8E¶V_éŔăx´R)C”Äń˘ÇpÍÁ{|;'D™€ŽaÇ <Ż^r2í"ČÜA‘j{áćŮ1ĆÄq,¤´±—©tş~P’$óüuĽ`[• V×A ČÔw T=l-ů ˝%sR7n¦R0kÍ5äÓq8gŞä bC ąťŻĐobŚ‚ąÚ~ 4Ăü°G+0@¨‰IS=°O(!‹IrnG0ĆžHĘV—Xúµ„ĺrĚ„şqJX?Ţ0›Č€Ŕ”/ąţW€1Ĺôo˝ăˇÉ@†’şe «–cĂň¤¦š©”4Ě:&PľĚŮÓQ O"{ Îv1©”äał^~bß8¤äUg4onIŤWôçZ–Uvç~˙ü¶é0ůĆÓŁž‰uö™0Ѳś-'`¸-ŔőÍţúfż:şc÷ć3[˝ťÓ˘nëĘSáϧ–@€&Űú\LäiGŘ4YÂĆÇXÔÄ ńă’USd2Äš–ŕ©CćŞc·cÎéJ/O#µĘ“á˘g’&2¤5CŁ8(ŔŽKÉą­j¬’ăą­Rł"çI˙ćďac…DÚőMCúd´Њqń‰l:wpXdm®ZiHRjhŠÁáˇzĄR©l:#„čę\–čdpd¸ ßĂÓĹ""¶µ´Ů–=]śŐ:€Ń‰1XŢŮĄ”Š˘¨oŕčŔđ ”2Iâ8Ib]IN1<:śNg ™Ń‰q%U{k›"ŠŁŁCĂ`¦ŠÓBć¦&&§¦FĆF­fĂčř˘Ł­=PAO˙‘±‰qß÷s™¬ťn†aŘ{´od|ÔS*Ś"­5ÖŇN˝AŻÉVCµlc —@ĄRA:ť$IÇD´čćfjů8ĺ®ŰĘźÔEPćŮA´>jđlW:”ďłőÍ·#ÄÂűb€8ЬśPKÉ´ÖQÎż;DŞE}4:Ă­; €†C¬zŘŚˇEÇÄcAa€ Hyú­züĆ™Í záî}šxeÎßÔ4˛™ýăa1–ŐP>«#˝¶)•öDBlŕÇ'ń©ˇ21[a·&_léζĄ=)`¸¤÷ŤUfsă9mjşöĽ6pĎľ HĚkšüŤ-A>%§Bło¬20“(ľÄkÎn1ÄJ '1Ň|ß [†ć”ĽdCËŕLňŘŃ%0ç‰Ë×·T íč›yb°TŃ$Á^ßśÚĐd}1^ŃűĆÂáRâK\[đ¶vúŠńSĄ¦@^ş±e*ÔősľŘľ!/)FZ nlń×·i%Ć*z˙Xe¤¬Ą€ć”ştc‹®LL„úţC“žU #˛Ţ ‰>€bë¬~f¸üÉ{ú­©?~ÓňO_ąę]› ßx|ŔŮžő/ZžbhIË7.îÚ[][|9Ż3˝ąŐß7Ziͨ7ugě rb <‘‘ő «#l§ăče4‘&­y1BfZé éX˛F#iKŘN5o'F“ŃČóí031$Äksąb¬»Ň¨µŽ K„yT‘Ńh$MFăÜő»É2—’™Úy~» >ňxd†Ka‡ Ď÷•RZëJą<Çű×(Çż <:IÂr9›Ď#b†J)K%ť$8o§«M™=—}‘¨ćd#$3úÂl ęLć„7Ż ÄŔČ„¤]…<ý&ŤÄ÷ľołýśŕÂ_?š•řţł[nŮÖŮ™őÇ+É?=5üů´řňĎßÜuÝ™­AÍăężý2PâÚň“§”¸lUţSW®^YH1ó/űfľňäĐOM~ăÚő(qŰőfbjŰ=’R˘Ů9·í[;ZŇŢŕLôŐ'‡żüř !.Ţ÷sSµÚŹ”’î˙9¬| «rţťżąé‘ţ™7˙ŻgŦćÔ÷ß»éčLü¶oězč[Ć+şíż?˘RŞ=­~g[űMç´çSŞw*ü‡'˙×Îa xÉĘćo^·éŢýďüß»ÎZŃüýßÜth2Üř÷OveŇ·ß°Ńżĺźžť®ĺy˙÷ßĐńŢłÚłľxa"üŇăß|zDkŢ´,}G­`đH_ńßźÁ´‚ŞăšŔ*‘“b+¸ç „h­ź*@Ć@ wf‚7ŻĚcsh2ÜÜš~Swć®]# Đžjň%\·ąé3Ó›[2W¬ÎŤ–“öŚW[m©'\f ŤěŰi7z0šI“1°XD†Tjk{Ş-­ŚÎD¸Xúf¤4±YÔÎ _`í°1dĹôűy_ ,€ĘB¦ fCÝ€µPÄ»÷Žý瞊4}ĂYť˙Ďe«~|`âşßý-˙Ď—¬<2Yůös#ńĂ[—˝÷ě¶}nôŻ~äżľuÍ [Ú 1 B@BŚdĂ_żuÍÚ–ÔoÝą˙á#SŰ» ·lëĽűůáÍźl߸°śĐšżŮáK‘Bňo:«ăĎ޲⻻G?ýł#ň–•˙岕˝•;öŚ‚±ń~ü/Ď˙ןö–µIIFŁ`h:|âčĚćÖ`MAŤ•őĹ+łp˙ “ÓĺŘň0&#ä‡Îm˙Ă7.˙ćSC_Ř1đ——Żú«ËW÷NTîÝ7ńT˙4¬.řů‚eH+ń†eérB-z´ż¸o°Řžó?z^Çď\Đőµ'ľľsčż\±ćŻ.[ud˘ňăl ”bóµ'˙ćáţPSĘ4Đpu„ŚF)­ŰA·˛W¬ÉŔóĂ%`#WdŐşćŕG¦żţäĐWßµéü®, ö¬Ă“áSĄ«74ţáľsŰ®śďľńm[Ě` `• "3ƶÓn±Ä i26pîëC4]ľV)E…†(đ}đ=Ď&ťcv;?N•®ŮÂyž(f"H§•R&I”R¶?OŃ:ž+őQÓ˝9F¶c)Xs/Z=l±üi&I’$QJAÍź,•˛ńIĎ—9–ÇŹY*=Ć÷}»o-ĆŁő˘ĺ™?Ő=ll7ˇ1ŰxěEĺ+ć0 nŰiGŘX~ń‘ľ}Ł3‰ˇ@‰ĎíČzâoŃóü‘‰ż3ÉĽ±űĆsÚżóĚ "ľ{K[JŠ~ňčľ‘™zâč [ÚŘXŃ f2‚áŚötBÔ3YťŞ™,I ţ©Š=ft˛ ž”đQŢxn‡'đo~Ţł»wňKŠ?rţ˛÷žÝvűsČ* }ń‘ľă%N+a珕°ě/.[óÖµ…ďíą|u!6ôĂ}ŁL­ :«Ľ÷žÓ® ýí/z÷ôOíqńľs:®ßŇvďîáé0Ţ9PlĎřë›˝ó»2C3ńd¨/]ťz`ďź­[RÁ{Înź‰ôß=Ü{ppćÍŢu[νvsËŹź¶­fp&ţęcý˝%D ”¨®„0ŐĽ^lŔrŞó—çţŹJt弟žüâ#G¤ä–”Řľ< OöO?50UŠÍꂿµ#ýĚѢ=ëČTt˙±O]µţCçu\±®©w2üÉ ăÚ¶ ™mk­z،󰝆ă—A2l4™ů d‘ˇÍ­ÁąmŢd94ÔťOmëđŮ7Ł‰Ĺ‚=Ď@É0-bçäĆRŁÁ^@Řâ7v5eÄĆôMÓLhŽ€a€”o^žŢ3RÖf¶ň1 0ȰYD4¸Q%N|LE‰&fnĄ54 IDAT_x•X+±'ĹÂÔ15Ű\ –0Á¶“nd›'ĂM=NµÁ15ĺ›Vt-Ż„áÔôT˙đ@©\ęlm·µ«#Amw sňłé 3ç3YDĚe˛Ŕ<61~¸Żłé´’*ŚB"⚸–e×0Ő컍‹ńL Ő­.XýkMŞjĂŔŚ€Cc#=}˝ĘS™TZJY*—‰©qî;«ťJlg¸5ŐňŮŮđ’ö9Ľž›ĚÂt~Wr޲ά—®iťD±|¸gň¦­]ç´§·uew™ ”|ëÚć‰Rz¤w2Š·tdĆ+ÉomďN ŻnNŔĹ«› I¬űk&Ň»ú'”µü€†j6ŁQ˛=¸›ÝSŰ3çueöŽňLłŃíéšÂH)ľ˙č‘âÇ/YŰň¦ągŹYÖW‰ő“}“Saňűu „Űź*†ŐΆ4QÓĐc íö°ť†MĎiZ@Ř4qWÖ»`Y`ťT)ÁÓ•řŚtĆŰ;V1ÄóTXŃhk6bÖĽČÖ.)pÚ•­EšŚž·sډËqŇ”ň}Ś@ DP‚‹‘!ŁÉ4ŽżÂŠ…Đ›a^WH­Ě©Á™¸#-`°-Ď©őŐ3-Ś|AŇhćěî[ÄĂVŹ31t Ť ç:ÂćpŠłOf@"“$…ĆTôąMY‰Ž •(Z›Z7¬Y§¤4DQŰ},Łccă›×oܰzť”ňÉçžžž˛ŹźRR•+]CĂb<#b9¬hŁ“H':I”’Ň©@IUŞTZŚIt’hť ŇRD™ž:{ó™k»WŔôLq¦4SWßA»Ŕ_ŰÝ™!E©\*äňQ‘Íżë–9NµÉ,¨<–eyžÂęć—gf”çů©3{ž‡BąyĆŞáĘâ3K)»÷l.ŚÖĚÜĘذć˛HefcÂJ…Ň™LN)fŽÂ°8=-« ę+&Ç ˘Ěl7˛B-QG†~*%•˛I±Qw¤ŞŮYűžm޶9\HÚrÍ“%lÄdĐ  ‰ůnHŔę*ŁĂI‚¬˛ť!2ĆL§Ę•J&”R†°&jCĐś/rů‘ˇ\6ŰRh.‡•ŢŁ}]íť]ËVĹčâ$›)ÍX)HcL!źĎ¤ÓŁă­Í-ĹŇL%Ş ŠšěŁăc-MMSĹb% [šš=Ą´ŃM…¦ôX026ÚRhšśžŠ˘°ł­C)Ď’BH!9ŠŁ‘ˇŞR­€@ y±[ Í#ăŁCŁ#…|at|4Ö "8чĄ´šEB‰ŘĄ™™°R±Ńż© ĐIRÍI˝'jˇ‡J"zľO i -»±RŤaĄ2çx"â8â%őđKű/6.ŐĚ%~UőËyĺ!˛ˇĹFëĘĚLEZë\>/•JŚ©ÓÎůr^6íYŃ őŽQ°AbŇFë“ó°‘l'˛®źvłĆš‚(›ęG†ţépCk檯î蛬ط,ôO…k[Ó˲ŢŔt¸"TŤ°©Ż¦#Fţ·˝C?Ý?rNWţ×ĎčřË·núŻůŇ/˘WKËÉ„6ý&Á`1ʧÔ[ľôđX9ĆÚµŇfS01ÍKÇ$´N~¸wäĂŰWţń%kbC?Ü;,°J`Č٧B]IĚE˙óé0ÖrÖĂ8Iž=:Ą\wö˛Äđ#=ăĹ0ßyńšß8Ł}`:Ú38í+ˇµ.'f`:Úţůź—c]?Ý÷ŞQŽviNzn´áÁµ2@-$Ň“)Ü;4őĄ_ţÎűßpÍćöŻ?Ö»ľ5Čú2퉯Ýpv}a嬎\:DBqŞôďűG>˛}ĺžá⣇FsŰŠY†Ćrvidá*óé¶VbĐĘč›Yi ĂĽ˛ÚÜâN‡Ý…Ôľ±J1Ňçuĺ§Ău-ÁÚ‚7^Šjôh!¤†Vć Mé7Ż,d|1Ź€=10óô`I72°-chčÔáńňˇ±˛&ú »™h2Ôßzv(Ň´Hş¬î…#cpÎ`+š‚őÍţţŃĘƶô3Ěü†ĺůĆ+gv¤Wääľ±d!]$$rQŃŞŠŽśaĂę@ěDGNĄő‚1€ô<Üß qŐň•…\Č"m4ŐćdĆ|6ż~őÚţÁŁű``ß÷[›[3éŚÖş«Łł–űŹĐĆhmól“!ÓÚÔŇÝąĽx`ç®g Ůź 3°!cĆ&ǧź+2p6Ȭ\Öm5*[›šW-_982Ľs÷łĐÚܲ˘«Űrą]ËŁ8:|¤§§Ż×^KW7˛1Fk]×N C­m3Ą™ÁŃáÇźÝij»=lKp,’đš™ĂJ…Ië8ŽŔh]*ă8&ct’TYÎÁ‹g-«)ćű©.ü>ŠŹ®Š4.–đzΉI’$‰•BYô *§Z,·1¦R*é8N´¶Â’IĎ‹žç-ĚĂV/Ϣ…±yŘęSO”d ‘1Ćś¸J$$f $ě¬ŃŐČÓ–°!¤ę ü÷ž>úź®ÜřGŻůóűvǚ޼¶őw/^÷[ßy´wč÷.^wăą]ółď?Ż»V 4 Y·ăIřܵ[?óŔľÇʦ˙ĺ[7)´`ÂfDkň`|&ĚĄ=ťđĎüŢĹk˙đâŐźřŃDĽ|CűMoXůŃo?‰¨Î«f…f"úÁó·\¸ęŞM•Äü`÷€ ĽŽL9ŚďÚ5đ VýîW}úţ}i%ŢľyŮŐg.ű˝ŰźJ)Q,GĎ Ď_ŃôÂhéÉŢ1AÝ…ŕ_vöłŃRČ©Rtßîˇ÷ś×ý[ŰW|öÁy_˝sK×›Ö¶ţÇď> ušŃó ›©–«¶Ş|Ýff4öŽÍ™¬léĚ]ą®ůÂbţâĎ~áç}%ÎčĚ˙ŹwžÝ]H]Ř]¨FľÓżďÜö?RŚ 2ŮLÄV‚ 4xó ’q•ůt[n4`‰VĂöc"RaSkp`ĽňËž‰‰J‚ÄŰşsy_Q5qVTŐvd˘R»†KĂĹJlř‰ţ C:çËCc3I’PĽ?[=RcŘŇsÍᾉrsW.ëÍi>ůŕx%I2ÔHجx iŤdŐ.ÄűGŠŰW6í)­ŮpMVaaC«Z©5ňl¤'3ť*?Ü3!ž(N•#x¤g lŘ2WżŻ…v`nâlŰ«ŕüH@ 6}˘ň!v±U &v!‘§#acř—'z”@¦ŮĽç»&ľřĐţ÷ś·rc{ŹoşŮĂSGĆţö§{ßyöňö\ęýמ»26„lČŔíO‰´‘lČđOąń «ÚŇr¬Xůâóß~˘Giť|őá&+ŃŠ¦´‡ ¬É§úĆżđł}ן·b]KÎ0ížúŢ3}RÇß¶o¬{H°žÍH±üů÷®lN?Ö;ž$:đD9Šî~®żŞ˘ť<Ţ3úŇřşsW¬nÎ$švLŢýlżŹŚlÂď~®/ź?90¬O–ÂĎ?¸Ż)í=Ö3ę!!C’G +äwťÓ˝˛)'ćŮŁă÷í:š’0V,˙`÷Ń禄ŕůcH°ľ=űŰżľeĽďśüŃóŹőŽ hŞ޶ł‡ČôN”'Ëád%Ů50™ „@ ăřö§zň‘ń™Ł“ĄŰ3đłF…”÷€cC‡G‹?Ţ3řŁ=ëşňď:wĹů+[ Pö:ś>k%5›™CŠýdźQÇĘ („ˇiýÖľă•؆ÉóěHɬčHÁđôŔ”6&đDăČEĚ{GĘQ’Ěi0†Éđ±äŁžňPŤóśÄp¬«{ŹĄ@_ %«ËéŮ”78]ćőů>qíţ‘â¶˙~źD,† ć š8j8=PB†ŘP¤É.e—RĂ‘©FmI)%¤@f @,ĂâďK±f)0ë+«!0ç†ŘPll)@ ô•¨ę‡3D†âÄ(%2ž"fk*ăËşŔ83$ NWBh˘r¤…Ŕ\j~ÁM¬n»÷w/ź‰tkĆřĐčUźű1H!„ČĄŞ%Ś5ņ"1#BĆSBT/kеń”ô$–#-Ą°÷U›„bb¨k ~ďöµßąĺ’Ń™îz¶ďÖoíȧ=W“O;ÂunĆp“hŢžg[çü‰«rQóް˙â9żÁquĽĐަĹU"ç éłMű~2µí(O 3=€!ÖÄjÁéłvP4íűÉäöĹôĐBB·ř}Íý¦ŽÂţĘ+Ďo,Čâ6bzş¨¤â$†Ă<5=Ýl“ä¸Ęčŕŕŕđ2•ă?Y#đRŘ!f±¨¬˙ÉßTµÚá5:Ëd<2VüöG/kɤ¤„yěŕ—Ře%F,}š‰«[îŃ“/Ë1ÂÚU˘’îńźŽŁ—AŞkßźrĎÉ€d¬Üá’ĆRH^ ;đŘ©FWľ¸‡MJŮŢÜ<>9©­Ak›D»ş§ 6Â![ĄW%„”ŇSĘóü–¦&«âઢĂË>ä-Ů3Ć ˛ţK´CDÂn*[zyě`łd;\“T™ý˛:íf¤Y/ …Ř=ZţÚýĎ2ű¬rl]ďr–¦ŮŔDD@@D!•š.ž">;•Č×c4>U+ ( şy‰?DŇř„D"ňů5­çc ‹3 °@ŰC5öSŐM€ĚDĆ…A:888Ľ˛0Ć$I˛”Ę*Ť¨”ËK·C†ÂJe©vŚ1Ć.RO mDZ~—BBăŠ$W‰×\[ő˘Q"@R!U%ŞGZ Á(Acěú¦#l'ĘGŘŔ%vśŔT×ď8eže÷6/u «wEKŃ,đ°Yl<ëĚĹŮ žx1^ůˇďĄ0ÂŻ&;üâ÷%…<:Đßsř ă±µ 륔i?¨T]$ˉcÝ0a°llVÚŻÎófŤUŹ6Őŕb7ţ˝Š[†J*÷^u`4Ł€¸´˝^XĬ\Z7Ś0-ózôčR·t!LË‚>ĽT'Ö´,pR-Ś1şřłYK[›sN›Ů)şĺl‡×5<Ą†Ć†rÍ…Ý«Ş"ŘĐC4LŮËĄ™ÁˇmđRµą‚‰˘đ˛ÍËß°¦36´€)ž >©~#EVŹşmőŻJΡ ă;ő6Î,˛@ńW ­¤—Úź3R…—>(\ť=vu­ţöcU#OuŠÄ§ÁŚ`Śq©ţÜt\'ÉŠîŐ[·žü#ÇÇÇJĺRyŞ8{.QWŢyÎĘŹ˝s;…±{ŻŃÁÜßۛ۲áŕŕpÚbÍšîď<ňü,a+ä›ÜCq8-P.Ď„aÎÉćŕ𺟑ÊÝöF4űS{$­î# bE]‰ŠaâžäkBť»voŮrÎq6::888ĽĘ±óą§ĐĹv;8888ĽfáśńŻď·ĎĚĽaĂf·Ŕçŕŕpšâąçž†Fчӵ9*ĄŚ©zŢ şÝŐMÖ_×µÂ÷SîQ888śÖp„ÍÁÁÁÁá52;ÇÇljL.—p;—ljxçaspp8ť±H`w’ĽrýDÔ××ç^ĂŇ [Ç{÷íŮ»oo’$B¸9úq‡!ę4Ćf>pĎÄÁÁÁá´!l;wî|Ĺ.?99yńĹ»×ŕŕŕŕŕ°trđŕÁÝĎďŢ·_ď‘^'5ń˘Ź«Nt…ŔFţćŕŕŕŕđŞ&lDô±Ź}ěŕÁŻĚĺ™yffĆ˝‡ĄŔóĽŁGűw=ż+ ĂrąĽo˙ľŃŃQOyŻ“Űgć|>ŻÔ‰nsČĺr·ŢúŰ{÷îő}bbňĎ˙ü/·ożp˙ţ'nÁÁÁÁÁáWFŘ`çÎťźţô§GGG_Ë#˘ďűî588888śúH&äčččSO?uäHoEQéíݵ{÷äÔÔëÄk”Íf?ýé˙wĎž˝'ȸ|؆­_ż~íÚµ®Y988ĽŞ ›âłźýěM7Ýtć™g^uŐU/ş `zz:‚(ŠYJ™ÉdęF†q[7Z*5««[©T’$BT*•FSQĹqĚĚľďA`żÔZW*"’RAŕ6aŚéZÖµňš•óÜ“$ĺ×A.¶éééŻ}í«I’$I‚Ťşónżž˙ ţĹĐĐĐúőëµÖݶ¦µţĘWľňťď|‡n¸á†O~ň“v˛‘$É?üĂ?ÜvŰmđž÷Ľç“źü¤ ˙qppxő`q2¶m۶Ď|ć3˙řÇwďŢ}üóŁ(:˙üóď¸ăŽË/ż|۶mýčGë?}ęSźşř⋯ĽňĘ/ůËőSÂ0üÄ'>qá…^uŐUwŢygť€%IňůĎţ˛Ë.»ä’K>÷ąĎŐűÖźýěgďxÇ;Î;ďĽw˝ë]?ýéOÝ;sppppXt<šžžśś<:<<E!âëB}Ä®®2s*•˛‹¤ét:‚ĆHĎó‚ H§Ó±Ęĺ˘(J§l6űziąë®»zčˇoűŰwÜqÇŁŹ>z÷Ýwۇđýď˙ᇾí¶ŰnżýöGyäî»ďv ĘÁÁáŐu¬~˙íoűřĂ[o˝őˇ‡:ŽS‹™{{{ň“ź|üăWJÝ˙ý_řÂ>ő©Oi­ż÷˝ď=óĚ3ń†áťwŢyĆg\sÍ5öű={ö|âźĂđ»ßý®5ž$É=÷Üó裏ţéźţi’$?úŃŹîşë®kŻ˝¶X,ţÝßýÝ 7ܰfÍšŃŃŃ|đ×~í×ÜksppppX8‘1ĆC¤µ6Dćőŕ^€\.÷'ňźŢ÷ľ÷^|ńĹ˙řoÝşőŮgźŰ˝{WWW×o˙ö­gžy&"f2™űî»ď{ß»cbb⦛n*gšš ř‡ëďď˙Ł?úżáË_ţ҆ ëŤ1ŻáuĎ=÷\wÝu۶m“Rľç=ďąďľűn¸áDĽ÷Ţ{ŻżţúóÎ;Żżţú{ď˝÷†npmĘÁÁáU‚c.§Ĺq<11±|e|ß IDATůň Ďd2Ű·o˙űßăŤ7^wÝu÷Üsh­ďĽóÎ+®¸âć›oľůć›·mŰvűí·[łwÝu×UW]uóÍ7ßxăŤgťu–˘(şűî»ßńŽwÜtÓMüŕßö¶·ŐŹß±cÇ\pÝu×ÝrË-]t‘{gŔ\ đł’ôBDQ´ĽNDG|ßż˙ţű‡‡‡ĺţě{ßű^…«V­»ë®»ÇÇÇ}ßß»wď˝÷Ţg uuu=řŕ̰rĺJĎó–/_ľaĂzßí‹j>ů䓿ţëż®”BÄ«Żľú©§žŞőŐWK)…W_}ő+™ßČÁÁÁá [E·ÝvŰ‘#G>űŮĎľ¨.RęŁý¨ŻĽňJiŚyúé§oąĺ‚ŕřŔŽ;,‘{ć™g>üá[¦÷‘Ź|ÄÍ'I˛cÇŽ 6<ýôÓ;wîěěě|â‰'ŔóĽ­[·>ńÄ<đ@OOϵ×^ëŢ™ ‚ݵ†aGq'Iś$‰Ö‰Öşęił˛‡ŻuÚĆĚą\UÖ?źĎĹqüÁ~ŕK_úŇďýŢď<řŕĎţöÎ;>Ş*{ŕďľ2oJf2é˝$S€I*Mš)ŇĄéÚöç®»«â®.X°ST¤H)ŠtBh ¤‡ôF2˝Ď«ż?.C& Nt—Ő÷ýđá3ó2sćľűŢ˝ďś{Î=§ąE,:tŘ`0ľňĘËź~ú‰żż?Ă0fłůő×˙âëëűĆolÝş-$$ä÷í^C¤µµ500ľ lmm…>XçăÂřxtč:ÖńňĺË+V¬ŘşukddäC™}ßÓ˝Édrww‡Ż•JĄÁ`@Ú Ż) Çq8Wň<___ď°Çxž BÄÝÝýí·ßţŕ>ůä“÷Ţ{oŔ€Âe@QL«Ußľ]ö`3㏖ŽŘfł=÷ÜÂ=zͦaÆ˝óÎ?m6+†çĎ_ČĘšĆqÜĽyswěŘÁó‚ Ç™L&“Éđ»·Öˇ(Ę‘M"‘ŘíöxD 6Žă^zéĄwß}7))Éeą…BˇŃh<==Ńh4JĄŇq\§ÓÁ·Ťşćááá[¶l‘Éd,Ëb&—ËávŕŔ«WŻÖét'Ožü׿ţC.ţŕ`ŞŐi¬VËĎ>Źh†cä¤[8ŽwwWŤ†aˇ›QĄjóňň"I’eŮ€€‘ücěď»’$m6›T*EÄb±8ňQĂăĐfëx\@@@ŕQ ‹H“É4fĚŃŁG„ëáě(ŠöéÓç믿FÄjµnذzĆpOLL\ż~=śżůćř+A¤ĄĄ]Ľx1***66Ö××&„´X,7n čŮłgHHHYY™pÍîŽăžrąÜÂ@„Bˇř=eŕ0ŁiŐ4Ö56Ő7=č_C“VĄĄ) ŕr čOgĘów/»HDŇ4Íó<Š˘EqŔn€řůů566Â׍ŤŤľľľpŐ¸Óq???a2x„îÎŹŔŃŁG/Y˛ÄµřłÍćŽř– I“&mٲĺ믿¶Űí%%%Ë–-CD$Mś8qË–-rąś¦éęęjXŠM,Ăă‚$©ÓéT*UVVĂ0yyy6›M,WWWŹ9R¸f÷QÓŃ;wîlÚ´™eYŽcCžzj˛V«#IQ[›ęĘ•+cĆŚˇ(ęwsľv;%ws ľ»Q “MPÔb6ßii¦)úcŻ!ť sázôčqýúőÄÄDż“'Oéőú?HÁޤ¤¤:t¨gĎž†egg''';Žóđđ7oLR‚ăř¨QŁš››7lŘĐÚÚšřĆo "‘H† ¶jŐ*µZÝŻ_żĺË— ×L@@@ K‚(--}á…•JĄÍfKMMMOO—ɤ4ÍěÝ»oőę5S§NŁ(Íďć|Y†‰ŽŤíź6đÁkkm=î,mµýľŻ>ÇqĐNă8®Ł+gzذˇ[·nŤŽŽŽ‰‰=xđ Z­†Î%ŽăäŹ9~üř?üpđŕÁ8Ž˙üóŕŕ “Éđĺ—źÓ4Ť ÉdZłfuhhMÓ(Š>őÔ”´´4𦂂‚FŤm2éżůćëXbçwŠ˘‹-7nĎó°ťCÓX˛d LU,¬ <ꛀ€€€Ŕ˙ŞőÂ#†"‚a"'Ěfł——×äÉ“żűnËďô¤ÁÝęŘŠŽ»űżű?š¦SR’ív;EQ)))6› ćč§i:5őî[–eĂĂĂEĹĆĆZ,Š˘ű÷ďoµZ˙9ý!]îű ‚ő„M@@@@ŕ·Ăж6Ő‘#‡iš.))6lhTTô‹/ľ´sçđĚ ř‡3~9^t:ˇ(Ę‘u–L&ˇM@@@@ŕ?2§ăDkkëرăxž:ôń“'Oi4*±XÜ1Ď»€€€€€€Ŕ˙¨Đż(ŠŠ‹‹ŰąsGppđáÇôz­ŕX 6Gð Ć/\¸ŕĄ—^vw÷ŕ˙8M@@@@ŕ‡¦i‘HňÔSOµµµmÝúť›››Tę&‘H0 ET*• &ś€€€€€€`° üç°‚p11ŃóćÍ{íµ˙cćěŮÓ7oŢŇéôW®äŢěXXE@ŕw Ďó BT°€€Ŕ˙ôD†IG~_ę)*‚Đ4m·ŰŻ_ż>dČPćľ_żţ™™™gÎśŇjµBw üîpĎqś`ł üŹNbEM@@@ŕ÷,şµ}ű6ÁŔq\˙ţý6nüÖÇÇçÜąÇQeÚÍÍÍ`0}%đ»‡çůččŘŠŠŇšš*ˇ7ţG‰ŚŚF¦GŃ`ăy^X paňtssóňň2›Íą\îĺĺe·Ű čďطƲ¬ĹbćXA‚`8ŢÍřPŽăX–ŕ8Ţ­^€cYŽăPíćŐá8Žăx ë®XJE±nŢ,P†aÝĽd.Č ‹%ťj‚˙ŰóËatSĎóÇţZr(ú«ČAQí¦–eQ´űr8–ĺş/‡ă88Ř9† Sú# ˲Ç9ř˝ ţ~’Ó…Áf4ĺrů^ĎĐjµ9994MOť:U¸Ŕ®=ö˲V«Îę÷šÂٲlkëťVŤ®;"—+ärĂ0-ÍÍV‹¸Ş~qçáá!ssÓé´v»­;MR*=D"R«USŐ9ž!R«U,ËtĂ^8Ž©Tm]j-/ÇÓÓEQ•Şőáłć (ŠaŽăä ţţŢ mmmâzöĹĽĽĽxQ©Z»sbîééĹqśJŐÖťq‰ă„§§'ðju[w.:A<<hęçç%‹ť˙rçN3ĂĐ3‰©5*Ä9$’çůcÇŽM0ˇă÷€aS§N-_ľĂ0Á`řMAQÔd2ÖÖT5¶¶ąşČ (Ęîăă×Ű 7^żˇÓi]^/g&"2Ň?0ŕNkłĹbvU÷eus“76ÖŰlV—ĺŘí¶đđH‰DR__GQ”«Ş  ({DD”HDÖŐŐ0 ă˛JIQTTT †áµµŐ<ďşáGÓtTT, ¶¶ş;M3Ńѱ<Ď×ÖV»|R<Źp˲L]]ŤË 7Ďó<ŹDEĹPU__şľjŔcełŮęş!‡#",,Ňb1766`‹rX–‹%ˇˇaˇĄĄŮU9€a77·  ťNŰÖvÇĺńÎ0´»»Ňß?PŁQ©Ő*—ĺĐ4ĺééíëë×ÖÖŞÓiş3˙řúú{yyßąÓl0PT0Ř9ŕÄŐit®^˝H’’ű zĐaŞˇhšîÚ`[˛dIXXXJJĘň”¬Vë¦M›>řŕáÇ X@@@@ŕ76ذĆĆzżÁCű Ö)dî!Á0¬ąą1??Ď`Đ×ŐÔşÉĺ1=z¸& J«(+kľÓ8bÔ Ŕ—›T[[uëÖŤŞŞĘ#ĆúřřşćÔÂ0¬ŞŞâÖ­“É8fĚww%Çń.u2ZYYVTThłYĆŤ›"•Ę\+)˘hyyqqńMŠ˘&LćršS@ié­’’[ÇMš”€ËŃh|qńͲ˛bE'NĚrąNÇqĹĹĺĺ%"9qb–k„¦™˘˘%%·ÜÜä“&=íŞ`·ŰoÝş^TtÓÓÓ«;r¬VËÍ›×oÝ*đ÷ś<ŮE9(ŠšL†›7ŻŢ ‹čŽ˝^wóf~aa~LLśËç…˘¨FŁľy3ż  ?>ľOFĆp—i[ŰťÂÂü‚‚kIIý|¤ËrZZ Ż\0 =**ÖĺÉGŕ7PVVTTT鼢Řر“:šë>ňÓ«’’›ĹĹ7‘.“ŽL¦—_~yóćÍÝi¨ĹbIKK#I288xďŢ˝˙TWW·rĺĘ›7oúúúľúę«iii ĂTUU 2ÄáŮ«®®~˙ý÷oÝşřꫯöë×AŁŃřÁś;wN©T.\¸pĚ1Ž5ł/żürďŢ˝^^^ ,;v¬pŁ)‡ŇƲ,DZ._t ăP㸻[eş!EQžW÷ä`żŠĹ@vHwÚ €aXřőnĘaYtoŢ€űú†…Ęz7)ĺŔ ‡.ËřÍ 68á°÷sćw¸ÁÁŰŰáď°čđ.żźđŢ{ď­X±ÂËËËĺ†â8>věX–eżüňËŽÇU*Ő‡~(‰ŇÓÓyž?|řpZZš\.7 0Ę“çůÖÖÖŹ>úH,gddpwäČ‘~ýúŮíö˝{÷ <¦écÇŽĹÇLJ††2 sţüů'N¤ĄĄY­Ö]»v%&&†„„÷Š€€€€Ŕýź¦>EiÚ•P=¨jĂ/áYŽă8ŕŠÁĆJ¤‘HPŔńĎ# ăʶ1Ĺ` {Eyž–[÷ähnąć©Í€%%8ŽcĆ5gwĺŔötc/ŕ8ĘóĽkťŚÜ AĽ+A—ĺp×.tGĂ0Âp7ÍŚk÷3 DÄYçš~’ÓŢÚ…hO˲ÂwhŹkrP§órEŠ˘p49ł®Îh{:‡Cw柎r\ľ~ĂG Ď?Ŕ“gEŽc†… 7í˙3 _pŽ9ďňţüç?Ďť;wçÎťóçĎďj«Ü=?–››UYY  ‡‰Dď˝÷‚ ß~űmÇiĺüůó7oŢ\łfM\\śÉdZ»v-‚ űöíłŰíçÎťă8.===77·¤¤díÚµ111z˝~ýúő‚L¦ť;wŽ7nÉ’%:ťîý÷ßĎÎÎ^˛d‰ŮlÎÎÎ [ąre]]Ý+ŻĽrřđáçź^¸Wô@˝«»bđIôáĺüěë(üáĺđ<=ŐĐĆűU®;Ďö$µżH€ĄY *\üŻq˙üvĐ);EQ;wî|îąç˘˘˘L&“H$zíµ×4ÍÜąsI’ś4i’ŻŻďÍ›7ż˙ţűçź><<Ül6KĄŇW^y~·¦¦fѢE‚(•Ę9sćĽţúëK–,±X,}ô‚ YYY»ví 6‡Sˇ\‰clWűŔ=O]—ňíŕ—z+ľ(čůéxŔU9śł`W;öÍ{x~ťöüÜiţ˘Kß·żčr=PđĂĘéÔ?®ÝĎÎíqUň‹äŘí6Š˘d2çýŤ\§/ţçĎ Äb1s'‘Hxžëdćą:o¸"‡ç9ŁŃBQ”X,&IĎwy÷rΫH˙U¸_:˘)Šş_ňű¦‚LNNž5kÖěŮłëęęĽÁÇńk×®ýđĂ‹ĺÍ7ßÜşuëüůóď÷a–eoܸ‘śśŚ˘č”)SţńŹxzz^˝zučСv»]Ż×$$$<öŘc"‘hęÔ©ýë_ĂÎÍÉó|mm-‚ Ă´´´ÄĆĆ"BDhhhMMŤp›¸dç<ś•:Żp#Ý0Ř{=®EýÝč\– ŔˇS€t/ ńĄÓĺĐĘŽ:tÇ0ˇnôň«śTwä8{Ř\;©N)aşq?sżŤśű$Iž>}fÍšŐü`µZî•ăěasĹ AŃ. ě‡9wýé?'Çń–––÷߯Ť«V}ôÜsĎĂ$ţ«ó<Ďq|wź üęüŇČ[–eĎ_ČĐ@—‰Cďk°566;vléŇĄ?›ßź ™3göěŮ“eŮéÓ§ďŢ˝űÇq---ŤŤŤoĽń†ŮlţńÇ·lŮ2kÖ¬°°0XćU.—·µµ577ßąsçď˙»ŃhCĂů-ßţ»¤#Nڦ)xiZZî8ß˝Îë!÷Ę;î7О?`ű–ó8uéÔź]ĘŃëőjµşKłę~rěvŰ6:[g?mRÂq‘t–CÄ©S§X–}ď˝wÓÓÓišę˛1żŠŰůW§}ćqĚ-ť‡?‚ ,KS íĎŽwDZ6›­Óp†ÝŇq|nôÁ0ěâĄ+uőu‰$9)Ůů\ş6Ćt:ÝÇ»hѢź5Q5jü±aÆ˝őÖ[?kq¦§§O›6Ť¦i¸-mÖ¬Y°şkG™éééS¦L±Űía×®]Ó§O—Éd“'O>tčP[[˲­­­]şţ:.9}ú$Éó>>/żüJXXŠ˘đ‹ Ă,^Ľ¸Ý€ě®Đét;vě<}ú´V«U*• őK—.•Édv»=''çűďż///7M~~~EÍžýŚ“ ÷ ńŤn۶ígĎž…[SSóâĹ‹6l‰‡b]_ß9ţĽNĘ%Ľ9ŽÓh4[·nÍÍÍ…[kkëÂ… Q˝zőę–-[Ş«k,‹R©LLLP(±±±]H<Ď57·|÷Ý–‹/Z,µZ=oŢ<A 7mÚXUUmłY´ZÝěŮłBä‰ ˲µµµ›7oÎËËłŮlÁÁAz˝aćĚŽ”ôđE‡¸Yţ~rnßľ˝iÓ¦üü»›Ůlž5k–ăĆo/’ĺä>{†)--Ý´iSAÁ šf"##m6Ű“O>é°™ˇżšçyŽcyžç¸űɡ 7nÜxëÖ-Žăbbb†5j\ôGQ´ĂśŔ#í)=»lO~ţµŤ7¶l=ÉĚĚě(žĽOîő„ý´BÓôĄK—6oţ®ĽĽŹaŘ€ýˇÔd2 (f±ŕç»쏚»DZk×®-_ţÎČ‘#ţńŹřűű!hllbVëĂ©ęőş+WóŚF#Š˘Fٱ °ŔÍÍM,ľgF»|z˝÷Ţ{źţyttôC>íŕ^2žçëęęśźîů=ŤŠŠ‚!‹<ĎŤĆN8haJř“ÉäřŚ\.˙裏._ľĽsçNúő0 IDATE{ě1hř#b·Ű«ŞŞ˘˘˘-D@@@@ŕg—ˇŞăężÎ€‰*oß޵{ObbâÎíŰľţjťÁh¬Őë1ťAÇń›7onŢĽiČĚŁGŹ|÷ÝćşşúýűčtZłŮřĺ—_”——ĆqlÇ&9)”<†aůůů›7ož8q±c?~űíú˘˘˘ěělО8p <µyóF//Ż•+ß×é´PC‡„=†ačĹ‹¶mŰşdÉâ“'O|úé''Ož<~ü8EQđÇľ÷Ţ»3gÎP*•Ž«ăl@˘(8wîÜÎť;ţď˙ţ|ň䉕+W<}ęÔ)–e¤RinnΕ+—óň.çĺ]ÎĎż†ăX—ÉŕÁłgĎěÝűý[o˝yňä‰ĺËßŢłçűłgĎňwîśĘĘʆ††ëč S띣­p?rähzúŕ!C2 yttÔüůónܸQSSűĆ}ć™™ááaAČĺňĹ‹566 z'Ź Ďq†af?ńĨAĘĺn=zÄ.Xđě… çďÜął|ů[“'O ÄqÜÓÓsѢçËĘĘ,‹łG‚ă8EřaňäIýű÷“Éd={ö\°ŕŮ'NX­V.µuëV›Í6yň$śŮ®vwáÝż˙‡3¦'''ÉdŇ„„řůóç>|†´) ™Lîć¦pss‰DŽ^rnĎóś;wNź>‰2™´OźÄąsç8p€ă¸Í›ż›ľ·L&MNNš1cĆľ}űř)i7Ďó---ăÇ?É0Śs{xž·ŮlÇŹźX¸pAŻ^=e2iż~©S¦LŢżÇq•••‹/ňôô‰đgž™•źÍ9ů ÔŤFăąsç.\ĐŁG¬\î6p`Ú1ŁřÁfł—••ýéO/xyyŠĹ⤤¤Yłffg‚ůÄ;ť‚ Ť&?˙úÂ… ˘ŁŁ yffFffơCŮALćíŰwŚ1rȡ}ô1´%ŕsöř57·”——Ďź?/""ÜĂC9|ř°ää¤ýtMÓµµµź|ňippČ‘#GżüruPPčîÝ»%‰c\8Ü×|w&˛ßؤ«WŻMś8Ń`0ŞT*žçQËÍÍť8qBZZšD"‘H$ńń˝˙ůĎw"##·nÝ“•5-::J$…††˝ýö[ţ† €Eç |Ç,č\ÜŁÇCú˝’’’g?3wáłĎ/|öů…Ď.znÁ˘!™Ź+•ž÷<ŮťíĽW_}uěر#~Ö4<÷Üs Ă0 3kÖ,xÜfłÁě#jµzţüů"‘híÚµ"‘hüřń«V­š?>¬ ÷ /Ŕćęt:řE’$ÇŤ÷É'źĚź?®µĽřâ‹Đ;g4áĄR)Ět‚ T*ť0a»ďľ;{öl–eCCCGŹ-(mLk­ĽĽ|ĹŠ÷e2éŁßZ›Í6lŘĐŮłg[,–˙Vxá8ŢĄbe|×6‚¨ŞŞ Ž“$Ź ÉII»vďÖôUUŐ!!Ááaab’äx>%9yçÎ]:­Ă0ĐŮŕŔJJJÓŇá8Áó|˙ţý7nܤŐęÚkßMéh Ď˙”ďępÇĂŤUS¦Löőő‰D,Ë 4đŰo7čőú¸¸v;Ų Ă0b±DĄR) Ĺ:µ·-((\şt‰‡‡'AX–MOO_ż~˝ÉdŽ‹‹Ł(;Ě`2™®]Ë—Je ťä@ôĆŤ‚ &( ‘HÄ0LFFĆúőßR…˘h}}ĂÖ­ŰfĚ7ę8'S€ąqŁ`îÜŮR©L$"@3336nÜȲśÉdZ¶ě«Ő¦P¸Ź9˛WŻ^0I'9đ2.[¶T,–Ŕ”[¶láyţÜąÜ žýčŁUŤŤMĘŚŚŚńăÇ›LFçöX–»uëÖź˙üI’!â8~đŕÁ»wďáyłk ŕ8nÆŤcĆŚU*•0ë`'9(ŠĐ4SRRú÷ż˙Ť D8ŽË劼őÖۆ\ż~ăńÇ‹Ĺjµş¨¨(<<śaXg9 6›ýöíŰË—żŤăŽcÉÉÉźţĎs‹5::š˘(–ĺärEpppqq ¨C˝td/DÄd2×××8Çq ĂĽ˝}âăă·oßa¸Z­ĘË»2iŇ$«ŐZ__wŕŔYYYí{á:%ŃAt:}kkŰ€`=±ŔŔ€‹/¦Ą lii©¨¸ýĚ3łZ[ŰŽ;šŔ0LWÉ9€JĄ6M)))†Ł( ®¬¬Ôëőßż˙ňĺË#GŽÄ0´­M•ź=>>¦™®BAKK Ă0}úôĹqA@TT”——wMM]SSăˇC‡1 ›={¶JĄ:{6'33ÎťBáÍÜĐĐ€ăDŻ^˝a&ˇ¸¸8©TÖŘŘŘÜÜôĂY–™5kfeĺí'NúúúFGGł,ë<¸P­®®Q(±±=`6Ž„„„]»vWWW4X,–ěŰ·×ŰŰgŕŔ´ž={Ůíw“ŽtĘ äÚ<öŰO Až={ÔÖÖ÷ík–H$žW®äEEEőęŐK&“I$www'rss‡a8ð†…‡‡ŮíMÓ<ĎÂJ÷E;¬ šf ß’¦ď9ţżB®Ŕ0 EaANŽă8†ˇm6ëĎl/Ľđ‚BˇxřźÁ0lâĉ›7oFQtҤI˝{÷vüI§Ó‘$9gεZ-“É üž={>üŕÁAŚ3fŔ€Đ«6{ölÇ5ŽŹŹ6lXvv6I’#GŽLMM…ź5jÔćÍ›yžďÝ»÷Üąsá*#†aÉÉÉ“&M:räR©|úé§}||˝M@@ŕ†aMMM{öěů_i0`áÂçţ«ďrŇ‘.OCQťNߣGww÷ââbĄRČ2,EQ:˝ľWĎžrąüVq±—§g@@ÍĐ6» ëÖ8tAD­V+ ©Tvýúu›ÍfłŮÚ[}×Ls¨’]zl¨T*OOO±ĽrĺjXXX@@ Ůl˘(Ęjµ1 ÍóIŠ´ZíĆŤ›’““<<”ť”9ÚŁRµůřřqůňĺŘŘ  @˝ŢŔ0ŚÍfEQtűöíFŁŃh4ĺćž?~¬››[W-A¶¶6???E/^ĽŘ«WŻŕŕ ­V˲,‚€íŰwČĺŠ'ž“Á´źB§ĐĘ»‡ŰÚZýýxžżpáBbbbpp°Z­¦izĆŚéfłĹh4Úí6łŮŞ×ë§NťŮi‡O{˝;ľ­­-00eŮóçĎ÷íŰ7((¨­MĹó|}}CUUuuu•Ůl6›MôňňJHH負3Ďs*•*((Đn§ňň®$%=ŘÖÖÖÁśćËËË‹ŠJţú׿B«†ăş0lX–Őh4‹Ą¨¨č±Ç hmm•H$S¦LٲeKyy…T*Q©ÔĹĹEłg?CQT—IY†ŃétFَ´´<)©ŻŻŻo[[A<<”ąąç“““qomm={ö,™ëlřń}gĚQTTôĺ—«Ź?‘śśÓţ4*ÚĺX­VОűúú655©ŐęřřŢrąÜ`0ÔÖÖž={611ńąçĘd˛ĽĽ<•J ýďMÎqWŽŮlfYÎÇÇ»¶¶Îl6÷ě'‘Ht:miiiYYYVÖ´'źź›{ţĚ™łP‡îráAÁ˘ŔËËł˛˛î…#ÂjµÔÖÖM›6uôč1ůů×VŻ^“źź—Z:].Aôz˝\.W*•ĄĄĄ"‘(""ĐÖ¦zîąĚĚĚĚŇŇ’¸¸¸W^yŐl6Ůí6§¤#HűÖÁGČbCQěúőëAAJĄ{BBbMMŤN§W(&|řđáĂ;‹Ĺ‡î4‰Ŕé2+++++«ăźärůşuë:&xś>}úôéÓ;~† ‘#GŽ9˛KeîÜąsçÎÔ5?8pˇ—$I??żGvŃ`4u:ťT*u*‹ü_0Ů~•/ŢŤ{C˱†‹Ĺâků×{ÄĆFEEń°Ëb8&‘H®^˝–Ńn 9§őç ÎŤaIŠ.\8?pŕ ĐĐ`Žă`V@ř™Ž†_uĘĘ·E1†‰DÄŮłgĆŤçççŰ×ÇĂę¦&“éôéÓŮهţůĎĺžžžť˛“9~‚¦Ç?yňd@€żR©lß4‹D˘Ď>ű¬®®žçywwĹ+ŻĽ,•Jśĺ@µ’ah‚Ŕ1 ;věÇČČOOO4Ąşşz×®]|đľ\îuŐ~jw»ą]{憉GŽéŐ«§H$˘iš¦©uëÖÂ^Őë EE·Ţ}÷ßv»ýo{ŁS˘HGŇ4-Â9r¸OźD‘ išçyО74Ô˙ýď knnţ÷żWnذaŐŞŹś÷ÔÁŘT†a‚`YćČ‘#ÉÉIPŽă>ˇiz˙ţý))Éá6›íŢ“ş+‡çŃöó †ŁGʦ¤$NÓ4Aŕ™™é;vě<{6Ă0@rrrff&ĂĐN…łď^w–eE"BĄRť8qĽ_ż‚Ŕ)ВɤÉÉÉ›7o&I‘D")--=t(»=˛ÓHäqv"ˇÓiOź>ÝŻ_*Žă4M3 íî®xâ‰Q•••(Šúřř644pwçŰ˝Ů/ąöP@Ž$E­­wrsĎĄ¦¦ŕ8FÓ Ă0!!!ăÇŹµZ-aaˇii> ĆtęÉA§ I’ ő…ÉÉI(Šr_[[c·ŰçĎźC’"›Íš”ô.%8yĆ8áX–Ež$ÉŞŞŰŤŤM}űöAQŔq\}}˝L&2$Ăb±ôé“8xđ`ťNŰţ­{B„CŽăX$I–––R”=!!ž{EEąHD„„„””ąąÉ0 ­««CQŕ”,ä®˝Á˛ б,,,T(={Ć!Ďq,EŮ0 Ł(ĘjµP”Őn·µĄ_«*ýo÷$Âňóó###d2YrrŇöíŰu:­źźď”)“I’Üż˙ţý¤RijjĘ3ĎĚ0`EQĂÂŹÎëc÷1Řx‡±úHV5ŕö9č°zÚă¦á Ë;ÖĂ˙ĂOčn~@@@@@ŕaHIIÉÍÍíT1ĺŃA"‘|ţůç0Üýż˝ębv5XÚ´ă÷O\‰XĚ0´ÉdzjĘdE z=†b!‹Ĺ M›L¦¬iS1 Ó p‹9@Ѷ»›1X–•H$6›MŻ×Ďś9Ă0ŤFă†a7H´'ęŕ»5‚;{˘8Ž“H$‹Ĺ`0Îź?Çq­VCTOyž'bëÖ­kÖ¬{á…e}űöEś2Ş;rHĄR“Él6›/^łĂ”`ÇŤĆďżßòl[›jýúo?űě‹˙ű]ooďNr R©Ě`0Y­Ö_|Ę‹ĹAĽůć[ŁFŤęÓ'Ç1G®ö ݵ"¤R©^oP(/żü†áZ­V*•Âí[Đ`éÝ»÷ŠďeeMýő˙ëTŽÖˇĘd2ťNďăăýĘ+ŻŔ R©öŰkŻ˝ęççg·Ű=<<^zéOYYO߯V‡öČ_yĺeš¦u:ťL&s\)­V»oßţm۶ŔÝzH׉ěďŽ؆?ýéO6›Í`0Čd2ŁŃ¸rĺűééćĚ™­P(jkk7nÜôî»ď}đÁűť2Ń;îg±X¬Őę”J÷ĄK—ÍfŁŃ(‘HÜÜÜćÍ›ű駟ϛ÷¬ÉdNH6lč±cÇ9ŽíS÷.ÂLŕ:ťÎĎĎoáÂFŁŃd2ÉdRŠ˘rss?ýôóŞŞŰ‹•¦™ä䤊fç!†˘(ŽZ­6<<|öěŮz˝Ţb±H$Žc ‚Je‹… p±„î>xs§ě©†ˇ(¦Ńh{őęŐŁGťNgłŮ$±ĹbeYF©ô€.>GĆr§ěŽĐ:â`$¤FŁMNNNJJŇjµE‰Ĺb«ŐʲśD"…~ĄR‰FŁé´g Ęá8že9¸3M«Őfd¤ó<ŻŃh†%I’ç‘Í›żŰłg\‹Ńjµ˙řÇß§:lŽťW$I2 ŁŐjGŤ Đh4pl˛, 7hÁ GÇMâl>jY"7nĚ1]ˇP$%=¶rĺűZ­®Ź 6tČLŽăš››·oßńÉ'ź~řa°‡‡Ň`0ÂĐč.ť´Ž ¤ÓůEĆ)«çŢÇ=taw˙Q§ŐjÝH@@@ŕ[Ýġć÷ȶP*}$vŮµŻť»ÖßąÔ/@Qáy___Á`2›<=:˝Ţl1{(=P­¬¨“bą›÷Z~×ýý}U*•ŮlV(†–––IĄ2‰DěČ é0ÚťE÷4§ÝÍÂú·´4Űí6™L†aŘ­[·ÜÝÝE"Ç1†ˇß}÷ßyyyK–,6l(IŠś{Ă‘1((°ˇˇľoß>b±ĂĐââb/// Ă$±Ýn—ËÝxžws“˝řâŇI“ž˛X,]fSä86((°¶¶şGŹh±DQ´˘˘ÂĎĎŹ sçα,{úôiAPĐ4ýÄc:¨PČďíű»IŘ‚ŞŞn‡†K$b@EEĚS-•Jěö»EE"Â×××d2:'Ös¸%‚‚oß®ô÷÷Ĺq1 \ âyÎßßßĂC‰ă˲†*•JłŮŇeÖJn400 ˛˛˘_żTÇX–«¬¬ â8¦âŘ»w_RŇcaaˇíö0čŞ=żż_eeerr†ˇ4MĂ„ć6›őĆŤ˙üç;ľľ>†ąąÉ¦Oú•W^sJé l€a¨··wUŐí>}1 µŰíµµµAAÂGEEľđÂ’§źžŠ @$ĺäś‹ŠŠt Ő»ëŃ"ÂĂCY]]Ő«W/‚ŔÍfscccppH]]í¦M›ÇŹ-‹ wďŢÓUÄ»rÄbŇÍÍ­¶¶666†ă8ÁxçN+,6ŲŚŐjEQŔ0 EQĐ7ŰĄ¸j “ őQQ‘Çi4ZŤFăëë‹a(¨Éd„–,ęe·ŰíčńăŰťÝrąĂĐćć¦ĐĐAZ[[M&“——†ˇ(ŠÚlV0ÇŁĂmčě©ă8V©tŻŻŻom˝ HSSłÝnS*•eź6mę3Ď̲٬HRj2ŰC4AÇ‹Î˛Ś§§‡JĄV«Ő~~ľ‚Ô××sçîîÎq,ĎŁHÇ©ăDĺH ĂÔjŐ›oľýé§źń<óćÍÚÚšÄÄx…BáČ÷#“‹=?sć3*•*.®GyyůŔ`ő9XÝjµµß ť{éŕ$w.&ńlţk}}Ťcí¦Ă"ßţpáyqÄ Ýl Aďż˙ľ  ’‘‘©Vkľ˙ţű¨¨¨QŁFĄ¤$«Őę«WŻŽ;Ć9) ôDÉĺnQQQŰ·ď0MJJJĎś93xđ µZSZZ6hĐŔ‰'$&&čtşvGPQ†a===víÚm6[)((ČËË0 ?ËrÍÍ-§Oź&I˛±±ńĆŤ‚ž={ÁL!ł ¶{´Xą\±oß~«ŐĘq|^^^qqqßľ}˝˝}D"Ń÷ßďĄ(Z$•••]şt Çqžç:ťÇń Ă„††˘(šť}Čn§†ÍÍ=_WWßŰŰŰŰjµ]ľś'‹KJJŻ^˝FD—ăŠččhłŮ|ěŘqš¦iš9uę”V«Ť‰‰ ôđđP*•ăĆŤ1b8Žmm*]&/ˇişWŻ^wîÜ9sć,L­qäČQš¦###Ú»˘óDĺ4H]śÇ~#P+,Ľ4bİ!C2‡6tčăuuu6›}Ďž˝çĎ_Đjµ 8Ž744ŔpâŃŁGçĺĺť>>›6}·jŐÇ©©©>>Ţąąçᆢ¤¤$ĄŇÝą‹ěvjčĐÇOź>säČŃÚÚ:ŤFsëÖ­Ĺ‹Ëĺňk×®ŐÖÖUWWKĄRłŮ’“s.##&ďhĎB94M>üĚ™łŮهËĘĘŰÚTĄĄeŻ˝öĎ#/żü’ŁÄbé×_óÎ;Ëah'ęÜ#GŽř±şĽđ IDATŰßr˛ł…‡‡57ß©¬ĽýôÓÓ1 ËÉ9§ŃhCCCE"‘JĄ:w.wҤIíy:÷ÜČ‘#Ţ|óí~8ÜĐĐXSS;ţłÇŹ9â믿‘ËţÔ©ÓăĆŤeY®Ëx-#FŚřç?˙yŕŔţ55uMMMK–,aY–aŘłgsP8p Eutd9‡D˘8Ž:ôý÷?Řż˙€ŹŹĎíŰ·U*ŐđáĂQËĚĚÜ˝{ŹJĄ†Y"Ďť;7fĚhśŁS(#‚pb±$##ă‹/ľÜ·oż§§gII‰Á`6l¨Á`8~ü$ÇńR©´­MuăĆ …B1xđ`Š˘ťŇńóÂĘ労´´Ť7íŰ·_ˇPÚíöŚŚ »Ý~íZ~SSSSSóŐ«×ŕő…˙ś ?ÖËË+))yßľ}űöí—ÉdWŻ^ 8°¸¸XŁŃääśc¦şşFĄRĎšő„Ýnw2l ÄÄÇÇź:u* P,&/\¸ ‘H’’ĂqSVV–ššú_.㼠řŔËÁĐL}]ÝCA ˙á=lŹžÁĆuÚÝô08o™‚Ŕ±lhHČÜąsż\˝ú/} ©OM™0áI7™Léî>oŢĽ/żüňő×˙B’ä´iSÇŹë®PPv»s“hš ť7oΚ5ëöîÝ+‘H¦M›:r䨏~üń§999rą|íÚuŤvßľ=¤iÚy{ MÓ‘‘áĎ>;oÍšuŰ·o—Éd3gÎ2$S.—11qÎśŮ_}őuccc``ŕ˘EĎ'&&p׿żŰ·«ľţú›¦¦&ź±cÇL›6Íůş;ö=öXß3f|óÍú;w†.Y˛¸wď^ ĂĐ4}čĐáąsçÜĐĹwY§ššňÔSSÖŻ˙V­VGFF.]ş¸GŹX»ÝľtéâŹ?ţäÝwß5Śţţ~#GŽ|îą…v»˝Ëúi8Ž VSSłfÍZťN×cÉ’%ŃŃ‘z˝!--íĂ?R«5ÁÁÁ#F öŮů8ŽĂd6ÎrD"QffF]]ݧź~f4–.]˘Óé&OžôŮgźkµÚ~ýRFŚžťťÍ˛¬Ó^Ż»r$ÉđáC>úh•ĹbINNZ˛dqHHpQŃ­ČČH‰DňňËŻ†††Îť;·˙T»Ýî\_Ęqss3扖–ć+VP5`Ŕ€%Kůůů±,›•5u۶í«V}¬ŐęRSS—-[JÓ”Ă˙éčfŽă†qwwź0áɶ6Ő»ďľ kKĚź?ßËËS©t=zôçźľoßţÁ§¦¦ÂbNÉBîĘńňňś2eň×_Ż_ľüžçGŚž•5 Ö™;vĚúőßţĺ/ĹqüÉ'Ç÷íۇ˘¨®öÂq Cűúú<ýtÖşu_żůć[€±cÇLž´Ůlfł…ă 7’Ľúë1pŹa(IŠaąEžçUŞÖ’’"77ů¸q“;Ęíç8ž p™LďO›Ín6›`Źv!0ß=ŰÚÚRVVěĺĺ3r丆†ZEáöĽr77Ś´Űí&“‰ăx‘‰H»Ýćéé méććĆŠŠŇ€€ŕÇ ĺ8ŽłZ­‹•çy‘€íůö®;Ľ©Şżçf§i›tÓşé eSö-2dYD@QDd"ěáE¶ ›Td–˝ …h i›yÇ÷ÇMÓŇMµŕ}źÇćpóËągżç·ŚFcnnžL&Óétb±H©TZź¦é””¤„„[AAˇMš´LMM˛ĘŃétz˝ŕxďPŢe——Ż×8Ž•H¤NNJ^5a6›“’îß»w'""şn݆ŹĄđr†Ńét|ÄN©Tćä¤äĺX'ťL&ĺ‡ďve2™îßż{˙~bÝş ÂĂŁŇÓ•”#“ÉxOQ4Mët:ž|Ęĺr…BÁ—›LĆ»wď$'?hܸEőę™™ŹIrž€\.W*•|âoŠ˘´Z­H$âcęX›Ńh¸}űÖŁG)-[ľäé陝ťUuÎE„P99Ů2™ŚŹKÄ{lňás(Šâ_“e9Š"|ZGß’ ĂPĄT:ńA_Ěfš·%fYÎĂĂ],ó뿀XËE"q…˙aÖš““}ůňĹví:RÔS!j)ŠÚşiӠ׆‰D"§řš5j$˙˙‹çĎ]şxaÚYť a @€€ç b1çě p`h’“JlŇW®\?~<Ă0fłąM›6 ,ŕŐJ7nÜřúëŻ?űěłgş5äŹ˙ Ísř–Ęq°MĂ»á.ŚŃĚńç6•żI34MÓ47.“ÉśT*>j9C3|9ˇ(”0‰ä ‰ÄĂĂžćźgYŽă<==¬ućy Ä)ÖS|>,»Rů”š¦˝Ľ<‹}…UĚí‡ÎĆ”ĄR)O>ůs9_‘ŇhÔüáŐŞy°:޶WAÔA–eĺrąJĄâźç)vńĆeY___>â_©ľgü •ĂuÖJň•§i¦ ł\éQ9ŽS(V7«Žă Üfő}QZtGëŚ(U>·R9đE5$NN…żKÓf>IEŤFcmç"őa‹žńŠŽg•JĺęęĘ·9_žů»¸8?-Äđ ä8äĘ’c}Y>Fź«« —Z¬>|ţeťťť55?&ůA(•J}|Ľ†qsÓđŤFÓ´Ő©Xűpá8–ĘŐŐĹÍÍŤŮ‚ú€§2ă«Äë¦JhęřŔ„o%µZÍ“(¦ŕ˘‡X'˛ź§j„-ÎŞź/)‡ż,Đh4"‘ŕŰ™á'iIMź1ąČóEëChšV«ŐĽ«ŰÓm()§Š,¬,K»»»1 kťz„>˘©Z]ĘrÁ7ݵ­ÓŰŰ‹ŞčťË2ź˘1ń CU‹;Rˇ}¦“J•—›Ë˛ Ëie ÁńĄ,[Ŕx“Hxľ@QäáCů˛ĺśXĚúű™†ĽF2źTČŮ’’’Ž?>bÄ˝^ź••µoßľ.]şdee˝ýöŰŹ=zÖ[ĂË—/_ąrĄXŞĚçö$]-ţ%BˇŽł‰¬ţ*„˛śéa6 ÂN(BŠYõn*yĘça|ÚŠ˛ČQ’ř•%§T!|­J6Q9rX–µFQ/Vٞäđçňň›·¬¤E#—*§¬F+ç8UV}J-/-qvrĘęŻbD”˘,%f3m6Ó%»·Ôv.# /Ç\,čż•UBËq¤ňrř ~śé,Ž2ëcí¬˘ĺĄĄ=(”Ăq¬ÉÄĹęĂ˙V)ő,v±RôB¤d{ňąËKŽźbďU´}Ę˙Ą–łl± (Ö‡`-·¶ ˙"üÂĎç…«j©ŘŚFS±±Î‚2–‹ŇGÁPú2UĚđ9˲ąąZž™3 Ă2Ö?ÖrĆHĄa  Ň‰DUçâJŔü b±(ńľbĆLlőętóćś·7Ęcµ;zÎŚ$-QÚXŰú˘d6BŠŁě¬ ŽÖ¦áQhŐf5A´qö/ë(99s;*I®Łâ8*a±5şMD‚Ř˙^ĄEżdí—cß{cC;“’Äφú}úLš4‰OÂůÓO?ýő×_}űömܸń;SxńâçË·­ «MÔŞŚBcä)jCřÄĐ6ĺŔ%%)€ýr R¸rö˱Íɤ4÷!ŰΦ%ۇsÔ r„›;«¤)Ł-ŤSšI¤mD‚}Ú%ÓF9O'¶±ß‹žµłÚÇQë†ăÖź*›<úż Ç´´4oooˇˇŕAQ˘;wn'&ŢšBŔż ‰\N‰$ś“„ŽŤ5LyOľp_.Ýľ]ńŮ"ý»ď°(”¶ůKĄŇ .Ś1‚·ľ[ąr%__ßÓ§O—ó‹iiifłyÎś9:ťîÉ“'kÖ¬‰‹‹‹‰‰iÝşőąsçřgrss-Zd2™–-[–ššúő×_Ź5ęąjW›M’JMśMlĐIB c١»”śĽ¶¶ČSwŰ”HĄůÔŮÂIJ#¶¤ŇŽŘ ;4le±‡.Ú<žËńa{ÖéTä#ěTgŽ(UjĎŚĄ¶ąsçĆÄÄtíÚ•ĎGQá:őđáC~ĐP%—Ë]]] bér)))„±X,¨ěĽ—%nnnrąL`m˙°,›––ĆŻl>>>˙:W7ÔĐĐŻżSi»ÉČPőí bĺň’_7ŤÍš5[ż~ýرcß{ď=TÎZٍç›Édrvvć˙ÖjµE=uëÖmâĉřt´ĎQ/óáím»á.vŰpb‘X*‘Úpfâ ™8Žš6B řěUâ84mfÖ‡1‹Á•Ůlâ“!Ű@üx9|Ěf­Ú9Çńrěr„ă»Űl6Űsş-˙Ăж˝”•źóUbĆŽNç bş°|ţk[Çł…ĄóńŤě—ò¬Éd¶ŤZ™ăŔ0,ßďvȱ$šŁiÚ9|w1 mwűr`çúCÓfš¶qüř;ŤĄßë9†°ËĺS¦Lń÷÷oĐ A…ß7™Lµk×ćoj=<<š7o>oŢ<:ť.<<\.—{xxÜĽySč9/Ö®]Ý®];cE<ďŕ“rÖ®]€››ŰµkWňóó˙ĺĄ_"‘ž;‡Î]Ë` P*J-'„äç燅…˝ůć›Mš4ůóĎ?Ë÷4łţ«őŠ˘ĘŠľS, óóŠ˘Ň3ŇŚleŁŔ—˛Š-Ń_8€c9gűř*ˇ¨ä”$W×"ů‹žąJĽZěÁD'''›9 ­Ś˘Hbâ]ą\n‡Ч%÷îÝ‹Ĺ6](Ę2nńJ?űn–5‡*)‡?Ż'$ÜbÖV!°ć›ş{÷–Íă$Ţ5›Íwď޶Gß>FŁ!1ń]ܶÎâĺčőůÜĺJŮ,‡äĺi““ďŰ,G$â INNvjj’}r!TfćĄŇÉćöá'!$##M$ŮąţB=z”jŤ/lßUl—!ŽĘĺ-.uš8qâ¤I“6nÜX}ät:ݡC‡L&Snnî.\řůçźóÄoĎž=z˝~đŕÁBź x1 R©Ôjµ@Řţ „ÍJB!®®kÄŽŤ°IĄ"…˛řńŞäy37—#TYË5€®]»Ţż˙Ť7ŢX»v-ggg«1ďqîÜąożývůňĺü2~üřńÚµkëőúFŤýřăŹü“ÎÎÎĽ%dQÉĎX–őňň1 —/_´Ůńe9µZ­R9űůű_‰ż´g×™TĆŮ´=ł,ëââmĐëtůą6źŕű‚ V(Ź=Ôjłˇl–.“É>LÉÎ~bO}"#kI$’ÔÔdŰLż¬c,&¦E‰RS“ŠE|VIuëÖ'„¤¤$ńłČf®Ő A#ŽăRR’lnd€Ł(ŞaĂX–e““ďóiÖm“#‰cc›ÍćääD{äH$’ĆŤ›™L†¤$»äHĄ˛¦M›ëőz{äđ‰Č›6m‘źźoźÖÉIŐ¬YËÜÜ;ĺ8;»4oŢ2;;Ëžvć8V­V¶ĘĚ|bOżsëééšššrçÎ Á­j˘fÍČ’}l¸2(ť° 0ŕâĹ‹‹-úřăŹ5Mů" EłfͬÇٸ¸8ž°‰D˘¶mۨŚiĄĎĚfłŃh۰ÍěÉwűż\'š¦ĽĽ0i"'—C&#OžČW®*Üą]\ ďN&ąąâ°0˘Ó•:tsssy±dÉ’'OžLź>ýîÝ»ńńń“'O®YłćرcoÝşőÖ[oť?>66vČ!,Ëj4šîÝ»çää4kÖ¬zőę®^˝ş`Á‚ëׯoÝşµ˙ţ&“ÉŞ~4ŤyyyĎ acÔjMPPu…K¦Ín–c]]ԮήÎŢľ”›GNv–U×ń¬`XÖĎĹĹ·FŔ'N={ěDfcLZ–ˇ˝ĂÂŔŁä$“Éh;AbďH™Ůü(9ÉL›m—Ă2Ő"kI †Ôä$†ˇí!~ľQѢĽĽÔ”$űu8ߨ˘ÍIMI˛çžřFĹ +3%5ŮöH‰DľQŃ Í¤¦&ŰSŽ‰Äľľ~fłůáĂ{¤D"őńň6Ą§?Jd»Ž•:©|‚‚őiŹŇŇÓm&Ç*\]˝üňĄf<~l»–urw÷đńÍ}ň$3Ó9Śł—·›‡WNjrvN¶í·!,ăęë§vUgĄ$ksµ6Ęá8V!w«ć§T(ÝÝ5..ÎBX˙*Žă´ZCXXda†5ËňĚť^:•rwwź:ujż~ýľűî» &T~ńóóÓëőEKř#‚ě‡L&5™ĚÖ{©TĘ›‹Ť¦˘…EŤFľ„€Éd*«€L&+úQ@Uð~ľş%KŁ^¶~Cá?Q”qčkş3 8Ů·§ä·˝˝˝ů4jµşgĎžŹ=ÚłgŹ——W˝zővîÜɧĎNOOżté’Ńh}ú#l¶Śľ˛ţ!00°gĎžüq\\\QÓ—RÁ«222Ö­[×°aCˇ‡ř;¦}VV¶\.ço !ŮŮŮüŤš“““ŐÝ/äKJ>S´Ä –’™™éää$4rŐçl$+R©řŹ?śâĆYM"Í­ZćŻXÉça#2Y©´ˇqăĆŤ7ćWłfÍxł¤¤¤bôŁE‹[¶lY¶lŮ’%Kř±QTµČłŽ;Ţľ}Űú•®]»víÚ•—ÜŁGŹ=z<yŘ(ŠĘÉÎ9sútÂý$›·Rš¦«×hV=@6{¶qăFłXl›SG‚¦ĹÇŹcĆ ů„ ظѮw‹ŽĆš5hŮŇŢ6ň÷Çî]Ś´WŽZŤcÇ`ě1™ gĎ@.·żďQnúÁgsἽBL&ČŞX†ĎZµp挽BNťÂčŃřë/{ĺěŘĎ>ĂÉ“öĘůňKěۇ;ě•óńÇxđ_~iŻś ŕ₏?¶KČ›obőjíŰ·4h°CVMĚ™3Ç!·áe¶K—.mܸń믿®­ †   ţo__ßM›6 Ý#@€cÁqśFăŢĽyËďľŰFÓ4˙1!!Áh4&$Üöôô4›ÍŤ{ăĆMoÝş•xWŁŃ¸¸¨5ŠMNN1 ÉÉśťU..šző¤ĄĄéőú‡S”J%/*$$ěÚµ+rą\°©x^č;?,0ˇˇy?˙DiłQą¨Źţkűöí­3š¦‹M”%đ©ÄĎĎCÖl‘H”t˙ľČ'°AŁXÖ6O}Bp'#=ÝM§{Îśőo˝Ą´)8M–FłłeË—ŤFŰrhÚ1Íäp2‡"ĆöŇű –…ť?çÝŽj‡î7BÓUKĂŔ!»ĂŔ!="§ŕŤ„Ťűż€Ň [RRŇÔ©SGŤŐˇC‡ EH$’ĺË—›L¦”””M›6 ăF€‡ł577Ź×^ríÚ5–e ““ÓСC_}„łłłD"6lřW_}\©TV(B$őîÝ€N§3Ťëׯ˙ä“O„– Ŕfz¦R9Q”OŐ’źź/‘HV¬X^pČ$©Tňý÷ßO›v5""Ŕ±c'(Š’J%?ü°iöěŮ!!ˇGŹ•ɤ?ü°iŢĽŹ‚9rD&“nŢüă˘E ýüü2jÔeË–®]»F.—Ź=ęôéÓK—.=z”¬ŞŮç(qRd}|L_ĺ¤R¶fMsËÖĽ1¤Łé á8Îßßßßß˙ą0q´íŰcúÓ4íää¤ŕCw"µ/,ŤHÇ-@€*OŘhš>zôč¦M›ĽĽĽžI–R©5jT«V­Ţ{ď=777Ë!ä•ţÇ IDAT"x¦9)_ąr5//ź?JĆÄD;;;Ż]»öčŃ#‡áŐ_Ç©ŐjAŻ×çŃ4ł~ý7ąąąĺęęj0čóós7lX@ĄRéőzť.ŹaŤżeYN*•čtşüü<ĄR©P( E\ܸGŹRőzýwßm$„ řŞ\.®ëŞ:a ĚŰôoůöw°µ˘|ω‰ŁíŻIۢƉD˲,ËaL  @€€°ń&Žaaa6suuŤŤŤýő×_­ą×hGYŇ đ߀łłó AC¬ąćOźţC&“ť<ů?WWעć MÓf3Í0LNN†1sGÓ4MÓ999ÎÎÎü4›Í,Ëfgç¨T*±XBÓŚŮl擌q§T*´Z­L&3™ô2™ěĹ>šżHśŤdeö6ŘHŘX–ć‹řP|—"„,_ľĽA•ü>ÇqŮŮŮ…üO,îرăwß}@§Ó5hĐŕÉ“'‘‘‘Ť5š[Ŕ‹Žăř ÚiµÚuëľůý÷“çÎť‰‹{óöíŰ%©”łłsÇŽťÂĂ#ýýkäĺĺi4šŘئZ­¶}űŽţţ5=zDQ”JĄjÓ¦]DDdőę&“Éh4ž>ýgŻ^˝ĂĂ#ôz}És*ÇÁŐŐUýź««« Nˇ(Űţ+3˙ÖÍ›;!!ŠÂ'źŔĘ®Ż_ǨQ–ň… ‘“SAÝ._ưaFt4–,5Ç]|<^{ ÁÁ‰Áňĺ(?ŇÉC`!Đ ™˙ô2ŕTnT®­Zµ‚§'üüp˙ţSĺ«VˇukˇvmLśŚŚ ä;†®]ŘXlÚTčĚsä:wF` 7Ć–-×ç·ßСѬ~ţą°|˙~ĽôŃĽyĄććâĐ Đ®´”ďÚ…V­€Ö­±o_BôzLźŽ „&M0o^ˇźŰ¶mhÖ čЇ=gÄhÄÚµ¨[AAč×gĎZĘ ¬^Ť:u„W_ĹůŠfćçcéRÔ®Ť  Ľö.]*lüĎ?GL ‚1l®\©@Nv6,@­ZƨQ¸Q0vł˛0>˘˘‚±cqëVr22đŃGŚDh(ĆŹÇÝ»–ň´4Ěś‰„†bâD$&V '5S§"<aax÷]XCď&'cĘÔ¬‰š5ńţűHI©@Nb"&MBXÂĂ1cŇŇ,ĺwďb„†""łf!=ýoęçQŁF©Őj//Ż#GŽŰB„¸$aëŃŁG…‘!­JĄ_ýu!˙ٍvíÚńžo‰ä­·Ţ‹Ĺ*•*77WpŚđÂŔÉÉiáÂE7oŢۓɧ Čd҇ÖŻ_ŻNť:uëÖ-˝^Ď0L1^a4šÄŰ-řáôůóçŤ5ňí·Ż 2ŘÉÉIĄRqg2™† ŞV« !ď˝7eîÜ9ŃŃŃŁFŤĚËË“ÉdÓ¦}X’«ČdŇ &ćççŰ‘ öy˘Ţ …báÂOMU0P›€f|ş ţŁH$’ÉdĽ%?ꮆ7B.µś˘(Rę4ÉÎĆ_ 'C‡ÂlƱcđńÁkŻ!?kÖ@§ĂС0™pđ ŞUC˙ţeFuň+W‚e1|8 ěŮ??ôéěl¬XО”ďŘtďIËŃ: č8"ŕ° <€Á@W`" ­\{ †ü|LśřE\·üV­ŕě †ÁŐ«X±ďľ —Ň…ś8qB``pNNÇqFŁńťwŢö÷ŻÁĎÍ)SŢ3™ ďľ;™ż]ůřăyťNŻP(!R©Âh4ŠĹâU«V˙§”Nźľř…$l”ťAđţ~Tţfđo!“H‘H”——wńâĹ”ÔTŠ€€€ą\NÉÍÍ˝páBęǡBBBd2˲Ąs€?ţŔŐ«4Ʀ1y2ŽEűö¸v 7n`Ř0  ł“&áđa4k†Ňkvü8îÜÁ¸qčÓF#ĆŤĂÁhŰ'Oâî]Lš„=`0ŕŤ7pŕbcáď_Ć‚´:ü™s0čxCË+Én9Ś Ú·‡TŠäd¬] żü–ĹŰoŁF Ü»‡ˇC±cŢż¬ő_|9s0dŃuë°t)&MÂŽ‹1y2ŞUĂŤ9»vaҤçcÉÉÁŢ˝đńÁôéP©př0fĎơCčÚżţ __ĚĄ`ţ|:„K—“žŽß~C@f΄\Žť;±t)Nś@łf8xAA92~ţ«VáÄ ôěYşśäd9‚đpĚš‰?ü€ đ矌ıcŠÂGA,Ć·ßâ‡đÇčÔ©L¶âęÔÁěŮ (¬]‹]»pἼpň$ę×ÇěŮ +Wb˙~ś?ŹÖ­K—síţüŤcútX´'OâúuPţú ÍšaęTřäüů'Ú¶Ellér.\Ŕąshß'ŔĚ™řýwtę„ĚL\ĽÎťńć›ŕ8|ř!NžD«V¨]ŰÁWW׳gO{öě¬NžÂć¨-°’…<‡`ťËşosM, ˲999Zm¶56‰V«ÍÍÍqrrR("‘řîÝ{^^^"‘HĄR1 ĂqlppPbbbLLLbâ]Š˘\\\r*´ÔzQđL÷SĎôz˝^Ż/j˛^Ąŕää”ţ·Ůö<ëneÍ;ĺĘ•ď6~éňeŠĆŤ6,:ş!äŇĺËß˙ýĺËW(‘¨i“&Ç‹ŠŚ¤(Š”E´ę×G·n #.|€pâ7F—. ‘ŕÍ71u*îÝ+“°ńôŚO®#“aâDĽ˙>ŇÓqč:vD۶ —cŇ$L™‚‡K'lđîÓ%/“C‘ş˛-UHNŠťĹ;t€5źA—.0ˇĽ¨÷;vXXLťŠ>McÇÄĹ!:<=1u*¦MĂ{ď•IŘ~ů'""ŞUĂÔ©93fX#ď‡ďç‡÷ßÇěŮ:µLÂöĺ—3ĆŇ/üý-éŚwďĆĚ™¨Q‚‚đî»X° L + Ý»[ZI&C·n1‡ýű1oŞU€Lś•+ź–™‰K—°x1T*hÖ }ú`Ď´l‰k×°x1řXâ-Zŕ•W°gO™„íŃ#Ü˝‹Ĺ‹-˝Ů®®]Ă Cr2>ű̢gćď5öď/“°%&âÉĽ˙ľEźÜą3®_DZcP© ŐâĂÁşëÖ ×ŻăčŃ2 ŰÍ›`ŚmŃßöę…›7-ÄO$ÂČ‘–~ěŰ·ná÷ßË$lńńpvĆС–ŹâÎ\Ľ‰îî2ÄR>x0îÜÁąse¶żţBŤčßßňqÄĚë×ńŕBBĐ·ŻeމéÓqőŞĂ ›ő|n2™„łú‹° đ_úüďÜ«Wo€0 sěŘŃš5Ă!±X,‘H!fłY,KĄBD4M—Z ë3%¦iÚÉISçÂ…óľľŐD"‰ŮlÖét.ś÷ńńMJşSç÷ßOj4Á>đĹŔŮłg˝ĽĽŞň]©Ů!I™íD݇X,NĽÓŹ?V«VíĂiSÍfzÉŇe?oßîďËŰ´ysŤ5¦řˇÉdZüů’íŰń~ĂËÍÍ­ô“ͨ_żĐ¦+4F#rs‘śŚ ‰MXôúňÜŘѰaˇ-VD´ZčtHLD“&–4€ČHää”éĆV¬‚ůŔJŔ P;® _~6ŔݡˇĐé°|9ę×G99nßFddˇˇcÝşxđ,‹Ű·UH ëÖĹýűĺżŰ· Žł|Ąn]Ü»ŽĂíۉ),ŻWwď–—óęĚ”š‹čöí§ŽĹuë"!ˇ<6Ű®-»ďBŁÁŁGXşť:a€:u¬ă µkăöíçf1‘–†Zµ,ĺr„†bËŤČČ@T”Ą\©DP¶m+SN~>˛˛,ě€J…ęŐqň$t:ääšş¸Ŕßż˙^¦~¨[Łâi4đöĆ™3ČÍ…^ŹĐPKą›<=qî\™rž<M#(ČňŃË  >„ŹXÖä“ŢŢpqAjj™rŇÓ!ˇzuËG__(HO‡L‰~~…·2Yˇ[ZI<|Ą>>–ʉ•…GŹ RÁł=0ĐRya @Ŕłö¸O?]PŻ^]“ÉaGOç¶m_Z°ŕ“š5Ă cTT¤łłsçÎ]’’’?~Üłgo–eŘř𡸸qŹ?1™L«WŻô÷÷gYN«ŐZÓ^ëtşĂ‡˝öÚ°śś“É´~ý7*•ęçź· 0 77Ďd2}˙ýFŤF#“ÉvěřĄM›¶+W.0 żü˛ýĹîJÉĎĎďßŔ‹ú‚|÷1 “gŤQQ…ˇÓéJ†żú‡Ç!D&“]¸pAĄRuíÚ%((ăĐó•W~Ýż?11155U­VwéÜ9((ăĐ«gĎý$$Üőöö.ÝÓ3/r9ÁŹ?""uë‚a`2!/ Á? vmÄÄ€¦QNö6­NN ëףysÔ¬ “ 4ŤÜ\¨T _Ť¶m˛ßAŔ9€hŕ3Ŕ.T}„¸8tí ±f3”J¬Yw÷2źĎΆ›ÁÂ…7j5rsÁqČΆ»;Á§źâ­·ŕć­¶<˘•ť ‚O>Á»ďÂËËÂ~­rćĎÇ”)đňBůzćôôÂu1nŔ{dÍ›‡?„—Wađ’‰0o^۶A"MĂĎ6€¦ˇŐÂÓf3-´iđôDUŐ{—şš@§B‡ńóĎ?®®ČÎËB݇\ŽäděÚ…qăŕęZŢíŮ ŁR)îŢĹáĂ=ÎÎĐj-S@"ÁíŰřß˙đúëP©Ę“ĂO±W®ŕâE Ąąą0™Ŕ0‰Źk×0p  äć–GD9Îb¸śŚŢ˝!“!/ݰü÷ß‘‘W^TŠrR˝Bpô(ŚFtę±:X"ÁˇCŕ8tč‘:]y„VŁ!Ř»ÎÎhŐ čt–ňť;áé‰fÍ,ĺÂ&@€€gBăƱ­[·eY‡1ŠĎžýŃ A}}}y›FŁŃĐ˝{÷ĽĽ|ť._"7iŇ´]»véééFٱk×®2™Ě`0Ěś9CŁŃ𜍦é–-[µk×6++‹†Ňľ}Çń®k×.Çĺççwěřr۶{z÷îͲ,Ă0íŰżô‚çÝ"ä¶ů¤i:00p„·WşĂa2™7n¬×ëţÝAQ”D,ľw÷ž»›{tt´T*Űh˙éé÷˝=˝˘˘˘řňĆŤc÷ýú룴4±XL@8p%ç°…fTŻ^¨O#„XĘkÔ(Ś…PÎ\łĘ °čŮř‡­ĺAA=[eüc7Ŕ\îzŔQ!“®]ˢQ#h40€«WQ·n™qD"đ÷J5kZ ŘřúSTńň˛Ś­rxý[x8Ă—ОśăË—Sę˙]Ŕ˘*_Çáňe89!2NNČÍĹǸt :XäPTˇś*ď_ZtvXj«PXlwy*bŤJĄ%€ Ë–÷^üřŕädŃkńĎ[ËU*‹úČ*ż|9®®kUž_-çő]|y9rx¸ąYfS±ú¸»[¬.Ë—cý'OOË(˛Ö‡kUŽU˛>>>…Úikeřú:… &‹a ŕyŮCŞNUňóóuşúh–UÉFÉĚ|<ţÇ„XžaY63óń‚źB’ťťĹÇĘĚ|Ľ|ů˛ěělţŁV«}ÁGĎ ýŽ Ă.[¶ x.ljŃhČĎĎ˙ď@‰ĹŮ99îînMRr˛T"ńöö&„čőz­6ÇÝÝ]ŁŃ>>8ť._Äß —„ZŤü|Đ4š7ç×ĹˡV#/4Ť–- /RiyŃŢxĂ ];Đj!—C*…Fěl0 ^z rr P Â8ĚVź©ÍŔ #PËA-¸`bc1q˘E«öĂřě3téRć«yx - !!?ĄÔT‹ÂÍÓŹ! ˝z@r˛ĄĽ,xxŕáCx{ŁwoHL´TŔÓ©©pwGź>–rŹňę_ŁnÝ*Ĺą—j‘“ś\fDţ¸?>ââ0jD"čőX˝sç˘sg¸»#%5jXę™’Rx‰b8;#+  :wĂ #‰,Ş077‹ĺçăÇ嵳TjQ…y{ĂŰ ¬,¸ąA"BĽž7Đ4ť••ů|Ťů÷×)Š˘(ŠaJ$R©Tüů§‡»{hHX–ĄF$«TŞS§Nůůú‚°ţĄ!4iiHN¶h âăˇTB­FHRS‘šjŃ \¸•ŞĽłix8‘–__8w T*„‡ăî]ddX<^Îś‡G™! Üt fyö]‚í˛ë×1wnˇ äŔx÷]”ă [»6ÎťC˝zM©S H„ś9Úµ-‡ćS§ UmeÉ9}QQŕĂŤž:eq‹‰Áź""¢!±–—…V­đ믨[ ËÂd‚\Žčhś:…ŕ`‹ŠěÔ)ÄÄ”sŞĹíŰ4ȢR(0hfφH„¨(ś:eét“ ţéđ#”JřůáôiKôŽěl\»†¨(ČĺđőĹéÓčز˛pófˇK[I¸¸ŔÓgÎXn22€đpË8wÎŐ#=‰‰…®nĄŢb8;ăÂËmHj*RRµNNŹGÓ¦VüčQˇK[IxyA"Á•+hŘîßÇ“'ކ§'( ×®ˇ~}¸wŮŮŚ,SŽŻ/®\ÁÍ›–>˝s:|}!‘ŕÂÜşe!r·nÁ`(3Ž+kŹ»w-DńúupĽ˝a2áüy$&ZÜö®^!…®n­lFŁŃl6Ëĺrq‘yTVy9r MÓ …BTDůisąR©,Äżc¦’ĺĘ/wrr*¶§čt:–eź©śă8ĄRigůßEŘî%Ü:Ş>8ŽsrVÉĺrá~A€Ž"l„™Lʲl^^^—Nť(ŠĘÍË# ‰D&•ńĺÝşu‹Äyąą„©DJIŕö:vÄűďcŰ6Ľý6ňó±d ÜÜ„đÎ;Řľo˝­źŽjŐ Ă'”D÷î2=YYX¸‘‘¨V Ýşáťw„#đä >ýuë–wśÔú®€XČ€˘wô ¬Ôâkˇ=„˙ÜB`zőÂÜą¨W8w‹cŢĽçfz¸»#6óćˇNT«†Ă‡±m–.…ZŤző0>ęÔ—~ű żü‚Ď?/SŽźÂĂń駨]nnŘ»żý†eËŕíŤ,\čhh4Ř˝GŽ”''$>>XĽµjAĄÂöířë/,]Š5ŕîŽ%K''lۆóç±xq™r˘Ł!—cĹ ¬\ ™ ›7ăÖ-‹'EaŐ*,[©ßŹÄDÄĹ•)§aCě܉/żÄÂ… (¬_ŹŚ ‹¶vÓ&|ó ćĎ€Żż†V‹&MʔӲ%öíĂ·ßbÖ,Đ4Ö®M#:5j`űvlÜéÓa2aŐ*D…1l*”)S–/_ţÓO?őáµÄ4iŇÚµkwîÜŮŁGëÉŠ_ÍD"‘ŐśŢZ8fĚŤ7>|¸Ď· 0bÄ-[¶?~Ľ%o5P€!C†üňË/§Nťjňô+÷ďßßľ}§OźnŔ+ Đ»wďC‡ť?>ćé;‘îÝ»ź8q">>>ňiÎÜ©S§Ó§O_ąr%ôiNŢľ}űóçĎ߸q#Ŕ6ЦM›«WŻŢşuËďioŐ-ZÜşu+!!ÁŰŰ»hy“&MďÝ»çţ´/nÆ SSSďßż_,ľt˝ző222’’’ś*§ü´—°™M&áü+ŕą lŠ‚¸`×zR$¬ż››»N§ËÉŃzz¸ääÎÎÎnnnůůůZ­ÖÝÝť’””DQ”ł‹3HéyłQŻúöĹ޽طÔjôë¨ŐčŰű÷cçNĐhĐŻž>(<…ƍѧvěŔŹ?€›úô‹ bcŃ»7~ú ßo9R÷éS^ŹćŔaŕgŔ Č%0ŕĎ3c;Ŕ=`0 6!ĺQ[ †”¤ĄˇwoDŘľ~~řŕ|ó Ţ|Ó=B"Á»ď–§9ěЧNáÓO1w.( uę GDčĐ'Obţ||ô( ”— @çÎ8u łfÁlEˇiStëBĐĄ NťÂôé0›!ˇE tíZžűPd$¦Oljřé'LP*-š´nÝđűď<Ůĺ⥗йs™B( łfaăF “ 2śťńŃGĐŁNźĆřń`H$čÜ٢•z.ŕâ‚Ţ˝qýş%ˇł\Ž>}Ь™ĺŹ›71p X úöµ„Ä(nnčŰwď˘ËóýúˇaCHĄčŰ‹Ło_‹`˙ţóżRáă~ý°lző*|ľNĹčŰ«VˇgOpśś0`ęÖ-SNŤč×_|=ŔqP©đę«Eˇ|ý5şw·”P$ł$BCŃŻľű]»‚ăŕěŚ ŽC˙ţřţ{téb)íµň4~‘‘č×۶ˇS'p\\đúëđóCµjč×?˙Ś—_ÇÁŐŁFái6RîŢ˝ ŕńăÇĹĘdff˝·š5kÖńăÇOś8ńŕÁO>ůdÉ’%Íy5&pëÖ-%ÍsnܸÁq\I  k×®±,›["č˵k×JŤ†uőęUš¦óK„ş˝|ů˛ŮlÖó† O—ŤFC‰ŕ+ńńńˇdůĹ‹ÍfsÉŘ.\@ińŠ/_ľŚ‚đ]EqýúőRËůöaĘ iëXÂFʲî  *eYa¨  Ŕ1ŕ5l,ËÔŠŠÚłwďéżNwéŇ…c#GŽpWÝżşX,Ţąs×™łg_~ůe†¦:L‰DÇR\%ôî šĆąsHĐ©“Ĺ|‹?S2 .\€TŠÎťŃ´iyDB*Ĺ€ü1r9şułdĄR ŠÂĺËP(Đ˝;4(ĎäďeŔ üä.@ wAm7ŔäŮ•đjwwG~>ĆŽ…V‹Ü\‹ÚŞU+deářq¤§C©D˝zčŮłĚäi<9›7#1j5 °D­ŕŁ›6áÁh4xőU‹MiYĐh0f 6oFr2ÜÝ1p EÍčćf)OM…‡ ˛Ř”–‰ÇC$ÂŮłČÉż?^}Ľ˝ńĆřńG¤ĄÄ't IDATÁŰC†”çĂFQčŢŮŮ8{ÖâUŐ¬™ĹŚĐßcÇbË|8öě^Ź hQĂ6lˇC±w/ Ô©ĘSĎRš4Á“'Řż&ę×Gßľ»ŮćÍ‘•…`6ŁaCôî]ž=-Eˇukdgăđa0 7¶ÜhŰ998z cą(G=Ë_4äĺáÄ pZ´@çΖ`!/żŚü|üďĐş5:v,OŽXŚ®]a0ŕ÷ßAQh×íÚDčŢF#ţü"^z mŰV>hMßľ}•JeÝÄuŔ€nnnĹÔY®®®®®®#GŽ4ŤŹ?–Qn:4((¨fÍšĹäŚ1âŹ?ţ-ADGŹ}ćĚ™Ŕówěر/^¬Á›Á¸qă._ľě[bžN0áúőëŢ%nµ&MštűömŹ>““'Oľwďž[‰Ű˘)S¦$%%•L»:uęÔ‡–L«űŢ{ďedd”T—Mž<933łd@ŻI“&ĺććĘ*t$¶s.᯿ @ëî%› ¨Ę„ÍU­V(˙Ř(Őh4m۶;vě8€ť;ißľ˝R©lѢթS§ěÝ»»M›6 :"ŕ8 kµÚ€€ ~‹JK{¨+m™ňřńă°°pžžž))IĎEü˙$Éą3g¤RYĂŘĆéiŹ8ŽŁ†e–ahšf¬łŚH$ľźhŇë˝<<"ňĺů”ÍW3%îᇑÍBBĂĄ2™˘R>ütáBŠP}úô¦izÆoCCCß?^Ż×}ą®ůűcĎžB5E…ż[\]qů2JśŇžR)ŇÓ oÚ Š‚É±}A×h ě߆´ÚňbZü+ŠÂŐ«ö 9zăĆáúu{ĺlۆ%KĘËĚVI¬^Ťýű±k—˝r>ú`Ý:{ĺŚ,X`—7ŢŔ_řňË/GŹ]bť( ÚQáߥFřŕ źIŞ^’=8Ęś9s¦M›VŇ]đ«5«FŽŤËHOă7,~ϲ‚-řE‰ÎťůkÚYUęo GđâŁŔ&’aŮęŐ«Ź1"7/oř×Çľçîá1pŕ@Ť›ĆĎß˙ő×Gdfe1⍸qŐŞUđę«îî,Ç=yV¶SÖóŽňk·'ĐŞ6О ˙.•rđ…Ď$e‘úŻ•;ĄÜ0ÝOL }±3ç  @€GŠ˘ř$„‘ÍšĄ}űmB ŃhÜÝÝů$µjŐš3{¶V›[PîQp«*pđŹ6Žă–Ż\5í©ŢŢŢ•äl.Ń„9ŽŁiÚh4ň;śX,–Éd"Ų–rAw'@€ŞďÄP*ˇˇ!b±ßÎĚf3żť)•ĘĐĐĐbĺE9đjUŧS3%‚}µ¨°í?p "<|ČŕAN*[Q8>–ewěŘi4 T&őôôŚŠŚ‰DÇeddÜľs';+[&“úůůŐ¬YS l  Ş16ŠŽ˘p€Éd*LڧrÇ•Zî ď#˛sřđĚÓ§ĄQQ×ëŐúD€”GŘ!NNNű iŐŞ•¨ś6łŮľĆG‰dmřbQďÎÖ9Ââ–™ąńťwÖ˝ô7r¤ŞF ąÁ`('ŕžřŹ6~Zňůçqqq>>>µjŐŞpS«Őě7›ÍYYYŰ~úiŐę5«V®Đ żîß?ôµ×˘"#µZíşőÖ¬]űńÜą%Ó  řŽăÄbńżČ‘J0K$R%Bp`0&ŔÁ„Ť”•»\üĐ^9gĎ"1ŃŢ÷’Épěrs çČHĄ0lr9Žă˙ĽxńbpppÉ„˘ţuŘfo_YÂĆ/„NNNAěŻĐëŚeŮÇ›i:77÷رcíÚ¶ĺ+§×ëůÓUnnîożlŢĽąŕ|"@@ĺNśłł @ ”Jĺ?ćůIQT|||NNNbâ}ľ&‰$!!A©T˛,[ż~ýQO~ňäI>Lßv`B¬7©,ËňćÖBk‰€J6/oo±„ŽżxŽ"”mŃChšŽ¬ĺéć†8;ۢRP©÷ßG§NhÓj5ęÔAt4fĚŔďż[ŻĎźů¬ś—‡3gpýş]ÄF$‚Á€ß‡Ba/A˘i?nŻ~p¶WoĂÓŕß~łW?Ć·ÉŻżÚ;…–-íbׄŔ`ŔůóhŮöäd"ůůŹÇž=öÖG§CF¦LqŔ\uqÁîÝvŐ‡˘đř1ňóí}/ŠBZĚfČIIEAŻ·ťđ‹DHNć˙LOOżuë–Q0[U÷šż‹°ńËбcÇvďŢ˝xŃB‰DRÎ ‰b6›ÇŤ‹˙čăíµî›oŠ,™ÍćËW®ě˙í·•+– ąÝx&lÝş588řźüĹ^˝zíرcÇŽáá5ťśśř)ĽeËVŁŃXż~ý˙ýď˙"atk ĂdeeYٵBˇŕ8ŽaĚĚLBH$’ËĺB`§g9rł*'ßęľ6Źjš¦•*yEČ´iě† 6p %Ăţü“,Y‚±cqâ–.ĹöíŘ·ß}gű‹EGcÍ´lioůűc÷nDEŮ+G­Ć‰đń±WŽL† `HFQ¸vÍ!K®^µWÁ«ŞÄv¤§#, GŹÚ+çĆ Ľô.]˛WÎŮłhÔČ1µm[ěŘaŻ/żÄľ}3w.<ŔW_Ů+ç­·ŕâ‚yóěňć›X˝ŔK/˝ôúëŻ KzŐÄś9sţÂĆ._ľüÎ;ďĽ7ůť cńs'•J÷îŢe2™î'%­\ąňAR’»»;˙-Š˘®^»¶čłĹ“ßyŰ·Z5á$!@Ŕł˙á_ěŃŁÇîÝ»żřâË5jôďßĎÉIąmŰĎ«WŻa¦WŻ^˙âV‰D˙ŇKÄb±ŮlnڴɱcÇőúüřřKM›6“JĄ-[¶8tčpfćcŮV"ŠJN~ŕٸU˝Ř–¶M4ŠĄĄĄ>xpoěËOtď)üĎn’DX69 `fv6«.K\$€młŽZ:"Çő1›@ذ¬L"«N ó-ă*Ń´Ăä8 QP0Ścä°l’S A°_ű/@\ęÁč>čÔ±căĆŤ%I…ă€h2™Ü=< ´~ý†úË—ńÇ‹óçĎŻ]ł¶WŻž 4p §˙üóS¦GŹ[¶l9pŕŔŠ+÷ď? ‘oßľóäÉ“ZµjőíŰ÷_TŻ «!$??źeŮU«VęőúŚŚŚ·ßž4zô¨Ď>űěË/ż`&==}âĉź}öi^^ľ0w*Ó˘4m‰Ĺb±D,¶ŃZO.W‚ÔÄÄ' ÜÝáîn›śą3fl;–ţć´h!ëß˙tll•8ăV59çČúŘąš9*ô‘ŁäĽ=î@ně(‚Íű.V9„ Í˙"aă8Î`0€ăúöíăââRÉ{G˝^o6›eRi‹Íżüę«ÄÄÄęŐ«_żqcďľ_CĂB čęâBÓ´ŕ)@@‡»»ű„ d2ŮŃŁGŹ9@"‘´nÝzřđáaaaBűü‹ŕ·ä5j 6Ŕ±cG üĘ+Ż @€(5qv``ŕ„·Ć{{{W’­YcYV©P4lĐŕđ‘#C_{móćOś8ń٢…÷i†ˇ(*8(HhqŞ8şté´víÚřřx†aBCCÇŽۤIˇeŞxaŁQo4•JĄZíŰaĚFŁŃdâc{ W­ĎB–,dµÁŽ”ăX‡´v!1S(P@¶&@€Ę#lłfL ¬ĽMŃ ˙„–-Zlřî»!˙Ľ}»T*óFŽăT*Őáż ÎT}DFF.]ş´čĽڤʀX†aX–eY¶nÝş[¶ü¨Ője2˲˙J⾡M9Î&›"ÂqVŇ'@€ü](ņ;&&¦ňç3©TúĂ÷­ěŽ˘¨FŤΞ5K$mýqóćľßří†ďľÝ°ń»ożX»F8ö đĽ€ĐU‰$1ń~``PíÚuçÍ›ŕŔŻąąąb±XˇP\ştiĆŚ™űöíŃjµBC=+_cmBy¶[·đĆ Ct4,@AlOܸ1c,ĺ‹!'§‚Ş]ą‚#ŠÚµ±lňň,ĺ—.ačP„†˘N¬XüŠŚ`ĎźÇŔ A˝zřâ‹ÂRgĎbŔ„„ ~}|ő*4 ýăôéŕ`4l  Kś:…^˝ŚFŤ°qcĹ~YÇŹŁ[7ŁIüřcaůŃŁčŇÁÁhÚ[·VÜuâĺ—ŚćÍńË/…ĺ CŁeKěÜY±ś˝{Ń®‚‚Ц öî-,ß˝mÚ (mŰV*‚˙/ż eKŁC8}ş9&ľřőë#$ŕÜ9KąÁ€5kPŻBB0p .\ř‡ćkN.DL BC1f nŢ´”geá“OŤ°0ÄĹáöí ä<~Ś9sP«jÖÄ„ ¸wĎRžžŽYł…š51i+“šŠiÓ‰đpL™b µŹ”Ľ˙>"">@…‰UďßÇ;ď <‘‘9ii–ň{÷0q"jÖDTfĎFF†°d˙7QJĐ…Bńö®;.Š«k?3ŰéKWŢQ»{o¨Xbc‹MÔŘ1ŻľQŁ1öň©i–M4Qš]ěb»(H/JgY`ëĚ|Ě FŘ Éj˘Żóüü%»ÇńěĚť{gÎsOŁśKDófÍŞ^x[™™IĄRĄRü‡W"Ăp9l8pŕđ·AÓ´™™Y÷îÝwîܵ~ý:ooźŇ҉D’ťť˝rĺŞ3fxyůpU"˙2]c@Ó4A Ă$€V«Q*•ěH2 ĂçóĹb»ĹIÓ”JĄzÎŮę#lĺĺř攕aÔ(h48sŽŽ@U¶o‡\®“ź<‰FŤ0|¸Ţ~kĄĄŘş ĆŚJ…řx4nŚđpČdزĆŚR‰8;cŔ˝ŤÎ ±iÄbDF˘şűöˇIôéâblÜSSDF˘Ş {÷ÂŐݺϯ_ĎӧذÖÖ;••Ř˝nnčÜOźbýzŘŮéä;vŔÍ !!z›ää`Ý:4i‚6mPQŻż†»;ÚµCVÖ­›ÚµL†mŰŕá–-őVIOÇşuđöFHĘ˱y3<<„'O°~=üüО2lÜOOęmĽöř16l@łfčÜĄĄXżžžđóCr26nDPşvEI Ö­§'||ôNŁ{÷°y3Z·FŹ(.ĆÚµđô„‡nßĆ–-hÓVV(*ÂÚµđđ€ľ šĆ͛ؾ!!°°@Aîxgg\˝ŠoľÁ{ďÁÂĎžaíZ¸»ĂŮą~=…ÄDě܉Nť`f†ü|¬[‡-[ŕč đĂčҦ¦ČËĂşuŘĽYoÓ­gÎŕ—_ĐŁLLťŤ °allpęöďGŻ^H•…Ť±nlm_ďrU©‡“'u>5Ű·cŮ2H$ŤĹ™3 źŹ”|ý5–,Ąeýz üţ;._Ć AŕńśŚďżÇ˘E°?®_Ç!şö»vaŢ<™Őݧş{÷âŢ= ŞŰaůńGĚž †ÁĎ?#9ÆévX~ţ “úő° *##F€¦‘”„}ű0u*4ě܉Ü\Ľ˙>( WŻÂÖ'B,ćÝaőkUýqoŹ˘(VCU—řÎŻ E999­Zőeii™T*Őj5 ĽĽ|×®ÝÖÖÖ&LäŘÚß"l:…Â+W®>zôH(·ôđpgGř|ľL&»víq^^I’îîî^^^b±¦éúă(Ż\Áýű5 ăĆA«ĹěŮ8}Ý»#9âŤ3gâÔ)tčOĎúĎěÜ9<~ŚiÓ0lT*|ôNś@—.HLÄ“'5 AˇŔ”)8~mŰÂÉ©~=§N!3‹ˇwoTUaâD=ŠĐP$$ ;K– GTVbÜ8>Ś–-őÚÜGŹâéSĚĐPČdŚÄˇChßGŹ˘ sç˘C”•!"ńń ‚…EýzâăQR‚Ď?GË–(.ĆčŃ‹C«V8teeX±AA(,ÄčŃŤEÓ¦zmÓŘXTVbútřűăéSŚ…ŘX4oŽŘXTUá“OŕăĽ<ŚŤřűë%ŃŃP©0kÜÝ‘•…1c…  ŤłgĂŐ@LŚŢNĐ4Ť0 ćÎ…“RR0nbc1kbb@’?Ť!9'".3gÖŻGŁAl,D",X{{ÜąŹ>B|<&OF\$DEÁÖIIřřc:„©Ső‰řxXXŕłĎ •âňeĚť‹cÇ0j‚•ţóXZââE,X€cÇ0n\ýzĘËqř0ěě°d ĚĚ€ĄKqęúőĂŃŁptÄ’%05űcXą 9ňő.×Ü\ś:,[?˙ŚÝ»qő*üüpú4üü°lř|ěŢŤ˝{qĺ z÷ÖËöĎťCłfřâ $¶oG\n߆ť.\@p0ľř-[pě’’Đ©Sýz>ÄĺËhŰ‹ŔęŐHLDr2HW® CDEŔĘ•¸|]ş@_Ř[·păşwǬY`,Y‚‹Ń«ĘĘ”„ľ}ńńÇ i|ö.\@§NhÖŚ{tżk ą!ŕŔ‡·JĄŇÎÎaîÜŮ&L”Éd4Mź>}úäÉ“»wď.//ýű.Ľµ †a}e"‘(>>nöěŮ‘‘cŹ="‹X"GÓôÍ›I7nŠŠZ´hŃg_ýujjęs÷Z}ŚíěY´l‰€ĎÇGA.Gv6ÎźG»vč×LźŽ’’Ú@¬ş8qÝşˇgO‰0s&rsQX“'Ń«şu‰ź~ŠôtCW‡cđ`„†€©)ćĚÁÉpä† [ ŇĚ óćáΔ–ęŐ‡]7dKK,X€«WˇP .ăơU+J±p! EiĆÄ`ęT€­-˘˘pú4´ZDGcútť%joʍ($$ŠŇŚŽĆĚ™đ÷€FŤ…#GŔ0‰ÁěŮ:W“.ġC†ĘxĆĆbţ|ťËËŐ č˘(ăâ°`\]ŔÝóćj»Ě08|QQ:ÚěăŮłqđ GŹ"* Ť€ż?fÎÄÁző¨ŐHH@Těí Y3L›†už.–­ ”)†ôTUáŇ%,\©ZµÂ¸q‰R‰«W±pˇÎőÔ¦ŤŽęCYîÜÁüů:Ó{ďaŘ0:„Š Đ}=¸u ÷îÁĆ:yD¬­kŁIëâęU¸¸ŕý÷€ 0~<„Bź—žž¶sçN—&‡Ĺíß˙«\^ń믿¤gfN¬­am­űęí • r9rr`g§3 Y›^ˇ0”Ć–™‰FŤjýTţţ¨¨@u523áě\Ł™ĚAJK«km,VÓ¦(.†J…ôt¸»×úŻš5CQ ˝zRSáí ˇP÷5(OźB«Ĺ“'đő­ Č B~ľ!˘•’˙Ú@Ç-“šFj*j‘•e(.%ÍšŐ6ł FF¦yzşˇžW©©hŢĽök‹xňž<ѱĘ=¬\aKK«=ža¤KŁJOG‹őČëE!#ŁVA iSEYhnn:ą,, í†Ç« LmÜ&&(,DQ‚Zął3D"ęŐóô)LLjS]]Á㡴OźÂÜ:9{ÂĹĹÜ“›#l8pxŤ`ĆÂÂB*µ–‚5AśŐ­×Ŕ&?@©´Ć&ţßşp­–’Éd!ÄbqVVMÓ÷ď?čĐá˝–-ŰOšôˇĄľś úW% Š˘Äb±ąąĄX,®ňxĽ+W®ZZZôďßßÍÍÍÇÇ'<<Ľ¸¸äŃŁ’$ë§Çr9$öíĂíŰŕóAQP«QY öîĹýű ŐBĄŇ{f05A`÷n¤¤@(„Z ­r9ĚĚ@رé鉠RAŁ1dăZX€ đő×ČÍ…D…™ –– lÝŞł«« $™ VV lÚ„’™ˇ˛4Ťňrť|Ă”•ÁÂrą!ŹVy9¬­AX»••JQQ†Ay9ll@X˝ ¬­urzŘăW­‚F{{ű-/‡­-_~ ­öö(/74ĘËag+W‚ajŹQŔŢľ¶xL˝„M&˝=( _~ ‚€ťĘËur;;h4XµJ'7¬G.‡µ5 ¬^ ‚€­-ĘĘtr++TUaÍll ]Mٞćć(/dž X[ŁĽ4ŤŞ*™ˇ¤7ÖĘőA«Eu5$<{†­[A°˛ŇéQ( #/Ű· `iůçEtŚ»ř|Ţ|Đ4óöú$ÉÖ­[óóź(ż®T*Ł˘ňxÜfŠľ @EEEŽýăóůsćĚţ«é¸o8(Šrqi2wîĄRˇŃhśśśćĎźçŕŕ0uę­VËŇ9//φwdáPCŘآ#4 Ei´Z-+¤iš$É””Çöööě˛mßľ}|üˇĽĽ<¶NI=IRG37®­y@ ťÜÉ ććµr}¨ŃÓ¤‰ÎźĆ\ŁÇĹEo —ô°ôÉŐ‰NBµúkül† kô¸»ëülě2¬ŃăáńůźęńôÔ°Őčaĺ^^:Ă´çăĺ‚E˝¬ÇŰ$Y+˙S=ŢŢző (h›ÁŽ'{Ś——îřőäËrŞđx:Ń‹zđů:9«Óđuŕáń‡ăYýBˇNnř|Řë éüN4ý‡»#×Ę˙lv07×ůŻX~U#·´ÔEĄ˛rĂ @*ŐmR0ŚN űWR©î2¨ÇĆF·iRs>,XÎßp=ööµ‹ş6aVH IDATćd8:Ö:ŰąDĺwś°™šrW9ĽÖřţ[KŘL6nÜśa k0aÂx¶T‡úx ˝jŐWzŘ‚ó˙÷›««kTÔÂňňr‚ ÜÝÝćĚ™]YYą}űöçŹnB«ŐTTTpuGţ6anďR÷ý\ZZćââjaa‘™™%‰ěí톩¬¬dIJ=ÍşA´Ztě<ß;‰`e…ĘJP:w€ĘJ…:U/XEˇ{w¨¨€X ˇPçˇ(]z›L˝Ą&YS’ ôęŰĘĘ`j >66()MëŇęJKan®·Ô$[[¦EE°°Ź[[‚a0hÂĘĘ·±łCA<=1däçC*Őąžž=‹ ÂĂ /Oç@3 çéS88č2|˛˛`cS+·±©•.]hg‡ü|řř`řpČÍŐٶ¶ČË—×ËrăśźWWÝńyy°łÓąÂňňФ‰î|ňňtůiú wkk<}ŠFŤ0t(OźÂީϞÁŃáá:ąóáń`i‰âbŘÚbĐ Đ4 `g’„Ą%JJ`c°0Đ4 éáóaf†ňrHĄčß4ŤâbŘ؀Ǚd2ŘŘ o_PJJ^{‰H– …¨®†‹ \\tg©"ř|(ps›4ťóVLL@’P*áí ooh4¨®†ĄĄn=ŞTđóµJ% „-™¦ˇVë˘LY_·™D"hµP«uQ¬*(Şv›¦.,, VCŁAëÖěĆ-&&°°Đéd«•°ËlŢ`žlőľ Ţ49‡żLŘš°™µ8Ľń¨®®R*oçĘgĚ <˛ź$yÜî‰qďô˙Í’ÇZ­V&“±3_«Ő˛-×ĘĘJ˙hďqoÄżĽô˘ŁŚ©ŤFC’„D">wî\ăĆŤű÷ďÇ0ŚV«e=eý==QXĽ<]˝Š»wab©ČĎG~>š4€Ű·afV›ęV>>ČĘBaˇ®^ER¤R™ÁÇ(.Öe¶Ü¸[[˝% %ĄĄ:{úÚ54j±ţţHNF—.şs¸zNN†\v¸w:čě×Ë—áć>M›âδk§łG/]‚»»!٬’’¬ű­K—ŕí M›âĆ 4o®3šá㣷ǫçÚ5čÜz‰‰đ÷A Y3\ąR›V—ř‡Ô¸şhÚ—.ÁÓ<—.éR¶Xą‡‡ÎEV#×G´‘¨»é ®\ŃńţţHLÔ•OT«qőŞˇ|>|}‘¨cwJ%®_Głf Ix{ăŇ%›U(pó¦!="<D@Äb4j„k×t»eexôŻ}ąJĄ07ÇíŰ ѱýĽúöŲeş˛˘W®`Ű6CzĚĚĐ­–/GN\Ľ;đţűHĐ©–/×őw>?ţhčşllЦ ľřĎžĐő^:VVĆĘ•şţÎ'O":Z׋ěµÂË X·Nçd>xWŻ˘W/¸ąÁÚ6 ˘Z-~˙·né­éĎî>Dز••Đh°w/?F§NđóIbëVTUA­ĆĎ?#3]şčŐÓş5Ş«ńí·P( Ra×.ˇM´l‰ňrěŘĄJ%ľ˙2ÚµÓ«'4yyřńG¨Ő¨®Ć×_C«EÓ¦ AF~ú  ŞŞ°u+xĽÚ6†ůó盚šĆÔ©úé§źš™™9rä%ůôéÓÍÍÍ^’O™2ĹÜÜüÜ‹=ÜăÇŹ·°°¸téŇKňKKËëěZţĂ#ä}++«ŰěÚüĂ#*\*•>¨Sý2,,ĚĆĆ&%%ĺ%yßľ}mmmÓŘ5ňzöěigg—]§ŘL—.]ňëŹ utt,ŞÓ‹Ľ}űöŤ7.­S2·M›6ÎÎÎěVé‹hٲĄ‹‹ËënfĆţ)TUU­^˝Ş´´Ě@ –FŁvvvú ç{…ŕńx;v|G6›ʧ1P‡?N†ˇk¶/†~îfنˇ(­Tj]UUU^^fmmCČÍÍ%IÂĚĚŚ¦©ú=l-[bčP=ŠŁGŔÜÇëĘĐ…‡ăřqÄĹ€…† Ó۰@»v211Ř·,-1t(,-Ѷ-Ćďżcϰ˛ÂС†loĂđÁx{{{ÖtSxމ'^»vÍ­¦;Âs|řá‡IIIMŘuú>ú裻wď6nÜř%ůôéÓ“““ę„€Î1#55Ő¶N8Ŕ¬Ył222¬ëě^Í™3'''§n ĺyóć=}ú´n˘Ęś9s ë†8Κ5«´´TRg7jĆŚš–'ŻÄéç.ѮϷŽÔjőëţUŚAuuĄR©üÇru¤Ri×®ÝΞ= 66şGŹ&&&ˇˇť>ߥK•ÚÜVVVţţʧ$''ű6}ŢPĹçóů|~II‘‘űXATTT¸şş°´´,(xZwŹ ââboo_vvvyy9•*;sř7 n^ż.ŠZ·mWXđŚa-EŃES”V«Ąj>ÓŹÇĎĘĚT+ö¶vńmRŢ/ŠŢŃňŃ˝¬śJK‹I’$I˛  PŁQ/_ľÂŮŮiěŘHss ;;ŰÜÜĽuëÖK$’°°Ťć‡~ôőőť0aśT*­®®~ö,/jňGç¦ĎŔÔ©Ć^Rh(>ůDŹg ±ył!÷KáěŚC‡Ą––¸w..Ćę uMŚ7úŐjCVxC ŐB €ń%‹Ů˘˙ÚÖ599 DźĆ_ĆÝ»čÓÇPç±âŇĄWćp0ŕ´ä޶ ÇŽéśŰĆŕóĎ‘ťŤť;ŤŐ3m,,°j•QJ¦NĹ7ßřöŰo?üđĂş[Q5fŇżőYßůĽ ň,[¶lѢEü:śď¶oť8壢Âö…Ĺľłj@?˙Iňn^ż¶čFu=4˝nÔ)8pŕđ?‰št5“ďżßŇńÜąó{öüŇńđáĂ|>ßÉ©ń1ŁKJJ>üpꌳěěě† leeĹV˙ço ^d˙Ög}çó.Č_9^&|4MO›6íŔ^2ˇ_Ĺ ’+eĆá·-D<’G€¨PUP őď.·Îť;§§§łź EZZיûaÔ°K„ˇiZ.—ŹŃ·o@0lł»ęęj†a||ĽçĎź[Q!'B*µ˛±±yÎÖ8ÂĆţq 99ůóĎ?_ż~˝˝ápíż…B±|ůň•+WrCĎá]†‰Ŕä‹Ë+rĺąJ­ň«Î«¬ÄVjJýš~‹ yóć}öŮgVúC‰Îź?żpáB6’[­V‹ Tfk0"##úé§lHĄb) ĘU\ö‡ż†Ű [ŁŃ8;;{xx°~3¶µZ­ˇPčîîΖ´Öjµjµš˘(‚ 88přw›‰‰IIIÉîÝ»§OźnÚ°ö|Év\łf GŘ8Ľăó%»ďíÎzš žVž3[Íŕ“|Ă~¶ze/ ëĂJÖ®]»`ÁĘE"Ń_|Á㽲nÝż˙ţ{ffćO?ýůڧ'úéÁĎ$Aň˛ŻG_šáJ¶ph8ac B€JĄT©ęö„`(ŠV(´uţ!ÁyŘ8pŕŔĂżCŘ‚XµjŐ¨QŁűôéc؆c¦¸¸ŘÜÜĽ˛˛’¦iˇPhaaQS˛Ľ˛˛RˇP!‘HLMM†ÉÎΖJĄ*•ĘÎÎŽ»Ţ.A’$@ÖĐ"VB6¸jÓóňŹ´™Đ$±ěÄň`‡]]ş ýöA%%%lµzš¦I’$˘¨¨ŤÎjÔ¨űŐÎή¨¨HŁŃ°’ęęjSSÓśś­VkooĎžjaa!EQ ðu™Ř:Z­VŁŃÔ­ÔôWQVVöÁTUU™››wíÚŐŮ@‡¨WtSŇĘÓĆř$ŔGŐąŠR¸#AĽHkI’¨{0A;přźŁlÇYĆĄ°qŕŔ‡ő[$Í›7_·nÝÜąsďÝ»gřß«ŐęŕŕŕvďŢ˝uëÖ“&MŞéL§T*W¬XѱcÇ=zlßľ€\.oٲĄFŁńđđa»ÔsŕđVA °á‚5ÖĽ@ l8D"Ńsn@¨)5Ř>S ů}hzy†€'0üë={ötrrjҤ‰““SŰ® urrrrrb›?«TŞ''§˛˛2ţţţUUUm۶mÔ¨QMČŕŕ`VŰů„a©TÚĽys'''ă»N»»»gff((( |Ý-Ńm~l €H bIŻH$2|+^¸§˘zď”HÄË}'¶`Řż.‡Ť8ü3ŕë{‡uíÚµgĎž&L¸ví_ő[†a Ďś9óß˙ţW >|xÓ¦MkÖ¬Ńjµű÷ďřđáŞU« Ĺž={|}}řĂ?Lť:őŔ\›)o#ćĎ_¸jŐjŹĽ{÷.+™3g®TjEÓ ˛ŰäňŠ}?îóńóŤ#Ăőů­oZi:A ÍŚ{˙äănR0 ú‹EgeemÝşŐÝÝ] Ś7n˙ţý“'O^˛d‰ŤŤŤ@ ŤŤU«Ő>>>_}ő•CĎž=Oś8ńŰożuîÜůŰoż•JĄ5ilńńńŤF$ 4čřńă*•ĘÓÓó˙ţď˙,--űőë[·3I BBBŞŞŞÔjurr2€=z$$$´oßľ˘˘âáÇd2ë?711©0ľĚ´AŞf&4 ÝŰIĄR±3•JE€P«Őýú čoÂCQşđ¶ŞŞŞ®]»R]絚k˝ýżÍŐ ¤¸"řlŰßĐA’<€ˇ)¦fŻdCfŻBŹg¨C×_ˇłŻ †ţ¨0¶¦?«á•ÔN{U坤ŇWs>VV oóőO\€WŇhĘÔÔP[¶†C"y5íćÄbCÍĺçŮć\/®w—°P(yyyţţţZ_N"‘těŘqČ!AD˘9sć°„-..®wďŢV©Tiii8p`xxř´iÓ:uę®V$‡·ÎŔ#—|ÎAÔ0·âËł_şąh5ZS…V  B@<É{ňĹĺNfNUšŞ…]đę{e’$Ɔ,öíŰW©TFGGoÚ´ÉŃŃ@ďŢ˝+++A›6mŢ˙}‚ şuëFD۶mÁ!CĚĚĚjÖÝĹ‹ĺrąX,>uę”\.˙ňË/ÓŇ҆  gĎžjMz÷îͰtéŇ˙ţ÷ż§Nťš5kVëÖ­†a%$IŞTŞç®Hâ•ßK‘%†(šZtţł«éW!>É_Ńý ˇ)­¦Ż\ąň§z†Ńjµl‡=ÇĽQ“Çă™™™˝ˇxA¨Őęęęę7ó9ĎĐ´Tj­PT—¦§q†„ąą™™věŔŁdŁşiI$HMĹ7ß 1Ć8Ą%äçcíZxx@«5Ę ,/ÇçźĂÁĆl°ŠDP*1o¬¬ŚŇ#@«ĹŚ‹Ťę~F’`Ě™c,-a0 ,0ę˘*( ‹uÓ P*ńź˙Ŕ¦ $‰‚”—cńbjÁă!'ç•­Ő»w±d  Ł(ßµkČČ0VŹH„3gPQaěřĹ8sB!4šżż$ś;ÇćŃŢąsçâĹ‹ c.ŤĂëI’ŻĘAU?aS*•{÷î-))ůá‡ţ´źĎ;v,űącÇŽ………(ŠşwďŢ®]»D˘QŁF………Éd5¦ÇÖ8Ľ-LŤ ę«k%˙ »y÷ÍP°ĺEDşm~ aJ츾  Äř6ăH‚§om>qXYYŐ4t677çńx …bçÎť,ÓXłfMÍyĘd2–°±´óçź–Éd&&&4ÍÂ… _x%‰ ŻÍˇC‡Ň4-‰üüü>űě3‰DĂĆ@ńź˙üçőÚŮ s"ó$€†Ö¬9»&ĎźŚŮÓ­Çńôc*Ąş!zxŚZ­~S&"ATTT\¸p‘oĽŕő¦){{o­1´á5žmmm ''ëo—ۡ(ŞU«¶k»„Sn…ĆĽy<ŢĂŇR»›7mź<1RĎ]ąĽÉĺË–wďCěy<Ţ-ĄŇëÜ9S±ŘH=75š€S§„Ƶ™&IňĂ;ĆăńŚŃCÄ  ĺáĂFÚ ´Š‹3Š=EQw¦uL mńSk4µÚVŃŃE38ŐJeŞJ|đ ‘z*ŞŞ˛MLš·nM±üI’,)**ČĘ z4¦{÷3ČŚĐ#Î\Ľ5yňŮsçŚé˛"~‹ŽţnÝşs/ó1¶}óÍ™ŁGccbĘŤ›Ě˙]ľŔôO>1ł°Xµb…Ü•>eúôź¶mĐ˝{÷‰'r¶Ú›‰eË–˝.ÂFÓô§ź~şzőę   cöW,--‹‹‹mmm”””°Ö!¸şZŢ6Čd˛­[˙O©TÖ++Ëđđˇ×Żßđí·ßtčСN+‘ehl§¬’,u6FĂ€T şŢlKKˡPXQQqáÂ[[۲˛2ÖK€­ÔZďďVVV˛-:<==SSS)ŠbYŠźźźR©433suuÍÎÎfăŕŐjµEęááqőęU;;»š­Vű˘Ź‚ašúײŢI}ő’trDpçÎm}­írye‡!ě^Ň­[7 ĆĂăńŞ««ß˝Úó6€Ç{s+mňH277Ç®]Çŕ6ˇĎH’Ľ‚‚üĽĽě˛ŇR0Ś0†Řh0 MÓ”qz¨ç;§Ćë@QÔ+ą.ö|(#őůäË?–çb¦oßľŃŃŃ*•jÖ¬YúőëwđŕAµZ=~üř¤¤$>ź?|řđ#GŽČd2•JexaN›6mÝşu|>żĆ)ń"[cŤ×đđđ}űömذA,Ź3ćŐŢ’ Ç´ÍćřŃ µçö^<7¶y$2•LČĘ++´´Vß ­IÎf¨TŠ?u ˝iÄĂŢŢľ˙ţoř6ǶmŰŢđĄM¤1iŠ<O«Ő¸ŤG8pŕđO¶+V8884Ü–mѢEíűŹ$Ů@JŹ7`Ŕ€äää_~ůE,Ź9˛K—.„BáČ‘#ׯ_/8ÂĆáä~j9©X:ţč„ܲ\‚O0caańMﯭDVeŠVb«zM@Š˘ĘĘĘj›-¶uëÖąŮćÍ›ëţ(Ă0ß~ű틇}˙ý÷ěç-[¶°¶Da°?çééY\\,“ÉŘš™ţţţ5)@~~~ěç}űö9::>{ö앏!ŹäýŘ˙öł†Ö\Č˝]žÍ:ÜřnŰ9.ć. ™Jö?<‘ŢĚ2/âŤőţ˝Ľ:t›ţśśaô:{çŔú©^׸ul®ë;žÓÓp= ńČé;ţUé!_en}Çsz¨‡yţ§z^<ţĄĹű§zô˙šôp±8ÂV __߆˙{‘Htůň嚯‰¤ć«@ ŠŠb«ĎŐĽ Áرc###ąˇçđ.c!4  48×Ȭ‘Šú7[Ňă%2fŕkĂk µĘ–ššĘ~˝wďI’÷ď߯!l<¨ůśźź˙Z†Žů»q©ńgöłŠRěhZřń3}Ůk8č›T+¦`Ô›UČč˙Lż`{5ŕAQ˙ńŻJţ˘Ľ…zđWô0 –ęş'ĂÔ7ţTÉ›©‡i€ü­Öó’B¦ÁJţ=ŢYĽ‚Śđ—ęk˝ř• ’$_˛2k„ÜčsxgA€«ĺPřfĐ×ÍěšŐůÎť;çîînŘîü'žĎ×ď‹˙­»ü˙™5n&4K}ĎsĐTZ®®1‡żĚ×čż}61‘’ňŮ´iť}}{6oľ}őęŠňr> Ň=Šš2ĄłŻoŻćÍż]·N.“Č—)÷ďĎ›0ˇ“ŹOź-vnŢ\]YÉ$ŔŁ»wçŚ×ÉǧOpđ[·*Ş«yő>QS§¦§¤>PQV¶ý«Żz5oŢŮ×÷?Ó¦e>yb`|@YqńćĺË{4kÖĹĎďó™3s22D€(),ܸtiʦM»řů-›=;/+Kdpň>}şćłĎşvő÷˙rÁ‚gyy"@äĺ}Ő-  [@ŔęE‹ ňóE's^VÖsćtő÷ď¸ţóĎ‹ …€ČÍĚ\öé§]üüş7mşiٲҢ"®Iö» >78üó¨VW-ęőeˇŞLMkÂ<óIž†ţ“ 7†a˙„ĬYłŠ‹‹I’dF,Ż]»öĄ”¶˙1him¨sčç=ţűyÂR řw=Łĺí/n“qž hšfw…B!ŹÇ.§U*EQ Ăđů|‘HD$š¦T*ŐsÎĆÔ5L‹d˛˝ß~[VRŇŘ0ŤFséÔ);‡ÁcĆ”UWďůćąLÖřpŤZ}ţřq;GÇ~Ç‹„B¦>÷iiéŹŰ¶©TŞ#F¨UŞ„¸8G'§Ţ—VTü°u+EQ¬üxt´Ł“S·ţýA˝zňŠŠvmŢĚăóĂFŽT*‡~ýµq“&ť{÷Î-)Ůąi“H,9RQ]łwocW×®]ů|>Sźážőô鎍Í­¬ÂFŤRTUýľk—ł«kŰNť˛ž=ű~Ă+›°QŁŞ++÷íŘŃÄÍ-¸C‡z« ‘@FNÎwë×Ű7jТEeEĹžŻżvqwjŰ6=;ű»őë9;7mٲ˛˘âçmŰ\<<ëÝú!€'ß­_ďâîÔ¦Ť\&Ű˝ył«‡‡_óć)iiß­_ďćĺŐ˘]»Šňň]›6ązzzč[Ź?ޱa—ż«YYŮŽ \===|}“=Ú±qŁo``›ĐPYié÷ë×»xzş{{ë[tîßßµys@‹í:w.+)ůnÝ:WŹ&÷ďÜŮ˝eK`ppű.]ĘŠ‹ż[»ÖĹĂŁ‰›[˝»kMßOJúyűö 6mĚ,,J ż]»¶‰»{#gçŰ×®íýć›ŕvíLÍÍ‹ ľ[»¶‰»{c'§z·ú´•téŇţť;[‡„HLM‹ž=űnÝ:ç-[l®_ĽřűîÝm:v”ćçż~˝Ó¦Möt}¬Öj/ź=łwoű.]ÄÉłÜÜť7:­_oimťxęÔˇýű;tí*–HňłłwnÚÔhÍ[Űző(5šóÇŹʉyŻGˇH”—•őĂ–-ŤľúĘÔÜüě±c ńń{ö…ą?ţß˙Í]±ÂZ*ĄęÓS­R%ÄÇź?y˛sďŢ +-mĎöíł—-I$'ââOźîŇ·/ŹĎĎzňdď7ßĚXĽŘ‚®oV*•G¸qéR÷ţýI’LOIŮ·cÇôE‹ř|ţáß~»uőj÷’Lôč·]»&ĎťkffVŻYuuÜ/ż$ß˝Ű+, @jrňÁź~š8k€č={R<č5h<ľ?vĎžČéÓMMLęŐSZYyŕ‡˛ŇÓű BÓô˝7íŰ7fĘ­Fł×®Ľ¬¬ľááMßşrĹÚÎnřřńÝh8p„ŤŻ ’ţ0Ż1*,Aiĺ.¤ZÄü©5Ý@;;;űŮłgl_ŤŁGŹ.^Ľřß"lńńńýű÷˙ül Ťâł‹.”& ľ€' ęíž$ÉĹ,Ť ”ʆT´(++KHH (ЦéĆŤł Ărą<::šĎç;99uîÜůŻr¶w‡ăŐÄC*Š””Ôěěěęę*>źĎvý677'I˛˘˘âńă”§Oó ‚tssőôô‹Ĺ4M×ui €¤+W’ďŢ4jÔ¨ńă•ͲO?M<}:¤{÷'ÉÉŹďß:věű‘‘Őjőç3f$&$´ěĐÁĂĂŁînŤ¸vţü“GŹĆ~ôŃ áĂ+•ĘĎ>účüńăí:wľ™ţřń„Ył\ˇPDMž|îرćmÚ899QőéąxęTVzúôE‹zőéS^Y9o„3GŽ´~ď˝Ä„„ÜĚĚ™K–tďŮłT.ź3nܙÇ›ŰŘÚ2őé9wěŘÓÜÜ…_~Ú±cQyů§‘‘§jŃ®ÝŮŁG ňó'͞ݡC‡Â˛˛™cĆ$ÄÇű™››3ő٧*),śąxq«V­žÍ=úd\\Ó–-*+.žł|yË  ÜÂÂŁFťŚŤő Őg›ň€“±±ĺĺ|üqÓ€€¬üüŁFťŤőmÖědllĄ\>nĆŚ_ßĚÜÜOFŤ:ăéçW/$€11 …bâ§źúxx<ÉĚś9f̉© śŽV©T“ćĚńrsKIOźq2&fĘĽyő-†¦ŹÇÄP5eŢ<7g燏Ď7îd\Üř™3ŹÇÄ0 óŃ‚.ŤßřpŢĉ qqg̨÷9ĄŐhNÄĆňřüé‹9ŮŰ'ÝąóŮ”)§5i҉ŘXP8}ѢFvv7oŢ\üńǧú`Ę”z ’˘şúd|ĽÄÔô“Ĺ‹íĄŇË—/1{öącÇŽ™oja1cńb;+«‹.|ą`ÁącÇFđŞ>=ňňňÓ‡Kmlfý÷żRsóÓ'On\ş4ńÔ©.}űž9rÄĆÎîÓĄK­LMO;ö+V$ž:5ôý÷Uő’’ÂÂsÇŹ;:9Í^¶ĚB"‰ŹŽŢąqăµóç[včpţřńĆ..s–-3‹cűíÇmŰ®ť??pĐ Şľ›ţ,771!ÁŐÓsŢŠb`˙O?řá‡ŰWŻzřú^:uĘĂÇgîŠb>˙—]»b÷î˝uĺJĎ^˝”őéÉJK»rîśoÓ¦óV®äîmŰâăŢľmmgwíüů€  y+VđIňűÍ›Ď?~˙Ö­Ž;Şę›ĚO’“o$&6oÓfć’%°ý«Żn^ş”Ö§AI—/·o˙ń˘E¶¬XqóŇĄö]ş´nÓF]ßâzxűöíë×Cşvť<{6Ĺ0ë/ľ~áB§^˝ĘËĘîݸѹOź‰ź|˘ĄéŐ‹]=w®MhhÓfÍ8;ę]—ČĂżÂÜśš6ĂúăýAHĽHÔÔk7ÚôŹÇËĚĚÜ»wďŇĄKçÍ›żxń’m۶ݸq­{óf҆ ćÍ›ż`Á‚íŰż~ňäÉsšÇÔµ˝®ś=۬eË€©@9mZeEE~VÖŐsç‚۵ëÖż?sˇđŹ?.+)ÉNOŻ7`Oś?qâ˝®];öęĹ–bń„™3ósrŠ .ś<Ůąwď÷şuŁ+‰dâ§źfgdćç“zôś>t¨÷ŕÁm;v¤k3łÉsç¦|xzT”łłłđôőť4{öц9{ôčÇ‹95n¬Ľ&ĚśyôŔžž“Q«Ő‰'O~ĽhQ#{{5ŕ׬YäôéÇĐjµ—Ďś™ľh‘ŁťťđoŃbĚ”)GäëŃŁ¨Şş™8=*Ę^*ŐÍZµ6~üńčh•RyűęŐé ÚYYi ¶m‡DFŹŽÖ§§Ľ¬,ůÎť©óç[››S@«÷Ţë7lXB|ĽĽ˘"őáĂ)óćIMM) MÇŽ˝NŹčąYEOźć¤§Oš=ŰR"ˇ÷şwďÔ»÷ąăÇKŠŠžćäLś5Ë\,f€Đž=Cşv=§'ú”ädf–•–ŽűäS€şöëע]»ËgÎäçäTĘĺc§O7ĺó  űŔM[µştú´@ĎdN{ô˘¨ŃS¦HH’ô ÷ôóKş|935•äńFNš$&IĐřpʉ‰úô<Ľ}ŰĚÜ|ذá”Fʶup¸ź”ôčŢ=©ŤMxd¤C"",­­ďŢĽ)ĐłHo]˝ęäâ2päH> &&„Â'ÉÉw®]sőôě?|8“äű“& R<ŕś-aăŔĂ?´­±.Pß|H8™ž !|ĚŔ×—Śr{{űÇ7nÜř_ąüćü6ÁľÍţ|>ďIšĄŻże‹fŁ#h +4 /‘˘(OOĎĘĘJą\ľpáÂNť:Ý˝{wéŇĄlź•™3g†††6ü:4xđŕwfď„]I´P(8uęTIIń˛eKOźN‹‹iÓ¦őŽ;®_ż–››»sç—&ńń±űöýRQ!űĺ—_ H’¨÷ťšźťmeccec€Ü˝˝Ő*UĄ\ţ4'ÇĆÎÎR* Ü}}• …\&ÓGHr22ě76ł° -ŕĺď_YQˇ¬®ÎÉĚttv657' ŕXQ^^]UĄOOVZšł››ÄÄ„4€ołfe%%j•*;-­‰»»H"!-ŕ׼yIaˇJˇĐG´2žy 35ŐżE ŕ4+OM%ô?śłž< hŃ‚xĂ0-Zd¦¦ČJK hŃBű\_MQ9™™ţĎŹ'ÂŻYłĚÔT†aň˛˛jô$éÓ´ifjŞ>NŁV?ÍÉń Ň<€/xůűgĄĄiµÚgyyľÍ›k…žľľ™OžzYĄT={ćŰ´){ĽX"qőňĘNOW«T%……>Ďĺ“&úv şŞŞĽ´ÔËß_ €©ąyc—ĽĚLEuu…LćéçG`niéčěś›™©ď|ä2YuU•»Ź;-¬¤R;GÇüÜÜ*ą\©P¸yy±r©µµŤť]~NŽ>=奥ZŤ¦‰»;ŰoĐĆŢŢŇĘŞ0?_VZJÓ´ósą­™…EA^©g2’<^Ł&MŘăśśÄ&&%EEĄEE|ŔŃɉ( Q“&B‘¨¸ @źžÂü|‰‰‰}ŁF @N®®$ŹW^ZZôě™©ąą­+oâî ¬¸łÝ9ÂƇzŢÄćććR©µô9R Đíp™›››I ›ça9$Áön&fďŹ$Š‹!ý+!š7oîééɶrf ëÁ»»»ł˝ŕX»dذa;wî xŁa4hÝşőŻżţúŹQ5ĆÜÜĽO?(WĹEě@˝xż^‚••ÔĘĘŞfHE"‰ô߇µĄĄĂ:Z)-Bˇä_˝jöŃTÚÚöO9ó˙ě]wX××>wf¶˛ »ËR¤ *€ŠŠŘP±! ‚Ř5jbŤ1j˘Ńh“ź±DŁ1önbbAŁ;("**š"˝loSľ?F °XĐÔ}źd9Ü=ĚÜ{çÎyď)—a¸\.‘HTQQˇŃh?~ |>ßĘĘŞĽĽĽńq„Z‘C† aĎŠh°ÍżňgĎF ť:uJ‡ŽŽŽŽŽŽ11ŃAäçç_»–*[‡‡‡{zz¶nÝzčĐ!ĺĺĺŮŮŮl¦h}[PŁRń BG¸™™)çphŠ2Ťµš/J:¸˙í[·ě8’$Ť2cSŞ•Jˇ•• B?íÜy˙ţ};Ďd4’$©Q*­D"k„önŰ–›“cÇă “ÉdŽŘ¨ ‘µµˇť?ţXřř±\ ĐkµE© kBŰřˇ¨¨ČN(Ôiµć¨Ş«m¤R!B›×®-ݍ‹ĹZµšˇieuµŤT*@čÇ5kŞ««í¬­5j5mŢŁĄ¬Ş’ŘÚňÚ°rĄZ­–KĄjĄ’aeuµÔÖ–‡ĐúożŐętv¶¶¬Ľ=2ąśĐş˙ýĎh2Éíí•  Ş®–Éĺ8Bkżů†$Ią˝˝˛şş‘‰«¬®–ŮŮ!€µ_Í0ŚÜŢ^YUĹĘmíě`í×_€ÜŢ^QUŐČ4R)¶vv$E­ýć ![;;EU0ŚZˇ°µ·7™Lëľů†@ȶQ= è•J[™L«Ó­_±‚‹L.WTU=•K$jŤfĂĘ•<„d¶¶ŤčˇiZŁVËĹâęęę׬ $•ÉUU Më4ąHTQYąiíZ!B™LY]mŽ@R$©×jm…Ââââm6˛–HT MÓzťÎ–Ď/,,ܱqŁ!k›Fô&“Ń`óxyąą{·młFH$«”JŠ$MśË}đŕÁţ;¬˛‹UJĄą‡Âd4R&“ś ngeýşoź † „BŤRi2)’´%›7nţůg †ńµy=˝ža9ާĄ¦ţvä ø<žFŁ1 Ŕ0¶vőʕߏcĺćÜĹ@ŻŐbf‹a—ÎźOůäŁŃh2™V­ZĹ^ÉÂ… /^¬ÓéV®\ AAANö0VBáÇ‹‰+Wžý €ÉdZ´hQ)+đ˙OB×ëőK—~nÎŘýÓ@Ó´˝˝Ý”)Sô4ó”É3 oű2¨łá­I¨˛Ľń Ůç*ŽăZ­ÖÇÇgáÂ…¬„ĂáÔ?Ř!”››»iÓ&Š˘H’ `O[ą}űö–-[BCCýýýBYYYŮŮŮÝ»w˙ä“Oúöí;bÄ_ni4[´đÄ0Ěh4ŤF.—kee% 9îÝ»ŮöľľľěŚęÚµëńă' Ů †ˇě­ÄbęY‡#„Xą}łfB±u54Ň™,!¤śť…B!ő¬1űw)Ggg+o´š"z¦§™«+ŹĎŞ!¬¶śÇŁž7‹0ڎiŔÉÝťĂáĐěť>»NŔŮÝť  {1=.Í›ăÁęA¬žgr Ă^äzŘŞ/®Í›cŃĹ®9¬~ŔŐĂaXŤĽ±~¦i`Ű#DÓtŤú™hŠÂpĽ±'ĂhšĆpüiű˙Ża«‡ĂęiôzB Žă. U[+oŢĽ¶Ľ‘ű˘ÇŮÝť®­!€Ăá8»ąŃĎ˝öľ¸<žëG˘éšyHđřüf®®t­ű5«!€/8:;SlźB€  śťkë7§‡mo%Ů7kF±Ů¶Ćę§Db±ťŁ#+oäzB€°¶±!M&€Ŕ؇!VÎ6xŞżŃ…—HĄ&“‰†yŞ€ÚÚ+7§‡y¦‡É塬˝hP2{{±µ5Yk†X`!lX`AÂfµq㦴´´Wę]»v˝”¶pw×ć~~&ى ěÄHĄPV ńöî#»w§Ľ˝Á˝z™łÎ###u:ťŤŤMóćÍgÎśioočСǏ[YYa6qâDkkë#GŽ?~<444,,ěµ§±%$$h4’$˛hѢΝ;ÇĹĹiµÚČČČŕŕ`sţ™×E˙zdN|˙+j,SHoŕF„–/˙úąĚ“a˝^żdÉg‡ićäě<{öťAÇČm©–-ń áóÉNť¨V­IA4Čä1 «ŞŞĘČČ0Ť·oß–H$łgĎŁŃxóćÍúßşuëÖ×_ݦMťN—źźâââR^^ľzőęÔÔÔĐĐP¸~ýú’%K>ýôÓÇ+•Ęŕŕŕż*ČöM6„N§«!˝!>>žËĺz{{Ą¦¦:88Z[[ççđx\{{{†aT*uÍ|¬c{YK$Z­VA’˝zö¤J4ś x<žµD˘Q«Ň»7 PŞV\.O `ĚŘp62™Z©TQT˙~ýh€b•ŠËçs¸\™LĄP¨)*44”(V*ůB!ÇŚžŘÚ**+54NWU E"‚ $2YUE…–¦#""(€˘ĘJ+‘0›ÍČäňĘňr=MGEE‘Eĺĺbkk ÇĄryEY™a† J—–Š%sŰ% €ĚήĽ¤Ä­E‹ččh#Ŕ“˘"©!$“ËËŠ‹ťÝÜbbbŚŹ %2™9ŰťŐSVT$··k(ČĎ—ÚÚ"™\^ZT$±µŤŤŤŐäççKĺňFźT./yňÄÓË+vÄ=@ŃăÇ2;;Éĺ%Ožx´h;b„Ž•Ëĺfש­mÉ“'®îî±±±Z€âÂB™ť $±µ-),tquÎĘź‡Ë-Őj=ÝÝ[ş»+HRŁRŮHĄ\'2ť®Ą‡‡—‡GµÉ¤U«­ĄRszB!°2˝ľµ—ćĺUe2éµZ‘Ť _ @埏¨4 z˝ŘĆĆś+‘¦é ٱ}۶Pa0L&ˇHÄĺr)’¬0;´oĎĘIŠ5T†‡Ő#˛¶6Ť•&SP` ”ëő Ă„B+±Řh0T‘d×  (Óé@`ee!l˙AXB"-°ŕą ĹbQvŢ+pë÷Ţç÷é'făëŹß»WŁ ¬fĚ´îŰ_ňó˘as'<<Ľ]»vžžžŔĺrU*Uff¦••ŘŘذŠçĎźżzőjnnnllě›8˝:99933óÎť;}úôˇ(J(öë×/##ăáÇ˝{÷6ßđˇŐ Tާ˙*+Ĺ#˙ř ‡Ł>|UTb*Ő‹é«If-˛bt¬ŞŠvpĐlßú‡WQ!Љ}z×ZmLžĂáíÝ»·ö&B||ü¶m۶mŰÖŔ´¦éŔŔŔ¬¬¬śśśńăÇGEE@Ďž=:Tgmmť››{üřń˛˛˛ČČČŘŘŘßăÍ0OźĺÚ¸sçî®]{š5k Ńh1 …üłgĎÝĽyK 0 C’deý)÷-ĘKJJž<1ĐwoŢä Ö‰«§giQQiQ+żť™iee%‘É´q)/ŻÂ‚‚О2 pëúu©ÔJ$ňhŐęQnneyą€¸•–&µµ[[3fô´ôńÉ˝wOQUŶż‘šjçčČăó[řř<Ľ{WĄP°ňĚ«WśťBazh€VľľŮ·niÔj=~ů2ëRóňő˝›™©}&ż~ů˛kóćć$ ŕíçw+=Ý Ó逴ääć-[b8îĺď3-Í`0hh€´äd//sűM €·żćŐ«&ٱ¦}‹Ö­!o˙Ś”ŇdŇ>ÓßŇ|Mđöó»~ů2EÓZŠa®''{ůú€—ŻďőädŠa´M_ż|ŮËĎŹ1Ď´Z¶i“–śLhH’LżrĹŰĎZ¶n]#7Ť))Ţţţć Nž^^ד“-€Ń`¸qíš·ż?†aÍ[µŞ‘tş›×Ż{űů5B\==Ż_ąÂč´ÍťĚL/__‚ĂqqwOOIy*W«ďŢĽŮĘĎŹ2GlG—Ě«W€ŞşúÁť;-}|x|ľ}łf7RSi€˘şúavvË6mhs„D,–ŮŮÝş~ťŐSU^^“ăéĺ%´˛’Čd·ŇÓYyEYŮăĽ<Ďg)jő'ŹD*‰Dw23i#@YQQqaˇ›§§µD" ď޸ÁĘKž<)+.voŃÂś[;;‚Ăąű6 `xRPP]Yéěć&•Ë1 {pç`xśźŻŞ®vqw7§ÇŢɉ"ÉÜ{÷H  'G§Ő:89Ů5kf4ó< (€Ľű÷ŤŁ™3h'77ŤZý(7—m˙đî]†alííť\]• Ea^+pç†]Cg04“ɤÓéęÇ97.ŻĎlNn4_V®×ë_V^™5'7 ˇÜBŘ,°ŕď‚úŻüW kJÉůŽ;nٲ%//OŻ×KĄRvµ­˝ćÖYGp˝Ńk¬~ą\.¶Ůl4ł˛˛p˙“F˘¬:Zv¶ělÝí˙ŐŇ@FŁŤ;ëŔÎâ=˙śŃ|ŤĐeßC­ŰXv¶ č Šů˙ĆńÁ‰·ŹuűVă&06Ö ľ•˝ĽĽâââÎť;W3R©©©ź|ňIrr˛ą¨™0µĂ™čZ!I:ť. `ßľ}¬Î?m”˙Ľ‡ú™‡­ć\5ˇP’ruÉ’ĎZ´đ‰‰ĆqśĂÁ)ŠT(”†´Ż®®fŔqĽÁ4-#@p˙ţYééÇůĹHQUJĺ¶Ő«%2™«‡Gpż~))'2ŃtĄB±eŐ*ąCM™„şc Đ/""ůĚ™ÓÇŽQ S^Yůă˙ţçćáaçčŘ'"â||üŮ'(€ŇŠŠ _íéímÎ4 6,ţČ‘‹ 4@qié÷_}ĺ`-‘ 6ěř/ż$%&ŇEĹĹëľü˛]` 9g‹ "6öŕ®]).@aaáÚ/ľčÜł§@(űó¶m©IIđčŃŁď–-ëÚ§Ź9g 9räî ŇSR@~^ŢwK—ö #"räČëÖe¦¦by99ß-]Ú'"‚Ëă™#˘‘#GnZąňVz:sďŢwK—†ŠíÚ˝`)ä Ĺ⸸¸:ň9sćĹâß˙˝ŽüÝwßµ¶¶NHH¨#ź2eŠŤŤÍůóçëČ'Mš$‘HężbĆŤ'‘HRSSëČGŽ)•J322ęČŁŁŁe2YVVVydd¤­­mvvvyXX\.ĎÉÉ©#ďßżż˝˝}AAAyHHCQQQypppłfÍĘĘĘęČ»víęääTU/G400ĐĹĹE©TÖ‘wčĐÁÍÍMc&GńuÁi/AWćÍ›ëďďĎăq?űěóěě{ ĂĚź˙a›6>lěúsa‰<§Ď€ęęÍç?jKĐt9)ׯ_÷óółµµť7o^UUka×&l"‘(&&fßľ}l ŤFc.ő˙•)ë[o˝µpáB‚ "##Ůn©©nňgä­1 V\löWůů ظc;n® ­V÷Ţ{ł@(nܸÁh4i4ęŮłç€HdµaÆúI_o4ŽŰćçĂçK±çEaě¨ ęaš¦ą\ndddVVÖ˘E‹ľúę+„P^^Ţ’%KV­ZĹçóŮÄłšôłš9ĎâßXomŤ¶Ús^"‘°ÍĎ ů‡?Ů4"ŽcGŽůő×Cľľ>Çwp°'I“T*Őh´ŐŐŐ2™ !xü¸ĂH$˘iŞţV+ ŕסCčСâăĎÇÇì¬bcbdvvb‰„•'ţö0ŚĐĘ*,&ĆÎŃ‘6cõďŇe@TÔ©#GŽ˙ň 0Ś•X-¶±  ęyâ×_ăöď+‘hŕ°a3Ńh$@çŕ྇wí:°m1:t¨@( ěŃŁĎ Ażl۶oÓ&`çč:t¨H,6w=ÝBBBÂÂvoذ}íZŕŇĽů€¨(—Ű­Oź^îX»vËŞU yË–˘˘řfB=I€ŕR/]úqĹŠőË—#„Ľ|}űEFb8ŢsŔ€Ô 6,_ľvŮ2 !ź¶mű l.D“ »véŇwź}FR†PŰŔŔľ#„BÂĂŻ]ş´ň“O(ŠÂjÔ'"3ź>ÔwĐ k—.}ýŃGEáŘŁGHx8ô<8-)é«> hǰ ž=CÂĂó„­ßŕÁד“—ľ˙>{JD·ľ}{ ę™~ĺĘgď˝GÓ4ă=úőëjn]&8śQQ7®^]<}:Í0Ž÷ îßĂńQQ7Ż]űxęTšaXţÖŁ_?sž1ľ@0`ČŰó'OfO~ďѵwo—:tčÝ7>ś4‰aAô<Ř!ˇÄbńŔˇCÜľ=wÜ8€CýŁ˘:uďÎFGçdgĎ;–ŕp8† éÔ˝»9=[۰č肜ś÷FŤb†Ăĺ†Ö.0Ëă…EGoYąňÝ‘#a8\îŔaĂŘŁ#Ôc߬YXtôÎuëf  ĂĺrâŁŰ´k‡Dxtô® ¦ÇÄðjŰĚ?g7·đý›7O:”m>|8[Ľ4<:úŔ¶mS† y*ʉiĺëk23™›·jsdĎž·##ax|~Änžž}t˙ţÉłň¨ŃŁ›·jEšy¸ZůúŚŽ>yđŕÄ`ľ@=aB3ÚÉ)lذSqq b屓'›óřŐÇ˝{÷(ŠŞOH˛łł)ŠŞ_ŚęÎť;$IVVVÖ‘ßľ}Űd2Ő'0·nÝ2ŤŐőLš›7oŤĆúÄ&33SŻ×«ę…Ŕdddčtşú„'==]«ŐjµÚú¶FŁ© bŻAZZšV«­ďěşvíšÉdŞ˙Zg)eý° ôôtv'´ţ}@ýš·oß®cŚýI„M©TZ[[[¬s ,¨Źđđđ>}úŔŹ?nĘÎľ‚{Ľ /ÂLYY†Ç™Ś·?*ݍ±ÎMáa´\ŽÔ®L ­ůóçoŢĽY,WTT°f¦FŁ©1Őj5EQR©tŐŞUð &ĽögyçÎť;vě€ÖµZ­P(¬ßűUŘǦNxËü  ĄRÁ6.—;nÜ¦ŞŞ’%l<ܸń/< Ż Ǖϗ>—Y4ČäBě+güřńłfÍJLLěÔ©ÓÎť;{őęŐ§OxćLCUTT$''<‚xđŕÁćÍ›u:]yyů;ďĽĂjµ=iÎaz-]cą¨JĄĽz5őÔ©''Ç ĆűűűŤF†ˇ[·n}ćĚŮ´´´>}zÓ4}ćĚ Ă\\śH’¬ ârĂcb(“)35•ŕpB ěŃŕq8†§HňFZëHéŘ­ĂĚ٦6<^ä¨Q ĂÜÎČŕńůýŁ˘ÚuîŚXóxCĆŚAwnÜŕ ˇC†´ ä`Ů(2`ŘřńŽßËĘ …a11ľíŰcRˇ0f‚ îßą#´˛4|¸O۶8†™sţČD˘á'Ţł'÷Ţ=‘µuÄ­|}€­H4bňäĂ»wç=x ¶±ożývZZš««ků”)SnܸѬYł:ňéÓ§ßľ}ŰŢŢľŽüÝwß˝w^NéěŮłsrrd2Yůś9s lllęČçÍ›÷äɱX\Gţţűď—––Ö·jfÍšUYY)ęČgÎś©T*ß´ÁÎś8Á~ c_]ű÷ď>|8çN…˛Ŕ‚żZ­ZŻ×˙ilR©4$¤Ďąsç .îpż~ý„BaŹ=“’’ŕřńc˝{÷~Q‡ Ă0b1ŕ8`R(¬»tĹď>őő3b±25…ňö†’"ĚÇ»uö˝{wîÜ©Y:Y»[·n)))ˇwďŢqqq :pŕ€››tęÔéđáĂ®®®;vĚĎĎW«Ő••• ň¨¦Ŕ××w÷îÝ666}úô)(( I’ ŤFĂţ!¶cnn.Žă^^^™™™Ařřř4}°(Š"‚ ĘŇb«'žşÔjE Dyy!“‰áó•WŻ€™l:„R©tw÷›’’"ťNWUUĺéŮd2YQQᛎm¨·uF`÷î‰ĂµA"I,/ŻÖoqĘĂ XÇg>^Ô·SçŔŔŔ«WŻÖüţÜąsďĽóÎýű÷ 99yĚ14hPnnn~~>XYYą»»SµnÝşożýöÎť;b±8>>~ŕŔŤfčСlćI’«WŻŢµkWrr˛X,Ţ·oßúőëŮ©ľk×®-[¶\¸páEnh×®]&L5jäľ}{«)†Ţp8ś´ÔT.—שsPiI1Ă0$EŃESI’TÍgšÂq"?/ϨÓŮËí8Út˝pVëĹ[6z€ĚÁą˛˛\ $''/Y˛”ËĺĚ™ó~Ë–-u:-EŃÍš9jµÚ+VZYYEEEšLĆíŰwzyyMžb„ľÖ–*·V{Ă3öBđŘs˝ţż$ľľźŻ]Ű»o_c-=5íŤĆ†ôÔ–€ @k—íżýÖ¶}{ňyzŘÓÔ#hncsňćMW7·š›ĺđ06sÉř<9\¸Ü´ŇR‰„©×ž~öw—ł·ŕŠa÷ŤĆÚŮq\nCíkË µ­dŠ$[p8ʦ6O6×Ţś(Š;»ÇFŁţ˙ëá zíy܆ä@áŁGý}}ó”Ju-ĺÜgí)[«ĐĽśíś[7nŚ80űÉEôpÎź=»xĆŚ´;wŞkéaO—®Ż§FNj%đţňËÖŐ«Ď&'WŐşYnCíÍÉ@đㆠçNžźß ŔĆ$´k׌FăkÜbp\‘zµĆŻ$qrůăW\®2-t:@Ţtí“× ’¤==·o±=߼eüGĺÝZ‘™ŽŞŞ¸\.ŞW­´öô¶¨P(,++‹Ĺ¬6$$äĚ™3çĎźź3gDGGź:uĘ`0těŘńÚµkEŐ|=>>~ţüů0věX6óˇćW55¦˙}6š¦9NBÂé7nD˘iÓf<}*UŞ%K>}÷ÝcÇŽŮ´iËäÉS 0l؉DŇ ‡íéh_Fnv^Ô2‚_DţWé1ý2ó\k˙Wé©Cęž+˙«ô^°Ů_ C\ľŚ(ęźÇÖŘű2™Ş®Ć˛Lžáóµk×Đ^ŢśÝĐ@‰D"vE"‘··7ÖeŹ÷öŰo·hŃÂÁÁL&“Bˇ¨ÓF"‘=ĺŠ4-•JĄR)KKj>˙ëΚ¦M&“‹‹‹§§ç˙wš!ÁŔžŁíééÉ2[’$ŤF#ë–´đ5 ,°Ŕ ţ†z˙ý÷'OžĽ{÷îiÓ¦5žCÓô©S§|||˛˛˛B-[¶dł)ŠJLL0ŕéÎ7I’gÎś0`BH&“˝őÖ[aÆ [·nµ6 ţs0±đHČÉťŢđÉ'Ś•zce źka#„âââjŇđ¸\î Aţ)Y¬H«Ő-ţ¸psöÜř?›Ę٧wa†©S #Gc5lí9ß{Î(3 coo?bÄvJ¸şş†‡‡7˘ˇĆťű"á.˙dÂĆ0 Ťf0č ††#Ş(ŠÔéČz_4WYĂ ,°Ŕ Ţ0a77·oľůfÄŢŢŢ jÔě4FDD,]şt×®]† 8đ‹/ľ …:ť.**ަć&›Ô®Ńhř|ţŇĄO+ˇńxĽŘŘŘ 6X†Á‚˙0Ť6÷«ŹH``ln0Ľ9»!T^^.“É©É>sćĚňňr Ă0 Óh4őë,˝JKKYSućĽQs©ŐęŁqR7ŕp€Ç˙§łŕp€ +!Ő®ťfÍw/ČÖ^p&Ôţôďó˝"e{žo‰´Ŕ ,°ŕŻ#lĐľ}űqăĆMś8ńńăÇŤ—Şäóů'NśĐjµ}ôŃž={¦L™VVVµ …úž:š¦Ż_ż^żN¨üëaͳۑYš©3iŻO¸ć%ó2Ro°HF»ví®]»Vżfn ˛˛˛X›U*•Ö>Oů•ѢE ÁŔć°ý$‡$ YwźţřĎ*7R$IµlY}?ÇUđ†ŮÔś­±·˙jÇ"dń°Y`Xđ—¶üüücÇŽ-X°ŕą‘QALś8ŃÓÓ“˘¨qăĆíŢ˝›%lĎ5 rss׬YóÁX†Á‚˙0„Uę*t-Ś<:ęÔx;ť24ĘJđ„ÔÖoĂJĘĘĘjČVżYÍů$ýű÷?tčPýăJ^ Ü˝{7A†őë×ďäÉ“ŻąîHťµ#ę}6śŔ.Î94pʉţ'†ă´ šţëîŻ78o ˘ĽŚĆ8lŰ«<ČŔPme%’4ĺk‚ñ‰d/Y¤®ľ ÇEÖÖŇ—¬LŘ€„¬%éKV’¬1 d#‘H›v¸ˇŕ™Éë0z$ŃÄo’ !i­šďŻř.°±AMt @%•B˛guä_ąsÄ †a¬ z¸bkkÇmÎş}Qđ¬D"‚Ăiâq˘V++‡ÓÄë.źßÄţ±ŕńů|@ÖţbJžvř_tä©=a«¬¬\±bE‡&NśřÜýW ĂŘłYqďŐ«×Â… _„­=~üxÝşum۶ ± ˙\…VBˇÇ㽉{Ľ5)#`€8č^áýĹ>YŐgĄ€hS#ßÝ´iSnn.Ă0:ťnĺĘ•A „ľýö۲˛2Á°jŐ* ĂV­Z5wîÜ+V<~üř»ďľC­\ą’a đxĽĎ>űL,#„ľřâ ¶4˙ęŐ«k(ÜÚµkýýý‡ú˛Ľ±âăăOž<É~4hĐ«™Â/1á⋟$ÝJ €, G˛¶›óí˝âĂ ˝ľćZ-ŹŘ›ęfš–Je:ť¶ňájRÍ• IDATýWv3""‘ČÎÁáŔöíy÷Pí†Ďçç=x°óćô+WšrX9źĎ/-*Ú˛jŐ©-ŘĄćŐŔăó•ŐŐß-]j߬YSa.—kĐëżůč#±DŇ”çŽ Š˘>ź3‡ÇoRŘ3†a Ă|<>Ö´jş MĂ,X´nÚbb4(Šš÷É'Mt„Jˇ0čős–,16!Äð˛âbĄB1çóĎ zý+ëÁqĽ '§¬¸xîçźë› ‡ ě[· >l˘‡“ž’ň('§‰z¸\nRb˘ZĄjb˙đxĽ+çÎqyĽ÷ĆřŞéë<>?ĺüyöóŤ7’““k˛,řű€-Ôü¦Ă0żüňKffćž={^$Ź!Tł}Îň®OŇę\nyyů/żür÷îÝíŰ·óů|ËZđĎEzúu„Ŕh|!CŤ¤ČŽí:D"@X[ď}ęýŇ€¬Đž”˝ANťÇ´ĂĂy 0P&ŔÂ… y<žX,Öh4!!!‘‘‘<8tčPii©Á`čÓ§Oddä‡~čééyřđá‚‚‚^˝z 6ěčŃŁ$Iž8qÂ`0,\¸P,@BBByyąŃh ëŰ·/Žă™™™łgĎ>wîÜsź÷¤¤$Š˘hšîÝ»7¤¤¤%%%™L&VŇĄK“ÉT㜣AwŚ“—đÍŮ˙CCQÔéÓ‰aćnAŁQ[¦î4MËd¶đčQŢ+ź„AQTÇŽťe2ŰßN—>)dšđbĆpĽş˘"#%ĺáť;M!6Ž«•Ę«/ŢĽ~š¦GŻ×'%&ňřü¦čAFšLçšěfGĆĐôécÇp kŇŔ#ń‡7q]b{äÄÁM¬rDÓ4Ă0Çhâ.I’Iűůç¦LB@Ȩ×ôúcű÷ÓMÓŁÓjŐ*ŐŃź~˘›°k€R«TŠŞŞ¦ęÁ0EU•NŁişžĘ˛2’$›Ř?†•c¦¨ŞzĺńÂpĽ´¨ý\TT”••Ő.jÁ?•°­ZµjĎž=/¸Üäää´jŐŠ¦éÜÜ\gggöů|>I’A0 STTTł8ęőú#GŽěÜąóŕÁŤ$ŐX`Á?sçľ\Loüéß;uę¤T+7‡nJ-şv«ôĂ0 †YÇfűÉýüíüM´IŔđ‘™UţâĹ‹-Z´›ű÷不§7oŢD"Q~~ľ››ŰСC‹‹‹$I``ŕůóçĹbń•+WěííkTť={–UHÄ“'OěííűőëÇápz÷î]TTäččŘČ-„‡‡«T*†a*++ĄRi—.]4Í€´ZmuuµŤŤÍĺË—kĚŮ7˝#S©ŻŠř)žeČŠą"¶{hherZĐř‹”$I„qř|†˝2a#iš®Ş¬X´bĹ»S§jšp9R€^={Nš=;6:Zß4=íüüľŘ°ˇOĎžM ‰´héâ˛ăĉvľľM ‰t–H^şäęäÔÄH/>3ÓĆĘŞ)̆pİó÷ď71J›pCčrvvSB"€R§ół±ą–ťÝÄČÇĹĹ!ŢŢéw瀞Ö97ďÜÓŻ_ćÝ»Š&čáś»xqáÔ©™·oW7Aŕ×Ç7Ż\yáŇĄŞ&č±X˙ăŹçNś8WÝ´Éüٲe…[7oV4íášńî»b›ĺ_~©zU%€©3fěůáčŰ·ďäÉ“-‹úß5Ą_?aÓétË—/xń}ťożývÝşuZ­ö»ďľëßż?k:;;˙ôÓOcÇŽ-..ţňË/ŮÝ5“É´˙ţ}űöýüóϬÝi˙)Ś;>w‹ÇP 㪠˙„çÁČcŁą8WiP^›zGDă[5lÉG ĂęHÔjőąsçŘÚŚ5{"5ÍŘF??żââbÇ)ŠbżxíÚ5ŕrąÝ»wOKKk$U„ Ëärąm۶}řđ!ŹÇ“Ëĺiii"‘¨]»vŮŮŮ5˘ööö7oŢ|˝' „¬ąO3L´Ég«/<3¶y8ďÎäŰ|‚/ćŠ˙ÝłčMźŤŢt‚ż{bXaá#» í;uµh4ÇKJŠ ŞŞ*Ő´- †¦iú~¶nü­®‡˘é&ćŚQ5÷Ő4OĹ­Ţ´›ÖáC5]MĂ4}°XŹ_Ó‹~ýC?»ž¦?\ M3MľęY(ěkĐĂ0LÓ şV™ZK˝Ú˙úĆТE‹ú÷ď˙âŃ ¬3müřńEńxĽqăƇĂyűí·÷ěŮsôčQ@`ggWUUz˝~É’%%%% .dCŇĹbńŽ;,#aÁ?Ż UZY âgVńG4ÂP‰˘=)cá: ðŤ,1Ł( Çń&†ă8B˘¨6mÚ°ŤYĎŰÓ7Äł8„Đ”)SfĚÁĺrťśś˘˘˘X îîîlśśs©/,Ů›={¶V«%"//Ź­-ą|ůrČĎĎŻéeË–µlŮňőö9ES±żŤŔ4C—T•Ô”z iňă‹‹UFixQŁ®ÎÉŃ˙Üżâĉƿk=L‚ îßż˙÷|ŤF#Ap¸\—Ë{5¦)Š$i†ˇ›V‚5żhš¦š¦‡ý.CQM×ĂĐMÖS›h˝âGQtÓJs˘gךFŘjV=lÔëĐĂĽľëy-z(š˘X˘ŐT=ĎdS'3Ă4ýzX"ĘĽŽ‡”aşi×CY›…°M›6­Ć(|ŕ8>lذź~ú !ęĺĺĹľ°Ł˘˘ž—Á`hZU¶7 ¶ţĽőĹqś$I„˛Ô†±Ŕ ,°ŕĎ$lĐxúJďĽ^˝zőęŐ«ŽÜÎÎîÓO?­ů±[·n¬y´{÷nKż[đŻÁÇ/ęŐ+„~±:ňF”í+Ë(Îä`çć)ňjJů34ă,ućá<ĄAÉĂy nńůüőë×óxĽęęę’’‡Ó¶mŰ{÷îi4@ŕííÍăń¤·oßvww˙â‹/ĆŽŰľ}űË—/»¸¸Ľ˙ţűŔĺrżů曀€©TĘăńĽ˝˝q°Ź3†˝6…B±gĎ–EhµÚšBůůůK—.-z–ýşY Ď< ŕp9Üť{w˝Č 0 ŁP(°&–1ř7„B­­­ŤŤőß˙jµZť‹‹K“CŘŢ0~Ú±ô+.†1ëěAĎţ±;3ôóäŤ\Ţ›ÖS3ő_PO훢§v'š“[ôĽš¬ÖJY»˝9ů+ëažý{A=uÚ˙ŁőÔy¸jÚ›“żé‡Ý‚˙a{ŻFË6¤˙:h4­VmxáĘĽŰne—m™@Ön{Ŕ­Ň[OßŔFŘ?xŻżť?I‘2Ĺ4@6 Err˛ŻŻ/[ÎRRR<<<ňňňŕáÇb±¸A_ßőëםśśŠŠŠ?~,‰ŇÓÓJKKU*•\.W«ŐyyyrąĽ˘˘JKK9‡­†žą¸¸4ř·8N«V­T*Ő^Mž#×*ŐŤźk÷O\—L&SëÖ­ďŢ˝ýOą`„Đ?"č” —z…űcřs\ć¬=ć%]őőŰ3čeôk˙Ęz^PnŃó zjóbňWÖ/©š¦çďµzü˙+gž'·Ŕ‚WCS÷•†©®®¶ôŁĽ x8ŹOđĺVvăŹOČ®Ę B ‚Ť‘?řÉý8GŔác¨á˛ţ ðEk{ŔŽ9rĺĘ•¤¤$¶¬kRR’““Sýď?~<))‰ §€“'O&%%‰D˘””öôŽS§N]ąr%99ŮÎή‘ëĎĘĘęСłłóéÓ§YIí„7–™L&___ŹćÍ›»¸¸ĽŢCçĆž97úěąŃgFžŞ}Ü,çe˝}ëÜč3§Gś2ŇĆĺüÁ0L đ˙!x˝őfŢśĹEżĚyŘřą÷ď/ž9ł·ŹĎ€öí7®Xˇ¬®&řłłMźŢŰÇ'4 `ÓŞU*Ą˛‘MSŔ˝¬¬ß~»WëÖa:ěX·N«Ńŕ€»7oΛ4©WëÖá;îÚ°A§ŐâŤęÉJOź=n\OoďŔŔ}›7  @p3-mÖ1=˝˝wîüó¶m&ŁkTOzJĘôŘŘžŢŢQ]şÜ˝›˘( ¸~ůňÔ`/Ż!]»Ţ»—¦éFŚo>ŔŐ‹ß2$ŘËkXŹÇ`Ťu>Ŕ•óç'EF{yE˙őWÔ¨ĎHJLśěĺ5ĽWŻř¸8ü™übB¸°°`/ŻŘ„cÇ/ŃĂ8űűďŁű÷öňŐŻßŮßgg-ŕĚńăŁúő öňÝż˙ůřřĆg3p*.nDHH°—׸/%&˛ů8ŔÉLJ÷îěĺ5!<<ůěY^Ł;Qŕ·˘˝Ľ&EF¦\ĽČÖGúiXŹÁ^^o’š”ÄoTMÓ‡vďŇ­[°—×Ôô”ţł¬ą_wîŚęŇĄ§—×ôŘŘŚÔTAŁ6˘ÉhüiË–Áť;÷ôöž5fĚ­ôt`4ömÚŘÓŰ{ö¸qY™™ŤčÁtZíÎďżďرWëÖó&MĘÎĘâŕZµzűÚµ¬üĂ·ßľw玠ŃNV)?®\ĐŰÇgŃôé9÷îńeuő˙ű߀öí{űř,~÷ÝÜé@UEĹÚ/żěß®]H›6źĎ™ó(/ŹŔ¨,+[łtiż¶mCÚ´YöÁŹ xŤNž˛˘˘ź|Ň×ßżŹŻď× ň¸%Ož|łhQ_?żľ~~˙[Ľ¸´¨×čd.,(řâĂűřúöó÷_ýů祥\ŔŁĽĽĄs熴iÓŻmŰďľř˘˛ĽÜ’GôßDS=lçűďż·ôŁĽ H6NŹa’ /› &ÄAŚš™Ômâ0ݎŚc¤Ś 4c¦(Š:­0 Ó®]»Ú?¶m۶A¦W»îkíŮŻ3 ÓˇC‡ą~ź &h4š   5kÖ`¶zőęšLÔŐ«WłpWVVÖĐą×pęáÜh†ţ´ď'K—€b¨źďüüyŹĎHšTU˙ĘůĂ0Ěß¶ÖČ?¶KMţDqą\‚ŕ<“Ó˘(†a‚ŕńxěÉ~4M †gśŤ©o–)ű7o®(+E’äĄÄDąŁcÔ¨QŐZíެ®¬0di4žŹŹ·st ʉárąLCnqUŐ®~Đkµ‡5 GŹ:8;2¤RˇŘµ~˝É``ĺ'rtv çp8 ę),/ßľnB(,:Ú Óűé''Wמˇˇ…ĺĺŰÖ®%8ś°čh˝Nwdď^'7·®˝{Á4d¸o]łĆJ$ ŹŽÖjµżlßîâîś_\Ľeőjk›A11ZŤćç­[]›7čŇĄÁ“©1€ÜÇŹ·¬Zeko?Č×WŁRíݸŃÍĂŁm``ÎŁG[V­˛oÖĚŰß_ŁRíٰÁÍÓłMűö . ŕA^ŢćU«śÜÝۨ•Ęťk׺{zzűűßĎÉٲj•kóć~:¨Šíß}çîéٲMsľôě{÷¶®^íáĺŐ®sgeuőÖŐ«ÝZ´đôňş{÷îÖ5kZx{· RVUmYµĘ­E‹ćfŞ(1 “••µ}íZ/?żÝş)*+7Ż\éćééęáqëĆŤťßßÚßżS÷îŐ¬ÜĹÝ˝Á]9ЦłŇÓ÷lÜč`%W–•m^ąŇÍĂĂŃĹ%óęŐ}?ţčß±ŁP$Ş,-ÝĽrĄkóćÍśťŚ‘#)ęúĺË?oŰÖľsgPX^R˛eŐ*—µkmííŻ]şôëŽ]ş„²ââ­«W;Ż^mďŕ@7ÔÉF’Ľrţü‘}ű:uďÎJž<ٶfŤÓŞU6Riň™3Gú)08Çç?~Ľă»ďš­XakkŰ ˝Ét1!áäáĂ]zőâňxO=Úůý÷ –/·‹ĎÇÇ'=ÚĄwo—ű$?÷úő|ń…D"iPŹÖ`8süř…řřî}űń(/oďŹ?Îůě3ž@pôčĄÄÄŕ~ýp‚(ČÉŮżiӬŋ­­­é†&ˇZŻ?yđ`ęĄK= Ŕ0,˙Á۶M˙č#‚ Ž˙úëő+Wz‡†" Ë˝˙×íŰßůŕ‘•UzZíŃź~şť‘÷oß>˛gĎÄŮłŕČ޽ٷn…  s÷ĆŤ¸}űĆÍ!ÔSĄVܵ+ďÁľ4Mg¦¦JmmGM™B’äŻ;v<ĘËëISÔőË—eryĚ[o ,'[ŰKź ^¤VXPwł#€FĎřşű.éţ©Çęą!|ÇŻ¬XÇ1g‘<·Ů‹‡2 łpáBö3[k„M„cÁ~ž5kÖe,JŁňŮű}Ňmń…ÇÎ=< iré…e ‚ćż`0¤@­xHŁŃ——WPP V« ‚°łłkٲĄX,Ć0L©TŢżż¨¨Ă››»§§źĎoŻ =%%+##räČŃ“&éM¦Ďß?éôén!!îŢ˝{ăưńăGŚŻ3—Ěšu)!! KOOĎú>h@Ę… ÷ł˛ĆMź>$6V­×/š:őüÉ“ť{öLKN~p÷î¤ŮłŞÔj?š2ĺüÉ“mťśś¨†ô$%&ćÝż?sѢaaŐjő'ž=q˘c÷îI‰‰Î^˛¤o˙ţ•*ŐĽńăĎ?îŰľ˝­\Î4¤çüÉ“…-_ÜłgYuőűcĆ$ţö[»ÎťĎźvĚ»m[±XĚ4dsś9~Ľ´¸řÝĹ‹;uěř¤¬ě˝QŁŽő Hüí·ňŇŇ9źĐľ}aIɬ‘#ââZµiĂkČ6ĹNÇĹUWV.Z±ÂżM›üÂÂwGŽ<çĺç—§¨®ţdölßÖ­s=š5jÔ©¸¸­[ن$8§Q«ß™;׫E‹űąąłÇŚI8rdęüů§ŽŃiµS>ü°eóć÷>ś=vlB\Ü”yóĚ…?ś:rÄd2M[°ŔĂĹ%ëîÝyo˝uúčŃ·Ţ{ďÔ‘#$IÎX¸ĐÝÉéćíŰNśxúčŃIłf5ÜIšL§ââˇw?ţŘŮÁ!=#cŃÔ©‰ÇŹŹś<ůT\Fł/nfgw--í“3Î?>~Ę”† ’V{úŘ1ľ@0űÓOíe˛äää/ćÎ=ňdħŹDďö™ťDrńÂ…Ż,¸?jüxCCzT Ĺ™ß~ł–Jç.]*‹Ö|öYrbbŻĎž8!•Ëç-]*‰Nýţű÷_~™ś8,6ÖĐ!©,-=÷űďöNN|ůĄX říС­kÖ¤^Ľеëůřřf..~ůĄĎ?rŕŔî ®^¸©opٰđbB‚«§çüŻľpą?ďÚupçÎŚ«W=˝˝“NźöhŐjţňĺ|gß¶mG÷ďOOIé׿żˇ!=99—ĎťóňőýčëŻ98ľ}ýúÄß~»“™)“ËSÎťkݶ킯ľÂ1lËš5˛®_ďlhh2?¸s'őŇ%˙Žß˙ě3°áëŻÓ’“{††" KKNn4ë㏀uË–]»t)¨WŻNť:z¸ngf¦§¤tíÝ{ęĽyĂ|»xqĘ… =ú÷WTUe¤¦ö }ű˝÷L4ýÍG]9w®SŹ~~~–ĄűżĚŇXđçfh+± ! öFě±Ř>—c0 łwď^—7q=•••eĎPZZÚH>Ďß*ă‹FeTvTl%fłgx<.cI°ŕ%€Řbú†=~üř×_]¶lŮĽy,ZôńúőŇŇŇXźöőëé«V­ž;wîĽyüđƇ2 Ó`H$ŕňŮłţ:ô‹ŚDVÎř™3UJeaAÁ•óçşté;hqąfÍŞŞ¨x”“Ó`ŔŕB||·>}‚ `lřüÉsćhřđNÝ»S¶bńÔ ngdTUV6ř„łń~ŃăƵ 2ŘI$Ó.Ľ~ĺŠ^§;;qbŰNťL2ŮŚŹ>J˝tI«V7¨8yčĐŘiÓÚ´kghfg7cáÂäÄD’$ăž0sfk€“ĂŚE‹.&$ŚFdĆv9yčĐŰsć´ňń1¸8;Ď\´čĚńă Ăś<|xĘĽy-Z·6¸şşÎX¸0ńŘ1s…|@üáĂÓ,hޢ… ą‡Ç´ ⏀„ŁGg|ô‘{óć€ć-ZL›?˙äˇCf—tš>óŰo3.tuq1´lÝúťąs?xas'NĽ»h‘ł““ U›6“ćĚ9qđ nćbŚF㥄„YÜĚÁÁĐşmŰń3gţ~đ IQ—ĎžťőńÇŽvv&€6íÚŤ™6í÷ 3z´͵¤¤™‹ŮÉd&€¶ť: ź81ţđa^ź‘’2sáB;‰ÄĐ.(hč¸q'6§§ş˛ňvfćŚ db1Đ©{÷đáĂO;¦R*ďeeM›?_*Qť rúŘ1Ž™Á*-.~”“3eŢ<€čÖŻ_ĎĐĐóńńĄĄEŹMž;ךĎg‚ čÚ§Ďą“'9f&ĎŁÜÜꊊ‰łf‰¸\ĐgĐ €.].ź=[ôč‘ZĄ?s¦‡ú ěסCň™3\3“ůÁť;EŤ™:U€ă@Xtt oď´ääÜű÷1őÎ;| #ĹĆşyz^KJâŃs;#C$ÇĽő€5z´ÜÁ!+=ýîŤR[ŰaăĆq¸CÇŹ·‘Én^»fNOú•+Înn‘ŁF|„b'MâpąîÜÉLMmޢŠáĂq†Ť|ç„Đ˝[·ËĘm!lX`Áź…AqpČŻŮoß}<˝ŔÍÚ•Ť„|Ž]ůŞLéEŞ)tîÜŮŮŮŮĹĹĹĹĹĹÁÁáźu:I“©ăSŔ@‚4ZJYđ2|Ť}DhŹ˙äÉ“O?ýôôéSqq‡»v Úľ}űŐ«W oÝşŐĹĹůر¸źŢŻP(öďßWZZ‚a¨Áwę“‚‰­­ÔÖ(€ć­Z µRYTP łłł‘ÉXą§——^§S*ćÉăĽ<''±Ť  ZúřhT*˝Vű8/Ż™‹‹•XĚĘ[µiŁŞ®6G0€ü‡ťÝÝB!@xűůU–— †ü‡]==ů+oíď_QZjĐëÍ­Ľű÷›·jĹárqŔ§]»Ň'OH’Ě»ßĂŰ›ŕpXy›€€âÂB“™Ŕ] ÷Ţ˝–mÚ`8ζ÷íС° €¦éÜěěVľľ˙ÇŢuÇEumëµĎ™Ţ` ˝Hď"ŘcA±ˇ(( Š%vc77‰WMĽĆôÜŤ-ĆKŚšh0` ˘ÁŢQ+ ]zf¦žňţ8ÂăFLrßsľßü\lľŮsfź}Ö·öŢk! cěAÝ»?),4WäçäřvíJ°šÚ—äçMääřuë4Í ‚şw/ĘĎď`,ČÍő ˇţ·ýăÇP“B°(€ŔĐĐÂÜ\d~š-|ü804”iO„„äć@Q^^@łť¦şu+ČÉ1ÇC‘dIAóľ8BČ78¸0'‡¦¨'……ţÝş8†ăľAAąąć|8“ŃX^RâĚ´g±Ů^ţţ…ŹQQZę×dçp8ž~~…Źcf.˛AŻŻ©¨đ "0ŹçćĺUś—g2j«Ş|;_ pőđ(ĘË3'Dµ őuu^ţţ$‰DN]ş<),Ôkµęúz/??Ć.–HśťźšëŹFĄŇ66şűř0ĂÂJ*µ±·//)iP«ő:ť›·7c·–Ëĺ¶¶eĹĹy!JL.L{ą­­D*­*/W)•Eą¸ą1uměíEI…™hP[U…ḣ«+“nÇŢŮ™'ÔTUŐUWłŘl{ggĆîčěĚár«++137WeY_ °µ·gň@:»ąa8^_WWU^.‹měíiŔŐÝťPÖÖZ|w‹`łŔ ţ ŮÂŐ—ţőú‰iă“&0yü˙Dʎ±cÇÖÔÔtЦ°°p×®]GŽ9|řpbb˘P(|)ońT9Łv»ü>ýĚŮ×?7ů¬‘2Y(˘AÓ´V«>|جYłşu vpppttŚŤŤE+**JOO‹E‘‘‘žžžţţţăĆŤ­®®ÉÎÎi.ăÖĘlÔhx|ľ5BI‡ßÍĚ´ał)’4ŤŤ |ŔˇÄC‡ÜżoĂáa4yßT Júi߾ǹą6\®Ń` ˘A­ŠĹ„ěŮSźoĂă “ÉćyÄVV"„ömß^ZZj#čµZ’$5*•ÄĘJ„ĐžmŰ***l„BťVKšżaŐőőVR©ˇť›7×ÔÖÚĹÚ†š˘ÔőőÖR)ˇí7*ëëm$mCC+Zęúz©\ÎCčŰőëm¤Ňµš¦C˛ç IDATiu}˝Tˇŕ"´uÝ:­Ng#—3vłĺˇ¬ĺr>ĂÓÜ@*—‹$˛Ĺ±Ŕ"Ř,°Ŕ‚ż<ś \@,ôõý˝zO Ś!Ś˘© YYYjµ‚ Ă0 !”žž®ÓéH’4hBčÖ­[=zôHOO×h4áááˇ{÷îńůü´´4ą\Ţ·o_‡şqă“éŽ)yŹ2Ť:ťŽ±tׯ_˙k®$cź)<łěÄ?`ÁěŕY¤%éP°!„t:‹Ĺ*,,,++7 .\ŕóůׯ߰··“HÄĹĹ%\.ÇĆƆ¦iŤ¦ˇŮlĺ{I¬¬´Z­Š$Ă ˘Ş´ZśĹârąb+«Ć†I2„¨lld±Ů\>ß\5+©´A­Öä#H€ Ť†Ăă±9+©TŁR5äČ‘#I€JµšÇçłą\sľ µ\®Ş«k¤¨1cĆőő‘…ăR™¬ľ¶¶‘˘˘˘Ł € ĄR(±ĚDmh©\^WS٧¨q11@yMŤH"Á0L*—×VWh:&6–(ŻŞ[Yá8nŽG¦PÔTUązzŽŹŹ7”•—[IĄ!©BQSYéčę?a‚  ´¬ĚJ&ëŔÇ•)Uĺĺr[Ű F€ââbką5Ů­e˛ €â’©BŃň“*•ĺĺŢŢ “&é*ž<‘*Oíeenžž “&é*JKećKž ©\^YVćâę:1!APÉ´GČZ&«,+svvžŔŘËĘ:âAČJ&«,/·wpź0AKÓ•ĺĺ2„•µueeĄ˝ťÝřřx-MWWTČllĚ9î8Ž‹­¬*kjlŠŘ¸8-EUWVĘ ĂDVV•uu62ٸFŠŞ©Ş’µ—f¦9–'‹«ęëRittt#EŐŐÔH ÇBa•Zm«PŚ3¦‘$ëkkĄíĄ|:Ks8<>ż˛ˇÁÉŢŢuÔ( IŞ”Jk™ŚÍápyĽŞĆF''7''5IŞU*k™ĚÜMÁĺńŘlvµVëŮĄ‹w—.*‚hÔh$ÖÖ.g±Şt:o_Źz‚Đ66J¬­Íńđř|„a5żŻ/ćë[g2éu:±DÂăó@ŤÁčďŹęL&^/–HĚńD"Š˘jŤĆĐnÝ Öh4™LB‘ÍáQk2ő € Ia{ixˇDb2™ęL¦ľ˝{@µ^OÓ4O ŠĹFAIý^{ Şôzŕ …Áö ²%Ň ţh[hš1,9¶ôNU&†žq?Ž;vŕŔaaaááá999Śq„ Ś%// TQQ1~üř!C†ŔČ‘#u:]\\Ü AšłíGGG‡…… <¸´´”±1zôčÁWVVvÜ ŁŃh4›k…3Yć[Z'¸Y ţŮS©WŽ>đx. ŕîăSV\\[]m îgdXIĄ‘ČÍǧ¤ @Y[ËŘďŢľ-U(Df|AŔËĎŻ 7W­T2íłnŢ´±·çňxžţţyŮŮ•Šąo3oܰsrâ íňP>9÷î564čh€;ׯ;uéÂbł˝eei{ƵkÎîîlNűŢ(ź  ű˝žiűęŐ.^^̡¬»·n  pëĘwoośĹ2'Ř|»vÍşyÓd2é(€ŰW®xúűB>AA™×ŻŃĚăĺďßÁDä”qíIQZ’¦o_˝ę>WŻR4­ )бwŽÉËß˙ö•+€€ Śë×}‚ ĄÝd2ÝąqĂ7(Čś°ÁY,wźŰWŻŇ:ŁÁp7=Ý'(Ă07oďŚk×»AŻżwű¶Źy6‡ăâîžqý:č´ZíŁ¬,ďŔ@›íÔĄËťë×iĆŢĐ}÷®O` i^ŘŘ99e޼ɴרTŹ>ôňóăňx¶Y7o€@U_źź“ăĺďO™á‰ĹR…âŢíŰ4€@Y[[śźďîí- ­e˛űŚ˝®şş´°ĐĂ×—43x¬¤RˇXü0+‹0TWTT–•ązxH¬­ůAöÝ»Ś˝˛¬¬ş˘˘‹§§9ą­-‹Íνź0”—”Ô×Ö:ué"U(0 Ë{ô J‹Š4*•“››9;GG’ rsI 8/O§ŐÚ9:Ú:8ŤĆ˘ÇŹ  đńcŁÁŔ,u¶ËăčęÚŘĐđ¤°iźźťMÓ´ÜĆĆÁĹEŁR•1öĽ‡1„vvĎů#‚‰ĚţIv“Éôö¶Óćßegü–?j7çY›üżŇiB¶P• ç'ťő·ńfBăÂč#cžhžHy2+®BX»7Nť:•źź_QQ_[[Ű«WŻ={öäçç———Ź;V­VKĄR‡VVVöďßżĽĽüîÝ»ŕŇĄKŹ?fŠb;v,//ݬ¬¬{÷îL±)…B‘ššZZZÚż˙úŽjxzzÚŮŮIĄRćźţţţŕîîÎŕfŕĺĺu˙ţ}xľ”'/ Ďâ÷ţˇ/4Eóő=Ëö~ ž=]ac R©,ńâ…¤¤ŁÓ§O;wîµk7„B!I*•zäČĐĐ•Şž¦Çńv·űŽq/#ăäáĂ&ŠŞ×hvmŘ`%•:»»6ěÎőë)GŹš(J©Vďüúk…ťť›—W»ľ  `č1WΞýýřq F©üîË/]ÜÝmí퇎}áÔ©´“')€ęşşo?˙ÜÝÇÇÁŚ/hŤ=uôčĹ3g(€ĘęęÍź~"‘J#bbŽ˙üó•´4 Ľ˛rÓ'ź÷ě)5łŘb=a‘}űn\ĽĄee?ú¨÷Ŕ|`ô„ ?}˙}úĺËŕÉ“'ß|ôQżđps’NHŘ·uëťë×@qaá7k×9’ĹbE%$ěŮ´)+=(,(řfíÚˇcĆpą\sB4*!aűşu÷320€‚ÜÜoÖ®Ť7!ť°íß˙~™‰äegoüčŁQqqůż1'nůôÓě{÷p€Üű÷7}ňɉ`t|ü¦O>ɹȹwoó§źF%$őĄ0ld\ÜĆŹ>ĘËÎĆffnűňËčI“B#ĆŤűfíÚüÜ\ŕAFĆöŻľ;y˛9aĂáp†Ž˝aíÚ‚ ëćÍÝ7Žť4 g±ŤąáĂ‹ŠŠ0€;ׯď۲eě¤I„ˇHôZxř7k×–|¸ťť]III+{xx¸˝˝}yyy+{XXŁŁcuuu+{ż~ýśťť•mÎöîÝŰĹĹĄmV¶=z¸şş6š9Łř˛ĐN쪼ĽÜÁÁÁň ·Ŕ‚—[´ňÂŞUŽpkžuec#.†tŤş7˙‡Ś'k05n» ÇÚw/üüü\]] ??ź xzz:99ŔăÇŹŤF#A|đÁkŻ˝ź|ň‰X,‰D8Žűűű7K¬řúúJ$řôÓO1 ;xđ`yy9SM;//Ď\f67n$Çń)S¦üřăŹůůůÆ [µj‹Ĺšvě…S§ŇNś.Ź7*.ÎĆÁ2ăĂ…öí;,**ő×_O9<>Tl¬ŘĘ*¤OźˇQQż>|ěĐ!ŕ #cc­ÍěF#z8dôčÄ}űďŢŤ¬e˛ľ@Đ{ŕŔđČČźż˙ţŕŽ@nk#‹Íő§ß!""~ŘşuϦMŔŃĹeĸql§ß!aÇďٸq׆ ¦]Ý݇ŹË3łRG 1âĆĹ‹ßýűß[żřxůűŹŽĆpdôč×6™ąČ"‰$"&&÷ÁwfĚ`Ú‹ŠęŐż?O “˙čŃŰŻżN°X¬aŃŃ= ĚđHĺňQ±±ŰżújéäÉŔb±FŚŰ­wo—;*6vçúőK&Mzj7.¤Os<¶öö#ăâönŢĽh¦ýČ€śĹ÷ĂÖ­ ăăźÚccCC 3ÂĎ©K—Q±±‡vîśÇ´ëĺďŹaب¸¸Ă»wĎ‹Ť6›=26Ö'(Čdf0»{yŤŚŤýőŔąăĆ1í#ăă]==`dlě±C‡ćŚËŘŁÜ˝˝ 37—O@ŔČSGŹÎŽŠ‡;mš‹‹IFÄÄśINž5f cŹź9ÓąK—çlŮŮŮ&“©ŞŞŞ•ýáÇFٱ­PyđŕŃh¬­­meżwďžÁ`hޡӌ»wďęőú¶Â&++K§Óµ6wîÜŃjµĚÉŽ–ČČČhllÔh4­ě·oßnhhh+„CZ­¶•ýćÍ›Z­V§Óµ˛ß¸qYdkegn´]»uë´Íä”™™ mS©Ý»w:vś^ľ`ŁizË–-Ë—/gś9 ,°ŕ%‚ssŽ”<]â>Í@Ťxčtö ô ŚPšŰŮĽ±‡ŮÁ% ›ç&@€aÁ`X¶lÓ`ć̙͍µZmł`Z­V"‘Đ4={öl&ľŐü\.·ă}ŚAL&„ĐöîÝËăń0 [¸p!‡ŰłgĎţýű™Ň4Í1ł3ę…AŃÔćŰ[0„Ażf%˙«'ô[nmfa¬Iţ $MZ†śĎ#×hšfłYYY™ŃĎĎW,SE„ŃhĐëő~~~ÇŹź¸uëvxř Š˘ÓŇÎaćääDDŰ:l€Ă=~ …Ł'LčÖ Ç0s‹?r‘hâ¬YżüđC~v¶X"‰JHđ D ±xâś9‰űöä抭¬ĆNšä€Ě×±µ¶žôƉűöçç[IĄă¦Lq÷ö[©tňo$îŰWRXh-“ĹLťęćéI›ç±—˧̟ź¸o_YI‰Lˇť6ÍĹŐ•p°±™:~â?”?y"·±‰›>ÝĹŮą×ÉŢži_U^nco7}ş“ ŔÉÁaꂉ?üP]Qaëŕ0~Ć ¦6š9¸¸¸Lť?˙čŹ?ÖVUŮ;9ĹĎśi§Pşté2eţü_÷ﯫ©qtq?c†ť\nî”-†»§çäy󒨯«svs‹ź1ĂĆÚÚŕéí=éŤ7’T)•®ăgĚPXYuŔă0gÎńź~R«TîŢŢăgĚ‹Dß  ‰łgź8|XŁRyřúŽź1C&éÍů2aćĚ“żüŇŘĐŕ7}şµ@`ęŢ}üŚ)‰‰ÚĆFź  ¸iÓ¬ů|˝™/‹ŤaÝz÷ŽyýőÔ¤$˝V3uŞË%BűöŤ™2ĺtr˛^§ ęŢ}Ü”).×Ç{  ¬©I;~Üh4÷ę5q˘ÍfjÁ)kkĎž("˘˙°a\ÎTČăĆŤĂ0¬k×®­ěqqq|>?  •}„ R©Ô××·•}ҤIöööŢŢŢ­ěS§Nussóđđheź6mÚµk×ŕrKĚš5+==˝m9Ů9sćdff¶]+š7oŢýű÷mmm[Ů,X““ŁP(ZŮ/^śźźßěę4céŇĄĹĹĹmuÍ?ţńʞ˛2‘HÔĘľdÉ’ŞŞ*@ĐĘľhѢÚÚZ>źßĘ>ţ|µZýŇ˝ťÖî_ÚÉ“ĚOáŁFEQ\.÷Çډ‰yž”q4Mş»»˙Ç‚˘Š‹‹ÝÜÜźóňňBl6»K—.çŔ‚ÎC«mĐëőYg©T>äÜąó”ttذa`Ŕ€°Ë—/Ŕ‰ÇÜî¶ćv¨xŇ®ßw»Wqďéfd¬Í´MŕÁ˛{ńaî?|đđáC??żćßŰŰŰďŢ˝ŰŰŰ›ĎçGFFž?ŢĂĂăÖ­[Ě (‘H |||nÝşĹÜ}ÍŕóůöööąąąŢŢŢ<ݤ¤„Ů™››ëéé™——×<łX¬ŞŞŞ–ű[˘´´ôµ×^Ójµ,«˛˛’ .—ŰpÂqś  ĂŠ‹‹M&“——WVVV```çż,’$Y,‹Ĺެ.—nóż—®UŞć{`Că;Ăs§A)•J/ÉdĺĺĄöŢ :6›}ëćM‡ŰłwźŞĘ 𦠒¤H’"I‚ Čćź)ÇYE……FťÎVaĂÇŃöŰĄďWŕ|¸M!łsŞ««‰D;wîĘËË:t¨ťť­Á`ĽpábffćĚ™3||Ľ?ţřS‘H3Öh4~˙ýnooďŮłgĘd2­V[QQşŕŤă-ť?~ó Á¸đ4,c`­µµZ¨)ŔЦ/Y?q˘ľEH•Ó^ű–v#€±Ź5@ŻŔŔ7nůüsM‹IÓ^ű–ö–“‰5ŔÂůó|÷lßľ}îÜąmýó–ŢżĺgsýyěÍX»víĘ•+YmŽăîřvËěy Ş«*™óĚjŐô? ĂoÝĽ±2]ŰΖH@đţűﻹąőîÝű™ŹLÁĐ·oßVY t:]ßľ}+**@«Őóx<©TÚvż©XđüH$‘‘‘L’îěělkkë?şß˝{÷ňňň–“K·nÝjjjBBBž˙üůóZ­666ÖâXđŠCmTďµCkj±Ë_˘łk˛„­¦wÄo÷“ůH›•AµŁÄ4ÍÁ=== ——Üąs'!!ˇ˘˘BŻ×:tH.—×Őյͅp÷îÝČČȲ˛˛ź~úI(fee >ĽľľŢh4&&&ňůüëׯ‡……544 †3gÎX[[›űz˝žůmŹ=Ú•‹&“éćÍ›z˝žĹbőîÝűüůó,ÖK-Â<ޱâí?ú cë,Í‚çŐ˙@Ó4m2™äry\\ÜŕÁŤF#Žc"‘ČÖÖĂ0“ÉäăăłlŮ;*• !$—Ëlll‚ é?5ĄŽX`t(Řbcc333?ýôÓ/żüR.—wLŃněĽŮăxďŢ˝iš6W•Ĺ ^j‚#g±·g|W««!şžŮoĆXŻh_A…łYíz‚A 8I1¸™îîîS¦L©®®6Ť#GŽ€M›6µÚŘMÓ´——×”)SŞŞŞ"##ŔŰŰ{ęÔ©jµşůŻ‚‚‚^ýő††“É4xđŕ>ÂćÍ›çĚ™C’äرcoßľ ˙yĐ–IµŇüÖ|ą×Çđµ#Ö „I‘kÎ|Ř|†ŤŤ1“ IDAT±ż‰ŢP«­ea,‚",ăÍ‚çŠĐŔÄ80 sp°wqqĆ0DÓ@’¤Éd"I’¦Ëĺzyy2O1‚ ŚF#I’ć g[`X`Áź.Ř@*•ľóÎ;'NܱcÇŠ+:żŢ§Ńhţ˛EC ,řŻÔhj)&űřę'5šZÄB´p ř°˙![Xo¨kľu»·‹^ŻW«ŐÍ‚Ťń—.]ÚR›-^Ľ¸m†¦éwŢy§e3&1IKËňĺ˟õĄ-Z4dČşşşÝ»w§§§#„ĆŚÓŽ=ztËĐLdd$A/w… CŘýVĐ Lg‹ĎžĎżŔD@)ş š˛d‰´ŕąMÓMMÁ@¶{•$)ťŽhó‡ć2kX`X`Á˄٤Ű...ŁFŤÚ°aCŰü•X`A§AYq$O głá`ÔŹ2ľě™I2[‰źVqçÜcݶŮsĆSfiiiL•ääd ĂŽ;Ćĺ>Ýxüřń–‰’Nś8ń’÷CĐ4­Ô×)őJĄľNcÔŹ;&Š·ŮHĂ~¬5j,jÍ‚?,Ů^”eÍ ,°Ŕ‚żS°Ýľ}ű‡~ŘłgĎËĚ`4ii ŽŤOvłr3‘Ď>$ăĆŤ¶ůs_q‘>íFóI|.‹kqˇ-ř÷!BĐ´•÷Ź‚¦iË ›X`Ú~-_ľ|éŇĄ zÎ^KüŮĹă,°ŕ˙:ÔFőľŃ{MZŠ&{ŘőúYžMÓVVV/đ^ĎĚ9ŰQQQ‹Ĺ˙W®$ ´‹ŘĺǸýS~ž X–Ý×<ŹV¨­­¦0vó1¶? Ăh’¤„B‘´)eů‹AŔbł…"‘ěE“Â5ó`8.’H¤03a;<I¬­Ą0d+!+kki‹´ć/> dmmmŐąŻťqz¬Y¬N†˘  ’¶ČůţbŔ¬¬@'żt @#•B˛¦<ő/|qÄÖÖ†YwÎpÄ ŽăVĐ©é ‹Ylv'ë řB!›ÍîdÄ|>źĂăuňúH¸<ŹĎ—™óÂź›äé˙“+€Yđ_*Řhš^·n]—.]&OžÜ¶<\[µ&‹5MKO©T¶­7g4Gx®ňqŤ®ĆDšşŮvă Î3«<żđ)P„І ć̙Ӷ:d[]wüřqÁĐIÁöő×_×ŐŐ1?“$ůńÇ˙©9‡Ś¤1ŢoüÝ!wq„[ŇŤXđĽRź˘¬­Ą:­V™ź‹ö˘keH$*lmŹěÝ[Ro2ľ¸DâńůEyy?íÚ•uófgN"đřüęňňďżůćwOĎÎOą<žZĄÚüÉ'¶/¦fźş’\®AŻ˙÷ŞUkëÎäha±Ů$I~´lYł“ú‚ÚĂhš^˝r%†uĆ劢€¦ß[˝š¦:ŁCÁh0$ą|ÍšÎ|é!ŤJeÔë—}ô‘Ń`čĚĹ©®¨Đ¨TË>ţؠ׿0ŽăĹůůŐ˙üä˝îĹĄ(‹Ĺzt÷nq~~'yŘÎí«W‹ňň:ÉĂár/ť>­Q«;y}¸<Ţő 8Î;öÂß—Ç»yń"óóÝ»wŻ]»¦ŐjÁ‚˙2`FunŠčH°™L¦ôôôýű÷·-"Ţî4áďďźššĹH|ŤFsîÜąVÔ-ű*-° %„láWUB¶prŔ$ aMýIo÷Ö[oMš4©cÁ†ĘĘĘÂ0¬“~ ĽóÎ;îîî A}ôŃźëym ńľă „Đźw-ř˙Š˘ärâř‹…ąi’${ôč-W(N¦¤–vćLŽauŐŐ·®\Éľ{·“<µúęŮłׯӝăŃëtçSR8ÜNm3Ć0Ś0™Î;Ćb±:ĹMQ)‰‰†u†‡‰{˙é'„Ý ćÚ&8ĐÉÎ0{kýńÇÎ|é€ ‚ řˇ3Ţ!0 zť.qß>˛3<éµÚµú—˝{;Ă!Ô ŃhTŞÎó¨ëëuZmgy0LYSCD'݆aµ••Ăęjj^řűÂ1¬ş©riiiVV–ľŇ‚? ˇ?Q°ńůü 6<çQÇcbb6lŘŕŕŕŕďďO’ä­[·¶mŰÖ˛ćşÉdŇjµĚěf2™,âÍ h %\1đ0X|lI€" §}Źg* “ÉÔě±ŮlfÍ­ŮČX[Ś16o“‰D:ťŽ Ç[ýUË­C† ˇ(Şó ]BŹ?îĽđ{~(őĘ;{,«ţÍ:#i´Ś±WńŃŘbóęp0ŹÇá±JEQĘÚşU_­[4^c':/ŻÄÇńřřx•Jµzőꊊ ĂśťťgĚ1iŇ$¦AccŁ··7‡Ă©««óđđ‹Ĺ™™™–ďĎ‚WŢłDcPƉş5ý¦«ÄµăD‘#GŽĚČČ•JU]]-“É oßľyyy uuu‰¤GŹYYY˝{÷ÎĚĚÔh4Bˇ0((¨ˇˇ!44T«Ő–””ŘÚÚ@pppEE…V«mlld9\Ľx±[·nGĺźóDEQŤ`C€x,^ŕ®®€?ý§et˝šŔ0 !„"›Ć`˘(0ł-ǰŇқ޺ő@¦xGÇ++ËËËK”ĘZfą¦3B‚nşż¨ÎńPÍ7ęKęĎKŕˇiš˘ţ‹úĂđt.2E7ý·“ig•T§?3ożž—r‘_b:?©#§óąóß;ĹđtîfoîLÓínÁ˙s´#ŘFŤő‡Á¬­­'Lŕëë«R©B2™,44´ůđ‡ĂYłf ‹Ĺ … Íéż-°ŕMÓV\+ĂÇöŹůaұÉ%ő%CÚFí씹?Gr’¸Đ€ Ýé7##cáÂ…®®®ˇĄK—n۶mőęŐS¦L8Ž/X°`ďŢ˝%%%ýű÷ź>}şH$ŠŹŹ?tčĐš5k¦L™˛|ůr‘HÄěŠ\°`Áüůóą\.ŽăQQQ‡˛˛˛zř𡿿?‹ĹęxęGŤ?^§ÓŤĆÓ§OŔôéÓ÷îݧŃhRSSźÎ,,Ö¸qăôz}JJĘźŞÖÄQ|ŇÄre9“đÁd4Y4Ű+Ç‹‹ óó1oNąO’„­­ťÂĆĆÜđ1Ť,6›ËĺľđI ’$IESdçňOOuÍKŕŠ$_BČ—Á$E‘ťK:BM3ýéü–H’$Qç*ŽÁôŞ“+lĚ9ĂNňĐÔËŕA/‰‡ H’¦é—ŔCQ/…‡™^Bhš~7)EÓTçúĂXŰ«+Ř@"ůĂůx\]]]]]Űý›Í~ăŤ7Zů¬–"ÚĽšŕ˛¸‡łŹÔęjBŽ"G a@ŤxčJö•-[ݬÜt„nzĎiĚŻÚzĄ‹/¶··€… ®[·năĆŤeee̢ټyó6lŘ ‰L&Ó’%Kp?sćŚÁ`?~ü¬Ył–.]* žm۶iµZ&ŞręÔ)‹uäČ‘yóć1·gÇGÝ@,3şnçÎťsćĚŮ·o_÷îÝI’dłŮ»víš={6MÓ›6m˘iÇńďż˙~ĆŚ/qµ !$d?ý Mmľ˝őhÖŻŔŔ>ż×<‹ÇÂXLr ^ťPź/PŘŘb8Ţě”Ó<Ź˘) µźó†É?ĆJ‚ă8A̲žĺ+°Ŕ ,°ŕ/l6,Ď6 ^Y٢÷/~Wž÷4%0çin`š¦‘}vás  0Ěw(ŽáíŢ;Ť†l"‘YĐV«ŐŚ`ł˛˛ÂqĽ±±ńÔ©S8ŽÓ4}čСfw¶ľľľY° •JĹçóiš>räÄÇÇ?xđ ĽĽś˘¨;wîôîÝ»űôË/ż¤išÇăYYYÍ1C ¬ZµŞˇˇéáŚ3üýýW­ZĄV«Ë믿ţMÓ÷kď3>ą‰2ţăÄ[Д˖…±VôYžY•‰ć&éB[jd˝2 IŇÉŮŮŰׯe¤ÇńĘňňŠň2Śc6IéSiGżČŃÍ64ˇ¦Ł©gŮ;čŢ-OËoÎţ7ň4Ď8ĎÉÓnű—Îóś»ň̵˙»x°¤e{sv Ďßx“Z`lX`ÁK"ޏíÔpˇn®â„a8ŮáđL·!¤V«ĄRéó8 Ím¬¬¬B4M÷íŰ·®®N*•šű+OOOŤFĂü-BČ`0ÔÖÖ6ő3™LYYYÍ~óKĐ4ŮcoŻ˙´-*ŹHçvoh>‹_±¨¬ăü‡Ăą›™ůŕţÝ–ĺµH’tuíâčěü}°żTź>wí2 ŕŢíŰK§NěďÝ·ďO»w›ŚF¬Cž;7n,LHäď?¶_ż_öď'Iđn_»6„0˙qýű=x˘¨ĽXŔÍK—ćÄƆůůņ…;|qOy×/\=n\źßřAN$&˘˝a.Ŕ•´´cĆ„ůůM?•śŚ7Ů/ť93môč0?ż‰C‡ž9~Ľă*€s))S""Âüü&Źq.%…™ĽŘgOžś˘Éh<´kWtßľýý—NťzďÎ>`4ěŘŐ§Ď`˙Lźţ +«@ŻŐîÝşutďŢáËfĎÎľź€hwoÚŮ«Wx@Ŕň7ŢČ}řßáEnP«·ýő¨=†®\´(?7—ŔP××oűę«‘Ý» |É’ÂĽĽ®@Y[»ůÓO#BC‡­}çť’ÂB. ¶şú›Ź?24(čăţł´¸Űá੪¨X·zőđn݆uíúĹŞUee\@eYŮ—ďż?<8xxpđż?ř ˛ĽśŰá`.-)ůtĹŠa]»ŽčÖmĂGŐTWs¸OŠŠ>^¶lh×®#BB6~ň‰˛¦ĆR$űŐ„e…Í ţ:čLÚĺ}ţYŃX!Ě^h·öĘÇĄęR@€Ń ôüţó]ÄNZBg/´')˛]Ż4::ÚÎÎN«ŐŽ5 věŘńŻý‹ÉŃ˙ŻýËĆƦ®®®mŃŹďľűnٲe&“iĆm۶í˙řI’4MGFF˛ŮěŕŕŕfÁ3lذę\_»v-<<VŻ^ݬ ŤF#«é?‹Ĺš;wîŽ;žúÂ/¸vŃ‘bS‹XS«g  €ěÔp ţďÇńÚęjĄRů›oišĹbµ»»ř? m«Yđů| ĂM&ŁÁ`@á8Îĺr€˘HÁФŮč¶nŤZ}hǎꊊđČH’ .ť>­°ł‹ž4©^«=°}{]uőŃŁM&Óů”‡Q±±‡nĎÁ­P*÷űmŁF3t̓њ”dçč8|ěXĄZ˝oëV˝N7tĚŁÁ’hďä4xÔ(6›M·çp—ŐÔěŮ´‰˘¨áŃŃ˝>ůŕAgç#F”ÖÖî޸aŘđčh˝N÷ëŹ?:şşö4¨Ý‚i@Ieĺ÷ß|Ăĺó‡GGë´ÚĂ»w;wéŇsŔ€âĘĘ]6D˘ŃŃ:­ö§ť;ť»t íÓkoÁ KKw®_o-“Ť7NŰĐp`Ű6Ww÷®={ĽgO×=x|~MUŐ®őëťÖŻ·±µĄÚ»Č&‚¸~áÂŻ„ôéĂĺńŞĘËwóŤÓW_I¤Ň«çÎ%:Ú·/‡Ç«*+ŰłqŁĂ_Čäňvyô&ÓĹ3gR{öëÇćp*JKزeůgź E˘ §NťNNîŐż?›Ă)/)Ů˙í·oŻ]kmmÝ.ŹÖhL;qâ|JJź°0śĹ*+.>řÝwo®YĂĺńÎ;véôéľă8ţ¤°đĐŽ‹W­‹ĹT{°AŻ?uô荋ű…‡c8^śźx÷î+Vŕ,ÖożürëĘ•ţC‡"„ŠňňŽěÝ;çí·EBa»Ţ‹`łŔ :l„nn·98b†Vßçb !DiW˙÷ú®pµv€G·[“M§Ó­Ył†9ĂƸłgĎ>yňdQQQccă·ß~ qqq­Ö»hš~ăŤ7ĆŚ“——÷ŕÁ„ĐĽyó"##«««u:Ý˝{÷Z6ŽŠŠ2 -‹łµBttôĎ?˙ĚçóĎž=űÔĂh‘6ťq|ďßżäČÇ1 ‹xąůý1„…űfŇHĐ4•–¶yĂ6:h´ÖÔČĹą–ňŮŻBZmcue%ÎÂ[ŽFkk©X"~–`Ł[†B†effćççuéâ jµ://Ż˘˘!ĚŐŐĹÝÝťĂá¶§×€qýú˝Ű·Ł¦Ěž­3™>|óÍK§Ożž÷čŃýŚŚ¸iÓ&Nź®3W/^|155´wowʶ…ÎŘ7.^|t÷îë ÄLś¨ŃéVΛw>%Ą÷Ŕ·®^ÍąÖ›oFĹĆŞµÚwçĚ9÷Űo]{ötttl¨ŕ\NKËĎÎ^´reDd¤RŁY6cĆŮ“'»÷ëwĺ÷ß rsßü׿†ŤQ§Vż=mZÚńă!!rąśnŻ?çSRŠ Ţýěł°AŞ”Ę7§L9sěXpŻ^çSRJ‹ŠV}őU˙ţý+kk—Nžüű±c~]»ŠÄbş=ź#íĉŠŇŇ…ď˝×«gĎ˛ŞŞ% §““BB~?~ĽŞĽüÍŐ«»‡†>©¨X’p:)ÉËߟ۞oŠśNN®«®~÷óĎ»•–.ž8ńtR’O`ŕé¤$emíűëÖúůĺ—”0<žľľ¨=‰R“’4*ŐÜeË|==s –Nšt:9ůŤeËR“’5šyË—{»»gçĺ˝9yňéääąożM›E©żţjĐéľ÷ž»‹ËýGŹŢž6íLrňô%KRýŐh4.Zą˛‹“ÓÝű÷˙9sć™ääY‹·U"L¦Ô¤$Š˘–~đ“ťÝ파•ó楝81qÖ¬ÓII€ĐŇŐ«mmo¦§°páŮ'^ź;·}¤ŐžINćp8˙řđC;™ěňĺËżýö…S§FOpćŘ1ź˙ö‡ÚHĄÎź˙|ĹŠ §N%Ľţşˇ=µJőűńă"‰äťŹ>’I$gRS7¬Ys9-mĐČ‘i'NXIĄË>ůD*ť:yró'ź\IK‹‰Ź7´'HꪫĎýö›ÂÎnů§źŠ‚c‰‰ßoŘpóâĹľ}ϧ¤Ř::®řě3źô§ź~ŘşőćĹ‹ŁŁ˘ôíF1ž<ąšęěćöî_đ9śźöîýeßľĚ7Ü}|.ť9ăęéůŢ_đŘěwîL>t(ăúőˇĂ†Úă)ÎĎż’–ćđŢ—_rpüű͛ӎ™)ł±ązö¬o×®+>űŚ…a;ÖŻżtúôýŚŚÚĚŹ>ĽqáB×=ŢZł!´ůłĎŇ/_‹@ÝĽt©[Ż^K?ř€ظv퍋ű„…őčŮÓŘŢÍőŕÎťŰWŻöärąL;;»VoJÓôńăÇ>|ČÄiš>yňäÍ›7[©5HNNnŢcŮ.’’’.\}ńâE°±±i]Ëĺr‚ ®\ą2{öěI“&ĹĆƦ¤¤°X/30„cřoń'OŚ?vbü±¤Ř_…|aó®46ĆŢąűäř‰1ż(“eĽ˝: L&Ooź¨ŘQc˘›_Ń1q^ŢŢ„©ă‘€dúͲŤ9şcÇÎńăăOž<ÁăńhšÎȸóŐWë–.}ó­·ŢÚ˛ek^^žą’il€«gĎvíŃcxt4±ŮÓ-ҨեEE×ÎťëŢ·ď1c@ÄáL_˛DY[[\PĐî ŕ©Sý‡ ‹ ¬řüŮo˝UVRRSYy15uPDD˙aĂhk`Î;ďççW–•afx~?v,"&¦OX ‹ßXľ<űŢ=M}ýď'NŚŽŹď5` —HćŻXq˙ÎťúÚZd&¸›š”÷úë!}úlĄŇ…ď˝—qíš^§KMJš0sfpŻ^&;ą|áĘ•7/]jlhh—HILśş`A`H ŔÁÖvŃĘ•—˙ť S‰‰Ó-ň68ŮŰ/ZąňBjŞÉhDf|—”ÄÄ9o˝ĺ`pqrZ´reÚ‰4M§$&ľ±l™§źźŔŐĹeá{ďť9v¬íľfMręčŃ+V¸{zÜÜÝĽűG ő×_ľű®›»»ŔÝÓsţŠ)‰‰ć†EQż?ľxŐ*€§źßÜwŢ9ůË/4Mź=yrÉŞUÎNNFꀀŮo˝őŰ/żŕf:c4/Ą¦.y˙};;€pđ´Ĺ‹;r„ É+iiKV­r°µ5†„LY°ŕä/ż°ĚđhÓ/_^Ľj•­LfîŐ+~Ö¬”ŁG z}Ƶk‹V®´‘JM!}úÄL›–rô¨9U]ÝĂ;wľű®\"!z 0:>ţ̱c *Uν{ V¬‰D$@ź°°ÓÉÉl3_VUyyq~ţË–Y 4@˙ˇCĂ""ÎĄ¤ÔVU••”Ě}űm źO„EDô2¤yWjŰÁó¤°°ľ¶vć›oŠ82zthßľWŇŇĘKJÔęK–Ůl0lěŘ®=z\ţýwŽžĽGŹH’ś2ožÇ1€Qqqž~~·Ż^-ČÉÁp|ňÜą| cŚ™8ŃŐÓ3ýŇ%¶™›âţť;"±8~ćLBl€)Svv÷nß~t÷®T.Źť>ť Ŕť6ÍZ&ËJO7Ç“qíš“«ëŘI“X< ›8{6›ĂÉ}řđÎŤn^^c&LŔř8>iî\„Pö˝{–Ĺ‹`łŔ ţĐ<śËl†-źäfĺf"źˇ1t:]+·ŁŐ&s{~žłŮs"''§şş˛łłqôčŻ)ž““ìÎĺçç—––VUUý WŽÖ:ćEPDúôб4† ď»ˇ#t–öJÍádÝÉŘąmëŢ];š_;ľÝ’y'ÍéđÄÇÓŐüâńx‡˘iş{÷îE!„ĺççďÚµËŮŮ)9ů×T©”¨®®Â0Ôî3µ´¨ČZ.—*@¸űř †µş¬¤Dfkk-“!ŔÓ×WŻŐjęëÍ ’’‚[GG±•ÓŢ+  A­Öiµ%öÎÎ"±±űŞëëµfP”—çěćĆ qŔŻk׺šŁÁPôř±«‡ŹĎj®­ŞŇëőć„VAN޻ʇËeÝşU–•‘Q›ëáçÇfľkń IDATł{`HHĹ“'&3•0€üělď€ Çź¶ďŢ˝´¨˘¨üśź  „aŚ=¨{÷Ң"ŇLÝsźťíĚR ¨GŹâü| éüś˙ŕ` i6 еGŹ˘ĽĽ6fää„„PLű îÝ ssźÚCCI6Ô˝{An.2;-Ń…Ź„„0í 4´0'ŠZŘi€€‚śs<I0íYĂüşv-ČÍĄ)ęIaa@HŔŔpÜ7(¨ 'Çśg2™ĘJJü»ucxŘl¶·żan.AĄĄţÁÁ ‡Ăńôő-ĚÍĹĚ\d˝^_]Yé۵+€đx<7/ŻâĽ<ŁÁP[UĺÄŘů«‡GQ^ž9!Şmh¨Ż«ó 0ˇXěčęú¤°PŻŐŞëë=ýýI ’H\\J ĚőG­Ri=||öV2™ŤťŁÖô:ť›·73\¤rąÜÖ¶¬¸33•µµ„ÉäęéÉEÓšjŢ z˝ÚĂ,ýö[–e5žžťŽűĽÜ©ëKżý4滋ôzŤ‡EÓËćĎÇ4zťXÖd0h<=ťNç˛ůó „ÔZ­ˇ˛˛ÚXe4jÔj«Í¶báB!•Vk¨¬|Ä+•fłyĺâĹB„TM÷ĂĐ´ĹdŇČdzᇥKĹ)ÔjNÇ2ŚĄŞJăî^QYąfůr †)U*NçĘ@Ňe5›5IiiéşU«Ü0L¦TőzšalV«F,.**úiőj)†É Ł‹Ů śN‡Í¦ óňň6­_/Ă0w™Ěd0Pĺ´Ű5$™ťť˝őçźĺć&•š WŤÂi·SN§Z HżsgÇÖ­ »ąU™LN‡¦( AÜşys÷¶mJ ‰ĹUFŁ+»ÍƲ¬ÇŻ^ľ|`Ď%† …BsU•Ýf–UăxjrňáýűUF’¤ŮdrĄcµX0 ScŘů3gN=ŞÂq‚ ¬‹ÍjĹq\…agNž>b±¸^ $"âŢ­[fł™;BňZJŠŻż?!„DDÜ˝yÓj6siý®]şä×´©«­ @hdäť´4»ÍĆé\˝x1 Y3 ÇC##o]˝ę°Űą¨W/^ Á]¤,bšGEÝHMĄśNkµNpX y=%…¦¨ľśţ™–śL3Ś€aŮ«/†DFÖđ ËZ†I»t)$2’uí´š…‡_˝x‘°Đu-994* ¸l €€r:ݧ¦†FFş268A††¦]şÄé8Ž›W®„FFbЬٵjŢnłÝNK ŤŠb]¤&M›^KNîtO‹%ýúő\ đ ¸–’Âńł9ăÖ­Ƶ±ńňő˝‘š v“Áťž.‰´ŢŢ7/_ćxŁÁ›‘Ń,,Ě•ŽÔÝ]ĄŃÜJKcěúŠŠ‚Üܦˇˇ77…JuűÚ5ŔPY^^x˙~`h(í˘ňČU*7w÷»7n0€‡%%ĄEEţAA2ą\,‘dÜĽÉńeEEKJü]é¨=< ë΀(.(0TVúřű+5„aŮwďr|ŃýűFÁ7 Ŕ•އ·7MQyYY4ź“cµZ=}|´^^»ý~v6@ÜĎÎvŘí^ľľŚ ź&MĚUUňň¸ň9™™,ËŞµZo??“ŃXźO0YwďbqKšOš¦ťNgÝřäçăëéî\đEý…řşĎíYy§ÓétľôoŘxđř“Ŕ H¸}Pˇ©P źěLţŘÝ4ĽS«m۶űöíóńńů߲«WŻfdddggűűűżěŽ âVëŰ´ßСŰ/Ý€Ż\»©G 3™ŚEE… ňóórsłłłîeŢ˸ű°ĽĽásŘPő I’»ví6›­‰‰C›4i‚ă‚ „B!AÓ”ŃhěׯoLLKÁŔ˛€ăx˝Ű´śÝúö˝uőęţß~s2ŚľŞjíâĹrĄ˛IÓ¦]{÷NKN>¸s'Ų:ŁqÍÂ…Ź€fÍęÝ4ć8đ‰Çöíc*ôúU˙ýo“Ŕ@­—WŻN>|ňŔŕaeĺĘŻżjŢÜËĎŹqˇźxhçÎsÇŽ±ĄĺĺËçÍ‹‰‘)•ý÷ýúëů'X€’˛˛Ą_~٢];Ą‹Ĺ'Ŕ€QŁ~۰!őěYPT\ĽäóĎŰuë&–HڵuíÚË. €ÂÂÂ%źŢ©gOW’}ú1ţµ×^S(.\xŚź8q˘R©LMM}Ś3fŚJĄşvíÚcü#ÔjőíŰ·㇠˘Őj333ă ŕáá‘““óß·o_OOĎ‚‚‚Çř^˝zy{{?ĆwďŢÝÇǧnv´Îť;űůůUÖŮkÚľ}{ŁŃXw¸`v±GńE‰äÁăĎA•Ă@–*ËäCS~˛U.”;hG˝ńĆ<°Z­‡ …Ó§O_ąrĺ´iÓŇÓÓŹ?ÎĹq1ýW®\ ~á+lŹm0¨wżAVVVDDw=wîÜŽá~!nMJJ“öŚÎ€€¸\Éă/š¦)Š˘išˇ]24Í0ĚSlidY–!üÖ­[,++űţűUˇ7nž?ˇeË>>>fłEŻ×©Ő*(,,Ä0$•ş1 ]wŇÄ ŐşuźÁĎ?~îŘ1`YB >q˘J«•)˝ :sčĐ©eAüđáŢŢ®ŚVëNťz pdçÎĂ;v°,+ ÉřaĂd E«Ž{%$ضm˙Żż˛,+‰ú%&*]DŁ9ÚwďżcÆí?ýIJ¬Lˇč—(–H:tëÖŁ_żm?ţřëÚµŔ˛*Ť¦ďСR™Ě•Nç^˝RĎžýyĺĘ Ë—Ëzűúö:T@’]zőJ>}zýŇĄë–,–ő č3dH"qeŘş÷ë—röěóçŻúď 04´ĎŕÁŽ÷č×/ĺôé•ß|łâ«Ż YxxďÁ]…h2± )gĎ.™;—Ű7hB¨ç€)gĎ.úäîۉnÝ:nŕ@W=! 7p`ęŮł˙ý׿¸Ţ,¦C‡^@Ü A©çÎ}={6Ç·éÜągBëÚ°ő4čĘ… _Ľű.Wľ}·n±ńńˇ>§]ĽřŮŰos}xÇ=zÄÇ»Z!!‚>C†\KIůdćLŔę×­OÇűzăňĺŹfĚŕř®˝{wíÝŰ•a‰Ĺýď\»öŻ7ŢŕĘwďׯSĎž$IöMLLżqăĂÉ“ąŰîß©gO§‹‡,•ÉâłîÜůç¤I\ůž m»vK$ń‰‰9ď˝ň ÇÇ жkWĘ…ŽRىOLüaţüL€ŞWËöíIˇ0~ذµ‹˝=nÇ÷<8¦CĘ…K÷đöŽ6lòełĆŚĂúCý‡ űyĺĘ™II5|TëÖ®t|⇠ۺvíô‘#eqď—Ž0,~ذßÖŻź6bD étQ™›†„Ä'&îŢ´ię°a\ůţ#F@żˇC÷ýú뉉?0))04”rm ű zd×®ÉC†Ëâ1lÂo??źľC†ß·Źă ‚ńę«~M›>ĄaKOO·Ůl%%%ŹńwîܱŮl\¶çÚ¸uë–Őj­Ë߼yÓb±TTT<Ć_ż~Ýb±čę$żIKK3›Íá1ţęŐ«UUUu Ď•+WL&SMśy ._ľl0ꡔ”˝^_7~'99Ůb±X­Ź§‰ľxń"—á©.Ž:)m9«Yw®9--­^ţĆŤđÇ3i_ĘĽ$˙šçÁăX1!v¸†Mm9Uî&g‰ĐůŚ SY)«;é.HB®ĎÄb±›››JĄúá‡`ýúőźţąN§#IrĺĘ•\˙…Ú˝{÷¸qă^ěh5¦qÍš5+W®\¶l÷ĎŤ7ŔęŐ«9ţ¸ÝnĆŚ/5,SDV¤­Üq}'Őé´ßŹýwâ҆`†aµŻžĆ®±,ëp8˘˘"{ôčîî.u84MsĽÓé k^\\|őęUŠr:ŽS§NcćëëCQTÝĘƸ …FŤjß­›H$’ĘdGŽěĐŁ‡!)IJJjŰĄ‹P(t—ÉŤÝ®kWĂ\… ĘE˘ˇăĆĹtč@ …2…bč¸q­:vÄä"Qâ„ -۵#IR®P$ŽÓľ˝ŔµŽR"ńĘ+‘­Z HRˇRŤxőŐ¨Ö­1Ą›ŰČI“"Z¶¤B­9iRdL áÚŘhÜÝ“^=42R (µÚŃ“'7ŹŠB™lôäÉ!áá„@ ŇjÇL™‰ąŢ{ćˇPŚ}㍠B ĐxxŚ›:5(4x*•c§NmÚ¬—ßbü´iÁÁ čxk4ă¦Mó $OźńÓ§ű€ŹV;~Ú4ż¦M ŔË×wÂŚMš4i řzyŤź>ÝÇßźËĂ>qĆ _oođóń™0}ş·ź!ř4i2aĆ /ŻtüýýÇO›ćéăC~M›N1ĂK«€¦M›Ž«ć›Žź>Ý«ľŁÉŤÉ jÖlÜÔ©\f—€qÓ¦i•JĐ,4těoh<= 04těÔ©Z{´89zňd•VKÍ""ĆL™˘vwGaŃŃIŻż®ŇhAHdäÉ“ŐR©Ë=lŃŞŐČI“¸ýfá-ZŚzí5ĄD‚D·i3â•WäJĄ€$#bbFľúŞ˛&[Fť/K€a1:$N W($٢mŰa&ČE"ˇÖť: ;V&—“BaLűö‰ăÇËE"—+8Ţľk×IIî2™P(lÓĄË ŃŁĄ$)@¨}÷îFŽtww …íşu8j””$]†zâx縸řÄD7©T$węŮł˙°ab‚bX×Ţ˝űâćć&‹»ÄĹő:ÔM pą‡Ť băăă”H$b‰¤G||ÜŔ"áxŻz&$H$±›[Ď„„^ ÂU#uú Ü­O±X,‘Jű Ü˝o_Ăܢ_bb—¸8‘Xě&•ö:´kďŢ"Ę—ÜŕÁ˘ŁŁăÂĂĂăGŚ‘ĐĽyóÇř¤¤¤4kÖě1~ěر |Śź0aÂŔýýýă_yĺ•Aůúú>ĆżöÚkööö~Śź¶ŻĘÓ·˛ň!BH$q•d2Ĺ«ŻľŇĽyó÷ßďĆŤ›óç/ÉdÆ%:Ž5k~lÖ,xňä×T*•Ĺb)))śţĆô3ßš6mZMĄÁČę'·iŤă…x5oŻeř”q]»ľňć›#“’lµt¸ňlµWž ëă@Đ.2ňłďľ‹Ť‹«™7vUľ9@źßş}űZÄÄPµt„·ăČYK§^ÜšĘĺ‡nŢlâď_3zćN®)ďxb?’ĽRVV;“ÄsčM0ěžĂQ{>«vy;€ł/ŕŇ :jń@ST°@PŔţˇŁ!ČúĘ»âąĹZiµŰ3ęبZSď…}"#óŚĆŞZâ‚úĘ#x4»UW‡¸uăĆÄřřŚ˘"C-ťšň4€Ł>ťÚk’$ Ăť;w ¸»»×¬eI$“Éô’ 8Ž‹ĹUUU‰$<<Ü`0Čd2‘Hd±XATTÔJţÂ×R¸ Ц:üüČ­‰“).Q …â—Ůx<5e‰´Z­5±4!‡ĂiµÚĚfłźźďřńăÖ¬Yűꫯá8Ţ·oźáĂ•Je˝+lP=Ž´şŕź) Ź«ňT­ÁńÓŔUů?KÇůGóóDţŻ˘ó9|"˙RuXĺ9SjťzË˙‰:6[žqÁ»óât¬ĎÂ7ĐŘ­ĎÂ?ý‹ňpíęďţťůްńŕńżduÚŔ NĚůhę¬ö ‡˘¸‰n–­ă™Ĺ|E IDATMBBÂW_}ĺĺĺĺççÍL»ąą=V¬wďŢ۶m«uđ¶ÜŢŚöí«ŞŞ0 łŮlŕt:Ź=Ęp+ŤEť8qB ŕ8Ţľ}ű‹/ľŔŕLЎbéĹe’`Yčߣ“qöůµźť¶ qŃŃQ‡ůt‘<ž¦Mţ~ {-LĆYłfŠDBn­µyóĐ÷Ţ{GŻ7 „4µ‡‡EQ,B;’––Ć]Ľ äĺĺ5iҤ˛˛˛´´ÔÓÓŕád\zôÜÜ\___‡ĂAQÔ‚y’5ŽđkŻ^ĺ´#|E$T9NâdÖ”Lť]‡5|˘¸¬ńőý4oY~…Ť¶žtşă™5©k@ Ël»ýŰú„uvÚÎW0O¨H ŁP(-seNÖs7„››Dăá±ăçź‹ňď;Ďo‘Dbq~vö¶uën§ĄQNgctĘKJÖ/]z*$„¦žßj Ĺb“Á°âëŻ=˝˝źĎÍ>J …v›mÁ'źČŠĆ„MÓófĎŠĹĐ ĂX–ýěăŹ1¬Qy‰†–ýčłĎX¦1>ěv;MÓ˙úâ‹Ć|é!ŁÁŕ°ŰgĎ›ç°ŰópĘŠ‹MĂ쯾˛ŰžÎ ÇńűŮŮ奥~ýµÍjmĚ—ž~ýzANN#u$yĺüůĽěěFęBá™#G˙|„"QęŮł¤PřI:žWG$_>wŽ»ľuëVrr˛Őj˙Ç€aŘűO@­Q?±Wă (†jçŐNFĘ,”eqŻE2Rö˘<B(--Ífł1 Óąsç—wÚ˙T9ŞVôYzľđ\zŮ]Ŕ8ż{ŤÇS¸Uj äçç=÷žOš¦Ú´iŻÖhö<śźťŐ±;†ăĺĺ)gÎÜNKk¤ŽIŻ?{ôhęąsŤ16Ç­Ëń˝{Iˇ°Q:F9ť‡vě ˘‘:,ĂěݲĂńĆčB°săĆFvdÜl˙é§FŢ Ă0,Ën[·®QĆ!Š˘śNçÖµk©ăp8lVë–µkYšnŚŽÍj5 [Ö¬aˇ0Ě\UőBtLÍjmĽŽľ˛’¦¨F>„ă•eeĂĘŠ‹źűűÂpĽ˘¬Ś».((HKKłŰů™Ę˙s@=y‹eĂ#˘ęü&äÜ»Ç6<ţd¦•}—? ŽôbW„† RPPyyyš)Ą¨ÇލË4,°UNó™1§µK= śá"ľvńxĘ)MQBˇđy[Mă,Ëč+*?Z°`ć´ićFÜŽ g·n“ŢzkÔČ‘ÖĆé´ŠŚü|ůňž±±Ť ‰”„úůýtđ`‹ččF†D6‘Ëw^ĽŘÄ×·‘!‘ŢBá‘[·äî’!|0ělNѸą' )BÉ99Ť ‰DFłą…Ry5;»‘!‘ŠŠâÂÂndg›÷pnŢľ=ľoß[YY†Fč§Ďś™3mÚµ;wtŤĐü¶}űš… Oź?ß7€ßęŕÁť»wëW™?›;·(?őš5†Ć5®YłfIe˛ŻćÍ3>Ż`úôéż˙úôéóúëŻóťú˙MĚť;÷‰¦nŰÖÍu­{ŰvíyĂĆÇź )ĽcČťŠtłÓ|fĚ)™˙‹ňlmÚ´ůĺ—_ĽĽĽD"Q||ü±cÇĽ˝˝˙”Ď~çÎťÚGĽ˝˝ËËË_Ćß"qňŢ™źn„ÇSǰÂÂÚö]Z´éBÓĎcI0 /--.))¨ÔU42ľŽýö‡ĂqîĚٶmÚT9ŞöŤŘŰâÇ–·Ęnł RłclĘk—˘µŃÜ"›«7Drr2g0Ľ˝˝oܸáďďß©S§ĚĚĚŹ”””+W®äçç@AAÁËŘŔÖ˛eËŞŞ*îŚl@a±X˘ŁŁ- EQ8ŽCť…ľ—‘qh–îđs'W[b–A€ěv{LLëg:š¦ćnőzCTT‹g»šnҤɽ{&“‰oŃ÷ĺs¬K#„Řš)QĂŻšk¶>ţ)-%Ş#Ň˙|:čéŚ_ĺ±ę˙ežeŕŽęH^ç)uč§ű˛ę-Źj#Ć>‹Ô©<ĎŞ\č Fë gÔA/G§¦}!םŔÓ|.Wť>ň˙‡(ČżOÓ4C˙ŽşéLů}ŇÇöďox5ź8uřđřţýc#"ĆĆÇź:| Kś11ß|ôQIQ‘€(-.ţöăŹűĆÄô‰‰™˙ź˙”•”¬ĚEó>ü°OË–ýZµZüĹĺĺ$€ŕÁýű_|đAď–-űµn˝ô«Ż*+*řC˛˙˙SęV~¸ŐŻA†e¶gü¶ćú§ýyR­ „žw™…üĽç_Ő®±Ź¶ě‹Ĺb˙Ă;ŃétŘív„ŽăBˇk• CŰíöG;QëT ŕˇÉ´eíÚŇÂÂn}úPuöČŤ§ç ŃŁ ËćŐ«–•uëŰ—r:O8ŕáĺŐ/1‘$I¶ľr©^żńűďMCŹ~ýÇ‘]»<}|z¬3^±ÂRUŐ#>Ţa·ÜľÝË×·Gż~ ^ť˘ŠŠź–-ŁśÎŘřx»Í¶gófo?ż®}úUV®_ş”eŮŘţýí6ŰÎŤ}üý;tďND˝:ee?.YB±ýű۬ÖmëÖů´éŇĄ ¬ěÇĹ‹…"QŻ„«ŮĽuÍż€€öí±úž1€űEEk/v—Éz `1›YµĘ/00şM›ĽÖ,Z¤P*{ `©ŞúyĹŠ&a-ZÔ€rîß_»h‘ĆÓ3¨ysłÉôÓŇĄţAAˇ‘‘Yyyk-ňôń  3›LëżűÎ?((8,ĚŐ”JfVÖÚĹ‹}ýýCŁ˘ŞŚĆµ‹ű5 ÉĚĚ\»d‰_@@óčh“Á°fѢ&AAÁÁ®úĆôôôőK—GÄÄőú5 úůÜąuë§eËCB"[µâř&ľţţlýý“~ýúĆ•+Ăã۶ŐWVrĺ=}|n\ľĽiŐŞíÚé+*Ö,\č÷Ýw^ŢŢőv¸4M§%'o]»¶yt´H,Ö=|¸vŃ"żĹ‹UZí• ¶­[ޢ…P,®,/˙qńbź… µZ-SßCvRTĘ™3»~ů%ŞU+R$zXZş~Éźůóĺ ĹĄÓ§÷lŮݦ )–—”¬_¶ĚëëŻU*U˝:v§óܱc‡věi×N@’ĄĹĹ?ŻXńĎ/żt“JĎ9rd×®V:AiaáĆ•+ßť;W.—׫cu8N8pňŕÁ6ť;ăQ\P°ů‡ŢţäˇHtlďŢłGʶíŇÇń˘‚‚-«WĎś3ÇÝÝť©ŻVŮí‡wíJ>}ş]·n†ääl[ż~ÚŕqhűöËçĎwčŢ!”›™ąý§ź&żű®›DRŻŽŃjÝűëŻ7._î 7oîŢ´éŐ7߀=›7ßľv­SĎž,Ŕí´´=›7Ź›6M"׫Ł3›wlÜu÷nç¸8–aŇ.]RŞŐŁ'O¦(jű† y÷îu‰‹c&őÜ9ĄF3|âD‘PČwÝ˙_Ť)ëoŘxđh,(ĘٵkW©Tú¬;Ä”ŕ”ę´9ę_ŰćŢq@.¦•?řಲ2­V›ťť=gÎÎ>ŤF.'$7h I˛f±H ĽŘe„Đ™3gŽ?n·Űą¬!§ÓąhѢGźŔEt(˲/*’a™Ąç–ýţkM˘R őéńą Äőc°§Ďż…śNçąs縇֣Gwú©EEv»íÂ…‹|‹ř‹6–eY‚Üľ};++€ĺćQ(ĘȲ¬ÉdşvízYY)BČĎĎŻiÓ¦$I2L=_píŇĄ—/JJ?y˛Őářô­·Î9Ň166űîÝ[WŻ›0aô«ŻZěöOfÎ<}řpËöíëć"RΞMż~}ü´iĂFŹ6Y­˙zăŤS¶ëÚőęĄKwoŢ|íí·n4›gOž|ňŔ¨Ö­}||ęÖZŔ…'Ďü׿â Đ™Lďľňʉýű[wętářńě»w˙ńź˙ôîׯÂ`xwâÄăűö…·l©V«ŮútÎ:”—ťýáW_őŤ-«¬|kܸc{÷F·m{úСüÜÜŹćĎďҵkIEĹ[cĆŰ»·yT”´ľÓ€ű÷ĺçľlY»ví ËĘf%%Űł'"&ćřţý%……o~ôQ›Ö­””ĚLJ:ş{wpx¸°ľ±)ptĎžň’’ćÍ‹ŽŠş˙ŕW>$"âŘîÝĺĺsľý62<<7?VRŇŃÝ»BCQ}ݽ۠ÓÍ]ş4´Ył{99oŤstĎž)ď˝wd÷nŁ^?}ĹŠfAAYYoŹ{lĎžÉďĽĂş¨EGví2›Í3çĚ ô÷żťžţîĉÇöě™8kÖ‘]»lVë¬˙;ŔĎďć­[ďOštlďŢI3gÖŰĹPNç‘Ý»)Šzű“OüĽĽ®\˝:gęÔű÷Źš4éčîÝ ĂüăÓO}<|Ř×ß˙_˙ýŻD(ܲ~ýö ®§¦†„ś=z´I`ŕśoż‘ä/«WďÝşőZJJݏ¸zu rrÎ?öďożÄŹK—žÜż?ýúuĄFsáäÉČČżţšŔń.}zXXX˝IGH€ 'OF·nÝwČ %ɉłf-üřăÂű÷/ť>ÝŞcǸAŔ](|ő­·ćüq~NNłú ›ŕôˇC]zőęĎČĹâ×ßygţG=,+;sřpl||×Ţ˝…›Űä÷Ţ›˙ŃGĄEE~. Űń˝{ă‡íŘŁ  rwźöÁßţűßF˝ţřľ}GŤj×µ+  ‘˧͞=˙ŁŹôµşŢ±Âá]»FLĐŞcG'€‡J5ă_˙ZđńÇ6«őČ®]Ł^{­E»vNOµzćś9 >ţŘüć›îő6ŕĐöí¦OŹhŐĘ ŕăá1ëß˙^ôé§3ţőŻC;vĽ2kVxË–/ŻY˙ţ÷’Ď>{ýťwDBa˝+~‡věüî»!‘‘??ż™sć,űňËé~xpÇŽ7ŢżYx¸Ŕßßćś9+ľţzĘ{ďa. Űáť;gĚžج™ 0(hú‡ţ°`Á”÷Ţ;˛k×Ě9s‚‚AÍšM›={í˘E“ßy§ţ‰$†9ľoß›}äďďďh>ĺý÷7®\9aćĚ“ĽýÉ'~~~€ČČ×ßygóęŐ“ë3lŔápś=räÝąs}ĽĽá-[Nś5kϦMĂ&NĽpâÄ{źîíááhŐjüôéű·m{őőםőéXĚćÔóç?řňKµÚ в]»QŻ˝vhÇŽ¸AŇ.]š=ožV©¤Zuě8lâÄC;vŚwaŘ ••w®]›ýŐWj™Śh×µkÂČ‘ÇöěiݱcćíŰłżúJĺîNtčŃăŢť;Çöěĺ°•ççäĚţę+…DBtíÝ;+=ýôˇCţAAEůůłżúJ.ÓÝűőËÎČ8yđŕ†­ 7W_QńÁĽyîB! ĐkŕŔśĚĚ 'NE˘*ŁqúěŮR’dú ’›•uţřńx†-+=ť¦é Ó§K‚H1â~vö• ‚ĂÂ0 ;uŞÇ€IIůąą©çÎĹş0lwŇҤîî#'M"‰ăÇŢżëęU@ T©†żň  ›8±0?˙ĆĺËë3l@ÚĄKľţţCĆŽ–4yňâO?ÍJO/ĘĎoڬ٠¤$@€ăcŢxcńţ“qëVKްýýŔďaăÁăهx9«ŐjµÚžéÇhĐ˙ś°áú¤´ËS ¦ßS‡q)ź °Ŕ–A›®OJËś’$Ş1rµ‘žžÎ%Äß·oźH$˘(Ęb±Ôx6‹Ĺb4ďÝ»7tčP’$<čëëű2>>xxx>îr9W>$"˘Ęh´šÍąą^~~R™  BŁ˘Ś:ťĄŞŞ^ /+Ë/0PěćĆ•kŃB÷đˇĂḟťí$’Hp ĽeˇĄĄ6›ÍŐýäŢ»J …SZTDSTî˝{ÁÍ› H’ "Zµ*),tşHś‹ädf†DDŕ8ÎéDµn]x˙>Ă09ÍŁ˘0 ăbĆŁZ·~—窓A9a-Zp¦”nÓ&?'X6'##ĽeË>ŞM›ű<ň1äddD´jĹ€¨6mňîÝ€śĚĚČßůÖ­óîÝs±Ŕ˛lŢ˝{‘­ZŃ\ŻŮŞÄ™ť IDATUnf&äeeŐć#bbr33]é04]“SSðđ-r23Y†)ČÍŤŚ‰ˇÇ›GGçffşĂ9ťÎ˘üüđ€dłÜ{÷(Š*yđ ĽeKŽ'I28,,ďŢ=ĚĹC¶Ůlĺ%%aŃŃ ‹›†„ÜĎÎvŘíËĘšGEqĽX" ľźťŤ»Đ±TUé++C""hŔÍÝÝ7   7×j6őúfáá4ŕ.—{7iR›ëę~LĹllŢś+ŻP©´^^EůůUFŁÍj ˇ€RŁQkµE÷ﻊeŃUTPN§P€4žžrĄ˛´¨Č Ó1 Ó$0[·ôđöv—ÉJ ]é<,-Ĺpś peĽüüDbqEiiEy9A’ŢMšpĽŹż?)>,)Á\4ŇҢ"‘DâáíÍĺlŇ´)†aşŠŠŇâb7©Tăĺ €P  {ř»ó†ŤOöą@1”V˘ős÷k¦ ýôÜgy†<@€bMěÜ~źuňéäĺćŐÄÝŹŔ¶ÎĚ=˲8Ž/^ĽxăĆŤ!!!űöíS(»víŞ±dűöíóôôÄ0léŇĄ7nÜ´iSttô ˙ŕÇŽ‹ŤŤm×®ÝĘ•+9¦öŠa‚ zôčŃąsg–e;tčĐľ}{Š˘ ŦM›:uę´nÝ:OOĎĆÜŽđÍ#6mľyËđÍ7@­•0'OL8¶eئmC·Ú)Ç3eʍ»Vů¬żĹăŻŢ–išńňňôđđ  –JĄ†’““%qBB˙°°°čč¨!C—––eddÖăöزĘh‰Ĺ Űł}űÍ›7µ$ÉĐ´Óá0›Lb‰DŽa;·mKżsGK’EŮ]$NÇM*•!ôë/żdgeiE"‡ÝNQT•Ń(uw—!´eÆÜÜ\‘Čn·×ΚSwŚë.—KúyíÚÂÂB­DbµXhŠ2ęő2… ˇźVŻ.))ŃşąqĽ+ŁN'W©$­]ą˛˘˛R+“YL&†a :ťBĄ#´fůrť^ď!—›M&W{Y€A§Sj4B„V}÷]•٬U©Ş –eŤ:ťR­&ú~ńb‹ŐęˇŃ WMŚÓQkµ„V,\čt:µ^^F˝ž0ętj­Xľ`EÓZ//^ß@C5čőj°|Á†eµžžť8Xľ`h==ő:]ɨ×k<<(š^ľ` ńđĐWVËšôzŤ‡‡Óé\±p!ĆĂĂPYŮ@m4ŤµÚjł­\ĽDHĄŐt:–e«ŚFŤJe¶XV-Y"DHĄŃč]ë04m©ŞŇĘdzaő˛eb„”jµA§cĆRUĄqwݬ¬\»b…Ă*•A§se iОšÍ7·ŇŇŇź~řAŠarĄŇ¨×Ó cłX4IQQŃĎkÖ¸cLˇh@‡r:6›V$ĘËËŰüÓO2 s—ÉLEQN‡C#fggoݸQŽaR©ÔŐ,pŘí”Ó©ďřőW†IÜÜŞL&§ĂAS”F ¸}ëÖîíŰ•&–HLFŁ+»ÍƲ¬š ®^ąr`ď^%† …BsU•Ýf–UăxjJĘ‘TF’¤ŮdrĄcµX0 Sář…łgO;¦ĆqB °Z,6‹Çq†ť=uęĚ©SjÇqÜb6kC+TvüđáK.¨ !d·Ů¬fł€$UväŔÔ” A€í…nMçńWÉÇ˙r6qqz"B´-c›ŮjFÄZŘ„–ý§´ś"$„§„ ¬űzŕ’[ôë׏űg\\ôéÓ§ć5ĎeaY6!!áĺ măââ~űí7ŁŃ8|řđ÷ß!ôŢ{ďŐ¬¤˝űî»8އ††:ťÎŽ;ęt:š¦ąąÄÄÄ={ö$%%5v’ aIáŁ8?KłôÉŽ§×¦®ĺňް,“ŁĎ}˝ĺd–ˇôv_ßxĚÍk«ŞśÝܦ͡¨®¨YXčäÝ]\Ë++ąžĹ8057Ż©¬´wtś6c† ¦˛ŇĚŇbävööS§OWÔTU™=ABB‘¨¦şÚĆĆfĘ´irš®­®6ł°@ D˘šÚZ++«ÉS§Ęiş®¦Fdi©Ďs㸉@PŰĐ`an>)6VNQőµµ" ĂŚ‚š¦&s‘h¤I2Šj¨«3ł°Đ§‡`±řĆĆ5b±Ą™YLLŚŚ˘šDćć8ŽóŚŚj$k ‹¨čhI6562Ś«S°ŘlŹW+“ŮŰÚvŹŚ”’¤¸ąYhfĆbł9\n­Lćhoďlo/!I©Xljf¦ďˇŕp8,«Vˇpuvvwvkµ2©T`jĘćpp‚¨S*Ý]]{şş6kµ2™LhjŞO—ÇCVŻRyőę…zőjŇh” …‰@Ŕáń@˝Zíăĺ…5•Ri,ęÓĂ76¦(Ş^Łé×·/4¨ŐŤĆČŘĹf“$٨Ńôëőjµ–$Ť:ŰŐÉč161Ńh4ŤZíŕ NĄ˘išgdddb˘V©š´ÚˇC†ĐuJ%𦦠óöż†H řglD6΀‚ăŹ[Yż@ŽA’¤V«Őę mę:gűtnŃ´Üśv]7“qą\Ú^߀g{¦i‰D:ţĽ‹Ď_¸pîôéř5kVKĄ-۶íČĎĎ 1 ăóů—.]ÎĘĘćóů4Mk4ÚNcbIG—†ÚÚÚŞ* Pp÷.—Ç315upv®­ŞŞŻ©aä÷srřĆĆB=¶) ŕěćVUZÚX_Ż îef E"ľ‘‘SŹĺ%%Í *&c¸ČÜÜXŹ-Čl–+),”673SLNZš…Ť ›Ëuőđ(ÎĎo‘HyvZšµťŹÇëTĐŁWŻ‚Ü\ąLĆl÷ĚJMµsp X,7OĎüś…\ÎČ3SRş99±ô”­§Ü˝ĽîefŞ•J% ‘śěčęŠpÜÍË+÷ÎŤZÍÄ{e$';ąąáz˛ËŇî^^ŮiiZŤFÁčIJrńđ„Ü˝˝łnß&µZťü 9ýŔÝË+35•˘(Eëů¸yz€›§gfJ EÓ Š¦3““ÝĽĽhý3cŹ^˝2’“iI’Y©©n^^ŕâá‘‘ś ­F“}ű¶»·÷–“›[fJ Ó^ŁVßMOw÷ňÂ0Ě©GŹŚVąZĄĘ˝sÇ]˙ů°ŘlgçĚÔTP(ŠűŮŮnžž8‹Ő­{÷,ť\&+¸{·‡§'ĄźŘŘtë–“–*€‰äÁýű.={r¸\+[Ű»ééŚ\"?,(píŮSź#3 ‹ÜŚ @ĐÜŘXV\ěěćĆ32š™ÝËʢÔMőőŹ9ąą‘zŹP$221ÉĎÉaÚ×ŐÔÔVU98;›…<>żŕî]Š‘WUŐ×Ô8¸¸čÓcniI°XEyy€ ŞĽĽą±ŃÎÁÁĚÜaŘű÷yei©D,îÖ˝»>=V¶¶$I>*,$´e* +[[KŤJUúŕ @”>x V©¬»uŁôč±st”·´T̤IżíÚ•žTTVnřüóA#Fčs&hĆNžüóćÍ™·oceĄĄVŻĆ"±S¦ěůńÇě´4ŕQIɆիGED°;KÉŃqS¦l_·î^Vđ°¨hýęŐˇŃѡ±“'oý曼ś ¸ `Ă矇O€é÷řENžĽiíÚ‚{÷€Â{÷6}ńEDl,DLš´qÍš˘Ľ<  7wÓÚµcőGtc6~ü†Ď?/.( îgemýć›qS§"„B˘Ł7¬^]\T„ÜËĚÜľnݸ©SI='ĂćpFED¬˙ěłG%%8@NZÚž7u*NĂBC×öYii)•šşoóćqS§jőčá9rĂęŐ••@ú­[żíÚËĺń7¬^]Y]Ťn'$Ţ»wěäÉ=zDćć˝~\ł¦ş®’®\9učPřřń&Bˇgź>×®­©Ż€[—.ť?v,|üxµBbcgçěîľů«Żę›šh€kçÎ]?>(2ŇŇÚÚÁŮyë×_7Ĺ$ŔĺÓ§o]ą2zěXŤ=Ž®®ÖÖ;ľű®I*Ő\8~üNRR`H}÷îB‘hç?4·´hiúěŃŁ9ééĂCCŐzˇ›—‹ÍŢ»i“DˇPSTüÁňóűĆpűź7o–*•*’=ţC†T–—ýůgĄVۢTŘşUŁŃ¸{yő4¨´¸řř*’”*ű7o„zőîý”Ç~( ăăăŰÉ—-[fjjzîÜąvňĄK—ššš^şt©ť|ѢE"‘čĆŤí䯽öš™™YRRűÚ6łgĎ677OKKk'ź6mš……EVVV;ů¤I“,--ďÝ»×NÎdP+((h'ʰ¶¶~řđa;yhh¨­­miii;yPPťť]eee;ůđáĂíííkkkŰɇ âŕŕĐŘaŹč€şwď.‘HÚÉýýýťťťezö(ľ(B" 0ŕ€–Ďőůüg(-ĄRňĂWZS!Ň“Tí٬O„–-[6uęT.—‹aX\\ÜúőëE"Ń?ŇÇůóço۶­můµůóçďرĂ^đ:I“~6}×Ď܇! G†ŇϸĐA ‚`!„©Őjš¦Řl–«« ŽăÍÍMfffrąĽąąÉÂÂUTT`266˘(˛ă/cĂŤ;6ńňĺÄË—išĆ0,fĆ 3KKˇ0("âĆůó7.\ ) Ăń°+}„ÍoŕŔ‘cĆ\<~üâ‰4Eá8#05í;pŕđ𳇟=r„¦(›#ŇŤ¦č?lذĐĐc?˙|l˙~š˘Ś‚ĐčhźßذŔĂ{öŢł‡¦(S3łčhc€Ňcă5*őĆŤ[¶ü˛e P”µ­mHt4‹Í”ríÚľŤ÷nÜ4mçŕĄĎS§šrăĆŽuë¶Ż[4Ý˝GŹŕqă0šrýúÖŻżŢ4íâá1zÜ8}µ.)€‘cƤܸńăęŐ4ĐtOź ±cBŁ""RoÜXżr%#÷ôő ŠŚÄô‡VEF¦ŢĽůíŠLűŢŁ"" hěŘŰ _}ř! šö0`TD­ź°Ť7.ýÖ­5ď˝Ç,ř2"<!u')éówŢaâG„…éó,VHTTfJĘĘĄK™öGŚ Áq<$::űöíO—,aäGŤ ÖGŘx<^htô˝;wV,\Č´ 4r$›ÍŤŽÎËĘúhÁF>,$dĐČ‘ú3Z ss—ϛǴ0t(ĎČ(4&ćA~ţűsç2ň‘cĆjőčYX„ĹÄl˙î»ełf1ÂQ‘‘ľ°9ś°]?üđöŚĚ ŠŚdJGtĘŇ­lmCcb~Ţ´éÍiÓöŁÇŤóňő%X¬Đ[·.ť:•‘GEyőí«ŐŁÇľ{÷°ßwď~#6–†DEőđôÄ0,4:účĎ?/™4é±<:ÚÝŰ[«g0;»»‡FGÇ<7a# ?ľ»«+ ućđáEăÇ?ć±±Îîîúô¸{{‡Ś÷G|ü¦dĚŚ¶ÖÝşŹwĺĚ™×ŁŁ™ťŤg϶ď¬H§¸wďž\.ŻŞŞj'ĎÍÍ•Éd555íä9992™¬®®®ť<++«ĄĄĄľľľť<##C*•v$6ééé‰¤ąąąť<--M,‹Ĺíw§¦¦677w$B)))MMM---íäÉÉÉb±¸#AJJJ’ËĺŠIYnÝşĄŐj;fuľuë¨;X_)))Đ1“Szzz§ňĚĚLřk¶—‡Íţ‰u}Źúeě߇°7l@J%ýúafFF±sçzxy€±@0iÎŻľ} =ë)€…@0ĺµ×\<<ŔÄÔtĘkŻőôńA–ÁÔ śÝÜ€¦¦¦S,p÷öÖ·.CX‹DÓ.ttqšš™M_¸ĐŐĂŘ™M_¸ĐŢÉ hÚÔÜ|ƢE.=zq˘Ap0,0$dô¸q̦¸AŁF…ĹÄłXúôđ bDxřČ1cXl6AĚoą8ÎĂńQ‘‘ĂĂ‹`±†‡…ŤŠŕ„ľ‡ÔĹ ‰Ž„›Í;vxXĂŚ"4&fĐČ‘Ś~üřĐĐPww÷vňI“&………ąşş¶“O™2%,,ĚÉÉ©ť|úôéáááíä3gÎ3fLÇjCsçÎŤ°éđ|Íź??22ŇĘĘŞťüő×_;v¬y‡Š‘ .7n\ÇEęĹ‹GEE ‚vň%K–DGG·“/Z´(&&¦cuŮ Ś?žËĺv<ω'˛őÄż0»ńĘٳ̧‘áá†7·˙ËeJĄâĺm¦Â0¬­rŔtäȑ׮]€S§NwĄúyE‹DB/üŢ=@hşĺ௚đ0f3 ššöę噟_——׳g϶?/++Óh4Eą¸¸`VVVćŕŕPVV¦R©\]]B&&&÷îÝc&JˇPx÷îÝŽ“ćËFyyyż~ýjkkU*3…•––öëׯľľ^«Ő>_6’$ ‚ ˘ˇˇ®ý:†á…‚ţoM2)¨TĎt„PccŁ““ ™™ŐÖV˙uéŽ&IŞÓqRQQáĺĺÝşu{ô¨X"‘Ďż ,+ýöm6›ăß@mM5MÓZ’¤H’"I­VKę>S$ŽŹJJÔ …•…%GŰďTĚ­ŔcÝ9źO 1łîÖŘXollĽcÇÎGŹJCB‚-,,¤Ré±cÇärŢEŻ ‚µkż …&ŚW«ŐŰ·ďtuuY°`ľąąąL&«®®{=nâ’7-Z¤48€ ´ŞVb×V®P·!|"€ ˇCg/]:iňde=ĽC{}r0đňúěÇGéÖŤ vgíőÉ@ĐÓŢ~ĎéÓ˝}}µťéQh:ÓÓV&NBáůśGGŞŤÖÚ^wž,vgrŕŘłŮéµµm3IčÚS­Ç}˛ś9´†ŞŐmť˙ϡ‡Ôj]Y¬2ú/3ŮLń´íőÉ€D,îkiY®V+˙އ Ŕ¤1Th˙›¨(+ öň*‘HZÚ(gµ¶'Ô­íőÉ™‹s7;{VXX~eĄ¸Ťćü;ęéTÎśçő«W?^Ľ8=/ŻYŹůD9pŽ>Ľë‡®&&6u¦G  nmʵ>\íäŔضyóµóçŹĆÇ7·ąhť¶o'W19[óęU«ŞJK·íŢ-î ZőPO”€ŕÍĹ‹Ť‚/ľúJÚFóP·kŹ·>\í䦋-úuŰ6Řľ}ű‚ :.Eý™‡ó%ÖwÜł\‡Ő«WŻX±‚č°(żcËOóĆŐŐÖ0/,来Őú? ĂÓo§®H“B" řßĂËN{ŃŽ°µ="BŽăĎÔ‡üébb>Đ4Oť&IM!{őÍ ç *,,d(C˙ţýóóóaeeĄ­­-I’/<ćđYáää$•JŤÚd˛b»y<ŢK)\F’‚Oť\.sIźé" „Ú<&{ű_Ź@ž»W4MS*•Ş˙€‚‚ÂeËŢkii‰DC‡™?®‹‹ ŽcÓ§OŰąs׬Ysp ž0!F$i4Đ“á†P<‹\ďĐ?‹\´mŚé§‘˙Sz4%E˙úÚ˙SzÚ‘Ě˙*©zh=íégףP=µüźŇC(źińTOűPĎ ™4Úľ×ţ¶ĎúŽűo–żpüIŘJKććfżď^ŹďććˇP(ňóďýă–ëßss §şşšŇŇ’çseü˙‡­­ťťť›Í~Öż@ XşôÍ„„[Îcď6ŽyyyĚçeËŢ …4ýść»T,٢WOO-€ôŹ &Ł‚đÂ"ćOĆăÇK®_Ł\z<ćpzzvćĚ•JĹçógÍšŹă¸‹‹ËŽ;bccŹ=š••5a„úúz‚ $ÉËx|}}e2™Z­~ôč <811±wďމ¤¤¤®\ąÂăńÚţäęŐ«\.÷ĹĎkŃFFB˙h H©„T*ŐŁŘlÖ3XÚÇ«±‰dŸ IDATŕŔA:^MQ´™™čÔ©x…ˇV髹üĂ$ˇŐjµ˝˝ýĽysŁŁÇiµ$‹EDf66Ö$IRŐł§Ç˛eď477!„,,,ml¬™e†Âé`€ü­„­°đľ˝˝ă˙ú»—$µuu5yyąwďîň܆ő˙dç¦PČš››$’,Źďěěú’ö ýŔ0¬ąą©¦¦ÚŘX`iiý×h”geeeĺäätşŽŇ1[ŃłB»jµ±}7µVK[Z"iËź7ŻĽ‚˙ɧ”­-’ɰĎVŃx{˘Ĺ¸ÝOť:U]]ÍçóŻ]»¦P(0 ŹŠŠÂ0,99Y"‘¸ąąŤ?ľˇˇËĺ®^˝úeX”łgĎV«ŐˇĺË—óÍ7IIIóçĎ3f #Y»ví°aĂÚý„‘Ľ“A65}Ěhµ$˙íwđěÖ›E˛ ?Đ|c’¦łłłź]1˘iZ«Ő¦¦Ţn+çrąŻ(hú±ß›Íf;;;ąąőĐŤŤFĂÄßr8Üž=ÝqśŤFĂČőÎ6Ŕ 0Ŕ€—EŘęęj‚^…ml™™·ďŢ͉ĚGŚčóo»ť …<--ůÁoo_/ŻWłűŤŤő·n]—Ë[˛y9G ť¦/Éă:„p;ÚŚ±=řřëKĂ;҉;wîś;w®®®ÎÄÄpW(6l`ÜhĆĆĆŚOuůňĺĚO6lŘđ2ş0xđ`’$9Žżż˙Úµky<^RR“!´zőj‚x‰±Ö˘ŘÇOB€4îć-m =ŮÇ—}üVý<› ő]+YţJ6š¦)šfË[§mH’’Ë5~ŔPôĎ 0Ŕ€ż“°1¦žVűżť›ÉÇ€ăcÂj4ę˙Wu~_*0 S©”@ĚžöW°ű†«Ő* C˝ô`Wš¦ů|>‹E ™LĆD@1’ç6ß%R)tęůl«Ă;5sss™ŚLćććĚccŁ™™™ŽÔµ´´1÷ýe$™U«Őaaa2™Ś9BH­VëʧüAČ$i}ú466vtd™¸»»ggg[XX€Bˇxá—ËÉÉéÎť;FFFććć‡*•ĘŽ‰n˙Ap8ěśȩ̌/m‡jnnö÷ďBˇ077GˇP444 0Čđ’xµÁdŤľź!$Ň 0Ŕ€†°=Çë‡Ăávšc]źüą©Žă,ű :™Č–¶–.EQO4MA,…BŢÖQ@Ó4‹ĹÂq˘ťüĹ-6›Ťa¸ľCĐ4ÍápžpLľxť-ńÝçryбűĺ:ˇîvt”Ľ PEÓĐ)™y°´´pppŔ¸\N«ÄŇÁÁ^©|Ţ´ţl–ć§ŤęĆ&@@ŮŰĎť‡=(Ö±5ů—k)WWP*Ť łĐ¬Ë—//Z´¨şşú>>}şV«mjjŇŮšÍÍÍ2™l˙ţýÓ¦M“JĄŤfĎž=ÖÖÖ/öšTUU9;;@TT”ΧĎŢmW–!ôRŁ%˙šĘÂz§< «ŞŞşté“Sˇ­Ľ¬¬ěúőëłfÍęJ®'ÇńĽĽűąąw'MšÔé!‚ČÉÉ),,?>ć çĐ•îłX¬ÄÄ[R©488¸m÷Y,ÖÍ›7”JUPĐ(ťśÍf_»vŤ˘ČáÇ3,Ž˘¨+W.c6lŘ0µZý’Ć+MÓ禕J­P(x<žnx«Ő*ą\ńüĂ@.§Gʧgź9 LâA„€¦5ááę9ł);Š„(şcßܧO.—;mÚ´‚‚>ź˙Áčâ!?üđC>źtîÜąššĄR9cĆŚNž—/_ţŮgźafiiÉHÚ>ăEá8ľvíZĆ»»rĺJ„ĐŞU«ľřâ F˛jŐ*„Чź~úü'†aŞ×łv@’ś;Ű>'Š÷ŢĹš›iKŃŇÚ§µ3BJĺźŐjĄBˇh+1ŕŐMQ¦¦"ą\Öô°!ěy'ÄçóĚ--O8PSQ®éÂÔÇĺóK‹‹ŹîŰw?;[«ŃtEO}uőĎ›7ßts#µĎOµ8<žT,ŢúÍ76ÝşQ]xŹłą\•RąţłĎ„"Ý…‚Ĺ"Iň«+¸<tÁ±‰0ڦé5«Vuqů•˘( é•kÖtĄS€J©$Iňă/żěĘMGIÄbµJµâëŻŐ]°R0 «©Ş’J$+ľýVŐ…Ľ¸8A”Ő×ÔügÝ:Ą\Ţ•›~/3łüáĂ.ęa±Ů·JŠŠş¨‡Íĺ^;^*wńúpxĽ´„6‡óʧ~Ţ —ÇKżu‹ůś››{űömyşfŔK†a/*t‘x˛ŃĎÔ#˘(JßńÔjő[o˝׎)•ĘwŢygÉ’ĹZ­öEőą©©iůň-Š{h7Ť·c,Lw4ÍíE Ă=z´r媹sçµ»ĹĹĹ«W>{öś—Ăb±îÜąłeË–ŘŘÉť‚ XÉÉÉżývh„ O>‡¶Ýҵd â8ŽŇ×}'Îť;_RRÖö8Nś:uş±±!88X'Ç0üĉjµjÔ¨ ˘˘BčŃĂíčŃcAŚ1ňĺ… ýĎ !„mQ"‘Ńâ%XeĂÖ(+KŮĆ ´@€šLM;.2ńW_~ů%óuŐŞU°fÍÝ•aţDÓôşuë^Ţő˙ú믽ĽĽęëëkjj233ŔĎĎOgúôíŰ— ˝{÷ŞT*__ß}űöi4š•+WîŢ˝[«ŐúúúîÝ»—$ÉO>ůäą Ťă˛m[€&éqă&žźß:X1őÜ9¤»;Đ4jn6Ľ* x˛ÁmffŹ=’$űő °°´:uć\qţý®ŘîŽ××Ô$]˝š•šÚ•‰Ă0qsóµłg“şLlrůĹ'Xlvőh4šS‡Ń%=Ńu|˙ţ®Ćą żďŮÓĹĄ,¦'żíÜ ]{+Q4MÓôŻŰ¶ué톩Őj4š_¶ní"Ô¨ŐJą|˙ćÍ]'˘±x˙O?uĹZEÉe˛©t˙ćÍ]Y5@&•HT EWĎĂÄMM$Ivńú kŞŻGVU^ţÜz%ĚçŇŇŇ´´´—äQ0 ëďš—BŘÚé%I’±őź…hjjÚŽŃ1–ĄP(|Ó{>…Â'wľÝźÚ1“¶Ýé892„A;=Ea.ŔKŰăG’$‹Eé;MS,‹©D¬ď¨żşeÚvźÉRÍÜ}[/8S>«Ý!¸ÜNä\.—yqnßľť¦éoż]Çĺr™€·—şňŮ4BÓ´P [ch9q‚¶¶ţŻ!|O 9ş?˝Ô43ŚňÜÜ\ćkZZ¤§§ëÜąs:?xđŕÁ Ľt¨éO2&ąyCdŐö©R }ú45ÖĂKóńđę!’$"86†=7aÓŇ4ŐÜĐđÉ÷ß-Ž‹“uátDŁçĽůfě¤IŠ®éńóňZ˝iÓČ‘#»ň<ěí÷ž;×Űǧ‹!‘ŽBá‰äd{ű.†DÚq8äć ‚®Ľ€n–đđ!Ń5âGŇ´3†Ą–”t%HZZú™e””t1$˛˘˘"¨WŻś‡Ą]»8wďŢť’ű𡸠zŘׯ_˙ϢEyyM]ĐĂ8zôčÎďżżvëVWôlٲĺÚůóÇNžlîÚ`ţěłĎ*KKwěÚ%îÚĂőĆ’%&ÁÚ/ż”<ŻS€¸¸¸[·ŔčŃŁ_{í5äţ˙«WŻ~鄍¦é#GŽüđĂúĺË—ŹÓŃ ×Ůý óőŶVKťÖĎXô&Á0¬ĄĄe÷î=ÇŹ_ąrĺčŃAÝtm÷€µ»LŇç—GEč6YĘ:=„ľsűË”Ťµ'3:ÂĆb±JJJľ˙ţ‡ššš˙üç?}úôîĚKIëŰ‚¦ˇăąéÇĹĹýUĂK%lčŮäŹjy\„­eß^˛WOxAľč§líH]GÉ˙8lÉ­›‚!şAox=đ4Ŕ1¬˛˛Ě˘˙Ţý?_$†áµµUŐŐĺŤM ŽŁ®mŹA­˙ľ=a]ÓµęyçCw]†uqŞBmúŐőŐ+¬kóP«ž®_ä©çEÜô˘{Ń×{zşţp˝ëÓö·˙žtč˙f<)éBčČ‘Ł...GŽ™4ibŰ GŹÇb±hFŘĘ6źĎ#Íđż¦Á„‰‰@©Tpą\¦ČµBˇ`Ś{„ŹÇcü3jµZ·{¤UÎbXMÓŚN„—Ëe±XmŰ3ĚŞí¸mëb’H$/^´˛˛ŠŹŹŹŁócĆăńЍA0'LÓô_ĺ,ć]Ó6ČĹbńů|•JĹáp@«Ő¨T*‹ĹfłV«V(”:şČ¨˘iJĄR©T*ć¬pçrąĚ!pgÁáp¤R)Ă?9›ÍfrĘ·Ň!Ç1.—K,Fá_Ż6ęx7 ‚ČĎ/(,,$"))) Ŕźé>Ó .—Ë,0ë΢¨żĘ1š¦t| t_)ŠtvvŠ")Šfł101P©T*™Ý†|>Ă0𦠂ĄR)U*Ó)„0š¦fLĆ|]3f©Őj’||Ců|>SÇöŐ(|„ZZdëףćf¤ŐjĆ„Žż<ÂÖŽŹ!„/^üĺ—_2ţjF2{öl±XĚ4322Úľ}». Ç˙w¤ÖĎOţí7ü÷—hµ`xuđtO!3c3Ů’žFFĆ$I’Z-EQd×ňO4M“Ąíšfa*ĘuQ @jµ]ď$©í·aL ć|şNüH’D]K€ÄěěâEF/HÝş—řśIMwý¦3M]„ڞËzIŰĺ~QEż‡”ńgtE @ý·u|^eÂFQŹícš†ÚÚÚâââŤ|űíwŞ««E"3O"„%''?xđ€ „MS4M!„%&&>xPĚfł\]]ľAÓşa„ÔjŐ‰'|}}3225Ť­­M˙ţýŇEQÔ­[·>,a±Ź^˝zi4„E‘7oŢ|ř°ÄČoaaaMS mKKK+,,BÜÝÝ˝˝˝´Z-@G“4i4šŇŇR™L¶xqÜŹ?n¬ŻŻcł9Ě9+•ʤ¤¤ŇŇ2‘HD’Z\KˇP$&&–••›››Éĺ Ăţě†aŐŐŐiii®®®999$IuďîčĺĺUVVvď^MS...}úôAa’ÉZnÝşUQQibběĺĺĺäÔ]­Öŕ8.•JnܸQYYiggWUUÍěŁ(..~ôčŃ#45ŽăEEEeeeááş}e4Ž#™¬%%%Ą´´”Ďç{{{;99i4&_Y»»‰a!$—Ë ň\]]óňň$ ă%˘ľľ>33ł¶¶ÎÍ­GCC=†aAŕuuµ™™Yuuőîîî Ť •Ňuź!Ź4 †ßş•C† Ĺ0¬±±)!áćýű÷-,,}}űXZZ ””ą\ŽaXAAAż~ý|||îßżź——×ŇŇ" űôéckkKDbb"SFݤ¤„Ď绹ą9;;sąš Ă®_żnnnîîîţŞ¤Ń¦Ë>źfĆËěBčđáĂ‘‘‘L\+lٲĺăŹ?Ö6Ëĺrą!$ 8°aÆ—MŘ<8eĘ”vë‚;w>Î ňLŃH©Tľý‘‘Aă8°XđŞĎđJ‚™ÖUżçř9ŽăZ­ö [ 0Ŕ 0ŕĄ6ťW†¦é„„gg§Á9::&$$ŚÉ8yę¶oßž––ÎápÂĂĂ™wEQuu5۶mKOżĂçóBBBpgČU«Ő2™lÎśąkÖ|ţŰo‡d2YŹ®+V|äëëK’dEEĹöíŰ33łŘlöČ‘#Ţ}w™±±1E‘ĺĺĺ›7oÎÎÎ152´ŐÉFVWWďŰ·/))™¦é#†ż˙ţ{ íáÚv†9ôť;w<={ 4pďŢ}ÉÉ)#GŽĐhHŠŇ>xP´iÓ¦{÷ňlmm===Y,MS$©-,,ܸqÓýű÷»uëćććĆfł™íÁşWu~~~\ÜâĹ‹ăŽ=¦P(úöőť:ujZZú™3gT*ŐŕÁŢ{o™łł‹FŁÉÍÍÝ´é§ÂÂB‘Č4&&fŢĽąl6[«ŐääÜݰaCQŃ777SS!›Í€äää˝{÷Ž3¦ąYĹb±nÝşuđŕoáácDZ«ŐŢ»—·}űŽśśccŁŘŘIłfÍâp8»@Ń4†ăřŁGŹĘĘĘüüúzxxüúëÁĽĽ{>>>4Mi4ę”””Í›7—••űůőmjjöđpgĚ—¤¤ä­[·–—Wřű÷«­­óőíÓV?ăacřáÁiš2d(‹EäĺĺýôÓćÔÔT{űn ľ.‰~ýő`NNŽłłóąsç>ýô“nÝěÎś9}öěůęęj33ŃüůóŁŁŁ¬­möěŮ[^^feeť(‰† ś={–‡‡EQbqó¶mŰFŤĺííőjxŘhcُ%Xq1´üvPúRi[lllEE…ްńů|fˇD÷>|řńĘźV›žžţÜ9ž€ŇŇRGGGÝ×iÓ¦Mž<ą­Ą[VVöŢ{ď1 388¸{÷îO}5i$“Éżřâńâůß\jŔ+š¦žtµNť-"´ uh›ŮVź\ďb„AŹAŹAĎߢ§­‹ŞíîƧq]ék˙ÂőĐŻ†dŔó­0¶űNµÁٳ碢˘T*UDÄS§N3%Iň—_455>|hçÎí))©ŚŻFŁŃ8đ«T*=zôđÖ­[’“StDNŕńx÷ďç˙ňËţÓ§Oy{{oŘđ#A …â—_(Š#G~߸qCNÎÝß?Śă¸\.?pŕWš¦ăăO¬[÷mRRŁS&“>|¤ľľá×_ěÜąŁ®®î×_AQT‡ŢźÝ‰DśśśŽăř AĎž=Ë„_666<ř›P(X~çNĆĄK—Řlv»Tš¦™Ć0,?ż@,–řůů98Ř›šš&'§ăxnî˝řřřáÇ]ľüǨQŁrssqŔrrrNť:tůňC‡˝w/ʎß:0äŤ9›Íał9 ‰-((“••€ńůĽŇŇҡC‡dd¤/XđÚž=űŞ«k6oŢtóćő×__ž~ń>,=ztJJŇÎť;Ş«k2331 c±X/ţaiiéăă­R©^ť¤#FŹ]XĆS¦âŔb˝ĽŁ·+€Ö–’µ5U-,,LMM_ř9xxx}ÁP‘Ć€§ús¶|f´NHßËŔ;l›Ń'ÂKZ×ţiäϤ=ŁôzĐ3ęA˙?ôŕzôŕĎĄÓŁű{őĽŚA^ô „—0źCú+‹{úëÓ¶=ŇŁ=ťLŹžg˝_ü[óęjhh¸˙~LL´@ Š—››ŰÔÔÄdĽzőęĽysíěěgÍšń82X«˝víÚĽysmmm»wď>sć ’Ô¶ľŇhÝëÍfĎ›7ĎÎÎÖÚÚ*22âîÝ\„@ĄR%&&Í›7×ĆĆĆŐŐuҤ‰/ţaBˇHNN™7o®µµµ««ë”)SÍN2YKRRň{ď˝ëéŮË×·ĎŚÓŻ^˝ÚĘéŽÝŃjµUUUµµµcÇFZYYŤ1<''‡ lnnÎÍ˝7{ö,+++OĎ^ăÇǨTjš†ĆĆĆüüü™3gZZZz{{EGG©TŞvÝ!I­ťťíĚ™3¬¬¬\]]Äb±fĚniiŃŁ‡kż~ýrsópś¨ŞŞ®¨¨:uŠĄĄe@€@@ŔŤ ,«˘˘˛şşfʔɖ––ţţýBCCUŞÇ;ńZéÝĘÁţ˛}îÁâ–٢EŻ;;»†„„řůő˝}űvkČbŰî?ţąJĄ*..ćóyC† öôôtqqÎË»ŻP(~ăĆŤ3776,pđŕÁĚ޶ĽĽű,+22ÂÂÂ|äČP©TmzO3źŰ-ú¨TŞ€˙QŁF™››‡‡‡ńxĽ»wsůŔFŚ! Őjutô¸Ĺ‹ăzöô°µí6yňdSSÓââb¦Ů!C† 422ęŮÓĂÖÖ&//ŻşşZĄR'''ŰŮŮąąąişP©ćŲ-ŃóŔě1SB‰%Ě0?ŐÖ«Ô<ţĐ!Š˘ž`Vrn'&.ŚŤéă3qÔ¨łÇŽ1V) 5!aÁĉ#}|&ť?qâÉf. ńÚµyŃŃ#˝˝'‡„üqú4Ţ*żuĺĘܨ¨‘ŢŢSCC/ź=űäÍjl€ë/ÎŚéí=}Ěë/2‹g,€kçĎO3f¤·÷Ś—.=y)¸túôÔĐĐ‘ŢŢsĆŤKĽvŤ™Đq€‹ńńSBBFz{Ď‹ŽNľqó߬öłÇŽĹŤôńY0qâíÄDn«ćČ‘‰ŁFŤôńY›žśĚ}˘š˘Ž<8~Ä‘>>‹§MËLKcôP$yôŔáĂGúřĽ1cFöť;Ľ'ÚZŤćĐ޽ѣz÷~{Μܬ, V«îŢ5tč¨Ţ˝—Í›w?'ç zpĄB±۶±őî˝|áÂÂĽ<. ÉönŢ9hPPź>ĆĹĺçóžx‘ĄRéÎ " ęÓçă7ß,)*â±xű?Ś0`´Żď§ďĽó¨¸ř ׇĐÔŘřÓ×_‡űú~ľ|yyi)€ĐX_żńË/Ăüýűöý⣏*ËĘ8O|XÂČq0`€ÎĄ[ĹgüE}űöa¶*ŮŰ;ĹbšŤFS^^ŢżĂčüüüľývBH­Ö”——$Éápú÷÷g¶źj4šěěěźţů×_Ąiş±±±°°Ńßi–H…B‘śśś““óÉ'źŞŐꆆƇK222¬P(ęëëüüü4Ť±±qßľ}˙ýwš¦ĺryCCŁź__­VkbbâëëŞmwhš&IŇÄÄÄŰŰK*ma±XÖÖÖ&&&žžžR©”ĹbYXXH$bJĄ2™¬wďŢŤĆĚĚĚĹĹ9%%!L"‘ČĺroµZmnnîĺĺy˙ţ}ť'M·‚ ­ĹĺtĚM*•¦¤¤lÚô“¬(#㎭­-S.ďŻ6`.xUUuffćíŰiË—ŔěýĂ0Ľ¨čAź>˝ëęę‚čŃŁ‡Z­¶··wuue úÚÚZ6›íęęŞR©śťť•JeŰî3ÚrKĐjµÝ»wwttT©T...\.ݦ¦†‘;::vëÖMˇÓ4mooźž~çŕÁßššš OHH`‚ß4­łł“­­ŤBˇŕóůýű÷?yňäĹ•••JĄ˛gĎž<OĄRÓ4ýŹoáóů›7o~đ xĆmë ąüŤuspÔ’÷-é›Xu „•—óß}_¶ĺ'ÚÚh ÖiÜĂ… ˘ŁŁmmm)ŠúôÓO U IDAT׬YłuëÖľ}űúůůŔÇüÝwß%''Oť:µ_ż~ţţţqqq?ýôÓ¸qăCCC9‡ĂaîHxx¸‰‰ MÓď˝÷ŢęŐ«ů|>BhÍš5+W®dë÷P!„VŻ^]SSĂ<†;vě`„ożý¶Z­ÖjµŰ·o€˙üç?_|ńĹ›oľ©R©¶mŰo˝őÄĹĹŃ4˝yóf ĂBqqqĚN×-[¶´;ĐđáĂź–<ńßY†geëLo@©ůLwÇP&ű_ †z=NF‡‹Ĺb±?$©e–ę\Pa@Q$#ětµhJßµ«Ş¬lŕ¤V{ă +«ČɓŠĹÁť;k«ŞŤ©ŐjŻž=kicĂf±čÎ ĺ±řŔ¶mÍŤŤGŽÔh4Ž·¶µ ;¶Y*ýeëV©X<8(HŁRť;rĦ[·aˇˇ,‚čTOUcăľM›T*Ő  µJuňŕA[‡!AAUŤŤ{7nÔjµC‚TJĺńýűíúFŕx§zĘkkw˙ř#†aCGŹV*•‡wďîćčč?xpYmíî X,V`p°R.˙mçÎnÝ»÷ Ŕ:‹¬ĆUVî^żžod¬ÉlÝjďääíçWRQ±kýzc€‘ď߼ŮÁŮą§Źę,˙>(.-ݵ~˝™ąą‹‹ĽĄeßĆŤŽ..nžžJJv®_oaeĺčę*oiŮű㏎...ú˘^ <Ř˝aµťťł‡‡L*Ý˝~˝Ł‹K÷= woŘ`koďÚł§Nî¨ÇůOÓôýű÷÷nÜŘ­{w7/ݱxç?88;wëŢ=/7wßO?98;»{{KĹâťßďŕělçŕĐéBIQyŮŮżlŮŇ˝GŹž}úHššv~˙˝““•ť]NzúmŰ\ÜÝ=}}ĹMM;řÁ~ýzk[ŰNcíH’ĚLM=´kWŹ^˝¸\nscăîőë»ýđ™…EzRŇá={Ü==9\nSCĂîőëíľűÎÂŇ’ęě"k´ÚÔ›7Ź˙ň‹‡Ź›Ăi¬«Ű»qŁÝ7ßLMS®_Ź?x°WďŢ,§ˇ¶vߦM6_}%‰:ŐŁŇhn]ľ|öČŻľ}Y,V]MÍţÍ›ß˙â ľ±ńÍK—.ž8áăçG°XµUU¶n}gŐ*ˇPŘ©…Z}íěŮ«gĎöŔ ˘¦˘âŕÎťo~ň ‡ĂąrćĚő |0Ż*+;´k×âŹ>216¦:„2•ęâ‰É×®ő8ð’˘˘Ł{÷ľţţű8Aś?~üöÍ›~! {p˙ţ±ýűç˝ý¶źß©‰Bqú÷ßłRSý‡ €Ľ¬¬“żţ:űŤ7ŕÔˇCwďÜaäwďÜ9}čĐ´… y\n§zšĺňżüR›Ű?0˘¨ôÄDS3łÉóçkµÚŁ?˙ü  `Ŕ°aEĄŢĽ)˛°?s&÷ż-ďđo lŹ_BgÎśéß?€©ł€üOť:Ěř–0 QIÓ€ăó+FΤ GşUČVͨ5e""I-ÓRGK(ŠDčq9p C$I¶ę¤tE¤L0žR©ĚĘĘbNÇńáÇ3ηÖ,#®›b&‘Hnőîí“””ÄĽ’ÝÝÝÎť;?lX EQ$ůř†á8F „‘¤š)·­szµ]‘eRĽ2©J]ó•éY«1@3«™xKŠ"hŠ"™ł%I!„ăX«'ŤŮÍôřpşäśmýgŤŤŤŚ~ ĂúöőU«Őív 2żÇ0¬°°°şşÚŇŇ211‰ąŚ,žššÚŻź_kĘMć”p Cş´ţmä#gînśtpčé˛ŇĚŻthš&‚3,;++ëĉůůů …!T^^ѶsP…BŢżż|ü©ŚŚ ±XlkkëéŮ“éă˙‡Ç†ËĺďÚµ';;ű9~ëââęŮKŁÖNN´± @ sËŮÇŹk‡’nnH©„°PşłäŐ,뫯ľ˛±±a>/_ľ|ůňĺ•••VVVĚťýđĂÍÍÍoŢĽY\\Ěfł‡ ÖÔÔôî»ď~öŮgëÖ­ÓĺQ*•ß˙=CŢBďż˙>ó§O>ůD«Ő>yŰĘ•+˝˝˝ ‚ĐjµgÎś‰HHH`Ć$yîÜąđđđµk×0 11Q­Vź;ud°Ů˙ńÇŤĎzkôŐ'4ŕ•'l ľ¬¬¬´´¬ĄEŠa˝˝=—Ë•JĄŮŮٵµµaööÝŮl6Eu2^X))™©©‘“'ĎX°@©VŻ\şôĆĹ‹‡źź}űöř™3§Îť+W©>^Ľřúů󽜝ťµť­ÜßľyónFĆŚE‹&Lť*•Ë?\°ŕÚąsţC‡f$'ßËĚśűÖ[Q'Jd˛÷çĎżzö¬·źź­­-Ů™'!ńĘ•üÜÜ%}Ů(‘,›=űĘéÓ} HĽrĄ0/ďíO?  k‹ßž1ăňéÓ={÷677§;ÓsăÂ…‡~őŐ°#jßś:őň©S>ţţ7.\()*úxÝşˇŐőőK§Lątę”»——±‰ Ý™§ĺęŮłe%%źoÚÔż˙Ššš%±±ÄÇ÷ęÓçĘ™3Ź­Ýşµ_ż~eUUKbc˙8yҵgOvg¶)p)>ľ¦˘â˝5kz{{—”•1í{ôęu)>ľ®ŞęŁŻľňňô,~ôčŤÉ“˙8yňő÷ŢCťÍlŕâÉ“Ťuu+ׯ÷ps+|đŕŤ©S˙Źmٲ?Nžljl\˝i“›«k~aá›Ó¦]ŠŹź˙öŰ´žQtńÄ ©D˛ô㏝ďŢ»·l֬˧NÍ\˛äâ‰ň––Ąź|âdoźť“óŢÜą—Nťšłxq§É‘´Í'N¨ŐęwV­˛·µMOO˙háÂ+gĎNš;÷Ź“'µZí;ź}ÖÍÚ:55őăĹ‹Żž;7}޼ΉŤ\ţG|<°÷>˙ÜÚÂâÖÍ›ź/[văÂ…1'^:u '÷żřÂŇĚěƵk_._~ăâĹŘéÓ՝鑊ŗOťâńů|ůĄąPřÇůóëW­JĽzuXHČĺÓ§ŤLL>řę+‘@pţôéźľř"ńĘ•č Tť’†şş«gĎŠ,,V|óŤŔČčä‘#»×ŻżťŕŰż˙ŐłgÍ­¬V|ű­1źěŕÁ_¶ląťˇęě¦WWT\żpÁÖÁáăďľăs8÷ě9¶ÖíŰÎnn7.\°wrúřűďąlö/Ű·ź>t(+%edPP§zJ‹‹.]röđřxÝ:AěÚ°áęąsòłE·._îáéůŃ×_ă8ľý»ďn]ľKşv- 0ĐĎĎOÝŮĂ•—•u;!ˇ˙°aqË—“$ůÍŠ‰W® 75Ą'&=úőeË4$ůĺňĺ·.]ę7x°§§§aęţ·ëôŐ%•JÓÓďl۶ĺÜą3çÎť9{öÔúőß''§Čd-`ccSXXÄÄ꬛˘˘"&±¨¨H—ѱŐD{Ěv(ŠÔ±&Ă$B`iiYTT@©Őއ‹»uł#IĂĄĄEQQ­V«Š‹0¤!đňňÚłgsz'O_»vŤ\.ë4ëE‘555UUŐżýöë… gĎť;sćLü;5pK©T°Ů,‘HX\\Ś(ň’’‡8ŽŃ4Éfł„B#—ËeŹ•`ţ×î<Vdś~­‡¦[{ǤÍš&9ŹÇ}ô¨ĂD"©­­µ˛˛"I ŹÇărąĄĄĄ†¤RIyy9†a$Žcˇ–)BĐŇŇR__‡a¨5}+ @˘ëÎÉ“ÇçĚ™ÝŇ"eNŕŻkIjóóď[[[ÇÇ»xńÜ… gOź>84==]­V …&4MWVVajhh¨©©a˛D …Š˘ŞŞŞ0 «ŻŻ«««Ĺ0Ô.H Ô¦ŘŞŻŻŻ««Ă0TSS­ŐjMM…ĚÖYš¦hš¤išĂať?ľˇˇaÍšŐ'Ož8}:~ôč ą\ŢfĄűq«ťť]Ż^ÉÉÉׯ_ďŃõ[7;­VÓŮ-ţG@™<ß/Ë?ŕDŽ3?A0/*úÓŠŮ»&cÇOŠEĄĄ€ť2 ±řqąN@€a™™™Dň¸đ¦P(Äq\*•¦§§łŮlš¦oܸakkË\٦¦¦¶zt_y<šH’¤………Nż>ŕ8ž‘‘‘‘‘‘““I’d```JJJFFFvvö1c(Šâp8QQQiiiŮŮٱ±±Ť&55!”™™™••ĹBŠ˘=™™™ÁÁÁŚňVHĄz«ż"šĆęę˙PU•ńä)N_,–lß^TY‰Ő7<źáŻLevžš§· >‡úúú“'O~ňÉ' .z㍥{öě­®®&<33ë믿Y´(nńâĹ›6mb˘¸;M:ÂHşzŐ§_ż¨(`ĚfĎ^ş´E")ô(ůÚ5żAFŹ &ÎÜ·Ţjlh(-.ît„pýüů!AAĂĂÂh!ź˙Ú˛eĄĄő557.\L˝ţ<¨©¨ŔôčątęTXLĚŔ#Hs`ŃňĺůwďJÄâK§OGNšHX…q~›‘ŃÜĐ€ô,î^8qb¬Y}ÔX›™-Y±âNR’R.żpâÄäyóúôﯰ¶°Xňź˙¤ŢĽ)kiѧçÜŃŁ3ăâĽüüÔvÖÖo|üń­K—´ÍůŁGç,]ÚË×W ĐÍÖöŤŹ?ľ~ń˘ZĄBzl—s˙ÇŢu†GUmíuĘ´Ědj:é!!Ť„:„tR z ŠzŻWE/‚âŐOĄ´KQEşĄ÷zBI(! émz9őűqČ“ ˘AŻâĽĎĂdÍžuöi{ďwŻöÝwÓ_~9(,Śđňňz~ŢĽC{÷˛,»űöçţńŹ®ˇˇ€ŹŹĎě7Ţ8°{·Íň­?lß>ëő×ý ߀€Y˙úWţöíđĂŽĎżń†o@ŕ8óµ×ö÷ťÍ)aîŮ3gŢ}r&MĘßľťgCŹş©éú•+ł^ÝI&ŁbLĎÍ=°{·NŁ))*Ę{í5•TĘô<8%'çŔ®]<7«®şşüîÝç^}U.3§¦Ýżż±ľľşĽ|ú+ŻČ`pjjż„„Łű÷wčćT”–674L}ńEG22˘úô9}čPUyąN«}fÎ źŹ$ee…GGźűl…ÉdŞ««Ű°á‹’$Éăń"""V­Zm6[jjj׬YËĄÖ …˝zEż÷ŢűuuµE]ştyѢ˙´dÝh[ńYŻ7\ľ|%44X,Ť&łŮL’”«««““ęôé3rąÜĎĎoÝşuA––Ţ߸ńK@@Ó´T*őňňZż~IRwďŢűňË- }Ŕ9´ŠVçŠksgg%5E;99)ŠŤ7QUXXxřđŃŘŘX“Éěââ,•:nŮňMÓ×®nßľC 2 ăččHä‘#G1 ;{öü·ß~' ­5Đ(Šôőőáńx+W®Ňé´fły÷î=_~ąY(¶óe-/ݍ®® ÄqžŃhäŚZľľ>A †={öŇ4{âĩÇóů|š&üŐjőľ}űiš9věřŃŁÇů|A»€{«—ćĂ|>˙äÉSGŽĄi6?˙dž††ŔŔ@Š"[ś<^łŮ‚˘¨T*eú«Ż¶ž>}†ĎçµđşźÂM&ÓŕÁęëëĺryxxAVŁĺźh­÷ë˝3ŰtˇµŢO“«VÇ}¶Ö0lß%.ń×öÍĎĎďäÉ“JĄňOŮZĂĐęEf•p I˛¬¬Śű\^^nuMüĹZ1ĺĺĺ]»vµŮ¦e=zʢcdŃ1˛ľý~Ö7‚u ‘EÇHűřÍ÷´eűŔŽż _{8Š#$ůé§ËŹ=:kV^~ţţmŰľAöÖ­›k×®őđpßąsű–-_655}őŐWÜ6V‡sjeY™ÂÉIáäÄUUö ˛Ízť®˛Ľ\ĺě,W*9y@·nfŁQ§ŃŘ"$ĺ÷îązxHe2€ Ókµ&ٱĽ´ÔÝËKâčĐAááÚćf[ ¸玗źźX̵ŽhŞŻ',–˛;wĽDś<$2˛ˇ¶Öl6ŰęĎ˝’ż  ľ@€PˇQQµUU4E•–”óř|€‹ŠŞyđ€´Q)¸W\†a€ďŮł˛¬Śa{ĹĹAáá(Šňh€îŃŃJKiU:€{ĹĹÁ‘‘)eşGG—ß˝ ,{ݏ8¤ENtďŐ«ěÎťGlÄÜ+) íŃŕĘ­vŹŽ.˝}JKJ¢˘VúKKJŰřýŰ·Ă{öäÚ@xTÔ˝’¸çNXĎžt‹<,*ę^q1bsxŁËďÝ ‹ŠâÚŁ(QZ\Ě2LĹýűˇ-r Ă‚»w/-)±sH’dUyyhŹś» ŹÇ ˝ű6EQŐ„´Čů|~×ŇŰ·QŮl6××ÔGDP€P$ň ,»s‡ †şşnݻӀH,ö(»{×5ęőꦦŔ°0®˝D*íâăSq˙ľÉhÔ¨Őˇˇ4 ŕ(“ą{zVÜ»g«?:ŤĆh0řwëĆ r•ĘŮÍ­Ş˘BŻŐšM&ż  ÎÉJéä¤rq©*/Çl<„ęĆF’$˝¸öή®2…˘¶ŞJÝÔÄ0Ś—źWÓÖĹÝÝQ&«±±‚4ÔÖ˘ćáíÍ=^îžžB‘¨ˇ¶¶±ľçó9ÇWŔĂŰ›/Ô×Ö˘6^ŇÚŞ*‘‹‡7÷{ůůˇ(ÚÜÔTWU%vttvsC©ˇµÝ?tP‡ŤeŮŻżŢšśś-ĄEŃÁőŐW ń#Fä,^Ľôąçňx<ÜĂĂ˝ąYùލ1bÉ’Ą3fĚäńxîîîGŹkťš‚ úR«5­ @ÓŤ†eY>źź““˝rĺŞçž›€89©˛˛†!˛łł–/˙lęÔg…Ba—.……EaËĚĚŘ´ióÜą˙°XĚ …˛˙ľ\ié6IGX–U«›üń@nîHÎe‹;G©TöÍ7Ű>účĂĚĚŚ5kÖMš4E"‘¸»»]§iF.—gd¤Ż[·~âÄÉŽŽww·;wîÂĎ g“$©Őę¬'‚ u:ëź I:ťŽ¦)77סCSżúęëÉ“ź€ĐĐřř8Áŕáᑜś´yóWăĆMT(...Z­–$É€€€Ţ˝c—,YşzőWWWggg­V\FJ’¤<==SR’wďŢ3mÚs4M»»»§Ą Ą(ęç…ł–e1 ˝~ýzyyyBÂëé“$ٵkŔŃŁG<4eĘäěŮł7?˙WW™L®×ë ‚ éßżßŢ˝ßďÝ»ĎÍÍU*•ęőúźÎfM&#A`4š8ąÁ`”HÄGŹűę«­’’F’„ŃhÜu1›- üć›młgĎÁqÜĎĎźÇăqŮ2 Ůl¶>4M‹Ĺ>źßŁG¤··7çňÚbiüłäIbYöí·ß §¨Çʆb‘8Lyšš:dB?q6†éđ333M&ÓňĺËÝÜÜęëëĄR)÷­Z­¶>ám~Č•Ľ€äää={öp99ÚżŠŠŠÖ9HqĘÖ¬$V·[ë­yD¬ü]]][/­Ť´ůłuăşşşGôie-lóZWB€MßnĹl¦¨AŚFă´iÓŔÁÁaăĆ/ÂbeÍ|>ßĎö·÷ă8~üř ŤF=zôčáÇ98H†DD©T=zT$ĄĄ afذĚ•””¸ąąµ§€^§ŠD ýfÇß®]c»wghš´X :ťH,–ˇč×۶……E‡„Pe±A˝V+–H¤(úĺ–-=z÷î@X,Ię5‰ŁŁ#ŠnÚ´)fŕŔ__‹Ĺb+! S«ĄR ‚lذapJJ€‡‡Éd˘)J«VKĺr1‚¬_»6!3Ó×ŐŐd4Ň6Rą"ÚćfąBဠkW­JĎÍuW* :Ă0µZ®TŠäż+V 7ÎE.çä¶ôhš›*•AÖ|úiîÔ©.*•NŁaYVÓܬtrâ#ČęeËĆNźîěäÄɡGĺěĚC•K–Lž=ŰŮÍMŁVłš¦&•‹ °rńâ)/Ľ`•Ű‚¦ąŮÉĹXńÉ'ĎÎťëěć¦inćä*XńÉ'Ó^~ŮŮŐUckä`´jµ“‹ EÓk—-›>w®“««¦© XV§V;»¸$ąvůňsç:ą¸h:śZžFťFăääd4›·¬^=ăĹU..ęćf–eőŤłR©5·®[7cÎĄłłÚ¶†¦ z˝“LÖ ŃěÜĽyú¬Y ''uSË0F˝ŢŮѱ¦ąyĎÖ­ÓgΔ+•š¦&›’˘LłX\V[{pĎž©Ó¦É ­ZMÓ´Ůhtvp¸W]}t˙ţg¦N•ÉĺÚćf[z(’´ÍNBá­˛˛sÇŹOš8ŃQ*Ő©ŐI’á$Ý»wéĚ™‰ăÇKµ6v1îpâó/ŢĽY\T4vÔ(±XŻŐ’AS”Źwľ¨č^IInNŽČÁA§Ő"¶‰(˲N8~ňŇĄÚŞŞśŚ @P_]m1›eU8~¬  ąˇařС|>żÎĆnçzŠ˘¨ ĂśźŐ#55Ą¨čş››khhčíŰwL&“U?çł7nÜNHQ”§§çŘ±Łą?I’ňňň=:×`0 …Â^ 7oŢR©Tńńqnnn\BĽÚÚúââb??_ŹććfÁ R)““ ¢V«CBBâă‡477kµÚŕŕnÆeŤFˇPŘłg”N§»pá"MÓaaaÖ«úł!’˘śśśââvµž>I’îîîńńń†‰D˘ţýűk4ÚŇŇŇđđđŘ؉Db0¤RéŔt:ÝýűeŃŃ= …Éd¶ę·X,ýúőŁiJŻ×ôďßôzMďޱśőďĘ•«>>> ɤ1.n°P(´XĚ\ĘĘîMMMçÎťg&&&Ú××'0°«N§MLLprrâ÷ł,ËăńĘËË]]]˘˘˘„B!gl™˙DHH4(Že«X3‚`ÄËs-Ą÷C•J°n=G08¶FŚČa]\Ŕ`¨TĐŃr‡a///ĄR©×ë'L˙ţ÷ż?űě3ʇ ČĚ™3U*•¦Ł%ΛoľůńÇóx<•JĹăń,ËĽyó¸Ľyyy‰Äj\zDŠH<ﭷނ̞=Çqš¦­v?ë*Íb±~y­‰ŕÝwßť7o´ËůŚ™ 6n çYĘ6>ź?bÄČÖ·ŹeYµZýűőÍŽ?!aăĘ´\˝zE1Š˘Ö®]k6[|}} ŕááYTTäććÁĹ30ŕ‡~¬¨x`+č‘3Ú1©T ˛­†–ËĺsćĚ6›Í\‡ë9 ‹ŽŽîÝ;–#T“&ŤÇqś¦š¦†MŐét‚ĹâÉ“'á8FÓ MÓééCu:˝UI’~~ľsçľÄ5&I2 Ŕ?<<”kC’dPP`÷îá\îu™L6eĘd Ă8ĆÂq’$ ĹôéĎâ8FÓ4—DŻ×Ł(ÖłgOE(Šć¬jµşgϨ޽c Ĺâ¬,îEQÜÍB~îGDz`±‘‘˝zE·j ĂD˘ôô4–eµZm—.sćĚĆ0”˘(„óEOOĎ^a(IrbV” L&ÓС)HSSszz455§¦¦ŕ8Ć0ě3ĎL¦iĆb±Í>|˲&“™Ó#‰˛˛†ç掂 1 #I˛ąą97wĂĐśqÇq‹Ĺrţ|——WPP őy€?[„‘^Ż7őm|µ6|ퟀcRWĂ˙n;p„ŤeYggăŢgş0<@Ž Ăš5k¸°4îGóçĎ8pŕ˝{÷ Cee%Š˘}úôiĎ”Ţ}÷ÝŘŘŘ’’’††E ´uëVNaCCw[cbbxŹQ ð 6 (j±X¸, ={ö<}ú4źĎÇqś[Ôv¸ąŢŁGŹóçĎă8ľfÍް ‚ HDDDFF¶d9‚ČČČGĚtp0ŕĂb7nüôŠR‘‘A°BNŻ[6±ţ±,k±Ú¸A"}BüŰ6®üf]]í©S§ .€——AŮŮYjµÚÓÓS*•VVVňů|–eőz]«ŐĎÖ^ŽrąÉhTÓtBB Pg2a8Î e2ŁÁ Ąé¤äd ÎhÄyĽÖŚ®Ť™\®×ju “––FÔęő€ÇçË ťV«cŚŚ  V§D<É]9~ĄinÖ3LVv6P«ŃÄbĂäJĄş©ÉŔ0Ů#FPµjµD‚Ű8>ÖÜĐ`bQąą@McŁD*ĺřCSC™esGŹ&je2[ą‹8ŐXWçíď?fÜ8 ş¶VŞP‚(śśëę<Ľ˝ÇŽOTWWËŠG¬q*U}MŤĘĹeüĉ@EE…\ĄBNNő55rĄrü¤I€Š˛2ŽąŮ‚BĄŞ«®öëÚu¤If€ÚŞ*Ą“ÇÓꪫ˝ýýĘ++9Će‹ČUŞşęę.^^ă'M2ÔVW+śťAdJemuµG—.ă'N4ÔUU=J‚HŠşÚZWW×±&Y¶®¦FéäÄÉkëę\\\ĆŚgdŮúšĄł3k{ v”Éęššś”ĘÜ1cŚ ÓPWÇ1a±TZŰܬR(Fĺ榱ľ^áädKÎă9H$uZ­łJ•3b„aš9f.‹ët:Wgç¬ělM«›šä*•-Żwź/‰ę /_MkÔj™RÉăńBaťŃčăééď驥iťV+S*m˝ˇÇăŐ›L~~~~Š2čőRąś/`8^o6uíܵ«š˘ Tˇ°ĄGčŕ€ h˝Ĺ‚„„4“¤Ůd’HĄ‘h đp ‰$-‹D&łĄÇA"a¦‘${FE!ŤA’¤X"á 4M7’dlŻ^ĐHE‰;JĂĂé‘8:’$ŮLQýűőc,–eEbGG‚ š)jŕ€,@˝Ů ˘_ÚWµăďBظ¤#í›Á•uâJW[ĺÜ »Ĺ)ÎĐˇÜ µZÝZ¨Vk:üm›EŞő3Ç%¸ö&“Éôs»pK¦ŻÖ„Ť ­§Óş3VŻ'š¦őúÖ‡6Y§p};űuk $Ir^(VËUë?­—‹ăTmTYóŕ·?Ă0‹Ą=h-¤(ŞĂÄmbŘX–mÝ ë·4M[W¨Ön·A‡ňÖúŤF“Ő,Óúî´‡µŐ×Ńhě P¨őŤfćňĺ+………\é<ëÍBlwýe€ \ˇ0V!—Ć'b%%Öot»v˛nnHs# ry‡{hśiČJظĄĚ‰'Z·9yňd‡[€çĎź·J:Ô^y돀Ĺb)..nm»xń˘w÷ąG´Ă|ú—/_ćńxśď.×&66¶őqĺĘëĆí#˘ÝXÓž=m•.n?}ĹăéNîŐřs”ěłăŻ@ظźĺ‰_~yîëŻżŽ˘Č—_nŮľ}§źź (ęŕŕpŕŔÁ.]şp»]$I1Ą‰¤Ľýüëëë««ůžž@IQ‘P$’Ędžľľő55 µµî@qaˇD"ł±¦¤|«**šx..ŔÍ«WĄ …Xě۵kĺýűę¦&ÜɉK{ P©$R©-=ݺݿsG§Ńŕ Pxń˘ł›_(ôďÖ­´¤Ä Óá2píÂWwwˇHÔˇ 04ôöŤŃýűŁ pµ ŔĂŰçńş†„őčÝ‹1€«çÎyúřŘ" @`XŘŤ+W¢˘Pˇ¸rö¬O@Šaˇˇ×/_Ž0 Ŕĺłg}»vĹlç`‚ /^ějÂqŕňŮłAA€ aa× ü»u3aÂɱ zőüyꀂŔĺłg»†„@×+çĎ{ůű›X–˝rî\`h(k{lľ|ö¬‡—— €¦é«çĎ…†@@pđ•sçWÎźOÎČ0ËőË—Ńźďéë{őüů„ÔT3€Éd*.,ěŠńx]Ľ˝Ż IN6ŚĆ’˘˘ŔĐPƱ‰\»t)ĽpaP|Ľ@ŻŐŢ-.čÖM :»ą^Ľ80.ΠÓjKoß¶ĄG,‘(TŞ—/÷0Ŕ ijzPZę۵«H,–)7Ż^íÝ·/ĐÜĐPYVćHŰxxd …Řѱ¸¨(:&†h¨«««Şňňós”ÉD%ׯ÷ŚŽ&¸ÍŰĎĎ–Ął3ÎăÝ˝u+"2’¨©¬T75ůwë¦P©˝W\Ţ˝; PUQˇS«}m÷ÇĹÍíöŤ÷ďÜ €Šű÷Í&“‹‡Žă7Ż\)żwŻ[·nP~ďa±¸zx06ô¸{yÝľ~˝˛¬Ě? (-)aYVéěl1›oVUTřůůqq›(‚¨\\ÇÜćżmóü˙Z97#?)y{–§UţdŃqŇ‘ż(:t‰ü[áçuŘŘżčYH$âŹ>úřŮg§řÇĆĆŃ&ŮÉSäˇÓ#‚€á‹ tH0رBŁŃübŢŽ?íGĄ‹/r5Ü®_żŢa1·«WŻq#řőY´—t|éPôá?@{ňřO_„´˙@V »CŁŹűţ4T’$™””šš"‘FŤéŕ şsçŽP(¤iJ«Ő&%%FFFpĺCąÚ-lu HJ*ştißwßQjaÝ’%RąÜËĎo@b⥳gówě šőú˙~ň‰ĘĹĹ·k×ׂ$@BFƩÇíÝË4j4«>üĐË××ŮÍmHzú±üüŁű÷ł jőĘ>đ tëŇ…±ˇ'%;;ÇŽ“@]căg‹…DFĘäň”ěě˝ß|súȨ­Ż_ţŢ{Ý{őRÚ0¶iŁFműâ‹‚“'Q€Şšše Ć  rpH5jëşuOźFŞŞŞ–.\Ř'.Ζ1Č=zăŠW P€ŠŠŠ%  NIááxć1–-+Ľx(/+[ş`Áôtľ@`‹fŽłćŁŹn\ą‚Üż{wé‚ÉYY‚dŽ˝ęĂo]»†”Ţľ˝táÂÔśÔ¶Ĺ/côčĺ‹•ܸÜąyóÓ÷ŢKĎÍ€ôQŁ>}÷ÝŰ7oâ·Ż__ľhQĆčŃŹSsr–.\xďömŕÖµk+?ü0sěXA’‡_úÎ;Ąwďâ7Ż\YóŃGĂĆŽĄmt†/ IK[ňÎ;eee8@áĹ‹ë—-6f †ăSR–ĽóNEEpµ `ăgź ;–˛můé;dČŇ *««Q€K§O˝vmFn®P$Š8pé‚Ő55(Ŕ…'¶}ńEFn.iŰŚѫײwß­­Ż€3GŽěÝş55'ÇQ& íŃců˘EuŤŤpęŕÁýŰ·§ćä6‰[—.ţAA+>ř A­fŽćçÍĎOČĚtruőňó[őÁM přűďO:”™IÚĐă rqYóńÇj˝žřaÇŽKgĎLJňôń‘)ë/Ö Ëîß¶­đâĹA))„Ť‡'(,ŚÇçľ|ąÎd"f÷W_Ý-.Ž80 8dăŠzł™ éť›7——–ö<´ńRtďŐ˨×őß˙ ÂDQŰ6lh¨«‹čŐ+4*JÓÜĽuýz#IšHrëşuZµşGď޶ôÄ PőŕÁw›6YhÚ`±l^˝š$Énáá=űő+żwoçć͆ћ͛V¬ ‰Ś¤o|ű׿ţ%—ËwďŢÝFţĘ+ŻČĺňüüü6ň^xAˇP´ßŇÍËËS(ÇŹo#ź6mšR©äĘö´ĆäÉ“U*•ŐeĆŠqăĆ999]ąrĄŤ<77×ŮŮůúőëmäŮŮŮ...%­¶¶9ddd¸ąąqŮz[#55ŐÝÝ˝ĽĽĽŤ<11ŃĂĂŁşşşŤ<..ÎÓÓłľľľŤ|Ŕ€ŢŢŢMíbDűôéăăăcőб"&&ĆĎĎĎ–Ůéw´°ý•7JŮ g˙mö‰Ůö…ł˙ŠÎ]&“ąwďŢJĄŞwďX…BŃÚĐ×’šň©X)rFF–5??›HK űE¶nÝ:Ź˙m·;´îr›‹VuřŰÖĄc:lóXµeXZů‹R˝z?üŔ៯q_aWŻ" ó‹WŇ;~>v2 C‹Ĺb''•łł“ĹB€‡‡ʇëő:ĄRa4ŐjµłłRUU‰˘X,抸t°†‹Ž’–vęŕÁ3GŽp%M†Ź§tvv”Ɇ¤ĄËĎ?qŕ7^§<óŚsGĹÓ8==űöŤKIůqçλwsJÉΖĘd=űô”’˛ďŰo÷÷šśť­pr˛EŘz4 1qǦM;·laĆA"IÉʉŽ ęźđí† Űľř‚e©\žś•ő0ţ§#˘Ő?!áü±c›W®Ü˛z5Ă0ή®IYY<>żBÂŮŁG7._ľiĹ –aÜştI>\dĂRG NI9wüř?úhí'ź° ăíďź8|8ŠaSRÎ=şęĂW#Ë0ľ‰Ă†ŮňÓf†¤§ź;~üÓwßE„e °°„ĚLAâÓÓĎ?ľäťw8yp÷î ¨m×Ę„ŚŚóÇŹôć›\űî={&¤§@bffÁÉ“ľţ:'ʉ‰OOgm¶ÄaĂ.ś:µčŐWe¦gź>C†E$iřđ‹§OżűňËś<ş_ż¸ÔT[o8Ź—<|ř•sçŢyá®}ďA&'c–ś•uµ ŕßĎ?ĎÉűÄĹ LJ˛EŘD"QrVÖőK—ć͜ɵď—Đ/>žĎç§deÝĽzőŤçžăäűb‹ I¤Ň”¬¬Űׯż6mk=(99fŕ@±8%+ëî­[˙ś:• Şś’3p eCŹBĄJÉÎţďÇż:y2 Ë0qC‡FĹĆň…”ěěu‹żźź5~|Tź><µĄG)‘ä>óL`XEˇpääÉÝ{őB9ůÔ©])‚ …٦L ďŮ·aťfśĄŇ1Ó§űtíJ„Ăčgź ‰@śe˛±Ó§{űű!‹ÇLźŢ­{w[ŢA,€«R9ţąçşřř‹ŘŃqüsĎuíÖ pS©&ĚśéîéIX,©tÂĚ™Ź ZÎÎóň\ÜÝ ‹E*—OĚËóőó€.®®óňś]] ‹E¦TNš5ËÇÇçyPĽ<<&ΚĄrv&,…“Ӥٳ=»t/OωyyJ•аX”ÎΓfÍňlqGďľ>>óňdJ%a±8»ąMš=ŰÝĹüüü&äĺI Âbqńđ4k–»íŘ3A‚‚Ć?÷śŁLFX,î^^ňň\•J 08xÜŚ©”°XşřřL9ÓŐ†?-G »w3mšDB„·ż˙řçžs’J€ČČŃS§ŠÄb’ |şv;}ş“ ZŔQ4<:zä”)‘"É€ŕŕŃĎ>«‹Q€“& „BŠ$CCs§NUŠĹ¶\"yŐ§Ďđqăx|>EQ!‘‘#'O–‰D8‚D÷ë7lěXźOSTXTTΤIr‘Č–†ő<8}Ô( ÇiŠŠŚŤ>nś„Ďç!H߸¸ˇ#F`8NÓtTź>™cĆ8 6]=q|`RRňđá(Š24;p`ÚČ‘bO€˘’“339Ďü>qq©#FH¸”?Z2yĽřôô¸ÔTîω‰IƉ0L„a‰’“ą°űA)) ™™8në%•đů)YY}‡ a$>=}pjŞEĹ<ŢĐ#zÄ2 ‚˘‰Ă† LIÚĐÓiii aaamäÆ KLL noŃJLL l#1bDRR’żż{ËXRR’ŹŹOůرc“““Űçť?~|JJJű}çI“&Ą¦¦şąąµ‘?óĚ3C‡uvvn#öŮgÓŇŇT*UůŚ3ŇÓÓŰ/“fÎś™‘‘Ńľ|n^^^fffű\k3fĚ6lH$jÜáÇ …Â6ň)S¦dggómř?±ŐÎá}ű¸O úĆěě1÷ďßůKÜł,«×ëoŢ,”ÉÉÉĄĄ%(ŠýťVPWW}÷îťŕŕ°°°î”ŰŠüţKßâ’’[^^>>>ţ4ýä ) …"))ůŕÁC°mŰ·iiCE"Ń!ńGŹ€]»v$&&:88 0čÔ©Sđý÷{âââ7éHëÓHCDŻo“R.—‡„„—ÜĽyłýú÷MÓ8Žă8ŢŘXßv AX>_îë<škWÁF (ëv†V«őńń™LV[[Ý>¤A†††ŔŔnŕěě\YYŃ>ÜEŃĘĘʰ°îĐĄK—˛˛{\;ţđxĽ‹|ľ WlďşÚ–e)šf¸äQE[?34†áe÷ď&“‹“łCÖ\Şüęz=–$X8.YéÚĄ©©Ďçß˝{oÆϝťťRSSÝ»wWVVM›ö¬łłÓ{ď˝/—ËGŤAäŞUkü¦M›ćä¤2 55•y3ňFÎ~aćĚ™Öý^ €€µŘ¸bgK €„&Ď™3jôhs'ôČbÂÂŢY¶,.!Áúŕü– Z€lioK2€`OĎ {÷FôčAµÓĂéi#G_™,ż°ĐËŰ›±ˇ‡ř%9<ůü‹uu2ąÜŞśÇ+`[úo•ó[Ҷ–s‡đBŃŰŃ:ÔÖVűGčˇ)*€Ç«řy‚ŕ_«Đj4QÎ΢őć?€Ŕ•Ţ"¨_’Ł•Iaa÷µZ}+弎ÚŰ’s§čÚµI©©ĹUUšÇĐĂo).ÇXčVý}ö%h)AŢa(ð‰$44\«Ő\»vé©<}†aär…L&zÜ#íx"ď…Lúpńl'lvüŠEÍĂ‘ÂPüŇK/ŞŐÍ •Ę<=»pŢ’ÁÁÁsçľŘÔÔŚ ‹‹‹»»We”µ»ßÚa‡vŘńG6™L~ófá_˘Ó|ľŔĂĂ“$‰ŠŠ˛öŽň† ‚ š››˙üó×B"qtsóŕńř„O0¬X,vrr–Je⧲ř/Ă0 …R,˙Ő­ÁŹ©Tj¤ZŢë_Ú}°Řyšż‰ęłŔ•»¤(J$…††pMÓApN Bˇ0$䡜˘(Nn«p¶vŘa‡vü^„M­nňööű+L®ŚŮlvtt¤iE±Žl‘,MÓ<ß××˙é»aśŽ‹‹›‡G—ŽÜ–ehš‰ÜÜş<ĄŮ†ˇ;¬€ôôáŔ~~~Ôß>ç!‚ OźsŻš9…KÎ@Q EuŕĽÖˇśe{†;ě°Ă;ţPÂVZz77wâ_‚°]˝zéĆŤB©Tš‘1âďvĂŚFCAÁ™˛˛RWW7Ňvi`šű÷/ľ2eŠýR´Y[#ý2Řń;P¶_ż„ v¶f‡vŘaÇKŘ8SŐď‘v(˛u!ö?}‡ź$Pĺvyű˘őiGűB"vŔĂ:'ö‡ßŽ'7¨"(Ŕo,Yů4•…´Ă;ě°ăŻAŘ8üůジ"pë6.ŕor·¸ň®v˛öÔĂ`0|úé2ťNggćm`÷Ť´ăÉ=LŤMő ĆßXóÁ0€ĄiF,–(:S…G €óxb‰Dů[“ÂYő &‘Jż&`ÇzD*—+~ećĆ6p‘ÉĺŠViÍD€ rą\ö$=rďd5I ÇAťÎCŤĘd@'o:  S(A”-yíóĹq”ËQ•·ŻŇűkŔp”J1 “unM vtÄyĽNs‹Db1ŹÇëdD"_(ěäő‘„BˇH¤lż ˙•J^đßąvÂöË‹3>_`6›Pĺ> Ň&7ŕ/ş˛ (ĘăńąßţŐö Ýż‚ČČHÇ0Ě~»ŰC­VŰ/‚ťË02™Üh04ë~{őQAD"ˇĘŮy×W_5ÔÖťČP*‰*JKwlÚtűĆŤG¸»?Žž†ÚÚ/W­:}ř0Ő‰Ý ˇP¨Ój˙űńÇ®]ştfa łyŮ»ďĘ ¦ŹÇchú˙ŢzK(ufXä¦ŃE ˘ťË˘Ě2 °ě‚÷ßďĚI!ł™f˙ß˙uć¦#˘mn&,–·>ţřWýůĹ©«ŞŇiµo}ň‰ŮlţÍz0 »űvC]ÝŰ‹wĆ[„‡ă×/_~p˙~'őđůüóÇŹ—ŢľÝI=ŕřŹ?j5šN^ˇPxńôiľ@0O"ůÍ÷K$]:}šű|ăĆŤ‹/¶/(jÇźaÝţ¤U[Âö§Z ’$yăĆÍĐĐ‹ĹróćÍö©&~Ń•Ĺh4–•Ý ~ ’ ţM2mŘÁUv¶_;ěř]‡S•ĘĘĘJsš¦ŁŁcśś]vďýţvQagĆgEëkkOŔ±ŁGßĚË»|ófsçnú¶mŰÖ-^|äÔ©Îč¬\±âX~ţw»w«;÷0/x睪ňň5ëÖi:÷rÍ™=["•.z˙ý߼5+5sććŐ« ))iÚ´iöAýω ü.„Ť3X98Ű75ô<+ĺâ †ĺ>´ⲺD"‚a@ ha5¬ĹbáÚsěö ZŘp„zýb„˘öw;ě°ĂŽ' E+++śbúuďŮ÷·UÎŔ0¬¶¶ş¶¶Ş©© Ă1  3 @PE;§‡3?ˇŘëÖąÚŘĂÉ Ĺ:·ăµ:ŻÎ÷ë¤˝Ź›Ź;w…­Ď!w×:yÓ9O´Ó7Ĺ0@Î?<(Š"ňΫĺ:w^ň$΋Ëx×ůţpz:s}0¤ĹÚlw˙;  Ă0ăĆŤCQ‘Ëe\Ća+W®ü#˝ 9&†ă8÷Çqö.‘‚TUU}óÍ7·oßa&88833# €eYnd~RTðâââíŰwĽýö[°ÇpËéŰßL;ě°ĂŽÎA, źÇ‰~łGGiUU9E‘ ĂPťKÎA°,KÓtçőCQO ?ô“ĐÜy1ťÔò\:?—S8Ţ 4Eq˝ę¤…ŤjŃÓ™‹Ś¶ęO'gÓ,űúCÓl§őPONĂ0ĚŇĂ>‰—ťł%tFŐĘń„üŘń« G Ôj5Š˘,ËlŢĽ9##eY‰D‚aŹÇ“É„˘(ŹÇăv>hš&IŇjćÂqścY$Ir#Qk!MÓ†e·WŘŠ›±\˘†{á~žt„#l‚Ô××oŢĽůÚµk\÷nܸ!;Yy×’ÇăqüŤ˘(kŚ/†a8ŽsG·ĘQEá8β¬5ŔT 466nٲeţüů|>ßd2á8Îçó)Šâńx4M[,îZqL˛őPĹqśK&A’$g6l-¤(ŞýEc†» ‚2ŚÝÂf‡vŘŃi°€˘(—1â·% Á0Ś$IAPűö¶vŘa‡$aăčÍž=»9âäęę¶gĎnš¦kjju:Ă0AÔ××sŽ"‘H.+•eŮĆĆFÁŔJĄRNŘÔÔd0X–uppJ;HĐj±Xęęę‚@D$Éd2E¬®Ś\ŻX–ł˙±í;L’äůóç·lůjţü2D$ť>}ú‡~´6`Y†ű±Z­6Ť‚ĹbGGGî[“ɤŃh¸©—“€Ůl®ŞŞ‹ĹZ­ŽÇĂ]]]ąţ †ĘĘJ‘HôŕA…Ĺbqqq1ŤUUUZ­–Ďçs­VK’$Š˘b±X"‘p˝%I˘±±‘ăxR©T(°¬UhĆ0T"‘Ĺb®«z˝^«Ő1 -¤R)ŹÇ`žÄޢvŘa‡­ç‘ßV‡íQ2ú1ü©ŇĘA‚}ŚŃÜV{»»»žGëy““­öV9űxK.[í˙Wzěx*¶źX–Ńétz˝NŻ×€^ŻS«›ŁŁ{m۶-++;>>ĂĐŠŠň7Ţx#--}čĐ´ ŤFî‡$I¬^˝:;;;3sŘ®]»Pá„k×®ÍÎÎÉĚöé§ź2 Í5¶ţcúîÝ;˙řÇ?RS‡¦ĄĄđÁaaYë“ÉpV5®q›Ç•e­VłwďŢiÓžMKĘăáEöęýŻýÓd2ZË5[¶lYfć°ěěśĎ?˙A€ĄięÚµk/ĽđBRRňđáY+V¬`šÇĂoŢĽ™––ľqăĆ„„„iÓ¦9:JX–áńđ+W®Lž<ĄĽĽ<$$4//ĎŃQzůňĺaÆŻ_ż~Čřçźźăŕ *(8ź———”ťťłaîۆVUU-\řnjęĐ)Sž9wîŹÇĂ0´şşúý÷ßOKK3fĚÎť;1 EQDŻ×óÍ7ŮŮY ‰ŻĽňĘőëE<ÎŃNűSk‡vŘńD€´lü1żÖęŐ˘8Ţ ÖzŇĺäčcx·#6Ú#ŘŻÔÓşý/ĘłěWęÁţ|zÇ?bE…ٸé6=řŻÔwZŹ­—éÜKOčĄčđĺÂ~ĄěO ÇŽż ak™„Öą:†Ńh4gÎśť?ţúőkÍfó›oľ?déŇĹ|đ‹…ŘĽy Š˘EíرóÂ…‹óć˝±pá;·nÝ’$÷îýţÂ…‹o˝5ďťwćßż˙»ďľă ˇXˇÓé,x7==můňe ľŁŃhľţúk Ă8c×#kßÚ¸ęrĆh4ŢşUrä™ěěřČČńC‡ĘĎt°ŕř“‡ ‹ŹŚś‘qüŕA®ö4ŕŘŹ?NĚČŹŚś”™yâСG'ĆîŰ7~čĐřČČg˛˛Î;& ŕÇ˝{ÇĄ¦ĆGFNÍÉ9{â„ŕ—ŘČţ;F''ÇGFÎČÍ˝p挰ĹĆňýwßĺ&&ĆGF>7fĚĹs焏Ôò쮭[GĆÇÇGFΞ0áęĹ‹ś†avlŮ’3dHBdäśI“®]ľ,|ä‘"Éoľř"{đŕ„=^š:őƵk"€$Ż7lČ4(ˇGŹ—§M»YT$˛­0™L_®Y3lŔ€Ä¨¨×ňňJnÝ`FŁqăŞU™ýű'FE˝1{öť’á#/˛^§[÷é§ýú%őěůöK/Ýż{W€h5š5K–¤÷í›ÔłçüW^)/-}„€ş©iĹ˙ý_ZďŢÉŃŃďţë_•ĺĺ@Scă§˙ůĎĐŢ˝“ŁŁß㍪Ź|xękk/\›Ň«×˙ýűßµŐŐ|>@]MÍÇ3“óń‚őµµüG>ĚŐügŢĽ”^˝†ĆĆ.{˙ýƆ>€ ˛˘bŃëŻ'GGíÝ{ů‡675Ů‹d˙=ŃKdë /+aýű÷KNN”HÄÍÍęřřřˇC‡zzz3 %–/_>cĆt’$÷íŰ—śśĚ%lä"ÖöďĎ>|Ř#¸ĚŤ;wî3fŚ5¬‹Ëî––ćććA’ Ă6nürÚ´iśaŠŰĘäşÖ>ëðÂ$ŮŘŘčëëK„µ˙4M[Kł,«VkNž<9rä‘#Gčő:Aźź˙Ă#’““ÓÓÓT*gAGQäÁ‡¦L™Ě˛¬BˇŹÇv´P®Óh¶¬YÓX_3`E’?lßîęîꑎÖéľ\µJÝÔ;p IűľýÖŐĂc`r2Ç;ÔSÝÔ´qĹ ŁŃŘ{Đ Âbٵył»§gżřřęćć/–/·X,ś|ǦM^^1âÖˇžőőź/[ƲlďA,fó7ë×{x{G÷íű ľ~ý˛e(‚ô‰‹łL_Ż]ŰĹÇ'"&¦Ă‚i(@yuőúĄKAź¸8łŃ¸yŐ*O_ß°¨¨˛ŞŞuK–8Ĺ}ăâLFă¦+<ýü‚ĂĂ‘Žô Ąë–,‘Éĺ}ăâŚĂź~ęíç×5$ä^YŮş%K*U—¸8ŁÁđů˛eŢ~~~AA¶Ľ^ďÜ»·~éRgWW/??^ż~É/??ꀀŰwî¬_şÔĹÍÍ' €“{űű{ůůŮzŠŠ‹‹?˙ôS÷.]ü‚‚ô:ݺŋ˝üü<Ľ˝oݸńĹňĺ^^ţÝşéµÚ‡rOOÖĆŢÁÍÂÂM«Vyúřt Ńk4ë/öôőuqw/ştióęŐŢţţaa:µzýâĹžK–¸şąu¸‰KÓôŐ‚‚Ż×®őíÚµ[x¸¦ąyý’%]>ůDáätéĚ™o6lđ â š¦¦Ď—.őřč#'''¦Ł‹LRTÁÉ“;ľü2 8/476~±|ąűHĺňsÇŹďÚ˛%04”Çç754lüě3·E‹ E‡z,$yúđá}۶u ÇyĽĆúúÍ+Wľ˛pˇDrňŕÁüíŰ#"po¨«Ű˛jŐKóçKĄŇőâh~ţáᅪŚÄpĽ¦˛rëÚµsćÍă …Göí;–ź…aXĺýű߬_ź÷Úk‰„éč!4X,?îŢ}úČ‘îŃŃŠ–·qăŚW_Ĺ0ě‡;Î?Ń«‚ ·oÜرiÓÔ_tppčPŹÎlŢ·mŰĺsçzÄÄŔőË—wýőäŮłY–Ýłuëµ zÄƲ×.\ÉĺcgĚ …ęQŤ;·l).,ŚęÓ‡e §NÉUŞÜgžˇ(jǦMwnŢěŮ·/Ë0çŽSŞTY&űĐýw'l­íWś‹eY†aÉĘĘbF­Ö (úěłĎ\»VxůňeŠ˘ Ârď^)—0ٍčúÇĚöNLL4›ÍE]ştiذĚ}űľg–a«Wݵ9@ EŃ... &“‰¦iOOOggç‹/ęőzĹôzĂ•‚666étşÔÔ‚ ”JĄłł3I’ŤŤMwďŢ3›M»víDDŻ×Ýąsśťť}||>r˙ţý€€®={FY,‚ŘÓú˙ŹÁăń„BaKňmNÂ؇οáóí{”vül›’ÇăŢż_†ă\VaŔqŚe!((ĐËËK«ŐŐ××#âáááĺĺĹçó™Ž\ÔyWÎźżtölƨQź{Îd±ü{Îścůů±Ý+.ľrţ|ö„ c§N5šÍófÍ:šźăëëKu´s_pňdá… ăgÎ1nśÎh|mÚ´#űöE÷ďĺÜą˘Ë—źyá…¬QŁ4zý?¦N=üý÷aQQîîîí3ňN>|ëÚµYŻż>43łY«ť;q⡽{{ÄĆž>|¸¸¨čĹ·ßN:´A­~i„C{öwď®T©ŘŽô˙á‡;·nýë?˙ţŘŃÁá»-[ľ\ą˛ŕäÉÔ´4KG7˝¦˛ňčţýn]şĽ˝x±H(üjýú›6]-(đ <öĂ>>˙^ĽX(ü?{×U±ľżÓ¶÷M%=$„ôPB/Pé˝@š ‚Ýź"W˝zéRĄWAŠ„zoˇ ˝'›ěn¶źöűă@ŚI–‹˝˘ç}|7łďΙsćĚĽ3ß|߆+öoß~ăŇĄÎ]şÔË“—•uúđa˙ŕŕOľýV@«,8qđ`űÄDµV{ćčŃơˇ~ý5Žă+ľýöÜńă­:vlÓ¦Ť˝ľ ôăű÷Ď?3sÎEÍť{!-­]×®‚śOK‹‹{űłĎX€łgźKKkŃ®]łŘXG}ťëŢÍ›OťjŮľý”÷ß§iúë?<{ôh›.] ••—Îśi—0qćLŠ˘ľ|ď˝ÓGŹ6kÝ:,,Śu˙Ó[Íń§:6#§…$EqYŃłgĎ.^ĽôŃŁG&“‰S\ś”2›ÍR©„‹sh±X†)//ź1ă­ę©’««k­čüEĄĄĄ-Y˛,++Ëb1ł,hµÚjmVíÉ9jÖ!9#Š"rąĽ¨¨ČŐŐµf®ň,űdHÎÎΞ2ejő•FFF°‹ĺčŃc?ü°2//ĎjµŇ4Á U ĂD"ˇÁ`«%ąóuś7& CE"^oEÄh4<şvíş‚‚›Íćp8:věŔ’$I’¤X,ć’$ÉMôŻ]»6qâ¤ę¦čÓ§ŹĂa4hŔęŐk˛˛˛ăââŢzkzDDEQĽ`űßÂh¬*//—H$Ő[ÄFŁA§ÓqxxĽ*‚­ŞŞŠoÜăŔŤ5"‘xóćÍ‹-ćbD!âp8ěvű˘E‹&Nśž~fůňĺçĎźÇq<11qňäI!!!őáRT\\÷×^CäBá7ßś˙Ůg99çOśŤŹďšśŚ(D˘q3fĚ˙ôÓÜÇŹ×'Ř€©©m:őě *‰dÂĚ™ßýß˙•—”śLMíÔŁGűnݵL6ńÝwżűż˙+)(đr"ŘŽíŰ×ăµ×ZwęÄhŠIďż˙źO?5 Çöďď=xpË(W•jĘüçÓO+u:­V[ď\áĐîÝFŹŽŤŹ§Ü´Ú©}4öl«ĹrhĎž!ŻżÓŞŕáâ2íăŹĚž=zÚ4y}‚ 8¸k×čÉ“#bc^Ó>ůdŃÜą“ß˙ŕ®]cß|3,:Úŕըћź|˛ř‹/^ź1C(Ö»ăwpçÎ 3g†DD8|}|¦}ňÉ÷_}őĆ{ďĄîÚőƻ9üüü¦}üńŠoľIyűmÔ‰`;ôÓOS?ü008Řиń”Ź>Z3~ĘŰoÚ˝{ÚG4něhܤÉä÷ß_»xńë3fÔű1 stßľéź|âëççź8kÖć~1yňń¦ň‰ŹŹŹ $"büĚ™ŰWŻ~˝>Á†ǩÇßúě3/OO@XLĚiÓöoŰöÚČ‘çŽ{{ölO@DlěČÉ“ěŘ1zÜ8˛>‹ÉtůĚ™™s渻¸P1­Z NIIýé§.II×.\5w®›VK4‹Ź0fLęO? w"ŘôwoÜx÷‹/\T* e‡IůůçV­ÜľýŢĽyZ…‚hݩӣ{÷Žüüó@'‚­´°073óÝyóÔR)Đľ[·Ěű÷O<číď_›űîĽy*‰„čŘŁGVFFÚ/ż$;lyYY•:ݬąsĺ" ЧOöÇçŽD&aćÜą2ˇHě×/çńăłÇŽ%:lŹîÝchzÔäÉ‚`’ÎËĘşzölă¦MQńĆbgú šźť}ůĚ™ŽNŰíë×erůŕ×_˘(ô5Ş0/ďöŐ«„@ ÖjŤ+@0fĚ’yóŇŻ\iQź`Ă®ť?ďĺëŰořp€Ŕ°ˇăÇ/ś3çáÝ»…ąąţŤ'Šp|řĉ ?˙üÁíŰQĽ`ă[Í#Rż őŐ¨(Šúć›:¤E‹‰Ôd2&'żĆŤ[*•ş¬¬ÔĂĂa‚ H’`˝ĽĽV­úAˇs»aBˇČfłV AĚfÓ‚ FŤ+KŠ‹ ÇŽM©‡S§lťĹQF üýýĎź??hĐ@«Ő OcĺW+î‹ááá+V,ăζa&‰L&SaaáÚµk'N)K®]»öő×˙~ęĘV˙z­ß|“©U='=z¸sçÎéÓ§†……‰Ĺ’cÇŽm۶ť«¤P(¬¨(çň’s‰X–éÜąÓ7ß|…aW+‰D˘×WŠDÂnÝş¶jŐ˛¬¬|Ë–­6l\¸p~U•l˙[Lš4Y( ˘ÓUp– Ţţ¶Ľr›*|#đx2'–e™Ş*ĂŚÓSRRPaYËekÖ¬˝uëvttäŁG«V­ňôôŘ˝{—Ýn_°`á–-[¦M›ęęę őÍ rrBŁ˘Ô..(b·ŮŞŚĆÂśś°•FĂŮš6µZ,Fˇ^G= /33,:ZˇTr囄‡›ŚF«Ĺ’—•'W(0 $"¨כM¦zy0€ěGŹúô‘HĄ\ůĐč芲2‡ÝžýđaŹţýĹb1ÎŮcbĘKKm6›łúdedŚśx0vútB ŕě±±Eůů¤“L (Ŕăű÷#"0‘qqŮŮ Ăd>x‰bXµ=/+‹so©÷ľ=ľ?4:ŞËç<~ ,űřÁ°ÎË~ôč]ţńáÍš±B@T\\VFd>xËěÍ›ged ÎÂô±lÖÇᱱĚÓňá±±™@öDZ±4€Ŕ“™‘áědMÓą™™áOË3(˝hî\†aň˛˛~µăxÓ¨¨e˙ú—ł3‡$Ićć†7kF4A4 ۸lEQEůůa11ś](6nÚtË? NŮfł•5ŤŽćĘ‹Äâ€ŕŕC»w;ěöňŇҨ(KĄ~ŤůůgĚ ŹŮlÖëtMÂĂąň2…ÂËß˙ĆĄKV‹ĹXYF  •ĘÓÇ'ýňegő©2,&Să¦M@­ŐşzzŢľvÍd4Z­Ö€ήquŐşąÝ˝qsňV–—“$éÄMć\ÝÝ•MqAÖÍŤaßŔ@Îîćé)W*‹óóQ'<ĺ%%(†yůůqO±X\^RB…„@ŕéăĂŮ˝|}BaYq1ꤓ–%w//îó DQTŻÓ•IĺrWOO€đkܨ(+CůW7/Ř~»ĂVL˙×Ü ĺńăL??ßččHť®rç΂pYÎââš­\ąęÝwßĹqlóć-BQ4>ľŐ¦M›ŞŃh˛˛˛öěŮ3fĚ(ŠbjĽY¨¬¬ś€€€¨¨Č˘˘âC‡Žpęĺ©O&óŚ # Ă HĄŇ„„ÎkÖ¬őňjŰŚ ·nÝ:wî¤I«ë,‘HÂĂĂ:üĆĄRéť;wŽ;>zô(›ÍZXXńčQfZÚ ‚Ŕ›K nŞn@°Z­rąÜjµpEŞżb2™KKK›4iq÷î˝3gÎâ8AÓ´V«Q*ĺ۶í?>%77÷öí;ÉÉ˝ÝÜÜÜÜÜÎś9;jÔH‚ŔĎźż““ľäŇ IDATÓżż›7oÝąsgذˇŤF äççĂ'U>qö˙rg†Ë#_ÓRYYÉ· Ż´zç\úU*•‹‹ ·šf2™Š‹‹ŁŁŁ"##wěŘ! {öěÎ0LďŢIÇŹ§=xáîî^W ¦Ş*‘D˘BŃť{öřµŚ`hš´ŰMUUb‰D…˘Űví  ‹ Ą(Ęa·#Îç¦R™L˘›¶l‰iŮ2˘qc‡ÝN‘d•Á S(ä(şqÓ¦ćmۆúűŰm¶ę=˙şA›ŐĘŮŐ(ş75UĄŐvlŃlV+˙Ţć[­3lŚŮl悎L¦šb©}űv‡˝~ý†ÝîČÎαX,ś_bďŢIë×ořţűĺ\”–e1 KJęąyó¶%K–â8ałŮěv;'oާĽ8޵nż˙ .Úl¶ěěl«Őʲ,ĂĐ\ö6š~ňˇ^—Hš‚ âăăĎž=˙ÓO»Oť:C¸Ůl掏Ó4ĹUO&“uéŇyßľ ,DQÔd2K$b.'xddäÎť??žf6[ňó l6;KQ”Ůl©+iš–ËZ­vŢĽ/‚‚†JQ'ۆˇ(JŁŃoÝş=5őÉd.,,¤iš˘(ww÷řřřÓ§ĎšLf«ŐâîîÁ0¬§§GË–-Îś9[RR€ ??_AívűĺËW ą<ćńńń\t>qö˙D©Y,V~[ćo Ω›Ç?\°q Žv»ťóm–JĄÇŽÓéĘ{öě!‘ČîÜąëá።(Š˘:t8räh^^‚ őľ§/ ‰T*¨áÎÇ˝`¤2!G}U¨ŐPăw9ä)òĎSA*ű[žßŘ˙ĂäJ%[łţÂţÖţ<őÁ0L®PÔ,˙ÄŽă2…â‰ďÓ3x„ű]ś ¸ĂŤ5— B&—3Ďs]” (R]AX@ ‘ɸĺögu .&€@(”HĄżÎGźÖS(‰ĄR¶şG;çáę/‹ąNÁ=3Ő<"±ž&yCś÷q®é‘D"¬äiçKĄŐv~ÍžluvŘbb˘9ąS-–P7něüů ÓŇNxxx 6$++“ahAÚµkűřqć†y㍠4M#ŇŞU«˘˘’ť;w•••Ož<±ćY,–e…Bá¨Q#.\TZZćë뛜ܧĽĽś˘( ⢢H’Âq<**’űV-E†aQ”//Ż7ßśúý÷+.^<Ŕ˛Đ¬Y̨Q#‡@ Śçڵk×¶¤¤ôçź6ŚŃŃŃ'¦Řl6­V;`@˙ďż_ˇ×ëCCC»uëzć̇Ă!‘ĂÂBI’¬5$Ó4íććÚ¶mŰŤ7EFFŚ5R&“†„„p%)ŠňööęŐ«çęŐkŞŞŞbc›uëÖ-#ăĂaW*•]»&äććíŰ·ßŰŰ«S§Žv»]ˇPtîÜą´´,5őÍfo۶M›6m¬V«§§gPPĐÎť?1 ťĐ»w’ŐjuEšÇ †ˇš6 ŃétŐ‘*0 ËĚĚ´X,,ËúůůqąÎů†zgęś«6߼`«#„ Ĺb9yň”ŹŹOddĂ>>>rą˘°°P ¸ąą˛,Ëĺ)­;GĺtŐj5Đt×nÝX€R«ĂqH$S(,fł¦»wgJ-‚ „"ëd§T«MFŁ‘a’z÷fJM&ˇPH„RĄ2ŤU Ó;9™(©ŞŠĹ„“8:ŹAŻ71ĚkýűS%X*ĹpśŰ*13Ě€)€˝^"•â8îŚGĄŐVętV†rdµÝŮŔa\©,©¨pŃh†na]i©ÚĹAQ™BQZY©Q«jfО2µsś $2Y©Ńč¦Ő4ČĚ0•:ťJŁÁ0L,•–VUy¸şö0ŔĚ0úŠ µVëěeJ„H,.3›˝5ňďŰ×HÓF˝^©Vă!‰J-?ź#MWŤJµÚY§ŠDA”ŮlAM e2™JĄ@(ÄqĽÜfkÜ48XOQł™S¶őň$EËް0$,¬’˘lV«L.ŠD@ąĂ‰T¤Ýn—)•Îx$R)Ă0:’Ś‹ŤEt$IR·"CÓ´Ž˘Z¶h芢¤őťę|˛"—“$YIQíÚ¶eĘív–eʼnT&s8•4ݡ}{ Ěn±TĘż·yÁµB,îŢ˝‹¦iEwďŢIŐ𔊊\·nuőWzöěáp<ńÇ=zä1Ł8{upĹääŢ}űö©._Ë+EŃćÍă6n\_] 9ą·ŮlV«Ő[·n2›ÍŤfË–M\¬ŽZăj—Enęüő×˙ŞůOv»ÝŰŰkÝş5Ü::AC‡6lHu’$qďÔ©#—ĂŤ36¤˛RĽbĹ÷uĐ4-“ÉRRĆŤ˙:čtşČČČĹ‹r%Y–={vďŐ«G5!‚ Fch4šYłŢy÷Ý™śÝáp€B!ź0!eâÄńŐío·ŰĺrůĂGŽQmäÔ/Ż ţ| Ć… Ô´¨TęöíŰź9s–-[Úąs'>čČ« ›ÍĆ7Â?[°AMO @páÂť®˘uë$•JMQ´Ăá@QT*•lÚtÄËË+)©˲$I1ő…‰¤|uĄĄeĹĹŤĽĽ0€Ś;wDb±B©ô (+../-őôôÄ2nß–HĄÎć¦4€PPa^^ey9áć†Ü»ySˇRId2ż  üělCEîâ‚Ü˝qCĄŃ8› Ň!!9Ź™ \­Ćn_»ćęî.‰CB232ĚUU¸R‰ÜşzŐ­Q#‘DR¸y€ ĐĐGwď6oÓ•Ép€ôË—=}|p‚ ͸}»Y|<*‘ŕé—.yůů9 @PXŘ˝ôôđfÍP‘¸qń˘o` Š˘ÁaawnÜhm8»Pć\@‡‡ßşzµqh¨ÇQ€ë.†„‚‡…Ýşr%0$ÄŠa(ŔŤ‹›6}ƦMPXXúĺËľŤ[n\ĽúÄ~é’O@€€eYÎÎ:WZŤ›6˝qńb#+CÓ7/_€Ŕ/zöďo )ęÖ•+ÁaaĎZţAA7.]ęާŹ€$ÉŰׯ……ˇ(ę׸ńŤK—“’l»ýîŤĎŕ!o˙›—/wéŢÝ`łZďßşŠă¸—ŻďÍ+W:wëf°Z,wî…†2΄ŤXěިѭ«W;tîl0WUeŢż" ]=věXWW×+W®Ô˛Ź1ÂÍÍ-==˝–}đŕÁîîîwďŢ­eďßżż‡‡GFFF-{ź>}<==ą`5ŃłgĎFŤĺĺĺŐ˛wëÖÍŰŰ»¨¨¨–˝sçÎ>>>eeeµěíŰ·÷ó󫡠M›6Fٱ–˝eË–Ť76›Í˙ł6¨>Ç\ë@3MÓ5wÉŞ?WďŐĺtëéé¦Y=„Ő«ž5?Ô RíĘR÷ĽY-ăsVŹűX/[˝?T÷Og×뼆Ü;äż4ZÝËçńç ÎÝdjćg§(ŠŞsRźeY…BáĚżÇ_&ď,ŠŹżáËĹ–€¸yófqqq‡í]\´$IŇ4ĄV«,ł^Żwss@ P‘JĄ C×}!“‘Í›węŮóěŃŁNž†ˇ(ŞĎСZ77ąJŐ±GŹ“©©gŹc†˘écƸŐ‹źă‰mÝş}bâˇ={ŽíßĎ2 Ë0Ýűő“+•ÍâăŰuëv`ÇŽC»wł ˘hbż~ÎĽŃH€V;¶éŇe÷† {·laF,‘$öë'–J[uěŘşsçëÖý´aĂ02…˘[ż~˛úsB«mBÂ…“'7-_ľeĺJ†a´®®‰}űAŰ„„óiië—.ݸ|9CÓnžžÝ’“Ĺb±3ÁÖ±GŹ‹'O®üî»Ő 04ííç×­o_Ă:öčqáĉß|łĂšö ě–śL„łťşÎIIOž\ňņ±4Ú59A.IIOž\řůçś˝Ixx×>}P箕 }ú\:}ú»˙ű?EYš‹‰IHJ€®ÉÉ—Nźţ÷‡r<±±]’’ś Ŕ(‚tKNľrćĚżŢ}—+Ó˛eçž=éÖ·ďŐsçćÍśÉŮ›ĹÇwęŮó®‰}ű޸xqÎŚ\ůćíÚuHLÄ0,±_żôË—gżů&‚a M·hßľ}b"ĺ|g,±_ż;×®ýß”)Š24ÝşS§6]ş„ÂîýúÝKO˙dҤ'ö.]ÚtéB9idąBŃ˝_ż‡wî|8aWľ]·n-۷瞢Ç÷ď’‚ (MÓí»uăRDÔËŁÖj»÷ë·ň»ďŢ7Aš˘:öčÓŞ•P$ęŢŻßš fŤËŮ;őěŮ,>Ţ™ĐrkÔ(±oß Ë–˝3z4‚ IvîŐ+ĽY3‚ űőŰĽbĹŰ#G‚Đ$ŮąWŻČ¸8ŇÉCčĺďß­oßťëÖÍ>hŠJčÝ»Ix8Š˘ÝúöÝ˝aĂôaĂ€˘¨„>}B"#)'°}ű´!C€"Én}űúËvíÓ'u÷î©sö6iâ¬>! IIiżü2eĐ ®|ňđáŤ|}išî’”tęСÉËR$ůÚ¨Q>Ď)ŘnŢĽi0 kŮÓÓÓőz}]sýúu˝^_RRRË~őęŐĘĘĘşÂćĘ•+ş:At.]ş¤Óéę ž .”——× ŢçĎź/++3 µěgĎž-++«ëévćĚÁP÷ú©S§¬V+çŽW'Ož¤(ĘZ'XËÉ“' ®‡ÔŮłgŔQ'Ôí… ę "®ž-sţÁöĘçřGť?yr¦™?pú*@(8đ‹N§«^Pŕńjőµş«h<ţ®rŤeY†{Áž8qB&“ĹĆ6ăÖ×H’lҤÉéÓgnܸѾ};–eOť:Ť˘hŁFžEŐ=TĚ(E˘äˇC6ŰŐóç  Ç€­;w&D,ö>śt8®_Ľ(z ŘŞcG!†9ťăJ$ýGŤ˘)ęć•+"±¸Ď°aqmÚ࢖HŽ˝}íÚŰ×®‰Ĺâ~#FĶnM`3Ż-­L6řő×·ŻYsďćM‰Tšü—ť;­KDlěŔ1cTb1·ąTV\|p×.«ĹŐĽů€ŃŁUb±3!†Ĺwě¨+-=üóĎv›­Y|ük#FČ…B MçÎeeGöî%ޏ6mú. íNxÄ8Ţľ[7˝Nwü—_hŠjŮľ}ŇŕÁR‚`:vďn¨¨8qđ MÓńť:ő0@&8ă‘DBRR•^úČ–eŰ&$$öë'Ć0Nđ›ŚĆ3ÇŽ˶OLěÚ§Ź„ śí@Ę‚ýű[Ěćó'N Ň©WŻÎ={ QEŃžXÍć‹§Na–Đ»wÇîÝE8ţś«‰={ö´X,ułl÷îÝ›aZöľ}ű\ËŢżą\XË>pŕ@­Vë÷4«A5† rćĚooďZöáÇ_ĽxŃÓÓł–}äȑ׮]swwŻe3fĚÍ›7ë&P7nÜ˝{÷4M-űřńă>|¨R©jŮ'Lťť­P(jŮ'Nśźź/­s&0%%Ą¸¸X,ײŹ;V§Ó‰D˘ZöŃŁGëőz?đ—6-9ţË/ܧr“nĐ ‘™™ń4,ËšLĆ{÷nËĺʤ¤×=z𬹳,[T”O’T‹ńüŔµZÝ­[âŃŁÇ`çνző¬{ĆI­V·k×[9p`_§NőśaS«5aaá÷îÝă›ôU_"quu-(Č«»‡˘hAAAxx$xyyĺädrGUyü9 âęĺ˰yËVĄ%Ĺ,ËR4ÍĐ4CÓEŃŐźĂđśěl‡Őęćâ*Ć®ląS€ n"ś;iҤj‡ @€°€ă©ępf5@B»vcŢ|sĐ!¶ßĂC5xT-ÂĂ?_´¨SB‚Ł>žšĺq Ź ©·÷ÚýűŁbb¨KĽ´>žzí đW*SoÝňńőeęăq˙Íboŕji©˛F$ gĺ  ŕ˘ŽšîŐĺ™§ő¶hŠjLy,[S'.e–€úovŔh04suÍw8lĎÁ# 곣yyÝÂĂłŤFS r˘ľňÎě\ăÜľystŹ őńĐŽ§î@Îě\=O¦Ą}2eĘŐ{÷ô5xx}<őÚ@°kÇŽŐóç§ť;WŮ ŔŠeËN¤¦îÚ»W_ŁŃ§ĺąÎĹ<ÓÎ=ĚsfĎ.ĘÍ]±fŤˇŹŕéîG-žzí >eŠLˇ÷ŐWUux¸ÎNÖá©eWL™4ióŠđĂ?L0ˇîtń×8ś/éł3~ŢţڎjÎś9}ôQ]«•ß/MycrYi 7`qcV5§˙CQěęĺK]±Ôëů×wşCjTůç8 "ÂG‰|…ĵD"ć[áU_ááźqꆑH”šzX(´hŃś˘(Î}Ăápx{{Ź9|ŐŞµ#FŚĆ0,!ˇË€Żi4j’$ť˝iëď±;ĂÍCŐ¬?ś•˙«ńÔW˙ÎĘ˙ŐxŽç¬ť”g˙wxp÷Ż?§dY– ĆŤívŰÇţi7Śa…BéááÉ0üě˙•ÁÔ©SZ´hYĂťÇ+&ą+++ůM¶żńý­v­w8ęWćĹPY狼Ź:xĐ›‰¤˛¤dóŞUĎśˇ©—Z"±¸Ęh\łpˇ‡ŹÓ€ĂíB‘Ča·/űúkĄZÝ5VB  izĹěŮb±¸!+µ(О,»ôË/цE,cXváż˙Ý`€ÍfŁć?«V‘ đ™GPTŻÓ‘Ç·kÖŘm¶o +ĘË«2?_˛Äf}q ‰áxÖş˛˛9K—Z-–źˇÄí«W‹łł˙łx±Ą<ŕôÉ“Y ä …Ź5čőß-Zdm@űE˘[çĎ …ÂoU*Ű‹Ţ/±X|űÂîó˝{÷®]»Ö*ńřăTĚËŠř,ÁV3Ë=ź{Ű"‚˘(§ †ixUp§jŚ+5˙$IňęŐkaaˇ|PD˙ĽL’4™ÍKgĎn(ŹÝnp8f~ó 4d `2ÝŢPhúÚż˙ÝPžĘJ@ÓŹż8ŠBe%ř(33óüůó|4ăżěXó‡ 6ĘÉâ˲/7d­ŞţEQťN7pŕ ěěL“ÉÄßuů jčĄEE-š>˝U‡ t¤P(Z´h±lٲđđpŞ;u2™,22rëöí^^^ ™¸Ĺâf!!U÷ďRŮĐöAQČɆ Q iŔq((hheŚĆ—pE/~~~ÇŹ7Ť/Ě Ξ=;wîÜS§Néőúć‰D‡÷왺w/ś:ŐĐ«Z¶ RSaďކňĚž yy°zuCy¦L…ľúŞA$“&±+V@bbâřńăů—ú_sćĚůcĂ0‰‰=L¦*D­V5oŢbÖ¬w”J%˲ׯßXłfíÍ›7Őju×® S§NEŃôWDDŻ7Ś1ňčŃĂ6› AŠŠŠŃŁÇ=zŘjµ2 ŁŐjwíÚŮQă8‚ đR2‹"†˘8Ž7D qׂaXwŘjň4¤>O6č^VćUĽÁçAţ:5ůĐŔ‡Ă0Ϋώă(ŠÂK9óäiŕ^1Gňt.ÍżŇ˙öpÚ‘X–MOżůĺ—_°,C’ô÷×­űńí·ß"IrË–­ľľľááˇ, wîÜŮĽyó1Łkíą!‰PeĆn·9$÷H …Bîp$I’V«A™LzóćM±X*L&“T*˝uë–H$!Â`0…ÂřřÖ:]ŽărąÜfł …BA(ŠâG+‹ ‚`†$I@`0©QÚfł7äTËŇFŁqďŢ}_}őő̙›ŰŔÂÂBÍfó† 6oŢ2nÜŘZ‚­¬¬ěúőëFc•T*ŤŚŚđđđŕüoÝşýřńc†a"""¬Vë¦M›E"ц ëéŮłÇĆŤ›„BáĆŤëíŰ7Ůd2Ą¦ęŮł‡Éd:xđ`XXŘ­[·išňôôlÖ¬†a‚Đ4}îÜąĽĽ|‰Děďďź›››čp8 ÓÓÓÍf‹R©Śpssĺźiýôc‡´Ůl†őíŰwţü…µvciš>~üřŞU«‹‹KÜÜÜĆŚ=jÔHŠ˘t:ÝĆŤOžűěÓM›6[­Öđđ°Ź>úó­ĎÍÍ]˛dizúM—–-[ěŢ˝'''Ëh4|{÷ţfwL݇C‡`ófŘłçIěŢ Í›×7Ő†ňrěđaŐ©SrťS*éÖ­MW*”XĚĽń†˙b€Y° 7 ŔNÓĎj©T:nܸśś@°lŮ2OOOnJ€aŘ®]»Ž;VRR"‘HâââĆŚĂ…(«—G$]ştiÓ¦M™™™jµzčС  /\¸°iÓ¦ěělŤF3lذΝ;?k*™“ë×CZTU‡ôí \ ĽÄD(,üMIŠ‚[·ŔYžÎťˇ¬¬¶ZľsŕČXĽňňŔ×Ţz :wvÚ:;‚ÁđŁPW®@›6PUőr©.]zU¤šĂáŘ·oßîÝ»M&ShhčČ‘####‡Ýn˙ůçź÷ěŮc6›ĂĂĂGŚá,«†a‹e˙ţýűöíłX,ŃŃŃÇ %IŇl6ďŰ·o˙ţý6›-&&fřđá!!!ĎĘNVU?ţ[·‚Í:Ŕ´i`4Âşu°mŘíĐ©Lť Ďş¶ĘJXłví’„®]aĘđńĐé`őjŘ˝haňdđňzOi)¬\ űöËBŻ^đĆŕáP\ ?üôé&€»űiîC‡`ø>Fڵňň`ůr8r0 ú÷‡”ř6syë­·öîÝ+‰~řá‡víÚ˝OFFĆ’%KÎť;§V«ß˙ýNť:á8ţ÷>†ZPPđő×_ż÷Ţ{hó_ŰńÁ»$ůÄc0$$Ś»íÚµeFŻ×_ĽxÉ«Ć#‹ăxAAáâĹK˘˘˘¸25I ‚˝SSSOž<ŇŻ__°ŰmwîÜä·Ú^Ý AüýËdňęg•<řb©lA‚ęŤ7»ÝΩ) Ă„B!wVŤ¦)‡ĂÁŤzuµŠ˘{öě)(( iúôéÓŤ&11Ńh4ţôÓOEEE‘‘‘4Mź8qB«ŐvîÜ™ ú5IZxx@\ÜŻq)Ěfđđ€Ă‡ÁË ˘ŁcW©ę˝:ˇůĺmn®ĐÇÇŔâ8““#Ü˝[•ś¬ ɨ(«—ąv­‹Á€ˇč‰xBÓtLLL``ŕÚµkM&Su‹8pŕŇĄKÜrjNNή]»† "•JëmźüüüŤ7â8c·Ű·oßިQ٦M›ćĺĺmܸQ pö­[·6jÔ(88Ř©–ţţ{°Z!<„BŔ0¸x0 ĆŤ#G`ęÔßČ3š~Vdż'`úôß„ěăŞýř1,\®®ŕë f3,XŕďďLľĂąsđÎ;żz—˛,@’páĚśůkă˛,…ŻĆú(‚$yýúő}űöůúúrˇŕ6oŢüöŰoËĺň«WŻţňË/~~~8Ž †­[·Î1C©TÖ € ÝnżtéŇáÇ0 «¬¬Üľ}ű´iÓÄbń… Ž=aXyyůŽ;&Ož,—Ëë:@’pčěßáá€a› «WĂÇPżüBD`deÁÚµđţű uRČn‡˝{áŘ1Šű÷aýz90 öě“'!:n߆Ťaút‹ëç±Ů`çN8bbAŕęUŘş¦LŘľ._†ŘX`Y¸xT*?D"§Í˝{7ěÝ  ´m žŃŃж-lÜwî@\0 ś8..0bü ::Çń… ćććľ0ɡC‡H’ěСĂáŘĽys@@@ăĆŤ˙Ţ#··÷°aĂňóó˙čÍáß6WW7¨áLŚ˘čwßý‡a¨ÂÂÂ/ľwŕŔ)S&ł,‹aXYYŮîÝ{=z´hŃBą\^kÇńÉ“'­\ą2==ýîÝ»(Ц¤Ś›Ívá·ŞÄbÖˇC{š¦ąc­7˛ł4†a ĂpÁ'«ÇKš¦qçă8ĆU*UJJĘęŐ«oܸńŕAAÆ µXĚUUF^°˝˘@Q´¬¬ÄÍÍSŁqq8ěü&<^Š`〢Xqqq~~~U• A@ˇPřúú)• AL&Óť;wËËËńôôôöö SŹÎ"âÖ­[7nÜHLL:t¨Íf›7oŢ™3gââⲳłÓÓÓ{÷î=hĐ ‹Ĺ2wîÜÓ§O‡‡‡űúú:Ť¤÷ÁXŰHQđÉ'СCÝ+©W– xT”ĄC‡*OOŇfCP­^íÚŞ•Y­¦¦N-Ńj©ŁGđ>V«őí·ßV«Őű÷ďŻ6 ‚Í›77kÖlôčŃŢŢŢV«uď޽˗/ďŐ«—L&«Ű@†ť:u*''çăŹ?nŢĽyaaá;3––|ęÔ©ÜÜÜĎ>ű¬Yłfůůů3gÎýúľű®¶Ńb oż}ΛőWl&“éĉAĚś9S­V§ĄĄ-[¶ěňĺËńńń'Ož …łfÍR©TGŽYąrĺĄK—zőęU7}3Š˘•••'Ož”Édďľű®Bˇ8pŕŔĆŤoܸ~ęÔ)ĄRůŢ{ďÉd˛˝{÷n۶íúőë ő§.(€ÁÓ.‘V݆Ťáňe†ÔTđö†E‹@(„ĺËaǸtÉé¦hV> ŤĂţóçCj*të..pä„„Ŕ7ߎÿ˙ ÇŹC‡Đşuý<÷ď?Q}_|sçÂńă( ÇŹCl,Ěž , ź}ÇŽA۶ЬYý<°gŕ8|đÁ“ C.ŐŰőëpę$$Ŕ¬Y@Q0k> ńńúŇ_ăĆŤ€ôôô†¸G˛,;zôčÖ­[ëőú6mÚäĺĺýí´lٲeË–ôŻÔt‰$şuKzúÔqín4ęiš–Éd3fLONî7jÔH©TjµZ:Ľyó¦µk×řřx×iŃhÔłgƲě/żüňŮgźOś8Aŕŕŕőë×q;u\~»ÝŽ € HMŹNŹŐ;ŻuJ•‡Z­&++ÓÇÇ×ápdgçTk\ﯿţŠ[¨űᇕcĆŚ–Je=z$ó”WçĎźbšwjĺÁÇËš”r;lśËÖˇC‡7mÚôřń#ACCCSRR¤RIzúÍďż˙ţüůó†őčŃ}ňäÉMš4©7čA—.] KHH@QT&“Ť1bٲe………—/_ŽŽŽîÜą3‚ rą|äȑ˖-ËËËów¶i `2ŐoŻébWÓ^ŹĘBgĚ(fY`ÄbA gOĂ’%îV+Š˘`2a4ý\Ë_‚TUUq‘™«ż€ HQQŃ{ď˝§Ńh¸Ś©IIIóçϧťěÖá8~ôčŃ!C†„……‘$ééé9iҤ+V¤¤¤=ztÄM›6%IŇËËëŤ7ŢXąrĺ#„Baý3Č+j¶;Śďż V«Ó-‘zÁ0ő$ĹÚ˝>ú‚‚š4?„Ĺ‹ź%ŘśÝÄz+˙*,8"b0îßż?mÚ4­VKQT\\\Ź=ŇŇŇ""">|řć›oj4Š˘Z¶l™•••–––śś\Ż`+++ËĎĎóÍ7U*MÓ­[·ÎÎÎ>}ú´§§gqqń´iÓ”J%MÓíÚµËÉÉ9}útŹ=ęlYYP^sç>ŮŞęÓ=‚cÇ@(ćÎ}˛{ůÚk™ GŹ:l÷îEýş;x0dgĂٳд) (Lšô$ëĂС“§O;lׯ\))OžźŃŁ!?®]‚­ĆŽ}âŇ S¦€ż˙‘ź’đÍ7Æqť&M‚Ď?‡[·^ş`«îŃśłŰ óLÚA***ärůę"řO^g)N_ŻLrqq mzňä©^˝zîŢ˝gýú +W®ŚŚŚDQ”óo¬YŢáp|ţůśwŢy§Q#. 7ŚuęÔqîÜysć|îîîv˙ţýőë7|őŐżˇPXVVîáán6›eeĺîînµhë­X, _ľ|Ĺś9s‹‹KVŻ^-ŃétK—.›9s¦R©@QŚ«MÓFŁž?ZůŠ‚ î "ß4bÄđřřx–eŽ;ľmŰVą\ŇtŐŞUî»ví°Ű‹-Ú˛eóÔ©S]]]ëňˇ(ZXX¬V«ąńŃßßßápL¦ÂÂÂĄRÉŮm6[UU•SG–­_u8ł;M#, b1˘`0`;vh Z&Ł_ĘPHÓtË–-÷íۧŃhüüü¬Vë–-[š4i"râú… HVVVPPż„˘¨ĐĐĐÂÂB†a233Qĺěaaaůůůôs&¦3á»ď 20ě÷¶wŰę1>x±±żţż»^…ť´gLâív{YYYHHĂ08Ž‹D"__ßcÇŽ‘$©Óéš4iÂŮĹb±ŹŹĎ‰'ęő`BÄb±čőú   nqD&“yzzŢşuËjµŤĆĆŤsvą\îááqűöm§ťBŻ“ š6}ň§‹ xzµk`4‚Ő Mšüjws7ś^›N$ Ő›? VCa!¸ąĂ<Ůă€FŤ@©„‚§<%%€aż:Ęz{X %% €@ľľOěľľ Aq±Sž¬,°Ů`ýzč×h:u‚÷ŢčhČĎą<=źă*\ëČĺ_fłyÚ´i±±±Ő-É㥠6š¦ŞĄ¶^˙«xĂ0¬K—.[¶léŃŁűW_}]PPđé§ź„€ah‚¬YłŞf/傼˙ţv»]"Oś8‘˘(‚ ú÷mőę5łf˝kłY•Jeóć͆ m۶7îuŤFł~ý:‘HÔşuüرă\\´?ţ¸ŽeY˝^ĎmÁéő†ęÉ:Ă0d2ŮŔý—,Y:jÔh‘Häîî^XXÄMî1 ź>}I’ …üő×_çËQÉ$•<žoHEř@FiҤożýöťwŢ …$IŇ4íě,<Ý´Q«ŐBˇpÆ ÉÉÉ®®®UUU,ËŤF.üŘúőë_{íµjű©AŻ^`±€ÍV+Ěź @ÇŽżŃ`ÇŹ; :‚˘őěäĄAeĺ“( ÂŚŕáĎ7˙ĎŢyÇEq§ü3łŤ-lˇwQEÄĆQ5‚Ř5ön.ą3ą¨ńrjSżó}ľOĂ 2ňwD"ěŰŠŞ(‹±˙{ńtPĄ×ëťśśŇÓÓOź>=pŕ@…BˇV«Kĺ©©©gĎž8p \.g+ T©‡}I×E °ČkPXćŹeĂYmBáë]&‘Čň/ 3XľÖ°ŔŚŮ GGDGŁ];¨W‹áęŐ˛â"b1ŢźđÂíŰ·Ź3¦M›6Üűĺ-lĺ–śČ~X˘VkJGR??żéÓ§Ż_ż®Ü@O° c~6$¤ehh;6Ř]Ż×łQ E…‡wüčŁ.¬ś-ŔĹăń"##˘ŁŁF­ÖđůüNť"»u‹fŐĘĺňďľ[ V«•J%ű#,Ď~ĺóůQQ]GŤˇŐ–ÄÇÇ{xxĐ4- ÂÂÂ"## ‚ (ł^o¨idÇűa»ŻńFçŕŕŕ°j° †Ö­[ł5BBZ1 }ęÔi‰DxţüyWWWąÜ>##C ¸¸¸0 Sôrѽ•a™L¦×ë5Mxx8Ă0999<O(Ęd26¬S§N4Mçääđů|‘•ůśFąsńŃGĺyyX˛:ÔđI:ůĺ—Á¨ŐĽ]»T»w«Z¶,ń÷כͶ®‚‰D˘•+Wúřř|üńÇŢŢŢ:ťnçÎť7nlٲe•H†a E~~ľ——Wll¬ÉdĘÎΖËĺA°r77·¸¸8“É”••ĄP(^mlŢ ŔRĹqî\tëĚg*Ä IDAT“ ńńŻq 4Ťź®BîčŚ Ô­‹‘#ŕĹ 8:Zł‰ ?ýTQÎć#ýďUo˙ÎĂÚQąąąNNN111ldŁR©äńxvvvąąą®®®=zôĐjµjµşş^ Ă‘H”““ăéééăăS\\\TT¤P(ŘG 77×ŰŰŰ××WŁŃ[é ;;…ĐëQż>ę×Eˇ¸ „B0Đ 4€ŮlĄtŞeŤ$a4"00›ˇÓÁŢŢb¤™LhÚÔňÁ`€\^­©4 “ ÁÁ–íÍfČd–…łl- Ö(“Ył?K­5;bëV¤¦B©„ŃОbóúŞ+}ůÎŕëëRU—[°V˛ÔZ{i˙›‹‹‹¨ŐjµZóňŹZS•ÓŮh4i4­V[ŢR2 ĄňŇčDÁ Ńh4‹śýĘúÄYłŤ ‰d?Ľ`-_ŮřŠeË–?{–vőęŐ˙ýo{XXŰ×Űh4ľü]%śµö—›b1śµĆÁÁQŁ †Ńëő;¶oĐ Á÷ß/íŐ«wŻ^}6oŢҦM›ćÍ›jµZ’$ĄRéˇC‡Ż]»ÎV«7™ĚtUe")ŠňôôĚĎĎĎÍÍ5›Í Ă<~üŘÎÎN&“yzzććććçç›L&†a>|(‘HäryŐĺËńúEGŞ·GĹĹdQŹÇC\\ZÍ+.&kĹ^ŕńxwîÜ‰ŽŽvvvÖétAÄĆĆfeeUęIÓtýúőďßż˙˛ęńŰoży{{“$Yż~ý»wďšÍf¶×Í›7}||jZŐY*ŧźâćM‹3íucĆŞś!ü®[ÚĄKhÜřµOĐű\t„a;;;—Ű·oł]—JJJRSSŮŇťNNNwîÜŔ†ű¦ĄĄŐ­[·şą–D"Q*•÷îÝc·×h4/^Ľđńń‹ĹrąüţýűL&“Z­ÎĚĚôńń©öˇP*!“YşäČζŐ ÄbÜľm‘ge!+ËZ6''đů¸wĎňőůsŔŰŽŽ ɲdĹôt¨Őe©h•qwEáńcË×§OQRww¸şÂhÄ“'ů“'0ŕáQ­77ČdżsϲĺsĽ˝ˇŃ =Ý"Ľw>Îđ—_~iŐŞ÷ry»›ďű~aggGQt˙ţľürF@@ŔСChšpüĺŕńx>_pďŢť';v0++kŇŔÁÁńĆ/=lŕСĂ7oţ6qℝ;ŢąóçAž8qââĹK‰„˘¨˘˘˘ČČȦM4 ĂXzĚTVh2™Ú¶m{çÎťŁGŹŇ4]TT´uëV{{{OOĎÖ­[§¤¤?~ś]pܲe‹JĄňöö~«ë‰ ˝x±kb˘RŻ'%Úl&věp IŘŮ14 ©”V((’d¤RZ©¤x<Ćúô]&“±^/©TĘVOˇiÚÇÇ'!!íšMÓôŽ;ärą šMŠ˘şvíş}űö[·nńxĽçĎźŻ\ą˛]»v|>˙ŁŹ>Ú¶mŰť;wř|>+  …Ő®Í}ü1ŽłĚq5,ZOOÔb+¤~ýđÍ7¸{nßĆĽy‹ű˙¶2ŞP(7nĽfÍšśś‚ ’““<)“É6l¸víÚĽĽ<‚ .^ĽxäČ‘ČČH“ÉTĄ•îââR§Nť 68sćLRRRűöí=<<6nÜXXXČ0LRRŇ… :tčPmngýúpqÁÂ…–|°={pţ<:uBť:P©°d JJ`×.\ąREKŚR!bŮ2KŇÚöí¸{~h)g˛bŚFĐ4ţ÷?<~lÍ›Śâb¬] “ …M›•…´hü|lŘłf36l@AZ·®VO›6¸}۶YľnÝŠ/P§ڵãGض +V€ ,Ţż0}útGGÇ˝{÷VO›6ÍŃŃńŕÁĺŻ5űĎçK_zđJ…lŤĄ¤¤¤ zĆŽëěě|áÂ… ňŘŘŘóçĎWŢź!C†¸şşŢ¸qŁ‚Ľ˙ţnnn·Kíí—ôíŰ×ÝÝýÁä={öôôô|Rjż$::ÚËË+--­‚ĽK—.ŢŢŢäuęÔÉ©TÄĄ}űöľľľě˝ZžĐĐĐzőęi¬äFľM*†Dj4ęÔÔ'ďÓë– L&Sť:AAŤ„Ba@€_FFZjęcn"ň¦iwwOł™˘iĘŰ»ŽD"%HĄ˛j×á8888j:/ĄţĄKÉ*•26¶ź«« ĂŔŰŰkÖ¬ŻoßľíěěTR˘-,,puu/^$!•JhšŞlKÍćŔŔŔĐĐĐóçĎ_ąr…ŤőčׯźL&k׮ݙ3g.^ĽČĘ»wďîěě\í VT„ަżĐhŞ–W=rÂ××xíšäĚMχŃHôďźďîn˛łcćÍsĎ̤§ çÎőJ©/żĚđň޶‰D"ů׿ţ•źźź——÷ŻýK(Κ5ËÓÓsřđáű÷ď_¸p!»ć[RR– ¨ŇĐ2›ÍˇˇˇÉÉÉ[¶lٶmEQnnnááá$I†……%''oܸqË–-¬Ł2<<śĎŻ6qŤaçNlŘ‚Źł3f€ @Q¨•ř‹ž=‘”„3ŔçĂlFóćčÖÍú}Tµđ˝}IŃ4-“É"##=z4{öl‚ Ř ţÁÁÁb±8""âÉ“'_ý5+oÝşuppp•uÝhšV*•[¶l™5k;mk۶mÓ¦ME"QDDÄÖ­[żúę+VŢ®]»fÍšU[ÎÝ11XąÇ `4"* -[B @L Ö¬Á°aer6L±J|}Ńł'6oĆС`0 [7‚$ŃŁ¶mĂŕÁeň  jőřűŁ{wÄÇcĐ Ëö=zXZAtďŽ={,ůőzô «ŐÓ˛%nÝBb"°¸Ö#"ТŤĂ‡g±Ů† ±ć9ü=7nÜČĎĎ^©Ęĺµk×ňóóË0A,^Ľ899ůÜąsjµzÓ¦M3gÎ ~y“““sssłłł+čątéRnnnnnnů‰'† RyÎť;—ťť]ľ˘!ËŮłgł˛˛ŘR‚ĺIJJĘÉÉ©l ť>}Z­VW @8yň¤N§cű‹Tس٬«äx?qâ€Ę $XÓ´ňŞÁąsçŘUąwÂ`KKK-,Ěż&ÁAřűű5i0133“ëÓőלRŃ´V[D„@ ‹ĹAđx<.0’ĂƱ……í ĘçóŘÉ"[K§Óůűű>|äúőaaˇ¬€$IłŮ\ů]ÖߊŠ2 ׯ_‘‘‘|đ Ň­[7ŁŃ’’":wîÜŞU+‘HTíÜ´GT٢­W/x{×đčŚF2"Bc2/J5ž˝=ÝĽyIŹ…   €ź–&ŚĐhµdf¦ŔzJAéééZ­¶  €˘(“ÉÔ±cGŤFsîÜąśś±XÜ´iÓnÝşU.,Qz¶ÝÜÜú÷ď˙ěŮ3…BŃ»wo¶µ.+ßµkWZZšR©ěÓ§O˝ző¬EżŠÍ›qń"t:8;#"Â2ÉîŰVĚĽĘôéSu€˘·7&NÄşuČČ€‡ĆŤ§gµJH}úT5ÉâŁoß÷÷éŕóů111ű÷ď/..nĐ Aßľ}ŚFcPPPŹ=8PRRҰaCVΆłVľčBˇ°yóć999‡ŇëőŤ7îÝ»·Bˇ0›Í-[¶ĚÍÍ=rä^ŻoҤILLŚR©¬RŹĺ|věělěŢ mŰbđ`KaŹdgă×_a4"4Y«ÂçŁKäĺaß>ÍčĐqq–Ę=QQČĎÇţý („‡#6ÖZµ=z@­ĆˇC`tîŚ^˝,·_ĎžP«qô(té‚k•$të†Ü\ś9ÁÁčÓlă~ý ŐâäIđxčŢ]»ÖüöîÚµkQQQ@Ą¦mŃŃŃFŁŃż´    ŕŃŁGť;w6 Oź>- zőę%‘HęV2űôéŁT*}*…Ś:´Nť:•÷gŔ€.\p/íRđ’A]ąrĹ•-ĘZŽ!C†¤¤¤899U>üöíŰä#FŚxđŕBˇ¨ 5jÔ“'Oä•rGŹť––&­”8bÄŚŚ qĄî Æ ËÍ͵ű“ŠÇ_Ö–Í-΋ŤňóĎ››7áńřŕŕxÇ^ŹÝţ<-22*//÷ţýŰ Ă4iŇÜÓÓ«vŠT*UçÎ]Ž= >~gttTĺ7‡JĄ köěY‰‰{;věXy…FĄR…„|pĺĘÇŽiÝşµµúÝď!$I>ţ<00€§§gjęcŤ¦;-ŕJr˛P( ů uvV&Ă0fŠ˘)Ц(łŮL•~¦)Źźúô©Q§sqró5Wź˙t+ŕĹů‹ć ęěŕꕟź+•J·műß‘#G:uęÔ¦Mkš¦Ź?qîÜůŹ?ްˇ˙ěŮsťú÷Ź5Ť+V¬ôőő;v´“““V«ÍĚ|>a”îÝcFŽQş˛K’¤P(dW”Ěf3›´€m>VY@©TëÖíÄĚ™Ťe'ąU[5)VŃ´é–©S[·oĎŽ9$ >źáó6ťŠ˘“‰`Ű$ş4„ PRB–®ÖĘĺňV­Z­X±"005)ŮúŤĄ ˛ŘćZ4Mł‹h<Źí/ÇZqĄËľ2™,((č—_~ńôô,ňů|@Ŕno2™JW¬«“°łłk٨QQn®µJ5~ta4ľžQWłA-¸ň4Tš_ţąÔŻ_˙řńăĄn öúňů|¶\ŰąÁŠ€P(˝r°ŔÚ•ËGŤ›“ťĹľ°ŘwV)ôËH’w%ůŇôË%üJăʦi˙śß‚ă]›çćf§§?3ŤM›¶ jF¤V[l0čąr˙oŠ%‹M§ÓEE}d4úéçożýŽ ?żúC‡iٲ…T*2dĐúőJ’ĽČČđľ}{«T*“ÉT]4MÓz˝ľt&T*g_Á•ĺUíńzňęˇiŤ„ŃHT¨AĐé~WzäU{D°eEĘĎ`ŘżY˰FÇe1vĚfłąrĄßęä"ěőeŤçňץ:ůŰÖĂQÓˇ­ÜŁúĘĎUÎŁJű7ĽR˙˙gůżšÝ"ą90Ç»7úÁýűwžůdJ^^>Ann®žžžl-bëÓËęţűĎš•V—cőşÓ÷7řŻ÷âüpü‹»čµi°qpĽł/ š¦•J•‡‡±XÂ0\Ń›ĚŇP=gggOOO6ꏢ(ŁŃČFŠĹâ&Mšđů|€1™ĚFŁ‘u”qłLÎ`ăŕ¨MÓJĄ@ `gKÜ„‰Ă6ŤašHŚFŃh¨ĽŤŮL›Í¦J?Hp®888888ŤŁ"ŕöí”»wo1 Ó¬YK//®+:‡­&Űë/ýp‰˙Ż ¶7.ĆÂń—Çd26oؔ̀7™ŚÜ­ÂÁÁńf €-uřfvw98888ţßl………cĆŚŮąsç{jąq¦ćۆÇă?yň(-í ĂŔÇÇ×ÁÁ‘ëťÍÁÁńÚźźKó(굇‚I’CÓ”D"V*•B+ýš^…R©äóxÉje””IĄJĄŇ–V" …‚$I™L¦T*«íWd2AöööJĄŇ–±Z,@-Ôô·Ě}řµ ˇVŢő•zCýé$©R©Jű7ĽBˇP&“ńx<•JeËŚČÎÎN*‘ÔÂĹ •Zkö:7"jĄ —ť*µůz%/O87˘sŰź0R°˝đt:Ý®]»Şě•ţNa4Ďť;wçÎĄRŮ®]»*{rÔ¶ÍFňxönáÎÇŔĐ´BˇÔj‹ Š˝ńś’ ;;‘ĘÁńäÁŚZm4™Ţ|hg÷ěĹ ěŮĚLŘŇłQ*EnîŢřř›WŻÚ.n'i‹‹Ůşő‘#¶Z"ˇĐh0l_·N©PŘâđůFšĆś9Hlę~F’`,X_l'»E‹`㊡Áđ®=…ůůËćÍÓ۰c<ďŃÓ§¬]u-°kdóďÜş…ôtlÝ ­öÍI$ÂáĂxřĐV=b1ÎśAf&–/‡Ng“ž `g‡eËđĆçG"ÁĹ‹ěÇ;wî\ż~˝´$Ç;eÔÔ–Sáť3ŘärůęŐ«Ź?ţÝ7ŘîÝ»·lٲ۷o«TŞěěě©S§r¶·ŠŮlŞ[×Ďǧ.€’­^ŻăN8ÇëĎ·iGGgH}úÇă˝™Š˘Z¶lĺćäĽcoâ‘'Ol5$4bÍfÍŤ6 ¸tÉÖýŃéÖ>l«_‚ `6ź7=Éez,_^;~­Ĺ‹kç6úî;›WlíÁm2áńcŘn@ć<}:}Ű6›ôôzh4_nÝj»"7—:´v®W­č‘É0ožMÇE’(,AŕŢ˝7×Ă*<~üřĚ™3†wĎřç`ß5M­ü*Šwü2äĺĺíÜąS"‘ś;wîüůó?üđCóćÍ;tčŔÝ o‚ ŤFCqq‘ő–ŽÖÇš¦đů|ÁlA0 MĺçcŃBLšdÓś› Ă$$Ř~` €_~AX­űăé‰ÄD4on«…. N[ő…¸s*•­zHĎžŮhGQ‘aëÎÂĹ·nŮŞçŮ34i‚ß~łUĎŤŠÂłg¶ę9q'âÎ[őěŰÇôčńnŤcÇbáB[ŹkâDČĺ?˙ÍőĆŹÇęŐ:wîuęÔeË–ńůüŽ?Ă0óćÍKNNćńx]»výꫯŘy6MÓ+V¬ŹŹ0mÚ´nÝşĺççÇĆĆîŰ·/$$D§Ó5nÜŘŮŮůÔ©S 䦦Ο?˙ęŐ«"‘¨GŹźţ9€ŚŚŚ|ňÉ'‹/Öëő;vś5k–˝˝=ťN·|ůň={öHĄŇĎ?˙<22€^Ż_ąrĺîÝ»ÁСC?ţřă×x VĘOËÎÎ~đŕÁčŃŁ•JepppXXŘ‘#G8ímĂĺůsppŘŹG>žîŇ6°ykŠz“-’äeggfggäA ´LˇlˇcĽYkÄĆý!ZÓĂşél×#¬Ťó ÔB:S©˝găΔf٨§ôl×Ăj°QOiŽźízŢ˝±Łvvöy·EĎËKů˙˙•&ĘÉ“'<ÉçóŻ\ąŇŻ_?łŮ˙üsťN7cĆŚíŰ·‡††Æ srr°aÆíŰ·łF]|||@@Ŕ´iÓŘ_€ ™L`ćĚ™7nśvěëĚ˙üóÜÜ\š¦CBBćĎź_áëŐ«wúôéęÎF…H†aĘ/lđů|ó;¸ÄńW¤|éˇę>sppÔČvcެÍć‹qpppppü™€ĽĽ<— VĘożý6kÖ¬””µZM„ÝË^A°n4NNNůůůhšľqăƬYłnÝşĄŃhXë‹ŐSXXXş˝u(ŠJNNţ÷ż˙}÷îݢ˘"š¦}||Jg¨Ą›ÁšLEi4š eK†ą~ýzëÖ­ŮwłÁ`hذˇŤ“fAąPx˝^/¶˝±G FŁ‘]Ô CégˇÁ`ŕúůrpÔâĺ«á ‚ ŢçŚ-BČÁÁÝśoýzrŤ˙TÍŢŢľ¨¨íŤVj;Í™3çĂ?=z´ťťť^Ż/_şŁ¸¸ Ôjµlp#›Ă1a‘H¤Ńh&MšÄľí¤R©V«­0V%ŤfáÂ…QQQS§N‰DłfÍŞć ʰ¦”D"1Ťú 6hĐ`ńâĹ<Ź˘(@PÁđŕÁľ}űĘßËŇd25mÚtíÚµ6¶łł“Ëĺ™™™nnn&“)??ßÍÍŤ»«8Ţ6R©´WŻŢß}·ŔËËK,¶‹‰é˝hŃBwwwĄŇ!::jńâEnnnśźŤŁ†Đô›xŘhšő°UőOž`ĺJś:ˇýűcŘ0KäGʰr%’’ aŕ@ Z;ť˛­š•2§NY>ł¨ŐHJ‚UȆżµÚ®^ŲeHIJ…±cŃ·ŻĄěÁ•+Xşżýڇ>}^1żxK—âî]89aÂÄÄXäçĎcéRÜżLśîÝ­)yö ?ţ'PTwwôčQŁŕ ×[v€a`oGŽX+4rü8–-ĂłgđňÂÔ©°ČŹŲeHO‡·7>ů;ľâl<+đâęÖĹÔ©řđC0°hŽ·„ŚŠÂË\ŹjIHŔŞUČΆż?>ů­[˘pý:6nÄŐ«`Ô«‡¸¸˛óVť9Źuë—‡&M0u*Z¶do\ě܉uëPP€¦M1u*š7·¦ÇlĆöíظ Z´ŔÔ©hŇŚFlߎ͛ˇŃ 8S§˘qăÝ“/bŇ$´oŹE‹ ¤۶aŰ6”” m[LžŚ ާá#;ë×cď^0 ˘Ł1f Řy`VÖ®ĹţýĐ­ĆŚAĄ çďxţkÖŕđa$zőÂČ‘pt€ôt¬^Ť#GŔăˇOŚrňwký‹ FŹ}ćĚ6(Źa‰DBQÔĆŤ›°÷ĚźÄĆŤwěŘQXXŘĄK—ţóźď©g…|ĺŮţńÇŮţ›ÇŽcßRIII!!!Ýşu‹ŚŚ,ߪĎl6˙ôÓO¬…Ě Ďž=ۦM›čččČČHíË®…|>?((Í‹cćĉw®śëLŻ×_Ľx1444***""B[MëĂŇUR±X\Ż^=vgŘÂ$$IË–-M&SÇŽ###CBBrss+O…;tčú{š6mZů×)•J77·={öxöěŮůóç[µjĹÍ~8Ţ6˙Č‘#Zm A|ľŕđá#Z­V©t;wÎőz=·ĘĹÁQCŘČv’$Ĺb±X,‹%ěś•!‰X9»ČĘ«öËcÓ&<|ćÍѰ!öďÇÁ (hµŘ¸Ož ysřű#!‡×ZÍ +8ooDF˘}{ËźČH88 1uë""âwr+ë§ąą–>ż­ZÁŰë×ăŇ%‹|éRLhŐ žžX·—/[+¨•…~€V­ŕîŽU«păddŕűďÁăˇU+¸¸`Ĺ ÜĽiMĎŞUČĘ‚ż?ÚµC¸p›7Ŕ‡˘CËu邇a˝ˇđ“'řţ{ŘŰŁU+(řţ{™1cFHHHďŢ˝YĂěď˙űÚµk °hѢNť:±ˇ’ oßľM›6ť6mÚ—_~É:L ‚`Ă%ILLĚäÉ“‡Î`“&MZşté€VŻ^Ýąsg6’­ÍXîĹD˛yk‰$..®nÝşS§Nť7o^PP+ěÓ§OPPĐ_|1lذÇł{XC*{-d2YŻ^˝GŽą}űöŘŘŘ€wň)âřË#‘Hz÷îłsç•JEQ\0$GMÇőŇÚQ&“éäÉ“3fĚřřăŹG޵dÉ÷Ź="‚ ””›óćýgذá#FŚüá‡RSSŮ–ŮU9v ÁÁčÓěě0u*Ôj<}Š'ж­%ŚM,Ćßţ†ś'"8ÜÝńŐW8z&âă1u*Z´OO|ő´ć”X»]»‚Ťn0r$?®XJ~ď^df":ÚZŹ»]»đĺ—`Ú4ŔôéصËrĽ3fXÂó6Ä—_">ľZ%4Ť„Ěś __ Ä´iر¬,Śa±e2 ŠgĎŞŐc4âĐ!|ő<= E L™‚ź†ť6oFh¨EŹ‹ ĆŽĹíŰŐę).FRľú ÎÎĐş5FŤÂ®]Đépţ<ľú lů€ví0|¸ĺx«$?×®aĆ ¨TСââđëŻP«qó&ľülĄ€đpôé={^q =|řxtč€,n˘ôt<{†iÓ,®Ý¨(DF"1ń˝?®^…˝=FŹŹ‚Ŕ°apuĹ•+HIŁ#Fڰô[1*•Ĺ#]%çĎŁN |>ĆŽ…P[·pń"üü0p ĺ&g ěÝĽůަżź$'''߼y3,,¬B9‰?’řřx•Jőé§źĘĺr“É4nܸ7nčtş÷ń]őę6>ź?eĘ”#F0 Ăžt‚ ÂÂÂĚf3źĎ···ŹŽŽf7ćńxcĆŚéŐ«kĚ” ĂĂĂK·ďńrMH"‘L›6m„ lu~ŽŽŽgĎžeÍĽńăÇ8˝A×®]Ű´ic6›T*e[x{zzžqpüIPíçWźÇăqe·88^Óś±ÄC^ąrŐÉÉ©GŹîľľľ4MÇĆĆîÜ˙đáŁüü<€ßµëGÍš5Łiş[·č“'OÝż˙ŔŐŐµężF‰$‰„ÔŻŹŔ@P †2ůîÝ@ŁF0™¬yj …ŁFÁŐµ,¬¨‰‰ptİapvţťü§źPŻ^Őzňóáŕ’ÄúőčÓ*Š‹AÓ((€Ł#k×".*4k†V~>śś@Xµ ÆÁÉ j5pvA`Ĺ Ś K®”uzô@I ôzcáB”/3–”„’DEYsݱűăę K—bňd¸»#? ĘäS¦ŔÍÍ"ŻŽ‚¸ą˘°r%&O†››%7ěëŻńŹ`ß>DĐë!“aÉk†_a!śťˇ×cĂLś—*rĚNťÂŇĄř׿¬~EEP*ˇŃ`űvŚ ''äç¦QT…ص ŁGĂŃŃÚq™ÍĐj!“!;ű÷ă㏡Rˇ …’HĄČĚÄáĂ6 J% ¬ťź›7ńË/7BaY;lŁěěđä .]B˙ţ°·˙#V1j‹’$ř|ś?;B €V ł$ g΀ađá‡ŕóQMń(.†JÇŽÁŢ|‚€NW&?|ŽŽKŢzNć»Á˝{÷ŇŇ҆ ňçŢľ}{ôčŃ`ůňĺÁÁÁ~~~?ţřă{j°‘µ«®¸¸¸v=?嬮‚B©Ľ†ŰspüU!čt:.uŤă 66$2''ÇĂĂĂĎĎĎh4Ň4Ü’¦éĚĚĚ{÷î»»»7oŢ‚$I>źßˇCŠ˘ŇŇŇJ‹W‹HTćGމü­!ěíˇRA©´üa§€4 {ű2ˇR ką^Ą/V;»Ş—…ÄâWFôĹUë)őÖäU®TBˇ€L‚¨čÖ[±˝zˇćĄ›ŮčĘĘ×´Tn}Âňł¶W«A’ˡPŔŢ4ý „ý)‚@i-» ż÷řq¬]‹† ŃąsŤÎv…šx¬6’¬éqYf‹$^6p*ŰĂ r+äĺ!1ľľ4ČrŠŘ;­ôlóxőż_–ĹöÂrĄň>Báď‡ęäď<[¶liÔ¨›Žô'’››Ë†B$&&4hŕŔb±řŻěa«©ńG’Í­‡ĺŕŕŕŕŕx÷ 6š¦ěíí5Mff¦\.§(*==ýéÓ'ŤóóóärűĚĚL¶ Ă0EEšjç– JJ@Qřč#ĐéŔçC$˛ČilN F“]Ńh°fÍď˘ţX đăŹeŃhŻÄÁÁRfpđ`Čχ\’„Ł#rsÁ0– śĽ<(Ö ?ää ^= ŮŮP*AptDv6Ľ˝Á6 ĘĚ´Č­óăŹP\ŚĹ‹1gÂĂ-§ôéS$%aţüW—Ł#23Qż>FŹ€/,ů]¬Ü××"ĎČ( g­î¸23áĺeé.‘''0 fÍB\¦LPÂB,Z„éÓQ©,vŮ]©Dv6\\0b™™(mWk6ăćM¬Z…Ü\ěŘaí$óxËQP• C‡‚¦‘“GG¤Ĺ…ĄTbđ`Đ4rs­ź™ EEpr€ iäĺY {‰ĹĹpqA\hÚ‭ŽGŹđż˙a®ä䲯—.ˇQ#hÔčwU".]˛VšŹ аaŮö4ŤË—ŠÂíŰ8ŃrB”Jڇk׬Z~~ezL&\»fů˝ ”|ü1H{÷–YqU"Â×·,LŻÇÍ›ź\ąb‘ët¸uËrĽU"ĂÝWŻZľăţ}KéN7·˛ŃhđđˇĄpK•čő¸ź~Šzőа!&LŔýűčŰ>>P*‘’bŮ,?ĎžáOÍzz=Ř ŘŇŇA©©()›\]a4ZúCxňµ»ŃË ZmY5š‡Á0pr‚§'4¤§[ä€ P]öě;æM›6lXe7¬?ą\ζďňóóKNN>qâ„Á`xOŁđj9$’‹Eäŕř ˘°P-“Iĺr%Ź'(**˘(J.—óx¶ÎŞBˇ"I’;QŻx”^zŘt:]XXXdd䯿&tďŢ3.n@vvV đů<Š˘ŠŠŠ"""‚‚šh4†ŹÇ«¶7}çθrżüb™/Yb±Ö"#qႥ’^I -‚łóű47í×›7ăěYČÎĆÜą D‚~ý°~=.\€ĚLĚ™Ža%Q<.Ë—[l‰çĎ1{6>úú÷ÇŇĄ - łg#*ŞÚšţFŽÄńă MŁÁâĹđđ°Ädćç#>ăĆ˝˘ÜKl,ćÍĂť;pďľů±±–ăýćKˇ‘;w0oâ⪟L‘čÝsćXćîżý†ożĹ€`xx`Ĺ ‹ZXŐ«Qż~µzD"DEaöl¤ĄŔŐ«řáK‘Ŕ„Ś‹°iÓ«},2:tŔěŮ–… °~=bc!#4sćXΞĹćÍÖŽËŃ!!řćKžŰÉ“řůgôî …ÍšaŢ6nE˘°a đÁŐę EZ¶nMĂdÂęŐ0¶m-ÎI†Ń+ Ć†ĐĚ™3ťťť÷íŰWAţĹ_¸¸¸:t¨‚üÓO?uuu=~üxůäÉ“]]]“’’*ČÇŤçććv}ö_BQÔîÝ»#""|ŮŠ©ĺ6l‡‡GJ©}ţ’zzzŢ®Tő466ÖËËëÁä˝zőňöö~Rjż¤{÷îuęÔIcź@ÝşuSSS†ůěłĎćĎźżaĂŁŃXşĐÖ©S§şuëćääTĐÓ±cÇúőëTĘÉüđĂ4h ©Tt·]»vţţţ%o9·đ}Šĺŕŕ`))Ń­\ąbÎśoŚF#MS_~ůO__߉'ŞŐę & …‚Ĺ‹;8¨¸¬6ŽWÁ0 MQŚ““C§N‘2™ěĹ‹2™T&“eddČd2…B^RRRXXŕćć/H’J%4MUý|…„ K9‚3g@ÓĐé0z4śťˇP S'8€“'-ňÁËęż˝=ÔęŞk6ŞŐeµjB§N8y«WcăFÍP©ˇť:ářq,_޵ka6ĂÉ 11ó¦ĘÓµ+NžÄâĹX¶ f3<=Ńł'xs¦EdÍ ô쉤$üóźŕóa6ŁE DGÇĂ´iHLDJŠ%»É`Ŕ_T«G @Ż^¸p˙;xxpµe*qíÚ5¶·dů•+Wrrr^ĽxQA~ůňĺěěěĚJŐ,/]ş”ťťť]đ’ .deeĺţľjĺĆŤe2YË–-y•ÜăgÎśÉČȨl%%%˝xńB]©ËČ©S§rrr*H'OžT«Ő•«f?~\§Ó•7ś"""úőë×µk׼ĽĄ(3çńćਉąĆ0 ŹGŢşu[Ż×÷ďűŹ|6pŕµZ­T*}|ĽëŐ«—™™yăFŠÉd2 IIgI’ôđp7›ÍU÷a‹1hš7G^Š‹ČHKm†!CĐ´)rsˇŐ˘O„‡˙…úô©şđFż~Ż[ĄTběX¸»#;…‘#-UăU*ŚWWde¦1f š6µV}ÄÉ &ŔŃŃâü7Ť€ł3&N„J…¬,ĆŹGŁFÖr؆ §'ňóńü9t:„‡cčPK%McҤšž[//Lš;;dfB$”)đöLšd©Ćng‡É“ËŞ®Wi°Ő«‡‰! + R©Ą°$IbČ„†ZŰ DFZóh5¸q•• “&YrĚĽĽĐł'pëž>Ej*ŇŇŞ­˘I’hŢŁF˘•WWL`‰żmŮ#GÂlFVÜÝ1~<¬ô7âńĐŞ† Ńělřř`ěXŘŰ Đş5†…Á€ělÔ­‹1cPóúŰčÖ ř||ř!ââ Ó!7Ťá㏫îBńn"˘GDFB­Fa!Ú·GďŢŕóÁç#&;˘ ……GLŚ5ŻH„ľ}Šü|¨ŐčŇÝşÇPŘX´iü|h4ŠBTTÍŤ.]ş´k×®Q%C1**Šu UwëÖ-44´~%pĎž=ĂÂÂ*{Ěz÷îćÍ>//Ńëő¬SÚę qqqíŰ·ŻśŘ6`Ŕ€:¸¸¸T4¨cÇŽN•˘‡ ^ąţäđáĂ#""ʇďŃŁÇXăčŃŁ{ôčńÉ'ź”v1bD§Nť¤•üŐÆ ëÜął¸ŇŞÓŕÁ?úč#»J‰Ç čÚµ« &ţ| ŽďßĎ~Ę-΋Ť˛sçÖ&Mšăăňĺ ·nÝčСł‡‡gqqŃ[˛FT*UçÎ]Ž= >~gtt”^ŻŻĽMXX{¶a`bâŢŽ;V^ˇQ©T!!\ąrŔ±cGZ·n]yµĆĆY¦T*eăµZ-MÓĄ_Y´Z-ç^{»Ë]$ůüůóŔŔ žžž©©Ź5š"î´üa‚+ÉÉBˇ(äÖŮY™ Ă)Ц(š˘Ěf3Uú™¦x<~ęÓ§FťÎĹÉYĚ#Ö\}ţÓ­€ç/š3¨ł«W~~®L&[ż~Z­‰Šę 0ׯßŘľ}ÇGu5jDzzú·ß~çää4`@ŁŃ¸lŮŠ:u|ĆŤăää¤Őj33Óż;ńÔ¤©–ž¶¶„„Ú9;gÎ 4”)޶yjRĐË űöÁöZb nŢ,ëIeËä­PbóŁ ŁŃVSŮl†@ŰÇXµÎΰýí–†ŔŔŞ;¤ż))čÚ•|/ŻÍ‰8ŃhZýkěŐ7áľ}xŮą÷]áďÇ˙k«’‰!—ר(ŽĆŹÇęŐÖ¬Y3fĚĘ“„ŇiŇë~®NĎ+ĺŐm\[úß@>uęÔ7nüío ‹ĹŽŽŽěL©¶ôż’ŮłgOź>ť_iŔY»rů¨qr˛łŘűÎ*…~ůIň®$_š~ą„ ‰äŕx/!B÷2ËźGJż– ąłÄÁńĘ'‰ ‰4 !!Ák×nŤíŔĎŻ~llßNť")ŠňňňűlőęŐďř zôčŃřńăe2YHHČŚ3Jĺ%%%[¶l9qâ„»»űŕÁ[µjĹVę+..޲eËÉ“'˝ĽĽĚĘ5Í–-[Nź>ííí=dČ-Z°rµZ˝yóć3gÎÔ©SgČ!Íš5ănJŽ·ůůą _ČĆCľ¶$I MŃĘjĺ­YkG'—×Ć)"P+ úďš ÚßńůµăcµŇíµP©jg”Jk=ô^ë¬Ô7ůO»“k—Z łłłÖ\ľ†DĄómnDç ¶7G  <¸şĆ|>Ó¦M¬ÁöĆÍ ţH’T*•;vě(5ŘĚfóůóç÷ďßoooź‘‘ďďďŻP(ĚfóąsçMÓJĄŇŮŮ™ÝRŻ×gffŤF>źďââ"“Éhš~ňä Ű1]§ÓeeeŤF@ŕââ"‘H®]»¦P(RSSŤFc L¦¬¬,¶—”Bˇ`[ž˘‹$ IDAT›Íć§Oźş¸¸dggÓ4-“ÉÜÜÜJ{ŢĺććŞŐj‚ \\\X;‡aĽĽĽÂÂB‚ T*Uĺ>čŻKÝşuwîÜyëÖ­!C†” sss}}}řá‡K—.Íť;÷řńă˝{÷ÎÎÎNLLôóó[´hŃąsçľýöŰ“'OĆÄÄdffîßżżQŁF ,8}úô˘E‹Nź>Ý˝{÷/^8p I“&óćÍ;~üřŇĄKĎś9ĹÝâoš¦śś\@ŕé“ÇĽ7uP”ąeË©«›tO‚Űůó¶DH’$™ž›+÷đ°—Ë^đ$Ź÷ěńcÇ”D6îĎÓ˘"× D¶µ‡& â±Áŕµr%ß6‰ ÇUgÉŇĆĺ]‚x Ô]°ŔĆEbxÔ›7ĎÖűaR)ŞŢś96†×ši:Ýh¬÷ďÓ¶č!ŁÉ”Qüě]w\TÇÚ~OŰĆVĘŇ›ôn T,WQcŤ±+©÷&WS4&šÄ¶Ř{7–ŘPě¨Ř+Š˘(uiËörÚ÷ÇŃ˝,1’|÷&wź?řŢ3çŮ9sćĚ™gćťwô_~Ů”^&‚ F«µR«ő˙â‹&ňčL&­HäăďĎ4aÔAQMuµŃhôňőm ŠaUTv¶{nnSî EŃrŤE×{÷Ţřyq$ÜFéŹ?>s挥)Füßš˙ÁĆ0L۶mçÎť»xńâęęj•JEQÔŞU«6oŢl4 0oŢ<‚ †9ţüçźţôéSooďO>ůdČ!FٱC‡*•ЦéłgĎ~ůĺ—ľľľ3fĚHNNNLL‰Dqqq...ůůů ĂäććΙ3'''Çń>}úĚź?_(VVV¶oß~ŢĽyóçĎ7 ť:uZ°`··7h4šďż˙~ßľ}|>Ö¬YC‡­VűŻýkĎž=(ŠŽ9˛¶cS ×ëkĎVVV|őŐWŃ«WŻ“'Or‚­¸¸řË/ż€čččîÝ»ź:uŠl*•ŠłÇĆĆ&&&ž9s¦oßľĹĹĹŐŐŐéééТE‹Ž;ž={Ö!ŘpŔţx Cŕ8ŽŁMĐ,ËjŞ«˙±đÇ)Ó§šđaV hrBÂčéÓfnŹEŰFF~ąxqR÷îÖ&đČP4ŇŰ{ŐˇC1-ZPMŕ‘ h L¶őĘꀀ¦t\„(ęÇăýüŕLˇhжÁQÔEŹ=ŽDSjMQ!|ţ)•Šnš ŃÖÔ´rw?_Vfjš(~ö¬gLLvY™ľ <8ŠŢ˝yslJĘĺ’Mxx(z6+kÖ´i9ąą5Mŕ čŢť;×.\x2;[Ý']±téŮcÇvA>żiť ¦óđ¸ń”¦ç'߇ĂšÎĂ@1 Ă0>€őMy8[[ÄiGĂţĆŻ7Y</%%%11‘6űöí=zt·nÝŔl6/]ştüřń ĂÜżßĂĂŁeË–ŕääÄ]KĐ4}˙ţ}OOOî¬T*€„„E#""^ŚŁŁGŹîׯźm¤sáÂ…ś`‹Ĺ©©©ť;wć”7Oe0233śHÓ4Ç©Ó鲲˛ĆŹß©S'Đjµ¬#Řärů„ ęl6@Ó´‡‡Çë—I’&“‰[ĺ‰ X,Öh4śÝl6ŰěNNN6»ĹbáJA‘H¤Őjáĺ¬Üf¬µí8ŕ€ü±@®ą‹ß|ٰĹb.++"I’fh€lŠ`Y–˘›ĘCËŇŐt€"I€jÚ}ËRE4Ĺ1çxH’jÚćwܵ$E±M‹;BSWJtSę E’OSĘń°ly¸'Î6™ (Şé<MÓ Ă4˝234Í49?Í0ěď’†ˇ›ĆCÖňµű˝śîřs 6A ôâefŮśśśŢ˝{ďßżźaÁpíÚ5Ŕ0¬[·n999 ŻüŽwíÚőŇĄK*•*00°C‡ś¸Ş={Ëçó‡ vńâĹĘĘJš¦5ÍÓ§OąSBˇ°WŻ^ÜqË–-+++Ŕb±<~ü›ÇĂ0,>>žׯ_0`ŔţýűY–-++»]oąŞłłógź}Öŕť2 ófŽ1‚48mo´Ă–ţÍ6˙qŔ®ň…BÇÚ—źÉdv”Â˙vEą$Ö7Š÷€aI’‚ Ž×ĐpŔ˙¸`㿌 Ťć“O>±ťrqq‚ ľüňËyóćíÜąS.—Ď1Łoßľ¶KÁçź>ţüíŰ·»¸¸Ě1#%%Ąî¸E=ztńâĹOź>Őëő,ËĘĺr¨@’eYÎw…óŐ$ęů ˝˙ţű¶cbbę$ iş˛˛˛~7Çń׏P‚ă8źĎ§iš[Şn08KÇy<žÍn4Ĺb±Ín„6;AAŘîŃl6svřU (ZZZJ7%zŰ˙0quuu —8đňËÂĽÁŘ˲ŤLö ŻhĂ_·7Âc aÉľ†ýOÁĽü['˝=»§é<ěkŘ˙\<żËËő—äqŕT°ŐŹŹĎŢ˝{ÝÜÜ8ůasó [ľ|ąŮl>~üřW_}U[°!ąrĺJ“Étäȑٳgs‚­öRŻ×óÍ7~řaÇŽE"ŃłgĎꋺÚú Ă0…BQYYéęęZű‡bcc÷íŰ'‹išFQ´ţŢOž<‰ŠŠ’˝şó EQqqq§Oź~ÍB …âÉ“'!!!FŁQĄRůúú€H$’ËĺOź> 6 >>>ŕääÄîoÖ¬™^ŻŻŞŞâěb±X,ętşęęj///GĄtŕu ‘H:?}úű]öşůßęťłR©4?˙‘éŤă);đ—‘î/«Ä¨wAě]„ŕśĂÍą;6j·;.ó<ý[xj§˙­<ţ˛Đ¨Z®’6;ű2źđů©źýx¨×đZ´—ţ÷âÁ°ßÂc/ý„yů|€ ^ş¶Úłżţrmákň4ţż§öKjĎŢ”—ýuxp6E»wďľfÍš/ľř‚ šššź~úé> (jÁ‚ďż˙ľ\.wqq)++«}•ĹbY´hŃ| P(jź%Â6EÓtaaa@@€§§§V«ÝĽy3Ńh'ˇP»páÂŻżţÚh4îÚµkĚ1NNN­[·^ż~=7řüůóÇOž<ąö…^^^űöí«CÎ0Ś´ŃÍĄRimoI??żőë×Ďť;÷ńăÇÇŹ0`¸ąąyzznܸqöěŮ>ĚĘĘâĽIÝÝÝ•JĺćÍ›?˙üóű÷ďź={–sćôôôT(۶m›9sćť;w.^ĽČĹştŔ×é,VWW;ö]y3X›˛ĺ‘90̛̰1 Ŕľ:ü x\P°eĹŠKgÎđřüľiiGŤ’K$8@Ţ“'[–/Ď9žĎç÷6lŕČ‘R±Řž,ÜĎËŰĽ|ůµ‹…"Ń€#úżő–“Pȸ÷ŕÁ¦ĺËo\ľ,rr8jTę°a"€¶ĎsëŢ˝Mw®_w‹‡Ľývź´4>AđnŢął1#ă4mܸ”!Cx8ÎŘçąvăĆ†ŚŚwîČäňa&ô4CQŔ•ë×7,]šwďž\ˇ>qbĎQ±×­\ÎÉٰtiţÎnn#&ONî×ř/]Ú°téÓĽ<Ąrä”)ÝűôidĘ…páüů Ďňó•٦MëÚł' Ŕ8wöěĆŚŚçOźş{yŤž6­Krr#ÚŹpćÔ©ŤĹĎź{ůřŚIOďÜĄ @ś>yrÓ˛e%……Ţ~~cŇÓ;'&ZíNe;¶yůň˛’żŔŔ1éé  ŕÄ‘#›W¬(/-őoÖlě»ďvčĐÁbż÷Ź;xpËĘ•Uĺ塡cß}7ľm[.ý‘ýű·®ZU]Q>öÝw۶nm¶ĎðěÁ={¶ŻYSS]56=˝U‹šaöďŢ˝cíZŤZ36=˝E\śŮľŠ°RÔĎ;wî^ż^«ŃD·h1&==6*Ę `±ZíرgăF˝VÓŞŐčéÓc##MöĄŁŃl>°uëľ-[ŚC‹víFM›JL¦ý[¶üĽu«ÉhlŐľý¨iÓÂÍö YŁ×ďŰ´éĐÎťłąm§N#§L ¤j´Ú˝›6ý˛k—Őb‰OL1eJ°żż= J­Ţ˝aĂŃ}ű(’ěŘ­Ű[“&řř0ŐŐ»×­;¶?MQťzôxkâD?//‹ýĘSVQ±cÍš“żüÂ2L—””ˇăÇ{»»@‰JµcÍšS‡@×>}†ľóާRiµ_™ź—”l˙駳ǏŁ(šÜżÚŰo»ą¸ ĎŠŠ¶­ZuîäI Ăz 8xěXW…‚t´ÚÁV\Ř ›`KKK[±bĹś9sPµÉ-–e+**ľţúk Ăt:ݰaĂ8Ł-„†JĄš={6†aZ­–;KD«V­>ţřcww÷Ź?ţĎç÷čŃcÓ¦M‡"I˛ĽĽ\§ÓŐ!©ýŻ““Ó AÖ¬Y3kÖ,ŕ< %É€6mÚôĹ_ B’díů7NNN}úôiđNÜż»¤¤dÉ’%ĺĺĺsçÎU*•&LpuuMNN^łfÍŚ3jjjÜÜܸ(,JĄ˛{÷îëׯçb]ş»»wéŇ<<<şté˛eË–™3gVVVzyyqA\Ľ˝˝“’’věŘ1sćLn:Ž —‿ –eą ä©S§*šçú ‹eÁ‚µÝĽřSEQ EąÍIQa„Î@^ÄD^çUúUÁ†aŹÇCQnx‘˛Z­Ü*˙úď Pm0ě^żţÉǡQQ MźřŰ\ČĘ Aî߸±ëÖ1Ó§ ¦ˇĘ¬·XŽěÝ{ĺüůfˇˇpóňe±T:bňd`ŮĂ»w_żx1(,ڏ–ť-‘ˇŽ'ŕóäŃL·ożsíZpDË0—Nź–;;˙môhЦ÷oÝz˙Ö­–a.ś8!wvN>ĽľűŇď‚ Š" Ô›6A8)bű·M›6ĄĄĄ7n,-- ůฏYßľ}—,Y˘R©˘˘˘fÎś /cŤp)))K—.­¬¬Ś‰‰á.áóůo˝őÖ’%Kx<ŢÇ, 'Nś8oŢĽśśś€€€´´4N(ňůü¤¤¤ŹĚ ÜżAtëÖíńăÇ …'A‰‰‰ĄĄĄŰ·oW«Ő-Z´;věoš˛hPŻîŮłÇĹĹĄyóć;wîlѢń ř|~—.]îÜąsäČź)S¦xxx°,Ëçó»víz÷îÝŁGŹúűűOť:ŐÝÝťeY@Đ˝{÷{÷îeffŚ3F©Tröäääű÷ďź8q"((hܸq¶ŤČpŕ5ńő×_+ G9Ľ>,Xŕ(„ż‹Ĺb0¬V+§»šfćß.Ž‚"(ŠraAX{]íĆ]"1 ÓëőĹĹĹUUU‚ş»+˝ĽĽ‚`."n]ąrůÜą”żýmĚÔ©&łyÖÔ©§nťđôŃŁśóçĽőÖČ  &ÓĚI“˛~ů%şeK˙úó?ŔŐóçŻ]Ľ8bҤÁ#GęôúŚwňСńń·rr®_şôvzúŔaĂ4:ÝGcÇžĺxŢy˙}¤!ďq óŔ˘gĎ–lÝţ0/oÚС'|űÝw3(),\úĂa!!ą¤vâŕÁ±Ó§łvjŃńýűËKKż\Ľ8(0đÎť;ďŹyňС·&N<ľeyůśŚŚ@˙›7o~4fLÖ/żŚś0ˇÁQ’$Źď߯Q«çýô“ź·÷•śśNśxúČ‘ŁFeî߯Óhľ[łĆÇÓóŇĹ‹źM™rćčѡŁG“ Ý”Éh<ľżŮdšůý÷žJĺŮÓ§ç|řáąĚĚžf8@’äĚ~pwu=}âÄ·ź|r>3sĐСֆxtMć‚ĚúńGW…âءC żúęŇéÓşu;qŕŽăź/\č,—ţůçŚoľątútßţý- ueĺÉ…NN_.^,“HömßľnńâëŮŮ1­Zťz4 8řÓ~Ŕ bůüůNžlÓ©S|»v ó<|xîřńĐččŹçÎEdŃěŮç33;tíŠ ČąĚ̸¸gĎ–ý×çźź;~ĽUűöÍ›7·6ô’>¸sçÂÉ“­:t>s&EÓó>ţřĚŃŁíµ55٧NµďŇeňÇS$ůőGť9z´y»váááŽö˙O˙ýB^oµZąP¨ÜÇ‹ĽwDQÔ¶;ËŻEÄ0ěřńăuŚ©©©»wďľpáÂúőëăââ8Ť””´gĎžóçĎŻ\ąŇßß„Bá‘#Gŕe É}űöť;wnٲeÜr/‚ ŇŇŇÎť;wňäI.M»ví¸M޶mŰ6pŕŔ}űö€‹‹Ël?íććöóĎ?sÇ</==ýřńăű÷ď·‰: ĂFŚqđŕÁóçĎ/Y˛„Űú¬)ČËË»xńâ‰'nÝşµ~ýzÎ.•J?űěł .ěرűuNďÉĺňĎ?˙<;;{۶mÜtgwvvţꫯ˛łł·nÝÚ±cG›ÝŐŐuÎś9/^ÜĽysűöí5ŘߊÚsŕü*¸©{ţ"Ă“VˇR=ÎË«(/ݬ¨¨®ŞŞ©©Ńjµz˝Ţd2Y,’"_~Y;łm§ôXű@äÎť»_=wäČQŁGŹ^´hńłg‚°,S_Ů'OƶjŐkĐ @*Ś}ď=­FSTPp1+«U||Źţý™P8îý÷«++źĺç7¸•púČ‘„nÝşôî ±xâß˙^üěYeYŮ™ŁG»ôęŐągOŔY"™ôŹ<~\V\ÜŕçśČžđT*Ó?űěňŮłť±3H|x÷î1S§Ć´jEx{yĄĎšu.3“"ÉĂ»wżýî»Q-[’ľ>>éłfť>zÔj±4Č޵kâG…ÇĆ’ţţţďΚuâŔ–eďÚ5ůăŹCŁŁI€€ŔŔôĎ>;ľż˝¸çŔ‘={¦Ďn ť6sć‘={ŕŘŢ˝éź~Ú,$Ä >eĆŚĂ»wŰ«Š Ăś8pŕÝYłI€ĐččI˙řÇ/;w˛,{ňС÷fÍňó÷'ÂccÇôѡť;1;™!­ÖłÇŽ˝˙Ĺ>ŢŢ$@TË–cÓÓíÜISÔůĚĚ÷ľřÂŰÓ“iŐjÔÔ©‡vîÄíđőúśsçŢűüsĄ’h?ôťwďŮc6™®egż;k–‡«+ ĐŞC‡żŤsx÷nÂOMuő˝7¦ú©›BA´KLě›–vüçźuÍ»w§Íśé*—3şví5hбź&ě<,UIɳǏ§|ň‰B"a:÷ě™Ř«WÖáĂ•ĺĺ%ĎźOţÇ?äb1$Ą¤tčÖ-ë—_ś? ź~ĽĂx(:hôhWw÷;WŻćŢşĄpqI7ŽŹ˘ ňöŰ2…âÖ•+¸žëŮŮŢ~~GŤ"D„ăĂ'N$xĽG÷ď߸|9 8¸˙đဠFLž ňŕÎÜŃú˙%pďŇŇŠňňŞĘJµZ­Ńht:ťŃh4›ÍV«•˘i†aąDŕ ‚Ž8ŕ€8ŕŔÉeiiIMMMmáÄí™R'%I’n.® ÷IeY†;âBUá8β¬Őj%I DZ‚‚‚Ő«R*ÝvîÜnµZ—.ÍضmŰ”)SÝÜ\ě „Ĺĸ(• nµXôZmŃłgqq WW €‰Ś4ŤÚš{‚äY~~XLŚTˇŔ€°ťFc4ź=y٢…D&ăěá±±µÚ ×#vú¦ŹuíÓG$4@dóćUV‹ĺéŁGÉE"ÎŐ˘EEY™Ĺd˛—ź'ź8‘/péŁ[¶,+.¦)ęÉ٧Măńů< ¦uëŇÂB’lx• ź›:kN\úŘ6mŠ †Éđ <6Ă0›˝đÉ{p€Çąą‘Í›ŁÂ bŰ´yöř1°lţQ-Zp»6[bŰ´)xô¨‘Ôü˘[µb€Ř6mž>|hł€Ŕ Űşő“‡űµOňňbZ·fřf‰nÝúŰO>€§yy1­[ł6{Ë–ßú©=\š¦źĺçG·jĹp»icXdóćß|Ă0Ěó§OcZ¶|a'đ¸¸ß}goĐť$ÉâgϢméyĽĐ¨¨­+WRUZXŐ˘ @đ‚kÖ v Ůb2•—–F6oÎB'§Ŕ°°ăű÷[-–ʲ˛¸8Î.‹ýO:dOôzuUUXL €Hd2ꀀŰWŻšŚFŤZÍŮe …—ŻďÝ«WíĺG[ScĐë#"X ŔŮŐUééyďćMťVk2›…‡ż°»ąą*•ą·ocv*ˇş˛’˘¨€î_Ą§§\ˇ(+.vQ*†ń Úçůŕ IDATâěî^^©´´¨µĂSQV†bO@—=/??ˇHTˇRńx<‚Çóöóă´w@źĎŻ(-EíĽ¤eĹĹB''oo.˝_PŠ˘ęĘJUq±“Dâîĺ…°ÁÁ,ËVWT ŽÖ˙φaîÜşůJ+ňňöjÓňb×GÇCwŔpŕOůµS*ÝŁbb‚BCĂĂĂ###ŁŁŁccăZ4oŃŞU«6mÚ´k×¶}‡řŽ ť۵ďŕęćĆ4Ôű·Í¤ˇ(ŞR©22– 6|Ę”©/^D <''Ăđ^˝z¶hѢM›6))˝‹‹K=ĘCQ´ľ @tZ­P(”ŁčáďÝżďĆçÓĹi6‘H$GŃű÷?|řĐM  HŇŢ çŤ&–H¤(şo×®'Oź*…B«ĹB‘¤®¦†łďޱŁŕůsĄHd1›I;qtŤZ-•É$(ş}óć’ŇRĄXl6iŠŇÖÔČär1ŠnݸQU^®”HLEQöxjÔjąłłE7­][ĄV+ĺrNÇ0ŚF­V¸¸dĂęŐ5ŤRˇĐkµŚ}ˇUS]íěęĘGu+WęŤFĄ««VŁ–­©®vqsă!ČÚ+Śfł»R©­©±'´8ww AV/[f%IĄ§§F­fjŞ«]•J`UFIÓîžžšęęFÖřjŞ«ÝÜÝ€U,Ë*=ßŐÝýţÍ›€@ŻÓ<~jŹG$‘Č]\roßFHmMMqAPČÉI&—?Ľs‡łkÔę’çĎ‚i{ŁrąH,~tďŐ奥>b™L >ÎÍ  RĄŞ*/÷  íTBgWWǹŊ4€Ş¤DS]íáă#wqAP´ŕŃ#Î^VT¤ÓhĽ|}íńpN°…Ož0 @ńłgfŁŃÍĂĂŐÝť´Z‹ 8{ŃÓ§V‹EééÉŘáńđń1 Ą……\ Ł‚ÇŹY–U¸şş{yéµZUq1·©}ÁŁG‚¸(•ŚŁáţßC°9ŕŔź GÉ(\Ä#GI;t”µh‰}׳ŮlëDÚŽŰ·oŻŐjé˛?~üÎť;4M?~üňĺË<Ďh4ĘĺrĂ0ŤćÔ©S9997nÜčС§Ů.]şÄ0Ě™3g§©ââ⸉¸Ú‹ajG°ŇŤÎb±,{ĺĘ•śśś .´lŮÇńË—/gggÓ4}íÚµ .PŐşuëk×®ĺääś8q˘YłfMkQ@Qi«6ŇŽť$}ű±BˇŁęýĺĽt‰äęůîÝ{FŽŐĄK×řř{öěă|Ép§iZ§ÓuéŇ%::Z«Ő˛,p;żŐ'$:vď~çúőŁ{÷Ň:“iíâĹRąÜ'  c·n7.]:ţóĎ €Ćh\ýăŹÎnnţAA ľV€®))NžĚ:|Pëő+ż˙Ţ' ŔÍĂŁKJĘéŁGĎ;ŐZíŠďľ  ńđön°Gô0ŕčľ}ŮYY@ĄZ˝ěŰo#bcĄryŹţýíÜyéĚ Ľş:cîÜV­®®¬ž”Á÷lŘp5;PUT,ţúëÖ; „”Áw¬YsýŇ% TĄZ~µV gŽ;}ôh×>}\”Jꀀ•߯ÖëŕÔáĂçOžěÚ·/içˇű5kćâćöÓŹ?jŚF s˙ţë/&$'{űůIĺňµ‹iM&ŕŘŢ˝·Ż^íÔŁ‡=ž¨(ś 6ddč­V ŕĐŽů´MH €MË—H’bŮý۶=ň¤]çΤťĘÓŞ•QŻßľzµ‰˘, ł{ÆJ•*¶uë¨ćÍkŞ«w®[g¦i3Mď\·®F­nŢ®eçĺjݱciaáľÍ›­,k$É­«V‘VkhTTËöíźĺçďßş•0X­›–/€ŘXęőÚ·YłfyxxüňË/uě˙üç?===ë˙裏<==Oť:UÇţî»ďzyyť?ľŽ}Ę”)ŢŢŢ—/_®c?~ĽŹŹĎőë×ëŘÇŽëăăsűöí:ö#FřůůĺććÖ±:Ôßß˙ŃŁGuě (((¨cOMM ,**ŞcOII *++«cďŃŁGpppeee{·nÝBCCŐęş.ô‰‰‰aaaőcM'$$DDD˙ŕµ…—HřĂ!‘Hśś$"ŃkąŘ!˘Őj˙­dX–qv~ű qř0 fs#—s]L۱H$z˙ý÷űôéséŇĄFt7=%ąˇń+V¤§§/Z´čÓO?ť?>źĎçVďp—ÜĽy“ËaLL †ať;wćě 77—c¨­ëhEEÇŽ;nܸĎ?˙ĽńŇhÝş5wpăĆ h۶-ÇÖ˛eK°X,·nÝâŽŕí·ßn’Z#§ń°ü|> ţwFDX†Ç=zôęŐ«11Ńńńíř|ţÎť»¬V+ŁPČŤFcMMŤ§§;RZZŠ˘XěÄ0tý6 ®M›„nÝÎef^ËÎfĆ Ó ?ŢU©”Čdşu;uäČĺłg9{ę°aî^^´ť>\«Žă“’ŽíŰwöŘ1†¦­KrjŞT.oŐˇC»ÄÄĂ»veýň CQ4EuOMU¸şÚlńII—Μٷyóá={ŠÂp<ą‘Hź”t!+k÷úőwě`(Š'$÷ď/‘Éě ­„îÝ/ž:µuĺĘÝ6Đ%‘É’ű÷çńůť’“łOžÜ´lŮÎ5k(’”;;wďß_ ŮăIęÝűâ©Sk~üqÓ˛eI*==“SS1 KęÝ;;+ë§ ÖóxIzx{wOM%ěĎÔuëŰ÷ŇéÓËľů†ŕń(’ô Lî×AÎľdî\‚ (’ô ęÖŻb_°uOM˝|ćĚÂ/ľŔ ‚"É đđn}ű@rjjÎŮł˙š5‹ł‡FFvíŰ×ŢĚŠ =RSŻś;÷ÝŚ8AVkD\\—>}éŃż˙Ő ć}ň gŹlŃ")%Ą×Áܸtiîß˙Žă8iµĆ¶nťŘł'†aÉýű߼|y·â8nµXâÚ´éÜł§=Á& { p÷úő/ß{ŹK߲}űŽÝşńřüýűßżqă‹ôt Ç­fsë:vëfŹG"•öčß˙Ń˝{ł¦NEqÜj2µíÜąmb˘ĐÉ)ą˙ÇąąźM™‚bĹdj—Ř.1Ńž`svuMîßőżţ5cŇ$EÍ&Sű.]Z¶o/ “SS×-^üĎ P5Ť»vmŐľ˝=ˇĄôňęžšşeĹŠŹßyEQ“ÁĐ˝{tË–Ź×˝_żí«W˙cÜ8ÎŢ©Gnë+ˇo@@·ľ}÷nÚô÷±cŔd0tîŐ+4:Ű®}úضíŁ1cŔh0$öęnG QÍBC»¤¤Ý»÷ĂŃŁŔ¨×wII  –íŇ»÷‰?5 :]r˙ţAaaöxÂcb:÷ěy.3ó˝‘#e :]ź´4/??oďÎ={^ĚĘzoÄ`˝^ßřpßŔŔ×lׯ_W©T………uěWŻ^-+++..®cĎÉÉ)++ł9ćŘpéŇĄŇŇR•JUÇžťť]RRRQQQÇ~áÂ…âââúBčěŮłĹĹĹő…Đ™3gŠ‹‹kjjęŘOť:UQQˇŐjëŘł˛˛¸řuě'Nś0™Lˇţ4MÓőUff&7TWź¬ő"9ť={¶Aű… ę R˙p̰9ŕŔŽăÇ3wďŢąăő°iÓfŤFóBá°,+•§ł„łgĂŔ‹ÝC€EďÝ»÷ŮgźÉd2»;ŐŠMµ€,ËNš4)##ðůóçüńÇ/: …ęfYÖÖŇ4ÝłgOnĹĆ‘——7kÖ¬7(ĚÚmbřf„`oĂF޶í/ ĂK´ţÜrŤeYÇsrr øqă>űěÓ‘#GxzzŇ4EQdHHJĄş}ű6I’V«ĺÂ… (ŠzzzRUż’0rˇpŔ11奥µ:ą˙ŽÝ»(* ŤU^ZŞU«{ŘľkWľť €ł“Ó±c›…†ŞJJtZmß´´¶ť;ăâěä”ööŰţÍš©Š‹ő:]ęđámxµĽĘă&•?ŢË×·¬¨Č ×9˛E»v(‚¸IĄoMŕáí]VTd4Źצ ^/JŠŤÇCˇ1y˛«RYVTd1™†Žݢŕ®PŚś2ĹŮĹĄ´¨Čj± ?>2.ł/Ľ\]GOť*•Ëąč˙#&M ‹ŠBĽÝÜFOťę$‘”R5rĘ”ĐÔţ6ŹŃÓ¦ D˘’ÂB†eGO›Ö,8üĽĽĆL›ĆçóK `ĚôéÍš5kÄż Ŕ×wôô鎗˘(:6=ÝßĎüýGO›†bXIa!†ăcŇÓý}|iCšŤž:J ůÁŘôt_OO 5e ˲%……ˇplzşŹ»{#Â/4"bĤI4E•:I$c¦O÷rsCÂŁŁßš8‘"ÉŇÂB©L6fútOűkĎ0ŤjŢ|č;ďXÍćҢ"…‹Ëč©SÝ  ¦eË´qă,&SYQ‘«R9rĘĄ\nĎ•ǰćmŰ5Ęh4–ą{{ż5q˘«D‚!HËřř#Gőú˛˘"/_ß·&Lp‘Hěńđ0¬MBBżaĂôZ­Ş¤Ä?(hč¸q ‘G¶ť;÷2D§Ń¨JJCC‡Ľý¶ÂÉÉ®‹&ŽwčÚµç€ÚššňŇŇĐč迍-x(šĐ˝{rjŞF­./- ŹŤ8r¤\(´Ç#$Ä^˝şôî­®ŞŞT©bZ·N6LĚă 0¬KJJç=Ô•••*Uó¶mű¦ĄIř|{®ŚN<^rjjű.]Ş+*ŞĘË['$ô4H„ă"‚č1`@ŰÎť«**ŞĘËă“’z ŕÄăŮă‘đů)·ŚŹŻT©Ş+*şwďÖ·ŻĂÄ<^ß´´¸¶m+ËĘÔUU‰={vIIrQ[^Ý»wo×®]XXX{Ďž=۵kWyďŢ˝ăăăëűŞôíŰ7>>žŰcą6ú÷ďßľ}{źzďĹŔ;tčŕíí]Ç>xđŕŽ;zxxÔ±§ĄĄ%$$(•Ę:öaÆuęÔÉĄŢZÍ·Ţz«sçÎ …˘Ž}äČ‘‰‰‰2™¬Ž}Ě1III‰¤ľ˝K—.˘zkGŽٵkWÎo¨6†Ţ˝{w>ź_?˙ÉÉɵ‡Ë˙ Y‡sG•úŞ!CFîÚµ9::.""Ćńwŕż WŻ^şwďVbb˛——·^Żű*Šää'Nś€Ý»wĄ¤ô®?ú˘P(:sc*żür0))Éb±ÔOÓşuŰk׮٠%×.d_‰Ťˇ( (JŤÚF¶p\sí*Ó,P*5 ~öěŮÓ§Ol×Ęĺň›7or©Tz÷î]???‹Ĺyyy^^^Ťü®@ (..¶5Žľľľ/^l×®]nn®T*ĺńxąąą‰„Ď燅…ĺçç;99†a:ťŽkň8?1î–Q5›ÍÜlŠ˘V«•‹g€ EQÜŇA¸ô vŁQ­¨¨`Y–˘¨¸¸8nAEQ<ŹźV«ŐÇÇçÁśŠ«ßÜׇN§“JĄ‰¤ĽĽĚd{j,‹=z$m˙ďˇÜ°0Íť[ÁĐČb6E‹‹‹Ł˘bŔŰŰűŮł'Z­cWî˙? bĐ´Z ‚"Ř‹([8†ˇ/Cmˇ/-A5jő“Ľ<]ŤFÂ'V]/ŢvŻK ĺĎy+ŮŮݧşşR*•~űíĽ’’˛qăĆH$ŇăÇŹ/Y’‘ž>-=}úýűąß}÷˝R©>|¨Őj]Ľ8Ăßßwâĉnn®ˇ¬¬hĘÄ©§˝;yňdC­ˇP{9|Nľv(ďĺ@im;(ş%$ŚIO2t¨­ĹÁ†ŇŰł€ MTÔW‹'uëfm‡ â©m@¸ŹĎşC‡b›7§^›‡}™$2ŮŃ;w|ýül˝U€ŕüQ_MoĎBďZyą¬ÖŞżÚéąü4nçNů˘čŁ—ÍŃóĐD…,KżJŢ`zoČŽh5šnnEVkíĎŚ˝ôµíVşV}+.,LŽŠ*Đjő ń0äËôČË|«v.˙woßÝ«×Ă’M­L6ľŔ™S§>›:őZnnM-âĄ[Wží Řłkך<•ť­n‡ Fí XąlŮéŁG÷8Pók<(n‡G0űË/Kź?_ąv­¦ˇ—˝OvĽ;uŞX*ť;ožî·đÔ~ŮĺS'OŢşr%¬Zµj„ őżˇż5úu˘I;ěŤŰłgĎž9sfýxNŹ> Ę׫‹[žćçwüţĂ%ŇţđńűßÜ€Ďg1Śd­[ٵü´çÎĐáˇ\äă×ěÔ68ő:(,,trr*((JĄśś G„$ÉââbN­Ő˙9Űýţ.ŠÚËËK$Y,–úNŔăńîÝ»çââÂ… «ď8ŃxѰţ‹Ň55Ňö˙ýČśťµ×Żð|~ă¨ütçi2™úöí»fÍÚѣDz,¤Ą đ7›-$IúúúŚńÖşuë‡ aXRRâ Aśť$IÖ ş^wČÜúęľÍniČnt­Nűö? U«SÎľ†ýĎÎS[t˝Ź˝ôż űyŘߏÇZK„łżfoůäěŮłíÚµł—&55•;8pŕoj°đ‹—j—íż˝­$qřŹÜá†đ×WáöË`Çń°°°ččh°Z­†Qe±X‰„qqqśO I’V«•Ű ul˙ŕ€8ŕŔźN°}řá‡Áć€`4ß˙=üMşű(ěŢőâŘrBŞV*¤Áq7«Őj[ůJ’díeí±‚\ąrĄM›6 wbäöíŰńńń$IvîÜůôéÓ]»v­VËąGÖI\ nçÎťąxJ6hŻ(ęčĆË—/×ŃfóćÍ IJJŞź[–eĎź?ß©S'N(ţĆž:b·lm6#˛˙_,˲,ò@ÓŚÉD˝Übđ•ĹPYĎŽ8ĆľpŔř“ 6°Ĺl±Z­ööÍüŹ€aš¦ąđÜľúźäÚ‘:QýŁă˝8đׂ őcÎľV÷Q&“ řŠŽ‚€ŐúŠ–ŕńAŔb±·†M"‘ŤF’$ ‚prrâ|qgYVŻ×Ëd2‚ 8ŤÔˇC‡üü|.$I}ÄĹĹét:‚ Îś9 7Ď`Żż«ŐjąwߦĎś9S{ă#@`0pÇ0ŚSw‹…K`2™PµăăăÍfsřčŃŁÚł¶’$“’’H’$IŇl6 ÓÎiÜíđx/—đ[kźby<„aX±“cí˙ÉökMľ˙8ŕ€üŁŃرcGnߤ˙X­Ö¬¬¬eË–=xđŔŰŰ{čС“'O®“ćńăÇ]»vEQ”‹©ĐĽyóú[ :ŕŔ˙‡ŇÓéô;¶I ¬L*kÝ©µ™‰öř1V©‹EâătsJyyyíÚµ+--5ŤçĎź÷ńń‰ŚŚ,))1 qqq&“©¸¸X©T†……QŐ¬Y3•Je i±Xjw[ëějÝ`Looo†aĽĽĽÔjµ@ ¨}yíăÇŹűűűÓ4MÓôýű÷1 S*•Üś——˲jµA.ÚŻ§§guuµ˝tť9Ăű÷ďËd2Çy<^>·…ÚköŃťś47Ż‚ľ:Ň9ŃćÉĘĺ5ą÷P• 0 ů·Âtŕ? A–eXö7ËŻ7“y8ŕ€8đ_!ŘD"ŃÇmź´ßäŹY˘V«wíÚ•””4`ŔťN—““#‘HFŚQ;ŤÁ`Đëő«V­2Ť øşş:*‡˙Đ4Üôʧ_żV2h°mţG8ožaÍjF©d1¬ţä˲2™ě‹/ľĐjµ$Irľ…ź~ú©^Ż‹Ĺ&“Éb±p[‘Ěť;wČ!łgĎ®Ěc۶m¶ŤJ¶mŰf›°Ú¶mŽăµ-6Ě™3‡ ĎČÍHoÝşŐ65˝eË›¤··÷Ľyó†aY–ŰăeŢĽy,ËŠĹbÁ`{ëçĎź?iҤůóç‚ [¶l±Ý—íĂ0Ű1‚ aaaß˙=Š˘8Ž{zzľvC€atDÄ «ŐřÝ|ŃÇźpš 1„ßÎ3.\3b08fRţ˘C#ŐęJçŮ–±ýf˝‡˘,M3NNbĹËço)NNb±ŔÔŠab©TńjDĘ7áA©\®x5ĽţÜ L.WÔŠ ř&ýŠ—<ň¦ůˇrM’oęâTÇAŻĆú:Ęd@: S(Aś›Ö«Ă$2Š˘r€¦´z|±TŠa¬i…,p‹q‚6íˇ‹„"AMĚŹ@(ň‚&–Ź €/„Bç—ńúßäĄ+Ę•G›˙Áf6›÷ďß?tčP›…˘¨={ö 4 «WŻććć˘([űÂ…  …µk×Ŕ¸qăŔd2ť;w®¤¤A:Řúa/^ĚË˱±±wď޵E5¸yóćÝ»w ::şyóćM‘|AÄĆĆ>\©TęőúĺË—ďŘ±ŁŽ`€€€€!C†üˇŇŃ^㎠¶e4z˝µO?Óß?~;Ź“gÄŃchQ+‘@˝­m>|xíëWu–eŢF„ I’~řÁÖ‰T€źW¬řCZŃš/ż´q  iš"ÉUźn#EQf“iĺgźŮ´MAH‚Điµ?,^l‹ş±Íz­öűE‹lä1›LFÁFA Ĺl¶ťGŻÓQeăőAPT«V#’őŕÁ;ß/†„yýüůó´´4“Évüź5ľ`“Éd :räH\\ó•ÇŹ9r¤@ X˝zµBˇ8qâ„Á`?ţöíŰ?řŕZ5ůäÉ˙śść ŚŃh\ľ|ůŞU«ÂĂĂkjjľů曄„„+VL¦ÄÄD Ă.\¸ P(âââ¤R)L¦Ý»w———'''›L¦/ľřbëÖ­~řaÝş•——7mÚ´vűÖ«g'đúłsáţýűaaa cfŚŃ6žvaa_¬]Ű=*ĘlŹÇ›zxl9~ĽyDaŹÇ$’ăwîxúůٲĹĂq6űBv¶D*µE“ŕ87Š‹qëÝ5‚Ń„ËMݍ°eAµJŐÚŐőaE…-7ŰŇÂÂľááO**´6đŕ8ţ(#cĘ€OĘĘT6đ°qüňůóźĎ›w;+«Ć–e^?ĽâÚµ)ׯŰÂĂÇńŤ?˙|ůě٤ăÇklkĚ+>˙Ľ¬¸8!1Ń–ë#Ćń÷çĚŠDËż˙^ó®<ź?kÖŢŤ **jćĚ™”0°ăŠ˘Ë–-űÓŠ˘#FŚřôÓOÁذaA©©©_~ůĄ››I’łgĎŽŹŹŻlŔxrĚx<^bbbPPózÁ‚“'OłŮ|ĺĘ•ożýÖŃŃQ"‘Ě1cáÂ…Ś/––¶zőj&ÁĽyó/^\O°999]ż~˝ŢS–¦éÚŻ¶†ű÷ďďÜąóű￯g Ľwď‚ Z­öÁ›7o¦(jŕŔöÖfÇM¬‰„˘!ĂĐü|D§W_»B9:"f3 â5~†Ńh¬őfŚF#3‚wěŘQĄR˝ffZˇPś9sF.—łX¬ž={ŢşuË`00(µ<555çĎź …8ŽwěŘńÚµk<ďĆŤ-Z´HKKc6ÓѲeËŚŚ 6›]7HIddä­[·ő˝»wď2ÓíLżłV1&˛knn.I’ľľľ8ŽËd2…BÁb±ž?,‹Ëĺ>}úÔÖkîę˘Ę¸( (j7ň÷†ˇee%Ž­Ű‡…·%ßIH (ZYY^UőRˇ¬ćpą<ʆQ<ĂŘl6lăAP”ÍápPx¸‚0<„ŤőA—ËEʶú‚pą\.†Ů~†ŤËĺÚz† ĂZ‘6ü(ŔĚă1WÉ–›Žp¸\AlĽYx“ |ř0!!ˇ˙ţ‘‘‘őÇ.·U«VĚkooďňňňÚ›˙UŹÇŇ3в2ŕωÓmŮ\.çüÝtLd˙… öë×ďĆŤŻw=»wďή{÷îétş„„„ ¬^˝zÉ’%ß~ű-‡ĂAQ”ÉĆŚŹŽaXmšl.—űäÉfU­® KOOŻ•‘ĚëiÓ¦˝f=ś¦é… 2gäĂr[·nť:u*MÓË—/_¶lł±óý÷ßź9s&SfĆŚ›6mz÷ Ž €ăś;Ţů|ăż>N•ŘńW‚ŤF›#‰ß™Ăl6˝|Yb±XH’´ŘśĂ@SAfŰx]ˤĹňÔ€°X,¶ĹŐ°M[Â`Ëü?ÎđX,ŰâO0źµm[ŘfaÍb[$€9şfăMG‹hÚĆ›ÎÜqÚf€ Űy0‚ (ОŘÜ)(’¤l®Ź€$IÚćÎn~•kĘKť˝vöµ5»`ćhYrrň‡~xâĉččhF ŐE†˝ľ­X,–íŰ·_ąrE«ŐšÍf‚ j7ÚÖý`]•e6›óóó' ðÁ×ă4 §NťŞ牦i@Őh5rss÷ěŮłfÍjxř­®séííÝ·oßşk†vŘa l6‡Çăý±3[˙^%cćĎ„ťśLlioš5 PŢfhFQ433355uŐŞUżŰOkCNY,–Yłf!˙Í7ßÔÍ{Ö0?!MÓz˝žĎç3ł-}úô9věXllěo}c¤nCäđáĂ 'bęŃ®Ył¦ö«;tč_~ů%|őŐWK–,“É_[¦6šŃ;Ş5 eďŘÉ]˝†ąp†Eź"vÁö7 (ŠR4Íű,..îěŮłL<A<<<˛˛˛ÂĂĂ)ŠzňäIĂÜ»uýWĆ©Z˝zußľ}QÍËËc|/EÝÜܲłłI’|úô)ó)E[´h±{÷îÚŘú MĄR9qâD±ř73Ł$Iúůů5*ŘŞ««“’’nßľ˝oßľşź"B«ŐJĄRŠ˘ôz˝@ `ň°UWWŰ#űŰń&¨ŞŞ,))1˙qž=EŃ2ą Ăq <ÜŃâbć$˙˙‘­ZíÚýń˙Í|D­V›ššĘ4ő×ě‰Ätä¤ÝhŠ™Sx«ĂQ4Mżf±ůŤ6ü}»ťçäAękó· ůŁxě7ËÎóßâ±ăź(ŘiÝşµFŁ9räX,f(ˇ(Ú­[·ďľű.!!Á`0¬^˝şžFBD TUUŐjłŮ,‰P-,,\˛d łcŠÍf·oß~ŐŞU?ýôSuuu||<3yĎăńşwďţńÇŻ\ąR.—?xđ`ÇŽ«V­Şű®®®%%% ˝˝F:´Zí¦M›.^Ľ¸{÷n''§şoeggO›6íćÍ›ĄĄĄk×®]Ľx±L&»sçΖ-[zôčaovü.¦OźisFźß@ĄRÝzŇ4Ś0›Ő—/Išb9ąŚxőí§ĘzLIľˇ`«í#Ż­Ćçó›5k&‰jjjňóó™Ók%%%Bˇ0??ź™ăŕrąL(HłŮ\RR"ýşZ—÷5ßH’dYYŮ_č.˘(Ťâťţm1íaGţ @^I/&Č0MÓŤ&·Öą¬é;Ŕh€xĺfYł[m,´1žFíV'#đĆĘ[łż Qg«¤5ű‹‡ą>Č[ň VęĂŘßd÷ٵňµv €xžzĺ˙+<Č«F[Ż|=űďnyµVަŃRݵ˙xXŻŇ©Ő-_ŰŮ»ĺ :{Łĺßvаă*Ř€ĂáôéÓgÉ’%ź}öY­(šź$IkT‹ĺÂ…  xýĚ7￯żpüäÉ“­ZµBQ”ĂáĽÝ ‚Đ29 € ZŤ(f ĽZ»ŁĹbuÚy`qi) Q*í©Řţö (ŠĎüřăŹÎÎÎăÇŹ3ĽYf$Š˘öSĎÎČ)(ŘłqăíË—Ylö€#†Ś/‰p€çyy»7l¸sí‡Ă‰5jđرbˇĐšśŕd=ľ+!!ăćM.Ź7xܸŁG x<Ŕ“ěě]żür˙Î>ź?düřQŁř\.iť'óÉ“ťë×?JOŠDĂ&Mę?b‡ĹâN›6íęŐ«Bˇ0$$äÂ… Ś=((hřđáiiijµÚÇǧWŻ^¶üH‘H4}út‘H¤Óé(Š˘(ĘÍÍŤyËÝÝťÉ,‹cbbX,–FŁńôôěŢ˝{m;ěhř4Ôëuđ램?ˇ[ŢąË>‚ü0őĉüçĎWďÜŢĽyN^ŢśáĂS’“§.X€4–mHIN.ĘËűyßľĐěgĎ掑züřäůóS’“K ÖíßܤIVVÖĽŃŁSŹźG[iEçŽ{YZúËš5ţţ™™™ďŹţäÉ13fś;v¬âĺË/úÉß×÷ţýű 'NĽpňä¸éÓ]µÍçŽSTU}ťŕíéyűÖ­˙›9óâéÓÇŹO9vLĄT~»i“—»űŤë×?›3çâ™3Ł&L°4*lôúsÇŽéuş•‰‰n..—ÓŇ–/\x5%ĄĎŕÁç’“M&Óg?ţčâä”–’ňÍ'ź\MI2r¤ą1ŤJ•’śLÓôkÖ8ČĺgŹ_óĺ—·.]ęĐłgJr2Š˘KăăĺRéÉ#GÖóÍ­‹ djěf)ŞŞR““ą<޲ź–ĹGöîÝďĆŤć‘‘çŹDË×­ …věŘ˝aĂÝ=˘úô15ÖxJĘĘÎź<)srZńË/|>×ĆŤÇvďîĺpáäI'Wׯ֭ăńxŰÖ­;}čP»nÝşvíjj¬1礝:ĺáăóĹš5,6{ăĘ•WÎťëÔ«—T.O;}Ú' ŕłU«p_˙ÝwWSSŰtîܶ];scţřâéÓíşuS×Ô\;ľ}÷îs>ůÄb6őá‡OťjѶmHp°}čţ§áŹOÚPoËÚśc7 ?üđCEEEffććÍ›{÷îýßY.±oy˛ăm V«×®]sýúµK—Ňţđ÷nÝň 6ŘěúűńX,`RQ[i´BˇPŻ×3‘9ř|>Š˘Ěkš¦u:]] סC‡âââz˝ 333::Úd2µhŃ"55•Ĺb]ľ|ągĎžfłŮZ7ˇiZŁŃÔ3^ąrĄnů7_Š´ľĺwíFŁńíbuÖű9ŤŐ–ÚCŹüíÔ®°1픦)ú·@äŃŁ‡Ë—Ż3fě¸qă×®]SXX MS 'MX×ÎźoÝşß°a(€Ç›˛`ZĄ*),Ľž–ѡCźÁQ)ź?íŞ«Ş ssMÚÍH;}şSŻ^=ú÷ąP8ó_˙*),¬*/żxćL÷~ýşEGÓbń¬Ź?.ĚÉyYZÚhëg¤$'÷:´SŻ^€ŁL6çÓOł>T×Ô¤$'9˛}÷î$€ł\·hŃŁôteu5b…ç̡CĂ'OŽěÔ‰purš˙Ůg÷®]3ęőg=}zDűö€»‹Ëü%Kn]ş¤Őh+“ħ4wnxëÖOw÷ůK–\II!,–SNyď˝f/OĎůK–\<}Úl25ĘśëăŹO&%Ń4}ţřńźîăëk źńá‡'öďǬTĆb6_:{öý/ľđôô´4‹<ţ‰¤$’ ®¦¤Ľ˙Ĺžîî€đÖ­'Ěť{") ·ÂŁÓjo_ą˛ŕóĎÝ\\€VíŰŹš6íÔÁF!ýúő÷–,qur"";u6iŇ©YVxjŠGééó/v’Ë)€öݻnjuöčQŤJ•ýđáĽE‹ĄR  cĎž}‡={ô(ËŠŁY^VV›;ç“Oäb1tíŰ·[ttÚÉ“UĄEEł?úH*@Źţý;őęuáäI¶•›^”—§¬ŞšńÁb>čŰŞC‡k©©ĄEE•ję‚":´ydäŐ”–žś'OH‚'`łYGŤ  ąsőj^v6Š˘ćĚáłX,‰;ÖŰß˙ö•+l+Ť™ŮfÝ~Kěřźő§ÖŞ5ű÷©ŇďŞnÝT–Sţ~u†ć`’*ý®*ăĺád#.ČłgĎ äččČfłOť:ĺéé.“Ét:]xx¸@ ¨¬¬€ŕŕ`‚ üýý«««á·é¶φÉó›©ßĆš<==)Šrww7ŤđŰ€®őDšµĐ,őt`đ«‰ĂzwuumT­Őn]ćrąo—‹¦žktŰ•Fk?Ŕöw×kL[Ł(šE <EQš¦0 -,,ŘĽył““Ăľ}{·TTTěŰ··ŞŞE‘F}Á’‚™ŁŁł3㔄†šM&­JURPŕčâ"wtdâ……ôzuM bĺŮ\”›ëęé)‘Ép ¸ysŤJĄ×éŠrsÝ˝ĽD c ŻQ*őZ­5a“˙ě™·ż?_(dĐM[¶¬®¨0™LůĎźűň6Đ´U«Ę—/Ťµúä>}Âĺr™ňÍ"#_”–‘›ťĘćr9$@óČȲâbk±[P€ś¬¬ŕćÍq‹@´hÓ¦$?ź˘¨ś¬¬Đđp Ç94@‹6mŠňň¬ĺ4Gr˛˛ÂZµBä×ňmŰääMçde5mŐŠÉÚĚŘóź?ÍśQNVVóČHŕľúŢĽělČ}ú´yëÖŚÂŰ´ÉÍÎF¬Ź'yŮŮá­[SŻrŽ7ŹŚĚÉĘ€üçĎĂ[·¦8(Š6‹ŚĚ}úÔI’…99Í##)†ăM[¶Ě}ú”˘¨˘ĽĽZ;Îb…¶h‘›•e͇łX,Ą……Í""ň§IłfyŮŮA”1v6‡Ë ËËÎF­\d“ÁPńâEXË–Lyž@ŕߤIÁóçf“©˛Ľ<´E Ć.‰|óź=ì Heuupóć4 –J=}}‹ňň :ťJ©lҬc—ČdîŢŢEąąÖ꣮©Ńi4aa4 sttvs+),ÔŞTF˝> $„ióÎÎÎÎ%•F¨¨Ş"·IćOgww‰\ţ˛¤¤Fˇ (Ę'0±»ş»‹$’ĹŨžĘ—/Q óôócţt÷öćńůU/_VUT°ŘlćP˘§Ź‡Ă©xńµŇI_–”đWOO¦€O@Š˘ĘŞŞ—ĄĄ±ŘŮÝť±űŇ4­¨¬´gČţ⿬ŇŮlöČ‘#q abÓŮaÇ˙„`űł¨ ‚öó6—÷ĹçHyĹŻr‚¦ ‹>%ştˇ…BšĆY hš–JĄK–,Q«Ő‹…Ů–üé§źjµZ‘H¤×ë™x­°|ůňQŁF-]şT(Ŕž={j÷:îŮł‡ĹbíŮł‡Çă1–Ý»wă8ľ{÷îZK-ľüňK‡ŁŃh=¶k×®ÚŤ—»víŞi{÷î0`ł^±}űv ĂbbbŞ_ż~púôičßżAAÁ€Nž<‰ ČŽ;úőëÇÄ[˙î»ďjc­ď…ăř˛eËü†íßż˙-ôźŻ[÷3ŕ‚hµü˙U»+’‰´;w /^Ź‹ŤöÖţ÷FíJŽceeek×®ľvízHHČĂ0 »}ű6Š˘ŃŃ}###)ŠĘËËżrĺĘłgĎťťťĘ@ŁVóx<)Š=yŇŰß?24”$łÉ¤U«ů|ľE''„„´lŇ„°X¬­ 1ľ©P$ŁčC‡šED„ůů™M&ÂbQ×ÔĹb1ŠîOJjŐľ}°··Ůh´¶Ť¨”J±T*DŃ˝{ötěŮÓ×ŐըדˇV*%2™EwďÜٵo_/ggNW7mF=žĄR*—óPtç¶m}bc]d2ťFCQ”Jˇ9:rdÇÖ­ý†w‘˵j5e]hŐ(r''‚$nÚ4xÜ8g''µJ4]ŁP88;łdëĆŤĂ&NtqqQ×ÔXZ@MuµŁł3† ›FO›ćěć¦R(h€…ÂÉĹŘüË/cfάµ[JˇptuE6­_?aÎg7·…WWš±ĎťëěćVS]mµ¨”J'WW’$7oÜ8qÎ'W×…hš±› bÇćÍ“fĎvruUľ†‡¦Ő55NÎÎŁq×öí“fÍrtq©©®¦iZŁR99:j †#»vMš1ĂŃŮů5őˇHR«V;ËdŐjőÉ&N›ćŕčXŁPĐĄÓhś$’ŠššłGŽL2EîčXŁP VG„^§s‰J*+/ž93n©\^ŁP$iĐ霄‚ňňk©©cÇŤ“Čd*ĄŇ*ŹŮl2śůügĹĹ÷nÜ5r¤H"QŐÔ0]Ŕ‰ÇË*(ČĽ{wäđá"±ŘŔtGçÁłg9YYCccBˇFĄbrü:q8÷ž>-ĚÉĂ4*•5ŁÁ@Q”#‹u33łňĹ‹ľ}ą\nŐË—&hÚĹşžž^ŁPôďÝ›ĂáTľ|iŤÇ ×Ł(ęăi7oZĚ樮]q×ëtl’ÄPTŽă®]Łzuę„á¸^§C¬ Z‰T*ǰ3iiˇ°K›6‚ ˝V+‘Éävęüy‰LÖ)" z˝}ܶ ¶˙4P µß ;ěx5x#Á4›ĹIŘ€hµŚ°tďf|°XV Đŕ,ĽŠŞ?věŘşŹ˙ &4ô FŽyţüůĹ‹3Ž3¦ö-ću] CX—¶ö­iÓ¦ŐµŚ7®ŃףGŹNJJ"‚˘¨‰'2Z‹˘¨É“'W×ń9ÇüŹ Č„ ’’’Á0lĆŚµĆäÉ“k_ÇĹĹť\÷ĎŁGŹ6,“śśxěرZËńăÇë•Á0,11±®ĺÔ©Sďć§#JEíCR»s»48©¬D« ŞĐi~UËvüÍ0’ ©ŞŞŠŽŽîŰ7j×®ÝçĎź ôńń­ŞRxzzŠĹ⊊ Ç]\\ęžŰ¬@(őúŠŠîßź¨41gs8"±Ř Ó©(ŞL Pa0°X,6‡C[éýb©T§Ń¨)*vČ BŻgsą8‹%–H´jµš˘†NTčt.—ÉnÚ(ŹD&S«T:Š1z4 P®Ńđř| ÇĹ2™Z©ÔQÔ¨±c €rµš'ZŰşLHärĄBa éq'ĺJĄP$BQT"—+««Ť4=~ňd \ˇŠĹÖÄ upPTU™üý'M›f(ݬIĄ€ RąĽş˛ŇÍËkňôé€ňňr‰Lfőč,€ÔÁˇşĽÜÁÉiĘĚ™f€˛ŇR‰L†HĺňŞňr‰L6ućL3@iq±D.M7–:8T–—{űűO›5ËPńâ…ÔÁ$ryĺË—^ľľµv™Ăk$„D&«|ůŇÝĂcęĚ™F€Ę—/e€ ŚÝŐÍí7vëŞH"©¨¬tvrš<}ş¦+ËËĄŚ˝˛ŞĘŃŃqŇ´i𮮍x ŠaB±¸˛¦F&•Žź<Ů@QŐ••RE"QĄJ%—JÇMš¤§(EU•ÔÁÁš2Áqś/TjµÎŽŽŁÇŤÓQ”RˇČĺ†ńřüJťÎŐĹeä1ZŠR)•RąÜÚ΋Ĺĺr+ oOOżáĂ5$©Q©ÄR)Îb±9śJŁŃ×Ç'ŔÇGM’µZ,“Yël.—ĹfWšLM‚‚B‚‚jHR§ŐŠ$6›ŤłXUfshppXpp Ięu:‘DbŤ‡Ëăˇ(Zm±„7oŽ4o®$ŁŃ(‹9\.Pm±´lŮP„ÉdŠĹÖxxEQŐŃ®m[¨¶X‚ŕ …,6›$IAtčб“Áo, PˇĐb±(H˛k·nPe6Ó4ÍĺóBˇŮlV’dŹž=i€Jłx|ľ}ÜţÂľÖ;ţ 9{†vpřăË˙eçęž>}ú_řVŠQ]˝üď'±Xd7ňŹl4EŃ4M›LĆž={¶k×Öd2EG÷„yyů`6›0 §Nťľw/] 0ůµ©ĆÂD’žľľŐ••Őĺĺ̦Ŕś¬,—+’H<|}+ËË••̦ĂçOžđ‰ß”đxQR˘R*-@öÇb‰„/x”ŞkjűÓĚL‰\.‰ďŕפIQn®VŁ1 Oîßwpqáp8~AAĎźëu:3 đ8=ÝŮŐ•ËăY«O@ppnV–Ń`0 ŹîÝsőôÄY¬€ŕŕ珛ŚFđđî]ook’ yš™i±XžĚ;wĽüüP Ízđ€$†çÁť;Ţţţuáú8#"I#yçŽ_P H`hčŁôtŠ˘ŚŻxü›4yÍňđî]`v??¸s' 8¸žťČĽ{7 $„¶>¤úgŢąókyŠzx÷n@h(řeŢą(’|”žjŤĂ0źŔŔ‡wî &’ žÜżŠ˘¨—żćÝ»ŚÝb±d=xúäáăóđî]Ŕ`2™ž=~Śă¸»—ףôt†Çd4>ň$ 8˛r‘9<žł›Ű“Ś Ŕ  ×éňź=ókŇ„Íá8ą¸<ąź±ë4š‚śż&M¬ńđ…B©ĂÓĚLŔŔ„áń `ş@öĂ‡Ś˝F©,+*ň  ­Ďbđ‚çOž ¨¬¬|ńÂĂ×W(sy<ćĐ P]QQ]QáéçGZi„rGGÇóź=cĘWĽxˇR*Ý<<¤r9‚˘99L±ňŇR­ZíîéiŤÇÉĹ…$Éâü| €(-*2 N..ŽÎÎłą¤°±—Ífg77Ę Ź«§§A§{YRÂ2*ĚÍĄiZîŕŕâî®U«_––2(xţA''Ę>pŰ›vŘń˘ŃhwîT_8ŻI=G6 ú‡čkü˙ ÇÝŐU{ř௿Fe_[űGô˛:["I’”JĄBˇ€ ą\NQłŚ†ă8I’Ť¦GŹîÍš5Őh44 (Š6zŐĐąwďGéé§Ź!4Fcb|ĽH"ńôőíŘłgĆ͛玣ÔĂ–5k䎎Ö|S3@ĎţýŻ]¸vęÔhµV®ôđńqruíѯߥłg/ź= JŤ&áűď}]=<őá,}bcĎ9r=- ¨Ş©Y˙Í7!Í›‹ĄŇ>±±Ç“’n^ş„T*•ëľţşYD„ĚŃ‘¶ÂÓořđ;vÜ»~xYY˙ŐW­;uâňxý†ß·ukĆ­[8ŔËŠŠřĺËŰuë&°˛@ 9rÇúőďÝĂJËĘÖ.[ÖµOśĹ0rä¶řřG8@IiéÚeËş÷ëgm’9răŞUO>d®]ľ<*6A#G&|˙ýłÇŹŮůůńË—÷2ÄÚ¶= ˙đáëľů&÷éS6@Ţłg?ŻXŃÄč7lŘO+Vä=ÎČ}úô篿`}Ó5Š˘}Ž_ľĽ ?ź đěńă„~8r$‚ ˝ Z»|yaa!ŕéÇW®8j”5AÂbł»GGŻY¶¬¤´xś‘‘3j†ă]űôY»lYé‹8ŔŁ{÷v¬_?pÔ( Ź@(l×­[üňĺ/**p€ű·níŰĽą˙\Żu§NńË——WUá÷®_?¸m[˙#,VxdÍ##Z±˘B©Dn]ştb˙ţľ‹$’đđu_]USÜHK;sřpßÁ-V‰‹»»oPĐ/ß}§ĐhŕňŮłOźî1`€Łłł§Żď†~PjµpńôékçĎ÷Љ±XąéŢţţrgçÍ«W«  %99ýƍν{{řřĄŇ­k×jŚF ŕĚáĂďÝëeŤ'(, g±¶Ż[§5›I€ăű÷ç>}Ú¦K˙ŕ`š¦w%$č, Ŕ±˝{ ssŰvíj±Ň›EFęµÚ}›7IŇLQ‡vě¨zů˛yëÖa-[Ö(Me˘¨¤ÄÄ…˘e۶„•ÎٱcYqńá]»Ě4­'=7šÍć&M›¶ęС(7÷ŘŢ˝€ŢbŮ•!ááÄ›Ťo_|ń…‡‡GĂM(‹-ňđđHII©g˙裏<==/^ĽXĎţţűď{yy]»v­ž=..ÎËËëvmzŘW9s¦··wzzz=ű”)S|||>|XĎ>aÂ__߬¬¬zö1cĆřůůĺääÔł>Üßßż   ž}đŕÁ%%%őě111AAA/_ľ¬gŹŽŽ®ŞŞŞgŹŠŠ Q*•őě=zô k»k×®M›6Ő˙Ég í["í°ăŻ ‚ "#ĂŃj˛Ď©ý©rŤš¶DE>_,śćń“É~Uţ)÷ž¦hš’$(Š‚° s8‡”ɤz˝ľ¦¦† IúâĹ E„BE‘ WŘ,ámÚtěŮóęąs7oŇ$©V©FN›ćŕě,’H:tď~ńôé;WŻR$©®©‰™5ËĹÝť´ćĂuęÔ®K—łGŽ\IIˇHҨ×G $–J#;vlÓąó©/ž>M’¤Ĺlî=hĚŃŃš`kߣǍ‹ŹîÚuöČŇbAP4*6–'´ďŢýÚůó·m;yŕi±°Řě¨ŘX‘•Ý_@—¨¨.ěٸńđÎť„Ĺ"‰˘bcŮN—¨¨ëçĎďZżţ@b"a±ĄŇ¨ŘX.źoŤ§{ż~7ŇŇ׬ٝ@ÍŽÎν Â0¬Gż~×ϟ߼jŐ.—0›ťÝܢbcYÖWęzĹÄÜHKűĺŰoYa6{x{÷8AŢ117ÓŇÖ}ý5‹Í&Ěf/?żŢ"Ö[Ô A·.]Zóĺ—,6Űb6űőЉWö?˙ś±„„ôЉ±6m† HźŘŘ;W®¬\´gł-&S“¦M{ŔŘď^»öý§źâ,–Ĺd ď1`€Ő•16»ĎŕÁ7o~ýŃG8‹e6›µjŐ-:ð>±±÷oÝZńᇌ˝ydd׾}­ 6.źß'6öŃ˝{ËŢg±LCËví:÷îÍfłŁbcgd,}ď=śĹ2éő­Ú·ďÜ«—5‘Xűěńă/ćÍĂpܨÓEvęÔ®[7ľ@››•µ$.Ă0^ߦsçvÝşYlrGǨA6˙řăâŮł1 Óëtíşu‹čĐÇăő801>~ѬY(†´ÚöÝ»GtěhMhą¸»÷Ž‰Ůłqă˙Í ¨^ŁéŘ«WóČH›Ý+&f˙–-źLźŽ ¨NŁéÔ«“:˘ŃFčéç×sŔ€#»v}>.Ń9*ęćĹ‹LŔ¤4fŚ·ż˙ ¶»wď–••Őłßľ}»¬¬¬ˇ°ąyófiiiYYY=űőë×KJJ ž«WŻ–””TTTÔł_ąrĄ¸¸¸ˇştéRQQ‘Bˇ¨gOKK+--­©©©g?ţ|eeĄJĄŞgOMMU©T …Óąsç N§«g?sć I’ ŐŮłgŔŘ ´Xjj*4–L‘˛ íW®\a\¶?őAe_ałĂŽżěä?‚čtZŤ¨ŐvµöźEAľüŇđŮăÂ…`%ěž?ąV%2''§¨¨ĹÂź>}J„ŁŁŮl ,//řđˇĹb6›Mׯ_GQÔÍÍ• †yŘ(ź?dܸ&M›–VUTô8°KTEĄ<ŢЉCBJ «++űұW/Ž[Ű‚č(Ž2Ĺ'  ´°PYU5`äȶ]»â" GN›ćéăSRP ¬®8ztŰ.]ŘfŤÇY,3c†‹»{q~ľŞ¦fčřńíŰcâ,‘Śť9ÓÉŐµ8?_­R ›8±e۶¸uW™lüś92ąĽ8/O«ŃŚš:µYDŕ*—Źź3G,•ĺĺé´ÚŃÓ§‡µl‰YHNNçÎĺ Eyyaě¬Y!Íš!ÎÎçÍăňůEyyFŁqüśĘĂ*ć IDAT9MBCQëgŘĽÜÜ&Í›‡łXEyyfłyb\\@Px{xLš7ð˘Ľ<‹Ĺ2iŢ<˙€€×l‰ôőöžEąą4EMž?ß×Çü|}'Í›GSTQn.Đô”ůó}ĽĽ^3ZLś;— ˘Ü\ æĽ÷ž—»;5i2a΋Ů\”—‡łX“ß{ĎÓŐŐšđC$8,lě¬Y&ˇ(/ŹËăMš?ßĂÉ iŢ|ěĚ™F˝ľ(/Ź/Lš7ĎÝĘr(`(Ú´U«QÓ¦éµÚ˘Ľ<±T:qî\™ AđČČ‘S¦č4šâĽ<©ĂÄąsťe2k[q kŐ®ÝĐ Ô55ĹyyŽ®®ăgĎv‹1‰ěĐađřń*Ą˛¸ ŔĹÝ}ěĚ™Žb±56Ž·éÜyŕ¨Q5ŐŐĹžľľŁ§O— 8жëÖmŔĘęęŇ‚‘S§Ęk<\ďÔ«WźŘŘꊊŇ€ĐĐa“&I¸\6Šv‰Šę=p`UEEYaa“¦M‡N ĺń¬nŃd±d†•/_–7Ť3FČfs1¬gLLçŢ˝+^ľ|Q\ŢşőŔQŁD޵­ŚB6»ĎŕÁí»u+/-}QRٱc˙aĂř,źĹŠ2¤MçÎ奥奥m»t‰:TŔf[ăsąFŚhٶ틒’Š/:öęŐkŕ@.†‰8śŁF…·nÍŘ»öéÓsŔ‹ő†űmzöěŮşuë&MšÔłGEEµnÝ:00°ž=::şM›6~~~őěýű÷oÓ¦Ť··w=űŔ۶mëééYĎŰ®];ww÷zö!C†´oßŢĹĹĄž}ذa:tprrŞg9rdÇŽśŐ=zt§Nťd2Y=űرc;wî,n’m„ ]ştaBd×Ĺřńă»víĘop&pĚ1Ý»wçrą ëÓŁG‡Ó°ţ˝zőŞ ‘ýgą„^-•Vi«GŚŕŔ®fÍZ„†6·?Ĺíř«áîÝ›Ź?čÖ-ĘÝÝC«ŐüI§°d2YTTźÔÔópđŕţýű˙’ÝĹbq@@Paaa~~ľŻŻŻ˝yĽ!4ŤX,‰D/ MÓ](ZZZÚ´isđđđ(,ĚS«5ö+üťĐĐęÔj‚"†aŽa8†ˇ†á8ó‚±`,«F©Ě{öLSŁqXÓK÷>®ŔF6á,%wńT(ޤRéÇrúôŮýka—.ťţmÉĎÍíôĂ ű–H;ě°Ă;ţąşďŐ–HÚ`0ř§¦ž˙ć›ďš4i2kÖŚ  @˝^ďĺĺ5nÜŘÄÄíŁFŤĹ0´[·®Ă† ‘Ëĺ ă;5ňh§ę®ĎŇżg·˛Ž“W·Ľ5űçwíoÂCżÝ:"~ű˙:O]1ů†<„•úĽ9mĄ<ýßă±Ô™ ĎţgóPVĘSoĎó‡ u§´~÷µµňvű_vÁf‡vŘaÇ?L”H­V;iŇłŮBQäСCd2Y@@$‰ HÓ¦aqqs*++ńđp÷ňňb┼&ý–v;Źťçç±_ś&ŹKüťŰľ¬i‡A…BűExs4ÜĹnÇ?Đ4Pe2™BCC™X‚8Ž‘$i4šCä‹…ĎçGD´bBĚ[,łŮL“ĎĐ~ í°Ă;ě° ¶FdZ­.--ŐjµÇÉɉ9×h6›÷m‡vŘa‡]°5łŮ|öěŮ„„„'Ož¸şş4čăŹ? …/^Ľh۶-4†$ÉŔŔŔ{÷î€Ńh}ęáá1tčĐ… ňíyâíř» 66Ö~ě°ĂVÉöökeö vŘa‡vŘ[ăĐjµIII ,.//ß¶mŰĘ•+—.]JQ”››ŰĚ µá5•Jĺ‘#G>ú裠  ’’’ť;w®YłfѢEö{oÇ˙4ŃjµöëđnĐh4öýŇvŠ MS4ýÖíáÝdžvŘa‡vü‘‚Ť¦éÍ›7GFFFDD0–Ű·o?|řpĘ”)sćĚ5jÔŢ˝{QŤŽŽ2dHí§öíŰwá‹կ_ż†'77wÓ¦MĄĄĄ...ăÇŹoŐŞŐ›?ëůU`Îś9mÚ´‹ĹJĄň»ďľ[şt)MÓŔÉÉ©6“óY‰D”‰DţţţUUU vÁfÇ˙:ôzýš5?j4Z»đx°X,“=/ö?€BYMălćŰ»č= I’„2[˛đpK ĘlI7!@1L(ËL6ň H*•ý6L˙;ü.@‰T*«ůđŔĹ#µm*ăôHĆŘ~K8"űm¬˙whD‚ŘxÓQŤTĘÔ·íâ$EĄŤ?}cp„b1†aŰ.2@ â,–ض›.ŕńů,ËĆú¸<›ËµńúH8\.—Ç“żŠű˙Ž$Ż‚±­ä—·ăź"Ř€$Éýű÷{zz:;;—––&%%………‘$ąqăF6›m0H’)))(((88Řl6oßľ˝¤¤AĄR™’’RO°ŤĆm۶5?ů|ţرcëą\nŻ^˝~­=ŽűůůŐ&/++;tčN§sttlٲĄ»»;ŁâzöěYëĄůřřŘ5;ţ0›ÍcÇŽE­d§µăwg‚”JĄ]ëţŁŰE‹ĹťVŁŇäOŁ!ĘfsdňsÉÇ,f“ن‡ O (+.>sřpyYayw‰Äă󕕇wíz”‘Aď®&¸|ľNŁŮ»qăeoďwSłżúî\®ŮdJŚŹ—98ز Ébł)’ܰr%϶ (ŠŇ4ýóO?1!dŢEMŻIH m¸8`4HŠZ˝i“ņ›Ž HŤBa1›WmÝj˛!q(Š˘eĹĹ:­veb˘Ń†4•Ž?ňDYUµjŰ6^˙î*‹u˙Ö­%%«¶o7ŘpüÍá\IIÉţÜĆúp¸ÜŰ—/«”ʕ۶mŕáňxďŢĺpą?Řpżx|ţŁôtćőłgĎ?~¬·ˇJvüI@Q”˛mx#Á† Čěٳnjsěر#F9r¤ĽĽ|ĺĘ•fłY$ŤĆ­[· †yóćíÜąó«Żľ"IrçÎťR©ôçźÖjµqqq»víZľ|ąŮl޶mŰ®]»şuëV]]˝~ýúz_d0–.]Zď\MÓÎÎÎ []¨TŞ .tęÔ‰rîîî+V¬0™Lľľľś8qb=N…BqĺĘ•Ž;ÚŰ˙ë@DĄRŮŻ-Đ~ţÉ (ŇŃŃ ČĎĎ}gßť$ÉHg·C‡ÝJKłE (Ş©©9™””rěŤý”¶Ť‡"IłÉôÍ'źŘ" !B§Ń|ýńÇ6ňX,N·âŁŹlä1›L&ŁqĹżţe#ŹŃh$,[ë˘ťŽ˘¨ŻmćŃkµ‚<ĘČxgEőš_Ónggg§¦¦ÚW#ţŞĎš?_°1řţűďXQQqřđá3gÎü:}‚aź|ň ›Íf±X|đÁś9sÁvőęŐ¤¤$6›-•J?řŕ ,_ľA>ź_\\\]]íŕŕ°xńâz_!“ÉŠ‹‹ßÖŁ˘(ęîÝ»»wď>pูą=yňt:Ýőë×WŻ^MÄĽyóę>Yoܸqřđáýű÷ŰvŘaÇ?\łSÍ<ÎŢU°Ń@Ó R*>_łvö{óő6,’HY¬ľť:MŚ‹6v¬Ń6žöaaźŻYÓ˝Oł >wî™33ç3çśç$'µlYz^žÖ—{ňđářź~ş|çŽ-:".wűĆŤ7.]:rîśÎ¶ĆĽfĺĘ[öěŃŰvq}´x±X&[ýý÷Ťo«#çrW,\xhÇŚŚ\¸páoe X~CP]µjŐ˙‘aóđđ6lŘćÍ›?řŕWËĂńńńyőKUUĐ4]SScŤŁ(ęăăSYY ŕË/żLLLܲe‹źźßŞU«¬eZ]Ţí?™÷R»{÷îš5kţö·ż˝:«Bˇ0`€^Żß±cGKĂvăĆŤőë×ńĹžžžlbaaaůC?G1´ŞŞÂľ{ŻÎ=ŢnW CkkkÔꚆµ@(ĐÜ·_Ĺ&@1ŚÇç‹Űtĺ "Ě1‚ |ˇP@Řx<"‰„FŮ0 Q"‹EŽíkŘ„Bˇ­kظ\"iCĺ „HôŻZ˛A…‚^Ř[WÎ+Ü_ @PT`¶AGŔçóQ łQGŔăń0G `±M‡Ëăq8±mőc˝6ą\®Č†‹KđęĄő•»Dâ÷Í/߲t:]^^^DDÄÇ ‚xŐ>,‹P(Ç_Ů-.—‹ă¸u$ŽăÖugĘ”)b±¸¨¨¨¬¬,66výúő-?Â`0|üńÇŻVOľ˛j2™lÍš5íUFFƦM›†:bĶ˙+•J;wî\SSó*’––¶cÇŽČČČČČHö¬ł°°°üÁAÄd2ňy|™ěí3X,–ššJÇI’ÄmKÎĐE„Ĺ6 Đ4‰ă¶ëĐŽă¶ĺŐŔ€¦qÇly˙ϱęX,¸Hd‹ałţ-N´Ť#lÖMŐmˤ‚ŕ‹µ¶m9Y(ă@Ó6ęXĎ8MÓ66f䥎ŤÇAQnsc&I’˘(‹Í)I’IÚ~qQ$IÚ¦/‡Ôر5Ö°śűěăŹ?>{ö¬5!$EQ)))cĆŚ!Iňúőë:t°š{˙äääŃŁGqíÚµ I˛  `üřńpéŇĄ… ¶2l$IćääXí_KæR©ÚEQEEE'Nś‹Ĺź}öYKůěŮłŽ;˘(ÚŘŘ••ĺëëk-˙ěŮłS§N)•Ę?ýéOě EQЦ­ŹŹ·éMbŽă‚ ězH–˙ a«®®Ţąsg\\\ÇŽ˙ň—ż|ýő×C†  …$IîÝ»7((Čd2íŰ·Ďšľðť;w †Ś7Îú,\·n݇~ččč¨V«ÝÝÝ[}ŠL&KKKk˙‘ÚfJdssó¶mŰ®]»vňäÉććf‚ PU(:ť.66ö>°··đŕÁ‘#GĆŽ z˝~Ë–-GŹmjj"Ă0ą\Ξ{ ię-’ĐĐ4ýšÜ’ČĎĽá/ÇYuč7‹˙Oč°'ťŐ±E‡ĺgŘ(ŠZ˝zőôéÓ­h}űö9räŞU«ľ˙ţ{E»ví:věXš¦GŽ9cĆ ŕp8sćĚyţüů¸qă¸\î#^Ĺűöí;wîÜúúúoľůćÍŹŻíCTŻ×˙ř㏠WŻ^Ö´QŮŮى¤K—.łfÍŞ««óöö~÷ÝwçĚ™jµzÓ¦MBˇ°GŹÖ HAAA·oßfĎ= ËäĄőz‹}‚0ý Ŕ°Nç ­ÓŰÄ â—ş_Lĺ1ÎŻŃa*˙:Ü—•F´ÍĹť–S.™âŻéÁp¬{2-Ę3Ĺ˙tŢd%ĆP{ą×ßęp^vňZ•gŠ3]#ŻĘSÄËňLń7Ôy5E–)ţ:Ü—Űš˝ˇN»ĺ[ĆIâ—tPN{ĺ™âo¨Óň¦Ńnś…5l?{-X°ŔĹĹĹ:ŤĎçOź>˝ˇˇ˘( ĂfÍš† ···X,¶ţ‰ŁŁăG}4iŇ$kŇkśĂáŚ;Ößßßd2)•Ę.]şŘrÄ*•ęěŮł|>ßb±Xź˛ÖÜý|>„ ;v4Ť2™Ě××׺(ÎŮŮąUy©TĘžx+ő6#lEĐmwĐ•–ÚľýŢÍ›\>Ô¤I㣣ĺR)  ¸řĐöí™·oóřü1S¦Ś‹Ž–‰ĹL6@WXx0.îţÝ»‘(ę˝÷ĆLť* ąOóólŰö0#C(Ź˙ýŃS¦ř|¦î˛ çÉ“ý۶ĺŢż/‘H&Ěś9rŇ$>—Ëxřřńţ­[ź=&fŔ A8ŕƵk¶m{QQáęá1céŇţX^Űťş~ĺĘÁíŰkŞŞ<Ľ˝g,]Ú·o_3ŕęĄK‡¶oŻ­®öôőťątiďŢ˝ÍĚ.¸rţüˇť;Őµµ>3—-ëŮ˝»µüĄłgďÚŐP_ď8céŇaa&fš¦Ďť>}tĎmCC`‡3—.íÚĄ‹€˘¨ÄS§ŽÇÇë4š Nťf,]úNçÎ&fDâńă'÷íkÔé:ĽóÎŚÎ:X,8~úرSű÷756vęÚuFLLÇŕ`łm6™Î9rćĐ!ŁÁĐĄgĎé‹ŕŁńěáĂg667wíÝűýĹ‹üüLĚ•¬oj:sđŕůăÇÍ&SŹ~ý˘-ň÷ö&tŤŤ§¸xâ„Ĺlî9pŕ{ úyz2épÔZí©}ű.ť>MDß!C¦ÍźďĺćFÔk4'’Ďž%I˛ßСÓćĎ÷pq137žęúúăńń×.\ )jĐ“çÎuut€µµÇöěąž”á#GNž3ÇŮÁÁÂÜË_Ľ8şk×ÍädE#ĆŽť8k–J…”UVٵëöŐ«† ‹Šš8s¦ťBłwmÖ°µ2lďĽóNË»»»»»»ŮlFÄŐŐŐŐŐµí_·ŇqvvvvvţMŽX Xg`¶ľ­ h»‡$‹Ű-ĎÂÂÂÂÂBÓô/6 Ăx<Šb@’„Ĺbˇ( i;.‡hš›OîŰ—˙ř±»ŹE’ɉ‰v‘ăÇ7™Í' óň<||H’Ľtú´ťŁcřčŃÜöŇ˘ę¦¦Ł»v•yúú’$yţŘ1gçĂ‡ë †Ă;wV”–ZăgvtqéÎÁ°vujuşŰ·×TUyůů8~j˙~g7·Ôęő¶m«Ż©ńň÷'püDB‚ł›[·Ţ˝1ť ű¶lŃi4ÖňGwďvőđíŃŁZ­NزĄI§óö÷',–Ă;v¸zxtxçťvWŚŁ•uu ›6™ŤFÜb9°m››—WP§Nµµń78î`±XöoÝęćĺĺŇî©AĘŞŞölÜÖň{7ov÷öö (­¬Śß¸EQź€‹Ůś°i“»··§Ż/Ó)..+‹ß¸‘ËăYËÇÇĆzx{»yy—”ÄoÜČ^ĹÝ˝˝]=hÄő ßĹĹɕʔsçj«ŞÚMuĎČş};ýćÍaăÇoHHXłu«@(L>{VŻŃdĄĄÝ»ukäĉľŮ˛…Ëĺ&'&6ÔŐˇ :wŻ_ĎJK‹ŠŽţ)>~Ő¦M4E]IL4 wŻ_Ďľ{wÂŚ?ĹÇ˙=6–ŔńäÄÄF˝ľ][ø•śü0#cÚüů±ńń_®_ohjş’h1›o&'çdfľżxql|üß~ü±Q§»’hjnnW¸~ńâ“ć¬XńS|üçëÖ©ëꮜ9C’äő ž>z4băă?_»¶®ş:91gčl WĎź/xňdń§źĆĆÇ˙yÍšŞ˛˛äÄDš¦SÎť+ĚË‹ůüóŘřř?}óMEqqrb"ÓöÄ@rbbqAÁŠ•+căă?üúë’‚‚äłgŕJbbŮóç~őUl|üŠ/ż|ţěYĘŮłs+şrćLUYŮ'«WÇĆÇÇ|ţyţăÇWĎź·Ć«+*ţĽfMl|üâĎ>{–“ső¦ľn±\9s¦ľ¶ö/k×ĆĆÇĎ˙čŁÇ¤&%‘$yůôiŤZý×ᅬŤŹźłbEnvvjR‡áK™š›Żś9ÓÔظňÇcăăß_ĽřaFĆ­äd‹Ĺrụ̊ѸrýúŘřřióçßOOżťśĚ¤Ó¤×_NL$Iňëź~ú)>~ÂŚYiiwSS› †+‰‰đ÷ŤJHŠŽÎĽu+=5•Ëp˛ęë“y|ţ7[¶lHH9qbúŤŮwîč´ÚäÄDˇXĽfëÖ ĂĆŹż›šš•–Ćeh<5UU)gĎ*TŞoăâ6$$ 1âÎŐ«ąŮŮő55)çÎŮ;:~·}űú„„ţi))Ź22¸ Ťą˘¸řęů󮞞kwîüqďŢýűßşr%?'§ŞĽüÚ… žľľßďÚőĎ„„n˝{߸|9ďŃ#ÎóüüëIIţ:¬Ű˝ű‡={:té’š”T\PPRXx=))¨sçöěůaĎž Nť®'%ćĺ1éäĺäÜĽ|9´GŹĆÇŻŰ˝ŰŰß˙Ú… •ĄĄůŹßLNîÖ·ďŹ ßďÚĺîí}íüůňçĎ9썛5lou" Ë˙2u„Ť¦™~hEsssW­Z=eĘÔ÷ދްaCYY‚ 4MµťŻÇ¸ť’Ň9,läĉ€L(śóÁŤZmEIÉť«W»őî=|üx@.Ďűč#u]]iQQ»†ŤpíâĹţC‡5 ”RéÂ?˙ą˛´´®¦&őâĹđ#Ť*™lѧź–ÖTV2¶ËgÎŚś8±ßС€RóůçyŹéµÚ+‰‰c§NíN8ÚŮ-ýë_s˛ł5őőÎĹ'&ϞݽŔĹŃqůßţ–yű¶ÉhL:qbÚüůÝúô!\ťť—Ż\™žšjhjb2~Ž›ątihŹ€‡›ŰŠ•+o^ľLŕřůăÇç®XŃ©[7ŔĂĂcĹĘ•×.^´ÍLĆďüŃŁ ˙ô§ĐP €·ŹĎŠ•+Ż$&Ň4}áرş~Ô©“ŔÇĎoůĘĹY#ż IDAT•—Nź¦ ŰĹăÇ—}ń…HŔ/(hŮ_\8~’NśXţ·żůYBBb>˙üü±cL͢¨+gÎ|đĺ—Ţ~~€ŕÎť}úéą#GhšN>{öŻľňňń±„„†.řä“sGŽ` [,©II~ő•‡‡Đ©[·9Ë—ź;z”$[ÉÉ~ő•››ÚŁÇŚĄKĎ9Âd´ CúŤ|ůĄ‹“Đ­Oź©óć]8~Üd4fĄĄ­XąŇŮŃ‘čŢż˙¤YłÎ?ÎeĐŃŞŐŹłł—ń…ŁťĐ;<|Ě”)—OźnÔéň=Zö׿:(•@żˇCGLtę“a«©Ş*),\ňŮg*™ Ť1hÄ«çĎ«kk+KK˙ůĎJ©ÂGŤę7tčŐsç [ůóç őő >ůD.ˇ‘QQ]űôą•ś\YVÖ¨ÓÍűč#™PŚ8±SXŘÍ+Wt žź0fÚ4żŕŕŚ[·žçç#2#&FĚăń$*:ÚÓ×7ýĆ &ă—›ť-–Jß[°@Ŕáđ1lâěŮöNN9™™O>TÚŮMť7ŹŹagňÜąrĄňá˝{¦·3iinžžfĚࡨˍ^´Ëă<~|?=ÝŰĎo|t4AÄ<Ţô%KA $ kŘÚ´-.7==ť­;–˙qżÖI‘ÖAř|žX,–HÄAĂĐ’’’;vÚŰŰ:tp×®555‡ŞŻŻCQ¤ý>eq±ĘÁÁŢŃŃÚ)÷ 1›ÍŤ:]EI‰˝““ĘÁÁčĐÁŘܬÓh†gsiaˇł»»\ĄâĐÁť;ëuşfˇ´¨ČŐÓS¦PXă!]şč Pśźďéë+–Jy4@‡®]Őµµfłůy~ľ·żżH,ćP»u««®6ŤLÇS”—ç,ř@ç°°ęŠ Ç óň:tŕ | ´{÷Ş˛2 óČXÁÓ§Áť;s¸\«N—ž=Ë‹‹)Š*|ň$¸KŚĂ±ętéŮłěůs¦=̀§O;víŠbŕeů’‚ é‚'O:u놠¨5ţNĎžĹůůŻI*S—×9, ĐĄgĎçĎžý+Ţ˝ű˙Ź÷čQ”—Ç8q–¦‹ž={UAĐîÝ‹ňň 8??´{w@€bX簰§O™tH’,),´–ç`N‡®] ź>Ą(ެ¨¨óË8‡ËíĐĄKQ^ŢkFę*KK;‡…Q|>źÔ©SŃłgAT•—węÖÍŞĂ:v|ΠŚĆšŞŞ]»R<‘XěTśźo1›ëjjBŢyÇKĄŢ%LF´ą©IŁV‡†Ň\™\îáí]VTÔl0č4š Îť­q…RéęéÉôĐiµ†ĆF˙kŰV988ş¸T–”4ét¦ćfżŕ`kÜÎŃŃŢÉ©˘¤ch„ őőAřXË;ą¸ČUŞZµš˘(/k1'77©\ţ˘˘‚I§®şĂ0póňDuŐŐő55\.×ÍËË÷đöćóůµ/^  :ŐB±ŘĹĂĂZŔËĎEцúúšĘJ‰LćäćfŤ{Đ4­fNga [›kAĽ˝˝Ůşcaaaaů_çĺ”HŠÇăi4 {.\8sćě]»v×××óůüŚŚ{‚ ŮŁG÷>}ú Y^^QPP€˘h[`ťE& –tá“§O’ ,fsŁ^/‹ĺ(zţěŮgůůŽB!ăL#H€^«•HĄ2=}ňdqI‰ŁHd1™×kµ™L†˘'Ź/-/w‹Í&“ABtŤ\ˇ čŃC‡ŞŞ«ť¤Rcs3IzŤF®TJPôđ5uuN2™±©‰ Fť†…ťťE$$4hµNJeSc#EQş†ĄťťAöíŮŁŐëťTŞ&˝žb6ZZµZĺŕŔG„]»šš›ťu: imCťŁ#Aâwěh6™śśśô “ŃB4jµŐłŕ¸“««Nَ´ öNN(Ŕ®¸8ś$]]u ŻI¬§U«śť€]۶Ń4íčâ˘U«@×ĐŕčěL[ăŻâí·"ťFăčěL䮸8ŔÁŮYŁVMë4G A쎋Ă^Ĺ™[Ł^«uptl6›÷ěŘÁC''­ZMÓtŁNçhoo0ăwîä!˝Łăkt(’lŇë•J]căľ={(jçŕ U«iŠ246:* Zíţ„ŠŞěíµ L’ fÁQ*­­«;ĽżE•*•¶ˇ$IŁÁŕ(‘T×Ô9xP‚˘rĄň5:¸Ĺb6E˘˛ŠŠÇŽI1L*—ëµZë%ŕ –”–ž:qB†aR™LĎđ°^A~AÁůÄD†‰%’FťÎb±áŔç?ÍË»xţĽĂDbqŁN‡0QŠ˘ěyĽGŹ%_ą˘äpˇ±Ńl2MŰsą÷ďßżš’bÇáđůü&†y€Ń`@QÔŽĂIOOżuó¦‡Ăĺpš cs3†avNZZZZZš—‹q8Í oUPCS—ËUaXjjjff¦=ʇ Éh445ńx<†]»zőţýű<››Ůű6kŘXXXXXXţX†ÍşPM­V'%]JK»ÓÔd0›333KJJ9îăÇO\]]ĂÂÂPĺp8C† !Ięĺ¬H#€ükä®Ý8üĘ-Ú±…LúżR~ŤÍĽ «|żjł˛ví.üš¬ĺ˙އßđgÇóĆőĂt_"“ EŤ7ލ3™8\.ŹĎgęË CS“ž˘ĆOśHÔ67ó—+U(šôz=EM<™¨1řŹÇcrYrĄRŻÓ(jjt4 PŰŘ(‰0G¦Pč5E˝7}:P«× %‡Ă¤ŁP*µ Fšž>{6PŁŐJ¤REĺ*•F­6ŃôŚ9s€š†‰L†bŁŽJŐP_oöőť=>PSW'•ËA*UC]ť‹‡Çś p€šš™BÁÔéĄvvőµµ*‡y‹Y^TUÉU*@ˇRŐ×ÔČ•Ęy‹[*+*¬q&ä*U]MŤ§Żďü%K̵/^(ěě¬ńúšw/ŻVq¦.»\©¬Ż®vvs›żx±  ®şZigbŤ;ą¸ĚłĆkj”ŻŃA™BQWWgďŕ0gáB#M××Ô(ěě‘Ęĺujµ˝ťÝě Ś4]_[űšăA1L"“ŐiµJ…bćÜąFŠR××+T*EĹRiťN§R(¦ĎžÝLQ őő •ŠÉ p8‘X\×ÔäčŕđŢôéŠŇ64(T* Ă„bqťÁŕâä45:ş‰˘tŤ\©dÔáńřBaťŃčéááăáŃHQŤ:ťLˇ°^u&“Ź··ź··ž$őz Ŕăóą<^ťŮ %ICS“D.çňx.·Ţb î¬%ÉfA*—3é„BEëqĽKh(Ş!“É$–Jů‚ őѵkW  ,fłD*eŇŠDE© ˘gŻ^€š ‚‰Ĺ\>ź$I5IöéŰPă8I"‰„IG,‘ŕ8®!ÉAÓő8NÓ´@(I$¸Ĺ˘!É!C‡Ňő Ů,HŘ6–?˛aŁ)Šćp8wîÜő÷÷›2e—ËĄizҤ‰={ö°XĚ‹ĂP‰D|ţüĹĚĚ,‰DBÓ4ŽăEµ}íM¸{{7Ô׫kk­“‹ňňřT.w÷ňŞŻ©ŃÔ×[ăOžD"¦>.ŕéë[]QˇÓhŕYn®L.‰ĹžľľÖ ˙ŠçäČU*¦ľ ŕPVTdhj˛ O<°stäóů>%……Íx|˙ľłł@(d:ß  ˘Ľ<“Ńh-ꛕĺěîÎár}‚ ž<±Lf '+ËŐÓ“É@R~!!y99Ž›P€śĚLEý‚ź>zD„UçQf¦§źĆlüüźÜżO‘¤ x‘áíďâü8;›¦(küQF†O`ŕkF;ü‚sł˛ŔşgףĚLß  đ ĘÉĚl÷ ¦™ť–O`ŕŁĚLŔ@ÓtNV–uI•w@Ŕ«8EQąŮŮ~!!L:†yúů=ĘĚDĚ$A|hŤK }IfC˘T©žĺä 8€^«­(-őôóŠDrĄňYn.@č4šĺĺž~~$ó[ ‘Xl]Hhęëë^Ľp÷ň’ĘdˇĐşhP×ÖŞkkÝ˝˝I†F¨´·çp8ĹÖňµŐŐzŤĆĹÝÝęiK ­ĹŞ«Şőz&{gg’$ËKJh  Ş¬Ěh4:8;Ű;:âKĺËxEi©Ĺbqtv¦.Rg77ŁÁđ˘˘ÂZ ¬¨¦iĄ˝˝“›[“^_SUeŤ—"˘rp Ř7kŘXXXXXXţ /§D@}}ťX,¶···:1 á(ŠĂá$ŮŘŘ8xđŔŽ;466Ň4 (ÚnâA ßС9YYI§NQŤ&ÓžŘX«[ë;dHöÝ»—ĎśˇôFă® TL}S @ř¨Q·SR®_ĽZaű?¸yy989…Ź™š”tăŇ%Đ46nűţ{og7·vűp8@äřńI§NĄ]»†¨uş-˙řGph¨LˇuîčŃô7P€zŤfówßuęÖMigG3茜4éxBBöť;@M}ýĆoľéŢŻź@(9qâ‘]»î§§sŞkk7~óMŻĹ ’3yňľ-[r˛łą•/^ü´ző€ČH—;zĘ”=±±Ź<ŕTVVţ´jŐŕ#F I€ŃS¦l˙ç?órsyeĄĄ±«W‹ŠBdô”)ŰÖ­Ëň„PZ\»zőđńăŰÝÎęFMš´ů»ďŠž=ălZłfÔ¤I0râÄŤkÖ±wo}MMçîÝCŢyGŰĐp,>ŢLQfŠ:¶gʶˇˇKĎžĂĹÖ·oUyů©,F‚8¸}»Ĺb ěر[ďŢĄĎźź9thĆńý۶@Hh(ńf÷·ŻżţÚÓÓóâĹ‹­â_|ń…§§grrr«ř§ź~ęĺ啚šÚ*ţŃGyyyÝľ}»U|ůňĺŢŢŢ÷îÝk_Ľx±ŹŹĎýű÷[ĹçÍ›çë뛓“Ó*>kÖ,??żĽĽĽVń÷ßßßßż°°°U|Ę”)%%%­â&L ¬¨¨h7n\pppuuu«řčŃŁCBBęëë[ŇޱcG­VŰ*Ń©S§ĆĆĆVńđđđĐĐĐćóÚBvJ$ Ë«eŁ0 #I’$ kĂP’¤H’P(FcłV«uuu€ęę(ŠĹbŠ"ŰŽ°á]zöě=xđÍË—Ţ»G‘¤F­ž2w®ť““D.ď5hĐő ˛ŇŇ(’ÔŞŐď-\čäęJ2ôáş÷ďß˝˙K§NÝNI! Âh0 ť;W¦T†őë×˝_ż ÇŹ§^şdMg2těX¦—î8@źÁď\˝zz˙ţ˧O“ăĆ ĹâŢáá·’“Ź'$\8q‚Äq ÆŤÇ4‹Ś0lXÚŐ«·o?}ŕn±E˘qăx|ţ€aĂn''ďßşőÄŢ˝¸Ĺ"‘J‡EE D"&Ł5xäČ´«W÷üôÓˇíŰq‹Eeg7lÜ8 ĂÂGŽLKIŮůăŹű…BÜl¶wrĹe©:fĚť«W·­]ËpłŮĹÍ-běX«AşsíÚćożĺ łŮÍË+bÜ8„ٰ 7îîő뱫Vńř|‹Ůěĺç7těX•žšşáëŻy|ľĹdň :f ÓČ‚ â˘îݸńĂ_XËű‡„ 3AČńă3oÝúţŻĺńxf“) cÇđŃŁGĆxĽČńăłďŢýÇgźqy<łŃŇĄËŕ#0 ‹ŚŠzžţíź˙ĚĺńLÍÍŢygĐđáL†M EFEĺfe­ţřc.—k4B»wďÁĺń"Ł˘ßżżęŁŹ¬ń.={öŹ`Ň‘Čĺâ˘ň?ţzĹ ŚĂ1 Ýz÷î5x°H,6nÜÖµkżZ¶ĚšN#¬oßŢ16•˝}Äر»6lř[L †a†ĆĆžtëŰW FŚżqăK–`Ö¤×÷80¬o_&Łĺäę:tĚŰ·˙uŃ"Ăuş>w ăńxCFŹ>˛k×ç ˘ҨÓő2$´{w&Łĺáí>jÔé>›?A˝VŰ?""¨S'k;<{äȧóć!˘×h Ćdß  Ă‡_9sćÓąs@§Ń >Ü' €yíÂ…?Ďť 4­Őh†Śí¤Ú?""íęŐ?ÍžMÓ´¶ˇaÔĉn^^Înný†Mżqăk\­;mš‡Żď¶ŚŚŚňňňŇŇŇVńôôôňňňňňňVń;w•UVV¶Šßľ}»¬¬¬­áąqăFiiimmm«xjjjIII]]]«řµk׊‹‹ZĹSRR*++5M«řĺË—ëëëu:]«řĄK—ôz}[ă”””d4­SŮ[ráÂ’$ŰŞ .€Édjűą`ÝołŐq@Ű Oׯ_¦ŚMżě ËÚ®Ń4M¸··WmmíŁG94‚@qqqmm EQţ55µąąą8n±XĚiiwPuqq&˘m˘ @)M1Ă?8¸¤°°ş˛rčر##y(މ&ÎśéhŤGFEőŹp8LSí%’)sçş{{—ÔUWŹš4©÷ A±—H¦Î›çâî^\PPWS3fęÔžđ0ŚIÇQ.Ź^¸ĐŢÉ©8?_][;ţý÷»őé!“\ţţ˘E*{űâgĎęę&ĚśůNŻ^f•jĆ’%2ąĽčŮ3mCĂÔyó:‡…!®vv3bbÄRiQ^žNŁ™6~Ç®]1D¸9:Î\ş”Ďçĺĺ5ętŃ‹w;9ÍZ¶ŚËĺĺĺ556N_Ľ8¨C”y ›§«ë¬ĺË)ĘËknnžąl™` xąąÍ^¶ hÚ:sÖ˛e~~~Ż™éăĺ5{Ů2Ç‹ňňp‹eöňĺ>^^ŕëí=kŮ2Üb)ĘË#bΊŢžžŔlŘüýýg.]j6‹ňňhšžłb…§«+Ή1 Eyy‚ĚY±ÂĂĹ…Éřˇܱăű‹‹ňň8\îśĺËÝ€ĐĐč… ›ôzë$ŰŮË—»:80N­DŃNÝşMť;WŻŃĺ剥ҙ˖9«T(‚tîŢ}Ęś9ş††˘Ľ<©\>3&ĆI©dšÉŰ®˝{O1َľľ8?_eo?}É™ Cn}űŽŹŽV×ŐççŰ;9˝żx±˝LƤĂăpz8fĘ”úęęâü|Źióç«Äb.ŠöŁ&Oqąb.wÄ„ a}űVW””ôč×oä„ ŹIG&Ś™2%´{÷ňçĎ«JKű†‡GŚ'Ŕ0)ź?vÚ´N]»–=^UVÖذ!ŁG‹¸Ü7Ě@޵k×€€€VńˇC‡víÚŐĎĎŻU<22˛[·nmóŔŹ1˘[·nžmÚ˙čŃŁĂÂÂÜÜÜZĹÇŽŰ˝{w—Vń¨¨¨=z8::¶Šżűî»={ötpphź4iRŻ^˝T*U«řÔ©S{÷î­P(ZŧM›Ö§O™LÖ*Ý·o_‰DŇ6ŢŻ_ż¶;KOť:uŔ€ íń 8Ďç·=ţÁsąÜëŁ ązá‚ő·ú&őäÉÓŹŰß©S—ÎěSśĺżŤĚĚ»Ź?4h««[SSăŰe`úE”Jĺ°a‘ÉÉ)püř±QŁF¶}űÂÂ(ŠVVVvěŘÜÜÜJKźżJDÁň‚ †&^ŻCPĂ0 ă`ĂP Ă8ë/ÖĆĺrµÍóüüF­NĘçnĎ®<ô¸›Č_=LĺäŢĐPĎçósrr·lŮęáá1uęd ĂÎť»Đ©SÇČČaĎžĺ˙ý:ggç÷ßĎb±lŘëîîľxńBÁP]]±da̤Ą+/^lhń*”űň…(đĘŘ1Ĺ@ 0´˙YË—Ož:ŐdŽ GÇŽŹŤ<’$I'''ÇQíÔ©cLĚâššZEÝÝÝ<==)ŞÝ$‘żl~~ínJ¬ÎP‡­VçQ‡ĺwÉ˙¤ałX,—/_ÎĎωD yő_őőő—.]ŞŞŞ˛łł‹ŚŚtwwgĎ1 Kű @Ó@QŠ˘8ŽóxĽÎť;wíÚAÇ łŮL’$I’"‘(,,ŚĂáXW»™Í‚ ^·q6 Ëٰ‘$™••µsçÎ/^D"ŤFăëëk]¨×ëOž<ůâĹ .—;cĆ öł°°°°0AÓ4MS4ŤXź/í¦f&˘m0š¦Ůwß,,,,,˙ żčŽZ˝A´>´‚ (Ęú kµM»qš¦I’$˘­ŕŻĄ±±qëÖ­ţţţ×®]۱cGAAARRŇ+#·qăĆO>ůäöíŰß˙ýŘĚÂÂÂÂňË–Ť¦~íëÖXXXXXţ󆍢¨™3gŢşuëU¤®®.""BŻ×÷čŃăŕÁ}úôéׯßĆŤ[Ľµk×öíŰ7<<<..î•NFFƸqăBCCGŤeÝÇŕͤ­"FŁ177÷ăŹ?‰DŢŢŢsćĚ9{ö,Ľ^[ştixx¸@  ýüóĎŮĚÂÂÂÂÂřDP„¦)ú×ó ‹ŘXXXXXX~#~aJdPPĐîÝ» `ýç©S§\]]ą\îÇ/]ş4kÖ,‹ĹríÚµĐĐĐđđp’$Ďž={÷îÝ™3gâ8~éŇĄŕŕŕđđpłŮĽaÆ^˝z˝űî»áęŐ«-?Ą±±qÖ¬Y­v< (J©TnÝşµ­Ť4 Ö L9Ž»»ű“'O¬F.=== `éŇĄ† >|ôčŃě faaaaihŤFMsxÖelouf^ß IDATă÷P€&IJ$–(lŮ…GŔárʼnŔhŽĹ0±L¦0ۨ Rą\ńótöoń˝Ad …âWf€l…D®P(lŮ´vzmsl˙JHDi[ĺ \ŽŘxŇQ€F…Âz<Ű*G*—Ł(Şh7ůéĂČd†Ém«d!€X"ápą2ŰNş@(qą\ŹG  y|ľŤő#ŕ ˇPů2_˙[ŠĽÜŚÇ°ż<Ëۡ(:mÚ´I“&ŐÔÔ899 †“'Oţĺ/árąR©4 `ٲe‹Ą®®îČ‘#VĂvüřń=z,[¶Ěh4VUUYăA¤¤¤,\¸pđŕÁEm¶áXţM (jË-âM úúú&&&.X° ''G­V<Řb±`¶dÉë=tţüůQQQ@’dvvö† @(Îź?ňäÉÖĂ |üř±T*uwwź>}z«O‘JĄ‰‰‰íßۤě …}úôŮąs§X,V«ŐgÎśÁ0ĚZŇh4:99}˙ý÷ŐŐŐ+W®Ü˝{·ő`XXXlĂ0[:m,,˙mPéŕŕ””ˇč[öÝI’ěÖ-ĚŮŮĺřŃŁ·““ÁC‚ HŁ^źxčĐĹ'lů^‚čuşĂ;wr¸\ušôú=±±mĆA‹ŮĽmíZEmüđC¶­°°üVo‰XĂĆň;{’RmmŰ6x š¦A«iřrĂO‹>Xa°aDÁăŤě×oFLĚÄ÷ß7Ú¦Ó·C‡•ë×>ÜbŽśÇ usŰqút§°0[Fę¤<^€\~63ÓÝŰŰ–Ž‹Çóĺń®={&S(lšÉářq8w+*l4´$A„ĹŮuu¶Ü€Fť®§›[nC-'EŃŞŇŇ‘]»>Q«›lĐáp8Źďßź7vlNU•ÎŹwóƕݖ/ż›—§µAGŔăť>thOlěĄ;wlŃóxŰcco^ľ|řÜ9[t¤<Ţ·+WV•—o‰Ź·Ą~d<ŢÇ‹Id˛żŻ[×ř¶: oĹ‚‡wî€ČČČ… ˛Ďč˙B0 [µjŐ˙…aCdđŕÁ_}őUBBBFFĆ·ß~űężôz˝R©´ţ"“ɬA‰D˘×ëĺrą5.•J­·’ţýű;;;«Őę»wď~óÍ7­ĆÓt:]ďŢ˝E"Q«×E—/_n{Hţţţk×®Őét(ŠŢľ};00ĐzŁńđđ°.„CD*•Ú21€……ĺ|>?<|ČÉ“'Äb1›eĺwňC_Ľ¨°ëŇą;AĽMGĂĐşşµş¶ˇˇA ŠV’HP ă bĚ Š˘BˇP`±MAˇX,AQÂ1‚ "±XÂáŘňžY"’HĶ-×±JÄb×°YëD‚a¤m#¤Db­%[N: ”H‘€ :€P$˛ę6čđB!Š˘’—ő–† €/`&µMGŔçó1ÇĆăpy<.—kcýH¬:<ž€~[ ÷ĺKë0¸Ťá,˙ĺüň-K©T><..®WŻ^ööö˙şĹäľ}űV¬XAġC‡zôča5fť;wŢ»wďňĺËÍfó¬qÇOź>=yňd˝^˙Ă?´}3iҤV‹&iš–H$mʧąąůňĺËăÇŹ€śśś›7oÎś9„Ba§NťÎś9ŐÜÜ|ńâĹ   öł°Ľš¦ …őÝ Š˘:ťÎšţNˇ#j}™BQ”H$ąw/C,+ ­VËz6–ß‚ŤF>ź/“)ŢZÇńšš*·$‰Xl8 MQAXlסiÇÜb±Ř–WšĆqÜb[ŇëĘÜbÁm[ĂfíôX‚˛-íIÖZ˛eP°.]łńdˇ„Ĺ4mŁ€ŔqÚfřŤtĐ—›HŮţ˝H’´]·ę¤íI’¤m:ňĺőo5éŽĺ۰Ń4ľ}űöü±eđîÝ»...‹ĺöíŰÖ©’'**ęرc...&“)==}áÂ…Vw—śśŚă¸T*}öěY˙ţý[}„P(\˝z5Ó§·ši6›/^ĽhÝí-77W XsNJ$’đđpëŘťZ­ÎČČx÷ÝwŮĚÂňşëźĂILL6lŘéÓ§ †ćńăŁ(Š‹Ĺ'NśÂq IRQQă0 ;}ú†a'NśäóůÇGÚś_Ť…ĺżáu (jMńvS1 ĂqAô·X ĹÂÂÂÂÂňö† ôzý;ďĽÓ»wď˙˙ÚEüĺ—_"=nÜ8ëÓkňäÉOź>ýňË/ů|ţ{ď˝gŤs8śČČȵk×ÖÔÔtíÚµĺĽĘ_¤í6ˇPö—żü…˘¨áÇŻ]»ÖšŘ”Çă :4==ýŁŹ>’JĄŃŃŃÓ¦McO0 Ëk …ďľ;177géŇĺ555÷ďgy{{kµÚ­VGÄÇćĎ_@’ä’%18Ž———rą\vŤĺwĺÝhę-RPĐ4ýšdăČĎĽá/Ç˙ă:oxI3•guţ€:˙µŤů®Ăň5l‚$%%µL7b5lóćÍ›4i´Ü?M |ńĹúÓźZĆ9Î1c† BQ‡Ăiw˘ă›ĂçógÎś9iŇ$š¦ů|~Ë•oBˇđóĎ?˙裏iµ« K»=NĄRŮ©Sç{÷Ň]]]ÂÂzź˘¨VűÍ´z82] (÷ĺr)ŮÍbŠ3p0€lQŕ 4@ĽN»ĺ˙M:ř/U;Syç×č´,Ź·şÉŕ mâŻŃi·üo®C˝¬·×ĂŕĽ,Ź·uÉ˙·ę /ëąUy¦ř[čX/ € Ţ@‡ű˛ój˝(¨×Ć˙Ý:čËďŐŞ|Ë‹ý uZŢötŢä¦ÁňÇ5l©©©Oź>m9ň_7\ {•(˛%b±X,·}ň˝ÚŕĎÖç+‚‚vý‚ í~: 8Ž˙óź?ĘdŠššš¦«ŞŞ\\\ěěěř|amm-IRžž^ŕćć&—ËŮť^X~PŐf˙ŃŹ?ţčîî6yňd¦üUEĐmwĐ•–ŮąóŢ­[<oäĉ㢣ĺ  °¤äđŽ™ii<>ôäÉc§M“‰ĹLÝwŔłÂÂC;vÜOO …cß{oĚ”)"€ đ´ ŕP\ÜĂĚLˇH=zňd!źĎÔÍä<}z0..÷ţ}‰TúîŚ#'Lŕqą|€GŹ‹{ňđˇT&›0sćwßĺ2§ÜôčŔ¶mĎ?–)“çĚ6n†˘|€ělŰVđä‰\Ąš2wnÄر(‚ĐĚß+#+ëŔÖ­Eůů*{űióç5 ř÷22öoŰV\P`çŕđŢ‚á#FĽf“p÷Îťý۶•;89E/Z4("‚थĄض­Ľ¤ÄŃĹĺýE‹ňŹÄ¸uăƸ¸Şňr7·÷—,é?p Ŕ¸yýúÁ¸¸••®îîÓcbúőďoymw*5%ĺĐöí5/^¸{y͉éÓ§Ź€píĘ•Ă;vÔVW{úř̉éŐ«—™ŮE W.^<Ľs§ş®ÎÇßĆŇĄ=¬ĺ/ť?d×®†úzßŔŔ11Ý»u31ëĐ4}ţĚ™ăńńÚ††€¦ÇÄt 5Puöôé :­6°cÇ11]:u21»ś Îťş{÷í”E#ĆŚ™0s¦˝R‰”UUÝ˝;íęU ÆEE˝;}şťBłwí?čëźak֬پ}{DDDKoFÓtcc#[w,,żĂ6cĆt0›ŤÖ·*|>ßd2ŤF“©™Ëĺ"Í&0™LÍÍÍR©aWě°üŽ išjÜ»wďéÓ<A­vŽĎç …"ˇPdÍŹEQEµ3.‡hš›Oíß˙ôŃ#g77…ťÝ•3gn]ąbˇ(­ŃxbďŢüÇŹťÝÜ*UŇÉ“iWŻš ax6745Ýł§8?ßĹÝ]¦Pś;r$=5• éáČ®]ĄĎ껏»ËäňÄC‡2nݲ$“N­^hÇŽŞňr7OO±TzjßľűwďR4]«×Řľ˝¦˛ŇÍÓS$‘śHHxpďÁ¬S­ŃěŰşU]Wçćé) ŹîÚő8;›¨nhŘ·e‹F­vóň‡wěxňŕɨޫKŘ´©QŻw÷ňâńx¶m{–›KTÖÖĆoÚdhlt÷ňârąű·nÍú”iŻm üĹ‹řŤÍ&“»—Šaű6o.*,€˛ŞŞřŤ-fł»—°iÓóçĎ_3/ ¤Ľ<~ăFŠ$Ý˝Ľ(ŠJظ±¤¬ ŠKK6m˘iÚÝË‹$ÉřŘŘŇňň×4Ł˘˘˘„M›q÷ňÂ-–řŤË_Ľ€‚‚‚˝›7Ł(ęîĺe6™âcc+Ş«™îˇM?{ňd˙Ö­\.×ÝËËĐÔżqcU] —›{`Ű6ŹçîĺŐ¤×'lÚô˘ľžI‡¤¨Üű÷ďÜÉ ÝĽĽ4jőľÍ›k4 '+ëčîÝB‘ČÍÓłˇ¶vß–-µZ-ĘPÉI>¸wďxB‚X"qóô¬©¬<°m[˝^OŇtöť;'÷ď—HĄ®žžUĺĺ‡ââę™t,$yďćÍÄC‡¤ …‹»{iQŃ‘]»4AÓwoÜ8ô¨Lˇpqw/ÎĎ?ş{wÁŔ¤c"Ű))—NžTŞTÎnnůŹźHHĐ™LŠşyĺĘ•ÄDĄťťł›[ŢŁG§öíÓŤL:Í8~íâĹk.¨ś\\r˛˛j˛XL$yőüů—.Ů9::ş¸ĎşĽÍ`0<}úôöíŰiiiEEEÖ jiş7Áx”™y+%ĄDÄOű÷ŻÝąSioźrö¬ş¶6'+ëvJĘŔ#~Úż˙;vČŠäÄÄšŞŞvSqs2ÓŇî^ż>lüřŘýűżŤ‹ă ɉ‰z­6+--=ő˙±÷ŢqQ\ű˙˙{f¶÷]z—&X@‰ Jě[4ö‚%jĘ'¦“vorcK˘ĆŠbŤ ‚˘ b*˝KŻ»lďSľ¬x :ĆČÍďwo2χŹGÖwŽŻ=sćĚěű5§ĚĄQS¦lÚż˙‹źf±XéIIjĄĄŃą‘™yëęŐ‰Ż˝¶)!áó-[OON6™LŮ™™w®]›ř 87÷Bj*EQéII 55ď~őŐć„„řµk ďßżxú4]îe·ŮÎ%%µ45}đÍ7›˝őVţť;—ŇŇ‚8wň¤ŞµőĂożÝś0ŐŞÜ[·.ť=ˢ36&Óą¤$ťVűńĆŤ›fÇÇßÍÎľ–‘ałZĎ%%őúő?ü°)!aĆâĹ9ׯ_;žNGŻÓť;yŇnł}¶y󦄄ÉsçŢşzőĆĺËfŁń\RI’¶lŮ”0ńµ×n^ľ|ăŇ%6ÝÓĄ2=9™Ĺá|ńÓO›öď5eJöĹ‹9ŮŮZµ:=9™ËçµmŰŹű÷Ź8ńú… 9YYOŐÁZ2Nť’Čĺ_ďŘńĂţýGŽĽzţ|ţť;Ęććó)) gçüňËű÷GÇÄ\IOĎ»}›MÓ ëŞŞÎ§¤xřř|łsç÷ű÷÷ŤŽľ|ölI~~cmí…ÔTo˙owďţ>!ˇOż~—ŇŇŠrsY4:•%%OźěÖí_{ölÜ·Ż{Ż^™gÎT••UUT\]Q\L§S’źéěŮ𨨍 ßîŮăx!5µˇ¦¦¬ ŕňŮł} ŘđÍîÝ^~~RSk<`6ţb ŰoŻ ËĎĎ?~ü¸——×o~ŘěĚĚL¦íţ’É+źĎłX¬ŽA6ʇ Ĺăq­V I#GŽ6›ÍĚ Ă_ć‘…c„Ť˘~ó(ꡗCQ4?żŕÓO?‹‹‹›>}úĆŤß×ÖÖ"Ň>%˛ŁAş–‘9*. óWŻÖiµuUU×/\0ŕŐ‰Q™P¸đÍ7ŰZ[«+*č [ćéÓŃÇ3PH$K˙ď˙ꪫ[›š2Ďś2jÔQŁŔI*Ť_»¶ŞĽĽ©ľžÎ°ťKJ5yrôđá$€‹B±üý÷‹rsujuzRҸéÓ B¸99­řđĂü;wÔ46l€3ÇŽMť7/jĐ ŔÓÍíŤuën_˝j1›ĎüúëĚE‹"Ä<ÝÝßX·îĆĄKFΰĄ=:wĹŠđ¨(ŔÇŰ{őÇ_>w·ŰSŹ]°zuĎČHŔ××wŐÇgž9cłZšÜ=őČ‘ĄďĽÓ­W/;@—€€UëÖĄ'%Q•zô貵kCÂÂlţAAo¬[wöäI’ްť>věŤ? ęŢÝşňĂO;g~ýőŤŹ> µwďľüý÷SŹĄëF$IžKJZýńÇţ6€°°Ąďľ›rř0EQ§N­Yżľ‹żż {Ż^‹ßyçÔáĂMeě6ŰĄ´´5ë×űřřŕ=##ç­ZuęđaÇŻ¦§ŻYżŢŰŰŹŠšłbEĘáĂtFËh4ŢĽ|yÍÇ{ş»ăN_¸0őŘ1‹Ů|çúőŐěîęJD 4eŢĽÔŁGŮ4:•*?'獏>rur" 2vúôł'Nč´Ú⼼•|ŕ˘PP‡uĘ”ł'Nж–††ę˛˛ĺď˝ç$•Ŕŕ‘#Źy!%EŐŇR_Użv­\,F†Ťs>%…ΰŐTV¶µ¶.~űm©PÄNśŃż˙ŐŚŚ†š˝FłđÍ7%0rĘ”°ČČ+éét:e……„Ý>wĺJŹÇBq3f††Ţşzµ˘¤A×—/r8ť0k–o`ŕÍË—éŚ_~NŽP,~mńb>›Í۸yóśÝÜroß.şwOîä4}áB‹Ĺc±¦-X •Ëďݼɢą¸î\żîéë;eΊ 9ś×–.ełŮĄwłł»Mś5‹Ť ".wö˛ePLc ţľ†Ťá/ž«"Ĺbiź,„X­V“É|çÎí#b»v uw÷LK;-‹ÍfËť;·âî~–y}6Ă_čp<¦xčÓX,L ŕ‹Ĺ"@QÄáÖŞ««~ůĺ''ĹűwěŘÖÜÜtđŕAĄR‰˘ČSsÁÚŞ*…łłł««#)îŢÝj±čµÚşŞ*g77'Gň×µGłÉ¤Óhč IUyą‡——Lˇ`Pˇáá:­Öd4V——{ůúJd2GĽ[Ż^Ú¶6Ł^O§SYZę(‹9@ŹUsłŐj}PZÚ%8X 9â=#"Z›š,f3Ý”ČňââŔnÝx|>€ďŰ·±®·Ű+ŠŠ‚{ôŕňx\  Wßľő556ú‘±ňÂÂđp6‡ăĐéUűŕI’eEEÝzőb±Xuúő«©¨ ‚öčÓĂ0Đ»_żee@Qĺ……=##Qu¬tďÝŻß’’gܲʋŠÂúöEĺ{˝ôREq±#Ţ·/đö8B˙¬«˛¸8<*ĘQEŃđľ}Ë‹Š ˛¤$<*ŠrÄ1,,2˛Ľ¨v*#AT•—;ĘsX,VŹ>}*Š‹I’¬®¨ďŰ×gs8Ýz÷./*zĆH]]UUXd¤Ł<—Ë «(.ĆqĽˇ¦¦çŁ8źßµ{÷ŠâbÚ)fssCCŹ>}H€@$  yPZjłZ[›šş÷éCpDb±PĐŇR:Ł^ߦR…†‡Sl©Lćíď_]Qa2µjuhXŘøBáĺçW]^NghµŤŃ`îŢÝá—..®žžuUUz­Öl2uëć;»ą9»ąŐ>x€Ńt¶ÖVÇşvu\#nžžR…˘©®NŁR‘$Ů%8ŘQĚÝŰ[,•6ÔÖŇé´45aćă^~~< µ©©µą™Íf{wéâ{űűsąÜ–ĆFş)‘ŤµµˇĐĂŰ@şˇ(Ú¦T6Ő׋Äbw//Ǧ,ţ]»RĄjiarwư100üŤ°X,[·n‹Ĺ`µZ·nÝ" şvíşfÍę˙űżwÖ®}722EQŠ˘BCCß|ó͵kßŤŠŠBQćľÁđ×j‡ĂáäççŻ_˙ÉěŮsvíÚŮÜÜ‚aróć-ęŐWcűő{):::6vDmmmYY™ăŇx2§4hµ|@†agĎś)*.váń·Y­z­V J1ětJJIY™+źo·Ű­ B“›ę4ˇD"AѤ'TW» 6‹·ŰuZ­H"Łč‰_­©­u ­ ťAB´mm™L„˘Gnhnv‹Í&ăZµZ*— Qôpbbsk«›Tj2č&<;täNN|MLHhÓhÜär^O’¤¦­MîäÄC{÷jt:7''NGŇ-µJĺäâÂE}»vL&7WW˝FĄQ©ś\]9˛wçN“Ĺâîć¦U«)ú5lj•ĘŮÍ Ř˝c‡ ÇÝ<=µj5ŐGvďŘa'7OOM[Ű3ž0iT*wwص};EQnžž• ´mm®îî”#ŕćáˇV©h{€F­vuwÇ b÷öí(€«ŁŠ*\\4*ťÄqÜd4şJ$-JĺáÄD!ŠĘ m[AfŁŃU$jln>zčEĄ …¦­ŤÖ@ÚíVłŮE ¨©«;qěĂ$R©NŁÁív›ŐęÂçWUW'ť8!Ĺ0±DB÷°Y,¸ÍćÂă•–—§¦¤Č0L(éµZ›Í†ă¸3—[\Rrćôi† „B˝VK§c5›I’tćpňňňÎgdČY,ŹgĐé¬ P”3›}ďŢ˝‹/*X,.—k ™'ŚŤFEťŘě›7o^˝zŐ‰ÍfłX&Ál2aćÄbeeeeee9łŮ‹e˘vFŚ›ÍV°X—/_ľ}çŽ3‡ Ĺd2 .Wa™/Ţ˝wĎ…Ă3łő×—ČE IDATßfX•áď‹Ýn_¶,^ŁŃPőčłZ­^˝z‚ Fó0aŇh4kÖ¬FôQ„á/cŘŻśillG}:śG‡ ü^+=üŢ'ë˙¨žíź·>E=©ăĆqi˙ü<ý› ×ç>_EíäPżWϧVăßĺŰ7¶ˇžĐtIţ~}H’xZ˙!I’¤Ů8§ăÉm/˙ř(.Ő^ĎçÔůÍ÷v¸¨y¸—,;¶!y˛ä“A†ż„aŠ"Y,VVVÖýű÷gĎž5zôȧ¦¦: ¨T*//o‰DÜÚŞd±0WWWŠ"u:ýc©řoA±Db1›5$9zěX  ĹjĹX,—+’HĚFن$ÇN@´Z,,6›ĂĺR4 ĄX*5 :’śG´šÍ.—Ĺf‹e2N§'É)Ó¦‘-&—Çcs8t‰©D.×k4’ś>kĐb0đŚĹ’Čd:ŤĆH’3_ťhŃëůB!‹Ĺ˘Ó‘ÉĺµÚLQłçĎ'Z4ˇXŚ˘¨T.W«TfŠš»pˇ E­I$(†Ńę(mJĄ5 `Á’%v€ĄR"•‚8â>> —.µ4·´Hd2şĺ˛UK‹ÂĹeѲe6€Ć†©B´ÇĄrůâĺËmőuuŽ8R…BŮŇâăďżdůr+@KS“Lˇ™\®lnööó[˛b… Ą±QćäôŚ”]*—·67»{z.^ľÜĐęĐA‰L¦lnvsw_´l™…˘Z›šäĎĐA‰LÖŞT:;;/\şÔLQĘ–™“‚ "©´UĄrrrZ°d‰™˘”­­Ď¨Ša"±¸UŁ‘Ëds.4“d›R)S(ŠD­:ť\&›ł`‰$ŐJĄTˇ sH,K ¶ n..3çĚ1¤¦­M¦P`Ć [ŤFw÷łgHŇ1`K«Ăápů|ĄŮěçăă?}şŽ$ő:ťT&s\­‹—.]şčBŻÓŃéP.—Ĺá(m¶®]»†víŞ!“Á –JŮ‹ÍVÚlÝşuëŃ­›š ĚFŁX*ĄÓáńů(Š*íö^˝z!˝z© Âj±Ĺb.źŹ Ç#""€6·Y­"±N‡/$©"~ýű#*Çq\ ˛9‚ T10:T8Nŕ¸@(¤ÓŠĹ8Ž« bČС€Ňn§(ŠÇç D"»Í¦&ÉáĂ)ĄÍüÇŢ?Ěđ÷™ÚÄŔŔŔŔđw6lIR†ĺĺĺ ĐßfłÇĆŽčăŘ Ňjµb*‰RSOßľ}G$9F¤űúwP#ĽüüÚZ[ŰZ[Ďí+‹‹ą<žH"ńňóS67«•J(/*™ě©9 ŕŘTW§U«q $?_"“ „B߀€†šťVëçĺÉärˇHôTŔ?8¸¦˛Ňh0ŘP€˘{÷ś\]ą\n—ŕŕę˛2“ÉäŢ˝ëâîÎĺóéęăRQ\l5›ĺósr<ĽĽX,V@HHyQ‘Íjµ`ywîxúř°ŮOݦH€ŔĐĐ’ü|Ün· y·o{űűŁ(R|˙>ăŹâľ˝ń -¸wŹ$IGůÜŰ·ý‚‚ACCósr(О ą·oű?cź¤ŔĽ;wGůĽ[·BB $$ďÎxż}; $„˘wZţÁÁy·oŁŠ˘ňsrCCŔG¬$EÜ˝J§ao@€CÇ @DŃ˝{ˇˇ(ŠúřűçÝąăăv{qnn`h(Ý ›Íöôó+ČÉq”·ŮlĄ!!,ËĂÇ'?'°X-–ň˘˘€’¦‘ą|ľ‹‡Gá˝{(€Ŕl4>(+ëĚárť]]‹îßwÄMCuE…p0AgHD"™BQśźŹŕz­¶ľşÚ' €/Hd˛Ň‚G\«Ń4ÖÖúĐŐG"“ …BÇ"@@­Rµ45yůů‰%ź_QRâ·µ¶ŞZ[˝üüšN(wrb±XUĺ县¶66jŐjwoo‡§­iŹ774ču:oo’FÇŮÝť şm¬©±ÍÎîîN®®v›­ˇşÚń"ÁúŞ*›ÍćâáAŇ\¤n^^&ˇ©ľŢQ ¦˛’˘(ąłł›§§AŻonhpÄ«+*Q¸¸0cmŚac`````ř»€´O‰ Ôj ‡Ă‘H$8Ž+ ±XâÄb±‚0 żÜ˝{w˝^OQ€˘čSg(٢‡ĎËÉI;q‚0X­»üQ,•zwé2pذ»7n¤''Sz‹eç÷ßË]\üźšSÚ†Ž}íÂ…Ě´4ĐŤŰżýÖË××ŮÍmČČ‘—Ξ˝rî 6¶ýóź~AAî^^OÍáě#&LH;q"+3Piµ[żţ:4,L"“Ť?>ĺčŃ—/cJŤfËW_őŚ;9Q4:٦LůuďŢ;ŮŮ@łJµé‹/"ŁŁyÁČ)SďÜyďĆ @Skë¦Ď?iđ`!Í 0fęÔ„­[ósrŘ MM?lŘđň,6{ĚÔ©»7m*Ľź P×ĐđㆠGŤ˘$ĆL›¶ă_˙*ÉĎgÔÔÔü¸aĂńă=uę¶oľ)+,äTWUmÚ°!vâDş•·Ŕ¨¸¸­_}UQZĘxP^ľůË/GM™#§LŮüĺ—ĘË9•ĄĄ[ľújĚÔ©´ąŠĆNśřăçźWWUqĘ ·}óÍŘiÓ>nÜ6ÔÔÔ°Jóówüë_c§MŁ36lgđ¨Q?nŘPßĐŔ(Ľwo÷¦Mc¦MĂX¬—GŚřqÆú¦&6@~NÎľ-[ĆN›†ÓčD˘~ŻĽňăçź7µ¶˛îݸqxçÎŃqq<>?rŕŔM_|ѬRawł˛ŽíÝ;:.ÎNŁ#S(zFDlůę+ĄFÜĽr%ĺđáŘ ÄRihxř–ŻżViµ@ÖĹ‹iÇŹÇNšd§9Ynžž]‚‚~ţç?ŐpĺÜąĚ3g†ŤíěęęÝĄËöożŐŤŔĄ´´kçĎ3ĆFcl|..żlܨłX(€Śä䜬¬A11žľľb©t÷?č­Vŕ쉹·ożnÜÎďż˙xĺJ‹Ą×jűFGGČbĆŽÝłiÓÇ+V`,–NŁé;hPdt4ťŃr÷ô6fĚÁ;>Z¶ EQťFÓođŕ°ľ}9ΰ1cŽěÚőa|<Š˘Zµş˙!áQQtFËÇßČČ‘I~°t)‚ •jŕ°a!aa(† 92őČ‘÷—,AD­R >Üńę§ę†„Ľ›qęÔÚE‹@­Tľëßµ+Ľi„.\¸PQQŃŇŇŇ!~ţüů¨žŘ,'==˝ľľţŃŤG¤ĄĄ)•Ę'ŤÓ™3gt:ťN§ë?}ú´Ůl6 â§Nť"Âh4v§¤¤€Ĺbyň{Ŕ1âC=ŕÉž.\¸dńí‹Áڰ10000ü­íEQ{x¸·µµŐÖְ٬˛˛˛úúEqÜÔÜÜ’ź_`·Űl6kVV†ˇn8Ž?ąß   'żţşc˘`íĂĆŚüę«• qsçú–ÖUWŹ?ţĺáĂy,Ý’‹X<}áBꞂ‚úššŃqq† a!łX^&——äç·46Nž3§O˙ţl ŁÓńtrz}ůrHT’—§lnž¶`Axßľ€§“ÓśĺËy|~I^žŞµuú˘E=#"0Dx»şÎ]±‚Ĺb•äĺ©UŞYK—v G|ÜÝç˝ń‚ %yyš¶¶ŮË–…öčŇŻaóőňšűĆAçćęµÚą+Vwí ]Ľ˝ç˝ńn·ĺćôúy+W=cJd€źßĽ•+-fsQn®Ůhśżj•—.ŕď?wĺJłÉT”›k±XćŻZĺďë ô†-88xΊF˝ľ(7·Ű¬^íçĺ]CB^_ľÜ Őçć$ą`őjOO:ă‡"H·ž=gĹÇkŰÚJrsťżj•·›Đ˝WŻ™‹«UŞ’Ľ<ŚĹš·j•—‹ íÔJ ‹Śśľ`A[KKI^ŹĎźűĆîNN(‚„GEMť?_ŐÜ\’—'‰ć®Xá®PĐMAdcXÄ€“gĎnih(ÉĎ—ĘĺŻ/[ć"•b9pŕ„×^k®Ż/ÍĎW8;ĎŽŹw‘Jét8,VżÁÇLťÚTWWZPŕćé9sńb…HÄFŃC†Śš2Ąˇ¶¶´ ŔÓÇgƢEN"ťŹÍ4bÄđqăꪪʋŠü§Î›'ăó9öJlě°ŃŁń€®]ăćΕ t:gč1†Ż©¨¨(. ›4k–ËĺłXĂÇŤ8lXuEEEqq÷Ţ˝ÇĎś)áńč¦DЏÜW'MŠŠŽ®*+{PZÚ»_ż1S§ Ůl!›=jĘ”ŞĘĘ”•E0*.NÄĺŇéHůü±Ó§÷ڍ,)©*/0xpě„ <KĚĺN9ł[Ż^ĹĹŐŃ111ăĆ 8śçÜÝgđŕÁáááAAAâC‡ č>|xŻ^˝üüü:Äccc{÷îíăăÓ!>jԨ޽{{zzvŹ;¶Oź>âăĆŤ‹puuíź0aBdd¤łłs‡řäÉ“űöí«P(:Äăâ⢢˘d2Y‡ř´iÓ^zé%‰DŇ!>cĆŚ~ýú‰D˘ńéÓ§0@đÄšŔ¸¸¸ňxĽńI“&EGGsąÜńńăÇżüňËtóŔ˙S Nźv|RTS§Î>ztĎž˝şu c~Ĺţ۸};» ŕţŕÁ#<=˝ ýźôîfą\>bDlFĆy8věččŃŁž|úÂŔ(ŠÖ××÷č^^^ŐŐ•Ź6˘`ř˙AŚŁN§EPĂ0 ca ĂP ĂX,ÇGcłŮµş˛´TŻŃŠąěí9ő Z°i]ą^ˇpónkSňůü«WŻËjµmÜř——g|üRWWŁŃŘÔT·lÉň¸«âă㍏= eµ?%;ş8Čb šűĆS§O·tBGգǧ?ţ8$&ĆöűŃ^D{y €ő´8HB˝˝w§¤„÷îýčąq‡ňż1@©4-/ĎÇ×—ě„Ŕ›ĂąÓŇ"}lŐß č°|P´Ěf{|{•Gĺ©övxT{Zdłk)Šř­8«ÝtĐyjĐiµ}\\ęl6K'tP€úÚÚ=zTét†Nč°ňssçŚYŇĐ }¬’Řcĺíd{ÜŃ>âŔ¸tńâGË—ß)*Ň<¦ó¨< €?Mçń8đ~=ztçĆŤŻ_WwBG°mëÖĚ´´_““;S1Ŕgź|ŇXSłm×®ÇۇÝ~1’öǶ |j$«–/I$_|ýµţE/vŔňřřÄmŰ`űöí‹/~ňQÔSÓ$&ţěřśĎ>űě>xr?§˛’bśÄ±‡°°Žü;ň ˘"ú›fJ$Ăß×÷9¦DZ,–ČȆ†¦ýűüë_‡ âáánµZl6»ŻŻďkŻÍÜ»wßÔ©30 4(zĘ”ÉNNŠö¶§üä;ňłgż§ă?¨c{Zyâ±dôyt:”˙ÝřŐéPOřÇő×!~kŇžç¸˙´őń?U‡˘)OýÖ ?ŹÎSË˙tžz1R˙?]ěŹ?Ňbâ/˙Ż…1l _»D† 8ŔŐŐE«ŐúřxOš4ÉĹĹűŽ<,¬g|üŇććfA|||üü|Iň©›Dţ~^őG_bř·Ňa‡Ńat:ŻĂđ—„1l W ¨‡/·%IŇĹĹŮŰŰE1»ÝŽaÝnłX¬‚‚¨¨ľŽ9-v»Ýjµâ8Ž óyư100000ü‰Pí€Íf{r0Š˘pr0Š˘gß Śac`````řł-ůCe˙sK ĂĆŔŔŔŔŔ𿊠E‘ő‡Ýףq9ư100ü)P%—Ëőz=IRÚWL;3ü7‚”Z­6÷Ń2¶?ě÷P€"HR Ę:ó ‹ÍŠDrs't¤(† %9€µ“:"–JeżÝ˙Ž D"“ÉţŕN’‚He2Yçćˇ:’Ů“{l˙A Dö·|˘"•"ť<é(€^&‘w.«cĄREeOÝüôąá$ äťkd>€P$b±Ů’Îťt!_ `łŮť¬Ź€Ççs¸ÜN¶Ź€ËăńxŤX­/n‘"QS]]Fr˛ZĄ˛Űl/®#Ş•Ę”Ă‡Ë ž\w÷reŔh0Űł'»K‚xqWÂăóí6ŰźV8;ż+~”’’±űÇůBag6Q Ł(jű¶m(†u¦˙$ őÓ®]ť9(AĚ&I’›÷íëĚIGDŁRŮm¶MXĚ/ný0 «Ż®6 ?&&šM¦Ď,Y¬Ň‚µJµéŕA“ŃřâżPNÎőëÍőő›2 /¬Ăĺrݤ§WWTt˛><>˙εkš¶¶N¶_ (¸{—Çăý؉ó% ďßw|.///..6u˘J (ŠvćÁ6Ź·`Á“ǏČĺrOO C â?: FQN®îť{ÉŔđ§@’„‹‹+ đŕA9ö˘ą;Ž‘îîžÇşś–Ö# Ń`8±Ę‘#ťÔ1čt~ţ™ĹfwRGŻÓýňÝw†ućA‚ V‹eóçź#( ťÓ!âŰuë:ątĐńŹżZ»ö?Ň‹6ĽőVço’A|şzu'§×R$iłZ?^ą˛S'€ “ѸnĹŠNvÜn·Í-_ŢI»ÍfłZ?Z¶¬“:6«ÇńÎ×Çj±$YÚéö1›L‚ädgż°ŽCÄńą°°đĚ™3¶Nx~†?ó·†1l ťM(…B1uúkv;~˙îM…BN’˙Ń;>‚0nŤáż„˘( APyA/˘EF­^·ńű%kV›,–®ŤŚÇ5pŕëË—Ož=ŰŇ9ťÝş­űî»Á#GÚ:1â'áńz{ym;q","˘3#u"/D*=uë–w—.ťI\ř<^ ‡s±´T*“u&Wf±XANv]]''EŃ]$şŰÚÚ™áGAtZmoď<µş3'EŃúšš1Ejµˇ:,«ŕŢ˝…ăĆĺ66ę:ˇĂáp®¤§˛zuVq±¦:<ďdbâžM›Ň˛˛:Ł#ŕńvüđĂ•s祦vFGÄă}őŃGŤµµ›÷îíLűHxĽ·–.‰Ĺź~ű­ţEu¤<ޚŋýň ÄĆĆ.]ş´3×)Ăź†a6l` Cç-b·ăđÚěy$IžN9IQÔęĂ-(†64Ô9Gô ‹|±śE±ÖÖć¶¶Vu›Š/J0Ţ‹O–`,ŹĎ—°;©aˇPŚ ¶Îé "‰Ä,Ţ o#včĹb§3·> H,sąť_Ă&‰:»†ÍˇĂfě_şP‰Łµ;sŇQ‘XŚ é„ @(ˇ(* :ˇĂ…(ŠŠNčđx|>†a’Îéx<‹Íîd}Ä.—Íát˛}$‡ĂĺJŕEu$ěöĄkl6Űá·™ű_ćě200Ŕ† Ö­[~´ţëŻ>çóů:ťŽŮŹáŻý¨Âl6są\©TţÂ"8noii°ŮmŰ:3fęTŹÇ(.+;´cÇýŰ·Bář™3GM™ÂçréŇ\>@~qńÁíŰ îÝŠD“fĎ~uŇ$›ÍČ/,LÜľ˝(7W$Ož3'vÂ6‹EŇëÜËËKܶ­¤ @*“ĹÍ›7|Ü8EąwďßOܶ­¬¨H*—Oť??fěXA(úăşť““¸m[ei©ÜÉiú˘ECGŽ.Ŕ­Ű·lŰVU^®pvž±xńŘŘg8i.@vvvâöíµ8»ą˝¶dÉËÆ\€¬¬¬ÄmŰꪫ]ÜÝ_[˛äĺˇCźám8×®\IÜľ˝ˇ®ÎĂÓóµřřč—_¶°®^ştpÇŽĆúzOoďYńńŁŁmĎL§.]¸phÇŽ–¦&o?żYńńýű÷·°RÇĘÁ IDAT.fdţĺ—Öćfź.]f/[öŇK/Yé]‘–vd×.Ukk—  ŮË–EFD8ľ÷ÜéÓGwďnS*ýg/[Ů§Ź…^‡8“ś|lĎŤZܭ۬eËz‡…YHŠJ=yň×}ű´M×=fÇLJ÷ěiˇwvO=qâÄzť®{xř¬řřˇˇ6›Ý~ęřń“‰‰F˝ľGďŢŻ-]Ú=$ÄBoőÍV뉣GO>l2{EEÍ\˛$$0Đ`˛X~=r$ĺČłŮÜűĄ—f.^Ü5 ŔBßČzŁńÔˇCgŽ·Z,‘ÎXĽ8Đ×Đ §L;qÂfłE 4}á ˝•mÓjO8qęn·2dꂾžž$€JŁ9±˙ů”‚ ˘‡ ›:ľ·»»•ľó4«TÇ÷íËLKŁ(ę•ŘŘ)sçz¸¸@SkëŻűö]>{Ź9yÎwgg}g®kj:¶gϵóçQ6vě¤Ůłťĺr ¶ˇáčž=×/^Ä0lř¸qgÍr’ÉěĚ]űďĘ4Ă#(Š9rdllě{ď˝÷öŰo_ąríĘŐk˙úî‡#‹f­Ă_±Ď“ż‚ \.—Ďđů‡ípk$I=ůĐÍ'(ĽwĎŮĹE$ź;yňZF†ť$5fóń„„âÜ\gWW‘Xśvüřő‹­8ŽĐü6·ŤG÷ě©(*rvs…)‡߼r§¨6ŁńČ®]ĘĘ\ÜÝůARbâík×lA§ÓŞÓܱٶŞĘĹÝťËăýšpďĆ @©Ó%nßŢPSăâîÎárŹíŮs˙Ö-ś$étšÔęý?˙ÜŇŘčęáÁbłďÜ™÷.ЬV'üô“˛ĄĹŐĂĹbÚ±Łčţ}‚f§Y A©Ü·e‹FĄrőđ@QôŔĎ?—Pő­­{7oÖi4®‚ě˙駲âb’ć9P×Ô´wófŁ^ďćáA‘äľ-[*+* ¶±qϦMf“ÉÍĂ$}[¶ľoŹÇsqwŻ­Ş:¸c‡JݧӱÄ­«W“ä .nnJKŹěÜ©6™pŠşqůň©Ă‡Bˇ‹«kEqńŃÝ»Ő&ťŽÇŻ]¸pćřqˇXěäęZś—w|ß>­Ĺb#É«gOžI$N..…wďžÜż_k±ĐéíöĚ´´ ©©©TáârďćÍS‡l6 A\HM˝”–&•ÉÎÎ9YY)GŽč­V”ć˘0ÚléII×Îź—Éĺr…âĆĄKiÇŹ›pÜ„ăgOžĚľxQćä$S(˛.^xpä”)×.\¸›ť­ÓhŇ“’8\î×;vl>x0v„kçĎçde=UhihČHNKĄ˙üĺ—Í~őŐ+çÎĺçä¨ZZ2’“ĺNNßěÚµéŕÁčËçÎĺ޾ͦé„uUUçOťr÷ňúvĎžűFG_JK+-(h¬­=ź’âĺç÷Ż˝{8p ÷K/ež>]ś—Ǣѩ,-˝šş1!áűýű»…‡_LM­*+«./żšÜłç÷ ‚»wżšZYRB§S’——yćLXßľ?ěßżqß>ꀀó))ő55e……™ii˝ű÷˙ńŔďöîőôńÉ8uŞöÁfvcŘţ˝¤íĘ•+wďŢ•ËĺÓgľ>n­Vűbűé10ü×vögʰQ…˘hAAá'ź|:iŇ丸©7n¬­­E¤}JdGt-##ĽoßQqq€T(śżfŤNŁ©«Şş~ţ|Ä€ŻNš„ČD˘Eo˝Ąji©./§3lOź3f  H–ľűn]UUkSSć™3CGŽ:jŕ,“ĹŻ]ű ¬¬©ľžÎ°Ą'%Ťš<9:&†purZńţűEąąŽDyÜŚ‡%ÜśťW|řaŢť;jĄˇŃ9}ěXÜĽyQnno¬[wűÚ5‹Ů|ćر FHxyx¬úřăěK—Śz=ťaK=rd˘˘poďŐë×_>w·ŰSŹ]°zuXd$ŕëë»jýúĚÓ§mV+B“»§9˛ôťwşőîmđXµnÝą¤$Š˘RŹY¶vmhx¸ (hŐşugOś é ŰécÇŢřđĂŕ=ěAÝş­üđĂÓÇŽŔ™_]őŃGAˇˇv€ŕ=–ż˙~ęŃŁtÝ$ÉsII«?ţŘ?(Č˙î»§¦(*#9yÍúőţv€n˝{/~çťS‡a4•±[­—ÎśYł~˝ŻŻ/9oŐŞS‡8~%=}ÍúőŢŢŢ8@ݍ¨9+Vś:|Îh™ †—.­YżŢÓĂ8pú˘E©GŽXĚćŰ×®­ůřc77 jĐ ¸yóRŹaÓčhÚÚňsrŢřč#7gg  ˙Сc¦O?{â„^«-ÎÍ]ůÁ® 3rňäł'Nж憆Şňňĺďżď$•"CFŤ_, … C‘ęęę_~ůEˇ'$ěÝ¶í§¦¦ĆC‡©TJEžš Ö>x pvvvss$UÁ=zX-˝V[[UĺâććäââHţşöěi6™t ť!©*/÷đö–999ʇ†‡ëµZłŃXU^îéç'‘ËŮ@÷^˝´mmt ¨,)ń I$  gD„ŞĄĹj±T–”t DŽxXddkSÝČ PQTÔ­źĎçPá}ű6ÖÖâv{yqqpŹÜGń¨¨†ššgŚŚ•††‡ł9Gů^/˝TSYI’dYaa÷^˝Xl¶#ŢűĄ—Ş+*č^0…”öŔ0Ś@ôé×ŻŞ¬ (ެ°°gd$Š˘Ž÷îׯ˛´ôS"Ë ĂűöE•Ż(*€ň˘˘đ¨(ŕ ˝űő+/*˘˝ńQTEqqŻöň(ІGE•@eIIݍ( €€aXxßľeô:AT•—;ĘsXlvĎ>}Ę‹ŠH’¬®¨oŹł9śî˝{—Ňĺp6›­®Ş*¬o_GyŹVQ\ŚăxCMMĎČȇq>?¸GŹňâbÚ)&SsCCĎ€ ‰CB*KK­VkkSSŹ>}(€H"é\YRB§cÔëŐJe·đp € •É|üý«+*LF٦­-$,Ě—)žľľŐt†V§Ń †®=z8|Ž“««›‡G]U•ăŇęÖÍᣜÝÝťÝÜꪪ0šNئTâv»HŁĽ›§§L.o¬«S«T$Iv F0woo±TÚX[K§ÓŇŘao@ €xűůń‚Ö¦&es3›Íöö÷wÄ}üý9\nsCÝ”ČĆş:Pčéă ~ÁÁ(ŠŞ•ʦúz‘Xěîĺ… ţ]»RĄjiar÷ż!ŚKg` E,ńůB>ź˙?šŠjµ’$˘(™ PA´ ˙đŰk˝ĽĽöîÝ sç΀+×lűy3—ËŐjµĎż‰ś÷đőÄj‹şă˙’Ë˙7[5 ĚeňżŽcę#Ĺĺň*++SRR‹‹‹˝ĽĽâ⦳X¬[·n‘$;bŔ€$IVWW_żžUVVćââňd˙GôZ-_ aXJZšŹżďÇmV«^«…R K>}Úżk×đ  »ÝnµXşÜT­J$=ž”ÔŁwďP??«Ĺb·ŰuŤX"ŁčŻÇŹ÷zéĄ`oo«ĹB7ôí$‘Čĺ"=zäHżÁýÜÜĚF#ăZµZ&— QôȡCŃ11Ţ..&ÇńgčČťśř(zp˙ţ±cÝ ^O’¤FĄR8;ó$1!!vÂw''˝Vű ŁĄQ©ś\]ą˛Ďž±Ó¦ą»şę5 (µJĺäęĘA„Ý»ÇĎśéćî®Őh(ú5lĄŇĹÍ Ř»s甹sÝĽĽ4mm€ZĄrqwGöüňËÔůóÝĽĽ4*Ő3îS•ĘĹĂöüňËŚ… Ý<=Ő*Őø»;ĺ/Zäćáá?˝hÚÚ\=_ŮÜlµX€˘ś9śěű÷5jő«C†pąÜÖ¦&:łŃ˘¨›}ĺÖ-›ÍÍf±LÎăaćÄbefgŔţýY,–É` {bÔëĄ2™‚ĹJżrE FGD b6™ŚT&“łXç23%rů€^˝Ŕl21÷mư100ü›´´łÍÍÍvű˙ä†Lv;>nÜX@@±XśC‡łpÜ6c: čőlEÍ™3233m6ŰöďOds8qS&±X,Óo<ř|>Lć˙°!ČîĽ=E’@Íî>ËŚ›˙'»víţ_Ü©Aж¶6ć2ů 6’$1 S*UçďÜąăxKK‹“““L&÷őőÎĎĎ÷ňňěŰ·/Š"(ĘŠ‰‰ąrĺZuuMttôSígŰív˘Ă^ ޏÍFĐěňdFč(O>ľE!í:Ž8őű}AlVk‡™ŹâEý®Ő>YÚQžNç÷Ľ]Çj±PŹZěßÍV‹ÚÇ>źS(ęńňŹęĎ÷~=GÇ÷>]~ďč¶ĎőG„z\ç÷:$@QÔŁúSŹŐ“˘(›Ĺ‚8ľëwë@Q”µC;üVžăM›IQ6› i×ü·>I:üîQ=Ô!‡Ó\ű^€ G:ĎS‚$Žâ>¶)@â¸ÝfCžŁ>ÔÁqűc{xPíőÄqî˝=–üaE9zÝşöÁívüńŤÚăv»ťxN)ư10ü­@dăĆď˙§!:z P($ů|áŇeÁdpůMář%۵käää¬}˙#ëŮÇăyzz´Żç Ă***#ľľ>ʞC ÁśZ$QîQ]¤~$E>_¸pŃ˙t?a^xđ?nŘ€˘H‹{űöí¬¬¬±cÇĆĹĹĄ¤śJJJ ěŇĹ_ĄRyyyK$ĄRĹb±ÜÜÜ(ŠÔëuí c"(’H,fł†$ÇŚG´Z­‹ĹárE‰ŮdŇ三I€‹…Ĺfs¸\Š&ˇKĄFAG’“§N%ZĚf—ËbłĹR©AŻ×“dÜŚ$@‹ÉÄĺńŘ]b*‘ÉôZ­$gĽţ:Đb0đŚĹ’ČdZŤĆHQŻÍťK4ëőˇĹbŃéHĺrM[›™˘ć,\H´h4B±EŃGńą‹á-jµH"A1ŚNG¦P´)•V˙ńń8@‹R)–JA¤ry›RéáăłpŮ2;@KK‹D&Ł›}íĐQµ¶*śťŻXahll”Čĺ€T.Wµ´HĺňĹ+VŘëę¤rů32o©Bˇlińń÷_˛rĄ  µ©IŞP€T.W¶´xűú.YąŇ ĐÚÔ$S(ž‘˛Ke˛ÖćfwOĎĹŽňÍÍ2''@‰LÖÚÜěćîľxĹ E)››źĄ ™L©T:9;/\¶ĚBQĘ–ąB H"imksR(ÄÇ[(JŐŇ"sr˘ÓA1L(+µZ™T:ońb I¶)•2…AQˇXÜŞÓÉe˛9 šHR­RÉśśčna,K ¶Ťn..łćÎ5¤F­–Ęĺ†ń‚V“ÉĂÝ}ćëŻHR«ŃHĺrZ‡Ëç+-_____IęµZ‰L渔Vk€żżżŽ$ z˝D&Ł»(—€Ňf éÚµ[×®Z‚0ţ{_WU™˙˙śsîľł\Ů‘UPÄ PPŔAs)ÓĘm˛šĄůM}gš™´ĹĚdĘj´2-sßA”}‘E@v.—»ogůýń$C™·fĘÎűĺ«×íÝÓŰsĎsžs?źçóy>­X*es8,«×b  R„AŻKĄt:<>EŃ^Gč#“Ń(‹ą<‚ Ź€ĽŮl‰Ĺt:|€$IAL™: ŔqÇůB!‡Ă!˘Ź ˘˘Ł!O„@(¤ÓD8Ž÷‘děĚ™€^‹…˘(ź/‰,fł’$g%$@Ŕ÷öoL,´ŰśżúĺŤ~·Ŕ)ˇ~ĎJ@”J€>ΰśŞŞŞ`­ČI)Ócăq0ňxô3y,ßąL@úűHń칀˘ŤôČÍÍ-**2™LE-}jŐü…‹ů|ľ\.ŹŠŽ;sćlvöµÜÜÜY s…Enü.ťĂb±Äš%ĺJź$źGĄR1…X~Ť@¦DBÇě‹/öÎźż 66.1qÎW_} Ó}Y,IZ­6&&:((P«ŐP@QtŘ¢fÍŞ()Éú¨Ş´” @[GLJ[¶ÄΙC$ź–öŮŽu••lZ[[?Üş5>) Ayii»·ożWUĹ ĄąůŁ·ŢJ\´ĄŮĄ˘»dÉ'ďĽÓx††]oż=wÉŔÜ””]ożÝÔĐŔ ±®îăwßť—–6ÂîXbrň‡[·677s¨ŻŞÚ˝}űü´4Aâ.ühË–ÖÖV6u••{>ř`ÁŇĄtŽ ›Ă‰ť3çĂ-[Ú::ŘTß˝»ďŁŹ,]бXŃ nŮŇŢŐĹ ˛¤ä«Ź?^°t)NŁ#‰&OźţŃÖ­]˝˝lJoÝ:ôĹóRSy|ţÄiÓ>zë­®ľ>w Žîß?/5ŐBŁ#ł·™0áăwŢéU©0n_ż~ćŰo““ĹRéŘĐĐŹß}WˇVc^»vńĉÄE‹,4“ĺäęęíç·{űö~ť ďňĺś‹ăćÍsprróňÚłc‡JŻGČÉĚĚżzućĽyfÇĆĂÇÇ^.ß›ž®1)®ś9SRX5k–›§§X&űňŁŹ´f3ŔĄ“'ËŠ‹Łăă-4:c‚‚0ëëO?Őă8ŔąĂ‡ëkj&FEůŽKQÔ7»wŕ̡C-ŤŤ“bb,4sČ„ :­öđŢ˝F’´püëŻ{şşB#"ĂÂúűúŽîŰg¦(EÝ·ŻżŻVFV'bÚ´ö––“Z0DĆgź™Íć1ÁÁă'Onnh8}č€ǿٽPTŔ¸qŹąuëÖŃŁG_ĽxŃŠ˙űß˙îççwőęU+ţő×_÷óó»~ýş˙ꫯŽ3¦  ŔŠĺ•Wüýý‹ŠŠ¬ř_|Ńßß˙îÝ»VüúőëÇŽ[YYiĹ?÷ÜsµµµVüęŐ«¬ř•+W777[ńË–- ikkłâ—,YÚŐŐeĹ'''‡……)†ś]°`Axxx˙ Ă bÎś9&LĐh4V|BBBDD„ţg>[ȤD2`đ=Ťş^x.6v]jĐO>ź÷ŃG»şşş)ŠZ·îggg’üÉ6ÎĚ&“ÄÝť”H(Óň±ŕĺW­ VW'řĂő˙J§d2 ÁŔŹw3(ŠšŮ IDAT„©S§ÍF™LŞ×ëűű•îîî€ÎÎNA„BICź[ a“&EFG_Ď̬(.&˘»Ł#mÍGgg±D21**űüů»7oˇčî~ęůçťGŤ"h¤Č¨¨Â)S.ž8Q“CX,•*ĺé§Ą2ŮĨ¨đI“Î=šő*a±čµÚ™ Đmş[wăęŐ“\={ž™µpˇ@(ś:sfŢĺËÇöďżtň$n6Sź”D—E†0=1ńĆŐ«‡>˙üěáĂ“‰Íf'$%q¸Ü鉉y—/óďź:xĐl2ńřüř¤$ľ@@ń‹›7/˙ęŐ}}třË/ÍFŁH*MHJÂ0lćüůůWŻîÝąóHd6ĄvvńIIt‘:€ř… o\˝ş{űvľ@`2ťť’’IX¸° +ëß۶ń“Áŕäęš”„Đ;l‰ÉÉ…ŮŮmÝĘăóMĂ(OĎř¤$@Brráµkľů&—Ď7ęőî^^ń Rô›n‰ÉÉ7Ż_ßů÷żsy<Ł^ďĺç7kÁA-şť—·ăoăňxťÎwĚ™ ŚKHN.ľqcűkŻqx<˝Vë;w.†a‰ÉÉw ·ýĺ/.WŻŐú‡„ÄÎťKç°ń‚„ääňââ·_}•ĂĺęÔę °°č„6‡“ś\yçÎŰü#›ËŐŞŐÁááŃ t:b©4>)©¶˘bËďĎfł5*Ő¸‰§ÄĆ „„¤¤O·m{ó•WXl¶¦ż?,2rjl,ťĂf/—ĎZ°`ozú?^z c±ÔJĺř)S"˘˘řÁ¬ öôŃß7oĆX,U__Ä´iŁ˘č-7·™óće|öŮß~÷; Ă” Edtô¸‰Ů\nÜÜąGöíűë¦MŠ*{{'OźIçhyřřĚ3ç̡C˙·a‚˘}==SăâĆŤC1lúěŮçŹy}ýzA F§ăőÜą×ÖŻGčí5ËÇßźsńâkëÖz»şfĚ™ăÓ,Ň€qă¦ĆĹÝĽ~ý/ëÖQ$ŮÓŮ9{ńbw//ÜÍmJlěíĽĽĆş:ČĎKKóôő}D‡­   ±±f F~~~CCCKKËЭ؆††CÄçääÔ××···[ńŮŮŮ÷îÝëěě´âŻ\ąrďŢ˝îîn+ţňĺËMMM˝CŠîdff¶µµ =~ţüůŢŢޡŽÓŮłgŐjµZ­¶âĎś9c0†;uęA:ťÎŠ?}ú4Ŕ`0XńçÎť[xCŻ0´ÂÓ•+WŔŁźWd6 ~čő†Ő«źa±8˙•2č‘#G»şş›7ż2€ź0ÓŐ]Ę$ (b\(ŕrV OBsżÜ‡ĎAÚŰs¸\đăűŞ i{őŐW7oŢ´X,{>Ű ľ+{këVAÖÍf±Y€É®“sé\°37}şÇtA(¶lyó×§!I˘żżź ˛ýJÝ5Š˘pwpp>=ćąçÖ:99Y,ŘlÍh4řůůÝľ}»˛˛jҤHŠ˘ 1 uqqÁq|č[‚Ŕ^(\˛zőO?˝yý:›ĂY¸lŮŚ9s8(* Sź}öŔ'źÜÎĎçp8IË—Ç$&ňŘlśĆĆ•K$Ëž{îëO>)),äńů‹W­š6s& Eĺbńňçź˙ęăŹď޾͖<óĚ”38,]ö—łL¶rÆŻví*/)‰Dik×NŚŠÂÄE&[µqăţ]»*ď܉ĹËž{nÂÔ©l ŁËţĺŕđô¦MűwíŞ()‘HĄË×­‰ŕćč¸úwżŰżkWEq±ÔÎnĹúőˇč RV:îÎÎĎľřâľ]»*Š‹íWmÜđpqyvóćý}T^\ě —?˝iS`HEó"¦đrs[óŇKűvíŞŻ®–;;Ż~ńĹ1cÇx{x<»yóţ]»îUW;ą¸<»yłß1#XRľŢŢĎnŢĽ˙ăŹďUUąşą­yé%_ Ł}}WżřâWź|RWU5ĘĂcíË/űxy™éߊcüýWoÚôő§źvutxx{Ż}ůe/wwţOoÜxŕß˙îîěôôńYűĘ+žŁF™čŢÚ(şrýúovďVôôřŚłöĺ—ÝťťM‡‡/_·îŕž=}˝˝ŁÇŽ]űŇKnNNt»DŠŽ›8qéÚµß~ţy_ßŕŕg7ovup06iRęłĎŢ»WĄTŽ ]˝ył‹˝˝‘ć&ł1,bęÔĹ«VÝ·OŁV‡‡?˝i““Lf`bTTňňĺÇľúJ«Ń„N°jăF'©Ô@ŁĂe±¦ÄĆv¶µť8pŔ Ó…OžĽbýz‘ČŔÔ¸¸®¶¶S † S¦,ţy±îzxlvLBBOGǙÇÍFcdLĚҵkeŔŚ9szşşÎ9b6›'OźžşzµťPH§#ŕpf-XĐ×ÓsńÄ Âb‰š5kńŞUb.— aáBeOĎĄS§‚IHX´b…”Ď7Ń<Ěb.wNJJ__ÖąsEĹÎť;Ů2!‡·d‰J©Ě>0kÁ‚y©©".×LŁ#ĺó“žzJ«V_żt EŃÄE‹-â±X(‹•Ľ|ąN­Î»zðً'$% 8śG¬„ÓÜÜ66¶łłÓÇÇÇŠź9sfż———ź`4áŽŐ`Ěž=›˘¨QŁFYńóćÍărą...VüüůósssĺrążpáÂÂÂB‡!g2-ZT\\l?äĚgJJJYY™T*µâ—,YR]]-‹­řĄK—Ţ»wO$YńiiiÍÍÍC+§¤¤´µµńx<+>99ą»»›ËĺZń ,čëëŁŰ]úÉ쌬óçá§^­"-mŐ‘#BBÂC™_qż4VV–Α0j”›V«yŚc™L6n\XEE% //7,,ÔbůÉvh(‰ŘÎÉůˇ2†rzčííu ?ż>2ŕ6>źo4ŤFăŕw‡Ĺ±üŮ0š ˘‡ßUń‡0®˝q ÓęÔj‚"†a ĂX†bĆbÁÁŘlvżRŮXW§éW‰ąě=%m•=`Kýą[V$Ř;»÷őőňxĽ’’;‡‚‚çÎťŁV«żů&cҤČĹ‹UW×l۶ÝÍmÔÓOŻ4›Í|>jÔ¨ Ö999étşÎÎ×mJýÝK6lŘżE`€@@0ŕŘŃń;fEGŻŢĽ9mŮ2ăp:Äp:y€ €Čŕŕ~řaě¬Yć©3ří# ŔÝýËłgÇ…‡ă4:<FŁ#Ŕ[*˝X^îáéIţĐx ÖĂşV:|Ü9śâîné SÇă?ÄĂ—ŠŢ3›çP<†ăŁŮěVŠLţXµJ5^.`6ż‘Řpăxňá<ĚK[kkBpđ}µZ;ś|ŘČGŕ+ĘĘž™3§¶˝]5č"±áĆÓń9ŮŮÝ´©¸şşßÇŽůbçÎě7”tŕC8TgX `÷'ź\»xńŘéÓýß׿Nđf’#ňđa~ó˙čhiŮ˝wŻŠFT‚rX ŕĄM›DÉ[ďľ«4‰Řpăéx›6l8¸{7`Ďž=/ĽđÂĐ­¨aÍ$†˙/ăÍ7ß|ýőׇ&mÝ«­ÁIű,Ě˙aš˘¶źe"l <©@q8˙…·Ôرc L´Úy˛–˙üÔ ł ĚL˙˝ßcl&“)88hîÜą‡Ú˝ű36›=sfśżżżÁ`đňň\±â©Żľú:-í)Ĺ˘Ł§Ą¤,vppxaf‘‘Xţ‡Á1":ž˙eťGx© ?ž€ü~úĽžaÇ“¤ŽůIÔ~ÂĐńtüĎŞC rZ?hĺ}±@‡Ť˘Hw7ýżvR Ôá#?Öa«¬¬dłŮ6lxyynďm—§R«ôzýľ˝ź‡„EM& ŽW–ßQk5'삥 kújw=lDN‚×€Ďţ( ßÔĎĚ˙¨‡ŕ8>lĄŻayŠb6ľ0`Ŕ€ă°1`Ŕŕń=6Q«”X,‰DŇUg],˘T"B!řń!‚I“&éőz^8ö¤Ńh2ż«ˇŐ«Päd_†źaO•I`ˇ¬/B‰óů(Č_™«6©™YbđËpŮČÇ•1EA0`Ŕ€ă°1`Ŕŕ'ňÝľë ŤŠŇś9M99ýX?mŕĐôÖ'Źćńy|>ߪw†˘°·›UDâ?ŢšÜx>źŤ˛qg¦†Á˙(‚€PIQŹÓI‰dŔ€ŚĂĆ€ŰÝ5tZh`ţďu|Ćt@’?ĘaŢÚË/żl±Xnßľý·˙{ŤÍaO0žÍfiµÖť(q‚^Ĺü]ą«÷çmŹpž łč™ađż] ”ý}€Í…ÇŘÇßCQ(‚$Bˇ [şđH`±XB‘Č :RP J$2Ě6ę X*•}żĽţŹ…€ ©Tf[—I>A¤2™Ě¶ôĹör9E>ľËĆćpH‚řęÓOůŹ•ČýßĂ(Šúbď^ ł©ŻI’€˘>űúk҆/Ĩד$ůďŚ [&AQeoŻĹlţäđa“Á`ËÍyp˙ľ^§űäčQîń÷Ô0«¶˘˘żŻďÓcÇôZ­-“^”źßŐŢnهÇËĎĘjil´Q‡Ëç—ö+6Ţľ@P]ZĘĺó?9rĨ×?ö ­./‡źęęęôŹ+Ĺŕ犢6˝"/s¦q6_ ĆŮŹk™R”X  ˘Ń ¶u„Bá¨Qî …b„ĆŮííí\.×ŃŃQ.wÄqĽřvÁŹĘłwt†Ä1ü 1k‡™ÁOđëe[ăl‚ ţo~X˘'«ţ~ËcŰîŹń÷żo=zôĎ·%€`0™Ř, ĂlŐ19l6fłŽŢhäq8(ŠÚŞc0đx<AlÔŃ ůItř|Ű Ôę Ű'ť˘(˝Ńh»IQFŁQ`»IÍfŹgŁA’fł™ołNçsą6ęXpś I‡cŁŽŮbˇ(ŠkłŽÉbAŕ°Ů”m"đčAJJJTT”Ůl ~yĐëőoĽńÓ8›Ź`ŘÚ°§ˇR©gO EŹ˝WÄři ~i ˘(@yüÍA) ¨TŞ?ýéOkÖ¬±e‡[*•¦ĄĄ-[¶láÂ…F"uR©töěŮŻľújÔ´if‹ĺ±u$ItttzzzPPnC¤N(FFF:thÔ¨Q¶ě4óxĽńăÇź=^"‘Řrtð«YY6&E1eĘ”Üü|†đ#‚ Ť&!!ˇđÖ-[&EŃŽŽŽeË–Ýľ}[gKd Ăjkj6żôR^^žFóřol6›]PP°m۶K—.ÁźŹÇ—Ë=wî\FFĆŃŁGmŃáóů_}őUAAÁź®R«mywîÜŮŐŐµý˝÷Ô6ܱXü׿ţU(ţĺ/Ń>D"yíµ×Ž?HLL\ż~˝Ĺ†őÎŕg‹ĹÚ˛eËO#ĹÜM XZ›;w®N§ëěě|ńŮżťťťQeöđ<@1´˝˝ÍaBäŘ ŹgsŁ(ÖÓÓĄTö*• @(‘Hlń¤R)†a|>_"‘Řr"E*•˘(*$R©-«U"‘ (* %‰-›H$BD$I$6AÄb±íüv¶;lPÇF‡mŕnŰ2é(ŠB˙ >E¶—B‘A©TjK ‡Ă …(ŠJĄR[&‹Çă  ĂlÔ<ŹĹbI¤R["c"‘Ëĺ˛Ůl‰T l¸?‰„Ífs8¸Z{Ą<3l6{ŕź žXߏą 0°rŐٱcÇŋֿŔfłăÍfł-vż( b0čy\žLfoŐŽ÷ôtÍf‚ Ěfł-’Ůl¦( ÇquL&ÓO˘3řzlYřđşŰâ“ čŘb»C?ÍĆ‹pŘŕÔŰň¨Ť“۾ۮC’äO˘gŠ˘(“Édă÷Âqś˘(݇Ĺba»śn’$m×!IŇĆ—ĆŕgĎ–‡ă°1`ŔŕWiĹćççcö§?ýiüřp@QŻżöŞP(ęďďg*3x˛6'Š˘°˙ÚăŮL†Y,Aen' 0`6 üWŚXŠŠŹŹ7Ť‚|óő—R©Ä`0šÍJćÎ0x˘AZ•é†}áp±Ś\·&• ŐˇăS:wVăéxFÇć!ü­é0`6 <™~üĎľ_ĽpšËĺšL̉5O2 ńK’˙q˝Pĺp8 Ź|A:ó EQ6› Oá8ÓĂÄavß`ž°ÄĺĐńtüŁčX,f6oŁÎ?`±Xl6Ú Çđ0óŃu¬Ćć-+é=˘Îŕń?•›Íf±XŹ®C7ţ1tŕą&ëç×iĹŹđś;Ax=Ź®3ěxu˛[óAX,–‘ł^éĆ^ĽŹ˘C7ţçĐy”Ĺ΀qŘ0`đÄÂŃŃqÍš5Z­¶ŞŞę˝mo ‚±ţţ0Yźą9 žx$ ťEU*Őßś>~öěى𦦦'N”––r8Č‹Ĺb:ł›ÇăŐ××?~Ľ˘˘‚ËĺΞ=;!!A °ŮěşşşăÇŹWVVňůü9sćÄÇÇóů|:3—ÇăŐÔÔ;v¬¦¦F Ěź?ćĚ™‡ĂáTUU;v¬®®N(.X° ..ŽÍfÓ­zŹW^^~ěرúúz±Xśśś$‹ĹşqăĆńăÇ{{{]]]—.]a6›1 ËËË;~ü¸BˇpssKKK›0a].;;űäÉ“ýýý^^^iiiaaatÍ0áýż|ůň™3gT*•ŻŻoZZZHHto.]ştć̵Zíçç—šš:°O7¬a±X.]ştîÜ9ťNçďďźšš_]Ľxńüůóz˝> 55uěرt:† †łgĎfff †ŕŕŕ%K–řůůá8®×ëĎś9“™™i4CCC—,Y2zôh:‹ĄŃh233Ż\ąb6›ĂĂĂ/^ěííM„Z­ľxńbVV–Ůl?~üâĹ‹˝ĽĽčî›ÍV*•çĎźżvíA'N\´h‘››EQ}}}çÎť»~ý:A“&MJNNvssŁÓáp8ÝÝÝgĎžÍĎϧ(jęÔ©IIIÎÎ΀®®®3gÎPµpáB'''şyçp8§Nťşuë‚ Ó§Oź?ľ‚ mmm§Oźľuë†a3fĚ7ož˝˝=Sň7&óžŕĂ?Ü·oßŃŁG“ÎjYÚňeiđ6sg<ń (Š˘H‹UTT|÷î]‰D" ážtç8ź/ŕóůˇ’Ć—@QT­Vź;w®ŞŞJ"‘pąÜ+W®ÜĽyÓb±¨ŐęłgĎÖÖÖÂ’€—/_ľ}ű¶Éd¶Š˘JĄňÔ©Sőőő°¦Ü… JJJpW*•'Ožljj’JĄ,ëüůówďŢ…§é†ŐQ(ÇŽkii%Oź>]^^N’¤Bˇ€Ţ,UwňäÉĘĘJ:ÇEŃžžž#GŽtvvĘd2A HQTww÷áÇ»»»e2ŕرcµµµt^‚ ťťť‡ęëë“Éd$I>|¸ľľž˘¨ÎÎÎŚŚ ĄR)“Ép˙öŰoFĐiooĎČČĐh42™Ěl6gddÜżđŕÁŚŚ ­V+“ÉL&SFFFssó@kkëÁ L&3 ­­­€–––ŚŚ ŁŃ(“ÉôzýÁŰÚÚFĐą˙ţˇC‡ĚfłL&Ójµloo455:tČb±Čd2µZ}đŕÁŽŽşŚ$I644>| ™L¦T*322şşş(ŠŞŻŻ?|ř0I’2™¬ŻŻďСCÝÝÝt:A@/ť˘(™LÖÝÝýí·ßöööRU]] kÁËd˛ÎÎÎÇ÷ööŇŐ*ÄqĽ˘˘âÔ©S°äăŽ=Ú××GDyyů™3g` Ç––Č« ŮlľsçÎůóçY,–T*…;*• Çń’’’ .Ŕ’‰őőőĐ#ĄÓ1™L·nÝş|ů2—Ë•H$555gÎśŃh4fłą°°đęŐ«\.W,WUUť;wN­VÓé †üüüśś>ź/‰ĘĘĘ.^Ľ¨×ëM&Snnnnn.äďÜąséŇ%­VK§ŁÓé®]»VPP „BáíŰ·Ż\ąb0ôz}VVÖ­[· óćͬ¬,˝^O·HµZíĺË—KJJ„Bˇ@ ČËË»~ýşÉdŇét—.]şsçŽH$âóůׯ_ĎËË3 O@ZŚĂĆ€Ť—_~Ů×ÇÇÓÓ#}çű8Ž+™# ~Kt˝(ŠÂ0V~~ž»»{FFFbb˘^݇^ŻżwďŢ­[7oßľÝÜÜ ·Ű)ŠşJX,Veee~~ţäÉ“ß˙ý·ŢzK"‘dgg÷őőUUUݸqcÚ´iďż˙ţÖ­[AvvvOOϰ¶ ›Íľ{÷nAAÁĚ™3wěŘńć›o˛X¬ěělŤFSZZZXXżcÇŽüăEegg+•ĘauX,VQQŃ­[·ćĎź˙ÁĽńĆfł9;;Ű`0%%%}đÁűŰß CVVťmĘb± KJJRSSwîÜůú믫Tެ¬,‹ĹRXXxçÎťeË–íÜąóµ×^S(ŮŮŮđě°:yyyeee«V­JOO˙óź˙ÜŮŮyíÚ5’$óňň***VŻ^ťžžţꫯ¶··_»vmňúőëUUUĎ?˙|zzúţđ‡–––k×®QuýúőšššuëÖĄ§§żňĘ+MMMPźÎń»víZ}}ý¦M›ŇÓÓ7oŢ|ďŢ˝śśŔµk×^|ńĹôôôßýîwµµµ999#8ZŮŮŮÍÍÍŻĽňJzzúúő뫪Şrssáě´¶¶ţţ÷żOOOţůç+++óňňFp˛˛˛:;;_}őŐôôôŐ«W—••ĺçç‘••ŐÝÝýç?˙9==}ŐŞUwďŢ˝qăưEüˇc“••ĄT*_{íµť;w.[¶¬¤¤äćÍ›fł9++K­Vżţúë;wîLMM-..ľyóć°M #‘••e4˙ö·ż}đÁÉÉÉ·nÝ*..6 WŻ^5›ÍoĽńĆ|0ţ|ČÓéô÷÷gee!ňĎţsÇŽńńń………eeeŤ&++‹ĹbA>..®   ´´”N§§§';;[(nٲĺý÷ßź6mZ~~~uuu___vv¶D"Ůşuëűďż?yň似ĽŞŞŞau0 kooĎÎΖËĺożýööíŰĂĂĂsssëëëáÓčęęúÎ;ďlßľ=44ôúőëuuuĂę°X¬ćććśśooďwß}w۶mcĆŚą~ýzKKKkkkNNÎčŃŁ·m۶mŰ6__ßśśś¦¦&:ťúúúëׯ˝÷Ţ{ďĽóŽ››Űµk×:::rssÇŤ·}űö·ß~ŰÁ’u IDATŮŮůÚµkmmm66Ą`Ŕ8l 0řµâđáo®e]‚ńćn0řÍůO|Ť$JĄR$rąťN÷Đ‹Ă*+«ţţ÷&'/JIYňÁ<ýôÓŤ¦­­íÖ­[aaańńń†Éd˛Ő«W÷őőµ¶¶ksłŮěÜÜÜ)S¦Lź>EQ{{ű5kÖ´··+ŠĽĽĽAź{îąćććîîn:Ç/+++!!aęÔ©ą\ţ /ÔŐŐ©Őęěěě9sćLš4 ŕää´nÝşŞŞŞţţ~:GëňĺËÉÉÉ&L IŇŐŐuÆ wîÜ1Ť—/_NII?~%%%33Ód2Ý˝{wÆ ź0aBrrrff&ťŽJĄŞ®®^·nť““`ҤIsćĚązőŞV«˝wďŢşuëär9`ęÔ©ńńńW®\¶‚ ===­­­Ď?˙Ľ˝˝=‚ 111ŃŃŃ999 …˘˝˝}íÚµvvv(ŠÎ1cňäÉ999ĂvĄĂ0ěÁJĄrőęŐ0\źżhŃ"‡ĘĘĘÚÚZ™L–’’Âçóů|~JJŠD")//§Óą{÷®««kRR—Ë …K—.ełŮ eee ,ŕp8"‘hůň债ş:[şí1`6 üÚlUQ(ßěżpî”L*Ç(ęa¸Áf kŃ2`đKZŕ»IpąI’l6›ÍćŔÓ\†¶´4ţůçvvŇýűżüôÓŹŰŰŰ:¤Pô˘(BgSÚŮŮ988@#Ř×××d2iµÚ888ŘŰŰCŁÍĎĎĎ`0Đemˇ(ÚŇŇâěě,“ÉŘl6EQţţţŤFŻ×777»şşÂĽJŠ˘T*ŐŇýű÷=<<   T(fłą©©ÉËËK @>((¨··—.2†aXCCŻŻ/źĎçrąEwvvâ8ŢŘŘčççÇĺr!ŇŢŢNwĆEŃúúz6› LJ††¶¶¶’$Y__Ŕb±x<ňtó©ŻŻ Â0l`¬ÓéśśśÔj5EQgłŮß~ű­Á`prrR©T#8ZýýýŽŽŽ†Á“cÎÎÎýýý<Š˘8Ž;99Až*•ĘŃŃ‘‘AQ”“““R©„Ľ\.§(ĘŠ§{Š Žă(ŠĘĺr8^­VËĺr‹ĹrčĐ! Ă•J原FŁqrr2 ß~ű-ô=ŕők4ą\®×ë>ĚápFÖ!IR«ŐĘĺrµZ}ôčQ.—kooŻT*)ŠŇétrąĽżż˙رc|>ßŢŢž.¬ HÁ —Ë{{{Ož<)d2Y?AFŁQ.—wuuť>}Z(JĄR•J5¬ŚšL&GGǶ¶¶sçÎÁža3›ÍrąĽµµőÂ… ‰D$Ť ۸;::644\ľ|Y*• ŤFkK:::Ţ»wďęŐ«R©”Ďçk4:ŁŃHQ”ŁŁ#Ě\µłłărąZ­öťwpp¨¨¨ČĎĎ·łłăp8Z­–NKł··‡§vvv†éőzŁŃa˝˝=Lř~đWř:$I¨éĐë¦ţ$:Źň"BÄĐB;ů‘ďü+čĆ#=ŔG˙^pÓd°üź ŔĆÄÄPĄP( ¸@ 0›Íýýý±±±đĄst™Ş`żA0)‘ 0`Ŕŕ·ě°}W%Ňh4šÍF»e4ę`rEQ&“ ĂP‘HtöěąŰ·‹D"EQfłĆĺ¬Ô`á ĄRŮ××ĂVÍÍÍ\.W$ąşş* xHA¦¦&>ź/‹‡Í$IŇÝÝ˝»»[­V˘hCCX,ćóůîîîťťťZ­ňőőő01lXŽ$IOOĎčőzÇQ­««‰žžžđŃďŕŕĎ• «ăĺĺŐÔÔwú1 «©©GkĽ˝˝- ě9VSSăââ2‚éăăS__ÓD1 «®®†G}|||ęęę`+d ĂŞŞŞÜÝÝéŠ+@ťÚÚZŠ˘Ěf3Š˘UUUžžžŘo`€‡G’čźęęjÄ@¤ŞŞĘŰŰŕíí]UU5ŔWWW{{{ŹŕhyyyUUUˇ( {mŐÔÔřřř<==óµµµ#č (ęîî>0ž$Éşş:oooČWWWcf6› ‚¨ŻŻ÷öö¦K=e±X®®®ŐŐŐPÇb±466z{{łX,ggçšš Ăŕ”ÝżßËËkXčŘČĺňÚÚZ8Ţh4¶¶¶zzzr8‡şş:Eq7 <đôô6Ą¦ĂŞý(ЎŐj;::ÜÝÝáhhh€ĽFŁéęęňđđ [p 455Áŕ^żBˇpuu …\.– ž’R©„…U†˝™L†aXKK ŻP(`&*ôi[[[aŔ°··W§Ó9;;Ó]ŹŁŁ#I’°lMa2™ŕQU‹ĹŇŃŃß!ťťť‹V&ÁvwwĂZ[[ĽHą\®Óézzz ËŮŮŮ=Jm0şgě×Î3 0`đŰň0%’$)’„ą‘€˘(‚řĂb±H’ĐjµŃŃQZ­–˘Š˘ĂÚL‹eňäÉŐŐŐ°bˇN§űć›oD"ѨQŁ&MšTVV–““CQ”V«=pŕ€L&ŁłM-KttôÍ›7oܸĎłíßżßĹĹĹÁÁ!***??ż  ¶ůţňË/=<<śśśčtbccł˛˛ŠŠŠ0 S*•_|ń…źźźX,ŽŤŤ˝téRII M|ţůçtÁ‹ĹćĚ™˛˛2‹ŐÓÓóŮgź………ńxĽYłfť8q˘˘˘‚ÍfwwwďŢ˝;""‚ÎÄq<11ńŰoż­©©ałŮťťť»wďž2e †a µµµl6»ŁŁc÷îÝQQQ°ŕĘP‚ żú꫆†‡ÓÖÖ¶{÷nذ;!!aßľ}MMMçÁ{ö쉋‹!â˙Ĺ_477s8ś–––Ď>ű,>>0kÖ¬Ď?˙ĽĄĄ…Ăá477ţůç ´‚ÄĹĹíŮłçÁ§±±ńË/żLLLDdĆŚ»wďnooçp8őőőű÷ďź={6ť#ÁfłŁ˘˘vďŢÝŮŮÉfłkkk<8{öl æL™2ŔWWW:thöěŮ#8H{öěéééałŮÇŹŹŹŹçrąááá{öě߲˛˛S§N%$$ Ű>˘(©Tđůçź÷őőaVRRrń⟸8‘H4fĚ/ľřB©TbVTTtĺĘ•™3g«C’¤\.÷ôôÜ·o<źVXXźźcooďęęş˙~µZŤ H~~~aaaLL̰g2I’tssłłł;pŕ€V«Ą(*''§´´tňäÉ®®®b±řŕÁ°¸kVVVeeĺÔ©S‡Ő!Â××—ĹbÁÓ’°“xccăřńăaUŹŁGŹŤFÇ/\¸ĐÚÚ:aÂ:ť€€ťNwâÄ čź={¶··7((hěر*•ęôéÓ0UňÔ©Sjµ:$$dŘűc±XÂĂĂ;::Îź?Źă¸Ńh}zaaáNś8a4E"Q\\]¤Ž$É3fÜĽyóË/ż°˝u\\‚ ±±±7oŢÜ»w/źĎ7Ťööö§›ű¸¸¸Ű·oďŮł‡ĎçĂb'±±±€™3gíŢ˝›Çă –FgĎś9ł¸¸ř“O>áńxz˝ŢÍÍ :3gÎ,))ٵkäÝÝÝgĚA!ałŮ3gÎ,--ýđĂą\®N§óööŽŽŽĆ0lćĚ™eee˙ú׿8ŽN§óńń‰ŽŽ¦s´x<^\\\UUŐÎť;Ůl¶V«3fĚ´iÓŘlv\\\uuőŽ; ďďď?uęT:8 ź}öŮöíŰŮl¶Z­4i’@ ŤŤÝ»wďöíŰY,–JĄ ŠŚŚ¤s´ěěě¦OźţÍ7ßl۶ŤĹbő÷÷‡„„„‡‡óůü3fdddĽűő÷÷Ź7nüřńt’łłsLLĚńăÇßyçŘ\><<<$$„ÍfGGGź:uęí·ß†ąŽăÇŹ VÇqww÷iÓ¦]ĽxqëÖ­°ŘăĉýýýQť6mÚ•+W¶nÝ P(‘‘‘°uİ:>>>S¦LÉÍÍݲe  §§gňäÉ0B ××›oľ ůiÓ¦ÁĂęřűűGFF–””Ľůć›$IvwwĎś9sÔ¨QNNNĹĹĹÍÍÍOHHđđđ ëOh…7nÜ»wV=ŚĽĽĽşşşˇ ĺsrręęę`ăřÁČÎή­­ę]˝zµ¦¦¦łłÓŠżtéRmmíP)33ł©©©··×ŠżpáB[[[__źŕˇ7Nź>­V«U*•ęÔ)Á Őj­ř'NˇÓé¬ř“'O‚áÁž9s0´"Ôůóç0Tnő˝ŕ<ţ¬?TL„Ť ü¶Ý5Š|řzk`€ÁqËčŃŁ»»»«ŞŞ,łŮl*,Ľ‰a¨‹‹ Ž[†Ó$IŇŢŢ>99ŮÍÍ­˛˛˛ľľ¶śâp8vvv‹-rqq©¬¬lllś1cFTTťcł­RRRĘËË›ššâăă'OžĚb±SSSe2Yyyůýű÷###a‰˙auśśś–.]* ËËË[ZZćÍ›7~üxXĘ|ٲe|>żĽĽĽµµuÁ‚ááát-Ř{můň冕••µ··/Z´ž˙<Š˘eee)))ÁÁÁt©Ś0ŐsĹŠA”––vvv¦ĄĄ âáá±rĺJ‹ĹRZZÚÝÝ˝lŮ2h@ÓÍš——×Ę•+ CiiiooďňĺËýüüŢŢŢ+W®ÔétĄĄĄ …bĹŠŁGŹ!%Ň××wĹŠjµş´´TĄR­\ą¦2úúú._ľĽżżż´´T­VŻZµ ât›źźßSO=Ő××WZZŞÓéV­ZS4ÇŚłlŮ2…BQZZj0ž~úiŹR"ŇŇŇş»»KKK-ËŞU«ÜÜÜ LMMíęę*++#ň#ś= Y´hQ{{{YYŠ˘+V¬pqqAQ444499ą­­­¬¬ Ă0ČŹń _°`Akkkyy9źĎ_ľ|ą\.Ç0l„ óćÍkii)//‰DË–-“Ëĺ#¤VNš4)!!áţýűĺĺĺvvviiil6{ňäÉłfÍjjj‚USSSčtx<Ţ´iÓbbb*++]]]SRR¤R)—ËŤŽŽŽŠŠ‚Ľ»»ű˘E‹čv1`266vҤI÷îÝ«ŞŞňőő]¸p!Ě·Ś‹‹‹¨«««®®öóó›?ľT*!E3!!aܸqµµµ555AAAsćĚ …Bˇö‚«©©©©© ILL‰Dt:R©tîÜąţţţŐŐŐuuułfÍâńx‰dţüůŁGŹ®ŞŞşwď^ddd\\]řz(˘ŁŁ|}}­řéÓ§ }žcccás;łfÍ rssłâ‚‚‚\]]­ř9sć;;;[ńsçÎ ˝űcţüůˇˇˇV|RRҸqăěěě¬řE‹……… =Sşxńâđđp±XlĹ/Y˛d„ "‘h(Áçó­řäää‰'rą\+~Á‚“&MzđxîÜąS¦Lůą»™#YçĎĂO˝ZEZÚŞ#G„„„†2żâ ~i(**¬¬,ť1#aÔ(7­Vó”K’ÉdăĆ…UTTňňrĂÂB-ś™h é× AtZťZ­BPĂ0 ca ĂP ĂX,ř2›ÍîW*ëę4ý*1—˝§¤-ٞl©?wËŠ{g÷ľľ^čH$’ßýîE//ď?ţń÷p;–Ĺb555m۶ÝÝÝýé§W™Íć;>puuݸq=¬kßŮů`ăĆ—,H^»vÍ@J Š˘°źŇw-ŢXt<|$%%­X±bѢEFŁń±u¤Rillě믿3°l5~`'x0OÄŕXźD"‰ŚŚüä“O`'ë‘ÇŹ #‰BCCŹ?îćć6`­˘(Ęb±ŕ1!+ťayŹÇ ĘÉÉ‘H$_Ă0ŘźĘj<'4((¨¤¤d°uő:A„‡‡WUU &EÇńű€ Fى‰‰©®®ôĆÓń(ŠBş˘˘bpxa`<|H†ęXń°ô† ŠŠŠÔjőę°X,XđÓŠçp8yyy[·nÍÉÉŔÎfCÇÓńpŇOź>ýő×_ź9sf ?íupxNÁŢ˝{óóóżúę+şë?‚ŽH$zď˝÷:;;ÓÓÓîĎŕńpŇëŔť‹Á<\\ţóź…BáoĽ1_‡ ĽźV‹šŽ—JĄüăŹ9ŘłgĎ /Ľ0Ô/ÖLú­ń˙sĽů曯żţúPwî^m NâŘw`aÖřÓÔеý,“É€ ~»~ڱA›Ź˘(ŁŃd6›‹ĹâééąbĹSű÷HK[†˘č´iSSR;88ŕ85l§A-9PË{ŔPŁăéđSé@ű~hmq:ţż 3PŁÜJgX~„ű3Ш`đx:~äű

>ްNɶťiőŁL®źJ‡Î:˙QVű“­óË™,F‡Ń±Q‡ă°1`Ŕ€O0LL¦ & î) IR(N™2ć´Ŕş˙ŹŢůš 0`6 Řö`±‚ [P‹'ÔCŔ8‡6ŘĂq|h0Xˇ„ą 0`Ŕ€qŘ0`đóâç®EË€Á/Ţeű˙ěťwxeöÇżSnŻIH'zď5Hé  €TĄXײ>–U—ŐźeqŐU`‘ŽH-„*¤„ĐI¤B )·÷;3ż?ćrŤInnPĘ|ž}ÜÜĂädÚ}çýÎ9ď9ě=„Ęů%‚`řë'Ş Z´hQQQałŮňňr}µx$!I 8Žĺ8âľ>BJ¤€€€€€ Řî#R©ôĺ—_7n,EQ$IĽöÚß>űěS…B!LC}pŕôşJĐľîČ˝ę=Žeą\¦Őj}uyľ´Z-EQrąśo*ĺ§…BˇŃhj6x˝s4 AJĄRŁŃř„W©TA¨T*_ͬîľW’Z­Öh4ţ P|¸FŁńłi_˛_ŁŃÔÚ÷üNďA‚ŕă´~^t’$M&AŤĆWĽ;<9JĄ’ ­VëOY,+•JŠ˘´Z­źO(™LĆűńç˘Ëĺr™LFÓ´źűŁR©$‰H$ňóü¨Őj±X,‘H4ŤŻNwňM÷6«ŮL@l|oPďCĹfł±,+—Ëív;˙äă` .*)) çg~řBˇΞŔîŚćÍ IDATŁ˙a9•Rm2 Vű=—!IR$k4šăÇ•H$ţ$™LVVVvôčQ«ŐęĎjR™Lf0öďßźźźďŹ–JĄ6›mçÎťçĎź÷Ghń§%999 Ŕź9·H$bY6))©f—Ű»˝dÇýôÓOţŔŁđ׬Yăçë-~@ްa?7I’•••.—kýúőUűąÝ-EÚl¶ĺË—űéçúőëaůňĺ6›Íyîܹʲ˛u?ü`ńĂŹD,>węTqaấK­~ř‘J$/ęôúÄeËüń#“Js23%ÉúĺËm÷zžĺ2YεküĎ999YYY|ëH Š˘ę+kIlŹ&$Ićççó3?Žă"""(ŠşqăFpp0ßâóĆŤ111111fłY"©T*•"‘HX–#đŔ˛LHH(äädÝóÜťaÜíŰw ß´iËáÇüŮ‚ l6[IIɶmŰü÷łvíZ? AV«uéŇĄ÷đúq:ťß}÷ť˙c Ă0 ,¨—1ęłĎ>«—»č_˙ú—ż/8Ža—_~ą^ögŢĽyőňěřÇ?ţá§eĆĺr}đÁţúq»,;{ţ|ř㇠ŕpŔížăż»,{Ú?6âŕĹ‹÷î‡ `ł\şti۶m‡CŘČgŤ Ř|ŁT*:uz:''—$I†arr˛˘ŁŁ{÷î{ěŘ/aaa2™¬gĎŢ'OţzâÄq‰DÂqM‹„*‘ŹÇqŕŕĎüź ŽÁ`|óÍ7§M›ćO0A­VO0aüřńÆ ógâĄV«źzę©·Ţz«GŹţ|ŁU*Uź>}ľţúëćÍ›ű©S(]ştY·n]dd¤?©TÚˇC‡;v¨T*®:EQť:uÚżż˙)‘Ý»w˙ĺ—_üśŤY,–„„„ꋳk×.“ÉtĎD"щ'ľüňËźţŮh4Ţł‰Dr`ÇŽ7vîÄńăđ'|¤Pŕ믱ovíň×Ď{kÖřëç… V㫯îÝŹB™3ą+ 4hÎś9ţiî4MňÉ'‚`¨k2YTTĽxń˘ĐĐP‘ž2eęćÍ ?˝ BŻ×ł,«Őjív{@@PÇŽňs}€ŔĂI‘ĹĹ7:tnÖ˛ý˝ ’¤ĘËKuş ť®R©Třł’Ä»†Ť˙Júă‡$I…BˇŐjý\ĂF’¤JĄŇjµţ¬aă×DńkĎü\ĂĆŻŃR«ŐÎ6­Vëç6?ˇ÷Š˘ü‰¬ňkŘH’ đ'"*•Jr9řĄˇ~ćę+ŕżž~ú‘ËÁŻ6ôÓŹT ©Ô_?Ľ‡ŰkŘ„•lʏöN€ŔŁ E‘C† މ‰ČaĂFŘív‰DrűńÉń?;Ž€€ ·ß~«mŰ6Æ cF¨)đXĽĎ «Ő*•H‚î٠˲ee%N§Ăíf‡?Éétrçv»ťN§?~G=úqą\N§ÓÁĆďďÇź±…×üAů#Řř}đsgĽ‚Íétú)ŘŔĽŽăüĽ™ů+îż’$]n7ęĺ‘TŹ~ü¸âUo zđsŰS/»$ 6żjRęp8ěv»T*Żş>Ťă8‘H€ă —Ë÷îÝłcÇÎ'Ž jMŕ1‚I’|˙µ{›SRĺr9 ‚ R8ť‚`¸{ąFz˝A©¬”Ëíjµš/Ź€$I˝^ÇqAv»}ôč1WŻfÜsˇ<‡¸—>l÷đŹü±ÜÝŔ"Ś‚`¨”JEßľý(ОZ­‡ µX,rą\­Ö6jÔČn·+Šví:;v4""śź™Ífa*&đřŔ«4–˝éĹW©’$Ĺb1EQ|v"ź€˘(‘HTÓî _Űß•’Ms4Í8 C8ťÇńv–$A°ZÉ? ®óťBřłV«µj4^,Ó4Í 9ľ<`ݱzš¦E"˙ ÉĺryÓ}Ůď·‚ řëE˲.—‹ĎĄiZ,óÇő‡©ˇUťT»."‘Ďq¨ęüá‘ô„H$âŻ/˲Ţ,ĐŞvţ˘×ťçkű»ő#p?ŕ_ŕúú( 6űř”-..ů׿ć;ťŽ6mZ;ťÎÍ›7Κő‚Ńh|睿ϝ;ŕrss_{íuÇÚíŽ-[6©T*Ał sćĚ–-[ŠŠŠ4hŔŰëĐH$I:޵kמ;wÎh4†‡‡?óĚ3­Zµ‰D§NťÚ˛eË­[·BCCÇŤשS§:´źŰí^·n]ZZšÉdŇjµ]»v;v,Ż®Ź?žśś\QQ9nܸöíŰ?,ýH’tą\űöí۵k—ĹbiÖ¬ŮرcăăăůĹ„{öěůůçź-K\\Üرcăââ|Őˡ(Ęn·ďÚµkĎž=6›­eË–cĆŚiҤ‰Űí¶Ůl;věŘ·oźÝnoŐŞŐčŃŁ7n\WˇT«6`ëV8čÖ 3f * ĚflŘ€”8ťčŮÓ¦ˇaĂşŽÍhÄúőرn7úôÁÔ©˝‰‰Řµ ~ý0u*BCëňSQuë°g8`Ę4hĺĺX»ű÷ă0h&OFPťËeKKńăŹ8t$‰§žÂsĎoó]R‚Ő«qä( ÆaâDh4÷cÂđŃGíŮłG&“}ůĺ—ť;wž Ü—Q8Ź$N§sÎśŮóćÍť={ö+ŻĽÂ×3f\Æ µZí´iSçÎťCÓô«ŻľŇ APAÁÁÁ!!ÁÂK5Ç ^ Čĺ ™LNQżŚ“‡ ‹e2Ż‘x…ĆK;Ţ.‘HůđKŐčI’FŁq×®]—/_–JĄ$Iîßż˙Ô©S.—Ëh4îر#==]&“‘$ąwďŢÔÔT‡ĂQë—Ž$IťN·m۶k×®Éĺr‚ víÚuöěY·Ű­×ë·nÝš••%—Ëěرăüůó.—«V?b1{ŕ€úňeÇ #“±—/Ë~ţYc4R4&<Üyň¤˛˛’úâ€Çi4šđđđ'NŤFţωD˘#GŽ=zÔĺri4™LvńâĹ]»vŮl¶Z÷‡ ’’’¤¤¤˛˛2ĄRét:7lŘťťÍq\iiéúőëËËË•JĄĂáHJJĘÉÉń©#˘¨¨(11Q§Ó)•J›Í¶~ýúĽĽ<Ľ]Ż×+•J«Őş~ýúüüüş‡Ęµk×fffRĄV«-ËŽ;$&&šÍfĄRi2™Ö­[wóćÍ:NÎîݻϜ9#‰ř›'OžÜ»w/ßńrýúő6›M©TętşÄÄÄ’’’‡e¤u»ÝW®\IIIaYVˇPäççoÚ´©˛˛’aË—/o۶Ť·ß¸qcË–-•••µÖ–äk«ś;wnçÎťär9˙&Â`0¸ÝîłgĎîŢ˝› ™LvíÚµ””ÁŕłFĄŰŤĂ‡±i( ŇҰv-°,Ä–- i(8}ëÖˇŽj«n7öěÁ¶m‰ “á×_±a\.0 ~ţ;wB,†L†ŁG±ięP×.věŔž=H •âŕA$'Ăí†ŰŤm۰żÇľ?¶mC‘^§[¶ŕČHĄ‹±{7víËÂĺÂĆŤ8v r9ÄběŘźĆý‰Đj4šŘŘŘÇ_ż~]x4<€6G›Í¶pá÷&“I§«ô>5++Ë—.ý˘H˝Ţđý÷ߍĆ˙ü竪ŹFÁ „ףG M•”çććRȲ,Çq$IZ­¶ňňŁŃD äe›Őj-++7™LEÇ0n‚ ˝šŤ¦é+W®;v¬˙ţ“&M˛ŮlóçĎ?xđ`ëÖ­ Ž?>xđŕgź}Öb±|ôŃGlÖ¬YDDDÍŕH$şpáÂŻżţ:věŘ1cĆŤĆ÷ß˙ŕÁ-Z´ČČČ8qâÄĉGŽi0Ţ}÷Ý6iŇ$88¸¦’DNŽ4.Îţä“ƧÍF&'$%¶icU«™÷ß/ r·jŐ w°ŚÍjµÎź?? ŕ‰'ž¨"Ĺ«WŻnܸńĚ™3ŁŁŁ­VëĆŤúé§ľ}űĘĺňš MÓÇŹ?ţü|ĐĄK—ÂÂÂ×^{íСC±±±ÇŽ»páÂÇܱcÇ‚‚‚×^{íđáĂ“&MâO{MAűË/ż\ľ|ů˙ţď˙Ú¶m›““óúëŻóŰ˙ňË/éééźţyëÖ­łłłyűĉ}i€ĚĚĚ 6Ě›7Ż˙ţ™™™K—.ŔĎ\żú꫸¸¸ŚŚŚ7ß|ó—_~yć™gj!†Y¶lŮ#&Ož¬ŃhĘĘĘVŻ^˝téŇÁ:t(//ď›oľiԨх Ţ}÷ÝcÇŽŤ=úÁOüăß>8pŔjµ.X° ((hßľ}˙űß˙şuëÖ±cÇ8ŽO>ů$00p÷îÝË—/ďÜąs˙ţýkI’,//?xđ ÇqóçĎ×h4)))‰‰‰]»vŤ‹‹;pŕI’óçĎW©TÉÉÉ›6męÔ©SŻ^˝jBcëV(•Xş*.DR‹”hµřß˙ PŕŰo±u+zőBŹµŰŤض aařî;H$řâ ěŘľ}€”DEáëŻ!áÓO±};şuCÇŽµűąv ۶ˇiS|ń~íŰŃ»7۶ˇE |ú)8ᅬmŰĐą3ZµŞÝĎĺËرť:á˙€ŰŤ·ŢBJ zô€Á€ť;Ń«Ţ}N'^))čĐM›Ö÷«+îŤ7ŢP^^.ĚĐďŁp I‚đv]«j4Ť:ťžă8^›ŤF}„‘Zŕ±B©T-Y˛´WŻŢÝşuŰ´iŁL&ĺEQ}ôńđáĂGŤ˝`ÁW………$IRuĺĘ•?üpřđá#GŽZ´hqYYE‘ŢÄH‘HtňäÉ-Z 4¦iŤF3eĘ“ÉTTTtęÔ©¶mŰ0€˘(­V;uęTťN—źź_k'.‘HtôčŃnÝşőíŰ—$É   3fUTT=z´WŻ^˝{÷&"((hćĚ™ůůůĄĄĄµ «•|ë­âqă*Ü6I;Vg6S E’°XHb;Š÷a6›ůQĹű $I޸qcäČ‘!!!6›Ť$ÉńăÇŤF_©EíŮłgâĉ­[·fY6**jŢĽyżţú«ŰíŢłgĎäÉ“[¶lÉ0LTTÔÜąsŹ=ęt:kÝ9ŢĎôéÓăăăÝnwllěś9s:ÄqÜž={fÎśçv»5j4gÎśřŠÔ‘$ąnÝşqăĆ 6LˇP8ŽŘŘŘO?ýŔľ}űfϞͧí5mÚôĹ_ÜłgO秸¸řąçž‹Ĺ|0mâĉ,Ë>|xîÜą111n·;>>~Ú´i»wďö§ËŮźüÉČČ={vHH€®]»2d˙ţý&“éÚµk/ľřbpp0€îÝ»0`˙ţýµŞk‚ ĘĘĘňóógÍšDDďŢ˝{÷î}äČ‘ŠŠŠâââ™3gRŐ·oßnÝş9rÄgK±ś”•áÍ7Á÷O=Ýşaß>äçCŻÇßţĄqăб#öîőyléépąđę«É@’xöYÄÇăčQdf‚ đŇKJAQ<ŤăČź~ŇŇ Raölʼn0}:BCqć ÎźGPfÍ‚H±3g" §Oűôsü8˘˘0u*hR)ćĚH„+Wpâš4ÁäÉ (Čdxé%¸xń~\kţ_±zA° ü5ͦ^™–vfÄá&“‰ă8Žc)Š,(Č_ľ|…JĄ\ąrůÂ…ß—–'&&ęőşÂÂÂĄK—¬\ąâűďż-++Ű»÷€Ĺb%IÂ+$ ‚‚‚ř:Mš4q8&“‰_jĹGę‚hÚ´©Őj5ŤµÎÝI’ĚËË Őjµü$¸Yłf&“ÉjµćççGDDh4~R§×ë-‹ŻiIrĄ’U«ŽCrr€BÁČĺL˝Ľśa¦]»v{÷î­¨¨P(A$''7nÜXz»ĄoÍăĘÎÎŽ‹‹‰D‰„ă8>öȲlVVV\\MÓüď¶nÝ:??ßWŠ ¬¬¬-ZPĹoߦM›7nŕí$IzýäććÖń*ęÜąs={öô^o3ëěěěV­Z!•J ‚ŕăuľN2A­ZµÚ´i“ŰíV(6›-99ą}űö Ăäćć¶nÝ€T*Ą(ŞeË–uřyĐ›Ýn/--mѢÇqb±X.—ÇĆĆ޸qĂét–••µhŃ·ŰdÇÄÄܸqŁÖ·AX,ťNÇoŻŃh"""ňóóm6›^ŻoÖ¬˙’‚ĎąÍËËó)hu:LżĹ©BBÜ\ °ZѲĄÇ†ĐPääř<¶˛2¸\‹ó|lŘ((@y9XÍšyěQQĐjQGJmq1( Mšx>6j™ ĹĹ(-…H„FŤ<öĆŤ!‘ŔwJ-  P :Úó±iS$ĘĘPXµú·Ĺxqqŕ8Üş% ÝŹ!BJ¤€€€€ŔcŠ›a˘c"#""#""8ŽĺĂk4Mź9“ćp8žzjdďŢ˝Y–-,,8qâdnnnaáM†aاO/†ał˛˛Nž®T*U*Ő®]»š5kÖ´iS‡Ăáv»y»R©ÜąsgË–-5jäp8ę(†Á˛„\Î~ţyxNŽÄí&JJDcÇVFD¸ę.1r‡8Ž^xaѢE|đ\.w:ťaÚ´ijµşVŤD„^Ż ‹Ĺ›6m0`@HH/• Żr7nÜ8xđŕĐĐĐş3´őz}PPEQIIIÆ ŃëőĽ=88$ɤ¤¤áLJ††ňv_”––6lŘĐű‡řB— Cpp0Çqëׯ5j”׿/!:gΜŋź:uJ"‘Řív—ËőňË/3 Ăűqą\ÉÉÉcĆŚ ÖétKa›Í\\\|úôé#FhµZ˝^Ď0ŚÝn.,,LKK1b„FŁŃëőľ.ş\.‡Ăś››{ĺĘ•§ź~Z­VókŘśNgpppVVÖŐ«Wź~úiĄRi0|ž»N'd2ääŕÚ5 Ą¸\Jqý:rs1h”JÔqÝ­V°,$\ą‚[·™ ·nÁnÇA,ĆĄKĐéЧ$””řôc±€$!!- N'şw‡Hłn7( "‘'ŞÖĄ hfłO?&´ZĐ4އBvířâ­0›=ö_~V‹6m<TŕńC° <¦ár9Ýn§Óéâ8pDz,I’W®\ŽďÚµ+I4M0€ă¸Â›éééŃŃQť;w±XÜ·ošéőo„ ·+b“$iłŮřü"o©C‚ ‚°Ůln·ŰŰń÷Đjµ2żO[äý[­V·Ű}']Ńz=UVF——ÓV+ˇR14]oÉω„eYťNWVVV^^n·Ű˝%ţkÝž_"Č+[ţ\ń[Ö´˙ń †$q»IµóSŐ^÷ůńő·řýáýŕşĎ‰Ĺb—ËUQQQVVVYYév»˝y}üµľC?ćׄeY>Š[őzń…ř­VkU{Ý×Ë»}5˙|ąHŢĎí“ÓéŃ-|·ŠŞv«ő.Ž­ęö|ł‹ŰŻ"îÎŹÝî©qâílČ˙ŕµ×Ťw{›íwŰ{÷ÇfC•3„›€€€€Ŕă Çăřýŕ#lĘË+‚C4ueĄŽ˘¨ĐĐ€3›M!!!*•J§Ó‰D˘ŕŕ`^Şyg™Ç) »Ýn0† Âq\yy9ß΋·ŤĆˇC‡ňv‘Häk­Çq|‘C“É4räH–eËËËůvgJĄŇb±L¦ŃŁGóv‰DBÓtjÍb!?ý´—m‰‰IIA-ZŘźxÂîvűç‘H$˙ýďCBBŢyçťŘŘX«ŐşnÝş~řˇyóć!!!5WŽq§V«őz˝ĂáxţůçÝnwyyąJĄ"B­VëtşĐĐĐ©S§şÝ2ŢîëO«ŐęĘĘJ­V;}út·Ű]ZZŞV«˝vµZ=}út—ËUZZŞ©ł :>jÚ´©WođÚC­VWTT„‡‡Ď1Ăét–——×á‡eŮ˙üç?=zô:uŞV«˝uëÖĘ•+żúę«Ĺ‹+•ĘŠŠŠ Lź>ÝápTTTh4š‡Ełń§ÁÁÁ&L°X,/ÉŰů.fłŮh4ú «âvG»ŠŠŠ¨¨¨“Éd6›ů^Ľ=66¶qăĆFŁŃb±ÔŐZF"H— ńńŹËÂbZ ±4 — -[˘eK°,¬V¨Ő>L*IÂíFűöhß ‡J%¤Rť:ĂŔéô¬—«ą, †AĎžží].(‹Á0`Yôén7 …O?J%\.°, đlĎqÉ PxěđÔ™”É„qű1D° <΂Ťă8–‚ń…ű9Žs8E*•Ęť;wť:uZ©TqśN—Ăá (JĄR¤¤l?s&MĄRňĺFĽş‚eŮ˝^ŻÓéřâyyy‰D©T†‡‡WTTčőzŢž››+•JU*U­ő0X–mذá­[·L&Ă0üŇ/ĄR)•J###KJJĚf3oĎĘĘŇh4µ–dĽ=çć(ŠłŰI›Ť”H¸©S+*+)“‰¬—¤<Š˘.^Ľ8jÔ¨ČČH—Ë%‰&Ož|óćM_©žÇ5jÔ(++‹o‘Ěw‰ I266öúőë|kiŢްaĂZ×Dń~bcc333¸\.’$322˘˘˘Tł§§§GGG×!üZ·n}âÄ ol‡ ^ýĆÄÄdddđŤČ‚ČČČŤŤ­#l‘‘1uęT>/T«ŐNž<ůŇĄK$IFGG§§§Sŧ­fff6jÔčˇlÇI$’ \»vŤ˘(>·   ::Z,]»vŤ$I>8VXX]ëšCľĺşFŁÉĘĘâl‹Ą¤¤¤aÆ2™LĄReggóvłŮĚg¨úlĽ®Ń@ˇŔŐ«žŹ()At4T*Čd¸vÍc/+CYbb|[PhŮŮžŹĄĄĐé‰Ŕ@ľ˛ŞÇ^\ Ł‘‘>ý„„€a—çůXP› !!†ÓůŰâ·ü|8 óé'" ŠŠ<ssÁq BDŚF{ě99 ßáĺ»+{}ůyĐě‚`x¸!Ŕ§Ar|>¤W¶Ń4ŲŚŮlîŢ˝{óćń|rI’4M1 c6[zőę٬Y3ëí¤)ď\ÁĺruéŇ%==ťŻXh±XÖ­[§P(""":wî|éŇĄ#GްX,?ýôS@@@TTT­sS—ËŐłgĎÓ§O˙úëŻAL¦Ő«W‡‡‡őěŮóřńă'Ožä«®ŻZµŞaƵ†łČděÂ…!{öhśNBˇ`8;wj9b1DzP*™€7IrJ%ŔPÔ¤ŞT*­VK’¤R©  I’eٰ°°}űöUVVňEGvíÚ%“É|EüÜn÷Ŕ“’’®^˝*‹KKK—,YŇ­[7Š˘xíÚ5±X\\\ĽdÉ’=zD"_eô ôăŹ?fgg‹Ĺâ›7o.Y˛¤oßľA 8pŐŞU999Ľý‡~HHHđUĂ㸠&lذaďŢ˝‡C.—ňÉ'ž|ňÉeË–ĺçç‹Ĺ⼼ĽeË– 8°Žó´mŰ6·ŰÍ÷…۱cGhh(_ůđ‡~¸yó¦X,ÎÎÎ^˝ző A| ’L°i4šćÍ›/[¶L§ÓŃ4}öěŮ={ö$$$(•ʦM›®X±BŻ×SućĚ™ôďßżÖĺ,ËGEE­ZµŠŻ˛sňäÉcÇŽőęŐ+000<<|Íš5&“‰ ţĆîÝ»·Ď5™Ť#8ß~ëÉܱ'NŕÉ' Ťß}ç‰AĄ¤ -Í­Ş•-@ÓXĽĽÂܸWŻ˘gO4kŽĂ’%{R˛łŃ»·O?:ŔlĆĘ•žÜŵkQZŠŽѶ-*+±zµgł5kPY‰:şQ÷肬[Çź/,[‡-Z kWdgcĂţ¦Ç’%ŕ8ź˝Ş nńŮgź5oŢ|ďď«e1ţüćÍ›:t¨¦ÚácřUŤAĽűî»-[¶tčĐîÝ»[ď*‡öîˇk‚ŢĹÓÖÔŠßÍV@@@ ^祬'ŇƱÇ2 ŁŃhl6»^Ż‹‰‰â8”––ÉdjµĆjµ úŘŘh€ČÉÉ®&'\.W›6mÚ¶m{üřńĚĚL†aJJJFڤP(Z·nÍw c¦¬¬lôčŃ!!!µ%\.WÇŽOź>˝˙~ľ_¶Á`xę©§4M‡Nś8Á÷Ýv»ÝfłyäČ‘µjŽRɦ¦*ÓŇ$ÉQ^N® uI$ܢEˇTaˇřűďC^¸ćö%%d2Ů7ß|c2™ĘËËżţúkĄR9oŢĽ°°°gź}öСC‹-‹ĹÇ•””Ś3ĆWVĂ0˝{÷>yňdbbâöíۇT*MHH (ŞOź>'Ožüé§ź¶nÝj·ŰĺryBBB­eây ĐŻ_żS§N­^˝Z.—ŰívµZť@DBB©S§V®\)—Ëm6›V«ĺíľ®}۶műőëwěرÔÔT>žĆ_‘ţýű§¦¦ţđĂ2™Ěfł…„„ôë×Ď×[|’$'MštęÔ)ľÂ!Ă0ĺĺĺS¦Lá8®˙ţgĎž]´h‘T*µX,‘‘‘}űö}X›R©ěׯ߲eË,X ‰ CłfÍ:wî,—Ëűöí»rĺĘ Đ4­×ëăăă;wî\«ĐbY6  oßľk×®ýňË/išÖét-[¶lßľ˝L&ëÓ§Ďúőëżřâ š¦+++[·nݡCź‚-2C†`ůrĽţ:( ĄĄčŢť:A*Ĺ!X˝Żľ ŠBI zô@—.>Ź­Q# „¤$Ľň ĹĹčÝmÚ€˘0`¶lńŘ‹ŠĐ§Úµóé'>ýűc÷nĽô……HHđźLHŔţýxé%p 1p š7÷é§MôéăÇ=ŰççcäHÄƢaCôîŤ_~AVX3U!ÖͱcÇ®^˝šSŁZć/żürőęUľŞŞWí¬Zµ*==ýěŮłß}÷ßÓ˘ŐmexŕŔôôôšŤă÷íŰ—žž^ě ŢćçźÎĚĚä‡ÍŞěŢ˝;77·¬¬¬š}çÎť7oެ)ś¶mŰV^^®ÓéŞŮ·nÝj4 C5{rr˛Íf«)¨6oŢĚÇoůîUíl6[µíSRRÔLرc€šwďŢÍżŤúS›JĄ2™ŚĺĺeŢ6 ŹĘ”ü5­÷âT·W€Ü_hšf–/-\MúľŠ")JD’$E‘|Á}·ŰٸqăÔÔ3éééť;wć8.55• 6[Ł“'Oed\íر€łgĎ1 #—ËĽóo–eGŽą~ýúÔÔT‘HôÔSOőîÝ›/‰>zôčÄÄÄ´´4±XüôÓO÷ěŮS*•ú J4hĐ`ܸqëÖ­;wîśT*1bD·nÝhš®j—Éd#GŽěŇĄ‹X,®Uř9ťäС†”íŃŁJŇhŘNť,ăÇë’äÎź—gfJ۵łććJÎťŁ&MŞ IËÖţŚ (ęěŮłyyyíŰ·ĎĚĚ4Ť3fĚp»ÝC‡5›Í‡.--•Ëĺ:t;v¬Bˇ¨u¬ć{ŻMš4iíÚµiii'NŚŹŹ'"::š·_˝z5 ŕąçžă«Ŕ×ę‡ă¸~űŚŚŚ Lš4©iÓ¦ ĂÄĆĆNš4é§ź~ĘČČž4iR“&MęčR-•JçÍ›·jŐŞÔÔT˝^őüóĎhҤÉsĎ=·nÝşŇŇҰ°°)S¦ÄĆĆú$I>óĚ3&“)55Őh4öěŮsôčŃÇ5kÖl„ ëׯ///oذáóĎ?íx Hp'‰Ú·o?tčĐääd‹Ĺ˙ěłĎ†„„8ťÎŽ;§¤¤X,–-ZLś81$$Ä^[ >µ˛K—.%%%Ű·o·ŮlmÚ´?~|PPËĺęÚµkiiéÎť;m6[»víĆŤd÷U¨C$Â!(.Ćúő°ŰѧfÎô¬ {ę)”” ) N'úőĂôéu­“H0|8nÝÂćÍp»1`ž|/Š‘#QV†äd0  ÂäÉu­“J1v,**°};8O?Ť‰Á/L}ćTVb×.p†ÇřńđŃëär<ű,ôzěÝ ’ÄčŃ=4 šĆ¤I0±o( cÇbÔ(řjRW=z\ż~˝‘·»ŔmzőęUPPóű”Ńóçϧ¤¤ÄÇÇ———oŢĽyôčŃŢJHH0Ť‘5RCź|ňI§ÓV#ŐsĐ AA„††Vł<řČ‘# 4¨fę©§~ýő×ŔŔŔjöaÆĄ¦¦TłŹ1âüůó5×”Ž92==Ý!ô2zôčëׯ+jÜŁFŤşqㆬĆő>|řÍ›7%I5űСCKKKk.<’ÚµkÇKkuÂqś÷ĽyĎO5?|IĚnÝş=P߬&MšµöčÁ˛LPPpLLăŇҢĽĽ4]?YŻüŞŹ°°đ'ž“Je÷ůÎá¤RŮůóg„űó®ŢŹ*•Ę?ANß?jć6Ô#*•jáÂĹ_|ń9˲E-^ĽäĂ?9sFttÔłĎNXłfí¸qH’ěÖ­ëŘ±ŁµZM@€ćŮg'ţřăOăĆŤ§(Ş[·.=yůňĺjnUçŁŢšţuŘëř űňĂôż?ĽBóÎ|Ş–.ŻÖŠí×jq*ďß­Şďü¸Ş9©Ăţçřń^Äš=ŮîÄŹ/'5ĎĎC8…¨}˙ďę¸xńěm ŕË.<âëń•ÖťŰëFwĺçO°?¶Tlyyą±±ŤFxÍ˙¨}sÝn׍Ů 8´Žä»‚$IAwófŐj ˝ß· ßŰG¸–wŽ\.ńĹ9•••U›D=\Ď›•+WĎoű‡Ýnďß?A,¦řjŤV«µcÇ6›Ťă¸Ö­[Ďš5ٍ¨ ŘŘFŤńŐ۶m#•J‹ŠŠ(ŠjŘ0R©”yΫMO}ĺňÝů-]sv[·˝ÍVë¶w»Ę×Ę«»ťg×ËÉ©G?ľ~ĺ/ÜźŠđz <î‚M§«hÔ¨‰V(śšG Š˘ ndgg…„„…‡GÖŁgĄRUPpĂh4VK;ą$) éw…H$Ú¸qăý®\t_YµJů ÜGśNgÇŽš5kâ-énłŮěv;A …˘{÷î|‹Ëĺr8|†›R©ěŃŁ;˙ţČjµÜ`Y†/î/ đg6Š˘† NÍ#†Édô¦Ćů¬żt÷:ĐétÄCťt÷Ăe¶Z­M›6˝ßËaëľ’pî+ĽBÓétŐn6>ç°Ör Uí ăfYNPkŞ`xT©ZżľBUó×d>ń],Žă|5̸·{_!C[@@@@@l÷ozÂÖ“Bh˙đPŔ÷2zć—ÂTXŕĎ$I€ŕ8–ăîú–Ţ‚Mŕ~Á/ťŻá'LW îw?ÇzG Ü˙·ŕŔéu• Ą‡{kdL’$Ŕ±,#“É4ŤŻ.Ďw‚Fَ(J.—k4ššýî­VKQ”BˇĐh45ĽŢŐţˇT*5Ť?R©$BĄRi4şEó˝’ÔjµZ­öç˛óˇ{ŤFăg–8N4Ťź‹·Ŕ—S$IjµZvL,+ ŢŹ?{"•Jr9ę%ź_.‡_ĎŞ7"üřzţ†DRW[¶;wrű„ #ş ŘAęk6,Ľ`xX‡A–S)Ő&“Ńhłßó"4‚ E"±Z­NK;łqc ?I.—WVVž>}š –Ëĺr“ÉtěŘ±ŠŠ ´„L&łŰíĽ~ýş?BK*•ş\®źţ9((Čźç…H$bYvű† r™ ~ř!)Šă¸­ëÖQţ-‘ĺßVnٲş“Ŕg‡čż“Ń´b…Íf»wULÓWŻ]3ŤI+VřSőJ$ťOKCi)€?-^¤Rś8‚ěßłŮ/µv‘’‹Ĺ/őxů2d2$'ăžĎłBË—ůsssłłłęcŹ*$IÖ×xđŕ0L-Żčärů˛eËl6Ű«Żľb±X!DŘk©Ő‚¤=Řú*'ĂŃ»woÁ`·ŰŻ]»&śiG ’"‹‹oµďÜ´E»{{J’Tyů-˝ľBŻŻÎçźDPP=¬üęMkŐĎ«•Ę/'žŘŁź~Ŕ'‹úéGُößφLVÇ%•B.÷×ĎíďżęUR/‹ëXí'ś‚Çr’ĎŠD˘ĚĚk›7o.//oٲßöúôéÓJĄbäČn·ť˘(±XLÓ4˲N§ÓétRť——g0H’‹Ev»ť „WË5R©tÁB§'śNŰď˘PÁw‚ ,XĐľ}{ţú~řá‡ďż˙ţť? Ţ~űíĎ>űěˇëü&đXA„Őj•JĄ üMËËK„ŰGý6·»"lő÷H®ź3ó@ůq:ëÍĎF˝\z†˙ĹŔnď SŹwŁ€ ؽƲ,EŃgÎś9yňÔ+ŻĽÜż‚X,ÎĎĎ߼9Ůh4ńYŽfłą   ˛R'“IŁŁc‚ssłóňňśN×Á‚4jÔHčĂVŹĹ"±XB’wş–ĆétrÇIĄ˛˙űś00Í›;źçIŇň›·ß~Ű›:KÄoĽqç‚íŔl=ĹúîŰ@’$ůŇ÷V,„˘(§ÓI„Đá]@@@@@lő:KářůvěhllŚ› *EŠUýú238­¶î\‹îÝ»ggg0›Ív»],·jŐ*55500@Ë–-Ďť;—žžîíwäv»k Ą¶m۶´´€Ăá𧎉‰ˇi://Źď Ó¬Ył‚‚‚¨¨(»Ýnń§˛€ŔýyąĆŢ‹ô"Bxc% đřÂqw]łô®~ĄŽŤďáO ‚Mŕášźđ-bG§NKKKOś8qđŕAŠ˘ăăăž~zhëÖ­)ŠĽtéŔ=˙üä–-[GD„ś;wvĐ ÁAAAFŁ©QŁ&FŁŢétÖc‰Ç^Heeewő+.…śSk9Ŕ´m«jôX˘¬ AŘlĘç&™R¶r ,Së4ôňĺË_~ůe@@EQ“&MÚ°aCNNŽ7 >77×ívGDDđ‡ ¶rĺJĄRYÓĎőë×/^̇ćžy晟~úI,űí·“&MňŢ……… ˙ţ÷żI’?~üúőë…ü1 oöďÝţŔÝs7™6 7oţ.ˇŔĺÂŢ˝Hpú4–/G~>BC1s&z÷ţWżţŠ+pó&""0s&zôđŘŹÇŠ(*Bd$fÍB·nҡíߏիQ^Ž&M0kÚµóŘ÷îĹš5¨¨ŔOŕ…ЦÍřٵ k×B§C|˝Ýş…µkqčHO=…‰ˇŐbőj¬Yó;?&Ţ#FŔă†0sz,_ qśËĺ 2dp·nÝÂÂÂ$qvvÎÎť»®^˝*‹ËĘĘ®\Iß˝űç ţ˝n]bZÚŮââN§Óív9ť6§ÓÁűΦź:ŤĎĽ‡3)^±Rúßoe_˙‡,,ôLY8A;.ýć[éż•ţűß„Ů\ëK8‘H4oŢĽiÓ¦M™2eÓ¦MV«U&“y'¬‰ÄűóâĹ‹išž6mZ­DH’ś3gδiÓ¦NťşiÓ&^ň=÷ÜsU%MÓjµzĆŚÓ¦M۸qٰ¶Mŕ @.WČdrŠ˘ŘŰ0 #‰d2y5;/íÄb±L&“H¤b±Xłýe¬^ ąĐjűA ´ ˘´2ôz,\ĽĽşĹ‹Š°p!ĘË!“ˇ˘ âćMţm.DEd2”—ăűďQTôgܑ׮ańbLÉPXE‹PY řß˙`6C&CA/†NWÇë\ĽĄKaµB&Cn.–,ÁçĎcůrŘlÉ•…%K`4Öĺ'- «VÁá€D‚«W±l,pRS±z5śNH$HOÇňĺuő’fś8µkárA"Á… Xµ 68ÇŹ#1n7Äbś;‡5kŕGĎî?›S§pęÂÂ~» Ńŕřqś9ó;{``]őrśNlŮ‚C‡@Ó ě܉ݻŕĐ!dd 4ôwţ…jŹ%B„íqś p .—+22bÖ¬4M[,ÖC‡­ZµF©TtîÜ… K—.{äÇ2Č«+8Î+Ő„˘#~Á0L||<Çán *)*ŕ˙>“Ôzu BöŻO<ŹÚńĎ€ kŠ&“‰/""‰|Ĺrss˙őŻůžŁáp8j#©zW0 “’’"\kЦJKKóňnPČżS I2//ݞ˛’$ɰ°0­VË{$IX­ÖŠŠ łŮL’Ŕ2Ś[čEůÍ_hÔ:¶ě܉ÔT¬]‹™‰1c°};ćÍó™B¶};ÎťCRZ·Ć•+7;v`öllߎ °aZ¶ÄĄK?;wâ…îďAą\HIAN’“‹ăÇ1köîĹ3Ď %yyHNFt4ŽÁܹػ&ÔîÇfĂÖ­(.ĆćÍŚÄŢ˝xă ôC±u+ĘʰiÂñkŢy 9ŇÇĂĆädŤHJBH¶lÁüůčß˝{#9V+ÖŻGذźŽľ}1dHí~**ś –Ĺš5ŔęŐX¸ hŰ[·‚$±j´Z,_ŽĄKŃ»7Ž›e1s&ľý¶ş}ď^ĚžŤš}ç}Ą2^ą‚íŰѱ#>ün7Ţ|[·bŔPŢ|oľy§~Á&đ(I6–ĺH’cŽe]‡“źy÷ë—pöěą‚‚B~˛ňěłß{ď]±XĚO_‚°ZÍ·(Že9xšĆ ‚íŢ1Ť?ţ¸ć^žju`Ó8ܸQ»"÷â;ůĐ›YG‚b||ÇĂŤńţűhŐ Z¶Ä`ĺJĚžŤM›đÁž4ÂV­đŢ{Xłćľ 6‡»váăŹ=iť:áŐW‘ŃŁ±w/>ţŃŃе+^z ë×űlf3ŽÁG!2zöÄĚ™HJBBŽLJ"<úôÁ´iHJň)Ř**–†ü!!Đż?23±e Ú´ÁĹ‹řŕ4hâÚ5lŮâS°áúuĽű®§ŢСČÎĆŽÇŤx÷]hµ0lrr°}űC#Ř·×o˙’¬ÝîëAy좢0u*h4Ť9sđĹ8{bqíńFA­=~)‘Źź\ăŔqśX,>tčđ—_ţ»  @,Ń´čäÉ“W®d„……;ťö¸¸8“Éś’˛M,‹Ĺ’ݻ޻wŻH$˘iÚáp¸Ý.©TĘ0BU˙z@$‰ď -&L&źĎŹ*rŞÖM E»ví˘˘˘‚÷îÝ+—Ëm6_b¤m۶‡C.—wéŇĺôéÓ|’Űw C‡^‹D"iÚ´iTTTXXŘ©S§¤·ó=‚:x <Í–3f¤¦ž6ěiŁŃČ×dâ8Öl6ÍžýâéÓ'‡ l6›x#E‘yyyË–-Ój5Ë—/ýöŰŻoÝ*Ű·ď€PMçŻܵ5ľrť:Á«˘»uCff])‘W® K—ßFÎnÝžééčŇĺ·qµkWŹýľÂ0¸~]»z>ŠĹčŘéé`Ydeýf—HĐľ=®\ńéÇéDnîoű/“ˇMddŔĺB^:wöŘĺr´j…Ś ź~l6ÜĽ‰Ž=ŐjÄÇ#3v;Š‹á}¨ŐhÖ WŻÖ%­ËË[ŚĆŤ‘•ł••u  AÄĆâúő‡iFUk˘#ËÖn÷u@ˇ@LŚçcłf I”–‚ Pkueaîőř!DŘCÁĆW‰d´ZŤŮl^´h±Űíć•X“&ŤúšL游¦]»v9qâÄ™3g8Ž“H$ tąśÍ›Ç]Ľxńůç§Ź9bäČáv»CXsď'î{kťi1Y˙5ź0@€ —żůQQá™UpśíťżsAA„Ă!ÖjkÖ].׌3ÔjµĂáčÓ§€ĺË—żřâ‹N§óąçž»xń"A©©©ß|ó _Ňét®^˝Z&“Í™3çÜąscĆŚILL”H$ ĂĚš5K,»Ýîηg3gÎdYvüřńëÖ­ŁişJ­€Ŕ÷dÜŃ1 6lŮăXď[(—Ë#“)"""X–ĺ8–ă8š¦SSO»Ý®‡÷ë×—aŘěěěS§N–”” gň/@,Ć„ ¨˝wą”„ňr„…Ŕš54 ‘‘ŕ‡G_TTxÂM«WcęTDDx¶//_{‰·GF˘ĽüĎ:ÂÂŕp`ăFLžŚ°0”—{ě!!°Ű±y3&MňŘë~‚‚`6cűv<ű,BCQQ–…ŃŔ@ŤŘ˝& 8¸.?.Ěfh4¨¨ŔˇC7  ˘ ‹j5ĘĘpô(ĆŚAPP]çŮé„ÍĄEE8s#F@«Ee%\.ŘíP(PXóç1lÔęşÖć=h(X˝&Óo ľ­VĚť‹ĐPĎÂČŞöçźÇ¨Q>­V šĆŻżBˇ@۶ Ď^˛—.ÁŰňÇbÁK/aŔaxčMESEÓMńĐ´÷'Š˘)š" ’ĎQŰă(ŮX–uąśM›>ŃŻ_ßýűÜşu‹¦éĆŤ 4 >>În·i4šľ}{ †“'O\ßľ}š7Ź·X,­ZµĘĚĽ~ŕŔA˝^O?‰Nč_€Ăáý"HŠ-Ľ@ü IDAT!J=ĹQq[­ą»t¶żý p"–ÇÖúŰ˙üç?˝A0ŽăfĚ‘śś\TT´nÝşłgĎ’$9yňäěělţú:>ő1//Ź˙/˙Ńĺr}üńÇŐśçććŽ9˛°°˙ÝQŁFył.GŽ)”x  Âĺr߉Çył|m6›D"v:]đäł$I^Ľx)**şK—Î!‹űőë›––VVV.śÉżäâ!?Uó“cŽód?ňµ:HňÂU·çö–qŞę‡ ţ¤°†÷Ż×ş˙,{wűĂ0ýCžś ţ·ŞÚďĐŹ^˙»íů˙şÝžZ&¨3ěs»,\.ĎöŐţ®Óé©}ň§ťçz$a0 7÷·V:f3ôzPôúęvőüđ1^‹ĺ·`/VV"7·W1Ŕd‚Żü‡ŠŇ’‡ÓN$E’ž˙đPżűHÓ˘ň[·ÁöXĘ5Ç1 #•Jűőë;`Ŕ“üšeY—Ëĺp8ř zPPĐ‹/Îś;w6·Űírąěv{hhčkŻ˝ňć›s:ť&“‰$I€R©˙ši&?ôk4ާžö„×8"‘yCÄbBWđůBDm÷§Óéřć{đ´“â¶oßÎLJJđăŹ?ÖüĹÝ»wGFF¦ĄĄyýX,…BQu›VýśśěýyëÖ­ÂĄx ‡Dľ@?ŞĺyóýŮxÇŰËĘĘ5ŠU©Ô:ťN$7 IÂöµ{´Ţ[á×_kYĚ€˛2ŕő× ¨Čłnʸu ±±řŰß ¤Äł=oŹŠňŘKKQ%Eü>ŞP>ś„W_ÇáÖ-‚ <ˇ§€Ľň 8eeuíEAĄ‚ŃŤóćeQ^ŽŔ@$”JLŔś9ůW‡š†\«!!5 , ťZ-( r9l6„‡cút°, †şÎłH©bb0eŠ'ЧŐB$‚D§ŤŁqc°¬'Öô°`6cút|÷]uűoŕű`OaV Ą.Xzd0ÇA.‡Á€ż˙oż}§~.^8_mń÷Ű˙ýörą\|ŃA°=–ó“۰,[5%ŻZq?–egŐ⍇ŁJąHá|ţŐS!'**@ڇţa×l^W»rw^ćîj•U Âĺx4ľC|Á[~H¬Úy‚×iŢâ8ÎápPĄR)cbbşwďÂá/ĂbAÍ‘qq¸pÁÓ+ @Zš4©kv۬Îťű­÷×ŮłhÚÔc?{QQŐí÷ŠBŁF8wΓóƲ¸tÉł˘)6çΡĎ„ţňĺߎ±VÔ°!ÎźGź>ü¤hÚ4Ť† qáző§WŻÖu\R)ÂÂpń˘§ťÍ†ë×ńÄ‹‚K—<Ëä,dg×Ő‡M©D` ®\ń,{3‘—‡FŤ “AŁAzşgy›Á€ÂBO¶‡oŇcUH˛v»Żű0"YY(*BÆ› ŽCp0XÇ]řůýČVë“]°? 1aŇľf•g˙Ô|É~.íĚůłiŠŽ<–ł“ęł/Üď©őźŞ~ĽÝ7Vŕ/ýĆŚü+ˢďľ ŮqčС   {űŞ*«ü<(­Ł±Ś€Ŕ˙řÂą|ęA XţyĎz,ËŇ4ŲŚŮléŃŁGłfMů>Šĺó¬&cÇbÁOŚ‚|ú)FެŁd.ĆŚÁ_ ;Ű3Qţě3ŚŁGăóĎ‘› YYřüsŚ{ߏH,ĆŕÁřä”–ţ?{çEŃ˙ń™ŮÝkąËĄA€ŇB ©Ň!€4A°‹(6Dźźřřř<ЍŠbA%)*˝7H/i$„~ýöövg~Lr„"ć$:ď—âݸĚîÎíÎĚgľßů~ŕÄ đÉ'`Ü8ŔqŕŢ{ÁěŮ ¨Ž ‚ńăoZŹŹčŐ Ľýv…˙ä‘#૯Ŕر@Ł=z€9s*ü!Ë—×v_ cGđî»ţŠ{÷‚5kŔČ‘Ŕhńńŕ˝÷€Í»wÔÔ›†š4o˘˘ŔűďúĘlŰ~ů  š6aa`ŢĽŠŠżţ ¶mÆýížä=@^XµŞâ©ţňKŕrÄDP·]wß}7>>~Ë–-ŐĘgĎžżsçÎjĺoĽńFBBÂľ}űŞ•żöÚkíŰ·?tčPµňW^yĄ}űöGŹ­V>sćĚ:ś8q˘ZůsĎ=—xćúŕ=§ź~şcÇŽ.\¨V>uęÔNť:eÓw°JůŁŹ>ÚąsçÜÜÜjĺ>ř`—.]Şĺ"‚>đŔ]»v-˘ďN&L””TZcďĺرc»wďn®áÂ:zôčž={ŇÁUIIIINN®«…FŁq:6›Ől6———•–”ä_ÎĎËÍ»”s);Ëd›YŘţ–C\ĺDÄűŮ[ZľË˘řňK°¬ H’4q"€đš§űÍţ>}úÔËcÔŻ±D^f0ţ CÄžŽ±jßHצ<ˇ#1VüüڇĂl6ED„ł˛2 !ŤZ]¬%ď4Ôm¬&ŁFmŰŔűďŘlŔߌY›`5 lßŢ}čőŔfM›VŹQŁŔŽ`Îś ÂfÍŔČ‘·ý¦ŚUy_§&ŚÇžŁGÁ믝”—¨¨Ú„ŤNFŤżýfÍZ-(+mÚ€A€Z FŽGŹ‚W_ (+±±`Đ ›Öc4‚”0gřç?Z JJ@|<čßčő`Ä0w.xĺ RâbĐľ}m±ř›4ÇůóÁË/• ‚Nť@r2ĐëÁС`ÁđŇK€çAa!čŇĄÂú×H†ŕ‡ÝĹ[ĆnF‡ŕž{Ŕľ} /` rr@J  ËŤÓÜ{öě9}útffć@ęiYÉÎť;Oź>ťťťÝ·oߪĺŰ·o?uęÔĄK—’““«–oٲĺäÉ“—/_NňÄ)đË/żś8|4ofĚmŰÖVOTxţy0>Čͭر11ŕąçŔÇĽ<ĐŞ9DFŢö›B$&‚§ž €˘"Đş59ł"e§N`ęT°p!()mŰ‚™3Aĺ>äŔq [7đŘc`Ń"PVâăÁĚ™ IčŢ<ü0X˛”—öíÁŚąÔnĎ{î“'/ż čŘ<÷\Ĺ^µŢ˝An.XşX­ sgđěł°‡­—–/v;čŢ<őđő€@~>řćŕp€äd0mZEyŁ uk|ň¶mŻĹuĽt:đŔŔl?˙ cĆT=ăăŻ9ĺţyzôčqîÜąpŹ»o%ÉÉÉ999­hNżë^©^ˇÔ-ł }úô)//oA¦Vˇ_ż~N§łYŤçpŔ€ăję0pŕŔť;wŐxŢĽoßľ€{)‡ vřđaż{GŚqüřqßĎIJJĘéÓ§ő5ܤGŤuáÂ…jűí#GŽĚÉÉ©©˛†~ůňĺšŮ‰\TT¤R©jŢoYYĎóuzăB¨"ž6!„Täő¬â$Y9éÚľiýTb+?~Ęš5ßĆÇwŤM`cÁ_ڬ¬‹{öloßľSllüĺË9ŐO¦WBHvv¦ŻŻ_llĽ,»oë-‚päČÁV­Â[¶ łŮ¬L0ü!ˇU«đ‚‚‚+W®4§C~ăYT ˝XYY Ćý”Ś.Řmv‹Ĺ Ľ™C•‘Qe '‚©Ľ<ë«ÉlP ‹ŹćŻ:] 7ˇµú­É|‚].ÇK/˝Ň˘E‹™3_pą$:`ʲ¬Óéž{î…gžyZ’$ŤF“‘‘ůî»˙‹ŚŚxčˇ)˘čz˙ýôzíéÓgÓÓŹ±_äN`2ë׼ë(Š$ đŢ-X+Š·5xđő­-~ŕ-’—ââ*˝áÄ 0d¸Ţ©¬.ěئOŻ-ĂŰ-˛aHIiXáK/Ý šČźeútŕë Ţ}·öđöŞ=őX´°xńâ©·;Ą;Ł®Ľů曳fÍŞ)ç–,üěńiO^oaS®űŚ„¸ô#‡gýć`{ŘţnS!Äř†»5ęKŢČ`0÷˘Ć‚ Ű´‰[·.mѢĹmÚÄ­YóV«Őëő}4żm۸Ť7}úégmŰĆ­[—Ćó|xxؤI÷_Ľ1v섇zDŁŃ xŻŻŻµ$Á¨÷kż jµZďs5íxŐź˘ČÖ8Ć_ „8EQ,SYY ¨Wí=¤2%€ÂZÁ`4:DQěŰ·BĐ`ĐBěvGÇŽEQ„öďßżE‹M_Ńľ}{Q ‰‰Ôjő•+WâZµ 5t¬ QWa—-_~řĐaŽă¨1D’¤íŰß7zTm‚-0°iqq‘ ¨X zĄcŞäíij ™Í¦-B%ÉuţüQ=>g„˝ŢŔ˘Ź4djşn7üţ‹ýjŚ;€$I]ştiÓ&†>rB§Ó)Š" [·®˝zÝC{6ˇĂápą\B˝^ß«W2Ďó@‡Ă‘——­(Ěk—Á`0uD­RíŢł§¸¸!„1čÜąSµcŞ ¶V­ÂŇÓggg˛ćóŽCjµˇ†âqŠ1 jŇ®]BaáŐüüÜz4˘*ŠŇ´ił  ¦ĚČÖ9qâDppp#ŐL˙3îŘŇ€Óé,//ŻŮ];ŽšQű !˛,Űlre(cLŘňÁ`0ę<á™4iŇ…‹×üđä’xž™’2~ějÁ‡kşD*<ĎBGzŰôz˝ľ]»öţţ '^]?6|Ł˘bnGÍl†Ý©—8ţ Ć_·Ď®Kŕ\ff0 †÷˘řܳϞúhßÖ­ßlŢěM=>Ă˙fÍşzůňüoľń¦} Fă+O<ˇ7^ź7ĎV×ëń5_zě±5K— ôôÓO×2weÜ-xžź3gN-’ˇ&7­ęĆŘßŇFÄóüůóćÍű૯–:ť7°, ‚pňäÉ… ?_Ľxń ¨l=Sl ŃpA*(¸رKtl‡şÍąâJJŠ,–˛˛˛2_Ł1ăěľľuľA0řú6§ xSÇóF?ż&ŤË‹M2~ „ü‚t:Ů‹v6  Ôë˝Y Ö lÚÔčť’Nz˝ÜĦĐëńńńĆ3Vî> R©ś^XDbPD¨ B/¶ůńř"„š xQŹ Łż?ÇqMཨG €Áhäˇ Ľ/—zAĄV{YŹťŹŹZ«ő˛}Śht:­ŹOŐu­ÇŹ3¶Z­hĽßǸ@ł2.şÝnşlH*éW!"śGÂý`ÓéŞćŰŢčúkßL¦ňm۶×"YKKKwîÜY»¦e.‘ ŃđK»ĂćăăؤΕ‚Pn*±Ů¬nYĆt_W0˘Ëĺ–eĹ»zDQt+Š÷ő8EQöş €Óé”ĹűöqK’¬`Ĺ;{(Ťk¬x˝ŞŞńň¦ ƲŰíe#dŚťN§âőőČŠâEďt·˘˘Ëű‡Đ-ˢ˅˝®G’eŃĺňţľ$ÉíŞ—z\’$IŢÔđř@˛¸G BČ íů˛,KOGŞ‘«çNÔB+^»ŘA ôŢUʆahPő‰÷ő !xY R1Ć„üäÇq/ś?|đ€‚14¶ŚDăń¨šŹ€ŞéOťřýřŃô?ŰK×¶‡Ťş]¶iÓZ–©ú‚“&M†pZż~ý/żüęrąúôé=iŇ$E‘].׳Ď>÷Ŕ“VŻ^c±ŁŁŁźxâ‰Ě̬5kÖÍćřřřiÓ¦jµZ€˘ŕŻżţzĎž˝jµzđŕA)))yyą~8îÜ÷BŠ”ĚťűţěŮor·fÍšm۶ ¸wܸ±.—TeX‚ĹĹE/Ľ0gĚűVŻ^ăt:¦L™|ňäéµk׊˘ŘĄK—G}XTB‡ĂţŐW_lĐ N§“ă8›Í¶hŃâLJ††DGG ‚ĚĚĚüúëe˙űß»v»çą‹/~űí·|đ~e<1ĚqČfłŻX±rďŢ˝Z­vÄaˇ!z`c0چ!DŁŃŞTjAPÝlO„@«Őń<Đë jŤĆ]ÝĽO*lY^O—0Á «\_ő(ő‡‹Ős§ęÁőQÁ„x_ŤĂĐ ęőRO}Ľ¤„\łŁ˙e\Ž4Z-ÇqÁ[Ď`Ö@ ć2˙€‡ăšý ŇgV]Z­®Ëj|-ORĺź!ŹE!„`¬ś>}ö§ź6ĐŢaëÖ­­[Ç$&&şÝîoľů& Ŕßí–€ééé<Ď;ťN·[‚¤§§˙ňK«1cĆH’”ž~tóćÍ:ťÎá°Ż[—áăăłoßŢsçεnCq»ĺß?~ôčQBȱcÇ7oţ™ă,Ë[¶l‰‰‰n×®]Ű"głŮ–.]ęçgÄXQ|ŕŔYv[­6B°,ˇ o5lŘ0»Ýľ˙m۶éő†ňň˛´´´°°VN§óŔý;vl7 ĹĹ%YYŮÔšW\\ĽvíÚ?ü€ !_XXšşîćy^‡ĂqčС;v‚`6›~ýuKXXxTT$m%6b0ŚF Ů0˘Xuş"Tşfp˛ě¦S=ڱÝn3•—3lFĂB’e™çůý醱Vb4dÍC“‘ „8Žk\ÁT‡ „˛,›M&Ď•«T*·[şŢŔ1®S\â›­ŻxBK?~üřńă\ľ|Ĺ=÷$»ÝňŹ?ţČqÜ{ď˝űÉ'·hŃbĺĘUÔĐ`0˘8gÎŰK–,2dČ'ź|ćrąćĚyűóĎ?ďÓ§÷ŇĄ_#„\.×ęŐ«‚çĎ˙čÍ7˙ërąÖ¬ůˇI“&C† IK[ʇ1Eq۶í'Ţ/ËrjjŞŻŻď‡~řţűs Ăwß}O˝)c ŹŹÇq|đţÂ… şvíúé§ 4ÍĽ˙ŮgźÄÇÇ/_ţŤJĄ2™L©©©‘‘ |ňĘ+Ż”””¦Ą­W©Teeeiië۶młxńç/Ľđ\II „‚ňőő­Ô¨ă*‚‘xÄXQQŃĆŤ›"##.üěŤ7ţírą~úi˝ ´éŘ[Ç`0ŤEµ‚=Pýć’DZJČő]zŐŔË FC (ŠŐjĺyŢjµđ<_ůąâOAP±Vb4üÇ®”QÍÖ@śgDńÜKQQ5¤ÖĽÇúlžáKQ” úČÁé•đ<˙ňË/iµZE‘‡ ĆóÜ‹/ľ¨Ńh0V†’••  ¶gžy†ă8ŁŃřÄŹďÜąK­Vpď¦M›éťŘl¶˝{÷Ą¤Ś°X,‡yá…gyžÓh4“&Mpŕ€#G~«4q˛ÄŮ Ń8Ŕ(ŠRU°ed^Ľ’ź*·†_󤂌«Ě`4(ǡýűýîŰçďpp˙>?˙€Cű÷ůůůÜ·/¸YsY–Y+1, ®ŘŐ‡ 7ÓČţń˝<ŁÉâ%KśNgŐ!F©«Ů°– #ÂqÜÚµ?ʲśźůÓO怂` IDATćć>đŔ*N0VňóŻ0Ć   ‘Ęą  @ŠCŁŃ˘HQĄ¤¤$44”´ ),,„¶jćëë{äČoqqíŽ;tĺĘ•sçÎŤ7BE—$ą¸¶m”n!ĺ8. Ŕn·#„4 B(00Ŕfłq§V«EŃI‚Lć·Ű-Bpppaa!fł9$$D’$•JŇ‚¶jE»ŠVR©c1Ć„Ę6E‘8’2ŠúĆ”——‡‡‡Óë!„°Ä٠р´ź§=ą YŮY‡Źę”Ř™ă8:~U]%„(3Ż2FC]}Ŕ+°bÄJ•ĎX,aŁÁwÇÔ2Ň]"=y<{Ł8ŽŰ¸q“"+˙řÇËU‡’ş™ŘntBj)‚={v—eŮd2™L¦/ľřňćj4š1cFS÷?žç©HŁ×!UnŕúŻĐăĂH^’$µZEcw ‚@Ńëu={öذaC||Ü–-[† Ju‘Á`7nµŞńĽŇÂétVUP•'‚•#.†Ňó"Ŕ•öGÂóś$ą D„`·[nQŕyÎĺrŃh6Z-BŃE¨ Ąf·J军6mz˙ýăé`/BëÖ­ív[˝Äćb0 Ć™ Đ…9BČq\n^îńߏŇ˝@t8€xRL0Vëä đY†`Ś"4!!Đó+ěée4čg~@!„×naOŚ~Ri^#W^^ľió怀€§L®Ptu˝©›ˇ[® !‹cEĄRĄ¤ŚřüóĹyyy ń={öčŰ·ŹFٵZ­.\ÄX¦â‡züoö!¶sç®A˘¸oßľÖ­cEć8®WŻ{Ţ|söĄK—222gÍú?I’8µoźĐ§OŻž={ŞTŞňňňěěYvWD×€ŠX™+„`B µ¦^˙˘¨TަM›îŮł·oß>ĺĺ¦ôôôh·Ű­V«›4 ÚżďŢ˝ĘĘĘ<Čó}*D]ťdB-Q"ˇ'ňĆcYŁŃ$%uŰľ}űС?ýtĎóM›6ÍÎÎůá‡?úhuôD+ąŮWŽăzöěąjŐĘđđ0‹ĹĽ~ý†#†ąÝnaTT!dÝş´°°VAAAN§S­V÷ęuĎüůź@ýüüĎť;·uë¶÷ßO]žFńl÷lŻüFh!XQ°ŹŹOűöíW­ú.44äŇĄK;wî7n¬Ëĺ2ôqqqß}÷}óćÍ/]şôóĎżňĽ (ŘÇGśšşnřđˇ§NťŮ¸q“ đžšeY jÝ:ć“O>›>ý)­V{čĐ‘ĚĚĚ×_Íáp0ÁĆ`0ŤG°ŚŽăňŻ\)¸’OÝ+*G.\ď‰1aS^FĺŁĎ)ő‘đŤÁ¸ÝP [Ł»ćj‚ŤúF ‚`2›SS×%'' <_çúo¶‡ŤP›žËĺňśŇŻ_ż%K–|űíň˘˘’ţsVQQQxxř“O>!Ë2őoôlŔ¸ÚWLżň7qâdAź’2|čĐÁN§Ó××wĚ1ď˝÷ż±cLJ„„$%uŰ˝{Ź,ËM›67něG}üé§źĹƶéŢ˝ŰÎť»éžŻ:ݵŻ<Ď'$$Đ­h’$yÂń<źHź EQÚ¶mcµZ!„~~~}úô¦÷(ËrëÖ1V«Íh4&'÷¤ „bbbÚµ‹*ŠârąhčK&Ř ă€ây"ČńÇń<Ç_K‰Ăó<Çq˙CÝ8e0Ä( †@´ZmTd”ÉdŇiuŠ‚Ą"`rŐAł)/ŁaęµĘ(‘‡ŚÇaEá8NÁ!ŽN«°˘°´ďŚFŃ·#Ä5®ë×…őWˇ"Ë1ŃŃăÇŹëÚąłR©âęY°y*5™LUË=:GEQ«ý­j×řjö|¦&Żš8ť˘Ó)Ö(t:ťÎ›ÝĆŘl6{Df-_1ĆUĹ^Ől6[MÉęąŮĘË·Ű]1’Gő“ 6Á¸ÓSEŃYZR ŕ8Ž&YĄŽ4•*JA°ŮlÔѱf=•Q"+ň †¶mcýüüdŮă~ťK$ł°1ěĐëő6«Í 7Řm6˝Á`łY z=ýLYłFC^tDÇ5®Ĺ…Ę ×˘DĘ„¤Ś>|Ř0O,ýúlLrÔ¶‡ŤÁ`0îĚčXpĺʱôtŤFS{ŻK‘Ąi`PP@`Í ]Îóěo—$—żźQ­DŃY0™T &Ě©ŚŃ_ŠČ¨č¬Ś‹Ń11YŁŁc˛32˘˘c˛33˘ŁcÎź9S{$Iăî?Ă‘Ćtzö°aŚG¦¤¸jŘ·ęŮ˙,lŚ?˝<!Í_Çš‚Á`0n+n·»]|Bň=˝¨ăUŐţĂq\AÁ•ĂŢp\Ł~’4ÎVŐręvAŔ4Ů'€„€@Á `<ŁAOBhV¦ü Řz2ŁËÂŃÎUFÉo4R“ăčź`Ą2^+®Ě}ý‘u‰YKâlöŘÔfac0Ś;Öăęt:•Zí’*‚Wćy©L÷‚1@‘eµZ-Őô`GČd*#Ľ cĄ†ś#á‡D!„ŠŠ jµ†-É1 Ćí€Ďó*AP•fă9B“ťÍqĽg?ŰŤEiťŚ‡ŐĆŘb1S?Fť€zňW˛AťÁ`0ncK0–$ÉT^NŁFa…"ËrĹgY‘A` / ů%fKíç@łŰmÂśě,ł©ĽÂÜĆ`0Śú!NE›ŐŞR«IcKś­(ĘďÇŽŞTÂŽ\׼Bę,Ř4mFĆ9{hĽQl˛,k4ZŞÜXÔcòćd0U!Đ˝† ˇ…„p€tÍ „PM…EŃju“©üŹçčtĄ%%ŤĄ['€»·ňz·é–îRµ~W.Ź9%2€^Ż·ŮlŤÎa !äççgµoĺ`Łźź·‚-:şő™3'ŮĽŘ0Ć>>ú¸¸¶7ťÁ`0&Š,‡…Eôéťh˙ôJgŁ"ďî\ç® ¶[»ë~y ĆßśF*C rűîńš`“$iÓ¦TQ«&FcÔ­OVůřńôÚ}XuxÍćňV­"XS0Śjp§Ńh Š,ËŠ˘(Š[’‡ěşńÂY…iŽăş%Żę1áť™ĘËËx3EQ""˘š7áîř&ˇĹb>wî´ä–î°!‹ܶm\@@Pí3!“©ěěŮÓw^;!„bcăŚĆćRË`üŃ»L!Ťl_ŞżýłńŻ ¶îÝ{a¬Đ¬5ěYńrŔ€(ŠÂÖŇnÍ›‡°(¦ Ł*‚ ś={ö—_~---ĺyžě’$?ٱ×=÷DD„ß°'¦ŃĆ„ÜRBŕyţjAľĂa×jµ Ľáňĺ\ŁŃOŻ7Üá‘ă¸ěě „8µJ}çÁĚĚ‹FŁ-ÓafćEµZ}W\`23/vęÔŤ a Ć-J ĆĹm}µŻ ¶°°đ˛˛Röx0¸v»ÝćµË`0ŞÎÂ%I:|äđ¶mŰ=%˝{÷îž”„ TęI6@M&“ ‘‘1Ç7äŮĎ ěvą\ďVM˘ââ˘ččÖMîpG !ÚµkëŢoQQabbgÁx‡‡EQöďßÍŢVá•`;}ú÷ŚŚ‹lĚhȸÝîŕŕf11±>>ú[\g0y$IęÜ©ÓăŹ?VRRš™™ !ŚxpňÚ··Z­Ď×׉Bn·ŰĎĎß`06đ6ŃjuwéĚ„ă8·[nÖě.8dňĽp ÇđŠ"‡„´ĽĂ׆1fL Ă[Á–™yqäȱ̉ŹŃ`á8îęŐüăÇÓËËK  éÂ`0<8E1ągňر™ź|ň pÔČ”¤¤$QoÇ.ćîţ‡@ÁÜůŤÜ·řÓP—Ř;˝ĹŽ= Ă[Á&˲ ¨X‹02*•ЦÇe9î FU0ĆÇ <(3#c2pŔŽăä?źë†ń7p‡]ŠĚg0ő Ř¨ŻąŰ-±Fa4L8Ž“e˛tl ăFȲÜ,¸ŮŘ1cEiÖ¬™(Ь§`0 Ć_J°QXđ˘:C“·rGqłeÝŰÓÂ,2Á¸Y˙@q+J‡Eq8̢Á`0Śż¦`c®ůu†"˲,Ë!ľţö¸3ެ&°Ç“Á`Ô&Ú’$ý™íĚ÷—|   6Ć F(IŇćÍ›_{í_:třńLJýÎ8ď©T*ŽăďŘéî˘(f6Q„‡Bc€ $Uúdáč1BxµÚWĄˇź˘(’$ɲě©AABÔoÂűá‘§$ąYůź­ç˙®^ŻE±vYK1 ‡ăÎűÝxsw˝(ŠžÉŚV«u:ťž˙«×ëŮ[Ă`0`«7ýŁŃh ôŔ%.—ëöĄąäy^ĄR{ľJ’Ëív˙©ă¸üüü]»vMś8199ůرŁË–-˙裏űíĚÔj5Ď v» B¨V«7mÚ|üř±×_˙÷í8]ĂcĚÖ FUµf*/żr%ßápJ!BqGĎ󡚒:ť.ő‡–­üžvŞQQQ÷Ý7:66–:JB¶oßńË/ż^˝Z`0ú÷ď?`Ŕ€†e?ţü·ß~›‘‘‘””4eĘ”   Z†¶Ó§Oűí·—.]ęŃŁÇ”)Süýý©>9yňäŠ+rss“““§L™b4ĄĄĄëׯ߻wŻŰín×®Ý>BëyóÍ7ÓÓÓ5Í[o˝Őşuë?Łg|fÍzmň䢢˘jU}|t/żüĘÔ©O´jŐ˛^ßť;w®^˝Úfł :tâĉµŚ°ÂÇ{Ěb±řřř,\¸P§«ČOŕv»żúę«Ă‡˲˙ä“OŇVŞ6šĎńâ[o˝Iý\8Ž[˛ä‹É“ §ă8îůçgôéÓ˝ćI7lŘšš =ztJJJí÷’––¶nÝ:ŽăĆŚ3lŘ0Oyjjęúőëyž;vě!CŘĘ`0n—`k{Ř „Š˘ěŮł7;;Űét¨TŞV­ZĹĹĹůúÖPÁ˘¤¤äđáĂ……E€ÄĶ)ŠŠŠ˛łłßzë­ŔŔ ýű÷!„ ·Ł=yž?{öěĺË—ď˝÷^I’č)čţ®żúÄę{ŘB˘[4»±P% …ef`Üč=˝Ĺ\U‚ p—źYQĎĐ!¸fUôD™M媺T*Őľ}ű˙ýD÷îI“S§Nk4ZŁŃŻE‹ć„]»voŢĽą¤¤ Š®ýűDGGó<ďrąŞVb·ŰÓŇŇNť:ĄR©věŘѲeË””•ęĆ!—m6[jjęůóçAŘşukxxř!CA°Z­k×®˝pá‚ żţúkDDÄ Axžßľ}űˇC‡‡FŁ9ţüúőë'LHµ‡^Ż˙ţűď§NťZ‹`CцȲ[’Üjµ65u]JJŠŻŻŻŮlĆS["ÇqBŚ1ő)U«u?üđĂ”)“ ĹbQĹÇÇGE:ĘB<_B*•Šţj7łC­ZµŞĽĽB¸fÍšvíÚ%$$ÔňCó<ŻŐj—/_ţá‡zۆ vďŢŤ‚:t(((čÁ¬¶!´uë¶'žx<22’ŢβeËĆŽŁŐj!„yyy[¶léÝ;©Úé.]ş´rĺJEQ „+W®LHHżŮµeff®\ą’>«ôŕ–-[B222V­ZEš+V$$$PuÍ`0ő/Ř‚…M–ĺłgĎ~űí·ż˙ţ»ŮlŇju:t5jä!C¨ł íŻŻ­§€ަU<%ž ‚ž«ÝŻÍf۲eËŞU«rr.Aăăă$iŇđáĂél˛ćą‡0&t°©Ś2$Ir:ťAv»­K—.={ö4›ÍôO%žy*-ˇĂç"=儺ľë)ń\ĆDĄRíÝ»75uÝСĂÜn·Óé|řá‡=zôŰoż˝eË–:„„„˘čëëK•’$I‹%((h˙ţýéééÓ¦M2dČ믿ţË/żÄÇÇGDDěŮłçرcĎ>űě€^}őŐźţ9>>ľU«VÝşu?~ĽÁ`رcÇś9s:věHyíµ×ůůůµw}n·»  Ŕn·CŤFŁźź_nnŽZ­ĘÍ˝těŘńćÍ›i4ŚńŐ«…6› cEŁŃ©Őęśś,­V›ťťÍó\HHFŁąpábppSA¨\ĽpáBpp°JĄ’$©  ŔétBüýýüýýk^Ɇ rss,XúĐC­_żľuëÖ‡CĄR zŚĂá°ŮlAAAÂĹ‹¶nÝZµ’?üpÔ¨QĎ?˙Ľ K—.ýôÓOďż˙ţj‚ cÜŻ_źýű„‡‡ó<_ZZzńbFqqq«V­ „»víęÝ»WÍĹ»µk×Z,–ożý!4yňäuëÖÍ1ُ¸X§ÓůřřxĶÓé JMMu:ť+V¬eyĘ”)iiiĎ>ű,!$55Őĺr­\ąŇét>ôĐCiiiÓ§Og/5Á¸-‚í®›h „V«őí·ç´iÓzéŇŻKKKwěŘąbĹĘáÇK’D×Ě<Ś~ö¨&O%žĎ^µc@Ą)ďđáĂ˙űßÜ™3_ěŰ·ŻJĄÚ˝{÷®]»GŽé9ž W†Ľ SOmôĆX–QtŃI’č*,˝<ĎEV˝ʦň6ZNĄ=]ŐĎ5`Śy^ ‹Ž´DĹš§«zÍU«˝aS4"ŐVu öôéyy—蔨vBv‹Ý%˛¬ F°Đ»o?ÖŚë$žĎ˝téě™Ó··I–ĺřöíÇLp+«6Ç]ÎąTwđŞjŹ˘(О,‰˘’2b÷îÝ—/_őöí;´ZÍ”)Sbcc].IŁŃL›6UĄR?ž^­ćĆÇÇ'''&LđÎ;ď=z4++kĘ”)ˇˇˇ€ăÇŹ˙đĂS§N=|řp×®]»ví ňČŁąąyĎ??Ăl6ďÚµłsçN……W.\¸iÓćňňň„„ř7ßüo·nÝ RXX8mÚS‹ĺŕÁý]»v›0áţŻż^Ú®][YVôzý¸qăW®\{öěŮwß}ď·ß~Óh´O<ńřăŹ?VSýüóĎ?üp‹-AxîąçŢ~űmŚńüůóĂÂÂ|đAjܲeËöíŰçĚ™ăŃHŐ/]ş4iŇ$ާL™ňď˙»ć@†10`ŕš5?Lśx?„đěŮłˇ3gΆ†¶ä8¸uë¶±cÇVŮęXÁŻżţú /ŤFásĎ=÷ŃGÍ1ăťwŢéÖ­Űĉé1ëׯOOO˙ý÷·lŮňňË/ BČ3Ď<ł`Á‚gź}cĽm۶W^yĹÇÇG«ŐNź>}ѢEL°1ŚŰ%Řąë‚ I’ëĚ™3ź~úq`` BH­V >´gĎî˘(‚óň.Ďź˙ÉÉ“'U*Ő!ź}ö™‹/Ěž=çŰo—˲L@fggý÷żo-]úĄ$IË–-ß°a#ĎócÇŽy䑇].É3é‡+--ݲeËčŃŁFŚN]&úôéťŘÁáp ËĘĘ,X¸gĎŢ   tß}÷ɲűĉłgĎ;vĚ—_~E8pŕ /<—ž~ňŃGĹ'&&R˙śľ}űĚź˙‘Ó)^ą’˙ńÇź:t¸]»Ř¶mŰćä\Z´hŃćÍ›~řáÇ%KY,µZ˝mŰöőë×/^ĽdăĆ K—.MNNţúëe˝zÝóńÇówěرdÉ™™Y“&M|đÁÓŇÖżúę«‚ ´iÓfÄá|0oŐŞ•GŽ™;÷.—ëâĹ‹źľřرcŹ=öHďŢ˝«WŻŮ±cG»víVŻ^ŁŐj'L˙ýT*Uă’m„Ŕjă·Ë劍ŤŻm'ǡ‚‹ĎuďqOxD$óÄ»Űr ś=uęĚéS2–!‹ŃǸnş D—3"2Ş{ň=µäĽF*-.ţíđaEQxžż•~ŚŁŰŘnÚ·ˇN§ă8Dý8.^Ľčď]ą¦A@čkCůůůŃŃŃMš4DFFş\®«WŻŽ;vÖ¬Yk×®ť>}zYYŮňĺË»wď“••Ő˝{węÓm·ŰÍf3 77·uëÖ´ÜjµZ­ÖŞ Ž€cÇŽiµZ__ß[oN­Vł`ÁÂĐĐ–‹!üé§Ťůů—,řlÔ¨űfĚxˇmŰ6‘‘*•0{öśččč>x_ĄRS×ýđĂŹÍš5űâ‹%#GŽú׿^  %Ó!Řc˘EĆD­VĎ›÷aÇŽ‰O?ý´,Ëëׯw:ť5[FFFLLŚZ­ÄĹĹĺĺĺ9ŽéÓ§?˙ü󡡡>yňä˛eË^ýőZ ‰7nś:u* ---66¶ćj!¤gĎ˙ýď›6›MŁQź={®]»ŘóçĎ4Đjµť>}fîÜ˙=z¨ćĺĹĹĹŃËŽ‹‹ËĚĚLź>ýĺ—_ďŢ˝űţýűWŻ^=oŢ[вeHhhĂá8uęÔ¶mŰcb˘KJŠŹ=–ŘAQ§Süí·tYv+ŠĽsç®C‡őîÝËétîßż?&&:))É b±Ďś93{ölŁŃ(Š"Ŕh4H’d·;~ůĺ—sçÎ pŻÉdÚ¸qcXXX§N-ë¶mŰbbbú÷ďołŮ.\8˙ÓOz÷îŐŻ_ß#GŽL0^–ĺ3gÎ9ňÇ eeW~ţů—üüü!C‹˘–¶žŽXĄĄĄ'Ož¤V/ş‰îÔ©S€˛˛˛_Ý:bÄđ„„„cÇŽ­]›Ú®]»ŘŘآ˘˘ĆÄÄDGG%%%]ľ|yĚűbbbWŻ^={öÇ 97n*++}:tčPK·0sćĚyóć:t㸜śśgžy¦ć^ABźźDDĉ'úőëwňä©ŃŁG§§§ŇÓÓĂĂĂj>W&“‰Şh@PPPyy9UÎ#FŚX¸pˇËĺúâ‹/RRR"##1ĆU ¤Ó÷†ĺ áőÄ 5D—HµZ=tč´´őW›4 2ýZ¶ Ł{ş0&“'OŽŠŠ6™Ę-Z”šš:oŢýúőKKKëŇĄł,ËV«uĎž˝&L°Ůě›7˙śřŇK3-ó‡Î_·.-99Ů3"„DQ,--mÓ¦5 2*=L8Ž+))ٲekRRŇ /<áÂ…÷ß˙`Ó¦MÝşuE †Ö­czčA«ŐúŮg ŇŇÖ?üđ#O>ůdNÎĄYł^lÝúëżţő:ŕĘ•üÝ»÷öë×ďÉ'§žzôč!C|pňÎť»ľřâ«}űöµoźČ󜏏O×®]GŤ™››űî»ďîÝ»očĐ!;×Ką~¨…Ôžér‰U·¦  ©X}ŕ8äv»EQ,fłĹbn\Hč,đf6ľnÂŞDY?̨˘Ä8„ ĆŘív—”Ń@Á‡č›^U×9BęaÝEĄŽ˙}ÝşT»Ýqđŕ˙€ŘŘXOWSŐ•˝–Né†ĺ={öÜľ}űňĺË].×ţóOü‰[ ë_mÇőĺË—Ďś9CEÝ͙ܷ[îŢ=Él6˙ý÷ˇˇˇť;wńó3R‘ëp8l6 12nÜŘÓ§OŻ[—ćr‰Ť&''‡ĘTډĂá°Z-cAµ-Äô,+˝zÝsĺJÁŞU«BBB»uëŞŃho¸]ĽÚ ŇŻ÷ß˙ęŐ«?ţřc“É4wîÜÚqüüül6›Ůl†:__ß6¦,ËÚ¶m{ż~ýrrrţńŹ—RS×!„~ţů—î˝ŮŹč9uŐýŃG]µjŐG}ät:}ôŃš÷âٰP­üVžÁřŠ­f·uwÁk4šgž™ńý÷«_}őµ7ß|kőę5%%%cŁŃ÷˝÷Ţáy>#ăbIII—.]Oź>ŁÓézöě±gĎ^—ËE)))={öě€÷–••ť:ujذˇW®\±X¬IIÝŽ=J»WŠ˘¸Ý˛Z­öěóŚ”fł©  `ňäÜnwHHč°aĂ>‚˘ë‚<đ€$I:ť®k×®GK–%‹Ĺd±XiÇ]RRb±ÇŽ#ŠbxxŘčŃŁ\.±˛ťAŐ“RGM·Ű5rdŠÍf+..éÜąÓĚ™/:ŽŚŚ LJ……eeeŃ5]·Ű-Ë’ÍfóÔČË»ĚóüđáCťN1111!!áäÉS—KęСðaC{HH‹čččâââ†đs˙Ůgăfc-Ćk˙H’$Ënúc|}ÉĆ—ĚMťt§Í ˙lt˝N•ŕ=b0ŞŔ!"ĎIĹărIŐőzś ë´ş´´őÓ¦M{őŐW/\¸8jÔČřřxEqŤľ˘č˛Z­Uçń7®A§«ş‰Žă8ʦęÜąsQQQHH'ä N§Ł®ô.xž§Ó‹žeSAŞ ł9sćěÝ»÷˝÷Ţ[·nÝ™3gţT×ńÔSOůűű/[¶ěŐW_[±b…Ĺb©v#<Ď˙ţűďź|ňé¬YŻÍ1sÚ´§322jćŻ#äşđôƢ(ľř⋇/^2kÖk«W˙@ű«jÝ`0P'O€Ýn×ëőžcúőëwäČ‘ľ}űţa˘×_ýŢ{ďÝ´iÓŽ;yä‘ŮłgW‹Řéą¶>}ú>|Řb±(ŠÜ˛eKB°Őj=pŕ@Ż^˝nř; “ÉD?———{üN!„}űö=pŕŔСC=OÂÍÖëőžr“Éô§śW ŁvbX€Nç3mÚ“Ź=öŰ-ť9svőęŐ~řŃ;ďĚq8ééGçÎť—‘qŃn·cŚCBZ „BBB<Řľ}‡cÇŽµoź`0ňóóĎś93xđPÚAK’Ô˛ehŐ{ÄC4uYY™N§«zď4MŞĂáE‘ç9__ßňňrb‘ă8­VCŁ2Ň0\T5PUťjřůů9žçŤF?OŘ@eĽ왝`LT*AŻ÷ˇ•;Ž­[·-^Ľ$//Ďĺr9ťÎűî]UďQUĂüf\ĚذqŁż@RR7»Ý^ąbU?‹McÁФI°ŹŹ­r% K’Ô§Oź.[öÍÓO?e±XľűîűŘŘXŤFUm}¤K—.+V¬8|řđŔSSSyž§ö´/żü2 ŕá‡>ţüŹ?ţĐĄK—¤¤¤ďż˙ţřńă˝zőZ˝zµ^ݧa${ôčńĂ?tďŢ˝GŹß}÷ťżż‹-«V­jÓ¦ ŤąmŰ6Bxď;Žă>^„oż]Q^^ޤ‹_V«MŻ×[­VŚqHHČ®]»Ű´iĂóÂ’%Kčajµú“O>2dh||BQQQii™˘Č5ŰyŔ€+V¬čÖ­[óćÍ-ZÔĄKşńďŤ7Ţ7nÜČ‘#­Vë{ď˝·xńbŤFSőFŞ&  Ú¶mŰ#Ź<řő×_iPÇ›ő-ÉÉÉË—/2d„0!!aůňo’’’h„Éšôďß˙óĎ?ďŇĄ BháÂ…tĂ!˝Ľ§ź~zذa—.]ú׿ţőĹ_P›=X–ĺE‹Ý{ď˝tŢŇ»wď… vîÜŮĺr-^ĽxŔ€ěŤf0·O°Ýe‡1ˇÓé\»vmŹÝCBBh$ò˛2•J ‹˘óȑߞzꩾ}űL¦•+WQÝĄV«şví2{öś3gΖ••uęÔI’$µZťĎó|JĘŤF“——węÔéŞ#=ĆŔ××·sçN«V}Ö!.+++++{ŕŔ:ť.((čçź=zÔŐ«W÷í;+ËnÚD+U<î€GüTBDQdÁ×ÇÇgűöíC‡ÉÉÉŮ˝{·J%˘¨Ő*EQΞ=‘••µ{÷A¨ŁůŻ Á‚«W rrrţď˙^ißľ}nnŢŻżn!„€!tó]®ÔŠJ“&MdYŮ·o˙ţýNś8‘™™…±LŻ‹Vë‰ő_mŇŁR ű÷°Z­ „ěŰ·ĎápÜ{oBČž={DŃŐż_—ën†ĹÇŢĐŠTj°˙oďÚŁ˘8Ň}U÷ôLĎ™Gđ±Â(/EuI 8†‡!• Ţ$÷şç^ÝWsĚĆÍĂlÜ˝+č11'ń±žxŁ'W0Y%×cgUŚňĐ *˛ 3ÓÓ]Ő÷Ź‚ŮáOÂ"“ÔďNuOMwMQ]]żúľď÷±,s«ńVEĹ•¦¦ŰBŚÉţë?]d,c„ ÷Č]`„†‘`V€e Ëe #,#${!óy| ?+0, ŘőPă‰,ŰíöĎżřâ/ňĽ*<ú裓'OBoŢĽůÄOLś8‘´üŕÁŤŤŤŐŐŐ»ví:yňdAAA_“yź:tčřńăv{çĚ™3M&ĆR\ÜśŁGŹť;wnÍšŐ“&Mš?˙ńĘĘĘW_}Ťa›­“dÓĆXŠŹźóᇇKKO=˙üłăÇŹĎĚ´–••˝öÚ*•ŞŁŁť°8ˇÍÖąwď>µš·ŮlÉÉót:]ßUĢE‹.^ĽřÖ[o©Őę›7onذA§Ó•––>xđ ;;ŰĎĎoéŇĄ_~ůĺáÇsss•JĺöíŰ%IjmmÝĽy3Çq/ľř"Ďó+W®ťťv­V›čĐ˙`Ś5umm}]]íś9qnѲ[™8·¬ěüŃŁG§NťJ^wîÜ]° Őh4Ě1ăřńˇˇˇˇşşfůňe‚ŕ"aoÄź@%B‡DQ".Ф,IČßtxxř±cÇU*e}}õk×ĆŽ+IČd2ůűűřáḸ¸ŞŞoŻ\©;v ń’$‰0âÜčççwéŇĺĆĆŰ••U/~< cd4Ź;Iľ%Š˘Ů4fĚ'N@ľřâ«ÎNűĚ™±‚ t_¶+˝›ç]Ü=ĎqĘżýítCCâEObŚ?ů䓦¦; ¦aŚKJNµ¶¶¦ĄYç#ý¸Dk$Ć`Ż\ą\ßPʱĚ)8eBŘ<ľ»Řť÷„Ë 3xcńĂ©äŤÄŐ9µ°Qôâđ ăv‰$Łc¬P°’(ž:uĘG«]łfő¨QŁ0BCĆ&IRhH°RëÓËłŽ\ÜjÍŕ8îČ‘#·n}çë뛞žrëV]Ż‹L¦ěěě;v”””$''[,…BńÍ7ßÄÄÄälJĄ2''çرc·oßŽŠŠĘÉÉ)***--ť?~jjŞZ­–e9 ''§¸¸řŇĄK©©©)))DL2))©ŞŞŞ´´”eŮŮłgçĺĺŻ<@yyůůóçCBB®_ż^^^žžžŢ—°‰˘ś<ďťwö|öŮ˙ůůů=÷ÜżŤ3ÖápdffěÜą«¬¬,7w‰(ŠůůyEEŧOźáy~ĺĘóç?®ŃhAČÎÎ..ŢyöěŮeËž22ŇęĎź˙L©T®ZőLee%Ď«EQLIyâí·÷TV^X»v­^ŻÇ¸÷'88xńâĹ{öěioo_˛dI||<ŕŇĄKO=őq5™LË–-+//—$I©Tž8q˘µµ5!!ˇ´´Ôn·Ż[·Žçů+VÜąsçÜąs’$EGG d1ĂOź5gN|xxą{bbbttô@δiÓ˛˛˛öíŰ'ËňňĺËŁ˘˘$aC```~~ţĺË—­Vktt´Őj%Y¶W®\A¸qlllzz:˝,(( ę5˙ÂöČuŤ’yžĎĎĎ;xđË—Ż`ŚĆŽk±¤®ZUčp8u:ÝňĺËţřÇ˙nii NKłÔ×7nŁTŞ’’řË{ďí±ŰDĽÄb±Ü»×ü»ßmmkk›1cĆڵϻ\®^šNS¦Lyá…uEE;ßyç]†a~ůËŮĎ swą\&LHO_´cGńsĎý‡ŮTXX=CRcD–A,«ŕ8ŽÜĹsKR«Ő „ĆX«ŐąË>>:7ĺ{„cŁŹ|HƢP(jnÔ|×x B(w‡«{ưáäąG&B˝1FnŹPJŘ(Ľ Ëş]" ‰"SD=SV952;+ËétöĄ?6›mÝÚµN—;:Î󹦧˙*##ť4‰Ěśőőý$׊ŤŤÝ·oźçw¶e7 şqqq$ĚÉc× ÁóĤI“^ýő~ż{÷î‡b¤ˇˇřĂ›B€M>cbbŢ˙=˘×*¸qă¶m{Ăý3/ÎA9ťÎYłf8°ŹTEQŁŃlÚ´ióć®j!—ËY\Ľ=É?«ß)++++++ËóĚĆŤ=SRRRRRHůěŮł}Ż Őj·nÝú°‹…âčŃż’ ;Ápôč_=2úô+VgK7ÁÍŤŚŚ ·Ń¬°°°°°°ďEVŻ^˝zőjú SPPüô €eŮŮłgMž.‚,…BˇÓi9Ž#‹ňÇKž>= !ÄqJťN›–f!ę#*•réҧž|ra@€?ęŢŐj5O?ť—‘ń+„0Ď«ŚFc/ÖAâ§§M›¶mŰ‚ @xžwçŢ řío_´Ű,Ëęő>!I’###ß~{W{{;áTQQÓví*nii™1cúÎťEä|llLQŃźIŮl6oŰözGG˲eeçZZZH˛×y󒢢¦I’¤V«9ŽE±ąą9))1&&†|!¤Óérs—X, 0ĆjµšÄ|·¶¶ř˙ć7˙µfÍ*ťN{ď^sZšĺ±Ç’É·ÂÂÂ~˙ű­‚ŕä8Î`0H’$I’Őš±paZ{{‡,Ëv»=''Ëĺ;::<»Ân·/]šKň"ňóó0F¤ĽlŮÓc›Í62uЉ…M]!ÁÁ´}űí·˛Śa—«$"Ś€ĐH\"˝Ę…o-î=Ż›}¨K$Eď!Á0îśdT»ť”JĄĹ˛ )1Ńápďî! ·–<Č´Öó#ď]Ľnxy w˝ç>fßjžźzVëu~¤˝ ú¶‚‚‚‚¶ˇ„Z­öńń!fnńý®8oŤFc4!$öÉd2Ůí]bľľĆŃŁM‚ x*1úúúŽm"bV˘(ö»XW*•żřĹxr;Ďj ð,K‚ŃÉţśJĄ t8dC‘çůŔŔ.UF˝^OΫŐjRfY¶ąąą¶¶ÎbYpíÚµË—Ż„‡‡ҨŃhŚFi±Ô9ťNbărkXCŤF#QŁň¬Ć˛¬żż˙¸qă$IAŻ×űúú’o)•J˘śI„.Ýű‹ Ă‚!”$ÉóĐÝ ’$ůúúBI,‡źźgŮŹ”9+$†ŤĘEDD`ŚŻ~}aě^óýsTC€eŚ†Čźjxđ˝ů|¨K$ĹO Ë@ȸs®0B$ ůÉ… 3­V­V+Šâ%ą‚PĆxpÂćů©wî0ôłEŐ—•őň¶č÷<č41Hµ‘˛ŰĺáéęŤ)+)((($l#dĺGXÓĂ|Dd0ČŰB„ľYYú;×Ď5r–č;Ë»+“›şÝŚ®;ž­«‘§OźľqŁö»ďn9ťÎ¤¤DApvżőţŤ˘(’“î÷qYéŰ*φyFĺőű[<+ô=ôě«ÁËŹö­<Ŕ* b,cŚ d0ĆľFß°°°¶¶6•R‰ö î°{ńâe62TŇ©Ç_Ô]feYĆo´°1, „Ť˘ç Î{îÝI’4MB||V¦ubPÝápĎtčPPPPPü| }!Bz˝^§Ó8pŔdť›»hţŇžůHÂT–1B¤Űu8¦QŁ"#§úřřH’ŘMk=÷’±ěU6 ˇZ­'Ď«§SĹóNÁÉójR'’$쥲ţ,ÍĂFŃsH0 †aÂä©fp ÂDły|޸›ÍČÖ „2€Ž Šź'a±ľ ^ ڱÁ`XłfőŞU…B"˛L»ĺ‡Âdý»¶ăɡ ţŁMÇş\‘šóT‰ÄŁ!Ń+6ÎďrEDN­«©  ­»QZWSZ[SÖP[ë•,„€şDRôËöČÆ D‚1e ŔÖŃŃł&í- Šź1aŁ+¨ˇďe…‚ä!őŢpŁ‘€ţ,l2Ë2„†AČxR;›Í†1–eŕÉÎX–EHBÉ^%Ŕ@F’DČô˙xĄ>$ H9:ÝPô2 „B„$bCc  @¸‡wşĄR¤     2†ş˙ž,cj`rP’6të9†lľ»ŰÚZYV†Đł“ˇ,K [/›Ř6†iľwO«ÓrJĄ×vđ“2(\[ ŽŁ6Š/$…BˇP´ÜżßÖÖ¦T©B’:ĺ‘ôŇĂĽmIó†ň!:Ďô1§  řQ„Í`0VWW2tŰ’bd6…‚S©xd ðMMŤN§cđu ˲˘$*ŠúşZŁŃH»q„Ŕn·SşFá Žă’î77ߨ®ţŢ©Ŕn·ëőúa¦@Z­îÁ¶¦¦FťNďŢ9`YÇ)9Ž~Ę&ËŔ`0vvv66ŢdYĹpŢBĆÇG˙˝LĚ`0¶·?hjjfΆ16}écNAAńŁŰĉÁW®üťöĹHBR`ŕDÁ—%˛,óŹÜokk}ĺ Ă*wď4Ý˝ÓD»q$BŘÔŘH-l=źS¶Ł˝ŁŁŁ˝Şňú÷V–$iÜřńĂĽŕ3f\kkËçźćé=2§ĘđđŤF;üąă0FfspEĹßoެv®(Oź3ř¬"Ë2YíÔÖÖ s󆉎žEe(((~ţřФ,IEND®B`‚gpsim-0.30.0/doc/screenshots/source_browser.png0000664000076400007640000021265313041763626016543 00000000000000‰PNG  IHDR`+Hô% IDATxśěÝwXWŔáßŇ»°bCQŁŇD°÷^QcŤ‰˝ 1±¤7Mbb¬±%v?1vEŤ‰[ŤÁ.Š,ŘşŔ˛ßČ*eĹU,ç}Ů™;÷ŢsgdĎŢ™ťQ¨Őj˛R(Ů !„Bť©ŐjEÖeFĎľP(ę¦Mł˙ßÝ”-[ćĺőL!„â Eł¦MÔ˙íĎ”)2fŔ …:`ýjŐŞYhťB!„xť>}†w{öŐ$aFž|ůŻYAőjUIMIŕúő+j |ůJúę«B!ŢúÎ;^µúŞW«Š˙š( µZ­V4iÜŞŐśHIMOľnEÝÄÍÝ«@ …ž8Bé2ÚV!„o}çŻj}U«9Ѥq#".žE¨˙Ü€CٲšF\Ý< ÔH†°ĐŁ’„ !^ ‰II(P`ffZČ˝Ń/•JEň“łF††rŹ„ĐťľóŽW˝ľ›‘‘tęünú)ČŚäë)ů¤âͰqÓ6ŚŚŚčÝÓ»{óüţÚľ›ÄÄDŢíÖ‰k×nňßácTuŞŚg·BďĽăŐ­/#ç2Ęiew¦B<ljĐÓÜąMJJ XZZPŰÍ™˛eKv÷ň´eëvbăâ3-300 XŃ"¸ąÖ˘T©…ÔłçŮä$?ű/:ú>Ęäd^Áý©T*IJRŕčXGÇ ¬ZPČ˝âůč;ďČZßú€MZËö|·›ÎőeÔůě¶Y_çĹ@KS™~Ň;®Î÷r!Ţdűqăf$ŐŞV¦IŁzÔ«ëA…ň( ´üwzE5kÚ€¦MиQ=Ş:Ućţ‡<\ŘÝzáňł˙vîÚÇŃc' ±—BĽmrĘ%tůÉ«>]ŰνLFB—‘e}ťźöóś۰1đIĄôčŢ5ĎĺBĽéĹÂÔÔ—Z5¨R%÷o$—-ótv§t©śżpxzŻŔ¬}đîÜ.׸Nť>ÇÉSgiۦ9v¶Ĺ9xčW®\ŁU‹&”,iĎÁ˙ŽĐ ľ'·oß%4ě4ŹbbHKScnn†§‡erŤ%§>e»çÝĄźŇKHHdŐšĽ;·ăÁĂGůÚź.Î58rss3š5i€µµUľÖçłJĄâȱ\żIjjjľbâuó˘gŔž·lÖ2=şwÍ”=»<żmç9ÖŁűÓk&ŇSkMoĚÝ2M!^oeË V«ŮúçNBĂNó8Óú+W®±?řjµšfMЬiCŇÔiě>ÄĺË×tjëň•k”/W–3g/p<$ 5PĎ˦ŤëăTĹCCC”Ędöě &!1‘–-cg[ś#ÇNó86׺oßľËíŰwąq3’Ź`llD]ŻÚZűW\%KŘ}÷wďFpďţÔj5·ďÜĄTÉôÓ›ţ;BĚăÇ4mÜ€vm[ŕQŰKK‹|Ç’Ń's33,,Ěó=¦yí?7—ô{!š™™Ň±}+nßą›Żý™”¤äęµ”°·ăńăXBNśĚTݶőyĹvň —/_ŁJ労oŰ“|Ç*ÄëăĹĎ€őčîťíG{Űy÷ďŮü(Łţü÷/ź×€˝ŰÍ›€Ť›Ř°ůéňîŢr˝xë4jčEřĹÂĂ#8sögÎ^ TÉxyşcmmĹ©3ç¨WŻE‹ŘPżn¶ý˝‹ÓgĎăčX!ßmµjŃsss6mţ+˝í^-Z@s˝RřĹË$''ăX© El¬qp(ĂŤ›QÜşu‡"6ÖZëŢ˝wżćwÜÝśsĽć)Ł[ţÜ‘k\Ű·ÂŔŔ€;wďQľĽ‰‰IXZZpďţbcăHLL˘d©ô$M­VŁRĄuëU*WÔ$SůŤ%ŁOíÚ¶Č÷xBŢű/#™300 hŃ"Ę5îŚýihhHł& HNNacŕ6înŘśŻľeČ1Ë)[{·{—LŤ˝«Éô„x»P˝šŐŞV!:ú>ç·s3ňű‚Ň©Ckâž\ŕţlÂ`óä÷¸,żç%#ÉHLLż•BĆ)«g%&&pţÂ%Î_¸¤Yžđdą6ýúľ‹Z­&11‰a§8FLĚălł`}Č+.CCCl‹#úŢ}nÝľCńâE±¶¶ćÖ­ŰÜąŤµµ–´hÖаÓ\żÄů ±łłĹÓĂ5ß±dô© ňÚ EćG¶ĺwahh™Yú‰…””TÔjµ¦>mës‹9c˙Č-&Ä›,‡Ś)ßeó[_n3[şŐ—5Ęx°10ßI–°ś;Ó˝[6nÚB÷n]´–âmˇP((QÂŽbĹŠâża3ŹÇ’––†••%±±qÄ<ŽŐĚ<~r:éŮJť–ţH©T’ňä^NÚXXźŔʰ··Í¶ŔÉÉŻ:î:Ç`aaŽ»«3WŻŢŕĘŐk9ž†ňWÉ’öDß»OřĹË”)]KK ®\ąFÄ嫚ӏŋĄEóFÄÇ'pö\8á# >DÍŐ ‹®´í?CCCŕéßÁüîĎ Jeúô”……y¶d.§őyí?###RSSIJJÂÄÄ„”ąLĽytÉ)ňS6§2ÚfŐ R_Ö|¨ ů‘–0íşwë˘ë&BĽQöţ{€’%ě±´´@­VsófžTâ\ł:ăСc¸»9ŁF͉§¨ő$Á011!1)‰'‰ŚşŤJ•–k›Ő«UáxČI<‚łó;XZXO {;Ę—sŕ䩳DD\ĹÜĚŚâĹŠ˘LNĆŘŘre´Ö™qj+--ŤČČ[Xä2ł”ź¸JŘŰđđá#ÜÝjafš~ăÓűRăI€')U˛ćŘŰ'übĆĆĆŠeűŽ=$&%iľĐ—Ľö€©©)Je2·oߥŞSeއ„ĺ7@jŞŠGŹbxr]XĹ ĺ2µ«m}^1—,aOdÔ-Ž=AŞJ…JĄĘWśBĽÎôťkĽÜ%kťş¶ˇÓ RSS9ţ"‰IIšŚ*•+á\ë*UŞ€ˇ‘gĎ]`ďżÁ †bŊҸa]Ę—Ożr­šŐ ;Íőë‘xx¸rěx( ÚOV«ZCCCÂ/^ćČŃôŰ#X[YRĽX1llLhݲ)ˇag8wţ"©©©››á\óť\ă8pđćwCCěím©SŰUkůüÄegg«™ő±łµĹČČCCCT*ĄJÚkęzđđ—Ż’śś‚±±1eKăî挩©î±$&%ĺ:vYĺµ˙Ü\krâ$űţ=@۶-hܨ^®q$''łíď]R©R\śkdjWŰúĽb®íîLl\wîŢŁ¶»3ŹÇ꯯}çŻz}ţťsuhČ!Í‚[Q7©QSűáü8{&LE$„x%¬Z€ŁcÜ]ť_ŘŁ˛ŢVD×ő•ń(˘Ť›¶ÉťđĹkKßyÇ«^€[ízé3`iĎLi—,YšłgÂx§†K9wö$%K–ÎT§B¦Ë—ŻqýúMzvďüâQ“űß˝ĽÖŔ•«×9|$$˝zµZţîŠ×’ľóŽW˝ľ @}ěđţlDGß)PCöö% ´ťBĽ®®^»‰‘‘ˇÖGĺµ^ˇ˙ĽăU®ŻNÝĆé Ř‘˙ţ-PĄB!„B7^ő›j»ľB!„xQŚbcçUN!„Bč‰@…ŠŽŮVTvŞ‘m™(<Ďv„Bˇ'9ެ˛S yĂĹT©Z“Kág »B!„Đťď„/^ľ }»¨PÉ©{ňząvĺâ7fobLůń¶Ćť—ďÚ•‹…Ýń†’ě5rřżě· Ú5jŇ’ŕ Ý…Ý ˝zcĘŹ·5îĽČ¸ĽxŤš´”łâ…oAŠ7ҡ˙vôîMŚ)?ŢÖ¸ó"ăňâÉ‹I0!„B—L0!„B—L0!„B—ě­JŔ”J%iii…Ý !„BĽĺ 5KJJâËŻľĹĹÍ“Ťšł!`Sľ¶ >pÉS¦ăÝ­'˙:śiťJĄbň”éÔńl€«»?˙2Eł®¦smŽ=ž­ľĂ‡ŹRĄjÍç FWHrr2iię\Ë$&&rń⥗ԣ—ămŤűM’ź}ŮÇâu s¶óź]ÜŤŽÖKăÓgĚ"<ü"ÁA{X0.ľźČŃc٤¬¶lů[Űâś9s6ŰŚÖĚYsů7h?m äĐÁ š7kšg}Ő«WcąßÍk}ĆXŽ;Îďó2x¨ÇCNdZw7:šożűŽťşŃ˘U{F~8šóç/°mŰß´ďŘ•‡fÚf×®=4jŇ’ËW®h–5jŇ2Ű@||ľźH§.ďҲu>ý ·nßαź'N„i¶{•emă…S‹Ví ;™k™óçĂ4d„^Ű}[ă~“)•J~™<ŤÖm;ѵ{/¶ýµ=_Űĺö÷GĄRńűĽ…tčÔ•6í:3÷·ůšuÚöˇ.Ç–ěcń:Đ9óýp4W._}’’X»n=#GÇĆĆçZ´kŰš+WçąíÔ)“6tp¶ĺ‰‰‰,˙ccÇ|D‰%077ŁAýzyÖW¤ Ô׼ÖWŚ…mçÎ]+V”đđ‹¨ł|˘?ţG4¨Ç–ÍřëĎ@śkŐäŰń?°`ŃFůŽ`ŃÂß5壣ď1áâŰůß’l X«ůP&+quuaíš?ضu&¦&Lž2#Çí«TqdÖŻÓôň •u\r§ ŻKLúö¶ĆýŞ ćţýűz©kÁÂ%\ľ|…MkůeŇDfü:›°“§ňÜ.·ż?K–úqčđţđ[Ę–Ŕ 4¨_7Ďú˛[úŠQźc%„.tJŔú}0€ÁCG0ń§_€ôGäl ¤MŰN8»ÖaÍZ‚¤ŽWC<<ëł}űNÍöUŞÖdé˙ü¨×  ‹/%)) WWÍzgNś-p0aa§HLL˘ŽGm­e®_żN§Îݨé\› ?üDZZZ¦S9ĹŐ+VѲu{jąxPŻAÍ©SµZÍě9żŃ a3ś]=đđ¬Ďúő™âĎďXéĂ7_Á{}{ç¸îü…pęŐóÂĐĐ33SZ4oJ\\<>˘DÉššjâúeň4|Đ/Çşěěl)aoŻů(^¬Ý»yceiů¤ţfś<™óĚ„µµ5uęhßgŻŠ¬ă’őőł^—ôímŤűUóő·¸~ýćsףT*ٲuý?臕•ďTŻFł¦Ť Ěs[m’’’Xż!€aCagg‹™™)ąüÍÎőŘŇWŚúŞG]销­ZáŔ˙–,ä»ożŇ,_ąr5sçţʰˇôË6mÚĚćMëiÖ¬i¶Y“ ›X¸ŕw°-^\ł®xńâÜ˝[đS7##Řúç_4mŢšşőłőĎż2•ů}ŢBľüň3.řŤµkýłM§k‹ńY•+;˛nÍJN…cŕ€ţLžśţ©,üâEćţ6źüŹSaÇ Ú·‹ćÍ›eÚV—±ĘŹFMZň÷öť ń!ÍZ´ĺ“Oż$&&&ĎíęŐőbÜ'_pţübbbűŰ|F »=űđůßđÇŠôŮČŔŔ-tîÜ1ÇşBBBµž^Ě}kk›×e=µĐ¨IKöîý—qź|AÓćmřüËo4§šŻ]żÎ'ź}I«6hŃŞ=cÇ}žg¬YĺVÇÍ›‘Śűä Z·íDgďwů}ŢBRRRłŤKNăT1…_ĽÄ¨ŹÇ1hČş÷č“iÝŮsçî3ŠÎŢďŇ˝G6oů3Ç:6l˘Oßţ´lÝ.Ţ=4˙7>˙âfĎy:˧V«éŰoÇŹ‡HÜů¨G­Vłô~xwëE«6hß±+nű;Óýő÷Ţ{ ­Útdó–?9zě8;uŁ}Ç®ěݤÓ|4zź|öĄ¦˙ş´Ń¨IKÖ®[Oď¬Z˝ĄRIŤŐ5ëßy§:§ĎüÎđgĎť')I‰‹K-­e"Ł˘0h-ZµgĆĚ9¤Ą©3[9ŨMnăŻK=Bč›^.Â÷őAµŞU©]ŰťÄÄ$&Ś˙–˛eËPŰÝŤŘŘŘLe?ĺ‹«‹3Elr~3~©©©@ú¸}{v2vĚÇ|ýÍw$$$hĘŚ=ŠF Шaj×vçß ÝďÓ°A}ěělIJRâčX‘GOk Yëżž‹/aaaťťm¦mu«üZĽřôěŮťE ~ăÚőëü>oažŰ|őĺ§Üąs—ˇĂ}éŃ«uëzŃ­kÖŻ`Ú”Iô˙ŕ=nŢŚdůŠU|ůĺ§(ŠlőÔ«çEŕć­|Đ0cĆ}ĆŁGʞ•‰‹Ź'póúôî‘ď.ZJŹw»1wöŻAűń[ľ"۸d}]1%$$đɧ_ЦuK–-]ČĆ k5ëbccůäÓ/éÖµ [70mę/Ěś5—ËŮę©XˇóćÍf×Îmôęő.żĎ[@ëÖ-Ř˝{/*• €S§Îš’Š»»»ÄťŹz._ąĘ2żĚž5ť];˙"`ýj4Č|iÄĆM›™řăŢëŰ‹ążÍăďżw°tÉÔŻ›ŻË2ž5wöŻĚ6™ŃX 6¶ýµťÉ“˘téŇ-ZTł®XѢܻWđSv·nĄXűg×zôzŹÎŢď˛kמLe–/_ɨ}2ů'6oŢĘž={ócNr]ęBßô’€Ů<™ŮČx¶±±ÎôúYĹźĚxŮŮŰđŕÁCÍş‡R˘„}ű‘‘ÔőéÝ…BA—ÎILLâŇ3t3ţ ”°·çq>f‹˛Z»n=ďöčĂ·ßM `ăÓ©řŇĄKá·l1Ă/Ń©KwÚwôÎvń©.c•_Ç ¦u«–T­ę„w—N8x(ĎmćÍ_„łsM~ůůGŠ/Ć2ż?8|äh¦2*•Љ?OfÄđˇšS‹YMźú żÍťIŔú5<|řżÎδ>99™oľýž:µéÓ»Wľc8ŕ}4¨G­Z駆ăââ9r‚»wŁýчŘÚÚbddDůňĺň]'k§Oź!22ŠýßÇŘŘ’%KĐąSţŢľC§6^vL‡!..ŽíŰf[÷ߡ#(•JJ—.Ĺ©SgŹ‹ÇŢŢŽc9ĚâÔ©S›âĹŠˇT&Sľ\9?N˙@ШayryŔ¶żţ¦C‡väď}[âÖVʵ•†††lÝşŤ+W®bnnNńbĹ2m;ŕ~Tv¬„łs-’’”Śű1ĄJ•¤V­šÄÇÇë4.ÚčŇĆŕý©ńNu¬­­€ěźžçď•ęÉe€őëV1lČ &OťNbb˘fůĐ!ń¬ăg\śkńßá#n/?ă/Da(´‡qWŻVsssÂÂNŇŞU ý¦»»[ë¬Qă ýxfff(éůĄą™YŽĺ|”Ý»ź~:«_Ż.őëŐ%66–ÉS¦óŃÇă8Ľ7—ź_É’%5żŰÚÚ—ků[·ołíŻílܰ–%ěńô¬Ă7ßM`ćĚą¬]ó‡¦ÜĺËW8sć,gÎśĺçIOoçŃŔP>ţČ—^=ßŐ,+R¤Ý»ygú6“JĄbÂ÷?Q¶l>7&ßoŘĎĆôě6÷ď? T©’9n“ąŐqďÉ:[Ű̧Ĺ3¶y^/*¦;wîbmm‘Qö˙Î3’›6mÖ,«ńNuJ–,‘­ě–-ňç¶żqp(KBÂÓ7Csss5lŔ?˙ě¦fŤwŘ»/?žůÖp^Ţ–¸µŐS˘„=żÎÂĘ•k8x8ĺĘ9đĹgăpv~z ÎĘęI˘"óëçHt˛ŇĄŤŚŻŚĚŹ=zú{LL¦˙#ş˛¶N˙ĐŮĄsG ­[·dęô™\˝vťwŞW D‰§űÉÖ¶xϤו÷ř QtNŔ,,,¸w˙jµúąţ8ššň^ßŢĚ_°zőĽ¸~ýŰwěŕK¸Î ĘăéY‡yóňőWźłőĎ?qppŔѱR¶˛—Ż\!äD(ŁGŹB•ŞĘ´.kŚßŤ˙şu=éÔ±¤żqÜľ}cţú;ý:Ź«WŻajjʵkש]Ű KKKĘ•s(p,uçÎÝ<ßÔîEߞξ™™™Ň©C{~ĚňĄĘ•ůgGćëfZ·íĢ…żăTĄJ¶zSSS124ÔĽ^°p 1Źcřů§ďuJľ´±·Kź5ŤŠşUŕ±Í­»'o*÷ď?ŔţÉ í˝{÷źëÍćyú“_–ÄĹšR©044Ět `éRĄP©T|öŮ8¬,-3mwâDć÷ËLť>˙µ+)S¦4'N„|ŕ f}ëV-ůń§ITŻ^Ťš5Ţy®Ä ŢĽ¸óŞÇٶ;µÝ‰‹ŹgŢĽ…|7áG7ú(î—©JeGĚĚĚ8söŤ5Ň?„ÖŞYđű&:UM˙Ű‘©©©ć˛Y_fxô(‡˛n^ßńo6ťOAŽ>„/ľü–MO.Ě~ăĆ~LŐŞN4jŇ’ˇĂF2ţ»ođ¬ă‘çv­ÚtŔٵÆűâěZ‡ë×oéçňĎž=‡[m/V¬\ĂďsgbřLR0zě'ĽŰŁŁGÂĎżĎń“Yc\łÖźcÇŇO]Ôőň¤KçŽ|0`ý>DŁF pssĺ˝~HR&1eętęx5ÄŐÝ‹;ţaö¬éĎ=NyIR&éoŮú']:wʵĽŁŁ#VVVüo٤¤¤đřq,[˙ü‹zőĽ2•300ŔÜÜ<Ó¤'lĆĆéąűŐ«×P«ŐÜşu› ›hŢ<ýľk—ݰvÝz:węČ˝ű÷ąťéŢjÓ¦Ďd×nÝf=<Ü)]ŞÓťMdd±±±Z/.HµjŐġlYţXąšÔÔTîÜąËÖ­Űhß®Mľę.Ľj“ššÂÎvĎO??ť­¬WϋҥJ1uęŻ<|řµZMtô=ÍV2dĚÝŤŽ&:ú{öîŇŹ)//O ™ż`1;¶—¸łÄť[=wďFr"”””,Ě-(]ş”Nq„ąą9>D­~ľššĐŐ»3+V¬&>>đ‹—Ř·ď_Ţ}·kët([7WţX± •JĹ?»vSşt)*T(ź­ěőë78uú m۴ζ.kŚÚŽĂĽĆ__c%„®tžűĐׇ}}4Ż/…?ý6LĂő3˝~ŻoďL_C~v¤Ď‚ý2i"żLšiyFr•“Ĺ ç±kç_Z×—)Sš5«˙Čq]Öö3Ô­ë™i]n1ň댩ü:cŞfYëVOżőµ)—OUşŚ•.>űükLMM)RÄď.ťčۧ'}Ţ믹Xöł/ľĆĐĐĺËS¶l~ť>™9sçŃ®7¦¦&4jŘ€ŹFŤÔąí1ă>#66KKKZ¶hĆáé7%˝t)µZťéÔ%@pĐn6oůCCCZµlžď¶ŚŤŤ™1}2Óg̢ß066ĆŐŐ9__aĎOFFFL›:‰é3fŃ®7fff´kŰŠúç«îŠ©lŮ2Ś;šŮs~gÁÂ%ŚţŘWó„cccfÍśĆÜßćÓ»ď¨T*ěíě9rćzD77WZ·jɱźQŞTI>9‚đ‹—řđٱlŢ䏱±Í›7eĎž}4iÜPâÎwnőü6çWćÍ_ĵk×Q«ŐT¬Xľ˙.ßqÄűýú0é—©$''çű„6Ç fĆĚ9tďŃ33sĆŽţWç<·ËíďĎwß~ĹŹ'Ѷ}gĘ•+ÇĎżÇŔŕé|Ŕ„ď'RŞTI’SRřâłq¸¸ÔĘ4s™SŚÚŽCĄR™ëřës¬„Đ…PgML*;Ő ââŮÂé‘Č&hß.­I^žŐ¨IKćÎţww×BčŮ«ëĐřô‹ń9ŽŮ몰cúqâ$¬¬¬7öă—ÚîŰw^ {\ZµÉů¶4S§üLí縞÷U‘1ĆÚ>Ľ QPUŞÖ,Ľ‹đ…ŻŹ{÷îł{Ď>çp×˙7ŮŰw~ěÚą­°» Äk­PĆ-žßźBůň/˙bńvąuű6úżŹ“Sö/_ĽÉŢÖ¸…/žĚ€˝ć:węPŘ]oçZ5q®Uđoľ˝®ŢÖ¸…/žĚ€ !„BĽd’€ !„BĽd’€ !„BĽdrŠ×He§…Ý!„Bč@ˇPd»•‰Ü†â5#I±BńfČ5 Ú·ëeőC!„âŤ1hŘÇ,[…B‘çr!„B·™N XPP0«×®C©Tź€ŹďG„„„‹‹›§¦ěŢÝ;Ř´y+'N„f[ngg«§î !„BĽ~tJŔš4iD“&Ťň]~őJ?]ű#„BńJzđHeO IDATŕź~ţÓ§ţBńâĹź«.ą(K!„"‰‰I ń!AAÁ ń!‰‰IĎUź$`B!„ąP©TŚ÷)aa' ;Éqź˘R© \§$`B!„ąřqâ$vďŢ›iŮîÝ{ůqâ¤×)Ď‚B!„ČĹßÇßë~_°ÜČ x)|}}ą}űö «ٲe,X°€ÔÔÔÖ†Bˇ/:Í€Ą¦¦rôŘqvďŢËńă!lÚčŔöí;ń[ľk"#o1lč şví@×î˝°-^îFG3bŘ:th§˙HŢ"~~~$%%ˇV«9uę...ś={kkk\]]éŐ«çÎťcѢEÔŞU‹ăÇŹăěěĚ˝{÷đđđ C‡ÄÄÄŕç燡ˇ!¦¦¦ 0­m_şt‰íŰ·cddD\\-Z´ŕěŮł^H$O?ů;ת©ů}ń’Ąx{wĆĘĘ €3gΰ1»wďríú –,š˙Ýyqqq!,, ĄRIĄJ•¸{÷®fÝť;w8pŕ-[¶ÄÄĄǏ“’’˘95X¤HîÝ»§­j†Ę”)S `ôčŃšu;wî$..Ž‹/j›áÇ“––ƨQŁ4ĺ<<<đđđŔ××—1cĆdzF¨¶ţűůůŃ˝{wjÔ¨ÁX·nľľľ¬Ył†>}úP­Z5|}}xôč«V­büřńXZZ˛sçNvěءIň˛Ę­üćÍ›™|Ç3qâD űÁĄP(ň<ĄvčĐ!Ú¶m‹……›6mâСC´lŮ€ŞU«Cxx8aaa”/_^/ýŹŹŹ'** '''śśśđ÷÷G©T…ŁŁc¦:"""P©T¬X±HO°˛žţĚoyfĚ»»;ŐŞUŁGŹyĆŕé鉧§gžĺ„BĽş‚vżĐú >–ĺŤz欹$$$0{ćôL3wďFS¶lŠ)ÂźJ»]${lmmQ©T\ż~ťRĄJeZץKâăăŮ·oíÚµĂĘĘ bbb(^Ľ8Ź=ÂÎNű)bµZÍŢ˝{™6m&&&”,Y’ůóçk°Š+b``€˝˝=Ó§O§sçÎzí˙ł )))f:ÍÍÍ)V¬>>>ůj3·ňäÖ­[ś?žŔŔ@ĚĚĚ2Íć !„ˇ—ŰP¬_Ŕ…đpľţęól§c&ý2Eó{HČ Ę•sĐG“"îîîT­Z5Çu­[·f÷îÝ$&&˘P(pssăäÉô;űž>}WW×\ë677ל466ĆÚÚ:[™řřxŚŤŤóě§ ¤ĄĄiľ´‘S˙---)]ş4—.]ž~űĐŇŇsss˘˘˘4§DŞT©B\\çÎťŇÇś®‡ËOůĹ‹ăŕŕ@«V­đńńáňĺËyö˙čŃŁřůůĺżB·—N3`AAÁ¬^»ĄRI||>ľJll,.nOO»ěÝ˝;;[nÜŚdř_’’”¤¤¦2{Ö ýFđ– ćÔ©S,X°€^˝zqůňeBCCéر#.\ŕŃŁGšdŕŔ4nÜęŐ«ł|ůr|||čŢ˝;~~~ś>}##Ł/TĎ P(0`«V­ÂĆƆÄÄDČĘ•+X¸p!©©©<|řľ}űO/ÂĎč' ™iňňňbňäÉ)R„.]şhí˙Ť78p ţţţěÝ»—””Ţ˙} ;vdÎś9šŮ6úő뇯Ż/ëÖ­cÆ ( š5kFŁFŤ˛ŤŰŕÁ111ŃZ>--ŤiÓ¦aeeEjj*ď˝÷žf<žíßľ}qpH˙pqăĆ Ž9’ëX !„x»)őĄđ3™VvŞAÄĹłíŰĹ aqńláôN䨲SŤZ˙¤I9?ZˇC‡¸ąą˝Đ¶…BÂđl®¸)€ző¨žşőłbŮ| űe‹ç0xřh˛ćYUŞÖ”G‰ěľţúëÂî‚BńF“G !„BĽd’€ !„BĽd’€ !„BĽd’€ !„BĽd:%`©©©üwč0?ý<™nÝ{i–oßľ“>}?`ř_:vęF`ŕ–lŰ.YşŚ†Ť[<Ź…B!^s:} 2$äááiÖ¬I¦$ëŘń&Ś˙†wީΥKxwëIűöm155ŕĘŐ«ś:uF[µB!„oťfŔĽĽ<Đ˙}ŞeąËş·wg*V¬€˝˝=JĄRó´´4~™<Ťoľţ\O]B!„x˝üY<}öžs­ššß/YŠ·wg¬¬¬Xµz-­[¶ D‰ĎŃM!„B7‡^/Â_˛t×®ß`ŇO?póćM}?`ř_:vę–éAÝď˝?g×:™~„Č0hĐ Nž<™íĆľůőđáC111áÂ… šŔë˘víÚěßżź´´´ő!«K—.±dÉ’ç^ž•źź ,`ţüůřúú˛`Áľúę«÷3<<\ë¸÷ďßź"EЏnm.]şÄożýĆ‚ >}:!!!ZËş»»ł˙ţ\ëË©źąĹĄ/ů=nőq| !ŢL:%`!!'żHłfM¸qă¦fů±ă!L˙ ‹Îcö¬é|óÝ÷(•JÍúSaÇ2ýˇ/666X[[cjjJ‘"E4OaĐ…™™~žĘ––ĆşuëHKKŁT©RqćĚť—çĆÇLJˇC‡j~ŻRĄJű;kÖ,­ D˝ző077/pÝÚ,_ľśţýűăăăĂđáĂń÷÷×Z6?ÉJNýĚ-®—MǧâͤÓ}ŔĽĽ<ńňň$:ú^¦ĺŢŢť©X±ööö(•JRRRäÓŢ+äöí۬[·ccc>|H‡pwwçćÍ›řűűcffFjj*¬^˝šŢ˝{łcÇÜÜÜxüř1'Ož$555ŰňäädFŽÉîÝ»9wî -Z”áÇłqăFvíÚEď޽ٹs'nnnôěŮ€V®\‰‰‰ÉsĹŐ¤ILMMQ(Ś1BłüäÉ“ěŮłSSS”J%¤hѢZÇŇOEfígÖńéׯ¶¶¶9öEĄRQ©R%"##©QŁׯ_§xńâ:/×fŕŔŮ– 2$×x÷ěŮÉ'°°° !!¬­­ Ň“…BAďŢ˝)S¦ ‹-BĄRqęÔ)ćÍ› u?ž?ž?˙ü ®\ą‚™™eË–ĺ˝÷ŢĂĆĆ&ÇLMM ¦]»vDFFRşté<ö0ś:uŠŤ7˘T*2d•+WαźÇŹ×WVçĎźgîÜąZŹgmű]Űq«müµźBQŕŹcjž~Ât®USó)tń’Ąx{wĆĘĘ Wg† ÷Ą[÷^|7ţĹÄłfÍâ믿ÎV>ă8Éh355Uď—5h;ÎłR(ZŹŰÜĆ_!´Ńˡë×p!<śŻżú<[ňµ`áÓŮ®ţŮ»»›>šą8zô(~~~š×ććć8::˛wď^Ôj5jµšÄÄD,--)]ş4—.]Ňż=–ń©_‰‰‰ÄÄÄŕęęĘăÇŹó,oii‰ąą9QQQ„††ęÜ^^ŞT©B\\çÎťŇßř3f%r‡Üú©ŹńyŃ´Ĺ °xńbhŐŞ>>>\ľ|Yłť ¤ĄĄeúŇL~ť>}šQŁF1räHFŤEĺĘ•óÜĆÜÜś»wďé °µµuľŰ ˇV­Zy–{޸´íwmÇmnă/„Úč4ĚęµëP*•ÄÇ'ŕăű!!ˇÄĆĆââć©)»w÷ěěl‰¸Â°áľ$$&`mmÍĚSôČćĆŤ9r$ÓEŰ bĺĘ•9rcccÚ¶mKť:u8p ţţţěÝ»—””7nĚůóç9pŕ 6$))‰[·nif˲.OJJâŢ˝{xzzňóĎ?SłfMŚŤŤY·nťćz¦ĐĐP,--Řłg­Zµ˘cÇŽĚ™3‡Îť;ŕďďOż~ýôż‰‰ ľľľ¬[·Ž 6 P(hÖ¬Ť5Ęqâââ´ö3ëřĽ˙ţűzécAsęÔ),XŔŕÁsŤ7cvŇĘĘŠÔÔTŢ{ď=M]^^^Lž<™"EŠĐ·o_4·gÔé×KAöń177géŇĄšo‘šP»vmZ´h‘cß  `ŐŞUŘŘŘă ˛š0aFFFŘÚÚŇż€ű™1•S\Y]»vŤ¤¤¤Źçk×®ĺ¸ß …ÖăVŰř !„6 @})<óWß+;Ő ââY‚öíbĐ°Ź‰¸x¶pz'rTŮ©FawA~ýőW €­­-jµšëׯ3kÖ,fÎśYŘ]Bť=›ën  ^ý†ާnýƬX6źAĂ>fŮâ9 >š¬yV•Ş5ő{ľâíQ˛dI–-[†ĄĄ% …ĄR©™ˇB‘;IŔ„˘ŻSĆBń6’Ű2 !„BĽd’€ !„BĽd’€ !„BĽd:]–ššĘŃcÇŮ˝{/ÇŹ‡°icú]Á·o߉ßňŘŘXy‹aCѵk ýQß˙đ·oßAa  aú šű …B!Ţd:%`!!'żHłfM ܢY~ěxĆĂ;ďTçŇĄĽ»ő¤}ű¶ššňÓĎ“)[¶,S&˙Lbbëü×ë=!„B׉N ——'^^žDGßË´ÜŰ»3+VŔŢŢĄR©ylGŕć­Ěüu*Ł>ťťcĆ|¤§® !„BĽž | š§ĎBs®USóđŮĹK–âíÝ+++nFFˇT*9~üS§LÂÖÖ–ń~|ţ^ !„BĽĆôzţ’ĄË¸vý“~úUj*>#†baaAŻžÝŮ·/HźM !„BĽv |#VµZťéőĚYsIHH`öĚéšr—*U HF€©©i¶í„B!Ţ6z™[ż>€ áá|ýŐçšä ŔĆĆš† ę¸y+GʧaĂúúhR!„âµĄÓ XPP0«×®C©Tź€Źoúő!!ˇÄĆĆââć©)»w÷ěělůůçřěóŻŮłg†F†LüaĽ~#B!„xÍ蔀5iŇ&MéÔ€Cٲ¬Yµ\§m„B!Ţdr'|!„B—L0!„B—L0!„B—L0!„B—L0ńĘ;xđ kÖ¬AĄR˝đ¶|}}ą}űö oçy-[¶Ś úäfÇşHIIaÁ‚šźÂđ*Śó«0B·—N Xjj*˙:ĚO?O¦[÷^šĺŰ·ď¤Oß>Â—ŽťşiÔ}řđQŞT­™éç×™sôx!Ž?ÎŚ3?>S¦LáŔšuááá/ô†şYëŻ]»6ű÷ď'--í…Ô˙¬ţýűS¤H˝´ó" 4“'Oh?ăăăĂđáĂ9yňä č]Ţrç}\eő*ŚâíĄSr‚đđ‹4kÖ„7nj–;„ńß°há\łźz÷îť-ŢV®\©yĽW^n߾ͺuë066ćáÇtčĐwww­ĺµŤgNýő—LËW­^KÓ¦ŤĺÔN!óôôÄÓÓ3ď‚@µjŐřî»ď8räsć̡iÓ¦´jŐ*DzńńńDEEáä䀓“ţţţšőmÚ´AˇPP­Z5VŻ^]ŕţ×­[cccRRRP«ŐDDD R©X±bţ©ďc¬M›6affF… ňÝnűöí100`Ŕ€ąÖďîîÎ?˙ü“cb”5Ţääd˘˘˘pttĚWßăă㉌ŚÔ$5kÖĚő‹ ąĹ•[?u‰WW...Ě1wwwŞU«FŹ=´–577ÇĹŅÇÓ¦MŽ=Ş™9Ě«˙ůń2Ž7!ÄŰŁŔ XÖk5fΚKBBłgNĎô@n•JĹ˙–-gýş‚żńŠ—ďňĺË8::Ň AŞT©ÂO?ý¤5ˉBˇČö{jj*¦¦¦î“BˇČTŻąą9ĹŠĂÇǧŔućĹČČHÓ¶.ífüČíôTZZÓ¦MŁk×®4lŘ}űöeZź5Ţ”” óu­TF2’.cccŚŤŤµ–×W^ý|¶-}źŽ8p ·nÝâüůóbffƨQŁ´–Ż_ż>ţţţ4lŘ ‹|ő_›ggĘ^Ćń&„x{čĺ6ë×p!<śŻżúHżî"((_¦LcűŽť\ľ|…3gĎňç¶ż ŘHxřE.ZĘü‹ż`˝zľ‹……ëüףR©čÜąc!„÷f*nk_ í>Lpp0;ć˝/Ž;ĆŢ˝{ ăÔ©SôíŰW3»qďŢ=6oŢLHHŽŽŽŘŘŘŕččH`` ˇˇˇÜĽy“÷Ţ{SSS¶oßΑ#GF©TŇ·oßvěuęÔŃş_Ž9Âľ}ű8yň$!!!tčĐ!ÓuY) âăă ĄwďŢ( ­ă\˝zőÇÁÍÍŤřřx¨\ą2§Oź&!!WW×oB×CF®pţü9Ęě˙¶Cą ś =†»G]BCłyëv˛ćYsćÎC¨/…źÉ´˘˛S ".ž%hß. ű‹g Ô ńbTvŞQ íT*S¦Lá믿ÖsŹr–’’ÂčŃŁóý­K!„˘°<›ën  ^ý†ާnýƬX6Ý™P IDATźAĂ>fŮâ9 >š¬yV•Ş5ĺNřo“ĐĐPÍ7ě^†={ö°`Á.\¸đŇÚB!^uzý¤xµyxxĽÔöÚ¶mK۶m_j›B!Äë@fŔ IĐľ]…Ý!„BIŔ AFň%IBńv’ě%ËHşťéµB!Ţ:'`†ŃŃ]¶śrť»i–)RS)Ű÷*ąÖˇ’»v?ţ On`hągš·ĆŃŐR>bký6ë7P±aS*ą{Qâ«oQ$'纼Äg_R©N=ťkS¦˙`ŚnߡĚŔˇT®ZÇw\Ňűôä'׉ˇäO¨äćI%7OŠý6_ł®Ě©\µ&Ć×o`‹Łsm*W­I%×:”oÓ‘"+WĂ“{fUhÜ‚ĘUkj~JŽůTSĎłÉץđ3ow–C‡BӦСCúż‡C—. P@×®pďÉ3G§LI_ÖĄ ÔŞĎĽv-sů®]ÁÁá…wýý%ďÓő÷®tžŰĹ0]ďJŮĎĘp+ć­~mE»Yíč1żńĘřôp“ş|(M§5ĄĂě4ťÖµZÍÄ?'ŇlZ3ÚĚlçë?E•¦âÁ˙Ăá3Ͷ ˙]Hů/Ęsţöů›B—C§Ěüŕ8ôę‡Íęµ\şBĄÂđî]®űʍĺK)˛r5Á°˙ć;b˝»pýŻ-Xîهĺ?»µÖozî<öß~ĎŁˇąą9«Í[)şp‰ÖĺFwîĺ·”››Öc~č0E-!Ę/}]Ě€¸vŚ+aÇňŚ­ä'_`|ý×ţÝÍý/>Ĺ )ý†• žO˙źyđҬ­‰é×€+!‡‰ůŕ=ě~ü™"«×jęş;m˛ć'ćýô˛Y“/ŕíNÂľřRR`ß>řë/°˛‚şuaăĆôőqó×/ľH˙wăFرľ˙âăˇB…ĚĺAËšő-đĂ@Öű¬×üŢŘ©1źř‚·›7ŰÇl§’}%~ţëçôľ E•ÂľO÷ń×čż°2µbiđRŽ^=ĘžO÷°cĚb“bůĺď_Üh0‘Ź"™şc*#šŽ AĺT/UýĄÄööî;,ŠăŕřűNé(°bG,{1ĆX"śFcš ţě)ćkLÔ¨Qc‹% AĹD±°c (VPQ,ŘLĄpwż?VN»Ł q^ĎĂăÝěěĚěŢÂ}śťťA^ľB`é­Zr=,””w»ćH×pc_(##2ëH—ÉźÎ8-ËĘÂôÄIä)RĎWFýëŘYěÜ  É={Y»M›`ąs—Ţt€„µżˇl怺ś´ŕ®Ę&çbŔň¤ÇX„ţ•#łí÷ ě´ďŤ®^Ĺ<"’GÇ W¦“ܧ7˙L€éŃc¤vęDf-[mP©U¦ IźJfÝ:”_÷l©Ą'n}´?é­Zę ľ˛˝‘AZ 0~ĽÔ{°cGÁöµ˛z¶Ź.ëÖ˝xűň±nxŢ:6xn@ĄV|"WGWܜ܊ B­Qp(€ńďŤ×.-´cĚ–…/cÔ;ŁËäČd2|şú°l˙24 ޵ůyĎĎÜř÷ĆK?Aˇä*Óţň*ř­&łv-Rßy€Äéßcvč0¶ý>â‰[”Íôîktë6đ,ʲ±ĆčĆM˝éeîPuÂdjüŚG#†óČs¸¶<«5Ôíü]•ٵĄ%ŞçÖ¬39-Eĺ6Q§Ó;Ôm×Ë]ˇ÷lśLŇŕAÜص5OŻ[ÂÚ߸vô ö˝<=]*«\9®?LVőjTţi> ÝvLkߎ´í‘''c{:o»Ő0–9ľąk×ţMjÇŘüoĺ¶ü <›a7÷,öŮďߨŐň âő €5kŕŰoónS(`ţ|Č — Üë Ęd24 ˛<đÓü2Ýż~jŤ4~rşŰtvÇíćŔĄĹŰPAˇÔ[fw뙳HXűY5ĄÉĺ7nĆčĘUţ÷$¬ö#Ą{7¬ü×ę-#óéšjeĄÁ×eek«7@mnNZűv$ÎüyJ ĺ×ć(3«fMîĎťŤŐďëőÖ›Uµ éÎN¨Ë—#Łq#ĘÜ»GŮ»÷0ľzŤZ˝\±ůZúŇ7ŹĚőe¨Ń`|ń"J‡g={z{`vôŮ­ĎÜAŘ|4¶«R%8[€ăöő}özĆ řđCX˛$oľŕ`ŘşUwĎX ±¶´ĆÂÄ‚„G $}‘ĄĄcvěĘćÍrcî ěŤ ľ@ę6Lzš1»Ç꼞'üÂĂsľź4 ,€GŹňćmÚŚŚŠµ©…!—ÉQ8)ŘvjŰc·Ó·E_d2Ă: cúöéd©Ąă=÷<#ßɲýË´=^+#V2Ňe¤vśŔ¨wFń$ýIÉŚ ‚đRj)"‹°pŞŚ›¨ť˘žc+2š6áŽßŻ]˝* f˙;€Ä™ßóxŔ‡]şL•)˙I™(ťą·pľŢň3Ů“8c•,¦âÂĹ$÷ů€‡^žhLLt¦¨*Wƶď4ĆĆ<ů°/ʆĄ†»4¬‚˙Z*ččq+ó(‰2ţŃľ×™rwŮlţ7Ťz­; lÚÄgPm„7eđp¤'Ćâ1Žż<- ÓS±Ňń·jOfÝ:Ü]şTiĚ›ĘÚšz­ŰŁ67ç‘ç0’>§ţËĎj<cMźcÇ‚ł3ŘŘ@­Zŕí 3Ą§µO3ž;'\ ő†yyÁ»ďÂŕÁ°x1Ś-mS(`ňdčСDšż2bĄ6ĐR,Uđűđß±0±`Ţ€y ňÄöŘí™0,@:\ĹtĆn‹óÎŘ”łˇVĹZ¬˛š„¤şýÜ Ł2F4­Ţ”)˝§đŰ߼ÉŮ„ł4­Ń”°öţžcAáő#4ąźĚË"Â÷2ÄcĚ›(Ľ‚rŹ#AáĹ<ë˙ą…ví;©ś¶í;ŕżś!cđ_µXç vöb&|AA„’&0AA„&°R"n# ‚ ›K`Ą ÷4‚ ‚ ĽYDVÂrO?!‚0AAxó*ËĘĘâĐá#Ě9›ľý>ҦďŢ˝‡Ź?„çozĐ—ŕŕ­ÚmgĎžĂ}îC=đňMJJŠÁ:î'&ňĹŕa ć‰Ď豤ĄĄLĎćëçOÇÎ]ó-Gź´´4ľüj ݇ă>ÔUľżi·ůý¶š÷{öŃľź7vö ÷Iß~1aŇW÷ýĹR}–ôAć!C±TéHSjY›ŃëGkóí‰ŰC9źr üu 2®ż¸Ňě»fLß>]›çNŇşýÜŤ {ĐyR”)ąz×_\µe?H~đŇŹIA(Y… ŔbbN—.ÜĽyK›~<:†ď¦NaĺŻËX´pSţ7 ĄR Ŕ„I_1yŇxV˙¶Š&Ť±hńRuĚšőÝşuĹßo%¶¶¶,]ö«Át€«×®qút\ĘŃgĆĚŮÔ¬Y“5«}Yľt FĎMčs‚păéú“'Ś`é/ ٲyr™śé3f,GßÄ«olöĺ—™)M´şs'XZB۶$m–fĚĎΠҶĐP6 RR NťśůźÍö’Ź f“×&ík…ł‚ :°ëô.íšźA'‚¨Y±&#¤Ő‚ĽĘ´­ÓHQJ˙™°qnNně»›z6őąs&mëµ%Č;H[vöĚř‚ ÂGˇ°6mZ3ř‹Ďidoź#ÝÍ­uëÖŔĆĆĄRIff&JĄ’‹/Ѩ‘”ßĺí.üµwźŢňU*í ăÝ®ďĐ­[WöěŮ«7@­V3kö\¦|39ßr˛Íš=;űgK)•J‚C¶Ń¸±=>ŁÇ2ç§y(®$%=ĆÜ܂Ν:¶?‹ĚĂÄÄD›Ţ˘…»v„°rĹRš6ˇ~ýzzˬX±fffÜ»w€{÷©UËVoú©ŘÓ\»~ť^(čŮŰŤĐł·ff¦:óëS­Z5ŚŤŤ011AŁŃ R©8î<_}ý-ß|ű¬¬ŚžoľžśçőSľťFVV*•Š ›«·*Gcärşż÷®v¬ŐţýátŻ›ŢôŢ˝z˛kGöÇÚÚš];B077×™?ŰÖm;0ńKíűňĺËѱC{‚C¤Ĺ•ŹʦcÇöDGÇđá‡}Y±l +–-ađŕAěË5LĄRńë*?>8+«ň:ËyŢóAŘ|Ô6lô4cvŹŐůóşó†‡ç|?i’´8÷ŁGyó6m Ď=ýŘ`_}9‰‰“ľ"l8&&&Ěź;Ű`:Ŕţđż ܸ™‡2aŇWĚź;Ű`ţ¸¸ł„lÝžă6äĚ™ß3iň7„……S¦l¦?• “ľÂÔÄ”!î_ R©ŘĆůóńx&%ŕ3z÷iŮÂzËÉíR|vöofđ•mút;śťÁĆjŐoo9SÚžý4ăąsRŔRo—Ľű.  ‹Ăč§Ó>(0y2tčP"Í_±R8)–*XüÉb˘.GÄ4×i„ťăöĂŰ ň$5?ŇŻ·˝x·ń» ţm0!>!Ě0ŹA~Ř»S#S†päęfîÎË\é<ś»s®DŽKA(2@“;hа)—/ž%"|/C<ĆĽ9Ă_oĚÓ’‚ ‚PBžŹu‚˙ÜB»ö‹TNŰöť đ_ÎŹ1řŻZ¬ón—ť˝ _Aˇ¤‰LAˇ„‰¬”軍8oţ1 ‚ ülj¬d_ş‚°żúňÝ´é¨Őę’n– ‚ %D`%,÷˛Dş‚°?Ö2qŇWd•ň¤˘‚ ‚ Ľ… Ŕ˛˛˛8tř3fΦożŹrlSôűaĂ˝đđôĆ­ďvîÜ ŔýÄDľ<Ś!Ă<ń=–´´4učËź_9ľ~ţtě܀ݻ÷đń'đáMďúĽ5ßcKKKăËŻ¦0Ř}8îC=Xĺű›v›ßo«yżgíűyó`gďŔpŹ‘ôí÷&}Ĺ“'O8rävö9~~^°X»_îŕËP¶uŰĽ}ţŹôôô|ŰţZJM…áĂáí·ˇW/éß#GŔŐUš'Lˇ–,3GJsu…fͤ),®_Ď™_ˇ[ýî—Ď}?G±TAź%}yČP,U`:Ň”Ú_ÖfôúŃÚ|{âöPΧĚC†ë/®4ű®Ó·O×ćą“t‡n?wŁÇÂô_Ţźe ţý‘yČŘ~?űĎďGć!cU䪗~\‚ BÉ)Ts‚řř‹¸¸táćÍ[9 ’Éđó]ÁŞ•ËřqĆ÷|=Eš˙jÖ¬źčÖ­+ţ~+±µµeé˛_ Öˇ/żˇr®^»ĆéÓĎń<ĂwS§°ň×e,Z8Ź)˙›†R©4Xł©Ył&kVű˛|錞›Đ3&ć<ŕĆ i=ɉưô—…lŮĽąLÎôłhÓ¦ÎĹj~Ôźîď˝ ä ľ˛ ÂÂÂÂćáEJJŠÁ¶ż–ľü23Ą‰VwîKKhŰ‚ž.F,Íźť¤mˇˇ0m¤¤@ť:9ó?›?ě% Ě&ŻMÚ× gt`×é]Ú1|A'‚¨Y±&#Ą÷ŢA„Ž eÚÖi¤(ĄĎtÂĆ ¸9ą±{ěnęŮÔcćΙ j/ÍöNăwx§±´ ü vJä¸A„’Q¨¬M›Ö ţâs=]rçyA[µŻ322°±±FĄRń×Ţ0Ţí*}‰tëÖ•={öćŮ7›ľü†ĘQ«ŐĚš=—)ßLÖ–ăćÖ‡şuë`ccR©$33S»}ÖěąŘŮ;hß+•J‚C¶Ń¸±=>ŁÇ2ç§y(®$%=ĆÜ܂Ν:igÖž\.ÇÓc(;w…˘V«)S¦ eĘ”áČŃcŘŘXÓ¬™Ţŕ+›ˇ ěČ‘c úb(ŹtÍüţşR«ĄuÇŹ¶.äŽŰ×ĘĘđZ’ëÖ˝xűň±nxŢ:6xn Nĺ:śşu •ZĹ퇷óäł2łŇ®ŞR«>Ś«Łt­ą9ąô[.‚ Ľ*Šľ$9źÔ‹‹;ËÓÄgôX¦N›ŽďĘĺüűďCŇÓÓ©Zµ U«TáĆÍ›zËÔ—ßP9ż˙±÷ŢíJ•*U´ĺĽŐĚ333VůúáćÖKKKív‡¦¸ą~ }ëvJĄ’ččü4çG*W®ĚÔď~ "ň]ştÂĺí΄……ëlwÝşuHOOçáC)HĘČČ`ń⥌đH–L&#"|Żv ČlŮi2™Lo€{ú ź|6ű‰‰zĎÝkĺÁHJ‚ĆŤ ·ß… 0u޸éZóqůrбXzIrur%äd‡®˘}śËP]¸{©!S˙Ţx,L,H|’HZf5*Ô †U ®$^ŃćW,U XŞ(Ńö ‚ %ŁŘáŰŰ7dĚQŚíMíZ¶řŻ Čł.¤L–wďŤŃ“__ú­[·Š:L=ëKúúůsýĆM~śń}Žt×>˝s,C¤z:ŘÝkÄpĚÍÍůh@?ÂĂ#ř;"’Îť;ŇĄK'ŽGǬă ^ĄRPÖHZŮé÷?6đöŰťµA č^»0 r_Ľx‰ ľ4çµa¨Ë€Xłľý6ď6…ć϶¶d)quteëÉ­ĹŃ×9纎‡Xµ†o{KíĎ{]Ërü~Ź &xTđËo´ ‚PâŠŢ–+ş?‘ VV4˛·çËÉŮ´i +VŔĚĚŚ{÷îpď~"µjé$­/żľôS±§ąvý:˝>PĐł·< go7ŇŇŇY°p ÷îÝgŃ‚y<–jŐŞ`ll €‰‰ Ť•JĹůsçůęëoůćŰď¨`eEdäÁ<ű_şt™*UŞ`Uľ<*•Šßü×ĐWá–7źŽ ¬  r7lhÇüůsňÍ÷Z°¶†J•ŕl–¸ňő}özĆ řđCX˛$oľŕ`ŘşUwĎX Şg]ŹLU&ŃףiR˝IŽm3úÎŕò$LjżµĄ5&$+hđŐü­f¬˙} UllňÍűZÉ`Ř0éiĆě«óçuç Ďů~Ň$iqn]câš6…çž(-ýZôĂĄ‘‹Îm“zLbÁŢϤ$|FŹă~b"-[8ă=Ň€C‡S§NmÇx)>;{‡_m۶f劥X”rĎN±›>ĆŽgg°±ZµŔŰfΔ¶g?ÍxîśpÔćĺďľ ĂâĹ0úé´ Lž :”HóWF¬ÔNŠĄ ˛¨ËQĹ1Íuaçøýđ6ü¤'}#}ńzŰ‹wżËŕßâÂĽóä7í±Ű152%`XËĂ—°óôNm}ËĂ—3î˝q%rl‚ ÂË'4ą ›růâY"Â÷2ÄcŚŢÁáBń{ţéĚ®]]XĽp>¦¦¦9ňč[ĆHA„˘y>Ö ţs íÚw,R9mŰw&Ŕ9C<Ćŕżj±Î»]vöb&üW•kźŢ,űeQžŕKA„ןŔ^Aź~2ysgS¶lˇî ‚ ‚đšßđŻŻĂ™0~¬v˛NAAţ{DöŠÉ^ćHA„˙.q Rx-lÝş•ňřńc-Z”g1ö¬¬,öîÝËĺË—_z[233Y±b…öçUËP«ŐĄRIž˙¨¨(ÖŻ_ŻťůU ďüçwÝ ‚đć*TXVVÇŽGłoß~˘Łcř3hŁv›˘ßGT®T ą\ÎýÄDFx Ł{÷nzó B||< 6,ĐíÖ‡bnnޱ±1.\Č1ą®Z­fĹŠ4oŢśúőë©|}’’’X˝z5eĘ”ÁÄÄ„ÁcllŚ——jµź"—]śíqpp`÷îݬ]»–Áç{ĚQQQ>|ŤFCăĆŤéÝ»·ÁtCJúü·hŃ‚uëÖѿʔ)S䲋«=†ÎżˇëV„7[ˇzŔbbN—.ÜĽy+gA2~ľ+Xµr?ÎřžŻ§L5_.\hpiŞç•/_žrĺĘabb‚••UŽ v8@ůňĺéŇĄKŽ/ű”ŻĎ–-[pttÄÇLJʕ+łk×®*ďEékO™2ečŐ«Ź?ćÔ©Sů–ł}űv|||đńńáŕÁů¦RŇçż4ź .ěů7tÝ ‚đf+TX›6­iÓ¦5‰‰ňl Ú¨}ť‘‘ŤŤµÁü«aßľ}ś;wŽÔÔT*T¨€§§4ˇlXX'NśŔÜÜśÔÔTZ¶l‰‹‹‹ŢôŘŘXÂÂÂ011A©TâîîÎĄK—X·n :”ŔŔ@LMMQ(DDHkm.\¸™LĆŔ©QنŢvvéŇd2#FŚČ±-22’jßGGGç)ßŃŃ‘-[¶0pŕ@BCCqrrâńăÇdddĐşukťíüţűď9uę …´ ¶ŁŁ#ëÖ­ĂÍ-ď2S%A­VlŹL&ŁC‡DFFâääd°,KKK._ľĚéÓ§qÉžôÖ@ş!ĄuţŁ˘˘ŘłgNNN 0 @m}E9˙†®[AŢlE„Ż!{  IDATç˙lăâβ%(ű÷ďsýĆM|W.7_xux{{ŁV«3f jµą\NHHłgĎĆĚĚŚÇŹ  3ýŃŁGüţűďLť: öěŮChh(¤E‹řřřpďŢ=ć̙Ò%Khٲ%-[¶ÄŰŰ›±cǨW rĺĘÚ×uëÖŐľÎĚĚäöíŰÔ¬YS›¦Żü]»v‘śśĚwß}Çřńă™4iK—.eäČ‘:Ű™śśLff&VVVXYYńŕAá˙3qđŕAţţűďiVVV899éL5j”Îr Ň[[[®_żn°=)))±dÉĽĽĽhذ!‡¦|ůň:Ó«WŻNť:ut–Ušç_.—3yňd¦NťJ˙ţýőŢę,ÍóŻďşA(¶§ íí2fĚ(îÝ»ÇâĹKń_Ŕ÷ß}[\Ĺ /‰łł3ýőIO—WĘÖĽysćĎźŹłł3Ť5˘˙ţzÓcbbP©TđčŃ#ĚĚĚr”׳gOär9.Öö§§§ř¶T÷îÝ)[¶,¦¦¦Ô©S'Ď-˛çŰ™ű ]&“é–ZÇŽéŘQ÷ŚĘúŇu)H{LMMóč˝qăF [·n%&&†ĆŤÍíŰ·2dHžô÷ß_oYĄyţ۶m‹‘‘™™™h4˝Ř«vţAŕEzŔrýáą?‘š5kPÁĘŠ/'O¤G/×Ř‹ŽŠźZ­fîÜą( :věHřs _»»»sçÎÎź?Opp0¦¦¦řřřčLďÚµ++VÄËËKo]Ů˝ *T(Öc055E&“‘––†ąąyľůł'·Ő÷eý|;5 ĆĆĆ$%%Q©R%=z„µµuˇŰX\=0–––ů¶'---ßuC/\¸ŔŕÁqwwgöěŮDEEˇŃhČĚ̤AyŇ őÜ”ćů—Édŕ˙ŞťA(ưgÍaé/‹i°~­Z¶ĹU´PLŽ;F\\îîî€ôe‘””„ŁŁ#˙ţűoŽĽ«V­ÂËË [[[ÚµkÇÔ©Ső¦{zz’śśĚąsçhҤ Ť†¤¤¤|-ą\Njj*ćććdffé 1###j׮͍7hܸ±Áň K&“áääDll,...ś9sGGÇB—Sś=0ůµçĆŤ9žDÔĹÚÚš¸¸8Ţzë- ÄŠ+čÚµ+ééé:Ó ­Č ÎáĎż 2‹8ŔQ*•¤¤¤âĺ=€‰ăÇróÖmţ"..]Ţšc›\&ĂĎw ­ ůéçî čߏď¦NˇI“Ć\şt·ľčŮóý"M¸)‚ ‚đ_Q¨¬M›Ö´iÓšÄÄĽ m ÔľÎČČŔĆĆ7·>Ô­+=’nccR©,ňŚç‚ ‚ ˙E_ ’śk;ĆĹťeKP0÷ďßçúŤ›ř®\® ľVůúáćÖKKˢ·VAá? ŘáŰŰ7dĚQŚíMíZ¶řŻ ĐnóőóçúŤ›ü8ăűâŞNAáµUä,{Ľl÷ď'RÁĘŠFöö|9y"›6m`ÁÂ%Ü»wźE ć‰[Ź‚ ‚ cŘŹłćh_ÇÄś V-[6mÚÂ…řxľůz2rąńBA 9,"âlD©T’’’Š—÷h&ŽËÍ[·ńáMzş’̬,-śĎÓäĉ“4wj­-c˙ľP¬­+ďQ‚ ‚ ĽF €ué҉.]:éܶ5xsž´?Ö­.RŁAAţËÄ}AAA„&0AA„&0AA„&0AA„&0ˇŔ˘˘˘Xż~=*•ęĄ×ĺííÍÝ»w_z=%YoTTłgĎć—_~aőęŐů¦żé233Y±b…öçURZ×çËö2Ž«¸ţnäzđ÷÷gĹŠdeeé-'22’őë׿P[^–’lXX‹-2X—đr*ËĘĘâĐá#Ě9›ľý>ʱMŃď#† ÷ÂĂÓ·ľŘąs·ÁtáŐµzőjV¬XÁňĺËńööfĹŠ|ýő×´hŃ‚ČČHÔju±ÔźgBßl_|ńVVVĹROaĽĚz·mŰưaĂđńńÉńe¤/ýMgdd„——žžžÄĆĆ–vsrĐuťč»ž ]çš8Ë/ĚqTqýÝ(Čő0dČbcc ¶×ŮŮ™ČČČjËËR’íďÚµ+.\x©×¦`Xˇ°ÄÇ_ÄĹĄ 7oŢĘYL†źď V­\ĆŹ3ľçë)S ¦ Ż6///†®}mgg‡©©i±Ö±páB˝żüíÚµĂĚ̬Xë+—YoRR*T`ذaů¦ Ż.]׉ľëŮĐu^ŠłüÂWA÷ߍőşŻČňş·_x¦Pó€µiÓš6mZ“ř ϶ -Ú×ŘŘXLJ^PP{÷îeٲeóą»»çI{>0ŠŠbĎž=8991`Ŕbcc ĂÄÄĄR‰»»»6¨Č-::š@úă.“É8p 5jÔ`ĺĘ•¨T*Nź>ͲeË8ţăöíŰěŰ·€%K– “ÉčŐ«JĄRgzŁFŤô–ŻŹľvęjOĺĘú'BŢ·oçÎť#55• *ŕéé©˝năsß°a‡FˇPŕââÂćÍ›‰ŽŽfĘ”)XZZć)ŰPţ#GŽä©Wźýű÷łiÓ&-ZÄ™3gXµj‹-ÂČȨP×áO?ýDÍš5ůä“OHIIA­VóÓO?ŃŞU+ţţűoť×Ź®ëDßő|çν׹®v†……é<Ďúú=*ěç^ăŞQنŢr ýľčú»ˇ«ť±±±z?_}._ľĚşuë066Ö›'·Ó§O„R©dذa4hĐ P×ĎńăÇőţťŃWŽ®ßŻâlżľňďŢ˝K`` FFF<|ř^˝záěě¬-k˙ţýlßľť÷ßźîÝ»¸ ‹)úZäüQ\ÜY~ţ#>ŁÇ2uÚt|W.7.”ĽZµjѦM›.G.—3yňd8€FŁáŃŁGüţűďxxx0räHš6mJhh¨Ţý[¶lɸqă;v,ăĆŤÓţQ÷ôôdÄÚĽŤ7ĆÜÜśäädľűî;ţţűoşuëĆŐ«WőÖŰŞU+~ţůgîݻǜ9s°¶6řç®7[HHŢŢŢŚ9 –łzőjzôč··7-[¶$00ćÍ›kŹwôčŃŚ7ŽFŤéM/ }íÔŐžüx{{3~üxNž<‰Z­¦_ż~@ŢĎÝÍÍ @ű‡ĽiÓ¦ôęŐKgđčĚßłgOmţÜőęóÎ;ďh_?˙%RŘë°YłfÔ¨Q‹/2cĆ Ę—/Źťť}űöŐ{ýčşNô]ĎúŇőµSßyÖÇĐďQa?÷—!†~_t—®vęű| Yż~=ü1_ýuň$$$0uęTúôéĂćÍ› }ýčű;“_9ş®óâhżˇňýüüh×®ŢŢŢôîÝ›¤¤$m~•JĹ•+WđńńÁW +T!öö 3f÷îÝcńâĄřŻ ŕűďľŐ›.”ĽÖ­[Óşuëü3ćŁm۶‘™™‰FŁáňĺ˨T*é‹°¸oăuďŢť˛eËbjjJť:u \oĎž=‘Ëĺ <¸Hő6oŢśůóçăěěLŁFŤčßżżŢĽ)))$$$аaC6lČĆŤ‹Toq´ł(íqvv毿ţĘń:[îĎÝĚĚŚćÍ›säČşwďNtt´Áó“;˙±cÇ´=!†ę-¨Â^‡Ő«Wçüů󤤤`eeĹ˝{÷ňÖ ţs &˙ŻPńODř^†zţ™™ř/gÇüW-f¨ç˙‘;βłw(ľAř«ďäÉ“Ú'­„Wßëđy8p€°°°|ź2ArؤeË–ĄÝˇ^‡Ď«S§NtęÔ©´›!‚đRD„ď}ie‹LA!——ýô°ŔAAr9±ďĄ–_lÓPBnQQQ¬_żľTö÷÷gĹŠdee•ZA!·B`YYY:|„3gÓ·ßG9¶)ú}İá^xxzăÖw;wîαÝ×ĎźŽť»ľx‹…×F‹-ŚŚ,ĐdŠ/Ë!CŤŤ}©‹! ‚ BaędLĚ âă/ââŇ…ŕŕ­9¶Ée2ü|WŇúŹź~îNŻ^=¸zí§OÇĺ)Ořoł* ‚ ‚n… ŔÚ´iM›6­IL|g[Đ–g‹˝fdd`c#=–®V«™5{.3~řŽľ~ü‚Í^DPP{÷îeٲeóíßżźM›6±hŃ"Îś9ĂŞU«X´h۶mcďŢ˝ 8={öŕää¤]ËďîÝ»bddÄÇéŐ«—ví±¨¨¨<ů÷íŰÇąsçHMMĄB… xzzjŰ—»üóçĎł}űvĚÍÍąző*¦¦¦Ô¬YS;ÉiXX&&&(•JÜÝÝ©Pˇ—/_fÝşużÜ“*‚ EPä1`rŢ҉‹;ËÓÄgôX¦N›ŽďĘĺüţÇŢ{·+UŞTy±– /¬V­ZZ.ćťwŢѾ΢íśTrąśÉ“'sŕŔí­=???Úµk‡··7˝{÷ᬮüŢŢŢŚ?ž“'O˘V«ő–żzőj>ţřcĽ˝˝ůꫯP©TxyyˇV«ůý÷ßńđđ`äČ‘4mÚ”ĐĐPÖŻ_ĎÇĚ×_ýgLA^Žb{ ŇŢľ!cĆŚâŢ˝{,^Ľ˙5x s'*ę0Ë–.*®j„Đşukíú{/˘m۶‘™™‰FŁ!55•Ű·ok5‡ďsç—Éd8;;ó×_ĺÔôĺW©TÚž¬2eĘh ľ|ů2*•Š€€=z„™™JĄ’„„„|—pA„ŇRä,÷ ćű÷©Ył¬¬řrňDzôrĄMë–\»~ť^(iM±ž˝ÝÚ™™ô:Đ5€^&“ĺE.—:Rł.##Łk‰ĺÎŻV«™;w. …‚Ž;n°|WWWćÎťKýúőQ©T :™­X±"^^^9öONN¤`M ľA^EĹÖöă¬9,ýEę銉9A­Z¶ôîŐ“Ţ˝zjótěÜ•];BŠ«JˇŽ;F\\îîîůć566&))‰řřř|óš™™Qż~}öďßOĎžŇçťžžŽ™™™Îüiii$%%áččČż˙ţ›oůgÎśÁÇLJ:uęäH·łł#99™sçÎѤI4 IIIXYYaffFBB‰‰yR-ĚyA„—ˇPXDÄţŘR©$%%/ďŃL?–›·nă9›ôt%™YY,Z8_»ßţđż ܸ™‡2aŇWĚź;»xŹB(›7orěرť;wfţüůÚ€jË–-T«V Ö(´°° ,,ŚnÝş1dČÖ­[ÇŃŁG122âý÷ß×öDéĘßşukfÎś‰FFFR˝zuťůÍĚĚđóóÓ>UillL‹-čÚµ+ŢŢ޲yófd2...tęԉ޽{łxńbúôéŔĆŤůěłĎ´çáčŃŁ"AJŤ Đä^Ą»Aæ\ľx–đ˝ ńS¨ŐŔ…—ŻAæEÚOĄR1gÎľůć›bnŃËőóĎ?3xđ`*W®ŚFŁáĆŤ,\¸ ”vÓA„˙çcťŕ?·Đ®}Ç"•Ó¶}gü—3Äc ţ«3Ôó˙ČgŮŮ;ĄŢ$'OžÔ>iř:©Zµ*ţţţXXX “ÉP*•|ńĹĄÝ,AA(2€˝AZ¶lYÚM(’ě[‡‚ ‚đ_!Ö‚,%á{K» ‚ ‚ ”€•‚ěŕKa‚ ‚đfX Ëş†zţ_Ž÷‚ ‚ Ľ9 €•IL¤‚˙jőé›#˝Ę¤Ż¨×ŞőßjAŤ/†Röî=ętîJ{íOŐ± –_~Ófęv|›zÎm¨ňő·Č22 ¦ VS㋡4°wČYľôÖ[Ă}8 ě¨ß¤9ő[idYYÔüdôŢą Ö?Ě„ç&,­1Čťöݸ™ŁŽçŻKńqoföĎ?P»6Śý,mĎ(W˘ŁaútpqîÝaâDP©ŕ˝÷ŔÖvď–ňŻ] 5kÂĘ•ŕę 2(đŕéĄmŰÂřńĎĘż{ęÔ“'‹ýpćÍ“š°y3tî }ú@óćđt‚~AAČŁPYÔ!l?úŚňlŔřBÎ :ËŢ»OÂj?nýą łĂG¨°ŇW»íţÜŮÚź¤Ď?Ń[ľÉąóŘ|;ŤGÇr+d –!ۨđ«ŻŢôlĺ7az<:OyúŇ ZoÂj©Ž¤Á¸zę8WO—vP©(s˙>׎"aŤVëţŔü@ňÔTLÎ_Î×Ú:r_Ŕ›„U® :Ŕ®]=K}PPť8ÇŽAX„†Â“'0k|ű-”/=zHů čŮ<=Ą}‚ÁZZž®]ĄH(>†…jŐ S'pr*ÖC‰Ź‡ăÇź˝?p–,mŰ`Ă©yééĹZĄ ‚đQ¨,˝UK®‡…’ňn×<ŰÖţ†˛™ęr–¨l¬µŰž¸őŃţ¤·Ň˙$žĹÎÝ ŃÜł™µk‘Ń´ –;wéM({ű6•~YFŇĐÁ9ĘŇ—`Űb†ĘĎ&OzŚEč_\=uŤ‰ 7ö…˘12"łNmiűăÇ=Fj§NdÖ˛Őeş‚ŻlodRŹÔ©SR×íŰRÚ˛e0jČĺRŻ–ŹŹ”ÖˇÔ‹uů˛”oĎx˙}ýe×® 7nHŃQHČł@Ż©ŐRÝĎ??KűüshŘPz]˝ş|=ßQ+‚ Ů €iŚŤĄ/FĘ&ܡę„ÉÔřŹF ç‘çpÔ–ÔkŐŰ~Q>p“Á/CŁ[Ňqvđ–ecŤŃŤ›zÓŃh¨2ĺ;ţ5’Ěš5źk¨žô§Ô––¨*TČ·ŢlVk¨Űů*ţş*OYüV“Y»©ďĽ €ůÁC¤vlOZűv>‚,+‹..Ýâ1Fďş„Ť†!cčâŇMďąůĎqu•‚ŁC‡ }{)ḭ́ł{–ÇŢîÜÇŹĄŻmۤôĐPĂXť:R -ZŔőëĹŢüeËŔÍ jÔx–ÖŞ<ťŔźź~’˛ňĺ‹˝jAá? Řá«+Xń¸?Ň›żEůuë1>w€›»¶qíŕߤvě€Í˙¦QnËźú ÉŰi4ŇŹžôň7SćŢ=Ň[¶ ě˝ű]ąŞ7=[ÂÚ߸vôŮíA˝ő>•4x7vm%ŁAýŮ,öěĹrÇNÖřˇ~úÍkvŕ iíۑ֡=ňädLbOĎfŘÍ=‹}öű7nµWWŘşUş…Ř÷éxBąžËQ­†>0• ’“ G6µkKAףGŇx˛˝{ˇJ•bkúŐ«°oźtwS—yó¤ÎşUyăuAAŠ337'­};gţ€<%…ňëµŰ4&&<ôöŔěčq}EY[şťW&QL]6ńY¶¶zÓÍ˙ŽŔřňjőéKĹe+¨1xŢôÂÖűĽ¬š5ą?w6VżŻŔ$î,Ö3g‘°ö7˛žö˛•˝{ă«×¨ŐË›ŻżŔ<ň€¶ŚÜAŘ|Ô«™™ŇŔű&M¤´·Ţ‚K—žĺąrŞV•ĆvőčQQRďW»vúËőő}v ¤Ńđ۶I˝bĹäčQ¸xQjnłfŇÝŃfÍ 5ţ÷?éŽę† đtéJAAȣذZ(0ľx ă‹Ň8UµŞRzźľČŇŇ1;v eófzËHîů>ČdXî Ĺčć-ŚĎž#ąw˝éw—-ár|—ăăHü~*×#Ăô¦g«>Ôşşä[Ż–FŤLĄB¦RQů§y RQuüd2ěí1;rŚrAÁ]»†ŮÁ(’}¦°źîŘł§ăŔ˛ĺÂŢČŕ+[ż~RU¶‘#Ą{{ŮO”®\)ĄÉdP±˘ôtă¸qRo>ááRďXBŘŘ€Ł#üő— #pô IDAT”“Ą»ĄŮ?ŐŞI˙®_§OKăÂôuć ‚ r)"‹°pŞŚ›¨ť˘žc+2š6áöúT•+cŰwccž|Ř—GĂĄű3*kkęµnŹÚÜśGžĂHúd Ţň3Ů“8c•,¦âÂĹ$÷ů€‡^žhLLt¦głí÷‘ö©ĚîõO/ęK/ó(‰2ţÉ·ŢîŇ8¶ ţk©ŕżV›_®Tbtő*FWŻbţw‰3żÇĘ-eđp¤'Ćâ1Žż<=ÓčŇ[¶ĐîůâYí‚çośţ‘z˛‚‚`Ú4)-,Lę6rt”§nÝŔČš6…)SžíۧřůAŇű#G`ćLéuv wîśôݵµT^­Z`l\¬=`Ůvěn3>xÁ͛Ҷrĺžĺą|YęÄA„çÉMî'ó˛đ˝ ńóf ݰÜăČAAx1ĎÇ:Ánˇ]űŽE*§műÎř/gÇüW-Ö9‚ť˝ _Aˇ¤‰LAˇ„‰¬”Ű‚ ‚đćX)Č= … ‚ o€•°ÜÓO LAŢ<…š†"++‹cÇŁŮ·o?ŃŃ1ü´Q»MŃď#*WŞ„\.ç~b"#<†Ń«WŇŇŇöý îŢ˝‡L.Łc‡öx ×3…8p?1‘‰ż˘LŮ2X›3÷§Y™™éMĎćëçŹ˙ę>ťď«°őęĘćĚYvěÜE×wŢF^¦ ććTŻ^Ťżúâňvţůçę7¨Ď´©S(W®śÁzs_ŮÓQĽQSRüó8;Këř,Y"ĄíŮ~(Íáµs§4ÍĽ±±4‰ęś9Ň$¬çÎI“¬öčk×Â×_Key{?[ńî]i®°Ĺ‹Ąé*¶m“ęi]Č[·Šĺ>÷ýśde2*µŠí±Űqsrc÷™ÝT)_7'7–|"מ¸=|¸üCz˝Ő‹ŤÇ7ŇDZWŻ0°ő@ţ÷Á˙¸“t‡A~(+/‹Ą‰%k†®áLÂfîɶSŰpsrĂw°/Ö–Ö†š$‚ Ľf Ős‚řř‹¸¸táćÍś_fr™ ?߬ZąŚg|Ď×S¤ PgĚśMÍš5YłÚ—ĺK—`ddd°ŽYł~˘[·®řű­ÄÖÖ–ĄË~5pőÚ5NźÎůgaëŐ•ŃÂy,YĽ€Ë–°bŮŞU«ĘÄ ăXúËB¶lŢ€\&gúŚYëŐ7ńę×Vą˛´¸ö®]Ď–{ ‚š5áÄ 8vLš,4ž§‘˝}žmA[ž-=”‘‘ŤŤ5JĄ’ŕm4nlŹĎč±Ěůi …«ŢňU*í ăÝ®ďĐ­[WöěŮ«7@­V3kö\¦|3Y[N~őΚ=;{‡çHMMĺÜů Lš8>Gş\.ÇÓc(;w…’ššŞłśüf˝ă‚0&F=uJZŰń¶´:Ë–Á¨QŇ4ň2řřHi:H˝[—ĄUŘłGZŚ;{ɡăÇĄ…˝ ,ôÎşuĹÖôuĂó–µÁstX•ëpęÖ)Tj·ŢΓĎĘĚ ŮÓíUjÁ'‚qu”®57'7‚b‚Š­ť‚ ««ČcŔ4äü˛‹‹;ËÓÄgôX¦N›ŽďĘĺÜşť€R©$:ú?Íů‘Ę•+3ő»ô–ůďżIOO§jUiáäŞUŞpăćM˝éż˙±÷ŢíJ•ç[ÎŻ^‡¦¸ą~PŕüŁÇŚc„—k~×Ůîşu랞Ι3q:Ëą|ń,2™Śđ˝D„ďͱovšL&{snC‚´wH4u|űöRÚ™3`g÷,Ź˝=ÜąŹK=^۶I顡RV§Ž€ĹĆB‹ŇÜş,_.-ŕ]\ť\ 9¡+‡hß }Žmî^`jČTĆż7  ź$’–™FŤ 5¨aU+‰WJ¤ť‚ Bé*¶Ařöö 3fŁG{S»–-ţkPeeŕ5b8ććć|4 ááú“k=™ 4ŤŢô[·nuţýűĺŘž_˝®}z3Ţśç_˛xsfĎÄ®A}ťíV©TOŰ%Ó[ÎĄř8†zţ€6ËţW×,ą˙y®®°u«t«°o_)Mߊjµ´ţă¶mRŹYr˛tK˛vm)čzôHşĹ¸w/<ŇíĘůóáégü˛ą:şň˙ěÝy\TU˙Ŕńϰ/ (h©¨ášZ"¸űą›‚d‘•Š"š©iő´h–•fţ[\—ÍSD[DTÔÜSW\€Ůfřýqc”e4żď׋׋9÷ÜsÎ=sgřrîą÷l9ş…Řş,´m啬ZÁ'ý”…Ú‹ź×*íĺK!„˙lĺ+ň‡"));[[š7kĆďOáçź7ňěłĎ`ff€ąąy©`jÔ°ĂŇŇ’›7“¸™”LýúŽ:ÓŹ?ÁĄË—éűŠ7}úyqëÖ-úôóÂÎÎVŻzËŇÎşuë0r„W®$Ű?>ţ<µkצŮß—fu•SRöT_NN› 11Т…’öâ‹?Ď… ĘBŠĘüݍ(eô«}{e{Á%HP&ě˙ňKń5CC•@ĎÚúŃŕäŕD®:—Ë1´¨Ó˘Đ¶™gňj›Wů!\™¤ďPÍkskSHLIÄÉÁ©Är—î]úh.„˘Rl쫯ďŹ(Ĺơ~}GllŞÓ©cB7+—Ž˘ÇĐ©S]E`ddDĎ/ľ;€Ý»#čŮŁ»Îô~}ű°ő·ÍÚ¶ţ¶™Úµk—Zď–_~ă˝)h_ëÓÎą˙÷]ˇ×jµš˙.YĆľŻakkóĐr žÚŕ«€ŹOáÉńcÇ*sľ4ĺőâĹJšJ5j(w8Nš¤Ś†2 –µj) oďءeEµl©,î]I|ÚřŕŮÜłÄmS{Oĺ?;˙CJf F*#Ľ]ĽůĺrľüzüW¶Xâ~g#Qk…BT˝CąŹ5ë‚ÉÎÎ&##“€Ŕw2y" WŻá?&¬¬lróňřnŢ\ľürSß˙đđŚMŚůbĆ´Rëřđ©L™ú!á»#077gîśYĄ¦ěŽŘCđú Ü˝{—÷¦~ČÜ9łJ­÷Ô©?ŮĽĺ×B—!KĘ˙îÄ)ř ŤęďËEµřvî˙Î$’’“qkăJŕX˙2o|Ü)š4kőt_·o+#Y!!đŮgJZx¸2ßŮY ¨şwW¦–-áăŹďďŰżżňx‰ĆŤď§98(űŐŻŻ<ş˘aCĺ˛ä;Ęą‰·7Ľ˙ľ2‘߀G.ÖNŢó˝ů~đ÷DťŹ"$6„Ď(Ç~&śkwŻ1dŮ@Ĺ řW/?˙2Ăţ7ŚÍă7óíkß2dŮ~=ţ+¦¬ą’Cńĺo_ŕ9Ç€Ó×O´ýB!Ş– Č/<—*2b'ĂGOxş&‡?žŞ»%…BJđ`¬şi#í;t*W9í:taeĐB†Źž@Đ’ďKĽÚŐ¤Y+yľB!De“L!„˘’I&„BQÉ$B!„¨d€‰'–-[Řż?iii|÷ÝwÜ»wď‘×™››Ë˘E‹´?ŹłŞč!„ĺ§×c(ňňň>Ă®]»‰‰‰eSČzí6oź×±ŻY###’’“3z$öööĽ5ÄŻPcÇ0yŇ4^<ŮâââhÚ´©vŇÜ˝{+++ĚĚĚ8{ö,ćććĺ*G—ÔÔT–/_ޱ±1ććć 6 333Đh4Ś?ľÜeWÄÎť; 端ľâČ‘#„‡‡ceeĹíŰ·éŃŁíÚµJď!„Ź˝FŔbcŹwOĎ®$$\-\JŲĄ‹X˛x_ÍśÁż?ž†‡G[Ξ>®ýń}}={ĽlĐO®yóć•yéŞWŻŽąą9¶¶¶…–ńѧ]6nÜłł3ăÇŹÇŢŢž­[·V¨©©© ¶ŚŚŚČĚĚÄĘĘŠÜÜÜrßąW´}©T*\\\8~ü8žžžśkÖ,lmmŇÓÓYľ|9wďŢĺâĹ‹Lš4I›çóĎ?ÇĆƦRÚ#„ÂpT@~ŃUş7mÉůs±“áŁ'Z!\T˝ĆM[Vu„B”cťĐMiߡěW.Ô®CV-dřč -ůžţďR4ÎjҬ•< _!„˘˛I&„BQÉ$B!„¨d€ !„BT2 Ŕ„B!*™^ʎČËË#úp »ví&&&–M!ëµŰĽ}^ÇľfMŚŚŚHJNfĚč‘ôíŰ›čĂ1,Xř_ĚĚ̸{÷.Ç ĄOź^?!„B'…^XlěââÎáéŮ•ĐĐ-…¶©T,[şPÖ…|óm?úöíÍÔ÷?âçŕŐÔŞĺ@rň-ú{ůH&„B§š^— =<Ü6ômš7kVl[ČĆ`íď999ÔŞĄ,ĺbmeEđú ¨ŐjÎĆĹŃ´I“ 6Y!„âÉVţµ )Ľä©S˛1$”¤¤$._I`éâ…|˙ý˙1Đçu¶JĹĘË*Öb!„B'śÁ&á7kÖ” ĆńÎ;4¨ďHĐŠ•„„l"`Ě(Ţxău._ľBȦ͆ŞR!„â‰Tţ°üÂ#`IIÉÔ«W;[[>x ˝ű`ú§±â§ŐDÚ‡ĄĄ%Ť9á?f#†«pĂ…B!žTűęëŮÚßccŹPżľ#*•ŠjŐ¬ąté2ćfćŘŰŰŞJ!„B'’^#`‘‘űXł.ěěl222 |€)“'’pőţcÉĘĘ&7/ŹďćÍEĄRńí7łřř“é88ŘóWzßÎůú‘B!Ä“Bݬk×ÎtíÚąÄm[B7”ŢąsG:wî¨Ë„B!ţˇäIřB!„•L0!„BJ&X‰ŚŘYŐMB!D‘¬ _„ !„O' Ŕ*YAĐ5Â˙ÝBŻ…BńôĐ;3NNĆ.hőű,”^{ę‡8µmOŁŰPwčLnÜDĄVă0c&Nníy®Cě–=´|›ź7đ\§áäęAí‚*'§Ôt4ęAăf­´IÖá4|©ŤśÝx6`F™™ĄÖk”šĘ3ßĂÉĹ'wjü¸ş~ŁhܬŤZ´ĆÉą-NÎm•×/¶ˇqłV89·ĄAĎ~Ř®ZůůT۶ťĆÍZú©3Ň_[ÇÁW|Ü©§3»}4€wŢąź¶};TŻ11đĹŕé ={”) VCŹŕč۶)ůú ęŐ <ů~97n@ưy3 *x{+?ŽŽ;„·—ľŤ÷|oú˙ĐŐhŢó˝±kAđÎÚűǵýÔvŞŹŻŽď}QŤV1ŕÇĽ0ýľřő mžë©×éţÝé=Ż7"#; ýA¨F«Ř}f7»ĎěF5ZĹ’˝K Ö~!„UOŻĚ2ꎯż…ÍšuťŤ+´Íäf‰Ë—quÓĎX<„ÝâĄT_żŰŐkI\ľ”[Ó>Á~ö·XEîÓYľůé3Ôúä3RFŤŕęćŤTŰü v˙]Ş3˝€MđĎXŽ)TV­Ź?ĺ/Ż\ů} ÖáXďŘUę±=óŢ^Iŕňž]Üţ` FY÷H\®Ô‘:lŹćâ±Ăh,-I}k0c‘:äM>˙Ű5ëČzń’ćĚR~f…ĆÖ–Ě®]€âÁđtaööб#lÝ «)„„(Ő‘# ááý_ ź|66Đ»·’ßŰúôI“ K‹#ŕŮgˇsgđňRĘ U~<= zˇăBů9ŕgíďŢ®ŢtlÜ‘­'¶jW‰9B˝őŁ,TBؤ0>ŰňŮĽ·ţ=Ľ\ĽŘ6qNµśřň÷/Ňa/=˙/=˙CÚ1hű…BT-˝°¬¶n\#ăĺnŶ%ţô?˛_h…¦z5Ôµ°=@vËÜkŰ€jżoŐYľőďŰ ?źô>˝ÉmPźś–-¨öűVťé&×®QóǤŽ(ĽĽ‘*/‹#G1ĘPFľr7Ňnsôy˝Đh™éĹ‹XEî%eÔpڞłHďߏŰS&*Ď(5 ë°\m|đlîYâ¶©˝§ňźť˙!%3#•Ţ.ŢürLą´úëń_Řf`‰ű !„řgŃ+łŹŔÉą-¶+VŕäÜ–z•»łÔöö8|Ť:ŁĆđ׫I5‚|33ĚOť˘Ń ®XďçĆ’…ä=űŚÎňsš7#yćgŘ-YŠă+ޤ÷…»ţ:Ó 8úĽŽĂĚŻ¨ë7Š´×^%ő­ÁÔţřSśÚ´ĂřönλIŃ8%ă[·µŻó--¸±ŕĚÎ_ŔÉ˝#j;[’żšI]żQŘýDŁ­iÔ˘5Ş{YŘ®\­ŰTŰň+7ćG¦çż°8ôŮÍ›ęś+÷®§2řş}[É Ď>3”»Ż]S‚(wwčŢ]™ăđńÇ÷÷íߌŤˇqăűiĘ~őë™™2vů˛Ür 2*Ęŕ‡±8r1Ż-zM©bľ7Wî\!ę|!±!|6ŕ3f Ař™p®Ý˝ĆeĘgdéŢĄ4­Ý”—ź™a˙SnůöµoŮ|t3˝çőćôőÓ|ŇďF,ŕ÷żóű‰ß´iB!ţT@~Ń;ó7mÉůs±“áŁ'<ťÂc¬č<2!„BṮN覍´ďĐ©\ĺ´ëĐ…•A >zAKľ/ń Mšµ’'á !„BT6 Ŕ„B!*™`B!„•L0!„BJ&x"lٲ…ýű÷“––Ćwß}Ç˝{÷yťQQQ¬]»µZýČ모Şč!„ĺg˘O漼<˘ǰk×nbbbٲľXžĄË‚Zľ’ý{ĂHJNfĘ”161ĆÚĘŠ9ß|ŤĄĄĄaZ/žhqqq4mÚT»6biîŢ˝‹••fffś={ssór•ŁKjj*Ë—/ÇŘŘsss† F›6mXµj ÂŘظÜeWÄÎť; 端ľâČ‘#„‡‡ceeĹíŰ·éŃŁíÚµJď!„Ź˝FŔbcŹwOĎ®$$\-¶ýâĄKś8QřVËŻżţ†îÝ»´l1ŽŽŽĚ_đߊµXücĚ›7OçúEŮŘŘP˝zuĚÍͱµµ-´ŚŹ>ĺč˛qăFśťť?~<ööölÝş ‹R–ÍŞIII\~`}Ëřřx|}};v,#GŽdÍš5ä~Ë(V IDATććĄ÷ŹBÇŹ^#`îxx¸“ü÷’@Ňh4|=k3?źÎŔWß@­Vłcg8SŢ›@÷îÝřčŁiLyo˘š. a×®]ś>}šĚĚLěěěđ÷WpΑ#G°˛˛"33777<==u¦?~śđđpĚÍÍÉÎÎĆĎĎŹřřxV­ZENN#FŚ 88 Ľ˝˝‰ŚŚ”ŕIĄRáëëKÝşuu¶łk×®››ŁR©3f 111ĹĘqvvfăĆŤřúú†‹‹ iiiäääŕîî^b{fĚÁ±cÇđöVľvvvfŐŞUxyyĘĄČíŰ·ăââÂkŻ˝öČŢ‹ĺççłqăFŢ|óMfĎž €‡‡µ˙^ëŇÖÖ–ÜÜ\Ôj5¦¦¦%öŹBÇ—^Řň)<â°zÍ:zĽÜMűŕÎť»deeńĚßk->S»6WĘ[ĄxDŃh4L0ŤF‘‘›7ofÖ¬YXZZ’––FXX@‰é)))¬^˝šiÓ¦ammÍöíŰ Ă××—6mÚ0~üxnŢĽÉěŮłůá‡pssĂÍÍŤŔŔ@&NśX¦Ń{{{íďĎý˝Čą®r¶nÝJzz:Ó§OgňäÉLť:•ůóç3věŘŰ“žžNnn.¶¶¶€ÜÜşu˙ź ###Ţ˙}¦M›Ć At^ęÜż?{öě)”fkk‹‹‹K‰éăĆŤÓyĽ{öěÁŮŮYŰ&€†¬sącÇ<<<´Łt%őŹBÇWą°]˝z•¨¨,˙]ˇô˘XU**|©H–««+;vě 55µPzëÖ­™;w.®®®4oŢśAéLŹŤŤE­VłrĄ˛DUJJJ±y~}úôÁČČaÆUĘqőěŮ,,,hذa±óîÁö ¨T*UˇüíÚµĂÔÔ”ÜÜ\ňóóu`ť:u˘S§’źś¬+˝$·oßćěŮłÚŃȢvîÜIrrrĄőĄBĂ+˙Ř Ž?ÁĄË—éűŠr çÖ­[ôéçĹĆź×biiÉÍ›IÔ«W—›IÉÔŻďXńV Đh4Ě™3ooo:uęDDD„v›źźׯ_çĚ™3„††baaÁřńăKLďÖ­5jÔ @g]Á¸ťťÝŁ>,LL”S[W°ô`{ňóó133#55•š5k’’’‚6ŻJĄ*ÓCŤ€]şt‰¤¤$fÎś @ZZ_|ń|đaaadgg3räČ Ýt „˘jd¬_ß>ôëŰGűşS—nlým3={ĽLřý&»wGĐłGwCT)Ę!::šS§NáççŔ˝{÷HMMĹŮŮ™;wîĘ»dÉptt¤}űöL›6Mgşżż?éééś>}š-ZźźOjjęC-###233±˛˛"77·Üwî-G_*• Ž?ާ§''OžÄŮŮYďr 5VpiµŔG}ħź~JTT×®]cĚ1| !ÄNŻ,2rkÖ“ťťMFF&ď0eňDš4iĚî=ŻßŔÝ»wyoę‡Ěť3‹?Ę”©ľ;sssćΙőHD<\BBüń‡6ł¶¶ĆÝÝť/żü’V­ZajjJpp0ÖŽŽU«VŤĽĽ<Ţ|óM€ÓÍĚĚ $88 6 R©đôô¤víÚěÚµ €E‹aaaˇ­”IĺłfÍÂÖÖ–ÁăčXľŃŃËéر#YYYěßżźNť:‘••Ĺőë×ÉĘĘbÇŽÄÇÇ—Ř–/_ÎÉ“'111ÁĎĎO;"xôčQ¬­­ĺć„îÝ+çź“'O˛oß>ŇÓÓYľ|9wďŢĺâĹ‹Lš4I›çóĎ?ÇĆƦRÚ#„ÂpT@~ŃUş7mÉůs±“áŁ'Z!\T˝ĆM[Vu„B”cťĐMiߡěW.Ô®CV-dřč -ůžţďR4ÎjҬ•< _!„˘˛I&„BQÉ$«"‘;«ş B!„¨"€U‚ŕK‚0!„âé$X%+şFřż[čµúPŤVqćĆ™Şn†BrŇ;3NNĆ.hőű,ľQَîĐ4nÖŞlůK`óóžëô/ś\=¨ýďOPĺ䔚®«^€şCühܬ¦Wľü‘Qj*ĎL|'wś\Ü©ńăBęúŤ˘qłV4jŃ'ç¶89·ŐÖaAĂ—zĐČŮŤgĆa”™©łś_ńq§žÎ ěömhĐŢyç~ÚöíP˝:ÄÄŔ_€§'ôě S¦€Z =z€Ł#lۦä˙é'¨W,,`ňäűĺܸ ÂćÍ0`€˛ô‚··ňSÎG\”&âlD…Wv¸žzťî˙םŢóz3há 2˛3Ú„j´ŠÝgvłűĚnTŁU,Ů»¤Đ~Aèc[§Bu !„¨:z`–Qp|ý-lÖ¬Ăěl\±í6Á?cq8¦Ěů‹2?}†Zź|Fʨ\ÝĽ‘j›ÁîżKu¦ëŞŔ(3ó3g•věŰ˙ĐşźyďLŻ$pyĎ.n0٬{$.WęH6„‹ÇsńŘa4/±SëăOůËkW~ß‚uxÖ;vé,Š_ŔÓ„ŮŰCÇŽ°u+/!!J@uäDGCx8„…Á_Á×_Ă'ź€Ť ôî­ä÷ö†>}`Ň$čŇââ`ÄxöYčÜĽĽ”2BC•OOĘKßľ„:_]ˇ2Ţ[˙^.^l›¸ §ZN|ůű— é0D)˙ů—xéů—Ň~Hˇýü:úaki[¬Ż-3˝x«Č˝¤ŚŽQvéýűq{ĘdJrńŘaTyyX9ŠQ†2ň•Ó¸‘ÎrJ ľ <•A(#UÇŽ)#\×®)i Ŕ¸q`d¤Ś^Ťݤu쨌nť?ŻäŰľzőRFŇ®\Ç•QŻŇFŁV­2XÓŁńśă ŔËs_ĆsŽ'˙ŮńŚýŤY±4ŕÝuďňĆâ7đăÖEŻĂzś5ŞŃ*Öţ±‡I4úw#Ô5ˇGBŕ<//BbCJ­Űg~€j´< _!ždz`ůffĘĆbň©ýńtîŚKn˝zĎŻéU屺–˛_^-LŻ$čL×U/€ŐţdvęŔ˝í±ĂGO «çS´LÓ€JĐtŕtč ¤ť< MšÜĎÓ¬\żiiĘ×/ż(éaaJÖ°ˇ€?mÚŔĺË%×µp!¤§¬éľîľDLŤ`×{»Á¤“¨a]äż’9óĹě^Ŕ{=ßăŔůĽáţ©?(‹ťź˝q–soШV#’˙Jć^î=ęÚŐ ®m].$_ĐÖă=ßďůŢ…ę !$°ô M!ÄăĎ “đmÖoŔřćM˛ÜÚ`r3 Ó ő/¨h¬–źŻüčH/­^Ë}űą×ˇ=÷:vŔ(=óă'´»'ţô?.ýq˙˛¤QVšęŐąxř yužĹţ›ąÚí¶+VҨŤćÇŽ+ůSS©9ď{Rý†’ĺęLőÍż`?÷?Ą–Sđ„ݢO±/xýÔ­60`l٢\*ř÷ü@#§ŁFŻĽ˘`jµLŮŘ(#`—/CJŠr‰qçN¨]»đľŢŢ0w.<€?Jöů+3+Ş[TÇý9wň)tňĘ'™°bÄ í‚ŕT*Uˇ =t\(ˇăB+ĄÝB!*—A0«=‘ťż@ýţ©±`u‡ŤÔ»śÜ 0Nľ€Iň-ňu¦ëŞ×äĆMĚ.^˘~ßÔú÷'J÷îÓYoŢ3Ęí,W46ŐÉyľ9Ć7oj·§Â…Ř?řëµW%ŕ4˝p‘Ű“Ţ%qů22zvÇ6觇–S4{j/''ČÍU&Ţ·hˇ¤˝ř"ü˝V#.Ŕ3Ď€2˙+*Jýjß^Ů^p  uk%@kذp=ˇˇJ ÷÷ZŽŹš™‰@±ŕŞ€‰‘˛üj=»z8TsŔÚܚĔDSqrpŞ”v !„¨Z Ŕn,řóq§8wŠäÓ¸Ľ7\ďrŇűô•Šj[Ă0M¸ŠŮź§Iď×[gş®z-÷G‘:ä-íÄů,çÖX>0¬ÎŃ<×±«öő=Ôö5±8rUv6fçâÉrs˝ß°| wÇŚV^ZY÷ş|33rš6yx9žĘŕ«€ŹOáÉńcÇ*sľ4Jłx±’¦RAŤĐ®ť2ńţ•W”í66µjł3ěءeEµl ¦¦oľ±‘1w3î˘Ö¨IĎÖ˙§‘Ęoo~9¦\ZýőřŻ lS¶»……B<Ůô Ŕ¬Ă#prn‹íŠ•89·ĄŢŕűwg9úĽŽĂĚŻ¨ë7ęˇů‹Ęiތ䙟a·d)ŽŻx“Ţ˙îřëL×UŻÝ˛ އnÁřÎ,Ä,îÇO` €qJ*Ć·nk÷Ď·´ŕĆ‚0;'÷ލílIţj&uýF`ôösţO›?íµWI}k0µ?ţ§6í0ľ}‡›óćę,§¨‚ ë© ľnßVF˛BBŕłĎ`Ć ĺ®Çk×” ĘÝşwWćx|üńý}ű÷cchÜř~š˛_ýú`f¦Ś€]ľ¬w \‚Ś*|†ˇ i?÷/Ýé<»3ëţXGÚ˝4–îUîśM»—Ćź‰’v/Ť9asđY ´Ç{ľ7C–Ý˙ |űÚ·l>ş™Ţózsúúi>é÷ #”G—ü~âw~?ń;€6ÍgOˇ˛ŠÎBńdPůEďĚkÜ´%çĎýIdÄN†Źžđt ʱ˘óČ„BQ1Ć:ˇ›6ŇľC§r•Ó®CV-dřč -ůľÄ' 4iÖJž„/„BQŮ$B!„¨d€ !„BT2 Ŕ„B!*™`B!„•LŻ,//Ź1óËY ôy˝Ä¦E‹ç‰Ź?Ź×Ŕ×čÓ§ćććoąB!ÄJŻ0w† }›ćÍšۦŃhřzÖ>ţčţ‚Ő^^ýyî9eiZµj‘ťťMnnn›,Ę+$$„ŔŔŔŞn†BńÔÓkěAE^˝f=^îFíC~ń…VÚß—,]†—WŞU«VŢ*EŐŻ_ŹŞn†BńÔ+wö «WŻuóż+qűŇeA\ľ’Ŕ·ß|męD9ą»»ăîî®}ťŔĘ•+ ĺiÝş5ÎÎÎ’.é’.é’^…鯬y+ţ±ĘµQrň-zőy…ŘĂří÷­ü8‘vű… iÔȉ Á,úď233ů÷‡S12’›. A–"B! «˛—"2ČXżľ}č×·Źöu§.ÝŘúŰf~ţy#găâX8˙{T*•!ŞÍ©S§đóó«ę¦!„O5˝°ČČ}¬YLvv6™ľŔ”ÉiҤ1»#öĽ~wďŢ彩rýú Ž9Jk—ű—˝vď ĂÁÁްG!Ę$!!ččh Ŕ„B*¦WÖµkgşví¬sűKž˙â%ĎU¸QâŃđňňâĚ™3UÝ !„â©'“˛ž"GŹĹÇǧޛ!„B<ő 2L<ÜÜÜŞş B!„@FŔ„B!*ť`B!„•L0Qa{÷îeíÚµĄć äĆŤ•Ô˘ű‚‚‚X´hyyy•^·Bˇ‹^X^^bć—łčóz‰y–. ˘S—nÚ×Ţ>Ż3rTŁýńřż˙ľ­b-•">>žü‘E‹ńí·ß«3Ż««+{÷î-µĽˇC‡bkk[(-..Žüü|{ĆđáĂ9~üx…ę1T;+ăx…B<ô ŔbcŹwOĎ®$$\-¶ýâĄKś8QřiŻF*Ë–.bÉâ|5s˙ţxZĹZ,*ĹŠ+:t(řűűł~ýzťyÍÍÍZ^űöí±´´,”6oŢĽ'" 1T;ź”ăBńčéu¤‡‡;î$'ß*¶MŁŃđő¬9Ěü|:_}C›˛1Xű{NNµj9T ą˘"BBBŘąs' ,xh^sssöíŰGďŢ˝ąvíuęÔyč>'Nś $$„ěělFŽIăĆŤYĽx1jµš'Nh덉‰!22P‚•J…ŻŻ/uëÖ-Vć™3gřá‡đőő%,, ŇŇŇČÉÉaěر\˝z•őë×caaA^^o˝őöööś?žU«VaffV¨ĽăÇŹŽąą9ŮŮŮřůůaggWâń”ÖN]儇‡säȬ¬¬ČĚĚÄÍÍŤęŐ«ë,§¤üžžžík!„O¶r?†"źÂ˙ÉŻ^łŽ/wŁvíÚ…ŇOťú“Ť!ˇ$%%qůJK/,o•˘‚ę×ŻŹ‡‡G™ňŽ5ŠŮłgsôčQŢ}÷݇î“Č´iÓ8xđ 6lŕ>ŔßߍFĂřńăµůÜÜÜpss#00‰'–şFčóĎ?Ź••éééLź>ťÉ“'3uęTćĎźŔňĺËńńńˇeË–ěßżźŕŕ`Y»v-oĽńÍ›7'00€””VŻ^Í´iÓ°¶¶fűöí„……áëë[bÝşÚYZ9›7ofÖ¬YXZZ’––FXXžžž:Ź·¤üB!ţů ň°«WŻuóż+¶­Ył¦L0Ž›7oňý÷ó Z±’Ó?1DµBOîî»?<#pđŕAzőę…••›6mâŕÁ4kÖŚ•+WĘ׺ukzőę@Ďž=Q©T4oŢś5kÖ´í={öÄÄÄ 6lH~~>$&&Ň´iSš6mĘúőëÉÎÎ&11‘FŤ*ăüůó¨Őjí1¤¤¤»,ZĄ•ÓşukćÎť‹««+Í›7gĐ AĄ–Ąo~!„˙ ĺ{`.˱ă'¸tů2}_ńŕÖ­[ôéçEȆ`îÜąC˝zu±łµĺ÷§Đ»ď ŔsůůůěŢ˝›9sć`ffĆ3Ď<ĂÂ… ™7o}ôQ±üąąąÚ×óňňĘ4/L&&&…ęĐEĄRiŰcll\č<µ´´¤FŤT¨-Ą•ăççÇőë×9sć ˇˇˇXXXý«h~!„˙ y Eżľ}ŘúŰfíŹ[ŰŚĄĄ_}=[›/6öőë;˘JQŃŃŃ,_ľĽLy---IJJŔÔÔ”ęŐ«—ąžŘŘX^xá…‡ć322"33ŤFCvvv™Ë/`mmMť:uŹŹ”» ›6mеµ5–––$&&j/ˇ4iŇ„ôôtNź> (fJJŠŢí,­ś%K–ŕččH÷îÝ ŕÂ… Ąoiů…Büsé5ąŹ5ë‚ÉÎÎ&##“€Ŕw2y"Mš4fwÄ‚×oŕîÝ»Ľ7őCćΙEÂŐkřŹ $++›ÜĽ<ľ›7÷‘x¸„„˘ŁŁńóó+5źJĄbذa¬^˝îÝ»÷Đ}¦OźŽ‰‰ ööö :@; `ѢEÚ‘#fÍš…­­-Ćѱxp~ůňe˛˛˛Řż?ť:u"++‹ëׯ“••ĹĺË—ńóócýúőěŢ˝›ÜÜ\Ţ~űmT*ýúőăűďż§˙ţ¬_żž·Ţz‹ŔŔ@‚ٰa*• OOO:wÖ˝ŔĽ®vę*GŁŃ0gÎŞU«F^^oľůf©ĺ”–_!Ä?— ČŹŹ+üčĆM[rţÜźDFědřč ś?÷gŐ´N”¨qÓ–ĺÚO­V3{öě/# !„OłcťĐMiߡSąĘiס +2|ô‚–|Ď˙w)g5iÖJž„˙49zô(>>>UÝ !„â©g» Ĺ“ÁÍÍ­Ş› „Bd-H!„BJ'B!D%“L!„˘’é€ĺĺĺqŕŕ!f~9‹>Ż—gé˛ :uéVćt!„B§Ť^XlěââÎáéŮ•„„«Ĺ¶_Ľt‰'N•9]!„âi¤WćááΰˇoÓĽYłbŰ4 _ĎšĂÇ˝_¦tQůBBB´ S !„˘ę”{X>ů…^Ż^łŽ/wŁvíÚeJ•Ż~ýúxxxTu3„B§žA&á_˝z•¨¨ äS¦tQ5ÜÝÝË´¤B!­r?5?˙ţرă'¸tů2}_ńŕÖ­[ôéçĹČ~%¦‡lĆŇҢ‚MB!„x2äIřýúöˇ_ß>Úםştcëo›ôęŔÓE勎ŽćÔ©S2 &„BT1˝.AFFî# đŢ˙đ#222 |‡€ŔwŹ?Ŕî=ľĂÝ»wyoę‡ÚýtĄ‹Ę•@tttU7C!„xęé5Öµkgşví¬sűKž˙â%Ď•9]T.///Îś9SŐÍB!žzň$ü§ČŃŁGńń‘"„BŞf9`âÉŕććVŐMB!2&„BQé$B!„¨d€‰r äĆŤUÝŚ*÷¤÷CPP‹-"//ŻLů+óx÷îÝËÚµk›öĚŞU«ČÉÉaÄcaaÁ_|Axx8GŽÁĘĘŠĚĚLÜÜܨ^˝:‘‘‘€ňe§R©đőőĄnÝşĺjÓFŽɲe˨Ył&×®]ŁnÝş¤¤¤Ëgii©ýWŁŃpěŘ1Ľ˝•%łśťťYµj^^^:ë.©€Ź×ÓÓłÄ2bbbtöĂńăÇ ÇÜÜśěělüüü°łłÓ»?u•sţüyV­ZU¦Q>]Ç[p>ůúú˛}űv\\\xíµ×J-ÇÜÜś}űöŃ»wo®]»Fť:uZ÷‰' !;;›‘#GҸqăŰSZućĚ~řá|}} ĂĹĹ…´´4rrr;v,WŻ^eýúőXXX——Ç[o˝…˝˝˝Î~ÓŐĎşěÚµ‹Ó§O“™™‰ťťţţţĄö§>ď×7ß|C˝ző>ľÄď//ŻÓ»uëĆĎ?˙Ěwß}ÇÉ“'Y˛d ß}÷ëׯg˙ţýŚ;¶Đy•’’˘ł=ú|®K{żôýŢ(é<)PŇçBC}Ă*÷°| ˙‡°zÍ:zĽÜŤÚµkJwný"Łýčó:źN›AJjjy«Tż~}<<<ôŢ/22’ěělüýýµŁcÚ¶mË˙ýß˙póćMfĎžŤ›7o&00±cÇ2zôh’““qsscҤILś8‘I“&é|=LëÖ­9vě/^ÄÉɩж›7oňË/żđňË/cffFzz:ąąąÚK¶¶¶ÜşUüźŚ•ÔPňńꢫRRRX˝z5ŁGŹfěر´lŮ’°°0ťĺ—§śµk×ňĆođď˙»LýYŇń_şĘ/í<)kű+ë{@čŻÜŘčcÇOpéňeúľ˘\Âąuë}úy˛!KKe±±1ÆĽEŹ^ŻT°É˘2pýúő2Q)Ş—_üüü¸~ý:gÎś!44 ˝'–‡˝˝=jµš+W®đěłĎÚ6`Ŕ222 wďŢT«V 333RSS©Ył&)))Ú<}âx---©QŁ*_W9ééé€ň™4Ä\•JU¦?ĘůůůěŢ˝›9sć`ffĆ3Ď<ĂÂ… ™7o}ôQ±üąąąÚňAą ČĐó_LLL Őˇ‹JĄŇ¶§hż•ö~•DŁŃ0gÎĽ˝˝éÔ©Ĺęz°=şęŐĺŮgźe÷îݨŐjÚ¶mKlll…nś(ëűk¨rĘŇźEżg–ţŕČŃí˛ťWú|îô}żt•řĐó¤,íŻ¬ďˇ?<†˘_ß>lýmłöÇÁÁ­żmĆŇŇ‚E˙˝?ÚµcG8®®.†¨R”Ctt4Ë—/×{ż:uęč}T%K–ŕččH÷îÝ ŕÂ… ÚmFFFdff˘Ńh´—8+Ň΢\]]‹Ýý©«kkk,--ILLäčŃŁĺ:Îň˛´´$)) PîÚŞ^˝z™÷ŤŤŤĺ…^xh>]çUYY[[S§NâăăűwĹéę·ŇŢŻ’Ü»wŹÔÔTśťťIKK+S{ôyżjŐŞĹŤ7011ˇI“&ěŰ·ŻLsí*ÚoĺĄĎůŻŻ‚¬<¨3OŃóޤ~Đçs]žĎWIĺ—ő\¨/ÜÜÜĘő=pčĐ!öîÝ[¦ďኂXŕĚ™Ó8Ö/ů3ü0Žőrüča\ÝÚq4ö›ŮFŃ8ëű ňăă ?:˘qÓ–ś?÷'‘;>zçĎýY®FGŁqÓ–ĺÚO­V3{öě/÷1|äČ‘%ć122ŇŽhŽ5ŠŔŔ@†ʦM›X·nŁFŤběر :”ÄÄDíľŹňü)ŹŇŢ—Ş(GńtÓkĚĂĂw’“‹/T¬ŃhřzÖf~>ťŻľ(kb…ţ?{weŐ6pü7 ¬*îŠK ‚” Kćš)™Ëcúř¸ëŁNjbefoZO‹¨i¦•Š”+¸ˇÖk.,!˘¸ â j*ú«0ĂűSŔ 08âv}?>Ę}ź9ç:羇ąćÜŰž}|˝| 3fΦqăĆĚž=Ó0‘ ˝íÚµ‹Ă‡Wéţ7999ššŇ®];âăăK=ŘÖLMM‰ _ż~¤¤¤Tz§î[·n@íÚµIOOgŔ€8;;“śśL`` fffâââ–-[9r$ŔÉɉ{÷îq˙ţ}ÍźăââصkůůůLš4‰6mÚŕëë‹JĄ"..N3>%ă5räH<““Ç 88óçĎ“““Cýúő™:u*§Oź&<<(ţV(Ś9’-Zh­(˙رcůí·ßt¶™3g°°° ''zőęĄsÜ´Őź’’Bpp0«V­BˇP0`Ŕěíí«´íęŐ«§yä @zz:VVVX[[kâÔw˙Ń6ž§NťbÓ¦MÜżOOO033ăłĎ>#66–LMMÉĎĎÇĂĂŁÜăgJT´]tŐŁmśëÖ­«w=‰‰‰lÚ´©ĘŹňB<;Ş}~Ążn޲Ť7úô¦iÓ¦šeÉ)©äççsúô–,ţ’FŤ±`᪭x ­[·ĆÍÍ­Jehßľ=íŰ·×<˘Ç&OžĚˇC‡đńńa÷îÝšäH— 6đꫯ˘T*8p ćá´ţţţôëץR‰‹‹ gϞł¬¬,.\Čożý†»»;WŻ^ŐÔ•ššĘ‚ 4h;vě`ęÔ©L›6­T›%÷"322bîÜąDDD”šůP*•Ě™3‡Ôj5...x{{0{ölĽ˝˝5wËÖVż¶ř*lwĎž=(•J¦OźÎ”)S*ť]ŇVż&Ι3gâíí]ĺä«  €ҵkW x;úůůńÓO?•ŠĄ:űOŮńěÔ©Ë—/ŕöíŰ,^ĽĆŤ“‘‘ÁćÍ›™2e Ó§O§]»v8p@g˝ş¶KEőhçęÔłuëVFŤŇ~XĄ1B<; r6hrr2‘‘Çůţ»oJ-Wŕ5m2Ś>TĆýąşşâęęZĄ˛çÎťcذa±yófňňň0333X,ÇŹçÍ7ßÄ‚ݻwsüřqúô飵lvv6)))8;;Đľ}{T*ŮŮ٤¦¦bgg€ťťĐ·o_jŐŞ…™™Ď?˙|©Ä©oßľ( ěííٲeKĄ±vîܙڵkSPP@QQ …ggg:¤I«CWüµëŕŕŔ˛eË4Źż6lXµë××?ü€BˇŕĄ—^˘{÷îŘŰŰóńÇsâÄ V®\ÉkŻ˝†»»»ŢűOeăŮżŚŚŚ0a‰‰‰¨T*6nÜ@FFFµëVTŹ>㬫žüü|RSS+|tŹâŮUíěďhgcă¸vý:ţ1(~–V˙ůŃŻřAÜ%Ó簾¦rîÄ@­V“śś¬ů@±´´$!!Á`'ÉĘŇĄK111ˇYłf¬^˝ZgVr¸KĄRĹ'ý×®]›ěěěreKNŚ.ąŇLۉŇ%Ë «t^Bˇ(UŹZ­féŇĄ 2„nÝşViUő÷vʶ ŕááÁÍ›7ąpáAAA™™Uů‡˛őëËÓÓłÜ9śIIIŘŘŘеkWlmmůüóĎéÝ»·^űOUĆłd¨_ż>ććć4hĐ௶­¨}ĆYW=YYYËß=!D9ąŘŔýŮ˙ËÍOăĆŤŮ˙Ëš6mJ·®]Úł€“§NÓ­[C4)ŞˇŞO·OLL¤K—.xyyáĺĺĹ믿N\\śAc177'-- (N¨ęÖ­[aYBCC)**˘¨¨ÜÜ\,--±¶¶ćĘ•+Ŕ_W§UUtt4:tĐ;öÜÜ\233qttäŢ˝{ĺÖ‘““Z­&??_g=Չݺu´jŐ wwwĽĽĽHJJ2hýú:vě&ąČÍÍĄqăĆzď?•ŤgY¶¶¶deeqţüy 8ˇĎČȨôue·KEőT4ÎU­ÇŇŇsssRSS‰‰‰)OUߏB§“1đI٧t7lÔ„ô?îpýZÎ.ť5OŹ`ŃâĄüzŕ IIW9—ŔĎżěç%{{6lHhŘo,^˛Ś‹/‘tőoöuÇŐŐ…ďľ_Ëţý8á"˙ůäcęÔ©óşúôhبIµ^EDDDĄO·ß¸q#éé鸺ş˘V« âňĺËĽüňËl۶ŤS§N‘––ĆŤ7ŹŹ§}űö¬[·®Ür'''­ő+ Z¶lÉŽ;‹‹#>>žQŁFѰaCť1ŮŰŰĆŻżţJdd$őęŐŁE‹ŘŘŘDLL ÉÉÉtëÖŤS§NaeeĹsĎ=Çľ}űpvv&44”—^z‰cÇŽqâÄ """ČĎĎgôčŃŕëëËÉ“'5ńź:uЬ¬,Îť;‡µµ5™™™ś8q333^zé%ŇŇŇŘ»w/ąąą¤¦¦’™™IÇŽâŕ={öŤŤŤ őęŐÓZ§NťĘĹ?fĚNś8ˇµ]Nś8AXX±±±DGG3`ŔÍyfÚh«˙ÚµkěÜą“Ű·o“’’Blll…łSk×®Ő”=wî\©ízęÔ)BCC9{ö,qqqŚ=š˝{÷jÝ´&Ú&&&ZÇÓÔÔ”íŰ·—Ű§ŚŤŤ±··g÷îÝsäČ,,,xîąçt޶íŇ AťőT4ÎU­çůçź§víÚlŢĽ™_|‘řřxţüóO€â÷ă‘#G*}? !jFI®páÂyZµ®řoŠ.­Z?OlĚ)ś]:Ĺž}żR6ĎZąę{@Q٧t·±kGâĺÂĂ3qʬROŹ^»vŐzťJĄbńâĹĚź?ßŔ !„O¶żç:A»wňj—nŐŞ§s—lô[ÍÄ)łđ[·Ď©ďP6ϲmŰ^Eô,‰‰‰Ń\a'„BGGž‰ń qqqyÔ!!„y·B!DŤ“L!„˘†I&„BQĂôJŔ 9v<ŠĎżđáźCGh-ł~Ýzô *ę$¶mŰ—úYţőĘŹZ!„â ¦W}†K—.Ó«WOnÜH.·ţęµkÄĹýu©Ą›['.žŹŐüŚ1ŚľohżŰąB!ÄłBŻĚÍÍ• ăÇaß¶mąujµšE>Kůhţ\Í2…B±±1ĆĆĆDť8I“&ŤéСýG-„Bń«ţł )ýlłÍ[¶ńFźŢ4mÚ´\Ůű÷ďłrĺwřýŕ[Ýć„B!ž9 ?99™ČČă ¦ý&ź›·lăµ×z`nnnć„B!žhŐNŔJŔ p66Žkׯ3ŕCč?p0wďŢĄ˙ŔÁäććˇR©řÁďGţ9d°AB!„xŇäNřôgŕ€ţšß»őčÍţ_öq4 ssš7of¦„B!žxz%`áálŮ@~~>ŮŮ9x)gđŢśŮŘÚ¶!4ě7wžžÎ»ďĎcŮRŽ;ÎóĎWď‰âB!„O#˝°ž=»Ółgwťë_ďőŻ÷z­Ô˛÷ß›S˝Č„B!žRr'|!„B& B!D “ěic×îQ‡ „BGD°G $ů’$L!„x6IVĂJ’®ÄË Ą~âIÉÖ­[Q©TzżÖĎĎŹ5kÖPXXXíöŹ=ĘÚµk«ýz]¤_5éČ‘#lÝşµÂ2JĄ’[·nŐPDĹ"##ńńńáŰożĹßßżFŰâI˘×U………ś<ÖŻ‡ĆŤańb7 ‚¤$9>ţ®_‡™3˙*pę$—PĽx0§Oź&,, îÝ»G÷îÝqqqaÓ¦M 6 ccc˝ę›8q"JĄ˛Ô ťő•źźOZZZµ__âŇĄKŘŮ١P(xĺ•WŞÝŻjµ___bccéر#EEEÜľ}wwwzôčˇu<»uëŔáÇ‰ŚŚdÁ‚¶áěěĚÖ­[=z´Î2ăÇŹÇĘĘŞÂţÚľ}ű3gMš4aÆ :Ëůűű“——GQQqqq888pýúu-ZDff&ţţţcjjĘ„ 011áţýű’––†©©)ůůůx{{ł˙~.^ĽH­Zµhٲ%C† ářńăüüóĎ|ňÉ'päČ~ýőWfÎśIóćÍJ߅Ї^3`ŃŃg¸té2˝zőäĆŤňrWŻ]#.î\©eďϝϟ/Y»ú[ľ[ő ź~öE…m,Z´w÷ŢřmđĄU«V|÷ýÚ —ëjwÉŇe˛e“?ÖŻÁŇ¢Âv?˙‡–-[ňŁ˙zV·ŠÚµkłčËĎXýÝJÖů~ĎŠĺKůjŮ ťýrsëÄĹ󱚟‘#†Ń÷Ť>@ůä«Ä3;öÁPPaađż˙ uę@çΰkWńú  â䫤,Ż;p>ů¤8a{ţůŇĺ‚ WŻîČła۶mLž<™éÓ§3~üxRSS133{¤15hĐ€† >p=+V¬(•˘_FFFxyy0yňd”J%ăÇŹg÷îÝ€öń,‘””Ä˝{÷¸sçN…mššVÇ«ŻľZîpeűkh™™™ÔŻ_€I“&UXÖËˋɓ'kţokk ŔÎť;qttdĆŚ4jÔýű÷„JĄÂŰŰ›·ß~333"##ą~ý:łgĎfĆŚäĺĺqŕŔşvíJFF GŹŘŘŘHň%z%`nn®L?ű¶mË­S«Ő,ňYĘGóç–ZniaA@ŕT*/]Âîżo0mT*‡‡Đ§÷븻÷ćŕÁĂ:—ëjW­V´gžž4ßňÖŻ[­YżČg)¶mŰk~ĎĎĎ'hĎ>^z©-3fÎfń’Ż2ä­rńýůçź4mÚDgż ĆĆĆuâ$Mš4¦C‡ö:“ŻĎ\¦VĂĆŤ0g”| ˙ĺ—Ş˝ÖĘęŻ×hłiÓÇW‰)?MA1EÁϱ?óŇÇ/Ńznk"®D°âđ ş/îÎ[ßľE÷ĹÝY˛ €ĺ‡–ÓoE?:Ů™­ţ×Cʱ*víÚ…R©¬růôôt¬­­>|¸fydd$}ôŰ·o×, ćŰożeÉ’%řúúj–'&&ňé§ź˛hѢRu'''ł|ůrľ˙ţ{V®\É˙ýß˙±dÉ6oŢŚZ­ćĎ?˙$33“Ź>ú7nТE :věXŞž–-[ĆęŐ«Y¶laaa:űsúôiľţúk 8)ůúëŻK%BÚúËŠ+X˝z5+V¬ ##ŁŞĂG˝ző02úëO®¶ńĚÉÉÁÔÔ”víÚ_ĄzăââřôÓO™?>‰‰‰řúú˛zőęRŰ·˘ţę3n }{ĹĆĆję_µj_ý5/^ÔY‡‡‡Gąe“&MB­VsöěYptt$&&†˘˘"˘˘˘čÓ§ŹćďşR©$<<ś×^{ …BBˇ WŻ^„‡‡STTD«V­ćŹ?ţ¨ŇX Q“Şý(˘"JÚĽeoôéMÓ¦MK-_ąr9˙:‚‚BÁĆuOI˙ńG:yyy4kV\Gł¦MůýĆ ťËuµ›žžÁźţI›µ¶Óľ};żőÍďÉ)©äççsúô–,ţ’ ?üČ‚…˙aĺŠe¬ő]Ozz'NžŇ,«¨_÷ďßgĺĘďđűˇř'ńr¶mŰóď7ôěĺ®)VśHÚ¶mĎ•KĄgńžZwďBf&Ľô’~Ż»x6l(NÜ,-ËŻ_˝ţýďâŮ´‡hŐčU¬?˛žř”xţ“ŔŹ‘?âŕÍÉŹNň᮹µěVćVÜĘĽ…Ď~Íë~™ő …ęB̦›ˇR«06ŞŢá-CiÝş5nnnU*;yňdüüühÓ¦ ýű÷§I“&šuFFFĚť;— 0lذRŽjµšYłfˇV«122bëÖ­Ś5 {{űRÉżż?C‡Ą]»v=z”€€:t耹ą9—/_ć‡~ŔÇÇ[[[Z·n @łfÍhÖ¬ô#ÎöěŮŹŹćććÜ»wŹčě“‹‹ ...(•JfĎž]*9ŇÖŻĚĚL6oŢĚ‚ °´´äŕÁ8p€‘#GV:~ú¨tą  âú´ÍŚ=$FŠâ/ů…ůÔ1-žuŰ8i#çRĎ|>v~@=łzü<ëgş,梎‹Ô}’ć°ä“$)) şv튭­-źţ9îîĹ3ą%‡~J¨Őj–.]Ę!CčÖ­›ćpVAAĆĆĆ•&R …‚ćÍ›ŠJĄ˘S§NDGG—;ˇĽ,nŢĽÉ…  ÂĚĚH±ř IDAT¬Ô,>ĘöËÜÜś hÎíŞ*OOĎrłAÚĆłwďŢ$''łqăF,--IHHŕ•W^©4N(ľHŞ*ç…ió ăfČúëÔ©‰‰ ™™™4lŘŚŚ 7nŚĄĄ%–––ÜĽyS3 вeKîÜąŁ™»{÷.őęŐĂňż ęÔ©ĂŔŮľ}{©™2!5Ě€ ĐźýżěŃü4nÜýżěÁÜÜś:u,ąví:¦&¦4jÔHw0FFô}Ł!ˇa„††Ń÷ wťË+jwřđńíwk4—’'&]Ő´łwß/ĽűŢšßëŐ«K·®]Úł(ľrł[·.ĺâËČČŔÔÔ…Bˇł_ÇŽGaanNóćÍĘ˝JĎ„=“ÉĎ€Mšź}ö׌Յ ÚË–=ĺý÷áëŻAŰą7íÚA5{<í§¶3 ă†ŻŽSk'Ţíű.{gě%21’{ą÷HÍHeÓnß»]ăńérňäÉ*ß&ŕرcš¤)77—Ć%Hh‘››Kff&ŽŽŽÜ»wOłÜŇŇsssRSS‰‰‰)µÜÚÚš+W®]Ą×¤InÝşE­Zµ°µµ%""kkë ă\·n­ZµÂÝÝ///’’’*훑‘999¨Őjňóóu–łµµ%++‹óçĎĹ_Bő9ěď´Ťgbb"]ştÁËË ///^ýuâââŞ\gtt4:t¨´ś¶ţę3nş¶—ˇ( śśśŤŤ >>GGG ]»ve˙ţý¨ŐjnÝşEŹ=4ç|DDDĐŁGŹRIaĎž=«4›(DMŇk,<<‚-ŰČĎĎ';;/ĺLŢ›3[Ű6„†ýF@ŕŇÓÓy÷ýy,[ęĂWK|řčҸq#ţĚĘ櫥‹*lcŢďóŢűó ĂÔÔ”eK}*\hm×{öL>˙‡A˙EÆ °nnÍŇ%_pî\{öţ\ę0ä_|Ęűsç†q-c>űtÎ˙€éoĎâţýűÜĽy‹Ď>]€BˇĐŮŻcÇŽóüóĎUŘÇ’™°g2ů*ńŮg0{vń X“&Đş5(•Ĺ·ˇ€ż®f<ľ8á‚âŮ0//čÓ&L€•+‹oCŇ çÎ…˙žcSlçŰbZŰ”żź‡…ęBş,ęB“şMČ+Čcíż×Ňв!c:ŹÁé?NôďĐóÚćĚÜ2“ŐăVWŇÂĂuăĆ Nž×¬Y ™ą+ŰßV­Zé=nÚ¶WBBáááš>›TzdDD„&É\łf žžž0tčPüýý‰ŹŹ§V­Zš±4hŰ·oçË/ż¤Nť:4hĐ€ńăÇ“™™É7ß|±±1ÖÖÖôďßźČČH®\ąÂÍ›7±¶¶fذaDEEUŹ5I•MJîKv‰Sf={÷¨zĚ=3WK>¦ň ň0WšS´îŃźÇő T*‹/fţüůŹ:!„xäţžëíŢÉ«]şU«žÎ]z°Ńo5§ĚÂoÝJ­G»l۶—;á ˇŻŻĎČ ůn!Bq4ŐĂСĺ/śBńđUű$|!žUř|ř¨Ăx`...Ź:!„xfÉ B!D “L!„˘†I&„BQĂôJŔ 9v<ŠĎżđáźCGh-ł~ÝzôÖüžpʉSđđś‚—r&ŮŮٱB!ÄNŻ,:ú —.]¦WŻžÜ¸Qţ‘WŻ]#.®ôĄ–ďľ?ŹąďĎÁ˙‡uĽü’=߬üîÁ"B!„xÂé•€ąąą2aü8ě۶-·N­VłČg)Íź«Y–źźĎĺËW°·/.ß뵞:ü€! !„B<ŮŞ}Xه o޲Ť7úô¦iÓ¦še&&&4iŇK—‹ď,}ěř RSoV·I!„B§‚Aî–śśLdäqľ˙î›RË ź}ş9ďÎĄuëV<˙ÜsÔŞ%·B!Äł­ÚŮPÉOÎĆĆqíúuücPü4úţłkGŻĽâÄţ_ö´›0d!„B'›A¦ŁčĎŔý5żwëŃ[“tÍyw.«V.GˇP°-`;ÇɣO„BńlÓ+ Ź`˶ňóóÉÎÎÁK9€÷ćĚĆÖ¶ ˇaż¸ôôtŢ}Ë–úđŇKmńđśBnnn®ť;fÔCéB!Ä“BݬgĎîôěŮ]çú×{˝Ćë˝^+µěťY3Ş™B!ÄSJî„/„BQĂ$B!„¨a’€ !„BÔ0IŔ„B!j$`≢T*ąuëÖC«ßĎĎŹ5kÖPXXřĐچێ{Đ&22ľýö[üýý«őú­[·˘R©(Ž‚‚Ö¬YŁůBř Jő]şt ;;; EµcĘĚĚÄßßcccLMM™0a&&&:Ë_ąr…_ý•Zµj‘••EďŢ˝IHH 22’Ž;RTTÄÝ»wéŃŁŻżţşćuăÇŹÇĘĘJgüŮŮŮ|ůĺ—8::2bÄÎź?ŹŻŻ/sć̡uëÖöcâĉ(•ĘR7.ËßßźĽĽ<ŠŠŠ4Űŕúőë,Z´¨*CUŽ!Ć˙aÚ´iSĄŰE_ڶ㣬GűöícÎś94iŇ„ 6TZľěö}ĺ•WŘ´iÆ ĂŘظÚqÔ®]///Ôj53fČŐćBĂĄK—éŐ«'7n$—[wöT©€E‹–ŕîŢż ľ´jŐŠďľ_kČźa/ĽđÓ¦MŔËË‹:uę””Djj*:tŕîÝ»U®oĹŠ&U±sçN™1cŤ5b˙ţý–˙ńÇ?~<^^^Lť:•ŔŔ@ĆŤŔ´iÓP*•xzzTęuŻľújąţďń[ZZbccĂąsç4Ëbbb¨_ż~ĄÉ—>ĽĽĽžžž`ffƧź~ĘŮłg2¤řQTŽŽŽlÚ´‰ÁëlŰÔÔ”úőëGJJ ÖÖÖĺĘäććj>č|}}Q©TÄĹĹńý÷ßëŚäČ‘4lŘ””Z´hAFF†¦Îääd133ٰ°±cÇҨQ#Ů´iSąY»ŘŘXBBB055%??<<<ĘĹZňA¬­|ýúő áĚ™3XXX““‹‹ uëÖŐ‹-صk‡Öô×ĐŞ[˙ß·‹¶ţŢşu‹źţ ®^˝Š™™-[¶dĚ1l۶­Üv,‰cäČ‘üđCMŮŚŚ 6oŢĚ”)S>}:íÚµăŔ:űTQů={ö T*™>}:S¦LáÎť;ĆĐşukÜÜÜ*ǡoýe·‹®ţúűű3jÔ(”J%óćÍCĄRáĺĺE˝ző´nǡC‹OfddÄÜąs‰ ¨¨HçrĐľ?č*_Q<şhŰO4ŰkćĚ™x{{ëLľ âýS[śúîoѵźk[^r¨>55• 0hĐ věŘQ­v…UggA|0÷] xÖËgÉWĚö~ŹeK—*ŁPT-1Ź^ßľ}©U«fff<˙üóĺ¶[˙ţý122b„ ĺÎ]R(•nçăÇŹóć›obaaÁîÝ»9~ü8}úô m۶dffréŇ%Ξ=ËsĎ=§wüřúú’››K÷îÝ‰ŠŠ";;›ÔÔTěěě€âĂŔŔ@ňóóIMMĹĆƦT‰‰‰¨T*6nÜ'XĽË–-ĂŮŮ{{{† Vi\]]quuŐ»ďUĄoýe·K‹-´öWĄRifŤŤŤ«|n[çÎť©]»6i^§kyUëŃ7]ű‰ˇ•ŤSßýM]ńWÖŻľ}ű˘P(°··gË–-衢"ŐNŔt}Ŕ3áßcyăÍĐ A}ĚÍÍą};Ť–-[p;í­[·Şv°B·ŁGŹŇ­[7ÍďščÖŞUĽkčú°22*ž<­_ż>EEE™™IÆ ÉČČ qăĆ:ë.**"44”ĄK—bbbBłfÍX˝zµ&{á…022˘I“&|őŐW 4Hďř5j„JĄâ÷ß§yóć:Ë) €â}÷ďăfnnN đňňŞR›•÷đđŕćÍ›\¸p   ĚĚĚž¸§Ën—©S§jíď‘#GXşt)666¨T*<==«TżBˇĐşżéZ^ŐzŢzë­jĹS¶NC+§ľű›ľmU¶Ľä˙………šš<!Di» Ĺšµë4˙?t(gg'ŚŚŚčűFBBĂ Łďî†jRüÍĺË—«ýZ###rrrP«Őäççëýz…B““±±±ÄÇÇăččXákĚÍÍIKKŠŻćŞ[·ną2ŮŮŮÔ®]»Úń;;;Ó¶m[Íď–––X[[sĺĘ௫Ó,--177'55•My[[[˛˛˛8ţ<€ć0‘.•_·n­ZµÂÝÝ///’’’*Ť˙äɓպÍAUU·ţ’í˘«żńńńĚ1éÓ§3cĆŚG~.‘ľńčÚOŞ«Şď/}÷7]*Úϫүččh:tč w»Býč5Á–mäç瓝ť—r&ďÍ™MbâU¦LU’“›CÝşuůzYńáÇyĽĎ{ďĎ#$4 SSS–-ő1|/ž1%·ˇřú미uë „‡‡SXXH~~ľćŢ@Öz’{ 777|||°˛˛˘k×®äĺĺifÔňňň¸yó&yyy:tHóÇ{Íš5™™iNH:t(ţţţÄÇÇS«V-­'Ş—P(L0Í›7SŻ^=rssńđđ`Ó¦M¬]»–ÂÂBŇÓÓ=z4đ×I×%mš™‚żÇ˙Ö[o‘””DLL ŕâĹ‹dddpăĆ <<< $44”‚‚ĆŤ‡Bˇ`ŕŔ¬\ąR3ŰČرcQ*•°cÇ ˝ző˘{÷îDDD§‰ÇÓÓťĺŐj5K—.ĄNť:2fĚ­ă?zôhZµ*ž%ľqă'Nś¨p,ÄŤ78yňdĄőëÚ.şúknnΆ 4Wű™đĘ+ŻĐ»wo­ŰńĄ—^ŠŻVµ´´ $$D3 [vą»»»^őTŹ.Úö“’÷Ŕúőë111©ŇUe·oÉ{H[żtí?Ú°aĂͬíßß“Úâ×ŐŻ .¤V­Z4jÔńăÇWÚ/!ÄQEW.ť+µ°Ť];/'v‰Sf‘x9áŃD'´jc×NŻň_~ůĄÖĺ ŔÉÉÉ!=V튪Q©T,^Ľůóç´ŢĺË—3aÂ5jDQQż˙ţ;+V¬Đ|Y¨iŹ[<Ź›‚‚Ţy睇vµ­OŠżç:A»wňj—n”Ö­s—lô[ÍÄ)łđ[·Ď©ďP6ϲmŰŢp'á‹Ç—ˇ?`÷vEŐÄÄÄh®4¤fÍšáç燥Ą% …‚üüüG:Łň¸Ĺó¸ ŠgĐ^ýő ŻěBŽ$`B<Ł\\\J˝cÇŽ}(őV×ăĎăćÍ7ßäÍ7ß|ÔańĚ‘gA !„BÔ0IŔ„B!j$`B!„5LŻsŔ 9yę4ÁÁˇś>Íî]ÝEyĚ8âââK•?sú¸ÎňB!„Ď*˝°čč3\şt™^˝z´·Üú¸ł§Jý~âÄÉ Ë !„B<‹ôJŔÜÜ\qssĺÎťŠ´\ÝňB!„Ď‚ę? ’ŇĎttčČ”©JîŢ˝K‡íy÷ÝŮÔ·˛ŇY^!„âYe°“đ?ű.ë|żgÇö­™›1Űű=CU-„BńT©vVňü±˛ŚŤŤ™đď±DEť¬Ry!„BgŤÁfŔÖ¬]§ů˙ˇC!8;Ëłţ„B!´Ńë°đđ¶l ??źě켔3xoÎlŻ2eŞ’śÜęÖ­Ë×ËWXŢÖ¶Ťá{#„BńĐ+ëŮł;={v׺né’/Ë-kÖ¬™ÎňB!„Ď*ąľB!D “L!„˘†I&„BQĂ$B!„¨a’€‰gNdd$>>>|űí·řűűWşĽ:”J%·nÝŞ4Ž­[·˘R©¨­'‘źźkÖ¬ˇ°°đQ‡R-UŮľ†Â7ß|óÄŽ•B;˝®‚,,,ää©Ó‡rút4»wjÖŤçA\\|©ňK‰˙Ź©WŻ.))7™2y"C†ĽeČĹcĺôéÓ„……aaaÁ˝{÷čŢ˝;ÝşuŕŇĄKŘŮ١P(¨ CŐłoß>ćĚ™C“&MذaCĄË«cüřńXýíQ\P>ţW^y…M›61lŘ0ŚŤŤ+­ÓßßźĽĽ<ŠŠŠ‹‹ĂÁÁëׯłhŃ"233ń÷÷ÇŘŘSSS&L€‰‰ ÷ďß'00´´4LMMÉĎĎÇŰŰ›ýű÷sńâEjŐŞEË–-2dÇŹççźć“O>ÁÄÄ„#GŽđ믿2sćLš7oţ@ăQÖĉQ*•Ţ Y[¨[·.ŽŽŽŚ1€óçĎăëëK‡8}ú4;väîÝ»¸¸¸0`Ŕ­ă“ššĘţýű5uŹ7Ž:uęT)~mŰ÷aéÝ»7;věxbnf­ďűÔPďk!ž4zÍ€EGźáŇĄËôęŐ“7’Ë­Ź;{ŞÔĎ©ÓŃ,\đľkżç›_ńŃÇźźźo°ŕĹăc۶mLž<™éÓ§3~üxRSS5ëV¬XaCŐ“™™Iýúő4iRĄË«ăŐW_ĹÜÜĽÔ˛˛ń›™™é]Ż——“'OÖüßÖÖ€ť;wâččČŚ3hÔ¨ű÷ď ((•J…··7ożý6fffDFFrýúufϞ͌3ČËËăŔtíÚ•ŚŚ <@Ź=°±±1xňĄŹ˛ýuttÄĆƆsçÎiĆ2&&†úőëk¶Ů´iÓ9s&żüň ÷ďß´ŹĎ /ĽŔ´iÓ4uW5ůíŰWÓ÷}j¨÷µO˝fŔÜÜ\qssĺÎť»U*?xđ ^xáyš4iB~~>ššę©¨q»víâđáĂ|˙ý÷U*źžžŽ••ÖÖÖ >śÓ§O˙‘U(Ś9’-ZĚůóçÉÉɡ~ýúLť:•S§N±iÓ&îßżŹ§§'™™1dČťőč’śśL`` fff2věXRRR`ŐŞU(  @~~ľÖĺöööZë^˛d -[¶dôčŃdggŁV«Y˛d ^^^ěßż•JE\\śfÜ*(>yđŕAśśś>|¸Î>yxx”[6iŇ$Ôj5gĎžeČ!8::˛iÓ&Ţzë-˘˘˘đööÖĚ.(•J-ZÄŕÁ5ËzőęĹŞU«čׯ­Zµ"88®]»Ň°aCť±”жKö›‘#G–ëWbb"›6mÂÄĤҺuőwÆ 4lŘ””Z´hAFFFąrćććšţéźÁWCYľľľĺ¶oEýŐE۸UEhh(?˙ü3oľů&YYY:ŰŐ¶˙oذAë~Ű´iS.^Ľ¨Wü!!!ś9s rrrpqqˇnÝşz˝ß+z_ÄĆƢ™µőđđĐ|9âiQýgARú‹ŁCG¦LUňϡ#řxÁ§ddfұC{Í·Äuë70x𠽾eŠG«uëÖ¸ąąU©ěäÉ“ńóóă§ź~âÎť;¸¸¸ŕíí ŔěŮłńöö.•4)•JćĚ™CLL jµšNť:±|ůrnßľÍâĹ‹iܸqĄőhăďďOż~ýP*•¸¸¸€¦ž™3gâí퍽˝˝ÎĺştčĐ-Způňe>˙üsęŐ«‡­­-­[·fęÔ©šY••ĹoddÄÜąs‰¨ÖL@VVšCbVVVÜ˝{—¬¬,rssËÍ`Ą¦¦Ň¤IÍďM›6%33“śśZ´h››AAAUnżěv:t¨Î~mÝş•QŁFńá‡ęÝĎżsppŕěŮł\˝z•_|±ÔşŰ·ołoß>úô鉉‰Îń©mŰ·˘ţV¤ě¸UFĄR‘””ÄŚ3čŰ·o…íjŰ˙uí·ďĽóŽŢńďŮłĄRÉôéÓ™2e wîÜŃűý®«|FF›7ofĘ”)Lź>ťvíÚqŕŔJÇG'Ť^3`ů`î»@ń ź%_1Űű=ü(~>äú ~\˙ý_-Yd¨ćD puuĹŐŐµJeíííůřăŹ9qâ+W®äµ×^ĂÝÝ]gyggg:Dff¦Öőýű÷ÇČČ &čwvv6©©©ŘŮŮ`ggG```%ŻŞ:kkk.\¸@vv6VVVÜľ}űˇtîܙڵkSPP@QQ‘Ţç”-ŻP(*¬G×ň’> 4… ’XiŰmDzýş˙>©©©ŘŘŘTZoeđőő%77—îÝ»ĄYETTź}ö {| MźíXŮţŻÍO?ý„››[ą„łl»999Z÷˙.]şT¸ßężË–-ĂŮŮ{{{† Vaěúô711•JĹĆŤČČČĂ˝â©Tý0ŔŚŤŤ™đď±DEťŕ뫸};ŤoľţJ=>Ĺ’’’¨U«]»većĚ™ěÝ»WgYµZÍŇĄK©_żľć$é˛ŚŚŠwMCv0ä ľÍ›7çćÍ›dddĐ©S'˘ŁŁč„l…Bń@ńŐ©S͇[FFŤ7ĆŇŇKKKnŢĽYŞ|Ë–-5ł”wďŢĄ^˝zXZZję8p Ű·oݰÝʶcŮ~Ĺ#4jÔ¨*•Šß˙˝Ü ß[o˝…““aaašţhmŽ=ZíŞş«˛˙kÓĽys:D^^žŢí*ŠJ÷[}öC<<<055%((ďľűNgY}űknnN đňňÂËË‹yóćifé„xšě6kÖ®Óü˙СśťťŘľ}'/]bţ‡s5¨âÉqňäÉ*ߎáرcšŐÜÜÜRpFFFäää V«ÉĎĎ'77—ĚĚLąwď^•ă)[Ź.–––X[[sĺĘ௫¬ ĄI“&Üşu‹ZµjakkKDDÖÖÖ‹__ …'''bccŹŹÇŃŃ…BA×®]Ůżżć×­[·čŃŁááášíAŹ=J}řöěŮłÜ}YúnGKKKĚÍÍIMM%&&¦şÝŐpvv¦m۶Z×˝ńĆ“››«s|´ą|ůňÇU™ęî˙ýű÷ÇÖÖ–Ő«Wk..ĐF×ţ_ÝýV›uëÖŃŞU+ÜÝÝńňň"))IłNß÷{Ůň¶¶¶deeqţüy řËţßĎóÓçď’Ź3cŕ“Y3ß.µ°aŁ&¤˙q‡ë×’pvéLúĹß–ĂĂ#X´x)ż8HRŇUÎ%$đó/űyÉŢžC‡CŘľ}'Űąs÷.>_~ĆŠ•ßqüř Öún`ő_VŻńeÄđaaańşúôhبIĺ… **ŠXiŮS§NĘŮłg‰‹‹côčњ٫»wď˛gĎ˘ŁŁ±±±ˇqăƤĄĄ±wď^rssIMM%33SSS¶oßNZZ7nÜ >>'''Meë©WŻžÎxlll "&&†äädĆŚõk×Řąs'·oß&%%…ŘŘX^yĺ´.×ĹČČcÇŽáââÂË/żĚĎ?˙Ś»»; 4Ŕ××—“'OjúpęÔ):uę¤5ţččhÎť;‡µµ5™™™ś8q33ł ŃEDDđ믿jęwppŔŘŘ8ŔÉ“'ÉÉyścAIDATÉařđáÔŞU ;;;®\ąÂŢ˝{‰ŽŽ&%%…üăÜ˝{—_~ů…“'OR·n]Ţzë-Ž;FTT/żü2VVV4nÜ””ťcabb˘u;ţß˙ýźÖ~µiÓ†Úµkłyóf^|ńEâăăůóĎ?qpp¨rmllřß˙ý_5jDĎž=i۶-/^$""‚[·n‘’’‚••íÚµăĆŤDGGÓ©S'­ă“śśĚ¶mŰHKKăŇĄK?~śk×®ńĆočŚGŰöÍĘĘŇk;ę·Ž;j-JBBMš4ÁÝÝť°°0"##ůóĎ?ąté’Övµí˙uęÔŃşßž={Vďýđĉ„……Ktt4 ĐśďUŐ÷{IË–oĐ öööěŢ˝›ŕŕ`Ž9‚……Ď=÷PüwéČ‘#Uú»$„>Jr€ ÎÓŞősŐŞ§Uë牍9…łKgb˘ŁŘłďWĘćY+W}Ź(şré\©měÚ‘x9đ°ĂLś2‹ÄË Ő B<měÚŐH;*•ŠĹ‹3ţüiO!„xTţžëíŢÉ«]şU«žÎ]z°Ńo5§ĚÂoÝJ<§ľCŮ<˶m{ąľĐ-&&FsĄ•B! Ç`WAЧʋ‹ËŁA!„x*É B!D “L!„˘†I&„BQĂô:¬°°“§NĘéÓŃěŢő×ÝĹÇŚó ..ľTů¸ł§2tŤ6ÄČČ´;w6eô3LôB!„O ˝°čč3\şt™^˝zTţNçqgO•[f¤P°aýÎťK`Ě8IŔ„BńLÓ+sssĹÍÍ•;wŞţ Ű];4˙ż˙>MšhB!Äł˘Ú·ˇ(˘ôłÜ:2eŞ’»wďҡC{Ţ}w6ő­¬8w.ť»‚HKKăúď7Xď»úB!„xşőč­÷k şöw»Řsߊďžîłä+f{ż‡˙ëhŰÖŽYłŢćöí۬\ů~?näÓ…˙c¨f…B! }žvXŻş«}dÉ|Ë266fÂżÇu€´´;Ô·˛Âľm[>űŰ·ď¬n“B!„O݆bÍÚuš˙:‚łsńC”ż\´Xł<:ú ­[·2T“B!„O$˝A†‡G°e[ůůůdgçड़ Ŕ{sf“x•)S•ääćP·n]ľ^VśxÝHNaę4%yyůňÍŠe†ď…B!ÄDݬgĎîôěŮ]뺥KľÔş|oĐýŁB!„xL,üä36oŮVnůŘ1Łřô“Ź«U§Ü _!„˘ >žOź>Ż—ZÖ§Ďë,řx~µë”L!„˘ĆĆƬXţŽŽ8::°bůWW»NIŔ„B!*annĆşµßŃłgwÖ­ýssłŞĎ`÷B!„xš5lŘÖŻ5H]2&K~~~¬Ył†ÂÂÂj˝~ďŢ˝=z”{÷îńÍ7ß››kĐřvýB!žnz%`………;Ĺç_řđϡ#J­3ÎŽŽťJýüÝú ~Őş­żx6Mś8‘ŘŘXť7ü­Lzz:ąąąpńâELMM ßĂ®_!ÄÓMŻCŃŃg¸té2˝ző$(hoąőqgOi}ÝŐk׋;W˝…¨†zőęQ·n]LMM±˛˛ÂČȰ“˝»~!„ŹžľŹ҇^ ››+nn®Üąs·ĘŻQ«Ő,ňYĘç˙YČ?˙5JďĹĂuëÖ-¨]»6ééé 0ggg’““ ÄĚĚŚÂÂB\\\زe #GŽäŔ899qďŢ=bcc),,,·üţýűLź>ťŕŕ`Îź?ONNőë×gęÔ©ěÚµ‹Ă‡3räH<““Ç 11‘M›6abbň@ýęŮł'¦¦¦( ¦M›ŔćÍ›9zô(Ó§Og×®]äçç3iŇ$Ú´iCHHgÎśÁ‚śś\\\čŐ«—ÖřuŐ/„âéˇP(jýŐ$Ą 9:tdĘT%˙:‚Ź|JFf&›·lăŤ>˝iÚ´éE*Š 6đꫯ˘T*8p ™˙ÝnţţţôëץR‰‹‹ gϞł¬¬,.\Čożý†»»;¦¦¦Z—_˝zUÓ†R©dÎś9ÄÄÄ V«:t(FFFĚť;—͡ƭ[·2jÔ(>üđĂęWŁFŤ¨S§/Ľđ#F6OMMeÁ‚ 4;ŠoĽgĎ”J%Ó§OgĘ”)ÜąsGgüşęBńtxgÎ< îWë§Ş@Ń•KĄ¶±kGâĺÂĂ3qĘ,˝ž.„Bń,+ÉźüÖ­Äsę;”Íłl۶—« …B!jš$`B!„5¬J'áíŢů°ăB!„x$Ţ™3ŹëW/×h›Uľ ňÝąú?í[ˇPTű>NB!„xú) " RWuî7ŞP(xgÎ<´Ż˝nCˇĎÉřżw†śÄ/„B˛Ć}¶Ş›«Ô49L!„˘†=p¦V«ůü CÄ"„BaPź᣹‡ăăä°ĽĽÇT…B!J<®9ŠÜU!„˘†é5VÝ[ö?Ę[ý !„âŮń¤äUNŔ Eµ¨îë„B!ôń$ĺUJŔŢ™3ď‘<)\!„˘Ş î?ęެŇĚoÝĘšC!„â™Qa6qʬšŠC!„♡3 ;üÄśČ&„Bń$Ńš€=I'± !„Bľ8ţ{÷î1jÔ(š6mŠ……˝{÷ćÚµkUŠĄ¬‡“vçŽÁËęăaŚkUąąvâĉSĄ–…‰@ĄRuâ¤fŮń¨8:tÄÂÂÂ`±r;>,ŹjźBńxŞ0366ÂŘŘš5kĆŰĘi\¸pÜÜ\>ýěKĆŤÍ{ďzÓŞeKĚĚĚhcó"ŁGŤ {÷®:ëýđĂ‰ŹŹçĆŤˇT*9räHĄÁVôşĘęLIIaŢĽyĄęËÍÍĄGŹ\ľ|™»wďbffĆäÉ“+ŤCĺŰďp5éšÁËęăaŚkUąşvââĄKdddpëÖm’’®ŇĽy3Ž=¦)yŚ.]^5h,†ÜŽËŁŘç…B<ľô:,-­xÖ¦QĂFDť8ÉźţÉČ‘Ăőj077___ćĎźOýúőquuĺ_˙úß~űmµ_WYťEEExzzňŃG•ŞłYłfĽýöŰXYYaaaÁ#t~€ý{÷u™pü˝@»Y3č&¤Ť$ż¦SVY~(©ĚyW9ĹÝh5 C'$u…Yţ8u®&Á$5:H±č4ŔšĎł™NMw(ĎQ:X-üU¨‡ž˛0âŢ+Ęîşü&úĽfüĂ}ľĎ>Ďçó<3űđ|źý®Ůl潿䠍śJŕ„BB#(.ŢŔssHúC o­Z ŔG´3Ż a˛6†’źŰĽÖ×ĺĺ·v‰Ú˙oŻÍţČkWLĐâęęĘ·‡nŢľ;xPGpđD¦M{ ťŢ`ąNo(%22˘WűŇ•qtÄ÷ßĎăO<ŸŔ`ţüć*nܸq×±đőÇćü&kcz-®žĚy!„›C °¶¶6ŞkjX˛l^^žhµ“ih8 Ŕ#ŢcşÔ`EEÍÍÍ„‡‡[^ Ł´´”ÜÜ\xŕصk´´´Ř­gŻ 77€ůóçŰíŰéÓ§ńđđ°ZVc4’ť“ËÇĺSYńOě˙ŠŘŘ©|ňqů›ňXąb>>cůt[!•‡HLÇŰożcóZ[ěµy§ľČ+ÜÜíś9s&*• wwwââ⬶ďęęJPĐËmČ:=Sb˘ŽÔR[[Çůóç9sć,?ţř4˝ĂťîÇěělüüüP*•xzzŢőVÝűňXşôuň>Čaűö"ţ¶{ŹCcQ˛ăsň>xż×âęÉśB1¸Ů]€Ą-|Ýr˙™gç1|¸-ÜŠ»»»ĺ)ß]}Ú÷ŮłgP«Ő–×Ôj5gÎś!%%…   ’““1™L¤ĄĄ‘““›››ÝzöĘŚF#ééélŢĽŮîą´¦¦&rssyőŐW­–ß?ě~śťťŮ^TŚŃX‹R©dÄá6ß/RÁĂ1™Z;Ö›˙459ťî·Ůymnn&..jkką|ů2ŮŮŮ6ű6‰ňoľĄ­­ ˝ŢŔ”hÂĂCqvvFo(Co(%<,ë?ŔĐÝ:˛6ŽŹ>ú(:ťŽ«WŻ’––ĆkŻ˝f3€´W^"*RKT¤–ŕŕ‰|}ŕ CcńňK©V—ý=ç…B ~vŠčťĚ ~3ó×8;;wúĐ5jĆÚ:ÇŹs¸Aggg€N‹!…B““›6mBŁŃGpp03f̸k=[emmmĚ›7ŹŚŚ FŹmłO&“‰řřx¦OźÎ˘E‹¬^ăĺĺIÁ–ÉËŰÄăO>Í#Źx“ľęMB‚'Z˝~ű§ĹďŔŰ{ ˙˝zŐfŰötĄÍľČëŢ˝{ůá‡Ř·o^^^Řěohč$rŢ˙ťŢ€««+ţ8994A^oŕĆŤhµ¶Ďu7†v¶Ćqúô›?F}íÚ5¸xń˘Í>–XT«ąÜÔäĐXŘÚ=íĎ9oďŹ !„‡Ý°{îą777«;áa“P*•|ÔĄ]0OOO~ęđ-ŔĆĆFˇžŻŻ/ˇˇˇNN¶S19ś‚-rč=!ÁůăËÖwËţ]]ĂŠ•oőîZÖ­]CRbÂ]óŇžĂÓ§oßÁp´ÍľČkű.Ë1ŽÝfž4'''ŢÍĘ&&:Ę’ËČH-zC)†Ň2» °îĆöÇqăĆŤ„‡‡“śśLAAC±´»xń"#GŽ‹ŢŠ«;sľăâQ!ÄŕŐí±ŞT*ţ´l1_ěÜĹ’ĄË©ŞúŽK—.QSc$oăfľŘąËj=ŤFJĄ˘ĽĽÜňÚˇC‡¸y0{çÎť455ˇŐjIOO·,LěŐłUĎ•+WnűP^^Njj*pó›d.\`Æ v_gĎžŁ¬ěZ[[Q©T<üđí;jJĄ’Ć ŤÍfËËąsç8ţ<»˙ľ€“'Ouş¶=—G+9vě8K–-w¸ÍľÎkű.ç‰'l¶Ű‘»»;M ÇŽ'&&Ęňzt”–ĆĆ řűůőz `{Ź=JJJ ۶mٰ°… : Ŕ‰úz˙ëłf=ŃĄ±č­¸ş3çŰßS!Äŕf÷äÝĚ™ý{T«Ů”_ŔěgćŇÜÜĚđá„……;µó·Áî˝÷^^xá222ŤŤĄ®®Ž’’öěŮõk×HKKcëÖ­Ś9’   ŠŠŠ={¶ÝzöĘî»ďľN}P*•¸şşRYYÉşuëزe‹e·°z»ŇÔbbMćZęNÔc6›ńőË{Yk-ĺ)ÉĎłdé ZZZ™őäă<ůÄo™›đ<ŁGŹbÉâEŻúŽgźKŔ ß۵O?5‹”äçÉz/›Ď>űśĚĚŐÄ˙nŽCmöu^ĂÂÂđöö&55•ĽĽ<<<<8|ř0Ó¦Mł9'ÂBC8r¤‚¨Č[Ź!Ńh6lÚÉvo‘u7{ăŘľCÔĐĐ€››EEEŤFül,_Y¸Q=Dkk+éo˝Á¤`ęOžtx,úclě• !„ü€ą¶ćxź5p`˙W$%żrŰn…ÉdâĹ_¤¤¤•JĹŞU«HJJbĺĘ•Ô××SXXŔúőëY˝z5UUU¨Őj›őě˝g§€ *++?~<………Ěť;·Ó5űZg¬ÂÇďWÔ«z;5=Ň_y­®®fÁ‚čt:ÜÜÜŽŽf÷îÝ–6{’źŢŠáË/ż´9Ž×Ż_'!!ââbĽ˝˝ÉĚĚdÍš5ś:uĘr`˝·Çx°ĚůÁ:w…â—Î×ÜŔ,Ŕ~Në‡Ř`Éko/ŔB,ŔÂ`ť»BńKçë?N~Ś[!„˘żÉL!„˘źÉL!„˘źÉL!„˘źőč1]!űĆPČëPÁšˇ—Bžs¨®©!ŔßżĎčo UC!ŻC!k†j\B!z¦ş¦¸ů0‹ťbŢ·a@;$„B1Ô%§¤ňŹ˝ű.fł…BNg *J{÷šB!„˘Ët:{÷} Ü:„ŻHLšŹNg¸^ !„B Q:ťÄ¤ůÍft8„o6› …ÂĹňeKđń;p˝B!„ęęNľz č,‹/ř˙°; + 9A,„BŃ :.ĽÚý·FďýĄ|JIEND®B`‚gpsim-0.30.0/doc/makefile.mingw0000664000076400007640000000141113041763626013236 00000000000000## Makefile for building the gpsim documentation. ## The build uses tools running on cygwin. ## Use: make -f makefile.mingw LYX = lyx PDFLATEX = pdflatex MAKEINDEX = makeindex PDFOPT = pdfopt RM = rm MV = mv LATEX = latex %.tex: %.lyx @echo "### Export Latex from lyx: $< -> $@" -$(LYX) --export latex $< %.dvi: %.tex @echo "### Create dvi from tex: $< -> $@" $(LATEX) $< %.txt: %.lyx @echo "### Export txt from lyx: $< -> $@" -$(LYX) --export text $< %.ps: %.lyx @echo "### Export ps from lyx: $< -> $@" -$(LYX) --export ps $< %.pdf: %.tex @echo "### Create pdf from tex: $< -> $@" $(PDFLATEX) $* -$(MAKEINDEX) $* $(PDFLATEX) $* $(PDFLATEX) $* all: gpsim.pdf gpsim.ps clean: $(RM) -f *.aux *.dvi *.idx *.ilg *.ind *.log *.pdf *.ps *.txt *.tex *.toc gpsim-0.30.0/doc/gpsim.ps0000664000076400007640000222075313117466025012114 00000000000000%!PS-Adobe-2.0 %%Creator: dvips(k) 5.996 Copyright 2016 Radical Eye Software %%Title: gpsim.dvi %%CreationDate: Mon Jun 12 20:25:25 2017 %%Pages: 73 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: NimbusRomNo9L-Regu NimbusRomNo9L-Medi SFTT1000 %%+ NimbusRomNo9L-ReguItal SFIT1000 CMSY10 StandardSymL %%DocumentPaperSizes: Letter %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -o gpsim.ps gpsim.dvi %DVIPSParameters: dpi=600 %DVIPSSource: TeX output 2017.06.12:2025 %%BeginProcSet: tex.pro 0 0 %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S /BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3 def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90 rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse} forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{ BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat {BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B /M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M} B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{ 0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc 0 0 % File 8r.enc TeX Base 1 Encoding Revision 2.0 2002-10-30 % % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, % W. Schmidt, P. Lehman", % version = "2.0", % date = "27nov06", % filename = "8r.enc", % email = "tex-fonts@@tug.org", % docstring = "This is the encoding vector for Type1 and TrueType % fonts to be used with TeX. This file is part of the % PSNFSS bundle, version 9" % @} % % The idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard encoding, ISO Latin 1, Windows ANSI including the euro symbol, % MacRoman, and some extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % These are /dotlessj /ff /ffi /ffl. % % (4) hyphen appears twice for compatibility with both ASCII and Windows. % % (5) /Euro was assigned to 128, as in Windows ANSI % % (6) Missing characters from MacRoman encoding incorporated as follows: % % PostScript MacRoman TeXBase1 % -------------- -------------- -------------- % /notequal 173 0x16 % /infinity 176 0x17 % /lessequal 178 0x18 % /greaterequal 179 0x19 % /partialdiff 182 0x1A % /summation 183 0x1B % /product 184 0x1C % /pi 185 0x1D % /integral 186 0x81 % /Omega 189 0x8D % /radical 195 0x8E % /approxequal 197 0x8F % /Delta 198 0x9D % /lozenge 215 0x9E % /TeXBase1Encoding [ % 0x00 /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef /Zcaron /zcaron % 0x10 /caron /dotlessi /dotlessj /ff /ffi /ffl /notequal /infinity /lessequal /greaterequal /partialdiff /summation /product /pi /grave /quotesingle % 0x20 /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % 0x80 /Euro /integral /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /Omega /radical /approxequal % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /Delta /lozenge /Ydieresis % 0xA0 /.notdef /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron % 0xB0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: cm-super-t1.enc 0 0 % This file is generated from `T1uni.map' and `glyphlist.txt', `gl-other.txt' % % LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ; % LIGKERN quoteleft quoteleft =: quotedblleft ; % LIGKERN quoteright quoteright =: quotedblright ; % LIGKERN comma comma =: quotedblbase ; less less =: guillemotleft ; % LIGKERN greater greater =: guillemotright ; % LIGKERN f f =: ff ; f i =: fi ; f l =: fl ; ff i =: ffi ; ff l =: ffl ; % % LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ; % LIGKERN one {} * ; * {} one ; two {} * ; * {} two ; % LIGKERN three {} * ; * {} three ; four {} * ; * {} four ; % LIGKERN five {} * ; * {} five ; six {} * ; * {} six ; % LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ; % LIGKERN nine {} * ; * {} nine ; % /T1Encoding [ % 0x00 /grave /acute /circumflex /tilde /dieresis /hungarumlaut /ring /caron /breve /macron /dotaccent /cedilla /ogonek /quotesinglbase /guilsinglleft /guilsinglright % 0x10 /quotedblleft /quotedblright /quotedblbase /guillemotleft /guillemotright /endash /emdash /afii61664 /perthousandzero % PERTHOUSAND ZERO /dotlessi /dotlessj /ff /fi /fl /ffi /ffl % 0x20 /uni2423 /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /hyphen.alt % HANGING HYPHEN % 0x80 /Abreve /Aogonek /Cacute /Ccaron /Dcaron /Ecaron /Eogonek /Gbreve /Lacute /Lcaron /Lslash /Nacute /Ncaron /Eng /Ohungarumlaut /Racute % 0x90 /Rcaron /Sacute /Scaron /Scedilla /Tcaron /Tcommaaccent /Uhungarumlaut /Uring /Ydieresis /Zacute /Zcaron /Zdotaccent /IJ /Idotaccent /dcroat /section % 0xA0 /abreve /aogonek /cacute /ccaron /dcaron /ecaron /eogonek /gbreve /lacute /lcaron /lslash /nacute /ncaron /eng /ohungarumlaut /racute % 0xB0 /rcaron /sacute /scaron /scedilla /tcaron /tcommaaccent /uhungarumlaut /uring /ydieresis /zacute /zcaron /zdotaccent /ij /exclamdown /questiondown /sterling % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /OE /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /SS % Germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /oe /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /germandbls % or /germandbls.alt ] def %%EndProcSet %%BeginProcSet: texps.pro 0 0 %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type /nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro 0 0 %! TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N /vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N /rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N /@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ /hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B /@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ /urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known {userdict/md get type/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale }if 0 setgray}N/@beginspecial{SDict begin/SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup} ifelse scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if/showpage{}N /erasepage{}N/setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{ count ocount sub{pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N /@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X /yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet %%BeginProcSet: color.pro 0 0 %! TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll }repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def /TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{ setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{ /currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC /Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC /Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0 setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0 setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61 0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC /Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0 setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87 0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{ 0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{ 0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC /Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0 setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0 setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90 0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC /Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0 setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0 0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{ 0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{ 0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC /BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0 setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC /CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0 0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1 0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11 0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0 setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0 0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC /Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0 setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0 0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0 1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC /PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0 setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{ 0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor} DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70 setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0 setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1 setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end %%EndProcSet TeXDict begin @defspecial systemdict /pdfmark known{userdict /?pdfmark systemdict /exec get put}{userdict /?pdfmark systemdict /pop get put userdict /pdfmark systemdict /cleartomark get put}ifelse /DvipsToPDF{72.27 mul Resolution div} def/PDFToDvips{72.27 div Resolution mul} def/BPToDvips{72 div Resolution mul}def/BorderArrayPatch{[exch{dup dup type/integertype eq exch type/realtype eq or{BPToDvips}if}forall]}def/HyperBorder {1 PDFToDvips} def/H.V {pdf@hoff pdf@voff null} def/H.B {/Rect[pdf@llx pdf@lly pdf@urx pdf@ury]} def/H.S {currentpoint HyperBorder add /pdf@lly exch def dup DvipsToPDF 72 add /pdf@hoff exch def HyperBorder sub /pdf@llx exch def} def/H.L {2 sub dup/HyperBasePt exch def PDFToDvips /HyperBaseDvips exch def currentpoint HyperBaseDvips sub /pdf@ury exch def/pdf@urx exch def} def/H.A {H.L currentpoint exch pop vsize 72 sub exch DvipsToPDF HyperBasePt sub sub /pdf@voff exch def} def/H.R {currentpoint HyperBorder sub /pdf@ury exch def HyperBorder add /pdf@urx exch def currentpoint exch pop vsize 72 sub exch DvipsToPDF sub /pdf@voff exch def} def /burl@stx null def /BU.S { /burl@stx null def } def /BU.SS { currentpoint /burl@lly exch def /burl@llx exch def burl@stx null ne {burl@endx burl@llx ne {BU.FL BU.S} if} if burl@stx null eq { burl@llx dup /burl@stx exch def /burl@endx exch def burl@lly dup /burl@boty exch def /burl@topy exch def } if burl@lly burl@boty gt {/burl@boty burl@lly def} if } def /BU.SE { currentpoint /burl@ury exch def dup /burl@urx exch def /burl@endx exch def burl@ury burl@topy lt {/burl@topy burl@ury def} if } def /BU.E { BU.FL } def /BU.FL { burl@stx null ne {BU.DF} if } def /BU.DF { BU.BB [ /H /I /Border [burl@border] /Color [burl@bordercolor] /Action << /Subtype /URI /URI BU.L >> /Subtype /Link BU.B /ANN pdfmark /burl@stx null def } def /BU.BB { burl@stx HyperBorder sub /burl@stx exch def burl@endx HyperBorder add /burl@endx exch def burl@boty HyperBorder add /burl@boty exch def burl@topy HyperBorder sub /burl@topy exch def } def /BU.B { /Rect[burl@stx burl@boty burl@endx burl@topy] } def /eop where { begin /@ldeopburl /eop load def /eop { SDict begin BU.FL end @ldeopburl } def end } { /eop { SDict begin BU.FL end } def } ifelse @fedspecial end %%BeginFont: CMSY10 %!PS-AdobeFont-1.0: CMSY10 003.002 %%Title: CMSY10 %Version: 003.002 %%CreationDate: Mon Jul 13 16:17:00 2009 %%Creator: David M. Jones %Copyright: Copyright (c) 1997, 2009 American Mathematical Society %Copyright: (), with Reserved Font Name CMSY10. % This Font Software is licensed under the SIL Open Font License, Version 1.1. % This license is in the accompanying file OFL.txt, and is also % available with a FAQ at: http://scripts.sil.org/OFL. %%EndComments FontDirectory/CMSY10 known{/CMSY10 findfont dup/UniqueID known{dup /UniqueID get 5096651 eq exch/FontType get 1 eq and}{pop false}ifelse {save true}{false}ifelse}{false}ifelse 11 dict begin /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def /FontName /CMSY10 def /FontBBox {-29 -960 1116 775 }readonly def /PaintType 0 def /FontInfo 9 dict dup begin /version (003.002) readonly def /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMSY10.) readonly def /FullName (CMSY10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.04 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 13 /circlecopyrt put dup 15 /bullet put readonly def currentdict end currentfile eexec D9D66F633B846AB284BCF8B0411B772DE5CD06DFE1BE899059C588357426D7A0 7B684C079A47D271426064AD18CB9750D8A986D1D67C1B2AEEF8CE785CC19C81 DE96489F740045C5E342F02DA1C9F9F3C167651E646F1A67CF379789E311EF91 511D0F605B045B279357D6FC8537C233E7AEE6A4FDBE73E75A39EB206D20A6F6 1021961B748D419EBEEB028B592124E174CA595C108E12725B9875544955CFFD 028B698EF742BC8C19F979E35B8E99CADDDDC89CC6C59733F2A24BC3AF36AD86 1319147A4A219ECB92D0D9F6228B51A97C29547000FCC8A581BE543D73F1FED4 3D08C53693138003C01E1D216B185179E1856E2A05AA6C66AABB68B7E4409021 91AA9D8E4C5FBBDA55F1BB6BC679EABA06BE9795DB920A6343CE934B04D75DF2 E0C30B8FD2E475FE0D66D4AA65821864C7DD6AC9939A04094EEA832EAD33DB7A 11EE8D595FB0E543D0E80D31D584B97879B3C7B4A85CC6358A41342D70AD0B97 C14123421FE8A7D131FB0D03900B392FDA0ABAFC25E946D2251F150EC595E857 D17AE424DB76B431366086F377B2A0EEFD3909E3FA35E51886FC318989C1EF20 B6F5990F1D39C22127F0A47BC8461F3AFDF87D9BDA4B6C1D1CFD7513F1E3C3D3 93BEF764AA832316343F9FE869A720E4AA87AE76FA87A833BBC5892DE05B867F 10FA225E233BCFA9BB51F46A6DF22ADCEACC01C3CD1F54C9AEFA25E92EFAC00D 7E2BA427C25483BA42A199F4D2E43DFCE79A7156F7417ACF78E41FCA91E6C9EF B933450D851B73A6AB6AEA7EE4C710CB5C14270D1674FA334686653793FCB31B 491E870D3C2BC654D2C1DE463EC9BA29D7371AA1078800EF93D3F66263A2EBBB F5723697BF7448BD0D2E301544BECF497FD475B85DFEF52AF4F8F8BE445CABE6 019318806D10C5952157FF8F8286C1EE701545C8F60EFA854EAE66835A2046A6 915D395F1E0366EFE0C0391583FE001FF16D82A2E2DA5F57754A2C6F69306E36 356ECF8EFC3F1188AD6FCD2427E0580C97A5B69B4E0E09B85EEDE142F5ADD2F0 5DE51D6DB72B127412A0D57106C19CA493048A4F815129ABE767D51715B1515D 9C21067CB5BC88741B7298C83EAE36A866DFA87D8981F179B1C31292F56BBB64 3C430779468AAF07C8A8B4934E1E775FE3F35186BD1FA6EE3689C1C750678AF1 FBF9B23195A124C5C991FE670AC0C86FD39D2B07B9A319E74EFD498B45820252 720ECDF7294F7B0B137CEB86D33BFCEB8606985A3260FD669E461C8BE94216C5 D434FD8854F44EE66E5A289A9F9E32BC36AF645D53F96652602BAED418C8D726 BD04A1B4617551FE4DEF54083D414F7DCE004E6BB2DC9C2EF7CE232B254BA2C5 7DCBD36C2072ED46FF711F121A701E2284BF1B718B3164382B8F453D68FA0377 DFE106503B8401D4DB87F5402A3AC9A442FA060B0610A9524D530C7157C26B56 AC970FCC1D5655FFFFA39246E6420CF97D08ADFB7B05822679BD40C638DDF0E7 A97BFE8918B611A145AC965C203F1428812F9D340AF499B3A915B22BE798594E 0F520109FC81E452180AE45B170FF999C5FC2761C6CECD8742A5A6FC97F16743 AD4EFCC6572A6D3F3E4E330C5CB2FF6FEA48A5B64DD3DBE943BD9918D4A18E18 CBCF598AEFBB6AB3CD2CBC9BFD6099272F6543F3E532E0E21E614BD2880B1023 0AC234CB705827BF016DB84E00E8C255FDEFA0101A842929540B7B4AA8A089BD 5EFF05B72356B6BC3727817823B5CDBB1B963103000D7F2A4E2A1472FC3E614B 5CBCB6D6D784023173DEFEBFA8F9ED87EC1A0A9EE98CA59CFC964CF943DC683F E9E00DA718C4425A705A69D99988EC6F152525C790912C2E46A2381A569424AB 54DF4798BC2D7E7A361E7991641D4B756CE2A7FF4A2848927092C59C2C4B8809 E13AB84FB6B111E680D7FB9F2FFC2C5C66B0B501E4447C2E46C10E2F6124476F A140C404CFE2DC9E0199BF61E035CEB481D438139A9630934E541D261FFD2906 4CAD99E20655FA746AFB81EDBB5601F5FD6B1D6832A01D585E2C55053F6A7378 4DAACCAC7608DBDADAAE732D66B3E7F87E79756337C1A961E53A4651BE7C77F4 038B89C87F650C54A2A90EB7F1D525BB353F33318551EE8D84A6A83C718EA5A4 B2AC0F7306B1E095819B87015A90CA3ED739B09061782C28CDB36BA4BD5E5308 5CBB70414E4112193DAC4A1FA30996327230D1E021F3CD8115E12D239D93FFDC B645910EB29E40D830E7BAF2DB255FD7C4E776557BB38157917D993EAC245837 A3B515147043574157B8342D829C7228CCEA843ABC89D1785A9672A5923FC4CD 2F3FF27E6FCACF84E2D3136CA2C0FD3EF1EE7354CD04C38B5FB874553646ED2D CEDF7E362EADD04B18051F20A8FB0DE18E152385B9D05F98A3A7EF177824E246 455ABE69E2F700EB78185CCFC07E3B4C6FA301112528D977367D30D0D5D59EDE FAEB706DDC970A9E296236C725B2B55B09B9C336B8E23CBA5FB8692D56F33B03 16294E5FC7FAA42E96395A57CE51CA8DDD77442F142E2E576B778373FB31C81C 16840BB422CA827E30A81829648BDF1CA36700EA32AD888D097C1FE0A05B2D9F 483AEE40269DF09AF0D1AD3DF80C45DDC59C2A03FBB661C79B87853737C6D352 67626B657321B16198DBD6DB98A092F17878AE4698121E1006E53D6F9B0A3BE2 3FB68828EF854A0CDBAA68B37ABCA6AD4A3D809AAF0BAB1697A81FE59C98C472 1E33CD70A75A22C249DD11D76C2575ED3370A25892A16D2FD569CDA70C130770 93F493C7D47D6F9A5424A7A542BAD726BFC3AB225DCEBBE6AC4BE006F8C7C0EA 051424B08305BF2D951AB2986AAFEA04E078CA79B399585BFF0F1ADCED02E15B 8765EB6BF6A8E4D0901EFF2C3AA104924EAD9637A35D877E0C51A3C37DA78CD4 8643C8CE6DCDDE3F116A6C2390F948E5371BEB5AD2E87B41C5F01FB5C196C436 6E256A88D082E3F46E4EFFBF605B2EFF1E9D9AD5EE4DDC323A137CD9451EDEE0 06F7D82898D71FAF2362C0FCF1F726F97F820305B7CE20728CA08C63575083A7 84BA28B7DE2B916432475510E274C12FFD1660A717F51DACFDF0A102D85224E0 D6DB607BB72569ABB8A7BC6A10354CBBC01732EFE35B72062DF269CB25EA3DE6 DC603B04C90C5912D2C38D7A5ACDCDD3F6F116D884F0D8C528F69D5D47BA20DB 0A9E585C7D8CC3C324FE8A1DF150279F7E8FB43BDB720E624E5E9918032C02CD 8020636AE5C38DA2484B7F4B34163E0D0A561B43B80E97746DC05C871AB620EC C5D47101ECED4A7E25F291184BEF8B80024AA7BB456C1B83A907652B331DEA34 754226C39C6889EBEEFDAD081E01EF8FE47751987667836FDE4C8BB8A3FD4406 1E643B4EA37BD370734D1A2DB17C2F4B74B4ED75098B433601F75A88C9A37A05 CCB157EF6E32023BFA33973F3E655A4D58289136996FCFA61EEABD70791B6523 1FF5DE71AB8A17038923118A5EED8D59C4C58D246FFA9BB26472346B40C8741F 153D19CAFF20DD2A86C6DB89154A630FB1761929FC3F0448EE2F089C1C953E02 905BA8DE75D101A982A611056C4B237596C10951DD98BAB838B742D3CF7DE718 617DB72E5268583223E37E029D1C8FD3F1D21690151F76B76C52C725CA135CA2 8666553E863CE188BFC9B99AF56AC2DB5BFEBEB12FB563D00244EB89E478657A 98AF2E1223C1ABC25A4500E8119B86EB3C26B8A2F3505A3E5610F89B7C34E278 53FA0A54A7F46D84A35EFEC36AE660A9E3C37EE3864106702DE5AF6C45ABF64B 888A4A51323138CE77DB935576FE6B4824B6942DF80625098CE1B5B32B234F1D 052A9D6039697118A9D793793775D8729D8574A2E74D7109C7B7E23BC5E2E87A CA8E019203952A4892544E1AD3D4EDD22971611358AB230E9A2ABDF00A288501 A01B67C42B33F6B78C39562DB50F4663B922D9BE0D8A150311AE44B83C1F129F 07337323E9A23211EE58E16043E127C6F9574019179F5635648A011266677B56 B5D0201A4E1470B952A1579B57AB2329CD4C615395023C653F784D36B5EE3672 10D191F29EA508CE84763CA4CE7C2C5229E38E241255A5CABCD6C7CBAED901A2 CA53B5E24111921CDDF83578D33D463D70EDACA0E470D8F592303FB6BFD68B4D 3F3BE2D7C5EC8BBF10C90111A33E205F2649B56E8443F6FAA6C721C66575AE12 D4C40F1F46CF9E9DA675AB5D5840D938780CD9E4AD6736ECBEB6A4397613586F 849B51048AC5F9405E03E14540A5E5582F61CDCDB57EDDF95A8C6705F433EE16 648F098C03DED8A2AD94AE3DE202D629B9422ABB031318D48F2C85F9DBFA17BE 84708AA3B6C9F81F4508F7A5CB7B6646AB8722ECF817877B77D473F577556DAA 2BA0ABACFCF5DEA7498C47328E873019A956FBB250FD9D8885D21D368FA70CBD 2709D2DA44EE7A9869963EAB48789541906DE49FAE785ECE1F18A22C7E7ED204 9768896B78E9EB7A2BD6EEC1B26083940656ECD689D92942CC8AF05CBF82AED0 B45A7DF4DD7AA6526FB597322560B9ED3087A65B5EEF1371C328A021411BFE3B D9B5088B2F1AAE381FFED52D2D1E02CD0DA78683E3B06171CBE94BE9760005D7 135893D7CC2DB097F6AC664D9594CF1C650F84DA80D2EDE04802DBA33CE3DAFE EB7A37E8AEFA4FDA6252FF21E8673DD98E67124D5DBC7BACF361E57077B71939 C1D1FB923E4E35C075CD1BCBE0E80DAEA1320D55B43EAB45D9B26C366B278782 7519FDC482D98839BF0DF2E7C3A56A1C1A3FC0E57A75CA414F6536C1FE8EB7A0 4ADFEE3BEDA0F53BE8CF5F64230784A797133E8CD46BCCB3BF38BCE38A73CCE2 9E073ADE792F7128231DDD1F63E6156ADB2609C200837C2E8A2D93D2A7BC9171 050C709A71E44E32B1B03C92EB5CF1D3BAB1C38E027DC4ED9AED633D98CD7486 3F773ACF8AE332631CF2ABE6D606607593FE862ADE31803964E3F4DC3CE3A271 C76BDD95C87CDB3B87BC26FC7A16D567EEC62E6FF0D471B4853DB8A94D4CACF8 843824F818083F10E88D52FC4253E8203292CB40F1414AE7E51DD7347007C342 CD70E8E9F2D2A13D71213B841DDEAAB208AD9EA644591C15DEB084165F9DF24B B91D3BBEEC2E34E38EF16A0C3F00700A7BDCBBFED2EC0D09601AD6538288DB50 3478B051B5E16B604A0341FE621A58718D960D699D3FAD284310DCF54EB13175 19A75A539EE98E804AEA24689D3540F0F12951A3C01FACCE9A7BAF4D0DAFA946 FF65A4D2A4C39969607272C6886F44E90ABE27CA3A1F12A29D9B32E60E8E34F0 17C5FE43D0E69A99A922D98909B2BBCD145E59A5E7F5426B3988F73B09A525F6 8BD4915663C1301323180E760BE81CB874B020FDA3AE63340E4261E4F3E4949B CC0966BDC4426190BE9F5D77F76A72AD925662E5FE1CEF9CCAB68F0BD33DA003 F11EB91AC4502FBD6AE48DA0F9D07C35B96B103E379B8A83A05FE728F1716194 1F650F75BEBADB2E3810388F3E2DC7B19F1BA9E32925F2FD9F19F4E8701F3E4E 4069125D7C401144740691E7A460021A47B1E27997FC1DDABEC5BD0EE0B20194 2D579C7D6727AA124083242BDA46D8E116E2751C5F298851A62B60AEBE82A929 9B9F2492BA35690D1EFD16215B8EF14E7A3803B93C28FA41D971B05B6AF3B593 E74AD1E68A5FCE12A86E63B78BFEA87D3949FD164F12277A4688BE96356791CB 8671C49365608F3EDECC109321AF92B4C29CAF073DA3A7D73E913D0D83FAC5EB BD884D4C686056404DAAAD6F82F94F803FA1FB0DD8908D1DF08FB87A8BB83027 04DE0CBB1C6FEB6B517FBD7CF065120079E608CE41893C2BC96A347826CCDFD5 C69E161217F2127A59F1A6F22037641613F191F22D5B4CDCBCC2EE5615623404 ABA7BE6C5FE475481615B2AC1A2412E54688DD21E44CC9AF5F16E634AFCA389C 4D740B7B51BB141BFAD1080E7C726C1606A28ED492E6BDE9F800EFACD1513909 84E98CEB6A0B7A2A6F3E1D1DCC3B2552795E0932673E59ECC56DDD37A1D52BA6 C3F0E905978AB568941A163F4CE3AAB5C5B16F86016EC47BA6F3F7AAAA77C3B6 09C8C3ABDB6D514A76ECD37C37AA88B5860630B3406B494F7725975596F84777 D9CF48686EC9C5DBCC1D78513F591C7C10AB9D153B3D41426B7BF668B0D04503 56BCB686258462C1DC61095724B9F3312316262FD7C1AEC6E54DE7E5A7BD8EFF 035299B8FD8A4A7B0F51404F4A760F4D8B4C0FB7A32FA4B2383AB6E9C78FDEDB FE6A5788D38A6701B123630C2A6D820A684166FBBC83DB17069494FBD411B333 CB37E2491C5BD035A33867A6D3A3D420CC31ACF43AA07182CAAE67E40EC63663 B678F71D4C6E0EC3A0AAF904CD3AA66E0DE5E3CDE049E94249B39A1C06E3CE9A F974B2484BB2CDA14282B9511E505B3C89F9C802218AE40D1A7541335C5736DD CD565D4B9F4CC78F3A393737EDB4FBD0DA299E21CCFEBA5478EEF013F0552A8B 0BB11FF46CCDB784E8BDCF730A16363E66572049E42C695886EAB42A9AD9094C B635DF4B5B9BD9B9AE8455DFA3EEFC77653190F9A8B1E93B7281C2A21EA7DDA9 33484745BDF7E3DD63C7AC66C286C9A5A698A5E4D7A91710B7FF943FB23609B6 4B442F83CB795788FAB5E9CF3F75D5487DA26170E4561C7941C910B088C3B86D F844B0F340CF82786A3FCF347048463EBD2006281A816627065DDA6CD4D3AC5E 2024BC96C7D896381BBB567951E7A1F29D4E95351298B000D29E5F3D0448CB5A CFDAE1BADE9403B90371C3A07D208948AFA022A69C519434B6813086ADF518D5 88E0B92072A44BA1B3EBB630A13B7AB90992E85B6D67361C8D96F3E0D826FF37 17B67E4B1EB7BADFD98D7F4FD17BECE740ADF13C141EBF0A91CB105DABB32FE0 55086D56A0D358841D15FD349E6B95512E4EDF4C430216FF85C2ABE995E4B40A A6044CC8820AD885C07E052B3F91C2E9A1D163BFFD210F7BE95B923E2500DB50 2075106DB541C267BD450B25B670CE80BCD068D4DBFF2D82634175B61FBD3BC3 406131F44C7D6F18D375D1F2270829DDF29DC14DBB58A30AC193245D18DE91F8 AB88AB548D8138605BB5A50073295534E314366E26665AE70482B890E4101D6B 60E4F3B37ABCA1346DAAE8FDB8DD9C832EFF3E73BA470E2BACE7B8515CB43388 C27AF99FF9322175CF8D4947E6B3846AFF5163E972156847F58A66660EC8A3A6 5FB47C9F637B4CBB4C73B6A080B0CF6FD1E9665E92032540570FFCC747C67C50 822811AADC404BC7ECD1673E8AA6C3A2F1D82F39430B58C29145E2F1B679C46E 94EDC711883F1E4EA84117A54757E8895A40401A26E1437B39A2F65CAADD6E02 D71FA8AF7453668DC613F326A3344F74AD7AC67569AF399385500ABDA5EDD3BA 343CC5EDD4B558467626850E752B9959FEF1454E53E7A3DCBC2255AD8F6AB4FE 894455118A61C58840CB68A925ACCAD75CEACE863D806916228F0614191A1CD5 DC9BAE256018615AA3725834519449B0A88B4F396654E74099C007930ADB1327 DD119BF799FE3B0B223E1EDA04FE2DA7A1C879143E1C33B6C6344F4BA033AD6F 8E88C33DEF1977796B454BAB2494C930F492A518E8198C708A75FFEF8C49C324 A718AB59B889DED521229E741FFE53F98EBE88B0405AD523254FD3FA4BBE96DA DA1C27C1C979A0DD4E61C3B1F4C4DE01E42F1C4435EECFC02D97994BC8AF5270 E7CB1458D76ED0229C5FFB4A23B8716018F9050970895D51722CDE8F2EA3D947 DFF374D84915D5C5D16463A6FFCD079D1ED416C4347BF831FF0C4ADFB61295DC 4D5785BB0852BF472CFC97EC174491CAF961AB90629F055E75DAA6D9898E8653 5BCF379816CAE46FEA62E7BE8E9B953466E51828172C4DBD0E1BBAD1CE28B5B1 02B3E36403BE80B49A47446A6677FCED438F01D60EB10F478C89528FA337D0D8 88D3FC123C076507ACDAF783A9A6E24ED73BF24B6E0F11C13E532DE5F70B15A0 657F5ED27D204449A841ED19E01432CFFE928E921321113780D036D34F2797DE D4459CFD15BB117B5C9745EF3CD2B296D91FAD48C80B136D94476967E255F808 AD2B5D522ADEC64176833756510391815A1D4A8DA1D0AEE7CAD36A1D161889F2 3347D5B6BC503300FDDD48F594F391D5FB42C42113C538E707C16EE24A3F375E 7C506E8F49CE50FF9DEF3B4A4C1BEB3848EAA3477349833BA22D2A9012287D8B A8C4CB4307A1188ACC0E6E9338E1559BE5FAFF381BD82A6C71C267409468B3C0 2C1A29F4281D565836EAE57F680490FEA4A952FF64C8CD11C377C294DCD1EC25 CEFB2B6DCE959D0208F85B6E32E9B44FD455F9B134A5306D95EA29F37BB8B86D 9E592159338E1293F449380E13C21AE42E6861DBBF4AE99A7469F871A3940835 FFBE7F316FA9BB834EAB18625F0960352C75105A92F175850289B1AE177E0D52 E43635C41B85F75CFB706BC92B0BF90367E180A141703EF69FD064C0FA34618A 5D9684895C3EF50F4AAF6E0F78D483280942D3F9C1A18FE7FA657928477AAC74 ABCC21B622EBE2C0AD9EDEDAEDAA9A6E3D96E01CC837668FAC44FB52307CE618 BE8399078154C80E7DB52F0CD16717DC59203497E89D69B390E9966C19D36188 E47270673493F7DFC14C72B5B4737AD52783C573B5F12D50E9D54AD65C2C310C 72BAF2A8ADAD81ACF0C49DF971775F2DB7404FC9AD6B30C947A348B28B0C042F CD9756359BA6942D643D8B7BC54E6047DFE25215CE5EE74CC3076975A3F324DF E8D80F42AE4A1C00B155FE56A61CCC09924E4D7DA7EE07987C2EF9E91AED55CF 524C54E553030B5F 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark {restore}if %%EndFont %%BeginFont: NimbusRomNo9L-Regu %!PS-AdobeFont-1.0: NimbusRomNo9L-Regu 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Roman No9 L Regular) readonly def /FamilyName (Nimbus Roman No9 L) readonly def /Weight (Regular) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusRomNo9L-Regu def /PaintType 0 def /WMode 0 def /FontBBox {-168 -281 1000 924} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8E152A40E590419249F2E4 C36159F8E54B532468E36965A38646781AB0B7F6A3E851FD10CAA49ADFC1E546 2FD2EC6150DC6E19523050F6148348A561AD8D2E2721EFF8A570CB33460A745B 926C889304C09753C2D78FB0CA95DC6DE5B8C524752C83601E7E9F73DF660674 F05AD83A166DA9BE89F22FEABD4B2665960F6FB5BC32928E1230C212E5D69CEE 0B3311A1738A11747AE263106916D8E95F25B25B4BC6AFB03B79ABB95DDA518B 41A49458111D2A1433C043627EF9460D324FFE22935F4F6DA88B8B91AE95B34E 08408A34EC8EAC3F65B6AE3E3E2524867EE9D29068F81E4372F4470BEEB4D6BE EE4DF956BECC0CB77F8490117B22B2FB75C938ED0A5E208D88BC38B2AB8B9CFB F1D53084B6F43DF336481ECA0AA2D5317BC83FC0E1D4DB01D0B7707EEF217E94 A7F985102DED27D8E8B009F7EF6DB91B91E78BFAE7BD688E10B3DC9AC77CDEE8 47AA4DC8EC78241E593D26EC7A60696151A2AE5325D736E99E01BDCBDE69579F 92EEEC224B6757EEDC64A75455BB665DF42A0E4CE7B99BF3E7D66F8FFC8C13F9 D7A1FF7A9D5FF7AC43396779F11C9B008C33A2043D48B61B88B03104B1425F09 675B559CA4302C001EE80D2B739CC0FD1023BF4F1FF9C01E892E59CCA7C26011 B8E0B6D29CC29FC72792FDA5E7D5D88EF98F9DBA960C96534C399C54865EAB86 0FA2E0D6C7C44B553EAC1574D55E7970744D4792FFFBDCE6FB4365BDBC2965BB 2E9EDAD9E0EBF0B620DB415AD98297F5AE83D9C710436657E74D26E83957C745 89834337035A7501803947F6880B70E56A3A404C62D57B849D28804CBE0F5884 435A0E12DCC9BA414ABB732BFBAE237001F557DEA5E972BA0838A3C7C9EB75AA 4A050DA0A529BDFFBF9011C360564FD17A02C18860AF6B86EFD4E2C125686C9A 5E114E95C71FC89A5DE9C589BFE5AC0480CFF716345265D2435EDAE67CFC4801 5BC08E7A48D683ACDB91E05F469C0C8919D73A5D07A1CCB173E30E76680ACB09 02A40A3E11916198BD69F1A26E88330F50692D0D5917E99E7A01B327413E24AA E98EA484E45897E6AE4D6997B6E8BBF61C9406E916D56985CB2BD297E8ACFC6E CF2D2281AD84696B7C6CB584BD85CC20BA14ADD3BC3E25DB91124C0ACF22E902 3CFBF04CC40DE331991E9075D22AB5EE0E849B340050E6C417C664A782D05549 DB2EF572F193B1C12B4635C2B358747046DE5858EC32B3B2E79D42750657977F ACDD2EE5A7C9320D907438DBA63AA05ED410FC7000F53549091BE71BE45DA4AB A315F95B724A60F17C70833E889CFE7EA206A7ABC4393CB6EF47BE3700BA5638 6831391809EF8384AEA8C22735E8062A9F9101ADD125A321FB65399CBCD9C9E6 0F46FBF271B2B1EC80832CC054BAB5CA80D4561DA0A380D56D5CB3D90AE89A19 48CD824EB1E7AC6127A6DBA3E8EA40F00ADD89749D77EC0EEBE26FD6EA5D8CCE F7239681B3D94898236AE92FF3912E0AFE84B6C7E08134C158B640B4AECAB5F2 A90028E67D33DF31B461A2846F83D90979BB22618E2A17C5D159FB59D5177E12 EDF1320F596E7A4C379329ADB367F92BF2869A9A97398E0C20F5F017CA9DB7BA B3BAB72B87A7B6BF4FEBD03132F9075C271F2054078396DF8403DC91461325F6 12CF1421F3099CCD799C2C099492C4F071336D985C0C360B2F5A5877FD00B6F9 2E5911DDDFB31D17A60124EE8DA6CBDA94196D7ED42804610E4F730DAF2F2D5A B767C320C62543E26534314FACAE006BA2064623902C8AC479EEEBB609E8C3E4 1516CE412CB410BD026231E22A9CD0F664D769E4E45CBB75B7341F06D8E37285 BEAA9AB71AABE3CBFE5A348681AA246047CA29CA6B442FEADE254C7582D32D3C 71B5E645C82E92F057EB5F859BEE23DAA95C575EDAAF9896D6C10980A09DB34E 084C8A754E31B618C6991BAA856CB86877044E10C2F189B284E3195A2DB6B910 2574E2461D2FAE65B7321C0093A2A34996C0B77123503E9EDC623DD02C44FB76 3C550840BDF969582D226510EBF89944E59684EB2E2C463E69702266FBCF8D1D 4C0BE400495E227B9CB21C8086F328782CA7294DCF3ECDC1A62714143A4C1B98 E5DE1DD554FBA60571188A58F0354A6B9EF580689B78A0C8515CA05A35832616 7E0A90F68F3C306AB60AAB20872FB167673F41E8E87FF0111F579CBD0DA68B56 3E35D2EBF9F28B104082E36187373EFC7A33F62D3FE4A390B63A76E9B2531871 6BD59861F51B561DCC115192A6FC22D15A5AF03BA09CDFA66B660CF4288E9D79 26E797256659B0FF64BB5D900990C3CB588E1E18810BCB009A91E5F4F8D9DB1A F2A063BDABD9C3332F4BDB701BB94B4FD24570B440AE74B8D924E48E7C2DEFB0 53A19E5B4DF39ABF4F6FC6160B5FCCA00608422A3091CD03E726B1EA1D203B3F C44173460B490498EDA3121881EBD21CB5B571D21A6228CC0A1B035EBE97F26B 0B58179BD22AC950EC3A98458051A874297CD6BFE731C5B413819503111F1F6E EBFB5628C955F5FCAED76F2402CE351F77E471D1C9821DAD627FF25131590577 5FF9335DD28D85A11BF155765632B34A3AA1DF9C01134BD8FE927E0064319951 E2C1D374C9ACFC30932712A5C3E0FE3C7E355E3356E9135A143F1B4E2738E208 8F44633DD9300BAFC770625A64B2BD20D4F672701310E5D1D5B2DD502802539A 65344601924C473B7618F9B87BF6EB49474FE62891097B9B381DFC9DD22F6CEB 340EFD950B74E614A2908EEA7B0D395E15943D0A9072E2C0E6C91D9141C84281 6A59F02111333723DB78C2C287675D73152EE3C63397F5EA6203C707568137E0 12438B86EAD16D71A0A56D00E6ACE9D80AFF646B05D829DCF08DCE2FED1A17D3 83A7C9E7C2A5CAEB38BDA802E6696BAB17A5D1E5D6C51B6371C642D5588A2945 1F3C8B0CD56806531579F7C0D10A9FBE254EA910522D955C86DDD693B8660BBD 17B2B23FEA57AF15B1720E42C6DE537074C071C50C114AC54C45BA2FEE00D13A 2573BB9243648A1BE2569CF68FF78E4CACACDB34DAD918A30005C31F17781633 6B74AF8B9931BEC0C1892780020C1A92470E3AD7F1BB6EF26C835F13A9C56DED 51DF4A7847C993B88B9FDA9A8955D8BDBF6BA773D06645E292CE26D9DF4BBD4F 3D20F52161853827837C837F33425990818B958ADCC3AE79B5791FF04DAA32FE 54050AA9D34606F16C7763DE770CC33C9ACB60E5354D5A27A687CA6E0FD74A4B 5CFFEADF6AD0BA87B906C09201FF65CE6C3F620BBFAACCBE54DA884B87E906B5 F5285D3841ECF78F0A1EE4A80724DA3A4FD49FFBAA66BE3402A2480A6F8FC164 343A369E2B8947FD5F58A4697234C742685421CE3D57398C5ED6F6B049FDF39F 6870236751D9EF2210E680B4D8A6DAAB758BD7FA7DA9680604E5BF85D1826611 2CA08E8922A1D46AC853F4BDCA37F7FE80D2D27854012E4A8F70BD854EA4C189 EA6939096B56168AEB971AAAFE1BCA667137A76761CBA2FBFFCEAFE3E98D5590 DB3DBC44B3F9D4EF0419CAE23086898BB25A222EEA19C1A760389672933EA7C2 8B31025619BD108B79D51D54E23F401F42165F0D513BB2409CE66BA3E83FC000 4372873EB8B4405A8F5BD88CC2F21D2D60FA4024707869C5FD40D94028ED13B2 5762CC7924D100D3CE0DD32CFCA124EC1FCE4CCE8C137070A18F05CD73809449 BCDEB0AC24DCF63679D46AA8B3A4A5D0DBFA9342716619CD3683DFA7A9D6683E 5A7A03DDB47833FDFF8935F2F004F58EDE6447ADCE4FDA1B734C75C52D16C406 9428CDF68855946014584F7FE49B03F896E0054CFFFF5DA4728BF4CE1D892052 701B48B81F58F5EA344E8EBFE13BAA70CB43CE4A979D8225ED78417648672E61 07EB7B31F81CF52B4136288200E640654E83534EADF05301FAF2F3A859772C3A 545FC20429119FF00C259AA582AF4E3CDE1C99769F4E433D9B178EDCECF142AD FFAA6DA004A90F53E70048AA8D15A26BFCF7B02ED70BC262D165E99F87CA7424 0EB98F3D7FC0D4926AE43C8D322BB9ECA24A4C45F7DBB0FEAA9A900E3521D6B3 87B52A30ACB29C914B06793F19A1EFBE3BE7D0B8E20CAD99D292C315B12376D5 655121189A833132715762CA7118685814F71AAA08B89E466C7468BCA01BD98B 63EC7CC3AC41DD06C5BBDA86227AFCC1F7796B5F878946C135BFA75A98DB1B57 0F38C49770AE23986FFAEDBF6644DF58A252C29AC821F4584B96B5DDAFA9B3A1 AA0EF6D17FC1E75916753BC8C799497E1279EC783EA86DF307CD54B58C2B3EBB FD722006D127834B089670E5F1E7BA8BC4A0F6181BB4EFBB8F99E4475181449F 2FCB255DA4233F7AB097EF0108BA3FC12CDA0618870EACB9FE4195DFAB182242 BAE0956D09E388D10DA2F940186E25C9926886E9806C70105DC75259FB1E5DA2 675E4E114F84862E6B822A10A9D364B1CD13DCA3D385B83499C715ECD7598766 B215910F002358D592FC36D0BD482EE9CC338378EA1566839526A5783F250818 078B97D73B1D62A1AAD3D5A9753BFEF23F7B3E6D5BD318C463AA04490B9063A0 E83E3E68109B182720D2B1C13B498F8F495661C0F4E6455B96A6A92FF806F1CB 3B1C6EAC82D9A687B83C572C42DF22BEAE31D1239719186F14EF637FE4E7C7B1 FE8F4F1BD8367D76D467BE95C394A818198D922BCAEEEE371FE17E396B27CEC5 F0554778587FC7D78ACDF317A8EFDFC82C2F57B6411B3AB68F96E3E7CD321A6D 4783435056AB5A0095726435BE6885BF2784FB2CBEFFC0F8248DCD594D34B21C 98E67DE50B6876C3D6D4D4CA7CE0B9013EBE754B104DCFC0719A10CDD9985E19 2CDF4E88876C2DD4E79E23AFA70AB5B4758AF32EE87B8415B881AC15C5C3E1BC D17A5B961EFB3A8DC987DEDED6F28A240D66F004AD05CE1C551E29B45668DB2B 305C9B1AF5CD5388A0802D80F18E0F4BC8065BAF393FFAB9A4D674312C2033D2 7C78B5E9461FB09B9B2CAAAB70CEB3AFA574C89BC620328211C85656F63A8DDD 97C827297327B7980C2FE0ACB1C34866AA3C5D7408E257EBA3C53DE8338BDF96 CB7BA55FE31BDDBF7807148C0A132BDBBE8A2C21A23E11889DA13E429914F7F5 7132936359A0CC65E5993CAF52902F76F75D6CB46DD20A3C0BE80D45F2C746BF 236733462080FBDC8C5C1DBE9781F45ABA74AF8033A6EF2BDB16F7B0930D6B6E 7CA7FAC8CFB2DFAB8C063D961077585D24E8FBB5E0B0BEE9C4509B23361DD06A DD25767833B9A770780B311F608CAE7ADDE000297A2672211F0DE8CF7F5FBC62 78FABA25D035FE3A7CC3A4743C0EFE1C4A5E9CADF1E05BC7982648D5C9FB2992 4A9EE1570BA2AB068CCE168552299361D62A2BC2C0DA48EE94D1CEDF1E2D29BB 43864AB5B770A14C98A432AB76C17998904F052A50EF845100533BA5CFB24C84 DA53581EC4F2201CA9FDAE76EF365515188ACE4CFC939AD6D193413CA7EE225B 0137F4637F09952213BE725CC7AEC579B2FE85F7C6AF18D70C4FDA0557567E64 D430F09ACA7BF28984977BA0F5849A5A86729D5640BBE4C30B17AB03262A02BD 8EE077EAD7FDAEFD37AF16007D83714ACA07FCF882ADC4792583AABB279579DF 6741F637CDF8598FB5827528771444B0AA82DD5E00E70EDEFA7405A1D8A7797B EF021A53BA68C7FF6780C94F1393D1745AB1FD7C728C6112766A3C2E21DFF002 9E45A5C5668F8B084F22CD6A6CFB056CF0F402A73B2C02118259352EFF6D680B 877CE3024C37D532C186F3D4A97603704CC0DDB25CAC00AEB4CF601F6FB45655 8939AB962CB9E16A2400938D226056535EBE5707CF0A8678B54E6E3A103B2EFF 0BB7306D7C7C3F523B2AEC267A5F1E3F99208D8EC9AB27D658C26F635C2984AB 5A4D214768C6DC775BCC616838159AA10D5BD93CFC8B2D836EAE5ED480FB6DDB 24253A62A1B798BFA51B068B6888B76D2233B6FB11794F166254CB3AC8CFB650 429866DBEB8D09E6D03889899A4E8BFC9A855EA4660F928D0AAE8247EEC1668C 8E798398D53E52A5684CAA59C47CB38C8F1009A8AA12A269A587593874C2DC78 0BA989078910F3D70211147751E9F7264D6E64F1B05410ED3427BB7D0704443E F2BAEB0FB9E3F1C1C14B178E716FEB4644240447A3F02211350E36E1A586A042 9AB336C6B44C0D2977294E704E8695B6DAF079BCA033B6BD3485EB7A78582FB9 373716136C63EADBAB3A2577738F553F81135829F9118F4BFE20CD51190BD7C5 17035EBE97F26B0B58973EA9B5E0D111D9EACF2FA54B223C4F40C139AB891A41 C7D5BA5338BFD58090EA727C3FD9D0C0217C05798787881D07CEFE019518CCDD A7AD72305F06A98717CDA80C5DAAAFC50E3C6D78D2B5D851BEEC46731A6C29ED DDCB9089DE5CC2DDB696D3B7DE3B67F066527AE22CC1AE6285DD1AD42E0809EE 65812268D28E7105859262E9368A3AA7FD0207D47DE5EA5591927F5E568386D3 A61FCBE872945A272C75384BE1E85B26AA094704715F1957DE37A2FDE2577BA3 85000D0708FC918D52360CDA828CEDD17CB7D625155CEB6931A29025B44EC8FC 3678FA08027B20FB9649D07F01484F2FD2E1746F290E32434FCD4D15ACF0708B EE3FE9948D3AE141749B47810558D71D592735C1C86EE375BE7413B2CF462660 0B115CD043EDE5612AB895CEE0909DA8D165408CD5C4C34114EE4D7FAB4C37B6 A31CB829C4BAB2DD04B1A7097DEC24C6429C13482667116522F94EDC99DE551C A693362BE4D277E12829BC466E13D09841B5D9AF504BE4EA59E9C2459EEA5AC2 C678E3FA30CDFC5AB855D56C1AD8374F9769A6B575A1DEE5AAAAB4F716DCEBE0 0FAB8B0B5522294CE3164F8446679FCC7AFF5BF49062CEA58F5C661A895AE753 8891536066F8416FF5E357FC34CC34D6B68ABE2FB2C540A7123BBF90D2671F65 90515B96CDD1BD2C1396BC15503CAA4CCD3CE28E0361801BDC5DA98887B2C39D B84A0A4DE7859C7DA394ACC497641ECE12AD8A7D62AC5F8E6BDA0577FE64D581 35390A37A1570CB25B23B747B236F3F2606A3FF6E487A78069A068E7AF13A8E9 31545D422493C3E2B5187E26E369F5367687A52D55B1636092FD7EFE7D9BDC28 7FA97D0495E28CC1A5F4C1B37022E32CC045B04A3609BF4B15DC990DAC03884E 79C0D930DE7C4FEC7D244AB3CA449709DA84D1B70D330D4DDD264FD3C7453EA2 92BBC6F33628CE825E163FEA3BE751DD3859C99C38A5817C8C965A593B9D9DBC 5013FB08C673603BC3946900C72DF7CF454503703E08CFF94634679185DD1260 C67D7A9BFC8533FDC27952B08A5ADA04C276873F17FF9859E31BCB657421E04C 0914C44CE56AF229D2CAFAA9F401092E1814D53EB57B30F6D4898DE502EDDDDD 7AE2A28CF1A20F7B73911F39D6E41D4A1AB7C9950EC394D6BE34C01E2317FA5E 3C8FEB7D74A3D879118BE4F2D2F5B4D6D5A90B188505175088F8092049D5A06F 34DE2335626096EA26D57B94A928ED441A2BA6C4DBF7F71098086A5C34185A18 4FF828345B5DB1DE6054E882EE083ACF0B95B9F10B0111760DB9F6FDE3F2558F D1C5ADA269CDC8F237A292E60D07D1234563C02B9DAB14A41206C3350B9DFC1D EC1CA5754797963443964081BCE8E27F4FB1DE885224E44592F9134C8FBA1B6D 5F1CCF350E3930ADAE5249B3D5CAE219455AC957F13666CE4476840B89B2CD1A 91779A441517AD085F2947375222A669366A3874E9FC795EE82FEC8FEA2C6578 BAC09D2D491F4E3943BE5175EF8EA25CAAD7062FF1E95AA22A46B36510A28D44 524AB42ADAF71BB59CB64D272D1446F6374E93A813E9DD63F1372235D19140F3 9524CBBACE849E45FF5A33624A369EEA12B5550286FC04510396B65715DD63A1 4FE70BBF7EEA5114584A91048A7CD6F761F782DC8D02D23C8646C6C70A5B9506 8488515563D8D3C67E79B6D697D9F368531C1987E0A89AD0A0863025DE74A928 A606F5F2F4C32717B3CEC4FFEACC4F2B9CEFC29A1772EDCA3717B631899C131E 3BB51FAFE6B8D988D7DA6EB45BD57560F7F6113F10BE471C4CAF1DCD6794E22E BE667559C0E796E048E2DA5CA27B0943DBB2E81A7F587D7C9FDE9177CE8345C4 EF37CB3E909E29891C4FE6038ED5FB513D587F7ACA029A191FCCF6028E7A161D C01499DBA8D89CDB076A9C726F2E8AD884FC8A25BF5DAC90EE56F9DEE0666C24 84BBCEC64AC7004C28C4F0A5E3A451E37F6A8C672B9351DA9385C5378AC3F83E CA814D9D7CBDFA938518614AB1EDAAE316C6058917A13F88D5E4CBC21733BDE3 617B9BE3D3050656C55146644AB458649731D74A38C087EA6D33D865F6347620 D46B7FA6DBFF5A0E469BF9B28EF4FE2257FEFC81E3E7CDAF3E482EA2C3A40206 43DCABD97B5790ADBDBB86F8261699FA0853CABF6D2DF686EEFC25592B676E85 BBD9F6A356201695536828DA89CD92C22E1CEA22C286B7F058E8F48EBFC36AAD 3511F899AD71F0C2F9FA448258460E39549B31B53AC47D80DFED0122B3E2267F 5BBF9A5A3E26A9B43D1720BA321E4E114178BD21561425B67461171F1C1789DE BD17C734D458EFD85F35C46908F2D9AD8564B5B3520F7279F8F171955769F08B 298CCD0466539B529914A1C7F47F1F0BA873C23E195EE882DF03BC9720643282 5068B6502C39559B7CB47B5640EFD1DD8DA1480BC889AC05E3F62F733ED797FF 672A3AC93BDD9A302944DBE536A3A86B890907F863A6BED3DAD3A595A40933C6 64ECFDC8C635D07F9451C8139B55BFEB38715B3D6303EBDA78543D12054FF9AD ABEFC06B7A97BCCF756EA9B3BF2DDC80B8A0A19757E28087E44C14F629B89DD2 B687BFB4CD24AC1941A8CB2A8A3F9247252BF0189059AEC7A0B738B4E3A363CE 18EBC435E522D1183612B014A7687524921D1F4D39C1DD6D89C85034BFB49CCE 64613E5274D98E4F2B23DC47BC6EE915FB4E14D191A136FAD0C22A1771AF31FA 95258B6F374ED8F1220A41190FC3ABC45CC68171A5B16911D17422A85D9C7B24 18523C6CF47235A3444D643B1ACD8BAA421EF8B5760B6A556DA5E2DE76C0237E 1A12DF66A27705A954A7B701993253F5E82CB62D4E3CEE3536F0E858895E78C6 951165CE06E367580D62A1A1EFA0D8BE0F0D8EDE5E0BEC408AD2F901C2B35627 21BE9AFC551315C78D3EEF38378129AC4FD719B3B15C9FE406C4A4206D6D03AB 95659175DE66FDB4A3EBB05563B31783E698185345ACDBDD4A363114BE1D5EA0 59D15006EFF78B1CA69BAFEE6263B8889C8B0AB91124316C357FB92E2003C2E9 2E685CF796EF84ECB10275A81CD3B4480B18CC83F6BF10CA544183F966070045 D2FAD558B937F7600D061DA9CE7A18913197603B6CCEC05220CD9233C9D085C6 E1DDF1A987496843F3C03A7AA614FAD29F65D719B623D9DE63E6754CB8D09528 6858D203DA05BB3886FFB4845FC753CA0601A3D82073F662121854D7E8EF83B4 7E8202AC4CC1B13DD795113FD87D6FA1E859CFB8EBB3037E6E3B2DEEEADADAB7 3CC953D25984834ED2390E6ACE54B7E7A9CF3D32E278603FDD8C754C643D6090 727543507A36A01100B17076AE6C6FF5F775FB0745FED2309EB885CF0BD48D1C 406D0D144E3CC4743F3EDD2FE3CD3ED8A1A2F2AFEE2D94018F78DACE5A54C070 8CA3989D205128155BEC0F2CBFB86BC2662D032BFA72463FF5D2DD6C72C2A11D 2562768C5BAC9EAB46ABFE397C62D41B823EFE2A427A41F1CA15DE92B7283144 E8396DF970ACE96ED7C49B83B536DC0B3C8A57085F16A93F44120D9B747303C1 AB5E335FA53C5341538CC03D6313DDD840753A95AB57A101D3634061E73D829B 4B03D3550D146C3A76223216CAC3FBFDB9786CC7B75FD713CC5303B8A2F42892 EBE9E2BB72A5C4EE00314F116B2C354852A9E3BD94EDE7A555C24C82624F710A E128438AFFB7A22B0D6AAC69A6EBCB15182FFE301E55B8C3BD9BBFF62DD950DC 55AA23B5CA2CAC35CEE74F5AB75D08165D4BB438DCDDA7F991258E14B5D0B5AB F98396DB82E59E6885D05EB257541FE8AD824A00C7711C26D358D6E64ECD0C19 71CF867004127012056867D0DFBE68948CC14D32F401113355385B2A29AE468C 2E2D14BB752252922B37655D955F71924CD5264583F9272FE201DA19A1AC2D14 80D20A709F4266EBF5615F154456F632E8429D5EC316C0CC33F1C1DAE7E85FE6 90251DC599A66FC393F03F7C6ABE3BC4C57E60B27900F2909D5BC4AED1B2AE87 9E7BED0FC2A0C703A8479904F0256C5A0B12BEF34533C9C6EBB93515FF99555E 34634B52F0B8B83EEF5CCA51B26401C43B8C441C04A64A0C41F8C9F34807DEDD F20BB1BC34EED5F730416FC7940668F722EFB7E8ECCE37D4138084B1ED188F7F DBE2A9AD81F7002A27F2EDE3459E49C274545F7FF148B2CDA2B90CB5884440F4 64CD57295728ACE174504BD81147F35D8989D2CA44BEDE6B8BA09F51138F64F7 FA2E48176AB5869BC64A0C6E9B0626C45A3FA816B86CD971653D9A62EF76D442 DDC338105F8B0501EB9171AAB950C284946E38EEE2F8D0D22BAAF56C7B8A44EB E6F1260FCC0DF081BA2329D53AF72B82632D05BB7CFC9396C5AA0E7C93BBB3F0 49FE4E20CB2F4E94AA53F87C803232015E8F0E38EA6E666E1555A111A6FB06D7 6857C7516D99DD1DB1F988A9890A693F7226259345EDF5AD4A686AD6A4BC7219 C5D2F9D95F7484B2B05F4604C4F128D2E7FFCCD26311D01399C843F2D473F939 B346D432765EBEFB539731C1B71AE80D9AB3DC92B1427A0C42AC7D8687A5CD30 E0DF721181F303A1528D8457125F18513483301CC48255F0C687891B280476F1 E7D276B9DDA3E75D7826986153CA8992DE3E327A0432B0B598C607DDA056EE99 DA65742ED08E46570EF1BDE0C7F2DA4318DB4204678BDD9B133591C1A586E5EB 5D7DAEC7FF59AFF0F77A9C9867975E893E12F61E6332DFAE2401DAAC51F54494 6051593ECEE9A1D757F840391D7F930468D9A2B92B1D1E9387041E5744C401D6 DC2345969A3926429F8B48969AC9CCE9E786D74B01A8FEC47161340EF4A0FCB9 852E1581AB1A676ABE803A866B99F1A539EBE5990504C9C0FCA28C31199EE482 EA78B6FD6C2462FC98217BF3B2B5CC52DB5F738D249185FD2A90545B8A2B4821 8289E5FEDC850C6D7EFD955F85BF7BFBC3591D48331B1078CDB36CFA524DFEAA 0A1A4E137774FA958C0E54413041A0FA4308F9F5BE43045D35C7224EAA14763C D15B285DF1D0BE40A1FED1AB37E00908EA7B0F9CB40BD8CA8E494C1D25FD0794 F73D6E3165EB3BE7A22843B9D9098CB63673EDF7798A4397FCE1C980B31D690C 0D4DA19AFB88D7A9C9A44B3294EB61A6667801BB46D6F315033E854CDD7188DC 2E043953E3B9A441DA122921AE686FDB1F427F7374DE7DC83F2BB7409E6CDE8E 7A3F122382B52ED6BC8BEFEEAD4FDFFC6D8E5F844D4988A574FB1247168F11B6 D1B9E1AD402097F7D142D0E8D87A50C10EF2EF55D57B5DC09C95C924C3BE9FEF 2E9F0A13BC4BA7A7367F8CE68790E7F42E7C6A97CA0C6BFD57170F1DA7EFA855 1A619213DBE5C89E3BC998AB1919E383D0BD91FAD8ED6F8C20942F04FE2868EF 79AD89B46D89B2575BB11BFBE1F9A8B9F2D3A9B1B3FEA6E6011AAEBB9FD2731E 3F56185401611D91AB109B6E274CE868C18E0A6FCD66E4C237422CCDDC33A8E4 8CE30B10F62B9ED0B8D5BC39093135BC7321DEC56AF7FB023A57F95DBE48FE4D A1BBAE742E19BCFFA9B024C740B0AEA7FB1AD48320AB299EAB77CC0EEBE951D6 2498E48D1DB0BFFA436CB8AB9824E30CB544AA4A74BE19F45CD4E6B99A7193E6 DDD89FB0F148F80078848CD9B621E632B55C193D4073AA4A21E208C2DDEFDF28 5CE5A854FF1B30BF5FCF65113E71D62AFEC3B3C15707128A882F2A6541C485E9 02DA0FE520B0EEF7FA87C2E64DB7A1A5A04B4F1DAE8A0395720F79F78572924A 9A20B4E038793245BF5C020B34EF73391045EEEFD13E2B7481F9D2B47165F977 8453A73601AFF237460D5AE67F202673C7F7B5CB20F31FF064EC98D9B5DDA5F8 9E19FD41E0765273C670187CF53A3B9BC6DCABBA7ED531340F2E127EE9BC7060 EF0AC15FAD60D0F0903E76F0FA3A2CCFA0D4FA04734A9E46C0D94B3911FFA435 B4560DB12A7687AF5CB12AA0F5E525C03402B8AF7F49C00D5E266D3F77726803 2593DF513D3154E07738A2E39D6AC9429F1A35956A6EC043DE844726A222F8E7 690F4294AFE8B5E7C491A63AE05F8351434248BB8425A5F9FA49189D45C42483 A908EB70F7261093F8A8E52BAA1E6DDBDBBB387CAE57A83466FB2E3AB8CE7FEC FE016537A52FD1A6086DFCD6F48652EA30A8EE16315D4FDF3D2B521CEDA9446F DBF1F295C2F356C40059012FA7ED8D85A93D8FE2BCAFD3BF56833137AF71C8ED 83A3155EAEC79A80F7422FC91F2164869B0727C61E323845F40614432A094B89 B84093FA2BFAF2ADE928C2269F25522F64B5411A7F36883543900232407BD79E C81E47869D5EB2834BA4FC0F115A4CD57C1F4E93E0147DBF07D22113C994B143 8B4AEB72DDB6564384FA1776F70B7E76F46407F6CDE219270F71F6DF88161D9B 57843CA29B55BB99CD69BB85938FBFD0E5B52F62B5890CD274B8BF4806C61442 FBA5BE26B9432B51619B100165270917FA6BA9854A9E363392350E5E9275BCB4 FB7C6FB85EC4CF5CA8ADA5F53CA25E6761D21B6B1752AA0E60ADAFDFFAE0E18B 9E251F5A4E3AD99E47E7DF799B5CE973BB06E726DBE5B8E4603E92D8C8BB02ED AE1251B3D77F0A8CF6038EB3DB7CADB39D650E1A5D2EC97518BF399473C94E07 A6DA979DC4E9C0312948BE29670AEB148E00C234C1EAE8E76815C389EB932443 AB7C855B75672B3C002AF1FC4744F39EBEDD54B9C5338955F942BE12124FDFD4 CBF87B1DFE2FD21D3541474DDA5086AD75C35E37CC601441D7FFDD6055C3ED9E 8BBF8FCCFE8CC04E0FDC543BD6B80476F65EA74CB0A90A62A05E0E6853A89537 F386F0A40166D91855CC803FAAB932CABE462536722E95FDB7E0463774DEDFC3 928949F19EEE06C1A0E5BE179E3D0656CB095BBA1D59795A5328CFA898FA25B4 D9BC59A92097C3EE64D775198719E3D7E8C725C04969A9EF331F17672F33F9A3 07656223A0A4E5E873DD5728751331DCFDA8347B4F9354DC900685CE73A8D573 8C2BC3A5CAAD6968E408B6BD71BFC42CC17B0608329D093E1F999048132D4349 37BA7ECE3B966FA4A35BEE2036FF9C5C423A2A5EA38D6F4AC60B650D0B4FEC36 4686C0A45403E4FA92F32A6B84E1B9EB4F4EB012393144D56BE2887CDFA36E50 D7011BCAD9B86B0B4FD92780A594BFE28454A9229329140D3C0046E353921778 D1E0AE96098CD10758E6FB302F2B31A7A2ADE6103D585819847CAD908F2FC9BA BDFF325B4A936312A0AC1CC0080083DA442932290DA18821F6A14D3339300481 DC187FB4E20EC3AB0A7D42FA2128E9DDDF04A4D7B4A327229051C328AE70075A 661305642A9EF7CC791121376D925BA8242807E29EBD6CB8017A27E311AE62FE 08BEE58F2B33AD698D3602A2428BBA8209D50F647728F58AFB5CE3F8E8392658 FBA2D9E6EA42F2E2E88E8C66D0C76B2A404F1C741A8428158134359B08B66C67 CAFF0AF3E4D393CB671090021849943A7F116E7BC9E4FB52044CEE316E2F0AE4 FEC87980C0B833315629060D58E961B9CB7015A19984E73E5A5A2297F5A45464 5FAF868438E075EBD8AE3E57B549EB35CFDA487CBF314702BD0D2112BB8C77B7 45B9E2E787A1852D14EAB6A99218B305183D06AA5E31AE64912A574225E83D3E 036A9A97569A9327941AEE6DAA904261F7DF59C129B3047F91779B01CACC2CF7 BA76E395D789B19FD747171BEA07FF70EADB5D360EA1DDDDEDEFBD9514CB6ECD 2211F6015DF85696AF202D90C75978876E765CE28EE4ABC81450E67A09733989 706BD4EA192A07777034407BC29192867A13263D2059F46A636EEEE6A62B6E12 14CE593C8E6A44DA2FC8A7CBFE350C693B23476C3C77F0D21406751D2DEF6F8E B012C6B55B92D9319A8760C424CD24EA32725A9ABE2BFE9E0D06A6FB148FBAB4 26656DBA85A2222275102ECAE44976EAD9D467CB7C70A7AD2352F264CF652F1E 602E7F24A14BDBD2877CCB53A1D320106682B8DD218855700518450AA9CB5331 2F1FAE92E92DEA1C9B6DD336B29C697C5D32A76F0918DBE49AC86D6B6799A996 999F2B786D626B4B7BD2D7BC9789F7AB6217C9CB40AD1A30249D5301FAF2F3A8 597174BD29EF0CD6495A7D1F18FC4E184AB0138C55F58EE66B6BE0B0C8501016 BB9F449C054E91CCAE698A3A58967D9C2E30019D6E645EA2B73CCF0BC0BF2E27 A0174B3CA0AD086F73B47C98A95D9C33AC9AB81AF734CB3B07194F4ABF08C343 D3AA6D7065140BF2998E6C3186826954FBC79F69B43CCF1D69F55D56BE380C35 8B794C2EE616B79E4DCAE2CA0251C4D90C0B02A21A769FEEFF38D4AB3FCF34FB 7780C8329287A5EABF0254FBF5D937B5A2F8BFA1B3A40EB1AE1279F582DC7704 8F499D8814CA2627286B95EEDAE717BCEA8EE88E5FE0464CBD7942D4A91D455E 1AAE17E74B0BAED9B47F196B0889286B0B37D434B3EC85C1A110A1897E68F06C 436B3DF24E7DC6ADB5F3411CA18B539091FD9791329631499FB05BB37003DAD2 45F8A3D527418B5A668DF06463201B00F833E5A1C0AE6F51A33757FD8DCEA248 8E7B130462CAC1C61E80D58958FCFD2269F2EA795142AC26E61CF7CA45E5974C E559A6AFF6FA89AB01DA0ACF1D4CC2A0E4DACA3ECD9815C50CEB69FD770003ED EFB73E10CC1A73572D74733869DFB1555B9F2089D69B7864EF02CCEA810BDD12 127EC4F6CC4ADDC26249951526794EA0C17AB0F88AE7BA63CA5517D3BD4CCF79 C32DCEE9F2AF40D860BE61FF3FCA6807D768CFFAB4CB966B5DD8436D1ABDC3EB F2B1B4C4A28780968331DEEC1A418382059D0ED70285DAB96A74355655EB6434 2E5FB6E18F2149FCF4C0F743ABC4EB5F06D14E4FB96F0F69193E868789380DC1 27C1A6C8A36E4FDBB4862DB295672CBEF8C0780AD1CED135244B236C5F077DE5 916A5E4571236CB05E25C0B681EE2907AF1C83C0BBD182EC25281FB52C452BDF 2419D6F7A4AD6708C78EF0F3BC496247F83C055002B4160B2C8A31D38E444303 83881E5ED0F7F184DBAA9A394D0E08138DA1B8361D551D1B385BD6E116AB4C51 D88BB4064EAEF6B60D91684979154D98437D6BBE4C8EEC74B6D9BB7D6DA791DD F81C9B6EB5D7DA81F912531205130061A6581B72B7B38A058C8B8EFBA9F66BBE BB32B92091028ADAC2F103DA8721D0716B233AB17836EDF8E2B06D381CD56DB5 013126B6F2C95FDAD066287C6DBA03B23D85CC8B8CC02BC5D4A7B452BFEAEE85 78E1B24A12E828965522842E83A736479DF26E8DAF06C3229A266915E85CD024 EEBC34E4AF881D40380AA322881D628793068097FF7918EF9C97060E1A78A4C0 95936997063AF99A17B81DF114E77AEBBD4174326BF9CE6D062A4CDE7A058FCF C69FCBED5D56F46FE13161E9F0BCBB26D61E5570EA404FC0CB9994F951EFAB6D 6AAF64865F5B411E61EB5680251900FA3721DDF0A5F8E4853FC2C07FFA2409A2 79E8E3D4698F03AD520C93E1495BD9B0D1476ABCBAF23CA6C60EB76792D3067D C940EC3934DD4FFDB90B422F61EDDEC224218C766D999D75509949EF9F182CEE 0192AE771CA82ABC301A10BE66BF8A1020BCAA2233F42E390E8B207D37C57CCC D4494FB929355641434FB5845674F5EE864E18D8C3165F273B4217FD5E67B1B0 A670F053F63C7BD08A48CE57F0D5853287471D25746171757A4465A7A87A8A7C E91653C37C2C7FA5ED7E5E6E4DDBD6CB2DA1570650F8C2503D0B732F37E1D4BE 58B11D408CDF2165BD766B92B23CBCB9C7A893CBA28848503871DF33D65C2EA5 BA4E00EC58A7946B7E251A1EB69BB5A9902B13F1D16018B2339223DC051A7A71 638F9565B0DFF72107468CD4BC5B6740E9FE623005DB72BB08EC68B26D5C5600 282DC87E6BE23606EC14A5F44DCCAC698D7C68E89469C90A458A03F41FB67CCF 92C11CA37AB6357A7938A51356FD11A5918075715B97A46353D653D98DA82E9B 2F35BCC57789DB0DED82B5B1E8F58886DF28223F643D6B491AEB164EF8816A0B 88701839BE1634653356714F4FD2842C22B7AFA7A84E36142C16BB5A5591CD26 80544ACFB987EC2C7C55CBA68B3191269EDA983AAC75985A90C0CC0595A231DE 817A9F229E202119E20DC45D416AEDE1D31D6BCEFB6CC8A1385BEBD60D212645 D17D9BF91ECEC26A5469D21898B44614972FF0D0B8DD60C1B2450D42BD399C43 522F8AA2BFDB492629177EB5E4AF0F834CA4C427413D4B0B7F1B88C66C110C6F 647C91161BE89D142CDE811FF109554D7EC482612A4F812E25E1D300B9C8C6C8 1BBA9D4AA1D902CABCF5EFD93A37C5A935454D811A69CB93410007BDD4E77624 D70FA3350B0318D193FC3990DBE8F8F2E27BF810C4562123930F478FE36598A3 5A1EBC7F43DCAE5A253420DB511A21651E03B5EE5CD90927CCCD1B62B4AAE85A 276605C353CD900CBC209C92F9B480B4B44AB9D5A978FF5F8973243B68F1BD0D 2F0F62D13E6741C8116C69A75347126CAC6CE1038BC805524335C6B287FB92A8 62582D36427CF420B689C75EC26C7D368DD5962A0BDBF9B3B404C12027592016 A3F8BBD9EEB8A621A16C3A3153338420449974F419227C37BF6E0DFF0BE70F7E 27EFEF37A58E2FA1EAD1838F9D7E350B1DA500B335F35F060FF9C9B545290A31 000FE8D9D54D92285DC1BC7652B9E765471E4E4005F58534718F1A09FD185176 A3AB653891CFB181AE2016873F0F6D0E1DCC8F517B8409A6DC3097B56ACF4615 CEC1F9308177572F6CAACD3F65DE42DEB0A85F66AF2CA7AC478B69EF6980DF93 0B400A28DD330F7D61FF9DDCFE2E70AFB4395CB6DD915E32AE3F6829AF97509E DDBE790327BAA97350B942E20F88CB3E6220D4EDBF4044F0E2DBA6F63761F7BE 67A36434D7FFFDD36CC3898AB4F2258A67B5097FA04AD57775C2AAE4262E2EF0 4D9838130CA3C86B72D45387AF7EEB1D3A3164888A6BC281A2656C9055C816CA A8E7115337C7F6ECAE1DAA0E457F5F0DD27BC378A218D947D2C16F0DA2A3725F 3037678D34BD14B307765DB7094636823E70DEEDE5A3DA85CD33507A95BBD29D D604B21EA064C9F77320AC96E4A9FC9747BB00CA6FE9E19821F9C8156624D7F3 653AB5623746216BBAFBBB3BF45BE850B16E83658C68D87B0FB2124797E1AB46 BAC457D798333FCA569E4E4E84AF7F866C9C0AFF5C3664C3C103D5D02A626FF4 E3F87C69214218F1C9EE33CC64C39D0312C1ACDCEF4C802E8698585008F1537C F4B6B321A6221E8E6E3CBFD5AA97D08A9D65F0FE762DA9F7367D9DFCE948E241 49E9AFD655D97D73438C9BAAEA4D7E1ACBA247FD7C9371181EEEF74A6461060C 41450AB0DE1DD8ED2DE8CA9C2AE0AD5AA5AF928375ECB1DB9567759340F6B9EE CECFBBC7547E7C76B0467B3D8B7EBBF77EFB6945BE73FA94FD808B0DDC3D31BC A52780BDA66B52594D58B71326FDC71AE893A85135487BCC99391AB1B23C6319 AB6FE2B6725D8EEF3D38C9D66B12475B14C81D2BAE96F24B5A34D384C20E201F 176560F60E50208603DC77B8E7430E22065F922D07C897256D7B923C4DC2097C CF7B2F50F410D302A8A6078A7BD3C00DC75045E3A36F3653593BE4774F66DF77 395FD38A48D432C10F1074A8D72947CD67E69FAFCDB16324844F238131F7C82D 233AE741CA223477B6A0D15167CCD25E17683D7E4F94AABD92F006F5BF2119BB 9057BF51F0EAC164CB2923233CD162DF0421FDF38D04F3ACF4484D2F6D17CF59 72B9BAF0B6A752E8C662962CFD44B7C0EA0C98434FAE3938C26DBEF33C83056A 19B30AFF96B7DD0108452551A3E55DA27A14DFD45DDEE2417D5146B5399C0856 9A6BBFB6D23B52E47D1EDF8A023546EE0C61221CE247B1CDDEE2AA3A8D9734A0 DAA2242944CC3B9EA5FD4B7D8BCA05055825E287261C8FD45E67BF88FB94B843 4BB39B14437BB53295072FD05D15BFB1E0021A786D03AAE9D09F21E083CA981C 8E22567E169DB4F04A7D07815FFEE9242E21D56F70F8C31F37831957ED7B46AB B1E059247E276EBEE1D419D1A88BB924BF4533659AB496486332EFD6573F7E37 C959C2E4330744305F7F86CCC93FBF5E0CD7BB8EDF43352BC4BE4F7BBCB666E0 B438C6E978F68EEF6D4A9F2CBEE6F1C64D290E0222CEF81DB7627880556205F1 439CFD8638D3808A5DF443190639A4199A70C1B2EA8667939950FBBC930CCC70 3E3131A2BCE37248F25A4B67682D2D16058B962538A2C1330263197551C559E2 B0342D0FFDBA68110040CB03351370F6BF85B6590A6872B83536B5A97F7874D0 EE68DC28EC3E0221E6D5DF1824F19DFE09EC3CD51F3D18D4D3BA0E89CDCE93AD B4E2FEB60EB7085F4882D46CBD166BA59B65BDB2D338D19105B18E7E73746B48 45C1AD627AFF0BD2D56ADFD88C31905EC4940FE501ED014C3D3FB3CF998B8479 6A514C971367CB6B052529DF42EDCFB95884E21DE2B4546C9E16620B7FD26EEF 9138751A86E52665A00C64C94594F6D3C8B3A248863DCA5CC78D94923CDC283D 5639DE4DEE644F56421DA4FF8E7F0ABC3FAE43019750F3E9F64FB2580E4FC3CA C17E30F85AF558430521661410A6ACD874407828F717EE2E59FD9EFFFCD342B0 81F88174847CA7DA498F7BE4B7EB95ED8957081F0EF2F1B5A82FA28527DD9487 CCA8249259C887EE2B8A824FB091828E6791D2D603A9F2D16D25673432E90915 6AEC50BE55668FBB94D9691C0D4C3EBCB2CAFF3EEE454AB8C1B05AFB147A4894 07AB3A9A3A500999A201473437DA53DFE872A6FFDD17614F2280C3C4E33C6A7E A7009FCE59C024655B47795ADE2AAC65B70D25450F997F7EA01971594DD62104 B3DB27C71DBE78F9861A6BF6EFC71981858797CC6A31AB7483910F2B59725589 D608699EEC8EC4E167D8FBB38D3533522871198AB3E9F8DA954ADD332A17416D 6AAAD61EDC164FFA115162E05D9207086CE3AD3BB9DDE91AD6E94E9D0D2F96D8 317192BB4F82C592A2DD3021D005A6691C4D7D2E3D11B923A88039517CEC35FF 684EBE30B21493D66B4DCC82B7EDDF9F72B6421639CBA8561479A43131AE6AE6 F6BB41AAE2D65EFDD1F5AC31031F580BAE438B143C6CBFE9406CA26D3A8B3AB7 439878AFC0CCB6B190214D010ED6DB447C883A31DC9BC1DA9BA00A94CCAB125F 92F9DC471ED6488AA68540FB047B6E1B02651B828C9755C70FEE630BEFFC5EE6 DDAA82F3F75F77108CFCD5F3CAB1896B59E7DB9460C022A023B2BBD4130FD0C9 CED9FF84D0A71965857BA533D49EB42317933628432F2CFB487EC92275913D7F 8FC947D57593483B21710D728512D00310E0A392B395D170F14A8C0CD1E5DEA1 4258DE7E613EDEF7D7B4BADCBB2DCD369FC6F5CE2582317C94E94799712DC402 DA1D499BC01BD78A977DB6A0095FE1A51842528D8C573C139D58D964A5A0E28D 6576AE3503EDB82A007543B091EA23CA84F8EFCD0973F613F80D3693D1E8B5F7 9B00A266954FC5F76D50C9CC7448FE2B292CAA6319E1566255BEDFC4D2FF29D2 A0475FB00FF06B50B9781A676C81EFE5FCAECDAB52B8460B1E3D25C43E7F0DD1 0669D77D82F2CD07C40EDA7BD84557E0A3EB1592F46F64ADFC6F1773BAEB6FC8 CDBB7D7C8F2D358E610FDFF3140BA79DB34B20E379202B7EE5F3BC91F69C38CC 6282F9ED7C7DB26D390857ECF21BF7A1A29FB2F6B999A361FB3616F2F197729C 688B8453A0B01A782D42EA303BAAA6E5A841AA1A0EFB8A33710048FDF1ABDE38 9518DA8F7D0024024AC35D23FBC584BCDEF9C3D6698417C05E87913C837E3E01 C43576D89D6A7BE234AA66A702BB023A052E127814AB4660172544480B02699E DB67B6DD994E4B6B52587AFB49B8A76A878C57D5ABD2068D4728655E2C91477E FB3E7C1C9FFC68EE584E9A53FA992CEFF815F232CC5741DAEC76E31A2FA65C3A 96559DF29BFD2B0FC2D771B23B0A9CF1F1FB1772970D25FE10CDD5B7E17D8813 C9AC3D51AC9B60E02CBC281516BD1A6C359F46F626F5A987F9A5CACB084DB140 04E6CA2D160F04ABBEA54D06EC532E7F720B769269C28EB6B5957BA772E98F16 F86888E54B16758317058E58B13F1FF460CA547171F85A3F1BA6DA904310996C CBFB05C105047FC51D5C30467535DDC8749FC04A41DF60004E2FC1993774A885 24AD63819DF4678587F465AF6AA9EF491138863ADF0A5500B39ED41D6FAA896B 22BE5036F54CEC5D4D3C5BB98A8C49828B9F13195EE05F27D916EC7053312049 E6347B07B95881385AEC4760BC6BC08C8DDDB5411DD651E65AA4AC1A7D3F27DF C590E382B9911FA3933E05D0CC6A9FEDDD1C343CDEEF7F7DACA8B37CD849F2D8 D0CA5DCC4500FBC2C433E7934E7962111A1C85FEDC3F1195107E45D10CB4A183 9B341470803CA14E8A43FE3F4C8E251E97235E60A1EC275866B0C3EB92122009 90F1A9AE5DDFA72E635B12E75F92BF66FD5D81A0F5C89915536CC5A7FF65FD47 483F295C23458F6C1893A1463C96AFE9E2E5A08FCC010AA354B3E1916D627125 62998C5102172B6CE52DFCF82F1A682D7275D16C2A8C412FE9140315026E804E BEE7EA451AE1B5575F5FB13461FB6A1E13932B1884A9C8B0132ABEB08AD21342 026CB55E23CE38288C127BBEA082415C094722525320E6D37773131C4EF26436 A9CF56DD29835AFBCFD91900B198F2919E44372A9A6737F7B0B1C074DDA55C75 B9B5B8FE9E53DAE9FF2C07EDF4B554F2A31FFA941605450095DA5A9D5689513E 73E1039FBD34C53DCED47F3031C87865C27881A8A8A7141F540AC25002AE37D7 17573676CDCD5A3CE2301D2E2CBF4D6936872AFF9AB0DA5DAD7A0C995EA07EE0 03E998E9C4F41AC7E214FC46936F94DCD6576A3A84259024C643B7EEBCB721B1 BED8D1F704BB2EA1F8698D4DEB81CE55B28A70FC8D39128C9869EC874031EEA5 0AFEA445B6A537DC3714D5E4F04B24DAA2BFD9808FCA48E32D8BD584CDFCB735 FA9DC70096305E6156CE42C7539751088DB8C3E68BB1122DA8AB8A086ACA9EA9 165DE956102AA3E9099334CBAA3AF35A501C87FD95CE26DF73374D2F00DB65F5 18B746B547FCBD5C5B9C8B5E6FD09A303AD1A1CD43497A27AA898FFCFF69F1D8 9EC1FB4AA5AF31A1F8F1D58C1DF36FC872A79F2B1C52DDE48F2A66AC9D537F25 766B752225DFF00A033FD27355E32A2FBBF8557D7225EA583B573945AF90E618 7287C6EF21CE6C35736DCB2864353554F2AB7E6DD8575B8688508A7019E1D3FD C1B3E33BFE4E6845EB7BAD06FA2F971B3002B97A55EDDC87FA567F99FAE80359 721D181293DFC270BBAF109E6370BA8878F0072D82CFC7B2DD773C5189DA5BAF 0EC890729CC85A6120B480C33B5BFFF1AD4D7988764781797E2EA4953378A57C CC639FBB5C997691CDD528403AAE3DA6CB3FECCEA316CDE8A62D9A8C154C6345 EAC54CD1F6EC8571E06DDEEBC0392BF798BA5F544403EC5566D6D4B2D1DB6AE7 ABFB685363B4E2D4A281A343D88A67D5C2EA1714DFF057224FA9DD6C60943E4E D1A9F32565D9F9956A764869D2B99DF0BE84DF28DCC035B90FB9D2C36073EBB1 B61B0786B6891F04BBC4F53C482F8932FE6A0833EE5AAE76537B81B0878368C9 4E457B1FE43BAD01F598359A597275E9B10711877E0B48FD26EC0B404C236681 50031F9D99B2091DADB8C7EE6C97079A100DF8171E457BC64202F259DC92E5A3 7001D1E7B62CBDF83565AC5831BFDD04D5684CA24C02D7FC4310ECF70C24F581 1B5362287CEE729CFA56E40A4017A331A1E0E9F5ADDE4F82264535CEED5E2DE8 2EEE4E29A61F1397AEE4883CA48632EEBD45D81E2FF5C59C3FC5A32847BE681F 258E92F312A2BB963C6E2C3B00DFBD5A6C6F2D700A16F572F41C09EADEE51086 BB296A080C901E646172B5CE26A26252DD876FA77B668E2D034C4A0B0870F624 66176A593D2AEC461F658A35EF2C0E17A13802518F1BBB954495BCAD9890F538 4878AF35CBC458528602CC748C8EED0F1062A164BEE1F920B5934DEE4C450A03 F825DB2B6E7F034CFBEE802093FAB448A108F376CB6C704776D450FF024BC5B0 6C275977E187FC39790988002EBC5E8161FD7BBE287D906CB9EEF5563DE0FBFC 7D62798DFA5AF75249A17F20977874911C6055F85A9940DB27C61C6A07FB4BFF E970F4EFC3B806AA5BA9991A89439A3A6A735F681D6971678EA3492A16E34154 6BE00C8D67A3739EE3A6B66358FC5FABB7C60E1A2F1154890949676CC8A3C4AD 53FEA22B7313F826308CCC1B2F2DC4A244A0103B54C05DDE42DBFF7DA1EAE5DF 3FC39D238213E02B2CD7F9819F9A3CCA4A7AD831B87CBCC95F08B6704A6879EF 544CFB0C891D95B8DFF24FEA1C2196A14A4D6F64D65CB508443BF5410BC411CC BD792B48992AAD51F6F915D50020658D6B75079F96E0EA272C4376D2FED35B0C BBF273C831B3B4C7FE6D7C3DF77AE0C307919C9FFDD31EDCBB351A7EB351D8DE A966BAA68932D7A068E72FDE5649E33D933F7B3579E71EC68CCD226C76811D32 D0EF31F51EFE549B0A4C57FB827DA07ED30A4CA13789786F9D4CD12290620D03 E68BF0EC1D91CDEC54EB71F8C1E3A31A6A4063945006E773EDFA0CCB61BD3561 0617C6A5C1EAF9B88D798413A46023F07BF7CA9B73A971E710AA3A940F0578BA 2463628532A7B9EC6176C94DB065E02FF958C118DE70CE6E05DC4492DE228DA2 0EFE5035165514E34E0E9F00A0C4CB6175C956AB27E1F533B55D9DA1A0B9AF36 9144E6E9B32967264DD0EFAB4F9260F1CED573672BF6315D02E7F2F27F8C0C48 8A19E738A0F933C18871CD0B771181E38D78E6564423DE2D0D5A7C03DA5DAF76 541FDE86D4C166CBC84EDDA6182E00A1E899D19268E8FB064B4A031FA47685B8 B82341B0A5048BB1E417289C2DBDA973D67328C5C6FB8F552D0F44230543D4BB F84EE9459B2B7302476102F23CC6DEC091C2DCA9D0A0AB8CDEA3B2A11DF0545A 0B533459ECC327179EDAF9A67885F5D9AE605BA90359B132A582BE39FD5B8E0B 6C2CBA64F23B3FCFE523C809B59913F2C99484F8958372365C7BB3042581B9E7 05AF521B768673433675573EFA486AD669613C17C5027CB9B6BA963BB47E2090 F25B4A287AF68EB3017A9388A06A4AE3FFA0B7A474B2D29C25F35C4DF2983C9D 8B9A5DDF5439EC6E5AF6E901392BE09C8FEEAE8CD751BCE48DF6A8D751ADFB88 7B14FD5448477000C071DF88D6A889D87C8C0B8DE5DD865CEF0A35FE201E91BE CB23B9E33BC9CF4FE100FCA2A93063DCE2E9B328B583C840EF71C69326BD0B75 441DD6211F6C0CE0C2552BE6B1CFAE622E6168E03A412B4BE1011278160D8602 BABF834602F2B54A9FA44CC7F64092DF15AC345BBAAFD420535705B8C70F13D8 BBB6CEA60B8145F245AF2D8019CF77A59209F15DE0F43AE893526C43479C8A16 C39FCB4F10FCE3E33E5B591416D930A97B3F8726D015100E14A3C0EA38846DBA 62D207EA1DD758E6416C6460E7BFA3C9F4AC59BE3127871D2C999F39ABAFC7E9 7B3F0A8D74EC0CC9D3D768CCAA715C2BCDEF9B7C6E91313E27AC558A46E4342E 86EA61EA476B261D5061E3802641AD368E7B66A855178C366D7BFC33BCE1EA17 651335E7AFE3BD67DECAE6ECA1C05B22ED4AF1FAEE32D5FDF61A084D5438F978 CC0EB4F102DDA45D4C7960A5F5A12524C3ECC29107558B64ED4D47674B0A9B8B 9F5CB0695947E106B0CA8BFD8584604BA98AF2B1CFD04E1F92DCBAFCB4B53E20 ACAE64EABDD15CA5AD321B7D928FFF4D1F05CB148EEE644C226D6E801BB4201F F79E94C1858AA43645420E475B02A26279013F0E378DCD70EFC9CC7A0BB9C972 719C4709B769F9406FAFF92BB4739E99ED468B0AD45A65AFB3F8A764539FD30F 0DA1F33FC3A9214CE99B928DB794EE6A627A43DD9446942054887EB177D6B869 8E5B9539614ED49F011CBA227F31BBCCDD7B15C1E99BDC77F4254C1CB531B602 E2FA5BE50180E4B9BADAECFCDFF1B32E2E84E214554DC120AC79F009195488D9 C9BC32E157C0C73C2ED577343D2E5C413476B7F0247EB401347CC1AF55F9C2AF 91563AAD2D80DB1BD64CD7E096F3198AB179C840F11A2F1AA0EF579571558AD2 ECFA1FFCE58D7978524643DE9DA4F7A6299348B276419B2542E16CB9A5044A7F 99EAC6D301C6FB27BEF48BB66FC9E406A19DA1F36A4C311A12DEA25281CE4DDC 512499EE61D186D3189658510F69DFF2D15BD1E892022797B82C29683114A465 D9AF62A6F43DA5FD5F0715BAF060B969D4438A9872AD7946A8449188F25E0D00 A13494E068A210BB8DFD90E758AF025D59646452B3171CEF5023DDE28495356C 415F795992CA224D8D9107617C869A4D424E8482B5601AC1C904CDA967479ED0 7C82504696F1A8063EFEE5FEC83A384765F7FF0D6EC0F751DD746635A76C27F3 F1854138EE36577045665D477A491032D22D4AEF3D363B359585D92CD256BCB3 76576D26DE54D741739E7A6FF1519E28839CC43CE9442E93CDF40D218927356E 98A4D6EB0964740B335C1E79784A80175E3E9B4B081EB02B513BEB6669D2617E 549AAF03203BAAA04C85C0F9898210C84BA623A7FAAFF822DA75D4EFF2ECDABC DE402403616C2D10F01BA92485D68896380C59F19EDFDF92C1163A153DC13C33 A40E960612912F0890FEF124D6BE9AB1C342E44CF3FF242060563867C87263F3 07456B91B4094B110900010673CD6F9C04ECCB29DC19EAD0FE62407F4DB5105A B65C49E0A89917A567CD08B3248326048D873836D949AADF9927FF25E47F68F9 DA8128DA155E5D0D3A89B7A5255FF8509D5FB3AB3FFB90D3255EB4DAF30DD97C 51CBDA8DEF32F89E4F66F3EF95CC18F0FA13EF4C487853AC8A73B09A1BB67BC6 86479A69AB0F382321D33B9EA9B6A2B20DFCAC745D3C46676BA0F3CE51FD7474 62B91D5E825C843DDAD0580DD9DAEBA529606AB2BCD7AB93A8C47FD39581AF75 3AE7B7CC55E1093BB91D63034448A95C3B3A9875CEAC3074B029147208B8C53D C7038C7B6A161B235ED887396AC18491998A8FD2D71EFF31921B7FF28D6EACAD 895CAB71F098219D6C5C158511E95247B747FE04216C3FAE7D53305087096528 B77561ADA5AD91969B4CBF910DACE3FF09C00096C1A45265229E4396A1227800 7637F048BB7006B4F65699D9E4A256AD23D3817E447767AA97C7E4BDDE780E51 1D3A98D81F8227D7EB9F61CF4062CEBB82C0F434BA3C373AE7830CF582B0A963 52163D7613C9EB8D6C986A7754CE014D6C2C7C5FAD12FABAA0F10A7175434516 D82C328BBC1303BEE1AB75087D67E696616D2265A7C502C8E03054B36B4F96AF BC5C62789A8C2D2CB2DD766CA3A2AB2B22F8BCCF0F7E52511FD295A992A921DA B1EE57852EE06988EF78DF062AEFF885AC3647A7BB19EB8561AD7B33C8D4EF87 ABD79309509AD41BDC42C84F9902E0CE63771F767C7BD7C47A3831DF16642DEE AA0FC2552B65B7E7F549D30B0DD51BD7FBC2F8CC7AF8C7B529535593A4000A7C 55FA84497F0110661F2BBF6B57F4E0AFC58E719A0A3450962679C494D4242167 3F4EDC364097CC6639B8E496BF593DAFE42D0C8DC6019F990FE0527A664B06FB 7AAD904A114876C2CC711EE6C273C690E8CC8D169119ACC4AFD681A9165C4150 A874A5FEC7F4E0ABB0BBE0545899782ACB0AFC4473683CE752445AD6C2167C95 A2300DE6AD98E96AFC4FD4E49D30CFFC70CD1CB9CFDA06719A5C86884574C566 91ED7A4752A862838CAFF8CD0340C80241D24D0F00ACDE62869CD18F0A8B403C F76C55C340E1AA9AE21F2522EC29763E5E230CE72FBB1628D0F802B81EB658B1 C7EDE855D85342B30FDA9094826E431329E49F38E2A75540121B7F47CE095BCF 8D9D02621BFF0015DF446C732E1914841FA7D8DE66E51C3C171513F0A2743BAE 24495EA0060EA121F7ACC5013EE62E1E38539CDD8BEDC722E68ECB1815EEFCB7 F16C1CF33AA1D4EAC14BD7C75AAA357D695D8C02166A65345E1741B2BF1C998D 078380FBF997352B719BFED784B3B0B3102894D7FECB5B22B242B5B2EF8AA17A 730545841972F76CD13994333B3E0B175CD1E05E65C9849C99EB7295A2E82AFC 68101556EDC990432F6412A8ABAE735B711E9AB90B0AE841D88240F3ADA46A56 DB059C3FE529219B6A320AE5570893F216AD9A4FDCD39268B0273BD1E0EE2CA2 76E2C6E926B751CE0D11D0C21031188DA32499E7EBE705D9827FDF729A64AB2F E81FD51E757087C0B9D6E14B783F5220E55BFBBC1D255EB89AAFB5D0F73A4DD0 6DD85AA49B2D9B593C1680D844B02F005C8D9307E27D4C7F45782A71B9E5CA44 19221BBADF669CDD574C1D017478D93449A49AAD3AFFBB4DEB31863ED60D20DA D5470B517049BB0AC5E86B0311C6E53F61D04F16194E6F713E9FF4D3BD78FBFB 3412902F5761E6305A26AB129CE06A617534D9B2689F8DCBB7BB5FFC00DF4BD1 66C3B5F58DF25D563717D076BDB6EB41483031106ADCB0C117EF2E6649682423 BAD9221930343FA0784F4283947312D1E8D055A5220B25AA0269686A27F15277 3A8A1074657EB376492F16167B18E9D4D8F35F3C6A945D2C93BD1D6E190FE0F1 C81BF9438066CFBDD54DE2C4C7A42A1D003242430EB6245728CAD2ED44937314 EC04201DD8E47D82AD83D9F39B9ECAEE5F71F360A8E340EBDF454AE53EE870B6 5F9071CF44E6B37A532DD88B1E9EE3CD533BD6566526AC2B6B7ECBFF2140E6DF C1A60CCA70686A4F74DA010209168FE07C655AF9225A91DB29900EF5B9A93215 F12B1BD593B0B4764FABED57B7348BCF979BEFAF35E89821264D88AD595B350D 5AAE1A20EF9FEBAEA25BC740329E745FA5734D11471084A3785C9B2CA13CE438 A76D5AADCD54D805043335E4FB1E429713E4F5E710E60328BB8888096615F8F6 486AA022C510B968C90D185D69BC9E2722BA799B93E00105BA0513E054AA9201 75B9ED610AE988834317AA38D1126B6AA55C266D1E12B60DE69267831166ECF9 46D4F50074C8BA15DB4002E1479A179D5F845CE3F84CE2B0E14EB59155AA9FA5 3595838C09D99FF64C0CD2999BC4B9F76888049CC7B22B4EC6894A6ADC3D0561 82466D8EE1E44DD4F8AEE4EB2C50F8BEE89E3505F8A2341F3B4F2050062E5616 AAC668189205B2D3902E2C12EB0C7BBA4272FD65CB631D1A143B321CC558FC10 91B3D63B99294DF8A7C2AF5FE106D6C519E818264CD9E4124AB64FA601D6F5D7 4EE69C801620D8FF65E2260D7DAA7EDCFCF5EA486738DEBB4DA6092D5012092D F0ACC82788AECF40FF9CDAAF83F3CE481EAB1AB45AB47DDF950C685A2DBF5804 A08216220789E11C5B9A5F97BFC9969EF1050B609CD062FF7E5E2C57FA97C050 CF8AD25A015261DBE5C6F1E44F07C8AC26F0950A285F43027AEC3C816B6466E3 793339FC0AE580992B12DE063941FD53D609688B718311F072CA95D2B97E5D94 0928D79AE46240FFF97DAB6234D8845E7A55447D7B54D5C57BE1A431E65E9566 E399162676D1AF584B4619357B2E44F69C69BC8F3A23AF0A95C5FCFDCDD98BA4 2AA91660B27F2482D1E446A88AAD8FF49247B6CD33B0F6BCE7A3A825AD89D479 7D2CB2B1FDC6D89054E7710310446C7D6C145894D56C5F66B0FB9B470D7D8D55 03A40D4662D9703C6C195382507B8615C0C3B8E6A01EC3DFB3D0E6ED4E649AD6 0D80E87B567A0437826458E9EE7D306621023B72B9D596049BE39C78A1F6D0F9 2337C4C740BC01959CE6B44BD6819584D82972A01688AB93A145DA799F93B253 59DDFF9B9C475F8ED38309F3DCB6DDF80296D2859D7CED25B4FD6BDD678F2645 0016D0AFAA9A7542C748EE9DCF110011905B058D1FD7BCE40FF25C4F583BD496 ADB7D1934A2498F3CA9BE0B8661D9B9F8C6E50D01EF9A67FC7684E60268A3290 1C89E0E0E128E785AF928A0B088A6535F0A58C3A7AED8A8B7CD1CCE7F25B7A79 AF06414E7D0F042F46B44A7963F7CD74C4F1202F066AC6B8D2FD81CF07757094 67E14BA5D8904195D599BCA6BCCBB3DE2F787B13EBED433915707836A884C446 753F8D0A32987AF2B2B51A649E58E5C3BB98ECEECAA4351BD942577CCDF86F90 02D3934CDF36C0EEC2D37BF1825057C36EAF64C915CF61DA1469AF7C2D41C8BE C476E16F2EAF7FDDE1963F7A389B9E8A70286F55FDD1C3C40F2D738D8458CBE4 DAA35BA10815B83AD59AE5A6EA064BFD7F635A58DA902FC0E967F6DECADEBC80 99747C97FB974E837EDA9BA406550CA24EEDCA184649BEF2272410FC0C1FBB43 2DC5AA0A3129A6BD02A2C85BDCA365FAFC6638976159491BDEA9C9D325008AF8 704E07124BC75697A823801E76E19278E73A3F59BAFFE203D30C5CAD0D87B3BB 8EF960785564B556A32109B864FE34566E9703448C9EF9302040F0110D18C812 C94E3159FDDB67A99CE5CD93675AB94BB98867031C0E9D909671965AC878B840 5796767203526808A0CC29F005B7993B4BEAA27958F4CF7C69FE0552AF98CD7F 461029BE1CF75A84EFB59598DC2DC154268220BE9A53D2636DC06FD29EC7B1F0 BBF70CE960665F37FFC7E57E63554D5F0F52775A103E6C2F3E927AB34F5F8CE6 76F9FD89D76DFDC43D 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: SFIT1000 %!FontType1-1.0: SFIT1000 0.3 %%CreationDate: Wed Sep 12 2001 % Copyright (c) 2001 Vladimir Volovich . % See the file COPYING (GNU General Public License) for license conditions. % Converted from METAFONT EC/TC and LH fonts: % ecit1000, tcit1000, lait1000, lbit1000, lcit1000, rxit1000. 11 dict begin /FontInfo 6 dict dup begin /version (0.3) def /FullName (Computer Modern Typewriter Italic) def /FamilyName (Computer Modern) def /ItalicAngle -14.04 def /isFixedPitch true def /Weight (Medium) def end readonly def /FontName /SFIT1000 def /Encoding StandardEncoding def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] def /FontBBox{-70 -360 1392 838}readonly def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052BD0CE60552BD63101D7CDBEEF5B11 69C468645FE4ED1AF2541AA0770C1DCF81623DE0ECDF49F2B522618F650CE6CB CC8C21885DD61AF8A523AA677EAEDDFA51A1F9B1885EEE0456196D634E04EF89 F17499DAD982502ACC349B9EEAAE4A71A73D1147318C60A8BAC10510DE90D8D3 F46E47295D27129A5AFE0C65E22BAD10D06885A2EE623FF8E1D90287A083E00C EF25195F68A2A98170E4875AA1B1EC5CA76F3FA433922B4C840F1C54D4B410FA 232DA4932F27F16BF8CDB753CD6792A9900A99C9E3BD6F918ACE957247053A6D CDE451BCC8152EC7EDF3B9CE759577DD04909FD40AB24CC6AA440A56F2CB9532 A73D218580C6DCD7E84886ADCE804D9F56F691CA8CF6E04FCDECDC50E89D7302 BB4D479AA36196E44A9D011AD1C00057557163AA01AA4B4C20C209D06ABB835D 1F5282F47D7332C6619F4935B9829E8079E6C4C87C5A575D0C55C7DCF7AFD6BC F67CF36212DA945EDC9224B1ECE9EB6152E6B57F3BF4792E91CDADD900B003C9 38CB162E3C1D4A8A925425634B2B530A17B104E9A21ECC2F6A30B3231C7C27BA 3EAB9BF231CED0440B8597B3A35E21A3E66C525B80AB147ECFE4E152371A4334 7DBF05A7A1276CB46FB64FE8C2484AFADBBD17B2F94A506A34A9BA0352A91B3D EFCBC9CA192F4D8DE86416ADB1869D73AD1A69D249329EDA2D1D461E41213E6B 67BC4EDEDB56018F4037D72E6541578BFDD16144EC5F060B95A21772C4119DE4 65FFB95D789B8CB67F10DE655754C0E291F5D1FB382E99E176828D613909BD2E 070F7DEF8E24A4F500B585D8B6CDC52556327CE9C1CC1340A4FE7C15A9E0DE60 0581DE277AD86FA6713EBFE15B8999EDD0406BBB0F061882534458E05F47E30F 9EDC56CB842043ACD4E4BA5C7E082994AACCCC572024A2FBC82DEFB47B9A7ED5 DAC997F0C96EBD73A06BD8216A3C4550E6174C2367BF8124D0B1DA92E27362B2 B9578F0F8E2742E4AC3390ACDFBBFA745CAF433C115BC700B365EDA52C52D99B BF3C16AB5A6F265D4BAE09F326C7A3B460F007C1D9B1D0194F525E6CAE7FD75C 8C34E6B895ADD598B347947BFB29E19B19B7B1996C96D8B52302D9B7E47FD932 AE04BA80A0B5C87DEDF27CFD603C275A1F76E771B475E1A557A52CF5D26CDF0A EAD7DAB007222B745D0B23C18060C4CB1831B22948BF12F26C82B2DAC99069F1 62BDC009DCED2FCDDF7AA5E402A021411BFFD9998F9AEBE37DE5068418F41A00 7E64514ECC2A92464398A1EDE91EDC4F4ABE39D2E21CE8C3731E27B0875ED86B 498E4793915F5AC9E2301686F8797624292BC3926D03E4312FB7EFB1E3181CE8 AA1E1021BF9D790BCD66B9872418F069ED55BFFB7FC986E5F6CB5689F1A9FFB7 1AA7E9AC2E727754189AF4EC871967BD941D8D902967B91008513A04D2CA8953 09CC0EB0CC9F750D3E83208C1680D7EC237281515637F0A5F17D7FB87BFAA3AF BDEBE3188BF82663CA731F3585C9B36A75CC7AC35A6FFF0BE78E130BE08DA99B 91A1A28AF31522A66B8E9D7F2FD3D3F43B63C0A85906EA4630758B5758A5F889 A5F503843C952897FC91509B6B005BD64976069ADDA18339E60749C218E063B3 95D84D04AA7720241888D3B8A97F5F335EDA4288B928203E2A322535DB173570 90B097E6BDE9FA15474AC675E8EE1F8ACD91E467EA0CA90AC3D4350A1D2629A0 BF31DA39D896411D284071D290F35E9B5A8B9C7E229F4FC592844ACEE1A51AF1 286DB7C95F1BA7E3806A1534708C378F4040B24E57BA7672E19E360549603C07 27A4C0D16EB37C370007FD788E29F5307474F5BC80E8420C2C6821DA85B67247 44DA0A4001DD7FAF6007B39AF03107E692DE39C36120FB8B7436070F4ECFE8B4 85C8713C7F7521A66CE5EBA4A3DD01B7C3A294BBD33CF33DAF8A4BC2C999DA93 F9BDD9A430ECDE68909538D6EB53D9EDEB8273F35B5525344780C3FE46F28CEE 9055AF13161B0F081D6BB68257AEB962FA833C544AD27F09499AC5CE6853F0DF 9F7538A7CB7C78A8C6FA2C41AD66D3EC9336767AA7FC3F80225397856BDA04DD 10EA95BC31763F5B08FBD9B21015A30F22586073086AB006C5491F3C9C9235A7 D5504E3D19C9D40FC304CAC934D15F54843673A03AEA4A5715C490B1EFCCACC5 8A1FEA7C7EAE33C2D9039CC3ACDB83FB1ED7D11499EF300E5CDFCA88076A4D46 7ABBCF8AA54D8B208F973B30B14681571753969E4DE4886646768299303CD0D8 39F87ADEF6159361BB0B9BD43D4B8D7191ABA95918FA239B603CA9EAFFEE039C DB86451D5EEDF753D98DE208137F2DA6C21235C6C2A77D5E12C4DFBD2BF4BFE1 6F013EA511AFF68F29ECBCBA6F781036AE44B7095C1DECBFCA593B9A88B37BAF 7CAA5689A784ADDBA4FE86B13236C6792C972DF81E1E424444BB684B00FB549A 92866A99B8C1DC48D348481F850CCB77143983C5F3D297158E004EEA31CF85C3 0F4545A5AF9515E57AE70AC9A1348DC7B8A82516AE3F39574F4183D4EBE24EC2 0B32463D48D7550F2B4E0F32924E1C6F28D8F4810E723C0D953E9900BAEE2FA9 14CA821B995E240815E2A866A4A74D6EAE39BEDFCA270D52DAA835C2F5AD4A68 6AD08D403BB53CA7458DB1F0D03553A5965623E103844D52478F6545177D6B1C 7CE49FF009D32E9F6C460C203D7DADC4AF3BB8317F8A749ACFD5D433FCFAD9CB A9F009AF07230FC9DD3C3E037A7D9611F4BA3E0CD4739A736F44FAB37523E494 1D032F2DF6FF5B2551BF8EF7E16BEBED01C6860AA8A1B609F032B4D0C796C291 702228C36C936559914ADF426FF193765CCEA9FABA3B61F7E812297D0C6D5072 0D6913F4FE6AE08598572C707E3CC5C40B8E50E255086311090CE3CAFE150568 7BCA1F8AC238508C65B7AFD0141326A5EA62521A4556AE3635BB5F0B081FBCF0 4073E6F764FDEF7746DFB35F0C15BE7C4870D2F906BAD15A22B013FDF3307FB0 98790EC321FFF0B0FDF48A94C2EE1671ED6281FE60F05B827AD4622A3F7BD3D2 F83B8E4BE3C9AF3BC9AB1F1F73DB96EF2F48A4E77A81EA1FDF8368AACA89B74F 523F936C90C0BCAD56EE3EC07F3B3E52F66EBCDA17DD88590311DCF8123E00A6 BBCC51C5C969387001D169C9685138A06387FB80B43EDCDF27B191A6D35CF856 DCB3A99BFFE362B7DF72E829AB36A40A0F8C127B7AF34AF7F028031A9531C4F3 8A56E58E84D52025B188E06E96D3F725A7708A9D51359AEFE3F4208ED2259395 F9FCF7BF6A5BDD21B951363A6352B8C1580C3DD5D13B3A95363D80116C2A2147 3D0756C31E77A356DC770756F4A887AB343451EFCAE6D585581A5EEF3F2EFB96 8EFE3496F7739B7AC62019A113EAEA907D8A1ED4CEDA6CF085245A684470B7E4 404F088F2B37B3D6B872FA35E2DF93E57E4880C21B0B5ACB813FEB797D0D8C10 16BB7ED124C0672AE7E8BFC4C09B1610D83271BC05231AE2F4794FF8D16234E4 4996C2889D3C44EF68E4E09A0E265BD2750EA8AED8C20FB1C97642F42A0329F5 0A916C82A7C17E05B644C2FBC093F5FC238B6279E7AE6D25E81034C170CA7E61 C44EB31407FCC2DAC7F13B0C4C93E1E8BEEB123C88893F31C056F1BEDCAB0E3B E746A4B0334EBCF29B163A35C9D440EF22585405F487D1904B3476E0A2CAEA1D 9C644E3FC3F6EE2A3D7690B054DBA04D4354E1D423DF121DD03476ECB75B06EF E5369A36F8951F39070CC945622608B9F601DB529DFEA26964314FC7B826CFC3 90CB2D51B630473F72ADC9E8B99EECE74415037DCA2B01DB899E8E63D0561E03 374C6A06BEA865F81614B151DDAA75064CAEA141908BE582B050E80AC9C00A37 3A23292B4BD5EC4969A9EF331F1D032BD9ADC9353BFA3BBF553C2DE2CEDC3DBD 0CF1F77D4B9785C876F7F296FAE914014C99A0ABC7B6E384E4253396F0E34A62 EADF2A532BD79C6B8A2122531BF23E9A79C06B2A0025DA665AD19EA3ED28F077 55A8D50EA75B7E74B2AB437F66414099BA8E0F0257B1F8CC05CB11BC9D20B273 73524C3F9C0BB1272CD354E43706244A8CF097121332724A0DB0D085EA16E376 43AFFAADDDBAE38EAB7F011897CDE24DB93D8CADD372D2B2818C9FCE8BFEB07E 548C41A595EB76C02F86B984A65408202616DE0247AFE827CE42213A597AB3F1 800CCFA3F238BA39DD6B83D587D99A05DB2F046C66FB961F688B8555A629B59C A1F4C216ECE1DEEF5C791A3035CF886B1FC03F4F786EC7D47B97E25432C19560 8A72C162E943ECCA5E60D66F587220828ED40B39AA924C980C2F5363892C77B7 4F294EB2C1F61CB01D00DEB2CD24D086B493FB63F7FC395A372EF115B8B185AA 90AF0EA788C83F264CD67157D4F9FD0EF0E6C2580016C1FD0FA0002E4F0EABC9 D0D922D93386023CDE5515FB84E4061B05B22E8F0418066AC7A926C8F5F6E8DE BA45DD56BF0DF020622A189E6063F74A7A9B1875C8189381FD05B4267E01CA2E 6562FF3F2F1B1FD4B0967C5EB884B0FBE995EDCF0D3DD6CD276C6374AA9B2C10 A047647ED31BD3A28177BBD016F03E617FB1064F0718A52ED50BE8FAF5F5EE96 48134F344D719E1D3195F7A8D54B09F4079AFD581C3F8F477747952B1BCAE8EA 243A5B05241460A6A05BB8C3A757F047423EBAC360D81B7DC39FEF8B47E005D9 AC4B5C5F8CB9DE003AA6BD1DFB29E80C94AF81CD11DDBB2F266DD6FC539FA763 24838E046E85CACE4898BC9404D7B6FAAECF3701E16C7C4C3BC2CF5F7253FB5D 2AE0F7E7130049E414CE906934D916A30EC7084D940B9AF8824628ECBD9E1B33 C6C9938B799CFC2F6EB2D290A75F015150434EF29083528D3315515604396820 373A057CD51649B79FBA352112F9143D273939DD770974B5E79235499B3200D6 A7E161BDDA5F6528CFD2539EDC3D52BF3D0EAFD00F03986016A0F309EA544405 9BDD7460BA7D25DD0C40EB980602D6D974031F0A1F2B7B3B42882D3FF8203156 78F283728378CC62D0E41D175FEFC91EB83A25202D522579A9764FFEE5AB9F30 080C857E92A2614CCA05073141CB9DD38DE2F85FCC4191441C18DC761571CDD2 D5B9071ACAB17EEFDDE4A950C7D0600E3FE6AEC76D0FF0552F7F63440B9D6A4C 2E6F97A069478FF0D54C3856B0C3A5A63EC928A672F3B000433D779006EB6317 F4E2B6772F4BCE612DF4B1BA5D736869A011BB3F2EF8E750EFD11D21CAB7A1FA 7A955C413CB84F7BDB71B717743C7AF418C2A393E6A14A7B954B28230D53EF75 A00DC590155D2897B48309837EC5BE659223157292148E85402079DF3CF06FAA AE42D0F64F68E5ECEE9D3629475DDF9CF1A646DAF4C2423C9897018625119851 7B5D810E7E0506C712066B3A0DFB3F10EA1B4F0CD1F449BE353FA79834858526 1D4FD4D9F110CEE18C589F507C35B2DE05725B80D85B0F740A5278C99C39A3C1 52CA0A6F6C22E4ADF5B4E0AD7681284A04229D58A68077CE35CF5732CA339647 F631DE208615D577871CC66743A2987424B7D9EB0C026B33B0D3A2166DAF909F 9BE74D3C040A37D9E595009C1D9672F694AA1996F7A50176A706D60CA1EB8A41 0EBC0B623FD18133498026E5DED90584FA4414A6C244AE410069FB3F1F51421F 2478E00B00252AE48BD87582EB6C88467D82474DC7628BA520178C8D8BA0E412 50BFB1A5A92D8CFC8E1692E83145D0B1F65AF4CE71F02335D367AB7EDDE99665 AF35102458632CF7F49CC767C4ADC987F38F8927A0D301270193D57C66CE1367 158F779933221D89B63ADB54453159709EB9D594326E2E2EAFDF7870D9D7DAC2 673B920C7C13BD757BD4822E6E92354ED262BBB2DD5531E735F3591694CDBA55 5D77BFA4CE7CE922E05D9918A4FC810E723C0D953E9900BAEE2FA914CF89D41D 0AE4153E4CDF61A014B2A4EE6C73D755AE1812A0FEA8F61429651F3CD4CB95D0 F3D53CFF27715DE148EFDA8E740A5DC1A5A3DDD1F2B776FAEBB5C4DC13B203D8 796B0A0A9D5B6E1EF767946562D768AC7A063CFB0EB3C6FF697509736BCACAA7 F29C2AC85B506D7677E95D4842B17E1E8BB69CBBA278E5F23E861AFC81D58DA9 32B1A4B000BAA5D77705218DDD134AAD7C32A0AAED60FCC123EAEB131B17067B 364E0F77DBF60D70E4198686C3D5180D223C92CC0262D6D134758B28F18B78B7 548EB4F8FDE32AFAD86B27BC4A273072C43104F4BBDBC85E1F77BFA1115C82D4 7C888075068836C459E9E427EEAF3D3C4B2272F5BAE4631844A244C922B12F89 12649381F03B54407D4DBBBAF70E40CDDD0811D99FE7268CA93155142470489A 70F5CCA069DAA3CDF009DBD599DA28EE5B0546A0474E2CC3A093168974C4F147 423EBAC360D81B7DC39FEF8B47E3AD09FE499E34ACC23303C77794CD2B6CE4B0 3940E31ED04F892C0D6FCFE4C05C80C73DD4BC5DCD32D2F758AD241AD247BD97 FC9468F5CB0501C276BD84A79D5BC89BDAA72DA4221841DFBA08A65779C42D24 4D9DBF356401D60DD0A499AA8CCD3101904DCF76276F67CE0A9E6BC3B74D807F 7DE678CDCDA9B1CB909D4DFFB07FD595F10B01117606E8B4603682EA6997F2AB 23F0AA866D2968C41AC81EB91E7AA056392610918E369E64112E5FC0119EB973 AFEAD8F7A080F28CADFE8A1C8CF9FAB8BD3B084EFAF64BA95B485D60758CC19E 81DAB955BB114FDF5F6888FC0EEF6188FEC4341FEE546C0AAFC0F22F96C2A3A4 A7F37394810E33BF64BEFE5CF81B1DEA2EE0E96A025E3838708EB224BA86E1AE 59E5EA772826DCCC56A87B0624F5791B79068E26B803BC80844C9EF91A6AFFBB CBEA8C2377AAA7FFD5B9BE66F05942607214A9CC58E599F5422BAD83C62B6A88 BD1CA3B75B50F0335693231295B2FE8226C32B74952B54E1D63AD89F845A4ABC 44BA3828D1708ACAAF5926AD7A2827D138BCBADAA0A72B0C0E056593AEB5D4E5 FAD48952E047003A38E4F900598B0AC2E83864D39B831B9D6A86C82E50ED1362 D9D387E567B96575C7505F8B60399C74CD8574049F71949A19C85057BE96D5EB FC0AD2FFCEF17F5BDD679B0988485DA32F3F514DF19A62E23446FDC94C7F107C 96C42BA51ED8CDD5C08077E0132BD512E3384BDB6709BC632656DFBED14B1702 91DE144D0F80F79771F5DDB909B8CDC6BB9B053AA1053D249E3AA85A3232617E 1912BDB70D1E79CF293CDFE711E988086D6EE9F4CF351DAF8F88418C32671862 B75328C36A5BB2BDDFA7B5861F7FD2003D4F299426A104D9601F647D3B89066A 22AB02D7DBC455FD33FB4E7F6110695C665F456EECE4F0AB31D4ABE6865733C4 064D8B66417A1102AFB5D819036CE606432EE212F87AF17FAD38D0B3C1973D17 1BCC4C30DF26DFB329137F7F96CADA9C3F77D24925C8573A019532F0BBB1BE3C 33C1FE44F00164BCFE6126B91DEEA1E9F720413771655C46DE2EADF4578042CC 624BEF6191519B639D87A4BFB18A28EAE9BFBBF2A42C2ACD8A06F29F64A60B30 78644C4EF58C1147CC8270B6B265374043839C772B9E0F1C77AEF7EFBFC364CA 9471EDE575FDB16D7BE525FA7BB0DED9CB57F7C25118B07A9944777D347A8B65 051DD9DA17845068139130E6936AF27B3CD156D5D9A3C59A516EFFD38CB6D279 41096459E584C76B5EF31F34604E83D3930C008336B7AB26CFCD688A7112493C D5E3519D16292A4647D72FCD0C2677DAF9AB2831BDF17C28624ACAE5652DAEB5 3FFE6A603B119FCBB47BE5D07BFA428551BE5416FE8C785B0F6AAC60237B1563 5878BB1D08740819F142F98C4A9BE6BDA7533667E0FC85ECA6D74309F084CF3E 886CBC91C5386A266731FE616CE9055A3D9E42CDBA2647F86CEE02A1BA437B22 73D5C097FE972352DE294B803C6A110587D374A29818882E960E1B92E46DE054 8D39F43EDB3C3F9448D07EDE0C113B10F14EF304528719AF5F022D7A587924AD 9A0ADAB5213B4F0F359C59A019B99967A8EB68C30A7B00FC107F2D8331D25E5B 0C3A9EE6BB645C05492A2752F88482CF7D33EBB9A7014296C8E353DC4388FDB8 F030E4FFFDA0D1FE4F0C41168731A27DD7DA80FD83AD1BDE7E037D4C437AEC69 F92A89067AED4EC34CD5DC430436E9C815EA54E08AF767B82DD2380FBC4E38C0 CBC3F1CC17443304494A7A0F8FDA3EBDC519C2D79EC99FDEAAC8B7DDED2E4C25 ECCB10E1C1B41B3B7A4F2EF978564357C31F9C1A8A64C98FAB5A70D30BF73763 B9139317F414752D07430C78CDF9A3DAFE021BFEAD9AF4759A563EFEF86C310E 3EF88A19C2D4875F588ADAE513A8EC06A4359464A7182A1222965E2FA5AAEE59 C57BACC6348E7E59BBC6F426AC06708064FEEFB930CE01125F3499357EFD3BCE 1E9537A854D3848E4BA296E27D7A66202B9DB714067BDB1C51BBD2C4C1BBEBFB E83A7B723AFAD713AD906B31EBEEA862D9DF32A398871BD38ACC4F2B176F782D ABE3FF873C255C93D7A30197A19D149BD83EE4E88530EA7EE4627F41E21B6B86 F75FE172D9B08F9B543BCE349D3F6487B5374F2A0C163CE1072C9EFD1B45E1FC 4061204CC6D61EDA89E1A0DC635BBB3BA76E01404DF023E599D8B4C95D24668C C7185ABD466083845E134C803132F44561F7D83E22555C164BB3AEC40D6901D4 93CC58D8DA984DEAA74C0DF18C9D8BD40D61E46A153C3C25D0C7DC1256F09A1D 1FB20805BF2431FBC95992607C9E38746A7BDA946D33464E7EFF3CFCE4A34342 7E103C1AD2C68CB09BA92BFF97CA0E369C729CE3911315A67A7A93E2728E8C85 88B5E3D3EF8353076A4D3B4330A982C30AA85A746153EBD412A0056B836A358E C93A7060BADA1464B3FFDE2815A6BACAEDDDB406D7E07CC3A3B954D537171F74 39B474B24635A7E9E075BB316D8D1AAE16BB13E034930C855B236651AD4B31D4 BED58C17846DE027BB0A040AEC165840EF7AA609AFC1CDBB3D2D85F0ED8C020C 091AD2D5F42AECB981001C66B4D7F8ED88249ED4E2CA22AC03C3EEBDCAB59798 D7FB1AF29946DCEFE11EA2CC61783A463CB52C2FF2892A528B5F2D43C5940884 2911DB483CCDCA00A2A2B20C4FD47CB3C6EA23F023FEEE0C2493FED90E980E01 6B6835D12D487FB29998A30FFA6722FA4D73A8C48D755A6B2434BCE500F78A24 C2FE442F026D1CF852F314912EDF4315E982C4FE8F3F350FC8ED47A84B487004 DD8F087BF3298E796042AB4A7093BE5FA7CB5A5780FA751B0A47BD5773F54A9C 01458DC21A88FDA01F80A9583171E1A19E0FEA3B9B5020CE44093FBAFFDF9D69 0162B7373CCD99A9028D732A32146C4E7563CD6CEFF0BFF1F88E0F5E176DCB6F AAB4165673ABD3ED33F610D729B4B96A754815E2259431C05D0A3BB3BC188D60 5AD21F1703A8BE0F77666133F9739767252F12528420A630ACE9DF4FED9F95B8 BF5EBD8A35C72A1C95BF082E7E67B0364AFD8597F8D81F1A705CE078F8FD53A7 FCDCEAAAC7E09BE1703B8FE781EC8A53AD3F44A6FD4EAE6F96D21342AAC9D0F2 7A2280C8499C3CC4D56EE0ACBEBFF0ADD6EA278D6CD43B35EBE1B1354266A57D 38F08CE3720C7938161863B28AB406FB94F0F5445A0F4F99B972832F0A626ADE 85A2199528964CB56DA11B12A643022BA9CDF2FB40B9C0B9E7DD1DFE92D00BC6 AC66C0B04B729B11CBB909D503FB6A54859C49042A0AFA7C25CE9F249C884EE1 DC5F71D8C40C2C7363FBBBBCD5A10054D4094FA159335DFE0F52A41DE3EC37BE 0B982999CAE7CA46CF4DDC629F3F5D3BAF96B67863C9619F0CEFF1FC44156876 340C4A0922B75E7EF41A4BF9B28CAEB99C22B2F2F8608CC44B4628750123FD66 305E92A7BBDBE48869E2D53DB8DDBA620A535CA4C7E11C559656ABF9DED16491 89329659C3AC03CFA2D6EC42440356836F528EF173E483782FCACA8DB225952C FCA43EAD3239B20114A5AEEDC690DB077ED1DD68ADE20EBB752C9566CB17ED81 4D2B4D6728315266C0F5724566F3E762FFDD46E29758F5899AFA1300D77B26EB 9D729F341BC7C48EBAFD76D4177A055524876CCE40301830258F5F31BA1D80EC 74D92E17607D54D39DFDAB7453F4666385EC8FC416BB44C61C9947F3E44BC25C 885A37FABD1965E41A028B8DF9FA6DE9E1A505C81CC95BC66419DB19EC740870 0F2E25DB51F220ECCC262EBD2F2A4EC939F3A357292D1F5A5E23476B4C1F9552 0B005EB3C043C02FADB55E3CD2F9DE7A4174B073B4220244808A44368164D9CB 24E75EA8BE8D6F9A9AAC2294A0AB5A0A05DAB8816B14A3BA5E41B5BA06E190CD A6CEACEDC0BA0C37D8018CA7A1B133A69FD16328D85C1CC9A3EF04B4401DD4CF 515E1CF72CC6D6D0BF556FB0ADE032280F7E7F510BC1CE3F75D7B6653DA44C48 75F7892086358F0DB799603233C8322E494B0E1893D3DAA9D0FEAEDDFBB79985 5B28202F6F0BCE3B2B6DABCC9956F75DE12403A443576D61C8C1F07E420A7545 B5D84AC8E0F70D7DF75032D8373A90851A4E4075CF3985E133A7383427E16C22 BA845046B7708F8558A29CC168D8F3F0D18AAD5DD896139920838EDD5FBFC571 1049CF44B1C7CCA5CF8B0BA38607CA4BA03C8C2F41E10CFF5C14B055D39F33BA FA02D5A15F9CAF1AF680016FB593C752DFBF9497E34EE79C367DA074BDB86D3E 704CE3A592FF330458E8F6E1B541E44101E235E4549E8BBD49384B9C069FBDB5 893064AB60736B3E6A7D975B417137A7210CC57625EA3898BC7643EF69F883A6 E09EC600916C82A7C17E05B644C2FBC093F5F997496CBFF6091916A23871E4E3 77278A32DB5374CDB53293157F9D8C533F144BF1D6697155812FDFA0AFBD12B3 0FEF7E8F70997216A5CA79254D1767D5502AF6AB41F6EE049BC37E770DE32A67 20A89DCC9638FF0AFA3F3B034988E139C2992A6DF724AE8D6636BE8B11BEDE3D 3D4009CDF5B02235BFCC8AAC45C94657B38B3D9CB2C1B407FBB749EF3E481112 E32A731C6C6DE2A23C4EA551527C0B0E090FDAD74FE0505B23F74FCF94A0FC38 F09139ECD44EDC4C4D95FCBCC141A26EE0D58D04FD7ECA65303AB421ABD113BF EE802B3FE1DC54CC0994D3927C838DA7A1DC74D0311D3A273FAAC4DDBC995D4E E9F88BB32850C294F085AEA94441A9EC47BFBE3ACC78A1AC8611948CDC7C93B5 F1E465C45D9A595D0D9CBC916924BEAA08B95A7CE0A89B2E487880C80381C700 5CF2E49BE9EBA5EE699975C7A2E84D1258EFC3FC2386EE78CD8F9970D8961FA4 C3229B20D0E4F0CB567524708F1B93EE25456BADC0F009B2E7291357F25378CD 7F65580F59FB589785C778C7C79E98D4F860D1FE4D5BAE8AEFC671FD9AE9CB50 09D3950AED31E65874E784DCD78B53CA0BF076AD971B63A4877FAD2DDFECCB92 243831FC222F3F3AB09286F9D0D0FBEF707B8FB92EA58FD666120062047AEFE2 A3C0D3C12A76B86E0EB1BE0981F7EF14C2C0ACEE037B8ECDAC62DC7398091032 A8E5E8EE4806567155154AD30306D719535B736C8CA8A18A5A3651EEF6D32D0A 115C9ACDA1E53F7F58D0C2AAE3C9DAB1124AAF7E712E7BF7A355AD7A846A5C50 41A2EAD4CBFC1E0C6F9A0BDAF83CFFEA552D25159772EECFD8735067D82C4CC3 53E04076632E70F54802503E9435DE151B18985FF2399AF8ED3805DFA9017780 009DCA4CC01F58938E87FB21F7B125E5C6D9C657821B55640289B60F7E4498F6 D20B640CCF85417AAB7F663FEE630DB0A4D9E00B7CF115225B57CF2E6B5D2430 C8EB8996F9C49C628C86531E9DFD74065616460334D7DC4C9081AF95E28E33D1 D5B53BF96E8F5890949B0A689F7A3836F3F1BF309ADFE4745232D6CF29D59695 A2DBC1CF0A053220794886DAAB96B8B60125A657200C1D2A831AC668D51066B5 7715E44AC54B45CD261B7770B831B28E117FF22F8337966F12D57AE9D3BEC01A CA510D7FD36A5828D0A891D908DA3E91D7106741D2E133389BB0DEDB030F1695 32EC1DEB5CBE6F498105E3409058E8E4F4605FFD4625F45A5B8698FFBBB86A02 4BCAF5FBE8F48775AA14BE74156798BA0727BA5DCA8E6B86BB4ABEB9644731B8 BA90DE08A4346E718F1AAF3DF62CBE18394A5F9B28527E679B4FBB61ECFB18E5 B966BCAAD3452DA12CEE2450B3A5772BD7C4CF63F101556CA950C3AD69D5DC50 15F89B15E0D38833A559D26FF4540915B0381184464F21655164224A10A803F1 237655EBE374A20432C97DEDD16B2F1FF4C1A90D72D46A3DB7F6F9A95FE61459 159490317737F63D69ACD9878F2C88449813611CD5BE08DB019A26B52A63FB1D 03DD52A661F00CB29BEBCF148B6E58826B135420ABC88DB06E31E540E3671A6F 35F91A6C3D5716C5FFC37C0E50B32F5C164B5243C3AB79D3FED9CEFC42B76422 8D6FB49DD87E655B321D70FBC7D75A038E3A0A737176A72B13FF17D3177853C6 CA0C068DDD25BBD71183536A3AD35E6D1BF207677E6008BE68A14AA6A82D7D75 67BED187D94D467E63D5997933482274E275CA6255517618D08AD1EFF92AD383 ADEFEB3458EBCB59D554361C690DC8AFCF5D4BA9B2AF92A63D02BB937F8A1FF0 1B63640A3F64674C2DB9F41469FA0DE739AD3BCADC8FD7ED834FD4A5833CFF2A CB26A3DDA7E5B5254E70764C5E1D239F23449C2C03F196AFA921C8B526F516A2 BEA74582543BA9F609494C89AEC8278075E21E1E1B545625093AB22B21D24D91 2BE8E1A5BA512968B2B59D408C8DF7CFE78AAE466A2D743490953E555EDA932F CBFF2A9621C0BC450FD1452BD351489E5ACAADBE434C82F2B3EB1E58EC90D4B3 ECFB42B1CB7F90348D49198C3940B8983DA511AFF68F29ECBCBA6F781036AE46 181A958F9C672AC2E5DCA4B0EE73ED1F63FE595AEED767BABE21F7B50B04B6F7 E0A057641E14423D32B40977FB26D168E25ECA5A67B8FA3E741DDB30D4BE9876 488AFA9A7FB3FBADD4A13BB564018575CD56BE0A96A542E64A4B4AC7C6C2C0E2 F133DD294C2FA20E72557C5EC4D1E9789043774A41103002ABFD010625FC5B1E 3D80A74DD371CBF95488147646AD45F956AD78B6395B87FE592F2F992A8A6438 AAAC7324595A421931A94C72FD5B02277BA53FFB06AA8D65134C4F82788CEE27 4AE7842BD8077F90731D9C031A6EA383E6C4B308062A0A611190E892DCE1EF4C C27DEECD64CDDCBE351F4D749EDE83D2D1377BB5BCC8DB8FD1FA6DB83CBE3A61 98507C35B2DE05725B80D85B0F740A564A72E988737A223D6BFF7C303BFB33BE 5746B6636388FF90546CFB8EE78F2BE1A10E2B344B0B782A82FBDCF64CAE5B12 0F1638CD5800E528090977B35B142C0FFB9E1B56E4C0631E9C362994EB9C0E30 B00D7E8202C340616C830F61F7C2F20A8845AD4333E1FC54727451C064543291 A4966DF31BCF2022653A7C65590AD386645655BF1B4C899036D78D706C4E5C4F 1256B77B740064C819A7DCB61420610DBA35BE10A0B99810EF405DCF2351942B 10206BBE5A35EBAACB7C1F6E6075E75A6ECB1C1AC5FAA702FD94B353A1133B5C 47E0933FC342E5C1AFD7F6D6E6D58E8631917D49BC5AD0083EBD2BE96BD511E7 AF1FD78169DC857F9BC31A61722DB25014F7C0EF51C36B43FAFDB76FC8FCD41E 7BA921D367B0F308A0BA859F396A34EC81D76D5EC23037BE508DC0A95CEFE4BA EC09CF1AC5E29F26AF6E6B603C0A71BED1AC0C446D6BC2DC6DEFCB7719BED856 5E9C7AC8135BD9496F6190BEF2632A955EA285C94FA51CD5F8FCE37DA2DFD923 DA4B7ED5551A3288657DD109CD9D40755348C63AD02717F0B09F052599426806 548380892E2176694428C2B6E79AE2D3FE49B10C79B3C763CEF3122402A341EC 5660888068E3818EEE8F702DFCE6DED05662C9315B9E6E73E10A02FBCDE59BA8 4E561534BD33754B494E3700F8CA64BAAD3EC532A8D31CA6A87F075E02FE5D47 55CBAB764EE2CA299F19F38E0E79896540C453796E340E3AF831B7F0E8F38977 2BC51C6CFF8FA969CE5F0B43AE421C5C3D66D5CFBF3A492BD6A31F9A1167F80F 7B38364CF6C04902CC8DB1193D486571DF39B5B1D41DE505CB7D0DFB088E2501 74C22F4FC6735122C136EFE22B5EB496665AEB27D6DD3839DCF6BD510F00E980 09AC80EE6177D9E09E418B68C24C03D033BF3F3CA294A4F3DA17340E96A8E01B 4C8D4CC320E9DD919C38730BEA3916CADBA3D2B293F3AD74717A8E2FC967762E F7B23DB76C15B5516B778534084B0429E54907F991C46036272D00B80E3418BD 07659025D9A065A5BA79E8D5627CD4A7D383F43CD31B54F27E41E1FE35FDFE07 70F1CBC70B97DBC4366800A2E47707ECA0EA73E1EC6CB4967DDFA2D5D27EB6DC F9A11121F93C7732C5E926B0736818BDF1AB7414D018CFB5EC9BD4A822DC3F08 7B3E2A2915E0454B7935118C0DC55E415833C72BF066D28657116994555F9610 FA63248A467785F345152739EA28ED49A587256097926C483E82D479EC0B5813 3BC73F013FF7BFD88AF285A5D885C5F29F61649A21FEAB076CCD14323DB74ADD 8C3E9DCABC41977A5C7391D8A702D2C4E2774A10345548608A0360F9E92CE3CD 3F5E192B10592673D8462BDF509BEBF99B2CA423D3B3127965C57D583A0E4944 D9E79C1532A8EBA0D4E23BB092357DFA5DDDA7BC0165587C3974EC94EDF82939 2A430C1AC6FD9033F21C47E9A5659E22B8CBD28A8BD79D2BFBE3996EFB8B88AA A27D75E80166E694EE9589432DD04F968558C89D12E469E28538D91FD6BBFAD4 D4FCA116CFFFFCD9E1AD0AAC6F1B527131E7274EEEAA28E6B72F04FBF83524C3 03452FB6179D3A010C446B5F3F28CFCCFF76EE84451C875873165941E8331B91 3B8711001F7F8F93BB3B8C96B137D2E4EEFD5AF3706980A3B9650D6B7C12CD36 FCBD29C2E569BFB53399FCDB0AEDA8CD01A1E68951CA025473663372C3947E74 977AD8AC96C9258C49F992C7BAD1CA1B6602619B4FC7178CDD5EB3A60FAB4F70 859FA018A8540F2A21850A92EA39B643322A63B5BA92A1A0175620A4601E0BCC 65DF3E009DA12ADCE4F6CAD515667BC689CB2B867B5611C6D408F9A68E9C3EED BD2E68FEA9170D89D583BC1FA56D6F762E81FBAD47C8C9FC037D536E519182E2 8743825823F0F9F6FE98A99664195A920FC239F97E12B2A4DAD91B995579ED10 2371E9C0DE5694918B099D70D9DDC2B97C4C0AD09EF99C25B84363BC09C45052 4C70C1901766A6477583D0E38C54BD82014D86233C2D47AB90B928C9A77DCF48 C69E07409BBDB25258FDA340EC4BB270C4073D8747F3BED6E631D300A4DD2A9F 210C68A8AB4FA98B37E8D41E976B24793593F82F73485EA0C6D98AF167692FA0 CD020A9DA242BAB1C3A23B5301D2364BBD6E0C6D6E20D7716E09B8B8C5CE3985 B0D8B49A6935D0ACFBAEEF071BE238E74784CDC7CCBA56A15C978EABE636D461 9D88875F41F26EFC7F16D94F29668DD97D27867F6095FF28A725DED5BE22368D F80CF8FEAAB3CE8903141E16A968E2986AF3423914169B2893A512DD290DF999 84F2BD9D7512C585205D8C66FFD7FA6E43AB2421CFAA76C3F420FC0AC26BE961 4F0744B3D928D7932ADBEF6C767667251BE71BE45DA38C32081FA8046AD5C8D6 AD4295B0BCA19D3868654AB327F8E201DADBF63D27EE5373FE4E72FC1ABC392D 62B3240677F64889D0A0646123A85D6A7D6CF1381B1DD5E631CA9E031208B496 0B9E7CF2782C2F3E67AB892D9BB8C31F310E5DFB9E4A62C5D741717DA2CE8492 EBF3B1FDE8BA54B86F9E70EE64F61AA3E479D45C48100D409B86497DC8BC02F0 CCDF68502CCF78BFF747B13B917083498445005470557B23B9D00570531115AD 54BC3F12ECF5D2A21749E12CD465CE0CC7DB8121F5EDA252F0C02D7EF32715E7 B8783FAD43305A046435F30D1C7BC3D88D828387199244C847A68F1A9E8AF6FC 13B4BEAD84A6FFF9F5CD9C8E87EEFC1EA2F869EC9B12426D220EC981E3B2E067 8CD4CD7A2637DE6F8ADFD7FEA20AEFCF53089B6D3DE1AB50B44666E964AF3789 4ED79930A3DA296414E84EE43C66D8931BA1BFF509B3AEB114CEFA8FE043CC12 B42AB034CFC435EDF4295FA4DA7A1C9895AA3F6C1A7EC970107D3BBCF30D19D7 ED1FDC17A1C17ECD829A0CF3752A66AABA99B9F86BECEB1AB7076A7B6FC40229 E09FC5CCD7F5BCFA2F2C43DAB86F73CE3B2BEFF110EE0ECC75DF427E5790951D AC29A64DF7B2B829951D29145EA74784561108647C88A037E133A909D3B50A57 EED9E39692AB12698C96E910707432882FFD7106F1045878C8A8C0F905CDFA02 A029B296B7CB8DD3EFAF62E431D578E3F6077D1CFD7389D267E9B5AE090C2E12 AA33C2AFF6969A9FA11A7D118E0EE3E998ED513CC507E623F2A8502911CAB495 34A03E2F265572431D3E9F6F096EF3B1771EFA1CE22019A09216E29C8F9BB07F DEF4FB300366AAC94288A59433E1BF6B81F045E3D3F5B5DB51E7745ADC1CAE1F 1CD29617D173784398077AE582525C4120FF2ADDD4F13836B44E482607441E52 A0F2B667CF75A4C82E3DA32C13BB200812BDD001D2CFBA62ABF55C7EBFED8716 3CC679DC85C12FA2E9049715FE414CF0FA18227D9D8CBB45AB5F7647D772DB19 14E82398052A0945C40B1E2318496627A5FF9E3762647B6C8F778E8EFDC931A7 10E9007FA971C311215AE27DE8394463BC6725A72A21CCCC8A800E6C1A2A54A6 03C2A5677E6089114AB17269EF51EFC4332567ED9E91EADB78CDE4A9F6A40DA6 E47D339BB2402778AA4A0EB5F9E4BFE3B43605F4D090CC34F1EE903A1D452216 38F93B29D9CFF024E745D8C964BC672573139F173E2702B93E115BC700B365ED F99EC7D6B979342E450C7835D5548FC8D4E5FA9A3C1C428F1C5A094BCAF5FBE8 F48775AA14BE7415679A1E9CAD461EA499C5C8BB385AA8902B8D60BB7D396CE1 60EA185511A471E174D03552B6522257394F5169385A0B58BDD2C8CC2D10446F 4EDAEAAB23E592C7F5AF03297DD57EAC81D03361EDF51CFCEC31CB4CE13C213D 085A10424DBE8D6FEF72372CC051A9D1C2117BAEF2EE57874A7345705B70BD77 2B094505660BBC96D6C127CB71E6A1D218CE21931C844158BA2018A393416A86 F976D3ACD856CD19A515BED3064BA8187484FD96AAF8EC01EBC403429F54DA01 E2EB6615E2C3D6698C1656984DA00263F9FB6D04779F9E334D4068081DCD6F1C 2845F973870CBC0452F6F0FE8692660DDC536B1A6CFBD3FF85F3A19ABCD1A44D 0B881A7F8CE68790E02AC4F0CFC492A8960F5DC092924B8AACE3E3627B9ED351 776A911DBB57D9D3424A07FAD93F1C02B136F0D3165ACAD0463DFA42D0FC9934 B61D2EB3BCFFBC0886A20B66AC3A89F91767DC7A412707B39C1C2FBC2084473D 60EC9588778D953A9E303E5FC195A7B76B30136BD0F36832E00CD8DE86610387 7459547E6AD9B24A0A08AA00186A7C0EFAAA4C85A41C27BDEEA7A48CACB4AC69 B3DE5D2554E7251BE2E085671644E889CB71E6849219F0DF24E568936163FD3F AFD44CD3CA9EA87E82CCF7DA3EF54594BCD74EBFF85D77D8B5414924DB2A1ACF FFEB527E7F78230449F7A595641BDD5B11833E4AE962A37434900064D09D467A 76FDA7D6BC309B31FB82B98B6813E529989F51B10F0445DCD34B0CA75A0AAC87 06E18BD37D29A3BCFCE569501D25E2B0D92569F49B88B2873C258706DAA88D04 78691AB71135ECD7851035CE5B4AD933DF5B214BB42B6DD39C20CE46CC10CA46 392D9310AC486AD94A9B7A7F52C29F61FF7805D8E62BA2233AACF09C0ED35A7C 50E3B33C9637D0A719670B422DF1DF792DBDE7AFF3000A002ACE02FFAB67E3CF 8D91021366A8A106ABFAB960C63167197E6F2AB74B2502B9C5E232CB4CF649C3 503F0C374CA87018A4950D52B8AD2F3D71789891DCC6FA33688B8A07A856417C 03535C3E4A421B5939463E7D4552773B8D7A24AB2C778D3D081A6B71F0EC6C70 372B72CF35172BB0B73EACFE68C1D545C7FF123FE5CEF55FF6871A0B67645FBF D305605B527ABF1AA7398D6AF07A3F58F5224574AB5F54BA9DF319F330C44F61 2C414D052E3F457674DDC7816FE0B1B9D76AC28A113EB472EC3A78982E582ABA 0DFAAA624A1371FF60479439BD97691EB2E596A8259F217D019E9F254AAFA23B AD7AB6B4870EA5D2C125B94E589B8666559F466E3941757E98B199BD156464C0 EEEA2A6C37538AE31B6AA25AC885C2330D0238E6CE245099A7E827C301EA631F 6E50BD6814E7C6BF4438FD851F400B499E55A6749192A6F0F2DBD54846573CFB 43CFEB5CD2B8B11EF62CDA62E8BF15A2B75F595BB8A199FC5A8153006042E525 32B2ACB83E6CE7C881CE711600F5E7809F20DC91F4F64FD697DF34DF0A02223B B64A0EA942EE4C01F48BB013522D7BF9EB2541F38ED4E2751ECCD9BAD04404D3 BF5724E909FF5EEB4E8ACE6F289F8F7EF560AD4EB8C79F3FF3AC9EAB595C5B20 BD753EDC62D4B534249B0DCDB77ABB407AB443420CA2A321B25AD1B100C50D33 3CA149724E226736526F5680F6A3D12CFE2F6D1B7942425AF95652CF8B3D78CF 8DA7701988E9FFA82E1EF5332C616239F132D3C21252001FB9FF6C56D848F46B E636DBC6AABB15EEC63300146F9D80E0B68388A07ACF97F2903ED99ABF3605E9 AFFFFB67AA21384C28631A43B722839B5D76C73AB1DE073A7690664EFF3E6818 2DCEA45E5DA99A80103510AD9197EDEF3865B7E7C25EDC118B50C1A0C60F7542 550BB439428900CC0332C97DEDD16B2F1FF4C1A90D72D4690FFC5E5F4D6C84EC 5E8081AAA523C72A61FCE14C74CD9697E2222CCFE870BD94DD0D1B0A815AC4A0 17F219834F3F0FE9A9BEA496952F15F153F1CA2F3C8E53D59DC7AA0480A5EC43 518099B902384C1A6123A48DB6D0C11D79EB1292E6BD02BB5C388195E807960A 63D102A96BF01EC16734B024B27788732F4B7653E2E8F9681EA54B4DAD7F9254 509F4E24BF3365E37CEF185F3D60D8C553C6ADDE0A293F6C4CA8C097227E9054 1B137C4E37043E043A79D6658B2B34061532308D247251810D72243D6D4D33EA 5CCA69907F926CDE98B20131EFEDCCDE81D66ACE43F49C2C0097DD7A352CDBB5 BE3810C38A4E3095481BA6D941BE7DBDD2B8F341AACA7B10000A43C3327E0CF3 A8C3EE4B4788D76519FE9BBF8260A33C35BA338890C5E4C89C63ACB9354113DD BAD0D21BA358B1683FBB94B5193FCD802747EEE3C87B92F8CBA53BD663A50DB6 10D50B43CE4CA78F87D3790857344D41E93300F0C37899DE97BBDD742349329C 5915B7A3138B5A39BDFB2EDF7D6ECDCB891695920917664559BD8C8B15B69765 E5B8974BE5945F8A7EC1F7A819068039D2AF282BD49866E12BDD2E8897CFE1D4 D6541E885E6E4AC9477347E3E6D9AFB6B922518CCB33823A798B40B16130735E 62DDADF72D2B035008B9F0EA046A4FC59801746F2CBA1C6F0EBFDC63445CC494 D6189EA6007DBAB994926B1E9E144441169F15B92FB0AE4EFF9A2DB58AEB30B5 BBD8541D72B9E5AF83C883B8C3C15E7A7FBB1855488EB552C072504C0C3E3F02 BDB58C471BA96CC440E8E00F16AAD2FDCA92BC85A23037BD32130470B1F592D0 D2026F6B0ADDEA73EB9B1A539071F4E4932E3671BEBB75FDBA7529663FE1B582 7212B89BC6A7396BEC782E44644C065BA8B56B201ECBB496FF2BF705AEB39F5E 219BD7A400BE3AD46912EA065022CB1620ED582E646B346E4D93FE54694EEB72 F6B3A2CDB7B335923ADF5122E22208EDB01BE4ED9A94573C73377C1A578CFFBE 68A01D019F26CA2A02DD73B7C5CA83BABE929E7A038B5D69BCDD7F9A183F82EB 2FA5E5B55D7DBA6582F021A9BF480BF2E8F003288281598382DBDFDB229F2428 48E744755961AC3BBB67F92B2BC1FA7D1536894DBD4662F4E08AECF14F6E981D 851B9888E6847DF5300EF748AEAC673B9A3CC07CEA9151BB3A8129D487928CB9 D8B0F3F63E76BE9897BFB022CD9C811A872D7B4394A7B5D6B23DA6BA827E4251 811A05E1D8104389E300E2278ADB4CCC799E0AD5EDE46024816DAE80E8BE033C 952B4BB09194B67EAF2336D298BE8174F02B15A90D1197D498923EEE9B65CBB3 1BA73E02A791232BA1CD623C98BEACE6088B486B5D1ABD5B704D8E9127D2B903 ACED2EE5158708D8CB96B1BFD6C4A6E116CC3A84F082670BBDD64001E690D169 6A82F4A3D14425CA53838B389D724C387DDF0BC7CA637532723BE86F7830E294 E6EB4158A7D556B9B2BA420C167E55841BCDA6376612AFCC83A50435391E3B9D 74A4BEAC791DCA3A3A71F23B66DFBA896D56069D208092E61063E6322A4D949D 9EFB29812B760381442B139EE14EFA784879FE1B12100F6A9DC3496A2911A198 0624EFF10EBBCCBC3568C01235C955CC16B822265607B4157CC39D699789AB06 50C31622A78056AD4D882347C5FC24706BA9FEDAD5F961651F372B94DAA5F6ED FFDA483F550637240FC107EC2418BF6E987CC8E8A35C49A2A277739CDEA1E8AF C96EC0EFFABB8FD9BFA72F0C9522F4693473FD74B85E06422471F9131CC3FB6C 53083885B278A03A77DB03287FED8AE46D9B3C890D2C390611006F4F2EBB98A5 4FEB210DAD585BA67413775D05A7BABDA7CD0C07D0B63DFEBA61715B43EFD6DE 163957750EED27B00B30FA031D6C6553AB83E3055471EF45B0E5115B3435AB96 C4658F475F9B09BB6A28C3D1DF5B423FD4D46D84223228549624AAFC82072894 78FCACC7201F3FF38C8006A592580131C102F212E5564446C0A81E46750709DA B7CEAD73FFFA799F55083596A3EC9F292FAF0C795FD36F21553308BAABE05DEE 6CE690AAEAE399B5637355A734651F69E8ECB9A3BA4E3B03CE06E34DE0803FAA 3DEB5AB57C791E196FAD6E5473CFBAC5735B22CA15E9C213EB0B08BA9EB17229 5D6E4BA08233EF8D7BEC8B2C3F2EFE1AE2ABB3850063E4DFDA2CBF946CCD9482 53DA4915FE35C62BE103FFB7F99BEDCB900B94A1D5BD84BB455EED3B4569E129 1096943ED3D80AABB7FFFAE859643EC4FD7373F283014E7C0287FBCB8FE0E68D 1E653A691244295F26A3C516DE9E343F33AB5F2D263DCEA30ED969517FCE5A00 7DC2478D5C6C9994A65784D786A6632C30029C317F6EE8F1AEB90500475C00C5 5D1BBCFEF125A3FAC8D6B9619242877659576F30911626D014ECB4081A235E6C 80195586EC40055197E775F8A697D4F3FE7EADBD34FF57EA62117C33CC900E0D 9C5F804EACB624DCA350EAC6BDC84191071628F7165973B5BCEC0ACB33CF858C 147849512AEEAC7C97779BE0053715E9969033AED800BB8980B6D858D72D2EC7 637E75F037C986D7DDF16A030FC86694531FEB83BAFC2F6B90CC75E064B779F8 122451E92585FE110B6A7C206EF6A14B6FDB9C91F942A413A39EDE5F8FBE951F 652B673614A79D1D916AE30F7D1A14407C177F1D83E5F6D0E8D3E3A412A54661 DE2A343AA93BBD16A3F899152F48B7A1A681DCB4A11607D209375B0DDF1702EB DADCE3C1BB16E804B0ED3A2614001179E518B4AFCCE8B96E3CC8B1A9128D305E F68C1904728974B3629977984700935156B0F2DB01FD068F8DC7C86B885BAB7D 28EB4BC762AFAFBF84372108DE7E17648FA5FBD48ADA15E93D6A5F2F432FC875 9C64BA2C4290C6FAE1E68C15F1A5DE57D5AC37973D5BDBC866D19C2CA36DEB36 611DAC3EF92E2D6D5CB8C0865EBCA972E997A4AD635BEC1E9601087C6E1B7918 7DD2D91288A356F84FA663FF6C86BC16026703FD96A192DA954841B58D9B5910 4420E60C483B1C9335C5D015F890F4B6ADCD60EB8C4F7D6DB20AE7F056978A08 7F7B33AD9787BCD18D892A192C0DA405FD5CE15A46D746C047D10FCD4078917A CE341933B41B83FF35823552F1195A11F988F6410C8B3ADC9FAE9CBBA98F0776 FB1F4AFD67AD06D78E9DC8EB8D6B671A59188A4177B078745172319DD854434F AEDFDB3FC0CB6CA9E285F3EFB32F07B3644D4630596133B9AE7F4C229540883E 73695A5170574A8BEDB54CE2010E3AE4164B13807743585DF3250CED191F698C E54E67E14C2AC63FB2BCC046072250E4A35BDDA3EE09C8B9396F2EB58213D728 CF52466E4162C82B841958A789E900C34572C75E3DFA749DA338B4522A8310DE 949F684937B81DCFB5914093E3E0BA66C9EFDABD430C9D28AD4676F79A7D72B4 8D7DA62473C4845367EA5D8D2D6227D15DE9ABCEA8959951E2B036DF75F9E61E 32B5D33A0E7026136EFE5EE5E34CF28BC6CCFF75EDBA80EC938E6A7B8AC4DA0A D23239091EB21BE65E5B3E9C66DC2D3690161866FB2889BD1F320B4D23270CC9 AF5E69D2D4B7AE7BA60D67870940CB9C7830471D09AF691DBEFD649B8AB3E8CA 33A8ABBCB86AC86B8AD898EAE7455CEE6C691DF608E24D684ADA0AADDB74EF3A E66C84BD334B499AC7B9843517BC3F84E7736B26106B913DCA7B82C16CCD291C 6CBED63AEA2005249CFC36860D7D4A07CA2F6C374A02F207CC2AE16B6A8841D7 832BBFA3B36A038CBD63F24E8D6FC0CEC3FA0661AC4AC5FD623A0FC9083AD120 070CDA65D491F02B0359AE702FD26B163B70DFA08D1B0DF3A07543F3AD476DBD 136A5625EBBA2415F779B2ABC8E729C5003D5FBB0E026928AE10FFBC850276EE A13953AFFDE8915F67EA3B2543A2C648CBFDED6849AA536EFA762C035660F38C 53D7510B0CA61E806B5D9BF307B516F249144805F2D33818F4156948116413CC 60BF7939E339FD0209FF35A42AC6BB65422F58594594232EC3DA79C65A0535E8 25F7022C27A22CC1241CC84534088D985EE11F0711DC910BC8E4AAA0DAFD413A 2E2C53BA021DC4CD5088B48A5BD4E372423B64AA01EDC8D122A77CA5E818327E 4865125CF5913593B687DCB0C3FE38D6361E3862C8B09FF80FF21EC260E4D6E8 0EBEAD538C98972CE54B58BCC29B955352DF3AC17789E62A6BCB770D4BA80746 A30C0E808D24851F7A655BBACC711743C2E15A55648964ABA1ADF00C519A7263 4C90B186246B80DE5BBEF8B1F004171667288E17F2E26CE4E8AF2B5FB3407F6B D3A023296B8FB928EE258BBCFE65308D4D47F7ADFCCE5EDE389FAEBC04CD321C 36DB9EB3AD939A0BC0F11DC57F2259E4E87FF8856D309621010A69D3538015A3 8BA931F733EED47D1A74AB01C2C929D4DEDDC30CA22B843F057F6D1CD6CF56A2 02530FFCF9F01DC83A82DA5B1A9A2C45C63002AF50EC52C66C960801BF54D10C 4AC2E1823AFA409FABC553A8BC86B858D505470861B426DA03C125510320848A 9BE5F178FB4058165DE2C7C1A82A0A7088391A77469DEFB18EC039B878790FBC A0F8413A4DB7D5278DC5A90475D3CBC81627EFD8A7CB32BBCEC1BA57802F490B 8AA49343279702CCD894345327245524209F9CD9ABFA714C8A5912935964FAE3 05AE9979F25A103090F5EE6BF76739845AA66B85A60AAA67625539738BACA4A3 1DEEB4636F8D308D335C089C9543DD8A44F4456406616578BAB23650792B3F26 1BA738A24E30D0C23FFF2529FD4D8FA9512CEF2307E2EC6C2CB918BD2D387CE4 6A20E6A58230656333073F69EF21E2FB22CF8681B10AF453592C84E523E23D14 0D9A70E0EB59876105C5A3019C4A29715FE177D5A61D3F16164420F6525A0DF4 F6E05E65CAF83CD3DEFA5B9DB85090029F6A3A3A769AC726DEDE1073CC8E9291 6140E6C67BC2BA41502A0AE331D80C39A04A4BF4B01CD6E2112AB7B7E189E0B3 A8D49AEDB47270D11417A239C6FF172DA9FFFA87BD71AD28DD7FBD4CA91A11B6 E6504D14C162A6640919707591097E124ACD7FB2F4BFE26A60820152D4A8F0E4 3C3D869272AFFBE4EBA4BB6820221EB223596EAD84F4C9ADBDCCADFBBA1E00AF E84806DF04A891D193FE4B02A10E5EEC43B7024D2F8F7ECCAB4B446655A33995 18CFF3F91BC4FDF044B76E7BF412905142438AF17735EFF8E7695D48356B1F75 48A398A26F3F7C68D0142F5B191FAFB3FE0074272363D024E842BD155F1DDBE9 CF1B49F2D19DF02C7563E654B0E6DD70DC69BCB650A1D9C2189091338FFFA99F 4537B849CA254C645763B0020E104AD11570E02CB6482E996122E38BAC030587 D4AD7E345F1E2CD1E0EEFF7F1C2C64297E41E836C329A2C389BE2F4028D6F89F F58F3D35C3857BB2720C9F777E0DFA2BFC65443465056BEF812807E4F704C943 E368315A8CD8E444BFCBC2C0DBCBAAA818E7024E8AC4AC3F07D7AA5DA32C9649 BE3AD6001DE0FE4D01E0E38630EC882100422A2EA409ECEBF02992A9586C6114 A3BF8A1FE9CE0535CFD5ADCEFEC76DE2104DFE310BE2717F00B13601B0FE804C B7650B5CFED2F84733D2C1535E421D61523BE2943E8D715616B98981E5B39BDF 029B760BBB3659A73B7B0BA0F1367B4BEFB8CFBBBA664858A06668508ED9045D 4C751B6B7DCAF4B2D81865038163916216E4493DF67EE280BA53DE6C8BE0D5FF 7D928A931161E94AAA63009D62C0D4C29F690E107A3D3B5E634643B847CD45D0 0201F40420327D7CC400CD86DE07056E0F5E789061AFCB0A6ECA60DF5B46D966 94EB96EE33290C77CB26900273FBCCB54083B319FEFF100930CE877D9936742B D9E39BE261CAD7DFDE4733D138D28E6081D3E9616E0B5F9F78FBAB40A7FE1DB8 012736EDCEFE5413C6B1B66C8C93CE84C0CFACD8B7C1A5BC4543C3D2D845B62C 72EAACD361D49664D5EAC19EBDE13717940838D2498D0FFBE2CBA2788AEB4F7D A1965F7FA6ACFC74A936BEB3433BA1671575A56BFE091483367F67E2B61806EF 94A652BD65E3A1901F12D070087E6EEFBAB9A22BF751169E3437DFB4537D399C A065E8E3EB771DE873F76FBC00B6102DB79E01671332EDD8AA2108732F380F2B 6912AC38B19384F7891FABD179BB3096552670CA3A1CBB59B37EBB9CCCDE223F DE395AEB94A2CF3FBAB617EC4710E8F56ABB0B3717CA7E8748108A2A560C6A29 FB490B60745C4F3288337966243564685B888F15B3ED1FEEE6AF8B1C066C35AF 9D57AFE562645E1C2CF91A977235C663574BB1800533BD18B3C560D06C25DA23 73FED151B64958E226CB82784F2509859ED52F17DE8E7A469568A0C8F7230B17 E71DE33521B2587B6F0CCE89A8AB5A218A9E13F427546E3DB603EA59AD7605B3 84AD9832D614DE691B7F1CE3919A6ED813DC1CDA1E258F577A9CA78E69104887 0495832A407E86FD8F55D86B22F05F91B1508A61267963DA8FDE00DF28882AC3 8C3C8EDB42A81AFBBC893DF7A6241B0104633A90C549474785C25FC9401357E4 77FA5999DE37BBA1ADEA22E7CD971AD528B7222F068C54FFB38B80DDDD5C87EB 2C2D96D728E44F666EAC9332475961FCDC89281B5685B7545CC226F29CC131F1 3CEBD2A4D4533274CCC62D75D9BE22E55CE7C3DEB1845D0978BA34451FB4B43E 06505280F86E106A40019DAB5595606FD53E046EFC5B99DACC05C8F49AC98E49 F48AAC60901DC76AD5505FEE14EEE21FFA38463069C9CCF233E99597EFA2F383 3C49BCA62DDD3C5A6773B88C72B0CAFA629E03018AA46DD5193DBC0FE6CB841C 276BC475690970D319B0554B354A4FC3234164D8667B5C7A4E96D8C70C4DAFC0 91EEA2C85C0C38BC37BB420198224D8F14E8B11BA4884B5709FE907B4E778D7A 4DC14779A0C74BFC05128C66C62A62C73D3F3C4D3ED369079958E1E25A07221B 4EE6FE54F9267655272F4F742B9BC75FA8A275568D6FA3FBF20D4FB41277D8D9 DB485AD55B51659910437EBDCD3D9FE928C48D7120BD6B19EB3D8F2919DD21F5 EE892FFC4B31D01B4A37CEEBF9AF417FB9F01DAF87BCB40EF087F3ABF9261DB5 CBC9571A59B5D3F4ABF6DF321B65B70DD210D42A66771DBE9CBBB175A75975CA E3EF2D447A2D86E705B0FB5E2F97F180030CBF6BDF77DE54A88AE7225B7C147C E46A698EE30CFF2FA0B7E6930BA9764F2E16F23973384708B823F049A0A64A50 88E9460D57359F11C77E5D5C92ECFADD4A016EAAD5DAAA71D52EA977C2280B90 058E1380A9AB143C4949A99EC3F45B587EEBD19EAE9FF862E34EC7B272241C01 0D279A0E2B1E4CC93974071A7C240151EB6E87784591EF409DA610E5E9BDF9A0 980BFA7F848AE8823A8416AEE4CC3B932D7C1141D8679562C34F120AA20B711A AE0BD7EA8BB53C448D80DD391446322C30AFC3AFE080B6CECC3A5DC230875B0B 34520A5F76138122B40C07CC1B4F8D1EDBF03CB17CE585D4403A1168214BDC95 1331424FF9FCCDC249D932667FA03A9D6D721905CCBAF90830946429D79768C7 D5F46E3BB448BBB805FAF1EA86C722680CE0C244C02C03B093F188A96CDFDC8D 95B3FA74C768F499FC80EFE4B2D20C85C52E00EA6083E3B0D2362FF449B68CE2 632849483B1F4919289E1454569183D2A1BF27299CF8A877FDB64A77F031FA56 C98FE24EB97396F1128BB1C61EC46D9FF611EFFBA38829A2126DC46EA26D6005 42DC40EE170FDE289D100C799D957F2F2336D2DC864AC5EEC47AF18A906010A6 C7E55205415960B09292DB38F38E4AFA8BF87FAA49A1ECDFD577ED02242CB4C2 D769A28270B510B84EE83CB5616C5DDD6C24E3EBBC6077C9E5103CE4E2CCE244 3BD308F5827D142E632ADDF5E16F900120FCE4F028360D6CBEA0EA8715C3F521 6790338EB539AF2BEFEBD9DD07A74D47302202EB142C324420437F8CEEA3B738 A51037E9550C01970C29E24A029994 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusRomNo9L-ReguItal %!PS-AdobeFont-1.0: NimbusRomNo9L-ReguItal 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Roman No9 L Regular Italic) readonly def /FamilyName (Nimbus Roman No9 L) readonly def /Weight (Regular) readonly def /ItalicAngle -15.5 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusRomNo9L-ReguItal def /PaintType 0 def /WMode 0 def /FontBBox {-169 -270 1010 924} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8E134D4CB5ABCED39AC635 DA001E9934C198A7F9B9ED0028A85E9AE00421DFD8EAA3BB3B4B4CE45D209303 237BD51809FE4D880900B1EEB236ACA87B9FF6EBE6B994A60AF5D67CCC42BD56 77295C346EB4C62BDC1EF22EE07DAAD928DFB73455F091F32408ED6430B97417 683AF27A03718A156E3F6E7B6E4F2E8177503CD82DDBF4557A3CCFF4C858AE7A F7EFED6CC521A28342436B953E4650B5792BE85EA2F989EB6D986905A61FA38B 96E1BBC830B74469150FB0B598A794FD80D10870084A877273A9502C3456E5EF 74350E6E3BE5863E8BA185EB59FB87B36566AF71200B6ED389D1287D4E925E33 B2383ED05D87D48586E698FBC5D562ED9D8A09EC3EAA1B1F300224AF20C23F26 A2EADC74562571DA84B3914D1D80B127C6FF4706C7046BBB372A0013E0AB94F0 C27946583871D272BF4F20FA84E89D745DE7BBA885CC09BA72E0F530ED4EF7D1 864B3C67007ED98800284235372F0A70C912E21E851AFBF812165B8DF912CD1A 013E271F0B347967876C68AE4C4107EF8AD1F170916210034C66394A9D971B68 FBFC1131E37FC178EB97C1B2A0F573ADD9D7C0BF944E6529734DF8A7EF54485B A3375CC30E9E328943733CBD352BC15B06C85BFB4A96994291C72A0EAE84FB01 0F1B24D0125FB8C16D60561DF8BB7AA7DDFE9549AFB70C1E89424214609FDE41 9A142892E30F02754FD234CEB3C59A2A04C06BAB7AE40E8FDEC50559B8347684 391C750987802D5452C47C1E0B5F222DE9A0EEAFEE19D796FF375A1E1EF0AEED 1BCAC4F485FCAEE18AEC585D1A9D80F41871DDA45FEF1EAE82C5893118987BEB 4D9E345C27C7419FE65E4853B40537D822E34FF1E0BD2819D21EF607981259E8 9F1040A2D708D7463858AA5381759AC49DF4DDDEB209A278FE60BD2508ACA0F4 6A249A05B652E4C7BF1B676943CDC463BC49115864B5B5A6569C59D057CF2A8C FD282B79BC3FA1308A61476AFF58D91BFD63D1BABC326C4FB78A42CA08478425 E8038116DCD68406DCCA2F5A85858019428DC1DA7A7F42131319C2B08B6B93C3 64413BF65B6D8554C69AF4C1D98BA42AA91660B2AE57BAD964F6AE9BD13DC93F 44DC05BF90F7E1C05C954ACAC42A93DCAB215675B1C7894E2A0D724B606E9DA8 F016953104BF247B66A7BB05C64AD7636D951338BD379956280919E1F6CCAE67 34BEAB789A232E1082DEA0383E98A6F55D8C71CEA9D1554E7A796586577CFA8E 0A1567CA0F3C0A445EC1752A47E705F4EEA6268E2323E3C3369D97355E3B32C3 3CCB9F39E828B8B8317E4E50F94EFED6873046F14E850D30BCFD2B6A49A29126 CABDEB8551410ABFC1BAD9D79E03CAE74D67249247577F67F6E02B76C71D6809 A3ADEC3800693DF0FC7EFEBB1BFA166A088B8F232012896F122727523E1AD51E E1D8B35EC2E6B2BB0314FD0E2835FB97FF4BC59F9E64756B4B5F2119B20D5BCF AB27289A93B316981EAC33605FFF98C7D011DAF6ED1AE0ECE6A43A7A29E27903 3C4AAC3E18B02E195E87257DEB8A1F6489CA0115898F910F38FD25CE03F740C9 69FCD8FC6085A66D841ADED0348EF0A843D0F05CE3F579148DC11183ADE03A18 83B216F1DA8BD7F20B32D5A200D311AD5B70D8D7A6DF940E23FDF870E2858CDB C2A33039814B0C5363F0ADB027A201E35FB4C9C631CF85C30F422B9F568B9ED2 25D9D69B6581864E351CA800EF635224885516C2A291A8A4132F4D2503B8C48A 50FA52CA3C85E11C1DC9E4C2143267370E240E581EEEDD6C8F062E85A8523B5B 3511CB2A4472AD2F31CC926B1958BEAB365EBCFD4E115498E2DC2DF2B4188BB2 9A5658D4C194A0990EBA589A7478D96BF1C37B5E81CC928D77CA54740EEA5E26 E4651F258EAE949DFF86E8DB2DF54D851AA72052511AF53DAF63F92AFED25998 FA67CBDFFD53A6555556089ADAB4DAF9B826BC53D97B40BBC552DE312337BE64 2A4FE8EDB821A8890E798B779352BF6848399710E25E104FDEDDCDB96DAAF34E 4E28E12C1F5928573B5E896EDA20A07AE6DDE6A36925BF28F77EF5B1E1D63D50 84032D2791A7306FC46D0D85E85E3E1A4348B76A2C31464B1A1C2079DDFB5552 4A28D6A826D6A9A1D45D110BF4173BE2C934C892C84B3E7A868AF976A2BE72F6 3AB655ED639EDA5CDC9D6A92E4F621DD8D2A012DDAF61C232D074BF3BE08E129 244B19C42AC80035D6B0129745977065D16F01B343AB4347CF24113CB5F145D0 1D5669473E51EC2560FE7FCDB9B6D54476BFDFB2CCE4DC60424C76B6ED7D29EE 971C8624BD5A520AFB638BC3AB6509A977F098D2629B31201AC008AEA293D484 ABA495E1F51CB28A0C152EFFF2ED47D1810FDF108F20CC8C5DE8E72E7119EC4D 76D140E55D74201DD6A979C8BFABDDE279883CA2050B29932B9E68DEA83C3C4D 4D984326353072AE1ED9DDB08D73402CCB57F9E6F6AF13FB7261A0519295C8BD 48B7C694FD40F4FE0BBA82223313143111682831293C15178311FA4DC6B27A1A 5982211AAABBA90479824AE8941E924052C7D8502433ABC88926561D2E9C6A13 4689AC7172329F0BC20768A0635F43165D9DC390DEB3D46DE19C8FA3CE5B7D42 CCCB7A2DBD5BD92951D2646362F8D3B0A35E680C77160143EFC9D437D8314814 14FB95562259F40C2B9B9672EF624F471E841737BA09E5A57115CB7F137B7563 558D914BA2F05A23C50BAE3496E16296AB41489C6AE179DA4DD6F38FBB31369D B6EC09B9F2DBF95727D3F918BF76C0678BA0F99C075906A629E464C2AD42C5E7 33B7DA4AFFEB7FF4ECC8F4A346093002FBE7BE949439027BA84718FE4CCB36A7 FFB12F2C8EA319309708F0B3785F24917C5A99F4A3267710395969C1005B864A D5B7AB8DB5CF68910B2B13F86B20AA32FF16CBBA24591A36AE569C9B2376E263 F8E151753FE788764702103ACFC4D72880B5A5E1FE286EB9298471822FB70107 9E6AC0236500EE00260B500D14DCBF1EB1C95BBFFA540EE5710E884911F452C3 39E3FF455F34F89764223F7DC55BA669B8793F48CA8E9AAD13D61857519977DD 5BBD317B3402D11CD481B9C1C1461479D489B8F6CEABBD6962F9D2DA9E68A450 215028FCC896C4BBE6E0A7D10C0337BBFF636A3D34662AB1A2FECFD8B025C2CD 224195F91A18B8B8E0339E0ECFF4E95A64E1AF8D8885891E6C7ACA5E857BB86E 9E568CBA2EA4399DABA9599D2FF00CFEB5310A2B4958823C2E721E0DB97368BE 9BFB6005AC0A20E4A412D097D66BC3B35A05F4FBF9DCCA6B64EF42A2958CFEEB 4A91870F1CAF2D199FB9CEC382CA26548C24AD096915A7389F154DA22674E67E C8D1E01A62333164FAE75BF1D24FD29F46B77B8F6DCD110E893B0FDFD1B98D9C D06FD4C53BA603E3D84479E2D1CBECB8CB569B56B4A68DC5FA8B547F79F05DAD 44BE2C9CBEAE9F08701B4BFB04882B144CE287917256F3EE3E3CEFAEA6504AB5 9C090A7E6B936A1FD433B259E18CAFA2683B06B0C5B25DE38089E3CC843CE0CE DA9421AB550DB7F147B729C5964BEA151336168F51D9954B822CCEDCF05C67C7 D32C5E45E5D0CD32FD2ED126F6D23805CB9620828E487F66DCADDD0BC42B683B 5A663AE434FB32A00B2A97ED67346257B0F0E9B794586A9CD11CAC7C13E4FCE5 AB9393B051A76DA5C916E393DAEB1BD37C004E3626477E63CCAF4B15FE1D1358 01390BB7815F1C30DCD49C6560688B9D1AACB2ABDE7D53D7BF4302060F88E5B8 35A2C2A6B5F891E5E7770F4EB66F8D8A77B39CD15EF9236CD6469C9835616A83 91563DA191F3E27C9EEDBBA328ED5FC1C01B2514001202E84ABC526C5F3169F7 2484B53509736B02887C831985FD743BE535BD110302131C9DAB191FED4037C4 FCB0803869718BD527D782098E0174672BEA355C2273FC98BE95AF020AAE36B5 7C5244013011F7709271E26B5C3E7CAED86C85B5E190C5C8294E49F4B99D4FCC 569F78BD73D380C572E5087A5556397E485D176360C70A54DDFCF2DB6271406D DCFAFAD927AB0EE1D0349033D576AB2D8915340AE364B05486B6A112B3098A5D BDBDB15EB8EAD5E65C190E8DF3952352E1CC0E58454613A930D0C33371CA0771 78173DFE2AB48F0B6A204DF1BF22A1A88659364A6E1AFF36D5F090E60A1E7065 F1168D56A02E543C2F0F0B0FB7F4A285214DBBCBD19618AA81C5DDB7D589B843 320C4F7FC5ED74C375E94631406B963B85BB230DFEB984E46A35AB362D65C77F 144AB527A857BE897B97B6F8C156B3CF698C80ED4E37697A08083CE756F748E9 A5E7CC1F474B29BFD407DD1D67EFA7EBCCBEF0D084FEC346E548BF81A58F0699 05C6077787722AF91909CFE492A8F04196514FF36285FFDDB9EDF03CE8A55034 1863F652D7132FD0789D1568EE7AD5F4796856890E1F6D98298B3F8F9A54BF8C 9F4BD6C50BB626F47155F5DC30A2961663C6A1959C28F67F64AA534A2AF512C1 F2BC5BEE9F21801514B5639CC4A9200AC342D2CD79E14C39DA6BE2D421829415 6CD7903C1C42E115E9C5203037C808BD295191A13E7E710108A7D53A4021CFFA 25B6D7FBB581F15A4090C99D86095BE64A36FA8733362A8D4A22738795376ABD 3D815E7369EBCB3C06B404819E48BF00F1A053FD2B4117D6C8BD31464EC731C9 2266A97DC3A56893D282665B4A9A9E06210DC568582584C21E0F14BF83FB844F 62D48618611F1FAE737BD2925C54BCD4A8BC5E3024F6F57B13A373A9E056241D 2E1B6F06A53C10DE7D78BD53B6100A15BA246767715C55F5EF74DC514FD192BC BF2E50E9F34B9325926CE9FE0129A6E2AA2B10862DC81816A84B5A0E61B4A9E4 D186EAFF8C66B2ED68FD17FDFEA03D4E0C9321AE22E720CC131F067BE82B7A77 48348387F888B5F6C016AA5A725C016187FBAB148AA2436D4AC8CFD3BEBB28DF FCF9EA12E640C17180DDE8F6871DA0C352A187EE47DFD6EE7925AC3E65418DB2 9D111F34568A63CF15CF82E391118667B4B564168A233A3383B490E30CB1712F 69A8CFDE8C8118C8DCCA925EE70CEC5EB14309A7F89713517058816E0BFD46E3 DCC397D3C25185376725F2251B04C3F39F94338ACE2FC6DACCDE2FFE2D0E7EC4 03FE3558E431CB20A2EA4BD5D79CF87BF6B5DA64D15164FEE55A96EEC5148593 5FD3FA9DEB375F42C96269169A35F545E430C697DF01C1F094DECCDD9F43AAB8 8640D0E9347A6382A49CB88706982B6687B8E51E12F0AD378B858C3FE410DDF4 CC88CFB52D075E2DD5A9A5121F9FD0A104652022022F51EF63B2D374A4906DCB 43730DB05E1A3C7203EDE66E6557E7BDBDBF3332E19DBF11EB708A15247FADD3 10C58FC911D294EE7E91E86684176105AB4F96BFAA2C8A8C89D44EAEA1A45BB6 EC900FE3F13778462E0B1CFF4690692DDBE68A92CAFAA72A6E48F0E31D8D407B F78624E191DBC2C225A3D3AF1E9F3D5D551C1BDE7D5E9A26CC8D7CCE79CA02A2 23ACAFC3D6000E2F1A2F16C98F3F6F29CB97659382B803AFED668E1A6ABEEB38 9E2DF0DF373FE5AD1F7D9D6AEAE9DA0EB2D0645E92A9B2106C8A8F1512C407DE 6B0BD906D936C579733D7270243C367AFBB76001E331C66FF748308BAE99AE06 106D90DE65FFC15685F8CF64A9C1CCBF297B75E73D446B75AE88E8F8F6783823 A960173E97FD27ED414AA9861BFED00D15B184B024738B7B93D0E73F8A48963C 704551FE062BF32A45C9103D25178B8623CF09A04FE9B3C0969AEDFD204E6C2F 8F599D48A7CF5253E65B70D4FD7F1C3871FC762BA667678CAB1DB0AFDCB4266A 94B9A48DA7DAF0561E56D09FA49FF5BD0A9CCF307F66A9E7CCDD17602B9DDA97 2CF72053ED0681C54829597F761909AAF09F2E35801FD76EB4956C28D804A74E 50AA5AE3CDB978DDBFA299B6FA47CC6B8539A81F67759C99AF012B908AACA1EE CAE6AF53B39E873407D8ECC2D0DB420BEEE48FA26E7F89CB3E76B883582FD986 BC2D96E6BD4E15F520450DD45CD828091AFFC55F6E3EA449BB6CA0AF8A510C59 E9B3594E689E73AFAA94F4E4BC090FF7203B6104C6EEBBD73068DE12D99D877A 7D066C777003B3BE938552007277960F522846300E8E87817070C74704415FB2 EE425A8DE4DF54D9F7801BCD203929C560C9077487939113249A93206D26343D 2AC31FE8B4774C284634F6C5848991DF7EA786A0596EA4DC7695CA533A0D3EF8 C8A2ED8D824612697BFE92941B44F2F70207F7B9817C88AA1294E63927F4DF7D 46D0971CC6FF84A1022E7551B91C07B4CA672C8A76BD7CAD08FE3944B94E4123 F330E87EE1DF050E94B96E0E04583E1121EAB25C87FAFE044CE17F72625960EF 2FA838FD99F3B8D0E180C8257A3ACC11A9F969BA8DD19019C07E9AAA8A9485DF 546FBC914A6FF849A8C8ABB60FAF8B43F94093DADB321A8012DE4D70018997A4 1EA3EE33ED47F4800D63FA9D0741AF0FF63C73BA0026FB8C07C924BEC0F27A24 C655404E9132A180D9EB0F44FA864C672D1D055CDB9AA959E2A7E4D1D7987281 3F4804B2950477F7722B9B4B62441A03AD99788F2DC93200C869DDC5AAE04253 AC240F7A64999F24219B76E8C2D9A6DA78FB9237FE0F5DABB6BF0AC69A91F258 E0650F515E9047932A1815954268AB12E0E256FA1A3BD35F4CE9F2E18D9A45A9 73757BC16C3585A3A247EC1FAEFAC35F51CD9CB3A940BC1EB554F85ECDE5A52A 19C3EBFF13D55AE496CA8E5304CD4E7AB11D7D34C8C8EE1CF346EC9872A0DF8D CA866FFE5630F8109E9C4CDAF0060A4AC7BAA99CB88706982B668748F740CC5A 06086C1C6800D1CE621B663082558C6DB0691E736851AEBB3A3A494B408429B6 ACC11FA69DDC5020CC79551F8C09D64FD8C2BA15DC87A026B5E7898A225588DD 66C14E593B7ED0048399746ED9391BD634029BC135C5A03C48D0CA77F48AC057 918A1EC24BA7CCBC49B4FD5BA3773D174DC13DFBEEA6C2575C96D0F45C4AD42F B4BF48183E7F7855E0C91DE7D3053F58B9C17ABE36DEE46699942C47EFBA39B6 DCAA65BBC62A69D1921289AA6808C9491823700E3130F3DF4045C9D8D0D70464 A4FE51A3EC0BCE19D9F8CA7138B538881AEED7EEE8536624CFFCD115DBD4D5A2 BF66A01520B0913BA440F9951AC6A399FB5D05EC0A62C71480A003D5666FEC7E D9E9CF49B37550398E2A60F51FF11037F4A4CD704E8EAFC757116FE3012E01AE BF584B1386D6F9E2676A7EF904B019D3B6AD98F74FD037431CBCF8048578D3C5 BA050BE03BCACE325F78FC232393D8A6A5B2C8336C331F091A85796A09D36E28 3977058032B8A905FABBEC189852EB39E2A25A7366BEC1FBFF16F0E7C18DEB36 BEFE56D8E991F9A84AC8F798008EED3D90C0FED41A102EA32F2ECD51AF4FC9B2 DA0D36D0C95DE0D68348BEFF9046B422EE8DEFEB66CABA6FB3A5511617D2F64E EF3C8B5BEFD9F942BAF7B3FDBF13623A9BC5E3D95C697BC0FB55CD42935F7495 6D7C9B33DFEA7DB0B2C2A71B2C955DEB09DE6CD69EFF58A2B6AD45C7B68BF53B 487900CE67B4FB7AB83E9E9CCDEC204F0346F6751AC2366302A4276ED50E2EA5 2D5BD2F0B2A9394D448E6BED62546F63725FE52CE02CB727B8B6F0158ADF3F1A F361DCC9970506D4A705F28794A01C38370607FA692892C9606BBB3B10F2985E 7FFEA35EF2566F4ACC3D7509167A95A3DEC24255692985D5555339DB6A4030CB FBDC44B3DAC100BF755A6E2424F9515A8391F042D2C46592CF9C831F7350B592 777B532858D2576083483025EDD19F2252EF370A345F0CFBEFD34D1E00EA2D40 4B41ECB52F3680F7F4ADA8F7DB9DE877BC6F7ADBE007B490F32A22DFCF6ABF27 3DA8A507A47CA5910DC9F1E79E4A8B750A7C0B3985DEC4ED584E2FCF9EC18AF2 E6BD97A7BE39BD9D280441616D979DD0E579887716F94563768083B58BB3131B C68CBAE26C0D2A251A80CD2662D13998A40BC77F52EB86D0880AA072BAF6AFA1 B1020B7336A84688E6029FA2CA010132C8E6978CA6F61365D1AA5BCF22F7E25E A1766B5B2800215616FC958B62CA3AABB13C8EF8EE35119C43CD7FE068E1F016 AADC734D4331754CF132253C51B9E6E27E63511004A58EFD38E70467329F35F4 DAB0438C65E5A1EBF76A46457B72DE6D987A95FC1F275B93C6107A0235BE1A84 845B61318A6B5EF4B50FBDD394C1383345B7B77FE29857333D5E0395B693A361 3C4FF5695EDA0501EF10B4F529FD7FF523C5AA09C5684C9A36F02597981A6F35 B95B2BBFE84844CB13A2F9C1A302C2E6E745A40A8E2C7EF6E362E6A3AFDFDB29 6E7BD01C8626CD726F6028288B8CFB9D59D680099EF8CEB0036F32186AF94831 A8C5FC31C99BB21163E68BDD4B8FE6BF62D669E86BB5B788713FB800179B55ED 87C36251D3F143653D304E42C2035536E8F7DDB680E2ED38F562260792EC1857 4F6E4B7F960B4A8B758544FA345F7E6EB57D05098A5FE552196E0315F306643F 0B743A6867E7C10A7C6B02D2743443CC9A8D466EDF09418B092F9F3F41197F5B 5320DB4E6C7F0CD2E7371CF447A5514ED43B584552F8C3CBA41712B3400CB0CA D145B131BA218DD8FBFDA06EAF929FA58727C484D54FA1913D547F6391DD7D53 DD213C46FFE5B407A8B2BC3DDB9886C41F280544669E9C2CA6447D4605D4E7DF 1B27AA1219ADBE3F9F03D03FB3BFCDF00DC63C94DC21019815DD1C983252E3CF D08F90D318B37206F1D4DCF61C6F87D414EF9C984203D8EFEF43374E288DC93D A75C38A76C2B1F015C7400C5AC4CE9C669856108F8E19EF7608F1C64CF1E6731 90AD0D6AA2E65929B73C90F182B995485CE83DD18FE592999BB3341656791C3D 210024633A4A82BD9287138C90254DD72FA2B950A6C5A6BE16495E83D036F21F D58983504BCC5FB6F94E1041E781800FA951F4CB93EBA873FEEA1662BABB1810 4D2D95881E547A1CE5B5BA62525CC2BB9AB02724484E52781CC0F813B3E7C2CD 6CD6DE9A76273DFD507B0641094FC4E874F5F49501F0AA9662966CA2B53DB31F 0659A977CA2FE119A16AA83EC6DAA18077DED5083960B6025062104B9D3B0649 0D121672BFD1848F08882B4621C9D919BBC0744F9AD653462B57E2736DCADBEE 9CAC7E77D79B2EFB13CC5A7746F0F3238CC1C1CF3FBFF392EF05F098DC7ABF4A FA8323B32617FE55A71730BED2715762D2B8968CDCAD0844036C6DF20AEB4FD4 38D68E9954F52FDA3750A38285A809922ED2DE5D74315D1543E95068F1A003A2 158EF16F7DD73DF94BCDCF2017B97315F040F4D3926484BAF4124ED0482DF362 59E12AE0D2E0BF6B1F2BF09C3A2210D7556A3F0D990504AB48A6C0E12F91A451 09D0EF9BB551C297FDE18B8377198EF19D0A800C8974E38C0F9FE79816B88D87 2A9694387BC6A7A58ADB6893DB7A96133B2E41002B7260CA0650358E5BCD423E 5EF9C3ED577FFA2E54B6B8DD9BA1939D7E997D0D9378BED8584DA8E8168D92A3 EEC37D004E654DF94DFE8ED53930F9966460173E0E631730E7FA761973987D73 AC6025034301FBF1EECBDB9E18BB30F087281DDC5DFB1AC311C765A7E386B4AD 6FF1742408DF23991798020E839E49B4F0D65D541269CD34AB86EF31F3E184F7 D01924B1AB8254134A704AD95D6BF11FF9D621C597D5A5D3BF3363406C943BB8 88DC353014D70921972509FFEC2DFEA930B758336AD62DAA7E253D6D50D8A7B4 53A4A15E8B8137495F25DBBEDCF736BD4B8AC85C7E817DBABA0E78F36954E992 2286067B7592EDDE2F6F2B8DBE85E4FFBD1208E5F29EE4BC9F76D90605D937E1 5529BFC43EA631B1A410AEFEEB515FAC324494896CAB73A2F2ACED52AF9D0667 94BEAF0EB7F5533E39C9823D47156B6B2D1A5498CF12C6BE50F14FFF4452CDFF E48DD5E718E97B1EDBE1ADBC9045F1C245A7EEB0F24FB66D9D364D8179ED0941 E8272CEE410ABF0851182D448224D6F882E4B8EB605255528B539F142567DBAE 8A337E58B4496C07D648D96EB319FD3AC12D9E0514C1F331C13E70B883AB097A F61474C60C7DC37C9BD1232E01AD2E972E4FA0B313994F5F51AFF99301DF539E 238E3059F7C5713A9F09D07F3E71BB0D11742D286485B9E53B9BDEF27BC2D409 DDD214356F2F45DBAEB9560610E8BC8794666459CE09D51544E38F98AAF6C37C B0DBE9499869CEF394B28F615A5F82E9D4AC9B5424312755C4B74383FD094BBB 2486546C037EC5139AE5F97CC27F2840FA366F1E2283CAA01EBF40FA8A4A7B83 20210619F4FA4CB8003758487C80073BBCAA723296E000463F8247E55F8E9CAB 0E678575600689E964FAFD82E425B65D3F8D5CE7C2A9F04C4E8765096A39E621 0AC25E07669C5BB03EFD1554FB810511A1B29222D619822D08CF5ACC9DDC68D8 9F32A2ECD19C4204D8C4369AB7F74A9A68EE853A35D512BF4CEDFAD42C62F53A A09B150479161D8B2F5FDCEA0020FDC7A51CF4442BC91FD47E1BA93B0C8B4BF4 C285A2D8EEC6E2A7B5B023F30BDA21AB8C8AD7F1F7F6455E4CBD4CEED62CF15D C7C36BCE4B2884FDD32972622A6C3147C3A450032AFE582388AEADBEBE941F39 B1C628E350E1C27BAEF83DB400A8340C9DD4C8766AA7A69AA7BC8AB2B8410C01 51D97D9B5F7FA4433AF445B08FAC37BF35DC83130423A84DE82B2C06EE776A4C 64991F18D9D7CF748F5423ADD67C16C224B505F8DCD234C4699BB084F049E32F A65CAA28B66BCCFC7855461372B4CF5400F4B7BCF0DDED0D2E03D0E0001285CC 46471BBEBD35B275F372BDBCD18A5909DF66C49523AB41242F1D916ED69D1B7F B6EDCF35F420175E17CD0741FD87972D92438937409FC21DD268D08DE0F7AFE5 9C922443FC26FF50A7BE430CF349242712010094DC211CB2CB94A27524A4C251 6A81623A6B79EF9890EF9F0C943861FEAA6E2EE8957F58F65494C9749AAFD4DC 3147EC63E3179574E6CCEE1FB1F67732C6A19444CA7C539201BEE064F7B85AA2 C769DA4EDD9F343645CE402700E4F6522AC928BB0867AA56FADF3E62F799A700 42EA7FD8C960D6B0A97BFF954666906CB153A58E3CFC8BCC391A6DB781683EFE E671F35592C3A28E1AFF05FC419AFEDCD976D4E5502D058BC848335E77799398 6DA3B6722B1B8DA03AB7A56C39CDAB0ACE131E97716DBA03B23D85CC8B701EAA 654C5EE74F40D1EC933E91A2E23D6B622779FC97D1C263411D2BB7F9B2928EB3 445FD18FABECF6253EFE917D154A48DB1BB6C9ED5A6F1362150C3524E59B0D53 3D10C6B7123EC9D0708FB42DE1184556CB3E2589878C471619BCE500F78A26A4 E3209CA6A5F41929D75D3B1EFE8A585E075227CFFB329F483B66FD0787D17722 826EC83CC42DC9991C1FBA0AFA48078866C7B64EEF7D730668026C32715F5B8F 87A8AD82DEE1B809035F4D7682D1A0AE125DF60CFF05C7454B82F991CDABFDDB 08E15D53E05E1BA56335E0765768AD37EE4DF66C62208AAFB953188F9C9B88B7 B5A19F8162E5D8454B7A1952F8731AEFEA2FDD6E298D3EF702D657FABE1CB502 F61FDFE9B08B5473DD51A322ADB72FBD8794B3F51A1B1101649E3ABAAE3472D6 E8D9BDCC1CA231B5538BCC09C1D9EE15C26F1F566BFFBE861D48AAC7C0A4EBF7 2DD47741E476DFF314B4595C18B7A24B0BC37E60159314BE576ED9D9502DB63A 323FCBA7403F4768DCBF9F6529F68E8EB6B7592D9A6218EC39A42B6E99271435 CFFEAE4961552034C5E8498A9F760FD6F6D4F4FC37AE95A92C24296144A189FD 645E5961A1A0568872A37ECAEA0C98434FAE39389F689F3A7F02EE5BB80D7C7C C1A8375D7C9B559BC4911C478C407682B48D364FF9AB4301736EB1CC9FEAFDAB CF66BCE0243AFF0CFD5FE881F9994498387CB426EBE776AC7CC6523C1A7F13AC 01DDF55E857BC6EB8AF6D8424C4DA1DF6AA199F07552F7C0EE18C17183B01D40 A7C72932933861EDBC39D9D9DB9DCC68BC9ECF43E542BE9D1FB07B824F77D5E7 FC4A7FCF6F871F8DE32AD3EBF4734B5C4A769F195DA51C16B307CAB651D4D407 EAFB020F2C888E29F7645A04650BEAD32012F56D06C0E46E5957FED915D2F844 835F9F2F13D29EB76A419AC6CCE838723E8658475456A26E900C781B83A36365 E29B6FF3516156E17A138561A319BCD4E9BD2E4A16523198B254D69E24CBC13C 5CC7B4F851CC09F820CA5FF6DB7E28533ECF1EF2168513881F348B1BA757F2F0 282329CE54D4B97BA78BD8240B7563D3E69FBCCC2BA0168E737CB65696A07B13 C43B3F8175D5C20E253287F946FAE02D6F7265F1CF6640446BD9E54C3F490CCD F20B7E851BA66CA17EF07BCE866B646026535A08BB2CF8354D10D963B68F6C70 13E52A5A716CB1F8525A71836BCDCDC1E5B9024EA01579672C5FB4775644B70B CD443260806FE4C9C252CEFE4ED60E7CB880C0637692D4024725C7BF21077B3A 73C222B867DE63CA7F03B0C9748B4030EA50877B53FB46324D537DFDEAB03839 B320FAE2E693EE523288BAC918D95C3842B8D3D7998896F7C1DB95F7B21F468B 310BFD46D1CE595531125FD9089278CEBB7E841913E172D2099C3C1850A17A93 C2DFE49B19744FA98149078CB525EECC12E53109AE0219FBA83540095C653A37 691A28C97AD1230BD170239601F765B9A9E361DDE5EB00B43CEC8D3B32B72011 FDEFA2610F59D8628EA6A1D21906F312BF12D0767D290CBD73C8C163D8625C95 59D8EE791F4AF7776DF7253A71FD8E888523B18E935DA9E8DC6ADA7EF7F195CA 6258048D5FE9D3C2D84D3D0BA29E3F6505ED18716EB27B3204E747440B92545E 8653E95751A2E0429792960B775690C47D95AC09E19E6C8B460FD2F5E9C247CA BF7B388D6852D9BE28A9031B9371992FB22784F58BC9D1A3FF37AF77B9BF050E 361D9E0A31E91BB322A66DDC0C1656FC654D6DDACF3314C4E64FEE0FFBFF04C8 88F5E3E9F8AE23CA143FB0F071DC4044726F711EB4C8209E69124F755E078EBC 05993D298E7B5DA380859C18CBB9DCFD1924B0216CD520CCB821ADEBB573C442 E73E3532DFA6D22DD75665525EC2DBFEA0B44309B9D81890CA68841BFFFCD39C 61721FDF10A09E4C1BE3AC1B72FBC1889E7C9D559950935F86B4A690832E02B3 38D49CA519F060AD299530DB6EAA1C78628CC31E0C08D1B011995794055345C8 4420857A38EC3D7BFB389ECBB3586D955BBA9160E2D07A4B9F9BF94DCFBB5BDE 84A0BC7D61B4E42006E2126B588FD1AA8106B7FE89FBE696E92A00779679746D F0D63F22BD9A13C5D04149AE193B3E6C9DA14348206B95338537B0D87F4DAFBF 7E62A19C964415277B76D8C872DEDA90B79F11967899E42792FAD372FE5D16D3 569CBD1CE0F80AE72E0CE2037D3477290C96E7564AF4793B2BAB0DFCBAA73DFF AC07C40627662E81198325C7AB1CE5054C21374DADA8B6620D44D6D673B20158 26B846ADDA5F4209A66177894647C2147F3142AC18D447B0F4B5880FD235797F 62B0D717512179EE17545E4331F62214AB2CF85C818C75D11597C078D97B5082 9D1A05E8657C5FAE0F9987FC1B454037C719774D1A17218D07DF4596DF59A275 522C7CDBF5B977010C1E685F759A0EB0B5FA94C7F0D9FABEBDD9324CF22CE187 81629F2735DE6926053D8C84983FD72268C9BB2183F6C3D5938CBD7628DF14D2 97E96170B4C3191D8A4E83E003B826B79F114EF4FE2CFEC1183851B7370B63B4 39058142E54943BABE829202A7A2297616808E7AA60C14235C3392A8C7808FB3 8BCD1C7CEF45AD133CB702CAA54563DFF96A3C260F84E854ECB52A113DCA67EE D74B513D4F41B874ADA7A2263F2BB65BED3EDD3AA4B25FB591CCC74C30B8F1B3 69602A940C30AED35318B7BC8F0570AF8E267DAF7E896AC00C8BCDD85FBA60A5 BF967967A15E30375F1B57C28259DF75B89D127E5DB62C86090D0DAF893983F9 6A0C2E4D3AC455ACE60CE55CFA2E65459352EAD6B4A2A6F3D2AE9F010733A1C1 0333222ED9BE170DF92567BA18DCF95B7C040388C8D118DF6C81C9E50FA80797 221D89A251E2AA7CC3DB3F28D7BB9600EDEFE6B718508CDD5086589118DC2E3D 0A132A5359F84BBB634BB6AD58527823A6657E160DACE06FDEC1099102AA8C67 EBBFB4DE8D3E1AFE03E468DBFDED737112316E3B60F13F2006A997F6C83266AD 9C6213CB265A9D8638A2A154E42AFE8AF65FE5439F350217E3B4B00159143228 0065D37C26BFED93DDD404831D268447DBE661DF35D87F58B60CCFBA5999F1FB 59707A0794D90E6B41BDDA8E621C6E9CF3A1A3EAEDC947C4EB033A1D01BC83B5 1DC27BA6EA057F5B750E2AF8259090A9BEA62C79F651DF78A12168A504AB259C 962F3B1206D68F51E5496D179B8C2F4EC48918BB5D97131385C47BFBB0200D3B 24E43D664CC13201A7E76947E1128D3D8A6154B22BB984BED59D7C35B681D2FF C564FB4CE86E839487FFFB4C55FDEE94ADACF86FE587167F72B512BA0371AAFD F03445F078CA82B0119B0D658A870D237068E429EC1D78716DB0C14124464B90 9B69BCA09EA84F4555FD872FF9E81DB8DE8FAE59320490A396D06867C9BEC2F8 44BB5B6E2832AF068FA7BE8D4C93ECFD823578E01FC2482172AD1166A08F4F67 CC5E041DE1187CDF6E8CC511DABFB9DCC8A5470B27621314FFE865AA73AB95B4 25F413F3277EA5688BED45967508B30196132FF913E65326244E30613AF65C38 257FC34E0BB51CD121430D11E87AA6790D9E3A6277B067991BE373D3A4DD661A 87F552483AB05F9246B3CFBF7014FC0D49731594354B6B8571E858BA2C7874BC 74F307AA6D5E56F5D7900BAF93CE16BABC4AC820B984C24BC18AEE074B9C3D1E 1C363E4D021483C7BF380EF2D8C1BE6817D53307EEB50963E5050871BAF9106A 0BBDDF90A80BFEC9331C6FD58BF1644867871B3D28145725DD6DA2E523B1429A 1EC9F25A96CD878A216D9B7889CCAB330379A55C9C5CA88A13583459085C1B7B D0CAC371C3E26DEB6F667FA72033657D676C4B3206327A5BB78CBDDDA9893B08 6C4B141939C090D78A92D03777212DAD8FFD805E6430EA76E6AEA5C35AA1F727 5950C4BC2CBE007EC18D71EA2E9806EB7DBFD55E7F92604EA6E52753EE917C1B 890EEA238E63C245DE13128006794A4CD419A1F433E1A9560C5B437E27E5E435 A50DD1E9C43BE6A136DF2543284BA48A63BBDB226FB5294533E7957AA138B65B F322481E3A954AC82A24693FE189102281C70C0A38774E2C6295E7633566D31A CABF9080492562FB6149C6BC72C7EFA4C44B0A75D5236D72BFE3B458502CF11C 3A71481514E5E3764124CE82D9C8E5B3B44D75DDAB9DA465B19429E69CE0D770 3D718E72B16FAAC1AE7B7434148F1F5CEEE9BA24BD9A45B694AA16FD998BDA01 CBF2CF29B64C220ABCC3A910282501CA98975C87D4A176FEE4970FF7B646FCF1 7F96F4BA97D32016A3DB7B855E57C2670F76E3CFB7122861E743782334DA10F3 8E020E4293E9F543C750CD37E68B4D94E8BA41B3955B376D7905F7302C853E87 4A98CFB7996DB747CA785B1F0762D043E62328C44B84C69898E30F6CB1C6385C D97903B57A4E146F6685BADE926E82B4AF466C8F2641A0331A1BA9111E174D56 6804B8CD226C8AA47E625CDC129D9BA3D629764829548D1C357DC8D0F92E015A D0E3F0FAC048C170A49FF15B544D8CFC02EF4699C2EC0F04755E2165EB26E7CC 556CF719DBE4B7884440F728B17BCD4E70D3DC997E80D7A8603129767C25288D 6230D33E84C2608FEB8BFA273749DDAE33B623C915E89CD762D87C018B61D725 2311CCD056F5BA8C054E8CB0A832F2D07A5A4D90F354AED024EA9EBC5C54D630 0AD3BE2E166C2FC9E4B80627C049B6826EC72AB0FB11C4F19BDFA2658138B67B 46E30F7A3EC03DBC10455DFC06A01FD07E74E3B5375C9B3CBA465398E7A58212 CAB7614283124CF5B3F340032DADE53C38DC632287A379965210C5A1694DC3F8 E2487296013D25E0E8CA1EE0524F8E941ECD05B6868971D03781DF1B0149B49C BAEACFD34EBEBD404E3B1904C87A0D386F5F3761628629F18A395F1921308F62 91C72F5A2F3387853E7DFD7CC7F8927980D47A1DF046F635ADA7BC6FF0AF87B8 449848984DD2CB424D567F186254974737FEEBF03D5DEBA524232570AB7B8F67 F542AF42E2856C750A5381BEAE4428C6FB7C6CC19691A0A65AC9546DAD610062 E1F6756D039D284936495811D8DE59049DF431FF0DE5C6C7F72F1BBBD9172FB1 D39C05A409BAC84C4C5110750F82518A4698693F4D42E1D1C8959BDEEDA1B004 DEC9C9B372598B91B8E79CFB144BACC2D0B5629B7FFB0DD98B8903E436FEE33F 280EAF732C12758C55A971C4710FFCB043A0EA1C3C088481464859EE19C0A2EB 758CCED69FC1D7F76BB7FB524E2C0241C41F75B0B8DD3919AA8197659CD133C2 9C62567A00D3C3D1210E8EC6239418F113C49B9A3C6997798D84D76E2F1D2B22 4D6D3EA341324C9145844CB46EB5B739137EDA47EA1C335AC1680C7ED8266237 2DDBEE44AA952CDC76B69FE7D3EDB1DD551BF8829DACC1E00B83E3C3FE602553 9616A994F5C939189F042BCA38594F77282AB14E26A49E3FD678F39FCE9C5762 4EB9DDE2B376227127BAB1324EFDA36A5BA3DFD12950DF3AB088300F49F7B8B4 0B305B5F6428F5C319E98386C2E11AF4A78FF50ED4E7AC6A543A3C84B464BA27 34B8D80FF391FCE09CD1877DD472F43A8EF3FA8E87B9935FB690ADAFD700F825 6694BDDAB2827CADF8CEFBF3F529DC03562EBBD5CB6EBD2BD8F6494640C961D9 CC1E07E19B19F5703742881D1A743F3701FAF362075FD3E7F97E4E3D7C22CCC5 880D8EEFAAB211C5906699DF606CF0FEB2B572F4BEF2E2AC000E72F080A937EB 5DCCFC8F4F526BDA3F3E2F21C4BF524D8768167AEFBF220DF87766BBE79D1E46 D1587E4EB88C22DF4FF5C5F9516239CF457C4F9A323D5E02BDB0E7493BBC2255 403823EC7354799C8E8939D6662833BEFA92A9DF8D76C4437F0A7F432E8A3CB3 E270C3168080512FFA809D6E929C7830F6E0B59B6AB559F730EDC061FBD32125 A1536BAD9B87C71C238CC25AE5FF81A66A161E20CE84DEC79AC888A860FD46F2 480F69B078EA7121EB20B6D2687A18EC9727087F64CE9D7A128A61967AF352D7 A647C4D362B85942F86C0F10642EFC126D7B32E745D31978E29ED46F1A5298FD 09FCA25E0DA3F0EBA218433C7EA1E4E89D322EEBE4D66B52B964CE387E27FE17 F5F42FB4BDB3D4B8DD88A31EE11A0B360B6C72A0FABDD2C2F2F6176484FA731A 994AD961B543FBDCCFD660ED4B211F631EF4D60B32877A8ED3418618FF5F9FD1 AA27E1CC1E319D5B6C6DFFAEEC08A7DCB7BCDEC67D2964F115B8DC84694B8F25 DE47B44CDED2D53F90B959CAECB8E9DF61AF043396B304735C5986F5D8BFFEE3 B137505968914BE128D40371BB62B729E2FF313C5D6840A7628A12BC3A67F5D4 B58E318C7913C470ED6E66B205B9549682250DD1C12C0785AAE67C409F9BBBF9 B39AF0C8C37058FD9C3C6B5108C79A7FE347BC1266B1BE28CC083C1C88B88207 458249394AB014252398E5584F7A67A62C706460874B135170FDE7748621C5C3 D1500872B4B8BCAC0610F67673F65595B67ECBA01F107F1894FE0446B9A38BFE ACA68FC485872E566EF19651D1B8CFD061E6C94371E600C92F84C8367068FD27 241C26BBE0EE54FA64EFADFC6916E222C81BF23CF7C2BF0EF10822A49EE9EBA0 4CC589DAAAFFFC6FB6ED76015BAC79865F250BE68B0CE8AF008B9A9896485E1F FD6E481D9E3C8E2422025988003939B42EBB576801F35BD23DB5E0F7FF4E3008 63A62C4A217E573FF14BDB67924FA678A04D8F366B4BF9B89A85A9E694EBB200 F0B21D315FDABCFE4C03BF3EBA7188ACD0E34AFCCC0C18343B2F1B17F10F5FFC BB8DF6DB0D95E1E6A0991E93F315DA53C3B59D1121165F9A528AA9B36A7E455A C1846114C7B67ECBB6AE378FC7056774CB235A1C3C965C4266C976FEB468FC7A A2DDBE2EAD8342F53689B7759DAF2DDAEED73EA680B0996BAAB40682A827F827 BCF1E9DF8ACD10772DD788D980B39341C747BED72265EB694470E2C21A9B8286 F67485A736876F2FB93A5BDD6FFB8283D82CA3A1066E016CF0A8A67BF8D4593F 18EB2EF313E0B7C7633EB0DA7BD6BC1310B408F5C061B6EC588A833E0B557E26 D3789CFD6047AF482BA1E8FB83316B1FB7E2163593C31E88BAC25D0E2FC80A4C 3C30E630E498B313202DC224AF2A263B977AEA1D71C0032DA1B4DA6E9159A567 05188BADB5BE2143B22431B84E2A9FE1F64EEDA3AC0CF8F0BDE543347E95137E 13FC64E22626B5C778C5A853D3AF35B1AAFF1EB6C7DED6EB08B2C1124CF1078D 9889BB0200A05BAE297418EC0427D5FA06B29FF2C59B36D7F5647FDC2636B480 FEA0C4055CC30EC1B50B6CCF946390193E0431AFAC0962B9E19EB87FB2C10508 8CC8BD7A2DF44DF65BC4BAC53FFE2BF5BC4C1131D7B5B3D26A23975A5ADFA4D4 08DAA3152A1210E6760F78697E99471D087FD74F9DCC0AC28CA5514AD2B322BA 29D32EA2C2B18E18553951EF6F031497B782C0B6A8C9FDAD15F208429A9817D8 329EF2B30ED1770692C839C3E8BF62845934CC61384947AE1593B0E873BEE255 799A2378017E048E7B2E8FB8FD0E93D361A343C358672C09F3206B7B272F5A30 7F300BE9773CDDD538E557E2FF743D658CDB60907362387F2B0634241724A5C7 8A4DF21B57D50BE18883F92A6254EADCB67ECD2BF30066C76B828E715DE7BC70 8C9D47BBCA551DCB074997B5273F5985943C6ADBFA2949DAC2EC3A00BC116516 01B377C6EEC3840625EB28E57BC5560AC87CC34FFE481213AB38B1C20D59F9D0 F6F000866BB40ACA07F544AC4BA7D7BCC5A33CB75D48A1C845101338CB8A2391 3D54F89E7F092CF803BF8C77914082D89337BB9D3ED45DFB6AE63BA8BB787227 4D66E083D1AE8143243D6AE158FFC9CE0BB291D6296AA0309233F01A4EDA16EC 66A62F358551F8A3232ED04D032CA89E0E97D09ED55BA15D75C6BA13FB37D99B FD5CD050029DAB7AB22DD1ABFCC711F604B29E375FB694A3424EC145E1F37556 0EFBF9185D1653305D43966B74EA9DEE85C5DC9BE2D9E449A4C6454EC3A850C4 0C895150BD5C73DDA2A46845A52BAE03FEA1AA09C519CDCE46EE81465D56232E 51F5744E55EBB575EAA2DABF6419D7ACCE1C65F9E73D867233B3A875600F0125 856288334CA3A4CCBF75FF5DCD4FE11178BE6E633E5E33522BC850B4147DB52A 9667BC2E5F152D506CF86C5D7DF54838A0937D4D77FE23845410E769D44EC85D 3A196B96105527E586660B5E09415511DFFA28D08522BA97443A256336E322DE E21A8D31BAE5495AE7D80C89ECAA6894F932ABD455CDA4B048617D390146C9C6 0BFFDC6BA1F73DD70D4A2636DB2ABE8CA6D0F89DBF662BA21CA18BAFF82C97B5 3738B4B2ED5617672B49694D0ECF4E00E082B02405A8CD34581AA39D940382FF 69E8FC2BDA3BAB0B431CC8012A2E71F7B476B78873AC98CD74E520F572867E2F 0A56684BF78145D0B1DA7620C726C8C5E291772272B7BF3F1B578B6F92C4A094 D77FDE1F0528550EFB34660EB2C1872E9677E77622A66E02CB63DC772EC4C89C 02CC31E6B4660A809D7D90A710188D230FF979F8F11F9FA53BC3AA3B6F207D51 4E49E67CF542CF2D26FA6937731FB59D3697DF2229CAA3A923345814CBE65C0A DDFC9F4A16DF96F2141752989209AA8574073B677C4AE6846C517FEA3C1F4A2C 44651C2EAA05AE13EDD86820145BFF91FAF82ECBCD18FFB5192576B47A00E1B8 3A57418BD6807B891B668358F4F7DBD2384FCF569CA71C0464C0046D4E0D3081 C29AF41B1E3132873EBCF9C66E7C421CDD48220A0AE84D967A6F23A6A6556CFB 7B8AC6C7179ABACDBD66877AF354215324F25E7B015C82D173C652DFCD1578F8 3E24D9D0CA1BEBF4E7CF6ACC09CAEB4D6B30ECD7CBEDD8B5CD3744C05C5158C0 F8FE27F011065F885480BB6C23D1622BD88C222395D2895FBD4BD664B176AFE9 512DDF62B27476BC80FD16AC4519941332ED37B1E7789B8717DA937B1E05DD4F 024C9B9A722856880AB86DFD522771F82B3289793E613204457E0E1BB24EEA4E D0704B1C8A4189A640DE56E8E8301ECC52B367F1432A652F52BB92BDD054567B F58497ECE9A311E7FB27171CC8049F46F321F8DFF85210ED1378D3C6539364C6 D9FDB1F6B880E4748357710B82F265007F94D650602E894905C234C6C7D73E10 39CED1564EE985FF52894DBEC9DD0E0E59584A3826CBEB63DFA2C4DF5BDCE3DF EC042150A36AC8D55D9787216E8F3FE3BE25202120735B233410DA5F8092DAE8 D2002DEFFF4B0398A8C38F33E60A80A368C1B575873EC142AF5F83430BE2 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: SFTT1000 %!FontType1-1.0: SFTT1000 0.3 %%CreationDate: Wed Sep 12 2001 % Copyright (c) 2001 Vladimir Volovich . % See the file COPYING (GNU General Public License) for license conditions. % Converted from METAFONT EC/TC and LH fonts: % ectt1000, tctt1000, latt1000, lbtt1000, lctt1000, rxtt1000. 11 dict begin /FontInfo 6 dict dup begin /version (0.3) def /FullName (Computer Modern Typewriter) def /FamilyName (Computer Modern) def /ItalicAngle 0 def /isFixedPitch true def /Weight (Medium) def end readonly def /FontName /SFTT1000 def /Encoding StandardEncoding def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] def /FontBBox{-208 -360 1374 838}readonly def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052BD0CE60552BD63101D7CDBEEF5B11 69C468645FE4ED1AF2541AA0770C1DCF81623DE0ECDF49F2B522618F650CE6CB CC8C21885DD61AF8A523AA677EAEDDFA51A1F9B1885EEE0456196D634E04EF89 F17499DAD982502ACC349B9EEAAE4A71A73D1147318C60A8BAC10510DE90D8D3 F46E47295D27129A5AFE0C65E22BAD10D06885A2EE623FF8E1D90287A083E00C EF25195F68A2A98170E4875AA1B1ED6A435B5950D131BC48179F5BE3191944DD 8626DE76AAFD8EC4DC8241F2ED33E10698DC7741D6E45CF5A02FC6D2068AA205 EF3C4FDCDE803F4D1D4FF03A079CD4FC4BAB3C558A8FDDF53D34AABB7D89E4E0 CF76F77ECE57575C27718A8074CE275DDE4AD245220A8236400BE47BC76DE13A 9EDA4BD5744C71DB407BCA39DBC9D857122A1DA969E6D0915FDC1622AB8BB88A 93D2EE72E9A2FA73193D6CDF254252980674DB644EEB36A2036E04DB649F816E E70C4C43E88609C8E8B8B84A920CA933FA00F41F2FC3C867825E2AC658FA0F7F 331323E22BD193A0A8009B3F0EE6D55281CF1076F1631FE509E79941FF08D0B7 ACFEE566C76FBC09F3B4AA57959D4EFC34413ADB46292ED99CC8EC4436DE2CAB 86B8B48847353E826F5346762CD5D353727DBB502E08B934DAE4E99894706BCA DC35AA52C8610137C7E336009D564831E1E7936600CC3891D3A58A539523329A 45DD54B8D76F43582CE621F74FE7F8FB06E32612FB06B66CBB3096C0DD63D097 08C206A620CCC9ECB49CDC17295CD0B3C9D2DFCAACE46137490589D72A6A57BD FE97C0CCB9087CF31EAA7860444C0D2A1B230F1879B1CD80CED3863680AE37F7 39A117963BCA696B1EFA8EA500DF5B1C5F6F42EA16D46CC0687DC684B2AE28CA 8511448362E82092B10FE7451F92E7798EB30D015614C10FAE46C0A4D32FCB0C 6BAB88710E429820C597271F5ABF0D001D837D04F7DAFD12E2E3E14A5D6A62F3 27A102A2D235520B22E90390172C479E98418A0D659DA46431137085B59AA611 233042AFA7CE671A231C00755B2090EAE0B6E67A05EF66353972C232A17C555C A15A5ACEA1F8AEBCAD32A5DE6ABAC1A2B9F68B0FB2B04A5D002635771456A885 0C4906DA5A96C2EC5EFF288CC22CA0D995EF0722B978B52BBDB729D4F897E737 0C4679B096318FF65F192BB465D4B28FD78BAF3AB21678BAA5AECECFB6EF2B8F 5C1F6DBCE36E6313C32A4C728BC84C955AADF23F2C763CB339B5547BD1FB64BC EA0E9538A6DAF6921C5F3881436FF74C1D2DA79EF543508330853A42A2512CF4 BDE155F7118DABA2710058926158D7179D08392FB590D91A9A334C7A0252273D 12E93E9BFF27EF0108342D68B5C88DA27B2A196D1680787FBAA3043842D5E8D7 09D13BE9F7D4292AB27FDD13ADBB9214184F53A25939ED58A375C6B24AB76815 CD83B5639199A68B3D7575BD95466C15C69817A611C490CA4A7628C2257AA084 F83F5DED18D9BE931E819EB6177E6889AA017F2ECCC26A80223DAE6F2B4E6292 59B2A280439AF75932BBF6A5C4C13473C8A479CE8AB6CFE5FF69257E42AA6F9C CB67CE1D684B8EE042A0DFDE5F67ACB933B4C82FC4538263CD6180CDC03DDB28 80A95C04C4F8108FB9A89B45C068ED203724FCC05E319A50916425C308D02F63 DA25848551454614AF83486A34CEE46E1FACB5DB6255EB11CF42880ECCB4EDD3 A6E842DAA661FD9B397A3F26BEA912693B0A2E1B36DE6E357F911C7F03FED1DA B28BB99A57DD4EA546F8EEB0DD871AE36D2AFCC4A55CF81BCB8031D291D5F75A 3A1ACEE2C1E8D76584C32A7059E8DB896279E7AE6D25E81034C170CA7E61C62B A2ED8164362ACDAC5DD9692B890757DD74E27F696B442C31F0BEC519652AFB0F 145E00AF29A5213CDDEF22E1DE92C7FE932325DFDDA18D698FDC2932E9D0E61B 740C2414522243F8942DC98340DBF93E48790D4025E339F8A7ACA13BCDBD10CD 7BDBFA7E97845ECF8EF3B6A3D13C4691B5C0A89731944DCA0993CE33FC4F48C6 D181E139C5C9617EC85B0149324F506C84F26B62003FFCA51DB3FCC6D7723CA8 6EC455FECC5B3729341CF5D74891C295A4F0FF4700AB0A2C8EFB3D5D3297720F EC65254242DF50BB4F2A69229CC39C8F087A72A9715F6076AB21332AD088DB29 77AA675CF294334355C2EFCCA828D59D85992FEAD42CAF4D91EAC21545815DD4 9583EB7FE74864545F979282A54E58F149C2EEB2970B37FB5A2F90A57149A835 B02533C338049F26BDCBA08BEC57BEBCCF128F34591EA974D380750404774E0B 19F8E058F51CC2AFFAA40AB22494D08EB379D8CB6206ADCCE107A624033BADF6 D86FC17A30DD6D4236326E6DC3A046FF00D80D3B96BAD65985A4C93BB4D66150 CC20D94E2CACFE7B0C2F5FA4150713F6FF5A943CE82CB1857A9B8E1B0842CA8C E511975D6DF8B1DBBAC85A8C373E00DA7F4B100C6CD4466FB09C83123094DDCC 81333957BF5AD353944DAAE92656BFD9FF6C32289274B455E87562C58A0F7739 F1A395E36FD23735A9CCAC02327C1428D478B2CDA05FD350DB066AD380471D52 712B846F6E784DBBF01924BC2D7187CD112D3ACD5C7CEC3AC2C8F19BCB9D0E53 EFC739D751DCCA9A4CCCB636F9CA857B3BEEEBCC23C1C78142B90F3153331686 98A10F2493559DC0CCF452B1A7E86610EC87F2DBA4296190A164EF8942B5A6D9 C1CCB2079328489503CE4AEE23CBA57153F85738BBC0569B52F812390BC29E70 AC3872FF04437F2F53418A4A6EC36147841FCFAC527C14F9DBD135F73FCF408F 1199E124C92B5C7CE0FAC02DBDAB88E34AB38324177752345BF694F806612DDB 459733371D366F6E252435A2F4A39F785395668130D77D222D4427DDAF25B2CF 72E1EC79A99A8AFA59B5B96B911CD7BAFF119EF9D00ADF04E86B1797B6F81CB0 76D4861E89ABE13B9874F39BD444ACF028E491BDE0985545128BE3879BF4EDA2 E7250CAD2FFB6AFCADF079CD1B8D9EB331CD0C7DAFAFADFCD8265F128A67C372 720840A20C25E8A0C7BF44EB8CC1328B778B0AAFA4AC3E7934AB8E09F6E413D0 28AEB72126F83FF84F15022F6B16187EAA6B23D44BACBF755EC54AEB8C0EE218 AA8828365FA8D0E21ED1C80F69170257C0566EA3CF270B1475849FF83B1380B2 90054C7918121DC99F7609372170A19CB1975BB90C59DBBAF1B1FEC48D4A2E5A 4C6D38DB1A06112EB251E08434CD1FB81B8961F030D2CA99962D5FF3180162D2 5EB096A30EA1BE19E1A0CB2353495C0945D0987108A3779C5147483F5E46B23F 2EFECCCF270CD3627F462489F20E18CC4DDB0863C58F00DABB609F455F23B7ED 90F772BF239C387A4ACBDB9EA5A5484D4BFB94C297F9E2BC85DE0DD56D5F596C B2275D1B0C65004551AA5F388A18D13626692FA02FE7E5F6474EE58EC31B946C 41CF80911826F482DFCDCB78A67C18271C5711A59D248BAB65900182933882E8 A20C99D5DC6EFF38D2448D8EAAA40892AD0636733B6A403FE5212309A329BF60 93798EF1F83466480BBC58301065E1FDC4A44141E23E3FD8919C11F5DFD1BB2C BD356D885D4654240039A153A419B6CF998758008E2A682E5B81FFCE29111C00 30063772B499539BF172111609CC88B755B6B5F35AE0F54F4B56187E2A770F90 DFF1307DF865EA1C8807C99581AC34411066E68344A9F1578A86E097EF32D554 17A119ADD0A8D9D4D8619D59D1C3B2EE24ABD913E36FD16208E4B31B852D771E 946E895E837A96E75454B2E3C63B2F29742B7A5F78CFF022EAAB02B6F9F44E13 9DAAD1AC10B7349186CDC274F5C739D8F42140840DBEE2AC618C923BABB066A9 5F49BBAE81C8600B84C8FB7257630403184EA2D752C23B476F55A202BB5A0413 958313EC78CCC37831BAE3F132F8AE3AC66015A9A69A4C787BFC613F3FA29928 9B211C25468FD4D9767A61FC7069A31D428F46C1085340A22DBC99B369119286 C288DD5A4BF3201B92300D99EC5C27BBE1ED4309F7D6A8D961E40F7B96A2EE47 E14FB85B0DE66D8AB8594459A05F39DD3E6629A21B197335AC0947E68E839DD0 A97665D726478D739895BBE590480F0E06D13419D0EA141CD3C232950A6CC061 C2ED9B7B6C6A3BFE801083D62459AAF538DE6C18FD77C17140BDDA95300A9FE4 49FCCBB8FCA8042756FBD961EAB16503D08FB97D8010B505F83646F7AC386825 7723C91CC771D68C11C8EF4950265D2B4F2D75BD27B64126F927CBE82A35E413 D5A315F51917E45B1BA4732E96D66E7DAA5549F5A4264BD84D7FBEB186853D05 BC41F2C8903192CAAE8A14B95868CFEFC00F204F46A0ED60AA130149651F5744 A278C1E050CC75AEF32776B3A29543F526BB826C004888A9E3D1F1E76D649106 8203CB0F98EB2028B9CE6DAEB974689851A9537EA46869D732F21DA37A7B2444 56BD98269A40A5DE0BAA262A55B498994F27FEB1D9F839F1052D11E5A12FFBD1 2A674BCC38AA841E8BE9061F1497CABDF651CF5ECC8387749FD94A29FE42BB4D AE707A8F03F70E01766E098E8DAACE7BF3E6015D0FF55BC9FDD3B39198B8C220 A07DA2EA2FD6605F4A98894ECFA6D02B0CD660A2E41CA448F1A2A7AB9F98DC6E D1533FD047CCD51C522441AA6FC203BACC4C774CE88D446E608FFD38593EECE2 F07D263496EBD6E1643F070730D8E7EF8EBC6BB490FB6BD5470C544DABFFD1BE D49C608D2A7E81AA54E3093EDE6068C67A6DB25F8E5B5F42C1C211203ED6EB5A 335712205BB6CF70EBDC1C61865AD6D13FFC9BA45B9D908A33B90179994BDEDE D13A24A72D49362A3CC7308A41409AE1E6D586D24DE7490F83213E52BCC8A1DA 627BC3064CE252798F4E3D0B78CBD11BD3F3D0D13EE0E72918A5B981AED053F4 FA2C9D09BAD4E0AB5C0FD8191503E232DEB91F953343D5DB796A2535BF487DBA 053B1BFF75458B28DADCC095FF2FFA13E2FEE7224BC98C4F0A9C6D0B80CED648 706746E56B977907151C40DDF2DC9D8B5474B0F577ECE7D42DE688F795A167C1 2979B4BC35B21F6085CAAB4C57679128C451ED6EB7504D1FAB025D5F1E53AE85 CE674D0226B6A0CDA289CFE590852795408094744B995E2D30FE7AA39D0AF5E7 8792BFE131577C965286154B6DCB4935939358D67986BF7CB907782934499044 B3C32A77254150C582F978CD4AA8268D4D88BE1571615EE882656481BE51292C DAF4F5770818D65F66B7279741C5640259491EDE6EB8DCCDEC2DDE7D445F57CC 792B026C8ECDF307D60C35CDF03990C23D5B2A650AE3510B137D55E6CBCC05C8 41BE95AB8EE4E073867117D0FCA3380CED6E70DF19FF919C24D67C59ACEEC8AE DF936D0C6C2365224934CADE4D51D2A389CCFD9B42CC4C5650BA6696C75DCA61 F867D7383B309C5540BF12F26C05AC72660877A4E809F029CC0F948A9E1A4B22 495B5AF313C627E6CD6315ABF4B08307A3B0A5E6A101A4E35BBC49BFE9041842 AF256A919E564481BC26000B6602C04BA385DE32BA45F6B24AB94AE1F3A6572F 8EBBB91295014DB10C6BF22F5D80E36EB764EDACF572C1AEC2F8A0E8CD4978A1 E94C541D63BE04E0815C0714659BE1E11E16AE8A2397B4CD0F9CA1E5420C0685 43E2343C71EE42190964E26C71F84D7A0176EDBA865845DA8AA762882B9E41EA A320F97F5DF87280FB9C8AFE6E8AAF31EED784AF7749DECD6F3571B916EA0CF2 4F1598DD3F7F028A07DB6850F3E2F2A76719A97992FE8722A82ABA9CDAF14EFD 8B85E3D10ADBFF2F2A4FBC23F42BED6FE85BF773ABAEDCFC5F6F6E60ABB01406 62EDE27BE80DEC005B37C320E7CED18754659BFA4EACDDA5E1EE1EDDB0B6F7D1 20FE40FCCE82ED63EB033F590E743364D40CF42E3B5B7122C12956F50E2145BC 7021573B5D3F3083CCF6FE034F2367A227B9612C3C2EFFF11E802D34228B1459 FD1BEE59B48E354876541551C769EF6C0B1EDBFCAC64F2EE2B44C299F3C1BB4F A903FFAC28422EC8051B4E8323540073DFE959CF33FB737296ED239CD9931C92 317C1B73D92B41C75E304ACF30C770953922F0110B890971A8249E0A8CB7A1A2 B2B8BCAEE867F9CB65F0379D401C655F722DA9E26CC84E721A361BE872D86958 18C0E9D9AEF42E1508FD51080085BE48413923DE84C65E6BDE600928D05606E3 51FF8A52DBF397A226E0879CE48637CD3C58B8559274352EDE610D488CBF10A5 7A79E32BAA789B7BFAA86D0BA3333480CFEA3EDFE5726FD5FB18EFEDF3CBB8FB FB7A9510527F3974CEB06CB3264EC6220EE0D94C938EEBF99BA638D5A89CD9E9 07BD5BDA9873E858EE0E96B00E1F90BBE9ED981D7EB6BD21DFA039735EA656F5 664E6923CBF3706A4B0808DE9D1F8452B09DFC984F9C1420F79F8A4286FAE4CA 644C50597F58D69B0D3A2F389F9825FD0F314476372605F25F912778B6BF4E1A EF672DDF12229D4A91E57FF154A4A77459AE1430481E43720771E6270A476844 43730F43ACC6A596B2A0797367224AC2FA0FAC3C587DABF1A686887B34E65341 9CE372DB43BF0F69F9F7FBDA30E84943B1A1D005D575CC9DECFC55F342604A32 65AB5150A4CBA7D996F08B42322217B06CB73574BBF2ED6204B881F5C4E42589 5C2623DDF714EFC79D7E9C5ED2573FDA847FA50F2E9A15EA0D1F88549CD8239C 645F54943D500D7702AC37E9F3737B3D223116A6DBBEB0C9784A4348C7A8ADBB 083A366131B9238834CA6C0DE548B6276DFFDFFCBB6E4073CA165A1180587836 396D1A886689DED9CA268054CC6A5FC0B48EBD976FFFC6B4B1BA4525028A5BB4 17EEEE67AB0278661B1E9E62B48838A442E796E113D82F628F7593A2A3A7F468 E33831FD692568ECAF8B2AB4372E98F0AB2D166A3CA7E94F930A139DF2B2F3EF 7160B838D2CDEF52F1823634FAB8572443E10A5411069D1A836B7AF919EF9654 03D92834B76721C396BB4C31D2FD31DDEFFFB0F2714F4EABBE388376277D26A4 EC7BCD1640AE330B803BAD093C909067BA841E7569C06F7AD2B65125BD4C66BD C23A903B6DD45E0DCD51B10F0445DCD79CC73E8CE18DE3AE6D832B77B6DF710D 630FECE19B6300EB1B060BF4040641A7D0BC5C4C0BB1400EA5B2946E56800425 DECDC2BDA27746B05096F2CF38B5F6874549A9EF41CA5122A37879AFE47282BD 8DE134AA195582C6DC9892AB406FF368ABDC4304AA7F14375F62BFD0CFBB4C09 7DE0CF386EA57844D99FFBBFF39611F32DC7AD923761DB59ADF303528479B0D3 7A4E26CD6CCADB5A6B27831370A5C8593A2B7DBB1040A412591D217337C5B887 C6A93C4C643F890E2AA9AF63E0AB51908D892B65486D88D0C4378940393157CE B30D3326610AA270C030EBC30D97BD362D4C76717442D5FB7A55AADBCD48DC1A 6586DEB6D302F8913C6BB608335B50D39A54FFB9B1C486D4E80B65440B3DA5FE C96EC0E3E11D2405E3DC0D87D76173ACAF64E30977F52AF5EB2231F0C4E85E2F 06988A5D6AAE598FBE55B74895C88B769875FC7D44D42C6EAB31789982D56614 8A8CAE9D805E9BDA093857AB3608352261202E73A757CF8A7C5B37E05DE8F788 98E721F2DE44E7D7B01AEA95F2CA5A2C7882233729937788F78F4CC28363CE8C B54B37655D9FAEC258393E4B6999DBEF9864BC27CBA2D8FD95A872A954BABB27 86987A899E28ECA3640C6CEDACF572324DAB9A7B6FA29987C6A1A0B08C8D36ED 6E248457781F5EE012F98F7F0955D5574901A6E5294D558161DDB8E77BB79A2A 631926D544E6887D1A3A499B0CE562DF10BA6196EDA348639FC3A0B52980A928 9F285C7547A8FE6FD08BBCFF7B4D5539A947C6FF8919BD78FFE3EAD9099FDDD4 7550679DAEB56A54FE2D4C4997E6FFB4158D89F17464E5C9FEE69ED095F3164E 2A29FA814FEC2FCA2792F4D2488B5B081F476EEF9FB8B83FFC443A43CA377F66 BF5BB7758DA04F84BA17AD7EA8C80342CE80C1EA3C1E47694C1952BD9DA12656 829E04F24BA7D6B3A5EC581BB47227BE70D0BC576B1DE985AB57FEE9A503FB22 D7690A4C60942ACF0E3097365632D473839A296DF31A11073D6791AD852810C6 86E0964E4A9A409D4903CF37F7D111385E014F297F013CD4914B8AF9A0E9F007 9549BEF30C77464FCC7C4BDF775410ED68C41B1E5D37F7CAD0EEA680B9B606E7 E31A4F73CE69ED291F0B78C2066AF0C6B4B3C307F37C6FD58CC6D81D7CCEDD2D 930FC0FBCCC7BFAAFFB7CC45A6E8FB20430DDDB5EF76C8A9A44C9B04554AFDC8 5D254AE0B9E48E826C6FF5F775F8FFA47844D99FFBBFF39611F32DC7AD923766 CAE8EBA53D7D94264B84715FC91FFA187CF5C4319DFCF7BE6724DA4A9A860C3B 96ECDC24124D0473EDAC9DCB6B366370BA0E59F4E8F7D527DACF0F1B6A4470E3 52CD34C4BE669785DA849333314C680490FEA4A2FBEECDDAF83672288E80B9F3 DAD5C26B03B9A6C644170B038E46921B745DAB0A083C4D42B45F27E35A712B03 99B802419FC8772175566DDE97A987F715808DC253D15626554CAF80F27517D2 B1F9341A4E6474BA273DBBABD015EC8A301F8A84FFF134B5597F3A1B73A1E252 15533E614CACADE6403ED44412E1B65F559576BE4C7F14151243D996CDED1E1C 09E1C5281C859EB777FDA513DFAA8C51D35498E005FC163DD57E53AB4918EE60 08C1EA7A3714968F2D3E002F30135A03D8EF9EB679AAF16A793C795088A101B9 AC62B7A93860F09352255F29DFE999E95C1A1F5D04BF52E36AA1DFB91FE62A19 3F3DF55C04DCD659B2BF1631C624D9A9538E1F48CD775AE897000C8044CEA285 BB97A7F154AA65788D33CB2BFDDAEFA453CDCB028B1A029B706B5DFAE2BB2EF3 6CBBB31824F9353A7F6E81A0FBAC570AF3D551F199375ED5BB71D1467E2E1845 06E6C4BD7F439982F025DA7024BA6AA4A5098E241E4058437BCAAA97A7B030A9 C18F14D805E6D0BD3AAF4DE1FFA0ACDE9AA862E0BBFE1300A73F6541BBED43FA 3A3722EFD41FF3FC588A75B49C17B06F1C059DE0CEF5D7F6A5ED34C0BE8A4DA7 D74BBE9A2A6319D540AE10297AEDF51089AC8F162225BF6696D66E6CF8751AA7 899133B34AB2C9C21E74681884ACAE902CE9F405E532B19E9E0A6EDBFD4DC125 36A95183168CAAEEAEBB5C388195E802A576163030FCCDB5DB13D440AEC78B54 1F0648AD2E653615DB54D1C7DFF51901B23EBC3367DA4F9BD09CFC9CCF691F60 91271BE3767FB3E937DFE7B3A8D694C9D23A70A2BBA23B7F62514C0A72701A3C 8161C09597E25050C866A1EA01687E0FAC16C206FC306E66607A29526145E194 F5574F5B1E84BA77607426584812DB10078F127F2A85579C08F3DB069E79C2ED A696775658C3D6E78C8C25E33489F1465C5176DA71C4083F409731FFDC39EA8B CFE8A75E1D354D164E9BB45F924B3245C688EFD775A6484A6798512FB334D5C2 78F0853C05BD7B93BF8708AEE473F9231A00129564D74A13486083D63DB4AE94 5A91BBF8C1F6EAF6B3EC2920E72D7759C8995C7031555A45FAFD3CE3F311E52B A1A2C68E50EFCA3431879AE2FF5132FA244964CE8CE031D2246BFB07F72BC370 90660C5B49E8882EB7FADFE44D6B4237A5C89310DCFF7AADC801637D2D197287 047422EEF2B48E8F38734EE1A56D80576753063E2F1B35F463E79640813D107F BCEAD013AA353EFCE9942F03F06D96079E1B793A54DBF753756CDC37D853338B BA57CD13C45EF003C1492E94840A2977DCF6E8EEF4CC55BB3ABB0E37660C7C10 3D436036E804286AD8535A03BF0799BDAA3C029EA25C4A80904F1CF3C330F682 05E26509381FBCE4DDF0AD6005B11DB03B13C745D0C0673BBFE5374AFCB99E07 0F61820249B13AFF9C98F53DB52D4B86E00C8E8B145BCC7E2BD6DA183F13D197 1976CE0E766EED20DF4357AB70D26D0DB673D7B04E6A3577A4F19CAAE87F6DB3 BEFC8BDF94C35AFF9978694E2B308182077B7A8ACEAE00EC642262135BAC906C DFC033FD887F11FE6DB43D71B7577603BD35764507476CA8A061EF9564EB0A35 F7699B564862C7AC76F1F53473114AA709332854BEBCEE8576E76EF9AFB0C6FD 80FF422423D93F10886EFF8D56DEB9D4008E222E0A626CF2FF4DB50714E8B1E3 F91C9907A396DBBEF785AF8D9080EEF0EED5270C6CF74ABE5E77F61EC499EBFD B315BF1628C60E4CCD406C3FD293CC43688A1DA063448A07DBFE0080A6A49318 0E0C096A85EE79D111426CA19AABE1C1606DE98C60393B5BA6F71670F362CB47 CB9B8C8F465B979E384D8BFAE56EE7E3080F67CB10F47824A4407BF6792C4576 D24A193B41953D291B478C6CCEA7FFF811A4ED3579B13B3FC1995ACD0D5A4970 C229FF0F5AA3FF122CAC89645D0597B02E075DB91903E04F1EB4BED57FD1FB32 F6A3569044D41BD71F8548F8B1DF83F468D5CFC9484C5FDBA2CAADD81F35DC55 BFC76826BE1AC3AAE071B00C9D85905B2E65E4BA0525E2A5D181D7E6B8121835 DA1DC435EBEA07CA1CF7CA45E5968450FEB935764507CA2A21E19882B5A30789 F3D4C39270A75DB4462C63A0B6D795D642190D575C3419AA7676A3C322FB4BD5 0B779A908AF0681D834DFDBD6686D396EC0BEB162BBEC8D19356E152E04F4DFD 7397BCB2F6BF9739E25CF526F45B6665B82189DD3BDF3452162A35A34391684E E30D969A19561439952DB0C2F3F8DE2AC0C6AAF67D70459066CE0BE387CFC2AD F4EBAB73776E7B25DAAE81CDA4B3259CEBD087E7E26F3A507D8555E368B917A0 768A6C447CB399037EDDB3BA2420344760F6ED7E6FBD75977C795C457210DE3C 85F6EFE29A062C8460299CA5AFB294242436BDEEF07E690C2945D128F9438630 EE5B300E9D90770698D8DCA31F260170EEB54CE201E61862259BC077A768597F 9468C5637E1E141DE2644F058C01113F2D533C84D7BD52C64E544959B43E5891 6A6D8C082BBACF47714565D427CCD0DA4F2AB823D9C0D4B99B946379B5A7E7B5 433B9A8DE06528D3573775794DEFAC69501F1CF6EFD9E1C83616CD3A9C108698 F3884E1CE4CFDB3D8C5F32233104A9F80E163B9464F5923243FA0A64273DDFA1 C565D4EC246FB1064A02401825974FBE0C17422B71F1F942BB389DA59DA87A77 59091609D31B3408406D8F1DF7416A7FE7063A503CDCF91DF4655003454CF93D C2E85BFD19567EA7C79D39A13EAD3239B20114A5AEEDC690DB077ED1DAFDC2FA 2DABE2FA79D170DE44B561BDBADECF4C73B7EB4A4AB71FE42FF9C37B2C609542 0417EFB11E568E69A54B519859AD5978FD243D7AE255D2AF18E2F500E5678EE3 7F991F28B404DFB8D1E6518F5985886CEA2A8B553F7B62C5C5497F6B79F694C1 2B9F978A2E2A59F8B16403020E8CBC71BF20B97908D6FA8F9D85AFB0092E7CC5 38FD567D69B399D3E21121E3D9ABCCC25FB9212EDE6527D3BDFA280E28B55B0A 0D22B1CA77DE8B3181E5E2262098327029C2E8B76657A40B3BB76D79D041D398 91DFD8C0EC2F4788B83C59784A1E54E91035EC65DFBCE76AE2F1FE98A9966419 5A920FC239F97E12B40186467F4FECAF2C88FFC87C846E94E394972E701660B9 C2069076EA389AE2391E44B4457469D677CAF816001D373F368AA90600E94382 61AFC191284C14774FB9454F342F7E010B1F1AA68FAF1DA06566EFDAD2821016 61CF8F45162457521F31F8E710D103F7FAFF4269126B48BDDE9BEEF7896CBA71 94C1DA72CC7E3972DB5E6E7B0CCC771783FEEC51489DD1A72C95AB97BB407E0A CC5355895F4D7616505CB27F53885AE2C67A870E9D9A8D14697EFF285FD6B883 076602764B263D6B9BECE264D19009D10788A7AAD9766604B65951E83399CD55 8C9934744B0982DA58B7E0B86AE371F88916F7CE9C3780E33E634FF1DFEE5C61 FEEC33D547A179665BDA466A73C8773A11BC6360F1E032C33A10767A04A9DF04 054EC926026DA25D51A46EE58B79B72E13B5F8B0FBE02762A656C5EA2964C2D9 F7389E4301E903851F015D1A74D1D1372D21BC4343DB4D790D552E9D77B5F2F0 C15A4520D4C8D7902CEB4D2B531CFB14DDC435F172BA8309054535D4C10F40F2 9056A30768599392AEA03F90ECE5DAE55E5C28688A2972DEA3FA3F1C730D6B88 26F5E1FDA8968942D28D34E0D95377E0D3F2330D2C81359299D326F98270AB9D CC4117D6EFD8829F136E24CC2E6915D47A897EEF0CEB94BD4F5149B411E6D0D4 11DA7F2296DB715566D32A57E5E229DAFA6A47330C602D778A9CA4B9A601761A 5E224350C95D7350F4BD10368B9A26E1D4CD5F47855C3026A43C045DE1DB02D0 D78964D5C9FB29924821F653C86C4A787731C8A0A3D3093085EC373DCFB41331 BB872A5581355CD86B96483F337C807C1111EF7A06657B71C1E241F559290BE7 19F8818E560C7D64282E9A503E6E562C22D9BCF0FA355B428482D66A81837FDA 3453972D5FA65D96A214E3614CC68637603C9865BCD81F1D0D7E8214F30327AD 1052E8671A35067D834DDF3A3AB3757D29639C608BA577442CAF42EE425217CE E42474234C8118785CD8CAD79148000277EC953C6517F9DABE6C645CEAABBEDD A6BFEBF2AC8EC0D8D7DB43F4C328A9E1117E316214BD4B08C994BD8D4CE6231F B6AA4DB98BAA20BF454E25ED440B96E48381BD10AB444F61FA96852DD5275F40 5DAAC5369650A0619C68A3541A59EACAFA2AC42B87DC2C2C53EA7B679784F637 86842CAEB6294A4C6822D915C801A4412C38F4949F89257B8BC3915336044190 2C88377AAE579017415784809839C06F9A8ED56A7342067C47D32240D835F6E6 A3CE8DC905D9959719657EB68AB16C110EE30E23D141DC8C74B161A800FDFD38 AD224699A2F16475999E1D74FA8A73F77251B081BE1D837AD5E333EFA90A3DD1 10F705FA5D88F4B8BCAC4070E7C2A9F04C4B7C905DC0A06F7528FDDC6102FECA E58D27E9055C393797B336899FF5075B4D37B783958211C40439A73626ADD5F8 3295BD8474E9A2D87A92FFE43F7ED763D73991B3D28D380FF4186ED33AD65666 4632B6E41849E2AA43D8D5E5F3015FD8891781C3A34FEB7192A52E3BEF129061 5BB3E6E309E0AFC3D9CC5B04D0CAD7A13FD4A435A1E6464D99B18E98A95EB745 1D7786D83B69E0A83A5566168CA3E50918E57C288783D93CA182B25CC5D1B192 A0014E80BF9F9FEB27C2D8530A8C3B50F358FDDF71D32FA9ECE0C669C03E12A9 00D3D25D4F05F076C55FB467E2F3B5F2E7B611BC5AC6069566DAA19066B51C28 07643C9BDEB5316C615F6E7A287953A4F5150FB2B562A6B036FA4BF90ABE89F5 DA4202B500B6E90AC2795D83332539DECEFDA65673AF0CE1C8F6AFB11825BCEB 184AF6991A8BE7CE234FAAE83A76BB6F786DEDB9CB0E3C151619C6FF36619FFC 6B21212750ECC1EC152542989BEBD49F84FEF4C2CF83F395CB5B0124F1CFF0FF 1F0E3B0DC0A674432256F5C491DFA028C9F1CB6735D3C2DABD9508C08F3E82DF BC1BC68973964AB81D012E103027C660873714F9E247DC93CBDA0220C4A3A59B 527EBC6AA58F4F89ED1837E9D0A6B572EC73E764D05C45D77C3D7439754281CA A77DB342D649C75879DB92989DFC0D293BB2318E11CD0538A356CEAD97662E2C 5BB06CCC853B6E186C68782CB641271AFD13B52AD6C61957583EFA0FD5560B7E 87AD9A2AC85B506D7677E95D4842B17E1E8D135B7A7DAD9AB28E20DE65B5AA43 6EFD81B2ECBC3F2D975F4ACE103FD05388059841878A3DA448E31527F62F479E 98418A0D6265A9EF4049AE91E7D9644C7B083B382988C235F8B57E4D6E997493 DD1F3D2EE51F9E295E3237E371CBD214054BA9FC6F3B6DA3AAB1F472A735385A 36AD7D9AE659559E9470C6923DC080CC3E496B7213987EB96A2B1787030FDA23 E27CF8A50C1FF29936422691C74E03B197865B66EEDCB85F0EA2FB52675E4528 8E2B3F57C07F43AEFFCFBE7A891DFF7E4ABBAF4D68A3D3565AA0CE8D74E8BEB2 594C0632113797CCC6593BE39DED366EAA218D7098F18ADDDA9E89265FD8D01A F842DB02C03FD0D605E5E0B7CC009C8F3B151BE57D7B2C537FACD18F19CBA044 21DF038D898DFA6D396697DE9CF67C8A86432D8E9449A35C57B260047D59B677 CEB6C2481BBF064B7DB5C2041D5403EDB955A9E3CF6B3286B7F225C67A7F16C5 5B067A40234781DFF3C798609482147DB6F8688CBB543A98D067B489D07D7BF3 BA998726FCFA82A973C9F37E9A6AF2D9A1086EF0D3361D0AB41B0A7834545294 455AE610339A30E9D1DA873F2C928A3304A859D98C2AE3B0DF0C168467B20720 E26BC985D885118AEA16615ECB934BFB600F58C43EEBF6DE56E8E946720C6B51 C0F50799E226E88FBAD27A8582599F2EA4500FD73B35B8DBEB8748BA48E0F931 32FF05B3C2F06BD00AD86443341719627ABC6FBBEB709848FF02492BDB555253 5CE466C2CE2A907E2A75DCD807228D7AB1600A49C8654C33769D65985E5AAD72 FA5E3111809C7E91994C1D1D0F45197C7C3BD368E4CE2FD9AB4D5AF64F82EC77 BFF8C37BE4205026E0319414B3E5133BD9A43FB56930EFCD846032D12EF18AF7 420BBE3DE513427253E9F3CC57300C19385BDD1CB32951C7F6E5E8E2FA6429E7 FBF6443E283A2FCB0B82EF6F7EC4AB9CF0E3C8B08206693ECCCA01BAE88B7A49 D7E74CE274CFB186696DB292E186432C5CC60A513920219A9C3DE1C7ED5A1BBA 1ECF0CA7631FD8CCF17D84AB3E81FE5A32846334F0D295E6949E690DC70C3381 9A274F2EC32FC0AFC27CE90EE8C3B1E15427DB427F8FA38FDD0ECFC086776220 36695B90D29599651B032B90B0B6722BE2F533CFB698AC0255083FF3F42AB387 9F9C3E30CD618D8723910BE458B43A3D1C2B921F2771A2D276F8A913F021D573 1F0E395EA5D3CE55A97F2BD9E1B6AD2FC3C2B9A4AF06CD6C849CB08A5A7FBE64 8A8D2F3ABE241C2539ACC235797D06389C0E6D5249BFE7D618E5C6AD6D53EB2C C157554DE510D2ACC92119BF5CE7050BE209E73C0EF588E027AEBA8A28373901 ACE1E9DFA9017780009C1CBF4B40B7341777E7598BE81A846E53596340AFDE03 D1D1274C0F3241574605591791D719003814459F0F0AC2525DA4029769AA1D48 CC7B155976DE96C45622B48BEC762028EFA87A839D70015EFA7FFAA12B256FAD 82A0B4477ACB6372136AAB81E636CD8FCA3516D513A048F34512336F94DAF510 4EF1B122FC5389A88F1D8B2763473C5E2AE54F8220971C4858BB10D38C78F05D 9A4102064B95E61DBC8A3D496C55FD63A4DFA95FA21F813E1C18D9154D3008E8 C339F174862B7DEF9A45A87DC222E362B91AAA50A2ECDFBA612E1A75953CC14D 73E0AE25E73862A0AD549F0FEEE2637A8247CCA21889F035AAE3E8E2FA6429E7 FBF6443E283A2FCB0B87D102B3602546EA6208DAFEADE6308DA8EEB9EF24E11E CBAF10682F0EE1A0A11306EEF7C6B9E319D1E74EE527B758BAE3A344BF6CCC9C D0F3A3BD3D0F938D3F29A8376E43FA45BC0573225EEA3028E769109A3CECF939 5965CD3BE30570E6B252F055CFE15A28BE63343CBEB9BCADC17997831D98B642 84AE40634014DDBD70D1A7A4312F68701233D2EFEADF3CD6139A05C899B59DCB D8CAEFF81AA34A79CEC11CA7D422CB58C8E21FD3E1315B11F3378473F6BC5FA8 97BB4B1B8C9B3210B257A4B5A863C4EA1C017E57F9DD6EEA01EC7FBE23E81118 7D512DAD1E9D80CD1C4B4781C6C7EEC99594A7A8C7FF2E7C2551076B259A086F D97C48146B5F31EB143A2C90536E57A107DF025A582564C994CED6E97BF4AEC7 CCD0268F14842D16062332E35E5D15B52661A4EA33999BA08C604A535DE83553 49CF77786554EA201593312619C7D6B638D132A8C4562DEAC3EFF381B3DF1D33 855FE2427336FBA63171D385F2B24E661A58FC9C6AE89500FB15491E2407ED9A 9AB80E850BF7447E411C842A3D61C78D25A6D7EF7327B65A190E11786E7A1D49 B3EB76D36B2A1CE58CB3D2CFD0D1237B3FD44353087EA04ABA776B70E1A12387 BA7E492D3C106138C21F43FCCFFC795515FAD3FF37BE754B4F0E7EFCFA401294 836F632C783FE802B6E8266DF987724975021FE4ED7538776CFFD7C2D17C9728 C18D2F186DA147A47038A0DC7551BDEB6830166E3EDBD8912A0C305FCD339E17 526479B4C390D8A6292E5CDA5E341576E55814B0AAD492FC6BFE764199706902 54F648420C6B8ECADB543E90A90648778B2E2DCC9C7932A77E7ABE62252BBAC7 8D1B54A4A54931E73BB6F7E0A105FD442E8199A95349E35A4EF76A128CDC1ABE 9D67AEE06AA10A5F8950F5879209A77184784C03525D082ABB14D66A5299662C 096223E92CBD1B1B943C1AA99370C24B13796D032862913E62047B916974D336 DA89509095D7B290F52F0132938BC6B31E4ADB8F26F3980B753CBE7EF196BA32 01D6F24499ECF3DC28017AF1DD8B9121561425B6702EA022160A3AA6D8AD7408 47322114D27C81B8B5DA43979B5A135402C14674BD7997457B9DDA5A95C556F7 2F4036E9CBCA5A92C0AB086DBE301E7B10A725777818CD7361381DA6C00D84FC 2A8D3D536E7AE9B17331876B395682C415E0C61731D7156C5ED84E3BADF70BF8 C91EBC8EF134ACF650F8DED74E1FA12FFB5346D7A5C5127E1F8D696AD230C6FB 5B030BC8B2B6056923FC48BFBA1E38F36A2C4282713DB21C6939909D5294C6C7 1C4861F7FF37D89A47251F5B90A8BD1D010D3FC266EB5850D333ED1C49CBE7C4 D84625A0C651AF60E25167D87981F4D01BAFFD11FEFC9FD4BF8ACFF0E6AF4D8D 220688A520C2A253CBBBB90FE593BDBE5AEE9EFDDF9A706965E71016AFE4CD49 A71C7040444126729E7FA45B9AD5509D65BBD302D467899ABA77906C6780C69A EE788DD70A36B6AA10FCD6E70A6296F807558EC45930779B7F2614434BEC3351 C00DFD29F397413DF96FDF096070F045637BF6F46DC6CD4FEA8E1A5D85D7D2E0 2A67D1DD429747ABA09AC814872215E63776442B8387AE96D8827B8E9CCE7A40 0C90DC58F281C574704A8EC892960AAA0BCCCD7FB910F31868139CB79AAEC810 0AF69F70758E365D18FA06419D43D12A32B44F2E6D1BC4166512796FB320785F A38AFCA91D4F728A9F427C6B6DE2E51387367873F8755B70B70EAA8A5E6C025A E551D8FE5D6A24F0C8652E70A5A16B56402A36E1F506B20DDF35F6E45CF953DA EC243FE25DC85F44E84ED069BD93767C7B2DCCC4ED4925CC1A998112F8AA6D49 1A97D932FB94D9C5E8A65FBE05FCC0D5E9AB36FC7CFE0215F94A2CC7AEED90E6 9EC9E1ADA3D27650D8FD3137B815A5A3850DAEF5934B2AC917DCFE5E9119FD1E A560312CC34E1E8D6734E7076E8D2193932B565F10FA90EAC371273A9AC5717B FAE027B8B6CE2AC29865D5BC83F2E78C2EF757CABD681BBAE2F834956C7787A8 4A179B602AFA49FFAE3604E275193CBBD7A8731C7368CD1E40099F7A500AE046 88A862D8C9DE88CC2CB1CBBA3E11A38B056DA716700855BFF8CA93F0A7AC7FCE B585A174C87A29F291E32223648C1E0DE52AFA8BAC531D4E1C1FB5A68C67AC57 B8802EB35DA5C4830CF8E30212D509A1EA7D24C28202166DE412AD59281952ED 375FA2D308CFC6BFD45280353DAFADE081A76FE2FA3B4B151579E61245C6B426 EF147AD8C2A90B9EA7261EAFAA05B11F0D9CFF9B0BB034C8EC9FCE61FFA44D56 831E2B0A817C17D50D661F8AD22517987800940F8BA6BDB446243B76C7ABDA4F 979488DC6218E918453ADF92C42624D512E3384BDB6709BC632656DFBED584B0 F56AF1A6329DF39B380DF4659E33C0B37C3F916D7684F3BAB22F1745D8620386 14FFAD1E062483D5D248A0DAEE658222AADB25664AB2C372D3F6237BDDA5167E 3C09F6E37FA3F0CFDF8B23A4659EF0FAA08F3E1BD7503CD427DB2A534434D361 E0B0A9F2ACA8C70F1CB9BC178F130B3D7BD0EC9428718DF2FB7E5634C3A62D8E F40B50A4BC2449A8E8523E11CEF846426006329D340EEE42B4F4732889790F22 FA156EB858681DCB1F09A39CF240990C2BEC2E7B46F86C3BB65787F072A9B114 AEC1CA30A07C4C11B8116634E9CC5D9F226359B0D0DA1D46AE862931CD2992D9 3FC8A78E5A88858CEF9F21F997C77A108C505EB38E048D94DA5864148CC34404 DDBF97D882BE1DFC802CBE8673254A3655D98A14C64BCF43CD2B834A6D01EEF9 3EEE15375EE13208DE14BA569F6512033F5B984BB095BF1EBA416123228A79F7 8E0C9556D3492D26324782F786D66629A9905FABADFC8AAD2A83B02FAC3C4FC4 5050FDEC3DAE8945CFA9A63415A0CBD3F0A6D550FF45DBD5E38B5C512F842309 EA1C8257F0BC22F398FE8E21EC7E119D220A197516A394B1C25102862435512E 39E39270C3A6F137E96230405F4B4C7E2E37BC5693961948FBB3C0188B2228CE 297C69E3F381D2CF52E68BF6B2868653BA55BF55B6746E856ED8A22BDB426F52 485729C2EBD87A1C043EA1A0C50A6483D5F723FD6D0BFB01BEDE9F74497F7B32 CD62522C1CCA23610FDFEBB57250D80E89D54CBD642A74904602DDC56B1984F6 4EFA9C8A8D56B0DC6E93ED9D24223D6C4CF4A2360F7296C92B04760E9C6C6164 4F213116A6DBBEB0C9784A4348C7A8ADBF4591DB780C2EDED8EC61E261BCE6EC 7A9B96EBA77911055D9390F968AD89CFE5908292286F8D46D6AF5D190D78906A CE661BF1DEF099693567B7222CCFE9F227B5BB96514F5EF32E4D559217B35786 577ED3D55905431DA0303BEAF123FF6F80B4C9AC15C3F438228E3418E15D1F34 ED1261A36005E1957D875A948EA6E61CA2342D7A63899555D2BBA295BCCDF91A A918766C82A978B7313B8D75A8B1E3D89BACE156C015FD5C20BB3C26798E4B50 A332EBAA6B6016D3DED4F1EB865C4171874BAD4745F085DAFE8565A494729DA5 302DFA0EB42690F4A8C2E17A046E6D0078799186331B3BF1298338F4E761FC7F 1F40A15074CB1BEA0FA116002CA02CAE79CA2D564F287AF8CE26F100D059D1F7 378FB4AA1FA76FD8A0B8A48679EC698FF9E0E6021817661735C09D9D005C3377 14AE5E1D63D905C3207EC9962A7ECC295E86E8F3BFDC2A5350D5D20F26E78B8C 80E92DDC5E0D50B0C6A3A3A35C4F04D4A1D542249CC9E1F636FD711A8E4C2539 A3C17FD3FFBD1A8EFBE67BB0961C49DA434AC921E2F2AC2B228F3DB9437B2273 D5C097FE972352DE294B84060E4259548C76B5DF85D2A77636909875004FD02A 97B54E9B468BAC685829A47BE34CA32E9B8115F2BD0997906704E49C9537F600 44DF6277B14ED66F8F8F6A1656BA97A286537877B9BBF26FA22D376427AC06A6 DBDDC1547DA09F3E799B1324CFE6F8EA75C8DDAAC242D262025BFD16743D5E41 F80021C34AF56DEC6294ED7896326E24A0D4792B98B35870C3DF29F96004362D 6B0DC629146DA80B304325E3CF06E9B2468083435F79FC5141E7B426D3A28DB4 895F1F95D5F5DA1F6A73151BD3DD30D3DAEF27125F0BD7C0628EF54A497AB027 198935EEA888124B921FB5F8BC9E9DDFDB255719DF0EDB7782FB9D24384AE314 BED285D78A786B1A04B82AC33CD610B00E828EA0B352F70D344307B49071FB18 714EDE7725C8D642D169A455E30D8DAEB8B8CE6D73403FE62E040FC34A3A28A7 85DB8E1F6B72C0AEA2C65E3AACDC376C225BA8C86597828D6D6DE43182306430 3C787536209011AD3260FDCEC2B61167DFDF66288A6607A85B8EC4A4C5CBB5E4 3CE0F7A615DD8A215CA1DF20DC7A6C18D0F50A7B1961E581577187EBCAA8C7E2 A66F97049C98B68B1E1C0E89E8C4621D16846C8FB2D672CAED72650F89E7E0B1 538C5D066066368DEFA769B4930DEABA7D32C3F37A9269C3A48161AEF571DBEC FA34C702038C74F29CFBCE7C280BF79FCE3F6461B27E1D67ABAD04619A6B73A5 C98CC86D69E5D78625CA18C9C661B3F92F71CFD9C6BF230152214C67BFEB02FB 23336FCF78D45D2DAB9987EA22A45400104934F94EC668867B13945959992040 CACC7E5B5A0484DE28DFA267308D2351BFD4E92219149E25F552C1D5987B3B20 B6CE4C06F84377AC07E9B15F4D96CDA004666BE470CD54093F5C3B3D29F97DF3 890240F7673E54BFFC596CA8703BEA9FD601A8A4AE62CDF5042F09825D9D918F 3BD37EA60C1F77A6C8848C67F2F620C9428EC243C02586AD62A56FC5AB99A90A 9500ECE26C5AFE8A0FAFD11AB0633C816C3FEA2F97D671F195D27FDCFA7C1A92 C23FADF09AFE275D11CD3883A31AF8D3FA8D9E62BC7B0BE5614BCDE5F18821EF C3824480793BF893C52733A2764E788808F85C056DF8D51FB2F9D57929F77334 570DD073B719BCCE356984C42401B9058D2087A48697A00339259B6698D0EFEE AAE9DC0881D81604E3B30B8B42D0C2D6CB76FAD8AE848188ABA8EF496F6DE0DD 42AF169E62712D2D450A597EAA14FA1A81FBD3CD96F4C3C84359790EEC08E7B0 8F1829DFC0BAA3AD0D7F6727000F9C62338F7EBEA6AED7EF979743EB77ED86D1 90A60FF0CBE1C582BAFC89E27545E24B979DB7A71A64A50FF8D6F9BA0428B76C B4AA180121B7106711A72719342AA0A045D56CD8D6CAF1FB7EE5411C8E41C38A 43EEAC604BCBB67C1A79399593D71AEEEEABC20A070A6173E98C2F07DFE69683 CB50B107CCC7C396B62A71B13808B25AF98791191B962D61B40F3A5FC8993BEC D923E542578E398AD21B64FADA2AE36099CBCB1F2761BBC8E28CF5E5CBC4569A AC25056B7892105951D1BF88EED34A5D7EC5BCBE99BCCC63B9902510FE6C3152 D829D94ACACECBD01F60422EE7BA9F84C137929BC8332375C90737CE43B15C46 35C3605F82B982419207535C12F48EE2580D08DBEA9CC0879E7CA668FF3BD876 ABB790F52219BF835B372D0D0FC290D982620725C2A48AEC3F2E8C6CEF532436 84692F358F26A83AA0054F3FF2E65C2C7CD975B7941FB6D5846434F37294723C 825B0D6143B23F6C200EE4D7C6653CC2F169B785AB3DA16FBFBBC0A5DB12AEB3 B4714EC451AB5BC3239D1A5BA328E8E655469D060D4353F326D236DB9DEA67A4 085B44C8689D5B67D9502E4B7297D1A3755BCCDEE4619834FEB40844ACCFE815 8F0E0A990C2E78D9E7ABAF7E72175BB67D0169F02935889CAA3A54DE3640DD5F B4E5376C606B0D79B2E316C10ADD3A13C1C8334F7FAE86C0F1380AA0744CEF6C 4CFD5668912C805088E9FF01B22C0E33D6FD92B868DE43BAE6A0FEB3FF04F3FC 1DA85C49E17A96C5076C49B4EC2601F60CFACD36E1A483445B5EA6E6F46FE853 2B2CD417D3BDEDEE9C2DAE7E6D248BBFEF50AAAE945BCF312FFA9FB3486C2AEA CB923949912A1F485EF202BE3B2323379695E7E24A345F755D57EEE0B7B98D9A 4A9A2438E956F584599D02F76E93A6EFEE514B8671658FA4F44A0E1B55688037 66325FAA1A2AC063F61C9FD185D5F430C68E88B25E67A8B4D5AC5198E405CF30 5067D2D302DB50D1598C2EFE363C31913C4FC10141D68652D7EE5B8E61644F26 A7347491F4AB1714FA40D96AC486144A27AE6A8DDD0AA03943A8BF68ADE3EB55 DB14D5999DFF6F717F8EE50675DF3F7359574B2BDED2556A356611F5106B4914 BF137E1EA8EED8CEC0234E07BAD15A22B013FDF3307FB0987799F1A6E4865F2E 6B153B595B877D7ACCD6394CB50F56EF46402BFBA4BDB61EE45F2EB4344657CC 787466CB6229130061A6581E8A9F48175DE40F3F1B5069FEF2432F10212BD15A 3938F83B8E7DD846643CC18D86E10697FB6766CA99773D34AD44CE5BB1A708FA 348C439BE79BF5D08F25EBDAE2ACAF8A39203A5681E35446D145400AA4DE5BF8 BFC9E32CD142DE3833A10F128772FDDAB877D39D518687A54A7AC0874061D3B4 B6B0F86F69093BF663259FD085D61D3597D2B5C464A9D95446A87CE61BDBC0CA 81ED1DCF61F10934191C104A638B02C078B63B17C3432CF71E931C4AD5AE5EC5 3FCBB22AC8F22E3D982C1C27CB09136B2EA833433FBCB8D099593DD15953FDB0 DBD513CB332FA4E69106EC5A14F253C5C983AB5B845CB7E96994004894A17512 9300F956C596958275909C45457F8D3D36EB7857ED75BF53017CB156EE2F2308 3E86DE9AA8C7B58093EFF706B129721A97E48B406D6B2F2A98D29249A1C49FA1 2D4419187A94B396AB0C4921FE539E4BDA80A6F2274EA5C29E054ACE80A737D2 DE049EEA87D7922FF2E4920ACE6D50AFE391014926110CB18A5BCFD452F5473B 8285A425E291BEA061CBC807301632F4EE2A27656E6FE5749069F6868B8B4F09 1AC6F497D0CFE52BB705E5A9DD0D86FB21B3D30C02C77978AA3E50F3581F2B2E 0F9F862E5D36D273BD314994D871C6CC02AC3B9BDF9E7E7D77565EEE35A7F1FC 8240243B13D79864AA4DA8F143C672552C622FF5C88C33C8E2D8E23805FED20C 0739854FA14B5C88F53908837FA899E3FB8440FFD625BDA46150284E4E709F69 00589DDDDEAE30F789118A10A2BF9BA68F3793EC00DB82584C47330CBB96D3EE E0741E96074019EF7645DFCA1827EA80BF663A842398C0FE69201A619C84B1BC C769C28A515EE05355D1DE06EAD8A3F18EBD70CEA55A4E95225E5552C7AB1604 14C567CDE5B7224151FA38FC7515BBAD3E2FE4D261FB3FB7E222FB7AA3B19AAD AD4454586F607D1B6F53288994F5CE18FE768ABA7FC8F0C253ADF4E6043DEE42 5217CEE428B19BCDBB89810EDEC2C94D13D415C156077DB30552B1E7F828145D C333A77FFBB7196DC626971884A2540043B1C4EE64CEDC533172A36A2B614C3E 62CEE4D2D57A88623EF6DBD136F91068E9B746DCE8DE3B2E3D48973E146C5A18 1C0C4119D17C560CD0AEDD84083D8FFA12368BDFDC6623F15CC5515C342FDF1E 836B7AF9EAA4CDDD997DB4E2BFAB6CC7B2212C74A0576DEA8F8C9B34FD5069B0 0D1B5BA2AEC0F487E99A6546157851DCE0CF45695BB33F79F53FCF8AAAF28E5F E6639DA2DF5E249C62B933EB55F3F40EA4FB7E76541FC92C6393A857AF2595BC D24F5DA97DD249F82300C96FED2A8398666D754409532BC70C3D4094F98FD5CF AB2DDE6BC1131EC7C1162573F54297D7D0112578F812E5287CCB97D9293D6223 83C3600DF6B57520B8317441CBBEFBCA48B9D6585D05527622EE8786CF1ABFB5 DDD86DE6038F46D39318DBC755F89AC21FC387E064454212E7629FDD358472A0 140641B4C74D80EB73C8244135A53356B1F30F596CD905DFC503C6DFE72D7759 C8995C7031555A4E38FAF0AFA050BC0E1AB8CBA5D919BD56CF34DE3A655C20C2 72F049D1DF66CDC5D47F08B07F4B3BDFD76950BB0C1540AD102C5D3106C27A7B 2C00372EDC99A4654DA95F0E7ECD3FE9E51E1B36D92CFAF283AED79E40F57D76 4D869DF6EDFA24BA3F8E2B3489A9462F3A27B3C7BA0D8E256BA310F19C771A3F 9EFE63A8F1AB2ED3D21567ECCD4DAEFD40C0014785CBF6AE954334D083A389BF 5D00522539CB573167B82B1A9CCC6587F9AD0BBEFB7D4539E862FD9A5698548E C65BFD5D2E3CDB4C63F5B008F8FC167C762789D29A978652490A31EFB184F781 3877856590DCE05692F5D3A8F8BE7EB048542CB59582906B55E3BC30C1FE9277 4D0FB3B99480E25614F8D87ADD0E7C187AAC6E48FC6DC38F2811A9C0A6AD6BB2 BA2182E2CBB009AEC889B4F686640337E446DEA5D0038ACB311863ACA97BBC1D C260E3A7B7249B0B51F776A7526E137348BE5E3303786A7607BECDD416F7AD73 32C30DDB469D66A81A5BC61E91F8C096084CF54C04DD72D0F7205DC1FBBB35B6 AE08FE8BE8834EE0CA7341F16665D0EC4DDE1F8A3453B331890A74C6B8C95F76 977E198F0FF28DD7D5E6D4C266ACC900CBF17E8709D2BD950ADD6E6C3D90F4B6 59CDB303737E0259ABCE91D62A4FAD4426BE815A2A0EE933F6B014CE9C08665F 55090ECD68E18C8694AA0F99EC4F3A5FB9576892455527DB449E78CA588AACB4 B028D3B2494A6D6CC7A175FEABD324A32605653B69A0B27DD6F717211AC591D6 7BAFBA23CB8080FFC16494477FDF68D8419C2FFCF0B37B972447475CB38C7A63 446E5660638A7BDFF906D336996638B11E9BCA1A4B7ECAEB8172BE08C6542602 2112C99C5CC1DC9280E13DC689C390C0AAF406F5022C5106EA512777BA49E80D 332113F628EFE2BE74DE555DE8F702531EA5A60DEDBC9249DC926E5811ADA0F8 765E184D7383DDF5BFBD20D50EAA7B9DE349F6B829C08A42C5E6D9E2D27E1C6E 7AC0E79B4F5F52577784FC256FDE30427CAAF45B1B541891B78E076FF023C2AD 6FCFCFA517EA2438E51FE647B57C7616CE321C02B0165D0508583D0BDDA1BEBE 4CBAD7A9C93FF9C7D5CF0D6BDF41B24A14735311585E6E9927D4775BE16900DF B77104F659C4A391B11D6AD08086609D3DA10639122D78042F3750D1FB69E8ED 974F029ECAB99C618D1EF9E9ABF127410BCA76AF4AD06985FBDFDA6D3FB9A2B5 A4C01E121EC6400CBABBEDCEF1662AE97D3F7336F918E8D2B7867B6994E2B35A F8A17DD0248CE95F03BD83B701F2F47A95F169647ABFC84016D55A0DEF4C5AD3 9FA7755ED9770942EB880572BE1D5BC14668452C9F3F5457AF842764D4B737D0 DB9A5488EE3D7BAA012D3C080FA8EDE859409DB91E759F8E93E2600B868A533D 843FAFE1383BC817F292CCC4E0DE1F5F5EDFBF14D6191D511982A5D8EBED7726 AEF53DD5F6D86BDDF9F66CDC2D623FD3612C77EC3A0A21DB3A067EAF0818C09B E1E3E60AC0270E179F916298A90B79BC7372D1C0A947F8AEAA171FF208F17B48 E13D922B92D835D846CDF4D94FFA70E5DC628A9EE0C46EC0905A2CE2B0CA9876 6B0E6759CEE018BD3256784F9E9422F5EE5895040A4FEF9752119931A09862E9 FA3A3E10881D95D6E57D6DABE86C80289DE6F997D891410923A4B57BF03C3756 A2E8BAC521DB5893C3CBB18094E5478E989B462240F9742A461FA27F05D2FCB1 15C31C80C9D2F842651D1A8E1939B8E584F897345F33726977332CCC63BA080A 10BB20BEBA9AD6C126A72ADC4D9762CFC84F7DBBD1C8A82941A3BEF0FA85C833 94B5C361C205B1CF363D965F07FF04CD85462774EEB98FCE14553B862CBF5A07 4D135620BC26151D66893E312892B18CC51005CA5B0197DD2F6109643A183DDF FFC2851569C402F737EC89B361A9FD262DF82DDD74FEC13E89AE26C9111EC14D 4ED775D6AD9A9A3855CC7BBDB851C58F62534603D4137939F759CEA67A6278CD 0E603FD1A9BAB3408606D13D653D8B0CBB1D6D2C62A3F6B7D8A09A53D62B21CD D85553D0BB8F00C3189562105BC864CE15AFE5B02B8A3B514BCAE1BEF9268558 9F36F15BA84639C5C1AABD38CFCD940A121CF88D2C59FF69B34D18E0E9998980 053EE97FCD238221E8E0E5DD1DDB2B1CD15434CBA8B4E4C87ABEB28963182772 2B74EB6C678F3BF0197A76FDDC3D00277AF0F9FB94D4CB4C56B642917B944666 AA27A37B983EBBDAFA4539A6438E26C040F9503C875232255404C38039EC2A71 34797F6503FF1180F4F19102ECED38F4EB1DBA101B4D8A973318A5848125FC37 5F6C07F6D3C7D88B3F6C02F89BA6630E748CEFDF7024C744D404E6C9EB8A74DE 836AB86EF03CE62E38E0F209E58D71248D2CF5C0C8195E04D09E25FFEC19F7B7 294A9FAFF3018448B47F563B1BC307D28F95F43B4B6CB1316EAA4C14832705F3 7B72557A6FB3DD2BC1E9C4733EDB2538301804DFB91962BDDCBE681A2112815E D509FBC6471FAC0F1A705142F8FAB0D292E84A0AD107C511E4D2300231E8C781 9C16F9818B9EF5C5033D454699D34DE208365815BE9F59C5F0398DD60110A45B 3CF7B854C4BF36AB1807E71C9E8BCB458C6FC2033B941F11DF46A51F36E08E18 3CD3F00509CE0EF32CAB3866965D9BB5DA96D07E213C47BD869B1E74B020D93E BB8C77B745B21EBDC7D3C610C2900C6A49DB7F48D70E952F9225455EA92EBAA3 1B386A68EC819C70C784BB742E15F37094573D882A536C00BA83E7B45AA937C3 E4F84E3F87BDE2AC70FE5FEBF90243199DC1E4F874D93C5008FE6517A15C58FC 473C70CF59CF25C6BEC5F77D49BAE108735ADAD9879520C633C46F613CB48B72 AC3545211BE59FAD51F170BA198CFB7607B6B044160CBE8D4CFF0728D3B0B667 3E366AE333DF6520E00BFAED6C06068374E935385ADCECFB7B49A95CDA39E996 555DA9410069FB3F1F51421F24705120C9C021ACE47863C0528738C6C6322550 A4A31267DEF773589780841F7506A5C91632DA91BAE681225C8C9E67D05506A9 67E5BD2FFBFFF12A09BE9BBAF243220747F80F6B9285B677FD6B341C7AFF57F7 1D09BB38AFA5F23D5FBED728BF7823BC92398FD59D187984C5129395D7B290F5 2F0132938BC6B31E4AD74A32CFB7CC93CAD84B6DE80B35AC8262335ED93A6365 E3C9181FA1CBAF4B0D544E7A1DED56C3AADD8ED8A443251DEE5EFECC8121740E B4CE6FAAE47D226BF3E078103BD24D920B6DBCCBA1E77C5FC561F61D00903894 30F2D4FF565C7D3F5758AD2CF636B2141F30D216EEF18F9BEB6D5F97FB210D86 C463F2826C679CE44A18722852D3C09C48A802A76053EC38986EFA0A8768FA0E D545B14D0663EE1766834068E600507DF980D3D0A56E9AC50B5D8EF292B31A17 1E129FD3D0E8330E2F435075E58A59A73CB383E4249689A4DC878DE4AE71C15C E86AE6B807FEAADC23E999934DABC56DF9C001F5A90522F8508BA61999574106 A8572528C6208AC39FC1FF5FE60F0B23FBF19DBB3F8D37C19E1D4A4535306D53 CB87CD3DE08AA4F174F5BA5E02E71C6A371D57093096B8C9A03E340ECBDDC3F7 0C8DB568A8A357761820EC28308602D96939D6D863E40F8653490DCEDE9E7772 808464F724A5D21C5EFC253116A6DBBEB0C9784A4348C7A8ADB06C3FF3CAD255 BFF140633F393060892D5B068045D2AE2EBF76B8477331B2A26D70EEA6214A18 5E024AC6185BA1F2CFA784EB155C3FD902C2647F8A5B917701C3DA1CFC891E8E 49ABD35F15B4023BACEAAA9EB0206D015EF283AE12FC1B8D0EE32743A15F8A9B 4AAD98E61A1393C237FE069504D47D4E03A2E2C372C3EDFF93E10E0EDDF48A51 82F77089ECB99C1073F9856F9D264DB872989201072C347C2F9BB547E60E0FC1 BC93C0735E3B57FC81B2084563AABA0045D4229070970E17F1A2452AC7CE2B0B 8C70D65C6799E0646780715C5E152957FD1F94EFED51370FBCE0D22024308F2A 50591F19938EF20D9199B7140327C51DC28497618BBA0BB817E70BF33DB6F317 B9F4AC0A9A99D550366374797C2C9DA70B8D47EF7A5512D6EC95007D13527EB8 E0BE0D8C70324795007691A221FDE9A3CC455AA3BF9AC2D35638A2E81DE3151F 1E7DAD437A201A6E0DE457EE4155841CEC67CA58305C441B9DDE92D88DD77695 5B8A6F8C14172D3760ED7D2C074997A4748DDE72C92D4F87E42AC18F29F582ED 8B3D1384835C1CB5E3BB4BB0A4C81748D368779311AD4C15FCADDD62D5D141FC A2179870C644B0D26322509DEE7CEA849F3EFC92A54289C3BABF5DA290E875D7 62DB6199496D80B65821D74880B8A050EF7D64841886D53F800E8063E468CDD9 5DAA4324F87F4149DDC739C68E778FDE58B248045A055B9E9CB4C6FC4D49CB80 61654EA2771727EDEB47E83E55BB557C491E30D11813801BFDF5F4C9A9E484C0 1F444B3CD05F1762444C5EE256CA4C83717D5F8100991F74A8BE2E59CBC2A213 F7E427E992F0F94B379DE46AB4329C6FC8D3A79D2F2AE8E024B1A059AA16DBEA 24E26ACC9A4B5593802277457CD318EE0DD5B7EB5469D328AC3AEE8803AA51CC 215ADA337CCBD921E0347711F423BA87244A45B2817070B243FAE6D06D2C9690 AAAEEE584117FC828A037543018E7057A863D1455D26BD337C5EB4F04A844920 174AB29E242F90407746B9D0280D2F2873375A989DD0879DA8DC28B930C1042F 661386CCE2C3DF1034B62CBEDBDF024284E50A794150CD80D23067922C25E906 446D3D5B053806759B3EB47C4F6B73CC7E213689DC847EEEBE0C41A7F8DB7379 101AC49658B50B9C8B98D16F60B7201B996A7C66E0B2E15C2F2C35235077B0AA A5080D23DD538A8A3E5DF5A898D0EF852EB0AF79A5EB6A574B199F17704DAA39 1257080F6684C90F828A19AE93119287DC965B9D8C5F424594CCC6E244C61B95 F2891E175679FD9054DF1C605092F60F1C31036EC6E0F128E1BE0EA805B8BE04 D971C721A08775F63AAE99B5BA3460F3B99FE53DDE42301672BCEFC060303824 AAC6755FCC82AB3D1E3297CF2458BB7E78530EF587AB37DA101E8458601CAFBC 7C845439301920F40D36C8A496DEC3F48C9BCFE5B67A95000A49C06ADBF2F89D 91243B032E891178B37D86BB44083AE9250ED1FE2041C4D31279330EDA0A83B3 6C96E2EA4C8FA0FF9BB410FD8E8ADF0D346F843774B39077897802F808498A2A 584787139451F2A95C954BB2C2F1471FB3A216EE5DFB6E5D141472201DCD4820 D5272BEAC7FF68FBD047A347B6611105BFDAE3F0134626FACE3A2E744CF9CFC8 4A4DC6EEEEB1D21800D722A9A3BD6E15B2F4A133A9C0661DFB09370239122D03 5FC3C01152CF8701502622C826AD26EBF2220A279BF25DDA437ED56129B03468 B177C2043FB9F74BFE5A9F1C75028E287466804D6AAB0C13F23602BA6119B95B 760219E59DD6207CA7FF4D49028E23FAD7CE467FBA75ACF5B387A0733D32D46C 7142AA126E34882206C96712E7EC251C00E8BB0781C2E54EC4CE72A35BFA29AF 83EF4D3E69D77EDFC561F55E0355AA31799D9CF22E4EB9AD071B4B41C0FE765F 2AFE686530847FFCD53507376874E27A0625D1B5832644E1966D27606AFEC9F2 DE4BA2E23539C8047F0C613A59A3EEDA53854FFFE3D9F9FABA4647BC0F04038A DC634CAED5201412387BADF51F6CF66BA5BE3059A076D567F556BF49614BB683 871829384E5C0C2EE896B4F3258CFC5BAF8711D79A2CC3702DA3BACF1E5FFBE9 9747C7C3C42D9C5B255193924BE58E0D11066D72BE85DCD6A6C892B97BB8CBCA 87983B8E6A4F9746C057EBFE6653F4F9DAA3401B6A9FFD1A6A8C0DDB550C9863 70360F2593FFBF790AE06153484E25E6441550C278B547A4D836B7BAE2BE7615 C82FC3000FED17EA056D12D37D551DE297EDCAC5A8B6E645481F40D0047EB2E7 1BCFDB2BE3384094EF696E73347CC3318E33297404AD825E83F2125C49EB845B D5ECDAD6A48EECA20CAA7CF4F1138F534C15749CF018F4E392B036883EA6EB10 3F12358E6640D331160746001D5988A53C0483DEF88E7D5E0648FD25B6E23403 E118E84ACD5635E36FD9C81AB52B9F7FF3D71E8396D904BED3487D1CA08C5D9D 908A33B90179994BDEDED13A24A7284740E7A7897A5E0D1CBFBDF51E17583FD6 1D07248F45D040E144DBF8C526A1042B12AC07CF03DE2F234B174D8B17FF2745 7D09F34BA7E9CCA3A222556396616E6E55456DEAD954565AF8A2590AAEFC846D 004D2DA38C110B0F69B053A1EAC90278B8AE446ABBB751053D4B80F1266B60BD 8E8DE59349F07C18994FF414A27305C80B1329E92389932AB8463247F1E67332 FF61B89500C27591C967E682605CE4ECBBDFBE4482AEDC13CD05EBF332F2D4BD 16E7A7653F532238190F8162E573A67E1BB58F9B007F734B9778F949763B2D68 BDEA255789E9A7673A732DB14F2538861E40915252EA75E6FDA5017F526FFA42 2183DAB388A92A7B5F77CFCE9F2158F0E17E460C12486A7658A9015CA01EE3ED CAD61976E7D3A90E401AB64F51DB01E87D26281DD04FD6E8F38DDCF804353D59 675CCCD85BFBBBA94E6093310CB0E76F4BC5266766228C3B70D746BB6683BB18 DF86BE7A0E79553AFF147DD5A48D67C0D2737CE83866B12F442B678502E7C5A1 EF0B1C42169287DA401A57937475729140022D651196BBDE507C529F5C5D00A2 CB5F5E287D4C7399E3BB738100CFA6D0FE70ED2CFDDEABD773BD2C99763982B9 C789194D0868E003DE18BE594B65D769B3A236E802F1F79C68EA7009B2081C4D E68DA24D6FCD440A00461078C14376C827664C531D62133697B341D04A405270 4CB324B0007B7A1577BF4CABBC706A929EBC90C0E77E0EFA3303F3A7DFD7880A B829B8B472A70259B3722BC7E23CB12C36612D0E9F1DC7BE4C83A070BA9974E8 932E2A992D4D8CF7E1385139E26F85DC7AD36AF64FBE7E007910667A3F47EF62 9B617D04EAE51DCD3118FD80F95CE121CA495921558333A83805640C5D11312C 76192227BB3D4C2B33799C8D4F87A3ACF4630A7BA2B09B2E41948C25033C1C5D BE6F9AB834ECB4EA7205334FC9EFC84868AD49E3E103D4CBFDD0B02B8A24532F 9B5B95A4D9B7310834A0C6D28258580471B9A02F00D1697E844D9A5F91CF1C5C 9571FB18714EDE7725C8D642D169A4530407EA3E85FD1E138775FB392C60E409 79EC3B8DA085AA0F47B446420B3F219204CA439B28FA933136B0164AB17269EF 51EFC4332560056DAF20C3307E856186CF1BA6EB7BB451424C1BA029E716AEA2 E16FFA5A475B876CCE429431325AF04BE29A49E5F081BBAFD83E00FC1AE70BAB 449BE5CCF75860E73572CA7C2A2A430B35F8E44D3F4D5D6F9E1555F31A6EBC1A F726AC41413ECB7E4D69D2D9C00EC73685E5EFDD00A2D56B6C3E39B5E645FF01 BC597924769EAC0B9EB57DB079B845ABE81EDCFCB0F58303CC9470B9A1A88669 90838A8596254E937C1433925724B1EE2502B955CAD748A7D7AC1DFA68CA4949 1CC1CA5DF75A45EE4D2FC29A8F6F881832191A5704CF691DAA85EC4C4EAB921F 55D7112C867DB50C6489E07458583101D973F4968630BB9FEB0543015F06CA55 83D635189EDBC7EFCA176624BC52285BFA2944925DDAFFCE9A496C86706B8107 F53BA5D6D7BA108E17E044E936CE0269AC33D2FC5D972E122870305D23D85B1D 215753B007CEB7A37F75F42829137A027937F12B78D4C35D3B49240A3714056C 2EB891C506C7AA9A47B69C9C0A965B53D8EC0D91766436B75EC5B3C0E326E0B5 642B13B481BC86FEADDE5507E1D03D9328B13028441D5EEDF753D98DE208137F 2DA6C2155EF62A003CFFF22CB3EE03841E657F371630324ABEEDEE9C2DAE7E6D 248BBFEF50AAAE92FE0A3B205BF693D7A84A6ED30F700841CB1B6DAF5FCF9408 254D3E3089F5BC891653DA647555AC31C809C50E4D2421E438D41D58EEEA3123 02A6913EDA0CB2580456A55E17CB51F702E1B63C28B47C3625AAE4CEA6C3F956 DD94E39433AAC87401AC1BB01EE4E713340C110924EB5CA9CEB548E54EA57F45 2E3896BCA6B351CBF61493FDA6856DCBD0EEC148FF48843F8A757D99EFC66DD8 580236D0ACD74368BDA94FA15FFBA55DB8D7050D67EA83DAA0E0C0072623C191 71EF2D509F710753C9AC13F612CEE32F8F7A5578440F8FF8B79F77C6BD16D11D 72C90BE04D553812A64548721482503D5D4BE2F02258D5BF200E0186CB857A20 E05E027F34F3FD5F1B62E7C08FE64DBF2CBB674BEBA51316281FE59FD806894A 7261C714D6D08320955591279D0B24D3BCB773D068EC79AF7D8937A92C097E5F 9DA482AFB2D1E1A0E97003661CD4E3E9710565DE42233EA6AD853268D738F117 8E4E432013030605F7BED34BF377544FD3222CA452944DF5BD79C2277C7B67D8 C7AAAB31ECE4273BFF14BB6E61BAFB497EAAA779D5BB48642225DF28C8245885 FEB908544B922A95BEDDF797FE68D98B9C96AC4411B5239532329525E2698279 AD86998912BCBBD6669F2D31C6DF4954D108F79DCCC296009E826E0F3FAAA939 155D3A2EF8F75D2B074BE3AB5458A80D65A02791DBAADA26A7159562865AAA81 C1F2588E2ADE4ED9682F6127939404CE3F29F788410B7AE271C4BA3955DD501A 1E6B6B303FD70C99E4963E6ACA131F5A67795B4D2921744DCB14534ED336D13D D46EE180E4B230734610B7FC39191954A6EEE713D22A147E3E46421A87832FFD 2F70E8F9F3EB231547157887116428238CEDDCA78E8314EDC6B44B38419853AA 2B02A445008B38619E6B853487B44A558277C28E939AED5C59459E230067967A 1A30825A14E1BF708CDFD2AD852E07E4A52B755B7F28F3436972E1A7DB4EF36F 5ADE6E0E23B879D5C01AC6298A742CB9F041E04E084BBAC89EE6102DF5FB249A 07431EAFE27409C518350E43BDA1712B6862AB7675BF17FB58DA05268C115D06 F73B91A2ED426944B879E23DDA5BEB557EF4B58EF85794BAAEE4BF03E66F3D87 52F33AC3659C56C59A0D58EA90EB13B8823D098739020A9DA242BAB1C3A23B53 01D2364F8C7CEBDC40EA140CDEC195884677488AADC0EA8D0258AA3B8A1EC03F BC5BA7E86AC4896D4759511101BE279FDAF309F24B757895A22D923DFD1F592C 3F727B5D756E04CC485B2C6795F0B067535AC80C18F244ABE9F2A95589EBFEC1 F9E0CFA91ED6C8AE5AD609C29290665D47326BB6C360FEE676E9585380AB3606 D02E175BE5F822C9C27F168D5FB6FFFC5B17C0E5ADC13215189E7D53064D95AD D723779B3785014DEE635D5877F272C28FC98B80B7E29E117F3FC37A12C37A9C 516294150AB0E31839256D7C37F3CFC2A5D9DB539BC9D4148844453A20FBF5D7 70960289B32F87CD81A612268EF302EC67DD89C47B1DDD78A31CFFAEDB24B15F F4F0B3BAF2863A7FBAF66143E6FECDE716F9CBF1FFBEDB64CC1A137E221A968B E6D54D31759893B104689BE439690CC84B129933E3FA02F6709CE159B8871109 C98CCFA815C7966DE2351A60D47FB341FA02A41E73A4A2B6C88D7603092C3735 1A04B0A2F95A47E96D18D1EF97091CAFB7E9057FD562AAB9E5ECE5A08EDD16DA 7DE1C201EF0915E329DA37137F04DA2DFCF83FF4245041397A2C449226E3051F E2211B46B7FA05C4AD68138531D6EF259737F27F0E953A925234A001971C0412 E8CF0E20E7D2CEE4E6512D6880B26FE9EA6D67A1A8C656DFAFDBA45076028EBB 5B768DCC141075B747F32A121C19AA41435DEE3671E793382B7F1B2879A96AE4 738D638A4585F4357916C6CFD3E6CA5EF0E5E6B879B9C2674E7A36A8AF511CBF 49EC8F9AF4B413CD4EDC2ACDA6915BA90063C61B8D2095250BD382187EFBD030 26506C2894E82A5981B64619BED151131E1FA003F01AE7AF4E0895485AD0E8A4 71B2D72DD8062C5E5DF0396F51D03964DBDFE38C6ACC76A99D5C134005B2E729 1357F25378CD7F65580F59FEE46B64A0541BF043EB89867B6EDE53822B4DE861 644E92ECACF64E79F0ACC2E5A57DA12602544C5CF2816DFB0214A4CA30227E5F 97C18D187A9F42B371DA95FD16A2F2399E862A20F136A2AE0D63A121E2ADB3BB D9FDE103446CEB588810BAB348947E9B286EFD9AAC09E009AA1F8BC0AB4D8F68 C9BABC338BA19D607C517F41C947E3CCF89A383B8036C7B52C4C2233CB0B742F 30BEDA350762BBFE38C28CDCBBA3BEBA28C447163E8C083BDB0ECDC694C0A0B8 11460CF33DB6F317B9F4AC0A9A99D550366B8D752B69F8F20BE3A067DFDDD557 102050EDA754D85B44408DFC7D5CF2322FAB047819D78534DC35B0FD0EB25D48 CE4F478E134BB128F0A4BE0008A794E9CBE589540AD1CED13527D1C547AFA7CE 671A2368DB3690281F24BC6823FD2C0C1AFA9F9668F65B9CFA779D95CD761005 D46F8AC4416562C7BC68EE3FD3923BD20BDE8D99D614DDA13758610BCBFC6A61 A485CEF198980DCFBAD0ECC54F561730F328E0D3EB507EA58F34DB25D164DDBE DD3790732E3B16CFF4B145C38261BB77AFE3AF02E333D61901B534B6E71DFAFE 7B51F1F36F391E16A04110636F3C61316CF9BE68FAEAD1C4D8C541676165F558 F6626B1DC3E27F0A36A9654D4002DC0BCC407D3D3E9D9180496CBA3FF47FAD35 9464A7B3B3C63F718DAB0D50CF5FA0C948B0C24B5B6BF1FF58DD7AC0F14D58E9 12DC7B33087318B006BB5A9263E95EDFBBF4AE34B00A41229D3CEDDE5BB94FAC FD9D64E4D67697C259DA9FCE8FDBCB16907124BAFD21A210F01B7E6990EC3414 642659FBC47B1D7123A90D075150ACEDC77556593D100499CFFB325485D459F4 AD5C7C262D5CAE88648BF5BEBC528F9DE93A9B6D97A192495D55029C1D33CC91 0FB3209AB8C189DD4B02987E508A79C1DE745C77471DF1117988FC9FBDCF1F64 9B3D501A80AC79F5C38E8FFC7C30375D52CC20860757B2C05FC345DFDE5F09E5 445375D36F7194C1F364340BFD2A83B0EBD3A791CED6A7D376AE10577F517783 6269ABDBA9B8DE945B5A67DFB8096B0405DD2FBF77A575F65011FEA13A7D1267 1D6DEEB6E7FDFB84ED90CED66A698E659C3BD5BB9088B7277B4729BB449A25D6 3E97736EEFD2F23B26AB4E37435BE59C2A1D11BE7C521F066B483D366B7A6F5A 712A4948AEF95DB6388E6BCFD1970E0DD4CB2B87834E458986EF8C382181261C EAC4C114FDA640CB3077B36C368E9661FB1F7B1128990701A7A98C53ABCE0A9F 25C7448970684BC555C8390E34A50EF764F32A8D11482CE473C6627B7A0DC42A 8A58D6D67AED8ABA065BBB1FBA8D41F80A9A28917F43904733FF13C69BA1FE22 DB80B51A7760223F143739A194E618EC3E3D2F351CB3CC2B70C0D781D80F76D3 99F60082DE73DABA5CB170DFB2988EFDBCAF8D54FA4AE5CC2D89023CCDB6CB72 1A39F6A3E56E0831AA0F47485F772156A879AB55F71E1D8A9717DE3214AB1B10 CCC0E60ED23148B7C2D9FC6637D2A3512711F33C07D3B132D86BC0502AFE5100 9B400AE6FCFD651B5925BF3CBDEE9A9283C348A87A39DFA6C0C1D0F456C201A3 EDB533E669CA97A58536FEF94F8DD079638C0BCCCD458F625D4210ED2ECF3E3E EFEDDCF36EBEEF2E21F30B469562727940B85395A2F710DC825ED7FE46C20531 11750BA1A61704E97DEF5DF782FA3D736EA62A37209DCF1871E19873253D0F47 E6A4075BE6DE1089334EDED921DEB9D1268AD634171C2180B57B9A5C5EB5BB14 8218321F077EF7BB34FEBFFB60BDED83023C053DE9C3C1E41C43EF758B32B77E 59BB4C8263E19EECADC8F4F47182CA9DD450BB793129E8DA2647D49C618F33F2 C2FC988A21B489E76CBE6E76962C454C5ABC825B4704139732DD1D68FAC8277C 7BE995FE4C484797E87663A3CAF1B8F2963EB70915501CF72AC5DB7C29161ED4 B141F160CE8E7DE6E0A9D18F41748045098E3C179FDAB37B66FC7A4D6CFF98C5 53FBF2368F70692F5A2B586627B2A435CBE1EA6F462F332F68A9B4053DD5971C B55C033B973AD12C6243FE895347248B374429FD09E13D18883B41A7F6D81409 A201F15386F8078F50CC345D771DBE163D69F2540A4CDF9EDA8461379EBDD3DE E2BB246177A5E2E76C52121F4E76ED4F5C2257BB80664556CCBCC799F9E2BAB3 5A8C52E6CE6D00E19DE7CAAF2008EC66F3C5FABCCB4E813F1EAEB1040B7D1B68 6A5B5CD63CE1E725166960A1D2641CB3F41C2149B6BE7D5C2B5C0BF6EB3D4063 F8D1C1FC88B2ADA5A9EC6BC39666DF30B9EC0B74DBFDE18B2FD2DCCA49A39980 04FCB9A43206CB547507AC7307A2EC6B2FD26977EE51025E2ADE83704C4C197C 0D3A41B01D2669C9EAB484884101981124C63E96633DE9C479417CA47BF49A46 734AD97D5CC6713C98ED63C014267D1FF54D52D381501498A386C6B5DF77C392 A9F101F2F5BD43A9F77F9DE8C8E107356EE38ABADA9A4157F0FE3EF78BA2A606 92E3CDE055DA7D5E43F290B3C2352376A6D05B51CB7256348B52476CF16F0D9F 2D0DBC2F4D40FE08CF8251A61968AE41418CBA8A420C0214AE4CBED9A4DC44CB 4AF35E4FF340E462F323A9D220DC6FF2A2232FF7616B1216BA0CDCCB93EA5A4C 5584A861FE9A9EB285D44CCAC47F12981B9BB14D60635BC871D3DD8055536693 5D96137B0712DF78CB9AA629CAA1D03A3E485C389813FA1C79A9065932DC70A1 2BDB668C1185FBABCE497AE336DEF8C6164D22953D026176E60A2463694E1327 D33B197CC78C8AC63759CFB81DAD4976E0C9544655E565EA5BB39454F85A68B7 342B73EFFF7F38CEFF9ADD38DCB0214AEBEAB5AEF255C64405022BB022906725 D0D79C9D7D64ADB41DD8BCFA172C171B88F504B6164CB21437EEA2E33D369779 27272CB8B68384F401AC065199525E11F907EF993401135384397D8143D88101 7407118FA439740B84DECD3D78C9238C29847A1D010C949C7241F78F814451CB 272B05A6EA11E084EE760C9607A349233C59611A572371F75A4469167B12A844 FF762C039874396D6DD67C75AF2F00C5A0DA59D33AD4FBE80316DFE10637013C 177CE4CB0933ABA699F59F96AA3D4C9F82B068A407180B07CEC08DB97E481ABD FCE934FCDB86669DBF5C1CC7821942972C6006E8E6B380946910C1CF1D4F801D FD996D244F38EAFEF4DE2D5E2F54834D70F404B843CE2DE91D6B3002A9C27216 DB83247F1AB4CA1B29B302DDC1DE1B0AEACACCDABAADD33228FBEFB4DC6F36E9 67EF1BF6E7D3FDE9C0B4BB348E9CAF64AF9013F6B75D0878042890A55B7E35C9 8C582488490F208DAEE84097C3DE7246F6CC2CB28004B9169C4E089C790E1975 E9A0D847FDD84105EA6AE159D8FD69294E336205A5393216A6C0B5470C571E21 2827D0494CCC5F2B7C1EFD71BEF362D3B3A25AA7AAAAC67F6E063B4CE8A7D40B 4B250BFCBC3E1230DE617975F8C8EA343E5063587CAE45AADAFDF12A999CFFE6 CB252CC398BB16A9B4BB600D2D564CF8F7B92744E878747B11CD91663481E4DB 70C8AC77AC972C0E3A83C79CB9E53668DCA7263B48E489E01C9032E81FE7D2CC 9A3532011CB374EEFF9A6F2AAD7D8BA937536B9978FA8E066C63DF23E6839C38 A0C09DCD3677DEDF881AFBCE8139288CB459187D21E9D205B8407667438F751F 22A2FB901B29A73F82B117AB26CFF268DCC2D249439826865C4DD5608EDA15DF C411BC60D06DE94D22E5D7E415D29CCB394A12DAC1ED1A7B81C19F26F94A560D 79F2C6A6217C187A52DFAE10A23C8CA9BC39D8DD6A43283FE07DE72B0812F113 48017372348CE07FCC7A78B96FF33F7A6B6106BA6B66872CC7AEBA1777D98118 54B922489E78AEF1CBA54E9A86C85856A1C876A4FE014CAE849D57032A13073B BC18526F063F767FB32A0760802B064C11B306690454FCE60D20485CBCF3460C A8118261D1B9931B396502A04B0361FCAFA8644CAA58241FCE33DCC2D3F6EB95 302AB141F3AF380EF0A18FCD90DB279B3660383B889282A34FEC1B01BB7D5EB4 4B048591EE2B8E6E3CA940DC09938630A605D01B42E2228F37E12CA2B3307C8A 2A2CDBBC4F3A1889D91BAC93C0DED24BACFC07D0D0410DDE5BAD51E5035FDDD7 78DF1863E54DC40BD9002C7A226DE21590C2DEE35E069911DBE4C8352AE2BC99 9BEF1B1C889DB200214701AB3C807A9DD1B541DE1301A598071ABDD8DD3A2B2B 8CC41494E10D2FA66520DC5F824C6A02D3DC2AC0369D56B902EE25F9AED2A473 C525B37F59E9A3FC4B220EA0673ED29EBEABC8CFE4DC042E34CCF948A5CD0287 A1A89CCAB298B4BCD42B744B20601AE2D3DD429660AB39A39B554B4C63E01FD3 526C868994FBF6949A2BBA8188AB7D987B5B260621BE0CA8C7EFAEC02BB60A51 93D5A286F81ADB4E66339F5014CC3F7AC20EF52B45014286E38AAA3BDE8102B4 E2A474FC0D6F3F1440153298DD3EB9E5150121FA3B346D2BE2345A3C1BA22778 368708AB9A016ED573E9E87FEA0151F6D2A0AA83063357B6DA5707C59AD75A2B A491CCA54BF6ED2E6887DC8ADF5F46415E32583EA74D2BDBD27D8E9565389201 F83CC61B869B33365187CD1193B3746B710E6492A9CD0119CB0CB1D332EFBEB1 3F3E620EFDE9D98F90985FAFD89EDCE7E1B3E9FCE2161EF1E24FF4D04E1B093B AB9A95A1A1D07D99ED2A2B4F826C14C94AA5803920B47069715A42B20A06EE93 120F785AB1204CFEA86DAF61FA2E2EC2944CF48719F76F0C94F5BABD9D53C591 DA9A9A85EE02A0B83929B985BC0B82AE3FADC5C5CFE9C705C5F0656D8B6D5495 20C12833C86C6A404D2BE5D4BF24D285E913E69B71C2F78DD91D7E4E12A3DE9C D642C2BA1E99646487A3436BF7A9F651FA32EF113D4CADE64676B79E1A8C2885 263F4667D0953D23C228ADA9CB0FDAA8DA871C588FD0C8BF3A0A2F32C99DE5B4 F2C9E41BF4A9400357D97146990167B61D818131CACDCDA0BC4E7200B2949EBD 305BF2A2BA658F501D2FF3B7CA091CD43E7488B8FC7FBC3B4F3DD72E04BDB79C 27B0B32233621034AEB87099FF4D41ECEE243FA83685995CE7B0DD373A0D7CBC 8231D072BF48200D46CF7EE4968C9B7F0F29834773D860D935ADDDF3467DD584 E678FFFD112A7E237D0A4213BD6FBDADE19B52B8A8E386FDCB140DC111147E9C 58FEE4CB51FF72947E4F00154A2962583E55AEEEC1F375C71589496017EE34D2 03F81629206DF69AB734FED5EFEEE17BF4CFAE873FF1DF9518DF332C78788FC3 14C676616DA98B968A427E76A89C804DD680258FE21F95340A73812EA157F973 035F696F143E9EB9BAF62B1A763BEDC9E30F503E3F5F45CAAD5B8A0A9214A306 300FB29FE5E21D8140AF6CD3AF9B3285DF31F723B7A7188477F522E3E0451E22 8BEA30C65427B9B36A2590C1A19CD3B31F9781C460C1909DB92A46CA29604A6A 9CE1C93C0633DF51382C9E7A1A3A965EB0254D5C1C6E21A29A1E40B3E7C480CB A590014FE0E391A5C05F380521F0A156115FD75B425B2A2EFFA7C86839F3E7A5 75B173ECCDFE674F64DD219A2135EA4BCEB64FAD95537FA0E77585ED90272358 1E88D3E20D1D9CE426289C0475E57A544D0E58D3D2F494BD46CDDC95BF670E61 D8CC33BD15C61DBD19A8B4C9510EB7E113508CD74D494799F3F68780E46FD341 9F23CE6D77A898D03B731B4F0249515CDD9BDCC07573FC153BFEA0D3EE1F395B 1A6B5E93924F184EEF5E8F393B4EB137D99FBB9A243B02C1C32993992FC890D0 3D30F751338C48EF6F023EF660493E8E7D150586CD97E2D6C7E68A8F5C2D90A2 F70FCF4264CFC765B5F3913E76C40B9B8568477D21D43A66C50FE1F76C7D4010 0CB4FF30BC68A2DC8DA87E9F9FF08908922C7041C212DBB3877BD23F388A8B1B 28FFC24CF9FE124AFA7D63D240CE1CCBF7051292B614C9C63F8587DEB6A6B2E0 06C7583A9642CF7A1544656FBAB5C46C0DE7375765847DD38AE1CA8ED2E0BE74 1B64AEBCFC08440189908263F99B693E60949D71BD16224E927FE4915DF68C92 4E0DCBB5A7C7F92D2EF5DD776D9B0CA9DE57B158C114997D93063C08806A8128 555D715A501C07C9B49B4CCCAAB8A6E2BA34A4CAF0E4764C09F0F1E85F8E2017 23B2038A7C770FAE488C2E0BA30CC7EFDD003429B03D3C60B3170697DF3BAF7B D20CDC6C6479817B6E1560E95EBCA0AF112119FDD7413CDE1046B31F3B297CA4 673027EC5DEEFEE09BE6DED3D498D8660DEFB21064D0BD4B4BCA61073561AF49 D06B5B7089B66EF4A07CE74F1B67194DC113B904E854AD6A96AAF554B9ADFE9B 703DC5B483ACDB1713FF357AFA8C3FAB813C3AE86FB912D23D024332089D2E17 3FD99243929559C3E8EAD9D2888DECDEC6213D77CCFF3D0FAE2BD62C0D74A003 0E59764EBEC191411421A751F3EB318A82F201F12EE9E4E9859C1E3073CEA7E8 4B0FD2CC45D58D8370BB1C2200BF21990C5A7E472E876423E0FAA735D9B33B7D B59115158AA805356201A7EA7D421200DF8CB8B3BFF4D5C296B2DFB05CEDD8AF 0360628434E396FC4626BC19CFD7D53D54240A9668E9F76D8BDFB2C666EEE323 927A4D6B479AA23E26ECD154A7F1B9D93046635B407669DAA65EDA2A5565429E E1585256DDC2272210B86B5FD50C31403A1BEA74D06E37CAE2B68CBA0E1F5237 AF23952F551A7C88800FC453A56FFAB152322005F1F977E1830F70C882990795 000E764E13F08904D946CB9DD17E9DDCE7A6D68966A1EBCF3AE5A441D86035E3 D451BBB000900B13C7D6BF78173C04C30D3B94A55BDEA9F190E3D622BEB6EB51 CDDE3C25F07EA57C9A5014056D44B2906DA4A6832BB38ADCE6FDEC986FD14992 9C55715AAAFE700073508E87A3FFCF3D125C75B109D3ACE5E906A37CC9455712 37282C66DFE60E594D41725A1E0CC021F7E5E75D15D5DEA195100DD156F84CA8 4E673A469B2BDB0D00BA4E43FF35D4D6A6C892242C6052D8BC581DCB482A1F44 65EAF114CDBE8521659B1251A8AF4C2CBE0C65C86265CD763E524A3D7560D710 0C7A78CE08D99F08EF2F3878C1DF62257D7F097DA15905C147383FE9F51C90B6 AA093CA6103900A8A55896ED32CC46E10DA95788E79AB81B6F1529E77B762A13 FA67FF394FCBAA0351779CF3415E5D27AB42A5D04A3441C92DF4E9B0911D3331 3B8E3195358949275FDD1AA5C2310631192E0AE17F0ACB4FE68B88C14B4DD19F E5CC881214D4A2FE1A924CA7A7F311AC0FD1C2EDFD60830E73DC011FBF53BDEB 7A96CAAAD7024C10638AD1136783301A12F84915741542968BAE3B54E19C54B9 58E0A21DBECF63679E772266B032F31D023A12B82FCA9A8E1A4EF5E5812AE4F4 1AFD394C2AE26484B8DAA5E5AE793373DB716D96B25FCA647EBBB5F0AEB5E5F6 47A660FA614F69268228D82440B230E145EA87F7E90E0646AE5001B8E01901BB 34889809BB7807B8758DADDF7646AA2F3CBEA4DD12C78B7C902A2C5F3C895137 7F79C500FD5CDC5A7DC840B250299F392A684C697193B9C5FA62A1B3C2D77A7D 732579F0FF90967CC6A11A7E2934554DB98EDA5A1684E7DE1DF25B114B2D8000 D297B0F825D4E7ABD010CF22AA47AA31190CF71229FC8242F0039743AB1C1C05 FD0EA8F96BC75FF2AE2F104126F0CB009D959B50FDCCEF10156CD3BFB915785C 39BEB30E8A82E0AE959E01E035EE92D7C1C9DB670BEE2DD430317801D532CE10 DE98C6732DD437255AD03F1E8579A556645A379410D2AFF74399793EB9C58ACB F6B3708FC54212EE8D098523CFD9B7DE4EDD196E00DCBF41890140CC80CC3B49 FB40CCA360E035E0C5AA5F6046CFAC40DF66E2DB6B56A525C70A8A64D1EECA08 A30FE50EB6DE2A155D110DED915B9B13861DA022C347E466522472C92B2242B3 6779ACDBAF2942A91547A5F7084D2D25F699C99A6BA19A3ECD51E049516C2F19 75F81FEE4518ADC313305A368CCF4DEC14E33B40176C8E9A4FAA47C6C39780C9 C234DE27460787C0704B5E4E8BB43E4D8A5BE56ADA6B68B45B4C9C883FC3AB6D 3C64B7A7F58A876AFCC666E682332AF707B39F4F19A5184F79D10882EB61E53A D10E0FAA312FEA0F59B5AFE1CEAA4068C93DCB36B991EC42590A066C1D52512F 440959A754234D1D3B431C90E310AB91EE0611C71C37F13ADFA6D1AC66C9184E 6378FFCD2D477DDC1F0EC652A61B57527E422CC527D72DB73C09D77ED26FACD6 245974A3912A7CFDE015AD3300E7B27DDD52D023ECF948D7306FCB7465EC5F38 47A81E6C67D731E48E308CA2BA12FD6EE2D32AFD7A2273D5C03B386E926FB2E0 52BEA6852D523383D3F7A0F3A5036270372157DDE0A44FC50E18A0CDE65E5395 76F921A6D2D8428753C68A948A8A8401FE2038702EAF3D76B552485975C9A061 3D01E4E929B2B07B97F62FFB8AEFECDF6B0676D5DB140AC41007D8C3BD4595EF 65B3F8BA775264DDA5D23C508992DE8BA47A4E890FD003E554D27C9E5F116A15 143CE41F3AB34E4429EEE061C547207DEB447F9554C1C9B42C4ACBA192BBB4D6 B905C033F62105F4D8F58F45FC35AE4CDC19E817E3C4E509426BC816A8426F4A 0D114E1C69D33BF756331E5F253004E87A23CD29DD2EDC13B5B87123253938AF A9D77188E1E27D6549EDA76148638DEF8190F2139E17119F7ED1F4B39A232CB9 4AAF42A11C3F7C33A6BF7260CA6067F924584A1346C8D0A8FE757C90DE092911 20732AAA8688FF09789B3A4D3C7A6BF0A80E37E591435B65649C9BED9B1253CA 02F34576A4C75DC29634A45EC306D0F66998A8DC6B25B26349D540F9DDF05556 8F4083D6FA2734972834121CB5EC4523E0A23A5205CD30D588596BC0DC60D380 11AD12A7333387E20E520A9DF01C60FE3A15CD1B76240E6885735162866D9500 592E9EBCE532ED4BA692E1D38002B46630665D6183F024C8F9EECC4DEB0EFB53 6E241E6FE516FF2A3E246841DC50FB73A0E6D1B14EC3BAF513B71012E1CD5A32 6FC627EA69853D8BF3EA789C73A985C6D8E2C982C32698461C00A2D1283DE86C 76595734DCF76A319C2FCE0C3ECED13BD5A1998F2487E06C734EFBAF7213D8F2 6197AEF31094BBE0A8F0BB5D35734A3B18569FD76E0F1B78037DD15CC627DC93 9FE4F93B41CA254D128153C2D85AAAAFCF7E996C1CB2F639AAC7D4B35BA5BE4D 1B2CF7BBC16449F2779D73BB98A3167007FDE54835C5B3F3388EA21E5CC0ABE9 65E4A46D45B89DE89E5EB7E47D8104FE111E51B56502D656CD1F27160A17648E 649D343A411CA165B4FA6B5144D160AE2D54542B1C55925D24CFB4FDB5ACE1BA E504A155A2D3207EF62793F3725CE71649D236FE662804EC14E92E7A359AC161 98ADA66694A78CCEB1C46C55328E62BFD909813616EDCD34FD26B8FAB75A8F87 08DC895898726E36CC627F2C91A187C9636C4EFE621F2C368BE9ECBCD905F730 E78264E89C4C1BFBDA1BC00BA84011E46E7513C1AB9F1C2C86F702371F3FE24C 4B9AAE9192B3D7398A9B4D42EE5E39FB8C94B8BB43E62C29F4E975863602D322 70C2BD0727DB670C98A796A64DA84D87B5FEC3A50C502B5C59E921A2D3B430ED 14DC300431789CBAF92BEFB313D592C6E1995C3DAA673C4BC3C683FB3CE74D62 D3A5D19900E6492A74D7EB2590A92DB886123F5263862A3D6EA5F5FBF1BA8A65 DD87AC12892B910C0926C32F4D786BC950909ECAE1653A72B44674822066E04F 78FC067FF2BB09B63BC598D49D659F29F349958E2971530C24F8B03AA45736D4 D2BD6EC656E52D40CF36F5897785C9F41FF1E554819847221ABC9D39A7493F78 C1A12287F7ADCFEBD92FC6E801B629CD11359B38519573841280DB9C84334541 24B0E9FAE31156C507F188D25B51A8DEB9F7FB35DEAE22B675E7128ADB0A32B6 B8CEC783EBC6033E378ECEB20C7E8D6199DA414BF3EF90AE1EFDBBE81FEE48E0 4C0CD7224429375AC941814888A6FC66088516BE7E4DEE36B1F1787C7BB160D8 CAA2571D7BC58C602A6A90EE20AE3BCC5F5057392E05EFA5D2D590AC389A0249 5E23CB901FB15C41831635453B2D0F61480CBB6CB6A1C4D56A1E46BF7078ED10 471AE1769D36A18B0B290687BDC30DC08A286209DDE54AC16DD46DC8784C5369 46588C20030DC8C94DAE16DBDF3656CD87F1300C65E35B4F37BCE08710A30B66 DDDE589FFEABE56E9F311EB814F1E5E24E5EB8CCB59B9EC2AD6DD980394CA5D5 76AA256D3B87AA4342EFCC8E863F38D31A46D776C3CACB05019C782453B1E8D4 DD18611D8E29EFB371A9CB0A4A728E35E90C57C6BCC1D703B2C25A0DE10FEC03 B109F43DC8455411D260C071FDE93476696FCC04189BF110CD47947E9E7178F8 FF12A813EC45CEB71BC46A93226ACA99F47A43DDD2ACB61E44A36FDE76BBA8C7 8A290138EE23FE1203102ED096BA34676BE6A2452F1EFE74C64CB1ED6B08C517 A6FC4F37514B75063D32DF1AEA12950A72E2C5C97F462699616886B56FDB84B0 A668ED36F257182D0861F2D24792D84BEA303527885E1F3D83487967871C072A B316ABC72C5577451ABBDF0394ABA0F4067B42BE47C5F6944BDEC4660C0FF1F8 F7143BFF5C05D45EAA7DF2128382323A26A4369B69E68BDE184A8D82F0D27395 08A4487DA1029C0FE3626BB537F39983E63856A6017486BCFF7F4A86A1A6CFEE E71D92B3D9D78A08DC655BDC3A97F676EA320AB04EEA7B636851ED1F4A629085 E70137EED3C5D0719E44BD6B244A05BE96BA87B9BABBB9F0B19B904FDAE16353 41D3445064CA422E5D47A22688BAD8DFDBE0F6747EDC520B5F7D2A2B38756EFC 816D0ED3EF16D9938834DB8162F8380E3C25AC9C418D0AC91944BF81695D9E4C D0AB36AA6A88FE3F8225C232E40E911D6C300488AF8BF80E2ED6BCDC2D8A4AB9 F39E652B53C316DCC1C1F560E38B219EA0C370DEC72E667C6F0B24E746C3D411 73727BF01DF22B5B3D6D1DADDDFDBFFCC419FA6DEB6485C26CA5FD52EC0363A1 BEEC7DFB29A85F68F8CEA4A1F52F404272CA42B85FE0A6D343113386044006BF 4CCC7E543D48077C7656E04DCD4DC14802222790718D2233A42F3093F55DA4F3 0B80365777DC76609CD774A28A231188B2FE3DB8B4ACB7E2D1A01891F4A83BB6 7EC6FDFC2F6BF8B4FC94B55777F45323758027A52BF961FD63DA5CA0B2B9176E B63F3081A3D29F334DA7A8F40E6EC67A3471DD3DDBFB72456B8AE90F9452ED15 B8805B554EA379963810F131311BA096887FFF320B257B140EEBB02DECEA46CF 3C82CAB06B468AD0A768E225EF16EEB184E91E00846FD960DFC6AC913F00E3E7 F704797F8E5385DA864ED653F53848110CAF433A9A9B5198F642764A82D2D4F1 DB18A4E6D8AD6C75529AF5AA99AB75B3DFCD3DC9F2BD3DE70205E7757A83CBCE 315755A9B5132EA3886C7314ABA26E26AE42DEF055E94269A67041402F67162D 81E9F3140772106FCC11CBF1901D72C6A37164E4EEA620112A2375E0F3722F18 CA8007CAB6EE33B64B0D181F2CDFB6D89EA991591C6493FE93B23E6A5DD1A20A 1FE3A594371FC75FDE5890ECAB1956F43F1DC95051E58078216C7F4334AF12A4 267FC4430AC68C0ABDCF6D3B893B1343597BDA0F38BDAF24B746D8665BAFCB36 06B010F5232E5937E1487FA723DCF2220DF42B6701F50338C8251A3E2EA141AB 12D8D03C153E7F219360E27942C3BF7E3B69916A67DD4C151EFA26E8E98110A7 495410909748118EE8B612E603BCC1B7D6AE04D250B8D4E7117A464F1E2965C7 8D3539F0574F5665B1F063A0441F6AA8ED4097DC01DAAAB9858C003C9BCB24E0 412EB1469D0C147E272ACE65F5D74D0F4A97CF326CDA19CD03C9CF4A2D9AA47D A1B47055FDA49CF1A047C005DCFAA428895F5C6FAF528E8F169201BBF1B00DC0 586D28862D807A4CCFACF67F9EFFD84A25A31ADECA28EEEF63F6F98FD71CA00B 45EE6D458E0EC5E6267EECD25AF24CCC42350F1ECD5C3091E33E102B90DEA5AA 32A63E0F07F106353590A4E1108BC75FBBB051B698F5B0DFC1B445B6ACA0EA55 9C0DCAADE1E57431CD87DDEAAD83869E11B48A7AAD7504AE017BF4DBE019AD00 8FACF26EBC0596E2D094EA7452C97670D13315D437A713554CA017B4B5E0A752 D6AC2A7195955D2DB2BBDF3C28E85F9E51A599E06F4CC8590348D4D352F9A5F9 4F4232B41339E659F19AAF8C0952BF96E867138CAA934F36ACB8AF6F2CAD1B9E E35AB31A0914D6B3C92B3131618FFB2042BA092D0A75CFFDB27758E85B9FDCD8 5A75FEDBE1656E27A4160150B31BC832F5BB1737CB74342451E11195FC7808E0 C9423CD4D9B16C4EAA23D39D328E1B38230CCE6294C96D0DCDA18700322AF8DC 1DDD50A994B3FA98DB8624480744A71B8FFF4D4BB6D1B85B20860D47500E784D 508C6237C3EC7556A3F91A10056449EB088EEDA39CEBB7D3EC1BB1D9A0718681 6FC12CB2208F87DF47A775D0415E4F5D531569FA3AB6677615992A3A60F8AAA8 5226BFDB5399BAFB8D71167F06481E4FE115E7E9B0A2DA58438CEC28B5CD9F54 8474C2750182936C6691AADDC9956D0624164544F50EDFD7EE3240CB1FF9B35C 324D07C4E9C3E87C511B845D23C17CB2FA017DF2EE2E65580BBB54ABE09D07E9 FBE957937D66170DFC9B22BFF9B73FC737B09D5EB1830F1208743644E5B712F0 0DD982E6D7565F390D2BC41CE23255F738396990F3AE49BE6BA85F519CE9FA70 10BCBE0D72118D49B43703F0FF5147E7BEE4156F9E0BDCF143EF871F53C62E6A A5EB2A31CB74F64A014591BD9FB0ABFA6CC1AF5BA31736CED580ADA1FC7F5DBD 145DD19421D54DBCAC56B204CDDB8305679B0C1F8A9D89127476A91F53EE0AA6 C3FC3A423E02DBF2DF8648EDCCB2A74CC78A637C82058C9D8400B8693D02F8B3 CAAB2B397A4A23C48FE7E819215284B8CB2A5F7BFF91FEC893E07FCDF53CA45D C79B0EEF41514DE372AD9843DCC88FE01B04903550C51B72DBB81C5B70A3E639 4BCBB48E3F0C4BE4474A35685E1D2CD9113051E7866110D4280285FCB96DA743 07028147973D87547C18D2EB90145263885ADD6AC1833CC788CAC99BCC8F4402 D28D53DDF2B2F7228BB953B3BA3C02D6FAE133CAEC1152A20955C083E9F71F32 D599FCF0E4772BE74BBC1D5E13CBA87D09C210BF6C1E849EFB495A345AA3E1A4 F517BDC642B57DD2CE04377D7D34722EE8FDA72D4051C940C674BADB2EF89ADE F2933BD3553F1870705E0C9A76C1C8E87ECD4C75691E933B1B718FFD9B710194 50C8B076C4D20DADE0230B7200E82E029BAC181476FFB242120CB81A34A6C484 F6D3364BE62FFCC7B314F9E16BBE5771F8163B3D40FD8872557DD33A7C3ABABA 6690FE1A1E63C0A7EAB370947A0389BDB7D08D3738042BCF481DEF09018085D9 D7FB98CC2A35685013A975834C3F3173AA2B3353E670815BA2417E7F2343DBEB 18E5FD583955070F24D0BF066B21F74F8F106668C5A24B6991600CD7E1962277 BB8103C352B16E086D4477274F085D1A2010E72340D9DA3805A373626D6404DC 081E555A5ECBD5E3530E13AFDC14555B6490F592DD3C58969EBA08DB499001EC C34F3EF3920D33C398E813F1086A8A1CAA00A0E90F8CE221886AD77E089F5468 FCD0D784E888A5DCA2FB235EAB62C444067E3329B949143A350240C0B075AACC A7CBF1FC3F139616D7C847A54BEA864D09E2CD39BA37BF04941858AE0AB42ACC 00F2FBDF7610BA13342F047E72301DF051D8EDAC490942F8E3CAEB8DC3AAF513 3881E06886F55E778A504FCF2F09CF60630507A725FA9E6565A7A92871030FC0 EDB630E167A6A5B7957FE8C70AF413AC5754CF10EA5D1324FB1ADB06C959C3A4 0163333256AA798C74342AC12240FE54EE60EA8C1E64806B3E64C962307ACB4F 74721BF11812ED2DB3A9185837A50D8E9B6DC1483A9E767E0D15C9222EC997A7 60317A170BFC130C773F96A72063B861ECE0AF170DE1BAE6B9D2C6A04C15FA27 57AF9D9104428BE424B763748796DB7D23DBA55E1F5E05FF2C27ACE107DD104D 577158EF856CC59E0C4ADD9688E34E3904D7265658893995CB51B550EFF58DC8 79FF910A87676702FDBA806CB785660BD33984555F1DC6EE103555469008A800 784A8CCF58C5FF654A48FDB530328D9585D2001A7C349CED6B24676973A6BDFC 6FDBA66CED5EF4C3BE801FBFA8736E94DCDD47B2343130A91E18A6D4E2C57AB8 931BEDEE56B7A131C868CCD27807F4ED3AE804DB9D156F5E03A39E50828B9378 9D3BE7EE3B0B04C044644CA03857504DA23545A2773789BE68F1D3BFA97D67A0 BEC5E9D64228D62EF575DE6433F0B42EEBEC854A60C0A420E817A5DD62F9A919 0766C65966790F326C33247ADCE68BD1A1D104796DA240758A1C2F803CE4B9FD 53DA9B162FEB0C60DE708EC35B982C6D0DC148740020489751A4813133B45ED4 9951BC14F9C0E3DBB2CA38B5D886AC63B9C9922A9E177BF9B6114933F1E4B13E 80AFA1E87B570C8FBE77FE9ED5B6278FC7DD68BDAA1632595A93540238F5377F E82AB2FF8635D2DC06AF6893C39F3A235CF75AC66C060E6463781D48E15E9811 9EE7762553248344F3E8933436C33980C8AE026426B301D51DC120045129270F E300552CF5E9C19B39A87553F0817E8FE9305D446C4C0DFE90C38C60FEFBD96F C0ECF98DDF805B4E47387FB00730C99C3798936D9AFB36F8D54B126224E2C579 27F1608C9E8534205A047F984A9BF0935A1344D8EFD38BF2D7D7298D40583510 F52CA96932316C98694625CFDA7223AC7CC1790CAF5C3A22DA1356DDE49E83AB 3AAB5AD382536598EECCB91CE188B5B146C379ADB872F3A43A4AF671D62C7DD6 BB9B3546F8FF15F837BC94C57B20B5F24A355D785B5BE46D3BE7AAE88925C768 CD36A199C0E64844D772FC6AF5AFA37C1D457130DC3B28E5CC051AD98B13D7D5 A2B641CC5EF6D0C8EC1DD9C8DB7CCA72005908BA60982DD8D77669148618510D 0A16B0E61155CB3A1959524097E4ED9E92EDE6D3198C132486E064ACE8C3F717 F277E605F45A92F857E1884F65ABA2B790BFA49CAD541097AA2DBEC227BF8264 C3C824B3C38B663813777BF0B0B5BDEE72F928516977B985A7ACF2449B7C3100 2A805E2AC6889D57703FE60D93B6DA9AE507715C3FE84BD2F39865F3F2B1B09E 5C8FAD8E7E85F188808299698F5EED965A71F080D3AE2CDB6CFF7A4F1CD80283 3F82A43700EB1DCEC7AA82051DC934D23EFE0691815349F6E98E6F7F6D105AC3 C20F623A2B9078DB20C425CCC18C23D33B7F293279FAD35C50C48624D904DDAA E55F47669FC835054AC300EADDCA0CC3FDB3FBE6E72A7A5EC22AFF3C6E8859EE 61FB47B9469A37FC029F9655F6F1B76B7C540FF68B8360BB71E6186633AC1E2B F194ACAC47208741D738CA956EB8B96261CFCA643688FC64FEBBCA5F21CC249C 9A122BA6ECB272AE65D84CD7003EBC1AB26040DC2FF01D11BFFD591C640B6116 65904F37E928F762F5AFD6F31CFCE9D0350C89228ED2ADBE8C1D7B9ED3F8EDB6 E7A0597DA8DECFA0355086E82F4973D5752B0BBCDE06CEA97A768756C91DB4E9 FD7195CFC1D5A89CFE5A05DF42AD078CC92222E28D977BFE5A70EE4C9350BC23 B4F213D56E581D3B98E263235CA78DBBB701331494B6ED63AE41B6C2218D1689 182AA3E356613B72D386E3584B352DD2A52CA713993AD54E1C6354CE44B7E88C ACFBD5072D9638B56CB4D1B40721173979157BBE66D2ACB6B4000EDAA148C3D5 87B4855F1D3CD175FF81C8CD0408957FD921B28B82FF7411AC9431257D4ECB92 7AF88DEA54BDC64975557A83DDC2C62A87D0DCAC45CCA5F1D1C2EE5C382DFBF3 94F6702E6866D21DFB766CF88182F5647FBCCC0FDB5D67F2619320F2E41C3670 1C28233E66EFC878FD473CA0906C4CC252F84BD9527B8756755E40033B7A9708 05D4991B3542CE71F6095EBCE61BE761FEDF0A9C174D36534ECA680B034C4A9C E4B37A04354C7885DDFE07A086EAFB3D3537FDC798A4263C7C5F905510AE2BBD B6B07AE911E3A0AC4E432687931EA3B833755E4AC1C536EF6D3282E7A365D7F9 A60DA57E911EE0915799C3AB4574FDA559577279C2BB494902A1EC3F9F2CBDB5 65C5940DEEC753B9F556F0123A8CDF909A8B00FABA0F8E63549181A357615B1E 9B89D338BC59C1F577E795A586EB24733FFD78D5FD92CD3F4CD1DDAB3D0A8358 9D002C0E5C6A77EBE3628EE3ADFDF2A3819CB082FC72D6EC4994AA7FF797BE2C 9F9EC899FEA82EF8BDAD4DDE7C87FC062B31948EF3DC64DE66B2F944293B17DF 06B13BD0A385A3E4A4F4B2378569C477A23041B71BF3FF399E912E946A615B81 01166730706B84FFD71416AFC0AA4B9139D33F79D9B2517BC9B2B65928CC09ED F827C4493C02668C5B0C0B0B6C85DA1C6596F2F7D49D7B7A403526B3AB86A441 16935924FDBB30B423347E74FA02D87EAF73DADBA2DEAB11321D474E6D186709 81B5750FC14D5EFFBDC060CF7E4F856849831A2C8AC7B6840CC03435A596FB7A 2266A9AC3336A14B63D7DF85A377EAD76F042798C3CD3431356229CD89877B80 9320B766DC0155BFE0F5EC31E7C7D477D1A1E6C1D724A272E4BA4BF562675CEE B7C63F4791122AB03216E4299EF247678071584DF52DD0E2411D4A5FED2DE651 58E633C2315FA2193CA626A5349B2CC89F252B33A074045DC3D7115DCA63AD1F 186BEE4BC1E4757ADA383979B201A0CC8C8B801B5D817FC3A04D7A1ABB0B951A 932CD4E5124BC87E857E910530EBA12B2F574A85AAF0B668C6F29E758A12C1E5 B564332BDA1BBC57ABA6A6A287A5D33E887CF1A1B9BBE7073D0CCC48F8EFA446 8DEA22D993A5BD12AEAEB57212B97F839AC0C9B7237F4C06AEF869684AED3159 6CEB65CA10FCFB5A68A056337945B2276A430C74B2D8266F8AA53FBA33E922CB 5376B44E02B8DC14B0AA5CC05B677CCEEBD89A331B52A619612963ADFEA0F7DC BF0E2E6CC2C867165E7EF172D3E6C0D32228A704705D219DF74E3CD3A97067C9 A077B2525ABFAF8411CC6B3E11C5B9203AEFFAFE5CBBBAA0B5B99F24AA974E30 4F3DC5C0B65C97C3AE70D1036435900B8DA13F93A9C6EF176822662FC876888D DE90248F68F1300DF1F6F5985D540C9D187AD9CAD9CC9D9B2130EB00CDAF4EFD E8886D8098E453A3176EF5DE31E7CA5A1BD6FCE67FA2139A5261D9F82FD2D568 D2E25C16B6581A30DF36578AD1803FACBB861247A9656F518375D1BF8E7D28C3 40FDB24CA785786652595D1FC14CEA1DA7A6E6767B51D235E8B4973DA20694D6 4F8A48D2834D41D798EDE8F19B0E0AF1F19E2336036FDEFD57257D85CDB9348F 217A8C02208BCEE2ABFE1CE686C8726544AA8E4A9373DCCD41743CD7DEF06FEB AA0CF4117FD9984D06EBE5F1280C6F47E46255739B235CA9F379AA4F988F9F7F D1182604B5EF2EA9BFC82039CC85A7BBFFB1BCEDBD46772C11072312C3B91877 8F4A41EFC4E9690B23E8C1CE863C229AB709574D25EC26181552A501C99E4B63 B48776B95623BD47BF1A2040F25C691F104485FF8A4A5BF005FC340A65464BCA AFFF6593437D34B9AC017E734B8E9BA6B3E9EE968A273ED0DF5F231D63BC901B 82BAE26EB3595244EB74666F13E05D7A5B5B891E345318E9F52E8C49C4B71BEB 95C8C782F24EB9A1BDB5D6944BF9BCC4F49AF69069340DB2ED6210ED33E99216 4CFB53952088C3AD46D2369FF9BC2BC38AA2035EA60F0D971F05242898139597 71EC3A3DBC6D42DAE3CA1975C300C734854A34C312FD3E4F007F952660B9EE59 70B2087E7D3FC70D77D7873E0FC5F1E9912F852E65F0A9EC425A0BDDD0689522 AC0D4AB1A4EC5E18895057B8125FCA67FE03695201545146CD872F4F145EB247 24D3C7FA8C300A0ECE201BA9FBFE4C809A10443361F57408F837DF9EF10BC908 0F5A126821EDE8EBB9552CA94C66F7EC15B6072CFFC0A7AF81010DF5FEFB88DD C197192C2C5A687EC265B03446B5F9C11D9B7C5EF58980554496590E85A350F2 42238D2E66D3E280E251F125BAC2598A484A9C8A37B0C8C7A2B21D1B0F07C8EB BDA5540861C2D304F1E4E1A225087326AA8F02DB7163B7AD076760A8D46E31B8 7A81554F8F4F6D5358CCDECC39F61082A3EAA6E4D09717C7F6D29C2E5FB45E33 0195AAE91C4630763E007252FCBC414CF5489EC526ED7729A19B45D24B1668F5 74FE05228CF00CF4E47E40CA48ED31396B60321C83C74C0E75A3DE4D639775B8 E353D1631C2BDC8079F6FCC349FD2ACDF4F04146CB3204807A67CF270B699AC1 C9C657C0F8C3780D79FE832BA866425F822B564DCF491F26F602AE65E9A72840 0ACDCE02BD10320925E7777A52B3BC28D5ED50241D15C80491F6E746AE69AE0B 268881CAA20E5B4CE991EE81F73D2AFB726DBEA7A3EEEA37ACBB1B80EA089F54 E7925CCD5A5D25E6A5AF86A342A97AAD2B4F2918044F5B9A110F8E7D7A266384 7A7DCA092F5741BDDDE4E6898C936753B2257CE0C91092EF95A6E27318A258C0 3433969100BC0716C430E42F88D0C245FA40088710B0C4956091C9F01892775A C4739E259B58E3DA7B936CF6E2B0C7C08C089B803E51BA828A1E2DC5CDD00648 CEEC5B136E45DFE89F23DC5F837D0E6CAC94CF3F3950EC6291CD3835D5D39D86 20B7920C45AEF671F2EE9F0D04AE2D58F9EFA5C5984BCA64A984FABB7330CB66 A994F435294D82767599E58536DD561BCB65F3E24E6EB51EA12CE6A2DCDDAD53 764E9E0E46F9EEE41B73DD331993F3E79781EE9B01C24B3BFCD93AD0C74D0B81 07F92B452272A5E3BF801A34758283C06E12FD8742FBF788922E41B9416268ED 3DFEEF9EF47E6D4BFAECD600E0CB851A1ECC3FEBDF3BB4FFEBC2EB03FD808078 28E5CE5F5D482A0114E458A02021E46DCE16FD6D112EB5BA8C11ECCD8CA07C3A 66FCE9C510D23B55D29D4B871C9A90E7B81F2B9D8713AE9542AEF61D9E245BCB 728CA569280F785838E9509273B6D85410E027F0C9B9703FE24FA59F7BE7B0D8 77ACBD4023040701283F11CD9D3EDAD56B57BC06F79E289583DEED3A2B879152 1ED0A785664CB57302173C1EC63DB68CCBFF02B124E57C45142E7FE20AA11220 DA90C4AF523247CE721BBA6343FE5CD40949452B105D9EF89C6C129076B5FA4D 2B3DA724EF878411F64A263BB5BCE784BE02AA68D8EF9E9ECA826F48347F2C68 7A5F05B16BF6C6D8579B1065A126B3C8164DC62BE0C570B135CAEB34CD7A1606 EA70A98D049A01C0DBC41255B220C0DBFF7CBF64943B92E1D9DEA485E0EF1CF3 2BBFAD83A4E6E23E2FD5236F33A4210550C91153BE8416EDE34C4F16D9020EEF 9B540C13E39925D446EFABF94165BEE4F69C4B5D3284AFB7AF9AF47E747B79F3 68F8EDD64FF7693379C02FA849ABFD88CDF3B13E8336EA3220B3651FC7901EE2 17788EC9FC1D2AA78AD7BC9B50998B8132002A51C53B70276AF2B81F9C0BEFE9 46B5A6ADD407967B3BB31CC200AA6306054DD411CC0BB2E6DD266EFB5866AC6C EFED3DBCB52E67F29962E276AB291CE6E7AEF378DAED5832F6F1C15271E975BA 5D63ACE746F5EA49236B4F38EB09435121231793F73F6A8D06F28478B70CBB01 2E70972398E7A4D436A55857ABA76ED753A338C82239A98F0C43948D85F51B75 1EFBC98F6A6DCE845C5EA5E61E8FBC7B851F71C93627BA1EDA35BB291440DF90 05C1E9A2B5EF5395DFA126F18677F8AF2EC64CFA5AABFE01F02A2F7D913B2B4F 650087A31E0C6DD8788C92E72D6767C46C7DAC3DA3F274AB7620400389A86EC4 3077007E7705129A0280C7198AE963AA35AE25F371B2C3899E4A55B0B71CAA3B 5F93CD0EB2E7C90D9F44B157BEE44EC336D7EB26AC2E8AE08FCCBAF54390BC2C 740494DC543119A90098389DCFF43B610660D20A364F4C096BE30DC7A35CACB4 D0BB9160D5DF295C041286A5ADE8FBA19D615932C5BE1C2F955BFD1DEE244474 F7A8200AD99C94DFC087E5C3B0569849A42CF88398776E17EA4DE23633F43BF4 D6C53D60C0CBDBB0D657CEF77DB077A7EA3E92F31B63E65BE76CBDD9FFD7F678 DCA66F9E6C48B0B363941625B30450F43766A7FA6E2F2FF9AC2A3863F9CADA71 42D4691E8C66DBC8E07AABA8CD349489BDA23709F059FACD3B037E98E13D6EC1 D9C0D33B0227B424EE8BA7B601EEAEC98706A39D0B11F3387FBB6B342C584DCA 92978188EA551289D79A640488BF78BC2465EE004346DA7F3D2ADF8D53381A78 A734D270F35EAAB8286012A4B25A5357B504AE0552919A5F80AEB1070F5FBA70 5CB3D14C20D8E2A817E904CB1C62BAEBC58CC6C7A799715116181E48028B0BC2 B426B26515A302F83AF1C354625F47FA430A9A2B79032370FE8158B0DF6F00C1 AB90A87596F35DB971EF99C4590B10F4386C4CBA47C9E5C2DDE8C39341CEAF0F E697774BB8417A3ECE8A47C9B9ACB4334B8025435C2523A99E0C6BB1C25E0904 5F2E5C4A50FAA9D68B1319EAD771A490A99A68892EFC59EB205969ADE0904163 AE91CFF7CD12E32FCF4FEECF877B875E16ED00BC24409E7FFD399BB5CCF9A448 CE35631D2FE5143AE26381E0FE699F33ABD100A07C7441BF627393947D7BFF05 216E9EC670AAF04611BAB146B4DCCE3A56F5F082E4C366D03AD6D05D4B04411A 105D280014CEA824CB7472BF2BF5756AAE9A4E8898C300A3CC1CF6C5EAF8C2CB BD101961CEF0F41560691F3F4AF9BDE87DAB1541D0DCDEA73B23570DD7564DF3 1A8478CF2E56BB157ED7556FCE5EAD7A535B80CB2DC6990C4087E388F7224BF4 B0241566E164D30EE0EF9555EB23FD805E6ADD35EA078065D8F186E493F6C688 A5C8B937E673FE386E5780D9738DBD68DEBF86BEAFD7F1720DE1294D55EEA177 04C42AE34CC9EB4FCF999C61C3082457A777945EB945DED20112B1AE05C223F4 05FB67A0F60BB09198E7F1A30B1B9D560D45BA9D586F0A066F9836A08BF99A62 DC86BAF863090ED8B0F5F6F9FDBFDFBC9FD28F4BFC0B35B58EE5709838BC1B26 B961D7390EDDB4A98BB0485B46DEA132958656954F40CF0776038415E4164306 ED56159A0DA6A1C2BC962B6BD39D6541176B467956A6F93491A638E457D98B7E 13F4444C0E4CCB0EACBBF6F4D7EB4AABC39F1ABC7C212CBFC85357C0985701A6 FD3F4AF0693487089FF32EBBEB3A1986E491957D9C40F3A4FB6870ED1013EC7D 050C6A95871E8AA73CBF8F5298B8489C3AE976C15208E322A160A552624240A6 5006245DAB47420A11ACBB7217329B675805D361C1004BBC198ED9617A6C093C 1BB8217367E105646C1FDCB723643DE845DA398BF8157EDA43C6F440AA70205D 1CACCC9A54C892A7E13895D931C4EEA2BCDD153295D3DD4F5AB867B132DAD999 4A1DBBF29C8B7E5385A3A98167A2209E0B6BE8BDC31E83C2528E259E7CE83C18 6F3F05D02269A6DC1259D955E51697C6F8512B244A2461D92A8E4E8C855B640B 02D532F29A2B1CFEC3486C34055974DE035CB36C13E266375250F8C93B37FC98 75D45EA27A4913DAA8E481F4B5D50E43661F477B49570B8EF298691A24B9F375 D7B83D0DCFB29619D8934C185843D3DF961C5E24ECF86E0BEA3EA9E86B7EE49A 6C652E23196BF58A918432F4CE2D49BAB4D843BC655539BF8FAEB8DA27044C9D 9FAE25522638932ED72BE77850B623500548E9AC106FF714184A57B2E9176DCC C06EB0DA15F15270D1EC7CED8F297441C184C7D9C71A8DCD89FF40744F6C7DCE D0DC9B53B38F51597727191F4C7E67338041F7AA4F96C1BFAD575920AAB8ADED A6CF6C7B69814CDC8208C9A045CCE6BDD698C66E2D345AAD49409CF415E8A3FD 23726D6374E57072958FE9719CB037E22D0243584752C4E5E18DEDA7F589043D 0160715FA33D36577442DDFE4E761914030F77D4D358A1A5D34A2661E5AD8D11 8D18EAE22BF3C61FD8D7D7C7CF19E02D88FB8C339F3DE80BECB36337F82C87A6 DD4EF30E22F89C753E890AAABAE5CB26968299B19F291BB5908BDBDFFDD8C65B 5D4898590F9E2AD52055EC289BCBBED8168464CF203C78EE6B315849A5D2F35E CF4E2556BF4C5234BBF66BA411DE1C6EDE2AFF4ABEFE9E369D7DD4011436BAC3 F236936CFC15A0544846804E8CBBCA8CB12234D592C660FD51ACEC2DA01D9A76 2F0583B7DFAF680FBB12C028343813014A57FC730D04329796D39E84C5B33EBA 625AA0E7A49397FBB540E07361B3B7B264462D9FE09E92588F02CA0F52C59D19 4E2E9BA9BE9C390E92FDB4815ECA71C5FCA07A8BC66D19B7257F00E3DEF732A8 AD6E456CADDFF54918180CC1AF32984C627B8615E66F32A2B8094B78E1E2F7F1 575D05F7F828D3B1BC485A294AEB774F4ACD314E5E5257B6A9FCAE516A2BBD64 3A9118DDBF23214951A36CD75FD89BD93A59083F7ABDBF0C04D68BEBBE1F41DC 272161F6F4D1CBA46DEC7D12D84ED6EFC9B7F8C01F5FCD836A5874A0495D280E 33301EF8133514903B1A7BE69B72396E2C2C765C31F8D3EB99D9E71C19BE500F 651A53FEA0956F7A55B473A52971F5CDCE5DD37182D7FF5DD9C3DA371B146488 02BBA1BDF9B777717179D670EC58EFB9B389373F7E8720EE705A1EA7804F27A8 444A0B946C6AF6B33FE57075CB4054C1F29C0B85115A6B8A85619AB665C024B9 36501579037BDC27644930681A91BA2E9CCD07089F51DACB86270EAFF5906A24 DDBF4CD791DE5CE92E2FAA02711E34BED927DDA9B13CB9A0EE486F174EE12C02 131D4042CE2198028F3570BE90ECBF02D5841B52F660A4F2E233015E96CACD0A 93AE847CAD008ED8D85688E1B2B6D9B36E35CB60C84A65D7C8036941EB0485DF FB70503D5C832A314E623A8956227F3A46CADE2EDF8C762E7D348941E6542588 412B6953BC29FC34C6F9E07C05BDFCE6CF343349718CFC690B5BA15F287C4167 ADCE37342818B8578566C26AAA08893B0BB10FA5C225DF3CC9A08D3C1A773C16 25013D435E15AD3A6AF1EB33CF7CB8B174582578EED29B9475080F6662D77949 D8DDF30F595EB0764930F49EEDE251CFBFB9CC69B91F6BACD828E13F4C8FED39 81B3AA421FFC94794241B99C44204D32CD23E56675A91A8AA9DD72982F0AD527 12DF066D9360EBA9D31FC8BAC933A3D410752E171B71AC86EAEE097351EC4066 3499377C42B1C7C78DB254956981E1B64C8C1DE716A9BD87495ECF13567311CB F489733E578400514EAB23DD2319C8F7B0D918730CA8A9168A86EC4FD1770E0C 3DE47A6975CE643B240E5AC7C36EFCCB6887B9F0106181514BB72D94B9A2B928 EEBF156AB7AC291E54CDCE3829401E87641F9A4B6CB486207396A8E172C447C8 5425A9BF1829AC07435AFEE5E9C062F8FE816ED09CDE2BC2ED30280667B3CD01 7167E866AB5DD6D63673A42E03B61ED95C5AB6B2FC2B92F0E36975CCE656FC56 CDC1CF4283DE60C663DCDD6A329B7C5A8FE0900DC2BA00301D6828F347E61D49 49AE8ED610808AD9982D42C08FBECD2CB51766871CB55271ACE4799DA244A5D0 85D4E8FDB0FBA4799D1D43DB952A8574EDA1E5D0328D203290D5087B2EF99F7B AD5122EBC689326C8DA934884949152970E054072F9DFD8B622B4D4BC43C20C0 6A05DC87B212955FDBA368C2662020298059C9BA03698FC9F35CB9C572A1AC83 50AC13ACDB4C764DF1E6ECABCFF6D53E31868F891483390489D0DF3FB596FD4C 3251BB2C248FF9C26C360F7321F2B26FA08514F5A0D4248847110DED98001DF8 A389322D4BBB0970124FA0EE720DFB2A69EBA267B4A16787E441F87BC2E591E8 378C618C093DBBAED50FC7366B63D7B2E522259DE368DAC70208BD3BA29FB3B0 1A65985854961562C172EDC5C63183ED7169A5403FA2504839411E3DE5642F2B D3539BE30269B2F3B22661F06A0D 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusRomNo9L-Medi %!PS-AdobeFont-1.0: NimbusRomNo9L-Medi 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Roman No9 L Medium) readonly def /FamilyName (Nimbus Roman No9 L) readonly def /Weight (Bold) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusRomNo9L-Medi def /PaintType 0 def /WMode 0 def /FontBBox {-168 -341 1000 960} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8E178732AD0E135F772215 EA7EB7EA7641D31502E1BB9661E7B0E875AEE90400138F2AAF4A8686C73EAA44 E5CAB467770A3D12E9807BAC97B24A8EFB0E276760F4F51EC7123C43BC6F8DCF 9A2F496A9172813FB461FD870763306B45670653A9780FF409B734CFA74C12CD 150B03344295918C4ED893FB620A9499404B83C71152BF2F2DBF769000D116D5 EE264C016EE3E1241018F59544CCE53E5AEC124CF6C59A4D7D7D511ECC9AFD49 6608ADDD237358D7CF8B4D1C5BD1158CDF2D6469D9BD6E6D9762ECF34D1C3C27 5F69900E0D12AF9B21F153585742E999870BEE3DFF6309CD82968EBB40D9C269 CD4306654AAB6734151132DE4194072485FD082FBB6DFCB3FDFF9E1FC88D9483 8AA64B5825293978C70C9EC095B18352BFDC34B4BE9C939384E3281BCC6B1808 A6B61EC4E47BB6AC14B105FFA7ED6AE99A1CA0B360D1A5C24E0FBB55C66F5811 A5CD0625654654651979A8C4C3612054181CD300CD42D1D9CAAA589118D6C7CD 5EA8A9A0C639D5539430D40318F4B739DA281ABF2BE2765D44F45B218BB192E1 9EFBDDF7777E8730FA7DC0651BCD5D68EB743C51D9CED55403021D45F77CAB5E 7E892B3D1F875DA86C030A2387487DBAC8795749E849EC93439C9E22EB20D11D 07DA0F09EE9356D55B8D0D8555F1B0EC98C72863B376D3436E10DE2FB1AB9453 DADA019DCB64F6D059AB3A95B28B94435004C9A8BD3FB80E2B9DE0E330D03622 3AD965B4283E6DC880A2130185CDABC053C52693CE3F50557F524D7CCA9BE05B FF9597ADF5D1C432C00C0B0D8EC2CA8436685B4BF3E2105B89FA6CC787B77637 248796C2F43872B3BFC8011159C22EDB7149AD8932360A88A223CC638BED257E 04908032ADA750F17279F7331189C322CB5ED9B66E502945BEB1EC68B1C7BCC0 2322EFD669C229B28CE1D0CBC0005FF967D0A4383E29538AFA13D41D484D739E 487D497DEAD8F661847A5D82D77D91219ACF666E565292384728E58E1A489054 8C3E34B413A6A550C499218E7FCF43694CBEAD016119CE85515F5EDAE3CD483B A0F32743E7A189708AF0CB6FBAB22AC8F23604FFECE038C838472CA40ADEBF08 47AB1D450E07F9D51828D25DDCA679E3FAE54634A37AE1A5A778365C5A2C8A27 64085AC775AC132CCF27CA164C4721F67B63D52E388B17122F15E5DF391674CC B6C9EDE307D79E390068970FE0AB210337558544E8CA59BEB1ED00C1C66DE2BB A2F092A3E458E62F713FF2C1B9B9B53E7CAFC805FD5D56D55FB6750B614E1E02 9C1B5EAB6B11A82801FC5B137FFA9FB4E3D6134A6FA1B22079BB360E27CFDFA7 B2AEEB52D2C2260C6176DE0C3C995E7B4F974D7BC3394593C5B714D11C6CABB6 D498BC122FFE12E223536914D2D3F4BA30989C7F4C81B377C7FDD9C11CCA9345 E1FB3E1E056247EE3C01A36A5E13CA29C7BC6C1903C77D0ADE7A166C98928886 0C393C74DDB8D3F95F78F5BBB2D47D8BA82BAD092F293B2DF2FB243E2CCB67B3 DAE953DEF56BC27E73404CA32C9FA8EC1DD9ECFA5E75253139E2BB94A71DBEB6 2D101D5C4DECE63C67831C0087075F08825969F1FCDF08AB7A26A46FF9CFE2A3 529B735031ED0B3FF53DE7A8FA45ECD89CC4E2AF82ABBF59E7E01EB6A7FBA4F7 E2CB0727559728448FB6E92B0345E5D3AD7E0009212A52D33A03F058614B77D0 112527C92DF85C31BE5BB722452187736D103AF57ED0F5B6AE95A022F1C722FE CF62CA43A38ED6285646AFB0D163B7F08BA3D9C9446A52633AA3AADCE73F5F01 81BD8456E553AF718E0CF6AC68B2C4A28780968331DEEC1A418382059D0ED702 85D9881F3AC128FE6CE93C051E13CE2DFE658B0A72CFB65FC59C5287D92E1A8C B5A195036AE42DFBAFB1E18A1CED44D2F499C69EA518C750370797B96D672132 CD2E47BC82CC947D4C7D771A71AC1645EEC33E4C86724CE7A2CECFFC5CCF48CA 297980F4F0CD65865D0A22C7FCD231075CB13E7FDADF3100FA271F92C1BF356E D0E5B2E3BDAEB057C127660E1C762559346AD0BCB540FF5D6630C448B5075E9B 2B3D5AC53D36734B1F3B0B7062C3F5E45C05AE3FE790F38F8FE49D5803331E5D 0D37014E61434D08750C6397BAEF73112D2B7767E060FCC8F7C0498700D06A64 7E7FD18FA038E60D43DE5CFDC40065B79CFF7CB3597E11FE4A823B246CD21005 7761ED8B3089D26D42B0CC36438603996CD4E789466852BDABAADD6B9E6E1B71 655C46DE2EA89FD8758F803BA06826F2D7CCAA906B3D76183DBF90B4EB8ED3FF 425821DAAABB08D1F8985E5AF62AB7BC7DB9CF32D37FB9CBAB682BF1C3AE87E2 06259A2B66315F256524E70D5622F024EFAADA5632EB66F9C7EDB57A8F61CC1B C6EB4C44EEBAAB56D5937DAAC57AC71565078A9CB36CDFE0F5E1030BFF5543E5 36D4AD4F9F029F396B40BBB90821443AA81D6CC327E310793730C8E5197204C1 EA6FA42C89D753DDB5D4DCDD19A45F93A98964F8879B6184DB82AC4495174DAE 6EE3C2D117AB5B9A79EB13FC18A14CD703312DF900636F21AC253C11931ED571 C97E2E4F0F76743D24AFAD83B2BBE4858480D500171B112035204D6615CA2D4F 65BCBF3D257E9AB7AD93AEBB8F33032B8514408528BF280E178C4A3A66DC9C52 96DF2C4A9C5DE43FC042F53FBE0E023452097E72492F295E64E2E417C6B64D04 CF75D347F67859A8B18884AD4BA3410C3442267D0010D96F09568FD192E619D9 EF7BAF78B862037B9AC06C1D9FDD66C24C5342A3E4CA7BA620A3B1458EA90D68 4591E99D1018C0BBDAD1377BA5BAD1633DE30B1AA70A301319BD2261195DC55F 0159FCC04F3057AB0B1F323BEEA3F4F1573E5AC2BDCE73C6E1A353C37B202A47 645F69BCC8605BB15E0ED74281E8F234A4BF7726FF63DF421F92C56F11541670 0116FDBAB22C81042A15B23AB0513F41DACDA9B9DAE58CC760BAF73EDC3832A0 A371A51F64CDC4E06F544F2055F67F0ACD4F401EEF1ABD87F62376C476215742 7BC374B0F3967E281FB2BE4315CA9820CDE879F89A896E9E37C73C748F3D94E0 843C9687417BCDE241F0C2538B781BEF205E8499D8A4C847186A02B66F97D7F5 A0D5812B105D0140E9BA4A58192E970B4A6571C33C5353B4F791B3BE5398B892 915C86F13BFF58F078F40A978E7127D9BB323463B9F522A4C3BDE3618EFDD587 8C5D66A2FE3A59337C288207ABAE3DD8F3ACD0B0CA890EE6D9C3FB0F63D796D0 CC1E19C7383D96A8F93E7FCAE743DB959968F3B44BB8012BCCAF89CA3FB1ACFA 385D9CAC57566163FCCEC2157AFC8FD8B73F6DC67463B7E16E4769F34F27755D EBECA9A38F1A17B1AA91AA60CE1A230290633B235953E222C1AB7FD82F35FC5B F375C555BE98C76E7D37A7EFF9338798E50E1D09219A25AB5A98FE81028F5FD6 E538B4C6F26ACBF9446EB606AF21E83D0FA04B0F9AC39183ED3F0C0341FEDD2A 8171D548FD4820D42035AEEAC6FE0A2813A353776D768911F72D917F2828CED3 20498C037068E61FC279EF726B0A8DFB8314B3D1B770A950A36F59F2967C7DE8 977BF81BD4D94A1A3FEE747172FBB3A1B2D58C5844252798A5A205E9C735102D F94A1EE649F99FA8A84C7005ED70BFD1801D890F42EB0A4D10399CB12D8A6DB0 D0AD766A25B9A807C18D0CAE0523B05002BEB07F67A8F619117A2250E9AFE0A0 6BD7C4E62B668E707C52E55E9B0EE7EDA8E3D5BA606330FF5FB642B2F470BA92 542CC5184562603F7B03B0C29A6665AA6064C8DDA0974B9997FAEF1B08DA208F E08B4C0B53377C0D573F526E899859481FE05FA8CBD9B0CC8D4C2CD459CDF89A A9AB1F8C02D0AED5946A6913D594E92923EF4E2DBF9B33760498C875EFEB33A3 60A12F35E45673FB12EE740814608C852A7201B04F6A7FA2A856BFB088E4EBEC 64CB82F396FBB454E5C570E779CD3F1FE806F82AADAF144006474B6126585F86 E9FDF42A714B5A0DE2DD5468277D92D34D22994F6B944700250389B8582A6C50 97EC50C755BE2BE67D58BDBDF02AA83FBA99188EDF183591D21D3CA9D3E5CBF4 CCC35FC6931CB24083D97EE5E407FE5C491EDD336C9F7F8767D2F6F42543581D 177D638B3C4044E730DA8A8703A9D0B5324ED7A14B243AFE039847A315DFE684 2889BB3F956DDFBAB7061CE2FBB6A0152F2B237F66EB1B66E6539F747EB1A9CE 2A3ED37719230617E10EF475F585B2E615996C11BDC84BD9EA2524776363A7B4 9F8D98AA894DFAE3AA308B496B6B65F19CAC09D590922561732CC807FFFFC738 3B81E766B5F50E79B62C4F6DE1A97B03BDA6EF533933CB2E1D6F7FD2EF1CC382 6DA19468F81A3640135970133F24B7EB6B0ABEFF57595F953465672E78D69ED7 7F81D20BCAF1F0B249C2800578F4D09DCA5CCDA0009800A7B4C3B0228E7846BB 7FDF74E7F7816F24BEE68198BDF97E53410D65BAEF23D727B4E245922C6D9B64 3E34154BD24A324966B21FA9CAA953953885B06DD96286DCC25EF8F6A417FC5A E7A23F9E6611F08790CDC97C907F002B26C9655081375092A7807014FAA4FBE1 00ACBBA0CEAC0DC1AB7FE2DBCDF6ACE18FEF071D9B0FB75B8CBC150F2608CBBC B3A2C968EF269DA03E2FC200455B81CFDB29F1D69760E4B4EEF6030B0D9B0DAD B574B3E9909285BBE76F051BFDAB3247216D8F96EBD8A2AF4CE3AF2D7ADD340B D28726FA52EE9A887DEFAF1A5E50128B92ADA43A9FE1D8CFA559C93965A847E3 5FA088D11AB789BC7729DB2E37A16097784D287D139F0FE3A7E91ABC70DE2003 29C772901AF0E084DC6EFC12DAB51FEABEBF2FA1296CC280743154E1DBCE5CBA A84AA35AF7F679764FCE7F4F929266E5A83986AFDCA502200D1641160D7C9BF8 967D144460F4C999C832DF25E9AEE67E53B3DA936E64F6582960A8857637A993 6A89D5DDB9BFC7DD57402FD9748C67F8878EC1697BD177565DB81497FE3D0A62 701D18826FEC47F867C4FC966D23A12CD7EB037278901957507D4B848A7F5DD3 F8C733D8779CCB53397B7E91B25258FDA340ED61DC927AF82D8D10AB50C2E89D 8334C87615F4BEC40E9B86F42D566340C42CB69C68A246686B505162949FBEC9 2D95DE6C2C53C20105CD8CA6FAE4AE039EB6C915A517B2931DEFBF7485919783 1D1D6EC97EF1B2E2DF13C4B64CE8AAC2237FC33D8E4E4AE75EA9BB09F4A55301 CF59F9E7D9EBCA7DF1EF31347807DFAEB7D17E25C7F2A7305BB71C6E3D58D473 DAC16E894E61A5B429F6FD1A0AFD6C051EF07936796D5A0F9FDBB73E2161A5E9 4487205C3355E0366F2EE92680FA3AF8F6ED9470D568D69F4D4A66F4769069A3 F87757F001F545440AA4A807414CF5B310E42D466862939CCB26A5AE326CF8AD 5F4DA7743A09AFECA6DC807448B48C85E461210177DD9FA088D3EAFB7F4C3146 DEA1EF3A730A16F873D93A66DD545E42A1186979609CD62EF3C72F91FE544DEF 8A29BA9972B1C7AA6BA53BA32A081D3006CF35BCEF2D18742DF7CA2D119CC12A 3246B9B5EA106E3D1223F2D92A82A96482D08216DF53ED0681C54829579361E1 A4AA6C03AB56400180B75A10B31E330BE538F5B1AFB1D8DCB2B603A436669899 74543B3403BE43C8DDA39B8D4EE57835BA4007125440C1C6A00AAD63BC614D48 067BB63A9677117D5EA7A4F614F72326C3F650CFADC44A92A1943904EBAC99AD 2D36D66AF102C6DE7766498043635873DA2BDAFBF4DF85A095EA8748EC5FF386 E6B8E70F94061ED37B98D73FAE8D0325B16D92FD7B5DA0FCDB04978D43466430 A36EC979FDB7D3BBFB7E52CBED653D9D9722CC1F3A91A3F379592FD08DCF0A11 3F1E5470B10FAA41536AC36841EC76847012B34B1AED4F0B9653FB9FAEDED595 CDC24BEFDB1660A6DB11B5FDEE8118D800F3B2A7B59C4C13689DFFF68497B143 B66F337432A326ECCE7B12CCD93AB92D3CF24F6243BC340FF3FE9458B4B81E37 824AA06F50BE1CD22C780278D973CC5D09551F62952C6AEC9BB506D3D4BE3DDA EC3071EB451EA4ED490D1137D8856DA7689FFA34517B3BAC37DE5E0367B7006F 75FFB6D73B4ABB00958726590A973A2605C55559C24B0A0E54C9F899E582541E 6F4CD3483BDB4C4057D14AD0DF80F5A8500C6E2E72C47D995F5DCC51D9CEEEE6 C2470FF7843512A3199A3CBD1D2CEAC818ACE6CDCDAC7037C3649E181A839DD1 FDD1A5C48B7CFBFFB0DF1A3F74B2422630180856A400DB7CBA9318C6778CBC65 0A9602B1F5D3FA76379C4597B7FE8D4D88C9484E74BDB9F7983C12F76D6446EA 0F954AD7D03474A6A82DAF5E1ABDF8CE3C6528234EDD16DD0E11384C2B9911C0 B7333AC1AB759281857E2B1A0BF9568C867B2214CB8FE1B9D5293F54D176809C 75D22373802023DD465F60E5E5492F17615230E4FD96E4063FB23B0C1334231C ACE3B876EACEA2B6D32C3D557ED2F6F284CBCF8856B2A22E72C0C529ACEE60D6 FB239685F5147CD3049BF8F3DC54D583F8C6D60DFF13F4B2BFF0C2D48D73A369 A4A30AEF82906E8A31140D83CAE2BA50264B1E097ED39AA1BCFDD77230FEA535 971EECC6EA4C239D51CC54EEE1BA1940C62D80E83E0BC1242EF89D7602F38FCD 0A3C36F5D7AEC70AA127E851A7FCF927153CC53609ED71175C5ED02CDEEA31C5 C24F873E1CF9AA03DB3E75DA4B8AC79FDD4B5C705375EF9C87627A1CFEA2A670 7D6B09A42796F8F409DFF33F62508230EAE1281A7B8642144B87FAA7132BE442 29304ADC8A686D6732B0207BF2E6CA493B759312C50E570718E5F3191D2F2E01 4709D3402AA9FC931E965594E03EDDA16809FFA292D1BA24E03328DE38D7CF0D B7626317598B0526C9AE7C8416D28AB0D2904BE8E2C84C3791C148D55B7715C0 47EDFCEA6299C7C48C7BA40A5962EE4575CBC6E27C201893ACF4E7FF00782496 3537E8785DFEF225DBB87D9CE546547C9B492CF6160BF12036F45D7B3EAF02FC 9047EFDABF1C2DC348AC0A72EF3D428D9BB777EA931E688A6E8CAE020235901F 8C76D2502BDB72A818922823F61B3EB6BBFC5B31E96F0A33A7CDD5F70C52CDBF 72C9FEB29A1FCC641D676CD12A52F23767C329FAE1045C5C6E476CC3E086CF61 B3BD4D3B46C96C64429E6F1328135427D3B56B0845455C012C50A56C1D07F84F 7183C20C699E45CEE85DC68E67EEB3B5F3770BE2D452461A524C9DBC24A40099 3E151956DB05672CAD186B82CF48AE4F035377DB140BC726C9DC92DC192AE04F 62C9372A0C770B87D1A32EB4B6139565396B6B38272829C49B77DA56D8C3459A EF9356949EDE08E4EC76FE3383700A594ADE0E9D59FF37C4F4E6E728EE1B399D FD6A9182A687B43D2F6449FC336C77570B5EB10FBAD1C9EBBF3457BC02F66414 215B6555B32B69CB55F0C1F3A20EFC98A3316728287CC34290EC9722D0EC3794 6983C7469E7815C20415A0490C9F1A740081C7826FFA26392CF4A5E7323EF2E1 FF8BD2A3F3500E28F18E6515A0ED165FD06DDAC8EE486574020FD303E9919963 81776B18092D1D94EC9526CA85F6C6B3253C4D08382BD6D9598B75DBD0350614 D6343452D38548E23CDA2BA79B2A0926D49402F02A8E1735643E53E9B1AF632B 818B007819EB6A3E1BF76F90C60FDE0AEB43F07920770DE6F6BE3E0CBE49819E A7CC98648A941C64D1298370EED3A91110E24E78A18E28A12BE9603A1B74B567 9972B1E742AEDFB5403D3858BD29064B94FCA8042756FBDBC4F3C0719D6EC9D0 65C88DBA943DEE4304EC170529B4442D530D9E3F079577AD402B32E799C9D884 9415A65C28AC30B740FD865BE9668856F9B50F73F9FB5F2F460FB990BB8C600C 9983A9780ACB75A68E131FABCAB225D733E12330D0E2FDC20DD8E324D2535EC8 048A126CE0852294CDD1896E3E2EB61624EEA5FC03C43BE397E8115FF14BE8A0 DF81C4121F1BEEDD200471AF584B8EE6509F82D3A29A528C86A36E47AC4E0C5C ACE37C66139856A99C7E310F2B2EC5B575EFC9DA0069EEBF11BFE57177D41F12 63119650203D3842A2C24196A61F5A102030FEF8E857AC5D22CD6D88EBE88D18 395675A90DC4E09DA04AE1A9AA61EA3C0B1AA08C8CF9EDF73114B31F28676BF6 1D7A28E1AD0072B1CD8390B3DEA090D692F78A049995BBA90255F722FDB58D8D ECFF1F3B308BE9F907D72815778BCE41EE8D3674778CF60B6627EF0965A3E0E6 A3ED207C14824206CEB751C69A8DE9D16E320913DE0F6F5038EC5FBFE0A25EC6 705996022DADC1B1AC7AAE6732DAC6E6E6F989D279899F0378BE91207AB57F34 C18CB75637513AA762A8A88C2E79E77ACED249FFA923AF2346E469D43E9A3111 7D4B00EAFA36630BA7F5BB6C30882385E60AAC74E6FA1A18E90331A61A4671D3 C33622ACF7D662646354EC560DB38F10525367D505BE995866EF858FC43BF59F 8840755891BA976FCE898A13B26112C2B23574478290F37CC2F8B8B7B52B5FA1 CDEFDE713E720C325DB5A04A73AF4A83C3AF0305AEEC07F9874C8D167AED252F AE2EDFA8AC2829344F6DBCCBAC3CA80C6561DF4B4C685581BC76A71DFD1E1EA8 D93C4F30EAF9526D54CB5219617B66CC87EA3E7C777272613030767F12275C91 EDB22ABB070B58AC683CAECED6AB1E0AFDE6E68E166CDA60AD45E5C49C53FCC5 151792F2D6482D2702ABEBBD09EF9F5BEEB6041622434D8B9D8B41BE784A26EC E63816933808FDC1DB6422E8C79A63EA4936720E108D1A9FE9932438D39A9FC3 84314FF4D2A34914800C596B5774BBB37ABCC39557A11CFDB99DFF29348A9C06 BFE7C610091EA58204F935EBB54C5CF501AFE0E9EDD68BB45A1AD4CCA10F53AF E4454D04EA2ADC07D0D9477C97C6D727B3669FB4F85770D21CEB7DDE50ABA411 46AD439E1921F853F6A8188534F1FC37D375546FCB5442A20674F5250D77C778 405F3A8FEE1D184F4565D68CFF6687283DAB9935E6CF2E2CCF78841C492E9A57 D84846762E77703BD781DD7823FC10CC77247E85D568DB053443D2F989D27989 9F0378BDE6CF4A278154EC7DBB3A5884F22DFEAE3808894877054A09E40B3275 426E5AA27DF296CF62092C4CAC9EFED7BD02200AA662CDD715D69CA527234DA2 190A43A455CAAC860DBF1901820D143F1F26585F1DB50E25934CFECA0D6C226B D5C5804AB6383BF2E9B0A86139AC1D864CBE3293D092044D9F6ED6F50AAECFAE AB179A95A14BE4FBF10C05AB2A81CEC34D9BF7912DDB2265F48F724023F029A7 9461E9451B3F916C161CED1E9838BAC9B9E1A148EB76088F7D66722B50DE1571 0BADA54B52C4049E82B0FF5AE56DCC5F414552E27876F252795AD1A91D37B54E E046DF87EDECF20FB059A7FAA9F9EA38BC447BBCB9B5491CDE4D0BC3BD8AD291 9186F556FBD5C3BDFEAB5860934D05EDB60AD6895BD4F911266EEFCB28FBE10D 39328466F42A16EA478C1605A709DB9A94BC08D61C1A6E98311D9F5D4B31C014 50286FC19405DB16C42D1F5F66E7F073A95797DAEA1C9925F23F0DBDCBF60902 699278982F6F938EC8045E4C8365FFFBBF8357D4DC0524B768EE0CF8066508A0 A63CFB398F8B5286E7CC869CE2AE5460C8910AF0B8B0D9EDEC9711F4EB03F4E1 52405EA8334CC2F26CF28E8D151A40F9AD36DC569B35CDEF9A87C6433A0F687A 6B8DEF89CA62DD62D87F22C1D6FB88AB5007D6675465315C78DC2F0C22701F55 14C142713C845CFC9F4D37CDD22B05380F9388AB5995729BA690B4F6F83819DB 2782ECD98DF43A39DF4F4942FCBA50A8DE9399AA84E583B94AD42D656694F27D E516D98219C82A22BD64092A555165B2B9CB5D1C2636D7287B209D2A8FB13D31 018A8718E49845E9707E242479A8B03F4923D878875F008072F19F03D1F6E988 1123B1BAE7EBFB55307A86B9E4C1EE00C991036875DB9658D88A208EFFB909D1 39D087B4582C914FCAA247084BEA75227823AAF5EB14A515EE9C95CCCDE329DC 9455A1AB0D17DBF7E80994E31A90B7D76914E3C753EEB382DF31F5C736BF691A C2C3BC8BD05622C4D46C21B81883962192FEA6DD965CD18FABECF6253EFE1E6E DCE9C0A6577A87ADD5D9D79382F68E3993AD0B93A7C03D1020B9FE9F780D0595 B109B0414419F5E85244AD7ACD9DCC6A49DBB19B8162792905CFFAE9EAF0BE18 FABF31EFDA6F20B5957F6F74AFC55EBA2ED5F6565A54833FBED85BD4588BBEAA 0C8D43A3B9F003AE5A62F38693164E569D55AE2CE26D8D471A1BFB36E562911F A408C969C49ED911D3F64DFF598CA1C4A297E4782B90379F6445BCF144A9DB59 1E2931EF752D98BEDEBD2737E97DE815BA34A7CF4256290EDC0205C88EAD24B2 F8DE2F54834C96F621A1E792EA73D345A7C773AAB8FFB6331FDDBAD32F860B54 3F668A1C36B3AE2C623837FE030C02915C9D423E0049B313559BA62457CF32A9 0E1DB4CAB9A2A918ADC1F09182D6B45C97555C54461D838D1CC3A3D9F0E590B9 2E5323D6F007DF65D1656DB7AB37C9EFE6118B05209FC4359443D3D6C9442065 E66502A90B678F90D275937BCA91E5AAD4B1A3ACB8A4DDCA6DDDBB0270370941 415C0FE2858FBA0DDAE75CD143ED4B9C0145E452A23171A224ABA4D376DCD4FB 4D814CDCAAC830DD6D2B2353019C8CBCEF3798248C6B93AD2F241B5CA8B55BF2 8DBD16720BB1C42C9A95DD77B9BEC948DB8FE7A03C5CEF1156392DB08FB51495 20ED801A65340FCADAC222B3FD287BE72B87834E458980328F25F06A23750F8B 09959C7769ABCACFFC8076E8C2F0CBA6D6C21A44ABF0D67EB82900489C93D287 82758D49CE07427C962E0DEF2C850F1DE966626BC5264A6275290AF9EA0ECEFA 45FEFFDEAE33D29A2B62BF68EF83C618839B96ED0556CB0708D934AF9B99C7AF C6FD0C20B0E29BFC3EF73825A0DD26FE70A69B58F4D5E179BE56FBBB8111DA19 8163F26444309A816C933FF53193EEE9D524F06BDE7FC34F88A144EE9F84E393 C7EE20A5363115E12D63F9ABC4F9F63C4253C69BC57E534C1C7F55E1B5E0B69A 5318A70757C586B98174ECA080612CAF16B6918D1DEC1A6DD2B605E334974DED C661D88F5D5ACF3563FE81C0936AF0B8A1183A8563AEE332472D2381DEA09B8B BBB61CF709BD16A5918C1EAA5DD57C55F1D452D1FE2B0C171A9386B8DF694C3F BC75583A79431FE56B6CD5CB64ABAEF9144E1B393EC104AB6EF99A35237B4DBF 2975364992B3996EA3B4F30C40106141EEB98F10CB4A80E94B9F75FA7DF1AAD0 F96B2F1290E8451D8A4C872C73287CCAAD11F956434F930010F29C0C9BF26EC6 55D90C8CCAC8BFACFCF0E923F2EF64841BC9B7B1B650A2904FD702766B36916D BA8F9C96141BBF4788FA4C870214079A4071287493CF60835B57D688D8741907 BAED6ED3A7A0E86C8EB19DA903FE24988EBA6FC48DFA1C1A35D99C0F14426139 1B4EDE0BCE9B255D18B359DA6840F4D37C1876C615489F76449C05CDD1A3E631 366D75F2377B3F1F1427F5826F5D00BD603C8E0FC735A9AA1E2C0CC78C4FFAF5 0A2A66D9959F98E7BA23D475D79EE4147E0A8EEB2A4D518DF5FE373DA1264FA0 65C0B2CD09894CD8DE501AC55BE69F055B01E0833264D7D208382832C8134939 CD28AF21976B42B06A63719C44432BD9ED1F4C3ED9B1676110F9C89AB74DC441 8F77DB1E4218E6AC5A90BCB42D8C0FDBBC83D08603E569E8BBBFFEC137335FE8 FD3A1882E046C9A49A2FE8993667D9C9BA17D596AB465DBC71EA789FB759A196 848F1E56E278CEEEB0B2291461BAD6507AA0F6A1F2A662AA101619AD3A45F608 9AC2250515C427BC5239E9A7D6CC4DC26B121F5D9C4AECF143C053205C1112B7 EC29AFB40388374D2E7BBDBA82197A29F5CAB161AEE5DC7A6CC93B54B73B808F 50AA358F5D9E38AEA8A45E9A29BBCF831946DD0022DFBA3203E94924F5C78670 6BEDEA4736A34677D5EEDE8D2A7BB7FC88CB3FD58DD84C1D2B5249C294BA8C85 98F9821EE447582750229E7065B09977A242A63FC2F76D8B9FCCCCDB9F327097 1F8E439DFB9E64F56AE838FF291C5C81C383F2A655A5F21AE59F5A0A2402B495 045A7372EB87999E94BB52F8168D7B194D57EECEC8A24F299EFE32DBF5035ABC B18BD682234879B240CC188E34950BA2906B425FE484270855BC7372D1C0A005 2B70ED7DEEBE820C02ED2F967DA29AEA44A0C27A8668A354360FDA3DC799FD07 482666F47C17D8A5BAD6E712F12CB0DF1FDE2D2E1EA7349E324829A88CD39230 C9934272141881665D08232C5A14A7EF671899B0597C59FD3BA483DAD551D0EC DC163CEAD83A7B9017415784858BA2C3B7C1C441D0C9D794B990AC60CCDB2398 885377CA00E3D656E8A33D96DDC2A5DF570FB390CAFF28E0E2A2F472BAB2F4AE CD6D198EBA263056B5AEEDFDED2D5729F1D102860A54D8E656ECEA88768396EF EC282985B8AED78C902403D7562D04AD6C66416E7D4C105DB75778839530DFDD 8B9C9935E7B787F601DADCC81385EBE8130BB25B68277FFB26A6046DFB2F4919 C6E9D972BBEAF973F24B7C3C8F0D77EBB7015679B2FBC22A2B3DDB49126096CC 4A39EB45CA067C42D0B51C0BD305EAB31373A2C8CFBA0FEAB801F01459540E1B 3A203F98CCAA37749FFDA272DE552758924182FBE603D54C4AA17DA5C7BD54C4 8FD5DB2CB0672592340ED84D48077A3374A777EA266A6881F019441C6043AFE0 6632C0CB5DDB1272F75C2009E4758911C1D6AD63219EBA6D57D71DFEA87B38BB 09BCB886B6CE9F9F03F2C632EE24E135047D1D415B789AC1E68D1B72E8D22BF6 11D6BC7F0C9014BEE383BCB287A9F9049B0DDE72B9F10BF392EEB7EB8AED2B53 A6F2E1BA5CE95AEA69D149FA8978990319C453911C7F03FED3BF3A0818B6C6F4 7775CBD59E060316A820A630ACE9DDE4F0B0B5E24F51F3B7FC5C87B2FA8CD5B6 51B729555370092C86259D60B1008F585FD03FA898F0FA2804E0BBCB6AA4F831 E99E3176CBD2466DE99C9D70145F783D9E6040FD4B716404CB5CD95D39463F54 7277DA21B7FBD6676F8C9E0B72B2D966F41E73C2F4C648D2916424A5FBDE1F93 5F13978A8506BEF79EC524565285330F3CF3E6698EE25EF3C6D9BF8BC7619F72 50217B0FFBB10240A344C911FF165960436A8BDE59944B0401DE68ABE0CCCC8E C2079FE9F74D53DAB010AA035CF61892B871697F1DB6E55F2EBB231F88BFE988 2F3847A9C3051D85400F9AC9F012CCB5C8C16086B89FE4BB84736CEE1B6CD354 2AA43722748EBAD8C81EE73B03FB45FCD0152B0AC9512BCF447499C2005348B8 48036DC6131FA84E3474F7F15E77B3FF03CA99BD1C8D0E4D7E4BC621F940CD19 95100A7091449727385DBF150BDC55A488DE2435E8E5567D483E1C52CB78A2F6 90393FBEDFC90E7D7F201AD2A486930E1EC4A31B87B81F1725B709CA15914778 26C6A169BB64E18955CE0DE58D24523D2D5BFBC771FD1CE6C579F66836352A81 B27F04ED16B0ED42FD8B0FA774D31C73B644F2B192EA473F87F1382A75E8ABF6 ADD7B213971FC0A972E9779F14F869718D6FF96FDE9EEBA90D72D43C96E22152 C19993A00F29C744A1FDE78D9AA4455C5837953508AE6C8205DFCC5FF311AC78 65F42E91289600AC2CFCDD780B4EE9EFCE8DF79630AF79CA21C09740DBEC20E5 5F2913C767D6230D71172562CCF6190D1879B71E7CA2497F5B4C6266921BC489 D2D21480FE48F9F899BE09D0A8CC067694FDCC586DA856B0201DEDAE1B224DD9 261C5E2113E05A540156D3F7A2DEE0FEBE72C02DF9FEED4CF8C807520F610701 2BC9C5121A119FA8654F2ED27E806DB721453C7A096D74B12C01DE85C33215B5 844A9B84EBD87B3525A62537BA54AAB879136368575A90F76A9EE857468DEE3E 8535CD771022D1E630EABF82F2052BA2B5E36FEE3B9A98010844D3DEBAF9084F A32F9CF94CB9ACD6CB03AA7D42220DF3AB81FB9DF3389BBC8F8C405F96413EFA BC514C61E90CBF10D412D73E4BE8BEE7560F2B3982EDAE7CF57F654EA4164E2B 9B493848E2B6A79E52675336766AF080D527999002FA63B081045F3A1D6203BE 800FE9D6691EE9A40D0008761BC143D5B48735969693C4506C4E50E408C51E3A B9AFFC84F2820CDE0D974F6A2EAFAFF67E0C9A16440D9921C529969F5017661E 1AB4DDF11815DB1110CACC52CAE906689EAC889481C5C57911BA9AC08BE368A4 742239D5526D9F2407B7A0D1F04C7052A4F3C9FC1B3EB9B79F5CE87A12DED9AE 0D779D14C9F50119CE994E1D1612FFCA7F66CB315E8F7A8DB5E0BB58F2BC4ED2 A735B926853E282FB2219802330175BEDD60B8D00EB02CF9EBC68CA7EE789FC0 8715F4E58EEEF44D48216B6C16425A6C6E42B11A6171C6F71F653707314C33C2 4FF331854468CA6BDD04ED53E0EBCED3281C5BD94902C37654DE0C0585F4A0D5 0197D2F32D6FC3359F83DCF3A92246B49AFECE98AA093F8E932676D73F3909D0 834B179A940287B5F192986F68452A7441E044C6C4709D6D550FE6080A7F4797 73E4F56D6DC85AAB1A78269C4C8FADAA459EAB80A0D6C0E48F1D0658D16E0EF5 F5E1020016D53B855683A051C877418600D75B7155B85EDE07CFAC0A9D63D563 C90CD98477C02D687EBFC41BE0C3BA2D4E4EB50C401659E8BFA20A7B28B740F4 62F1EB490B9E94ED9EFE33F654B74E3840D465E8F5F4628DB356D997FAEF7AF1 A60533ED9692FA1868E8F5C1500058A065A405866DCDD19AAC3A07E331014084 233AD43F5245C8B2C7E4C9B4F87957C30682AFC29275F76794A52155B05FA74B 94FD084C25227F03A4A8EA03348164D295C92A63689D4701FC12365467D56D21 0B18FA197B89E6D481F55C2E0F54E6749FC5A5D21DDE42346E830A357F32DEBE 2FCCAD0C63CC27AC15D4072188145B9C13A494C4951FF288CC5EFB5962E0521F F31577ADB52C6BA035E3328586BBD9114F1D53EA398161F464729E090FB3C6C5 9D85E8166827EB01833EF3AD903ED3EECA7CF57C82032A69832459FA1606FB60 3F00799E25D090816C27045DAFF8508B172D48B2FF057C994E2DFF781ECF64DA 16836A146AC06E8F779625436E7FD84AFDA555985C013859445FDBCD5A124EC1 4DFFA96B380B547F59D937121322BDFD26FCDF711C234F1BF3C8120EEBBB2D88 FE1811ECBB5EDD9373255EF01C27E7D80729BDE90B2A4A8246D5B9296D86F711 BDEA95B86E113CD460799407022AEBDF6964C01CCD163293FD5AA32FF2A39E9C 9D7979868ABAE2CDD708F3433055F3896AA323432AA3FF89E5F8435541CE01D2 77841E6EE1DCC5FD03D4F19BE4933B761DDE796B3070B22FEDCE315ED42FE47F 91FBB7C05B2D41D2AD8F83926A62E796ED52A9093E150D5E1D94A0FBFB4ADAD5 35C633BFA0064C2A2CC26D8B2D7B3A43C5144CEB521D51ADEF307DF903CED651 4C36C23E9996CEB41E0D0DF1D2AE3B20656CACA1944F61B3289BC269D6A236F3 04D33FFBA7A9ADB2E17B26D75C1AD3A71182012441BB2A5F77E281FFB66A4AC0 5370EDF218F458CF75AC159980E209A3809DBC9A3234167AEC65D4A3F7A4B4AD 0B0CC248ECCB2201FFF3F4AF4DD75E4CD5E8ACCF3B1D340141031267080E11E5 28861C5DAE117A35187E668DE17C588767D5F6EE3F9169BE56D1DEA83AEA3F0E 83BCB5C576627535C016B666F4148991C35310FDC913CEC7B7087EFD399C79FF D2729131E9ACE4515AD071C1E85E5B7B12A22A02D9679757A4714E87BB25B730 5CB54C8461D9F049FCD0CB5E137C2DD1CD60E0768623EF41C8418B44BDC8506B 9ECB20AEAFD080499E5679AF3192873B982CBF67B8ADC74617B317601B5C2CC2 DED220487C40EE1957079F40CA23B08B40987D02F9A4AEC8A9B8F14EFB94345A 5C010BE0CEAAA3BD0E7BB45E7E6481F6A52CF4C5F235F2E9AB31AB83EAEDA618 C79FC11392343DB1D3867BAE9A60A60EB56CAD27D78985A842AC5A35563265D3 5789BFFD7D740425FC466386DB8102AB47F2EA9278FAED3F77A97021165175A5 BB799FD15CD4339D1063178669CC9FA1BD7944B6A6BA23D1A6CAF64D360675F8 0FE3D590CA29A6E49F101C92819E290AC76C52EBA6E8A0CEC58C23F137E76D10 046891552A35C8514C9786598A2A36480CB69C5509B2667DD2C75DF8DC502EF4 9FB8CA1E3A777B035C9DE38C4E191E2289EBD57D22D095A3247A83C6983C9FFC A3360428999F4ADD8CB19C2765D533B37B19F0D7A90B8032903FB771116EBAD6 66408352E417810A48AA3ACAA33891ED82005F337E6ACA572B7DC03389A5B005 C2D154930F0DA8C3879B45BEDB3954C7B23BB987DA51E58CC60A064A805686BF DB38A32DA0E7F33DBF4FDCBFA38DE572FF8940DC13AA02F177A2E9ACD5A51576 FB0861DE943B1E1FC43D6EAD62F268DF522E887390B1068BC307DE6B83A898B0 C9B0D6A2FE1155CA9588C23F05660EFE0FD8373C7A4472F444E28F5766FA4F35 57D0633071D05B7F6DFD061665C053629023033CB6C47CBA0BA4C3FC5B8B1003 22B7281CEC89DF7379EF6105764F575DA0A98312CF6C27DDAEBF19F411F4F84B 5E900777A93128061E660D7E6AD6231D2739CE10DD5D42CBA9E6EDC14FD6B448 B7DDDFDD9B7D500E143288E12F918A080126C88E0D8148A8E20FCD744077E96A 1E51FA0150B157FC4D7CB37719EBB76B1DF4F8EA2D27BBFE2936BE92185BBAD5 293B29C9B90CFF4E0F5F442C16FBD947E2840A74F5D8E146257477A4EF20AD5F 81706EAF71701473C6436C9D36FA737F17FF063176FE622A764C418D22882BAC 40518720EAF7867FDE0C73E1C2D617905D2DE0446CFC136D39A84A7F5EFA63BE F6C22CD70F83437AB8E86E227A6B4FC4C415E2DA8EF1DCC524645BD9D6CA7160 3A3A48DF4539D9D77374292C2E5384B91F036C4692494CB392A848EF217DCDA4 505BBCA62FA1CEE33171A9CA80840657CF2897CC0D4BBEA9A743E6FE6D9119BF D74046AE6203F77DEA65EF5A62AC18D5E9C36515B22D688351E639C39A1E7F17 E81EBA231DCC2C68833D8B93E0750B62E30FB09DA9D23AC085D6C16722856E08 A1DAB0F3F3EF69A5738D03E54C57B4DBD2CF90B3DC4DE8948068785ADC7D5244 FBFA41AF4E8CBACC820EBC624DAA3C498ECF4E15A973000C4BD9D1590C8BD836 1B713301CE6707C5F95D2BBA48D5526A5726607AF2E15A306C425398DF4D0C16 2EE130A71C0389672D382EBED30DBBABEBCFF6ACD389D01DBAF89474C9F0D434 FD6AA06E6D51DE070B42CC131E71FB919BE113358FDEE0F6D4017400EB0C2DB1 9BF8872CED4D6697A2B320DC8FCB33FB6E9548948B4DEC84DA1D075DFEE913DF 8D787ABDB72DDBD0F9C178CBCC12CE243BE648681CF88CE44202C0ADEC62BFC0 254CB0088DBC3053BE68C9F4F067B1F0C83BE35ECDC454411C1C6C19B6EDF89A C953E8DA712DE5BAC701DE4CCB37865FBDA6FF7D0F9B72B0B0187BD73F1AC32D 067C6C627E3CCB3F9AF7601B15621C148D6B3DE04745BA2B4CA03AC0051A4019 D2E9143950ACE5D80BCACD8873899EBA94B83AC1A0DDC2456B7A45645D5DD05F FE7ADA0A70F06BB99EDA397F6F538F828055090EF6B37FAE71278E670A4CDA5B 4E2736B3A881E950072972FA56437567CF05754F874711138A133A9EE91DD210 2C4DE2FE001AD47785BE47ADF19439CA1C3B5D86DE9C81B6013F2ED80A621E5A E92AC8F518B06AA38E7DF3FAAE7A308124C2C8087626C9A6ED78A536D9AB07EC DE760B1FD0708157715E496F7050A16AC7E7050F59BDF34E7A2241011D0158DB 1E2BB3F6D4FECE15E47DC498C33F37E0A76CAFFEBEEE7BDBD81B371F2F5FD9B4 483F4C8CE1CB7CBAD6331B736AFB58B57719C9EBD995BE81F8897938353845BC B321861BA469413F6BEA75DBF69C037C1282946154693486E18D154EC0FB3FB0 A2ED0568C11B882E40BFB199FCB4F27F7259445193A52E2D28A26954BE21DFC9 F923F0CCC948E99B74C459CBC5E825DCCF5B62B1142F1CBFFB633C040A4BD4EA C08E0946C86D91C1CFC2A8008B153C8E451AFCE034A26CD4D49C26390C4968CA 5D9B513F2C03AFC7ADFB879172693F0856ACE512CACF5D8110F473EEC8A587B7 7653D7B2A5CB4382DFAC185F945841E94DC5C1F3B750896B2E088A36525CF28A 32ACF288148300C5D4673B108C70B756B5AB0C832F8E663CAFD998DE890E57D4 9E4500F5D86C8FDF185912EB2DB6F58F43DAA058704272043DDD5DCD01518B63 A7FE6D2304FDC0EE651D396AB0A905A3B9BE6181B0C115873F3E87880916F60E 1CE2733500D55DC4958D95C3E2474214C7553A5A09A420C5F98F7EBE4A40CFC7 F7F2350C620E25A97485708A5C3F81670B73EC5A38DB94BA60A1C0925124BFF3 9434E3F7589F196639B9A9AD649CE2F995D0B2DF444686C8F0DB7FEF48A65D70 1A73878E106D7ADCE37A2F47B3077558E1B279B7E733AFEC587EADFDE5AF422C 91AC39A18DA063602783AAD902928C15EBF7543FAE08A403D027F437112836A9 68932ED10670BF0672AA63F253710ADD3F98FAC5436D58229E97D9E83582F700 07BE58B2DCC540013610FAF099541FE9D695773E9546BEF5E0F074547B22963E 9F3A646A2DD21DFBC33FAC17819EED90B1068BD768065218100EF59438A73C41 70BC12B35893336490B7C4194662911582B4CA057EDAFD3BEE8C7B75A23F5B62 FEAABAE2D7252FDB7FC6D6E4FF1020ADBFE00490C154236C4E960A168F7B0629 6AFB53899EBEE3B54502E65B0BE4A8B649E82A948A740896F16A0CA3404B93F3 919108B91E7309FF25C3ACC7A82E3EECCFAA9FF29D1D4839A93D73FEDB1E65BA B493296249E7D53F699E040EBD16FF53FD08BB08DCF54DA0D9C201874C92763D 6A01A866523FB8F1BD0C4EE4D883F2ABBB8698B8939330057302E86DC1CF98A1 A588690C2BB37231940BBA3718B6E503E2D1A1F2C548130037C8AED9C2AE4BA6 D93461AA6A26D05E6077C30A2B1496337884A6327FD14A80D599428C29539522 44BCFCB749FEF2B1920B8101FAD95EC68CA3B3EEC30F8F5F9BFB43A7E16BDFE0 3F223A999452AF9279C3B94599BAA63E4F6C5A7F05530FB1762AC80B70966AAE 66CE035B3D9F5880244E7BD39EA6D2B630850C08FF0CCBBFBC5E41025E4D270D 5FA80AC17EAC85A7CF4DEBAD21D5F92139BD61AE4FC6E82CDEBB3FCA88DC3D63 9818A692FC09D36239DE9170737ED84987BADFA150796E6396508F709718767E F3757612619E3E01ACA6F6CB20B0AB85A6566145EA34105B1B44227102498E65 F4EA7EA7ACA2D4D1C0B1A4BC5D04BDC01ACF1101BAAE8076639BC6AA42A3A5A9 84745681A42FB79254F8E2CEC3B017B403013F29E59708F73076A65282B1E6E2 5673DDEDCB496A858E83234A85C5A7D42F5129B456DD36FD938905E7450079C4 950700E589A52B8475E9FD5B408206267B10CB1196363D53116324394BF31F2C 3A12C5965137DDBF9A04615C7DBEF7C22433634B804EC2FE1B4A28AA4A649F6C 75E5295FA4954D11470E31D7828812818DDA5CA2F89D33B2C29DBB946EBB9A05 1A5047CA8ECE4025466E53F5B2D499ABB1BFA0D91E361561CFFB78FE92685B5E 1843A54B922402D6EEE00074411FBDC52E994C0DB80E2A36171522E53EA0818C 3DF553696C7999CDDE5D63F04DD389202E1F52F01DFEB8AE71BD077D2596ED13 1EFB699470C85BDDA87CE4912EC0F36FA7AE19F337D3C887B531BF55DF20201E 4E923BC3A252AD29794926419E747B919E8EE6E4F4834E7B584D9396B044EB35 C855602E13DEFCE023855607A044A0153224ED064C548BF6D7208F98A54A40B8 83C841FA3767F43FA7D330FE27FAE64EEA65CA7594CDF710BD9EA9EA7B5AAE7D C43303BA4530C33A38B6A577C044D785B670A9FC9D5EE58CDEBDB161FFFCAEE1 EACF84BBCA69E6A1787CB926AEEB572DB8E679ABC1954216839E94A461E94EB0 00676944D287331CD397852BD355A98338B8A04147FBF33CE1691D5A290A6B3B 4702D25F09CF034BD86D055967DBF5A30FF169C2DB231E0C296211E222C04904 0C5C7CAFA5599496B720D7FE13313173AF58DFE6E701F84595D78095D0BB6D8E A7EE83835E7563F93D797E4F6BB2DEE01594F5565A50E5046E75D963A05FEEC3 6816EC50804708CDB42E37BC0AC43DE699F11465E58D59788F0A16FF21D8CEFD B5CF2B275F9513123D8BFC0949E778C161371032BE4902119587A95ECB8187F8 E632DCE5D956C165328DB2F92DEC1BAD882D89D348253C702D6586B83649ACB7 FC3B73296F43F428FBF4EDF31893A3B2AA68CA25E674AFB451B5E6F3CB073526 819931A6623221216D900BA30D83B7B1B42E16D2DC79B1415A11037A0B464E8A DF97B9B86C148B1B538B2CF2EDE51F813888DC7F092B21502FFD9BF2269514A1 29AE47955EFE00649B3D11FA8CC44E9AC7A1D7ACB000F1F1D00DDC9D4984FB44 AA5FC90DBAE9FAF8521B0CC2274F522EE1920B7B72B7E4C967F80D301311EB45 C2BDCB8410E890E3CD87745F17D0C7A5D56C7361C37598173374E09A8A9E77FD 30F0D7B3AF95C884EB8CF4853E48CE579297210D356807A96972C3A2C62A24A3 3E8CE4E2A0CEA310D96B489F4ECC0E69CD224DB2559CA6E3658218AF47E0608F 6CEC478BF49C72150FD3C7C1C9589619DA3ADD7718EAF9C22DFC777E2A871F30 57EB88F2E3CDE50F7693D5A47AA1CD1CB39704E498B6E1D7E30C92E7176BA440 B784F91FE9300AFBEB012AEAC7C323DA49947D7F46C1640A73ECE77435364212 6A4F3CC1795F9FDC5FDAFFD0FCA901EAB0FF7F3C8B6D6EAC8130A04A4AA53A1D 8A295191383FB52DD701BBB8D09FC133FF71069E1BF6211248310A238682AEC3 17F900C7571FA5B4175679D8CA7037ED6872DFCF6CEA80048C2C76347A8C4DE0 4217CFEE995096299797505A9600AF9885F29C5F33292792E4FF4466D6FA0F75 1F9A6C6E16E8471A09F1C804548302A0FB11634E247639F012C3A2190E83CDF3 52188C9C94BEE1F3BCC862091A3A8C4A17F52AB988092A97206575393B0B7312 0D5934F1F25454919A1A6D18418A3E0345DB8AFAFAD864FE0B1837E7EA0446F5 0BECCC9CE7102BFEA74C248A41093F5FD2159B752A9C5B2E3B8543824F8D77D9 8CB7196FD250F7AA0183308713DFDB154347EFFAC77324C8F6C1838BFDFEBA9D 7317705961B8420A93A912012E5A286CDA05D7C948F1E0FA5C91779ED2CD85A2 5A0D6FFC0BC16484B548958991AFBFD122F49718E8425D412BE76CA5EDDD65C4 9A843F0E765684BEC53FD7FF5F2C94D545D7F8760E28C727CCA9CAE52AEDE375 950DEF9A506FFA1D8B948DB4C4CC771CF114A991BD6E28A95C122382448267E5 55E2E8EC52E6022BD3AF2AF596EB5A0733A3597CC86235558EE7F1ABCACE0E92 8F4BE309C7CB20E361F938E512C9CEE0C1C6024664BF6FC4851E11AF8D7B421D C5C37FDDA13A50C88FF8EF039D3AA81376E46824C73785FC373A88FEEDD3E480 19211402EB895758A5618C462178157F41983841AD6CFE0C272B9713A1EF0B39 5FBEA1DC6D7D45DDEC4B133E78569928BC06722CC0B8784AF7351512AE2C9F4A A2D6ECD728D578FD6278BB7822FA1BFEDB519359AAEB688D118BC46D84CEE8A3 158111BA3E756CD354417DCEE985A06FB49F8923C5CBB91DA46E71D76BED3B79 975ECC7B18FAE8DA44B3EC39B398A8725A856F16A965F1415CC73435CA7417E4 7E2713AD39A1AC52A6A3E6C73DBD6312A3770983044BE9434E08F268A1C63230 2C197A49237F73414B5CDB1A3C1376B18814E51924DE685941EB13789E9B4694 F1CD319253863DCD44A2F5C5A909B641CD94720522370613D9CAE06ED30DDB05 2CC977169F3C1E3FD7D7FEAAFB601E35DFCFC0AA68E63F28562FCF4756AAC219 92F11C77525F82048E8212833F8A3567889DBA63C13F646A59AC665DC0F40861 58A910E2AE9236729D97ECB55F2F7BDCC6EA8168E4E333238B716A31EB8D8B8B 44944553A339A4F56C465A6DE057DE6975C112AB3700181A62039C3AA6D7CF99 F7BABD35F20260B3EE5A712DC180E56B648549334B1A7C341105B044E7AA43FC 5AF9E4B8A2A2385386D7ADBFC782E0DEF25108438DA20ED587898D8CBA9BB5D2 ED9ADFC81B4E85958658E5396C243C6BE961ECC6056F35400E3A310523A45222 F447322FE2BFF63E665F815DA368D003A16C786B51EE237C1979BA058F944401 1D84BF05DD377F0A0581B4EAFB9EF2879FF1ADBD484459A70C335A83A40423D5 ED999944C65AB54FEDC28D043259A6251C9B87C60A3D664FE89767FC5DDF575B 37821DC3956EC6325370781A0D9BC484EDF36A3DA288182E468E76E29823151E 945EB0BAFE1682464FD6407D5FF96D7968822666BE29708594D07A87C6F18F61 332D8BB527D147EF8EA872940BB43C420115E6B6E4AB539912E1DE5F095EDCB1 BD4F83F9C635C57858A3BC7289E4F09BCF30B0217D595C6283AD966838CFAECE 6195B0EE8B38CDD4B07401286623778314FBFD5E9E9D213F8C74C0035ADA5B40 2512A4F7B06E79D05E30055BC590375403D905CE571D84581EB6CF4472FA8817 5111976083C7C657D8CE22E49579843D59789D6A97133D0BF604E6F563B77973 8A2D8ED05907BAC946DC627494A0A9A51FD3D28212B02C485C745C44C2093565 07710A3260DB101ECB9462 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont TeXDict begin 40258437 52099151 1000 600 600 (gpsim.dvi) @start /Fc 240[42 1[83 13[{}2 83.022 /CMSY10 rf /Fd 205[45 50[{ TeXBase1Encoding ReEncodeFont }1 90.9091 /NimbusRomNo9L-Regu rf /Fe 134[44 3[44 44 44 44 1[44 44 44 44 44 44 1[44 44 44 1[44 44 44 44 44 1[44 10[44 32[44 44 3[44 46[{ T1Encoding ReEncodeFont }24 83.022 /SFIT1000 rf /Ff 134[33 33 48 33 33 18 26 22 1[33 33 33 52 18 33 1[18 33 33 22 29 33 29 33 29 8[48 63 2[41 37 2[37 2[59 3[22 2[37 41 1[44 44 48 17[18 17 22 17 2[22 22 22 36[37 2[{ TeXBase1Encoding ReEncodeFont }43 66.4176 /NimbusRomNo9L-Regu rf /Fg 205[25 25 49[{ TeXBase1Encoding ReEncodeFont }2 49.8132 /NimbusRomNo9L-Regu rf /Fh 134[37 37 55 37 42 23 32 32 1[42 42 42 60 23 37 23 23 42 42 23 37 42 37 42 42 1[42 1[32 1[32 3[69 51 60 46 42 51 1[51 2[69 3[28 1[60 51 51 60 55 1[51 2[56 3[28 1[42 42 42 42 1[42 42 42 42 23 21 28 2[42 2[28 2[42 1[35 30[42 3[{ TeXBase1Encoding ReEncodeFont }60 83.022 /NimbusRomNo9L-ReguItal rf /Fi 130[44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 1[44 44 44 44 44 44 1[44 44 44 44 44 44 44 1[44 44 44 44 44 44 1[44 44 44 44 44 44 44 44 44 1[44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 1[44 44 44 44 9[0 5[44 44 16[{ T1Encoding ReEncodeFont }90 83.022 /SFTT1000 rf /Fj 134[50 50 72 50 55 33 39 44 1[55 50 55 83 28 55 33 28 55 50 33 44 55 44 55 50 1[50 6[72 100 72 72 66 55 72 1[61 78 72 94 66 2[39 78 78 61 66 72 72 66 72 7[50 50 50 50 50 50 50 50 50 50 28 25 33 25 5[83 35[55 2[{ TeXBase1Encoding ReEncodeFont }62 99.6264 /NimbusRomNo9L-Medi rf /Fk 134[60 60 86 60 66 40 47 53 66 66 60 66 100 33 66 1[33 66 60 40 53 66 53 66 60 1[60 6[86 120 2[80 66 86 1[73 93 1[113 80 2[47 93 93 73 80 1[86 80 86 7[60 60 60 60 60 60 60 60 60 60 33 30 1[30 41[66 2[{ TeXBase1Encoding ReEncodeFont }56 119.552 /NimbusRomNo9L-Medi rf /Fl 139[57 1[76 1[96 7[96 2[76 3[86 29[124 9[86 86 86 86 86 86 86 86 86 86 48[{ TeXBase1Encoding ReEncodeFont }17 172.188 /NimbusRomNo9L-Medi rf /Fm 205[31 31 49[{ TeXBase1Encoding ReEncodeFont }2 61.4362 /NimbusRomNo9L-Regu rf /Fn 166[60 60 78 60 60 51 46 55 1[46 60 60 74 51 60 1[28 60 60 46 51 60 55 55 60 1[37 4[23 1[42 42 42 42 42 42 42 42 42 1[21 28 45[{ .167 SlantFont TeXBase1Encoding ReEncodeFont }36 83.022 /NimbusRomNo9L-Regu rf /Fo 42 79[28 24[42 1[37 37 24[37 42 42 60 42 42 23 32 28 42 42 42 42 65 23 42 23 23 42 42 28 37 42 37 42 37 1[42 1[28 23 28 51 60 60 78 60 60 51 46 55 60 46 60 60 74 51 60 32 28 60 60 46 51 60 55 55 60 1[37 47 47 47 23 23 42 42 42 42 42 42 42 42 42 42 23 21 28 21 47 42 28 28 28 65 69 1[42 34 28 29[46 46 2[{ TeXBase1Encoding ReEncodeFont }93 83.022 /NimbusRomNo9L-Regu rf /Fp 134[42 42 60 42 46 28 32 37 1[46 42 46 69 23 46 1[23 46 42 28 37 46 37 46 42 1[42 7[83 1[60 55 46 60 65 51 65 60 78 55 65 1[32 65 65 51 55 60 60 55 60 1[42 4[28 42 42 42 42 42 42 42 42 42 42 23 21 28 42[46 2[{ TeXBase1Encoding ReEncodeFont }61 83.022 /NimbusRomNo9L-Medi rf /Fq 134[103 103 149 103 115 69 80 92 1[115 103 115 172 57 115 1[57 115 103 69 92 115 92 115 103 9[207 1[149 138 115 149 2[161 149 195 138 2[80 161 161 126 138 149 149 138 149 1[103 4[69 7[103 103 103 1[52 69 42[115 2[{ TeXBase1Encoding ReEncodeFont }49 206.559 /NimbusRomNo9L-Medi rf /Fr 139[28 14[44 3[44 28[72 9[28 2[50 50 3[50 50 50 2[33 8[50 50 35[{ TeXBase1Encoding ReEncodeFont }13 99.6264 /NimbusRomNo9L-Regu rf /Fs 140[56 2[72 2[112 3[40 1[72 103[{ TeXBase1Encoding ReEncodeFont }5 143.462 /NimbusRomNo9L-Regu rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter /setpagedevice where { pop << /PageSize [612 792] >> setpagedevice } { /letter where { pop letter } if } ifelse %%EndPaperSize end %%EndSetup %%Page: 1 1 TeXDict begin 1 0 bop 0 0 a SDict begin [/Producer (dvips + Distiller)/Title ()/Subject ()/Creator (LaTeX with hyperref package)/Author ()/Keywords () /DOCINFO pdfmark end 0 0 a 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.1) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin [/Count -3/Dest (chapter.1) cvn/Title (\376\377\000g\000p\000s\000i\000m\000\040\000-\000\040\000A\000n\000\040\000O\000v\000e\000r\000v\000i\000e\000w) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -3/Dest (section.1.1) cvn/Title (\376\377\000M\000a\000k\000i\000n\000g\000\040\000t\000h\000e\000\040\000e\000x\000e\000c\000u\000t\000a\000b\000l\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.1.1.1) cvn/Title (\376\377\000M\000a\000k\000e\000\040\000D\000e\000t\000a\000i\000l\000s\000\040\000-\000\040\000.\000/\000c\000o\000n\000f\000i\000g\000u\000r\000e\000\040\000o\000p\000t\000i\000o\000n\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.1.1.2) cvn/Title (\376\377\000R\000P\000M\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.1.1.3) cvn/Title (\376\377\000W\000i\000n\000d\000o\000w\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.1.2) cvn/Title (\376\377\000R\000u\000n\000n\000i\000n\000g) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.1.3) cvn/Title (\376\377\000R\000e\000q\000u\000i\000r\000e\000m\000e\000n\000t\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -24/Dest (chapter.2) cvn/Title (\376\377\000C\000o\000m\000m\000a\000n\000d\000\040\000L\000i\000n\000e\000\040\000I\000n\000t\000e\000r\000f\000a\000c\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.1) cvn/Title (\376\377\000a\000t\000t\000a\000c\000h) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.2) cvn/Title (\376\377\000b\000r\000e\000a\000k) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.3) cvn/Title (\376\377\000c\000l\000e\000a\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.4) cvn/Title (\376\377\000d\000i\000s\000a\000s\000s\000e\000m\000b\000l\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.5) cvn/Title (\376\377\000d\000u\000m\000p) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.6) cvn/Title (\376\377\000e\000c\000h\000o) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.7) cvn/Title (\376\377\000f\000r\000e\000q\000u\000e\000n\000c\000y) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.8) cvn/Title (\376\377\000h\000e\000l\000p) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.9) cvn/Title (\376\377\000i\000c\000d) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.10) cvn/Title (\376\377\000l\000i\000s\000t\000\040) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.11) cvn/Title (\376\377\000l\000o\000a\000d) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.12) cvn/Title (\376\377\000m\000a\000c\000r\000o\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.13) cvn/Title (\376\377\000m\000o\000d\000u\000l\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.14) cvn/Title (\376\377\000n\000o\000d\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.15) cvn/Title (\376\377\000p\000r\000o\000c\000e\000s\000s\000o\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.16) cvn/Title (\376\377\000q\000u\000i\000t) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.17) cvn/Title (\376\377\000r\000u\000n) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.18) cvn/Title (\376\377\000s\000t\000e\000p) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.19) cvn/Title (\376\377\000s\000y\000m\000b\000o\000l) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.20) cvn/Title (\376\377\000s\000t\000i\000m\000u\000l\000u\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.21) cvn/Title (\376\377\000s\000t\000o\000p\000w\000a\000t\000c\000h\000T\000h\000e\000\040\000s\000t\000o\000p\000w\000a\000t\000c\000h\000\040\000i\000s\000\040\000r\000e\000a\000l\000l\000y\000\040\000a\000\040\000c\000o\000l\000l\000e\000c\000t\000i\000o\000n\000\040\000o\000f\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s\000\040\000a\000n\000d\000\040\000n\000o\000t\000\040\000a\000\040\000c\000o\000m\000m\000a\000n\000d\000.\000\040\000B\000u\000t\000\040\000t\000h\000e\000\040\000b\000e\000h\000a\000v\000i\000o\000r\000\040\000i\000s\000\040\000s\000o\000\040\000s\000i\000m\000i\000l\000a\000r\000\040\000t\000o\000\040\000a\000\040\000c\000o\000m\000m\000a\000n\000d\000\040\000t\000h\000a\000t\000\040\000i\000t\000\040\000h\000a\000s\000\040\000b\000e\000e\000n\000\040\000i\000n\000c\000l\000u\000d\000e\000d\000\040\000h\000e\000r\000e\000.) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.22) cvn/Title (\376\377\000t\000r\000a\000c\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.23) cvn/Title (\376\377\000v\000e\000r\000s\000i\000o\000n) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.2.24) cvn/Title (\376\377\000x) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -11/Dest (chapter.3) cvn/Title (\376\377\000G\000r\000a\000p\000h\000i\000c\000a\000l\000\040\000U\000s\000e\000r\000\040\000I\000n\000t\000e\000r\000f\000a\000c\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -3/Dest (section.3.1) cvn/Title (\376\377\000M\000a\000i\000n\000\040\000w\000i\000n\000d\000o\000w) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.3.1.1) cvn/Title (\376\377\000M\000e\000n\000u\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.3.1.2) cvn/Title (\376\377\000B\000u\000t\000t\000o\000n\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.3.1.3) cvn/Title (\376\377\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000\040\000m\000o\000d\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -2/Dest (section.3.2) cvn/Title (\376\377\000S\000o\000u\000r\000c\000e\000\040\000B\000r\000o\000w\000s\000e\000r\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.3.2.1) cvn/Title (\376\377\000.\000a\000s\000m\000\040\000B\000r\000o\000w\000s\000e\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.3.2.2) cvn/Title (\376\377\000O\000p\000c\000o\000d\000e\000\040\000v\000i\000e\000w\000\040\000-\000\040\000t\000h\000e\000\040\000.\000o\000b\000j\000\040\000B\000r\000o\000w\000s\000e\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.3) cvn/Title (\376\377\000R\000e\000g\000i\000s\000t\000e\000r\000\040\000v\000i\000e\000w\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.4) cvn/Title (\376\377\000S\000y\000m\000b\000o\000l\000\040\000v\000i\000e\000w) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.5) cvn/Title (\376\377\000W\000a\000t\000c\000h\000\040\000v\000i\000e\000w) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.6) cvn/Title (\376\377\000S\000t\000a\000c\000k\000\040\000v\000i\000e\000w\000e\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.7) cvn/Title (\376\377\000B\000r\000e\000a\000d\000b\000o\000a\000r\000d) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.8) cvn/Title (\376\377\000T\000r\000a\000c\000e\000\040\000v\000i\000e\000w\000e\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.9) cvn/Title (\376\377\000P\000r\000o\000f\000i\000l\000e\000\040\000v\000i\000e\000w\000e\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.10) cvn/Title (\376\377\000S\000t\000o\000p\000w\000a\000t\000c\000h) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.3.11) cvn/Title (\376\377\000S\000c\000o\000p\000e\000\040\000W\000i\000n\000d\000o\000w) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -2/Dest (chapter.4) cvn/Title (\376\377\000S\000c\000r\000i\000p\000t\000i\000n\000g\000\040\000a\000n\000d\000\040\000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -3/Dest (section.4.1) cvn/Title (\376\377\000E\000m\000b\000e\000d\000d\000e\000d\000\040\000C\000o\000m\000m\000a\000n\000d\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.4.1.1) cvn/Title (\376\377\000.\000s\000i\000m\000\040\000m\000a\000c\000r\000o) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.4.1.2) cvn/Title (\376\377\000.\000c\000o\000m\000m\000a\000n\000d\000\040\000m\000a\000c\000r\000o) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.4.1.3) cvn/Title (\376\377\000.\000a\000s\000s\000e\000r\000t\000\040\000m\000a\000c\000r\000o) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.4.2) cvn/Title (\376\377\000S\000o\000c\000k\000e\000t\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -1/Dest (chapter.5) cvn/Title (\376\377\000A\000s\000s\000e\000r\000t\000i\000o\000n\000s\000\040\000a\000n\000d\000\040\000E\000x\000t\000e\000n\000d\000e\000d\000\040\000B\000r\000e\000a\000k\000p\000o\000i\000n\000t\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.5.1) cvn/Title (\376\377\000A\000s\000s\000e\000r\000t\000i\000o\000n\000s\000\040\000a\000n\000d\000\040\000E\000m\000b\000e\000d\000d\000e\000d\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000o\000n\000\040\000c\000o\000m\000m\000a\000n\000d\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.6) cvn/Title (\376\377\000T\000r\000a\000c\000e\000\040\000a\000n\000d\000\040\000L\000o\000g\000:\000\040\000W\000h\000a\000t\000\040\000h\000a\000s\000\040\000h\000a\000p\000p\000e\000n\000?) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -5/Dest (chapter.7) cvn/Title (\376\377\000S\000i\000m\000u\000l\000a\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000R\000e\000a\000l\000\040\000W\000o\000r\000l\000d\000:\000\040\000S\000t\000i\000m\000u\000l\000i) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -1/Dest (section.7.1) cvn/Title (\376\377\000H\000o\000w\000\040\000T\000h\000e\000y\000\040\000W\000o\000r\000k) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.7.1.1) cvn/Title (\376\377\000C\000o\000n\000t\000e\000n\000t\000i\000o\000n\000\040\000a\000m\000o\000n\000g\000\040\000s\000t\000i\000m\000u\000l\000i) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.7.2) cvn/Title (\376\377\000I\000/\000O\000\040\000P\000i\000n\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -1/Dest (section.7.3) cvn/Title (\376\377\000A\000s\000y\000n\000c\000h\000r\000o\000n\000o\000u\000s\000\040\000S\000t\000i\000m\000u\000l\000i) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.7.3.1) cvn/Title (\376\377\000A\000n\000a\000l\000o\000g\000\040\000A\000s\000y\000n\000c\000h\000r\000o\000n\000o\000u\000s\000\040\000S\000t\000i\000m\000u\000l\000i) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.7.4) cvn/Title (\376\377\000E\000x\000t\000e\000n\000d\000e\000d\000\040\000S\000t\000i\000m\000u\000l\000i) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -1/Dest (section.7.5) cvn/Title (\376\377\000L\000i\000m\000i\000t\000a\000t\000i\000o\000n\000s\000\040\000o\000f\000\040\000t\000h\000e\000\040\000S\000t\000i\000m\000u\000l\000u\000s\000\040\000M\000e\000c\000h\000a\000n\000i\000s\000m) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.7.5.1) cvn/Title (\376\377\000P\000r\000o\000p\000a\000g\000a\000t\000i\000o\000n\000\040\000D\000e\000l\000a\000y\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -3/Dest (chapter.8) cvn/Title (\376\377\000M\000o\000d\000u\000l\000e\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -7/Dest (section.8.1) cvn/Title (\376\377\000g\000p\000s\000i\000m\000\040\000M\000o\000d\000u\000l\000e\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.1) cvn/Title (\376\377\000U\000S\000A\000R\000T) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.2) cvn/Title (\376\377\000L\000o\000g\000i\000c) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.3) cvn/Title (\376\377\000I\0002\000C\000\040\000E\000E\000P\000R\000O\000M) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.4) cvn/Title (\376\377\000S\000w\000i\000t\000c\000h\000e\000s\000\040\000\046\000\040\000R\000e\000s\000i\000s\000t\000o\000r\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.5) cvn/Title (\376\377\000V\000o\000l\000t\000a\000g\000e\000\040\000S\000o\000u\000r\000c\000e\000s\000,\000\040\000R\000e\000s\000i\000s\000t\000o\000r\000s\000,\000\040\000a\000n\000d\000\040\000C\000a\000p\000a\000c\000i\000t\000o\000r\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.6) cvn/Title (\376\377\000L\000E\000D\000\137\0007\000S\000E\000G\000M\000E\000N\000T\000S\000\040\000a\000n\000d\000\040\000L\000E\000D) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.1.7) cvn/Title (\376\377\000I\0002\000C\000\040\000s\000l\000a\000v\000e\000\040\000t\000o\000\040\000P\000a\000r\000a\000l\000l\000e\000l\000\040\000p\000o\000r\000t) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -7/Dest (section.8.2) cvn/Title (\376\377\000E\000x\000t\000r\000a\000s\000\040\000M\000o\000d\000u\000l\000e\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.1) cvn/Title (\376\377\000T\000e\000m\000p\000e\000r\000a\000t\000u\000r\000e\000\040\000a\000n\000d\000\040\000h\000u\000m\000i\000d\000i\000t\000y\000\040\000s\000e\000n\000s\000o\000r\000\040\000-\000\040\000D\000H\000T\0001\0001) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.2) cvn/Title (\376\377\0006\0004\000\040\000x\000\040\0008\000,\000\040\000S\000e\000r\000i\000a\000l\000,\000\040\000I\0002\000C\000\040\000R\000e\000a\000l\000-\000T\000i\000m\000e\000\040\000C\000l\000o\000c\000k\000\040\000-\000\040\000D\000S\0001\0003\0000\0007) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.3) cvn/Title (\376\377\000H\000i\000g\000h\000-\000P\000r\000e\000c\000i\000s\000i\000o\000n\000\040\0001\000-\000W\000i\000r\000e\000\040\000D\000i\000g\000i\000t\000a\000l\000\040\000T\000h\000e\000r\000m\000o\000m\000e\000t\000e\000r\000\040\000-\000\040\000D\000S\0001\0008\0002\0000\000\040\000F\000a\000m\000i\000l\000y) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.4) cvn/Title (\376\377\000C\000h\000a\000r\000a\000c\000t\000e\000r\000\040\000L\000C\000D\000\040\000-\000\040\000H\000D\0004\0004\0007\0008\0000) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.5) cvn/Title (\376\377\000G\000r\000a\000p\000h\000i\000c\000\040\000L\000C\000D\000\040\000-\000\040\000S\000E\000D\0001\0005\0003\0000) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.6) cvn/Title (\376\377\000L\000C\000D\000\137\0007\000S\000e\000g) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (subsection.8.2.7) cvn/Title (\376\377\000S\000o\000l\000a\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.8.3) cvn/Title (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000n\000e\000w\000\040\000m\000o\000d\000u\000l\000e\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.9) cvn/Title (\376\377\000S\000y\000m\000b\000o\000l\000i\000c\000\040\000D\000e\000b\000u\000g\000g\000i\000n\000g) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.10) cvn/Title (\376\377\000M\000a\000c\000r\000o\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.11) cvn/Title (\376\377\000H\000e\000x\000\040\000F\000i\000l\000e\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.12) cvn/Title (\376\377\000T\000h\000e\000\040\000I\000C\000D\000-\000\040\000N\000o\000t\000\040\000S\000u\000p\000p\000o\000r\000t\000e\000d\000\040\000i\000n\000\040\000v\000e\000r\000s\000i\000o\000n\000s\000\040\0000\000.\0002\0001\000.\0000\000\040\000a\000n\000d\000\040\000l\000a\000t\000e\000r) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.13) cvn/Title (\376\377\000E\000x\000a\000m\000p\000l\000e\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (chapter.14) cvn/Title (\376\377\000R\000e\000g\000r\000e\000s\000s\000i\000o\000n\000\040\000T\000e\000s\000t\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -8/Dest (chapter.15) cvn/Title (\376\377\000T\000h\000e\000o\000r\000y\000\040\000o\000f\000\040\000O\000p\000e\000r\000a\000t\000i\000o\000n) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.1) cvn/Title (\376\377\000B\000a\000c\000k\000g\000r\000o\000u\000n\000d) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.2) cvn/Title (\376\377\000I\000n\000s\000t\000r\000u\000c\000t\000i\000o\000n\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.3) cvn/Title (\376\377\000G\000e\000n\000e\000r\000a\000l\000\040\000F\000i\000l\000e\000\040\000R\000e\000g\000i\000s\000t\000e\000r\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.4) cvn/Title (\376\377\000S\000p\000e\000c\000i\000a\000l\000\040\000F\000i\000l\000e\000\040\000R\000e\000g\000i\000s\000t\000e\000r\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.5) cvn/Title (\376\377\000E\000x\000a\000m\000p\000l\000e\000\040\000o\000f\000\040\000a\000n\000\040\000i\000n\000s\000t\000r\000u\000c\000t\000i\000o\000n) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.6) cvn/Title (\376\377\000T\000r\000a\000c\000e) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.7) cvn/Title (\376\377\000B\000r\000e\000a\000k\000p\000o\000i\000n\000t\000s) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.15.8) cvn/Title (\376\377\000T\000I\000M\000E\000R\0001\000\040\000E\000x\000t\000e\000r\000n\000a\000l\000\040\000i\000n\000p\000u\000t) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -3/Dest (chapter.16) cvn/Title (\376\377\000L\000I\000C\000E\000N\000S\000E\000S) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.16.1) cvn/Title (\376\377\000G\000p\000s\000i\000m\000.\000l\000y\000x) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.16.2) cvn/Title (\376\377\000G\000p\000s\000i\000m) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/Count -0/Dest (section.16.3) cvn/Title (\376\377\000L\000i\000b\000r\000a\000r\000i\000e\000s\000\040\000l\000i\000b\000g\000p\000s\000i\000m\000,\000\040\000l\000i\000b\000g\000p\000s\000i\000m\000\137\000m\000o\000d\000u\000l\000e\000s\000,\000\040\000l\000i\000b\000g\000p\000s\000i\000m\000\137\000e\000X\000d\000b\000m\000\040) /OUT pdfmark end 515 432 a 515 432 a SDict begin [/PageMode /UseOutlines/Page 1/View [/Fit] /DOCVIEW pdfmark end 515 432 a 515 432 a SDict begin [ {Catalog}<<>> /PUT pdfmark end 515 432 a 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (Doc-Start) cvn /DEST pdfmark end 515 432 a 515 432 a SDict begin [ {Catalog} <>1<>]>>>> /PUT pdfmark end 515 432 a Black Black 1771 2184 a Fs(gpsim)1503 2840 y Fr($Date::)30 b(2017-06-12#$)p Black Black eop end %%Page: 1 2 TeXDict begin 1 1 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.1) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter*.1) cvn /DEST pdfmark end 515 432 a 772 x Fq(Contents)515 1744 y SDict begin H.S end 515 1744 a Fp(1)82 b(gpsim)21 b(-)g(An)f(Ov)o(er)o(view)1388 1744 y SDict begin 12 H.L end 1388 1744 a 1388 1744 a SDict begin [/Subtype /Link/Dest (chapter.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1388 1744 a 1949 w Fp(6)639 1869 y SDict begin H.S end 639 1869 a Fo(1.1)86 b(Making)19 b(the)h(e)o(x)o(ecutable)1586 1869 y SDict begin 12 H.L end 1586 1869 a 1586 1869 a SDict begin [/Subtype /Link/Dest (section.1.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1586 1869 a 70 w Fo(.)42 b(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)p Black 165 w(6)p Black 830 1993 a SDict begin H.S end 830 1993 a Fo(1.1.1)98 b(Mak)o(e)20 b(Details)h(-)f(./con\002gure)e(options)2233 1993 y SDict begin 12 H.L end 2233 1993 a 2233 1993 a SDict begin [/Subtype /Link/Dest (subsection.1.1.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2233 1993 a 46 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 165 w(6)p Black 830 2118 a SDict begin H.S end 830 2118 a Fo(1.1.2)98 b(RPMs)1303 2118 y SDict begin 12 H.L end 1303 2118 a 1303 2118 a SDict begin [/Subtype /Link/Dest (subsection.1.1.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1303 2118 a 42 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 165 w(7)p Black 830 2242 a SDict begin H.S end 830 2242 a Fo(1.1.3)98 b(W)m(indo)n(ws)1410 2242 y SDict begin 12 H.L end 1410 2242 a 1410 2242 a SDict begin [/Subtype /Link/Dest (subsection.1.1.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1410 2242 a 59 w Fo(.)42 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 165 w(7)p Black 639 2367 a SDict begin H.S end 639 2367 a Fo(1.2)86 b(Running)1118 2367 y SDict begin 12 H.L end 1118 2367 a 1118 2367 a SDict begin [/Subtype /Link/Dest (section.1.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1118 2367 a 40 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)p Black 165 w(7)p Black 639 2491 a SDict begin H.S end 639 2491 a Fo(1.3)86 b(Requirements)1293 2491 y SDict begin 12 H.L end 1293 2491 a 1293 2491 a SDict begin [/Subtype /Link/Dest (section.1.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1293 2491 a 52 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 165 w(8)p Black 515 2699 a SDict begin H.S end 515 2699 a Fp(2)82 b(Command)21 b(Line)g(Interface)1540 2699 y SDict begin 12 H.L end 1540 2699 a 1540 2699 a SDict begin [/Subtype /Link/Dest (chapter.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1540 2699 a 1797 w Fp(9)639 2823 y SDict begin H.S end 639 2823 a Fo(2.1)86 b(attach)1029 2823 y SDict begin 12 H.L end 1029 2823 a 1029 2823 a SDict begin [/Subtype /Link/Dest (section.2.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1029 2823 a 67 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)p Black 124 w(10)p Black 639 2948 a SDict begin H.S end 639 2948 a Fo(2.2)86 b(break)1016 2948 y SDict begin 12 H.L end 1016 2948 a 1016 2948 a SDict begin [/Subtype /Link/Dest (section.2.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1016 2948 a 80 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(11)p Black 639 3072 a SDict begin H.S end 639 3072 a Fo(2.3)86 b(clear)992 3072 y SDict begin 12 H.L end 992 3072 a 992 3072 a SDict begin [/Subtype /Link/Dest (section.2.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 992 3072 a 42 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)g(.)h(.)p Black 124 w(13)p Black 639 3197 a SDict begin H.S end 639 3197 a Fo(2.4)86 b(disassemble)1232 3197 y SDict begin 12 H.L end 1232 3197 a 1232 3197 a SDict begin [/Subtype /Link/Dest (section.2.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1232 3197 a 51 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(14)p Black 639 3321 a SDict begin H.S end 639 3321 a Fo(2.5)86 b(dump)1021 3321 y SDict begin 12 H.L end 1021 3321 a 1021 3321 a SDict begin [/Subtype /Link/Dest (section.2.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1021 3321 a 75 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(14)p Black 639 3446 a SDict begin H.S end 639 3446 a Fo(2.6)86 b(echo)988 3446 y SDict begin 12 H.L end 988 3446 a 988 3446 a SDict begin [/Subtype /Link/Dest (section.2.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 988 3446 a 46 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(15)p Black 639 3571 a SDict begin H.S end 639 3571 a Fo(2.7)86 b(frequenc)o(y)1164 3571 y SDict begin 12 H.L end 1164 3571 a 1164 3571 a SDict begin [/Subtype /Link/Dest (section.2.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1164 3571 a 56 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(15)p Black 639 3695 a SDict begin H.S end 639 3695 a Fo(2.8)86 b(help)974 3695 y SDict begin 12 H.L end 974 3695 a 974 3695 a SDict begin [/Subtype /Link/Dest (section.2.8) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 974 3695 a 60 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) h(.)p Black 124 w(15)p Black 639 3820 a SDict begin H.S end 639 3820 a Fo(2.9)86 b(icd)932 3820 y SDict begin 12 H.L end 932 3820 a 932 3820 a SDict begin [/Subtype /Link/Dest (section.2.9) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 932 3820 a 39 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) g(.)h(.)p Black 124 w(15)p Black 639 3944 a SDict begin H.S end 639 3944 a Fo(2.10)i(list)953 3944 y SDict begin 12 H.L end 953 3944 a 953 3944 a SDict begin [/Subtype /Link/Dest (section.2.10) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 953 3944 a 81 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(15)p Black 639 4069 a SDict begin H.S end 639 4069 a Fo(2.11)i(load)974 4069 y SDict begin 12 H.L end 974 4069 a 974 4069 a SDict begin [/Subtype /Link/Dest (section.2.11) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 974 4069 a 60 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(16)p Black 639 4193 a SDict begin H.S end 639 4193 a Fo(2.12)i(macros)1071 4193 y SDict begin 12 H.L end 1071 4193 a 1071 4193 a SDict begin [/Subtype /Link/Dest (section.2.12) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1071 4193 a 25 w Fo(.)d(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(16)p Black 639 4318 a SDict begin H.S end 639 4318 a Fo(2.13)i(module)1081 4318 y SDict begin 12 H.L end 1081 4318 a 1081 4318 a SDict begin [/Subtype /Link/Dest (section.2.13) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1081 4318 a 77 w Fo(.)d(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(18)p Black 639 4442 a SDict begin H.S end 639 4442 a Fo(2.14)i(node)993 4442 y SDict begin 12 H.L end 993 4442 a 993 4442 a SDict begin [/Subtype /Link/Dest (section.2.14) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 993 4442 a 41 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)p Black 124 w(19)p Black 639 4567 a SDict begin H.S end 639 4567 a Fo(2.15)i(processor)1150 4567 y SDict begin 12 H.L end 1150 4567 a 1150 4567 a SDict begin [/Subtype /Link/Dest (section.2.15) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1150 4567 a 70 w Fo(.)e(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)g(.)h(.)p Black 124 w(20)p Black 639 4691 a SDict begin H.S end 639 4691 a Fo(2.16)i(quit)960 4691 y SDict begin 12 H.L end 960 4691 a 960 4691 a SDict begin [/Subtype /Link/Dest (section.2.16) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 960 4691 a 74 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(20)p Black 639 4816 a SDict begin H.S end 639 4816 a Fo(2.17)i(run)942 4816 y SDict begin 12 H.L end 942 4816 a 942 4816 a SDict begin [/Subtype /Link/Dest (section.2.17) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 942 4816 a 29 w Fo(.)e(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(20)p Black 639 4940 a SDict begin H.S end 639 4940 a Fo(2.18)i(step)964 4940 y SDict begin 12 H.L end 964 4940 a 964 4940 a SDict begin [/Subtype /Link/Dest (section.2.18) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 964 4940 a 70 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(20)p Black Black 1926 5208 a(1)p Black eop end %%Page: 2 3 TeXDict begin 2 2 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.2) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CONTENTS)2388 b Fo(2)p Black 639 515 a SDict begin H.S end 639 515 a Fo(2.19)44 b(symbol)1076 515 y SDict begin 12 H.L end 1076 515 a 1076 515 a SDict begin [/Subtype /Link/Dest (section.2.19) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1076 515 a 20 w Fo(.)d(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(21)p Black 639 640 a SDict begin H.S end 639 640 a Fo(2.20)i(stimulus)1112 640 y SDict begin 12 H.L end 1112 640 a 1112 640 a SDict begin [/Subtype /Link/Dest (section.2.20) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1112 640 a 46 w Fo(.)d(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) g(.)h(.)p Black 124 w(21)p Black 639 764 a SDict begin H.S end 639 764 a Fo(2.21)i(stopw)o(atch)1167 764 y SDict begin H.S end 1167 764 a -30 x Fm(1)1201 764 y SDict begin 12 H.L end 1201 764 a 1201 764 a SDict begin [/Subtype /Link/Dest (Hfootnote.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1201 764 a 1201 764 a SDict begin 12 H.L end 1201 764 a 1201 764 a SDict begin [/Subtype /Link/Dest (Hfootnote.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1201 764 a 82 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(22)p Black 639 889 a SDict begin H.S end 639 889 a Fo(2.22)i(trace)992 889 y SDict begin 12 H.L end 992 889 a 992 889 a SDict begin [/Subtype /Link/Dest (section.2.22) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 992 889 a 42 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(23)p Black 639 1013 a SDict begin H.S end 639 1013 a Fo(2.23)i(v)o(ersion)1075 1013 y SDict begin 12 H.L end 1075 1013 a 1075 1013 a SDict begin [/Subtype /Link/Dest (section.2.23) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1075 1013 a 21 w Fo(.)d(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(23)p Black 639 1138 a SDict begin H.S end 639 1138 a Fo(2.24)i(x)872 1138 y SDict begin 12 H.L end 872 1138 a 872 1138 a SDict begin [/Subtype /Link/Dest (section.2.24) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 872 1138 a 37 w Fo(.)d(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) h(.)f(.)g(.)g(.)h(.)p Black 124 w(23)p Black 515 1346 a SDict begin H.S end 515 1346 a Fp(3)82 b(Graphical)20 b(User)h(Interface)1531 1346 y SDict begin 12 H.L end 1531 1346 a 1531 1346 a SDict begin [/Subtype /Link/Dest (chapter.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1531 1346 a 1765 w Fp(24)639 1470 y SDict begin H.S end 639 1470 a Fo(3.1)86 b(Main)20 b(windo)n(w)1293 1470 y SDict begin 12 H.L end 1293 1470 a 1293 1470 a SDict begin [/Subtype /Link/Dest (section.3.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1293 1470 a 52 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(24)p Black 830 1595 a SDict begin H.S end 830 1595 a Fo(3.1.1)98 b(Menus)1323 1595 y SDict begin 12 H.L end 1323 1595 a 1323 1595 a SDict begin [/Subtype /Link/Dest (subsection.3.1.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1323 1595 a 22 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(24)p Black 830 1719 a SDict begin H.S end 830 1719 a Fo(3.1.2)98 b(Buttons)1355 1719 y SDict begin 12 H.L end 1355 1719 a 1355 1719 a SDict begin [/Subtype /Link/Dest (subsection.3.1.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1355 1719 a 52 w Fo(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(24)p Black 830 1844 a SDict begin H.S end 830 1844 a Fo(3.1.3)98 b(Simulation)19 b(mode)1667 1844 y SDict begin 12 H.L end 1667 1844 a 1667 1844 a SDict begin [/Subtype /Link/Dest (subsection.3.1.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1667 1844 a 52 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(25)p Black 639 1968 a SDict begin H.S end 639 1968 a Fo(3.2)86 b(Source)20 b(Bro)n(wsers)1394 1968 y SDict begin 12 H.L end 1394 1968 a 1394 1968 a SDict begin [/Subtype /Link/Dest (section.3.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1394 1968 a 75 w Fo(.)42 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(25)p Black 830 2093 a SDict begin H.S end 830 2093 a Fo(3.2.1)98 b(.asm)20 b(Bro)n(wser)1551 2093 y SDict begin 12 H.L end 1551 2093 a 1551 2093 a SDict begin [/Subtype /Link/Dest (subsection.3.2.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1551 2093 a 43 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(25)p Black 830 2217 a SDict begin H.S end 830 2217 a Fo(3.2.2)98 b(Opcode)19 b(vie)n(w)h(-)g(the)h (.obj)e(Bro)n(wser)2153 2217 y SDict begin 12 H.L end 2153 2217 a 2153 2217 a SDict begin [/Subtype /Link/Dest (subsection.3.2.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2153 2217 a 64 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(26)p Black 639 2342 a SDict begin H.S end 639 2342 a Fo(3.3)86 b(Re)o(gister)20 b(vie)n(ws)1318 2342 y SDict begin 12 H.L end 1318 2342 a 1318 2342 a SDict begin [/Subtype /Link/Dest (section.3.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1318 2342 a 27 w Fo(.)41 b(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(27)p Black 639 2466 a SDict begin H.S end 639 2466 a Fo(3.4)86 b(Symbol)19 b(vie)n(w)1269 2466 y SDict begin 12 H.L end 1269 2466 a 1269 2466 a SDict begin [/Subtype /Link/Dest (section.3.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1269 2466 a 76 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(28)p Black 639 2591 a SDict begin H.S end 639 2591 a Fo(3.5)86 b(W)-7 b(atch)21 b(vie)n(w)1221 2591 y SDict begin 12 H.L end 1221 2591 a 1221 2591 a SDict begin [/Subtype /Link/Dest (section.3.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1221 2591 a 62 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)p Black 124 w(28)p Black 639 2715 a SDict begin H.S end 639 2715 a Fo(3.6)86 b(Stack)20 b(vie)n(wer)1260 2715 y SDict begin 12 H.L end 1260 2715 a 1260 2715 a SDict begin [/Subtype /Link/Dest (section.3.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1260 2715 a 23 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)p Black 124 w(29)p Black 639 2840 a SDict begin H.S end 639 2840 a Fo(3.7)86 b(Breadboard)1220 2840 y SDict begin 12 H.L end 1220 2840 a 1220 2840 a SDict begin [/Subtype /Link/Dest (section.3.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1220 2840 a 63 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(29)p Black 639 2964 a SDict begin H.S end 639 2964 a Fo(3.8)86 b(T)m(race)20 b(vie)n(wer)1262 2964 y SDict begin 12 H.L end 1262 2964 a 1262 2964 a SDict begin [/Subtype /Link/Dest (section.3.8) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1262 2964 a 21 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(30)p Black 639 3089 a SDict begin H.S end 639 3089 a Fo(3.9)86 b(Pro\002le)20 b(vie)n(wer)1297 3089 y SDict begin 12 H.L end 1297 3089 a 1297 3089 a SDict begin [/Subtype /Link/Dest (section.3.9) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1297 3089 a 48 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) g(.)h(.)p Black 124 w(30)p Black 639 3214 a SDict begin H.S end 639 3214 a Fo(3.10)i(Stopw)o(atch)1181 3214 y SDict begin 12 H.L end 1181 3214 a 1181 3214 a SDict begin [/Subtype /Link/Dest (section.3.10) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1181 3214 a 39 w Fo(.)e(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(31)p Black 639 3338 a SDict begin H.S end 639 3338 a Fo(3.11)i(Scope)20 b(W)m(indo)n(w)1336 3338 y SDict begin 12 H.L end 1336 3338 a 1336 3338 a SDict begin [/Subtype /Link/Dest (section.3.11) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1336 3338 a 71 w Fo(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(32)p Black 515 3546 a SDict begin H.S end 515 3546 a Fp(4)82 b(Scripting)21 b(and)f(Con\002guring)1572 3546 y SDict begin 12 H.L end 1572 3546 a 1572 3546 a SDict begin [/Subtype /Link/Dest (chapter.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1572 3546 a 1724 w Fp(33)639 3670 y SDict begin H.S end 639 3670 a Fo(4.1)86 b(Embedded)18 b(Commands)1586 3670 y SDict begin 12 H.L end 1586 3670 a 1586 3670 a SDict begin [/Subtype /Link/Dest (section.4.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1586 3670 a 70 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(33)p Black 830 3795 a SDict begin H.S end 830 3795 a Fo(4.1.1)98 b(.sim)20 b(macro)1466 3795 y SDict begin 12 H.L end 1466 3795 a 1466 3795 a SDict begin [/Subtype /Link/Dest (subsection.4.1.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1466 3795 a 66 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(33)p Black 830 3919 a SDict begin H.S end 830 3919 a Fo(4.1.2)98 b(.command)18 b(macro)1674 3919 y SDict begin 12 H.L end 1674 3919 a 1674 3919 a SDict begin [/Subtype /Link/Dest (subsection.4.1.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1674 3919 a 45 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(34)p Black 830 4044 a SDict begin H.S end 830 4044 a Fo(4.1.3)98 b(.assert)20 b(macro)1535 4044 y SDict begin 12 H.L end 1535 4044 a 1535 4044 a SDict begin [/Subtype /Link/Dest (subsection.4.1.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1535 4044 a 59 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(34)p Black 639 4168 a SDict begin H.S end 639 4168 a Fo(4.2)86 b(Sock)o(ets)1088 4168 y SDict begin 12 H.L end 1088 4168 a 1088 4168 a SDict begin [/Subtype /Link/Dest (section.4.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1088 4168 a 70 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(35)p Black 515 4376 a SDict begin H.S end 515 4376 a Fp(5)82 b(Assertions)21 b(and)g(Extended)f(Br)o(eakpoints)1974 4376 y SDict begin 12 H.L end 1974 4376 a 1974 4376 a SDict begin [/Subtype /Link/Dest (chapter.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1974 4376 a 1322 w Fp(36)639 4500 y SDict begin H.S end 639 4500 a Fo(5.1)86 b(Assertions)20 b(and)g(Embedded)e (Simulation)h(commands)2465 4500 y SDict begin 12 H.L end 2465 4500 a 2465 4500 a SDict begin [/Subtype /Link/Dest (section.5.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2465 4500 a 63 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(37)p Black 515 4708 a SDict begin H.S end 515 4708 a Fp(6)82 b(T)-6 b(race)20 b(and)h(Log:)k(What)20 b(has)h(happen?)1873 4708 y SDict begin 12 H.L end 1873 4708 a 1873 4708 a SDict begin [/Subtype /Link/Dest (chapter.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1873 4708 a 1423 w Fp(38)p Black Black eop end %%Page: 3 4 TeXDict begin 3 3 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.3) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CONTENTS)2388 b Fo(3)p Black 515 515 a SDict begin H.S end 515 515 a Fp(7)82 b(Simulating)21 b(the)f(Real)g(W)-6 b(orld:)25 b(Stimuli)1897 515 y SDict begin 12 H.L end 1897 515 a 1897 515 a SDict begin [/Subtype /Link/Dest (chapter.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1897 515 a 1399 w Fp(41)639 637 y SDict begin H.S end 639 637 a Fo(7.1)86 b(Ho)n(w)20 b(The)o(y)f(W)-7 b(ork)1383 637 y SDict begin 12 H.L end 1383 637 a 1383 637 a SDict begin [/Subtype /Link/Dest (section.7.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1383 637 a 24 w Fo(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(41)p Black 830 759 a SDict begin H.S end 830 759 a Fo(7.1.1)98 b(Contention)19 b(among)f(stimuli)1963 759 y SDict begin 12 H.L end 1963 759 a 1963 759 a SDict begin [/Subtype /Link/Dest (subsection.7.1.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1963 759 a 67 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(42)p Black 639 881 a SDict begin H.S end 639 881 a Fo(7.2)86 b(I/O)21 b(Pins)1105 881 y SDict begin 12 H.L end 1105 881 a 1105 881 a SDict begin [/Subtype /Link/Dest (section.7.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1105 881 a 53 w Fo(.)41 b(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(42)p Black 639 1003 a SDict begin H.S end 639 1003 a Fo(7.3)86 b(Asynchronous)18 b(Stimuli)1576 1003 y SDict begin 12 H.L end 1576 1003 a 1576 1003 a SDict begin [/Subtype /Link/Dest (section.7.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1576 1003 a 80 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(43)p Black 830 1125 a SDict begin H.S end 830 1125 a Fo(7.3.1)98 b(Analog)19 b(Asynchronous)e (Stimuli)2106 1125 y SDict begin 12 H.L end 2106 1125 a 2106 1125 a SDict begin [/Subtype /Link/Dest (subsection.7.3.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2106 1125 a 48 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) g(.)h(.)p Black 124 w(44)p Black 639 1247 a SDict begin H.S end 639 1247 a Fo(7.4)86 b(Extended)19 b(Stimuli)1410 1247 y SDict begin 12 H.L end 1410 1247 a 1410 1247 a SDict begin [/Subtype /Link/Dest (section.7.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1410 1247 a 59 w Fo(.)42 b(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(44)p Black 639 1369 a SDict begin H.S end 639 1369 a Fo(7.5)86 b(Limitations)20 b(of)g(the)g(Stimulus)g(Mechanism)2151 1369 y SDict begin 12 H.L end 2151 1369 a 2151 1369 a SDict begin [/Subtype /Link/Dest (section.7.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2151 1369 a 66 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(44)p Black 830 1491 a SDict begin H.S end 830 1491 a Fo(7.5.1)98 b(Propagation)17 b(Delays)1748 1491 y SDict begin 12 H.L end 1748 1491 a 1748 1491 a SDict begin [/Subtype /Link/Dest (subsection.7.5.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1748 1491 a 33 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(45)p Black 515 1696 a SDict begin H.S end 515 1696 a Fp(8)82 b(Modules)943 1696 y SDict begin 12 H.L end 943 1696 a 943 1696 a SDict begin [/Subtype /Link/Dest (chapter.8) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 943 1696 a 2353 w Fp(46)639 1818 y SDict begin H.S end 639 1818 a Fo(8.1)k(gpsim)20 b(Modules)1346 1818 y SDict begin 12 H.L end 1346 1818 a 1346 1818 a SDict begin [/Subtype /Link/Dest (section.8.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1346 1818 a 61 w Fo(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(47)p Black 830 1940 a SDict begin H.S end 830 1940 a Fo(8.1.1)98 b(USAR)-5 b(T)1363 1940 y SDict begin 12 H.L end 1363 1940 a 1363 1940 a SDict begin [/Subtype /Link/Dest (subsection.8.1.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1363 1940 a 44 w Fo(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(48)p Black 830 2062 a SDict begin H.S end 830 2062 a Fo(8.1.2)98 b(Logic)1291 2062 y SDict begin 12 H.L end 1291 2062 a 1291 2062 a SDict begin [/Subtype /Link/Dest (subsection.8.1.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1291 2062 a 54 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(48)p Black 830 2184 a SDict begin H.S end 830 2184 a Fo(8.1.3)98 b(I2C)20 b(EEPR)m(OM)1575 2184 y SDict begin 12 H.L end 1575 2184 a 1575 2184 a SDict begin [/Subtype /Link/Dest (subsection.8.1.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1575 2184 a 81 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(50)p Black 830 2305 a SDict begin H.S end 830 2305 a Fo(8.1.4)98 b(Switches)20 b(&)h(Resistors)1806 2305 y SDict begin 12 H.L end 1806 2305 a 1806 2305 a SDict begin [/Subtype /Link/Dest (subsection.8.1.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1806 2305 a 37 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(51)p Black 830 2427 a SDict begin H.S end 830 2427 a Fo(8.1.5)98 b(V)-11 b(oltage)20 b(Sources,)f(Resistors,)i(and)f(Capacitors)2516 2427 y SDict begin 12 H.L end 2516 2427 a 2516 2427 a SDict begin [/Subtype /Link/Dest (subsection.8.1.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2516 2427 a 74 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(51)p Black 830 2549 a SDict begin H.S end 830 2549 a Fo(8.1.6)98 b(LED_7SEGMENTS)18 b(and)i(LED)2102 2549 y SDict begin 12 H.L end 2102 2549 a 2102 2549 a SDict begin [/Subtype /Link/Dest (subsection.8.1.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2102 2549 a 52 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)g(.)h(.)p Black 124 w(51)p Black 830 2671 a SDict begin H.S end 830 2671 a Fo(8.1.7)98 b(I2C)20 b(sla)n(v)o(e)h(to)f(P)o(arallel)g(port) 1923 2671 y SDict begin 12 H.L end 1923 2671 a 1923 2671 a SDict begin [/Subtype /Link/Dest (subsection.8.1.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1923 2671 a 45 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f (.)g(.)g(.)h(.)p Black 124 w(52)p Black 639 2793 a SDict begin H.S end 639 2793 a Fo(8.2)86 b(Extras)20 b(Modules)1355 2793 y SDict begin 12 H.L end 1355 2793 a 1355 2793 a SDict begin [/Subtype /Link/Dest (section.8.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1355 2793 a 52 w Fo(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)p Black 124 w(53)p Black 830 2915 a SDict begin H.S end 830 2915 a Fo(8.2.1)98 b(T)-6 b(emperature)18 b(and)i(humidity)e(sensor)i (-)h(DHT11)2533 2915 y SDict begin 12 H.L end 2533 2915 a 2533 2915 a SDict begin [/Subtype /Link/Dest (subsection.8.2.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2533 2915 a 57 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(53)p Black 830 3037 a SDict begin H.S end 830 3037 a Fo(8.2.2)98 b(64)20 b(x)g(8,)g(Serial,)g(I2C)g(Real-T)m(ime)g(Clock)g(-)h(DS1307) 2640 3037 y SDict begin 12 H.L end 2640 3037 a 2640 3037 a SDict begin [/Subtype /Link/Dest (subsection.8.2.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2640 3037 a 75 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(54)p Black 830 3159 a SDict begin H.S end 830 3159 a Fo(8.2.3)98 b(High-Precision)18 b(1-W)m(ire)i(Digital)g(Thermometer)e(-)i(DS1820)f(F)o(amily)3172 3159 y SDict begin 12 H.L end 3172 3159 a 3172 3159 a SDict begin [/Subtype /Link/Dest (subsection.8.2.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3172 3159 a Black 124 w Fo(54)p Black 830 3281 a SDict begin H.S end 830 3281 a Fo(8.2.4)98 b(Character)19 b(LCD)i(-)g(HD44780)2005 3281 y SDict begin 12 H.L end 2005 3281 a 2005 3281 a SDict begin [/Subtype /Link/Dest (subsection.8.2.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2005 3281 a 25 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(54)p Black 830 3403 a SDict begin H.S end 830 3403 a Fo(8.2.5)98 b(Graphic)19 b(LCD)i(-)f(SED1530)1944 3403 y SDict begin 12 H.L end 1944 3403 a 1944 3403 a SDict begin [/Subtype /Link/Dest (subsection.8.2.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1944 3403 a 24 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)p Black 124 w(55)p Black 830 3525 a SDict begin H.S end 830 3525 a Fo(8.2.6)98 b(LCD_7Se)o(g)1470 3525 y SDict begin 12 H.L end 1470 3525 a 1470 3525 a SDict begin [/Subtype /Link/Dest (subsection.8.2.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1470 3525 a 62 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(55)p Black 830 3647 a SDict begin H.S end 830 3647 a Fo(8.2.7)98 b(Solar)1272 3647 y SDict begin 12 H.L end 1272 3647 a 1272 3647 a SDict begin [/Subtype /Link/Dest (subsection.8.2.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1272 3647 a 73 w Fo(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(55)p Black 639 3769 a SDict begin H.S end 639 3769 a Fo(8.3)86 b(Writing)20 b(ne)n(w)g(modules)1549 3769 y SDict begin 12 H.L end 1549 3769 a 1549 3769 a SDict begin [/Subtype /Link/Dest (section.8.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1549 3769 a 45 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(56)p Black 515 3974 a SDict begin H.S end 515 3974 a Fp(9)82 b(Symbolic)21 b(Deb)n(ugging)1370 3974 y SDict begin 12 H.L end 1370 3974 a 1370 3974 a SDict begin [/Subtype /Link/Dest (chapter.9) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1370 3974 a 1926 w Fp(58)515 4179 y SDict begin H.S end 515 4179 a Fp(10)40 b(Macr)o(os)906 4179 y SDict begin 12 H.L end 906 4179 a 906 4179 a SDict begin [/Subtype /Link/Dest (chapter.10) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 906 4179 a 2390 w Fp(59)515 4384 y SDict begin H.S end 515 4384 a Fp(11)g(Hex)20 b(Files)969 4384 y SDict begin 12 H.L end 969 4384 a 969 4384 a SDict begin [/Subtype /Link/Dest (chapter.11) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 969 4384 a 2327 w Fp(60)515 4589 y SDict begin H.S end 515 4589 a Fp(12)40 b(The)21 b(ICD-)g(Not)f (Supported)g(in)h(v)o(ersions)g(0.21.0)d(and)j(later)2494 4589 y SDict begin 12 H.L end 2494 4589 a 2494 4589 a SDict begin [/Subtype /Link/Dest (chapter.12) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2494 4589 a 802 w Fp(61)515 4794 y SDict begin H.S end 515 4794 a Fp(13)40 b(Examples)985 4794 y SDict begin 12 H.L end 985 4794 a 985 4794 a SDict begin [/Subtype /Link/Dest (chapter.13) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 985 4794 a 2311 w Fp(63)515 4998 y SDict begin H.S end 515 4998 a Fp(14)g(Regr)o(ession)20 b(T)-8 b(ests)1222 4998 y SDict begin 12 H.L end 1222 4998 a 1222 4998 a SDict begin [/Subtype /Link/Dest (chapter.14) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1222 4998 a 2074 w Fp(64)p Black Black eop end %%Page: 4 5 TeXDict begin 4 4 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.4) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CONTENTS)2388 b Fo(4)p Black 515 515 a SDict begin H.S end 515 515 a Fp(15)40 b(Theory)20 b(of)g(Operation)1374 515 y SDict begin 12 H.L end 1374 515 a 1374 515 a SDict begin [/Subtype /Link/Dest (chapter.15) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1374 515 a 1922 w Fp(65)639 640 y SDict begin H.S end 639 640 a Fo(15.1)44 b(Background)1239 640 y SDict begin 12 H.L end 1239 640 a 1239 640 a SDict begin [/Subtype /Link/Dest (section.15.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1239 640 a 44 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g (.)h(.)p Black 124 w(65)p Black 639 764 a SDict begin H.S end 639 764 a Fo(15.2)i (Instructions)1224 764 y SDict begin 12 H.L end 1224 764 a 1224 764 a SDict begin [/Subtype /Link/Dest (section.15.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1224 764 a 59 w Fo(.)d(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h (.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(65)p Black 639 889 a SDict begin H.S end 639 889 a Fo(15.3)i(General)20 b(File)h(Re)o(gisters)1572 889 y SDict begin 12 H.L end 1572 889 a 1572 889 a SDict begin [/Subtype /Link/Dest (section.15.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1572 889 a 22 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(66)p Black 639 1013 a SDict begin H.S end 639 1013 a Fo(15.4)i(Special)20 b(File)h(Re)o(gisters)1553 1013 y SDict begin 12 H.L end 1553 1013 a 1553 1013 a SDict begin [/Subtype /Link/Dest (section.15.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1553 1013 a 41 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(66)p Black 639 1138 a SDict begin H.S end 639 1138 a Fo(15.5)i(Example)19 b(of)h(an)g(instruction)1692 1138 y SDict begin 12 H.L end 1692 1138 a 1692 1138 a SDict begin [/Subtype /Link/Dest (section.15.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1692 1138 a 27 w Fo(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(67)p Black 639 1262 a SDict begin H.S end 639 1262 a Fo(15.6)i(T)m(race)1017 1262 y SDict begin 12 H.L end 1017 1262 a 1017 1262 a SDict begin [/Subtype /Link/Dest (section.15.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1017 1262 a 79 w Fo(.)d(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(68)p Black 639 1387 a SDict begin H.S end 639 1387 a Fo(15.7)i(Breakpoints)1233 1387 y SDict begin 12 H.L end 1233 1387 a 1233 1387 a SDict begin [/Subtype /Link/Dest (section.15.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1233 1387 a 50 w Fo(.)d(.)g(.)g(.)h(.)f (.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(68)p Black 639 1512 a SDict begin H.S end 639 1512 a Fo(15.8)i(TIMER1)20 b(External)f(input)1625 1512 y SDict begin 12 H.L end 1625 1512 a 1625 1512 a SDict begin [/Subtype /Link/Dest (section.15.8) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1625 1512 a 31 w Fo(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g (.)g(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(69)p Black 515 1719 a SDict begin H.S end 515 1719 a Fp(16)e(LICENSES)1048 1719 y SDict begin 12 H.L end 1048 1719 a 1048 1719 a SDict begin [/Subtype /Link/Dest (chapter.16) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1048 1719 a 2248 w Fp(70)639 1844 y SDict begin H.S end 639 1844 a Fo(16.1)k(Gpsim.lyx)1180 1844 y SDict begin 12 H.L end 1180 1844 a 1180 1844 a SDict begin [/Subtype /Link/Dest (section.16.1) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1180 1844 a 40 w Fo(.)e(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(70)p Black 639 1968 a SDict begin H.S end 639 1968 a Fo(16.2)i(Gpsim)1052 1968 y SDict begin 12 H.L end 1052 1968 a 1052 1968 a SDict begin [/Subtype /Link/Dest (section.16.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1052 1968 a 44 w Fo(.)d(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g (.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) g(.)g(.)h(.)p Black 124 w(70)p Black 639 2093 a SDict begin H.S end 639 2093 a Fo(16.3)i(Libraries)20 b(libgpsim,)f(libgpsim_modules,)e (libgpsim_eXdbm)2735 2093 y SDict begin 12 H.L end 2735 2093 a 2735 2093 a SDict begin [/Subtype /Link/Dest (section.16.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2735 2093 a 42 w Fo(.)41 b(.)h(.)f(.)g(.)g(.)h(.)p Black 124 w(70)p Black Black Black eop end %%Page: 5 6 TeXDict begin 5 5 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.5) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter*.2) cvn /DEST pdfmark end 515 432 a 772 x Fq(Intr)l(oduction)515 1661 y Fo(gpsim)30 b(is)h(a)g (full-featured)d(softw)o(are)i(simulator)g(for)g(Microchip)e(PIC)k (microcontrollers)27 b(dis-)515 1761 y(trib)n(uted)d(under)g(the)h(GNU) h(General)e(Public)h(License)g(and)g(GNU)h(Lesser)f(Public)g (License\(see)515 1860 y(the)20 b(LICENSE)g(section\).)515 1985 y(gpsim)25 b(has)i(been)e(designed)g(to)h(be)g(as)h(accurate)f(as) g(possible.)43 b(Accurac)o(y)24 b(includes)i(the)g(entire)515 2084 y(PIC)19 b(-)g(from)e(the)i(core)f(to)h(the)f(I/O)h(pins)f(and)g (including)f(ALL)i(of)f(the)g(internal)g(peripherals.)23 b(Thus)515 2184 y(it')-5 b(s)19 b(possible)f(to)g(create)g(stimuli)h (and)e(tie)i(them)f(to)g(the)g(I/O)h(pins)f(and)g(test)h(the)f(PIC)h (the)f(same)h(w)o(ay)515 2284 y(you)g(w)o(ould)h(in)g(the)g(real)g(w)o (orld.)515 2408 y(gpsim)30 b(has)h(been)f(designed)g(to)g(be)h(as)h(f)o (ast)f(as)g(possible.)57 b(Real)31 b(time)g(simulation)f(speeds)h(of) 515 2508 y(20Mhz)19 b(pics)h(are)g(possible.)515 2632 y(gpsim)h(can)h(be)g(controlled)f(from)g(either)g(a)i(graphical)d(user) i(interf)o(ace)g(\(GUI\),)f(a)h(command)e(line)515 2732 y(interf)o(ace)25 b(\(CLI\))g(or)h(by)f(a)h(remote)f(process.)41 b(T)-7 b(ypical)26 b(deb)n(ugging)d(features)i(lik)o(e)h(breakpoints,) 515 2832 y(single)18 b(stepping,)g(disassembling,)g(memory)e(inspect)j (&)g(change,)e(and)h(so)h(on)f(are)h(all)g(supported.)515 2931 y(In)j(addition,)g(comple)o(x)g(deb)n(ugging)e(features)i(lik)o(e) h(real)g(time)h(tracing,)e(assertions,)h(conditional)515 3031 y(breaks,)c(and)h(plugin)f(modules)g(to)h(name)g(a)g(fe)n(w)g(are) g(also)h(supported.)p Black 1926 5208 a(5)p Black eop end %%Page: 6 7 TeXDict begin 6 6 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.6) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.1) cvn /DEST pdfmark end 515 432 a 727 x Fl(Chapter)44 b(1)515 1594 y Fq(gpsim)52 b(-)g(An)f(Ov)n(er)n (view)515 2046 y Fo(If)16 b(you)g(don')o(t)f(care)i(to)g(w)o(ade)f (through)f(details,)i(this)g(chapter)f(should)g(help)g(you)g(get)h (things)f(up)g(and)515 2146 y(running.)25 b(The)c(INST)-8 b(ALL)21 b(and)g(README)g(\002les)h(will)g(pro)o(vide)d(more)h (up-to-date)f(information)515 2246 y(than)g(this)i(document,)d(so)j (please)f(refer)f(to)i(those)f(\002rst.)515 2390 y SDict begin H.S end 515 2390 a 515 2390 a SDict begin 12 H.A end 515 2390 a 515 2390 a SDict begin [/View [/XYZ H.V]/Dest (section.1.1) cvn /DEST pdfmark end 515 2390 a 152 x Fk(1.1)119 b(Making)30 b(the)g(executable)515 2749 y Fo(gpsim')-5 b(s)18 b(e)o(x)o(ecutable)e(is)j(created)e(in)i(a)f (manner)f(that')-5 b(s)18 b(consistent)g(with)g(much)f(of)h(the)g (other)g(open)515 2848 y(source)h(softw)o(are:)p 515 2881 2485 4 v 513 2981 4 100 v 565 2951 a(command)p 1507 2981 V 663 w(description)p 2998 2981 V 515 2984 2485 4 v 515 3001 V 513 3100 4 100 v 565 3070 a(tar)h(-xvzf)f(gpsim-x.y)-5 b(.z.tar)g(.gz)p 1507 3100 V 95 w(e)o(xpand)18 b(the)i(compressed)f (tar)i(\002le)p 2998 3100 V 515 3104 2485 4 v 513 3203 4 100 v 565 3173 a(./con\002gure)p 1507 3203 V 633 w(Create)f(a)h('mak) o(e\002le')e(unique)g(to)h(your)f(system)p 2998 3203 V 515 3207 2485 4 v 513 3306 4 100 v 565 3276 a(mak)o(e)p 1507 3306 V 813 w(compile)g(gpsim)p 2998 3306 V 515 3310 2485 4 v 513 3409 4 100 v 565 3379 a(mak)o(e)g(install)p 1507 3409 V 591 w(install)i(gpsim)p 2998 3409 V 515 3413 2485 4 v 515 3498 a(The)f(last)h(step)f(will)h(require)e(root)g(pri)n (vile)o(ges.)515 3633 y SDict begin H.S end 515 3633 a 515 3633 a SDict begin 12 H.A end 515 3633 a 515 3633 a SDict begin [/View [/XYZ H.V]/Dest (subsection.1.1.1) cvn /DEST pdfmark end 515 3633 a 119 x Fj(1.1.1)99 b(Mak)o(e)25 b(Details)f(-)h(./con\002gur)n(e)i(options)515 3928 y SDict begin H.S end 515 3928 a 515 3928 a SDict begin 12 H.A end 515 3928 a 515 3928 a SDict begin [/View [/XYZ H.V]/Dest (section*.3) cvn /DEST pdfmark end 515 3928 a Fp(gui-less)515 4104 y Fo(The)d(def)o(ault)g(con\002guration)e(will)j (pro)o(vide)d(a)j(gui)g(\(graphical)d(user)j(interf)o(ace\).)36 b(The)25 b(cli)g(\(com-)515 4204 y(mand)f(line)h(interf)o(ace\))e(is)j (still)g(a)n(v)n(ailable,)g(ho)n(we)n(v)o(er)d(man)o(y)g(people)h (prefer)g(just)h(to)g(use)g(the)g(cli.)515 4304 y(These)20 b(hardy)f(souls)h(may)g(b)n(uild)f(a)i(command-line)c(only)j(interf)o (ace)f(by)h(con\002guring)e(gpsim:)p Black Black 722 4485 a Fi(./configure)39 b(--disable-gui)515 4723 y SDict begin H.S end 515 4723 a 515 4723 a SDict begin 12 H.A end 515 4723 a 515 4723 a SDict begin [/View [/XYZ H.V]/Dest (section*.4) cvn /DEST pdfmark end 515 4723 a Fp(deb)n(ugging)515 4899 y Fo(If)25 b(you)g(w)o(ant)h(to)g(deb)n(ug)e(gpsim)h(then)h(you)e (will)j(probably)c(use)j(gdb)m(.)40 b(Consequently)-5 b(,)25 b(you)g(will)515 4998 y(w)o(ant)20 b(to)g(disable)g(shared)g (libraries:)p Black 1926 5208 a(6)p Black eop end %%Page: 7 8 TeXDict begin 7 7 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.7) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(1.)45 b(GPSIM)21 b(-)f(AN)h(O)l(VER)-7 b(VIEW)1419 b Fo(7)p Black Black Black 722 515 a Fi(./configure)39 b(--disable-shared)515 684 y Fo(This)20 b(will)h(create)f(one,)f(huge)h (monolithic)e(e)o(x)o(ecutable)g(with)j(symbolic)e(information.)515 817 y SDict begin H.S end 515 817 a 515 817 a SDict begin 12 H.A end 515 817 a 515 817 a SDict begin [/View [/XYZ H.V]/Dest (subsection.1.1.2) cvn /DEST pdfmark end 515 817 a 117 x Fj(1.1.2)99 b(RPMs)515 1108 y Fo(gpsim)19 b(is)j(also)e(a)n(v)n (ailable)g(in)g(RPM)h(form)e(from)h(linux)f(distrib)n(utions)g(such)h (as)h(Fedora.)515 1241 y SDict begin H.S end 515 1241 a 515 1241 a SDict begin 12 H.A end 515 1241 a 515 1241 a SDict begin [/View [/XYZ H.V]/Dest (subsection.1.1.3) cvn /DEST pdfmark end 515 1241 a 117 x Fj(1.1.3)99 b(W)n(indo)o(ws)515 1532 y Fo(Gpsim)25 b(runs)f(on)g(W)m(indo)n(ws)h(too.)38 b(Both)25 b(release)g(and)f(snapshot)g(gpsim)h(apps)f(can)h(be)g (installed)515 1631 y(and)19 b(run)h(on)g(windo)n(ws)f(machines.)515 1749 y(The)29 b(release)g(v)o(ersion)f(of)h(the)g(gpsim)g(apps)g(are)g (generated)e(on)i(each)g(ne)n(w)g(release)g(of)g(gpsim.)515 1849 y(These)20 b(can)g(be)g(do)n(wnloaded)d(from)j(the)g(follo)n(wing) e(web)i(site:)p Black Black 722 2007 a(https://sourcefor)o (ge.net/projects/gpsim/\002les/gp)o(sim-win)o(32)o(/)515 2165 y(The)27 b(snapshot)g(v)o(ersions)f(are)i(generated)e(from)g(time) i(to)g(time)g(from)e(the)i(then)f(current)f(source)515 2265 y(code)f(and)g(will)h(contain)e(b)n(ug)h(\002x)o(es)h(and)f(ne)n (w)h(features)e(added)h(since)h(the)f(last)i(release.)41 b(These)515 2365 y(v)o(ersions)23 b(should)h(w)o(ork,)h(b)n(ut)f(are)g (not)h(gi)n(v)o(en)e(the)h(e)o(xtra)g(testing)h(of)f(a)h(ne)n(w)f (release.)38 b(Snapshots)515 2464 y(can)20 b(be)g(do)n(wnloaded)d (from:)p Black Black 722 2623 a(https://sourcefor)o (ge.net/projects/gpsim/\002les/snap)o(shot_)o(b)n(uild)o(s/gpsim-)o (win3)o(2/)515 2781 y(If)27 b(you)f(wish)h(to)g(b)n(uild)g(your)f(o)n (wn)g(windo)n(ws)g(v)o(ersion)g(of)h(gpsim,)h(the)f(late)g(Borut)g (Razem)g(has)515 2880 y(documented)17 b(the)k(process)e(which)h(can)g (be)g(found)e(at)j(this)g(location:)p Black Black 722 3039 a(http://gpsim.sourcefor)o(ge.net/gp)o(simW)m(in3)o(2/g)o(psimW)m (in)o(32)o(.htm)o(l)515 3181 y SDict begin H.S end 515 3181 a 515 3181 a SDict begin 12 H.A end 515 3181 a 515 3181 a SDict begin [/View [/XYZ H.V]/Dest (section.1.2) cvn /DEST pdfmark end 515 3181 a 150 x Fk(1.2)119 b(Running)515 3535 y Fo(The)24 b(e)o(x)o(ecutable)f(created)h(abo)o(v)o(e)f(is)i (called:)34 b(gpsim.)k(The)24 b(follo)n(wing)f(command)g(line)h (options)515 3635 y(may)19 b(be)i(speci\002ed)e(when)h(gpsim)g(is)h(in) m(v)n(ok)o(ed.)p Black Black 722 3903 a Fi(gpsim)42 b([-?])g([-p)g ()e([]])e([[-c])k(])d([[-s])i(])809 4002 y(-p,)i(--processor=)216 b(processor)40 b(\(e.g.)h(-pp16c84)f(for)i(the)h('c84\))809 4102 y(-c,)g(--command=STRIN)o(G)735 b(startup)40 b(command)h(file)h (\(optional)e(.stc)h(files\))809 4201 y(-s)1525 b(.cod)42 b(symbol)f(file)h(\(optional)d(.cod)j(files\))809 4301 y(-L,)h(--)1350 b(colon)41 b(separated)f(list)i(of)h(directories)38 b(to)2422 4401 y(search.)809 4500 y(-v,)43 b(--version)1042 b(gpsim)41 b(version)809 4600 y(-i,)i(--cli)1218 b(command)40 b(line)i(mode)g(only)809 4700 y(-d,)h(--icd=STRING)910 b(use)42 b(ICD)g(\(e.g.)g(-d)h(/dev/ttyS0\).)809 4799 y(Help)f(options:)809 4899 y(-?,)h(--help)1174 b(Show)42 b(this)g(help)f(message)809 4998 y(--usage)1305 b(Display)40 b(brief)i(usage)f(message)p Black Black eop end %%Page: 8 9 TeXDict begin 8 8 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.8) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(1.)45 b(GPSIM)21 b(-)f(AN)h(O)l(VER)-7 b(VIEW)1419 b Fo(8)p Black 515 515 a(T)-7 b(ypically)19 b(gpsim)h(will)h(be)f(in)m(v)n(ok)o(ed)e(lik)o(e:)p Black Black 722 723 a Fi([My-Computer]$)38 b(gpsim)85 b(mypic-program.co)o(d) 515 930 y Fo(\(The)17 b Fh([My-Computer]$)h Fo(te)o(xt)h(is)g(an)f(e)o (xample)f(of)h(a)h(typical)f(bash)g(command)f(prompt)g(-)h(you)g(will) 515 1030 y(only)h(type)h(the)g(te)o(xt)g(after)g(this)h(prompt\).)i (This)d(loads)g(the)g(.cod)g(\002le)g(generated)f(by)h(gputils.)515 1155 y(Under)j(W)m(indo)n(ws,)h(gpsim)g(can)g(also)h(be)f(in)m(v)n(ok)o (ed)f(by)h(na)n(vigating)e(through)g(the)i(Start/Program)515 1254 y(menu.)g(This)c(will)h(open)e(a)i(DOS)f(windo)n(w)g(to)g(pro)o (vide)e(access)j(to)f(the)g(command)e(line)j(interf)o(ace.)515 1354 y(It')-5 b(s)23 b(also)f(possible)g(to)h(open)e(a)i(DOS)g(windo)n (w)e(\(or)h(CygW)m(in)g(bash)g(session\))g(and)g(in)m(v)n(ok)o(e)f (gpsim)515 1453 y(from)e(there.)515 1585 y SDict begin H.S end 515 1585 a 515 1585 a SDict begin 12 H.A end 515 1585 a 515 1585 a SDict begin [/View [/XYZ H.V]/Dest (section.1.3) cvn /DEST pdfmark end 515 1585 a 174 x Fk(1.3)119 b(Requir)n(ements)515 1969 y Fo(gpsim)29 b(has)g(been)g(de)n(v)o (eloped)d(under)i(Linux.)51 b(It)30 b(should)e(b)n(uild)h(and)g(run)f (just)i(\002ne)g(under)e(the)515 2069 y(popular)17 b(Linux)g(distrib)n (utions)h(lik)o(e)h(Fedora,)e(Ub)n(untu,)h(etc.)25 b(gpsim)18 b(has)h(also)g(been)f(ported)f(to)i(the)515 2168 y(MA)m(C,)i(MicroSoft) g(W)m(indo)n(ws,)f(Solaris,)i(and)f(BSD.)h(T)-7 b(w)o(o)22 b(packages)e(gpsim)h(requires)g(that)g(may)515 2268 y(not)26 b(be)h(a)n(v)n(ailable)f(with)h(all)g(Linux)f(distrib)n(utions)f(are)i (readline)f(and)g(gtk)g(\(the)h(gimp)e(tool)i(kit\).)515 2368 y(The)17 b(./con\002gure)g(script)h(should)f(tell)h(you)g(if)g (these)g(packages)f(are)h(not)g(installed)g(on)g(your)e(system)515 2467 y(or)k(if)g(the)g(re)n(visions)g(that)g(are)g(installed)g(are)g (too)g(old.)515 2592 y(There)f(are)h(no)g(minimum)f(hardw)o(are)f (requirements)h(to)h(run)f(gpsim.)25 b(F)o(aster)20 b(is)h(better)f (though!)515 2716 y(gputils,)32 b(the)e(gnupic)e(utilities)j(package,)f (is)h(also)g(v)o(ery)d(useful.)54 b(gpsim)30 b(will)g(accept)g (straight)515 2816 y(he)o(x)21 b(\002les,)j(b)n(ut)f(if)g(you)e(w)o (ant)i(to)f(do)h(an)o(y)e(symbolic)h(deb)n(ugging)e(then)i(you)f(will)j (w)o(ant)e(to)h(use)g(the)515 2915 y(.cod)657 2915 y SDict begin H.S end 657 2915 a -30 x Fm(1)690 2915 y SDict begin 12 H.L end 690 2915 a 690 2915 a SDict begin [/Subtype /Link/Dest (Hfootnote.2) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 690 2915 a 22 w Fo(\002les)g(that)f(gputils)f(produces.)27 b(The)21 b(.cod)g(\002les)i(are)e(in)h(the)g(same)f(format)g(as)h(the)g (.cod)f(\002les)515 3015 y(MP)-8 b(ASM)807 3015 y SDict begin H.S end 807 3015 a -30 x Fm(2)842 3015 y SDict begin 12 H.L end 842 3015 a 842 3015 a SDict begin [/Subtype /Link/Dest (Hfootnote.3) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 842 3015 a 21 w Fo(produces.)p Black 515 4837 1146 4 v 605 4893 a Fg(1)634 4917 y SDict begin H.S end 634 4917 a 634 4917 a SDict begin H.R end 634 4917 a 634 4917 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.2) cvn /DEST pdfmark end 634 4917 a Ff(.cod)17 b(\002les)h(are)f(symbol)h(\002les)f (that)h(were)g(created)h(by)e(ByteCraft)j(and)d(are)h(used)f(by)g (Microchip.)605 4974 y Fg(2)634 4998 y SDict begin H.S end 634 4998 a 634 4998 a SDict begin H.R end 634 4998 a 634 4998 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.3) cvn /DEST pdfmark end 634 4998 a Ff(MP)-6 b(ASM)17 b(is)g(Microchip')l(s)i(Assembler)l(.)p Black Black Black eop end %%Page: 9 10 TeXDict begin 9 9 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.9) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.2) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(2)515 1603 y Fq(Command)52 b(Line)f(Interface) 515 2060 y Fo(The)17 b(command)f(line)i(interf)o(ace)g(is)g(f)o(airly)g (straight-forw)o(ard.)j(The)d(table)g(belo)n(w)f(summarizes)h(the)515 2159 y(a)n(v)n(ailable)24 b(commands.)35 b(Brief)25 b(descriptions)e (of)h(these)h(commands)e(can)h(also)g(be)h(displayed)e(by)515 2259 y(typing)c Fh(help)g Fo(at)i(the)f(command)f(line.)p Black 1926 5208 a(9)p Black eop end %%Page: 10 11 TeXDict begin 10 10 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.10) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(10)p Black Black Black 784 436 2327 4 v 782 535 4 100 v 870 505 a(command)p 1283 535 V 843 w(summary)p 3108 535 V 784 539 2327 4 v 784 555 V 782 655 4 100 v 935 625 a(attach)p 1283 655 V 677 w(Attach)20 b(stimuli)h(to)f(nodes)p 3108 655 V 784 658 2327 4 v 782 758 4 100 v 942 728 a(break)p 1283 758 V 789 w(Set)h(a)g(break)e (point)p 3108 758 V 784 761 2327 4 v 782 861 4 100 v 977 831 a(b)n(us)p 1283 861 V 651 w(Add)g(or)h(display)g(node)f(b)n (usses)p 3108 861 V 784 864 2327 4 v 782 964 4 100 v 953 934 a(clear)p 1283 964 V 718 w(Remo)o(v)o(e)g(a)i(break)e(point)p 3108 964 V 784 967 2327 4 v 782 1067 4 100 v 834 1037 a(disassemble)p 1283 1067 V 492 w(Disassemble)i(the)f(current)f(cpu)p 3108 1067 V 784 1070 2327 4 v 782 1170 4 100 v 940 1140 a(dump)p 1283 1170 V 444 w(Display)h(either)g(the)g(RAM)h(or)f(EEPR)m (OM)p 3108 1170 V 784 1173 2327 4 v 782 1272 4 100 v 869 1243 a(frequenc)o(y)p 1283 1272 V 596 w(Set)h(processor)e(frequenc) o(y)p 3108 1272 V 784 1276 2327 4 v 782 1375 4 100 v 963 1346 a(help)p 1283 1375 V 227 w(T)-7 b(ype)20 b(help)g("command")e (for)h(more)h(help)f(on)h(a)h(command)p 3108 1375 V 784 1379 2327 4 v 782 1478 4 100 v 983 1448 a(icd)p 1283 1478 V 634 w(In)e(Circuit)i(Deb)n(ugger)d(support.)p 3108 1478 V 784 1482 2327 4 v 782 1581 4 100 v 983 1551 a(list)p 1283 1581 V 654 w(Display)i(source)g(and)g(list)h(\002les)p 3108 1581 V 784 1585 2327 4 v 782 1684 4 100 v 963 1654 a(load)p 1283 1684 V 519 w(Load)e(either)h(a)h(he)o(x)e(or)h(command)e (\002le)p 3108 1684 V 784 1688 2327 4 v 782 1787 4 100 v 981 1757 a(log)p 1283 1787 V 675 w(Log/record)g(e)n(v)o(ents)h(to)i (a)f(\002le)p 3108 1787 V 784 1791 2327 4 v 782 1890 4 100 v 953 1860 a(node)p 1283 1890 V 576 w(Add)g(or)g(display)f (stimulus)i(nodes)p 3108 1890 V 784 1893 2327 4 v 782 1993 4 100 v 910 1963 a(module)p 1283 1993 V 602 w(Select)f(&)h (Display)f(modules)p 3108 1993 V 784 1996 2327 4 v 782 2096 4 100 v 875 2066 a(processor)p 1283 2096 V 683 w(Add/list)g (processors)p 3108 2096 V 784 2099 2327 4 v 782 2199 4 100 v 970 2169 a(quit)p 1283 2199 V 912 w(Quit)g(gpsim)p 3108 2199 V 784 2202 2327 4 v 782 2302 4 100 v 956 2272 a(reset)p 1283 2302 V 512 w(Reset)i(all)e(or)g(parts)g(of)g(the)h (simulation)p 3108 2302 V 784 2305 2327 4 v 782 2405 4 100 v 979 2375 a(run)p 1283 2405 V 700 w(Ex)o(ecute)e(the)h(pic)g (program)p 3108 2405 V 784 2408 2327 4 v 782 2508 4 100 v 988 2478 a(set)p 1283 2508 V 444 w(display)f(and)h(control)f(gpsim)h (beha)n(vior)e(\003ags)p 3108 2508 V 784 2511 2327 4 v 782 2611 4 100 v 967 2581 a(step)p 1283 2611 V 548 w(Ex)o(ecute)h(one)h(or)g(more)f(instructions)p 3108 2611 V 784 2614 2327 4 v 782 2714 4 100 v 893 2684 a(stimulus)p 1283 2714 V 734 w(Create)h(a)h(stimulus)p 3108 2714 V 784 2717 2327 4 v 782 2817 4 100 v 866 2787 a(stopw)o(atch)p 1283 2817 V 504 w(Measure)e(time)i(between)e(e)n(v)o(ents)p 3108 2817 V 784 2820 2327 4 v 782 2920 4 100 v 912 2890 a(symbol)p 1283 2920 V 757 w(Add/list)h(symbols)p 3108 2920 V 784 2923 2327 4 v 782 3023 4 100 v 953 2993 a(trace)p 1283 3023 V 701 w(Dump)f(the)h(trace)g(history)p 3108 3023 V 784 3026 2327 4 v 782 3126 4 100 v 913 3096 a(v)o(ersion)p 1283 3126 V 639 w(Display)g(gpsim')-5 b(s)20 b(v)o(ersion)p 3108 3126 V 784 3129 2327 4 v 782 3228 4 100 v 1013 3199 a(x)p 1283 3228 V 389 w(\(deprecated\))e(e)o(xamine)g(and/or)h(modify)g (memory)p 3108 3228 V 784 3232 2327 4 v 515 3460 a(The)h(b)n(uilt)g(in) g('help')f(command)f(pro)o(vides)h(additional)g(online)g(information.) 515 3607 y SDict begin H.S end 515 3607 a 515 3607 a SDict begin 12 H.A end 515 3607 a 515 3607 a SDict begin [/View [/XYZ H.V]/Dest (section.2.1) cvn /DEST pdfmark end 515 3607 a 153 x Fk(2.1)119 b(attach)p Black Black 722 3946 a Fi(attach)41 b(node1)h(stimulus1)e([stimulus2)f(stimulus_N]) 515 4139 y Fo(Attach)25 b(is)h(used)f(to)g(de\002ne)g(connections)f (between)g(one)h(or)g(more)f(stimulus)h(and)g(a)h(node.)39 b(One)515 4238 y(node)25 b(and)h(at)h(least)g(one)f(stimulus)g(must)h (be)f(speci\002ed,)i(b)n(ut)e(in)h(general)e(tw)o(o)i(or)f(more)f (stimuli)515 4338 y(are)d(used.)30 b(Attach)22 b(can)f(be)h(vie)n(wed)g (as)g(wiring)g(stimuli)g(together)m(,)e(with)i(the)g(node)f(acting)h (as)h(the)515 4437 y(wire.)i(A)20 b(stimulus)h(is)g(either)f(a)g(CPU)h (or)f(module)f(I/O)i(pin)e(or)h(a)h(stimulus)f(name.)515 4559 y(Attach_pointN)e(can)i(ha)n(v)o(e)g(one)f(of)h(the)g(follo)n (wing)f(formats)p Black 515 4738 a(pin\(\))p Black 37 w(or)h(pin\(\))930 4868 y(This)g(refers)g(to)g(a)h (pin)f(of)g(the)g(current)f(acti)n(v)o(e)g(CPU.)930 4998 y()f(is)j(the)f(pin)g(number)p Black Black eop end %%Page: 11 12 TeXDict begin 11 11 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.11) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(11)p Black 930 515 a()19 b(is)i(an)f(inte)o (ger)f(symbol)g(whose)h(v)n(alue)g(is)h(a)f(pin)g(number)p Black 515 680 a()p Black 38 w(or)g(pin\(\))930 811 y(These)g(tw)o(o)h(forms)f(are)h(treated)f(e)o(xactly)f(the)i(same) g(\()g(i.e.)26 b(the)21 b(pin\(\))e(has)i(no)g(mean-)930 911 y(ing\).)930 1043 y()d(is)j(a)f(stimulus)g(name)g(or)g (an)g(I/O)h(pin)e(name.)930 1175 y(I/O)c(pin)g(name)g(can)g(be)g(just)h (the)f(pin)g(name)f(for)h(the)g(CPU)h(or)f(.pin_name)930 1275 y(for)k(a)i(module)e(or)h(CPU)515 1461 y(Example)p Black Black 722 1663 a Fi(**gpsim>)40 b(load)i(instructions_14bi)o(t.)o (co)o(d)212 b(#)43 b(load)f(code)722 1763 y(**gpsim>)e(module)i (library)e(libgpsim_modules)d(#load)k(module)g(lib)722 1863 y(**gpsim>)f(module)i(load)f(usart)h(U1)522 b(#)43 b(create)e(USART)722 1962 y(**gpsim>)f(node)i(n1)1089 b(#)43 b(define)e(a)i(node)722 2062 y(**gpsim>)d(node)i(n2)1089 b(#define)41 b(another)f(node)722 2161 y(**gpsim>)g(symbol)i(TWO=2)869 b(#define)41 b(symbol)g(with)g(value)h(2)722 2261 y(**gpsim>)e(attach)i (n1)g(pin\(1\))f(pin\(TWO\))302 b(#attach)41 b(CPU)h(pins)g(1)h(and)f (2)722 2361 y(**gpsim>)e(attach)i(n1)g(U1.RXPIN)607 b(#add)42 b(usart)f(pin)i(to)f(n1)722 2460 y(**gpsim>)e(attach)i(n2)g(portb0)f (pin\(U1.TXPIN\))82 b(#connect)40 b(portb0)h(to)i(UASRT)e(TX)i(pin)722 2560 y(**gpsim>)d(node)1219 b(#)43 b(show)f(results)515 2708 y SDict begin H.S end 515 2708 a 515 2708 a SDict begin 12 H.A end 515 2708 a 515 2708 a SDict begin [/View [/XYZ H.V]/Dest (section.2.2) cvn /DEST pdfmark end 515 2708 a 155 x Fk(2.2)119 b(br)n(eak)515 3073 y Fo(The)27 b(break)f(command)f(is)j(used)f(to)g(set)h(and)f(e)o(xamine)f(break)g (points.)45 b(Ne)n(w)28 b(break)e(points)h(are)515 3173 y(assigned)21 b(a)g(unique)f(number)-5 b(.)28 b(This)21 b(number)f(can)h(be)h(used)f(to)g(query)f(or)h(clear)h(the)f(break)g (point.)515 3272 y(Break)16 b(points)h(halt)g(the)f(simulation)g(when)h (the)f(condition)g(associated)g(with)h(them)g(is)g(true.)24 b(Break)515 3372 y(points)f(are)g(ignored)f(during)f(single)i (stepping.)34 b(See)24 b(chapter)2357 3373 y SDict begin H.S end 2357 3373 a Black -1 x Fo(5)p Black 2398 3315 a SDict begin H.R end 2398 3315 a 2398 3372 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (chapter.5) cvn H.B /ANN pdfmark end 2398 3372 a 24 w Fo(for)f(more)g(e)o(xamples)f(of)h(break-)515 3471 y(points.)515 3716 y SDict begin H.S end 515 3716 a 515 3716 a SDict begin 12 H.A end 515 3716 a 515 3716 a SDict begin [/View [/XYZ H.V]/Dest (section*.5) cvn /DEST pdfmark end 515 3716 a Fp(Examining)d(br)o(eak)g(points)p Black Black 722 3871 a Fi(break)42 b([bp_number])515 4073 y Fo(Break)18 b(points)f(can)h(be)g(e)o(xamined)f(by)g(typing)g (the)h(break)g(command)e(without)h(an)o(y)h(options.)23 b(Spe-)515 4173 y(ci\002c)d(breaks)g(can)g(be)g(queried)f(by)h (specifying)e(the)i(break)f(point)h(number)-5 b(.)515 4417 y SDict begin H.S end 515 4417 a 515 4417 a SDict begin 12 H.A end 515 4417 a 515 4417 a SDict begin [/View [/XYZ H.V]/Dest (section*.6) cvn /DEST pdfmark end 515 4417 a Fp(Pr)o(ogram)18 b(Memory/Execution)h(br)o(eaks)515 4597 y Fo(The)25 b(most)g(common)f(break)g(point)h(is)h(an)g(e)o(x)o (ecution)d(break)h(point.)40 b(This)26 b(one)f(halts)h(e)o(x)o(ecution) 515 4697 y(whene)n(v)o(er)18 b(the)i(program)e(counter)h(reaches)h(the) g(address)g(at)h(which)f(the)g(break)f(point)h(is)h(set.)26 b(The)515 4796 y(syntax)19 b(is:)p Black Black 722 4998 a Fi(break)42 b(e|r|w)f(ADDRESS)g([,expr)g([,message]])p Black Black eop end %%Page: 12 13 TeXDict begin 12 12 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.12) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(12)p Black 515 515 a(The)15 b(simulation)f(halts)i (when)f(the)g(address)g(is)i(e)o(x)o(ecuted,)d(read,)h(or)g(written.)24 b(The)15 b(ADDRESS)h(can)515 615 y(be)22 b(a)h(symbol)e(or)h(a)g (number)-5 b(.)30 b(If)22 b(the)h(optional)d(e)o(xpression)h(is)i (speci\002ed,)g(then)e(it)i(must)g(e)n(v)n(aluate)515 715 y(to)c(true)h(before)e(the)h(simulation)g(will)h(halt.)25 b(The)19 b(optional)f(message)h(allo)n(ws)h(a)g(description)e(to)i(be) 515 814 y(associated)k(with)h(the)f(break.)37 b(The)24 b(read)g(and)g(write)h(options)e(only)h(apply)g(to)g(those)h (processors)515 914 y(that)20 b(can)g(manipulate)f(their)h(o)n(wn)f (program)f(memory)-5 b(.)515 1157 y SDict begin H.S end 515 1157 a 515 1157 a SDict begin 12 H.A end 515 1157 a 515 1157 a SDict begin [/View [/XYZ H.V]/Dest (section*.7) cvn /DEST pdfmark end 515 1157 a Fp(Register)20 b(Memory)g(br)o(eaks) 515 1337 y Fo(gpsim)27 b(can)g(also)g(associate)h(break)e(points)h (with)h(re)o(gister)f(accesses.)47 b(This)27 b(is)i(useful)d(for)h (cap-)515 1436 y(turing)k(b)n(ugs)h(that)g(stomp)g(on)g(RAM.)g(E.g.)61 b(you)31 b(can)h(say)g(something)f(lik)o(e)i(\223halt)f(e)o(x)o (ecution)515 1536 y(whene)n(v)o(er)18 b(bit)i(4)h(of)e(re)o(gister)h (42)g(is)h(cleared\224.)j(The)c(command)e(line)i(syntax)g(is:)p Black Black 722 1735 a Fi(break)42 b(r|w|ch)f(REGISTER)f([,expr)h ([,message]])515 1935 y Fo(The)26 b(simulation)f(halts)i(when)e Fh(REGISTER)g Fo(is)j(read,)f(written,)g(or)f(changed)e(on)i(write,)i (and)e(the)515 2035 y(optional)19 b(e)o(xpression)f(e)n(v)n(aluates)i (to)g(true.)515 2158 y(Other)g(syntax)o(es)f(with)h(a)h(boolean)e(e)o (xpression)f(are:)p Black Black 722 2358 a Fi(break)42 b(r|w|ch)f(REGISTER)f(==)j(value)515 2557 y Fo(The)20 b(simulation)f(halts)i(when)e Fh(REGISTER)g Fo(is)i(assigned)f(the)g (speci\002ed)g(v)n(alue,)f(and:)p Black Black 722 2757 a Fi(break)42 b(r|w|ch)f(REGISTER)f(&)j(mask)f(==)h(value)515 2957 y Fo(The)34 b(simulation)g(halts)h(when)f(speci\002ed)g(bits)i(in) e(REGISTER)h(are)g(assigned)f(the)h(speci\002ed)515 3056 y(v)n(alue.)515 3180 y(Here')-5 b(s)26 b(an)g(e)o(xample)f(of)h(a)g(re) o(gister)g(write)g(break.)42 b(This)26 b(one)f(will)i(halt)g(the)f (simulation)f(if)h(an)o(y)515 3279 y(v)n(alue)19 b(is)i(written)f(to)h (the)f(v)n(ariable)f(named)g Fh(temp1)p Fo(.)p Black Black 722 3479 a Fi(break)42 b(w)h(temp1)515 3678 y Fo(Sometimes)30 b(it')-5 b(s)32 b(necessary)f(to)g(specify)f(an)h(auxiliary)f (condition)f(with)i(a)g(break)f(point.)57 b(F)o(or)515 3778 y(e)o(xample,)25 b(there)g(may)h(be)f(a)h(temporary)e(v)n(ariable) h(that)g(is)i(shared)e(throughout)e(the)i(code.)41 b(Y)-9 b(ou)515 3878 y(may)29 b(wish)i(to)f(trap)g(writes)h(to)f(that)g(v)n (ariable)f(only)h(while)g(e)o(x)o(ecuting)e(a)i(speci\002c)h (subroutine.)515 3977 y(F)o(or)24 b(e)o(xample,)h(the)g(follo)n(wing)f (break)g(point)g(triggers)g(when)h(temp1)f(is)i(written)f(and)f(while)i (the)515 4077 y(program)18 b(counter)h(is)i(in)f(between)f(the)i (labels)f Fh(func_start)h Fo(and)f Fh(func_end)r Fo(:)p Black Black 722 4277 a Fi(break)42 b(w)h(temp1,)e(\(pc)h(>=)h (func_start)c(&&)k(pc)g(<)g(func_end\))515 4476 y Fh(TIP:)24 b Fo(Use)h(this)g(type)f(of)g(break)f(point)h(if)h(you)e(suspect)i(an)f (interrupt)f(routine)g(is)i(o)o(v)o(er)e(writing)h(a)515 4576 y(v)n(ariable.)515 4699 y(Another)19 b(situation)h(is)i(one)e (where)g(you)g(wish)h(to)f(trap)h(writes)g(to)g(a)g(v)n(ariable)e(only) h(if)h(some)f(other)515 4799 y(v)n(ariable)f(is)i(a)g(certain)e(v)n (alue:)p Black Black 722 4998 a Fi(break)42 b(w)h(temp1,)e(\(CurTask)f (&)j(0x0f)f(!=)h(0b101\))p Black Black eop end %%Page: 13 14 TeXDict begin 13 13 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.13) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(13)p Black 515 515 a(If)24 b(the)h(\002rmw)o(are)f (writes)h(to)g(the)g(v)n(ariable)e(temp1)h(then)h(the)f(simulation)g (will)i(halt)e(if)h(the)g(lo)n(wer)515 615 y(nibble)19 b(of)h(CurT)-7 b(ask)20 b(is)h(not)f(equal)g(to)g(5.)515 739 y(This)g(e)o(xample)f(breaks)g(only)h(if)g(the)g(he)o(x)g(digit)g ('C')g(is)h(written)f(to)h(the)f(upper)f(nibble)g(of)h(temp1:)p Black Black 722 947 a Fi(break)42 b(w)h(\(temp1)e(&)i(0b11110000\))c (==)k(0b11000000)515 1193 y SDict begin H.S end 515 1193 a 515 1193 a SDict begin 12 H.A end 515 1193 a 515 1193 a SDict begin [/View [/XYZ H.V]/Dest (section*.8) cvn /DEST pdfmark end 515 1193 a Fp(Pr)o(ocessor)19 b(exception)g(br)o (eakpoints)515 1374 y Fo(Stack)h(o)o(v)o(er\003o)n(w)-5 b(,)18 b(under\003o)n(w)g(and)i(w)o(atchdog)e(timeout)i(can)g(also)g (halt)h(the)f(simulation.)p Black Black 722 1581 a Fi(break)42 b(so)722 1681 y(break)g(su)722 1780 y(break)g(wdt)515 2026 y SDict begin H.S end 515 2026 a 515 2026 a SDict begin 12 H.A end 515 2026 a 515 2026 a SDict begin [/View [/XYZ H.V]/Dest (section*.9) cvn /DEST pdfmark end 515 2026 a Fp(Attrib)n(ute)20 b(Br)o(eakpoints)p Black Black 722 2182 a Fi(break)42 b Fe(attribute)515 2390 y Fo(gpsim)22 b(also)h(supports)f(a)h(concept)f(of)g Fh(attrib)n(ute)h(br)m (eakpoints.)31 b Fo(Attrib)n(utes)23 b(are)g(parameters)e(that)515 2489 y(gpsim)j(and)g(its)h(modules)f(e)o(xpose)f(to)i(the)g(user)f (interf)o(ace.)37 b(F)o(or)25 b(e)o(xample,)f(the)g(simulator)g(stop-) 515 2589 y(w)o(atch)f(e)o(xposes)f(attrib)n(utes)h(which)f(support)g (breakpoints.)31 b(This)23 b(feature)f(is)i(intend)e(mainly)g(for)515 2688 y(module)d(writers)h(to)g(pro)o(vide)e(a)j(mechanism)e(for)g(allo) n(wing)h(the)g(user)g(to)g(control)f(the)h(module.)515 2934 y SDict begin H.S end 515 2934 a 515 2934 a SDict begin 12 H.A end 515 2934 a 515 2934 a SDict begin [/View [/XYZ H.V]/Dest (section*.10) cvn /DEST pdfmark end 515 2934 a Fp(Cycle)g(counter)g(Br)o(eakpoints)p Black Black 722 3090 a Fi(break)42 b(c)h Fe(cycle_number)515 3298 y Fo(The)24 b(c)o(ycle)f(counter)g(is)j(gpsim')-5 b(s)24 b(time)g(k)o(eeper)-5 b(.)37 b(It)25 b(increments)e(once)g(e)n(v)o(ery) g(instruction)g(c)o(ycle.)515 3397 y(The)18 b('c')f(option)g(to)i(the)f (break)f(command)f(allo)n(ws)j(a)f(break)f(point)h(to)g(be)g(set)h(at)g (a)f(particular)f(v)n(alue)515 3497 y(of)j(the)g(c)o(ycle)g(counter)-5 b(.)515 3646 y SDict begin H.S end 515 3646 a 515 3646 a SDict begin 12 H.A end 515 3646 a 515 3646 a SDict begin [/View [/XYZ H.V]/Dest (section.2.3) cvn /DEST pdfmark end 515 3646 a 156 x Fk(2.3)119 b(clear)p Black Black 722 3987 a Fi(clear)42 b(bp_number)515 4195 y Fo(The)28 b(clear)g(command)f (is)i(used)f(to)h(clear)f(break)f(points.)49 b(The)29 b(break)e(point)h(number)e(must)j(be)515 4295 y(speci\002ed.)54 b(The)30 b Fh(br)m(eak)h Fo(command)d(without)h(an)o(y)h(ar)o(guments)e (displays)i(all)g(of)g(the)g(currently)515 4394 y(de\002ned)f(break)h (points.)56 b(This)30 b(can)h(be)f(used)h(to)g(ascertain)f(the)h(break) e(point)h(number)-5 b(.)55 b(Once)515 4494 y(cleared,)19 b(a)i(break)e(point)g(is)i(deleted.)1613 4494 y SDict begin H.S end 1613 4494 a -30 x Fm(1)1647 4494 y SDict begin 12 H.L end 1647 4494 a 1647 4494 a SDict begin [/Subtype /Link/Dest (Hfootnote.4) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1647 4494 a Black 515 4565 1146 4 v 605 4620 a Fg(1)634 4644 y SDict begin H.S end 634 4644 a 634 4644 a SDict begin H.R end 634 4644 a 634 4644 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.4) cvn /DEST pdfmark end 634 4644 a Ff(A)c(break)h(point)g(disable/enable)k(feature)d(has)e(been)h (discussed)g(and)g(may)e(be)i(added)g(a)f(future)h(date.)p Black Black Black eop end %%Page: 14 15 TeXDict begin 14 14 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.14) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(14)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.2.4) cvn /DEST pdfmark end 515 432 a 83 x Fk(2.4)119 b(disassemble)p Black Black 722 701 a Fi(disassemble)39 b([[begin:end])g(|)k([count]]) 515 908 y Fo(The)23 b(disassemble)h(command)e(decodes)h(the)h(program)e (memory)g(opcodes)g(into)i(their)g(standard)515 1008 y(mnemonics.)60 b(W)m(ith)33 b(no)g(options,)h(the)f Fh(disassemble)f Fo(command)f(disassembles)i(instructions)515 1108 y(surrounding)17 b(the)j(current)f(program)f(counter:)p Black Black 722 1315 a Fi(gpsim>)41 b(disassemble)722 1415 y(current)g(pc)i(=)g(0x1c)897 1514 y(0012)e(2a03)h(incf)g (reg3,f,0)897 1614 y(0014)f(0004)h(clrwdt)897 1714 y(0016)f(5000)h (movf)g(reg,w,0)897 1813 y(0018)f(1001)h(iorwf)g(reg1,w,0)897 1913 y(001a)f(1002)h(iorwf)g(reg2,w,0)722 2013 y(==>)h(001c)e(1003)h (iorwf)g(reg3,w,0)897 2112 y(001e)f(e1f4)h(bnz)h($-0x16)e(;\(0x8\))897 2212 y(0020)g(d7ff)h(bra)h($-0x0)e(;\(0x00020\))515 2419 y Fo(W)m(ith)22 b(a)g(single)f(numeric)f(option,)h(the)h Fh(disassemble)f Fo(command)f(will)i(disassemble)f(gi)n(v)o(en)g(num-) 515 2519 y(ber)f(of)f(instructions)h(starting)f(with)i(the)f (instruction)f(at)i(the)f(PC.)515 2644 y(W)m(ith)j(a)h(tw)o(o)f (numbers,)f(the)h Fh(disassemble)g Fo(command)e(will)j(disassemble)f (instructions)f(starting)515 2743 y(and)d(ending)g(gi)n(v)o(en)g (number)f(of)i(instructions)g(from)f(the)h(PC.)515 2892 y SDict begin H.S end 515 2892 a 515 2892 a SDict begin 12 H.A end 515 2892 a 515 2892 a SDict begin [/View [/XYZ H.V]/Dest (section.2.5) cvn /DEST pdfmark end 515 2892 a 156 x Fk(2.5)119 b(dump)p Black Black 722 3234 a Fi(dump)42 b([r)h(|)g(s)g(|)g(e)h([module_name)38 b([filename]]])515 3441 y Fo(dump)15 b(r)i(or)g(dump)e(with)i(no)g(options)f(will)h (display)f(all)i(of)e(the)h(\002le)h(re)o(gisters)e(and)g(special)h (function)515 3541 y(re)o(gisters.)515 3666 y(dump)i(s)i(will)g (display)e(only)h(special)g(function)e(re)o(gisters.)515 3790 y(dump)g(e)i(will)g(display)f(the)g(contents)g(of)g(the)h (processor)e(EEPR)m(OM)h(\(if)h(the)f(pic)h(being)e(simulated)515 3890 y(contains)h(an)o(y\).)515 4014 y(The)f(')l(dump)f(e)i (module_name')c(command)h(will)k(display)e(the)g(contents)g(of)g(an)h (EEPR)m(OM)f(where)515 4114 y(module_name)29 b(can)j(either)h(be)f(the) g(name)g(of)h(a)f(module)g(or)g(processor)f(which)h(contains)g(an)515 4214 y(EEPR)m(OM.)515 4338 y(The)g(')l(dump)f(e)i(module_name)c (\002lename')j(command)e(dumps)i(the)g(contents)g(of)h(a)g(module')-5 b(s)515 4438 y(EEPR)m(OM,)17 b(in)g(Intel)g(he)o(x)f(format,)h(into)g (the)g(\002le)h(with)f(the)h(gi)n(v)o(en)e(name.)23 b(The)17 b(')o(load)f(e')i(command)515 4537 y(can)h(later)g(be)g(used)g(to)g (read)g(the)g(dumped)e(\002le)j(thus)f(allo)n(wing)f(the)h(contents)f (of)h(the)g(EEPR)m(OM)g(to)515 4637 y(be)h(preserv)o(ed)e(between)h (runs)h(of)g(gpsim.)515 4761 y(See)g(the)h('x')e(command)f(for)i(e)o (xamining)e(and)i(modifying)d(indi)n(vidual)i(re)o(gisters.)p Black Black eop end %%Page: 15 16 TeXDict begin 15 15 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.15) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(15)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.2.6) cvn /DEST pdfmark end 515 432 a 83 x Fk(2.6)119 b(echo)515 724 y Fo(The)20 b(echo)h(command)e(is)i(used)g(lik)o(e)g(a)h(print)e (statement)h(within)g(con\002guration)d(\002les.)28 b(It)21 b(just)h(lets)515 824 y(you)d(display)h(information)d(about)j(your)f (con\002guration)e(\002le.)515 971 y SDict begin H.S end 515 971 a 515 971 a SDict begin 12 H.A end 515 971 a 515 971 a SDict begin [/View [/XYZ H.V]/Dest (section.2.7) cvn /DEST pdfmark end 515 971 a 155 x Fk(2.7)119 b(fr)n(equency)515 1334 y Fo(This)20 b(command)f(sets)i(the)g(oscillator)f(frequenc)o(y)-5 b(.)22 b(By)f(def)o(ault)e(gpsim)h(uses)h(20)f(MHz)h(oscillator)-5 b(.)515 1434 y(The)28 b(oscillator)g(frequenc)o(y)e(is)j(used)g(to)f (compute)g(time)g(in)h(seconds.)49 b(Use)30 b(this)f(command)d(to)515 1534 y(adjust)g(this)g(v)n(alue.)42 b(If)26 b(no)g(v)n(alue)f(is)i(pro) o(vided)d(this)i(command)e(prints)i(the)g(current)f(frequenc)o(y)-5 b(.)515 1633 y(Note)17 b(that)h(PICs)h(ha)n(v)o(e)e(an)g(instruction)g (frequenc)o(y)e(that')-5 b(s)18 b(a)g(quarter)e(of)h(the)h(oscillator)f (frequenc)o(y)515 1733 y(clock.)515 1863 y SDict begin H.S end 515 1863 a 515 1863 a SDict begin 12 H.A end 515 1863 a 515 1863 a SDict begin [/View [/XYZ H.V]/Dest (section.2.8) cvn /DEST pdfmark end 515 1863 a 172 x Fk(2.8)119 b(help)p Black Black 722 2220 a Fi(help)42 b([)p Fe(command)11 b Fi(])515 2418 y Fo(By)22 b(itself,)h(help)e(will)i(display)e(all)h (of)g(the)g(commands)e(along)h(with)h(a)g(brief)f(description)g(on)g (ho)n(w)515 2518 y(the)o(y)f(w)o(ork.)27 b(W)m(ith)22 b(a)f(command)e(as)j(a)g(parameter)d(help)i(pro)o(vides)e(more)h(e)o (xtensi)n(v)o(e)g(online)g(help.)515 2617 y(The)g(help)f(command)g(can) g(also)i(display)f(information)d(about)j(attrib)n(utes.)515 2764 y SDict begin H.S end 515 2764 a 515 2764 a SDict begin 12 H.A end 515 2764 a 515 2764 a SDict begin [/View [/XYZ H.V]/Dest (section.2.9) cvn /DEST pdfmark end 515 2764 a 155 x Fk(2.9)119 b(icd)p Black Black 722 3105 a Fi(icd)43 b([open)e(])515 3302 y Fo(The)22 b(open)g(command)f (is)j(used)e(to)h(enable)f(ICD)i(mode)e(and)g(specify)g(the)h(serial)g (port)f(where)h(the)515 3402 y(ICD)g(is.)33 b(\(e.g.)f("icd)22 b(open)g(/de)n(v/ttyS0"\).)31 b(W)m(ithout)22 b(options)f(\(and)h (after)g(the)h(icd)g(is)g(enabled\),)f(it)515 3502 y(will)f(print)e (some)h(information)e(about)h(the)h(ICD.)515 3649 y SDict begin H.S end 515 3649 a 515 3649 a SDict begin 12 H.A end 515 3649 a 515 3649 a SDict begin [/View [/XYZ H.V]/Dest (section.2.10) cvn /DEST pdfmark end 515 3649 a 154 x Fk(2.10)119 b(list)515 4012 y Fo(The)20 b(list)h(command)d(allo)n(ws) j(you)e(to)h(vie)n(w)g(the)g(source)g(code)f(while)i(you)e(are)h(deb)n (ugging.)p Black Black 722 4210 a Fi(list)42 b([[s)g(|)i(l])e([*pc])g ([line_number1)c([,line_number2]])o(])515 4407 y Fo(W)m(ithout)19 b(an)o(y)h(options,)f(list)i(will)g(use)f(the)h(last)g(speci\002ed)f (options.)515 4530 y(list)h(s)g(will)g(display)f(lines)g(in)h(the)f (source)f(\(or)h(.asm\))g(\002le.)515 4653 y(list)h(l)g(will)g(display) e(lines)i(in)f(the)h(.lst)f(\002le.)515 4776 y(list)g(*pc)e(will)i (display)f(either)g(.asm)g(or)g(.lst)g(lines)h(around)d(the)i(PC.)h(W)m (ithout)f(*pc)f(use)i(current)d(PC)515 4876 y(as)k(a)f(reference.)515 4998 y(Line)g(numbers)e(are)i(relati)n(v)o(e)g(to)g(the)g(line)h(of)f (the)g(PC.)p Black Black eop end %%Page: 16 17 TeXDict begin 16 16 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.16) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(16)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.2.11) cvn /DEST pdfmark end 515 432 a 83 x Fk(2.11)119 b(load)515 726 y Fo(The)20 b(load)f(command)g(is)i(used)f(to)g(load)g (a)g(program)e(\002le,)j(a)g(command)d(\002le,)i(or)g(eeprom)f(data.) 515 850 y(Program)30 b(\002le)i(is)h(usually)e(used)g(to)h(program)d (the)j(physical)e(part.)59 b(A)32 b(.he)o(x)f(\002le)h(pro)o(vides)e (no)515 950 y(symbolic)22 b(information.)33 b(.cod)23 b(\002les)h(on)f(the)h(other)f(hand,)g(do)g(pro)o(vide)f(symbolic)g (information.)515 1050 y(The)e(only)f(reason)g(to)i(use)f(a)h(he)o(x)e (\002le)i(is)g(when)f(there')-5 b(s)20 b(no)g(.cod)f(\002le)i(a)n(v)n (ailable.)515 1174 y(The)f(syntax)f(for)h(loading)e(program)h(\002les)i (is:)p Black Black 722 1382 a Fi(load)42 b([processortype])37 b(programfile)i([label])515 1589 y Fo(Gpsim)23 b(will)g(automatically)f (determine)f(if)i(the)g(\002le)h(is)g(a)f(.he)o(x)f(or)h(.cod)f (\002le.)34 b(The)22 b(optional)g Fh(pr)l(o-)515 1689 y(cessortype)29 b Fo(is)i(needed)d(if)i(a)g(.he)o(x)f(\002le)h(is)h (being)e(loaded)f(and)h(the)h(processor)e(type)i(is)g(not)g(yet)515 1788 y(de\002ned.)515 1913 y(The)24 b(optional)f Fh(label)h Fo(is)i(used)e(to)h(identify)e(the)h(processor)g(module)f(on)h(the)g (breadboard)e(and)i(as)515 2013 y(the)19 b(pre\002x)g(in)h(the)g (symbol)f(table.)25 b(If)19 b(a)h(label)g(is)h(not)e(gi)n(v)o(en)f (then)i(the)f(processor)g(type)g(is)i(used)e(for)515 2112 y(this)h(functionality)-5 b(.)p Black Black 722 2320 a Fi(load)42 b([i])g(commandfile.stc)515 2527 y Fo(Command)25 b(\002les)j(contain)d(gpsim)h(commands.)43 b(These)27 b(are)f(e)o(xtremely)f(useful)h(for)g(creating)g(a)515 2627 y(deb)n(ugging)16 b(en)m(vironment)f(that)k(will)g(be)f(used)h (repeatedly)-5 b(.)22 b(Normally)17 b(loading)g(a)i(command)e(\002le) 515 2727 y(residing)25 b(in)h(other)f(directories)f(changes)h(w)o (orking)g(directory)-5 b(.)39 b(This)26 b(can)g(be)g(o)o(v)o(erridden)c (with)515 2826 y(the)e('i')g(\(include\))f(option.)p Black Black 722 3034 a Fi(load)42 b(e)h(module_name)c(file)515 3241 y Fo(This)29 b(command)e(loads)h(the)h(contents)f(of)h(either)f(a) i(processor')-5 b(s)27 b(EEPR)m(OM)i(or)g(an)g(EEPR)m(OM)515 3341 y(module)23 b(from)h(a)h(\002le)g(containing)e(the)h(data)h(in)f (Intel)h(he)o(x)f(format.)37 b(In)24 b(either)g(case)h(the)g(address) 515 3441 y(of)30 b(the)g(\002rst)h(cell)g(of)f(the)h(EEPR)m(OM)f(is)h (0x0000.)54 b(Used)30 b(in)h(conjunction)d(with)i(the)h(')l(dump)d(e) 515 3540 y(module_name)c(\002lename')i(command,)g(the)h(contents)f(of)h (an)g(EEPR)m(OM)f(can)h(be)g(carried)f(o)o(v)o(er)515 3640 y(from)19 b(one)h(run)f(of)h(gpsim)g(to)g(another)-5 b(.)515 3789 y SDict begin H.S end 515 3789 a 515 3789 a SDict begin 12 H.A end 515 3789 a 515 3789 a SDict begin [/View [/XYZ H.V]/Dest (section.2.12) cvn /DEST pdfmark end 515 3789 a 156 x Fk(2.12)119 b(macr)n(os)515 4155 y Fo(Macros)19 b(are)i(de\002ned)e(lik)o(e:)p Black Black 722 4363 a Fe(name)57 b Fi(macro)41 b([arg1,)g(arg2,)h(...,)f(argN])853 4463 y(macro)g(body)722 4562 y(endm)515 4770 y Fo(And)19 b(the)o(y')l(re)g(in)m(v)n(ok)o(ed)f(by:)p Black Black 722 4977 a Fe(name)57 b Fi(param1,)40 b(param2,)h(...,)h(paramN)p Black Black eop end %%Page: 17 18 TeXDict begin 17 17 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.17) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(17)p Black 515 515 a(Macros)23 b(are)h(a)h(w)o(ay)f (of)g(collecting)f(se)n(v)o(eral)g(parameterized)f(commands)g(into)i (one)g(short)f(com-)515 615 y(mand.)53 b(The)30 b(\002rst)h(line)f(of)g (a)g(macro)f(de\002nition)g(speci\002es)h(the)h(macro')-5 b(s)29 b(name)g(and)h(optional)515 715 y(ar)o(guments.)23 b(The)e Fh(name)e Fo(is)j(used)e(to)h(in)m(v)n(ok)o(e)e(the)h(macro.)25 b(The)20 b(ar)o(guments)f(are)h(te)o(xt)h(string)f(place)515 814 y(holders.)25 b(When)20 b(a)h(macro)f(is)i(in)m(v)n(ok)o(ed,)c(the) j(parameters)e(are)i(aligned)e(with)i(the)g(ar)o(guments.)j(I.e.)515 914 y Fh(par)o(am1)h Fo(in)i(the)g(in)m(v)n(ocation)e(can)i(be)g (thought)e(of)i(being)f(assigned)g(to)i Fh(ar)m(g1)e Fo(in)h(the)g(de\002nition.)515 1013 y(The)20 b(parameters)f(replace)g (the)h(ar)o(guments)e(in)j(the)f(macro)f(body)-5 b(.)515 1138 y(In)19 b(the)h(follo)n(wing)d(e)o(xample,)h(a)i(v)n(ariable)f(or) g(attrib)n(ute)g(called)h Fh(mac_\003a)o(gs)d Fo(is)k(being)e (manipulated)515 1238 y(in)j(an)f(e)o(xpression.)29 b(The)21 b(ar)o(guments)f Fh(add)j Fo(and)e Fh(mask)j Fo(appear)c(in)i(the)g (macro)f(body)f(and)i(pro)o(vide)515 1337 y(a)e(parameterized)e(w)o(ay) j(of)e(manipulating)f(this)j(e)o(xpression.)p Black Black 722 1545 a Fi(mac_exp)41 b(macro)g(add,)h(mask)809 1644 y(mac_flags)e(=)j(\(mac_flags+add\))38 b(&)43 b(mask)722 1744 y(endm)515 1952 y Fo(Note)20 b(that)g(the)g(indentation)f(is)i (arbitrary)-5 b(.)23 b(The)d(macro)f(is)i(in)m(v)n(ok)o(ed)d(by:)p Black Black 722 2159 a Fi(mac_exp)41 b(1,)i(0b00001111)c(#)k(increment) d(the)i(lower)g(nibble)515 2367 y Fo(The)19 b(parameter)g Fh(add)i Fo(is)g(replaced)d(by)i(the)f(number)f Fh(1)i Fo(while)g Fh(mask)i Fo(is)e(replaced)f(with)h(the)g(binary)515 2466 y(number)e Fh(0b00001111.)j Fo(The)f(in)m(v)n(ocation)e(turns)i (into)g(the)g(gpsim)g(command:)p Black Black 722 2674 a Fi(mac_flags)40 b(=)j(\(mac_flags+1\))38 b(&)43 b(0b00001111)515 2920 y SDict begin H.S end 515 2920 a 515 2920 a SDict begin 12 H.A end 515 2920 a 515 2920 a SDict begin [/View [/XYZ H.V]/Dest (section*.11) cvn /DEST pdfmark end 515 2920 a Fp(Nested)20 b(Macr)o(os)515 3100 y Fo(The)28 b(macro)g(body)f(can)i(contain)e(an)o(y)h(gpsim)g(command.)49 b(Of)29 b(particular)e(interest)i(are)g(macro)515 3200 y(in)m(v)n(ocations)d(within)h(other)f(macros.)46 b(Here')-5 b(s)28 b(another)e(macro)g(that)i(in)m(v)n(ok)o(es)e(the)i(one)f (de\002ned)515 3300 y(abo)o(v)o(e.)p Black Black 722 3507 a Fi(#)43 b(Nested)e(macro)h(example)722 3607 y(mac1)g(macro)g (p1,)g(p2)809 3706 y(run)809 3806 y(mac_exp)f(p1,)h(p2)722 3906 y(endm)515 4113 y Fo(And)19 b(it)i(could)f(be)g(used)g(lik)o(e:)p Black Black 722 4321 a Fi(mac1)86 b(1,)260 b(0b00001111)127 b(#)87 b(test)41 b(lower)h(nibble)722 4420 y(mac1)86 b(\(1<\027<4\),)40 b(0b11110000)127 b(#)87 b(test)41 b(upper)h(nibble)515 4628 y Fo(The)24 b(\002rst)i(in)m(v)n(ocation)d (starts)j(the)f(simulator)f(by)h(e)o(x)o(ecuting)e(a)i Fh(run)g Fo(command.)37 b(When)25 b(a)h(break)515 4728 y(point)f(is)i(encountered,)e(control)g(returns)h(to)g(the)g(command)f (line)h(and)g(the)g Fh(mac_e)n(xp)f Fo(macro)h(is)515 4827 y(in)m(v)n(ok)o(ed.)p Black Black eop end %%Page: 18 19 TeXDict begin 18 18 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.18) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(18)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 12 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.12) cvn /DEST pdfmark end 515 515 a Fp(Displaying)20 b(De\002ned)h(Macr)o(os)515 695 y Fo(All)i(currently)e(de\002ned)g (macros)h(can)g(be)h(displayed)e(by)h(typing)g(the)g(macro)g(command)e (without)515 794 y(a)g(name)g(or)g(ar)o(guments:)p Black Black 722 994 a Fi(gpsim>)41 b(macro)722 1094 y(mac1)h(macro)g(p1)g(p2) 853 1194 y(run)853 1293 y(mac_exp)f(p1,)h(p2)722 1393 y(endm)722 1493 y(mac_exp)f(macro)g(add)i(mask)897 1592 y(mac_flags)c(=)44 b(\(mac_flags+add\))37 b(&)43 b(mask)722 1692 y(endm)515 1821 y SDict begin H.S end 515 1821 a 515 1821 a SDict begin 12 H.A end 515 1821 a 515 1821 a SDict begin [/View [/XYZ H.V]/Dest (section.2.13) cvn /DEST pdfmark end 515 1821 a 174 x Fk(2.13)119 b(module)515 2204 y Fo(The)26 b Fh(module)g Fo(command)f(is)j(used)f(to)g(load)f (and)g(query)g(e)o(xternal)g(modules)f(\(see)j(section)3213 2205 y SDict begin H.S end 3213 2205 a Black -1 x Fo(8)p Black 3255 2148 a SDict begin H.R end 3255 2148 a 3255 2204 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (chapter.8) cvn H.B /ANN pdfmark end 3255 2204 a 27 w Fo(for)515 2303 y(more)21 b(information)e(about)i(gpsim)g(modules\).)29 b(A)22 b(module)e(is)j(a)f(special)g(piece)g(of)f(softw)o(are)g(that) 515 2403 y(can)j(e)o(xtend)f(gpsim)h(in)h(some)f(manner)-5 b(.)37 b(LED')-5 b(s)25 b(and)f(switches)h(are)g(e)o(xamples)e(of)h (modules.)37 b(A)515 2503 y(module)19 b(library)g(is)i(collection)e(of) h(modules.)515 2746 y SDict begin H.S end 515 2746 a 515 2746 a SDict begin 12 H.A end 515 2746 a 515 2746 a SDict begin [/View [/XYZ H.V]/Dest (section*.13) cvn /DEST pdfmark end 515 2746 a Fp(Loading)g(module)g(libraries)p Black Black 722 2902 a Fi(module)41 b(lib)i Fe(lib_name)515 3102 y Fo(The)19 b Fh(lib)i Fo(option)e(is)i(used)e(to)i(load)e(a)i (module)d(library)-5 b(.)24 b(Module)19 b(libraries)g(are)i(system)f (dependent)515 3202 y(shared)28 b(libraries,)j(i.e.)52 b(on)29 b(W)m(indo)n(ws)f(the)o(y')l(re)g(DLL)-8 b(')j(s)30 b(and)e(UNIX)h(the)o(y')l(re)f(shared)g(libraries.)515 3301 y(This)16 b(means)h(that)f(either)g(the)h(libraries)f(should)g (reside)g(in)h(a)f(path)h(where)e(the)i(OS)g(kno)n(ws)f(libraries)515 3401 y(e)o(xist)31 b(or)g(that)h(the)f(full)g(path)g(name)g(must)g(be)h (speci\002ed)f(along)f(with)i(the)f Fh(lib_name)p Fo(.)57 b(gpsim)515 3501 y(pro)o(vides)18 b(a)j(module)e(library)g(with)h(a)h (fe)n(w)f(modules:)p Black Black 722 3701 a Fi(gpsim>)41 b(module)g(lib)i(libgpsim_module)o(s)515 3944 y SDict begin H.S end 515 3944 a 515 3944 a SDict begin 12 H.A end 515 3944 a 515 3944 a SDict begin [/View [/XYZ H.V]/Dest (section*.14) cvn /DEST pdfmark end 515 3944 a Fp(Displaying)20 b(a)n(v)o(ailable)f(modules)p Black Black 722 4100 a Fi(module)41 b(list)515 4300 y Fo(The)22 b Fh(list)j Fo(option)d(will)h(display)f(all)h(of)f(the)h(modules)f(that)g(can)h (be)f(loaded.)31 b(Here)23 b(is)g(an)g(e)o(xample)515 4400 y(of)d(gpsim')-5 b(s)20 b(b)n(uilt-in)f(modules.)p Black Black 722 4600 a Fi(gpsim>)41 b(module)g(list)722 4700 y(Module)g(Library)g(Files)722 4799 y(libgpsim_modules.)o(so)853 4899 y(switch)853 4998 y(and2)p Black Black eop end %%Page: 19 20 TeXDict begin 19 19 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.19) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(19)p Black 853 515 a Fi(or2)853 615 y(xor2)853 715 y(not)853 814 y(led_7segments)853 914 y(led)853 1013 y(push_button)853 1113 y(PortStimulus)853 1213 y(pullup)853 1312 y(pulldown)853 1412 y(pulsegen)853 1512 y(Encoder)853 1611 y(usart)853 1711 y(TTL377)853 1810 y(I2C-EEPROM2k)853 1910 y(I2C-EEPROM16k)853 2010 y(I2C-EEPROM256k)515 2252 y SDict begin H.S end 515 2252 a 515 2252 a SDict begin 12 H.A end 515 2252 a 515 2252 a SDict begin [/View [/XYZ H.V]/Dest (section*.15) cvn /DEST pdfmark end 515 2252 a Fp(Loading)20 b(a)g(speci\002c)h(module)p Black Black 722 2408 a Fi(module)41 b(load)h(module_type)d ([module_name])515 2604 y Fo(Once)18 b(a)h(library)e(has)i(been)f (loaded,)g(speci\002c)g(modules)g(can)g(be)h(instantiated.)24 b(The)18 b Fh(module_type)515 2704 y Fo(is)23 b(what')-5 b(s)22 b(displayed)e(by)i(the)g Fh(module)f(list)j Fo(command.)k(The)22 b(optional)e(module)h(name)g(speci\002es)515 2804 y(what)f(the)g (instance)g(is)h(called.)k(Here')-5 b(s)20 b(an)g(e)o(xample)p Black Black 722 3000 a Fi(gpsim>)41 b(module)g(load)h(led)h(D1)515 3243 y SDict begin H.S end 515 3243 a 515 3243 a SDict begin 12 H.A end 515 3243 a 515 3243 a SDict begin [/View [/XYZ H.V]/Dest (section*.16) cvn /DEST pdfmark end 515 3243 a Fp(Display)20 b(loaded)g(modules)p Black Black 722 3398 a Fi(module)515 3641 y SDict begin H.S end 515 3641 a 515 3641 a SDict begin 12 H.A end 515 3641 a 515 3641 a SDict begin [/View [/XYZ H.V]/Dest (section*.17) cvn /DEST pdfmark end 515 3641 a Fp(Querying)f(modules)515 3819 y Fo(Dumping)f(modules)h(and)h(listing)g(the)g(pins)h(is)g(not)f (yet)g(implemented.)p Black Black 515 4145 a SDict begin H.S end 515 4145 a 515 4145 a SDict begin 12 H.A end 515 4145 a 515 4145 a SDict begin [/View [/XYZ H.V]/Dest (section.2.14) cvn /DEST pdfmark end 515 4145 a 173 x Fk(2.14)119 b(node)p Black Black 722 4503 a Fi(node)42 b([new_node1)e(new_node2)f (...])515 4700 y Fo(The)20 b Fh(node)g Fo(command)e(de\002nes)j(or)f (queries)g(\223nodes\224,)g(used)g(to)h(connect)e(e)o(xternal)h (signals)h(to)g(the)515 4799 y(simulated)d(PIC.)i(If)f(no)f(ne)n (w_node)f(is)j(speci\002ed)f(then)f(all)i(of)e(the)h(nodes)g(that)g(ha) n(v)o(e)f(been)h(de\002ned)515 4899 y(are)h(displayed.)26 b(If)21 b(a)g(ne)n(w_node)e(is)i(speci\002ed)g(then)f(it)i(will)f(be)g (added)f(to)h(the)g(node)e(list.)28 b(See)22 b(the)515 4998 y("attach")d(and)h("stimulus")g(commands)f(to)h(see)h(ho)n(w)e (stimuli)i(are)f(added)f(to)h(the)g(nodes.)p Black Black eop end %%Page: 20 21 TeXDict begin 20 20 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.20) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(20)p Black Black Black 722 515 a Fi(examples:)722 615 y(node)478 b(//)43 b(display)d(the)j(node)e(list)722 715 y(node)h(n1)h(n2)g(n3)86 b(//)43 b(create)e(and)h(add)g(3)h(new)g (nodes)e(to)i(the)f(list)515 852 y SDict begin H.S end 515 852 a 515 852 a SDict begin 12 H.A end 515 852 a 515 852 a SDict begin [/View [/XYZ H.V]/Dest (section.2.15) cvn /DEST pdfmark end 515 852 a 168 x Fk(2.15)119 b(pr)n(ocessor)p Black Black 722 1305 a Fi(processor)40 b([new_processor_t)o(yp)o(e)e ([new_processor_)o(na)o(me])o(])f(|)43 b([list])e(|)j([pins])515 1512 y Fo(The)23 b Fh(pr)l(ocessor)i Fo(command)d(is)i(used)f(to)h (either)f(de\002ne)g(a)h(ne)n(w)f(processor)f(or)h(to)h(query)e(one)g (that)515 1612 y(has)i(already)f(been)g(de\002ned.)36 b(Normally)23 b(there')-5 b(s)24 b(no)g(need)f(to)h(e)o(xplicitly)f (de\002ne)h(the)g(processor)515 1712 y(since)f(the)g(symbol)f(\002le)i (already)e(contains)h(that)g(information.)31 b(The)23 b(tw)o(o)h(e)o(xceptions)d(are)i(when)515 1811 y(a\))i(the)h(symbolic)f (information)e(is)j(not)g(a)n(v)n(ailable)f(or)g(b\))g(you)g(wish)h(to) g(o)o(v)o(erride)d(the)j(processor)515 1911 y(speci\002ed)20 b(in)g(the)g(symbol)f(\002le.)26 b(\(See)20 b(the)g Fh(load)i Fo(command)c(on)i(ho)n(w)g(the)g(processor)f(in)h(a)g(symbol)515 2011 y(\002le)h(can)f(be)g(o)o(v)o(erridden.\))515 2135 y(T)-7 b(o)27 b(see)h(a)f(list)h(of)f(the)g(processors)f(supported)g (by)g(gpsim,)i(type)f(')p Fh(pr)l(ocessor)g(list)q Fo('.)47 b(T)-7 b(o)27 b(display)515 2235 y(the)22 b(state)g(of)g(the)g(I/O)g (processor)m(,)e(type)i(')p Fh(pr)l(ocessor)f(pins)p Fo('.)30 b(F)o(or)22 b(no)n(w)-5 b(,)21 b(this)h(will)h(display)e(the)h (pin)515 2334 y(numbers)c(and)i(their)g(current)f(state.)p Black Black 722 2542 a Fi(examples:)722 2641 y(processor)345 b(//)43 b(Display)d(the)j(processors)c(you've)i(already)g(defined.)722 2741 y(processor)f(list)129 b(//)43 b(Display)d(the)j(list)f(of)g (processors)e(supported.)722 2841 y(processor)g(pins)129 b(//)43 b(Display)d(the)j(processor)c(package)i(and)h(pin)h(state)722 2940 y(processor)d(p16cr84)h(fred)129 b(//)42 b(Create)f(a)j(new)e (processor.)722 3040 y(processor)e(p16c74)h(wilma)129 b(//)42 b(and)h(another.)722 3140 y(processor)d(p16c65)390 b(//)42 b(Create)f(one)i(with)f(no)g(name.)515 3289 y SDict begin H.S end 515 3289 a 515 3289 a SDict begin 12 H.A end 515 3289 a 515 3289 a SDict begin [/View [/XYZ H.V]/Dest (section.2.16) cvn /DEST pdfmark end 515 3289 a 156 x Fk(2.16)119 b(quit)515 3655 y Fo(Quit)20 b(gpsim.)515 3804 y SDict begin H.S end 515 3804 a 515 3804 a SDict begin 12 H.A end 515 3804 a 515 3804 a SDict begin [/View [/XYZ H.V]/Dest (section.2.17) cvn /DEST pdfmark end 515 3804 a 156 x Fk(2.17)119 b(run)515 4171 y Fo(Start)22 b(\(or)g(continue\))e(simulation.)30 b(The)21 b(simulation)h(will)g (continue)f(until)h(the)g(ne)o(xt)f(break)g(point)515 4270 y(is)g(encountered.)515 4402 y SDict begin H.S end 515 4402 a 515 4402 a SDict begin 12 H.A end 515 4402 a 515 4402 a SDict begin [/View [/XYZ H.V]/Dest (section.2.18) cvn /DEST pdfmark end 515 4402 a 173 x Fk(2.18)119 b(step)515 4786 y Fo(Ex)o(ecute)19 b(a)h(single)g(instruction,)f(or)h (a)h(speci\002ed)e(number)g(of)h(instructions.)p Black Black 722 4994 a Fi(step)42 b([over)g(|)h(n])p Black Black eop end %%Page: 21 22 TeXDict begin 21 21 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.21) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(21)p Black 515 515 a(W)m(ith)24 b(no)g(ar)o (guments,)f(the)i(step)f(command)f(e)o(x)o(ecutes)g(one)h(instruction)f (of)h(the)g(PIC)h(code.)37 b(If)24 b(a)515 615 y(numeric)i(ar)o(gument) f(is)j(gi)n(v)o(en,)g(this)g(speci\002es)g(a)g(\002x)o(ed)f(number)f (of)h(instructions)f(to)i(simulate.)515 715 y(The)19 b(speci\002c)h(w)o(ord)f(\223o)o(v)o(er\224)f(as)i(an)g(ar)o(gument)d (to)j(step)f(tells)i(gpsim)e(to)h(run)f(e)n(v)o(erything)e(in)m(v)n (olv)o(ed)515 814 y(in)30 b(the)g(current)f(instruction.)53 b(This)30 b(w)o(ould)g(normally)e(be)i(used)g(on)g(a)g(CALL)g (instruction,)h(in)515 914 y(which)19 b(case)i(the)f(whole)g (subroutine)e(runs)i(and)g(the)g(simulation)f(stops)i(after)e(it)i (returns.)515 1063 y SDict begin H.S end 515 1063 a 515 1063 a SDict begin 12 H.A end 515 1063 a 515 1063 a SDict begin [/View [/XYZ H.V]/Dest (section.2.19) cvn /DEST pdfmark end 515 1063 a 156 x Fk(2.19)119 b(symbol)p Black Black 722 1404 a Fi(symbol)41 b([symbol_name)e([symbol_type)f(value]]) 515 1612 y Fo(The)19 b Fh(symbol)h Fo(command)e(is)j(used)e(to)h(query) f(and)g(de\002ne)g(symbols.)24 b(If)c(no)f(options)g(are)h (speci\002ed,)515 1712 y(the)f(whole)g(symbol)f(table)i(is)g (displayed.)j(The)c(creation)f(of)h(user)h(de\002ned)e(symbols)h(is)h (limited)f(at)515 1811 y(this)h(time)h(\(see)f(the)g(online)g(help)f (for)h(the)g(current)f(state)i(of)f(this)h(command\).)515 1960 y SDict begin H.S end 515 1960 a 515 1960 a SDict begin 12 H.A end 515 1960 a 515 1960 a SDict begin [/View [/XYZ H.V]/Dest (section.2.20) cvn /DEST pdfmark end 515 1960 a 156 x Fk(2.20)119 b(stimulus)p Black Black 722 2302 a Fi(stimulus)40 b([[type])h(options])515 2509 y Fo(The)21 b Fh(stimulus)g Fo(command)f(creates)h(a)h(signal)f(that)g (can)g(be)g(tied)h(to)f(a)h(node)e(or)h(an)g(attrib)n(ute.)28 b(If)21 b(no)515 2609 y(options)e(are)h(speci\002ed)g(then)g(all)h (currently)d(de\002ned)h(stimuli)i(are)f(displayed.)515 2734 y(Note)k(that)g(in)g(most)f(cases)i(it)g(is)f(easier)h(to)f (create)f(a)h(stimulus)g(\002le)h(then)e(to)h(type)g(the)g(command)515 2833 y(by)c(hand.)515 2951 y SDict begin H.S end 515 2951 a 515 2951 a SDict begin 0 H.A end 515 2951 a 515 2951 a SDict begin [/View [/XYZ H.V]/Dest (table.2.1) cvn /DEST pdfmark end 515 2951 a 891 2954 2111 4 v 891 2954 V 890 3054 4 100 v 941 3024 a Fo(initial_state)p 1377 3054 V 290 w(state)h(at)f(the)h(start)f(and)g(at)h(the)f(rollo)o(v)o (er)p 3001 3054 V 891 3057 2111 4 v 891 3057 V 890 3157 4 100 v 956 3127 a(start_c)o(ycle)p 1377 3157 V 112 w(simulation)g(c)o (ycle)f(when)h(the)g(stimulus)g(will)h(be)o(gin)p 3001 3157 V 891 3160 2111 4 v 891 3160 V 890 3260 4 100 v 1029 3230 a(period)p 1377 3260 V 690 w(stimulus)f(period)p 3001 3260 V 891 3263 2111 4 v 891 3263 V 890 3363 4 100 v 1045 3333 a(name)p 1377 3363 V 509 w(speci\002es)h(the)f(stimulus)g (name)p 3001 3363 V 891 3366 2111 4 v 891 3366 V 515 3590 a(Here')-5 b(s)24 b(an)f(e)o(xample)f(of)i(a)g(stimulus)f(that)h (will)g(generate)f(tw)o(o)g(pulses)h(and)f(repeat)g(this)h(in)g(1000) 515 3690 y(c)o(ycles.)p Black Black 722 3897 a Fi(stimulus)40 b(asynchronous_stim)o(ul)o(us)722 3997 y(#)j(The)g(initial)d(state)i (AND)g(the)g(state)g(the)g(stimulus)e(is)j(when)722 4097 y(#)g(it)g(rolls)f(over)722 4196 y(initial_state)c(0)722 4296 y(start_cycle)h(0)722 4395 y(#)k(the)g(asynchronous)38 b(stimulus)i(will)i(roll)g(over)g(in)h('period')722 4495 y(#)g(cycles.)e(Delete)g(this)h(line)g(if)h(you)f(don't)f(want)h(a)h (roll)f(over.)722 4595 y(period)f(1000)722 4694 y({)i(100,)f(1,)809 4794 y(200,)g(0,)809 4894 y(300,)g(1,)809 4993 y(400,)g(0)p Black Black eop end %%Page: 22 23 TeXDict begin 22 22 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.22) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(22)p Black 722 515 a Fi(})722 615 y(#)43 b(Give)f(the)h(stimulus)d(a)j(name:)722 715 y(name)f (two_pulse_repeat)722 814 y(end)515 1022 y Fo(A)20 b(stimulus)h(can)f (be)g(queried)e(by)i(typing)f(its)i(name)f(at)h(the)f(command)e(line:)p Black Black 722 1229 a Fi(gpsim>)41 b(two_pulse_repeat)722 1329 y(two_pulse_repeat)c(attached)j(to)j(pulse_node)809 1429 y(Vth=0V)85 b(Zth=250)41 b(ohms)85 b(Cth=0)42 b(F)86 b(nodeVoltage=)39 b(7.49998e-07V)809 1528 y(Driving=0)h(drivingState=0) e(drivenState=0)g(bitState=0)809 1628 y(states)j(=)j(5)897 1727 y(100)e(1)897 1827 y(200)g(0)897 1927 y(300)g(1)897 2026 y(400)g(0)897 2126 y(1000)f(0)722 2226 y(initial=0)722 2325 y(period=1000)722 2425 y(start_cycle=0)722 2524 y(Next)h(break)g(cycle=100)515 2732 y Fo(Ev)o(en)23 b(though)f(this)i (e)o(xample)e(uses)j(1')-5 b(s)24 b(and)g(0')-5 b(s)24 b(for)f(the)h(data,)g(one)g(can)f(use)i(inte)o(gers,)e(\003oating)515 2832 y(point)f(numbers,)h(or)g(e)o(xpressions)f(instead.)33 b(Inte)o(gers)22 b(are)i(useful)e(for)h(supplying)e(a)j(stimulus)f(to) 515 2931 y(an)i(attrib)n(ute.)41 b(Expressions)24 b(are)i(useful)f(for) g(abstracting)f(the)i(data.)41 b(See)26 b(Chapter)3018 2932 y SDict begin H.S end 3018 2932 a Black -1 x Fo(7)p Black 3059 2877 a SDict begin H.R end 3059 2877 a 3059 2931 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (chapter.7) cvn H.B /ANN pdfmark end 3059 2931 a 26 w Fo(for)f(more)515 3031 y(discussion)19 b(and)h(e)o(xamples)f(of)h(stimuli.)515 3180 y SDict begin H.S end 515 3180 a 515 3180 a SDict begin 12 H.A end 515 3180 a 515 3180 a SDict begin [/View [/XYZ H.V]/Dest (section.2.21) cvn /DEST pdfmark end 515 3180 a 156 x Fk(2.21)119 b(stopwatch)1362 3336 y SDict begin H.S end 1362 3336 a -43 x Fd(2)1411 3336 y SDict begin 18 H.L end 1411 3336 a 1411 3336 a SDict begin [/Subtype /Link/Dest (Hfootnote.5) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1411 3336 a Black Black 722 3522 a Fi(A)43 b(timer)f(for)g(monitoring)e (and)i(controlling)d(the)j(simulation.)722 3621 y(The)h(units)e(are)h (in)h(simulation)c(cycles.)809 3721 y(stopwatch.rollove)o(r)e(-)44 b(specifies)39 b(rollover)h(value.)809 3820 y(stopwatch.directi)o(on)d (-)43 b(specifies)d(count)h(direction.)809 3920 y(stopwatch.enable)c(-) 43 b(enables)e(counting)f(if)j(true.)515 4128 y Fo(W)m(ithout)20 b(an)o(y)g(options,)g Fh(stopwatc)o(h)g Fo(will)i(display)e(the)h (contents)f(of)h(the)g(stopw)o(atch)f(timer)-5 b(.)28 b Fh(stop-)515 4227 y(watc)o(h)f Fo(is)h(writable,)g(so)g(you)e(may)h (initialize)h(it)g(to)f(whate)n(v)o(er)f(v)n(alue)g(you)h(lik)o(e.)46 b(The)27 b(beha)n(vior)515 4327 y(of)c(the)g(timer)g(may)f(be)i (manipulated)d(via)i(the)g(three)g(attrib)n(utes.)34 b(The)22 b Fh(.r)l(ollo)o(ver)k Fo(attrib)n(ute)c(is)j(the)515 4426 y(number)e(of)h(c)o(ycles)h(at)g(which)f(the)h(stopw)o(atch)f (timer)g(rolls)h(o)o(v)o(er)-5 b(.)38 b(The)24 b Fh(.dir)m(ection)g Fo(and)g Fh(.enable)515 4526 y Fo(attrib)n(utes)30 b(are)g(boolean)f (types.)56 b(When)30 b(true,)i(the)f Fh(.dir)m(ection)e Fo(attrib)n(ute)h(will)h(instruction)f(the)515 4626 y(stopw)o(atch)19 b(to)i(count)e(up.)p Black 515 4697 1146 4 v 605 4752 a Fg(2)634 4776 y SDict begin H.S end 634 4776 a 634 4776 a SDict begin H.R end 634 4776 a 634 4776 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.5) cvn /DEST pdfmark end 634 4776 a Ff(The)e(stopw)o(atch)i(is)e(really)i(a)e(collection) k(of)16 b(attrib)o(utes)k(and)d(not)h(a)f(command.)k(But)c(the)h(beha)o (vior)h(is)e(so)f(similar)i(to)g(a)515 4855 y(command)f(that)i(it)e (has)g(been)h(included)i(here.)p Black Black Black eop end %%Page: 23 24 TeXDict begin 23 23 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.23) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(2.)45 b(COMMAND)21 b(LINE)f(INTERF)-6 b(A)m(CE)1152 b Fo(23)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.2.22) cvn /DEST pdfmark end 515 432 a 83 x Fk(2.22)119 b(trace)p Black Black 722 701 a Fi(trace)42 b([dump_amount])515 908 y Fh(tr)o(ace)30 b Fo(will)i(print)e(out)g(the)h(most)g(recent)f ("dump_amount")d(traces.)57 b(If)30 b(no)h(dump_amount)c(is)515 1008 y(speci\002ed,)19 b(then)h(the)g(entire)g(trace)g(b)n(uf)n(fer)f (will)i(be)f(displayed.)515 1157 y SDict begin H.S end 515 1157 a 515 1157 a SDict begin 12 H.A end 515 1157 a 515 1157 a SDict begin [/View [/XYZ H.V]/Dest (section.2.23) cvn /DEST pdfmark end 515 1157 a 156 x Fk(2.23)119 b(v)o(ersion)p Black Black 722 1499 a Fi(version)515 1706 y Fo(Display)16 b(gpsim')-5 b(s)16 b(v)o(ersion.)22 b(Note,)17 b(this)g(command)d(will)j(probably)d(get)j(replaced)e(by)h (an)g(attrib)n(ute)515 1806 y(with)k(the)g(same)h(\(or)e(similar\))h (name.)515 1951 y SDict begin H.S end 515 1951 a 515 1951 a SDict begin 12 H.A end 515 1951 a 515 1951 a SDict begin [/View [/XYZ H.V]/Dest (section.2.24) cvn /DEST pdfmark end 515 1951 a 160 x Fk(2.24)119 b(x)515 2321 y Fo(The)26 b Fh(x)h Fo(command)d(is)k(deprecated.)41 b(It')-5 b(s)27 b(former)e(use)i(w)o(as)g(to)f(e)o(xamine)f(and)h(modify)f(memory)-5 b(.)515 2421 y(The)26 b(preferred)f(w)o(ay)i(to)h(do)e(this)i(no)n(w)e (is)i(with)g(e)o(xpressions.)44 b(The)27 b(help)f(for)h Fh(x)g Fo(no)n(w)g(indicates)515 2521 y(this:)p Black Black 722 2728 a Fi(x)43 b(examine)e(command)g(--)h(deprecated)809 2828 y(Instead)f(of)i(the)f(using)g(a)h(special)d(command)h(to)i (examine)d(and)j(modify)809 2927 y(variables,)d(it's)i(possible)e(to)j (directly)d(access)h(them)h(using)f(gpsim's)809 3027 y(expression)f(parsing.)g(For)i(example,)e(to)j(examine)e(a)i (variable:)722 3127 y(gpsim>)e(my_variable)722 3226 y(my_variable)e ([0x27])i(=)i(0x00)f(=)h(0b00000000)809 3326 y(To)g(modify)e(a)i (variable)722 3426 y(gpsim>)e(my_variable)e(=)k(10)809 3525 y(It's)f(also)g(possible)e(to)j(assign)e(the)h(value)g(of)h (register)d(to)j(another)722 3625 y(gpsim>)e(my_variable)e(=)k(porta) 809 3725 y(Or)g(to)g(assign)e(the)h(results)f(of)i(an)f(expression:)722 3824 y(gpsim>)f(my_variable)e(=)k(\(porta)e(^)j(portc\))d(&)i(0x0f)p Black Black eop end %%Page: 24 25 TeXDict begin 24 24 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.24) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.3) cvn /DEST pdfmark end 515 432 a 728 x Fl(Chapter)44 b(3)515 1597 y Fq(Graphical)52 b(User)f(Interface)515 2050 y Fo(FIXME:)20 b(W)-7 b(e)21 b(could)e(use)i(a)f(fe)n(w)h(illustrations)e(here!)515 2172 y(gpsim)30 b(also)h(pro)o(vides)e(a)i(graphical)f(user)g(interf)o (ace)g(that)h(simpli\002es)g(some)g(of)f(the)h(drudgery)515 2271 y(associated)19 b(with)h(the)f(cli.)26 b(It')-5 b(s)20 b(possible)f(to)h(open)e(windo)n(ws)h(to)g(vie)n(w)h(all)g(the)f (details)h(about)f(your)515 2371 y(deb)n(ug)k(en)m(vironment.)33 b(T)-7 b(o)25 b(get)f(the)g(most)g(out)g(of)g(your)f(deb)n(ugging)f (session,)j(you)e(will)i(w)o(ant)f(to)515 2470 y(assemble)19 b(your)f(code)g(with)i(gpasm)e(\(the)h(gnupic)f(assembler\))g(and)h (use)g(the)g(symbolic)f(.cod)h(\002les)515 2570 y(it)i(produces.)515 2716 y SDict begin H.S end 515 2716 a 515 2716 a SDict begin 12 H.A end 515 2716 a 515 2716 a SDict begin [/View [/XYZ H.V]/Dest (section.3.1) cvn /DEST pdfmark end 515 2716 a 153 x Fk(3.1)119 b(Main)30 b(windo)o(w)515 2957 y SDict begin H.S end 515 2957 a 515 2957 a SDict begin 12 H.A end 515 2957 a 515 2957 a SDict begin [/View [/XYZ H.V]/Dest (subsection.3.1.1) cvn /DEST pdfmark end 515 2957 a 136 x Fj(3.1.1)99 b(Menus)p Black 515 3271 a Fo(File->Open)p Black 279 w(.stc)21 b(or)f(.cod)f(\002les.)p Black 515 3430 a(File->Quit)p Black 312 w(Quit)h(gpsim)p Black 515 3590 a(W)m(indo)n(ws->*)p Black 233 w(Open/Close)g(the)g(windo)n (ws.)515 3727 y SDict begin H.S end 515 3727 a 515 3727 a SDict begin 12 H.A end 515 3727 a 515 3727 a SDict begin [/View [/XYZ H.V]/Dest (subsection.3.1.2) cvn /DEST pdfmark end 515 3727 a 120 x Fj(3.1.2)99 b(Buttons)515 4024 y Fo(\(These)19 b(are)i(also)f(found)e(as)j(k)o(e)o(yboard)d(bindings)h (in)h(the)g(source)g(windo)n(ws.\))p Black 515 4200 a(Step)p Black 516 w(Step)g(one)g(instruction)p Black 515 4359 a(Ov)o(er)p Black 498 w(Step)g(until)g(pc)g(is)i(after)d(ne)o(xt)h (instruction)p Black 515 4519 a(Finish)p Black 456 w(Run)g(to)g(return) f(address)p Black 515 4679 a(Run)p Black 525 w(Run)h(continuously)p Black 515 4839 a(Stop)p Black 511 w(Stop)g(e)o(x)o(ecution)p Black 515 4998 a(Reset)p Black 480 w(Reset)h(CPU)p Black 1905 5208 a(24)p Black eop end %%Page: 25 26 TeXDict begin 25 25 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.25) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(25)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (subsection.3.1.3) cvn /DEST pdfmark end 515 432 a 83 x Fj(3.1.3)99 b(Simulation)25 b(mode)515 696 y Fo(This)20 b(controls)f(ho)n(w)h (gpsim)g(simulates,)g(and)g(ho)n(w)f(the)h(GUI)h(updates.)p Black 515 885 a(Ne)n(v)o(er)p Black 421 w(Don')o(t)33 b(e)n(v)o(er)f(update)h(the)g(GUI)h(when)f(simulating.)64 b(This)34 b(is)g(the)g(f)o(astest)1137 985 y(mode.)46 b(Y)-9 b(ou)27 b(will)h(ha)n(v)o(e)f(to)h(stop)f(simulation)g(by)g (pressing)g(Ctrl-C)h(in)g(the)1137 1084 y(command)19 b(line)h(interf)o(ace.)p Black 515 1250 a(x)g(c)o(ycles)p Black 353 w(Update)g(the)g(GUI)g(e)n(v)o(ery)f(x)i(c)o(ycles)e (simulated.)p Black 515 1415 a(e)n(v)o(ery)g(c)o(ycle)p Black 245 w(Update)i(the)g(GUI)g(e)n(v)o(ery)f(c)o(ycle.)28 b(\(you)20 b(see)h(e)n(v)o(erything,)e(if)i(you)g(ha)n(v)o(e)f (\002lled)1137 1515 y(up)g(on)g(cof)n(fee)f(:-\))p Black 515 1680 a(x)h(ms)h(animate)p Black 178 w(Here)33 b(you)e(can)i(slo)n (w)g(do)n(wn)e(simulation)h(with)g(a)h(delay)f(between)g(e)n(v)o(ery) 1137 1780 y(c)o(ycle.)p Black 515 1945 a(realtime)p Black 349 w(This)20 b(will)f(mak)o(e)g(gpsim)f(try)h(to)g(synchronize)e (simulation)h(speed)h(with)g(w)o(all)1137 2045 y(clock)h(time.)515 2176 y SDict begin H.S end 515 2176 a 515 2176 a SDict begin 12 H.A end 515 2176 a 515 2176 a SDict begin [/View [/XYZ H.V]/Dest (section.3.2) cvn /DEST pdfmark end 515 2176 a 174 x Fk(3.2)119 b(Sour)n(ce)30 b(Br)n(o)o(wsers)515 2560 y Fo(gpsim)h(pro)o(vides)f(tw)o(o)i(vie)n(ws)g(of)f(your)f (source:)48 b('.)p Fh(asm')31 b Fo(and)g('.)p Fh(obj')f Fo(bro)n(wsers.)59 b(The)31 b('.)p Fh(asm')515 2659 y Fo(bro)n(wser)19 b(is)i(a)g(color)e(coded)g(display)h(of)f(your)g(pic)i (source.)515 2799 y SDict begin H.S end 515 2799 a 515 2799 a SDict begin 12 H.A end 515 2799 a 515 2799 a SDict begin [/View [/XYZ H.V]/Dest (subsection.3.2.1) cvn /DEST pdfmark end 515 2799 a 122 x Fj(3.2.1)99 b(.asm)24 b(Br)n(o)o(wser)515 3102 y Fo(When)32 b(a)h(.cod)f(\002le)i(with)f(source)f(is)h(loaded,)i (there)d(should)g(be)g(something)g(in)h(this)g(display)-5 b(.)515 3201 y(\(T)o(ODO:)19 b(add)h(section)g(about)f(high)g(le)n(v)o (el)h(deb)n(ugging\).)515 3326 y(There)30 b(is)h(an)g(area)g(to)g(the)f (left)h(of)g(the)g(source,)h(where)e(symbols)g(representing)f(the)i (program)515 3425 y(counter)m(,)f(breakpoints,)g(etc)h(are)f (displayed.)53 b(Double)29 b(clicking)g(in)h(this)h(area)f(toggles)f (break-)515 3525 y(points.)e(Y)-9 b(ou)20 b(can)h(drag)f(these)i (symbols)e(up)h(or)g(do)n(wn)f(in)h(order)f(to)h(mo)o(v)o(e)f(them)g (and)h(change)f(the)515 3624 y(PC)h(or)f(mo)o(v)o(e)f(a)h(breakpoint.) 515 3749 y(A)25 b(right)f(b)n(utton)f(click)i(on)f(the)h(source)e(pops) h(up)h(a)g(menu)e(with)i(six)g(items)g(\(the)f(w)o(ord)g('here')f(in) 515 3848 y(some)18 b(menu)f(items)h(denote)f(the)h(line)g(in)g(source)f (the)h(mouse)f(pointer)g(w)o(as)i(on)f(when)f(right)g(mouse)515 3948 y(b)n(utton)i(w)o(as)i(click)o(ed.\):)p Black 515 4137 a Fp(Menu)g(item)p Black 217 w(Description)p Black 515 4303 a Fo(Find)f(PC)p Black 328 w(This)f(menu)g(item)h(will)g (\002nd)f(the)h(PC)g(and)f(changed)f(page)h(tab)g(and)g(scroll)h(the) 1117 4402 y(source)f(vie)n(w)h(to)h(the)f(current)f(PC.)p Black 515 4568 a(Run)h(here)p Black 299 w(This)i(sets)h(a)f(breakpoint) e('here')g(and)i(starts)g(running)e(until)i(a)g(breakpoint)e(is)1117 4668 y(hit.)p Black 515 4833 a(Mo)o(v)o(e)f(PC)i(here)p Black 124 w(This)f(simply)f(changes)g(PC)i(to)f(the)g(address)f(that)h (line)g('here')f(in)g(source)h(has.)p Black 515 4998 a(Breakpoint)e(here)p Black 69 w(Set)j(a)f(breakpoint)e('here'.)p Black Black eop end %%Page: 26 27 TeXDict begin 26 26 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.26) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(26)p Black Black 515 515 a(Pro\002le)20 b(start)h(here)p Black 52 w(Set)g(a)f(start)h(mark)o(er)e(for)g (routine)g(pro\002ling)g(here.)p Black 515 680 a(Pro\002le)h(stop)g (here)p Black 57 w(Set)h(a)f(stop)g(mark)o(er)-5 b(.)24 b(\(See)d(the)f(section)g(for)f(the)i(pro\002ling)d(windo)n(w)-5 b(.\))p Black 515 846 a(Select)20 b(symbol.)p Black 112 w(This)26 b(menu)e(item)i(is)h(only)e(a)n(v)n(ailable)h(when)f(some)g (te)o(xt)h(is)h(selected)f(in)g(the)1117 945 y(te)o(xt)16 b(widget.)24 b(What)17 b(it)g(does)g(is)g(search)g(the)f(list)i(of)f (symbols)f(for)g(the)h(selected)1117 1045 y(w)o(ord,)h(and)g(if)i(it)f (is)h(found)d(it)j(is)g(selected)f(in)g(the)g(symbol)f(windo)n(w)-5 b(.)23 b(Depend-)1117 1145 y(ing)h(of)g(type)g(of)h(symbol)e(other)h (things)g(are)g(also)h(done,)g(the)f(same)h(thing)f(as)1117 1244 y(when)19 b(selecting)h(a)h(symbol)e(in)h(the)h(symbol)e(windo)n (w:)p Black 1216 1426 a Fc(\017)p Black 41 w Fo(If)f(it)h(is)f(an)g (address,)g(then)f(the)h(opcode)e(and)h(source)g(vie)n(ws)h(display)g (the)1299 1525 y(address.)p Black 1216 1657 a Fc(\017)p Black 41 w Fo(If)i(it')-5 b(s)22 b(a)e(re)o(gister)m(,)f(the)h(re)o (gister)g(vie)n(wer)f(selects)j(the)e(cell.)p Black 1216 1789 a Fc(\017)p Black 41 w Fo(If)g(it')-5 b(s)21 b(a)g(constant,)e (address,)g(re)o(gister)h(or)g(ioport,)e(it)j(is)g(selected)f(in)h(the) 1299 1889 y(symbol)f(windo)n(w)-5 b(.)p Black 515 2070 a(Find)20 b(te)o(xt)p Black 305 w(This)h(opens)f(up)g(a)i(search)e (dialog.)26 b(Ev)o(ery)20 b(time)h(you)f(hit)h(the)g('Find')f(b)n (utton,)1117 2170 y(the)30 b(current)f(notebook)f(page)i(is)h(found)e (and)h(the)g(source)g(in)g(that)h(page)f(is)1117 2269 y(used.)p Black 515 2435 a(Settings)p Black 334 w(A)20 b(dialog)g(with)g(which)g(you)f(can)h(change)f(the)h(fonts)g(used.)p Black 515 2600 a(Controls)p Black 315 w(A)32 b(submenu)e(containing)g (the)h(simulation)g(commands.)58 b(\(these)32 b(are)f(also)1117 2699 y(found)14 b(as)j(k)o(e)o(yboard)c(bindings)i(\(recommended\),)e (or)j(in)g(the)g(main)g(windo)n(w)-5 b(.\))515 2888 y(These)20 b(are)g(the)g(k)o(e)o(yboard)e(bindings:)p Black 515 3077 a Fp(K)n(ey)p Black 273 w(command)p Black 515 3242 a Fo(s,S,F7)p Black 207 w(Step)i(one)g(instruction.)p Black 515 3407 a(o,O,F8)p Black 183 w(Step)g(o)o(v)o(er)f(instruction)p Black 515 3573 a(r)m(,R,F9)p Black 205 w(Run)h(continuously)-5 b(.)p Black 515 3738 a(Escape)p Black 179 w(Stop)20 b(simulation.)p Black 515 3903 a(f,F)p Black 320 w(Run)g(to)g(return)f(address)p Black 515 4068 a(1..9)p Black 289 w(Step)h(n)g(instructions)p Black 515 4233 a(ctrl-f)p Black 248 w(Find)g(te)o(xt)515 4355 y SDict begin H.S end 515 4355 a 515 4355 a SDict begin 12 H.A end 515 4355 a 515 4355 a SDict begin [/View [/XYZ H.V]/Dest (subsection.3.2.2) cvn /DEST pdfmark end 515 4355 a 140 x Fj(3.2.2)99 b(Opcode)25 b(view)g(-)g(the)g(.obj)h(Br)n(o)o (wser)515 4675 y Fo(This)g(windo)n(w)f(has)h(tw)o(o)g(tabs.)43 b(One)26 b(with)g(each)g(memory)e(cell)i(on)g(one)f(line)i(and)e (information)515 4775 y(about)c(address,)h(he)o(xadecimal)e(v)n(alue)i (and)g(decoded)e(instruction)h(\(i.e.)32 b(disassembly\),)21 b(and)h(one)515 4874 y(with)e(the)g(program)e(memory)515 4998 y(displayed)h(with)h(sixteen)g(memory)e(cells)j(per)f(ro)n(w)g (and)g(a)g(con\002gurable)e(ASCII)j(column.)p Black Black eop end %%Page: 27 28 TeXDict begin 27 27 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.27) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(27)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 12 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.18) cvn /DEST pdfmark end 515 515 a Fp(The)21 b(Assembly)g(tab)f(y)n (ou)g(can:)p Black 639 696 a Fc(\017)p Black 41 w Fo(Double)f(click)i (on)e(a)i(line)f(to)h(toggle)e(breakpoints.)p Black 639 862 a Fc(\017)p Black 41 w Fo(Right)32 b(click)g(to)g(get)g(a)g(menu)f (where)g(the)g(breakpoint)f(can)h(be)h(set)h(or)e(cleared)g(on)h(the) 722 962 y(selected)20 b(line.)p Black 639 1128 a Fc(\017)p Black 41 w Fo(Under)g('Settings')f(you)g(can)h(change)f(the)h(font.)515 1374 y SDict begin H.S end 515 1374 a 515 1374 a SDict begin 12 H.A end 515 1374 a 515 1374 a SDict begin [/View [/XYZ H.V]/Dest (section*.19) cvn /DEST pdfmark end 515 1374 a Fp(The)h(Opcode)f(tab)m(.)515 1554 y Fo(Here)i(the)g(program)e (memory)g(is)k(ordered)c(as)j(columns)e(of)h(sixteen)g(memory)e(cells)j (per)f(column)515 1654 y(and)d(as)i(man)o(y)e(ro)n(w)h(as)h(needed)e (to)h(contain)f(all)i(memory)-5 b(.)515 1778 y(The)20 b(se)n(v)o(enteenth)e(column)h(contains)g(an)h(ASCII)h(representation)d (of)i(the)g(program)e(memory)-5 b(.)515 1903 y(Y)c(ou)19 b(can)h(change)f(font)h(with)g(the)g(menu)f(item)i('Settings'.)515 2027 y(The)i(breakpoints)f(can)i(be)g(set)h(or)f(cleared)f(on)g(one)h (or)f(more)h(\(drag)e(the)i(mouse)g(to)g(select)g(more)515 2127 y(cells\))c(addresses)g(with)h(the)f(right)f(click)i(menu.)515 2276 y SDict begin H.S end 515 2276 a 515 2276 a SDict begin 12 H.A end 515 2276 a 515 2276 a SDict begin [/View [/XYZ H.V]/Dest (section.3.3) cvn /DEST pdfmark end 515 2276 a 156 x Fk(3.3)119 b(Register)29 b(views)515 2643 y Fo(There)23 b(are)g(tw)o(o)h(similar)g(re)o(gister)f(windo)n(ws.)35 b(One)23 b(for)g(the)h(RAM)h(and)e(one)g(for)g(the)h(EEPR)m(OM)515 2742 y(data,)c(when)f(a)n(v)n(ailable.)515 2867 y(Here)f(you)g(see)h (all)h(re)o(gisters)e(in)h(the)f(current)g(processor)-5 b(.)23 b(Clicking)c(on)f(a)h(cell)g(displays)f(it')-5 b(s)20 b(name)515 2966 y(and)d(v)n(alue)g(abo)o(v)o(e)f(the)h(sheet)h (of)f(re)o(gisters.)24 b(Y)-9 b(ou)17 b(can)g(change)f(v)n(alues)h(by)h (entering)e(it)i(in)g(the)f(entry)515 3066 y(\(or)i(in)i(the)f (spreadsheet)f(cell\).)515 3190 y(The)25 b(follo)n(wing)g(things)h(can) f(be)h(done)g(on)f(one)h(re)o(gister)m(,)g(or)g(a)g(range)f(of)h(re)o (gisters.)42 b(\(Selecting)515 3290 y(a)28 b(range)f(of)g(re)o(gisters) h(is)h(done)e(by)g(holding)f(do)n(wn)h(left)h(mouse)f(b)n(utton,)i(mo)o (ving)d(cursor)m(,)i(and)515 3390 y(releasing)19 b(b)n(utton.\))p Black 639 3581 a Fc(\017)p Black 41 w Fo(Set)27 b(and)f(clear)h (breakpoints.)41 b(Use)27 b(the)g(right)f(mouseb)n(utton)e(menu)h(to)i (pop)f(up)g(a)h(menu)722 3680 y(where)18 b(you)e(can)i(select)h(set)f (read,)g(write,)g(read)f(v)n(alue)h(and)f(write)h(v)n(alue)f (breakpoints.)22 b(Y)-9 b(ou)722 3780 y(can)17 b(also)h("clear)f (breakpoints",)e(notice)h(the)i(s)g(in)f("clear)g(breakpoints",)e(e)n (v)o(ery)h(breakpoint)722 3880 y(on)k(the)g(re)o(gisters)g(are)g (cleared.)p Black 639 4046 a Fc(\017)p Black 41 w Fo(Set)31 b(and)f(clear)g(logging)f(of)h(re)o(gisters.)55 b(Y)-9 b(ou)29 b(can)h(log)g(reads,)j(writes,)g(reads/writes)d(of)722 4145 y(speci\002c)17 b(v)n(alues)g(and)f(to)h(bits)h(selected)e(by)h(a) g(speci\002ed)g(mask.)23 b(Y)-9 b(ou)17 b(can)f(select)i(a)f(dif)n (ferent)722 4245 y(\002le)j(name)f(with)g(')-5 b(set)20 b(log)f(\002lename...)-6 b('.)23 b(Def)o(ault)c(is)h("gpsim.log".)j(Y) -9 b(ou)18 b(can)h(choose)g(LXT)722 4344 y(or)h(ASCII)h(format.)j(LXT)c (can)g(be)g(read)f(with)i(the)f(program)e(gtkw)o(a)n(v)o(e.)24 b(ASCII)c(is)i(def)o(ault.)p Black 639 4511 a Fc(\017)p Black 41 w Fo(Cop)o(y)e(cells.)26 b(Y)-9 b(ou)19 b(cop)o(y)h(cells)h (by)e(dragging)f(the)j(border)d(of)i(the)g(selected)g(cell\(s\).)p Black 639 4677 a Fc(\017)p Black 41 w Fo(Fill)i(cells.)29 b(Mo)o(v)o(e)19 b(mouse)i(to)g(lo)n(wer)g(right)f(corner)g(of)h(the)g (frame)f(of)h(the)g(selected)g(cell\(s\),)722 4776 y(and)f(drag)f(it.) 26 b(The)20 b(one)f(cell')-5 b(s)21 b(contents)f(will)h(be)f(copied)f (to)h(the)h(other)e(cells.)p Black 639 4942 a Fc(\017)p Black 41 w Fo(W)-7 b(atch)21 b(them.)k(Select)20 b(the)g("Add)g(W)-7 b(atch")21 b(menu)e(item.)p Black Black eop end %%Page: 28 29 TeXDict begin 28 28 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.28) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(28)p Black 515 515 a(The)20 b(cells)h(ha)n(v)o(e)e (dif)n(ferent)g(background)d(colors)k(depending)e(on)h(if)i(the)o(y)e (represent:)p Black 639 702 a Fc(\017)p Black 41 w Fo(File)i(Re)o (gister)f(\(e.g.)25 b(RAM\):)20 b(light)g(c)o(yan.)p Black 639 866 a Fc(\017)p Black 41 w Fo(Special)g(Function)f(Re)o (gisters)i(\(e.g.)j(ST)-8 b(A)f(TUS,TMR0\):)25 b(dark)19 b(c)o(yan)p Black 639 1030 a Fc(\017)p Black 41 w Fo(aliased)27 b(re)o(gister)g(\(e.g.)44 b(the)27 b(INDF)g(located)f(at)i(address)e (0x80)g(is)i(the)e(same)i(as)f(the)g(one)722 1130 y(located)20 b(at)h(address)e(0x00\):)24 b(gray)p Black 639 1294 a Fc(\017)p Black 41 w Fo(in)m(v)n(alid)18 b(re)o(gister:)24 b(black.)g(If)19 b(all)g(sixteen)g(re)o(gisters)f(in)h(a)h(ro)n(w)e (are)h(in)m(v)n(alid,)f(then)g(the)h(ro)n(w)g(is)722 1394 y(not)h(sho)n(wn.)p Black 639 1558 a Fc(\017)p Black 41 w Fo(a)h(re)o(gister)e(with)i(one)e(or)h(more)g(breakpoints:)j(red.) h(Logged)19 b(re)o(gisters)h(are)g(also)g(red.)515 1745 y(gpsim)31 b(dynamically)e(updates)i(the)g(re)o(gisters)g(as)h(the)f (simulation)g(proceeds.)57 b(Re)o(gisters)31 b(that)515 1844 y(change)19 b(v)n(alue)h(between)g(updates)f(of)i(the)f(windo)n(w) g(during)f(simulation)g(are)i(highlighted)d(with)j(a)515 1944 y(blue)e(fore)o(ground)e(color)-5 b(.)515 2068 y(The)20 b(menu)f(also)h(has)h(a)f(')-5 b(settings')21 b(item)f(where)f(you)h (can)g(change)f(the)h(font)f(used.)515 2216 y SDict begin H.S end 515 2216 a 515 2216 a SDict begin 12 H.A end 515 2216 a 515 2216 a SDict begin [/View [/XYZ H.V]/Dest (section.3.4) cvn /DEST pdfmark end 515 2216 a 155 x Fk(3.4)119 b(Symbol)30 b(view)515 2581 y Fo(This)23 b(windo)n(w)-5 b(,)22 b(as)i(its)g(name)f(suggests,)g(displays)g(symbols.)33 b(All)24 b(of)f(the)g(special)g(function)f(re)o(g-)515 2680 y(isters)i(will)g(ha)n(v)o(e)f(entries)h(in)f(the)h(symbol)f(vie)n (wer)-5 b(.)34 b(If)24 b(you)e(are)i(using)f(.cod)g(\002les)h(then)f (you)g(will)515 2780 y(additionally)15 b(ha)n(v)o(e)h(\002le)i(re)o (gisters)e(\(that)g(are)h(de\002ned)f(in)h(cblocks\),)f(equates,)h(and) f(address)h(labels.)515 2904 y(Y)-9 b(ou)23 b(can)g(\002lter)i(out)e (some)g(symbol)g(types)h(using)f(the)h(b)n(uttons)f(in)h(the)g(top)f (of)g(the)h(windo)n(w)-5 b(,)23 b(and)515 3003 y(you)h(can)i(sort)f (the)h(ro)n(ws)g(by)f(clicking)f(on)i(the)f(column)f(b)n(uttons)h (\(the)h(ones)f(reading)f(')-5 b(symbol',)515 3103 y(')o(type')18 b(and)i('address'\).)515 3227 y(Y)-9 b(ou)19 b(can)i(add)e(the)i (symbol)e(to)h(the)h(w)o(atch)f(windo)n(w)f(by)h(right-clicking)e(and)i (selecting)g(the)g("Add)515 3326 y(to)h(w)o(atch)g(windo)n(w")f(menu)g (item.)28 b(This)22 b(will)g(add)e(the)h(ram)g(re)o(gister)g(with)g (address)g(equal)f(to)i(the)515 3426 y(symbols)d(v)n(alue)h(to)g(the)g (w)o(atch)h(windo)n(w)-5 b(.)515 3550 y(The)29 b(symbol)g(vie)n(wer)g (is)h(link)o(ed)f(to)h(the)f(other)g(windo)n(ws.)52 b(F)o(or)30 b(e)o(xample,)g(if)g(you)e(click)i(on)f(a)515 3649 y(symbol)19 b(and:)p Black 639 3836 a Fc(\017)p Black 41 w Fo(If)h(it)h(is)g(an)g (address,)e(then)h(the)g(opcode)e(and)i(source)g(vie)n(ws)g(display)f (the)i(address.)p Black 639 4000 a Fc(\017)p Black 41 w Fo(If)f(it')-5 b(s)22 b(a)e(re)o(gister)m(,)f(the)h(re)o(gister)g (vie)n(wer)f(selects)j(the)e(cell.)515 4148 y SDict begin H.S end 515 4148 a 515 4148 a SDict begin 12 H.A end 515 4148 a 515 4148 a SDict begin [/View [/XYZ H.V]/Dest (section.3.5) cvn /DEST pdfmark end 515 4148 a 155 x Fk(3.5)119 b(W)-8 b(atch)30 b(view)515 4513 y Fo(This)21 b(is)h(not)f(a)g (output-only)d(windo)n(w)i(as)i(the)f(name)f(suggests)h(\(change)f (name?\).)26 b(Y)-9 b(ou)21 b(can)f(both)515 4613 y(vie)n(w)29 b(and)h(change)e(data.)54 b(Double-clicking)27 b(on)i(a)h(bit)g (toggles)f(the)h(bit.)54 b(Y)-9 b(ou)29 b(add)g(v)n(ariables)515 4712 y(here)e(by)g(marking)e(them)i(in)h(a)f(re)o(gister)g(vie)n(wer)g (and)g(select)h(\223)-7 b(Add)27 b(w)o(atch\224)g(from)f(menu.)46 b(The)515 4812 y(right-click)18 b(menu)i(has)g(the)g(follo)n(wing)f (items:)p Black 639 4998 a Fc(\017)p Black 41 w Fo(Remo)o(v)o(e)g(w)o (atch)p Black Black eop end %%Page: 29 30 TeXDict begin 29 29 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.29) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(29)p Black Black 639 515 a Fc(\017)p Black 41 w Fo(Set)21 b(re)o(gister)f(v)n(alue)p Black 639 681 a Fc(\017)p Black 41 w Fo(Clear)h(Breakpoints)p Black 639 847 a Fc(\017)p Black 41 w Fo(Set)g(break)e(on)h(read)p Black 639 1013 a Fc(\017)p Black 41 w Fo(Set)h(break)e(on)h(write)p Black 639 1179 a Fc(\017)p Black 41 w Fo(Set)h(break)e(on)h(read)g(v)n (alue)p Black 639 1346 a Fc(\017)p Black 41 w Fo(Set)h(break)e(on)h (write)g(v)n(alue)p Black 639 1512 a Fc(\017)p Black 41 w Fo(Columns...)515 1703 y("Columns...)-6 b(\224)30 b(opens)21 b(up)h(a)h(windo)n(w)e(where)h(you)f(can)i(select)f(which)g (of)g(the)h(follo)n(wing)d(data)i(to)515 1802 y(display:)p Black 639 1993 a Fc(\017)p Black 41 w Fo(BP)p Black 639 2159 a Fc(\017)p Black 41 w Fo(T)-7 b(ype)p Black 639 2325 a Fc(\017)p Black 41 w Fo(Name)p Black 639 2491 a Fc(\017)p Black 41 w Fo(Address)p Black 639 2657 a Fc(\017)p Black 41 w Fo(Dec)p Black 639 2823 a Fc(\017)p Black 41 w Fo(He)o(x)p Black 639 2989 a Fc(\017)p Black 41 w Fo(Bx)21 b(\(bits)f(of)g(w)o(ord\))515 3180 y(Y)-9 b(ou)17 b(can)g(sort)h(the)g(list)h(of)e(w)o(atches)h(by)g(clicking)f (on)g(the)h(column)e(b)n(uttons.)24 b(Clicking)17 b(twice)h(sorts)515 3280 y(the)i(list)h(backw)o(ards.)515 3412 y SDict begin H.S end 515 3412 a 515 3412 a SDict begin 12 H.A end 515 3412 a 515 3412 a SDict begin [/View [/XYZ H.V]/Dest (section.3.6) cvn /DEST pdfmark end 515 3412 a 173 x Fk(3.6)119 b(Stack)30 b(viewer)515 3795 y Fo(This)24 b(windo)n(w)e(displays)i (current)e(stack.)36 b(Selecting)23 b(an)g(entry)g(mak)o(es)h(the)g (code)f(windo)n(ws)f(dis-)515 3895 y(play)d(the)i(return)e(address.)24 b(Double)19 b(clicking)h(sets)h(a)f(breakpoint)e(on)i(the)g(return)f (address.)515 4044 y SDict begin H.S end 515 4044 a 515 4044 a SDict begin 12 H.A end 515 4044 a 515 4044 a SDict begin [/View [/XYZ H.V]/Dest (section.3.7) cvn /DEST pdfmark end 515 4044 a 156 x Fk(3.7)119 b(Br)n(eadboard)515 4411 y Fo(Here)29 b(you)g(can)g(create/modify)f(and)h(e)o(xamine)f(the) h(en)m(vironment)e(around)h(the)h(pic.)53 b(Pins)31 b(are)515 4510 y(displayed)18 b(as)i(an)f(arro)n(w)-5 b(.)23 b(The)c(direction)f (of)h(the)h(arro)n(w)e(indicates)h(if)h(its)g(an)f(input)g(or)g(output) f(pin.)515 4610 y(The)i(color)f(of)h(the)g(arro)n(w)f(indicates)h(its)h (state)g(\(green=lo)n(w)-5 b(,)18 b(red=high\).)515 4734 y(Y)-9 b(ou)21 b(can')o(t)g(instantiate)g(pic)h(processors)f(from)f (here,)i(you)e(will)j(ha)n(v)o(e)e(to)h(do)f(that)h(from)f(the)g(com-) 515 4834 y(mand)e(line,)h(or)g(from)f(a)i(.stc)f(\002le.)p Black Black eop end %%Page: 30 31 TeXDict begin 30 30 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.30) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(30)p Black 515 515 a(Y)-9 b(our)25 b(can)i(create)f(nodes)g(by)g(clicking)f(on)h(the)h("ne)n(w)f(node")f (b)n(utton.)43 b(\(A)27 b(node)f(is)h('a)g(piece)f(of)515 615 y(wire')21 b(to)h(which)g(you)f(can)g(connect)g(stimulus.\))29 b(Y)-9 b(ou)21 b(can)h(see)g(the)g(list)h(of)f(created)f(nodes)g(under) 515 715 y(the)f("nodes")f(item)h(in)h(the)f(upper)n(-left)e(tree)j (widget.)515 839 y(Y)-9 b(ou)28 b(can)i(create)f(connections)e(to)i (nodes)g(by)g(clicking)f(on)h(a)h(pin,)h(and)e(then)f(clicking)h(on)g (the)515 939 y(b)n(utton)22 b("Connect)g(stimulus)h(to)g(node".)31 b(This)23 b(will)h(bring)e(up)g(a)h(list)h(of)f(nodes.)32 b(Choose)23 b(one)f(by)515 1038 y(double-clicking)17 b(on)i(the)i(one)e(you)h(lik)o(e.)515 1163 y(If)e(you)g(click)h(on)f(a) h(pin)g(that)g(is)g(already)f(connected)f(to)i(a)g(node,)f(then)g(you)g (will)h(see)h(the)e(node)g(and)515 1262 y(its)k(connections)e(in)i(the) f(lo)n(wer)g(left)h(part)f(of)h(the)f(windo)n(w)-5 b(.)28 b(Y)-9 b(ou)21 b(can)g(disconnect)f(a)i(stimulus)g(by)515 1362 y(clicking)d(on)h(it)h(and)e(pressing)h(the)g("remo)o(v)o(e)e (stimulus")i(b)n(utton.)515 1487 y(When)g(you)g(w)o(ant)h(to)f(add)g(a) h(module)f(to)g(the)h(simulation,)e(you)h(\002rst)h(ha)n(v)o(e)f(to)h (specify)f(the)h(library)515 1586 y(which)32 b(contains)f(the)i(module) e(you)g(w)o(ant.)62 b(Click)33 b(on)f(the)h("add)e(library")h(b)n (utton)f(and)h(enter)515 1686 y(the)23 b(library)g(name)g(\(e.g.)35 b("libgpsim_modules.so"\).)d(No)n(w)23 b(you)g(can)h(click)f(the)h ("add)f(module")515 1786 y(b)n(utton.)50 b(Select)30 b(the)f(module)e(you)h(w)o(ant)i(from)e(the)h(list)h(by)e (double-clicking)e(on)j(it.)52 b(Enter)28 b(a)515 1885 y(name)e(for)g(the)h(module)e(\(this)i(has)g(to)g(be)g(unique,)g(and)f (not)g(used)h(before\).)43 b(Y)-9 b(ou)26 b(no)n(w)g(ha)n(v)o(e)g(to) 515 1985 y(position)17 b(the)h(module.)23 b(Mo)o(v)o(e)17 b(the)h(mouse)f(pointer)g(to)h(where)f(you)h(w)o(ould)f(lik)o(e)h(the)g (module,)f(and)515 2084 y(left-click.)515 2209 y(If)25 b(you)f(middle-click)f(on)i(a)g(pin,)h(you)e(will)i(see)f(ho)n(w)g(the) g(pin)f(is)i(connected.)38 b(Press)26 b(the)f("trace)515 2309 y(all")20 b(to)h(see)g(all)f(at)515 2433 y(once,)26 b(and)g("clear)g(traces")g(to)g(remo)o(v)o(e)e(all)j(\(you)e(will)i (only)e(remo)o(v)o(e)f(the)i(graphical)f(trace,)i(not)515 2533 y(the)19 b(connection!\).)j(If)d(the)h(tracing)e(doesn')o(t)g(w)o (ork,)h(try)g(mo)o(ving)f(the)h(packages)f(so)i(that)g(there)f(are)515 2632 y(more)g(space)h(around)f(the)h(pins.)515 2757 y(When)f(you)g(are) g(done,)f(you)h(can)g(sa)n(v)o(e)h(by)f(clicking)f(the)i("sa)n(v)o(e)f (con\002guration")e(b)n(utton.)24 b(Y)-9 b(ou)19 b(can)515 2857 y(then)26 b(load)g(this)h(\002le)g(from)e(the)h(command)f(line)h (lik)o(e)h(this)g(\(assuming)e(the)i(.cod)e(\002le)i(with)g(your)515 2956 y(source)19 b(is)i(called)f("mycode.cod",)d(and)j(the)g(\002le)h (you)e(just)i(sa)n(v)o(ed)f(w)o(as)h(called)f("mynets.stc":)p Black Black 722 3164 a Fi(gpsim)42 b(-s)g(mycode.cod)e(-c)j(mynets.stc) 515 3371 y Fo(Y)-9 b(ou)20 b(can')o(t)f(load)h(only)g(the)h(.stc)g (\002le)g(since)g(this)g(doesn')o(t)e(contain)h(the)g(processor)f(type) h(and)g(code.)515 3471 y(Y)-9 b(ou)21 b(can)h(create)g(\(with)g(an)g (editor\))f(your)g(o)n(wn)g(.stc)i(\002le)g(\(e.g.)30 b(my_project.stc\))19 b(and)i(in)i(that)f(\002le)515 3571 y(put)f(a)i(command)d("load)i(c)g(mynets.stc")f(after)h(you)f(ha)n (v)o(e)h(loaded)f(the)h(.cod)f(\002le.)31 b(Y)-9 b(ou)22 b(then)f(only)515 3670 y(ha)n(v)o(e)e(to)i(load)e(this)i(\002le)g (\(gpsim)e(-c)i(my_project.stc\).)515 3819 y SDict begin H.S end 515 3819 a 515 3819 a SDict begin 12 H.A end 515 3819 a 515 3819 a SDict begin [/View [/XYZ H.V]/Dest (section.3.8) cvn /DEST pdfmark end 515 3819 a 156 x Fk(3.8)119 b(T)-9 b(race)30 b(viewer)515 4186 y Fo(This)20 b(windo)n(w)f(sho)n(ws) i(the)f(trace)g(of)g(instructions)f(e)o(x)o(ecuted.)k(See)2478 4187 y SDict begin H.S end 2478 4187 a Black -1 x Fo(6)p Black 2519 4129 a SDict begin H.R end 2519 4129 a 2519 4186 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (chapter.6) cvn H.B /ANN pdfmark end 2519 4186 a Fo(.)515 4317 y SDict begin H.S end 515 4317 a 515 4317 a SDict begin 12 H.A end 515 4317 a 515 4317 a SDict begin [/View [/XYZ H.V]/Dest (section.3.9) cvn /DEST pdfmark end 515 4317 a 174 x Fk(3.9)119 b(Pr)n(o\002le)30 b(viewer)515 4701 y Fo(This)24 b(windo)n(w)f(sho)n(w)g(e)o(x)o(ecution)f(count)h(for)g (program)f(memory)g(addresses.)36 b(The)24 b(pro\002le)f(win-)515 4801 y(do)n(w)g(must)g(be)h(opened)e(before)g(starting)h(simulation,)g (because)g(the)g(tracing)g(is)i(not)e(enabled)f(by)515 4901 y(def)o(ault.)p Black Black eop end %%Page: 31 32 TeXDict begin 31 31 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.31) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(31)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 12 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.20) cvn /DEST pdfmark end 515 515 a Fp(Instruction)20 b(pr)o(o\002le)515 696 y Fo(This)g(sho)n(ws)g(the)h(number)d(of)i (times)h(each)e(instruction)g(are)h(e)o(x)o(ecuted.)515 942 y SDict begin H.S end 515 942 a 515 942 a SDict begin 12 H.A end 515 942 a 515 942 a SDict begin [/View [/XYZ H.V]/Dest (section*.21) cvn /DEST pdfmark end 515 942 a Fp(Instruction)g(range)g(pr)o(o\002le)515 1122 y Fo(Here)g(you)f(can) h(group)f(ranges)g(of)h(instruction)f(into)h(one)f(entry)-5 b(.)515 1247 y(The)20 b(right)f(click)h(menu)g(contains:)p Black 515 1438 a(Remo)o(v)o(e)f(range)p Black 183 w(Remo)o(v)o(e)g(an)h (entry)-5 b(.)p Black 515 1604 a(Add)19 b(range...)p Black 252 w(Open)24 b(a)h(dialog)f(from)g(where)g(you)g(can)h(add)f(a)i (range)d(of)i(instructions)f(as)1179 1704 y(an)c(entry)-5 b(.)p Black 515 1870 a(Add)19 b(all)i(labels)p Black 203 w(Add)f(all)g(code)g(labels)g(as)h(ranges.)p Black 515 2036 a(Snapshot)e(to)h(plot)p Black 124 w(Open)30 b(a)i(windo)n(w)e(containing)f(a)j(graph)e(of)h(the)g(data.)57 b(From)31 b(this)h(ne)n(w)1179 2135 y(windo)n(w)19 b(you)g(can)h(also)h (sa)n(v)o(e)f(\(postscript\))f(or)h(print)g(it.)515 2381 y SDict begin H.S end 515 2381 a 515 2381 a SDict begin 12 H.A end 515 2381 a 515 2381 a SDict begin [/View [/XYZ H.V]/Dest (section*.22) cvn /DEST pdfmark end 515 2381 a Fp(Register)g(pr)o(o\002le)515 2562 y Fo(This)g(sho)n(ws)g(the)h (number)d(of)i(reads)g(or)g(writes)g(the)h(simulator)e(does)h(on)g(re)o (gister)-5 b(.)515 2808 y SDict begin H.S end 515 2808 a 515 2808 a SDict begin 12 H.A end 515 2808 a 515 2808 a SDict begin [/View [/XYZ H.V]/Dest (section*.23) cvn /DEST pdfmark end 515 2808 a Fp(Routine)20 b(pr)o(o\002le)515 2988 y Fo(Here)k(you)f(can)g(see)i(statistics)g(about)e(e)o(x)o (ecution)f(time)i(for)g(a)g(selected)g(routine.)35 b(Y)-9 b(ou)23 b(mark)h(the)515 3088 y(entry)j(and)g(e)o(xit)h(points)f(from)g (the)h(source)f(bro)n(wser)f(\(pro\002le)h(start/stop\).)47 b(If)28 b(the)g(routine)e(you)515 3188 y(w)o(ant)c(to)g(measure)f(ha)n (v)o(e)h(multiple)f(entry)g(and/or)g(e)o(xit)h(points,)f(then)h(you)f (ha)n(v)o(e)g(to)i(put)e(a)i(mark)o(er)515 3287 y(on)i(e)n(v)o(ery)f (entry)g(point)h(as)h(well)g(as)g(\(and)f(especially\))g(e)n(v)o(ery)f (e)o(xit)h(point.)40 b(Otherwise)25 b(you)g(will)515 3387 y(get)20 b(bad)g(data.)515 3511 y(When)f(you)f(ha)n(v)o(e)g(done)g (that,)i(gpsim)e(will)i(\(as)g(simulation)e(goes)h(by\))f(store)h(the)g (e)o(x)o(ecution)e(times)515 3611 y(of)29 b(that)g(routine)f(and)g (calculate)h(min/max/a)n(v)o(erage/etc.)49 b(Y)-9 b(ou)28 b(can)h(also)h(use)f(the)g(menu)f(item)515 3711 y('Plot)19 b(distrib)n(ution')f(to)i(open)e(a)i(windo)n(w)e(displaying)g(a)i (histogram)e(of)h(the)g(data.)25 b(From)19 b(this)h(ne)n(w)515 3810 y(windo)n(w)f(you)g(can)h(also)h(sa)n(v)o(e)f(\(in)g(postscript\)) f(or)h(print)g(it.)515 3935 y(Y)-9 b(ou)28 b(can)g(also)h(measure)e (call)i(period)e(by)i(switching)e(the)i('entry')e(and)h('e)o(xit')g (points.)49 b(If)28 b(also)515 4034 y(w)o(ant)23 b(the)g(time)h(from)e (reset)i(\(or)e(some)h(equal)g(point\))f(to)h(the)h(\002rst)g('entry',) e(then)h(you)f(must)h(also)515 4134 y(put)d(an)g('entry')e(point)i (there.)515 4283 y SDict begin H.S end 515 4283 a 515 4283 a SDict begin 12 H.A end 515 4283 a 515 4283 a SDict begin [/View [/XYZ H.V]/Dest (section.3.10) cvn /DEST pdfmark end 515 4283 a 156 x Fk(3.10)119 b(Stopwatch)515 4650 y Fo(The)30 b(stopw)o(atch)g(windo)n(w)f(sho)n(ws)i(a)g(c)o(ycle)f (counter)f(and)g(a)i(re-settable)f(counter)-5 b(.)55 b(The)30 b(c)o(ycle)515 4749 y(counter)18 b(is)k(the)e(same)g(as)h(the) f(one)g(in)g(the)g(re)o(gister)g(windo)n(w)-5 b(.)23 b(It)e(basically)f(counts)f(instructions.)515 4874 y(The)24 b(other)h(counter)e(counts)i(at)g(the)g(same)g(rate)g(as)h(the)f(c)o (ycle)g(counter)m(,)f(b)n(ut)h(can)g(be)g(cleared)f(by)515 4973 y(clicking)19 b(the)h("clear")g(b)n(utton)f(\(or)h(preset)g(by)g (entering)e(a)j(number)d(in)j(the)f(entry)f(box\).)p Black Black eop end %%Page: 32 33 TeXDict begin 32 32 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.32) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(3.)45 b(GRAPHICAL)21 b(USER)g(INTERF)-6 b(A)m(CE)1097 b Fo(32)p Black 515 515 a(The)20 b(up/do)n(wn)e (indicator)h(denotes)g(the)h(direction)f(the)h(counter)f(counts.)515 640 y(The)j(rollo)o(v)o(er)f(v)n(alue)h(speci\002es)h(the)g(range)f (the)h(c)o(ycle)f(counter)f(can)i(be)g(in)g(\(a)g(modulo)e(counter\).) 515 739 y(F)o(or)f(e)o(xample,)f(if)i(the)g(rollo)o(v)o(er)d(v)n(alue)i (is)i(speci\002ed)e(to)h(be)f(0x42,)f(then)i(whene)n(v)o(er)d(the)j (resettable)515 839 y(counter)27 b(reaches)i(0x42)e(it)j(will)g(rollo)o (v)o(er)d(to)i(zero.)51 b(If)28 b(the)i(counter)d(is)j(counting)d(do)n (wn,)j(then)515 939 y(when)19 b(it)h(reaches)f(0)h(the)f(ne)o(xt)g (state)h(will)h(be)e(0x41.)k(If)d(you)e(don')o(t)g(w)o(ant)i(is)g(lik)o (e)g(this,)g(then)f(set)i(the)515 1038 y(rollo)o(v)o(er)d(v)n(alue)h (to)i(something)d(lar)o(ge.)515 1187 y SDict begin H.S end 515 1187 a 515 1187 a SDict begin 12 H.A end 515 1187 a 515 1187 a SDict begin [/View [/XYZ H.V]/Dest (section.3.11) cvn /DEST pdfmark end 515 1187 a 156 x Fk(3.11)119 b(Scope)30 b(W)n(indo)o(w)515 1554 y Fo(FIXME:)20 b(The)g(scope)f (windo)n(w)h(still)h(needs)f(some)g(w)o(ork...)515 1678 y(The)31 b(Scope)h(W)m(indo)n(w)f(graphs)g(I/O)h(pin)f(states.)61 b(It)33 b(is)f(similar)g(to)h(an)e(oscilloscope)g(or)h(logic)515 1778 y(analyzer)-5 b(.)23 b(It)18 b(can)g(be)f(controlled)f(either)i (from)f(the)g(command)f(line)i(or)g(from)e(the)i(GUI.)g(Currently)515 1878 y(only)h(the)h(digital)g(state)h(of)f(I/O)h(pins)f(are)g (supported.)515 2002 y(T)-7 b(o)19 b(use)g(the)f(scope)h(windo)n(w)-5 b(,)17 b(each)h(scope)g(channel)g(being)g(used)g(must)h(\002rst)g(be)g (connected)e(to)i(the)515 2102 y(stimulus)25 b(being)g(track)o(ed.)40 b(This)26 b(can)f(only)g(be)g(done)f(on)i(the)f(command)f(line)h(\(or)g (via)h(the)f(.sim)515 2201 y(directi)n(v)o(e)17 b(in)i(the)g(.asm)g (\002le\).)25 b(The)18 b(follo)n(wing)f(e)o(xample)h(sho)n(ws)g(ho)n(w) h(this)g(is)h(done,)d(b)n(ut)i(note)f(that)515 2301 y(in)i(the)g(.sim)h (command)d(the)i('\224')-5 b(s)21 b(need)e(to)i(be)f(escaped)f(with)i (a)f('\\'.)p Black Black 722 2509 a Fi(**gpsim>)40 b(scope.ch0)g(=)j (\020portc3\021)722 2608 y(**gpsim>)d(scope.ch1)g(=)j(\020portc4\021) 515 2816 y Fo(Once)20 b(the)h(data)g(are)g(captured,)f(the)h(scope)f (windo)n(w)g(display)h(may)f(need)g(to)h(be)g(altered)g(to)g(better)515 2915 y(see)g(the)f(data.)25 b(In)19 b(the)i(GUI,)f(the)g(follo)n(wing)e (k)o(e)o(ys)i(can)g(be)g(used:)p Black 515 3106 a(z)p Black 378 w(Zoom)f(In)p Black 515 3272 a(Z)p Black 364 w(Zoom)g(out)p Black 515 3439 a(l)p Black 392 w(P)o(an)h(left)p Black 515 3605 a(r)p Black 387 w(P)o(an)g(right)515 3795 y(In)15 b(the)g(command)e(line,)j(zooming)e(and)g(panning)f(can)i(be)h (achie)n(v)o(ed)d(by)i(modifying)e(the)i(scope.start)515 3895 y(and)k(scope.end)g(v)n(ariables.)p Black Black eop end %%Page: 33 34 TeXDict begin 33 33 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.33) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.4) cvn /DEST pdfmark end 515 432 a 729 x Fl(Chapter)44 b(4)515 1600 y Fq(Scripting)51 b(and)h(Con\002guring)515 2055 y Fo(gpsim)19 b(does)h(not)g(ha)n(v)o(e) f(a)i(nati)n(v)o(e)e(scripting)g(language)f(per)i(se.)26 b(Ho)n(we)n(v)o(er)18 b(it)j(is)g(possible)f(to)g(place)515 2155 y(gpsim)d(commands)f(into)i(a)g(\002le)h(and)e(load)h(them)f (later)-5 b(.)25 b(This)18 b(is)h(useful)e(for)h(loading)e(modules)h (and)515 2255 y(stimuli)j(and)f(connecting)f(v)n(arious)g(de)n(vices)i (together)-5 b(.)24 b(By)c(con)m(v)o(ention,)d(gpsim')-5 b(s)19 b(con\002guration)515 2354 y(\002les)i(ha)n(v)o(e)e(the)i(e)o (xtension)d Fh(.stc)p Fo(,)j(for)e Fh(st)q Fo(artup)i Fh(c)p Fo(on\002guration.)515 2502 y SDict begin H.S end 515 2502 a 515 2502 a SDict begin 12 H.A end 515 2502 a 515 2502 a SDict begin [/View [/XYZ H.V]/Dest (section.4.1) cvn /DEST pdfmark end 515 2502 a 155 x Fk(4.1)119 b(Embedded)31 b(Commands)515 2866 y Fo(If)26 b(you')l(re)e(using)i(gputils,)i(it)f (is)g(possible)f(to)h(embed)e(con\002guration)f(commands)g(directly)i (into)515 2965 y(your)e(PIC)h(assembly)g(source.)39 b(The)25 b(gputils)f(supplied)g(include)g(\002le)i Fh(cof)o(f)o(.inc)e Fo(contains)g(se)n(v)o(eral)515 3065 y(macros)19 b(that)i(embed)e (simulation)g(command)f(into)i(a)h(COFF)g(and)f(COD)h(\002les.)515 3186 y SDict begin H.S end 515 3186 a 515 3186 a SDict begin 12 H.A end 515 3186 a 515 3186 a SDict begin [/View [/XYZ H.V]/Dest (subsection.4.1.1) cvn /DEST pdfmark end 515 3186 a 139 x Fj(4.1.1)99 b(.sim)24 b(macr)n(o)p Black Black 722 3481 a Fi(;)43 b(Simulator)d(Command)722 3580 y(.sim)i(macro)g(x)809 3680 y(.direct)f("e",)h(x)809 3779 y(endm)515 3979 y Fo(The)15 b Fe(.sim)28 b Fi(macro)42 b(allows)f(gpsim)g(configuration)d(commands)i(to)j(be)g(embedded)d(in) 515 4078 y(the)i(PIC)g(source.)85 b(While)41 b(gpsim)g(loads)h(a)h (.cod)f(file,)f(the)i(commands)d(in)j(the)515 4178 y Fe(.sim)28 b Fi(macros)41 b(are)i(collected.)82 b(After)42 b(the)g(.cod)g(file)g(is)h(loaded,)d(the)j(commands)515 4278 y(are)f(redirected)d(to)k(gpsim's)e(command)f(line)i(interpreter)d (in)k(the)f(order)g(they)515 4377 y(were)g(received.)515 4500 y Fo(Here')-5 b(s)20 b(an)g(e)o(xample)f(of)h(switch)h(module)d (being)i(loaded)f(and)g(con\002gured:)p Black Black 766 4700 a Fi(;#)43 b(Module)e(libraries:)766 4799 y(.sim)h("module)e (library)h(libgpsim_modules)o(")766 4899 y(.sim)h("module)e(load)i (switch)f(SW1")766 4998 y(.sim)h("SW1.state=fals)o(e")p Black 1905 5208 a Fo(33)p Black eop end %%Page: 34 35 TeXDict begin 34 34 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.34) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(4.)45 b(SCRIPTING)21 b(AND)g(CONFIGURING)1051 b Fo(34)p Black 766 515 a Fi(.sim)42 b("SW1.xpos)e(=)j(216.0")766 615 y(.sim)f("SW1.ypos)e(=)j(156.0")766 715 y(.sim)f("SW1.Ropen)d(=)k (1.0e8")515 922 y Fo(This)29 b(loads)g(gpsim')-5 b(s)30 b(module)d(library)-5 b(,)30 b(instantiates)g(a)f(switch)h(module,)g (and)f(con\002gures)f(the)515 1022 y(switch')-5 b(s)21 b(attrib)n(utes.)515 1144 y SDict begin H.S end 515 1144 a 515 1144 a SDict begin 12 H.A end 515 1144 a 515 1144 a SDict begin [/View [/XYZ H.V]/Dest (subsection.4.1.2) cvn /DEST pdfmark end 515 1144 a 140 x Fj(4.1.2)99 b(.command)25 b(macr)n(o)p Black Black 722 1440 a Fi(.command)40 b(macro)i(x)809 1540 y(.direct)f("c",)h(x)809 1639 y(endm)515 1847 y Fo(The)15 b Fe(.command)26 b Fi(macro)42 b(is)h(similar)d(to)j(a)15 b Fe(.sim)29 b Fi(macro)41 b(except)g(that)h(it)h(associates)515 1946 y(a)g(gpsim)e(command)g(with)h(a)h(particular)c(instruction.)82 b(This)42 b(is)h(useful)e(for)515 2046 y(changing)f(attribute)g(values) h(at)h(different)e(points)h(of)i(the)f(program.)515 2186 y SDict begin H.S end 515 2186 a 515 2186 a SDict begin 12 H.A end 515 2186 a 515 2186 a SDict begin [/View [/XYZ H.V]/Dest (subsection.4.1.3) cvn /DEST pdfmark end 515 2186 a 123 x Fj(4.1.3)99 b(.assert)24 b(macr)n(o)p Black Black 722 2464 a Fi(;)43 b(Assertion)722 2564 y(.assert)e(macro)g(x)766 2663 y(.direct)f("a",)i(x)766 2763 y(endm)515 2971 y Fo(The)16 b Fh(.assert)j Fo(macro)d(pro)o(vides)g(a)h(source)f(code)h (mechanism)e(for)i(setting)g(breakpoints)d(\(see)k(chap-)515 3070 y(ter)620 3071 y SDict begin H.S end 620 3071 a Black -1 x Fo(5)p Black 662 3014 a SDict begin H.R end 662 3014 a 662 3070 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (chapter.5) cvn H.B /ANN pdfmark end 662 3070 a Fo(\).)24 b(An)17 b(assertion)g(is)h(an)g(e)o(xpression)d(associated)i(with)h(a)g (speci\002c)f(instruction.)23 b(It)17 b(essentially)515 3170 y(means,)g(\223If)g(the)g(e)o(xpression)f(at)h(this)h(instruction) e(e)n(v)n(aluates)g(to)i(f)o(alse,)g(then)e(halt)h(the)h(simulation.)-6 b(\224)p Black Black 722 3477 a Fi(;)43 b(Close)f(the)g(switch.)f (Because)f(of)j(capacitance,)c(portc1)i(will)h(go)g(high)g(after)g(a)h (delay:)853 3577 y(;)g(R=145,)e(C=4.2e-6)f(TC=6.11e-4)g(or)i(1527)g (cycles,)f(0-2)h(volts)g(requires)e(0.51)i(Tc)853 3676 y(.command)e("SW1.state=close)o(d")1071 3776 y(nop)1071 3876 y(;)j(portc0)e(should)g(be)i(same)f(as)g(portc1)853 3975 y(.assert)f("\(portc)f(&)j(3\))g(==)g(0,)g(\\"SW1)e(closed,)g(cap) h(holds)f(low\\"")1071 4075 y(nop)515 4282 y Fo(In)18 b(this)g(e)o(xample,)f(the)h Fh(.command)h Fo(macro)e(writes)h(to)h (the)f(switch)g(module')-5 b(s)17 b Fh(.state)i Fo(attrib)n(ute)e (\(see)515 4382 y(section)767 4383 y SDict begin H.S end 767 4383 a Black -1 x Fo(8.1.4)p Black 933 4326 a SDict begin H.R end 933 4326 a 933 4382 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (subsection.8.1.4) cvn H.B /ANN pdfmark end 933 4382 a Fo(\).)24 b(Just)18 b(prior)d(to)i(e)o(x)o(ecuting)e(the)h (\002rst)i(nop)e(instruction,)f(the)i(switch)g(will)h(be)e(closed.)515 4482 y(The)h Fh(.assert)j Fo(macro)e(at)g(the)g(v)o(ery)f(ne)o(xt)g (instruction)g(mak)o(es)h(sure)f(that)i(the)e(e)o(xpected)g(state)i(is) f(seen)515 4581 y(on)i(POR)-5 b(TC.)p Black Black eop end %%Page: 35 36 TeXDict begin 35 35 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.35) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(4.)45 b(SCRIPTING)21 b(AND)g(CONFIGURING)1051 b Fo(35)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.4.2) cvn /DEST pdfmark end 515 432 a 83 x Fk(4.2)119 b(Sock)o(ets)515 726 y Fo(gpsim)25 b(supports)f(a)i(sock)o(et)f(interf)o(ace.)39 b(This)26 b(is)g(inhibited)e(by)h(def)o(ault.)40 b(Adv)n(anced)24 b(users)h(may)515 825 y(wish)h(to)h(study)e(code)h(in)g(the)h Fh(e)n(xamples/scripts)f Fo(subdirectory)-5 b(.)40 b(This)27 b(code)e(is)j(not)d(distrib)n(uted)515 925 y(and)19 b(is)j(only)d(a)n (v)n(ailable)h(in)g(the)g(sub)o(v)o(ersion)e(repository)-5 b(.)p Black Black eop end %%Page: 36 37 TeXDict begin 36 36 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.36) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.5) cvn /DEST pdfmark end 515 432 a 723 x Fl(Chapter)44 b(5)515 1587 y Fq(Assertions)52 b(and)g(Extended)515 1836 y(Br)l(eakpoints)515 2285 y Fo(gpsim)23 b(supports)g(a)h(wide)g(v)n(ariety)f(of)g(breakpoints)f (and)h(assertions.)36 b(Man)o(y)23 b(of)g(these)h(were)g(de-)515 2384 y(scribed)f(with)h(the)g(break)e(command.)34 b(This)24 b(section)g(will)g(illustrate)g(ho)n(w)f(to)h(e)o(xtend)f(the)h(break) 515 2484 y(command)18 b(e)n(v)o(en)h(further)g(and)g(introduce)g (simulation)g(assertions.)515 2732 y SDict begin H.S end 515 2732 a 515 2732 a SDict begin 14 H.A end 515 2732 a 515 2732 a SDict begin [/View [/XYZ H.V]/Dest (section*.24) cvn /DEST pdfmark end 515 2732 a Fj(Br)n(eakpoint)26 b(Messages)515 2904 y Fo(A)i(breakpoint)d(message)i(is)h(an)g(ASCII)f (string)g(that)h(is)g(displayed)e(whene)n(v)o(er)g(a)i(breakpoint)d(is) 515 3004 y(encountered.)56 b(An)o(y)31 b(break)g(point)g(can)h(ha)n(v)o (e)f(an)g(associated)h(message.)59 b(The)31 b(syntax)g(at)i(the)515 3103 y(command)18 b(line)i(is)p Black Black 722 3264 a Fi(break)42 b(conditions,)d(\020)p Fe(This)i(is)i(a)g(breakpoint)c (message)12 b Fi(\021)515 3424 y Fo(The)17 b(conditions)f(are)i (described)f(abo)o(v)o(e)f(in)i(the)f(break)g(command)f(and)h(are)h (the)g(conditions)e(under)515 3523 y(which)j(the)i(break)e(occurs.)515 3640 y(Breakpoint)f(messages)j(are)f(useful)g(for)f(distinguishing)f (among)h(man)o(y)g(dif)n(ferent)g(breakpoints.)p Black Black 722 3800 a Fi(break)42 b(w)h(counter)e(&)i(0xf0)f(==)g(0x80,)g (\020Counter)e(overflowed!\021)515 3960 y Fo(In)28 b(this)h(e)o (xample,)g(the)f(user)g(is)i(monitoring)c(the)i(upper)f(nibble)g(of)h (the)h(v)n(ariable)e(counter)g(and)515 4059 y(breaking)18 b(whene)n(v)o(er)g(it)j(is)g(equal)f(to)g(8.)25 b(When)20 b(the)g(command)f(is)i(entered,)d(gpsim)i(will)h(display:)p Black Black 722 4319 a Fi(break)42 b(when)g(bit)g(pattern)f(1000XXXX)f (is)i(written)f(to)i(register)d(counter\(0x26\).)e(break)j(#:)i(0x20) 515 4479 y Fo(The)20 b(breakpoint)d(can)j(be)h(queried)d(with)j(the)f (break)f(command:)p Black Black 722 4639 a Fi(gpsim>)41 b Fe(break)h(32)722 4739 y Fi(32:)h(p18f452)d(register)g(write)i (value:)f([0x26])g(&)i(0xf0)f(==)h(0x8)897 4838 y(Message:Counter)37 b(overflowed!)515 4998 y Fo(When)20 b(the)g(simulation)f(encounters)g (the)h(break,)f(e)o(x)o(ecution)f(halts)i(and)g(the)g(message)g(is)h (printed.)p Black 1905 5208 a(36)p Black eop end %%Page: 37 38 TeXDict begin 37 37 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.37) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(5.)45 b(ASSER)-5 b(TIONS)21 b(AND)g(EXTENDED)e (BREAKPOINTS)519 b Fo(37)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.5.1) cvn /DEST pdfmark end 515 432 a 83 x Fk(5.1)119 b(Assertions)29 b(and)h(Embedded)i(Simulation)f(commands)515 726 y Fo(gpsim')-5 b(s)26 b(breakpoint)d(design)i(is)i(a)g(po)n(werful) d(tool)i(that)g(can)f(catch)h(man)o(y)f(problems.)41 b(The)25 b(as-)515 825 y(sertion)20 b(design)g(e)o(xtends)f(this)i(po)n (wer)f(e)n(v)o(en)f(further)-5 b(.)25 b(An)20 b(assertion)h(is)g(lik)o (e)g(a)g(breakpoint)d(that)j(is)515 925 y(de\002ned)e(in)i(the)f (program)f(source)h(code)f(for)h(a)h(particular)e(instruction.)25 b(gpsim)20 b(reads)g(the)h(break-)515 1025 y(point)c(from)g(a)h (special)g(message)g(area)g(in)g(the)g(.cod)f(\002le.)25 b(F)o(or)18 b(e)o(xample,)e(you)i(may)f(ha)n(v)o(e)g(a)i(routine)515 1124 y(that)i(requires)g(B)m(ANK)h(0)g(be)f(selected.)29 b(A)22 b(gpsim)f(assertion)g(can)h(be)f(placed)g(at)h(the)g(entry)e(of) i(the)515 1224 y(routine)d(to)h(v)o(erify)f(that)h(this)h(is)g(the)f (case.)p Black Black 722 1531 a Fi(.assert)84 b("\(status)41 b(&)i(0x60\))e(==)i(0,)g(\\"Bank)e(0)i(must)f(be)h(selected!\\"")515 1739 y Fo(The)28 b(syntax)g(is)h(identical)f(to)h(the)f(e)o(xtended)e (breakpoint)h(command.)47 b(The)28 b(e)o(xpression)f(is)j(the)515 1838 y(condition)21 b(that)i(is)i(check)o(ed.)32 b(If)23 b(the)g(e)o(xpression)f(e)n(v)n(aluates)h(to)g(f)o(alse,)h(then)f(the)g (code)g(halts)g(and)515 1938 y(prints)i(the)h(message.)41 b(The)26 b Fh(.assert)i Fo(is)e(a)h(macro)d(that)i(is)h(part)e(of)h (gputils.)41 b(It)26 b(requires)f(a)h(string)515 2038 y(as)c(its)g(input)f(ar)o(gument.)27 b(Notice)21 b(that)g(the)h (assertion)f(message)g(is)i(embedded)c(in)j(the)f(ar)o(gument.)515 2137 y(gpasm)d(and)h(MP)-8 b(ASM)20 b(cop)o(y)e(C')-5 b(s)21 b(method)c(of)i(placing)f(a)i(backslash)e(in)i(front)e(of)h (quotations)e(that)515 2237 y(are)j(part)g(of)g(a)g(string.)515 2499 y SDict begin H.S end 515 2499 a 515 2499 a SDict begin 14 H.A end 515 2499 a 515 2499 a SDict begin [/View [/XYZ H.V]/Dest (section*.25) cvn /DEST pdfmark end 515 2499 a Fj(Command)25 b(Assertions)515 2680 y Fo(A)h(command)e (assertion)h(is)i(a)f(gpsim)f(associated)h(with)g(a)g(particular)e (instruction)g(in)i(your)f(PIC)515 2780 y(source)h(code.)46 b(These)27 b(are)h(useful)f(for)f(changing)g(the)h(beha)n(vior)f(of)h (the)g(simulation)g(based)g(on)515 2879 y(where)e(the)i(code)e(e)o(x)o (ecutes.)43 b(Almost)26 b(an)o(y)f(gpsim)h(command)f(can)h(be)g(placed) f(in)i(a)g(command)515 2979 y(assertion.)d(Ho)n(we)n(v)o(er)m(,)18 b(the)j(most)f(useful)g(ones)f(are)i(assignment)e(commands.)k(F)o(or)d (e)o(xample:)p Black Black 722 3186 a Fi(.command)40 b(\020SW1.state)g(=)j(open\021)515 3394 y Fo(This)20 b(assignment)f(writes)i(to)f(the)h(state)g(attrib)n(ute)e(of)h(a)h (switch)f(module)f(named)g(SW1.)p Black Black eop end %%Page: 38 39 TeXDict begin 38 38 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.38) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.6) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(6)515 1603 y Fq(T)-15 b(race)50 b(and)i(Log:)64 b(What)51 b(has)515 1852 y(happen?)515 2309 y Fo(Inspecting)18 b(the)i(current)f(state)i(of)e(your)g(program)f (is)j(sometimes)f(insuf)n(\002cient)f(to)h(determine)f(the)515 2408 y(cause)h(of)f(a)h(b)n(ug.)25 b(Often)19 b(times)h(it')-5 b(s)21 b(useful)f(to)g(kno)n(w)f(the)g(conditions)g(that)h(led)g(up)f (to)h(the)g(current)515 2508 y(state.)26 b(gpsim)19 b(pro)o(vides)g(a)i (history)e(or)h(trace)g(of)g(e)n(v)o(erything)e(that)i(occurs)f(-)i (whether)e(you)g(w)o(ant)i(it)515 2607 y(or)f(not)g(-)g(to)g(help)g (you)f(diagnose)g(these)i(otherwise)e(dif)n(\002cult)h(to)g(analyze)f (b)n(ugs.)p Black Black 1046 2816 1803 4 v 1044 2915 4 100 v 1199 2886 a(What')-5 b(s)21 b(traced)p 1810 2915 V 583 w(notes)p 2846 2915 V 1046 2919 1803 4 v 1046 2935 V 1044 3035 4 100 v 1153 3005 a(program)d(counter)p 1810 3035 V 308 w(addresses)i(e)o(x)o(ecuted)p 2846 3035 V 1046 3038 1803 4 v 1044 3138 4 100 v 1235 3108 a(instructions)p 1810 3138 V 586 w(opcode)p 2846 3138 V 1046 3141 1803 4 v 1044 3241 4 100 v 1223 3211 a(re)o(gister)g(read)p 1810 3241 V 391 w(v)n(alue)f(and)h(location)p 2846 3241 V 1046 3244 1803 4 v 1044 3344 4 100 v 1209 3314 a(re)o(gister)g(write) p 1810 3344 V 378 w(v)n(alue)f(and)h(location)p 2846 3344 V 1046 3347 1803 4 v 1044 3447 4 100 v 1207 3417 a(c)o(ycle)g(counter)p 1810 3447 V 460 w(current)f(v)n(alue)p 2846 3447 V 1046 3450 1803 4 v 1044 3550 4 100 v 1096 3520 a(skipped)g(instructions)p 1810 3550 V 267 w(addresses)h(skipped)p 2846 3550 V 1046 3553 1803 4 v 1044 3653 4 100 v 1200 3623 a(status)h(re)o(gister)p 1810 3653 V 203 w(during)d(implicit)i (modi\002cation)p 2846 3653 V 1046 3656 1803 4 v 1044 3756 4 100 v 1270 3726 a(interrupts)p 1810 3756 V 2846 3756 V 1046 3759 1803 4 v 1044 3859 4 100 v 1225 3829 a(break)f(points)p 1810 3859 V 624 w(type)p 2846 3859 V 1046 3862 1803 4 v 1044 3962 4 100 v 1334 3932 a(resets)p 1810 3962 V 735 w(type)p 2846 3962 V 1046 3965 1803 4 v 1044 4064 4 100 v 1810 4064 V 2846 4064 V 1046 4068 1803 4 v 1044 4167 4 100 v 1810 4167 V 2846 4167 V 1046 4171 1803 4 v 515 4414 a(The)h(')o(trace')e(command)h(will)i(dump)d (the)j(contents)e(of)h(the)g(trace)g(b)n(uf)n(fer)-5 b(.)515 4539 y(A)24 b(lar)o(ge)f(circular)g(b)n(uf)n(fer)g(\(whose)g (size)i(is)f(hard)f(coded\))g(stores)h(the)g(information)d(for)j(the)g (trace)515 4638 y(b)n(uf)n(fer)-5 b(.)35 b(When)24 b(it)g(\002lls,)i (it)f(will)f(wrap)g(around)e(and)h(write)h(o)o(v)o(er)e(the)i(old)g (history)-5 b(.)35 b(The)23 b(contents)515 4738 y(of)18 b(the)h(trace)f(b)n(uf)n(fer)g(are)g(parsed)g(into)h(frames,)f(where)g (one)g(frame)g(corresponds)e(to)j(a)g(simulation)515 4838 y(c)o(ycle.)515 4962 y(Here')-5 b(s)20 b(an)g(e)o(xample)f(of)h(a) h(trace)f(output:)p Black 1905 5208 a(38)p Black eop end %%Page: 39 40 TeXDict begin 39 39 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.39) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(6.)45 b(TRA)m(CE)21 b(AND)g(LOG:)f(WHA)-9 b(T)21 b(HAS)f(HAPPEN?)762 b Fo(39)p Black Black Black 722 515 a Fi(gpsim>)41 b(trace)722 615 y(0x00000000000026F)o(6)c (p18f452)k(0x001C)g(0x1003)g(iorwf)85 b(reg3,w,0)853 715 y(Read:)41 b(0x00)h(from)g(reg3\(0x0003\))809 814 y(Wrote:)f(0xE7)h(to)h(W\(0x0FE8\))d(was)i(0xE7)809 914 y(Wrote:)f(0x18)h(to)h(status\(0x0FD8\))38 b(was)k(0x18)722 1013 y(0x00000000000026F)o(7)37 b(p18f452)k(0x001E)g(0xE1F4)g(bnz)173 b($-0x16)85 b(;\(0x8\))722 1113 y(0x00000000000026F)o(8)37 b(p18f452)k(0x0008)g(0x3E00)g(incfsz)g(reg,f,0)853 1213 y(Read:)g(0xE4)h(from)g(reg\(0x0000\))809 1312 y(Wrote:)f(0xE5)h(to)h (reg\(0x0000\))c(was)j(0xE4)722 1412 y(0x00000000000026F)o(9)37 b(p18f452)k(0x000A)g(0xD004)g(bra)173 b($+0xa)129 b(;\(0x00014\))39 b(0x00000000000026)o(FA)e(p18f452)j(0x0014)h(0x0004)g(clrwdt)722 1512 y(0x00000000000026F)o(B)c(p18f452)k(0x0016)g(0x5000)g(movf)129 b(reg,w,0)853 1611 y(Read:)41 b(0xE5)h(from)g(reg\(0x0000\))809 1711 y(Wrote:)f(0xE5)h(to)h(W\(0x0FE8\))d(was)i(0xE7)809 1810 y(Wrote:)f(0x18)h(to)h(status\(0x0FD8\))38 b(was)k(0x18)722 1910 y(0x00000000000026F)o(C)37 b(p18f452)k(0x0018)g(0x1001)g(iorwf)85 b(reg1,w,0)853 2010 y(Read:)41 b(0x03)h(from)g(reg1\(0x0001\))809 2109 y(Wrote:)f(0xE7)h(to)h(W\(0x0FE8\))d(was)i(0xE5)809 2209 y(Wrote:)f(0x18)h(to)h(status\(0x0FD8\))38 b(was)k(0x18)515 2408 y Fo(Each)29 b(trace)h(frame)f(be)o(gins)g(with)h(a)g(ne)n(w)g (simulation)f(c)o(ycle.)53 b(T)-7 b(ypically)29 b(this)i(will)f (include)f(a)515 2508 y(simulated)19 b(instruction.)24 b(Here')-5 b(s)20 b(each)g(of)g(the)g(\002elds:)p Black Black 772 2785 a Fi(64-bit)41 b(simulation)e(cycle)98 b(processor)183 b(PC)j(opcode)162 b(instruction)881 2885 y(0x00000000000026)o(F6)246 b(p18f452)140 b(0x001C)97 b(0x1003)g(iorwf)41 b(reg3,w,0)515 3079 y Fo(Other)27 b(e)n(v)o(ents)g(that)h(occur)e(during)g(the)i(trace)f(frame)g(are)h (indented.)46 b(T)-7 b(ypically)26 b(these)i(will)h(be)515 3178 y(re)o(gister)24 b(read)g(or)g(write)h(traces.)39 b(The)24 b(read)h(traces)f(sho)n(w)h(the)g(v)n(alue)f(read.)38 b(Write)25 b(traces)g(sho)n(w)515 3278 y(the)20 b(v)n(alue)f(written)h (and)g(the)g(v)n(alue)g(that)g(w)o(as)h(pre)n(viously)d(in)j(the)f(re)o (gister)-5 b(.)515 3581 y SDict begin H.S end 515 3581 a 515 3581 a SDict begin 18 H.A end 515 3581 a 515 3581 a SDict begin [/View [/XYZ H.V]/Dest (section*.26) cvn /DEST pdfmark end 515 3581 a Fk(Sa)m(ving)30 b(T)-9 b(race)30 b(to)f(a)h(\002le)515 3790 y Fo(The)d(trace)g(b)n(uf)n(fer)f(may)h (contain)f(thousands)g(of)h(entries)h(making)e(it)i(dif)n(\002cult)e (to)i(search.)46 b(The)515 3889 y(trace)20 b(sa)n(v)o(e)g(feature)f (will)i(allo)n(w)f(the)h(trace)f(b)n(uf)n(fer)f(to)h(be)g(written)g(to) g(a)h(\002le.)p Black Black 722 4088 a Fi(gpsim>)41 b(trace)h(save)g (mytrace.log)515 4288 y Fo(The)22 b(entire)h(contents)f(of)h(the)f (trace)h(b)n(uf)n(fer)f(are)g(decoded)g(and)g(written)h(to)g(the)f (\002le.)34 b(The)23 b(format)515 4387 y(of)d(the)g(trace)g(is)h(the)f (same)h(as)g(it)f(is)i(when)d(displayed)g(at)i(the)f(command)e(line.) 515 4690 y SDict begin H.S end 515 4690 a 515 4690 a SDict begin 18 H.A end 515 4690 a 515 4690 a SDict begin [/View [/XYZ H.V]/Dest (section*.27) cvn /DEST pdfmark end 515 4690 a Fk(Raw)30 b(T)-9 b(races)515 4899 y Fo(The)24 b Fh(r)o(aw)h Fo(trace)f(b)n(uf)n(fer)f(is)i(the)g(trace)f(b)n(uf)n (fer)f(displayed)g(in)h(a)h(minimally)e(decoded)g(form.)36 b(This)515 4998 y(is)28 b(primarily)e(used)h(for)g(gpsim)g(de)n(v)o (elopment.)44 b(When)27 b(sa)n(v)o(ed)g(to)h(a)g(\002le,)i(the)d(ra)o (w)g(trace)h(is)g(not)p Black Black eop end %%Page: 40 41 TeXDict begin 40 40 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.40) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(6.)45 b(TRA)m(CE)21 b(AND)g(LOG:)f(WHA)-9 b(T)21 b(HAS)f(HAPPEN?)762 b Fo(40)p Black 515 515 a(decoded)20 b(at)j(all.)31 b(In)22 b(addition,)f(the)h(processor')-5 b(s)21 b(state)i(is)g(written)f(to)g(the)g(\002le.)31 b(Thus)22 b(third)f(party)515 615 y(tools)f(can)g(be)g(written)g(to)g (create)g(custom)g(trace)g(reports)2167 615 y SDict begin H.S end 2167 615 a -30 x Fm(1)2200 615 y SDict begin 12 H.L end 2200 615 a 2200 615 a SDict begin [/Subtype /Link/Dest (Hfootnote.6) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 2200 615 a Fo(.)p Black 515 4840 1146 4 v 605 4895 a Fg(1)634 4919 y SDict begin H.S end 634 4919 a 634 4919 a SDict begin H.R end 634 4919 a 634 4919 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.6) cvn /DEST pdfmark end 634 4919 a Ff(FIXME)c(-)g(The)h(dynamically)i(created)g(trace)f(type)g (information)h(needs)e(to)g(be)g(written)h(to)f(this)g(\002le)g(too.)k (W)m(ithout)d(it,)515 4998 y(it)f(is)g(dif)n(\002cult)i(to)f(tell)g (what)g(each)g(traced)h(item)f(is.)p Black Black Black eop end %%Page: 41 42 TeXDict begin 41 41 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.41) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.7) cvn /DEST pdfmark end 515 432 a 727 x Fl(Chapter)44 b(7)515 1595 y Fq(Simulating)53 b(the)e(Real)h(W)-15 b(orld:)515 1844 y(Stimuli)515 2297 y Fo(Stimuli)23 b(are)g(e)o(xtremely)f(useful,)h(if)g(not)g(necessary) -5 b(,)23 b(for)f(simulations.)34 b(The)o(y)22 b(pro)o(vide)f(a)j (means)515 2396 y(for)19 b(simulating)h(interactions)f(with)h(the)g (real)h(w)o(orld.)515 2517 y(The)30 b(gpsim)f(stimuli)i(capability)e (is)i(designed)e(to)h(be)g(accurate,)i(ef)n(\002cient)d(and)h(\003e)o (xible.)54 b(The)515 2616 y(models)21 b(for)g(the)g(PIC')-5 b(s)23 b(I/O)f(pins)f(mimic)h(the)f(real)h(de)n(vices.)29 b(F)o(or)21 b(e)o(xample,)f(the)i(open)f(collector)515 2716 y(output)g(on)h(port)g(A)i(of)e(a)h(PIC16C84)f(can)h(only)e(dri)n (v)o(e)h(lo)n(w)-5 b(.)32 b(Multiple)22 b(I/O)h(pins)g(may)f(be)h(tied) f(to)515 2816 y(one)e(another)f(so)j(that)f(the)f(open)g(collector)g (on)h(port)f(A)h(can)g(get)g(a)g(pull)g(up)f(resistor)h(from)f(port)g (B.)515 2915 y(The)i(o)o(v)o(erhead)e(for)h(stimuli)i(only)f(occurs)f (when)h(a)h(stimulus)f(changes)g(states.)32 b(In)23 b(other)e(w)o (ords,)515 3015 y(stimuli)f(are)g(not)g(polled)f(to)i(determine)e (their)h(state.)515 3135 y(Analog)e(stimuli)i(are)f(also)g(a)n(v)n (ailable.)24 b(It')-5 b(s)20 b(possible)f(to)h(create)f(v)n(oltage)f (references)g(and)h(sources)515 3235 y(to)i(simulate)g(almost)h(an)o(y) e(kind)h(of)g(real)g(w)o(orld)g(thing.)27 b(F)o(or)21 b(e)o(xample,)f(it')-5 b(s)23 b(possible)e(to)g(combine)515 3335 y(tw)o(o)f(analog)f(stimuli)i(together)e(to)h(create)g(signals)g (lik)o(e)h(DTMF)f(tones.)515 3455 y(Note,)e(ho)n(we)n(v)o(er)m(,)e (that)i(gpsim)g(does)g(not)g(attempt)g(to)g(be)g(a)h(full)f(electronic) f(circuit)h(simulator)m(,)f(and)515 3555 y(certain)24 b(approximations)d(made)j(for)g(ef)n(\002cienc)o(y)f(will)j(cause)e (inaccurac)o(y)e(in)j(comple)o(x)e(simula-)515 3654 y(tion)d(en)m (vironments.)515 3782 y SDict begin H.S end 515 3782 a 515 3782 a SDict begin 12 H.A end 515 3782 a 515 3782 a SDict begin [/View [/XYZ H.V]/Dest (section.7.1) cvn /DEST pdfmark end 515 3782 a 170 x Fk(7.1)119 b(Ho)o(w)30 b(They)f(W)-9 b(ork)515 4158 y Fo(In)27 b(the)g(simplest)h(case,)h(a)f (stimulus)f(acts)h(a)g(source)e(for)h(an)g(I/O)h(pin)f(on)g(a)g(PIC.)h (F)o(or)f(e)o(xample,)515 4258 y(you)e(may)g(w)o(ant)h(to)g(simulate)g (a)g(clock)f(and)g(measure)g(its)i(period)e(using)g(TMR0.)42 b(In)25 b(this)h(case,)515 4358 y(the)20 b(stimulus)h(is)g(the)g (source)f(and)g(the)g(TMR0)h(input)e(pin)i(on)f(the)g(pic)h(is)g(the)g (load.)k(In)20 b(gpsim)g(you)515 4457 y(w)o(ould)d(create)h(a)h (stimulus)f(for)g(the)g(clock)g(using)g(the)g(stimulus)g(command)e(and) i(connect)f(it)i(to)g(the)515 4557 y(I/O)h(pin)g(using)g(the)g(node)f (command.)515 4677 y(In)25 b(general,)f(you)h(can)g(ha)n(v)o(e)f(se)n (v)o(eral)g(')-5 b(sources')25 b(and)f(se)n(v)o(eral)h(')o(loads')f (that)h(are)g(interconnected)515 4777 y(with)30 b(nodes)888 4777 y SDict begin H.S end 888 4777 a -30 x Fm(1)921 4777 y SDict begin 12 H.L end 921 4777 a 921 4777 a SDict begin [/Subtype /Link/Dest (Hfootnote.7) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 921 4777 a Fo(.)55 b(A)31 b(good)e(analogy)f(is)j(a)f(spice)h (circuit.)54 b(The)29 b(spice)i(netlist)f(corresponds)e(to)i(a)p Black 515 4840 1146 4 v 605 4896 a Fg(1)634 4920 y SDict begin H.S end 634 4920 a 634 4920 a SDict begin H.R end 634 4920 a 634 4920 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.7) cvn /DEST pdfmark end 634 4920 a Ff(Although,)25 b(gpsim)d(is)f(currently)k(limited)e(to)g('one-port')h(de)n(vices.)37 b(In)22 b(other)h(w)o(ords,)g(it)g(is)e(assumed)i(that)g(ground)515 4998 y(serv)o(es)17 b(as)g(a)g(common)g(reference)j(for)d(the)h (sources)g(and)f(the)h(loads.)p Black Black 1905 5208 a Fo(41)p Black eop end %%Page: 42 43 TeXDict begin 42 42 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.42) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(7.)45 b(SIMULA)-9 b(TING)20 b(THE)g(REAL)g(W)o(ORLD:) i(STIMULI)640 b Fo(42)p Black 515 515 a(node-list)21 b(in)g(gpsim)g(and)h(the)f(spice)h(elements)f(correspond)e(to)j(the)g (stimuli)g(sources)f(and)g(loads.)515 615 y(This)d(general)f(approach)e (mak)o(es)j(it)h(possible)e(to)h(create)g(a)g(v)n(ariety)f(of)h (simulation)f(en)m(vironments.)515 715 y(Here')-5 b(s)20 b(a)h(list)g(of)f(dif)n(ferent)f(w)o(ays)h(in)g(which)g(stimuli)h(may)e (be)h(connected:)515 791 y SDict begin H.S end 515 791 a 515 791 a SDict begin 12 H.A end 515 791 a 515 791 a SDict begin [/View [/XYZ H.V]/Dest (Item.1) cvn /DEST pdfmark end 515 791 a Black 619 906 a Fo(1.)p Black 40 w(Stimulus)g(connected)f(to)h(one)g(I/O)g(pin)515 957 y SDict begin H.S end 515 957 a 515 957 a SDict begin 12 H.A end 515 957 a 515 957 a SDict begin [/View [/XYZ H.V]/Dest (Item.2) cvn /DEST pdfmark end 515 957 a Black 619 1072 a Fo(2.)p Black 40 w(Stimulus)g(connected)f(to)h(se)n(v)o (eral)g(I/O)g(pins)515 1123 y SDict begin H.S end 515 1123 a 515 1123 a SDict begin 12 H.A end 515 1123 a 515 1123 a SDict begin [/View [/XYZ H.V]/Dest (Item.3) cvn /DEST pdfmark end 515 1123 a Black 619 1238 a Fo(3.)p Black 40 w(Se)n(v)o(eral)g(stimuli)g(connected)e(to)j(one)e(I/O)i(pin) 515 1289 y SDict begin H.S end 515 1289 a 515 1289 a SDict begin 12 H.A end 515 1289 a 515 1289 a SDict begin [/View [/XYZ H.V]/Dest (Item.4) cvn /DEST pdfmark end 515 1289 a Black 619 1404 a Fo(4.)p Black 40 w(Se)n(v)o(eral)f (stimuli)g(connected)e(to)j(se)n(v)o(eral)e(I/O)i(pins)515 1455 y SDict begin H.S end 515 1455 a 515 1455 a SDict begin 12 H.A end 515 1455 a 515 1455 a SDict begin [/View [/XYZ H.V]/Dest (Item.5) cvn /DEST pdfmark end 515 1455 a Black 619 1570 a Fo(5.)p Black 40 w(I/O)g(pins)f(connected)e(to) j(I/O)f(pins)515 1761 y(The)g(general)f(technique)f(for)i(implementing) e(stimuli)i(is)h(as)g(follo)n(ws:)515 1837 y SDict begin H.S end 515 1837 a 515 1837 a SDict begin 12 H.A end 515 1837 a 515 1837 a SDict begin [/View [/XYZ H.V]/Dest (Item.6) cvn /DEST pdfmark end 515 1837 a Black 619 1952 a Fo(1.)p Black 40 w(De\002ne)f(the)h(stimulus)f(or)g(stimuli.)515 1986 y SDict begin H.S end 515 1986 a 515 1986 a SDict begin 12 H.A end 515 1986 a 515 1986 a SDict begin [/View [/XYZ H.V]/Dest (Item.7) cvn /DEST pdfmark end 515 1986 a Black 619 2118 a Fo(2.)p Black 40 w(De\002ne)g(a)h(node.)515 2152 y SDict begin H.S end 515 2152 a 515 2152 a SDict begin 12 H.A end 515 2152 a 515 2152 a SDict begin [/View [/XYZ H.V]/Dest (Item.8) cvn /DEST pdfmark end 515 2152 a Black 619 2284 a Fo(3.)p Black 40 w(Attach)f(the)h(stimuli)f(to) g(the)h(node.)515 2475 y(More)e(often)h(than)f(not,)h(the)g(stimulus)g (de\002nition)f(will)i(reside)f(in)h(a)f(\002le.)515 2608 y SDict begin H.S end 515 2608 a 515 2608 a SDict begin 12 H.A end 515 2608 a 515 2608 a SDict begin [/View [/XYZ H.V]/Dest (subsection.7.1.1) cvn /DEST pdfmark end 515 2608 a 129 x Fj(7.1.1)99 b(Contention)26 b(among)e(stimuli)515 2918 y Fo(One)e(of)h(the)g(problems)e(with)i(this)h(nodal)d(approach)g (to)i(modeling)e(stimuli)i(is)h(that)f(it')-5 b(s)24 b(possible)515 3017 y(for)d(contention)f(to)i(e)o(xist.)30 b(F)o(or)22 b(e)o(xample,)f(if)h(tw)o(o)g(I/O)g(pins)g(are)g(connected) e(to)i(one)g(another)e(and)515 3117 y(dri)n(ving)g(in)j(the)f(opposite) g(directions,)f(there)h(will)h(be)f(contention.)30 b(gpsim)22 b(resolv)o(es)f(contention)515 3217 y(with)c(attrib)n(ute)g(summing.)23 b(Each)17 b(stimulus)g(-)h(e)n(v)o(en)e(if)i(it')-5 b(s)18 b(an)g(input)e(-)i(has)f(an)h(ef)n(fect)e(on)h(the)h(node.)515 3316 y(This)24 b(ef)n(fect)g(is)h(characterised)e(by)g(a)i(v)n(oltage)f (and)f(an)h(impedance.)35 b(When)24 b(a)h(node)e(is)i(updated,)515 3416 y(gpsim)c(performs)f(a)i(The)n(v)o(enin)e(v)n(oltage)h(summing)f (of)h(all)i(the)e(stimuli)h(together)-5 b(.)29 b(The)21 b(resultant)515 3516 y(v)n(oltage)e(is)i(then)f(propagated)d(to)k(all)f (connected)f(stimuli)h(as)h(the)f(current)f(state)i(of)f(the)g(node.) 515 3640 y(F)o(or)j(e)o(xample,)h(in)g(the)g(port)f(A)i(open)e (collector)g(/)i(port)e(B)i(weak)f(pull-up)e(connection)g(e)o(xample,) 515 3740 y(gpsim)i(assigns)g(a)h(v)n(oltage)f(of)g(5V)g(with)g(an)h (impedance)d(of)i(20k)o(ohms)f(to)h(the)g(pull)g(up)g(resistor)m(,)515 3839 y(and)19 b(a)i(v)n(oltage)e(of)h(0V)g(with)g(an)g(impedance)e(of)h (150ohms)f(to)j(the)f(open)e(collector)h(if)i(it)f(is)h(acti)n(v)o(e,) 515 3939 y(or)d(100Mohms)e(if)i(it')-5 b(s)19 b(not)f(dri)n(ving.)23 b(The)17 b(The)n(v)o(enin)f(sum)i(will)h(be)f(roughly)e(0.05V)h(if)i (the)f(output)515 4039 y(is)j(dri)n(ving,)d(or)i(5V)g(otherwise.)25 b(Capaciti)n(v)o(e)19 b(ef)n(fects)h(are)g(not)g(currently)e (supported.)515 4187 y SDict begin H.S end 515 4187 a 515 4187 a SDict begin 12 H.A end 515 4187 a 515 4187 a SDict begin [/View [/XYZ H.V]/Dest (section.7.2) cvn /DEST pdfmark end 515 4187 a 157 x Fk(7.2)119 b(I/O)29 b(Pins)515 4554 y Fo(gpsim)23 b(models)g(I/O)h(pins)g(as)h(stimuli.)36 b(Thus)24 b(an)o(ywhere)d(a)k(stimulus)f(is)g(used,)h(an)e(I/O)i(pin)e (may)515 4654 y(be)i(substituted.)38 b(F)o(or)24 b(e)o(xample,)h(you)f (may)g(w)o(ant)h(to)g(tie)h(tw)o(o)f(I/O)g(pins)g(to)g(one)f(another;)i (lik)o(e)f(a)515 4753 y(port)d(B)h(pull)g(up)f(resistor)g(to)h(a)g (port)f(A)h(open)f(collector)-5 b(.)32 b(gpsim)22 b(automatically)f (creates)i(the)f(I/O)515 4853 y(pin)c(stimuli)g(whene)n(v)o(er)e(a)j (processor)d(is)k(created.)j(All)c(you)e(need)h(to)g(do)g(is)h(to)f (specify)f(a)i(node)e(and)515 4953 y(then)24 b(attach)g(the)g(stimuli)h (to)f(it.)39 b(The)24 b(names)g(of)g(these)g(stimuli)h(are)f(formed)f (by)h(concatenating)p Black Black eop end %%Page: 43 44 TeXDict begin 43 43 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.43) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(7.)45 b(SIMULA)-9 b(TING)20 b(THE)g(REAL)g(W)o(ORLD:) i(STIMULI)640 b Fo(43)p Black 515 515 a(the)19 b(port)g(name)g(with)g (the)h(bit)f(position)g(of)g(the)h(I/O)f(pin.)25 b(F)o(or)19 b(e)o(xample,)f(bit)h(3)h(in)f(port)g(B)h(is)h(called)515 615 y(portb3.)515 738 y(Here')-5 b(s)20 b(a)h(list)g(of)f(the)g(types)g (of)g(I/O)h(pin)e(stimuli)i(that)f(are)g(supported:)p Black Black 750 937 2394 4 v 748 1037 4 100 v 1000 1007 a(I/O)g(Pin)h(T)-7 b(ype)p 1675 1037 V 835 w(Function)p 3142 1037 V 750 1040 2394 4 v 750 1057 V 748 1156 4 100 v 959 1127 a(INPUT_ONL)f(Y)p 1675 1156 V 402 w(Only)20 b(accepts)g(input)f(\(lik)o(e)i(MCLR\))p 3142 1156 V 750 1160 2394 4 v 748 1259 4 100 v 874 1230 a(BI_DIRECTION)m(AL)p 1675 1259 V 172 w(Can)f(be)g(a)h(source)e(or)h(a)h(load)f(\(most)f(I/O) i(pins\))p 3142 1259 V 750 1263 2394 4 v 748 1362 4 100 v 800 1332 a(BI_DIRECTION)m(AL_PU)p 1675 1362 V 294 w(PU=Pullup)f (resistor)g(\(POR)-5 b(TB\))p 3142 1362 V 750 1366 2394 4 v 748 1465 4 100 v 841 1435 a(OPEN_COLLECT)o(OR)p 1675 1465 V 267 w(Can)20 b(only)g(dri)n(v)o(e)f(lo)n(w)h(\(RA4)g(on)g(c84\)) p 3142 1465 V 750 1469 2394 4 v 515 1703 a(There)g(is)j(no)e(special)g (pin)g(type)g(for)g(analog)f(I/O)i(pins.)29 b(All)22 b(pic)f(analog)f(inputs)h(are)h(multiple)o(x)o(ed)515 1803 y(with)i(digital)g(inputs.)37 b(The)24 b(I/O)h(pin)f(de\002nition) f(will)i(al)o(w)o(ays)g(be)f(for)g(the)g(digital)g(input.)37 b(gpsim)515 1902 y(automatically)18 b(kno)n(ws)i(when)f(I/O)i(pin)f(is) h(analog)e(input.)515 2050 y SDict begin H.S end 515 2050 a 515 2050 a SDict begin 12 H.A end 515 2050 a 515 2050 a SDict begin [/View [/XYZ H.V]/Dest (section.7.3) cvn /DEST pdfmark end 515 2050 a 154 x Fk(7.3)119 b(Asynchr)n(onous)30 b(Stimuli)515 2413 y Fo(Asynchronous)19 b(stimuli)k(are)g(analog)e(or)h (digital)h(stimuli)f(that)h(can)f(change)g(states)h(at)g(an)o(y)f(gi)n (v)o(en)515 2513 y(instant)32 b(\(limited)g(to)g(the)h(resolution)e(of) h(the)g(c)o(ycle)g(counter\).)59 b(The)o(y)31 b(can)i(be)f(de\002ned)f (to)i(be)515 2613 y(repetiti)n(v)o(e)19 b(too.)p Black Black 973 2812 1949 4 v 971 2912 4 100 v 1050 2882 a(parameter)p 1458 2912 V 668 w(function)p 2919 2912 V 973 2915 1949 4 v 973 2932 V 971 3031 4 100 v 1037 3001 a(start_c)o(ycle)p 1458 3031 V 113 w(The)h(#)g(of)g(c)o(ycles)g(before)e(the)j(stimulus)f (starts)p 2919 3031 V 973 3035 1949 4 v 971 3134 4 100 v 1086 3104 a(c)o(ycles[])p 1458 3134 V 494 w(An)g(array)f(of)h(c)o (ycle)g(#')-5 b(s)p 2919 3134 V 973 3137 1949 4 v 971 3237 4 100 v 1120 3207 a(data[])p 1458 3237 V 456 w(Stimulus)20 b(state)h(for)f(a)h(c)o(ycle)p 2919 3237 V 973 3240 1949 4 v 971 3340 4 100 v 1110 3310 a(period)p 1458 3340 V 367 w(The)f(#)g(of)g(c)o(ycles)g(for)f(one)h(period)p 2919 3340 V 973 3343 1949 4 v 971 3443 4 100 v 1023 3413 a(initial_state)p 1458 3443 V 277 w(The)g(initial)g(state)h(before)e (data[0])p 2919 3443 V 973 3446 1949 4 v 515 3681 a(When)30 b(the)g(stimulus)h(is)g(\002rst)g(initialized,)i(it)e(will)g(be)f(dri)n (v)o(en)f(to)h(the)h('initial)f(state')h(and)f(will)515 3780 y(remain)15 b(there)h(until)g(the)h(cpu')-5 b(s)16 b(instruction)f(c)o(ycle)h(counter)f(matches)h(the)h(speci\002ed)f(')-5 b(start')16 b(c)o(ycle.)515 3880 y(After)32 b(that,)j(the)d(tw)o(o)h (arrays)f('c)o(ycles[]')e(and)i(')l(data[]')f(de\002ne)g(the)i (stimulus')f(outputs.)60 b(The)515 3980 y(size)25 b(of)g(the)g(arrays)f (are)h(the)g(same)g(and)f(correspond)f(to)i(the)g(number)e(of)h(e)n(v)o (ents)h(that)g(are)g(to)g(be)515 4079 y(created.)41 b(So)26 b(the)f(e)n(v)o(ent)g(number)m(,)g(if)h(you)f(will,)i(serv)o(es)f(as)g (the)g(inde)o(x)f(into)g(these)h(arrays.)41 b(The)515 4179 y('c)o(ycles[]')19 b(array)h(de\002ne)g(when)g(the)h(e)n(v)o(ents) f(occur)g(while)h(the)f(')l(data[]')f(array)h(de\002nes)h(the)g(states) 515 4278 y(the)26 b(stimulus)g(will)i(enter)-5 b(.)43 b(The)26 b('c)o(ycles[]')f(are)h(measured)f(with)i(respect)f(to)g(the)h (')-5 b(start')26 b(c)o(ycle.)515 4378 y(The)d(asynchronous)e(stimulus) j(can)f(be)h(made)f(periodic)g(by)g(specifying)f(the)i(number)e(of)i(c) o(ycles)515 4478 y(in)c(the)g('period')e(parameter)-5 b(.)515 4601 y(Here')g(s)20 b(an)g(e)o(xample)f(that)h(generates)g (three)f(pulses)i(and)e(then)h(repeats:)p Black Black 722 4899 a Fi(stimulus)40 b(asynchronous_stim)o(ul)o(us)d(#)43 b(or)g(we)g(could)e(have)h(used)g(asy)722 4998 y(#)h(The)g(initial)d (state)i(AND)g(the)g(state)g(the)g(stimulus)e(is)j(when)p Black Black eop end %%Page: 44 45 TeXDict begin 44 44 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.44) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(7.)45 b(SIMULA)-9 b(TING)20 b(THE)g(REAL)g(W)o(ORLD:) i(STIMULI)640 b Fo(44)p Black 722 515 a Fi(#)43 b(it)g(rolls)f(over)722 615 y(initial_state)c(1)722 715 y(#)43 b(all)g(times)e(are)i(with)e (respect)g(to)i(the)f(cpu's)f(cycle)h(counter)722 814 y(start_cycle)d(100)722 914 y(#)k(the)g(asynchronous)38 b(stimulus)i(will)i(roll)g(over)g(in)h('period')722 1013 y(#)g(cycles.)e(Delete)g(this)h(line)g(if)h(you)f(don't)f(want)h(a)h (roll)f(over.)722 1113 y(period)f(5000)722 1213 y(#)i(Now)g(the)f (cycles)f(at)i(which)e(stimulus)f(changes)h(states)g(are)722 1312 y(#)i(specified.)d(The)i(initial)f(cycle)g(was)h(specified)e (above.)h(So)722 1412 y(#)i(the)g(first)e(cycle)h(specified)d(below)j (will)g(toggle)f(this)h(state.)722 1512 y(#)h(In)g(this)f(example,)e (the)j(stimulus)d(will)i(start)f(high.)722 1611 y(#)i(At)g(cycle)f(100) g(the)g(stimulus)e('begins'.)g(However)h(nothing)f(happens)722 1711 y(#)j(until)f(cycle)f(200+100.)722 1810 y({)i(200,)f(0,)809 1910 y(300,)g(1,)809 2010 y(400,)g(0,)809 2109 y(600,)g(1,)809 2209 y(1000,)g(0,)809 2309 y(3000,)g(1)h(})722 2408 y(#)g(Give)f(the)h (stimulus)d(a)j(name:)722 2508 y(name)f(asy_test)722 2607 y(#)h(Finally,)e(tell)h(the)g(command)e(line)i(interface)e(that)i (we're)f(done)722 2707 y(#)i(with)f(the)h(stimulus)722 2807 y(end)515 2928 y SDict begin H.S end 515 2928 a 515 2928 a SDict begin 12 H.A end 515 2928 a 515 2928 a SDict begin [/View [/XYZ H.V]/Dest (subsection.7.3.1) cvn /DEST pdfmark end 515 2928 a 141 x Fj(7.3.1)99 b(Analog)24 b(Asynchr)n(onous)i(Stimuli)515 3250 y Fo(Analog)j(Asynchronous)f (Stimuli)i(are)h(identical)f(to)g(Synchronous)e(Stimuli)j(e)o(xcept)e (the)i(data)515 3349 y(points)19 b(are)i(\003oating)e(point)h(numbers.) 515 3498 y SDict begin H.S end 515 3498 a 515 3498 a SDict begin 12 H.A end 515 3498 a 515 3498 a SDict begin [/View [/XYZ H.V]/Dest (section.7.4) cvn /DEST pdfmark end 515 3498 a 157 x Fk(7.4)119 b(Extended)31 b(Stimuli)515 3865 y Fo(Discuss)j(the)f(e)o(xtended)f(stimuli)h(in)h(the)f(modules/)f (directory)-5 b(.)62 b(In)33 b(particular)m(,)i(describe)e(the)515 3965 y Fh(PulseGen)c Fo(module)g(and)g(ho)n(w)g(it)i(can)f(complete)f (replace)g(the)h(asynchronous)d(stimuli.)54 b(Also)515 4064 y(describe)19 b(the)h Fh(PullUp)f Fo(and)h Fh(PullDown)f Fo(modules)g(and)g(ho)n(w)g(the)o(y)h(can)f(be)h(manipulated)e(into)i (be-)515 4164 y(ing)e(general)f(purpose)g(DC)i(v)n(oltage)f(sources)g (\(FIXME,)f(w)o(ould)h(it)h(mak)o(e)f(sense)h(to)f(rename)f(these)515 4264 y(modules?\).)515 4409 y SDict begin H.S end 515 4409 a 515 4409 a SDict begin 12 H.A end 515 4409 a 515 4409 a SDict begin [/View [/XYZ H.V]/Dest (section.7.5) cvn /DEST pdfmark end 515 4409 a 160 x Fk(7.5)119 b(Limitations)29 b(of)g(the)i(Stimulus)f(Mechanism)515 4779 y Fo(The)21 b(simulation)g(of)g(e)o(xternal)g(de)n(vices)g(using)g(gpsim)g(stimuli) h(and)f(nodes)g(is)i(intended)d(to)i(assist)515 4879 y(in)g(PIC)h(softw)o(are)e(deb)n(ugging,)f(not)i(electronic)f(circuit)h (design.)29 b(As)23 b(such)f(it)h(tak)o(es)f(a)h(simpli\002ed)515 4978 y(approach)18 b(to)i(certain)g(things.)p Black Black eop end %%Page: 45 46 TeXDict begin 45 45 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.45) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(7.)45 b(SIMULA)-9 b(TING)20 b(THE)g(REAL)g(W)o(ORLD:) i(STIMULI)640 b Fo(45)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (subsection.7.5.1) cvn /DEST pdfmark end 515 432 a 83 x Fj(7.5.1)99 b(Pr)n(opagation)25 b(Delays)515 696 y Fo(gpsim)e(mak)o(es)h(no)g (attempt)f(to)h(simulate)g(propagation)d(delays)i(in)i(the)e(circuit.) 36 b(Usually)24 b(this)h(is)515 795 y(not)f(a)i(problem.)38 b(Ho)n(we)n(v)o(er)m(,)24 b(when)g(using)h(modules)2084 796 y SDict begin H.S end 2084 796 a Black -1 x Fo(8)p Black 2124 739 a SDict begin H.R end 2124 739 a 2124 795 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (chapter.8) cvn H.B /ANN pdfmark end 2124 795 a 25 w Fo(to)h(e)o(xpand)d(gpsim')-5 b(s)25 b(en)m(vironment,)e(it)j(is)515 895 y(possible)17 b(to)i(create)e(situations)h(where)g(it)g(matters.)25 b(F)o(or)17 b(e)o(xample,)g(daisy-chaining)e(tw)o(o)k(or)e(more)515 995 y(shift)j(re)o(gisters)f(with)h(a)g(shared)f(clock)g(relies)h(on)f (the)h(propagation)c(delay)j(of)g(the)h(\002rst)g(re)o(gister)f(to)515 1094 y(ensure)j(the)h(second)f(shifts)h(the)g(correct)f(data)g(in.)33 b(Since)23 b(gpsim)g(does)f(not)h(simulate)f(this)i(delay)-5 b(,)515 1194 y(the)20 b(results)g(may)g(be)g(wrong)1351 1194 y SDict begin H.S end 1351 1194 a -30 x Fm(2)1384 1194 y SDict begin 12 H.L end 1384 1194 a 1384 1194 a SDict begin [/Subtype /Link/Dest (Hfootnote.8) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1384 1194 a Fo(.)p Black 515 4919 1146 4 v 605 4974 a Fg(2)634 4998 y SDict begin H.S end 634 4998 a 634 4998 a SDict begin H.R end 634 4998 a 634 4998 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.8) cvn /DEST pdfmark end 634 4998 a Ff(The)o(y)d(may)g(be)h(right,)f(it)h (depends)g(on)f(e)o(x)o(ecution)j(order)m(,)e(which)g(is)f(subtle.)p Black Black Black eop end %%Page: 46 47 TeXDict begin 46 46 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.46) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.8) cvn /DEST pdfmark end 515 432 a 730 x Fl(Chapter)44 b(8)515 1601 y Fq(Modules)515 2056 y Fo(gpsim)30 b(has)g(been)g(designed)f(to)h(deb)n(ug)g (microprocessors.)53 b(Ho)n(we)n(v)o(er)m(,)31 b(microprocessors)d(are) 515 2156 y(al)o(w)o(ays)h(a)h(part)e(of)h(a)h(system.)51 b(And)29 b(in)m(v)n(ariably)-5 b(,)28 b(the)h(b)n(ugs)g(one)f(often)h (encounters)e(are)i(those)515 2256 y(that)f(are)g(a)h(result)f(of)g (interf)o(acing)f(with)h(a)h(system.)49 b(Modules)27 b(pro)o(vide)g(users)h(with)g(a)h(w)o(ay)f(to)515 2355 y(e)o(xtend)18 b(gpsim)h(and)h(simulate)f(a)i(system.)k(F)o(or)19 b(e)o(xample,)f(the)i Fh(system)h Fo(may)e(be)h(a)g(processor)e(with) 515 2455 y(a)31 b(fe)n(w)f(pull)h(up)f(resistors)h(and)f(switches)h(or) f(it)i(may)e(be)h(a)g(processor)e(and)h(an)h(LCD)g(display)-5 b(.)515 2554 y(gpsim)23 b(pro)o(vides)g(a)i(fe)n(w)f(modules)f(that)h (one)g(may)g(use)g(either)g(for)f(deb)n(ugging)f(or)i(as)h(templates) 515 2654 y(for)19 b(creating)g(ne)n(w)h(modules.)515 2777 y(Note)d(that)h(gpsim')-5 b(s)18 b(modules)e(are)i(pro)o(vided)d (to)j(f)o(acilitate)g(deb)n(ugging)d(of)i(the)h(PIC)g(code,)f(not)h (the)515 2877 y(hardw)o(are.)34 b(gpsim)23 b(does)h(not)f(attempt)g(to) h(be)g(a)g(circuit)g(simulator)f(by)g(itself.)36 b(If)24 b(you)e(need)h(that)515 2977 y(functionality)-5 b(,)17 b(the)j(gpsim)g(core)g(can)g(be)g(embedded)e(into)i(third)f(party)h (simulators.)515 3100 y(Modules)28 b(reside)h(in)h(a)f(library)f(and)h (are)g(dynamically)f(loaded)g(with)h(the)h Fh(module)e Fo(command.)515 3200 y(All)f(modules)e(ha)n(v)o(e)h(I/O)h(pins)g(which) f(can)g(connect)f(to)i(other)f(modules)f(or)h(processors.)43 b(Most)515 3299 y(modules)20 b(pro)o(vide)e Fh(attrib)n(utes)k Fo(that)f(allo)n(w)f(the)h(user)g(to)g(control)f(a)h(module')-5 b(s)20 b(beha)n(vior)f(or)i(query)515 3399 y(its)i(internal)e(state.)31 b(F)o(or)21 b(e)o(xample,)g(the)h(USAR)-5 b(T)23 b(module)d(has)j (transmit)e(and)h(recei)n(v)o(e)f(baud)g(rate)515 3499 y(attrib)n(utes)f(that)g(may)g(be)g(con\002gured:)p Black Black 722 3700 a Fi(gpsim>)41 b(U1.txbaud)f(=)j(9600)129 b(#)43 b(set)g(the)f(transmit)e(rate)722 3799 y(gpsim>)h(U1.rxbaud)432 b(#)43 b(query)f(the)g(receiver)e(rate)722 3899 y(9600)515 4100 y Fo(The)20 b(symbol)f(command)f(can)i(be)g(used)g(to)g(query)f (all)i(attrib)n(utes)f(of)g(a)h(module.)p Black Black 722 4301 a Fi(gpsim>)41 b(symbol)g(U1.)217 b(#)43 b(note)f(the)g (period)722 4401 y(U1)h(=)g(USARTModule)722 4500 y(U1.console)d(=)j (false)722 4600 y(U1.crlf)e(=)i(true)722 4700 y(U1.loop)e(=)i(true)722 4799 y(U1.rx)f(=)h(0)722 4899 y(U1.rxbaud)d(=)j(9600)722 4998 y(U1.tx)f(=)h(0)p Black 1905 5208 a Fo(46)p Black eop end %%Page: 47 48 TeXDict begin 47 47 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.47) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(47)p Black 722 515 a Fi(U1.txbaud)40 b(=)j(9600)722 615 y(U1.xpos)e(=)i (72.0000000000000)o(0)722 715 y(U1.ypos)e(=)i(276.000000000000)o(0)515 922 y Fo(Modules)19 b(may)h(pro)o(vide)e(help)i(which)f(can)h(be)g (accessed)h(using)e(the)h(help)g(command:)p Black Black 722 1130 a Fi(gpsim>)41 b(help)h(U1)722 1229 y(USARTModule)722 1329 y(no)h(description)515 1536 y Fo(W)-7 b(ell,)28 b(the)e(USAR)-5 b(T)26 b(module)f(isn')o(t)g(the)h(best)g(e)o(xample)e (here!)42 b(Ho)n(we)n(v)o(er)m(,)25 b(a)h(better)f(e)o(xample)g(is)515 1636 y(one)19 b(of)h(the)g(USAR)-5 b(T)21 b(attrib)n(utes.)p Black Black 722 1844 a Fi(gpsim>)41 b(help)h(U1.txbaud)722 1943 y(9600)722 2043 y(USART)g(Module)f(Transmitter)e(baud)j(rate)515 2174 y SDict begin H.S end 515 2174 a 515 2174 a SDict begin 12 H.A end 515 2174 a 515 2174 a SDict begin [/View [/XYZ H.V]/Dest (section.8.1) cvn /DEST pdfmark end 515 2174 a 174 x Fk(8.1)119 b(gpsim)29 b(Modules)515 2558 y Fo(gpsim)16 b(pro)o(vides)f(a)i(library)e(of)h(useful)g(modules)g (for)g(simulation.)23 b(The)16 b(current)f(v)o(ersion)g(includes)515 2658 y(the)20 b(follo)n(wing)e(modules:)p 515 2713 2744 4 v 513 2812 4 100 v 1283 2812 V 3256 2812 V 515 2816 2744 4 v 515 2832 V 513 2932 4 100 v 716 2902 a(pushb)n(utton)p 1283 2932 V 3256 2932 V 515 2935 2744 4 v 513 3035 4 100 v 793 3005 a(pullup)p 1283 3035 V 592 w(A)j(resistor)f(connected)e (\(nominally\))g(to)i(Vdd)p 3256 3035 V 515 3038 2744 4 v 513 3138 4 100 v 744 3108 a(pulldo)n(wn)p 1283 3138 V 550 w(A)h(resistor)f(connected)e(\(nominally\))g(to)j(Vss)p 3256 3138 V 515 3141 2744 4 v 513 3241 4 100 v 819 3211 a(usart)p 1283 3241 V 516 w(A)f(serial)h(interf)o(ace)e(with)i(a)f(GUI) h(terminal)e(windo)n(w)p 3256 3241 V 515 3244 2744 4 v 513 3344 4 100 v 753 3314 a(pulse)o(gen)p 1283 3344 V 3256 3344 V 515 3347 2744 4 v 513 3447 4 100 v 606 3417 a(I2C-EEPR)m(OM2K)p 1283 3447 V 231 w(A)h(256)g(byte)f(I2C)i (serial)f(EEPR)m(OM)g(lik)o(e)h(the)f(24LC024.)p 3256 3447 V 515 3450 2744 4 v 513 3549 4 100 v 585 3520 a(I2C-EEPR)m(OM16K)p 1283 3549 V 224 w(A)g(2k)g(byte)g(I2C)g(serial)h(EEPR)m(OM)f(lik)o(e)g (the)g(24LC16B.)p 3256 3549 V 515 3553 2744 4 v 513 3652 4 100 v 565 3623 a(I2C-EEPR)m(OM256K)p 1283 3652 V 188 w(A)g(32k)g(byte)f(I2C)i(serial)f(EEPR)m(OM)g(lik)o(e)h(the)f(24LC256.) p 3256 3652 V 515 3656 2744 4 v 513 3755 4 100 v 775 3725 a(i2c2par)p 1283 3755 V 569 w(A)g(sla)n(v)o(e)h(I2C)f(de)n(vice)f (with)i(an)f(8)g(bit)h(I/O)f(port)p 3256 3755 V 515 3759 2744 4 v 513 3858 4 100 v 791 3828 a(switch)p 1283 3858 V 544 w(Switch,)g(which)g(connects)f(tw)o(o)i(nodes)e(together)p 3256 3858 V 515 3862 2744 4 v 513 3961 4 100 v 819 3931 a(and2)p 1283 3961 V 866 w(2-input)g(logical)h(AND)g(gate)p 3256 3961 V 515 3965 2744 4 v 513 4064 4 100 v 844 4034 a(or2)p 1283 4064 V 924 w(2-input)f(logical)h(OR)h(gate)p 3256 4064 V 515 4068 2744 4 v 513 4167 4 100 v 823 4137 a(xor2)p 1283 4167 V 874 w(2-input)d(logical)i(XOR)h(gate)p 3256 4167 V 515 4170 2744 4 v 513 4270 4 100 v 847 4240 a(not)p 1283 4270 V 864 w(In)m(v)o(erter)d(\(logical)h(NO)m(T)h(gate\)) p 3256 4270 V 515 4273 2744 4 v 513 4373 4 100 v 653 4343 a(led_7se)o(gments)p 1283 4373 V 733 w(A)h(7-se)o(gment)d(LED)i (digit)p 3256 4373 V 515 4376 2744 4 v 513 4476 4 100 v 849 4446 a(led)p 1283 4476 V 383 w(A)h(single)f(pin)g(LED)g(which)g (can)g(be)g(acti)n(v)o(e)g(either)f(high)h(or)g(lo)n(w)p 3256 4476 V 515 4479 2744 4 v 513 4579 4 100 v 761 4549 a(TTL377)p 1283 4579 V 653 w(A)h(74xx377)d(style)i(8-bit)g(tristate)g (latch)p 3256 4579 V 515 4582 2744 4 v 513 4682 4 100 v 761 4652 a(TTL165)p 1283 4682 V 475 w(A)h(74xx165)d (parallel-in-serial-out)f(shift)j(re)o(gister)p 3256 4682 V 515 4685 2744 4 v 513 4785 4 100 v 761 4755 a(TTL595)p 1283 4785 V 475 w(A)h(74xx595)d(serial-in-parallel-out)f(shift)j(re)o (gister)p 3256 4785 V Black Black eop end %%Page: 48 49 TeXDict begin 48 48 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.48) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(48)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.1) cvn /DEST pdfmark end 515 432 a 83 x Fj(8.1.1)99 b(USAR)l(T)515 696 y Fo(The)22 b(USAR)-5 b(T)23 b(module)e(is)i(a)g(full)f(duple)o(x)f(con\002gurable) f(USAR)-5 b(T)f(.)23 b(In)f(graphics)f(mode,)h(the)g(US-)515 795 y(AR)-5 b(T)21 b(will)g(display)f(its)i(output)d(in)i(a)g(console.) 26 b(In)20 b(addition,)f(the)i(console)f(will)h(accept)f(k)o(e)o (yboard)515 895 y(input.)515 1140 y SDict begin H.S end 515 1140 a 515 1140 a SDict begin 12 H.A end 515 1140 a 515 1140 a SDict begin [/View [/XYZ H.V]/Dest (section*.28) cvn /DEST pdfmark end 515 1140 a Fp(Attrib)n(utes)515 1320 y Fo(.tx)g(-)h(The)g Fh(.tx)g Fo(attrib)n(ute)f(is)i(the)f(USAR)-5 b(T)21 b(transmit)g(re)o(gister)-5 b(.)26 b(Data)21 b(written)f(to)h (this)g(attrib)n(ute)g(will)515 1420 y(initiate)26 b(a)h(transmission.) 42 b(The)25 b(USAR)-5 b(T)27 b(supports)e(a)i(transmit)f(FIFO,)g (making)f(it)i(possible)e(to)515 1520 y(stuf)n(f)20 b(se)n(v)o(eral)f (bytes)h(into)g(the)g(transmit)g(queue)f(while)h(the)h(program)d(under) g(test)k(is)f(paused.)515 1644 y(.rx)h(-)h(The)f Fh(.rx)i Fo(attrib)n(ute)e(is)i(the)e(USAR)-5 b(T)24 b(recei)n(v)o(er)d(re)o (gister)-5 b(.)32 b(Data)23 b(recei)n(v)o(ed)e(by)h(the)h(USAR)-5 b(T)24 b(is)515 1743 y(a)n(v)n(ailable)19 b(for)h(querying)e(through)g (here.)515 1868 y(.txbaud)g(-)j(The)e Fh(.txbaud)i Fo(attrib)n(ute)f (speci\002es)h(the)f(transmitter)f(baud)h(rate.)515 1992 y(.rxbaud)e(-)i(The)g(.rxbaud)e(attrib)n(ute)i(speci\002es)h(the)f (recei)n(v)o(er)f(baud)g(rate.)515 2116 y(.console)26 b(-)i(When)g(set)g(to)g Fh(true)p Fo(,)i(the)e(console)f(windo)n(w)f (will)j(display)e(recei)n(v)o(ed)f(data)i(and)f(will)515 2216 y(accept)20 b(k)o(e)o(yboard)d(entries)j(for)g(the)g(transmitter) -5 b(.)515 2340 y(.crlf)16 b(-)h(When)g(set)h(to)f Fh(true)p Fo(,)g(carriage)f(returns)g(and)g(line)h(feeds)g(generate)f(ne)n(w)g (lines)h(in)g(the)g(console)515 2440 y(windo)n(w)-5 b(.)515 2564 y(.he)o(x)17 b(-)h(When)g(set)h(to)f Fh(true)p Fo(,)g(the)g(data)g (is)h(assumed)f(to)g(be)g(binary)e(and)i(all)g(bytes)g(are)g(sho)n(wn)f (in)i(he)o(x.)515 2688 y(.loop)g(-)h(When)g(set)h(to)g(true,)e(recei)n (v)o(ed)g(characters)g(are)h(looped)f(back)g(to)i(the)f(transmitter)-5 b(.)515 2812 y(.xpos)19 b(-)h(horizontal)f(position)g(in)i(breadboard)c (windo)n(w)-5 b(.)515 2936 y(.ypos)19 b(-)h(v)o(ertical)g(position)f (in)i(breadboard)c(windo)n(w)-5 b(.)515 3182 y SDict begin H.S end 515 3182 a 515 3182 a SDict begin 12 H.A end 515 3182 a 515 3182 a SDict begin [/View [/XYZ H.V]/Dest (section*.29) cvn /DEST pdfmark end 515 3182 a Fp(I/O)20 b(Pins)515 3362 y Fo(.TXPIN)g(-)g(transmit)g(pin)515 3486 y(.RXPIN)g(-)h(recei)n(v)o(er)d(pin)515 3610 y(.CTS)j(-)f(Clear)g (to)h(send)f(pin.)k(This)d(can)f(be)g(left)g(unconnected)515 3735 y(.R)-5 b(TS)21 b(-)f(Request)g(to)h(send)e(pin.)515 3874 y SDict begin H.S end 515 3874 a 515 3874 a SDict begin 12 H.A end 515 3874 a 515 3874 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.2) cvn /DEST pdfmark end 515 3874 a 123 x Fj(8.1.2)99 b(Logic)515 4177 y Fo(The)30 b(only)h(attrib)n(utes)f(supported)f(be)i(the)g(logic)g(de)n(vices)f (are)h(the)g(standard)f Fh(.xpos)h Fo(and)f Fh(.ypos)515 4276 y Fo(breadboard)15 b(positions.)p 0.800781 0.800781 0.800781 TeXcolorrgb 24 w(FIXME)j(There)f(should)h(be)g(attrib)n(utes)g(to)g (specify)g(the)g(switching)g(char)n(-)515 4376 y(acteristics.)p Black 515 4638 a SDict begin H.S end 515 4638 a 515 4638 a SDict begin 14 H.A end 515 4638 a 515 4638 a SDict begin [/View [/XYZ H.V]/Dest (section*.30) cvn /DEST pdfmark end 515 4638 a Fj(and2)25 b(-)g(T)-7 b(w)o(o)25 b(input)h(AND)f (gate)515 4818 y SDict begin H.S end 515 4818 a 515 4818 a SDict begin 12 H.A end 515 4818 a 515 4818 a SDict begin [/View [/XYZ H.V]/Dest (section*.31) cvn /DEST pdfmark end 515 4818 a Fp(I/O)20 b(pins)515 4998 y Fo(.in0)f(-)i(First)g (input)p Black Black eop end %%Page: 49 50 TeXDict begin 49 49 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.49) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(49)p Black 515 515 a(.in1)19 b(-)i(First)g(input)515 632 y(.out)e(-)i(Output)515 880 y SDict begin H.S end 515 880 a 515 880 a SDict begin 14 H.A end 515 880 a 515 880 a SDict begin [/View [/XYZ H.V]/Dest (section*.32) cvn /DEST pdfmark end 515 880 a Fj(or2)k(-)g(T)-7 b(w)o(o)24 b(input)i(OR)f(gate)515 1052 y Fo(.in0)19 b(-)i(First)g(input)515 1169 y(.in1)e(-)i(First)g (input)515 1286 y(.out)e(-)i(Output)515 1533 y SDict begin H.S end 515 1533 a 515 1533 a SDict begin 14 H.A end 515 1533 a 515 1533 a SDict begin [/View [/XYZ H.V]/Dest (section*.33) cvn /DEST pdfmark end 515 1533 a Fj(xor2)j(-)h(T)-7 b(w)o(o)25 b(input)h(XOR)e(gate)515 1706 y Fo(.in0)19 b(-)i(First)g(input)515 1823 y(.in1)e(-)i(First)g(input)515 1939 y(.out)e(-)i(Output)515 2187 y SDict begin H.S end 515 2187 a 515 2187 a SDict begin 14 H.A end 515 2187 a 515 2187 a SDict begin [/View [/XYZ H.V]/Dest (section*.34) cvn /DEST pdfmark end 515 2187 a Fj(not)k(-)g(In)l(v)o(erter)515 2359 y Fo(.in0)19 b(-)i(Input)515 2476 y(.out)e(-)i(Output)515 2724 y SDict begin H.S end 515 2724 a 515 2724 a SDict begin 14 H.A end 515 2724 a 515 2724 a SDict begin [/View [/XYZ H.V]/Dest (section*.35) cvn /DEST pdfmark end 515 2724 a Fj(TTL377)k(-)h(Octal)e(Latch)515 2896 y Fo(The)k(TTL377)f (module)g(simulates)i(an)f(8-bit)g(parallel)h(latch)f(with)h(output)e (enable.)50 b(It)28 b(latches)515 2996 y(all)f(bits)g(simultaneously)e (so)i(that)f(connecting)e(an)j(output)e(to)i(an)f(input)g(gi)n(v)o(es)g (correct)f(results.)515 3096 y(Ho)n(we)n(v)o(er)m(,)18 b(this)j(is)g(not)f(guaranteed)d(where)j(multiple)g(modules)f(are)h(so) g(connected.)515 3212 y(.D0..7)f(-)h(Input)515 3329 y(.Q0..7)f(-)h (Output)515 3446 y(.E)g(-)g(output)f(enable)515 3562 y(.CP)i(-)f(clock)g(\(rising)f(edge\))515 3810 y SDict begin H.S end 515 3810 a 515 3810 a SDict begin 14 H.A end 515 3810 a 515 3810 a SDict begin [/View [/XYZ H.V]/Dest (section*.36) cvn /DEST pdfmark end 515 3810 a Fj(TTL165)25 b(-)h(P)o(arallel)d(to)i(Serial)g(Shift)h(Register)515 3983 y Fo(The)d(TTL165)g(module)f(simulates)i(an)g(8-bit)g(parallel)f (input)g(serial)i(output)d(shift)i(re)o(gister)-5 b(.)36 b(It)25 b(is)515 4082 y(particularly)17 b(useful)i(for)f(connecting)f (to)i(a)h(SPI)g(peripheral.)i(Note,)d(ho)n(we)n(v)o(er)m(,)e(that)i (the)g(common)515 4182 y(practice)g(of)h(daisy-chaining)e(such)i(shift) g(re)o(gisters)g(is)h(not)f(guaranteed)e(to)i(simulate)g(correctly)-5 b(.)515 4299 y(.D0..7)19 b(-)h(parallel)g(input)515 4415 y(.Ds)g(-)h(daisy-chain)d(serial)j(input)515 4532 y(.Q7)f(-)g(output) 515 4649 y(.nQ7)f(-)i(in)m(v)o(erted)d(output)515 4765 y(.CE)i(-)h(clock)e(enable)515 4882 y(.CP)i(-)f(clock)g(\(rising)f (edge\))515 4998 y(.PL)h(-)h(parallel)e(load)p Black Black eop end %%Page: 50 51 TeXDict begin 50 50 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.50) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(50)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 14 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.37) cvn /DEST pdfmark end 515 515 a Fj(TTL595)25 b(-)h(Serial)e(to)h(P)o(arallel)f(Shift)i(Register) 515 696 y Fo(The)d(TTL595)g(module)f(simulates)i(an)g(8-bit)g(serial)g (input)f(parallel)h(output)e(shift)i(re)o(gister)-5 b(.)36 b(It)25 b(is)515 795 y(particularly)17 b(useful)i(for)f(connecting)f (to)i(a)h(SPI)g(peripheral.)i(Note,)d(ho)n(we)n(v)o(er)m(,)e(that)i (the)g(common)515 895 y(practice)g(of)h(daisy-chaining)e(such)i(shift)g (re)o(gisters)g(is)h(not)f(guaranteed)e(to)i(simulate)g(correctly)-5 b(.)515 1020 y(.Q0..7)19 b(-)h(parallel)g(output)515 1144 y(.Ds)g(-)h(serial)f(input)515 1269 y(.Qs)g(-)h(daisy-chain)d (serial)j(output)515 1393 y(.OE)f(-)g(output)f(enable)515 1518 y(.SCK)i(-)f(shift)g(clock)g(\(rising)g(edge\))515 1642 y(.RCK)h(-)f(output)f(latch)h(clock)g(\(rising)g(edge\))515 1767 y(.MR)g(-)h(master)f(reset)515 1889 y SDict begin H.S end 515 1889 a 515 1889 a SDict begin 12 H.A end 515 1889 a 515 1889 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.3) cvn /DEST pdfmark end 515 1889 a 140 x Fj(8.1.3)99 b(I2C)24 b(EEPR)m(OM)515 2210 y Fo(There)14 b(are)h(currently)f(three)g (I2C)i(EEPR)m(OMs)f(supported:)21 b(I2C-EEPR)m(OM2k,)14 b(I2C-EEPR)m(OM16k,)515 2310 y(and)19 b(I2C-EEPR)m(OM256K.)515 2434 y(The)j(commands)f(')l(dump)g(e)i(module_name)c(\002lename')j(and) g(')o(load)g(e)h(module_name)c(\002lename')515 2534 y(can)j(be)g(used)f (to)i(sa)n(v)o(e)f(and)f(restore)h(the)g(contents)f(of)h(the)g(EEPR)m (OM)g(module.)29 b(This)22 b(allo)n(ws)h(the)515 2633 y(contents)c(of)h(the)g(EEPR)m(OM)g(to)h(be)f(preserv)o(ed)e(between)i (runs)f(of)h(gpsim.)515 2758 y(The)e(cells)i(of)e(the)h(EEPR)m(OM)f (can)h(be)f(e)o(xamined)f(and)h(modi\002ed)g(using)g(the)h(command)d (interf)o(ace)515 2858 y(with)26 b(the)g(commands)e ('module_name.eeData[inde)o(x)o(]')c(and)25 b('module_name.eeData[inde) o(x)o(])515 2957 y(=)18 b(ne)n(w_v)n(alue'.)j(The)d(follo)n(wing)d(e)o (xample)i(sho)n(ws)g(loading)f(an)i(EEPR)m(OM)f(module,)g(setting)g (cell)515 3057 y(16)j(to)g('0')f(\(0x30\))g(and)g(checking)g(that)h (the)g(ne)n(w)g(v)n(alue)g(w)o(as)h(written.)p Black Black 722 3264 a Fi(**gpsim>)40 b(module)i(load)f(I2C-EEPROM16k)d(e2) 722 3364 y(**gpsim>)722 3464 y(**gpsim>)i(e2.eeData[16])f(=)k($30)722 3563 y(**gpsim>)d(e2.eeData[16])722 3663 y(e2.eeData[$10])e(=)43 b($30)722 3762 y(**gpsim>)515 4008 y SDict begin H.S end 515 4008 a 515 4008 a SDict begin 12 H.A end 515 4008 a 515 4008 a SDict begin [/View [/XYZ H.V]/Dest (section*.38) cvn /DEST pdfmark end 515 4008 a Fp(I/O)20 b(Pins)515 4189 y Fo(.A0)g(-)g(Chip)g(select)h(to)f(set)h(bit)g(0)f(of)g(sla)n(v)o (e)h(address)515 4314 y(.A1)f(-)g(Chip)g(select)h(to)f(set)h(bit)g(1)f (of)g(sla)n(v)o(e)h(address)515 4438 y(.A2)f(-)g(Chip)g(select)h(to)f (set)h(bit)g(2)f(of)g(sla)n(v)o(e)h(address)515 4563 y(.SCL)g(-)f(I2C)g(serial)h(clock)515 4687 y(.SD)m(A)f(-)g(I2C)h (serial)f(data)515 4812 y(.WP)h(-)f(Hardw)o(are)f(write)i(protect)p Black Black eop end %%Page: 51 52 TeXDict begin 51 51 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.51) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(51)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.4) cvn /DEST pdfmark end 515 432 a 83 x Fj(8.1.4)99 b(Switches)25 b(&)g(Resistors)515 696 y Fo(The)g Fh(switc)o(h)g Fo(module)f(is)i(a)g(model)e(of)h(a)h (simple)f(tw)o(o)g(terminal)g(switch.)40 b(It)26 b(may)e(be)h (controlled)515 795 y(either)f(from)f(the)h(command)e(line)j(or)f(the)g (breadboard)d(GUI.)j(The)g Fh(switc)o(h)h Fo(module')-5 b(s)23 b(open)g(and)515 895 y(closed)18 b(resistance)h(are)g (controlled)e(by)i(attrib)n(utes.)24 b(Thus)19 b(a)g(tw)o(o)g(terminal) f(resistor)h(can)g(be)g(mod-)515 995 y(eled)h(as)h(a)f(switch)h(that)f (is)h(al)o(w)o(ays)g(closed)f(\(or)f(open\).)515 1241 y SDict begin H.S end 515 1241 a 515 1241 a SDict begin 12 H.A end 515 1241 a 515 1241 a SDict begin [/View [/XYZ H.V]/Dest (section*.39) cvn /DEST pdfmark end 515 1241 a Fp(Attrib)n(utes)515 1421 y Fo(.Ropen)g(-)h(Switch)h(resistance)f(in) g(ohms)g(when)f(the)i(switch)f(is)h(opened.)515 1546 y(.Rclosed)f(-)g(Switch)h(resistance)f(in)g(ohms)g(when)f(the)h(switch) h(is)g(closed.)515 1670 y(.state)30 b(-)h(Switch)f(state.)56 b(The)30 b(switch)g(state)h(tak)o(es)f(the)h(v)n(alues)e(of)h Fh(open)f Fo(or)h Fh(closed)p Fo(,)i(although)515 1770 y Fh(false)23 b Fo(for)g(open)f(and)h Fh(true)g Fo(for)g(closed)g(is)h (supported)d(for)i(backw)o(ard)e(compatibility)-5 b(.)33 b(The)22 b Fh(.state)515 1870 y Fo(attrib)n(ute)e(is)h(writable.)515 2116 y SDict begin H.S end 515 2116 a 515 2116 a SDict begin 12 H.A end 515 2116 a 515 2116 a SDict begin [/View [/XYZ H.V]/Dest (section*.40) cvn /DEST pdfmark end 515 2116 a Fp(I/O)f(Pins)515 2296 y Fo(.A)g(-)h(One)f(side)515 2421 y(.B)h(-)f(The)g(other)f(side)515 2543 y SDict begin H.S end 515 2543 a 515 2543 a SDict begin 12 H.A end 515 2543 a 515 2543 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.5) cvn /DEST pdfmark end 515 2543 a 140 x Fj(8.1.5)99 b(V)-10 b(oltage)24 b(Sour)n(ces,)i(Resistors,)e(and)i(Capacitors)515 2864 y Fo(The)e Fh(pullup)g Fo(and)g Fh(pulldown)g Fo(modules)g(are)g (tw)o(o)h(terminal)g(de)n(vices)f(with)h(one)f(terminal)g(tied)h(to)515 2963 y(a)j(v)n(oltage)g(source.)49 b(Their)27 b(v)n(oltage,)j (resistance,)g(and)e(pin)g(capacitance)f(are)h(controllable)f(via)515 3063 y(attrib)n(utes.)515 3309 y SDict begin H.S end 515 3309 a 515 3309 a SDict begin 12 H.A end 515 3309 a 515 3309 a SDict begin [/View [/XYZ H.V]/Dest (section*.41) cvn /DEST pdfmark end 515 3309 a Fp(Attrib)n(utes)515 3490 y Fo(.v)n(oltage)19 b(-)h(DC)h(v)n(oltage)515 3614 y(.resistance)f(-)g(resistance)g(in)g(ohms)g(between)f(the)i(I/O)f(pin) g(and)g(the)g(v)n(oltage)f(source.)515 3739 y(.capacitance)f(-)j (capacitance)e(in)h(f)o(arads)g(between)f(the)i(I/O)f(pin)g(and)f (ground.)515 3985 y SDict begin H.S end 515 3985 a 515 3985 a SDict begin 12 H.A end 515 3985 a 515 3985 a SDict begin [/View [/XYZ H.V]/Dest (section*.42) cvn /DEST pdfmark end 515 3985 a Fp(I/O)h(Pins)515 4165 y Fo(.pin)f(-)i(the)f (only)f(pin)h(e)o(xposed.)515 4305 y SDict begin H.S end 515 4305 a 515 4305 a SDict begin 12 H.A end 515 4305 a 515 4305 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.6) cvn /DEST pdfmark end 515 4305 a 123 x Fj(8.1.6)99 b(LED_7SEGMENTS)27 b(and)e(LED)515 4625 y SDict begin H.S end 515 4625 a 515 4625 a SDict begin 14 H.A end 515 4625 a 515 4625 a SDict begin [/View [/XYZ H.V]/Dest (section*.43) cvn /DEST pdfmark end 515 4625 a Fj(led_7segments)g(-)g(7)g (segment)g(common)g(cathode)h(LED)g(display)515 4805 y Fo(The)20 b(se)o(gments)f(are)h(numbered)e(as)j(per)f(the)g(follo)n (wing)e(\002gure.)p Black Black eop end %%Page: 52 53 TeXDict begin 52 52 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.52) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(52)p Black Black Black 853 515 a Fi(___)722 615 y(5)43 b(|)h(0)f(|)g(1)853 715 y(___)722 814 y(4)g(|)h(6)f(|)g(2)853 914 y(___)897 1013 y(3)515 1259 y SDict begin H.S end 515 1259 a 515 1259 a SDict begin 12 H.A end 515 1259 a 515 1259 a SDict begin [/View [/XYZ H.V]/Dest (section*.44) cvn /DEST pdfmark end 515 1259 a Fp(I/O)20 b(Pins)515 1440 y Fo(.cc)g(-)g(common)f (cathode)515 1564 y(.se)o(g0)g(-)i(se)o(gment)e(0)515 1689 y(.se)o(g1)g(-)i(se)o(gment)e(1)515 1814 y(.se)o(g2)g(-)i(se)o (gment)e(2)515 1938 y(.se)o(g3)g(-)i(se)o(gment)e(3)515 2063 y(.se)o(g4)g(-)i(se)o(gment)e(4)515 2187 y(.se)o(g5)g(-)i(se)o (gment)e(5)515 2312 y(.se)o(g6)g(-)i(se)o(gment)e(6)515 2574 y SDict begin H.S end 515 2574 a 515 2574 a SDict begin 14 H.A end 515 2574 a 515 2574 a SDict begin [/View [/XYZ H.V]/Dest (section*.45) cvn /DEST pdfmark end 515 2574 a Fj(Led)26 b(-)f(Simple)g(LED)515 2755 y Fo(The)c(simple)g(LED)g (is)h(a)g(single)f(pin)g(module)e(internally)h(tied)i(to)f(either)g (Vss)h(or)f(Vdd.By)f(def)o(ault)515 2854 y(the)15 b(LED)g(is)h (internally)e(tied)i(to)f(Vdd\(0V\))e(and)i(turns)g(on)g(when)f(the)i (pin)e(is)j(dri)n(v)o(en)c(high.Ho)n(we)n(v)o(er)m(,)515 2954 y(by)21 b(setting)h(the)g(Acti)n(v)o(eState)f(parameter)f(to)i(lo) n(w)-5 b(,)22 b(the)g(LED)f(is)i(internally)e(tied)h(to)f(Vss\(5V\))h (and)515 3054 y(turns)27 b(on)h(when)f(the)h(pin)f(is)i(dri)n(v)o(en)d (lo)n(w)-5 b(.Lik)o(e)27 b(a)h(real)g(LED,)g(the)f(module)g(will)i (either)e(sink)h(or)515 3153 y(source)19 b(current)g(from)g(the)h(dri)n (ving)f(line)h(which)g(may)g(af)n(fect)f(its)i(logic)f(le)n(v)o(el.)515 3278 y(The)g(LED)g(color)f(is)i(by)f(def)o(ault)f(red,)h(b)n(ut)g(can)g (be)g(set)h(to)g(other)e(colors.)515 3524 y SDict begin H.S end 515 3524 a 515 3524 a SDict begin 12 H.A end 515 3524 a 515 3524 a SDict begin [/View [/XYZ H.V]/Dest (section*.46) cvn /DEST pdfmark end 515 3524 a Fp(Attrib)n(utes)515 3704 y Fo(color)g(-)i(LED)f(color)m(,)e(possible)i(v)n(alues)g(red,)g (green,)f(yello)n(w)-5 b(,)19 b(orange)f(or)i(blue)515 3829 y(Acti)n(v)o(eState)g(-)g(LED)g(acti)n(v)o(e)g(state)h(mode,)e (possible)h(v)n(alues:)k(high)c(or)g(lo)n(w)515 4075 y SDict begin H.S end 515 4075 a 515 4075 a SDict begin 12 H.A end 515 4075 a 515 4075 a SDict begin [/View [/XYZ H.V]/Dest (section*.47) cvn /DEST pdfmark end 515 4075 a Fp(I/O)g(Pin)515 4255 y Fo(.in)g(-)g(dri)n(v)o(es)g(LED)515 4378 y SDict begin H.S end 515 4378 a 515 4378 a SDict begin 12 H.A end 515 4378 a 515 4378 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.1.7) cvn /DEST pdfmark end 515 4378 a 140 x Fj(8.1.7)99 b(I2C)24 b(sla)n(v)o(e)g(to)h(P)o(arallel)f (port)515 4699 y Fo(The)e(i2c2par)f(is)j(a)f(7)f(bit)h(address)f(I2C)h (module)e(with)i(an)g(8)f(bit)h(I/O)g(port.)32 b(The)22 b(direction)f(of)i(the)515 4798 y(I/O)h(port)f(is)h(determined)e(from)h (I2C)h(R/)1722 4782 y(\257)1694 4798 y Fh(W)35 b Fo(bit.)h(When)23 b(R/)2267 4782 y(\257)2239 4798 y Fh(W)35 b Fo(is)25 b(zero)e(the)h(I/O)g(port)f(outputs)g(the)515 4898 y(data)e(sent)g(by)g (the)g(master)g(de)n(vice.)26 b(Otherwise)21 b(the)g(port)f(is)i(set)g (as)g(an)f(input)f(port)h(and)f(when)h(the)515 4997 y(master)f(de)n (vice)f(requests)h(data,)g(the)g(port)g(is)h(read)e(and)h(transmitted)f (to)i(the)f(master)-5 b(.)p Black Black eop end %%Page: 53 54 TeXDict begin 53 53 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.53) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(53)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 12 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.48) cvn /DEST pdfmark end 515 515 a Fp(Attrib)n(utes)515 696 y Fo(.Sla)n(v)o(e_Address)18 b(-)j(I2C)f(7)g(bit)h(de)n(vice)e(address)515 942 y SDict begin H.S end 515 942 a 515 942 a SDict begin 12 H.A end 515 942 a 515 942 a SDict begin [/View [/XYZ H.V]/Dest (section*.49) cvn /DEST pdfmark end 515 942 a Fp(I/O)h(Pins)515 1122 y Fo(.p0..7)e(-)j(I/O)f(pins)515 1247 y(.SD)m(A)g(-)g(I2C)h (serial)f(data)515 1371 y(.SCL)h(-)f(I2c)g(serial)g(clock)515 1503 y SDict begin H.S end 515 1503 a 515 1503 a SDict begin 12 H.A end 515 1503 a 515 1503 a SDict begin [/View [/XYZ H.V]/Dest (section.8.2) cvn /DEST pdfmark end 515 1503 a 174 x Fk(8.2)119 b(Extras)28 b(Modules)515 1887 y Fo(In)20 b(addition)g(to)g(the)h(standard)f(modules,)f(modules)h(lar) o(gely)f(supplied)h(by)g(third)g(parties)g(are)h(sup-)515 1987 y(plied)f(in)g(the)g(libgpsim_e)o(xtras)e(library)-5 b(.)p 515 2041 2904 4 v 513 2141 4 100 v 747 2111 a(Name)p 1175 2141 V 475 w(Alias)p 1838 2141 V 839 w(Description)p 3417 2141 V 515 2144 2904 4 v 515 2161 V 513 2260 4 100 v 751 2230 a(dht11)p 1175 2260 V 472 w(dht11)p 1838 2260 V 468 w(T)f(emperature)18 b(and)h(humidity)g(sensor)p 3417 2260 V 515 2264 2904 4 v 513 2363 4 100 v 710 2333 a(DS1307)p 1175 2363 V 404 w(ds1307)p 1838 2363 V 398 w(64)h(x)h(8,)f(Serial,)g(I2C)g(Real-T)m(ime)g(Clock)p 3417 2363 V 515 2367 2904 4 v 513 2466 4 100 v 710 2436 a(DS1820)p 1175 2466 V 404 w(ds1820)p 1838 2466 V 259 w(High-Precision)f(1-W)m(ire)g(Digital)i(Thermometer)p 3417 2466 V 515 2470 2904 4 v 513 2569 4 100 v 687 2539 a(DS18S20)p 1175 2569 V 365 w(ds18s20)p 1838 2569 V 243 w(High-Precision)e(1-W)m(ire)g(Digital)i(Thermometer)p 3417 2569 V 515 2572 2904 4 v 513 2672 4 100 v 682 2642 a(DS18B20)p 1175 2672 V 357 w(ds18b20)p 1838 2672 V 237 w(High-Precision)e(1-W)m(ire)g(Digital)i(Thermometer)p 3417 2672 V 515 2675 2904 4 v 513 2775 4 100 v 655 2745 a(lcd_display)p 1175 2775 V 305 w(lcd_2X20)p 1838 2775 V 570 w(LCD)g(-)f(HD44780)e(2X20)p 3417 2775 V 515 2778 2904 4 v 513 2878 4 100 v 691 2848 a(lcd_20x4)p 1175 2878 V 351 w(lcd_20x4)p 1838 2878 V 588 w(LCD)j(-)f(HD44780)f(4x20)p 3417 2878 V 515 2881 2904 4 v 513 2981 4 100 v 650 2951 a(lcd_dt161A)p 1175 2981 V 320 w(lcd_2X8)p 1838 2981 V 622 w(LCD)i(-)f(HD44780)e(2x8)p 3417 2981 V 515 2984 2904 4 v 513 3084 4 100 v 629 3054 a(LCD100X32)p 1175 3084 V 226 w(LCD100X32)p 1838 3084 V 488 w(LCD)j(-)f(SED1530)f(100x32)p 3417 3084 V 515 3087 2904 4 v 513 3187 4 100 v 565 3157 a(OSRAM128X64)p 1175 3187 V 97 w(OSRAM128X64)p 1838 3187 V 425 w(LCD)i(-)f(SSD0323)f(128x64)p 3417 3187 V 515 3190 2904 4 v 513 3290 4 100 v 692 3260 a(lcd_7Se)o(g)p 1175 3290 V 359 w(lcd_7se)o(g)p 1838 3290 V 473 w(LCD)i(-)f(7)h(se)o (gment)e(no)h(controler)p 3417 3290 V 515 3293 2904 4 v 513 3393 4 100 v 758 3363 a(Solar)p 1175 3393 V 487 w(Solar)p 1838 3393 V 521 w(Solar)g(P)o(anel,)g(Controler)m(,)e (Battery)p 3417 3393 V 515 3396 2904 4 v 515 3517 a SDict begin H.S end 515 3517 a 515 3517 a SDict begin 12 H.A end 515 3517 a 515 3517 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.1) cvn /DEST pdfmark end 515 3517 a 102 x Fj(8.2.1)99 b(T)-9 b(emperatur)n(e)27 b(and)e(humidity)h(sensor)f(-)g (DHT11)515 3800 y Fo(This)32 b(module)f(emulates)h(the)g(DHT11)g (temperature/humidity)c(sensor)k(using)g(a)g(single-wire)515 3900 y(interf)o(ace.)515 4145 y SDict begin H.S end 515 4145 a 515 4145 a SDict begin 12 H.A end 515 4145 a 515 4145 a SDict begin [/View [/XYZ H.V]/Dest (section*.50) cvn /DEST pdfmark end 515 4145 a Fp(Attrib)n(utes)515 4326 y Fo(temperature)18 b(-)i(T)-6 b(emperature)19 b(de)o(gree)f(C)j (*)g(100)515 4451 y(humidity)d(-)j(Relati)n(v)o(e)f(humidity)f(\045)h (*)h(100)515 4697 y SDict begin H.S end 515 4697 a 515 4697 a SDict begin 12 H.A end 515 4697 a 515 4697 a SDict begin [/View [/XYZ H.V]/Dest (section*.51) cvn /DEST pdfmark end 515 4697 a Fp(I/O)f(Pins)515 4877 y Fo(.pin)f(-)i(Serial)f (I/O)h(pin)p Black Black eop end %%Page: 54 55 TeXDict begin 54 54 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.54) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(54)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.2) cvn /DEST pdfmark end 515 432 a 83 x Fj(8.2.2)99 b(64)24 b(x)h(8,)f(Serial,)h(I2C)g(Real-T)n(ime) g(Clock)g(-)g(DS1307)515 696 y Fo(This)c(module)e(emulates)i(the)g (Dallas)h(Semiconductor)c(DS1307)i(Real-T)m(ime)g(clock)h(which)f(also) 515 795 y(has)g(56)g(x)g(8)g(eeprom)f(memory)g(and)g(connects)h(via)g (an)g(I2C)g(serial)h(b)n(us.)515 1041 y SDict begin H.S end 515 1041 a 515 1041 a SDict begin 12 H.A end 515 1041 a 515 1041 a SDict begin [/View [/XYZ H.V]/Dest (section*.52) cvn /DEST pdfmark end 515 1041 a Fp(I/O)f(Pins)515 1222 y Fo(.SD)m(A)g(-)g(Serial)h(Data)f(Line)g(I/O)h(pin)515 1347 y(.SCL)g(-)f(Serial)g(Clock)g(Line)g(I/O)h(pin)515 1471 y(.SQW)g(-)f(Square)f(W)-7 b(a)n(v)o(e)21 b(Output)515 1610 y SDict begin H.S end 515 1610 a 515 1610 a SDict begin 12 H.A end 515 1610 a 515 1610 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.3) cvn /DEST pdfmark end 515 1610 a 124 x Fj(8.2.3)99 b(High-Pr)n(ecision)28 b(1-W)n(ir)n(e)h (Digital)e(Thermometer)k(-)d(DS1820)h(F)n(am-)814 1850 y(ily)515 2030 y Fo(These)24 b(modules)g(emulate)g(the)g(DS1820,)g (DS18S20)g(and)g(DS18B20)f(High-Precision)g(1-W)m(ire)515 2130 y(Digital)d(Thermometers.These)d(de)n(vices)j(uses)g(a)h (single-wire)e(b)n(us)i(interf)o(ace.)515 2376 y SDict begin H.S end 515 2376 a 515 2376 a SDict begin 12 H.A end 515 2376 a 515 2376 a SDict begin [/View [/XYZ H.V]/Dest (section*.53) cvn /DEST pdfmark end 515 2376 a Fp(Attrib)n(utes)515 2557 y Fo(R)m(OMCode)f(-)g(De)n(vice)g(R)m(OM)g(code)515 2681 y(temperature)e(-)i(T)-6 b(emperature)19 b(of)g(de)n(vice)515 2806 y(po)n(wered)f(-)j(De)n(vice)e(is)j(self)e(po)n(wered)515 2930 y(alarm_th)f(-)h(T)-6 b(emperature)18 b(high)h(alarm)h(re)o (gister)515 3055 y(alarm_tl)f(-)i(T)-6 b(emperature)18 b(lo)n(w)i(alarm)g(re)o(gister)515 3179 y(con\002g_re)o(gister)d(-)k(V) -9 b(alue)19 b(of)h(con\002guration)e(re)o(gister)h(\(ds18B20)g(only\)) 515 3425 y SDict begin H.S end 515 3425 a 515 3425 a SDict begin 12 H.A end 515 3425 a 515 3425 a SDict begin [/View [/XYZ H.V]/Dest (section*.54) cvn /DEST pdfmark end 515 3425 a Fp(I/O)h(Pins)515 3606 y Fo(.pin)f(-)i(Serial)f(I/O)h(pin) 515 3745 y SDict begin H.S end 515 3745 a 515 3745 a SDict begin 12 H.A end 515 3745 a 515 3745 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.4) cvn /DEST pdfmark end 515 3745 a 123 x Fj(8.2.4)99 b(Character)26 b(LCD)f(-)g(HD44780)515 4049 y Fo(The)k(library)g(libgpsim_lcd)f(contains)h(se)n(v)o(eral)g (LCD)h(display)g(formats)f(using)g(the)h(HD44780)515 4149 y(controller)-5 b(.)p 515 4186 1194 4 v 513 4286 4 100 v 661 4256 a(Name)p 1005 4286 V 304 w(Description)p 1706 4286 V 515 4289 1194 4 v 515 4305 V 513 4405 4 100 v 569 4375 a(lcd_display)p 1005 4405 V 102 w(20)20 b(col)g(2)g(ro)n(w)g (LCD)p 1706 4405 V 515 4408 1194 4 v 513 4508 4 100 v 606 4478 a(lcd_20x4)p 1005 4508 V 138 w(20)g(col)g(4)g(ro)n(w)g(LCD)p 1706 4508 V 515 4511 1194 4 v 513 4611 4 100 v 565 4581 a(lcd_dt161A)p 1005 4611 V 96 w(16)g(col)g(1)g(ro)n(w)g(LCD)p 1706 4611 V 515 4614 1194 4 v Black Black eop end %%Page: 55 56 TeXDict begin 55 55 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.55) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(55)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 14 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.55) cvn /DEST pdfmark end 515 515 a Fj(I/O)24 b(Pins)515 692 y Fo(.DC)d(-)f(Data)g(/)h(command)d (select)515 812 y(.R)-5 b(W)21 b(-)g(Read/Write)f(select)515 933 y(.E)g(-)g(start)h(data)f(read/write)515 1053 y(.d0-7)e(-)j(data)f (b)n(us)515 1172 y SDict begin H.S end 515 1172 a 515 1172 a SDict begin 12 H.A end 515 1172 a 515 1172 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.5) cvn /DEST pdfmark end 515 1172 a 136 x Fj(8.2.5)99 b(Graphic)25 b(LCD)g(-)g(SED1530) 515 1484 y Fo(This)30 b(module)f(emulates)h(a)h(100X32)d(pix)o(el)i (graphics)f(LCD)i(based)f(on)g(dual)g(SED1350)e(con-)515 1584 y(trollers.)515 1702 y SDict begin H.S end 515 1702 a 515 1702 a SDict begin 12 H.A end 515 1702 a 515 1702 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.6) cvn /DEST pdfmark end 515 1702 a 137 x Fj(8.2.6)99 b(LCD_7Seg)515 2015 y Fo(A)23 b(7)h(se)o(gment)e(LCD)i(display)e(without)h(a)g (controller)-5 b(.)33 b(If)23 b(common)e(>)j(2.5V)-11 b(,)23 b(\(cc-)f(se)o(gn\))h(>)g(1.4V)515 2115 y(se)o(gment)c(is)i(on)f (otherwise)f(se)o(gment)h(is)h(of)n(f.)515 2235 y(The)f(se)o(gments)f (are)h(numbered)e(as)j(per)f(the)g(follo)n(wing)e(\002gure.)p Black Black 853 2418 a Fi(___)722 2518 y(5)43 b(|)h(0)f(|)g(1)853 2617 y(___)722 2717 y(4)g(|)h(6)f(|)g(2)853 2816 y(___)897 2916 y(3)515 3154 y SDict begin H.S end 515 3154 a 515 3154 a SDict begin 12 H.A end 515 3154 a 515 3154 a SDict begin [/View [/XYZ H.V]/Dest (section*.56) cvn /DEST pdfmark end 515 3154 a Fp(I/O)20 b(Pins)515 3331 y Fo(.cc)g(-)g(common) 515 3451 y(.se)o(g0-6)e(-)j(7)f(se)o(gment)f(dri)n(v)o(es)515 3587 y SDict begin H.S end 515 3587 a 515 3587 a SDict begin 12 H.A end 515 3587 a 515 3587 a SDict begin [/View [/XYZ H.V]/Dest (subsection.8.2.7) cvn /DEST pdfmark end 515 3587 a 119 x Fj(8.2.7)99 b(Solar)515 3882 y Fo(This)26 b(module)e(emulates)i(a)g(20)f(W)-7 b(att)28 b(solar)d(panel,)i(a)f (20mah)e(battery)-5 b(,)26 b(and)f(a)i(PWM)f(controler)515 3982 y(for)19 b(testing)h(control)f(strate)o(gies)h(for)g(the)g (controler)-5 b(.)515 4220 y SDict begin H.S end 515 4220 a 515 4220 a SDict begin 12 H.A end 515 4220 a 515 4220 a SDict begin [/View [/XYZ H.V]/Dest (section*.57) cvn /DEST pdfmark end 515 4220 a Fp(Attrib)n(utes)515 4396 y Fo(Aof)n(fset)19 b(-)i(V)-11 b(oltage)20 b(on)f(Asol)i(pin)f(for)f (zero)h(panel)g(current)515 4517 y(Ascale)g(-)h(V)-11 b(oltage/Amp)19 b(panel)g(current)g(scale)i(f)o(actor)e(for)h(Asol)515 4637 y(VSscale)h(-)f(scale)h(f)o(actor)e(for)h(Vsol)g(pin)515 4758 y(VBscale)h(-)f(scale)h(f)o(actor)e(for)h(Vbat)g(pin)515 4878 y(inductor)e(-)j(controler)d(inductor)h(size)h(in)h(Henries)515 4998 y(BDOC)g(-)g(Battery)f(de)o(gree)e(of)i(char)o(ge)f(\045)p Black Black eop end %%Page: 56 57 TeXDict begin 56 56 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.56) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(56)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 12 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.58) cvn /DEST pdfmark end 515 515 a Fp(I/O)20 b(Pins)515 696 y Fo(.Vsol)g(-)g(Solar)g(P)o(anel)g (output)f(V)-11 b(oltage)515 820 y(.Asol)20 b(-)g(Solar)g(P)o(anel)g (output)f(current)515 945 y(.Vbat)h(-)g(Battery)g(V)-11 b(oltage)515 1069 y(.PWM)21 b(-)f(Pulse)h(W)m(idth)f(Modulation)e (signal)515 1194 y(.OK)i(-)h(PWM)g(is)g(enabled)515 1326 y SDict begin H.S end 515 1326 a 515 1326 a SDict begin 12 H.A end 515 1326 a 515 1326 a SDict begin [/View [/XYZ H.V]/Dest (section.8.3) cvn /DEST pdfmark end 515 1326 a 173 x Fk(8.3)119 b(Writing)30 b(new)h(modules)515 1710 y Fo(A)19 b(module)f(is)i(a)g(library)e(of)h(code.)24 b(On)19 b(W)m(indo)n(ws)g(the)g(library)f(is)i(a)g(.DLL)f(and)f(on)h (Unix)g(a)g(shared)515 1809 y(library)-5 b(.)23 b(There)18 b(are)g(a)h(fe)n(w)g(details)g(that)g(a)g(module)e(must)i(adhere)e(to,) i(b)n(ut)g(in)g(general)e(the)i(module)515 1909 y(has)h(full)g(access)h (to)f(gpsim')-5 b(s)20 b(API.)515 2033 y(The)26 b(easiest)i(w)o(ay)f (to)h(write)f(a)g(ne)n(w)g(module)f(is)i(to)f(start)h(from)e(the)h (source)f(code)g(from)g(one)h(of)515 2133 y(the)d(e)o(xisting)f (modules.)34 b(F)o(or)24 b(e)o(xample,)f(suppose)f(your)h(project)g (produces)f(a)i(serial)g(bit-stream)515 2233 y(in)c(PPM)h(coding)e(and) h(you)g(w)o(ant)g(to)h(display)f(the)g(output)g(during)e(the)j (simulation.)k(The)20 b(e)o(xternal)515 2332 y(module)g(you)h(need)g (is)i(similar)f(to)g(the)g(usart)g(module)f(b)n(ut)h(not)f(the)h(same,) g(so)h(start)f(by)g(making)e(a)515 2432 y(cop)o(y)f(of)h(the)g(usart)g (module)f(and)h(then)f(modify)g(it)i(to)f(w)o(ork)g(ho)n(w)g(you)f (need.)515 2556 y(T)-7 b(o)15 b(be)h(able)f(to)h(load)f(your)f(module)h (into)g(gpsim)g(it)h(needs)f(to)h(be)g(in)f(a)h(library)-5 b(.)22 b(Usually)16 b(you)e(will)j(be)515 2656 y(creating)k(a)h(ne)n(w) f(library)g(just)i(for)e(one)g(de)n(vice,)g(b)n(ut)h(sometimes)g(you)e (will)j(ha)n(v)o(e)e(a)i(fe)n(w)e(de)n(vices.)515 2756 y(Either)c(w)o(ay)-5 b(,)19 b(the)f(library)f(must)h(declare)g(to)g (gpsim)g(what)g(de)n(vices)g(it)h(contains.)24 b(This)18 b(is)h(achie)n(v)o(ed)515 2855 y(with)g(an)g(array)f(of)g(Module_T)-7 b(ypes)17 b(class)j(instances,)f(returned)e(to)i(gpsim)g(by)f(a)h (function)f(named)515 2955 y(\223get_mod_list\224.)30 b(All)24 b(gpsim)e(module)g(libraries)g(must)h(declare)f(this)h (function.)32 b(Y)-9 b(ou)22 b(can)g(cop)o(y)515 3055 y(the)d(required)f(template)h(from)g(the)h(gpsim)f(source)g(\226)h (probably)d(one)i(of)g(the)h(\223e)o(xtras\224)f(modules)g(is)515 3154 y(slightly)g(cleaner)h(than)f(the)h(main)g(library)-5 b(.)23 b(F)o(or)d(our)f(PPM)h(decoder)f(e)o(xample,)f(we)i(might)g(ha)n (v)o(e)f(a)515 3254 y(module_manager)-5 b(.cc)16 b(containing)i(the)i (follo)n(wing)f(code:)p Black Black 722 3461 a Fi(/*)43 b(IN_MODULE)d(should)h(be)i(defined)d(for)i(modules)f(*/)722 3561 y(#define)g(IN_MODULE)722 3661 y(#include)f()722 3760 y(#include)g()722 3860 y(#include)g("ppm.h")722 3959 y(Module_Types)f(available_modul)o(es[)o(])e(=)722 4059 y({)809 4159 y({)44 b("ppm_display",)37 b("ppm_rx_iface",)g (PpmDisplay::const)o(ru)o(ct})o(,)809 4258 y(//)43 b(No)g(more)f (modules)809 4358 y({)i(NULL,NULL,NULL})722 4458 y(};)722 4557 y(#ifdef)d(__cplusplus)722 4657 y(extern)g("C")i({)722 4756 y(#endif)e(/*)i(__cplusplus)c(*/)722 4856 y(/****************)o (**)o(**)o(***)o(**)o(**)o(***)o(**)o(**)o(***)o(**)o(**)o(***)o(**)o (***)o(**)o(**)o(***)o(**)o(**)o(***)o(**)766 4956 y(*)k(get_mod_list)c (-)k(Report)e(all)h(of)h(the)f(modules)f(in)h(this)g(library.)p Black Black eop end %%Page: 57 58 TeXDict begin 57 57 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.57) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(8.)45 b(MODULES)1872 b Fo(57)p Black 766 515 a Fi(*)766 615 y(*)43 b(This)f(is)h(a)g(required)d(function)g (for)i(gpsim)g(compliant)e(libraries.)766 715 y(*/)809 814 y(Module_Types)f(*)k(get_mod_list\(voi)o(d\))809 914 y({)897 1013 y(return)e(available_modul)o(es)o(;)809 1113 y(})722 1213 y(#ifdef)g(__cplusplus)722 1312 y(})722 1412 y(#endif)g(/*)i(__cplusplus)c(*/)515 1619 y Fo(This)22 b(declares)g(that)g(this)h(library)e(pro)o(vides)f(one)i(module,)f (called)h(ppm_display)-5 b(,)19 b(implemented)515 1719 y(by)f(the)i(C++)f(class)h(PpmDisplay)-5 b(.)24 b(The)18 b(class)i(which)f(implements)f(the)h(module)f(must)h(pro)o(vide)e(a)515 1819 y(static)k(method)e(\223construct\224)f(to)j(create)f(a)g(ne)n(w)g (instance)g(of)g(the)g(class.)26 b(F)o(or)20 b(e)o(xample:)p Black Black 722 2026 a Fi(Module)41 b(*)i(PpmDisplay::const)o(ru)o (ct\()o(co)o(ns)o(t)38 b(char)j(*_new_name=0\))722 2126 y({)897 2226 y(PpmDisplay)e(*ppmd)i(=)j(new)e(PpmDisplay\(_new)o(_na)o (me)o(\);)897 2325 y(ppmd->create_io)o(pi)o(n_m)o(ap)o(\(\))o(;)897 2425 y(ppmd->create_wi)o(nd)o(ow\()o(_n)o(ew)o(_na)o(me)o(\);)897 2524 y(return)f(ppmd;)722 2624 y(})515 2832 y Fo(Y)-9 b(our)18 b(module)g(will)i(need)e(to)i(include)e(stimuli)h(for)g(its)h (I/O)g(connections.)i(Y)-9 b(ou)19 b(can)g(use)g(the)h(stan-)515 2931 y(dard)14 b(gpsim)h(stimulus)g(classes:)24 b(IOPIN,)15 b(io_bidirectional,)e(io_bidirectional_pu,)f(io_open_collector)-5 b(.)515 3031 y(In)17 b(man)o(y)f(cases,)j(ho)n(we)n(v)o(er)m(,)c(you)i (will)h(w)o(ant)f(to)h(deri)n(v)o(e)e(your)g(o)n(wn)h(class)h(from)f (one)g(of)g(them.)23 b(This)515 3130 y(will)e(allo)n(w)f(you)f(to)h (customise)g(the)h(actions)e(when)h(the)g(node)f(state)i(changes.)j(F)o (or)c(e)o(xample:)p Black Black 722 3338 a Fi(class)42 b(DecoderPin)d(:)k(public)e(IOPIN)722 3438 y({)722 3537 y(private:)897 3637 y(PpmDisplay)e(*)k(Parent;)722 3737 y(public:)897 3836 y(DecoderPin)c(\()k(PpmDisplay)c(*)44 b(parent,)c(unsigned)g(int)j(b,)f(const)g(char)g(*)h(name=0)e(\);)897 3936 y(virtual)f(void)i(setDrivenState\(b)o(oo)o(l)c(new_state\);)722 4035 y(};)515 4243 y Fo(The)24 b(only)f(methods)g(we)i(pro)o(vide)d (here)i(are)g(the)h(constructor)d(and)i(an)g(o)o(v)o(erridden)d (\223setDri)n(v)o(en-)515 4343 y(State\224.)31 b(This)22 b(is)h(because)f(our)f(PPM)i(decoder)d(needs)i(to)g(be)g(told)g(when)f (the)h(input)g(pin)g(changes)515 4442 y(state.)p Black Black eop end %%Page: 58 59 TeXDict begin 58 58 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.58) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.9) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(9)515 1603 y Fq(Symbolic)52 b(Deb)l(ugging)515 2060 y Fo(gpsim)19 b(maintains)h(a)h(symbol)e (table.)515 2184 y()p Black 1905 5208 a(58)p Black eop end %%Page: 59 60 TeXDict begin 59 59 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.59) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.10) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(10)515 1603 y Fq(Macr)l(os)515 2060 y Fo()p Black 1905 5208 a(59)p Black eop end %%Page: 60 61 TeXDict begin 60 60 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.60) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.11) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(11)515 1603 y Fq(Hex)51 b(Files)515 2060 y Fo(The)20 b(tar)o(get)h(code)f(simulated)g(by)h(gpsim)f(can)h (be)g(supplied)f(by)h(a)g(he)o(x)f(\002le,)i(or)f(more)f (speci\002cally)515 2159 y(an)f(Intel)g(He)o(x)g(\002le.)25 b(gpsim)19 b(accepts)g(the)g(format)g(of)g(he)o(x)f(pro)o(vided)f(by)i (gpasm)f(and)h(mpasm.)24 b(The)515 2259 y(he)o(x)h(\002le)i(does)e(not) h(pro)o(vide)e(an)o(y)h(symbolic)g(information.)40 b(It')-5 b(s)26 b(recommended)d(that)j(he)o(x)g(\002les)515 2358 y(only)c(be)g(used)h(if)g(1\))f(you)g(suspect)h(there')-5 b(s)22 b(a)i(problem)d(with)h(the)h(w)o(ay)g(.cod)f(\002les)i(are)e (generated)515 2458 y(by)30 b(your)g(assembler)g(or)g(compiler)g(OR)h (2\))g(your)e(assembler)i(or)f(compiler)g(doesn')o(t)f(generate)515 2558 y(.cod)f(\002les.)51 b(Also,)30 b(you)e(must)h(supply)e(a)i (processor)e(when)h(loading)g(he)o(x)f(\002les.)51 b(See)29 b(the)g(load)515 2657 y(command.)p Black 1905 5208 a(60)p Black eop end %%Page: 61 62 TeXDict begin 61 61 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.61) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.12) cvn /DEST pdfmark end 515 432 a 730 x Fl(Chapter)44 b(12)515 1601 y Fq(The)51 b(ICD-)h(Not)g (Supported)e(in)515 1850 y(v)n(ersions)i(0.21.0)g(and)g(later)515 2306 y Fo(gpsim)27 b(supports)g(\(partly\))f(the)i(\002rst)h(v)o (ersion)e(of)g(the)h(ICD)g(\(as)h(opposed)d(to)i(ICD2)g(\(the)f(round) 515 2406 y(hock)o(e)o(y-puck)16 b(shaped)k(one\)\).)515 2667 y SDict begin H.S end 515 2667 a 515 2667 a SDict begin 14 H.A end 515 2667 a 515 2667 a SDict begin [/View [/XYZ H.V]/Dest (section*.59) cvn /DEST pdfmark end 515 2667 a Fj(Special)25 b(con\002guration)h(of)f(the)h(code)515 2847 y Fo(Read)20 b(the)g(MPLAB)h(ICD)g(USER')-5 b(s)21 b(GUIDE.)515 2971 y(Here')-5 b(s)20 b(the)g(short)g(v)o(ersion:)p Black 639 3158 a Fc(\017)p Black 41 w Fo(disable)31 b(at)h(least:)48 b(bro)n(wn)30 b(out)h(detection,)h(lo)n(w)g(v)n(oltage)e(programming)e (and)i(all)i(code)722 3257 y(protection.)23 b(It)c(is)g(probably)d (good)h(to)i(turn)e(of)h(the)h(w)o(atchdog)e(too.)24 b(see)19 b(the)f(MPLAB)h(ICD)722 3357 y(USER')-5 b(s)22 b(GUIDE)e(for)f(more)g(information.)p Black 639 3522 a Fc(\017)p Black 41 w Fo(ha)n(v)o(e)h(a)h(NOP)f(as)h(the)f(\002rst)h (instruction.)p Black 639 3686 a Fc(\017)p Black 41 w Fo(Don')o(t)e(touch)g(RB6)i(or)f(RB7.)p Black 639 3851 a Fc(\017)p Black 41 w Fo(Don')o(t)f(use)i(the)f(last)h(stack)f(le)n(v) o(el.)p Black 639 4015 a Fc(\017)p Black 41 w Fo(Don')o(t)f(use)i (these)f(re)o(gisters)g(and)f(program)f(w)o(ords:)p 722 4045 2532 4 v 721 4144 4 100 v 772 4114 a(Processor)p 1143 4144 V 643 w(Re)o(gister)p 2608 4144 V 774 w(Program)p 3252 4144 V 722 4148 2532 4 v 722 4164 V 721 4264 4 100 v 793 4234 a(-870/1/2)p 1143 4264 V 493 w(0x70,)h(0xBB-0xBF)p 2608 4264 V 516 w(0x6E0-0x7FF)p 3252 4264 V 722 4267 2532 4 v 721 4367 4 100 v 825 4337 a(-873/4)p 1143 4367 V 151 w(0x6D,)g(0x1fD,)f(0xEB-0xF0,)g(0x1Eb-0x1F0)p 2608 4367 V 130 w(0xEE0-0xFFF)p 3252 4367 V 722 4370 2532 4 v 721 4470 4 100 v 825 4440 a(-876/7)p 1143 4470 V 506 w(0x70,)g(0x1Eb-0x1Ef)p 2608 4470 V 450 w(0x1F00-0x1FFF)p 3252 4470 V 722 4473 2532 4 v 515 4695 a SDict begin H.S end 515 4695 a 515 4695 a SDict begin 14 H.A end 515 4695 a 515 4695 a SDict begin [/View [/XYZ H.V]/Dest (section*.60) cvn /DEST pdfmark end 515 4695 a Fj(icdpr)n(og)515 4875 y Fo(Do)n(wnload)g(and)i(install)h(icdprog.)515 4998 y(Use)g(icdprog)d(to)i(program)e(the)j(tar)o(get)e(with)h(the)g (he)o(x)g(\002le)h(\()p Fh(icdpr)l(o)o(g)e(mycode)o(.he)n(x)p Fo(\).)p Black 1905 5208 a(61)p Black eop end %%Page: 62 63 TeXDict begin 62 62 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.62) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)17 b(12.)39 b(THE)16 b(ICD-)h(NO)m(T)f(SUPPOR)-5 b(TED)16 b(IN)h(VERSIONS)f(0.21.0)e(AND)j(LA)-9 b(TER)p Fo(62)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 14 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.61) cvn /DEST pdfmark end 515 515 a Fj(ICD)24 b(usage)515 696 y Fo(Start)c(gpsim)g(lik) o(e)h(this:)515 820 y Fh(gpsim)f(-d)g(/de)o(v/ttyS0)f(-s)h(mycode)o (.cod)515 945 y Fo(,)g(assuming)g(the)g(ICD)h(is)g(connected)d(to)i (the)h(\002rst)g(serial)f(port.)515 1069 y(No)n(w)g(you)f(can)h(type)g ('icd')f(to)i(see)f(some)g(information:)515 1194 y Fh(**gpsim>)f(icd) 515 1294 y(ICD)h(ver)o(sion)h("2.31.00")c(was)k(found.)515 1393 y(T)-8 b(ar)m(g)o(et)20 b(contr)l(oller)g(is)i(16F877)c(r)m(e)o(v) i(13.)515 1493 y(Vdd:)k(5.2)19 b(Vpp:)25 b(13.3)515 1593 y(Deb)n(ug)19 b(module)g(is)i(pr)m(esent)515 1717 y Fo(2.31)e(is)i(the) f(\002rmw)o(are)g(v)o(ersion.)j(I)e(ha)n(v)o(e)e(only)h(tried)g(this)g (particular)f(v)o(ersion...)515 1842 y(Y)-9 b(ou)23 b(can)h(step,)h (reset,)h(run,)e(halt,)h(set)g(the)f(breakpoint)e(and)h(read)h(\002le)h (re)o(gisters.)36 b(It)25 b(w)o(orks)e(both)515 1941 y(from)c(the)h(GUI)g(and)g(the)g(cli.)515 2204 y SDict begin H.S end 515 2204 a 515 2204 a SDict begin 14 H.A end 515 2204 a 515 2204 a SDict begin [/View [/XYZ H.V]/Dest (section*.62) cvn /DEST pdfmark end 515 2204 a Fj(ICD)k(T)n(ODO)p Black 639 2384 a Fc(\017)p Black 41 w Fo(MPLAB)d(has)f(a)h(setting)f (for)g(tar)o(get)f(CPU)i(frequenc)o(y)-5 b(,)17 b(I)k(ha)n(v)o(e)e (only)g(tried)h(with)h(a)f(20MHz)722 2484 y(crystal,)e(so)f(there)g (may)f(be)h(adjustments)f(to)i(be)f(made)f(to)h(the)g(serial)h(port)e (timeout)g(settings)722 2584 y(in)21 b(gpsim.)p Black 639 2750 a Fc(\017)p Black 41 w Fo(The)d(source,)f(disassembly)-5 b(,)18 b(w)o(atch,)g(symbol)f(and)h(RAM)g(windo)n(ws)g(w)o(orks.)23 b(And)18 b(the)g(rest)722 2849 y(doesn')o(t.)26 b(I)21 b(guess)g(the)g(breadboard)d(should)i(be)h(able)f(to)h(w)o(ork)g(at)g (least)h(for)e(the)h(pic,)g(b)n(ut)g(it)722 2949 y(doesn')o(t.)p Black 639 3115 a Fc(\017)p Black 41 w Fo(EEPR)m(OM)f(support)p Black 639 3281 a Fc(\017)p Black 41 w Fo(modifying)e(data)p Black 639 3447 a Fc(\017)p Black 41 w Fo(Fix)j(the)f(UI)g(to)h(gi)n(v)o (e)e(more)g(feedback)g(about)g(what')-5 b(s)21 b(happening)c(during)i (long)g(delays.)p Black 639 3613 a Fc(\017)p Black 41 w Fo(Better)i(error)e(detection.)24 b(gpsim)c(doesn')o(t)e(al)o(w)o (ays)j(see)g(that)f(the)g(tar)o(get)f(is)j(not)d(functional.)p Black Black eop end %%Page: 63 64 TeXDict begin 63 63 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.63) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.13) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(13)515 1603 y Fq(Examples)515 2060 y Fo(The)27 b Fh(e)n(xamples/)36 b Fo(subdirectory)24 b(contains)j(se)n(v)o(eral)f(e)o(xamples.)45 b(The)27 b Fh(e)n(xamples/pr)l(ojects/)36 b Fo(sub-)515 2159 y(directory)29 b(demonstrate)g(sample)h(projects)g(that)h(can)f(serv)o(e)g(as)i (templates)e(for)g(ne)n(w)g(projects.)515 2259 y(In)24 b(addition,)f(the)h Fh(e)n(xamples/modules)f Fo(subdirectory)e (contains)j(se)n(v)o(eral)f(e)o(xamples)g(illustrating)515 2358 y(ho)n(w)h(to)h(use)g(gpsim')-5 b(s)24 b(v)n(arious)g(modules.)37 b(Finally)-5 b(,)25 b(as)g(described)f(in)h(chapter)e Fp(??)o Fo(,)j(gpsim')-5 b(s)25 b(re-)515 2458 y(gression)e(tests)i (illustrate)e(man)o(y)g(po)n(werful)f(deb)n(ugging)f(techniques)h(that) i(ha)n(v)o(e)f(not)g(been)g(fully)515 2558 y(documented.)515 2804 y SDict begin H.S end 515 2804 a 515 2804 a SDict begin 12 H.A end 515 2804 a 515 2804 a SDict begin [/View [/XYZ H.V]/Dest (section*.63) cvn /DEST pdfmark end 515 2804 a Fp(usart_gui)c(example)515 2984 y Fo(Each)31 b(e)o(xample)f (contains)h(a)i(brief)e Fh(README)i Fo(e)o(xplaining)c(its)k(purpose.) 58 b(F)o(or)32 b(e)o(xample,)h(the)515 3084 y Fh(README)21 b Fo(for)f(the)g Fh(usart_gui)f Fo(e)o(xample)g(in)h(the)h Fh(e)n(xamples/modules)d Fo(directory)h(contains)p Black Black 722 3291 a Fi(The)43 b(tests)e(the)h(USART)g(module)f(with)h(the) g(GUI)g(fix.)722 3391 y(The)h(code)e(for)i(a)g(16f628)e(PIC)h(is)h (used.)e(The)i(code)f(first)f(transmits)f(a)j(string)e(of)722 3491 y(characters,)e(which)j(are)g(instructions)c(to)43 b(the)f(user,)g(to)h(the)f(USART)f(module)g(which)722 3590 y(will)h(then)g(be)h(displayed)d(on)i(its)h(GUI.)e(This)h (verifies)f(that)g(the)i(USART)e(can)h(receive)722 3690 y(serial)f(data.)722 3789 y(When)h(the)g(focus)g(is)h(on)f(the)h(USART) e(GUI)h(window,)f(characters)e(typed)j(on)h(the)f(keyboard)722 3889 y(are)h(sent)e(from)h(the)h(USART)e(to)i(the)f(PIC)g(and)h(then)f (retransmitted)c(from)k(the)g(PIC)g(back)722 3989 y(to)h(the)f(USART.) 722 4088 y(If)h(all)f(works,)f(the)i(typed)e(characters)e(will)j(be)h (displayed)d(in)j(the)f(GUI)g(text)g(window)722 4188 y(of)h(the)f(USART.)f(Both)h(transmit)e(and)j(receive)d(must)i(be)h (functioning)c(for)j(this)g(to)722 4288 y(happen.)515 4495 y Fh(F)l(ixme)20 b Fo(-)h(we)f(really)g(need)f(to)i(document)d (all)j(of)f(the)g(e)o(xamples!)p Black 1905 5208 a(63)p Black eop end %%Page: 64 65 TeXDict begin 64 64 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.64) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.14) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(14)515 1603 y Fq(Regr)l(ession)52 b(T)-19 b(ests)515 2060 y Fo(Starting)25 b(with)h(v)o(ersion)f(0.22.0,) g(gpsim)h(distrib)n(utes)g(re)o(gression)e(tests.)44 b(The)25 b(purpose)g(of)g(a)i(re-)515 2159 y(gression)j(test)i(is)g(to) f(v)n(alidate)g(correctness.)56 b(The)31 b(tests)h(are)f(designed)f(to) h(e)o(x)o(ercise)f(man)o(y)g(of)515 2259 y(the)24 b(aspects)h(of)f (gpsim)g(and)g(gpsim')-5 b(s)25 b(modules.)37 b(While)25 b(designed)e(primarily)g(for)h(de)n(v)o(elopers,)515 2358 y(the)h(re)o(gression)e(tests)j(also)g(serv)o(e)e(as)i(a)f(rich)g (source)f(of)h(e)o(xamples.)38 b(There)25 b(are)f(man)o(y)g(features) 515 2458 y(gpsim')-5 b(s)20 b(de)n(v)o(elopers)e(will)j(tuck)f(a)o(w)o (ay)f(into)h(a)h(re)o(gression)e(test)i(and)e(f)o(ail)i(to)f(document!) p Black 1905 5208 a(64)p Black eop end %%Page: 65 66 TeXDict begin 65 65 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.65) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.15) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(15)515 1603 y Fq(Theory)51 b(of)h(Operation)515 2060 y Fo(This)22 b(section)g(is)h(only)f(pro)o (vided)e(for)h(those)h(who)g(may)g(be)g(interested)g(in)g(ho)n(w)g (gpsim)g(operates.)515 2159 y(The)28 b(information)f(in)i(here)f(is)i ('mostly')d(accurate.)50 b(Ho)n(we)n(v)o(er)m(,)29 b(as)h(gpsim)e(e)n (v)n(olv)o(es)g(so)h(do)g(the)515 2259 y(details)d(of)g(the)g(theory)f (of)h(operation.)41 b(Use)26 b(the)g(information)e(pro)o(vided)g(here)h (as)i(a)g(high)e(le)n(v)o(el)515 2358 y(introduction)17 b(and)j(use)g(the)h(\(well)f(commented)e(:]\))25 b(source)20 b(to)g(learn)g(the)g(details.)515 2504 y SDict begin H.S end 515 2504 a 515 2504 a SDict begin 12 H.A end 515 2504 a 515 2504 a SDict begin [/View [/XYZ H.V]/Dest (section.15.1) cvn /DEST pdfmark end 515 2504 a 159 x Fk(15.1)119 b(Backgr)n(ound)515 2874 y Fo(gpsim)25 b(is)i(written)f(mostly)g(in)g (C++.)43 b(Why?)e(W)-7 b(ell)28 b(the)e(main)f(reason)h(is)g(to)h (easily)f(implement)515 2974 y(a)f(hierarchical)e(model)g(of)i(a)g (pic.)38 b(If)24 b(you)g(think)f(about)h(a)h(microcontroller)m(,)d(it') -5 b(s)26 b(really)e(easy)g(to)515 3073 y(modularize)h(the)j(v)n (arious)e(components.)45 b(C++)28 b(lends)g(itself)g(well)g(to)g(this)g (conceptualization.)515 3173 y(Furthermore)17 b(Microchip,)g(lik)o(e)j (other)f(microcontroller)d(manuf)o(acturers,)h(has)j(created)e(f)o (amilies)515 3272 y(of)j(de)n(vices)g(that)g(are)h(quite)f(similar)g (to)h(one)f(another)-5 b(.)27 b(Again,)21 b(the)g(C++)h(pro)o(vides)e ('inheritance')515 3372 y(that)g(allo)n(ws)g(the)h(relationships)e(to)h (be)g(shared)g(among)e(the)j(v)n(arious)e(models)g(of)h(pics.)515 3521 y SDict begin H.S end 515 3521 a 515 3521 a SDict begin 12 H.A end 515 3521 a 515 3521 a SDict begin [/View [/XYZ H.V]/Dest (section.15.2) cvn /DEST pdfmark end 515 3521 a 156 x Fk(15.2)119 b(Instructions)515 3888 y Fo(There')-5 b(s)24 b(a)i(base)f(class)h(for)f(the)g(14-bit)f(instructions)g(\(I)h (plan)g(to)g(go)g(one)f(step)i(further)d(and)i(cre-)515 3987 y(ate)k(a)g(base)g(class)g(from)f(which)g(all)i(pic)e (instructions)g(can)h(be)f(deri)n(v)o(ed\).)48 b(It)29 b(primarily)f(serv)o(es)515 4087 y(tw)o(o)20 b(purposes:)k(storage)19 b(that)i(is)g(common)d(for)h(each)h(instruction)f(and)g(a)i(means)f (for)f(generically)515 4187 y(accessing)28 b(virtual)g(functions.)49 b(The)28 b(common)f(information)f(consists)j(of)f(a)h(name)f(-)h(or)f (more)515 4286 y(speci\002cally)20 b(the)g(instruction)f(mnemonic,)g (the)h(opcode,)f(and)g(a)i(pointer)e(to)i(the)f(processor)f(o)n(wn-)515 4386 y(ing)h(the)g(instruction.)j(Some)d(of)g(the)g(virtual)f (functions)g(are)h('e)o(x)o(ecute')e(and)i('name'.)j(As)e(the)f(he)o(x) 515 4485 y(\002le)26 b(is)h(decoded,)d(instances)i(of)f(the)h (instructions)e(are)i(created)f(and)g(stored)g(in)h(an)f(array)g (called)515 4585 y(program_memory)-5 b(.)49 b(The)30 b(inde)o(x)e(into)i(this)h(array)e(is)i(the)f(address)g(at)g(which)g (the)g(instruction)515 4685 y(resides.)25 b(T)-7 b(o)20 b(e)o(x)o(ecute)f(an)h(instruction)f(the)h(follo)n(wing)f(code)g (sequence)g(is)i(in)m(v)n(ok)o(ed:)p Black Black 847 4876 a(program_memory[p)o(c->v)m(alue])o(->e)n(x)o(e)o(cute\()o(\);)p Black 1905 5208 a(65)p Black eop end %%Page: 66 67 TeXDict begin 66 66 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.66) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(15.)45 b(THEOR)-5 b(Y)20 b(OF)h(OPERA)-9 b(TION)1291 b Fo(66)p Black 515 515 a(which)28 b(says,)j(get)e(the)f (instruction)g(at)h(the)f(current)g(program)e(inde)o(x)i(\(pc->v)n (alue\))e(and)i(in)m(v)n(ok)o(e)515 615 y(via)d(the)g(virtual)g (function)e(e)o(x)o(ecute\(\).)38 b(This)25 b(approach)e(allo)n(ws)i(e) o(x)o(ecution)e(break)i(points)f(to)i(be)515 715 y(easily)18 b(set.)25 b(A)18 b(special)g(break)f(point)h(instruction)e(can)i (replace)f(the)h(one)g(residing)f(in)h(the)g(program)515 814 y(memory)g(array)-5 b(.)24 b(When)c('e)o(x)o(ecute')e(is)j(called)f (the)g(break)f(point)h(can)g(be)g(in)m(v)n(ok)o(ed.)515 1046 y SDict begin H.S end 515 1046 a 515 1046 a SDict begin 12 H.A end 515 1046 a 515 1046 a SDict begin [/View [/XYZ H.V]/Dest (section*.64) cvn /DEST pdfmark end 515 1046 a Fp(Pr)o(ogram)e(memory)515 1220 y Fo(Note)j(that)g(in)h(the)f (abo)o(v)o(e)e(discussion,)i(the)h(pc->v)n(alue)d(is)j(referred)e(to)h (as)h(the)f(\223program)e(inde)o(x\224.)515 1319 y(On)30 b(the)h(12-bit)e(and)h(14-bit)f(PIC)i(cores)f(this)h(is)h(unambiguous) 27 b(as)k(the)g(program)d(memory)h(is)515 1419 y(instruction-w)o (ord-wide)13 b(and)k(the)g(program)f(counter)f(increments)i(by)g(one)f (for)h(each)g(instruction.)515 1519 y(On)25 b(the)g(PIC17)h(and)e (PIC18)i(cores,)g(ho)n(we)n(v)o(er)m(,)e(the)h(program)e(memory)h(is)i (accessible)g(through)515 1618 y(the)k(TBLPTR)h(in)f(byte-wide)f(form.) 55 b(The)30 b(program)e(counter)h(increments)g(by)h(tw)o(o)g(for)g (each)515 1718 y(instruction.)515 1835 y(The)22 b(program_memory)c (array)k(in)h(gpsim)f(is)i(al)o(w)o(ays)f(an)g(array)f(of)g (instructions.)32 b(Thus)22 b(the)h(pc-)515 1935 y(>v)n(alue)c(on)h(a)g (PIC18)g(is)i(an)e(inde)o(x)f(whose)h(v)n(alue)f(is)i(half)f(of)g(the)g (PC)h(re)o(gister)n(-triple)e(v)n(alue.)515 2077 y SDict begin H.S end 515 2077 a 515 2077 a SDict begin 12 H.A end 515 2077 a 515 2077 a SDict begin [/View [/XYZ H.V]/Dest (section.15.3) cvn /DEST pdfmark end 515 2077 a 149 x Fk(15.3)119 b(General)30 b(File)h(Registers)515 2429 y Fo(A)j(\002le)g(re)o(gister)f(is)h(simulated)f(by)g(the)g('\002le_re) o(gister')f(class.)66 b(There)33 b(is)h(one)f(instance)g(of)g(a)515 2529 y('\002le_re)o(gister')21 b(object)i(for)g(each)g(\002le)h(re)o (gister)e(in)i(the)f(PIC.)h(All)g(of)f(the)g(re)o(gisters)g(are)g (collected)515 2629 y(together)e(into)h(an)h(array)e(called)i(')l(re)o (gisters')e(which)h(is)i(inde)o(x)o(ed)c(by)i(the)h(re)o(gisters')e (correspond-)515 2728 y(ing)g(PIC)g(addresses.)28 b(The)21 b(array)f(is)i(linear)f(and)f(not)h(bank)o(ed)f(lik)o(e)h(it)h(is)g(in) f(the)g(PIC.)h(\(Banking)e(is)515 2828 y(handled)e(during)h(the)h (simulation.\))515 2970 y SDict begin H.S end 515 2970 a 515 2970 a SDict begin 12 H.A end 515 2970 a 515 2970 a SDict begin [/View [/XYZ H.V]/Dest (section.15.4) cvn /DEST pdfmark end 515 2970 a 149 x Fk(15.4)119 b(Special)31 b(File)f(Registers)515 3322 y Fo(Special)h(\002le)h(re)o(gisters)f(are) g(all)h(of)e(the)i(other)e(re)o(gisters)h(that)g(are)g(not)g(general)f (\002le)i(re)o(gisters.)515 3422 y(This)22 b(includes)g(the)h(core)e (re)o(gisters)h(lik)o(e)h(status)g(and)f(option)f(and)h(also)h(the)f (peripheral)f(re)o(gisters)515 3522 y(lik)o(e)g(eeadr)f(for)h(the)g (EEPR)m(OM.)g(The)f(special)h(\002le)h(re)o(gisters)f(are)g(deri)n(v)o (ed)e(from)h(the)h(general)f(\002le)515 3621 y(re)o(gisters)29 b(and)h(are)g(also)g(stored)g(in)g(the)g(')l(re)o(gisters')f(array)-5 b(.)53 b(There)29 b(is)i(one)f(instance)f(for)h(each)515 3721 y(re)o(gister)f(-)h(e)n(v)o(en)e(if)i(the)g(re)o(gister)f(is)i (accessible)f(in)f(more)g(than)h(one)f(bank.)52 b(So)30 b(for)f(e)o(xample,)515 3820 y(there')-5 b(s)22 b(only)g(one)g (instance)h(for)f(the)h(')-5 b(status')23 b(re)o(gister)m(,)f(ho)n(we)n (v)o(er)f(it)i(may)f(be)h(accessed)g(through)515 3920 y(the)d(')l(re)o(gisters')f(array)g(in)h(more)g(than)g(one)f(place.)515 4037 y(All)30 b(\002le)g(re)o(gisters)g(are)f(accessed)h(by)f(the)h (virtual)f(functions)f('put')g(and)i('get'.)52 b(This)30 b(is)h(done)515 4137 y(for)21 b(tw)o(o)i(main)f(reasons.)31 b(First,)24 b(it)f(con)m(v)o(eniently)c(encapsulates)i(the)i (breakpoint)d(o)o(v)o(erhead)g(\(for)515 4237 y(re)o(gister)25 b(breakpoints\))e(in)j(the)f(\002le)i(re)o(gister)e(and)g(not)g(in)h (the)g(instruction.)40 b(Second,)25 b(and)g(more)515 4336 y(important,)17 b(it)i(allo)n(ws)g(deri)n(v)o(ed)e(classes)j(to)f (implement)e(the)i(put)f(and)h(get)f(more)g(speci\002cally)-5 b(.)24 b(F)o(or)515 4436 y(e)o(xample,)k(a)h('put')e(to)i(the)f(indf)f (re)o(gister)h(is)h(a)g(whole)e(lot)i(dif)n(ferent)d(than)i(a)h(put)f (to)g(the)g(intcon)515 4536 y(re)o(gister)-5 b(.)25 b(In)20 b(each)h(case,)f(the)h('put')e(initiates)i(an)g(action)f(be)o(yond)e (simply)i(storing)g(a)g(byte)g(of)h(data)515 4635 y(in)f(an)g(array)-5 b(.)24 b(It)c(also)h(allo)n(ws)f(the)g(follo)n(wing)f(code)h(sequence)f (to)h(be)g(easily)g(implemented:)p Black Black 722 4799 a Fi(movlw)129 b(trisa)g(;Get)41 b(the)i(address)d(of)j(tris)722 4899 y(movwf)129 b(fsr)722 4998 y(movf)173 b(indf,w)85 b(;Read)41 b(trisa)g(indirectly)p Black Black eop end %%Page: 67 68 TeXDict begin 67 67 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.67) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(15.)45 b(THEOR)-5 b(Y)20 b(OF)h(OPERA)-9 b(TION)1291 b Fo(67)p Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (section.15.5) cvn /DEST pdfmark end 515 432 a 83 x Fk(15.5)119 b(Example)29 b(of)h(an)g(instruction)515 724 y Fo(Here')-5 b(s)25 b(an)g(e)o(xample)f(of)g(the)h(code)g(for)f(the)h(mo)o(vf)f (instruction)f(that)j(illustrates)f(what)g(has)g(been)515 823 y(discussed)20 b(abo)o(v)o(e.)j(Some)n(where)c(in)h(gpsim)g(the)g (code)f(sequence:)p Black Black 722 1020 a Fi(program_memory[pc)o(->)o (va)o(lue)o(]-)o(>e)o(xec)o(ut)o(e\()o(\);)515 1216 y Fo(is)28 b(e)o(x)o(ecuted.)43 b(Let')-5 b(s)27 b(say)g(that)g(the)g(pc) g(is)h(pointing)d(to)i(a)g(mo)o(vf)f(instruction.)44 b(The)26 b(->e)o(x)o(ecute\(\))515 1315 y(virtual)19 b(function)e(will)k(in)m(v)n(ok)o(e)d(MO)l(VF::e)o(x)o(ecute.)23 b(I')l(v)o(e)18 b(added)h(e)o(xtra)g(comments)f(\(that)h(aren')o(t)f (in)515 1415 y(the)i(main)g(code\))f(to)h(illustrate)h(in)f(detail)g (what')-5 b(s)21 b(happening.)p Black Black 722 1611 a Fi(void)42 b(MOVF::execute\(vo)o(id\))722 1711 y({)809 1810 y(unsigned)f(int)h(source_value;)809 2010 y(//)h(All)f (instructions)d(are)j('traced')e(\(discussed)g(below\).)g(It's)i (sufficient)809 2109 y(//to)g(only)g(store)g(the)g(opcode.)f(However,)f (even)i(this)g(may)g(be)h(unnecessary)38 b(since)809 2209 y(//the)k(program)f(counter)f(is)j(also)f(traced.)e(Expect)h(this) h(to)h(disappear)d(in)i(the)809 2309 y(//future...)809 2408 y(trace.instruction)o(\(o)o(pco)o(de)o(\);)809 2607 y(//)h('source')d(is)j(a)g(pointer)e(to)i(a)g('file_register')37 b(object.)k(It)h(is)h(initialized)809 2707 y(//by)f(reading)f(the)h ('registers')d(array.)i(Note)h(that)g(the)g(index)g(depends)e(on)j(the) 809 2807 y(//'rp')e(bits)h(\(actually)e(just)i(one)g(bit\))g(in)h(the)f (status)f(register.)f(Time)i(is)809 2906 y(//)h(saved)f(by)g(caching)f (rp)i(as)f(opposed)f(to)i(decoding)d(the)i(status)f(register.)809 3006 y(source)g(=)j(cpu->registers[)o(cp)o(u->)o(rp)37 b(|)43 b(opcode®_IN_IN)o(ST)o(RUC)o(TI)o(ON)o(_MA)o(SK)o(];)809 3205 y(//)g(We)g(have)f(no)h(idea)e(which)h(register)e(we)j(are)f (trying)f(to)i(access)e(and)h(how)g(it)809 3305 y(//should)f(be)h (accessed)f(or)h(if)h(there's)e(a)i(breakpoint)c(set)j(on)h(it.)f(No)h (problem,)809 3404 y(//the)f(virtual)f(function)f('get')h(will)h (resolve)f(all)h(of)h(those)e(details)809 3504 y(//)i(and)f('do)h(the)f (right)g(thing'.)809 3604 y(source_value)d(=)k(source->get\(\);)809 3803 y(//)g(If)g(the)f(destination)d(is)k(W,)g(then)e(the)i (constructor)c(has)j(already)f(initialized)809 3903 y(//'destination'.) c(Otherwise)j(the)i(destination)d(and)k(source)e(are)h(the)g(same.)809 4002 y(if\(opcode&DESTINA)o(TI)o(ON_)o(MA)o(SK)o(\))897 4102 y(destination)d(=)k(source;)258 b(//)43 b(Result)e(goes)h(to)h (source)809 4301 y(//)g(Write)f(the)g(source)f(value)g(to)i(the)f (destination.)d(Again,)i(we)i(have)f(no)g(idea)809 4401 y(//)h(where)f(the)g(destination)d(may)j(be)h(or)809 4500 y(//)g(or)g(how)f(the)h(data)e(should)g(be)i(written)e(there.)809 4600 y(destination->put\()o(so)o(urc)o(e_)o(va)o(lue)o(\);)809 4799 y(//)i(The)f(movf)g(instruction)d(will)j(set)g(Z)i(\(zero\))d(bit) h(in)h(the)f(status)f(register)809 4899 y(//if)h(the)h(source)e(value)g (was)h(zero.)809 4998 y(cpu->status.put_Z)o(\(0)o(==s)o(ou)o(rc)o(e_v)o (al)o(ue)o(\);)p Black Black eop end %%Page: 68 69 TeXDict begin 68 68 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.68) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(15.)45 b(THEOR)-5 b(Y)20 b(OF)h(OPERA)-9 b(TION)1291 b Fo(68)p Black 809 615 a Fi(//)43 b(Finally,)d(advance)h (the)h(pc)h(by)g(one.)809 715 y(cpu->pc->incremen)o(t\()o(\);)722 914 y(})515 1144 y SDict begin H.S end 515 1144 a 515 1144 a SDict begin 12 H.A end 515 1144 a 515 1144 a SDict begin [/View [/XYZ H.V]/Dest (section.15.6) cvn /DEST pdfmark end 515 1144 a 175 x Fk(15.6)119 b(T)-9 b(race)515 1529 y Fo(Ev)o(erything)24 b(that)j(is)g(simulated)f(is)i(traced)e(-)h Fh(all)g Fo(of)g(the)g(time.)44 b(The)27 b(trace)f(b)n(uf)n(fer)g(is)h (one)g(huge)515 1629 y(circular)d(b)n(uf)n(fer)h(of)g(inte)o(gers.)40 b(Information)23 b(is)k(or'ed)d(with)i(a)g(trace)f(tok)o(en)g(and)g (then)h(is)g(stored)515 1728 y(in)c(the)h(trace)f(b)n(uf)n(fer)-5 b(.)31 b(No)23 b(attempt)f(is)i(made)e(to)g(associate)h(the)g(items)g (in)f(the)h(trace)f(b)n(uf)n(fer)g(while)515 1828 y(the)e(simulator)f (is)j(simulating)d(a)i(PIC.)f(Thus,)g(if)g(you)g(look)f(at)i(the)f(ra)o (w)g(b)n(uf)n(fer)f(you)g(will)i(see)g(stuf)n(f)515 1928 y(lik)o(e:)34 b(c)o(ycle)24 b(counter)g(=)h(...,)g(opcode)e(fetch)h(=)h (...,)h(re)o(gister)e(read)g(=)h(...,)g(re)o(gister)f(write)h(=)g(...,) g(etc.)515 2027 y(Ho)n(we)n(v)o(er)m(,)h(this)h(information)e(is)i (post)g(processed)f(to)h(ascertain)f(what)h(happened)d(and)j(when)f(it) 515 2127 y(happened.)h(It')-5 b(s)22 b(also)g(possible)f(to)h(use)g (this)g(information)d(to)j(undo)e(the)h(simulation,)g(or)h(in)f(other) 515 2226 y(w)o(ords)f(you)f(can)h(step)g(backw)o(ards.)k(I)c(don')o(t)f (ha)n(v)o(e)h(this)g(implemented)f(yet)h(though.)515 2375 y SDict begin H.S end 515 2375 a 515 2375 a SDict begin 12 H.A end 515 2375 a 515 2375 a SDict begin [/View [/XYZ H.V]/Dest (section.15.7) cvn /DEST pdfmark end 515 2375 a 156 x Fk(15.7)119 b(Br)n(eakpoints)515 2742 y Fo(Breakpoints)19 b(f)o(all)h(into)g(three)g(cate)o(gories:)k(e)o(x)o (ecution,)18 b(re)o(gister)m(,)h(and)g(c)o(ycle.)515 2988 y SDict begin H.S end 515 2988 a 515 2988 a SDict begin 12 H.A end 515 2988 a 515 2988 a SDict begin [/View [/XYZ H.V]/Dest (section*.65) cvn /DEST pdfmark end 515 2988 a Fp(Execution:)515 3168 y Fo(F)o(or)c(e)o(x)o(ecution)e (breakpoints)g(a)i(special)h(instruction)e(appropriately)e(called)j ('Breakpoint_Instruction')515 3268 y(is)22 b(created)f(and)g(placed)g (into)g(the)h(program)e(memory)f(array)i(at)h(the)g(location)f(the)g (break)g(point)g(is)515 3368 y(desired.)35 b(The)24 b(original)f (instruction)f(is)j(sa)n(v)o(ed)f(in)g(the)g(ne)n(wly)f(created)g (breakpoint)f(instruction.)515 3467 y(When)c(the)g(break)f(point)g(is)i (cleared,)e(the)i(original)d(instruction)h(is)i(fetched)e(from)g(the)h (break)f(point)515 3567 y(instruction)i(and)g(placed)h(back)f(into)h (the)g(program)e(memory)h(array)-5 b(.)515 3692 y(Note)29 b(that)f(this)i(scheme)e(has)h(zero)f(o)o(v)o(erhead.)49 b(The)28 b(simulation)g(is)i(only)e(af)n(fected)f(when)i(the)515 3791 y(breakpoint)18 b(is)j(encountered.)515 4037 y SDict begin H.S end 515 4037 a 515 4037 a SDict begin 12 H.A end 515 4037 a 515 4037 a SDict begin [/View [/XYZ H.V]/Dest (section*.66) cvn /DEST pdfmark end 515 4037 a Fp(Register:)515 4218 y Fo(There)e(are)i(at)g(least)g(four)e(dif)n(ferent)g(breakpoint)f (types)j(that)f(can)h(be)f(set)h(on)f(a)h(re)o(gister:)k(read)20 b(an)o(y)515 4317 y(v)n(alue,)h(write)h(an)o(y)f(v)n(alue,)g(read)h(a)g (speci\002c)g(v)n(alue,)f(or)h(write)g(a)g(speci\002c)g(v)n(alue.)30 b(Lik)o(e)21 b(the)h(e)o(x)o(ecu-)515 4417 y(tion)c(breakpoints,)e (there)i(are)g(special)h(breakpoint)d(re)o(gisters)i(that)g(replace)g (a)h(re)o(gister)f(object.)23 b(So)515 4517 y(when)h(the)h(user)g(sets) h(a)f(write)g(breakpoint)e(at)i(re)o(gister)g(0x20)e(for)h(e)o(xample,) h(a)g(ne)n(w)g(breakpoint)515 4616 y(object)c(is)i(created)e(and)g (insert)h(into)g(the)g(\002le)h(re)o(gister)e(array)g(at)h(location)f (0x20.)29 b(When)21 b(the)h(sim-)515 4716 y(ulator)e(attempts)g(to)h (access)g(re)o(gister)f(location)f(0x20,)g(the)i(breakpoint)d(object)i (will)h(be)g(accessed)515 4815 y(instead.)515 4940 y(Note)e(that)h (this)g(scheme)f(too)g(has)h(zero)f(o)o(v)o(erhead,)e(accept)i(when)g (a)h(breakpoint)d(is)k(encountered.)p Black Black eop end %%Page: 69 70 TeXDict begin 69 69 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.69) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(15.)45 b(THEOR)-5 b(Y)20 b(OF)h(OPERA)-9 b(TION)1291 b Fo(69)p Black 515 515 a SDict begin H.S end 515 515 a 515 515 a SDict begin 12 H.A end 515 515 a 515 515 a SDict begin [/View [/XYZ H.V]/Dest (section*.67) cvn /DEST pdfmark end 515 515 a Fp(Cycle:)515 696 y Fo(Cycle)19 b(breakpoints)e(allo)n(w)i(gpsim)g(to)g(alter)h(e)o(x)o(ecution)d(at)i (a)h(speci\002c)f(instruction)f(c)o(ycle.)24 b(This)c(is)515 795 y(useful)d(for)g(running)e(your)h(simulation)h(for)g(a)h(v)o(ery)e (speci\002c)i(amount)e(of)h(time.)24 b(Internally)-5 b(,)16 b(gpsim)515 895 y(mak)o(es)24 b(e)o(xtensi)n(v)o(e)g(use)h(of)g (the)g(c)o(ycle)f(breakpoints.)37 b(F)o(or)24 b(e)o(xample,)h(the)g (TMR0)g(object)f(can)h(be)515 995 y(programmed)17 b(to)j(generate)f(a)i (periodic)d(c)o(ycle)i(break)f(point.)515 1119 y(Cycle)26 b(break)f(points)h(are)g(implemented)e(with)i(a)h(sorted)e(doubly-link) o(ed)e(list.)43 b(The)26 b(link)o(ed)f(list)515 1219 y(contains)c(tw)o(o)i(pieces)g(of)f(information)e(\(besides)i(the)h (links\):)29 b(the)23 b(c)o(ycle)f(at)h(which)f(the)g(break)g(is)515 1319 y(to)27 b(occur)f(and)g(the)h(call)h(back)e(function)1706 1319 y SDict begin H.S end 1706 1319 a -31 x Fm(1)1739 1319 y SDict begin 12 H.L end 1739 1319 a 1739 1319 a SDict begin [/Subtype /Link/Dest (Hfootnote.9) cvn/H /I/Border [0 0 1]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1739 1319 a 27 w Fo(that')-5 b(s)28 b(to)f(be)g(in)m(v)n (ok)o(ed)e(when)h(the)h(c)o(ycle)g(does)f(occur)-5 b(.)515 1418 y(The)21 b(break)g(logic)g(is)i(e)o(xtremely)d(simple.)30 b(Whene)n(v)o(er)20 b(the)i(c)o(ycle)f(counter)g(is)i(adv)n(anced)c (\(that)j(is,)515 1518 y(incremented\),)16 b(it')-5 b(s)20 b(compared)d(to)i(the)g(ne)o(xt)f(desired)g(c)o(ycle)h(break)f(point.) 23 b(If)c(there')-5 b(s)19 b(NO)g(match,)515 1617 y(then)24 b(we')l(re)h(done.)39 b(So)25 b(the)g(o)o(v)o(erhead)e(for)h(c)o(ycle)h (breaks)g(is)h(the)f(time)g(required)f(to)h(implement)515 1717 y(a)30 b(comparison.)53 b(If)30 b(there)g(IS)g(a)h(match,)h(then)d (the)h(call)h(back)e(function)g(associated)h(with)g(this)515 1817 y(break)22 b(point)h(is)i(in)m(v)n(ok)o(ed)d(and)h(the)h(ne)o(xt)f (break)g(point)g(in)h(the)f(doubly-link)o(ed)e(list)k(serv)o(es)e(as)i (the)515 1916 y(reference)18 b(for)i(the)g(ne)o(xt)f(c)o(ycle)h(break.) 515 2065 y SDict begin H.S end 515 2065 a 515 2065 a SDict begin 12 H.A end 515 2065 a 515 2065 a SDict begin [/View [/XYZ H.V]/Dest (section.15.8) cvn /DEST pdfmark end 515 2065 a 156 x Fk(15.8)119 b(TIMER1)28 b(Exter)n(nal)i(input)515 2432 y Fo(The)22 b(timer1)g(module)f(can)h(support)f(e)o(xternal)h (input,)g(on)g(some)g(processors,)g(as)i(either)e(a)h(crystal)515 2531 y(using)c(tw)o(o)i(pins)f(or)g(a)h(single)f(pin)f(dri)n(v)o(e.)515 2777 y SDict begin H.S end 515 2777 a 515 2777 a SDict begin 12 H.A end 515 2777 a 515 2777 a SDict begin [/View [/XYZ H.V]/Dest (section*.68) cvn /DEST pdfmark end 515 2777 a Fp(Exter)o(nal)g(Crystal)515 2958 y Fo(If)25 b(an)g(e)o(xternal) f(crystal,)i(typically)e(32,768)f(KHz,)k(is)f(being)e(used,)i(then)f (both)f(T1OSCEN)h(and)515 3058 y(TMR1CS)f(in)h(re)o(gister)e(T1CON)h (should)g(be)g(true.)36 b(Gpsim)24 b(will)h(then)f(automatically)f (simulate)515 3157 y(timer1)k(being)h(dri)n(v)o(en)e(at)j(the)f (crystal)h(frequenc)o(y)c(which)j(can)g(be)g(changed)f(from)g(the)h (def)o(ault)515 3257 y(frequenc)o(y)17 b(by)j(changing)e(the)i(v)n (alue)g(of)g(the)g(processor)f(symbol)g(called)h(tmr1_freq.)515 3503 y SDict begin H.S end 515 3503 a 515 3503 a SDict begin 12 H.A end 515 3503 a 515 3503 a SDict begin [/View [/XYZ H.V]/Dest (section*.69) cvn /DEST pdfmark end 515 3503 a Fp(Single)g(pin)h(dri)o(v)o(e)515 3683 y Fo(If)16 b(the)h(single)g(pin)f(dri)n(v)o(e)g(is)i(being)d(used,)i(then)g(the)f (T1CON)h(re)o(gister)f(bits)i(for)e(T1OSCEN)h(should)515 3783 y(be)23 b(f)o(alse)g(and)f(TMR1CS)i(true,)f(and)f(the)h(T1CKI)f (pin)h(must)g(be)g(dri)n(v)o(en)e(manually)g(such)i(as)h(by)e(a)515 3883 y(stimuli)e(command.)p Black 515 4840 1146 4 v 605 4895 a Fg(1)634 4920 y SDict begin H.S end 634 4920 a 634 4920 a SDict begin H.R end 634 4920 a 634 4920 a SDict begin [/View [/XYZ H.V]/Dest (Hfootnote.9) cvn /DEST pdfmark end 634 4920 a Ff(A)f(call)i(back)f(function)i(is)d(a)g (pointer)i(to)f(a)f(function.)30 b(In)19 b(this)h(conte)o(xt,)h(gpsim)f (is)f(gi)n(v)o(en)i(a)e(pointer)i(to)f(the)g(function)515 4998 y(that')l(s)e(to)g(be)f(in)m(v)o(ok)o(ed)i(\(called\))g(whene)n(v) o(er)g(a)e(c)o(ycle)i(break)f(occurs.)p Black Black Black eop end %%Page: 70 71 TeXDict begin 70 70 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.70) cvn /DEST pdfmark end 506 174 a Black Black 515 432 a SDict begin H.S end 515 432 a 515 432 a SDict begin 12 H.A end 515 432 a 515 432 a SDict begin [/View [/XYZ H.V]/Dest (chapter.16) cvn /DEST pdfmark end 515 432 a 731 x Fl(Chapter)44 b(16)515 1603 y Fq(LICENSES)515 1937 y SDict begin H.S end 515 1937 a 515 1937 a SDict begin 12 H.A end 515 1937 a 515 1937 a SDict begin [/View [/XYZ H.V]/Dest (section.16.1) cvn /DEST pdfmark end 515 1937 a 172 x Fk(16.1)119 b(Gpsim.lyx)515 2320 y Fo(Cop)o(yright)894 2317 y(c)871 2320 y Fc(\015)p Fo(2000-2010)515 2444 y(T)-6 b(.)20 b(Scott)g(Dattalo,)g(Ralf)h(F)o(orsber)o(g,)d(Robert)i(Pearce,)f (Borut)h(Ra\377em)g(and)g(Ro)o(y)g(Rankin)515 2569 y(The)g(source)f(of) h(this)h(document)d(is)j(gpsim.lyx.)515 2693 y(This)d(document)e(is)j (free)f(softw)o(are;)g(you)f(can)h(redistrib)n(ute)f(it)i(and/or)e (modify)f(it)j(under)d(the)j(terms)515 2793 y(of)g(the)g(GNU)h(General) e(Public)h(License)g(published)f(by)h(the)g(Free)g(Softw)o(are)g(F)o (oundation;)e(either)515 2893 y(v)o(ersion)i(2,)h(or)g(\(at)g(your)f (option\))f(an)o(y)i(later)g(v)o(ersion.)515 3017 y(This)26 b(document)f(is)i(distrib)n(uted)f(in)g(the)h(hope)e(that)i(it)g(will)g (be)f(useful,)h(b)n(ut)g(WITHOUT)f(ANY)515 3117 y(W)-10 b(ARRANTY)i(;)29 b(without)d(e)n(v)o(en)g(the)h(implied)g(w)o(arranty)f (of)h(MERCHANT)-8 b(ABILITY)27 b(or)f(FIT)-8 b(-)515 3216 y(NESS)28 b(FOR)h(A)g(P)-8 b(AR)j(TICULAR)29 b(PURPOSE.)g(See)g (the)f(GNU)g(General)g(Public)f(License)h(for)515 3316 y(more)19 b(details.)515 3441 y(Y)-9 b(ou)16 b(should)f(ha)n(v)o(e)h (recei)n(v)o(ed)f(a)i(cop)o(y)e(of)h(the)h(GNU)g(General)e(Public)i (License)f(along)f(with)i(gpsim;)515 3540 y(see)j(the)g(\002le)h (COPYING.)f(If)g(not,)f(write)h(to)h(the)f(Free)g(Softw)o(are)f(F)o (oundation,)e(59)j(T)-6 b(emple)19 b(Place)515 3640 y(-)h(Suite)h(330,) e(Boston,)g(MA)i(02111-1307,)16 b(USA.)515 3783 y SDict begin H.S end 515 3783 a 515 3783 a SDict begin 12 H.A end 515 3783 a 515 3783 a SDict begin [/View [/XYZ H.V]/Dest (section.16.2) cvn /DEST pdfmark end 515 3783 a 162 x Fk(16.2)119 b(Gpsim)515 4155 y Fo(The)22 b(Gpsim)h(program)d(is)k (licensed)e(under)f(v)o(ersion)g(2)i(or)g(higher)e(of)h(the)h(GNU)g (General)f(Public)515 4255 y(License.)30 b(Details)22 b(of)g(this)h(license)f(can)f(be)h(found)f(in)h(the)g(COPYING)g(\002le) h(which)e(should)g(ha)n(v)o(e)515 4355 y(come)14 b(with)i(this)f (program.)22 b(If)15 b(not)g(the)g(license)g(can)g(be)g(found)f(at)2402 4373 y SDict begin H.S end 2402 4373 a Black -18 x Fo(http://www)-5 b(.gnu.or)o (g/licenses/gpl-2.)o(0.h)o(tml)p Black 3770 4298 a SDict begin H.R end 3770 4298 a 3770 4355 a SDict begin [/H /I/Border [0 0 1]BorderArrayPatch/Color [0 1 1]/Action <>/Subtype /Link H.B /ANN pdfmark end 3770 4355 a Fo(.)515 4503 y SDict begin H.S end 515 4503 a 515 4503 a SDict begin 12 H.A end 515 4503 a 515 4503 a SDict begin [/View [/XYZ H.V]/Dest (section.16.3) cvn /DEST pdfmark end 515 4503 a 157 x Fk(16.3)119 b(Libraries)22 b(libgpsim,)j(libgpsim_modules,)f(libgpsim_eXdbm)515 4870 y Fo(The)30 b(libraries)h(libgpsim,)i(libgpsim_modules,)e(and)f (libgpsim_eXdbm)e(are)j(licensed)g(under)515 4970 y(v)o(ersion)22 b(2.1)h(of)g(the)g(GNU)h(Lesser)g(General)f(Public)g(License.)34 b(Details)25 b(of)e(this)h(license)f(can)h(be)p Black 1905 5208 a(70)p Black eop end %%Page: 71 72 TeXDict begin 71 71 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.71) cvn /DEST pdfmark end 506 174 a Black 515 282 a Fn(CHAPTER)21 b(16.)45 b(LICENSES)1844 b Fo(71)p Black 515 515 a(found)25 b(in)h(the)h(COPYING.LESSER)g(\002le)g(which)f (should)g(ha)n(v)o(e)g(come)g(with)h(the)g(program.)42 b(If)515 615 y(not,)19 b(the)i(license)f(can)g(be)g(found)e(at)1566 633 y SDict begin H.S end 1566 633 a Black -18 x Fo(http://www)-5 b(.gnu.or)o (g/licenses/lgpl-2.)o(1.h)o(tml)p Black 2957 559 a SDict begin H.R end 2957 559 a 2957 615 a SDict begin [/H /I/Border [0 0 1]BorderArrayPatch/Color [0 1 1]/Action <>/Subtype /Link H.B /ANN pdfmark end 2957 615 a Fo(.)p Black Black eop end %%Page: 72 73 TeXDict begin 72 72 bop 0 0 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end 0 0 a 506 174 a SDict begin H.S end 506 174 a 506 174 a SDict begin H.R end 506 174 a 506 174 a SDict begin [/View [/XYZ H.V]/Dest (page.72) cvn /DEST pdfmark end 506 174 a Black Black Black 515 990 a Fq(Index)p Black 515 1407 a Fo(7SEGMENTS,)1036 1408 y SDict begin H.S end 1036 1408 a Black -1 x Fo(51)p Black 1119 1351 a SDict begin H.R end 1119 1351 a 1119 1407 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.51) cvn H.B /ANN pdfmark end 1119 1407 a 515 1589 a Fo(and2,)718 1590 y SDict begin H.S end 718 1590 a Black -1 x Fo(48)p Black 801 1533 a SDict begin H.R end 801 1533 a 801 1589 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.48) cvn H.B /ANN pdfmark end 801 1589 a 515 1688 a Fo(attach,)755 1689 y SDict begin H.S end 755 1689 a Black -1 x Fo(10)p Black 838 1632 a SDict begin H.R end 838 1632 a 838 1688 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 838 1688 a 515 1870 a Fo(break,)741 1871 y SDict begin H.S end 741 1871 a Black -1 x Fo(10)p Black 824 1814 a SDict begin H.R end 824 1814 a 824 1870 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 824 1870 a Fo(,)865 1870 y SDict begin H.S end 865 1870 a Black Fo(11)p Black 948 1814 a SDict begin H.R end 948 1814 a 948 1870 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.11) cvn H.B /ANN pdfmark end 948 1870 a 515 1970 a Fo(b)n(us,)670 1971 y SDict begin H.S end 670 1971 a Black -1 x Fo(10)p Black 753 1913 a SDict begin H.R end 753 1913 a 753 1970 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 753 1970 a 515 2151 a Fo(Capacitors,)911 2152 y SDict begin H.S end 911 2152 a Black -1 x Fo(51)p Black 994 2095 a SDict begin H.R end 994 2095 a 994 2151 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.51) cvn H.B /ANN pdfmark end 994 2151 a 515 2251 a Fo(clear)m(,)714 2252 y SDict begin H.S end 714 2252 a Black -1 x Fo(10)p Black 797 2195 a SDict begin H.R end 797 2195 a 797 2251 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 797 2251 a Fo(,)839 2252 y SDict begin H.S end 839 2252 a Black -1 x Fo(13)p Black 922 2195 a SDict begin H.R end 922 2195 a 922 2251 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.13) cvn H.B /ANN pdfmark end 922 2251 a 515 2432 a Fo(DHT11,)810 2433 y SDict begin H.S end 810 2433 a Black -1 x Fo(53)p Black 893 2376 a SDict begin H.R end 893 2376 a 893 2432 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.53) cvn H.B /ANN pdfmark end 893 2432 a 515 2532 a Fo(disassemble,)957 2533 y SDict begin H.S end 957 2533 a Black -1 x Fo(10)p Black 1041 2476 a SDict begin H.R end 1041 2476 a 1041 2532 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 1041 2532 a Fo(,)1082 2532 y SDict begin H.S end 1082 2532 a Black Fo(14)p Black 1165 2476 a SDict begin H.R end 1165 2476 a 1165 2532 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.14) cvn H.B /ANN pdfmark end 1165 2532 a 515 2632 a Fo(DS1307,)828 2633 y SDict begin H.S end 828 2633 a Black -1 x Fo(54)p Black 911 2575 a SDict begin H.R end 911 2575 a 911 2632 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.54) cvn H.B /ANN pdfmark end 911 2632 a 515 2731 a Fo(DS1820)19 b(F)o(amily)-5 b(,)1078 2732 y SDict begin H.S end 1078 2732 a Black -1 x Fo(54)p Black 1161 2675 a SDict begin H.R end 1161 2675 a 1161 2731 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.54) cvn H.B /ANN pdfmark end 1161 2731 a 515 2831 a Fo(dump,)745 2832 y SDict begin H.S end 745 2832 a Black -1 x Fo(10)p Black 828 2775 a SDict begin H.R end 828 2775 a 828 2831 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 828 2831 a Fo(,)870 2831 y SDict begin H.S end 870 2831 a Black Fo(14)p Black 953 2775 a SDict begin H.R end 953 2775 a 953 2831 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.14) cvn H.B /ANN pdfmark end 953 2831 a 515 3012 a Fo(echo,)713 3013 y SDict begin H.S end 713 3013 a Black -1 x Fo(15)p Black 796 2956 a SDict begin H.R end 796 2956 a 796 3012 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.15) cvn H.B /ANN pdfmark end 796 3012 a 515 3194 a Fo(frequenc)o(y)g(,)882 3195 y SDict begin H.S end 882 3195 a Black -1 x Fo(10)p Black 965 3138 a SDict begin H.R end 965 3138 a 965 3194 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 965 3194 a Fo(,)1006 3195 y SDict begin H.S end 1006 3195 a Black -1 x Fo(15)p Black 1089 3138 a SDict begin H.R end 1089 3138 a 1089 3194 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.15) cvn H.B /ANN pdfmark end 1089 3194 a 515 3376 a Fo(GNU)20 b(GPL,)914 3377 y SDict begin H.S end 914 3377 a Black -1 x Fo(70)p Black 997 3319 a SDict begin H.R end 997 3319 a 997 3376 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.70) cvn H.B /ANN pdfmark end 997 3376 a 515 3557 a Fo(HD44780,)884 3558 y SDict begin H.S end 884 3558 a Black -1 x Fo(54)p Black 967 3501 a SDict begin H.R end 967 3501 a 967 3557 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.54) cvn H.B /ANN pdfmark end 967 3557 a 515 3657 a Fo(help,)699 3658 y SDict begin H.S end 699 3658 a Black -1 x Fo(10)p Black 782 3601 a SDict begin H.R end 782 3601 a 782 3657 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 782 3657 a Fo(,)824 3658 y SDict begin H.S end 824 3658 a Black -1 x Fo(15)p Black 907 3601 a SDict begin H.R end 907 3601 a 907 3657 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.15) cvn H.B /ANN pdfmark end 907 3657 a 515 3838 a Fo(I2C)g(EEPR)m(OM,)1035 3839 y SDict begin H.S end 1035 3839 a Black -1 x Fo(50)p Black 1118 3782 a SDict begin H.R end 1118 3782 a 1118 3838 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.50) cvn H.B /ANN pdfmark end 1118 3838 a 515 3938 a Fo(i2c2par)m(,)802 3939 y SDict begin H.S end 802 3939 a Black -1 x Fo(52)p Black 885 3882 a SDict begin H.R end 885 3882 a 885 3938 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.52) cvn H.B /ANN pdfmark end 885 3938 a 515 4038 a Fo(icd,)658 4039 y SDict begin H.S end 658 4039 a Black -1 x Fo(10)p Black 741 3981 a SDict begin H.R end 741 3981 a 741 4038 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 741 4038 a Fo(,)782 4039 y SDict begin H.S end 782 4039 a Black -1 x Fo(15)p Black 865 3981 a SDict begin H.R end 865 3981 a 865 4038 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.15) cvn H.B /ANN pdfmark end 865 4038 a 515 4137 a Fo(instructions,)944 4138 y SDict begin H.S end 944 4138 a Black -1 x Fo(65)p Black 1027 4081 a SDict begin H.R end 1027 4081 a 1027 4137 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.65) cvn H.B /ANN pdfmark end 1027 4137 a 515 4319 a Fo(LCD_7Se)o(g,)929 4320 y SDict begin H.S end 929 4320 a Black -1 x Fo(55)p Black 1012 4263 a SDict begin H.R end 1012 4263 a 1012 4319 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.55) cvn H.B /ANN pdfmark end 1012 4319 a 515 4418 a Fo(LED,)718 4419 y SDict begin H.S end 718 4419 a Black -1 x Fo(51)p Black 801 4362 a SDict begin H.R end 801 4362 a 801 4418 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.51) cvn H.B /ANN pdfmark end 801 4418 a 515 4518 a Fo(list,)658 4519 y SDict begin H.S end 658 4519 a Black -1 x Fo(10)p Black 741 4462 a SDict begin H.R end 741 4462 a 741 4518 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 741 4518 a Fo(,)782 4519 y SDict begin H.S end 782 4519 a Black -1 x Fo(15)p Black 865 4462 a SDict begin H.R end 865 4462 a 865 4518 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.15) cvn H.B /ANN pdfmark end 865 4518 a 515 4618 a Fo(load,)699 4619 y SDict begin H.S end 699 4619 a Black -1 x Fo(10)p Black 782 4561 a SDict begin H.R end 782 4561 a 782 4618 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 782 4618 a Fo(,)824 4619 y SDict begin H.S end 824 4619 a Black -1 x Fo(16)p Black 907 4561 a SDict begin H.R end 907 4561 a 907 4618 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.16) cvn H.B /ANN pdfmark end 907 4618 a 515 4717 a Fo(log,)662 4718 y SDict begin H.S end 662 4718 a Black -1 x Fo(10)p Black 745 4661 a SDict begin H.R end 745 4661 a 745 4717 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 745 4717 a 515 4817 a Fo(Logic,)750 4818 y SDict begin H.S end 750 4818 a Black -1 x Fo(48)p Black 833 4761 a SDict begin H.R end 833 4761 a 833 4817 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.48) cvn H.B /ANN pdfmark end 833 4817 a 515 4998 a Fo(macros,)796 4999 y SDict begin H.S end 796 4999 a Black -1 x Fo(16)p Black 879 4942 a SDict begin H.R end 879 4942 a 879 4998 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.16) cvn H.B /ANN pdfmark end 879 4998 a Black Black 1988 1407 a Fo(module,)2279 1408 y SDict begin H.S end 2279 1408 a Black -1 x Fo(10)p Black 2362 1351 a SDict begin H.R end 2362 1351 a 2362 1407 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2362 1407 a Fo(,)2403 1408 y SDict begin H.S end 2403 1408 a Black -1 x Fo(18)p Black 2487 1351 a SDict begin H.R end 2487 1351 a 2487 1407 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.18) cvn H.B /ANN pdfmark end 2487 1407 a 1988 1507 a Fo(Modules,)2320 1508 y SDict begin H.S end 2320 1508 a Black -1 x Fo(46)p Black 2403 1451 a SDict begin H.R end 2403 1451 a 2403 1507 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.46) cvn H.B /ANN pdfmark end 2403 1507 a 1988 1690 a Fo(node,)2191 1691 y SDict begin H.S end 2191 1691 a Black -1 x Fo(10)p Black 2274 1633 a SDict begin H.R end 2274 1633 a 2274 1690 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2274 1690 a Fo(,)2316 1692 y SDict begin H.S end 2316 1692 a Black -2 x Fo(19)p Black 2399 1633 a SDict begin H.R end 2399 1633 a 2399 1690 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.19) cvn H.B /ANN pdfmark end 2399 1690 a 1988 1789 a Fo(not,)2136 1791 y SDict begin H.S end 2136 1791 a Black -2 x Fo(49)p Black 2219 1733 a SDict begin H.R end 2219 1733 a 2219 1789 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.49) cvn H.B /ANN pdfmark end 2219 1789 a 1988 1972 a Fo(or2,)2141 1974 y SDict begin H.S end 2141 1974 a Black -2 x Fo(49)p Black 2224 1916 a SDict begin H.R end 2224 1916 a 2224 1972 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.49) cvn H.B /ANN pdfmark end 2224 1972 a 1988 2154 a Fo(processor)m(,)2345 2155 y SDict begin H.S end 2345 2155 a Black -1 x Fo(10)p Black 2428 2098 a SDict begin H.R end 2428 2098 a 2428 2154 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2428 2154 a Fo(,)2469 2155 y SDict begin H.S end 2469 2155 a Black -1 x Fo(20)p Black 2552 2098 a SDict begin H.R end 2552 2098 a 2552 2154 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.20) cvn H.B /ANN pdfmark end 2552 2154 a 1988 2337 a Fo(quit,)2159 2338 y SDict begin H.S end 2159 2338 a Black -1 x Fo(10)p Black 2242 2281 a SDict begin H.R end 2242 2281 a 2242 2337 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2242 2337 a Fo(,)2284 2338 y SDict begin H.S end 2284 2338 a Black -1 x Fo(20)p Black 2367 2281 a SDict begin H.R end 2367 2281 a 2367 2337 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.20) cvn H.B /ANN pdfmark end 2367 2337 a 1988 2520 a Fo(re)o(gisters,)2310 2521 y SDict begin H.S end 2310 2521 a Black -1 x Fo(66)p Black 2393 2463 a SDict begin H.R end 2393 2463 a 2393 2520 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.66) cvn H.B /ANN pdfmark end 2393 2520 a 1988 2619 a Fo(Resistors,)2334 2620 y SDict begin H.S end 2334 2620 a Black -1 x Fo(51)p Black 2417 2563 a SDict begin H.R end 2417 2563 a 2417 2619 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.51) cvn H.B /ANN pdfmark end 2417 2619 a 1988 2719 a Fo(run,)2141 2720 y SDict begin H.S end 2141 2720 a Black -1 x Fo(10)p Black 2224 2663 a SDict begin H.R end 2224 2663 a 2224 2719 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2224 2719 a Fo(,)2265 2720 y SDict begin H.S end 2265 2720 a Black -1 x Fo(20)p Black 2348 2663 a SDict begin H.R end 2348 2663 a 2348 2719 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.20) cvn H.B /ANN pdfmark end 2348 2719 a 1988 2902 a Fo(SED1530,)2353 2903 y SDict begin H.S end 2353 2903 a Black -1 x Fo(55)p Black 2436 2845 a SDict begin H.R end 2436 2845 a 2436 2902 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.55) cvn H.B /ANN pdfmark end 2436 2902 a 1988 3001 a Fo(set,)2122 3002 y SDict begin H.S end 2122 3002 a Black -1 x Fo(10)p Black 2205 2945 a SDict begin H.R end 2205 2945 a 2205 3001 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2205 3001 a 1988 3101 a Fo(Solar)m(,)2202 3102 y SDict begin H.S end 2202 3102 a Black -1 x Fo(55)p Black 2285 3045 a SDict begin H.R end 2285 3045 a 2285 3101 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.55) cvn H.B /ANN pdfmark end 2285 3101 a 1988 3201 a Fo(step,)2164 3202 y SDict begin H.S end 2164 3202 a Black -1 x Fo(10)p Black 2247 3144 a SDict begin H.R end 2247 3144 a 2247 3201 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2247 3201 a Fo(,)2288 3202 y SDict begin H.S end 2288 3202 a Black -1 x Fo(20)p Black 2371 3144 a SDict begin H.R end 2371 3144 a 2371 3201 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.20) cvn H.B /ANN pdfmark end 2371 3201 a 1988 3300 a Fo(Stimulus,)2325 3300 y SDict begin H.S end 2325 3300 a Black Fo(41)p Black 2408 3244 a SDict begin H.R end 2408 3244 a 2408 3300 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.41) cvn H.B /ANN pdfmark end 2408 3300 a 1988 3400 a Fo(stimulus,)2311 3401 y SDict begin H.S end 2311 3401 a Black -1 x Fo(10)p Black 2394 3344 a SDict begin H.R end 2394 3344 a 2394 3400 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2394 3400 a Fo(,)2436 3400 y SDict begin H.S end 2436 3400 a Black Fo(21)p Black 2519 3344 a SDict begin H.R end 2519 3344 a 2519 3400 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.21) cvn H.B /ANN pdfmark end 2519 3400 a 1988 3499 a Fo(stopw)o(atch,)2366 3500 y SDict begin H.S end 2366 3500 a Black -1 x Fo(10)p Black 2449 3443 a SDict begin H.R end 2449 3443 a 2449 3499 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2449 3499 a Fo(,)2490 3499 y SDict begin H.S end 2490 3499 a Black Fo(22)p Black 2573 3443 a SDict begin H.R end 2573 3443 a 2573 3499 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.22) cvn H.B /ANN pdfmark end 2573 3499 a 1988 3599 a Fo(Switches,)2330 3600 y SDict begin H.S end 2330 3600 a Black -1 x Fo(51)p Black 2413 3543 a SDict begin H.R end 2413 3543 a 2413 3599 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.51) cvn H.B /ANN pdfmark end 2413 3599 a 1988 3699 a Fo(symbol,)2274 3700 y SDict begin H.S end 2274 3700 a Black -1 x Fo(10)p Black 2357 3642 a SDict begin H.R end 2357 3642 a 2357 3699 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2357 3699 a Fo(,)2399 3699 y SDict begin H.S end 2399 3699 a Black Fo(21)p Black 2482 3642 a SDict begin H.R end 2482 3642 a 2482 3699 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.21) cvn H.B /ANN pdfmark end 2482 3699 a 1988 3881 a Fo(trace,)2191 3882 y SDict begin H.S end 2191 3882 a Black -1 x Fo(10)p Black 2274 3825 a SDict begin H.R end 2274 3825 a 2274 3881 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2274 3881 a Fo(,)2316 3882 y SDict begin H.S end 2316 3882 a Black -1 x Fo(23)p Black 2399 3825 a SDict begin H.R end 2399 3825 a 2399 3881 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.23) cvn H.B /ANN pdfmark end 2399 3881 a 1988 3981 a Fo(ttl165,)2224 3983 y SDict begin H.S end 2224 3983 a Black -2 x Fo(49)p Black 2307 3925 a SDict begin H.R end 2307 3925 a 2307 3981 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.49) cvn H.B /ANN pdfmark end 2307 3981 a 1988 4081 a Fo(ttl377,)2224 4083 y SDict begin H.S end 2224 4083 a Black -2 x Fo(49)p Black 2307 4024 a SDict begin H.R end 2307 4024 a 2307 4081 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.49) cvn H.B /ANN pdfmark end 2307 4081 a 1988 4180 a Fo(ttl595,)2224 4181 y SDict begin H.S end 2224 4181 a Black -1 x Fo(50)p Black 2307 4124 a SDict begin H.R end 2307 4124 a 2307 4180 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.50) cvn H.B /ANN pdfmark end 2307 4180 a 1988 4363 a Fo(USAR)-5 b(T)21 b(module,)2567 4364 y SDict begin H.S end 2567 4364 a Black -1 x Fo(48)p Black 2650 4307 a SDict begin H.R end 2650 4307 a 2650 4363 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.48) cvn H.B /ANN pdfmark end 2650 4363 a 1988 4546 a Fo(v)o(ersion,)2273 4547 y SDict begin H.S end 2273 4547 a Black -1 x Fo(10)p Black 2356 4489 a SDict begin H.R end 2356 4489 a 2356 4546 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2356 4546 a 1988 4645 a Fo(V)-11 b(oltage)20 b(Sources,)2566 4646 y SDict begin H.S end 2566 4646 a Black -1 x Fo(51)p Black 2649 4589 a SDict begin H.R end 2649 4589 a 2649 4645 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.51) cvn H.B /ANN pdfmark end 2649 4645 a 1988 4828 a Fo(x,)2071 4829 y SDict begin H.S end 2071 4829 a Black -1 x Fo(10)p Black 2154 4772 a SDict begin H.R end 2154 4772 a 2154 4828 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.10) cvn H.B /ANN pdfmark end 2154 4828 a Fo(,)2196 4829 y SDict begin H.S end 2196 4829 a Black -1 x Fo(23)p Black 2279 4772 a SDict begin H.R end 2279 4772 a 2279 4828 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.23) cvn H.B /ANN pdfmark end 2279 4828 a 1988 4927 a Fo(xor2,)2182 4929 y SDict begin H.S end 2182 4929 a Black -2 x Fo(49)p Black 2265 4871 a SDict begin H.R end 2265 4871 a 2265 4927 a SDict begin [/Color [1 0 0]/H /I/Border [0 0 1]BorderArrayPatch/Subtype /Link/Dest (page.49) cvn H.B /ANN pdfmark end 2265 4927 a Black 1905 5208 a Fo(72)p Black eop end %%Trailer userdict /end-hook known{end-hook}if %%EOF gpsim-0.30.0/doc/metadata/0000775000076400007640000000000013117466025012256 500000000000000gpsim-0.30.0/doc/metadata/gpsim.desktop0000664000076400007640000000041013041763624014704 00000000000000[Desktop Entry] Encoding=UTF-8 Categories=Development Name=Gpsim Comment="A simulator for Microchip (TM) PIC (TM) microcontrollers" Comment[fr]="Un simulateur pour les microcontrĂ´leurs PIC (TM) Microchip (TM)" Exec=gpsim Terminal=true Type=Application Icon=gpsim gpsim-0.30.0/doc/metadata/gpsim.appdata.xml0000664000076400007640000000313213041763624015450 00000000000000 gpsim.desktop CC0-1.0 GPL-2.0+ and LGPL-2.1+

Gpsim is a simulator for Microchip (TM) PIC (TM) microcontrollers. It supports most devices in Microchip's 12-bit, 14bit, and 16-bit core families.

Gpsim can be controlled from either a graphical user interface (GUI), a command line interface (CLI) or by a remote process.

Typical debugging features like breakpoints, single stepping, disassembling, memory inspect and change, and so on are all supported. In addition, complex debugging features like real time tracing, assertions, conditional breaks, and plugin modules to name a few are also supported.

Gpsim supports dynamically loadable modules such as LED's, LCD's, resistors, etc. to extend the simulation environment beyond the PIC.

http://gpsim.sourceforge.net https://a.fsdn.com/con/app/proj/gpsim/screenshots/control_source.png Control and Source Windows https://a.fsdn.com/con/app/proj/gpsim/screenshots/breadboard_register.png Breadboard and Source Windows gpsim-devel_at_lists.sourceforge.net gpsim gpsim-0.30.0/doc/metadata/gpsim.png0000664000076400007640000000254713041763624014034 00000000000000‰PNG  IHDR00Wů‡.IDATxśí™_nŰ8ĆC*’ł>‘ÓޢÉ1úŕö Đk4{‡<1Úś'këÉ} ES˛(Óq‹MÁpB‡ÎÇá|˘<>>:ÁĂ÷ďß1Ć µćýű÷h­ßt»P‰s.|ţ„v`č€ÖzđýÖŰEy|| îYk’RŠ?ˇ}2Ŕ lĂźJ«Iý¸Ůż:رÎNęĆ•Óó9ÚS·ŰÚ‚ë;“úAly¨ŮšW÷MÍç„•ČžĚÖđtűD×t””|ćóěDleŮ|Ű`—űbĎë[Z6̵A¬$ő˛%áÓí:ş¶CˇĐh*ÝŻlvÓ ćd_eN9śň«ťr"Ëłó9×ě Ą*Q(J)1ĄAHŻŽ­†%ôŹë±4‚ŠmŰ8IÂiÖ#ظ’uł¦ Ŕ––çoĎ'Cl+;˙ű*ö/‹ýgłşŁ¬KÖÖRĚÂ);}诸BŁq8Źík?Á°˘ăEčŇ“ö{m±ÖŇŇŇŃ!şń0ű5{`z‡ĂľřAĹJrCŽa4ißĘáĂÄXjzq˛Ą7jjĂćnĂŽ |âÓ‘ËÓNĽVÎv S{X ĹQV™ },}¶qĘ?}‚¸B)Ń•¦š¦ˇpĹŢh&–eg§=LwÂWţŰ”>űĄ2Đ«čWEWšŐ·U8¤îďî1µßä§©XT­XÝ®Â˙ďšw€ß;ĎĎ… it*YŁ8;VµT°ô:55›ú±áď†Ög§>u^té…Ć)‡vš¶i}¢^ö˝@EEA‘úX¦2Użâs“?逳U)nţľ 'ńýí˝?hš’őÝ:@ĺÜĐÇ“ßb0„^”‰¨ZŞ^JÍ'¶9pŔěÎ`LD+íŔn'VwĚČ^̱éLÎgdł€ßǶâZč”NĽ‰çć3Ö?Š@.cĘa[ăM™Ň‰™—BͲżY>Ăâśę;®…R:yYń\@ŤŘeŇćI ŰŇCe*Oźb[9˘jĹęĂ ::ľđ…ššĘU¬›5ŤćyŚl™8h2ŘVލFí'SĐŃŃҢŃTTłśŰ÷Éý˘ÁźŚ—äďX:: p))©©/Ź@(wG q)Űę1ÝŇrĎ˝‡ ů"ń•ŻłŚďČ©Z!ŽĺRěÇŇĐPS#%eČ8íţŃčdßá»Ń‰Z%U>䲭)Ę‚Bаň‚ĐąiYkÖP6?Ü„~đăp Ü=˝ŠmÍÉ€Ů=¬B9ý“ź!Ťš[ÔéW6Á^ƵŠ(Á(3`[żCôBĂőľ´îÇŤ_kĎČđ$Ő*˘¶C¶ő;ÄYç @Ëá­PćÖBwű×zŁZ¨g[ľĂĺđů•rcŽkˇ©šhĽB)¶u®ÎąúG{ŔŐŁ,”q}”b[çęś«?Ľ#k^ű2Ů÷:±äč#pe!1&‰ŘV|ćĐŇ‹čţK˘ Ĺwd ű±ťÁ]X†ţp´‘RĆmaL)łôöSvrô}ÚßÔ?==…›ń›››p3ţVŰE„B)… nĹťs(ĄPJ˝év€b»ÝnEÄߎ´-Ƭµěv;”Roş]DŞŞ®Áož1vűČĽĺö˙ĺż–?¨l“ s_/IEND®B`‚gpsim-0.30.0/acinclude.m40000664000076400007640000000432613041763642012050 00000000000000dnl Borut Razem dnl dnl This macro checks for the presence of the readline library. dnl It works also in cross-compilation environment. dnl dnl To get it into the aclocal.m4 dnl file, do this: dnl aclocal -I . --verbose dnl dnl The --verbose will show all of the files that are searched dnl for .m4 macros. AC_DEFUN([wi_LIB_READLINE], [ dnl check for the readline.h header file AC_CHECK_HEADER(readline/readline.h) if test "$ac_cv_header_readline_readline_h" = yes; then dnl check the readline version cat > conftest.$ac_ext < #include wi_LIB_READLINE_VERSION RL_VERSION_MAJOR RL_VERSION_MINOR EOF wi_READLINE_VERSION=$($CPP $CPPFLAGS conftest.$ac_ext | sed -n -e "s/^wi_LIB_READLINE_VERSION *\([[0-9\]][[0-9\]]*\) *\([[0-9\]][[0-9\]]*\)$/\1.\2/p") rm -rf conftest* if test -n "$wi_READLINE_VERSION"; then wi_MAJOR=$(expr $wi_READLINE_VERSION : '\([[0-9]][[0-9]]*\)\.') wi_MINOR=$(expr $wi_READLINE_VERSION : '[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*$\)') if test $wi_MINOR -lt 10; then wi_MINOR=$(expr $wi_MINOR \* 10) fi wi_READLINE_VERSION=$(expr $wi_MAJOR \* 100 + $wi_MINOR) else wi_READLINE_VERSION=-1 fi dnl check for the readline library ac_save_LIBS="$LIBS" # Note: $LIBCURSES is permitted to be empty. for LIBREADLINE in "-lreadline.dll" "-lreadline" "-lreadline $LIBCURSES" "-lreadline -ltermcap" "-lreadline -lncurses" "-lreadline -lcurses" do AC_MSG_CHECKING([for GNU Readline library $LIBREADLINE]) LIBS="$ac_save_LIBS $LIBREADLINE" AC_TRY_LINK([ /* includes */ #include #include ],[ /* function-body */ int dummy = rl_completion_append_character; /* rl_completion_append_character appeared in version 2.1 */ readline(NULL); ],[ wi_cv_lib_readline=yes AC_MSG_RESULT(yes) ],[ wi_cv_lib_readline=no AC_MSG_RESULT(no) ]) if test "$wi_cv_lib_readline" = yes; then AC_SUBST(LIBREADLINE) AC_DEFINE_UNQUOTED(HAVE_LIBREADLINE, $wi_READLINE_VERSION, [Readline]) break fi done LIBS="$ac_save_LIBS" fi ]) gpsim-0.30.0/ANNOUNCE0000664000076400007640000000346713041763642011015 00000000000000 gpsim GNU Pic Simulator, a simulator for Microchip's PIC microcontrollers. Version 0.27.0 release http://sourceforge.net/project/showfiles.php?group_id=2341 http://gpsim.sourceforge.net/gpsim.html Highlights: The Enhanced Mid-Range Architecture is now supported by gpsim. Gpsim will compile with either gtkextra-2 or gtkextra-3. Memory cleanup, processor classes release memory on closing. The extra modules integrated into release package Cycle counter increments when MCLR pin low. Fixes for building with more recent tool chain. Extras module for DS1820 1-wire temperature sensor. New Processors: pic12f1822 pic16f684 pic16f1823 Bugs Reports closed: 131 Computed GOTO broken on big ROM 18F 132 Segfault on first loading COD file when compiled with clang 133 gpsim doesn't compile with a modern Linux build chain 134 can't generate lxt log 137 CCP match does not clear TMR1H:TMR1L 138 Computed GOTO cycle timing wrong 139 Data addressing wrong (PIC18 w/​ extended instruction mode) 146 LCD module: wrong #include 147 Conflicting declarations of variable DbmParseLineNumber 148 logging register writes does not work as expected 150 gpsim-0.26.1 UART transmitter not working 151 18f6520 PSP functionality missing 152 TRISD, TRISE incorrect on 18f6520 18c4x2 in WDT reset 153 P18 processors do not reset on stack overflow/​underflow and stack window does not work 155 p16f684 reset regression test does immediate WDT reset 156 Wrong register names when single stepping on 14bit processors 157 SVN does not compile with automake >= 1.12 Feature Requests closed 31 support for 16F684 32 Support for 16F enhanced midrange parts 33 1Wire DS1820 Digital Thermometer implementation. Patches Applied 28 Build with gtkextra-3 29 Check for libdl gpsim-0.30.0/Makefile.in0000664000076400007640000006466313117441634011734 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = gpsim.spec CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/gpsim.spec.in AUTHORS COPYING COPYING.LESSER \ ChangeLog INSTALL NEWS README TODO compile config.guess \ config.sub install-sh ltmain.sh missing ylwrap DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = eXdbm src cli xpms gui gpsim modules examples doc regression extras EXTRA_DIST = PROCESSORS HISTORY README.EXAMPLES ANNOUNCE README.MODULES \ README INSTALL.gpsim COPYING.LESSER \ config_win32.h.in \ makefile.mingw \ plat/win32/uxtime.h \ plat/win32/libgpsim.def \ plat/win32/glist.cpp \ plat/win32/settings_reg.h \ plat/win32/makefile.mingw \ plat/win32/modules.def \ plat/win32/icd.cc \ plat/win32/uxsleep.cc \ plat/win32/gpsim.ico \ plat/win32/gpsim.def \ plat/win32/gpsim.nsi \ plat/win32/uxtime.cc \ plat/win32/fd2raw.cpp \ plat/win32/unistd.h \ plat/win32/fd2raw.h \ plat/win32/settings_reg.cpp \ plat/win32/configure_win32.awk \ plat/win32/make.mingw all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 gpsim.spec: $(top_builddir)/config.status $(srcdir)/gpsim.spec.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile dist-hook: cp gpsim.spec $(distdir) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/Makefile.am0000664000076400007640000000137013041763642011707 00000000000000 ACLOCAL_AMFLAGS = -I m4 SUBDIRS = eXdbm src cli xpms gui gpsim modules examples doc regression extras dist-hook: cp gpsim.spec $(distdir) EXTRA_DIST = PROCESSORS HISTORY README.EXAMPLES ANNOUNCE README.MODULES \ README INSTALL.gpsim COPYING.LESSER \ config_win32.h.in \ makefile.mingw \ plat/win32/uxtime.h \ plat/win32/libgpsim.def \ plat/win32/glist.cpp \ plat/win32/settings_reg.h \ plat/win32/makefile.mingw \ plat/win32/modules.def \ plat/win32/icd.cc \ plat/win32/uxsleep.cc \ plat/win32/gpsim.ico \ plat/win32/gpsim.def \ plat/win32/gpsim.nsi \ plat/win32/uxtime.cc \ plat/win32/fd2raw.cpp \ plat/win32/unistd.h \ plat/win32/fd2raw.h \ plat/win32/settings_reg.cpp \ plat/win32/configure_win32.awk \ plat/win32/make.mingw gpsim-0.30.0/missing0000755000076400007640000001533012734477075011263 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gpsim-0.30.0/gpsim.spec0000664000076400007640000001300113117466031011634 00000000000000Name: gpsim Version: 0.30.0 Release: 1.%{?dist} Summary: A simulator for Microchip (TM) PIC (TM) microcontrollers Summary(fr): Un simulateur pour les microcontrĂ´leurs PIC (TM) Microchip (TM) Group: Development/Debuggers # Source code is GPLv2+ except src/, modules/ and eXdbm/ which are LGPLv2+ License: GPLv2+ and LGPLv2+ URL: http://www.dattalo.com/gnupic/gpsim.html Source: http://dl.sf.net/gpsim/gpsim-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: gtk+extra-devel, flex, readline-devel, popt-devel BuildRequires: autoconf %description gpsim is a simulator for Microchip (TM) PIC (TM) microcontrollers. It supports most devices in Microchip's 12-bit, 14bit, and 16-bit core families. In addition, gpsim supports dynamically loadable modules such as LED's, LCD's, resistors, etc. to extend the simulation environment beyond the PIC. %description -l fr gpsim est un simulateur pour les microcontrĂ´leurs PIC (TM) Microchip (TM). Il gère la plupart des microcontrĂ´leurs des familles 12, 14 et 16 bits. gpsim gère Ă©galement les modules chargeables dynamiquement tels que les LED, afficheurs LCD, rĂ©sistances, etc. afin d'Ă©tendre l'environnement de simulation des PIC. %package devel Summary: Libraries and files headers for gpsim Summary(fr): Bibliothèques et fichiers d'en-tĂŞtes pour gpsim Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description devel The %{name}-devel package includes the static libraries, header files, and documentation for compiling programs that use the gpsim library. %description -l fr devel Le paquetage %{name}-devel contient les bibliothèques statiques, les fichiers d'en-tĂŞtes et la documentation nĂ©cessaires Ă  la compilation des programmes qui utilisent la bibliothèque gpsim. %prep %setup -q # Fix files with non UTF8 characters mv AUTHORS AUTHORS.raw mv ChangeLog ChangeLog.raw iconv -f ISO88592 -t UTF8 AUTHORS.raw -o AUTHORS iconv -f ISO88592 -t UTF8 ChangeLog.raw -o ChangeLog rm -f ChangeLog.raw AUTHORS.raw autoconf %build %configure %{__make} %{?_smp_mflags} %install %{__rm} -rf %{buildroot} %{__make} install DESTDIR=%{buildroot} %{__rm} -f examples/Makefile %{__rm} -f examples/modules/Makefile %{__rm} -f examples/projects/Makefile %clean %{__rm} -rf %{buildroot} %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(-,root,root,-) %doc ANNOUNCE AUTHORS COPYING COPYING.LESSER ChangeLog HISTORY NEWS %doc README README.EXAMPLES README.MODULES TODO %doc doc/gpsim.lyx doc/gpsim.pdf doc/gpsim.ps %doc examples/ %{_bindir}/* %{_libdir}/*.so.* %files devel %defattr(-,root,root,-) %doc COPYING COPYING.LESSER %{_libdir}/*.so %exclude %{_libdir}/*.la %exclude %{_libdir}/*.a %{_includedir}/* %changelog * Sun Jun 06 2010 Roy Rankin 0.25.0-1 - Add LGPLv2+ license, do not include *.a files * Sun Mar 01 2009 Roy Rankin 0.23.0-1 - Convert doc files to UTF8 character set, version 0.23.0 * Thu Sep 27 2007 Alain Portal 0.22.0-5 - Add BR popt-devel * Tue Aug 21 2007 Alain Portal 0.22.0-4 - Licence tag clarification * Tue Feb 13 2007 Alain Portal 0.22.0-3 - Remove Makefiles that are in conflict between i386 and x86_64 arch Fix #228362 * Mon Feb 5 2007 Alain Portal 0.22.0-2 - FE7 rebuild * Tue Nov 14 2006 Alain Portal 0.22.0-1 - New upstream version - Remove patches that are no more needed (applied by upstream) * Thu Oct 05 2006 Christian Iseli 0.21.11-9 - rebuilt for unwind info generation, broken in gcc-4.1.1-21 * Sat Sep 23 2006 Alain Portal 0.21.11-8 - Add patch to fix a ktechlab crash, a ktechlab upstream contribution See http://ktechlab.org/download/gpsim.php - Use macros for rm and make - Use macro style instead of variable style * Fri Sep 1 2006 Alain Portal 0.21.11-7 - FE6 rebuild * Wed Mar 15 2006 Alain Portal 0.21.11-6 - Update Patch * Wed Mar 15 2006 Alain Portal 0.21.11-5 - Update Patch * Tue Mar 14 2006 Alain Portal 0.21.11-4 - Patch to make gcc-4.1.0 happy * Mon Mar 13 2006 Alain Portal 0.21.11-3 - Rebuild for FE5 * Thu Oct 6 2005 Alain Portal 0.21.11-2 - Remove useless Requires * Wed Oct 5 2005 Alain Portal 0.21.11-1 - New version - Improve download url * Fri Sep 30 2005 Alain Portal 0.21.4-5 - Improve prep section to make rpmlint happy - Contributions of Jose Pedro Oliveira Thanks to him. * Mon Sep 19 2005 Alain Portal 0.21.4-4 - Add missing a rm -rf RPM_BUILD_ROOT statement in the install section * Thu Sep 15 2005 Alain Portal 0.21.4-3 - Exclude .la file - Add examples * Tue Sep 13 2005 Alain Portal 0.21.4-2 - License is GPL - Add french summary and description * Mon Sep 12 2005 Alain Portal 0.21.4-1 - New version * Mon Nov 8 2004 Alain Portal 0:0.21.2-0.fdr.2 - Add BuildRequires flex, readline-devel * Wed Oct 27 2004 Alain Portal 0:0.21.2-0.fdr.1 - Initial Fedora RPM gpsim-0.30.0/COPYING.LESSER0000664000076400007640000006364213041763642011714 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! gpsim-0.30.0/INSTALL.gpsim0000664000076400007640000001464713041763613012033 00000000000000 gpsim Install Instructions -------------------------- TOC --- 1.0 Install instructions 1.1 Dependencies 2.0 How to Build gpsim without the gui 3.0 How to Build gpsim without root privileges 4.0 How to create your own gpsim distribution 5.0 Installing gtk+-extra 6.0 How to install gpsim from RPM's 7.0 MAC OS 8.0 Windows 9.0 CVS & SVN 1.0 Installation instructions ------------------------- INSTALLATION (the most common way) ---------------------------------- If you've ever installed software under Linux/UNIX before, then this will be completely familiar to you. 1) create a parent subdirectory for gpsim (e.g. gnupic) $ mkdir ~/gnupic # choose whatever directory name you like 2) Copy the tar ball to this directory and expand it: $ cd ~/gnupic $ mv the_path_of_where_ever_the_tarball_is/gpsim-0.x.y.tar.gz . $ tar -xvzf gpsim-0.x.y.tar.gz (Where 'x.y' is the release number.) This will create a subdirectory called gpsim-0.x.y . All of gpsim's source code will be untarred to here. 3) cd gpsim-0.x.y 4) ./configure This will check your system for the proper tools necessary to build gpsim and then it will create Makefiles. 5) make all This will create the executable. 6) su root . You'll need su privileges to complete the install. If you don't have root privileges or don't wish to install gpsim in the /usr/local/bin directory, then see the steps below on building without root privileges. 7) make install This copies the executable into the /usr/local/bin subdirectory. 1.1 Dependencies The most significant non-common gpsim dependency is on the gtkextra package: http://gtkextra.sourceforge.net/ Other dependencies include gtk-2.0, readline, popt. These packages should be installed on most distributions. However, it should be noted that the "developer" version are required if you're building gpsim from the source. 2.0 HOW TO BUILD gpsim WITHOUT THE GUI ---------------------------------- Repeat steps 1,2, and 3 from above. 4) ./configure --disable-gui Note: if you already have built gpsim with the gui support and then decide you want to take it out, then you'll also needed to do a 'make clean' before you do the 'make' in step 5. The make clean will remove all of the old object files. 3.0 HOW TO BUILD gpsim WITHOUT ROOT PRIVILEGES ------------------------------------------ Contributed by Erik Thiele ( Preface by Scott: Erik has created a step-by-step list of instructions for completely installing gpsim into a local directory. If you do not have root priviledges or just do not wish to install gpsim into the default directories then these instructions are for you. ) first create your local installation directory, # if you don't already have one. mkdir $HOME/localinst # now make the directory where you compile the programs in. mkdir $HOME/compiling # go into that directory cd $HOME/compiling # now download exdbm-VERSION-tar.gz and # gpsim-VERSION-tar.gz into the current directory. # also download gtk+extra-VERSION-tar.gz # if your distribution doesn't contain it. just start gtkextra-config # if that program was not found, you need to install gtk+extra # now let's first compile and install gtk+extra # you can skip this step if you already have gtk+extra installed. cd $HOME/compiling tar xzvf gtk+extra-VERSION-tar.gz cd gtk+extra-VERSION- ./configure --prefix=$HOME/localinst/gtk+extra make install cd $HOME # edit your shell configuration and add something like export PATH="$PATH":$HOME/localinst/gtk+extra/bin export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":$HOME/localinst/gtk+extra/lib # don't forget to relogin to let changes take effect. # now you can try to execute gtkextra-config # if it worked, gtk+extra is now installed. # now lets install exdbm library. cd $HOME/compiling tar xzvf exdbm-VERSION-tar.gz cd exdbm-VERSION- ./configure --prefix=$HOME/localinst/eXdbm make install cd $HOME # edit your shell configuration and add something like export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":~/localinst/eXdbm/lib # don't forget to relogin to let changes take effect. # now lets install gpsim cd $HOME/compiling tar xzvf gpsim-VERSION-tar.gz cd gpsim-VERSION- ./configure --with-exdbm=$HOME/localinst/eXdbm --prefix=$HOME/localinst/gpsim make install cd $HOME # edit your shell configuration and add something like export PATH="$PATH":$HOME/localinst/gpsim/bin # don't forget to relogin to let changes take effect. # if you want to save diskspace you can now do rm -rf $HOME/compiling/eXdbm rm -rf $HOME/compiling/gpsim rm -rf $HOME/compiling/gtk+extra # as these files were only needed for compiling and installation. 4.0 HOW TO MAKE YOUR OWN gpsim DISTRIBUTION --------------------------------------- Since gpsim uses automake, you get a whole lot of features for free. I won't go into all of them, but sometimes you might want to tweak gpsim and make your own tar ball. All you have to do is: $ make dist If you want to dink the rev numbers, then edit gpsim-0.x.y/configure.in and then from within gpsim-0.x.y/ : $ automake $ autoconf $ ./configure $ make dist 5.0 INSTALLING gtk+-extra ------------------------------- First, you're going to need to grab gtk+-extra. The best place to get this is from gpsim's web page since gtk+extra's page doesn't have a valid tar ball... $ tar -xvzf package.tar.gz $ cd package $ ./configure $ make $ su $ make install $ exit Where package is gtk+-extra. 6.0 INSTALLING RPM's ---------------- gpsim has two RPM's that both must be install. In addition, gpsim depends gtk+extra's RPMs. First, get the latest versions of: gtk+extra2-LATEST.rpm gtk+extra2-devel-LATEST.rpm gpsim-LATEST.rpm gpsim-devel-LATEST.rpm As root, install gtk+extra: # rpm -ihv gtk+extra2-LATEST.rpm # rpm -ihv gtk+extra2-devel-LATEST.rpm Then gpsim # rpm -ihv gpsim-devel-LATEST.rpm # rpm -ihv gpsim-LATEST.rpm Note that the order is important (and rpm will tell you if you're wrong). 7.0 MAC OS ------ There's a conflict with shared libraries and gpsim on the new MAC OS's. So for the MAC, configure gpsim like so: $ ./configure --disable-shared 8.0 Windows ------- Borut Razem has ported gpsim to windows. See http://gpsim.sourceforge.net/gpsimWin32/gpsimWin32.html for details on how to build and install gpsim Under Windows. 9.0 CVS & SVN --------- CVS is no longer supported. See http://gpsim.sourceforge.net/gpsim_cvs.html for instructions on how to retrieve and build gpsim from SVN repository. gpsim-0.30.0/cli/0000775000076400007640000000000013117465763010510 500000000000000gpsim-0.30.0/cli/cmd_set.cc0000664000076400007640000000441413041763642012351 00000000000000/* Copyright (C) 1999-2000 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "cmd_set.h" #include "input.h" #include "../src/pic-processor.h" static int radix = 0; // FIXME cmd_set c_set; enum { SET_VERBOSE, SET_RADIX, }; static cmd_options cmd_set_options[] = { {"r", SET_RADIX, OPT_TT_NUMERIC}, {"radix", SET_RADIX, OPT_TT_NUMERIC}, {"v", SET_VERBOSE, OPT_TT_BITFLAG}, {"verbose", SET_VERBOSE, OPT_TT_BITFLAG}, {0,0,0} }; cmd_set::cmd_set() : command("set",0) { brief_doc = string("display and control gpsim behavior flags"); long_doc = string ("set\n" "\twith no options, set will display the state of all of gpsim's\n" "\tbehavior flags. Use this to determine the flags that may be\n" "\tmodified.\n" "\n"); op = cmd_set_options; } void cmd_set::set(void) { cout << "r | radix = " << radix << " (not fully functional)\n"; cout << "v | verbose = " << (unsigned int)verbose << '\n'; // cout << "gui_update = " << gi.update_rate << '\n'; } void cmd_set::set(int bit_flag, Expression *expr) { int number=1; if(expr) { try { Value *v = expr->evaluate(); if(v) { gint64 i; v->get(i); number = (int)i; delete v; } delete expr; } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; return; } } switch(bit_flag) { case SET_VERBOSE: GetUserInterface().SetVerbosity(number); break; default: cout << " Invalid set option\n"; } } gpsim-0.30.0/cli/cmd_log.cc0000664000076400007640000000667113041763642012346 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_log.h" #include "../src/trace_orb.h" #include "../src/pic-processor.h" #include "../src/trace.h" #include "cmd_break.h" cmd_log c_log; #define LOG_ON 1 #define LOG_OFF 2 #define WRITE 3 #define READ 4 #define LOG_LXT 5 static cmd_options cmd_trace_options[] = { {"on", LOG_ON, OPT_TT_BITFLAG}, {"off", LOG_OFF, OPT_TT_BITFLAG}, {"w", WRITE, OPT_TT_BITFLAG}, {"r", READ, OPT_TT_BITFLAG}, {"lxt", LOG_LXT, OPT_TT_BITFLAG}, { 0,0,0} }; cmd_log::cmd_log() : command("log",0) { brief_doc = string("Log/record events to a file"); long_doc = string ("\n\ The log command will record simulation history in a file. It's similar to the\n\ break command\n\ log [[on|lxt [file_name]]|[off]]\n\ Enables or disables logging. Specify no options to see log status.\n\ The lxt option encodes the log file so that an external viewer\n\ like gtkwave can be used to view the file.\n\ log w|r reg [, expr]\n\ Specify a register to log. See the break command for expression syntax\n\ \n Examples:\n\ \tlog - Display log status\n\ \tlog on - Begin logging in file gpsim.log\n\ \tlog on file.log - Begin logging in file file.log\n\ \tlog lxt - Begin lxt logging in file gpsim.lxt\n\ \tlog lxt file.lxt - Begin lxt logging in file file.lxt\n\ \tlog off - Stop logging\n\ \tlog w temp_hi - Log all writes to reg temp_hi\n\ "); op = cmd_trace_options; } void cmd_log::log() { GetTraceLog().status(); } void cmd_log::log(cmd_options *opt, ExprList_t *eList) { if (!opt) { log(); return; } switch(opt->value) { case LOG_ON: case LOG_LXT: { int fmt = opt->value==LOG_ON ? TRACE_FILE_FORMAT_ASCII : TRACE_FILE_FORMAT_LXT; //const char *fn=0; if (eList) { ExprList_itor ei = eList->begin(); Expression *pFirst = *ei; LiteralString *pString=0; string m; if (pFirst) { pString = dynamic_cast(pFirst); if (pString) { String *pS = (String *)pString->evaluate(); GetTraceLog().enable_logging(pS->getVal(),fmt); delete pFirst; delete pS; } } } else GetTraceLog().enable_logging(0,fmt); } break; case LOG_OFF: GetTraceLog().disable_logging(); break; default: c_break.set_break(opt,eList,true); } } void cmd_log::log(cmd_options *opt) { switch(opt->value) { case LOG_ON: GetTraceLog().enable_logging(0); break; case LOG_OFF: GetTraceLog().disable_logging(); break; case LOG_LXT: GetTraceLog().enable_logging(0,TRACE_FILE_FORMAT_LXT); break; default: cout << " Invalid log option\n"; } } gpsim-0.30.0/cli/cmd_break.h0000664000076400007640000000256613041763642012512 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_BREAK_H__ #define __CMD_BREAK_H__ #include #include #include "command.h" class gpsimObject; #define CMDBREAK_BAD_BREAK_NUMBER 0xffff class cmd_break : public command { public: cmd_break(); void list(guint64 value=CMDBREAK_BAD_BREAK_NUMBER); unsigned int set_break(cmd_options *co, bool bLog=false); unsigned int set_break(cmd_options *co, ExprList_t *pEL, bool bLog=false); unsigned int set_break(gpsimObject *v); private: unsigned int set_break(cmd_options *co, Expression *pExpr1, Expression *pExpr2=0, bool bLog=false); unsigned int set_break(int bit_flag, bool bLog); }; extern cmd_break c_break; #endif gpsim-0.30.0/cli/cmd_shell.cc0000664000076400007640000000201713041763642012662 00000000000000#include #include using namespace std; #include "command.h" #include "cmd_shell.h" #include "../src/cmd_manager.h" cmd_shell c_shell; static cmd_options cmd_shell_options[] = { {0,0,0} }; cmd_shell::cmd_shell() : command("!",0) { brief_doc = string("Shell out to another program or module's command line interface"); long_doc = string ("!cmd.exe copy a.c b.c\n" "!picxx args\n" "\n"); op = cmd_shell_options; } string sTarget; void cmd_shell::shell(String *cmd) { sTarget = cmd->getVal(); char *pArguments = (char *)sTarget.c_str(); if(*pArguments == '\0') { CCommandManager::GetManager().ListToConsole(); } else { while(pArguments != NULL && *pArguments != '\0' && !isspace(*pArguments)) pArguments++; *pArguments = 0; pArguments++; int iResult; iResult = CCommandManager::GetManager().Execute(sTarget, pArguments); if (iResult == CMD_ERR_PROCESSORNOTDEFINED) printf("%s module command processor not found\n", sTarget.c_str()); } } gpsim-0.30.0/cli/ui_gpsim.cc0000664000076400007640000000256113041763642012550 00000000000000#include #include #include #include "ui_gpsim.h" #include "../src/sim_context.h" #include "../src/symbol.h" #include "../src/cmd_manager.h" extern GlobalVerbosityAccessor verbose; /// /// CGpsimConsole /// Connector between the gpsim console and the /// console handler for the loaded modules. ////////////////////////////////////////////////// CGpsimConsole::CGpsimConsole() { } void CGpsimConsole::Printf(const char *fmt, ...) { va_list ap; va_start(ap,fmt); vfprintf(m_pfOut, fmt, ap); va_end(ap); } void CGpsimConsole::VPrintf(const char *fmt, va_list argptr) { vfprintf(m_pfOut, fmt, argptr); } void CGpsimConsole::Puts(const char*s) { fputs(s, m_pfOut); } void CGpsimConsole::Putc(const char c) { fputc(c, m_pfOut); } const char* CGpsimConsole::Gets(char *s, int size) { return fgets(s, size, m_pfIn); } void CGpsimConsole::SetOut(FILE *pOut) { m_pfOut = pOut; } void CGpsimConsole::SetIn(FILE *pIn) { m_pfIn = pIn; } CGpsimConsole g_Console; // From input.cc class Macro; void add_string_to_input_buffer(const char *s, Macro *m=0); void NotifyExitOnBreak(int iExitCode) { add_string_to_input_buffer("abort_gpsim_now\n"); } void initialize_ConsoleUI() { g_Console.SetOut(stdout); g_Console.SetIn(stdin); GetUserInterface().SetConsole(&g_Console); GetUserInterface().SetExitOnBreak(NotifyExitOnBreak); } gpsim-0.30.0/cli/cmd_break.cc0000664000076400007640000002501513045306453012637 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "command.h" #include "cmd_break.h" #include "../src/cmd_gpsim.h" #include "../src/pic-processor.h" #include "../src/operator.h" cmd_break c_break; #define CYCLE 1 #define EXECUTION 2 #define WRITE 3 #define READ 4 #define REGCHANGE 5 #define STK_OVERFLOW 7 #define STK_UNDERFLOW 8 #define WDT 9 static cmd_options cmd_break_options[] = { {"c", CYCLE, OPT_TT_BITFLAG}, {"e", EXECUTION, OPT_TT_BITFLAG}, {"w", WRITE, OPT_TT_BITFLAG}, {"r", READ, OPT_TT_BITFLAG}, {"ch", REGCHANGE, OPT_TT_BITFLAG}, {"so", STK_OVERFLOW, OPT_TT_BITFLAG}, {"su", STK_UNDERFLOW,OPT_TT_BITFLAG}, {"wdt", WDT, OPT_TT_BITFLAG}, {0,0,0} }; cmd_break::cmd_break() : command("break", "br") { brief_doc = string("Set a break point"); long_doc = string ("The 'break' command can be used to examine or set breakpoints.\n" "gpsim supports execution style breaks, register access breaks,\n" "complex expression breaks, attribute breaks, and other special breaks.\n" "Program Memory breaks:\n" " break e|r|w ADDRESS [,expr] [,\"message\"]\n" " Halts when the address is executed, read, or written. The ADDRESS can be \n" " a symbol or a number. If the optional expr is specified, then it must\n" " evaluate to true before the simulation will halt. The optional message\n" " allows a description to be associated with the break.\n" "Register Memory breaks:\n" " break r|w|ch REGISTER [,expr] [,\"message\"]\n" " Halts when 'REGISTER' is read, written, or changed\n" " and the optional expression evaluates to true\n" " break r|w|ch boolean_expression\n" " The boolean expression can only be of the form:\n" " a) reg & mask == value\n" " b) reg == value\n" " - Note the 'ch' option is similar to the write option.\n" " The change option evaluates the expression before and after\n" " a register write and halts if the evaluation differs.\n" "Cycle counter breaks:\n" " break c VALUE [,\"message\"]\n" " Halts when the cycle counter reaches 'VALUE'.\n" "Attribute breaks:\n" " break attribute\n" " Arms the breakpoint condition for those attributes that support breaks.\n" " For example, the stopwatch (help stopwatch) attribute can cause a break.\n" "Miscellaneous breaks:\n" " break so # halts on stack overflow.\n" " break su # halts on stack underflow.\n" " break wdt # halts on Watch Dog Timer timeout.\n" "Expressions:\n" " The conditional expressions mentioned above are syntactically similar to C's\n" " expressions.\n" "Examples:\n" "\tbreak # display all of the break points\n" "\tbreak e 0x20 # set an execution break point at address 0x20\n" "\tbreak w reg1 == 0 # break if a zero is written to register reg1\n" "\tbreak w reg2 & 0x30 == 0xf0 # break if '3' is written to the\n" "\t # upper nibble or reg2\n" "\tbreak w reg3, (reg4 > 45) # break if reg4>45 while writing to reg3\n" "\tbreak c 1000000 # break on the one million'th cycle\n" ); op = cmd_break_options; } void cmd_break::list(guint64 value) { if(value == CMDBREAK_BAD_BREAK_NUMBER) get_bp().dump(); else if(!get_bp().dump1((unsigned int)value)) printf("break not found at given break point number %u (0x%x)\n", (unsigned int)value, (unsigned int)value); } const char *TOO_FEW_ARGS="missing register or location\n"; const char *TOO_MANY_ARGS="too many arguments\n"; //------------------------------------------------------------------------ static gpsimObject::ObjectBreakTypes MapBreakActions(int co_value) { switch(co_value) { case READ: return gpsimObject::eBreakRead; case WRITE: return gpsimObject::eBreakWrite; case REGCHANGE: return gpsimObject::eBreakChange; case EXECUTION: return gpsimObject::eBreakExecute; } return gpsimObject::eBreakAny; } //------------------------------------------------------------------------ unsigned int cmd_break::set_break(cmd_options *co, ExprList_t *pEL, bool bLog) { if (!co) { list(); return MAX_BREAKPOINTS; } if (!pEL || pEL->size()>3) { // FIXME - fix this error message cout << "ERROR: Bad expression for break command\n"; return MAX_BREAKPOINTS; } ExprList_itor ei = pEL->begin(); Expression *pFirst = *ei; ++ei; Expression *pSecond = (ei != pEL->end()) ? *ei++ : 0; Expression *pThird = (ei != pEL->end()) ? *ei : 0; if (verbose) { cout << "setting breakpoint:\n"; if (pFirst) cout << " first expression " << pFirst->toString() << endl; if (pSecond) cout << " second expression " << pSecond->toString() << endl; if (pThird) cout << " third expression " << pThird->toString() << endl; } LiteralString *pString=0; string m; if (pSecond) { pString = dynamic_cast(pSecond); if (pString) { String *pS = (String *)pString->evaluate(); m = string(pS->getVal()); delete pSecond; delete pS; pSecond =0; } } // If there is a third expression and the second expression is not // a string, then try to cast the third expression into a string. if (pThird && !pString) { pString = dynamic_cast(pThird); if (pString) { String *pS = (String *)pString->evaluate(); m = string(pS->getVal()); delete pThird; delete pS; pThird =0; } } if (!pFirst) return set_break(co->value,bLog); // See if the expression supports break points. If it does, the break points // will get set and the expressions deleted. int bpn = pFirst ? pFirst->set_break(MapBreakActions(co->value), (bLog ? gpsimObject::eActionLog : gpsimObject::eActionHalt), pSecond) : -1; if (bpn == -1 && co->value!=CYCLE) GetUserInterface().DisplayMessage("break cannot be set on '%s'\n", pFirst->toString().c_str()); if (bpn<0) { // We failed to set a break point from the first expression. // It may be that we have a type of break point that is not supported // by the expression code. if (co->value==CYCLE) { LiteralInteger *pLitInt = dynamic_cast(pFirst); Integer *pInt = pLitInt ? dynamic_cast(pLitInt->evaluate()) : 0; guint64 ui64Val = pInt ? (guint64)pInt->getVal() : 0; if (pInt) bpn = get_bp().set_cycle_break(GetActiveCPU(),ui64Val); delete pInt; } } if (bpn>=0) { if (pString) get_bp().set_message(bpn, m); if(verbose)get_bp().dump1(bpn); //RRR if (dynamic_cast(pFirst)) delete pFirst; } else { delete pFirst; if(pSecond != 0) delete pSecond; } delete pEL; return bpn; } //------------------------------------------------------------------------ // set_break(cmd_options *co, // Expression *pExpr1, // Expression *pExpr2) // // Given two expressions, this function will call the set unsigned int cmd_break::set_break(cmd_options *co, Expression *pExpr1, Expression *pExpr2, bool bLog) { if (!co) { list(); return MAX_BREAKPOINTS; } unsigned int bit_flag = co->value; if (!pExpr1) return set_break(bit_flag,bLog); // See if the expression supports break points. If it does, the break points // will get set and the expressions deleted. int i = pExpr1 ? pExpr1->set_break(MapBreakActions(co->value), (bLog ? gpsimObject::eActionLog : gpsimObject::eActionHalt), pExpr2) : -1; if (i>=0) { get_bp().dump1(i); return i; } unsigned int b = MAX_BREAKPOINTS; delete pExpr1; delete pExpr2; return b; } unsigned int cmd_break::set_break(cmd_options *co, bool bLog) { if (!co) { list(); return MAX_BREAKPOINTS; } int bit_flag = co->value; return set_break(bit_flag, bLog); } unsigned int cmd_break::set_break(int bit_flag, bool bLog) { unsigned int b = MAX_BREAKPOINTS; if(!GetActiveCPU()) return b; switch(bit_flag) { case STK_OVERFLOW: b = get_bp().set_stk_overflow_break(GetActiveCPU()); if(b < MAX_BREAKPOINTS) cout << "break when stack over flows. " << "bp#: " << b << '\n'; break; case STK_UNDERFLOW: b = get_bp().set_stk_underflow_break(GetActiveCPU()); if(b < MAX_BREAKPOINTS) cout << "break when stack under flows. " << "bp#: " << b << '\n'; break; case WDT: b = get_bp().set_wdt_break(GetActiveCPU()); if(b < MAX_BREAKPOINTS) cout << "break when wdt times out. " << "bp#: " << b << '\n'; break; case CYCLE: get_bp().dump(Breakpoints::BREAK_ON_CYCLE); break; case EXECUTION: get_bp().dump(Breakpoints::BREAK_ON_EXECUTION); break; case WRITE: get_bp().dump(Breakpoints::BREAK_ON_REG_WRITE); break; case READ: get_bp().dump(Breakpoints::BREAK_ON_REG_READ); break; default: cout << TOO_FEW_ARGS; break; } return b; } // attribute breakpoints unsigned int cmd_break::set_break(gpsimObject *v) { if (v) v->set_break(); return MAX_BREAKPOINTS; } gpsim-0.30.0/cli/cmd_version.h0000664000076400007640000000170613041763642013106 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_VERSION_H__ #define __CMD_VERSION_H__ class cmd_version : public command { public: cmd_version(void); void version(void); virtual int is_repeatable(void) { return 1; }; }; extern cmd_version version; #endif gpsim-0.30.0/cli/cmd_step.cc0000664000076400007640000000313513041763642012530 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_step.h" #include "../src/pic-processor.h" cmd_step step; static cmd_options cmd_step_options[] = { {"over",1, OPT_TT_BITFLAG}, { 0,0,0} }; cmd_step::cmd_step() : command("step","s") { brief_doc = string("Execute one or more instructions."); long_doc = string ("\nstep [over | n]\n\n\ \t no arguments: step one instruction.\n\ \tnumeric argument: step a number of instructions\n\ \t \"over\" argument: step over the next instruction\n\ \n\ "); op = cmd_step_options; } void cmd_step::step(int instructions) { get_interface().step_simulation(instructions); } void cmd_step::step(Expression *expr) { get_interface().step_simulation((int)evaluate(expr)); } void cmd_step::over(void) { get_interface().advance_simulation(gpsimInterface::eAdvanceNextInstruction); } gpsim-0.30.0/cli/cmd_macro.cc0000664000076400007640000001461113045306453012654 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_macro.h" extern int parse_string(const char * str); extern void add_string_to_input_buffer(const char *s,Macro *); extern void start_new_input_stream(void); class MacroLine { string text; }; map macro_map; Macro::Macro(const char *_name) { new_name(_name); if(verbose & 4) cout << "defining a new macro named: " << name() << endl; } //---------------------------------------- //add_argument(char *new_arg) // // Add a new argument to the macro. This is called when // the macro is being defined. void Macro::add_argument(const char *new_arg) { if(new_arg) arguments.push_back(string(new_arg)); if(verbose & 4) { cout << "defining a paramter named: " << new_arg << endl; } } //---------------------------------------- //add_body(char *new_line) // // Add a new line to the macro body. This is called when // the macro is being defined. These same lines will get // redirected to the lexer input stream when the macro // is invoked. void Macro::add_body(const char *new_line) { if(!new_line) return; body.push_back(string(new_line)); if(verbose & 4) { cout << "macro body: " << new_line << endl; } } //---------------------------------------- // invoke() // // Invoke a macro by copying its body to the lexer input // stream. void Macro::invoke() { list :: iterator si; start_new_input_stream(); for(si = body.begin(); si != body.end(); ++si) add_string_to_input_buffer( (*si).c_str(), this); add_string_to_input_buffer("endm\n", this); } //---------------------------------------- // substituteParameter(const string &s, string &replaced) // // Given a string 's', this function will search to see if // this is the name of one of the macro parameters. If it // is, then the text that should replace that parameter is // is returned in the string 'replaced'. // // This routine gets called when the lexer comes across an // undefined identifier while it is trying to expand a macro. // int Macro::substituteParameter(const string &s, string &replaced) { if (!arguments.empty()) { list :: iterator asi; list :: iterator psi; for(asi = arguments.begin(), psi = parameters.begin(); asi != arguments.end(); ++asi, ++psi) if(*asi == s) { replaced = *psi; if(verbose&4) cout << "Found match, replacing "<<*asi << " with " << *psi< :: iterator si; for (si = arguments.begin(); si != arguments.end(); ++si) std::cout << *si << " "; std::cout << std::endl; for (si = body.begin(); si != body.end(); ++si) std::cout << " " << *si; std::cout << "endm\n"; } // hack.... static Macro *theMacro = 0; // Used during macro definition Macro *isMacro(const string &s) { map::iterator mi = macro_map.find(s); if(mi != macro_map.end()) return (*mi).second; return 0; } //======================================================================== cmd_macro c_macro; static cmd_options cmd_macro_options[] = { {0,0,0} }; cmd_macro::cmd_macro() : command("macro",0) { brief_doc = string("macro definition and listing"); long_doc = string ("\nListing Macros:\n\n" "\tmacro -- display the names of the currently defined macros\n" "\t (use the symbol command to see a particular macro definition)\n" "\nDefining Macros:\n" "\nname macro [arg1, arg2, ...]\n" "macro body\n" "endm\n\n" "Example:\n\n" "s macro n, regs\n" "echo Step and Show\n" "step n\n" "x regs\n" "endm\n\n" "Invoke by\n\n" "gpsim> s 5, 1:10\n" " (note that the parameters must be separated by commas)\n" ); op = cmd_macro_options; } void cmd_macro::list() { if(macro_map.size()) { map::iterator mi; for (mi=macro_map.begin(); mi!=macro_map.end(); ++mi) mi->second->print(); } else cout << "No macros have been defined.\n"; } void cmd_macro::define(const char *name) { if(!name) return; map::iterator mi = macro_map.find(string(name)); if(mi != macro_map.end()) { cout << "macro '" << name << "' is already defined\n"; return; } theMacro = new Macro(name); macro_map[theMacro->name()] = theMacro; } void cmd_macro::add_parameter(const char *parameter) { if(!parameter || !theMacro) return; theMacro->add_argument(parameter); } void cmd_macro::add_body(const char *line) { if(!line) return; theMacro->add_body(line); } void cmd_macro::end_define(const char *opt_name) { if(verbose & 4) { GetUserInterface().GetConsole().Printf( "ending macro definition of '%s'\n", theMacro->name().c_str()); } theMacro = 0; } gpsim-0.30.0/cli/scan.ll0000664000076400007640000006401613114656207011704 00000000000000%{ /* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #ifdef _WIN32 /* declaration of isatty() */ #include #endif #include "../config.h" #include "../src/operator.h" #include "../src/symbol.h" #include "../src/stimuli.h" #include "../src/processor.h" #include "command.h" #include "cmd_macro.h" #include "parse.h" #include "input.h" #include "scan.h" /* Since our parser is reentrant, it needs to pass us a pointer * to the yylval that it would like us to use */ #ifdef YY_PROTO #define YY_DECL int yylex YY_PROTO(( YYSTYPE* yylvalP )) #else #define YY_DECL int yylex ( YYSTYPE* yylvalP ) #endif extern int yyparse(void); #define exit exit_gpsim /* This is the max length of a line within a macro definition */ static char macroBody[65536], *macroBodyPtr=0; static char* max_bodyPtr = ¯oBody[0] + sizeof(macroBody)-1; struct LexerStateStruct { struct cmd_options *options; command *cmd; int input_mode; int end_of_command; int have_parameters; int mode; struct LexerStateStruct *prev; struct LexerStateStruct *next; }; static char * m_pLastFullCommand = NULL; void SetLastFullCommand(const char *pCmd) { if (strlen(pCmd)>1) { if (m_pLastFullCommand) free (m_pLastFullCommand); m_pLastFullCommand = strdup(pCmd); } } const char * GetLastFullCommand() { return m_pLastFullCommand; } static LexerStateStruct *pLexerState = 0; static int sLevels=0; extern int quit_parse; extern int parser_spanning_lines; extern int last_command_is_repeatable; static string strip_trailing_whitespace (char *s); static int handle_identifier(YYSTYPE* yylvalP, string &tok, cmd_options **op ); static int process_intLiteral(YYSTYPE* yylvalP, char *buffer, int conversionBase); static int process_booleanLiteral(YYSTYPE* yylvalP, bool value); static int process_macroBody(YYSTYPE* yylvalP, const char *text); static int process_floatLiteral(YYSTYPE* yylvalP, char *buffer); static int process_stringLiteral(YYSTYPE* yylvalP, const char *buffer); static int process_quotedStringLiteral(YYSTYPE* yylvalP, char *buffer); static int process_shellLine(YYSTYPE* yylvalP, const char *buffer); static int recognize(int token,const char *); static void SetMode(int newmode); void scanPopMacroState(); int cli_corba_init (char *ior_id); extern Macro *isMacro(const string &s); static Macro *gCurrentMacro=0; #define YYDEBUG 1 //======================================================================== // MacroChain class // // class MacroChain { public: struct Link { Link *prev; Link *next; Macro *m; }; MacroChain() { head.prev = head.next =0; curr = &head; } void push(Macro *m) { if (verbose & 4 && m) { cout << "Pushing " << m->name() << " onto the macro chain\n"; } Link *pL = new Link(); pL->m = m; pL->prev = &head; pL->next = head.next; head.next = pL; param = pL; curr = &head; } void pop() { Link *pL = head.next; if (pL) { if (verbose & 4 && pL->m) { cout << "Popping " << pL->m->name() << " from the macro chain\n"; } head.next = pL->next; if (pL->next) pL->next->prev = &head; delete pL; } } Macro *nextParamSource() { if (curr) curr = curr->next; if (verbose & 4 && curr && curr->m ) { cout << " selecting parameter source " << curr->m->name() << endl; } if(curr) return curr->m; return 0; } void popParamSource() { if (verbose & 4 && curr && curr->m ) { cout << " popping parameter source " << curr->m->name() << endl; } if (curr) curr = curr->prev; } void resetParamSource() { if (verbose & 4) { cout << " resetparameter source\n"; } curr = &head; } private: Link *curr; Link head; Link *param; }; static MacroChain theMacroChain; %} D [0-9] S [ \t] NL ((\n)|(\r\n)) SNL ({S}|{NL}) BS (\\) CONT ({EL}|{BS}) CCHAR (#) COMMENT ({CCHAR}.*) SNLCMT ({SNL}|{COMMENT}) INDIRECT (\*) IDENTIFIER ([\']?[/_a-zA-Z\.][/_a-zA-Z0-9\.\-]*) INDEXERLEFT (\[) INDEXERRIGHT (\]) EXPON ([DdEe][+-]?{D}+) DEC ({D}+) DEC2 ([dD]\'{D}+\') HEX1 ((0[Xx])[0-9a-fA-F]+) HEX2 ("$"[0-9a-fA-F]+) FLOAT (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)) BIN1 (0[bB][01]+) BIN2 ([bB]\'[01]+\') SHELLCHAR (^[!]) SHELLLINE ({SHELLCHAR}.*) QUOTEDTOKEN (("\"".*\")|("\'".*')) QUOTEDTOKEN2 (([\\]"\"".*\")|([\\]"\'".*')) %{ /* Lexer States */ %} %x MACROBODY %x DECLARATION %{ //************************************************************************ //************************************************************************ %} %% %{ // Comments. Ignore all text after a comment character %} {COMMENT} { return recognize(COMMENT_T,"comment"); } {S}+ { /* ignore white space */ } \n { if(verbose) cout << "got EOL\n"; pLexerState->input_mode = 0; // assume that this is not a multi-line command. if(pLexerState->cmd && pLexerState->cmd->can_span_lines() && pLexerState->have_parameters && !pLexerState->end_of_command ) pLexerState->input_mode = CONTINUING_LINE; else { pLexerState->cmd = 0; return recognize(EOLN_T, " end of line"); } } { // Got an eol. if(verbose) cout << "got INITIAL\n"; pLexerState->input_mode = 0; // assume that this is not a multi-line command. if(pLexerState->cmd && pLexerState->cmd->can_span_lines() && pLexerState->have_parameters && !pLexerState->end_of_command ) pLexerState->input_mode = CONTINUING_LINE; //else // return recognize(EOLN_T, " end of line"); } q{S}+\n { /* short cut for quiting */ quit_parse =1; return QUIT; } abort_gpsim_now { /* a sure way to abort a script */ return ABORT; } "=" {return(recognize(EQU_T, "="));} "&&" {return(recognize(LAND_T, "&&"));} "||" {return(recognize(LOR_T, "||"));} ":" {return(recognize(COLON_T, ":"));} "!" {return(recognize(LNOT_T,"!"));} "~" {return(recognize(ONESCOMP_T,"~"));} "+" {return(recognize(PLUS_T,"+"));} "-" {return(recognize(MINUS_T,"-"));} "*" {return(recognize(MPY_T,"*"));} "/" {return(recognize(DIV_T,"/"));} "^" {return(recognize(XOR_T,"^"));} "&" {return(recognize(AND_T,"&"));} "|" {return(recognize(OR_T,"|"));} "<<" {return(recognize(SHL_T,"<<"));} ">>" {return(recognize(SHR_T,">>"));} "==" {return(recognize(EQ_T, "=="));} "!=" {return(recognize(NE_T, "!="));} "<" {return(recognize(LT_T, "<"));} ">" {return(recognize(GT_T, ">"));} "<=" {return(recognize(LE_T, "<="));} ">=" {return(recognize(GE_T, ">="));} "[" {return(recognize(INDEXERLEFT_T, "["));} "]" {return(recognize(INDEXERRIGHT_T, "]"));} {BIN1} {return(process_intLiteral(yylvalP,&yytext[2], 2));} {BIN2} {return(process_intLiteral(yylvalP,&yytext[2], 2));} {DEC} {return(process_intLiteral(yylvalP,&yytext[0], 10));} {DEC2} {return(process_intLiteral(yylvalP,&yytext[2], 10));} {HEX1} {return(process_intLiteral(yylvalP,&yytext[2], 16));} {HEX2} {return(process_intLiteral(yylvalP,&yytext[1], 16));} {FLOAT} {return process_floatLiteral(yylvalP,yytext);} "true" {return(process_booleanLiteral(yylvalP,true));} "false" {return(process_booleanLiteral(yylvalP,false));} "reg" {return(recognize(REG_T,"reg"));} "pin" {return(recognize(GPSIMOBJECT_T, "pin")); /*return(recognize(STIMULUS_T, "pin"));*/} "port" {return(recognize(PORT_T, "port"));} "endm" {scanPopMacroState();} ^[!].* {return(process_shellLine(yylvalP,&yytext[1]));} {QUOTEDTOKEN} {return(process_quotedStringLiteral(yylvalP,&yytext[1]));} {QUOTEDTOKEN2} {return(process_quotedStringLiteral(yylvalP,&yytext[2]));} %{ //======================================================================== // Macro processing %} ^[ \t]?+"endm" {SetMode(INITIAL); return(recognize(ENDM,"endm")); } \r {/*discard CR's*/} \n {*macroBodyPtr++ = '\n'; *macroBodyPtr = 0; macroBodyPtr = macroBody; return(process_macroBody(yylvalP,macroBody));} . { *macroBodyPtr++ = *yytext; if(verbose&4) printf("adding [%c]\n", *yytext); if (macroBodyPtr > max_bodyPtr) { cout << "buffer overflow in macro definition\n"; exit_gpsim(0); } } %{ //======================================================================== // Declaration Processing %} \n {SetMode(INITIAL); return(recognize(EOLN_T, "end of declaration")); } "int" {return recognize(DECLARE_INT_T, "int type"); } "float" {return recognize(DECLARE_FLOAT_T,"float type"); } "bool" {return recognize(DECLARE_BOOL_T, "bool type"); } "char" {return recognize(DECLARE_FLOAT_T,"char type"); } {IDENTIFIER} { return process_stringLiteral(yylvalP, yytext); } %{ // The 'echo' command is handled by the lexer instead of the // parser (like the other commands). All it does is just display // the contents of yytext beyond the "echo". %} "echo"{S}.*{NL} { fprintf(yyout,"%s",&yytext[5]); return recognize(EOLN_T, " end of line"); } "echo"{NL} { fprintf(yyout,"\n"); return recognize(EOLN_T, " end of line"); } %{ // Indirect register access.... this should be an expression operator. %} %{ /* {INDIRECT} { return INDIRECT; } */ %} %{ // If this is a command that is spanning more than one line // then the 'end' command will finish it. %} "end"{S}* { if (pLexerState->cmd && pLexerState->cmd->can_span_lines() ) { pLexerState->end_of_command = 1; return(END_OF_COMMAND); } printf("Warning: found \"end\" while not in multiline mode\n"); } %{ // Identifiers. These are either gpsim commands or user macros. %} {IDENTIFIER} { string tok = strip_trailing_whitespace (yytext); int ret=0; if(strlen(tok.c_str())) ret = handle_identifier (yylvalP, tok, &pLexerState->options); else ret = recognize(0,"invalid identifier"); if(ret) return ret; } %{ /* Default is to recognize the character we are looking at as a single char */ %} . {return(recognize(*yytext,"Single character"));} %% /* make it work with flex 2.5.31 */ #ifndef yytext_ptr #define yytext_ptr yytext #endif #define MAX_STACK_LEVELS 16 static int input_stack_index=0; YY_BUFFER_STATE input_stack[MAX_STACK_LEVELS]; /************************************************************************ * yywrap() * * Revert to an old input stream if there is one. If there is not an old * old stream, then the lexer will try to get data from YY_INPUT which * is a macro that calls gpsim_read() (see scan.h). * An 'old' stream is one that was interrupted by a macro expansion. * */ #ifdef yywrap #undef yywrap #endif int yywrap (void) { if(input_stack_index) { yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(input_stack[--input_stack_index]); return 0; } return 1; } /************************************************************************ * push_input_stack * * called when macros are being expanded. */ static void push_input_stack(void) { if(input_stack_indexname() << endl; else cout << " but there is no current macro\n"; } if(currentMacro && currentMacro->substituteParameter(s,replaced)) if(replaced != s) { if (verbose & 4) cout << " -- found it and replaced it with " << replaced << endl; if (bTryMacroParameterExpansion (replaced)) return true; push_input_stack(); yy_scan_string(replaced.c_str()); theMacroChain.resetParamSource(); return true; } theMacroChain.popParamSource(); return false; } /************************************************************************* * * handle_identifier * * input string &s * cmd_options **op * output int * * 1 - If `op' is NULL, then handle identifier hasn't been called * for the current command that's being processed. So, the * the string `s' is compared to all of the valid commands. * If it is valid, then `op' is assigned a pointer to the * options associated with the command. If the string is not * found, then that's a syntax error and the string is ignored. * 2 - If `op' is non-NULL, then handle_identifier has been called * at least once before for the command that's being processed. * So the string `s' is then compared to the options associated * with the command. If an option is not found, then the string * is returned to the parser (as a type STRING). This places the * burden of syntax checking on the parser and/or the individual * command. * */ int handle_identifier(YYSTYPE* yylvalP, string &s, cmd_options **op ) { int retval = 0; // If no command has been found so far, then the options (*op) // haven't been selected either (and consequently *op is null). if(! *op) { // If the first character in the string is a ' (single quote character) then // this means that the user is explicitly trying to access a user defined symbol // (e.g. if there is variable named "help" in the user's symbol table, then the // only way to get access to it is by using the single quote character: // 'help if(s[0] == '\'') // Strip away the quote, we won't treat this as a command and the parser // doesn't want to know about it. s=s.erase(0,1); else { // Search the commands pLexerState->cmd = search_commands(s); if(pLexerState->cmd) { if(verbose&2) cout << "\n *******\nprocessing command " << (pLexerState->cmd->name()) << "\n token value " << (pLexerState->cmd->get_token()) << "\n *******\n"; *op = pLexerState->cmd->get_op(); pLexerState->have_parameters = 0; retval = pLexerState->cmd->get_token(); // ugh. This is problem when the parser becomes re-entrant. last_command_is_repeatable = pLexerState->cmd->is_repeatable(); return recognize(retval,"good command"); } } // Search the macros yylvalP->Macro_P = isMacro(s); if(yylvalP->Macro_P) { return MACROINVOCATION_T; } if (bTryMacroParameterExpansion(s)) return 0; } else { if(verbose&2) cout << "search options for command '" << (pLexerState->cmd ? pLexerState->cmd->name() : "?") << "'\n"; if (bTryMacroParameterExpansion(s)) return 0; // We already have the command, so search the options. struct cmd_options *opt = *op; // We also have one or more parameters now (though they // may not be correct, but that's the parser's job to determine). pLexerState->have_parameters = 1; while(opt->name) if(strcmp(opt->name, s.c_str()) == 0) { if(verbose&2) cout << "found option '" << opt->name << "'\n"; yylvalP->co = opt; return recognize(translate_token(opt->token_type),"option"); } else opt++; } // If we get here, then the option was not found. // So let's check the symbols Processor *cpu; if(s[0] == '.' && (cpu = get_active_cpu()) != 0) s.insert(0,cpu->name()); string s1(s); gpsimObject *obj = globalSymbolTable().find(s1); if(obj) { yylvalP->Symbol_P = obj; if(verbose&2) cout << "found symbol '" << obj->name() << "'\n"; return recognize(SYMBOL_T,"symbol"); } //cout << "didn't find it in the symbol list\n"; // Either 1) there's a typo or 2) the command is creating // a new symbol or node or something along those lines. // In either case, let's let the parser deal with it. if(verbose&2) cout << " returning unknown string: " << s << endl; return process_stringLiteral(yylvalP,s.c_str()); return 0; } /***************************************************************** * Process an integer literal. This routine constructs the * YYSTYPE object. The caller is responsible from returning the * LITERAL_INT_T token identifer to the parser. */ static int process_intLiteral(YYSTYPE* yylvalP, char *buffer, int conversionBase) { char c; char *pt = buffer; gint64 literalValue=0; gint64 nxtDigit; while (*pt) { c = toupper(*pt++); nxtDigit = (c) <= '9' ? c-'0' : c-'A'+10; if ((nxtDigit >= conversionBase) || (nxtDigit<0)) { if(!(c == '\'')) { cout << "Error conversion to integer " << buffer << endl; literalValue = 0; } break; } literalValue *= conversionBase; literalValue += nxtDigit; } yylvalP->Integer_P = new Integer(literalValue); return(recognize(LITERAL_INT_T,"literal int")); } /***************************************************************** * */ static int process_macroBody(YYSTYPE* yylvalP, const char *text) { yylvalP->s = strdup(text); return recognize(MACROBODY_T,"macro body"); } /***************************************************************** * */ static int process_booleanLiteral(YYSTYPE* yylvalP, bool value) { yylvalP->Boolean_P = new Boolean(value); return(recognize(LITERAL_BOOL_T, "boolean literal")); } /***************************************************************** * */ static int process_floatLiteral(YYSTYPE* yylvalP, char *buffer) { double floatValue; #if 0 errno = 0; floatValue = atof(buffer); if (errno != 0) { /* The conversion failed */ throw new Error("Bad floating point literal"); } #else char *endptr=0; floatValue = strtod(buffer, &endptr); if (endptr == buffer) throw new Error("Bad floating point literal"); #endif yylvalP->Float_P = new Float(floatValue); return(recognize(LITERAL_FLOAT_T, "float literal")); } /***************************************************************** * */ static int process_stringLiteral(YYSTYPE* yylvalP, const char *buffer) { yylvalP->String_P = new String(buffer); return(recognize(LITERAL_STRING_T, "string literal")); } static int process_quotedStringLiteral(YYSTYPE* yylvalP, char *buffer) { char * pCloseQuote = strrchr(buffer, '\"'); if(pCloseQuote == NULL) pCloseQuote = strrchr(buffer, '\''); *pCloseQuote = 0; if (*(pCloseQuote-1) == '\\') *(pCloseQuote-1) = 0; yylvalP->String_P = new String(buffer); return(recognize(LITERAL_STRING_T, "string literal")); } /***************************************************************** * */ static int process_shellLine(YYSTYPE* yylvalP, const char *buffer) { yylvalP->String_P = new String(buffer); return(recognize(SHELL, "shell line")); } static string strip_trailing_whitespace (char *s) { string retval = s; size_t pos = retval.find_first_of (" \t"); if (pos != string::npos) retval.resize (pos); return retval; } //------------------------------------------------------------------------ static void SetMode(int newmode) { BEGIN(newmode); if(pLexerState) pLexerState->mode = newmode; } void initialize_commands(void); void init_cmd_state(void) { if(pLexerState) { if (verbose) cout << "scan: clearing lexer state and flushing buffer\n"; pLexerState->cmd = 0; pLexerState->options = 0; pLexerState->input_mode = 0; pLexerState->end_of_command = 0; pLexerState->have_parameters = 0; pLexerState->mode = 0; } } void FlushLexerBuffer() { #ifdef YY_FLUSH_BUFFER YY_FLUSH_BUFFER; #else yy_flush_buffer( YY_CURRENT_BUFFER ); #endif } static void pushLexerState() { if(verbose) cout << "pushing lexer state: from level " << sLevels << " to " << (sLevels+1) << endl; sLevels++; LexerStateStruct *pLS = new LexerStateStruct(); if(pLexerState) pLexerState->next = pLS; pLS->prev = pLexerState; pLexerState = pLS; pLS->next = 0; init_cmd_state(); } static void popLexerState() { if(verbose) cout << "popping lexer state: from level " << sLevels << " to " << (sLevels-1) << endl; sLevels--; if(pLexerState) { LexerStateStruct *pLS = pLexerState; pLexerState = pLS->prev; if(pLexerState) { pLexerState->next = 0; pLexerState->cmd = 0; pLexerState->options = 0; } SetMode(pLS->mode); delete pLS; } } int scan_read (char *buf, unsigned max_size) { static int lastRet = -1; // hack int ret = gpsim_read(buf,max_size); if (lastRet == ret && ret == 0) { *buf = '\n'; ret = 1; } lastRet = ret; return ret; } int init_parser() { pushLexerState(); int ret = yyparse(); popLexerState(); return ret; } // Tell us what the current buffer is. YY_BUFFER_STATE current_buffer (void) { return YY_CURRENT_BUFFER; } // Create a new buffer. YY_BUFFER_STATE create_buffer (FILE *f) { return yy_create_buffer (f, YY_BUF_SIZE); } // Start reading a new buffer. void switch_to_buffer (YY_BUFFER_STATE buf) { yy_switch_to_buffer (buf); } // Delete a buffer. void delete_buffer (YY_BUFFER_STATE buf) { yy_delete_buffer (buf); } // Restore a buffer (for unwind-prot). void restore_input_buffer (void *buf) { switch_to_buffer ((YY_BUFFER_STATE) buf); } // Delete a buffer (for unwind-prot). void delete_input_buffer (void *buf) { delete_buffer ((YY_BUFFER_STATE) buf); } //------------------------------------------------------------------------ // called by the parser error handler. command *getLastKnownCommand() { if(pLexerState) return pLexerState->cmd; return 0; } //---------------------------------------- // void lexer_setMacroBodyMode(void) { macroBodyPtr = ¯oBody[0]; if(verbose&4) cout << "setting lexer MACROBODY mode\n"; SetMode(MACROBODY); } //---------------------------------------- // void lexer_setDeclarationMode() { if(verbose&4) cout << "setting lexer DECLARATION mode\n"; SetMode(DECLARATION); } //---------------------------------------- static bool isWhiteSpace(char c) { return (c==' ' || c == '\t'); } //---------------------------------------- // getNextMacroParameter(char *s, int l) // // returns true if a macro parameter can be extracted // from yyinput buffer. If it does return true, then the // extracted macro parameter will get copied to // the string 's'. // // This routine will lexically analyze a character string // and split it up into chunks that can be passed to a // macro invocation. It might be possible to add a new // lex state and do this work in the lexer... // // If input stream looks something like: // // expression1, expression2, expression3, ... // // then this function will return true and copies 'expression1' // to 's'. static bool getNextMacroParameter(char *s, int l) { char c; // delete all leading white space. do { c = yyinput(); } while(isWhiteSpace(c)); if(c==',') goto done; unput(c); if(!c) return false; { int nParen=0; bool bDone = false; do { c = yyinput(); if(c == '(') nParen++; if(c == ')' && --nParen < 0 ) bDone = true; if(c==',') break; if(c==0 || c=='\n' ) { bDone=true; unput(c); } else *s++ = c; } while(--l>0 && !bDone); } done: *s=0; return true; } void lexer_InvokeMacro(Macro *m) { if(!m) return; if(verbose &4) cout << "Invoking macro: " << m->name() << endl; theMacroChain.push(m); m->prepareForInvocation(); int i=0; bool bValidParameter = false; do { i++; char s[256]; bValidParameter = getNextMacroParameter(s,sizeof(s)); if(bValidParameter) { m->add_parameter(s); if(verbose &4) cout << "macro param: " << s << endl; } } while (bValidParameter && inParameters()); m->invoke(); } void scanPushMacroState(Macro *m) { gCurrentMacro = m; } void scanPopMacroState() { theMacroChain.pop(); } gpsim-0.30.0/cli/cmd_stimulus.h0000664000076400007640000000226413041763642013306 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_STIMULUS_H__ #define __CMD_STIMULUS_H__ #include "command.h" class cmd_stimulus : public command { public: int valid_options,options_entered; int have_data; cmd_stimulus(void); void stimulus(void); void stimulus(int bit_flag); void stimulus(cmd_options_expr *coe); void stimulus(cmd_options_str *cos); void stimulus(ExprList_t *); void end(void); bool can_span_lines(void) {return 1;}; }; extern cmd_stimulus c_stimulus; #endif gpsim-0.30.0/cli/cmd_disasm.h0000664000076400007640000000176613041763642012707 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_DISASM_H__ #define __CMD_DISASM_H__ class Expression; class cmd_disassemble : public command { public: cmd_disassemble(void); void disassemble(Expression *); virtual int is_repeatable(void) { return 1; }; }; extern cmd_disassemble disassemble; #endif gpsim-0.30.0/cli/ui_gpsim.h0000664000076400007640000000065613041763642012415 00000000000000 #ifndef __UI_GPSIM_H__ #define __UI_GPSIM_H__ #include "../src/cmd_gpsim.h" class CGpsimConsole : public ISimConsole { public: CGpsimConsole(); void Printf(const char *fmt, ...); void VPrintf(const char *fmt, va_list argptr); void Puts(const char*); void Putc(const char); const char* Gets(char *, int); void SetOut(FILE *pOut); void SetIn(FILE *pIn); protected: FILE * m_pfOut; FILE * m_pfIn; }; #endif gpsim-0.30.0/cli/parse.cc0000664000076400007640000032061113041764265012047 00000000000000/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Copy the first part of user declarations. */ #line 2 "parse.yy" /* yacc.c:339 */ /* Parser for gpsim Copyright (C) 1999 Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include using namespace std; #include "misc.h" #include "command.h" #include "cmd_attach.h" #include "cmd_break.h" #include "cmd_bus.h" #include "cmd_clear.h" #include "cmd_disasm.h" #include "cmd_dump.h" #include "cmd_frequency.h" #include "cmd_help.h" #include "cmd_list.h" #include "cmd_load.h" #include "cmd_log.h" #include "cmd_node.h" #include "cmd_macro.h" #include "cmd_module.h" #include "cmd_processor.h" #include "cmd_quit.h" #include "cmd_reset.h" #include "cmd_run.h" #include "cmd_set.h" #include "cmd_step.h" #include "cmd_shell.h" #include "cmd_stimulus.h" #include "cmd_symbol.h" #include "cmd_trace.h" #include "cmd_version.h" #include "cmd_x.h" #include "cmd_icd.h" #include "../src/expr.h" #include "../src/operator.h" #include "../src/symbol.h" #include "../src/stimuli.h" #include "../src/processor.h" extern void lexer_setMacroBodyMode(); extern void lexer_InvokeMacro(Macro *m); extern void lexer_setDeclarationMode(); #define YYERROR_VERBOSE extern char *yytext; int quit_parse=0; int abort_gpsim=0; int parser_warnings; int parser_spanning_lines=0; int gAbortParserOnSyntaxError=0; extern int use_gui; extern int quit_state; extern command *getLastKnownCommand(); extern void init_cmd_state(); extern const char * GetLastFullCommand(); // From scan.ll void FlushLexerBuffer(); void yyerror(const char *message) { const char *last = GetLastFullCommand(); if (last) { int n = strlen(last); char *pt = strdup(last); if (n > 0 && *(pt+n-1) == '\n') *(pt+n-1) = 0; printf("***ERROR: %s while parsing:\n\t'%s'\n",message, pt); free(pt); } else printf("***ERROR: %s \n",message); init_cmd_state(); // JRH - I added this hoping that it is an appropriate // place to clear the lexer buffer. An example of // failed command where this is needed is to index // into an undefined symbol. (i.e. undefinedsymbol[0]) FlushLexerBuffer(); } int toInt(Expression *expr) { try { if(expr) { Value *v = expr->evaluate(); if (v) { int i; v->get(i); delete v; return i; } } } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } return -1; } #line 207 "parse.cc" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* In a future release of Bison, this section will be replaced by #include "y.tab.h". */ #ifndef YY_YY_PARSE_H_INCLUDED # define YY_YY_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 1 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { ABORT = 258, ATTACH = 259, BREAK = 260, BUS = 261, CLEAR = 262, DISASSEMBLE = 263, DUMP = 264, ENDM = 265, FREQUENCY = 266, HELP = 267, LOAD = 268, LOG = 269, LIST = 270, NODE = 271, MACRO = 272, MODULE = 273, PROCESSOR = 274, QUIT = 275, RESET = 276, RUN = 277, SET = 278, SHELL = 279, STEP = 280, STIMULUS = 281, SYMBOL = 282, TRACE = 283, gpsim_VERSION = 284, X = 285, ICD = 286, END_OF_COMMAND = 287, MACROBODY_T = 288, MACROINVOCATION_T = 289, INDIRECT = 290, END_OF_INPUT = 291, BIT_FLAG = 292, EXPRESSION_OPTION = 293, NUMERIC_OPTION = 294, STRING_OPTION = 295, CMD_SUBTYPE = 296, SYMBOL_OPTION = 297, LITERAL_INT_T = 298, LITERAL_BOOL_T = 299, LITERAL_FLOAT_T = 300, LITERAL_STRING_T = 301, LITERAL_ARRAY_T = 302, SYMBOL_T = 303, GPSIMOBJECT_T = 304, PORT_T = 305, EQU_T = 306, AND_T = 307, COLON_T = 308, COMMENT_T = 309, DIV_T = 310, EOLN_T = 311, MINUS_T = 312, MPY_T = 313, OR_T = 314, PLUS_T = 315, SHL_T = 316, SHR_T = 317, XOR_T = 318, INDEXERLEFT_T = 319, INDEXERRIGHT_T = 320, DECLARE_TYPE = 321, DECLARE_INT_T = 322, DECLARE_FLOAT_T = 323, DECLARE_BOOL_T = 324, DECLARE_CHAR_T = 325, LOR_T = 326, LAND_T = 327, EQ_T = 328, NE_T = 329, LT_T = 330, LE_T = 331, GT_T = 332, GE_T = 333, MIN_T = 334, MAX_T = 335, ABS_T = 336, IND_T = 337, BIT_T = 338, BITS_T = 339, LOW_T = 340, HIGH_T = 341, LADDR_T = 342, WORD_T = 343, INDEXED_T = 344, LNOT_T = 345, ONESCOMP_T = 346, UNARYOP_PREC = 347, POW_T = 348, REG_T = 349 }; #endif /* Tokens. */ #define ABORT 258 #define ATTACH 259 #define BREAK 260 #define BUS 261 #define CLEAR 262 #define DISASSEMBLE 263 #define DUMP 264 #define ENDM 265 #define FREQUENCY 266 #define HELP 267 #define LOAD 268 #define LOG 269 #define LIST 270 #define NODE 271 #define MACRO 272 #define MODULE 273 #define PROCESSOR 274 #define QUIT 275 #define RESET 276 #define RUN 277 #define SET 278 #define SHELL 279 #define STEP 280 #define STIMULUS 281 #define SYMBOL 282 #define TRACE 283 #define gpsim_VERSION 284 #define X 285 #define ICD 286 #define END_OF_COMMAND 287 #define MACROBODY_T 288 #define MACROINVOCATION_T 289 #define INDIRECT 290 #define END_OF_INPUT 291 #define BIT_FLAG 292 #define EXPRESSION_OPTION 293 #define NUMERIC_OPTION 294 #define STRING_OPTION 295 #define CMD_SUBTYPE 296 #define SYMBOL_OPTION 297 #define LITERAL_INT_T 298 #define LITERAL_BOOL_T 299 #define LITERAL_FLOAT_T 300 #define LITERAL_STRING_T 301 #define LITERAL_ARRAY_T 302 #define SYMBOL_T 303 #define GPSIMOBJECT_T 304 #define PORT_T 305 #define EQU_T 306 #define AND_T 307 #define COLON_T 308 #define COMMENT_T 309 #define DIV_T 310 #define EOLN_T 311 #define MINUS_T 312 #define MPY_T 313 #define OR_T 314 #define PLUS_T 315 #define SHL_T 316 #define SHR_T 317 #define XOR_T 318 #define INDEXERLEFT_T 319 #define INDEXERRIGHT_T 320 #define DECLARE_TYPE 321 #define DECLARE_INT_T 322 #define DECLARE_FLOAT_T 323 #define DECLARE_BOOL_T 324 #define DECLARE_CHAR_T 325 #define LOR_T 326 #define LAND_T 327 #define EQ_T 328 #define NE_T 329 #define LT_T 330 #define LE_T 331 #define GT_T 332 #define GE_T 333 #define MIN_T 334 #define MAX_T 335 #define ABS_T 336 #define IND_T 337 #define BIT_T 338 #define BITS_T 339 #define LOW_T 340 #define HIGH_T 341 #define LADDR_T 342 #define WORD_T 343 #define INDEXED_T 344 #define LNOT_T 345 #define ONESCOMP_T 346 #define UNARYOP_PREC 347 #define POW_T 348 #define REG_T 349 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 148 "parse.yy" /* yacc.c:355 */ guint32 i; guint64 li; float f; char *s; cmd_options *co; cmd_options_num *con; cmd_options_str *cos; cmd_options_expr *coe; BinaryOperator* BinaryOperator_P; Boolean* Boolean_P; Expression* Expression_P; Float* Float_P; Integer* Integer_P; String* String_P; gpsimObject* Symbol_P; gpsimObject* gpsimObject_P; StringList_t *StringList_P; ExprList_t *ExprList_P; gpsimObjectList_t *gpsimObjectList_P; Macro *Macro_P; #line 461 "parse.cc" /* yacc.c:355 */ }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif int yyparse (void); #endif /* !YY_YY_PARSE_H_INCLUDED */ /* Copy the second part of user declarations. */ #line 176 "parse.yy" /* yacc.c:358 */ /* Define the interface to the lexer */ extern int yylex(YYSTYPE* lvalP); #line 481 "parse.cc" /* yacc.c:358 */ #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE # if (defined __GNUC__ \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C # define YY_ATTRIBUTE(Spec) __attribute__(Spec) # else # define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif #ifndef YY_ATTRIBUTE_PURE # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) #endif #ifndef YY_ATTRIBUTE_UNUSED # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif #if !defined _Noreturn \ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) # if defined _MSC_VER && 1200 <= _MSC_VER # define _Noreturn __declspec (noreturn) # else # define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 137 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 486 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 101 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 62 /* YYNRULES -- Number of rules. */ #define YYNRULES 200 /* YYNSTATES -- Number of states. */ #define YYNSTATES 269 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 349 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 95, 96, 2, 2, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 321, 321, 325, 331, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 374, 391, 395, 397, 401, 410, 417, 418, 419, 429, 430, 431, 436, 437, 438, 442, 443, 446, 453, 457, 458, 462, 463, 464, 470, 484, 492, 496, 511, 517, 524, 531, 541, 542, 546, 547, 548, 552, 553, 556, 567, 578, 592, 605, 619, 639, 640, 644, 645, 646, 651, 661, 665, 669, 674, 682, 687, 696, 700, 704, 705, 706, 710, 711, 722, 726, 729, 733, 737, 741, 751, 757, 763, 769, 779, 780, 786, 787, 792, 793, 794, 795, 796, 797, 800, 804, 805, 809, 810, 831, 832, 833, 839, 841, 838, 846, 848, 853, 861, 863, 867, 868, 872, 873, 894, 899, 893, 910, 911, 912, 913, 914, 938, 944, 950, 953, 962, 970, 991, 992, 998, 999, 1000, 1004, 1007, 1023, 1029, 1050, 1051, 1055, 1056, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1091, 1092, 1093, 1094, 1095, 1109, 1110 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "ABORT", "ATTACH", "BREAK", "BUS", "CLEAR", "DISASSEMBLE", "DUMP", "ENDM", "FREQUENCY", "HELP", "LOAD", "LOG", "LIST", "NODE", "MACRO", "MODULE", "PROCESSOR", "QUIT", "RESET", "RUN", "SET", "SHELL", "STEP", "STIMULUS", "SYMBOL", "TRACE", "gpsim_VERSION", "X", "ICD", "END_OF_COMMAND", "MACROBODY_T", "MACROINVOCATION_T", "INDIRECT", "END_OF_INPUT", "BIT_FLAG", "EXPRESSION_OPTION", "NUMERIC_OPTION", "STRING_OPTION", "CMD_SUBTYPE", "SYMBOL_OPTION", "LITERAL_INT_T", "LITERAL_BOOL_T", "LITERAL_FLOAT_T", "LITERAL_STRING_T", "LITERAL_ARRAY_T", "SYMBOL_T", "GPSIMOBJECT_T", "PORT_T", "EQU_T", "AND_T", "COLON_T", "COMMENT_T", "DIV_T", "EOLN_T", "MINUS_T", "MPY_T", "OR_T", "PLUS_T", "SHL_T", "SHR_T", "XOR_T", "INDEXERLEFT_T", "INDEXERRIGHT_T", "DECLARE_TYPE", "DECLARE_INT_T", "DECLARE_FLOAT_T", "DECLARE_BOOL_T", "DECLARE_CHAR_T", "LOR_T", "LAND_T", "EQ_T", "NE_T", "LT_T", "LE_T", "GT_T", "GE_T", "MIN_T", "MAX_T", "ABS_T", "IND_T", "BIT_T", "BITS_T", "LOW_T", "HIGH_T", "LADDR_T", "WORD_T", "INDEXED_T", "LNOT_T", "ONESCOMP_T", "UNARYOP_PREC", "POW_T", "REG_T", "'('", "')'", "','", "'\\\\'", "'{'", "'}'", "$accept", "list_of_commands", "cmd", "rol", "opt_comment", "aborting", "attach_cmd", "break_cmd", "log_cmd", "break_set", "bus_cmd", "call_cmd", "clear_cmd", "disassemble_cmd", "dump_cmd", "eval_cmd", "frequency_cmd", "help_cmd", "list_cmd", "load_cmd", "node_cmd", "module_cmd", "processor_cmd", "quit_cmd", "reset_cmd", "run_cmd", "set_cmd", "step_cmd", "shell_cmd", "stimulus_cmd", "stimulus_opt", "symbol_cmd", "trace_cmd", "version_cmd", "x_cmd", "icd_cmd", "macro_cmd", "macrodef_directive", "$@1", "$@2", "opt_mdef_arglist", "mdef_body", "mdef_body_", "mdef_end", "declaration_cmd", "$@3", "$@4", "opt_declaration_type", "bit_flag", "cmd_subtype", "expression_option", "numeric_option", "string_option", "string_list", "expr", "array", "gpsimObject", "gpsimObject_list", "expr_list", "binary_expr", "unary_expr", "literal", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 40, 41, 44, 92, 123, 125 }; # endif #define YYPACT_NINF -132 #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-132))) #define YYTABLE_NINF -5 #define yytable_value_is_error(Yytable_value) \ (!!((Yytable_value) == (-5))) /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { 173, -132, -132, -40, -10, -7, 168, 168, 75, 168, -30, -12, 75, 75, -7, -132, 73, -9, 168, -132, -132, 75, -132, 36, 80, 72, 195, -132, 168, 84, -132, -132, 112, -21, 39, 168, -132, 41, 83, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, 60, -132, -132, -132, -132, -132, -132, -132, -132, 169, -132, -132, -132, 168, -132, 105, -132, -132, -132, -132, -132, 90, 235, 235, 235, 235, 235, 235, 78, 168, 357, -132, -132, -132, 357, 127, 357, -132, -132, 137, 157, 92, 168, -132, 105, 104, -132, -7, 162, -132, 357, 168, -132, 357, -132, -132, 159, -132, 168, 168, -132, -132, -132, -132, 357, 357, -132, -132, 168, 168, 168, 168, 244, 181, -132, 83, -132, -132, 174, -132, -14, -132, -132, 129, -132, 169, 357, 134, -132, 168, -132, -132, -132, -132, -132, -132, 168, 276, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 190, -132, -132, -132, 191, 134, -132, -132, 105, -132, 357, 56, 357, 357, 198, 357, 25, 126, 303, -132, -132, -132, -132, -132, -132, -132, -132, 168, -132, -132, -132, 63, -132, 168, 26, 330, -132, 408, 384, 71, 408, 71, 408, 408, 400, 400, 408, 236, 199, 292, 292, -132, -132, -132, -132, -132, -132, -132, -132, -19, 203, -132, 205, 211, 17, 164, 165, 357, -132, -132, 218, -132, 168, 168, -132, -132, -132, -132, -132, 232, 357, 357, -132, 30, 233, -132, 259, -132, -132, -132 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 37, 41, 0, 43, 52, 0, 56, 58, 69, 71, 0, 46, 74, 82, 126, 84, 88, 92, 94, 95, 96, 102, 99, 103, 111, 115, 121, 122, 124, 128, 36, 0, 62, 0, 0, 141, 0, 39, 5, 6, 7, 18, 45, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 21, 127, 11, 0, 149, 44, 51, 50, 155, 53, 194, 195, 197, 196, 200, 198, 0, 0, 0, 0, 0, 0, 0, 0, 55, 157, 158, 186, 57, 59, 70, 72, 73, 78, 79, 0, 47, 75, 83, 0, 85, 86, 90, 89, 93, 97, 101, 100, 150, 104, 113, 114, 0, 0, 119, 120, 117, 118, 116, 123, 125, 129, 0, 0, 0, 0, 0, 144, 1, 39, 40, 2, 0, 106, 105, 107, 163, 0, 164, 42, 166, 49, 156, 0, 192, 188, 191, 187, 190, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 81, 80, 76, 0, 48, 153, 154, 87, 91, 98, 0, 151, 152, 132, 64, 0, 0, 0, 63, 145, 146, 147, 148, 142, 3, 38, 0, 108, 109, 110, 0, 165, 0, 0, 0, 193, 172, 185, 171, 169, 170, 173, 168, 175, 176, 174, 184, 183, 177, 178, 179, 181, 180, 182, 61, 77, 112, 133, 39, 65, 54, 67, 0, 0, 0, 0, 167, 199, 159, 0, 130, 0, 0, 143, 160, 162, 161, 134, 135, 66, 68, 137, 0, 136, 139, 0, 131, 138, 140 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -132, -132, 247, -131, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -132, -2, -132, 207, -132, -24, -1, -6, -132, 140, -132, -101, -132, 256, 101 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 37, 38, 140, 141, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 143, 64, 65, 66, 67, 68, 69, 70, 193, 258, 238, 262, 263, 266, 71, 136, 242, 203, 76, 118, 124, 125, 110, 78, 149, 209, 147, 148, 150, 94, 95, 96 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 93, 97, 126, 99, 184, 129, 98, 204, 72, 104, 105, 106, 113, 107, 109, 112, 100, 116, 101, 114, 127, 115, 128, 73, 123, 73, 108, 73, 73, 135, 131, 195, 196, 74, 102, 139, 103, 111, 75, 77, 264, 137, 1, 132, 2, 3, 4, 5, 6, 7, 8, 213, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 73, 133, 30, 265, 31, 249, 79, 80, 81, 82, 83, 84, 206, 160, 32, 85, 33, 239, 247, 142, 86, 87, -4, 88, -4, 121, 79, 80, 81, 82, 83, 84, 243, 244, 250, 189, 187, 73, 245, 73, 108, 212, 191, 192, 254, 119, 208, 120, 117, 212, 212, 108, 194, 89, 90, 197, 130, 91, 92, 168, 169, 134, 34, 35, 139, 182, 36, 183, 207, 171, 172, 173, 174, 175, 176, 177, 178, 185, 151, 186, 214, 152, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 159, 1, 179, 2, 3, 4, 5, 6, 7, 8, 180, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 181, 246, 30, 188, 31, 190, 79, 80, 81, 82, 83, 84, 145, 146, 32, 85, 33, 240, 212, 210, 86, 87, -4, 88, -4, 205, 212, 73, 121, 122, 108, 234, 235, 79, 80, 81, 82, 83, 84, 237, 259, 260, 85, 199, 200, 201, 202, 86, 87, 251, 88, 252, 253, 89, 90, 255, 256, 91, 92, 257, 261, 267, 34, 35, 268, 144, 36, 173, 174, 175, 176, 177, 178, 79, 80, 81, 82, 83, 84, 138, 89, 90, 85, 211, 91, 92, 236, 86, 87, 0, 88, 161, 162, 0, 163, 0, 164, 165, 166, 167, 168, 169, 170, 172, 173, 174, 175, 176, 177, 178, 171, 172, 173, 174, 175, 176, 177, 178, 0, 0, 89, 90, 0, 161, 162, 92, 163, 0, 164, 165, 166, 167, 168, 169, 170, 198, 153, 154, 155, 156, 157, 158, 171, 172, 173, 174, 175, 176, 177, 178, 161, 162, 0, 163, 0, 164, 165, 166, 167, 168, 169, 170, 175, 176, 177, 178, 0, 215, 0, 171, 172, 173, 174, 175, 176, 177, 178, 161, 162, 0, 163, 0, 164, 165, 166, 167, 168, 169, 170, 0, 0, 0, 0, 0, 241, 0, 171, 172, 173, 174, 175, 176, 177, 178, 161, 162, 0, 163, 0, 164, 165, 166, 167, 168, 169, 170, 0, 0, 0, 0, 0, 248, 0, 171, 172, 173, 174, 175, 176, 177, 178, 161, -5, 0, 163, 0, 164, 165, 166, 167, 168, 169, 170, 0, 0, 0, 0, 0, 0, 0, 171, 172, 173, 174, 175, 176, 177, 178, 163, 0, 0, 165, 0, 0, 168, 169, 171, 172, 173, 174, 175, 176, 177, 178, 171, 172, 173, 174, 175, 176, 177, 178 }; static const yytype_int16 yycheck[] = { 6, 7, 26, 9, 105, 29, 8, 138, 48, 11, 12, 13, 18, 14, 16, 17, 46, 23, 48, 21, 26, 23, 28, 37, 26, 37, 40, 37, 37, 35, 51, 132, 133, 43, 46, 54, 48, 46, 48, 46, 10, 0, 1, 64, 3, 4, 5, 6, 7, 8, 9, 152, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 37, 95, 34, 46, 36, 97, 43, 44, 45, 46, 47, 48, 99, 92, 46, 52, 48, 65, 65, 32, 57, 58, 54, 60, 56, 38, 43, 44, 45, 46, 47, 48, 206, 43, 238, 114, 110, 37, 48, 37, 40, 97, 121, 122, 100, 46, 143, 48, 41, 97, 97, 40, 131, 90, 91, 134, 17, 94, 95, 61, 62, 95, 94, 95, 54, 46, 98, 48, 143, 71, 72, 73, 74, 75, 76, 77, 78, 46, 46, 48, 159, 64, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 95, 1, 48, 3, 4, 5, 6, 7, 8, 9, 46, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 48, 212, 34, 46, 36, 51, 43, 44, 45, 46, 47, 48, 48, 49, 46, 52, 48, 96, 97, 95, 57, 58, 54, 60, 56, 56, 97, 37, 38, 39, 40, 46, 46, 43, 44, 45, 46, 47, 48, 46, 251, 252, 52, 67, 68, 69, 70, 57, 58, 51, 60, 51, 46, 90, 91, 96, 96, 94, 95, 46, 33, 33, 94, 95, 10, 63, 98, 73, 74, 75, 76, 77, 78, 43, 44, 45, 46, 47, 48, 37, 90, 91, 52, 148, 94, 95, 190, 57, 58, -1, 60, 52, 53, -1, 55, -1, 57, 58, 59, 60, 61, 62, 63, 72, 73, 74, 75, 76, 77, 78, 71, 72, 73, 74, 75, 76, 77, 78, -1, -1, 90, 91, -1, 52, 53, 95, 55, -1, 57, 58, 59, 60, 61, 62, 63, 96, 85, 86, 87, 88, 89, 90, 71, 72, 73, 74, 75, 76, 77, 78, 52, 53, -1, 55, -1, 57, 58, 59, 60, 61, 62, 63, 75, 76, 77, 78, -1, 96, -1, 71, 72, 73, 74, 75, 76, 77, 78, 52, 53, -1, 55, -1, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, 96, -1, 71, 72, 73, 74, 75, 76, 77, 78, 52, 53, -1, 55, -1, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, 96, -1, 71, 72, 73, 74, 75, 76, 77, 78, 52, 53, -1, 55, -1, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 71, 72, 73, 74, 75, 76, 77, 78, 55, -1, -1, 58, -1, -1, 61, 62, 71, 72, 73, 74, 75, 76, 77, 78, 71, 72, 73, 74, 75, 76, 77, 78 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 34, 36, 46, 48, 94, 95, 98, 102, 103, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 132, 133, 134, 135, 136, 137, 138, 145, 48, 37, 43, 48, 149, 46, 154, 43, 44, 45, 46, 47, 48, 52, 57, 58, 60, 90, 91, 94, 95, 155, 160, 161, 162, 155, 149, 155, 46, 48, 46, 48, 149, 149, 149, 154, 40, 149, 153, 46, 149, 155, 149, 149, 155, 41, 150, 46, 48, 38, 39, 149, 151, 152, 153, 155, 155, 153, 17, 51, 64, 95, 95, 155, 146, 0, 103, 54, 104, 105, 32, 131, 151, 48, 49, 157, 158, 155, 159, 46, 64, 161, 161, 161, 161, 161, 161, 95, 155, 52, 53, 55, 57, 58, 59, 60, 61, 62, 63, 71, 72, 73, 74, 75, 76, 77, 78, 48, 46, 48, 46, 48, 159, 46, 48, 154, 46, 155, 51, 155, 155, 139, 155, 159, 159, 155, 96, 67, 68, 69, 70, 148, 104, 56, 99, 149, 153, 156, 95, 157, 97, 159, 155, 96, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 46, 46, 162, 46, 141, 65, 96, 96, 147, 159, 43, 48, 155, 65, 96, 97, 104, 51, 51, 46, 100, 96, 96, 46, 140, 155, 155, 33, 142, 143, 10, 46, 144, 33, 10 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 101, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 104, 105, 105, 106, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 112, 113, 114, 114, 115, 115, 115, 115, 116, 116, 116, 116, 116, 116, 116, 117, 117, 118, 118, 118, 119, 119, 120, 120, 120, 120, 120, 120, 121, 121, 122, 122, 122, 122, 123, 123, 123, 123, 124, 124, 125, 126, 127, 127, 127, 128, 128, 128, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 134, 135, 135, 136, 136, 137, 137, 137, 139, 140, 138, 141, 141, 141, 142, 142, 143, 143, 144, 144, 146, 147, 145, 148, 148, 148, 148, 148, 149, 150, 151, 152, 153, 153, 154, 154, 155, 155, 155, 156, 157, 157, 157, 158, 158, 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, 162, 162, 162, 162 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 2, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 3, 1, 2, 1, 1, 2, 3, 3, 2, 2, 1, 2, 4, 2, 1, 2, 1, 2, 3, 4, 1, 3, 3, 4, 6, 4, 6, 1, 2, 1, 2, 2, 1, 2, 3, 4, 2, 2, 3, 3, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 1, 1, 1, 2, 3, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 4, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 2, 1, 2, 1, 1, 1, 0, 0, 8, 0, 1, 3, 0, 1, 1, 2, 1, 2, 0, 0, 5, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 1, 4, 3, 4, 4, 1, 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 4, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*----------------------------------------. | Print this symbol's value on YYOUTPUT. | `----------------------------------------*/ static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T yystrlen (const char *yystr) { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*----------. | yyparse. | `----------*/ int yyparse (void) { /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Number of syntax errors so far. */ int yynerrs; int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (&yylval); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 321 "parse.yy" /* yacc.c:1646 */ { init_cmd_state(); } #line 1846 "parse.cc" /* yacc.c:1646 */ break; case 3: #line 326 "parse.yy" /* yacc.c:1646 */ { init_cmd_state(); } #line 1854 "parse.cc" /* yacc.c:1646 */ break; case 36: #line 365 "parse.yy" /* yacc.c:1646 */ { //if(verbose&2) cout << "got an END_OF_INPUT\n"; /* If we're processing a command file then quit parsing * when we run out of input */ //if(Gcmd_file_ref_count) //quit_parse = 1; YYABORT; } #line 1868 "parse.cc" /* yacc.c:1646 */ break; case 37: #line 374 "parse.yy" /* yacc.c:1646 */ { init_cmd_state(); yyclearin; // FIXME // In some cases we may wish to abort parsing while in others not. if (gAbortParserOnSyntaxError) { YYABORT; } } #line 1883 "parse.cc" /* yacc.c:1646 */ break; case 41: #line 402 "parse.yy" /* yacc.c:1646 */ { abort_gpsim = 1; quit_parse = 1; YYABORT; } #line 1893 "parse.cc" /* yacc.c:1646 */ break; case 42: #line 411 "parse.yy" /* yacc.c:1646 */ { attach.attach((yyvsp[-1].Symbol_P),(yyvsp[0].gpsimObjectList_P)); } #line 1901 "parse.cc" /* yacc.c:1646 */ break; case 43: #line 417 "parse.yy" /* yacc.c:1646 */ {c_break.list();} #line 1907 "parse.cc" /* yacc.c:1646 */ break; case 44: #line 418 "parse.yy" /* yacc.c:1646 */ {c_break.list((yyvsp[0].Integer_P)->getVal());delete (yyvsp[0].Integer_P);} #line 1913 "parse.cc" /* yacc.c:1646 */ break; case 45: #line 419 "parse.yy" /* yacc.c:1646 */ { int n = (yyvsp[0].i); if (n < 0) { yyerror("Breakpoint not set"); } } #line 1925 "parse.cc" /* yacc.c:1646 */ break; case 46: #line 429 "parse.yy" /* yacc.c:1646 */ {c_log.log();} #line 1931 "parse.cc" /* yacc.c:1646 */ break; case 47: #line 430 "parse.yy" /* yacc.c:1646 */ {c_log.log((yyvsp[0].co));} #line 1937 "parse.cc" /* yacc.c:1646 */ break; case 48: #line 431 "parse.yy" /* yacc.c:1646 */ {c_log.log((yyvsp[-1].co),(yyvsp[0].ExprList_P));} #line 1943 "parse.cc" /* yacc.c:1646 */ break; case 49: #line 436 "parse.yy" /* yacc.c:1646 */ { (yyval.i)=c_break.set_break((yyvsp[-1].co),(yyvsp[0].ExprList_P));} #line 1949 "parse.cc" /* yacc.c:1646 */ break; case 50: #line 437 "parse.yy" /* yacc.c:1646 */ {(yyval.i)=c_break.set_break((yyvsp[0].co));} #line 1955 "parse.cc" /* yacc.c:1646 */ break; case 51: #line 438 "parse.yy" /* yacc.c:1646 */ {(yyval.i)=c_break.set_break((yyvsp[0].Symbol_P));} #line 1961 "parse.cc" /* yacc.c:1646 */ break; case 52: #line 442 "parse.yy" /* yacc.c:1646 */ {c_bus.list_busses();} #line 1967 "parse.cc" /* yacc.c:1646 */ break; case 53: #line 443 "parse.yy" /* yacc.c:1646 */ {c_bus.add_busses((yyvsp[0].StringList_P)); delete (yyvsp[0].StringList_P);} #line 1973 "parse.cc" /* yacc.c:1646 */ break; case 54: #line 447 "parse.yy" /* yacc.c:1646 */ { cout << " call\n"; //$$ = $3; } #line 1982 "parse.cc" /* yacc.c:1646 */ break; case 55: #line 453 "parse.yy" /* yacc.c:1646 */ {clear.clear((yyvsp[0].Expression_P));} #line 1988 "parse.cc" /* yacc.c:1646 */ break; case 56: #line 457 "parse.yy" /* yacc.c:1646 */ {disassemble.disassemble(0);} #line 1994 "parse.cc" /* yacc.c:1646 */ break; case 57: #line 458 "parse.yy" /* yacc.c:1646 */ {disassemble.disassemble((yyvsp[0].Expression_P));} #line 2000 "parse.cc" /* yacc.c:1646 */ break; case 58: #line 462 "parse.yy" /* yacc.c:1646 */ {dump.dump(2);} #line 2006 "parse.cc" /* yacc.c:1646 */ break; case 59: #line 463 "parse.yy" /* yacc.c:1646 */ {dump.dump((yyvsp[0].co)->value);} #line 2012 "parse.cc" /* yacc.c:1646 */ break; case 60: #line 466 "parse.yy" /* yacc.c:1646 */ { // key, module_name quit_parse = dump.dump((yyvsp[-1].co)->value, (yyvsp[0].Symbol_P), NULL) == 0; } #line 2021 "parse.cc" /* yacc.c:1646 */ break; case 61: #line 472 "parse.yy" /* yacc.c:1646 */ { // key, module_name, filename //quit_parse = dump.dump($2->value, $3, $4->getVal()) == 0; if (dump.dump((yyvsp[-2].co)->value, (yyvsp[-1].Symbol_P), (yyvsp[0].String_P)->getVal()) == 0) cout << "dump to file failed\n"; delete (yyvsp[0].String_P); } #line 2034 "parse.cc" /* yacc.c:1646 */ break; case 62: #line 484 "parse.yy" /* yacc.c:1646 */ {c_symbol.dump_one((yyvsp[0].Symbol_P));} #line 2040 "parse.cc" /* yacc.c:1646 */ break; case 63: #line 492 "parse.yy" /* yacc.c:1646 */ { c_symbol.EvaluateAndDisplay((yyvsp[-1].Expression_P)); delete (yyvsp[-1].Expression_P); } #line 2049 "parse.cc" /* yacc.c:1646 */ break; case 64: #line 496 "parse.yy" /* yacc.c:1646 */ { Value *pValue = dynamic_cast((yyvsp[-2].Symbol_P)); if (pValue) { try { pValue->set((yyvsp[0].Expression_P)); } catch(Error Message) { GetUserInterface().DisplayMessage("%s (maybe missing quotes?)\n", Message.toString().c_str()); } pValue->update(); } delete (yyvsp[0].Expression_P); } #line 2068 "parse.cc" /* yacc.c:1646 */ break; case 65: #line 512 "parse.yy" /* yacc.c:1646 */ { c_symbol.dump((yyvsp[-3].Symbol_P),(yyvsp[-1].ExprList_P)); (yyvsp[-1].ExprList_P)->clear(); delete (yyvsp[-1].ExprList_P); } #line 2078 "parse.cc" /* yacc.c:1646 */ break; case 66: #line 518 "parse.yy" /* yacc.c:1646 */ { c_symbol.Set((yyvsp[-5].Symbol_P), (yyvsp[-3].ExprList_P), (yyvsp[0].Expression_P)); (yyvsp[-3].ExprList_P)->clear(); delete (yyvsp[-3].ExprList_P); delete (yyvsp[0].Expression_P); } #line 2089 "parse.cc" /* yacc.c:1646 */ break; case 67: #line 525 "parse.yy" /* yacc.c:1646 */ { int i=toInt((yyvsp[-1].Expression_P)); if (i>=0) c_x.x(toInt((yyvsp[-1].Expression_P))); delete (yyvsp[-1].Expression_P); } #line 2100 "parse.cc" /* yacc.c:1646 */ break; case 68: #line 532 "parse.yy" /* yacc.c:1646 */ { int i=toInt((yyvsp[-3].Expression_P)); if (i>=0) c_x.x(toInt((yyvsp[-3].Expression_P)), (yyvsp[0].Expression_P)); delete (yyvsp[-3].Expression_P); } #line 2111 "parse.cc" /* yacc.c:1646 */ break; case 69: #line 541 "parse.yy" /* yacc.c:1646 */ {frequency.print();} #line 2117 "parse.cc" /* yacc.c:1646 */ break; case 70: #line 542 "parse.yy" /* yacc.c:1646 */ {frequency.set((yyvsp[0].Expression_P));} #line 2123 "parse.cc" /* yacc.c:1646 */ break; case 71: #line 546 "parse.yy" /* yacc.c:1646 */ {help.help(); } #line 2129 "parse.cc" /* yacc.c:1646 */ break; case 72: #line 547 "parse.yy" /* yacc.c:1646 */ {help.help((yyvsp[0].String_P)->getVal()); delete (yyvsp[0].String_P);} #line 2135 "parse.cc" /* yacc.c:1646 */ break; case 73: #line 548 "parse.yy" /* yacc.c:1646 */ {help.help((yyvsp[0].Symbol_P));} #line 2141 "parse.cc" /* yacc.c:1646 */ break; case 74: #line 552 "parse.yy" /* yacc.c:1646 */ {c_list.list();} #line 2147 "parse.cc" /* yacc.c:1646 */ break; case 75: #line 553 "parse.yy" /* yacc.c:1646 */ {c_list.list((yyvsp[0].co));} #line 2153 "parse.cc" /* yacc.c:1646 */ break; case 76: #line 557 "parse.yy" /* yacc.c:1646 */ { quit_parse = c_load.load((yyvsp[-1].co)->value,(yyvsp[0].String_P)->getVal()) == 0; delete (yyvsp[0].String_P); if(quit_parse) { quit_parse = 0; YYABORT; } } #line 2168 "parse.cc" /* yacc.c:1646 */ break; case 77: #line 568 "parse.yy" /* yacc.c:1646 */ { quit_parse = c_load.load((yyvsp[-2].co)->value, (yyvsp[-1].Symbol_P), (yyvsp[0].String_P)->getVal()) == 0; delete (yyvsp[0].String_P); if(quit_parse) { quit_parse = 0; YYABORT; } } #line 2183 "parse.cc" /* yacc.c:1646 */ break; case 78: #line 580 "parse.yy" /* yacc.c:1646 */ { quit_parse = c_load.load((yyvsp[0].String_P)->getVal(), (const char *)NULL) == 0; delete (yyvsp[0].String_P); quit_parse =0; if(quit_parse) { quit_parse = 0; YYABORT; } } #line 2200 "parse.cc" /* yacc.c:1646 */ break; case 79: #line 594 "parse.yy" /* yacc.c:1646 */ { quit_parse = c_load.load((yyvsp[0].Symbol_P)) == 0; quit_parse =0; if(quit_parse) { quit_parse = 0; YYABORT; } } #line 2216 "parse.cc" /* yacc.c:1646 */ break; case 80: #line 607 "parse.yy" /* yacc.c:1646 */ { // filename, processor quit_parse = c_load.load((yyvsp[0].Symbol_P), (yyvsp[-1].Symbol_P)) == 0; delete (yyvsp[-1].Symbol_P); delete (yyvsp[0].Symbol_P); if(quit_parse) { quit_parse = 0; YYABORT; } } #line 2233 "parse.cc" /* yacc.c:1646 */ break; case 81: #line 623 "parse.yy" /* yacc.c:1646 */ { // filename, processor quit_parse = c_load.load((yyvsp[0].String_P), (yyvsp[-1].String_P)) == 0; delete (yyvsp[-1].String_P); delete (yyvsp[0].String_P); if(quit_parse) { quit_parse = 0; YYABORT; } } #line 2250 "parse.cc" /* yacc.c:1646 */ break; case 82: #line 639 "parse.yy" /* yacc.c:1646 */ {c_node.list_nodes();} #line 2256 "parse.cc" /* yacc.c:1646 */ break; case 83: #line 640 "parse.yy" /* yacc.c:1646 */ {c_node.add_nodes((yyvsp[0].StringList_P)); delete (yyvsp[0].StringList_P);} #line 2262 "parse.cc" /* yacc.c:1646 */ break; case 84: #line 644 "parse.yy" /* yacc.c:1646 */ {c_module.module();} #line 2268 "parse.cc" /* yacc.c:1646 */ break; case 85: #line 645 "parse.yy" /* yacc.c:1646 */ {c_module.module((yyvsp[0].co));} #line 2274 "parse.cc" /* yacc.c:1646 */ break; case 86: #line 647 "parse.yy" /* yacc.c:1646 */ { c_module.module((yyvsp[0].cos),(list *)0); delete (yyvsp[0].cos); } #line 2283 "parse.cc" /* yacc.c:1646 */ break; case 87: #line 652 "parse.yy" /* yacc.c:1646 */ { if ((yyvsp[-1].cos) != NULL && (yyvsp[0].StringList_P) != NULL) c_module.module((yyvsp[-1].cos), (yyvsp[0].StringList_P)); if ((yyvsp[-1].cos) != NULL) delete (yyvsp[-1].cos); if ((yyvsp[0].StringList_P) != NULL) delete (yyvsp[0].StringList_P); } #line 2294 "parse.cc" /* yacc.c:1646 */ break; case 88: #line 662 "parse.yy" /* yacc.c:1646 */ { c_processor.processor(); } #line 2302 "parse.cc" /* yacc.c:1646 */ break; case 89: #line 666 "parse.yy" /* yacc.c:1646 */ { c_processor.processor((yyvsp[0].co)->value); } #line 2310 "parse.cc" /* yacc.c:1646 */ break; case 90: #line 670 "parse.yy" /* yacc.c:1646 */ { c_processor.processor((yyvsp[0].String_P)->getVal(),0); delete (yyvsp[0].String_P); } #line 2319 "parse.cc" /* yacc.c:1646 */ break; case 91: #line 675 "parse.yy" /* yacc.c:1646 */ { c_processor.processor((yyvsp[-1].String_P)->getVal(),(yyvsp[0].String_P)->getVal()); delete (yyvsp[-1].String_P); delete (yyvsp[0].String_P); } #line 2329 "parse.cc" /* yacc.c:1646 */ break; case 92: #line 683 "parse.yy" /* yacc.c:1646 */ { quit_parse = 1; YYABORT; } #line 2338 "parse.cc" /* yacc.c:1646 */ break; case 93: #line 688 "parse.yy" /* yacc.c:1646 */ { quit_parse = 1; //quit_state = $2; // FIXME need to evaluate expr YYABORT; } #line 2348 "parse.cc" /* yacc.c:1646 */ break; case 94: #line 696 "parse.yy" /* yacc.c:1646 */ { reset.reset(); } #line 2354 "parse.cc" /* yacc.c:1646 */ break; case 95: #line 700 "parse.yy" /* yacc.c:1646 */ { c_run.run();} #line 2360 "parse.cc" /* yacc.c:1646 */ break; case 96: #line 704 "parse.yy" /* yacc.c:1646 */ {c_set.set();} #line 2366 "parse.cc" /* yacc.c:1646 */ break; case 97: #line 705 "parse.yy" /* yacc.c:1646 */ {c_set.set((yyvsp[0].co)->value,0);} #line 2372 "parse.cc" /* yacc.c:1646 */ break; case 98: #line 706 "parse.yy" /* yacc.c:1646 */ {c_set.set((yyvsp[-1].co)->value,(yyvsp[0].Expression_P));} #line 2378 "parse.cc" /* yacc.c:1646 */ break; case 99: #line 710 "parse.yy" /* yacc.c:1646 */ {step.step(1);} #line 2384 "parse.cc" /* yacc.c:1646 */ break; case 100: #line 711 "parse.yy" /* yacc.c:1646 */ { if ((yyvsp[0].Expression_P)) { int i=toInt((yyvsp[0].Expression_P)); delete (yyvsp[0].Expression_P); if (i >=1) step.step(i); else yyerror("Invalid value"); } } #line 2400 "parse.cc" /* yacc.c:1646 */ break; case 101: #line 722 "parse.yy" /* yacc.c:1646 */ {step.over();} #line 2406 "parse.cc" /* yacc.c:1646 */ break; case 102: #line 726 "parse.yy" /* yacc.c:1646 */ {c_shell.shell((yyvsp[0].String_P)); delete (yyvsp[0].String_P);} #line 2412 "parse.cc" /* yacc.c:1646 */ break; case 103: #line 730 "parse.yy" /* yacc.c:1646 */ { c_stimulus.stimulus(); } #line 2420 "parse.cc" /* yacc.c:1646 */ break; case 104: #line 734 "parse.yy" /* yacc.c:1646 */ { c_stimulus.stimulus((yyvsp[0].co)->value); } #line 2428 "parse.cc" /* yacc.c:1646 */ break; case 105: #line 738 "parse.yy" /* yacc.c:1646 */ { /* do nothing */ } #line 2436 "parse.cc" /* yacc.c:1646 */ break; case 106: #line 742 "parse.yy" /* yacc.c:1646 */ { if(verbose) cout << " end of stimulus command\n"; c_stimulus.end(); } #line 2446 "parse.cc" /* yacc.c:1646 */ break; case 107: #line 752 "parse.yy" /* yacc.c:1646 */ { if(verbose) cout << "parser sees stimulus with numeric option\n"; c_stimulus.stimulus((yyvsp[0].coe)); } #line 2456 "parse.cc" /* yacc.c:1646 */ break; case 108: #line 758 "parse.yy" /* yacc.c:1646 */ { if(verbose) cout << "parser sees stimulus with bit flag: " << (yyvsp[0].co)->value << '\n'; c_stimulus.stimulus((yyvsp[0].co)->value); } #line 2466 "parse.cc" /* yacc.c:1646 */ break; case 109: #line 764 "parse.yy" /* yacc.c:1646 */ { if(verbose) cout << "parser sees stimulus with string option\n"; c_stimulus.stimulus((yyvsp[0].cos)); } #line 2476 "parse.cc" /* yacc.c:1646 */ break; case 110: #line 770 "parse.yy" /* yacc.c:1646 */ { if(verbose) cout << "parser sees stimulus with an array\n"; c_stimulus.stimulus((yyvsp[0].ExprList_P)); } #line 2486 "parse.cc" /* yacc.c:1646 */ break; case 111: #line 779 "parse.yy" /* yacc.c:1646 */ {c_symbol.dump_all();} #line 2492 "parse.cc" /* yacc.c:1646 */ break; case 112: #line 781 "parse.yy" /* yacc.c:1646 */ { c_symbol.add_one((yyvsp[-2].String_P)->getVal(), (yyvsp[0].Expression_P)); delete (yyvsp[-2].String_P); delete (yyvsp[0].Expression_P); } #line 2502 "parse.cc" /* yacc.c:1646 */ break; case 113: #line 786 "parse.yy" /* yacc.c:1646 */ {c_symbol.dump_one((yyvsp[0].String_P)->getVal()); delete (yyvsp[0].String_P);} #line 2508 "parse.cc" /* yacc.c:1646 */ break; case 114: #line 787 "parse.yy" /* yacc.c:1646 */ {c_symbol.dump_one((yyvsp[0].Symbol_P));} #line 2514 "parse.cc" /* yacc.c:1646 */ break; case 115: #line 792 "parse.yy" /* yacc.c:1646 */ { c_trace.trace(); } #line 2520 "parse.cc" /* yacc.c:1646 */ break; case 116: #line 793 "parse.yy" /* yacc.c:1646 */ { c_trace.trace((yyvsp[0].Expression_P)); } #line 2526 "parse.cc" /* yacc.c:1646 */ break; case 117: #line 794 "parse.yy" /* yacc.c:1646 */ { c_trace.trace((yyvsp[0].con)); } #line 2532 "parse.cc" /* yacc.c:1646 */ break; case 118: #line 795 "parse.yy" /* yacc.c:1646 */ { c_trace.trace((yyvsp[0].cos)); } #line 2538 "parse.cc" /* yacc.c:1646 */ break; case 119: #line 796 "parse.yy" /* yacc.c:1646 */ { c_trace.trace((yyvsp[0].co)); } #line 2544 "parse.cc" /* yacc.c:1646 */ break; case 120: #line 797 "parse.yy" /* yacc.c:1646 */ { c_trace.trace((yyvsp[0].coe)); } #line 2550 "parse.cc" /* yacc.c:1646 */ break; case 121: #line 800 "parse.yy" /* yacc.c:1646 */ {version.version();} #line 2556 "parse.cc" /* yacc.c:1646 */ break; case 122: #line 804 "parse.yy" /* yacc.c:1646 */ { c_x.x();} #line 2562 "parse.cc" /* yacc.c:1646 */ break; case 123: #line 805 "parse.yy" /* yacc.c:1646 */ { c_x.x((yyvsp[0].Expression_P)); } #line 2568 "parse.cc" /* yacc.c:1646 */ break; case 124: #line 809 "parse.yy" /* yacc.c:1646 */ { c_icd.icd(); } #line 2574 "parse.cc" /* yacc.c:1646 */ break; case 125: #line 810 "parse.yy" /* yacc.c:1646 */ { c_icd.icd((yyvsp[0].cos)); } #line 2580 "parse.cc" /* yacc.c:1646 */ break; case 126: #line 831 "parse.yy" /* yacc.c:1646 */ { c_macro.list();} #line 2586 "parse.cc" /* yacc.c:1646 */ break; case 127: #line 832 "parse.yy" /* yacc.c:1646 */ { } #line 2592 "parse.cc" /* yacc.c:1646 */ break; case 128: #line 833 "parse.yy" /* yacc.c:1646 */ { lexer_InvokeMacro((yyvsp[0].Macro_P)); } #line 2598 "parse.cc" /* yacc.c:1646 */ break; case 129: #line 839 "parse.yy" /* yacc.c:1646 */ {c_macro.define((yyvsp[-1].String_P)->getVal()); delete (yyvsp[-1].String_P);} #line 2604 "parse.cc" /* yacc.c:1646 */ break; case 130: #line 841 "parse.yy" /* yacc.c:1646 */ {lexer_setMacroBodyMode();} #line 2610 "parse.cc" /* yacc.c:1646 */ break; case 133: #line 849 "parse.yy" /* yacc.c:1646 */ { c_macro.add_parameter((yyvsp[0].String_P)->getVal()); delete (yyvsp[0].String_P); } #line 2619 "parse.cc" /* yacc.c:1646 */ break; case 134: #line 854 "parse.yy" /* yacc.c:1646 */ { c_macro.add_parameter((yyvsp[0].String_P)->getVal()); delete (yyvsp[0].String_P); } #line 2628 "parse.cc" /* yacc.c:1646 */ break; case 136: #line 863 "parse.yy" /* yacc.c:1646 */ {; } #line 2634 "parse.cc" /* yacc.c:1646 */ break; case 137: #line 867 "parse.yy" /* yacc.c:1646 */ {c_macro.add_body((yyvsp[0].s));} #line 2640 "parse.cc" /* yacc.c:1646 */ break; case 138: #line 868 "parse.yy" /* yacc.c:1646 */ {c_macro.add_body((yyvsp[0].s));} #line 2646 "parse.cc" /* yacc.c:1646 */ break; case 139: #line 872 "parse.yy" /* yacc.c:1646 */ {c_macro.end_define();} #line 2652 "parse.cc" /* yacc.c:1646 */ break; case 140: #line 873 "parse.yy" /* yacc.c:1646 */ {c_macro.end_define((yyvsp[-1].String_P)->getVal()); delete (yyvsp[-1].String_P); } #line 2658 "parse.cc" /* yacc.c:1646 */ break; case 141: #line 894 "parse.yy" /* yacc.c:1646 */ { cout << "declaration\n"; lexer_setDeclarationMode(); } #line 2667 "parse.cc" /* yacc.c:1646 */ break; case 142: #line 899 "parse.yy" /* yacc.c:1646 */ { cout << " type:" << (yyvsp[0].i) << endl; } #line 2675 "parse.cc" /* yacc.c:1646 */ break; case 143: #line 903 "parse.yy" /* yacc.c:1646 */ { cout << "identifier: " << (yyvsp[0].String_P)->getVal() << endl; delete (yyvsp[0].String_P); } #line 2683 "parse.cc" /* yacc.c:1646 */ break; case 144: #line 910 "parse.yy" /* yacc.c:1646 */ { (yyval.i)=0; } #line 2689 "parse.cc" /* yacc.c:1646 */ break; case 145: #line 911 "parse.yy" /* yacc.c:1646 */ { (yyval.i) = 1; cout <<"int type\n";} #line 2695 "parse.cc" /* yacc.c:1646 */ break; case 146: #line 912 "parse.yy" /* yacc.c:1646 */ { (yyval.i) = 2; cout <<"float type\n";} #line 2701 "parse.cc" /* yacc.c:1646 */ break; case 147: #line 913 "parse.yy" /* yacc.c:1646 */ { (yyval.i) = 3; cout <<"bool type\n";} #line 2707 "parse.cc" /* yacc.c:1646 */ break; case 148: #line 914 "parse.yy" /* yacc.c:1646 */ { (yyval.i) = 4; cout <<"char type\n";} #line 2713 "parse.cc" /* yacc.c:1646 */ break; case 149: #line 939 "parse.yy" /* yacc.c:1646 */ { (yyval.co) = (yyvsp[0].co); } #line 2721 "parse.cc" /* yacc.c:1646 */ break; case 150: #line 945 "parse.yy" /* yacc.c:1646 */ { (yyval.co) = (yyvsp[0].co); } #line 2729 "parse.cc" /* yacc.c:1646 */ break; case 151: #line 950 "parse.yy" /* yacc.c:1646 */ { (yyval.coe) = new cmd_options_expr((yyvsp[-1].co),(yyvsp[0].Expression_P)); } #line 2735 "parse.cc" /* yacc.c:1646 */ break; case 152: #line 954 "parse.yy" /* yacc.c:1646 */ { (yyval.con) = new cmd_options_num; (yyval.con)->co = (yyvsp[-1].co); } #line 2745 "parse.cc" /* yacc.c:1646 */ break; case 153: #line 963 "parse.yy" /* yacc.c:1646 */ { (yyval.cos) = new cmd_options_str((yyvsp[0].String_P)->getVal()); (yyval.cos)->co = (yyvsp[-1].co); if(verbose&2) cout << " name " << (yyval.cos)->co->name << " value " << (yyval.cos)->str << " got a string option \n"; delete (yyvsp[0].String_P); } #line 2757 "parse.cc" /* yacc.c:1646 */ break; case 154: #line 971 "parse.yy" /* yacc.c:1646 */ { String *pValue = dynamic_cast((yyvsp[0].Symbol_P)); if(pValue != NULL) { (yyval.cos) = new cmd_options_str(pValue->getVal()); (yyval.cos)->co = (yyvsp[-1].co); if(verbose&2) cout << " name " << (yyval.cos)->co->name << " value " << (yyval.cos)->str << " got a symbol option \n"; } else { cout << " symbol option '" << (yyvsp[0].Symbol_P)->name() << "' is not a string" << endl; (yyval.cos) = NULL; } //delete $2; } #line 2779 "parse.cc" /* yacc.c:1646 */ break; case 155: #line 991 "parse.yy" /* yacc.c:1646 */ {(yyval.StringList_P) = new StringList_t(); (yyval.StringList_P)->push_back((yyvsp[0].String_P)->getVal()); delete (yyvsp[0].String_P);} #line 2785 "parse.cc" /* yacc.c:1646 */ break; case 156: #line 992 "parse.yy" /* yacc.c:1646 */ {(yyvsp[-1].StringList_P)->push_back((yyvsp[0].String_P)->getVal()); delete (yyvsp[0].String_P);} #line 2791 "parse.cc" /* yacc.c:1646 */ break; case 157: #line 998 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P)=(yyvsp[0].BinaryOperator_P);} #line 2797 "parse.cc" /* yacc.c:1646 */ break; case 158: #line 999 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P)=(yyvsp[0].Expression_P);} #line 2803 "parse.cc" /* yacc.c:1646 */ break; case 159: #line 1000 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P)=new RegisterExpression(toInt((yyvsp[-1].Expression_P))); delete (yyvsp[-1].Expression_P); } #line 2810 "parse.cc" /* yacc.c:1646 */ break; case 160: #line 1004 "parse.yy" /* yacc.c:1646 */ {(yyval.ExprList_P)=(yyvsp[-1].ExprList_P);} #line 2816 "parse.cc" /* yacc.c:1646 */ break; case 161: #line 1008 "parse.yy" /* yacc.c:1646 */ { // Ex: pin(MyVariable) -- where MyVariable is the name of a symbol // This allows one to programmatically select a particular pin number. // If Symbol has an integer type, assume it is a CPU pin number // otherwise assume it is a stimulus such as a pin name if (typeid(*(yyvsp[-1].Symbol_P)) == typeid(Integer)) { (yyval.gpsimObject_P) = toStimulus((yyvsp[-1].Symbol_P)); } else (yyval.gpsimObject_P) = (yyvsp[-1].Symbol_P); //$$=new Pin_t(Pin_t::ePackageBased | Pin_t::eActiveProc, $3); } #line 2836 "parse.cc" /* yacc.c:1646 */ break; case 162: #line 1024 "parse.yy" /* yacc.c:1646 */ { // Ex: pin(8) -- select a particular pin in the package (yyval.gpsimObject_P) = toStimulus((yyvsp[-1].Integer_P)->getVal()); delete (yyvsp[-1].Integer_P); } #line 2846 "parse.cc" /* yacc.c:1646 */ break; case 163: #line 1030 "parse.yy" /* yacc.c:1646 */ { // The symbol should be a stimulus. This is for the attach command. // Ex: attach Node1 portb0 // The scanner will find portb0 and return it to us here as a SYMBOL_T (yyval.gpsimObject_P) = (yyvsp[0].Symbol_P); //dynamic_cast($1); } #line 2857 "parse.cc" /* yacc.c:1646 */ break; case 164: #line 1050 "parse.yy" /* yacc.c:1646 */ {(yyval.gpsimObjectList_P) = new gpsimObjectList_t(); (yyval.gpsimObjectList_P)->push_back((yyvsp[0].gpsimObject_P));} #line 2863 "parse.cc" /* yacc.c:1646 */ break; case 165: #line 1051 "parse.yy" /* yacc.c:1646 */ {if ((yyvsp[0].gpsimObject_P)) (yyvsp[-1].gpsimObjectList_P)->push_back((yyvsp[0].gpsimObject_P));} #line 2869 "parse.cc" /* yacc.c:1646 */ break; case 166: #line 1055 "parse.yy" /* yacc.c:1646 */ {(yyval.ExprList_P) = new ExprList_t(); (yyval.ExprList_P)->push_back((yyvsp[0].Expression_P));} #line 2875 "parse.cc" /* yacc.c:1646 */ break; case 167: #line 1056 "parse.yy" /* yacc.c:1646 */ {(yyvsp[-2].ExprList_P)->push_back((yyvsp[0].Expression_P)); } #line 2881 "parse.cc" /* yacc.c:1646 */ break; case 168: #line 1060 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpAdd((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2887 "parse.cc" /* yacc.c:1646 */ break; case 169: #line 1061 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpSub((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2893 "parse.cc" /* yacc.c:1646 */ break; case 170: #line 1062 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpMpy((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2899 "parse.cc" /* yacc.c:1646 */ break; case 171: #line 1063 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpDiv((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2905 "parse.cc" /* yacc.c:1646 */ break; case 172: #line 1064 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpAnd((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2911 "parse.cc" /* yacc.c:1646 */ break; case 173: #line 1065 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpOr((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2917 "parse.cc" /* yacc.c:1646 */ break; case 174: #line 1066 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpXor((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2923 "parse.cc" /* yacc.c:1646 */ break; case 175: #line 1067 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpShl((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2929 "parse.cc" /* yacc.c:1646 */ break; case 176: #line 1068 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpShr((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2935 "parse.cc" /* yacc.c:1646 */ break; case 177: #line 1069 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpEq((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2941 "parse.cc" /* yacc.c:1646 */ break; case 178: #line 1070 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpNe((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2947 "parse.cc" /* yacc.c:1646 */ break; case 179: #line 1071 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpLt((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2953 "parse.cc" /* yacc.c:1646 */ break; case 180: #line 1072 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpGt((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2959 "parse.cc" /* yacc.c:1646 */ break; case 181: #line 1073 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpLe((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2965 "parse.cc" /* yacc.c:1646 */ break; case 182: #line 1074 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpGe((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2971 "parse.cc" /* yacc.c:1646 */ break; case 183: #line 1075 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpLogicalAnd((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2977 "parse.cc" /* yacc.c:1646 */ break; case 184: #line 1076 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpLogicalOr((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2983 "parse.cc" /* yacc.c:1646 */ break; case 185: #line 1077 "parse.yy" /* yacc.c:1646 */ {(yyval.BinaryOperator_P) = new OpAbstractRange((yyvsp[-2].Expression_P), (yyvsp[0].Expression_P));} #line 2989 "parse.cc" /* yacc.c:1646 */ break; case 186: #line 1081 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P)=(yyvsp[0].Expression_P);} #line 2995 "parse.cc" /* yacc.c:1646 */ break; case 187: #line 1082 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new OpPlus((yyvsp[0].Expression_P));} #line 3001 "parse.cc" /* yacc.c:1646 */ break; case 188: #line 1083 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new OpNegate((yyvsp[0].Expression_P));} #line 3007 "parse.cc" /* yacc.c:1646 */ break; case 189: #line 1084 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new OpOnescomp((yyvsp[0].Expression_P));} #line 3013 "parse.cc" /* yacc.c:1646 */ break; case 190: #line 1085 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new OpLogicalNot((yyvsp[0].Expression_P));} #line 3019 "parse.cc" /* yacc.c:1646 */ break; case 191: #line 1086 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new OpIndirect((yyvsp[0].Expression_P));} #line 3025 "parse.cc" /* yacc.c:1646 */ break; case 192: #line 1087 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new OpAddressOf((yyvsp[0].Expression_P));} #line 3031 "parse.cc" /* yacc.c:1646 */ break; case 193: #line 1088 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P)=(yyvsp[-1].Expression_P);} #line 3037 "parse.cc" /* yacc.c:1646 */ break; case 194: #line 1091 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new LiteralInteger((yyvsp[0].Integer_P));} #line 3043 "parse.cc" /* yacc.c:1646 */ break; case 195: #line 1092 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new LiteralBoolean((yyvsp[0].Boolean_P));} #line 3049 "parse.cc" /* yacc.c:1646 */ break; case 196: #line 1093 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new LiteralString((yyvsp[0].String_P));} #line 3055 "parse.cc" /* yacc.c:1646 */ break; case 197: #line 1094 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new LiteralFloat((yyvsp[0].Float_P));} #line 3061 "parse.cc" /* yacc.c:1646 */ break; case 198: #line 1095 "parse.yy" /* yacc.c:1646 */ { try { (yyval.Expression_P) = new LiteralSymbol((yyvsp[0].Symbol_P)); } catch (Error *err) { if(err) { yyerror(err->toString().c_str()); delete err; } delete (yyvsp[0].Symbol_P); YYERROR; } } #line 3080 "parse.cc" /* yacc.c:1646 */ break; case 199: #line 1109 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new IndexedSymbol((yyvsp[-3].Symbol_P),(yyvsp[-1].ExprList_P));} #line 3086 "parse.cc" /* yacc.c:1646 */ break; case 200: #line 1110 "parse.yy" /* yacc.c:1646 */ {(yyval.Expression_P) = new LiteralArray((yyvsp[0].ExprList_P)); } #line 3092 "parse.cc" /* yacc.c:1646 */ break; #line 3096 "parse.cc" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 1113 "parse.yy" /* yacc.c:1906 */ // parsing is over //-------------------------- // This initialization could be done by the compiler. However // it requires two passes through because the token values are // defined by the parser output (eg. y.tab.h) while at the same // time the parser depends on the .h files in which these classes // are defined. void initialize_commands(void) { static bool initialized = 0; if(initialized) return; if(verbose) cout << __FUNCTION__ << "()\n"; attach.token_value = ATTACH; c_break.token_value = BREAK; // c_bus.token_value = BUS; clear.token_value = CLEAR; disassemble.token_value = DISASSEMBLE; dump.token_value = DUMP; frequency.token_value = FREQUENCY; help.token_value = HELP; c_list.token_value = LIST; c_load.token_value = LOAD; c_log.token_value = LOG; c_macro.token_value = MACRO; c_module.token_value = MODULE; c_node.token_value = NODE; c_processor.token_value = PROCESSOR; quit.token_value = QUIT; reset.token_value = RESET; c_run.token_value = RUN; c_set.token_value = SET; step.token_value = STEP; c_stimulus.token_value = STIMULUS; c_symbol.token_value = SYMBOL; c_trace.token_value = TRACE; version.token_value = gpsim_VERSION; c_x.token_value = X; c_icd.token_value = ICD; c_shell.token_value = SHELL; initialized = 1; parser_spanning_lines = 0; parser_warnings = 1; // display parser warnings. } gpsim-0.30.0/cli/cmd_dump.cc0000664000076400007640000002172213041763642012524 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "command.h" #include "cmd_dump.h" #include "input.h" #include "../src/value.h" #include "../src/pic-processor.h" #include "../src/14bit-processors.h" #include "../src/interface.h" #include "../src/eeprom.h" #include "../src/i2c-ee.h" cmd_dump dump; static cmd_options cmd_dump_options[] = { {"e", cmd_dump::DUMP_EEPROM, OPT_TT_BITFLAG}, {"r", cmd_dump::DUMP_RAM, OPT_TT_BITFLAG}, {"s", cmd_dump::DUMP_SFRS, OPT_TT_BITFLAG}, {0,0,0} }; cmd_dump::cmd_dump() : command("dump","du") { brief_doc = string("Display either the RAM or EEPROM"); long_doc = string ("dump [r | e [module_name [filename]] | s]\n" "\tdump r or dump with no options will display all of the file\n" "\t registers and special function registers.\n" "\tdump e will display the contents of the EEPROM (if the pic\n" "\t being simulated contains any)\n" "\tdump e module_name \n" "\t Display the contents of an EEPROM module where module_name\n" "\t can either be the name of a module or processor,\n" "\tdump e module_name filename \n" "\t dumps the contents of an EEPROM module\n" "\t to a file as Intel hex format. The 'load e' command \n" "\t can load the file generated by this command.\n" "\tdump s will display only the special function registers.\n" ); op = cmd_dump_options; } #define REGISTERS_PER_ROW 16 #define SFR_COLUMNS 3 #define MAX_SFR_NAME 10 void cmd_dump::dump_sfrs(void) { Processor * cpu = GetActiveCPU(); unsigned int reg_size = cpu->register_size(); unsigned int uToDisplayCount = 0; unsigned int uColumns = SFR_COLUMNS; vector RegListToDisplay; unsigned int auTopRowIndex[SFR_COLUMNS]; // Examine all registers this pic has to offer list :: iterator itPMA; itPMA = cpu->pma_context.begin(); for(; itPMA != cpu->pma_context.end(); ++itPMA) { list::iterator itReg; for(itReg = (*itPMA)->SpecialRegisters.begin(); itReg != (*itPMA)->SpecialRegisters.end(); ++itReg) { uToDisplayCount++; RegListToDisplay.push_back(*itReg); } } if(RegListToDisplay.size() == 0) { for (unsigned int i = 0; i < cpu->register_memory_size(); i++) { Register * pReg = cpu->registers[i]; if(pReg->isa() == Register::SFR_REGISTER && // Found an sfr. Display its contents only if not aliased // at some other address too. i == pReg->address) { uToDisplayCount++; RegListToDisplay.push_back(pReg); } } } // // All this is so we can have the reg number sequence go // from top to bottom of each column instead of across columns. unsigned int uMod = uToDisplayCount % uColumns; unsigned int uRowsPerColumn = uToDisplayCount / uColumns; auTopRowIndex[0] = 0; for (unsigned int i = 1; i < sizeof(auTopRowIndex) / sizeof(unsigned int); i++) { auTopRowIndex[i] = auTopRowIndex[i-1] + uRowsPerColumn + (uMod > i ? 1 : 0); } uRowsPerColumn += (uMod == 0 ? 0 : 1); putchar('\n'); unsigned int uRegCount = 0; for (unsigned int uRow = 0; uRow < uRowsPerColumn; uRow++) { for (unsigned int uColCurrent = 0; uColCurrent < uColumns; uColCurrent++) { unsigned int uIndex = auTopRowIndex[uColCurrent] + uRow; if(uRegCount > uToDisplayCount) break; // printf("%03d ", uIndex); // used for testings uRegCount++; Register *pReg = RegListToDisplay[uIndex]; printf("%03x %-7s = %0*x ", pReg->address, pReg->name().c_str(), reg_size * 2, pReg->get_value()); } putchar('\n'); } } int cmd_dump::dump(int bit_flag, gpsimObject* module, const char * filename) { Register **fr=0; unsigned int mem_size = 0; int reg_size = 1; int address_off = 0x0000; char s1[256]; pic_processor *pic; string symName; I2C_EE *eeprom; PromAddress *sym; FILE *fd = NULL; int iReturn; if ( bit_flag != DUMP_EEPROM) { printf("cmd_dump: invalid option\n"); return 0; } module->name(s1, sizeof(s1)); symName = s1; symName += ".eeprom"; fprintf(stdout, "cmd_dump module=%s file=%s\n", s1, filename); if (filename && (fd = fopen(filename, "w")) == NULL) { perror(filename); return 0; } if (( pic = dynamic_cast (module)) && pic->eeprom) { fr = pic->eeprom->get_rom(); mem_size = pic->eeprom->get_rom_size(); reg_size = pic->eeprom->register_size(); address_off = 0x0000; } else if ((sym = dynamic_cast(globalSymbolTable().find(symName)))) { sym->get(eeprom); fr = eeprom->get_rom(); mem_size = eeprom->get_rom_size(); reg_size = eeprom->register_size(); address_off = 0x0000; } else { cout << "*** Error cmd_dump module " << s1 << " not EEPROM" << endl; iReturn = 0; } if (fd) { if (reg_size == 1) { IntelHexProgramFileType::writeihex8(fr, mem_size, fd, address_off); iReturn = 1; } else { printf("cmd_dump: module EEPROM register size of %d not currently supported\n", reg_size); iReturn = 0; } fclose(fd); } else { gpsim_set_bulk_mode(1); dump_regs(fr, mem_size, reg_size, bit_flag); gpsim_set_bulk_mode(0); iReturn = 1; } return iReturn; } void cmd_dump::dump(int mem_type) { unsigned int mem_size=0; unsigned int reg_size=1; Register **fr=0; Processor *pCpu = GetActiveCPU(true); if(!pCpu) return; switch(mem_type) { case DUMP_EEPROM: { pic_processor *pic = dynamic_cast (pCpu); if(pic && pic->eeprom) { fr = pic->eeprom->get_rom(); mem_size = pic->eeprom->get_rom_size(); } else return; } break; case DUMP_RAM: mem_size = GetActiveCPU()->register_memory_size(); reg_size = GetActiveCPU()->register_size(); fr = GetActiveCPU()->registers; break; case DUMP_SFRS: dump_sfrs(); putchar('\n'); return; } if(mem_size == 0) return; gpsim_set_bulk_mode(1); dump_regs(fr, mem_size, reg_size, mem_type); // Now Dump the sfr's if(mem_type == DUMP_RAM) { dump_sfrs(); pic_processor *pic = dynamic_cast(pCpu); if(pic) printf("\n%s = %02x\n",pic->Wreg->name().c_str(), pic->Wreg->get_value()); printf("pc = 0x%x\n",GetActiveCPU()->pc->value); } gpsim_set_bulk_mode(0); } void cmd_dump::dump_regs(Register **fr, unsigned int mem_size, int reg_size, int mem_type) { unsigned int i, j, reg_num; unsigned int uRegPerRow = reg_size == 1 ? REGISTERS_PER_ROW : 8; unsigned int v; bool previous_row_is_invalid=false; bool all_invalid=false; if(reg_size == 1) { printf(" "); // Column labels for (i = 0; i < uRegPerRow; i++) printf(" %0*x", reg_size * 2, i); putchar('\n'); } reg_num = 0; for (i = 0; i < mem_size; i+=uRegPerRow) { /* First, see if there are any valid registers on this row */ all_invalid = true; for (j = 0; j < uRegPerRow; j++) { if(fr[i+j]->isa() != Register::INVALID_REGISTER) { all_invalid = false; break; } } if(!all_invalid) { previous_row_is_invalid = false; printf("%04x: ",i); for (j = 0; j < uRegPerRow; j++) { reg_num = i + j; if( (reg_num < mem_size) && fr[reg_num] && fr[reg_num]->isa() != Register::INVALID_REGISTER) { v = fr[reg_num]->get_value(); printf("%0*x ",reg_size * 2, v); } else { for (int i = 0; i < reg_size; i++) printf("--"); putchar(' '); } } if(reg_size == 1) { // don't bother with ASCII for > 8 bit registers printf(" "); for (j = 0; j < uRegPerRow; j++) { reg_num = i + j; v = fr[reg_num]->get_value(); if( (v >= ' ') && (v <= 'z')) putchar(v); else putchar('.'); } } putchar('\n'); } else { if(!previous_row_is_invalid) putchar('\n'); previous_row_is_invalid = true; reg_num += REGISTERS_PER_ROW; } } } gpsim-0.30.0/cli/cmd_reset.cc0000664000076400007640000000234113041763642012675 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_reset.h" #include "../src/pic-processor.h" cmd_reset reset; static cmd_options cmd_reset_options[] = { {0,0,0} }; cmd_reset::cmd_reset() : command("reset",0) { brief_doc = string("Reset all or parts of the simulation"); long_doc = string ("Reset all or parts of the simulation\n"); op = cmd_reset_options; } void cmd_reset::reset(void) { if(GetActiveCPU()) GetActiveCPU()->reset(POR_RESET); } gpsim-0.30.0/cli/cmd_dump.h0000664000076400007640000000232513041763642012364 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_DUMP_H__ #define __CMD_DUMP_H__ #include "../src/hexutils.h" class cmd_dump : public command, IntelHexProgramFileType { public: enum { DUMP_EEPROM = 1, DUMP_RAM, DUMP_SFRS }; cmd_dump(void); // void dump(void); void dump(int bit_flag); int dump(int bit_flag, gpsimObject* module, const char * filename); private: void dump_sfrs(void); void dump_regs(Register **fr, unsigned int mem_size, int reg_size, int mem_type); }; extern cmd_dump dump; #endif gpsim-0.30.0/cli/cmd_node.h0000664000076400007640000000174413041763642012350 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_NODE_H__ #define __CMD_NODE_H__ #include "misc.h" #include using namespace std; class cmd_node : public command { public: cmd_node(void); void list_nodes(void); void add_nodes(list *); }; extern cmd_node c_node; #endif gpsim-0.30.0/cli/Makefile.in0000664000076400007640000006452213117441634012475 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # gpsim cli VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = cli ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsimcli_la_DEPENDENCIES = ../eXdbm/libgpsim_eXdbm.la \ ../src/libgpsim.la am_libgpsimcli_la_OBJECTS = parse.lo scan.lo cmd_attach.lo \ cmd_break.lo cmd_bus.lo cmd_clear.lo cmd_disasm.lo cmd_dump.lo \ cmd_echo.lo cmd_frequency.lo cmd_help.lo cmd_icd.lo \ cmd_list.lo cmd_load.lo cmd_log.lo cmd_macro.lo cmd_module.lo \ cmd_node.lo cmd_processor.lo cmd_quit.lo cmd_reset.lo \ cmd_run.lo cmd_set.lo cmd_shell.lo cmd_step.lo cmd_stimulus.lo \ cmd_symbol.lo cmd_trace.lo cmd_version.lo cmd_x.lo command.lo \ input.lo socket.lo ui_gpsim.lo libgpsimcli_la_OBJECTS = $(am_libgpsimcli_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap @MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ -e s/c++$$/h++/ -e s/c$$/h/ YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) AM_V_YACC = $(am__v_YACC_@AM_V@) am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) am__v_YACC_0 = @echo " YACC " $@; am__v_YACC_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgpsimcli_la_SOURCES) DIST_SOURCES = $(libgpsimcli_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/ylwrap INSTALL README parse.cc scan.cc DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ MAINTAINERCLEANFILES = parse.h parse.output lib_LTLIBRARIES = libgpsimcli.la libgpsimcli_la_SOURCES = \ parse.yy \ scan.ll \ cmd_attach.cc \ cmd_break.cc \ cmd_bus.cc \ cmd_clear.cc \ cmd_disasm.cc \ cmd_dump.cc \ cmd_echo.cc \ cmd_frequency.cc \ cmd_help.cc \ cmd_icd.cc \ cmd_list.cc \ cmd_load.cc \ cmd_log.cc \ cmd_macro.cc \ cmd_module.cc \ cmd_node.cc \ cmd_processor.cc \ cmd_quit.cc \ cmd_reset.cc \ cmd_run.cc \ cmd_set.cc \ cmd_shell.cc \ cmd_step.cc \ cmd_stimulus.cc \ cmd_symbol.cc \ cmd_trace.cc \ cmd_version.cc \ cmd_x.cc \ command.cc \ input.cc \ socket.cc \ ui_gpsim.cc \ cmd_attach.h cmd_bus.h cmd_dump.h cmd_load.h cmd_reset.h cmd_symbol.h \ command.h cmd_break.h cmd_echo.h cmd_log.h cmd_module.h cmd_node.h cmd_run.h \ cmd_shell.h cmd_trace.h \ input.h cmd_clear.h cmd_help.h cmd_processor.h cmd_set.h cmd_step.h \ cmd_version.h misc.h cmd_disasm.h cmd_list.h cmd_quit.h \ cmd_stimulus.h cmd_x.h symbol_t.h cmd_frequency.h cmd_icd.h \ cmd_macro.h ui_gpsim.h AM_YFLAGS = -dvt libgpsimcli_la_LIBADD = @X_LDFLAGS@ @LIBREADLINE@ ../eXdbm/libgpsim_eXdbm.la ../src/libgpsim.la EXTRA_DIST = scan.h parse.h makefile.mingw all: all-am .SUFFIXES: .SUFFIXES: .cc .h .ll .lo .o .obj .yy $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cli/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cli/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgpsimcli.la: $(libgpsimcli_la_OBJECTS) $(libgpsimcli_la_DEPENDENCIES) $(EXTRA_libgpsimcli_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(libgpsimcli_la_OBJECTS) $(libgpsimcli_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_attach.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_break.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_bus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_clear.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_disasm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_dump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_echo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_frequency.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_help.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_icd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_list.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_load.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_log.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_macro.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_module.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_node.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_processor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_quit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_reset.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_run.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_set.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_shell.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_step.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_stimulus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_symbol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_trace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_gpsim.Plo@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< .ll.cc: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f parse.cc -rm -f scan.cc -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile .yy.cc: rm -f $*.h $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $*.cc y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) .yy.h: rm -f $*.h $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $*.cc y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/cli/Makefile.am0000664000076400007640000000270213041763642012456 00000000000000# gpsim cli AM_CPPFLAGS = @X_CFLAGS@ MAINTAINERCLEANFILES = parse.h parse.output lib_LTLIBRARIES = libgpsimcli.la libgpsimcli_la_SOURCES = \ parse.yy \ scan.ll \ cmd_attach.cc \ cmd_break.cc \ cmd_bus.cc \ cmd_clear.cc \ cmd_disasm.cc \ cmd_dump.cc \ cmd_echo.cc \ cmd_frequency.cc \ cmd_help.cc \ cmd_icd.cc \ cmd_list.cc \ cmd_load.cc \ cmd_log.cc \ cmd_macro.cc \ cmd_module.cc \ cmd_node.cc \ cmd_processor.cc \ cmd_quit.cc \ cmd_reset.cc \ cmd_run.cc \ cmd_set.cc \ cmd_shell.cc \ cmd_step.cc \ cmd_stimulus.cc \ cmd_symbol.cc \ cmd_trace.cc \ cmd_version.cc \ cmd_x.cc \ command.cc \ input.cc \ socket.cc \ ui_gpsim.cc \ cmd_attach.h cmd_bus.h cmd_dump.h cmd_load.h cmd_reset.h cmd_symbol.h \ command.h cmd_break.h cmd_echo.h cmd_log.h cmd_module.h cmd_node.h cmd_run.h \ cmd_shell.h cmd_trace.h \ input.h cmd_clear.h cmd_help.h cmd_processor.h cmd_set.h cmd_step.h \ cmd_version.h misc.h cmd_disasm.h cmd_list.h cmd_quit.h \ cmd_stimulus.h cmd_x.h symbol_t.h cmd_frequency.h cmd_icd.h \ cmd_macro.h ui_gpsim.h AM_YFLAGS = -dvt libgpsimcli_la_LIBADD = @X_LDFLAGS@ @LIBREADLINE@ ../eXdbm/libgpsim_eXdbm.la ../src/libgpsim.la .yy.cc: rm -f $*.h $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $*.cc y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) .yy.h: rm -f $*.h $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $*.cc y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) EXTRA_DIST = scan.h parse.h makefile.mingw gpsim-0.30.0/cli/cmd_frequency.h0000664000076400007640000000171213041763642013417 00000000000000/* Copyright (C) 2001 Salvador E. Tropea This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_FREQUENCY_H__ #define __CMD_FREQUENCY_H__ class Expression; class cmd_frequency : public command { public: cmd_frequency(void); void set(Expression *); void print(); }; extern cmd_frequency frequency; #endif gpsim-0.30.0/cli/cmd_icd.h0000664000076400007640000000171613041763642012161 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_ICD_H__ #define __CMD_ICD_H__ class cmd_icd : public command { public: cmd_icd(void); void icd(void); void icd(cmd_options_str *cos); virtual int is_repeatable(void) { return 0; }; }; extern cmd_icd c_icd; #endif gpsim-0.30.0/cli/cmd_processor.h0000664000076400007640000000200013041763642013424 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_PROCESSOR_H__ #define __CMD_PROCESSOR_H__ class cmd_processor : public command { public: cmd_processor(void); void processor(void); void processor(int bit_flag); void processor(const char *proc, const char *name); }; extern cmd_processor c_processor; #endif gpsim-0.30.0/cli/cmd_clear.cc0000664000076400007640000000413413041763642012643 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "cmd_clear.h" #include "../src/pic-processor.h" cmd_clear clear; static cmd_options cmd_clear_options[] = { {0,0,0} }; cmd_clear::cmd_clear() : command("clear", "cl") { brief_doc = string("Remove a break point"); long_doc = string ("clear bp_number\n\ where bp_number is the number assigned to the break point\n\ when it was created. (type \"break\" without any arguments to\n\ display the currently set break points.\n\ "); op = cmd_clear_options; } void cmd_clear::clear(Expression *expr) { if(expr) { try { Value *v = expr->evaluate(); if(v) { if (typeid(*v) == typeid(String)) { char szParam[20]; ((String*)v)->get(szParam, 20); if(strcmp(szParam, "all") == 0) { get_bp().clear_all(get_active_cpu()); } } else if (typeid(*v) == typeid(Integer)) { /* for now, assume that the expression evaluates to an integer (later, things like 'clear all' will be add) */ gint64 i; v->get(i); get_bp().clear((unsigned int)i); } delete v; } } catch (Error *err) { if (err) { cerr << "***ERROR cmd_clear " << err->toString() << endl; delete err; } } delete expr; } } gpsim-0.30.0/cli/cmd_macro.h0000664000076400007640000000330613041763642012520 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_MACRO_H__ #define __CMD_MACRO_H__ #include #include "../src/gpsim_object.h" typedef list StringList_t; class Macro :public gpsimObject { public: Macro(const char *new_name); StringList_t arguments; // declared when macro is defined StringList_t body; // what the macro contains. StringList_t parameters; // passed to macro during invocation void invoke(); void prepareForInvocation(); int substituteParameter(const string &s,string &replaced); int nParameters(); void add_argument(const char *new_arg); void add_parameter(const char *s); void add_body(const char *new_line); void print(void); }; class cmd_macro : public command { public: cmd_macro(void); void list(void); void define(const char *name); void add_parameter(const char *parameter); void add_body(const char *line); void end_define(const char *opt_name=0); virtual int is_repeatable(void) { return 1; }; }; extern cmd_macro c_macro; #endif gpsim-0.30.0/cli/cmd_load.h0000664000076400007640000000222413041763642012334 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_LOAD_H__ #define __CMD_LOAD_H__ #include "../src/hexutils.h" class cmd_load : public command, IntelHexProgramFileType { public: cmd_load(); int load(int bit_flag,const char *filename); int load(int bit_flag, gpsimObject* module, const char *filename); int load(gpsimObject *file, gpsimObject * pProcessorType = NULL); int load(const char *file, const char *pProcessorType); }; extern cmd_load c_load; #endif gpsim-0.30.0/cli/cmd_quit.h0000664000076400007640000000166513041763642012407 00000000000000/* Copyright (C) 1998,199 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_QUIT_H__ #define __CMD_QUIT_H__ class cmd_quit : public command { public: cmd_quit(void); void quit(void) { cout << "quit command\n";}; void quit(int); }; extern cmd_quit quit; #endif gpsim-0.30.0/cli/cmd_bus.h0000664000076400007640000000174013041763642012210 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_BUS_H__ #define __CMD_BUS_H__ #include "misc.h" #include using namespace std; class cmd_bus : public command { public: cmd_bus(void); void list_busses(void); void add_busses(list *); }; extern cmd_bus c_bus; #endif gpsim-0.30.0/cli/cmd_x.cc0000664000076400007640000001174213041763642012027 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "cmd_x.h" #include "cmd_dump.h" #include "../src/cmd_gpsim.h" #include "../src/pic-processor.h" #include "../src/symbol.h" cmd_x c_x; static cmd_options cmd_x_options[] = { {0,0,0} }; cmd_x::cmd_x() : command("x",0) { brief_doc = string("[deprecated] examine and/or modify memory"); long_doc = string ("\nx examine command -- deprecated\n\ \tInstead of the using a special command to examine and modify\n\ \tvariables, it's possible to directly access them using gpsim's\n\ \texpression parsing. For example, to examine a variable:\n\ gpsim> my_variable\n\ my_variable [0x27] = 0x00 = 0b00000000\n\ \tTo modify a variable\n\ gpsim> my_variable = 10\n\ \tIt's also possible to assign the value of register to another\n\ gpsim> my_variable = porta\n\ \tOr to assign the results of an expression:\n\ gpsim> my_variable = (porta ^ portc) & 0x0f\n"); /* long_doc = string ("\nx [file_register] [new_value]\n\ \toptions:\n\ \t\tfile_register - ram location to be examined or modified.\n\ \t\tnew_value - the new value written to the file_register.\n\ \t\tif no options are specified, then the entire contents\n\ \t\tof the file registers will be displayed (dump).\n\ "); */ op = cmd_x_options; } void cmd_x::x(void) { dump.dump(cmd_dump::DUMP_RAM); if(GetActiveCPU()) GetActiveCPU()->dump_registers(); } void cmd_x::x(int reg, Expression *pExpr) { if(!GetActiveCPU()) return; if(reg<0 || (reg >= (int)GetActiveCPU()->register_memory_size()) ) { GetUserInterface().DisplayMessage("bad file register\n"); return; } Register *pReg = GetActiveCPU()->registers[reg]; RegisterValue rvCurrent(pReg->getRVN()); if(pExpr == NULL) { char str[33]; // Display value const char * pAddr = GetUserInterface().FormatRegisterAddress( reg, GetActiveCPU()->m_uAddrMask); const char * pValue = GetUserInterface().FormatValue( rvCurrent.data, GetActiveCPU()->register_mask()); GetUserInterface().DisplayMessage("%s[%s] = %s = 0b%s\n", pReg->name().c_str(), pAddr, pValue, pReg->toBitStr(str,sizeof(str))); } else { // Assign value Value *pValue = pExpr->evaluate(); if(pValue != NULL) { Integer * pInt = dynamic_cast(pValue); if(pValue != NULL) { char str[33]; pReg->toBitStr(str,sizeof(str)); RegisterValue value( GetActiveCPU()->register_mask() & (unsigned int)pInt->getVal(), 0); pReg->putRV(value); // Notify listeners pReg->update(); // Display new value x(reg); // Display old value const char * pValue = GetUserInterface().FormatValue( (gint64)rvCurrent.get(), GetActiveCPU()->register_mask()); GetUserInterface().DisplayMessage("was %s = 0b%s\n", pValue, str); } else { GetUserInterface().DisplayMessage( "Error: the expression did not evaluate to on integer"); } delete pValue; } else { GetUserInterface().DisplayMessage("Error evaluating the expression"); } delete pExpr; } } void cmd_x::x(char *reg_name) { cout << "this command is deprecated. " << "Type '" << reg_name << "' at the command line to display the contents of a register.\n"; // get_symbol_table().dump_one(reg_name); } void cmd_x::x(char *reg_name, int val) { cout << "this command is deprecated. use: \n symbol_name = value\n\ninstead\n"; // update_symbol_value(reg_name,val); } void cmd_x::x(Expression *expr) { /* try { Value *v = toValue(expr); cout << v->toString() << endl; if(typeid(register_symbol) == typeid(*v) || (typeid(LiteralSymbol) == typeid(*expr) && !((LiteralSymbol*)expr)->toString().empty() )) { // v->toString() dumped the value to cout } else if(typeid(Integer) == typeid(*v)) { int i; v->get(i); x(i); } else if(typeid(AbstractRange) == typeid(*v)) { unsigned int i = v->get_leftVal(); while (i<=v->get_rightVal()) { x(i); i++; } } delete v; delete expr; } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } */ delete expr; } gpsim-0.30.0/cli/cmd_shell.h0000664000076400007640000000170613041763642012530 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_SHELL_H__ #define __CMD_SHELL_H__ #include using namespace std; class symbol; class cmd_shell : public command { public: cmd_shell(void); void shell(String *cmd); }; extern cmd_shell c_shell; #endif gpsim-0.30.0/cli/cmd_step.h0000664000076400007640000000176313041763642012377 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_STEP_H__ #define __CMD_STEP_H__ class Expression; class cmd_step : public command { public: cmd_step(void); void step(int); void step(Expression *); void over(void); virtual int is_repeatable(void) { return 1; }; }; extern cmd_step step; #endif gpsim-0.30.0/cli/parse.yy0000664000076400007640000007441013041763642012124 00000000000000 %{ /* Parser for gpsim Copyright (C) 1999 Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include using namespace std; #include "misc.h" #include "command.h" #include "cmd_attach.h" #include "cmd_break.h" #include "cmd_bus.h" #include "cmd_clear.h" #include "cmd_disasm.h" #include "cmd_dump.h" #include "cmd_frequency.h" #include "cmd_help.h" #include "cmd_list.h" #include "cmd_load.h" #include "cmd_log.h" #include "cmd_node.h" #include "cmd_macro.h" #include "cmd_module.h" #include "cmd_processor.h" #include "cmd_quit.h" #include "cmd_reset.h" #include "cmd_run.h" #include "cmd_set.h" #include "cmd_step.h" #include "cmd_shell.h" #include "cmd_stimulus.h" #include "cmd_symbol.h" #include "cmd_trace.h" #include "cmd_version.h" #include "cmd_x.h" #include "cmd_icd.h" #include "../src/expr.h" #include "../src/operator.h" #include "../src/symbol.h" #include "../src/stimuli.h" #include "../src/processor.h" extern void lexer_setMacroBodyMode(); extern void lexer_InvokeMacro(Macro *m); extern void lexer_setDeclarationMode(); #define YYERROR_VERBOSE extern char *yytext; int quit_parse=0; int abort_gpsim=0; int parser_warnings; int parser_spanning_lines=0; int gAbortParserOnSyntaxError=0; extern int use_gui; extern int quit_state; extern command *getLastKnownCommand(); extern void init_cmd_state(); extern const char * GetLastFullCommand(); // From scan.ll void FlushLexerBuffer(); void yyerror(const char *message) { const char *last = GetLastFullCommand(); if (last) { int n = strlen(last); char *pt = strdup(last); if (n > 0 && *(pt+n-1) == '\n') *(pt+n-1) = 0; printf("***ERROR: %s while parsing:\n\t'%s'\n",message, pt); free(pt); } else printf("***ERROR: %s \n",message); init_cmd_state(); // JRH - I added this hoping that it is an appropriate // place to clear the lexer buffer. An example of // failed command where this is needed is to index // into an undefined symbol. (i.e. undefinedsymbol[0]) FlushLexerBuffer(); } int toInt(Expression *expr) { try { if(expr) { Value *v = expr->evaluate(); if (v) { int i; v->get(i); delete v; return i; } } } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } return -1; } %} /* The pure-parser mode is used to enable reentrancy */ %pure-parser /* Bison declarations */ %union { guint32 i; guint64 li; float f; char *s; cmd_options *co; cmd_options_num *con; cmd_options_str *cos; cmd_options_expr *coe; BinaryOperator* BinaryOperator_P; Boolean* Boolean_P; Expression* Expression_P; Float* Float_P; Integer* Integer_P; String* String_P; gpsimObject* Symbol_P; gpsimObject* gpsimObject_P; StringList_t *StringList_P; ExprList_t *ExprList_P; gpsimObjectList_t *gpsimObjectList_P; Macro *Macro_P; } %{ /* Define the interface to the lexer */ extern int yylex(YYSTYPE* lvalP); %} /* gpsim commands: */ %token ABORT %token ATTACH %token BREAK %token BUS %token CLEAR %token DISASSEMBLE %token DUMP %token ENDM %token FREQUENCY %token HELP %token LOAD %token LOG %token LIST %token NODE %token MACRO %token MODULE %token PROCESSOR %token QUIT %token RESET %token RUN %token SET %token SHELL %token STEP %token STIMULUS %token SYMBOL %token TRACE %token gpsim_VERSION %token X %token ICD %token END_OF_COMMAND %type mdef_body_ %type mdef_end %token MACROBODY_T %token MACROINVOCATION_T %type break_set %token
  • INDIRECT %token
  • END_OF_INPUT %token BIT_FLAG %token EXPRESSION_OPTION %token NUMERIC_OPTION %token STRING_OPTION %token CMD_SUBTYPE %token SYMBOL_OPTION /* Expression parsing stuff */ %type binary_expr %type expr %type literal %type unary_expr %type expr_list %type array %type gpsimObject_list %type gpsimObject %token LITERAL_INT_T %token LITERAL_BOOL_T %token LITERAL_FLOAT_T %token LITERAL_STRING_T %token LITERAL_ARRAY_T %token SYMBOL_T %token GPSIMOBJECT_T %token PORT_T %token EQU_T %token AND_T %token COLON_T %token COMMENT_T %token DIV_T %token EOLN_T %token MINUS_T %token MPY_T %token OR_T %token PLUS_T %token SHL_T %token SHR_T %token XOR_T %token INDEXERLEFT_T %token INDEXERRIGHT_T %token DECLARE_TYPE %token DECLARE_INT_T %token DECLARE_FLOAT_T %token DECLARE_BOOL_T %token DECLARE_CHAR_T %type opt_declaration_type //%type
  • _register %type bit_flag %type cmd_subtype %type numeric_option %type string_option %type expression_option %type string_list // Here are token definitions for expression operators %nonassoc COLON_T %left PLUS_T MINUS_T XOR_T OR_T AND_T %left MPY_T DIV_T %left SHL_T SHR_T %left LOR_T %left LAND_T %left EQ_T NE_T %left LT_T LE_T GT_T GE_T MIN_T MAX_T ABS_T %nonassoc IND_T %left BIT_T BITS_T %right LOW_T HIGH_T LADDR_T WORD_T %nonassoc INDEXED_T %right LNOT_T ONESCOMP_T UNARYOP_PREC %right POW_T %left REG_T %left GPSIMOBJECT_T %left PORT_T %% /* Grammar rules */ list_of_commands: cmd rol { init_cmd_state(); } | list_of_commands cmd rol { init_cmd_state(); } ; cmd: /* empty */ | aborting | attach_cmd | break_cmd | bus_cmd | call_cmd | clear_cmd | declaration_cmd | disassemble_cmd | dump_cmd | eval_cmd | frequency_cmd | help_cmd | list_cmd | log_cmd | load_cmd | node_cmd | macro_cmd | module_cmd | processor_cmd | quit_cmd | reset_cmd | run_cmd | set_cmd | step_cmd | shell_cmd | stimulus_cmd | symbol_cmd | trace_cmd | version_cmd | x_cmd | icd_cmd | END_OF_INPUT { //if(verbose&2) cout << "got an END_OF_INPUT\n"; /* If we're processing a command file then quit parsing * when we run out of input */ //if(Gcmd_file_ref_count) //quit_parse = 1; YYABORT; } | error { init_cmd_state(); yyclearin; // FIXME // In some cases we may wish to abort parsing while in others not. if (gAbortParserOnSyntaxError) { YYABORT; } } ; /***************************************************************** * All lines must terminate with a 'rol' (Rest Of Line) - even empty ones! */ rol : opt_comment EOLN_T ; opt_comment : /* empty */ | COMMENT_T ; aborting: ABORT { abort_gpsim = 1; quit_parse = 1; YYABORT; } ; attach_cmd : ATTACH SYMBOL_T gpsimObject_list { attach.attach($2,$3); } ; break_cmd : BREAK {c_break.list();} | BREAK LITERAL_INT_T {c_break.list($2->getVal());delete $2;} | break_set { int n = $1; if (n < 0) { yyerror("Breakpoint not set"); } } ; log_cmd : LOG {c_log.log();} | LOG bit_flag {c_log.log($2);} | LOG bit_flag expr_list {c_log.log($2,$3);} ; break_set : BREAK bit_flag expr_list { $$=c_break.set_break($2,$3);} | BREAK bit_flag {$$=c_break.set_break($2);} | BREAK SYMBOL_T {$$=c_break.set_break($2);} ; bus_cmd : BUS {c_bus.list_busses();} | BUS string_list {c_bus.add_busses($2); delete $2;} ; call_cmd : SYMBOL_T '(' expr_list ')' { cout << " call\n"; //$$ = $3; } clear_cmd: CLEAR expr {clear.clear($2);} ; disassemble_cmd : DISASSEMBLE {disassemble.disassemble(0);} | DISASSEMBLE expr {disassemble.disassemble($2);} ; dump_cmd: DUMP {dump.dump(2);} | DUMP bit_flag {dump.dump($2->value);} | DUMP bit_flag SYMBOL_T // dump m module_name { // key, module_name quit_parse = dump.dump($2->value, $3, NULL) == 0; } | DUMP bit_flag SYMBOL_T LITERAL_STRING_T // dump m module_name filename { // key, module_name, filename //quit_parse = dump.dump($2->value, $3, $4->getVal()) == 0; if (dump.dump($2->value, $3, $4->getVal()) == 0) cout << "dump to file failed\n"; delete $4; } ; eval_cmd: SYMBOL_T {c_symbol.dump_one($1);} /* // This would really be a nice feature to have, but unfortunately there's bison conflict. | expr { c_symbol.EvaluateAndDisplay($1); delete $1; } */ | '(' expr ')' { c_symbol.EvaluateAndDisplay($2); delete $2; } | SYMBOL_T EQU_T expr { Value *pValue = dynamic_cast($1); if (pValue) { try { pValue->set($3); } catch(Error Message) { GetUserInterface().DisplayMessage("%s (maybe missing quotes?)\n", Message.toString().c_str()); } pValue->update(); } delete $3; } | SYMBOL_T INDEXERLEFT_T expr_list INDEXERRIGHT_T { c_symbol.dump($1,$3); $3->clear(); delete $3; } | SYMBOL_T INDEXERLEFT_T expr_list INDEXERRIGHT_T EQU_T expr { c_symbol.Set($1, $3, $6); $3->clear(); delete $3; delete $6; } | REG_T '(' expr ')' { int i=toInt($3); if (i>=0) c_x.x(toInt($3)); delete $3; } | REG_T '(' expr ')' EQU_T expr { int i=toInt($3); if (i>=0) c_x.x(toInt($3), $6); delete $3; } ; frequency_cmd : FREQUENCY {frequency.print();} | FREQUENCY expr {frequency.set($2);} ; help_cmd : HELP {help.help(); } | HELP LITERAL_STRING_T {help.help($2->getVal()); delete $2;} | HELP SYMBOL_T {help.help($2);} ; list_cmd : LIST {c_list.list();} | LIST bit_flag {c_list.list($2);} ; load_cmd: LOAD bit_flag LITERAL_STRING_T { quit_parse = c_load.load($2->value,$3->getVal()) == 0; delete $3; if(quit_parse) { quit_parse = 0; YYABORT; } } | LOAD bit_flag SYMBOL_T LITERAL_STRING_T { quit_parse = c_load.load($2->value, $3, $4->getVal()) == 0; delete $4; if(quit_parse) { quit_parse = 0; YYABORT; } } | LOAD LITERAL_STRING_T // load [programname | cmdfile] { quit_parse = c_load.load($2->getVal(), (const char *)NULL) == 0; delete $2; quit_parse =0; if(quit_parse) { quit_parse = 0; YYABORT; } } | LOAD SYMBOL_T // load [programname | cmdfile] { quit_parse = c_load.load($2) == 0; quit_parse =0; if(quit_parse) { quit_parse = 0; YYABORT; } } | LOAD SYMBOL_T SYMBOL_T // load processor filename { // filename, processor quit_parse = c_load.load($3, $2) == 0; delete $2; delete $3; if(quit_parse) { quit_parse = 0; YYABORT; } } | LOAD LITERAL_STRING_T LITERAL_STRING_T // load processor filename // - OR - // load filename ReferenceDesignator_for_processor { // filename, processor quit_parse = c_load.load($3, $2) == 0; delete $2; delete $3; if(quit_parse) { quit_parse = 0; YYABORT; } } ; node_cmd : NODE {c_node.list_nodes();} | NODE string_list {c_node.add_nodes($2); delete $2;} ; module_cmd : MODULE {c_module.module();} | MODULE bit_flag {c_module.module($2);} | MODULE string_option { c_module.module($2,(list *)0); delete $2; } | MODULE string_option string_list { if ($2 != NULL && $3 != NULL) c_module.module($2, $3); if ($2 != NULL) delete $2; if ($3 != NULL) delete $3; } ; processor_cmd: PROCESSOR { c_processor.processor(); } | PROCESSOR bit_flag { c_processor.processor($2->value); } | PROCESSOR LITERAL_STRING_T { c_processor.processor($2->getVal(),0); delete $2; } | PROCESSOR LITERAL_STRING_T LITERAL_STRING_T { c_processor.processor($2->getVal(),$3->getVal()); delete $2; delete $3; } ; quit_cmd: QUIT { quit_parse = 1; YYABORT; } | QUIT expr { quit_parse = 1; //quit_state = $2; // FIXME need to evaluate expr YYABORT; } ; reset_cmd: RESET { reset.reset(); } ; run_cmd: RUN { c_run.run();} ; set_cmd : SET {c_set.set();} | SET bit_flag {c_set.set($2->value,0);} | SET bit_flag expr {c_set.set($2->value,$3);} ; step_cmd : STEP {step.step(1);} | STEP expr { if ($2) { int i=toInt($2); delete $2; if (i >=1) step.step(i); else yyerror("Invalid value"); } } | STEP bit_flag {step.over();} ; shell_cmd : SHELL {c_shell.shell($1); delete $1;} ; stimulus_cmd: STIMULUS { c_stimulus.stimulus(); } | STIMULUS cmd_subtype { c_stimulus.stimulus($2->value); } | stimulus_cmd stimulus_opt { /* do nothing */ } | stimulus_cmd END_OF_COMMAND { if(verbose) cout << " end of stimulus command\n"; c_stimulus.end(); } ; stimulus_opt: expression_option { if(verbose) cout << "parser sees stimulus with numeric option\n"; c_stimulus.stimulus($1); } | stimulus_opt bit_flag { if(verbose) cout << "parser sees stimulus with bit flag: " << $2->value << '\n'; c_stimulus.stimulus($2->value); } | stimulus_opt string_option { if(verbose) cout << "parser sees stimulus with string option\n"; c_stimulus.stimulus($2); } | stimulus_opt array { if(verbose) cout << "parser sees stimulus with an array\n"; c_stimulus.stimulus($2); } ; symbol_cmd : SYMBOL {c_symbol.dump_all();} | SYMBOL LITERAL_STRING_T EQU_T literal { c_symbol.add_one($2->getVal(), $4); delete $2; delete $4; } | SYMBOL LITERAL_STRING_T {c_symbol.dump_one($2->getVal()); delete $2;} | SYMBOL SYMBOL_T {c_symbol.dump_one($2);} ; trace_cmd: TRACE { c_trace.trace(); } | TRACE expr { c_trace.trace($2); } | TRACE numeric_option { c_trace.trace($2); } | TRACE string_option { c_trace.trace($2); } | TRACE bit_flag { c_trace.trace($2); } | TRACE expression_option { c_trace.trace($2); } ; version_cmd: gpsim_VERSION {version.version();} ; x_cmd : X { c_x.x();} | X expr { c_x.x($2); } ; icd_cmd: ICD { c_icd.icd(); } | ICD string_option { c_icd.icd($2); } ; //------------------------------------------------------------ // macro definitions // // Syntax: // // name macro [arg1, arg2, ...] // macro body // endm // // 'name' is the macro name // 'macro' is a keyword // arg1,arg2,... are optional arguments // 'macro body' - any valid gpsim command // 'endm' is a keyword // macro_cmd: MACRO { c_macro.list();} | macrodef_directive { } | MACROINVOCATION_T { lexer_InvokeMacro($1); } ; macrodef_directive : LITERAL_STRING_T MACRO {c_macro.define($1->getVal()); delete $1;} opt_mdef_arglist rol {lexer_setMacroBodyMode();} mdef_body mdef_end ; opt_mdef_arglist : /* empty */ | LITERAL_STRING_T { c_macro.add_parameter($1->getVal()); delete $1; } | opt_mdef_arglist ',' LITERAL_STRING_T { c_macro.add_parameter($3->getVal()); delete $3; } ; mdef_body : /* empty */ | mdef_body_ {; } ; mdef_body_ : MACROBODY_T {c_macro.add_body($1);} | mdef_body_ MACROBODY_T {c_macro.add_body($2);} ; mdef_end : ENDM {c_macro.end_define();} | LITERAL_STRING_T ENDM {c_macro.end_define($1->getVal()); delete $1; } ; // Declarations // A declaration begins with the backslash delimeter: \ // and has the syntax: // // \ [type] name [= value] // // Where the optional type is // // bool, int, float, or char // // The name is of the form of a gpsim identifier and can be anything as long as a name // of the same type does not already exist. Also, if the name is suffixed with brackets [] // then this will designate an array. // // The optional assignment allows the newly declared type to be initialized. declaration_cmd: '\\' { cout << "declaration\n"; lexer_setDeclarationMode(); } opt_declaration_type { cout << " type:" << $3 << endl; } LITERAL_STRING_T { cout << "identifier: " << $5->getVal() << endl; delete $5; } ; opt_declaration_type : /* default type */ { $$=0; } | DECLARE_INT_T { $$ = 1; cout <<"int type\n";} | DECLARE_FLOAT_T { $$ = 2; cout <<"float type\n";} | DECLARE_BOOL_T { $$ = 3; cout <<"bool type\n";} | DECLARE_CHAR_T { $$ = 4; cout <<"char type\n";} ; // Indirect addressing is supported with the indirect // operator '*'. E.g. If register 0x20 contains 0x2e // then *0x20 means that the contents of register 0x2e // are referenced. // //indirect: INDIRECT _register // { // if(verbose) // printf(" indirect register *%d",(int)$2); // $$ = $2; // } // ; // //_register: NUMBER // { // if(verbose) // printf(" --- register %d\n", (int)$1); // } // ; bit_flag: BIT_FLAG { $$ = $1; } ; cmd_subtype: CMD_SUBTYPE { $$ = $1; } ; expression_option: EXPRESSION_OPTION expr { $$ = new cmd_options_expr($1,$2); } ; numeric_option: NUMERIC_OPTION expr { $$ = new cmd_options_num; $$->co = $1; } ; string_option: STRING_OPTION LITERAL_STRING_T { $$ = new cmd_options_str($2->getVal()); $$->co = $1; if(verbose&2) cout << " name " << $$->co->name << " value " << $$->str << " got a string option \n"; delete $2; } | STRING_OPTION SYMBOL_T { String *pValue = dynamic_cast($2); if(pValue != NULL) { $$ = new cmd_options_str(pValue->getVal()); $$->co = $1; if(verbose&2) cout << " name " << $$->co->name << " value " << $$->str << " got a symbol option \n"; } else { cout << " symbol option '" << $2->name() << "' is not a string" << endl; $$ = NULL; } //delete $2; } ; string_list : LITERAL_STRING_T {$$ = new StringList_t(); $$->push_back($1->getVal()); delete $1;} | string_list LITERAL_STRING_T {$1->push_back($2->getVal()); delete $2;} ; //---------------------------------------- // Expression parsing expr : binary_expr {$$=$1;} | unary_expr {$$=$1;} | REG_T '(' expr ')' {$$=new RegisterExpression(toInt($3)); delete $3; } ; array : '{' expr_list '}' {$$=$2;} ; gpsimObject : GPSIMOBJECT_T '(' SYMBOL_T ')' { // Ex: pin(MyVariable) -- where MyVariable is the name of a symbol // This allows one to programmatically select a particular pin number. // If Symbol has an integer type, assume it is a CPU pin number // otherwise assume it is a stimulus such as a pin name if (typeid(*$3) == typeid(Integer)) { $$ = toStimulus($3); } else $$ = $3; //$$=new Pin_t(Pin_t::ePackageBased | Pin_t::eActiveProc, $3); } | GPSIMOBJECT_T '(' LITERAL_INT_T ')' { // Ex: pin(8) -- select a particular pin in the package $$ = toStimulus($3->getVal()); delete $3; } | SYMBOL_T { // The symbol should be a stimulus. This is for the attach command. // Ex: attach Node1 portb0 // The scanner will find portb0 and return it to us here as a SYMBOL_T $$ = $1; //dynamic_cast($1); } /* | PIN_T '(' LITERAL_INT_T ')' {$$=new Pin_t(Pin_t::ePackageBased | Pin_t::eActiveProc, $3);} | PIN_T '(' SYMBOL_T ',' SYMBOL_T ')' {$$=new Pin_t(Pin_t::ePackageBased, $3,$5);} | PIN_T '(' SYMBOL_T ',' LITERAL_INT_T ')' {$$=new Pin_t(Pin_t::ePackageBased, $3,$5);} | PORT_T '(' SYMBOL_T ',' SYMBOL_T ')' {$$=new Pin_t(Pin_t::ePortBased | Pin_t::eActiveProc, NULL, $3, $5);} | PORT_T '(' SYMBOL_T ',' LITERAL_INT_T ')' {$$=new Pin_t(Pin_t::ePortBased | Pin_t::eActiveProc, NULL, $3, $5);} | PORT_T '(' SYMBOL_T ',' SYMBOL_T ',' SYMBOL_T ')' {$$=new Pin_t(Pin_t::ePortBased, $3,$5,$7);} | PORT_T '(' SYMBOL_T ',' SYMBOL_T ',' LITERAL_INT_T ')' {$$=new Pin_t(Pin_t::ePortBased, $3,$5,$7);} | SYMBOL_T {$$=new Pin_t(Pin_t::ePortBased, $1);} */ ; gpsimObject_list : gpsimObject {$$ = new gpsimObjectList_t(); $$->push_back($1);} | gpsimObject_list gpsimObject {if ($2) $1->push_back($2);} ; expr_list : expr {$$ = new ExprList_t(); $$->push_back($1);} | expr_list ',' expr {$1->push_back($3); } ; binary_expr : expr PLUS_T expr {$$ = new OpAdd($1, $3);} | expr MINUS_T expr {$$ = new OpSub($1, $3);} | expr MPY_T expr {$$ = new OpMpy($1, $3);} | expr DIV_T expr {$$ = new OpDiv($1, $3);} | expr AND_T expr {$$ = new OpAnd($1, $3);} | expr OR_T expr {$$ = new OpOr($1, $3);} | expr XOR_T expr {$$ = new OpXor($1, $3);} | expr SHL_T expr {$$ = new OpShl($1, $3);} | expr SHR_T expr {$$ = new OpShr($1, $3);} | expr EQ_T expr {$$ = new OpEq($1, $3);} | expr NE_T expr {$$ = new OpNe($1, $3);} | expr LT_T expr {$$ = new OpLt($1, $3);} | expr GT_T expr {$$ = new OpGt($1, $3);} | expr LE_T expr {$$ = new OpLe($1, $3);} | expr GE_T expr {$$ = new OpGe($1, $3);} | expr LAND_T expr {$$ = new OpLogicalAnd($1, $3);} | expr LOR_T expr {$$ = new OpLogicalOr($1, $3);} | expr COLON_T expr {$$ = new OpAbstractRange($1, $3);} ; unary_expr : literal {$$=$1;} | PLUS_T unary_expr %prec UNARYOP_PREC {$$ = new OpPlus($2);} | MINUS_T unary_expr %prec UNARYOP_PREC {$$ = new OpNegate($2);} | ONESCOMP_T unary_expr %prec UNARYOP_PREC {$$ = new OpOnescomp($2);} | LNOT_T unary_expr %prec UNARYOP_PREC {$$ = new OpLogicalNot($2);} | MPY_T unary_expr %prec UNARYOP_PREC {$$ = new OpIndirect($2);} | AND_T unary_expr %prec UNARYOP_PREC {$$ = new OpAddressOf($2);} | '(' expr ')' {$$=$2;} ; literal : LITERAL_INT_T {$$ = new LiteralInteger($1);} | LITERAL_BOOL_T {$$ = new LiteralBoolean($1);} | LITERAL_STRING_T {$$ = new LiteralString($1);} | LITERAL_FLOAT_T {$$ = new LiteralFloat($1);} | SYMBOL_T { try { $$ = new LiteralSymbol($1); } catch (Error *err) { if(err) { yyerror(err->toString().c_str()); delete err; } delete $1; YYERROR; } } | SYMBOL_T INDEXERLEFT_T expr_list INDEXERRIGHT_T {$$ = new IndexedSymbol($1,$3);} | LITERAL_ARRAY_T {$$ = new LiteralArray($1); } ; %% // parsing is over //-------------------------- // This initialization could be done by the compiler. However // it requires two passes through because the token values are // defined by the parser output (eg. y.tab.h) while at the same // time the parser depends on the .h files in which these classes // are defined. void initialize_commands(void) { static bool initialized = 0; if(initialized) return; if(verbose) cout << __FUNCTION__ << "()\n"; attach.token_value = ATTACH; c_break.token_value = BREAK; // c_bus.token_value = BUS; clear.token_value = CLEAR; disassemble.token_value = DISASSEMBLE; dump.token_value = DUMP; frequency.token_value = FREQUENCY; help.token_value = HELP; c_list.token_value = LIST; c_load.token_value = LOAD; c_log.token_value = LOG; c_macro.token_value = MACRO; c_module.token_value = MODULE; c_node.token_value = NODE; c_processor.token_value = PROCESSOR; quit.token_value = QUIT; reset.token_value = RESET; c_run.token_value = RUN; c_set.token_value = SET; step.token_value = STEP; c_stimulus.token_value = STIMULUS; c_symbol.token_value = SYMBOL; c_trace.token_value = TRACE; version.token_value = gpsim_VERSION; c_x.token_value = X; c_icd.token_value = ICD; c_shell.token_value = SHELL; initialized = 1; parser_spanning_lines = 0; parser_warnings = 1; // display parser warnings. } gpsim-0.30.0/cli/cmd_echo.h0000664000076400007640000000226513041763642012340 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_ECHO_H__ #define __CMD_ECHO_H__ class cmd_echo : public command { public: cmd_echo(void); // The echo command is handled by the lexical analyzer (scan.l) // and not by this class. Note that this is different than the // other commands. The only reason the 'echo' class exists is to // provide a consistant way for displaying help text. void echo(void) { cout << "BUG: echo command does not execute!\n";}; }; extern cmd_echo echo; #endif gpsim-0.30.0/cli/parse.h0000664000076400007640000001456413041764265011720 00000000000000/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_YY_PARSE_H_INCLUDED # define YY_YY_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 1 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { ABORT = 258, ATTACH = 259, BREAK = 260, BUS = 261, CLEAR = 262, DISASSEMBLE = 263, DUMP = 264, ENDM = 265, FREQUENCY = 266, HELP = 267, LOAD = 268, LOG = 269, LIST = 270, NODE = 271, MACRO = 272, MODULE = 273, PROCESSOR = 274, QUIT = 275, RESET = 276, RUN = 277, SET = 278, SHELL = 279, STEP = 280, STIMULUS = 281, SYMBOL = 282, TRACE = 283, gpsim_VERSION = 284, X = 285, ICD = 286, END_OF_COMMAND = 287, MACROBODY_T = 288, MACROINVOCATION_T = 289, INDIRECT = 290, END_OF_INPUT = 291, BIT_FLAG = 292, EXPRESSION_OPTION = 293, NUMERIC_OPTION = 294, STRING_OPTION = 295, CMD_SUBTYPE = 296, SYMBOL_OPTION = 297, LITERAL_INT_T = 298, LITERAL_BOOL_T = 299, LITERAL_FLOAT_T = 300, LITERAL_STRING_T = 301, LITERAL_ARRAY_T = 302, SYMBOL_T = 303, GPSIMOBJECT_T = 304, PORT_T = 305, EQU_T = 306, AND_T = 307, COLON_T = 308, COMMENT_T = 309, DIV_T = 310, EOLN_T = 311, MINUS_T = 312, MPY_T = 313, OR_T = 314, PLUS_T = 315, SHL_T = 316, SHR_T = 317, XOR_T = 318, INDEXERLEFT_T = 319, INDEXERRIGHT_T = 320, DECLARE_TYPE = 321, DECLARE_INT_T = 322, DECLARE_FLOAT_T = 323, DECLARE_BOOL_T = 324, DECLARE_CHAR_T = 325, LOR_T = 326, LAND_T = 327, EQ_T = 328, NE_T = 329, LT_T = 330, LE_T = 331, GT_T = 332, GE_T = 333, MIN_T = 334, MAX_T = 335, ABS_T = 336, IND_T = 337, BIT_T = 338, BITS_T = 339, LOW_T = 340, HIGH_T = 341, LADDR_T = 342, WORD_T = 343, INDEXED_T = 344, LNOT_T = 345, ONESCOMP_T = 346, UNARYOP_PREC = 347, POW_T = 348, REG_T = 349 }; #endif /* Tokens. */ #define ABORT 258 #define ATTACH 259 #define BREAK 260 #define BUS 261 #define CLEAR 262 #define DISASSEMBLE 263 #define DUMP 264 #define ENDM 265 #define FREQUENCY 266 #define HELP 267 #define LOAD 268 #define LOG 269 #define LIST 270 #define NODE 271 #define MACRO 272 #define MODULE 273 #define PROCESSOR 274 #define QUIT 275 #define RESET 276 #define RUN 277 #define SET 278 #define SHELL 279 #define STEP 280 #define STIMULUS 281 #define SYMBOL 282 #define TRACE 283 #define gpsim_VERSION 284 #define X 285 #define ICD 286 #define END_OF_COMMAND 287 #define MACROBODY_T 288 #define MACROINVOCATION_T 289 #define INDIRECT 290 #define END_OF_INPUT 291 #define BIT_FLAG 292 #define EXPRESSION_OPTION 293 #define NUMERIC_OPTION 294 #define STRING_OPTION 295 #define CMD_SUBTYPE 296 #define SYMBOL_OPTION 297 #define LITERAL_INT_T 298 #define LITERAL_BOOL_T 299 #define LITERAL_FLOAT_T 300 #define LITERAL_STRING_T 301 #define LITERAL_ARRAY_T 302 #define SYMBOL_T 303 #define GPSIMOBJECT_T 304 #define PORT_T 305 #define EQU_T 306 #define AND_T 307 #define COLON_T 308 #define COMMENT_T 309 #define DIV_T 310 #define EOLN_T 311 #define MINUS_T 312 #define MPY_T 313 #define OR_T 314 #define PLUS_T 315 #define SHL_T 316 #define SHR_T 317 #define XOR_T 318 #define INDEXERLEFT_T 319 #define INDEXERRIGHT_T 320 #define DECLARE_TYPE 321 #define DECLARE_INT_T 322 #define DECLARE_FLOAT_T 323 #define DECLARE_BOOL_T 324 #define DECLARE_CHAR_T 325 #define LOR_T 326 #define LAND_T 327 #define EQ_T 328 #define NE_T 329 #define LT_T 330 #define LE_T 331 #define GT_T 332 #define GE_T 333 #define MIN_T 334 #define MAX_T 335 #define ABS_T 336 #define IND_T 337 #define BIT_T 338 #define BITS_T 339 #define LOW_T 340 #define HIGH_T 341 #define LADDR_T 342 #define WORD_T 343 #define INDEXED_T 344 #define LNOT_T 345 #define ONESCOMP_T 346 #define UNARYOP_PREC 347 #define POW_T 348 #define REG_T 349 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 148 "parse.yy" /* yacc.c:1909 */ guint32 i; guint64 li; float f; char *s; cmd_options *co; cmd_options_num *con; cmd_options_str *cos; cmd_options_expr *coe; BinaryOperator* BinaryOperator_P; Boolean* Boolean_P; Expression* Expression_P; Float* Float_P; Integer* Integer_P; String* String_P; gpsimObject* Symbol_P; gpsimObject* gpsimObject_P; StringList_t *StringList_P; ExprList_t *ExprList_P; gpsimObjectList_t *gpsimObjectList_P; Macro *Macro_P; #line 268 "parse.h" /* yacc.c:1909 */ }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif int yyparse (void); #endif /* !YY_YY_PARSE_H_INCLUDED */ gpsim-0.30.0/cli/command.cc0000664000076400007640000001112713041763642012350 00000000000000/* Copyright (C) 1998,199 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "../config.h" #include "../src/expr.h" #include "../src/pic-processor.h" #include "../src/sim_context.h" #include "../src/trace.h" #include "command.h" #include "cmd_attach.h" #include "cmd_break.h" #include "cmd_bus.h" #include "cmd_clear.h" #include "cmd_disasm.h" #include "cmd_dump.h" #include "cmd_echo.h" #include "cmd_frequency.h" #include "cmd_help.h" #include "cmd_list.h" #include "cmd_load.h" #include "cmd_log.h" #include "cmd_macro.h" #include "cmd_module.h" #include "cmd_node.h" #include "cmd_processor.h" #include "cmd_quit.h" #include "cmd_reset.h" #include "cmd_run.h" #include "cmd_set.h" #include "cmd_shell.h" #include "cmd_step.h" #include "cmd_stimulus.h" #include "cmd_symbol.h" #include "cmd_trace.h" #include "cmd_version.h" #include "cmd_x.h" #include "cmd_icd.h" int quit_gpsim = 0; command *command_list[] = { &c_shell, &attach, &c_break, // &c_bus, &clear, &disassemble, &dump, // &echo, &frequency, &help, &c_icd, &c_list, &c_load, &c_log, &c_macro, &c_module, &c_node, &c_processor, &quit, &reset, &c_run, &c_set, &step, &c_stimulus, &c_symbol, &c_trace, &version, &c_x }; command::command(const char *_name, const char *_abbr) : m_pName(_name), m_pAbbreviation(_abbr) { op = 0; token_value = 0; } /* command::command(struct cmd_options *options,int tv) { abbreviation = 0; op = options; token_value = tv; } */ int number_of_commands = sizeof(command_list) / sizeof(command *); command *search_commands(const string &s) { int i=0; while(iname(), s.c_str()) == 0 || (cmd->abbreviation() != 0 && strcmp(cmd->abbreviation(), s.c_str()) == 0 )) { return cmd; } i++; } return 0; } void execute_line(char *cmd) { if(verbose) cout << "Executing a line:\n " << cmd; } Processor *command::GetActiveCPU(bool bDisplayWarnings) { Processor *pCpu = CSimulationContext::GetContext()->GetActiveCPU(); if (bDisplayWarnings && !pCpu) cout << "No cpu has been selected\n"; return pCpu; } Value *command::toValue(Expression *expr) { if(expr) return expr->evaluate(); return new Integer(0); } double command::evaluate(Expression *expr) { double value = 0.0; try { if(expr) { Value *v = toValue(expr); v->get(value); delete v; delete expr; } } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } return value; } static gint64 evaluateToInt(Expression *expr) { gint64 value = 0; try { if(expr) { Value *v = expr->evaluate(); v->get(value); delete v; delete expr; } } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } return value; } void command::evaluate(ExprList_t *eList, guint64 *parameters, int *nParameters) { ExprList_itor ei; if (!eList) { if(nParameters) *nParameters = 0; return; } if ( !parameters || !nParameters || !*nParameters) return; int n = 0; for(ei = eList->begin(); (ei != eList->end()) && (n < *nParameters); ++ei, n++) { parameters[n] = evaluateToInt(*ei); cout << "p" << n << " = " << parameters[n] << endl; } *nParameters = n; } //======================================================================== // Command options cmd_options_str::cmd_options_str(const char *new_val) { if(new_val) str = strdup(new_val); else str = 0; } cmd_options_str::~cmd_options_str() { if(str) free (str); } cmd_options_expr::cmd_options_expr(cmd_options *_co, Expression *_expr) { co = _co; expr = _expr; } cmd_options_expr::~cmd_options_expr() { delete co; delete expr; } gpsim-0.30.0/cli/cmd_attach.cc0000664000076400007640000001305613041763642013024 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "../src/stimuli.h" #include "../src/processor.h" #include "cmd_attach.h" cmd_attach attach; static cmd_options cmd_attach_options[] = { {0,0,0} }; cmd_attach::cmd_attach() : command("attach", 0) { brief_doc = string("Attach stimuli to nodes"); long_doc = string ("attach node1 stimulus_1 [stimulus_2 stimulu_N]\n" "\tAttach is used to define connections between one or more stimulus\n" "\tand a node. One node and at least one stimulus must be specified, but\n" "\tin general two or more stimuli are used. Attach can be viewed as\n" "\twiring stimuli together, with the node acting as the wire. A stimulus\n" "\tis either a CPU or module I/O pin or a stimulus name.\n\n" "\tstimulus_n May be one of four forms:\n" "\tpin() or pin()\n" "\t This refers to a pin of the current active CPU.\n" "\t is the pin number\n" "\t is an integer symbol whose value is a pin number\n" "\n" "\t or pin()\n" "\t These two forms are treated exactly the same\n" "\t ( i.e. the pin() has no meaning).\n" "\t is a stimulus name or an I/O pin name.\n" "\t I/O pin name can be just the pin name for the CPU or\n" "\t .pin_name for a module\n" "\n" "\texample:\n" "\n" "\t**gpsim> load instructions_14bit.cod # load code\n" "\t**gpsim> module library libgpsim_modules #load module lib\n" "\t**gpsim> module load usart U1 # create USART\n" "\t**gpsim> node n1 # define a node\n" "\t**gpsim> node n2 #define another node\n" "\t**gpsim> symbol TWO=2 #define symbol with value 2\n" "\t**gpsim> attach n1 pin(1) pin(TWO) #attach CPU pins 1 and 2 to n1\n" "\t**gpsim> attach n1 U1.RXPIN #add usart pin to n1\n" "\t**gpsim> attach n2 portb0 pin(U1.TXPIN) #connect portb0 to UASRT TX pin\n" "\t**gpsim> node # show results\n" ); #ifdef Q long_doc = string ("attach node1 stimulus_1 [stimulus_2 stimulu_N]\n" "\t attach is used to define the connections between stimuli and nodes.\n" "\tAt least one node and one stimulus must be specified. If more stimuli\n" "\tare specified then they will all be attached to the node.\n\n" "\tstimulus_n May be one of four forms:\n" "\t pin() or pin()\n" "\t The single argument form refers to a pin of the currently\n" "\t active cpu. The argument defined the pin number\n" "\t of active cpu. The argument refers to the\n" "\t name of the pin. If the is scoped to a specific\n" "\t attribute (i.e. MyProc.PORTA0) the pin of the specified\n" "\t module will be attached.\n" "\t pin(, ) or pin(, )\n" "\t The dual argument form refers to the pin of the specified\n" "\t module.\n" "\t Name of the module or string variable that contains the\n" "\t module name.\n" "\t A symbolic integer constant representing the pin number.\n" "\t A literal integer value of the pin number.\n" "\n" "\texamples:\n" "\n" "\t processor p16f627 P16\n" "\t node pin2pin_test // Define a new node.\n" "\t attach pin2pin_test pin(porta4) pin(P16, portb0) // Different ways to \n" "\t attach pin2pin_test pin(4) pin(0) // connect two I/O\n" "\t attach pin2pin_test pin(P16,portb0) // pins to the node.\n" "\t attach pin2pin_test pin(P16,0)\n" "\t node // Display the new \"net list\".\n\n" "\tdeprecated:\n" "\t attach pin2pin_test porta4 portb0\n" ); #endif // Q op = cmd_attach_options; } extern void stimuli_attach(gpsimObject *pNode, gpsimObjectList_t *pPinList); void cmd_attach::attach(gpsimObject *pNode, gpsimObjectList_t *pPinList) { stimuli_attach(pNode, pPinList); //cout <<"deleting stimulus list\n"; pPinList->clear(); delete pPinList; } stimulus *toStimulus(int pinNumber) { Processor *pMod = attach.GetActiveCPU(); stimulus *pStim = pMod ? pMod->get_pin(pinNumber) : 0; if (!pStim) { cout << "unable to select pin " << pinNumber << "\n"; // GetUserInterface().DisplayMessage("unable to select pin\n"); } return pStim; } stimulus *toStimulus(gpsimObject *pObj) { Value *pVal = dynamic_cast(pObj); if (!pVal) { cout << (pObj?pObj->name():"") << " cannot be converted to a pin number\n"; return 0; } return toStimulus((gint64)*pVal); } gpsim-0.30.0/cli/symbol_t.h0000664000076400007640000000014413041763642012421 00000000000000#if !defined (__SYMBOL_H_) #define __SYMBOL_H_ extern int search_symbols(const string &s); #endif gpsim-0.30.0/cli/cmd_icd.cc0000664000076400007640000000407113041763642012314 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_icd.h" #include "../src/icd.h" cmd_icd c_icd; #define ICD_OPEN_CMD 1 static cmd_options cmd_icd_options[] = { {"open", ICD_OPEN_CMD, OPT_TT_STRING}, {0,0,0} }; cmd_icd::cmd_icd() : command("icd",0) { brief_doc = string("ICD command."); long_doc = string ("\nicd [open ]\n\ \tThe open command is used to enable ICD mode and specify the serial\n\ \tport where the ICD is. (e.g. \"icd open /dev/ttyS0\").\n\ \tWithout options (and after the icd is enabled), it will print some\n\ \tinformation about the ICD.\n\ "); op = cmd_icd_options; } #include void cmd_icd::icd() { if(icd_detected()) { printf("ICD version \"%s\" was found.\n",icd_version()); printf("Target controller is %s.\n", icd_target()); printf("Vdd: %.1f\t",icd_vdd()); printf("Vpp: %.1f\n",icd_vpp()); if(icd_has_debug_module()) puts("Debug module is present"); else puts("Debug moudle is NOT present."); } else { printf("ICD has not been opened (use the \"icd open\" command)\n"); } } void cmd_icd::icd(cmd_options_str *cos) { switch(cos->co->value) { case ICD_OPEN_CMD: cout << "ICD open " << cos->str << endl; icd_connect(cos->str); break; default: cout << " Invalid set option\n"; } } gpsim-0.30.0/cli/cmd_run.cc0000664000076400007640000000266113041763642012364 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_run.h" #include "../src/pic-processor.h" extern void redisplay_prompt(void); // in input.cc cmd_run c_run; static cmd_options cmd_run_options[] = { {0,0,0} }; cmd_run::cmd_run() : command("run",0) { brief_doc = string("Initiate the simulation"); long_doc = string ("run\n\ \tStart simulating and don't stop until a break is encountered.\n\ \tUse CTRL->C to halt the simulation execution.\n\ \n"); op = cmd_run_options; } void cmd_run::run() { Integer &verbosity = *globalSymbolTable().findInteger("sim.verbosity"); get_interface().start_simulation(); if((int)verbosity) redisplay_prompt(); } gpsim-0.30.0/cli/cmd_trace.cc0000664000076400007640000000733513041763642012661 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_trace.h" //#include "../src/processor.h" #include "../src/trace.h" #include "../src/trace_orb.h" cmd_trace c_trace; #define TRACE_RAW_CMD 1 #define TRACE_MASK_CMD 2 #define TRACE_SAVE_CMD 3 #define TRACE_LOGON_CMD 4 #define TRACE_LOGOFF_CMD 5 #define TRACE_INFO_CMD 6 static cmd_options cmd_trace_options[] = { {"r", TRACE_RAW_CMD, OPT_TT_NUMERIC}, {"raw", TRACE_RAW_CMD, OPT_TT_NUMERIC}, {"mask", TRACE_MASK_CMD, OPT_TT_NUMERIC}, {"log", TRACE_LOGON_CMD, OPT_TT_STRING}, {"save", TRACE_SAVE_CMD, OPT_TT_STRING}, {"info", TRACE_INFO_CMD, OPT_TT_BITFLAG}, {"disable_log",TRACE_LOGOFF_CMD, OPT_TT_BITFLAG}, {0,0,0} }; cmd_trace::cmd_trace() : command("trace", "tr") { brief_doc = string("Dump the trace history"); long_doc = string ("\ntrace [dump_amount | raw | log fname | disable_log]\n" "\ttrace will print out the most recent \"dump_amount\" traces.\n" "\tIf no dump_amount is specified, then only the lat few trace\n" "\tevents will be displayed.\n\n" "\ttrace raw expr -- display the trace contents in a minimally decoded manner\n" "\ttrace log fname -- log all raw trace events to a file\n" "\ttrace save fname -- save the decode trace buffer to a file\n" "\ttrace disable_log -- stop all file logging\n" ); op = cmd_trace_options; } void cmd_trace::trace(void) { get_trace().dump(0,stdout); } void cmd_trace::trace(Expression *expr) { int n = (int)evaluate(expr); get_trace().dump(n,stdout); } void cmd_trace::trace(cmd_options *opt) { switch(opt->value) { case TRACE_LOGOFF_CMD: get_trace().disableLogging(); cout << "Logging to file disabled" << endl; break; case TRACE_INFO_CMD: get_trace().showInfo(); break; default: cout << " Invalid set option\n"; } } void cmd_trace::trace(cmd_options_expr *coe) { double dvalue = 0.0; if(coe->expr) dvalue = evaluate(coe->expr); int value = (int) dvalue; switch(coe->co->value) { case TRACE_RAW_CMD: get_trace().dump_raw(value); break; default: cout << " Invalid option\n"; } } void cmd_trace::trace(cmd_options_num *con) { switch(con->co->value) { case TRACE_RAW_CMD: get_trace().dump_raw(con->n); break; case TRACE_MASK_CMD: // trace_watch_register(con->n); cout << "THIS IS BROKEN.... logging register " << con->n << '\n'; break; default: cout << " Invalid trace option\n"; } } void cmd_trace::trace(cmd_options_str *cos) { switch(cos->co->value) { case TRACE_LOGON_CMD: get_trace().enableLogging(cos->str); break; case TRACE_SAVE_CMD: { FILE *fp = fopen(cos->str,"w"); if(fp) { get_trace().dump(-1,fp); fclose(fp); } } break; default: cout << " Invalid set option\n"; } } gpsim-0.30.0/cli/cmd_clear.h0000664000076400007640000000164113041763642012505 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_CLEAR_H__ #define __CMD_CLEAR_H__ class Expression; class cmd_clear : public command { public: cmd_clear(void); void clear(Expression *); }; extern cmd_clear clear; #endif gpsim-0.30.0/cli/cmd_processor.cc0000664000076400007640000001006213041763642013571 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_processor.h" #include "../src/sim_context.h" cmd_processor c_processor; static cmd_options cmd_processor_options[] = { {"list",1, OPT_TT_BITFLAG}, {"pins",2, OPT_TT_BITFLAG}, {0,0,0} }; static void put_chars(char c, int number_of_chars) { for(int i=0; iget_pin_count(); if(number_of_pins <= 0) return; for(i=1; i<=number_of_pins/2; i++) { const char *s = cpu->get_pin_name(i).c_str(); if(s) if( (j=strlen(s)) > longest_name) longest_name = j; } printf(" +--+"); put_chars('-',longest_name+3); printf("\\/"); put_chars('-',longest_name+3); printf("+--+\n"); for(i=1; i<=number_of_pins/2; i++) { const char *s = cpu->get_pin_name(i).c_str(); if(s) { putchar( (cpu->get_pin_state(i)>0) ? 'H' : 'L'); printf(" |%2d| %s",i, s); put_chars(' ',longest_name - strlen(cpu->get_pin_name(i).c_str()) + 6 ); } else { printf(" |%2d| ", i); put_chars(' ',longest_name + 6); } j = number_of_pins-i+1; s = cpu->get_pin_name(j).c_str(); if(s) { printf("%s |%2d| ", s, j); putchar( (cpu->get_pin_state(j)>0) ? 'H' : 'L'); putchar('\n'); } else { put_chars(' ',longest_name); printf(" |%2d|\n", j); } } printf(" +--+"); put_chars('-',2*longest_name+8); printf("+--+\n"); } cmd_processor::cmd_processor() : command("processor", "proc") { brief_doc = string("Select & Display processors"); long_doc = string ("processor [new_processor_type [new_processor_name]] | [list] | [dump]\n" "\tIf no new processor is specified, then the currently defined processor(s)\n" "\twill be displayed. To see a list of the processors supported by gpsim,\n" "\ttype 'processor list'. To define a new processor, specify the processor\n" "\ttype and name. To display the state of the I/O processor, type 'processor\n" "\tdump' (For now, this will display the pin numbers and their current state.\n" "\n" "\texamples:\n" "\n" "\tprocessor // Display the processors you've already defined.\n" "\tprocessor list // Display the list of processors supported.\n" "\tprocessor pins // Display the processor package and pin state\n" "\tprocessor p16cr84 fred // Create a new processor.\n" "\tprocessor p16c74 wilma // and another.\n" "\tprocessor p16c65 // Create one with no name.\n"); op = cmd_processor_options; } void cmd_processor::processor(void) { if(verbose) cout << "cmd_processor: display processors\n"; CSimulationContext::GetContext()->dump_processor_list(); } void cmd_processor::processor(int bit_flag) { switch(bit_flag) { case 1: cout << ProcessorConstructorList::GetList()->DisplayString(); break; case 2: dump_pins(GetActiveCPU()); break; } } void cmd_processor::processor(const char * processor_type, const char * processor_new_name) { if(!CSimulationContext::GetContext()->SetDefaultProcessor( processor_type, processor_new_name)) cout << "Unable to find processor " << processor_type << "\n"; } gpsim-0.30.0/cli/cmd_bus.cc0000664000076400007640000000357613041763642012357 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_bus.h" cmd_bus c_bus; //extern void dump_bus_list(void); //extern void add_bus(char *node_name); static cmd_options cmd_bus_options[] = { {0,0,0} }; cmd_bus::cmd_bus() : command("bus",0) { brief_doc = string("Add or display node busses"); long_doc = string ("bus [new_bus1 new_bus2 ...]\n" "\t If no new_bus is specified then all of the busses that have been\n" "\tdefined are displayed. If a new_bus is specified then it will be\n" "\tadded to the bus list. See the \"attach\" and \"stimulus\" commands\n" "\tto see how stimuli are added to the busses.\n" "\n" "\texamples:\n" "\n" "\tbus // display the bus list\n" "\tbus b1 b2 b3 // create and add 3 new busses to the list\n"); op = cmd_bus_options; } void cmd_bus::list_busses(void) { // dump_bus_list(); } void cmd_bus::add_busses(list * busses) { /* if(busses) { list :: iterator si; for (si = busses->begin(); si != busses->end(); ++si) { string s = *si; add_bus((char *)s.c_str()); } } */ } gpsim-0.30.0/cli/scan.h0000664000076400007640000000206513041763642011521 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // Portions of this were obtained from octave. #if !defined (__SCAN_H_) #define __SCAN_H_ int scan_read (char *buf, unsigned max_size); #ifdef YY_INPUT #undef YY_INPUT #endif #define YY_INPUT(buf,result,max_size) \ if ((result = scan_read (buf, max_size)) < 0) \ YY_FATAL_ERROR ("gpsim_read () in flex scanner failed"); #endif gpsim-0.30.0/cli/README0000664000076400007640000000253313041763642011304 00000000000000 gpsim - Gnu Pic Simulator, a simulator for Microchip's PIC microcontrollers. cli - Command Line Interface Obligatory GPL stuff: =========================================================================== Copyright (C) 1998,1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =========================================================================== gpsim/cli provides the command line interface for gpsim. As of gpsim-0.0.13, lex & yacc (or actually flex & bison) are used as the parser and the lexical analyzer. Together, these provide gpsim's grammar. The gnu readline library provides command line editing like you find in most terminal programs. This textual interface is very similar to gdb. Scottgpsim-0.30.0/cli/cmd_load.cc0000664000076400007640000001640713041763642012502 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_load.h" #include "input.h" #include "../src/sim_context.h" #include "../src/processor.h" #include "../src/fopen-path.h" #include "../src/hexutils.h" #include "../src/eeprom.h" #include "../src/pic-processor.h" #include "../src/i2c-ee.h" extern int parser_warnings; extern void redisplay_prompt(void); // in input.cc // instead of including the whole symbol.h file, just get what we need: void display_symbol_file_error(int); cmd_load c_load; #define CMD_LOAD_HEXFILE 1 #define CMD_LOAD_CMDFILE 2 #define CMD_LOAD_CODFILE 3 // s for Symbol file #define CMD_LOAD_INCLUDE_CMDFILE 4 // like load, but don't change directories. #define CMD_LOAD_EEPROM 5 static cmd_options cmd_load_options[] = { {"h",CMD_LOAD_HEXFILE, OPT_TT_BITFLAG}, {"c",CMD_LOAD_CMDFILE, OPT_TT_BITFLAG}, {"s",CMD_LOAD_CODFILE, OPT_TT_BITFLAG}, {"i",CMD_LOAD_INCLUDE_CMDFILE, OPT_TT_BITFLAG}, {"e",CMD_LOAD_EEPROM, OPT_TT_BITFLAG}, { 0,0,0} }; cmd_load::cmd_load() : command("load","ld") { brief_doc = string("Load either a program or command file"); long_doc = string (" load programfile.cod [label] \ \n load processortype programfile.hex [label] \ \n load [i] cmdfile.stc\ \n\n\tLoad either a program or command file. Program files may be in\ \n\thex or cod (symbol) file format, however, a cod file is required for\ \n\tfull Gpsim functionality.\ \n\t(Gputil .cod files are the only program files with symbols\ \n\tthat are supported.)\ \n\ \n\t processortype - Name of the processor type simulation for .hex file\ \n\t used. (e.g. p16f88)\ \n\t programfile - a hex or cod formatted file. Cod is often called\ \n\t a symbol file.\ \n\t label - optional field used to identify processor on\ \n\t breadboard and symbol table prefix.\ \n\t If not supplied processor type is used.\ \n\t cmdfile - a gpsim command file. Must have an .stc extension\ \n\t unless the 'i' option is used.\ \n\ \n\t By default, .stc files residing in other directories will change\ \n\t the working directory. The 'i' option overrides that behavior. \ \n\ \n load e module_name hexfile\ \n\ \n\t This command loads the contents of either a module or processor\ \n\t EEPROM from an Intel hex format file. The address of the first\ \n\t cell of the EEPROM is 0x0000. \ \n\t This command will load a file generated by the 'dump e' command and\ \n\t thus can be used to restore state of EEPROM from a previous run.\ \n\ \n\tdeprecated:\ \n\t load h | c | s file_name\ \n\t load s perfect_program.cod\ \n\t will load the symbol file perfect_program.cod\ \n\t note that the .cod file contains the hex stuff\ \n"); op = cmd_load_options; } //-------------------- // // #define MAX_LINE_LENGTH 256 extern void process_command_file(const char * file_name, bool bCanChangeDirectory); /** * cmd_load.load() * returns boolean */ int cmd_load::load(int bit_flag,const char *filename) { int iReturn = (int)TRUE; bool bCanChangeDirectories=true; switch(bit_flag){ case CMD_LOAD_HEXFILE: FILE *file; Processor *cpu; cout << "cmd_load::load hex file " << filename << '\n'; if ((cpu = get_active_cpu()) == NULL) { fprintf(stderr, "cmd_load:: load hex, Processor not defined\n"); iReturn = (int)FALSE; } else if ((file = fopen(filename, "r")) == NULL) { perror(filename); iReturn = (int)FALSE; } else { IntelHexProgramFileType::readihex16 (cpu, file); fclose(file); //cmd_cpu->regwin_eeprom->Update(); } break; case CMD_LOAD_CODFILE: if(verbose) { switch(bit_flag) { case CMD_LOAD_HEXFILE: cout << "cmd_load::load hex file " << filename << '\n'; break; case CMD_LOAD_CODFILE: cout << " cmd_load::load cod file " << filename << '\n'; break; } } iReturn = CSimulationContext::GetContext()->LoadProgram( filename); break; case CMD_LOAD_INCLUDE_CMDFILE: bCanChangeDirectories = false; // ... fall through case CMD_LOAD_CMDFILE: /* Don't display parser warnings will processing the command file */ parser_warnings = 0; process_command_file(filename,bCanChangeDirectories); parser_warnings = 1; break; default: cout << "Unknown option flag" << endl; iReturn = (int)FALSE; // as a boolean } // Most of the time diagnostic info will get printed while a processor // is being loaded. redisplay_prompt(); return iReturn; } int cmd_load::load(int bit_flag, gpsimObject* module, const char *filename) { Register ** fr=0; gint32 mem_size; char s1[256]; string symName; pic_processor *pic; I2C_EE *eeprom; FILE *fd; PromAddress *sym; int iReturn = (int)TRUE; module->name(s1, sizeof(s1)); symName = s1; symName += ".eeprom"; fprintf(stdout, "cmd_load module=%s file=%s\n", s1, filename); if (bit_flag != CMD_LOAD_EEPROM) { cout << "Unknown option flag with module, filename" << endl; return (int)FALSE; } if ((fd = fopen(filename, "r")) == NULL) { perror(filename); return (int)FALSE; } if (( pic = dynamic_cast (module)) && pic->eeprom) { fr = pic->eeprom->get_rom(); mem_size = pic->eeprom->get_rom_size(); iReturn = IntelHexProgramFileType::readihex8(fr, mem_size, fd, 0x0) == SUCCESS; } else if ((sym = dynamic_cast(globalSymbolTable().find(symName)))) { sym->get(eeprom); fr = eeprom->get_rom(); mem_size = eeprom->get_rom_size(); iReturn = IntelHexProgramFileType::readihex8(fr, mem_size, fd, 0x0000) == SUCCESS; } else { cout << "*** Error cmd_load module " << s1 << " not EEPROM" << endl; iReturn = (int)FALSE; } if (fd) fclose(fd); return iReturn; } //------------------------------------------------------------------------ // // load static int load1(const char *s1, const char *s2) { FILE *fp = fopen_path(s1,"rb"); if (fp) { fclose (fp); return gpsim_open(get_active_cpu(), s1, s2, 0); } if(!s2) // can be called s1=name s2=file perror(s1); return s2 ? gpsim_open(get_active_cpu(), s2, 0, s1) : 0; } int cmd_load::load(gpsimObject *file, gpsimObject *pProcessorType) { cout << endl; char s1[256]; file->toString(s1, sizeof(s1)); if (pProcessorType) { char s2[256]; pProcessorType->toString(s2, sizeof(s2)); return load1(s1, s2); } return load1(s1,0); } int cmd_load::load(const char *file, const char *pProcessorType) { return load1 (file, pProcessorType); } gpsim-0.30.0/cli/cmd_version.cc0000664000076400007640000000227213041763642013243 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_version.h" cmd_version version; extern void gpsim_version(void); static cmd_options cmd_version_options[] = { {0,0,0} }; cmd_version::cmd_version() : command("version", "ver") { brief_doc = string("Display the gpsim's version"); long_doc = string("Display the gpsim's version"); op = cmd_version_options; } void cmd_version::version() { gpsim_version(); } gpsim-0.30.0/cli/INSTALL0000664000076400007640000000027113041763642011452 00000000000000 Installation instructions: NONE. The higher level subdirectory will invoke the make file in the cli subdirectory. The make file creates a library against which the simulator may link.gpsim-0.30.0/cli/cmd_list.cc0000664000076400007640000000454013041763642012531 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_list.h" #include "../src/pic-processor.h" cmd_list c_list; static cmd_options cmd_list_options[] = { {"l",1, OPT_TT_BITFLAG}, {"s",2, OPT_TT_BITFLAG}, { 0,0,0} }; cmd_list::cmd_list() : command("list",0) { brief_doc = string("Display source and list files"); long_doc = string("list [[s | l] [*pc] [line_number1 [,line_number2]]]\n" "\n" "\tDisplay the contents of source and list files.\n" "\tWithout any options, list will use the last specified options.\n" "\tlist s will display lines in the source (or .asm) file.\n" "\tlist l will display lines in the .lst file\n" "\tlist *pc will display either .asm or .lst lines around the\n" "\t value specified by pc (e.g. list *20 will list lines around\n" "\t address 20)\n" "\tline_number1, line_number2 - specify the list range.\n" "\n" "\tExamples:\n" "\tlist s *0x3a -5 5\n" "\t will list 11 lines (5 before, 5 after, & 1 at) around addr 3a\n" "\tlist\n" "\t repeat the last list except use the current pc as the reference.\n" "\tlist l\n" "\t will list lines from .lst file around the current pc.\n"); op = cmd_list_options; file_id = 0; starting_line = -5; ending_line = +5; } void cmd_list::list(void) { Processor *pCpu = GetActiveCPU(true); if(pCpu) pCpu->list(file_id,pCpu->pc->value,starting_line,ending_line); } void cmd_list::list(cmd_options *opt) { switch(opt->value) { case 1: file_id = 1; break; case 2: file_id = 0; break; } list(); } gpsim-0.30.0/cli/command.h0000664000076400007640000000562213041763642012215 00000000000000/* Copyright (C) 1998,199 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined (__COMMAND_H_) #define __COMMAND_H_ #include #include using namespace std; #include #include #include "misc.h" #include "../src/errors.h" #include "../src/expr.h" #include "../src/gpsim_def.h" class Processor; enum COMMAND_MODES { NO_COMMAND, COMMAND_PENDING, COMMAND_ERROR }; // Token types for command options #define OPT_TT_BITFLAG 1 // #define OPT_TT_NUMERIC 2 // indicates that a numeric parameter // is associated with the option #define OPT_TT_STRING 3 // indicates that a string parameter // is associated with the option #define OPT_TT_SUBTYPE 4 // indicates that this command can // be subtyped (e.g. the stimulus command // is subtyped by the type of stimulus // that is being created). #define OPT_TT_SYMBOL 5 // A symbol is the option parameter class command { public: struct cmd_options *op; string brief_doc; string long_doc; int token_value; virtual bool can_span_lines() {return 0;}; command(const char *_name, const char *_abbr); virtual ~command() {} struct cmd_options *get_op() { return op; }; const char *name() { return m_pName; } const char *abbreviation() { return m_pAbbreviation; } static Processor * GetActiveCPU(bool bDisplayWarnings=false); int get_token() {return token_value;}; // Assume command is not repeatable virtual int is_repeatable() { return 0; }; virtual double evaluate(Expression *); virtual void evaluate(ExprList_t *eList,guint64 *, int *); virtual Value *toValue(Expression *expr); private: const char *m_pName; const char *m_pAbbreviation; }; class cmd_options_expr { public: cmd_options_expr(cmd_options *, Expression *); ~cmd_options_expr(); cmd_options *co; Expression *expr; }; extern command *command_list[]; extern int number_of_commands; extern command *search_commands(const string &s); extern int quit_gpsim; extern void execute_line(char *); #define DEBUG_PARSER 0 //======================================== // typedefs typedef list StringList_t; #endif gpsim-0.30.0/cli/input.h0000664000076400007640000000247313041763642011737 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __INPUT_H__ #define __INPUT_H__ #define CONTINUING_LINE 1 extern int gpsim_read (char *buf, unsigned max_size); extern void initialize_readline (void); extern void exit_cli(void); extern void exit_gpsim(int); extern void SetLastFullCommand(const char *pCmd); extern const char * GetLastFullCommand(); extern void EnableSTCEcho(bool bEnable); #ifndef HAVE_GUI extern char *gnu_readline (char *s, unsigned int force_readline); #endif class Processor; extern int gpsim_open(Processor *cpu, const char *file, const char *pProcessorType, const char *pProcessorName); #endif gpsim-0.30.0/cli/cmd_frequency.cc0000664000076400007640000000376213041763642013564 00000000000000/* Copyright (C) 2001 Salvador E. Tropea This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "cmd_frequency.h" #include "../src/pic-processor.h" static cmd_options cmd_frequency_options[] = { {0,0,0} }; cmd_frequency::cmd_frequency(void) : command("frequency", "freq") { brief_doc = string("Set the clock frequency"); long_doc = string ("\nfrequency [value]\n" "\tThis command sets the clock frequency. By default gpsim uses 4 MHz\n" "\tas clock. The clock frequency is used to compute time in seconds.\n" "\tUse this command to adjust this value.\n" "\tIf no value is provided this command prints the current clock.\n" "\tNote that PICs have an instruction clock that's a forth of the\n" "\texternal clock. This value is the external clock.\n"); op = cmd_frequency_options; } void cmd_frequency::set(Expression *expr) { Processor *pCpu = GetActiveCPU(true); if(!pCpu) return; double frequency = evaluate(expr); if(frequency <= 0.0) cout << "Error: the clock must be a positive value.\n"; else pCpu->set_frequency(frequency); } void cmd_frequency::print() { Processor *pCpu = GetActiveCPU(true); if(pCpu) cout << "Clock frequency: " << pCpu->get_frequency()/1e6 << " MHz.\n"; } cmd_frequency frequency; gpsim-0.30.0/cli/cmd_run.h0000664000076400007640000000166613041763642012232 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_RUN_H__ #define __CMD_RUN_H__ class cmd_run : public command { public: cmd_run(); void run(); virtual int is_repeatable() { return 1; }; }; extern cmd_run c_run; extern bool GbDoRun; #endif gpsim-0.30.0/cli/cmd_echo.cc0000664000076400007640000000222613041763642012473 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_echo.h" // See cmd_echo.h for why this file is basically a skeleton cmd_echo echo; static cmd_options cmd_echo_options[] = { {0,0,0} }; cmd_echo::cmd_echo() : command("echo",0) { brief_doc = string("echo \"text\""); long_doc = string ("echo \"text\" - useful for command files\n"); token_value = 0; op = cmd_echo_options; } gpsim-0.30.0/cli/misc.h0000664000076400007640000000227613041763642011534 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __MISC_H__ #define __MISC_H__ #include "../src/cmd_gpsim.h" // miscellaneous definitions that are used struct cmd_options { const char *name; int value; int token_type; }; /* Command option with a numeric parameter */ struct cmd_options_num { cmd_options *co; int n; }; /* Command option with a string parameter */ class cmd_options_str { public: cmd_options *co; char *str; cmd_options_str(const char *); ~cmd_options_str(); }; #endif gpsim-0.30.0/cli/cmd_symbol.h0000664000076400007640000000230213041763642012717 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_SYMBOL_H__ #define __CMD_SYMBOL_H__ class Expression; class gpsimObject; class cmd_symbol : public command { public: cmd_symbol(); void dump_all(); void dump_one(const char *sym_name); void dump_one(gpsimObject *); void dump(gpsimObject *, ExprList_t*); void EvaluateAndDisplay(Expression *pExpr); void Set(gpsimObject *s, ExprList_t*e, Expression *pExpr); void add_one(const char *sym_name, Expression *); }; extern cmd_symbol c_symbol; #endif gpsim-0.30.0/cli/cmd_help.h0000664000076400007640000000177213041763642012354 00000000000000/* Copyright (C) 1998,199 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_HELP_H__ #define __CMD_HELP_H__ class gpsimObject; class cmd_help : public command { public: cmd_help(); void help(); void help(const char *cmd); void help(gpsimObject *); virtual int is_repeatable() { return 1; }; }; extern cmd_help help; #endif gpsim-0.30.0/cli/makefile.mingw0000664000076400007640000000352013041763642013241 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw TOP = ../.. include ../plat/win32/make.mingw ################################################################ # Nothing much configurable below INCLUDES = -I ../.. -I ../plat/win32 \ -I $(GLIB_PATH)/include/glib-2.0 -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GTK_PATH)/include/gtk-2.0 -I $(GTK_PATH)/lib/gtk-2.0/include \ -I $(CAIRO_PATH)/include/cairo \ -I $(GDK_PIXBUF_PATH)/include/gdk-pixbuf-2.0 \ -I $(PANGO_PATH)/include/pango-1.0 \ -I $(READLINE_PATH)/include DEFINES += -DHAVE_READLINE -DHAVE_GUI -DHAVE_NSCLEAN_READLINE -DUSE_READLINE_DLL -DYYSTACK_USE_ALLOCA -DHAVE_SOCKETS # -DREADLINE_STATIC all : \ ../config.h \ libcli.a cli_OBJECTS = \ cmd_attach.o \ cmd_break.o \ cmd_bus.o \ cmd_clear.o \ cmd_disasm.o \ cmd_dump.o \ cmd_echo.o \ cmd_frequency.o \ cmd_help.o \ cmd_icd.o \ cmd_list.o \ cmd_load.o \ cmd_log.o \ cmd_macro.o \ cmd_module.o \ cmd_node.o \ cmd_processor.o \ cmd_quit.o \ cmd_reset.o \ cmd_run.o \ cmd_set.o \ cmd_shell.o \ cmd_step.o \ cmd_stimulus.o \ cmd_symbol.o \ cmd_trace.o \ cmd_version.o \ cmd_x.o \ command.o \ fd2raw.o \ input.o \ parse.o \ scan.o \ socket.o \ ui_gpsim.o ../config.h : ../config_win32.h.in (cd .. ; $(AWK) -f plat/win32/configure_win32.awk config_win32.h.in > config.h) fd2raw.o : ../plat/win32/fd2raw.cpp $(CXX) $(CFLAGS) -c -o fd2raw.o ../plat/win32/fd2raw.cpp parse.o : parse.cc scan.o : scan.cc parse.h parse.cc : parse.yy $(BISON) -dt -o parse.cc parse.yy $(RM) -f parse.h $(MV) parse.hh parse.h scan.cc : scan.ll parse.h $(FLEX) -oscan.cc scan.ll ################ The libcli LIB libcli.a : $(cli_OBJECTS) $(RM) -f $@ $(AR) $(ARFLAGS) $@ $(cli_OBJECTS) gpsim-0.30.0/cli/cmd_list.h0000664000076400007640000000200113041763642012361 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_LIST_H__ #define __CMD_LIST_H__ class cmd_list : public command { public: int file_id, starting_line, ending_line; cmd_list(void); void list(void); void list(cmd_options *opt); virtual int is_repeatable(void) { return 1; }; }; extern cmd_list c_list; #endif gpsim-0.30.0/cli/cmd_stimulus.cc0000664000076400007640000002757713114436304013453 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "cmd_stimulus.h" #include "../src/pic-processor.h" #include "../src/stimuli.h" #include "../src/symbol.h" static ValueStimulus *last_stimulus=0; cmd_stimulus c_stimulus; #define ASYNCHRONOUS_STIMULUS 1 #define SYNCHRONOUS_STIMULUS 2 #define STIM_NOTHING 0 #define STIM_PERIOD (1 << 0) #define STIM_PHASE (1 << 1) #define STIM_HIGH_TIME (1 << 2) #define STIM_INITIAL_STATE (1 << 3) #define STIM_START_CYCLE (1 << 4) #define STIM_DATA (1 << 5) #define STIM_ASY (1 << 7) #define STIM_SQW (1 << 8) #define STIM_NAME (1 << 9) #define STIM_TRI (1 << 10) #define STIM_ATTRIBUTE (1 << 11) #define STIM_ANALOG (1 << 12) #define STIM_DIGITAL (1 << 13) #define STIM_DUMP (1 << 14) const unsigned int SQW_OPTIONS = STIM_SQW | STIM_PERIOD | STIM_PHASE | STIM_HIGH_TIME | STIM_START_CYCLE; const unsigned int ASY_OPTIONS = STIM_ASY | STIM_PERIOD | STIM_PHASE | STIM_HIGH_TIME | STIM_START_CYCLE | STIM_DATA; const unsigned int TRI_OPTIONS = STIM_TRI | STIM_PERIOD | STIM_PHASE | STIM_HIGH_TIME | STIM_START_CYCLE; const unsigned int ATTR_OPTIONS = STIM_ATTRIBUTE | STIM_PERIOD | STIM_PHASE | STIM_HIGH_TIME | STIM_START_CYCLE | STIM_DATA; static cmd_options cmd_stimulus_options[] = { {"asy", STIM_ASY, OPT_TT_SUBTYPE}, {"asynchronous_stimulus", STIM_ASY, OPT_TT_SUBTYPE}, {"attr", STIM_ATTRIBUTE, OPT_TT_SUBTYPE}, {"attribute_stimulus", STIM_ATTRIBUTE, OPT_TT_SUBTYPE}, {"period", STIM_PERIOD, OPT_TT_NUMERIC}, {"phase", STIM_PHASE, OPT_TT_NUMERIC}, {"high_time", STIM_HIGH_TIME, OPT_TT_NUMERIC}, {"initial_state", STIM_INITIAL_STATE, OPT_TT_NUMERIC}, {"start_cycle", STIM_START_CYCLE, OPT_TT_NUMERIC}, {"start", STIM_START_CYCLE, OPT_TT_NUMERIC}, {"name", STIM_NAME, OPT_TT_STRING}, {"digital", STIM_DIGITAL, OPT_TT_BITFLAG}, {"analog", STIM_ANALOG, OPT_TT_BITFLAG}, {"d", STIM_DUMP, OPT_TT_BITFLAG}, {"dump", STIM_DUMP, OPT_TT_BITFLAG}, {"sqw", STIM_SQW, OPT_TT_SUBTYPE}, {"square_wave", STIM_SQW, OPT_TT_SUBTYPE}, {"tri", STIM_TRI, OPT_TT_SUBTYPE}, {"triangle_wave", STIM_TRI, OPT_TT_SUBTYPE}, { 0,0,0} }; cmd_stimulus::cmd_stimulus() : command("stimulus","stim") { brief_doc = string("Create a stimulus"); long_doc = string ("\nstimulus [[type] options]\n" "\tstimulus will create a signal that can be tied to a node or an\n" "\attribute. Note that in most cases it is easier to create a\n" "\tstimulus file then to type this by hand.\n" "\n" "\t Supported stimuli:\n" "\n" //"\tsquare_wave | sqw [period p] [high_time h] [phase ph] [initial_state i]\n" //"\t port port_name bit_pos end\n" //"\t\t creates a square wave with a period of \"p\" cpu cycles.\n" //"\t\t If the high time is specified then that's the number of cycles\n" //"\t\t the square wave will be high.\n" //"\t\t The phase is with respect to the cpu's cycle counter.\n" //"\t\t The \"port_name\" and \"bit_pos\" describe where the stimulus\n" //"\t\t will be attached.\n" "\tasynchronous_stimulus | asy [period p] [phase ph] [initial_state i]\n" "\t { c0,e0 [,c1, e1, c2, e2, ... ,cn,en] } [name stim_name] end\n" "\t\t creates an asynchronous square wave with a period of \"p\" cpu\n" "\t\t cycles. The phase is with respect to the cpu's cycle counter.\n" "\t\t The data is specified as a pair of expressions. The first expression\n" "\t\t is for the cycle time and the second is the data. " "\n" "\texamples:\n" "\n" //"\t stimulus sqw period 200 high_time 20 phase 60 port portb 0 end\n" //"\t create a square wave stimulus that repeats every 200 cpu cycles,\n" //"\t is high for 20 cpu cycles (and low for 200-20=180 cycles). The\n" //"\t first rising edge will occur at cycle\n" //"\t 60, the second at 260, . . . Bit 0 of portb will receive the stimulus.\n" "\t # define a stimulus to generate two pulses every 1000 cycles\n" "\t \n" "\t stimulus asynchronous_stimulus \n" "\t \n" "\t # The initial state AND the state the stimulus is when\n" "\t # it rolls over\n" "\t \n" "\t initial_state 0\n" "\t start_cycle 0\n" "\t \n" "\t # the asynchronous stimulus will roll over in 'period'\n" "\t # cycles. Delete this line if you don't want a roll over.\n" "\t \n" "\t period 1000\n" "\t \n" "\t { 100, 1,\n" "\t 200, 0,\n" "\t 300, 1,\n" "\t 400, 0\n" "\t }\n" "\t \n" "\t # Give the stimulus a name:\n" "\t \n" "\t name two_pulse_repeat\n" "\t \n" "\t end\n" "\n"); op = cmd_stimulus_options; options_entered = 0; } static string table_name; void dumpStimulus(const SymbolEntry_t &sym) { stimulus *ps = dynamic_cast(sym.second); if (ps) { cout << table_name << "."; cout << ps->name(); ps->show(); cout << endl; } } void dumpStimuli(const SymbolTableEntry_t &st) { cout << " Symbol Table: " << st.first << endl; table_name = st.first; (st.second)->ForEachSymbolTable(dumpStimulus); } void cmd_stimulus::stimulus() { cout << "\nSymbol table\n"; globalSymbolTable().ForEachModule(dumpStimuli); } //------------------------------------------------------------------ // stimulus(int bit_flag) // // For the bit_flags of SQW, ASY, TRI: // A new stimulus is dynamically created and a pointer to it is // is assigned to 'last_stimulus'. The last_stimulus also acts like // a flag. If it is non-null then a stimulus is in the process of // being created. When the stimulus 'end' option is specified at the // cli, then 'last_stimulus' is set to NULL. Note the memory for // used by the last stimulus is created here, but destroyed by the // stimulus code in ../src/stimuli.cc . // void cmd_stimulus::stimulus(int bit_flag) { switch(bit_flag) { case STIM_SQW: if(verbose) cout << "creating sqw stimulus\n"; if(!last_stimulus) { //create_stimulus(NEW_SQW,stim_name); valid_options = SQW_OPTIONS; options_entered = STIM_SQW; //last_stimulus = new square_wave; } else cout << "warning: ignoring sqw stim creation"; break; case STIM_ASY: if(verbose) cout << "creating asy stimulus\n"; if(!last_stimulus) { //create_stimulus(NEW_ASY,stim_name); last_stimulus = new ValueStimulus; valid_options = ASY_OPTIONS; options_entered = STIM_ASY; }else cout << "warning: ignoring asy stim creation"; break; case STIM_ATTRIBUTE: if(verbose) cout << "creating asy stimulus\n"; if(!last_stimulus) { last_stimulus = new AttributeStimulus; valid_options = ATTR_OPTIONS; options_entered = STIM_ATTRIBUTE; }else cout << "warning: ignoring asy stim creation"; break; case STIM_TRI: if(verbose) cout << "creating tri stimulus\n"; if(!last_stimulus) { //create_stimulus(NEW_TRI,stim_name); //last_stimulus = new triangle_wave; valid_options = TRI_OPTIONS; options_entered = STIM_TRI; } else cout << "warning: ignoring tri stim creation"; break; case STIM_DUMP: stimulus(); // Display the list of stimuli. return; case STIM_DIGITAL: if(last_stimulus) last_stimulus->set_digital(); return; case STIM_ANALOG: if(last_stimulus) last_stimulus->set_analog(); return; default: cout << " Invalid stimulus option\n"; return; } } void cmd_stimulus::stimulus(cmd_options_expr *coe) { /* double dvalue = 0.0; if(coe->expr) dvalue = evaluate(coe->expr); int value = (int) dvalue; */ if (!coe || !coe->expr) return; Value *value = toValue(coe->expr); switch(coe->co->value) { case STIM_PHASE: if(verbose) cout << "stimulus command got the phase " << value << '\n'; if(last_stimulus) last_stimulus->put_phase(value); break; case STIM_PERIOD: if(verbose) cout << "stimulus command got the period " << value << '\n'; if(last_stimulus) last_stimulus->put_period(value); break; case STIM_HIGH_TIME: if(verbose) cout << "stimulus command got the high_time " << value << '\n'; if(last_stimulus) last_stimulus->put_duty(value); break; case STIM_INITIAL_STATE: if(verbose) cout << "stimulus command got the initial_state " << value << '\n'; if(last_stimulus) last_stimulus->put_initial_state(value); break; case STIM_START_CYCLE: if(verbose) cout << "stimulus command got the start_cycle " << value << '\n'; if(last_stimulus) last_stimulus->put_start_cycle(value); break; default: cout << " Invalid stimulus option\n"; return; } options_entered |= coe->co->value; delete coe->expr; delete value; } void cmd_stimulus::stimulus(cmd_options_str *cos) { if(!last_stimulus) { cout << "warning: Ignoring stimulus (string) option because there's no stimulus defined.\n"; return; } switch(cos->co->value) { case STIM_NAME: if(verbose) cout << "stimulus command got the name " << cos->str << '\n'; last_stimulus->new_name(cos->str); break; } options_entered |= cos->co->value; } void cmd_stimulus::stimulus(ExprList_t *eList) { ExprList_itor ei; bool bHaveSample=false; ValueStimulusData sample; sample.time = 0; sample.v = 0; if(last_stimulus) { for(ei = eList->begin(); ei != eList->end(); ++ei) { try { Value *v = (*ei)->evaluate(); if(!bHaveSample) { v->get(sample.time); delete v; bHaveSample = true; } else { sample.v = v; last_stimulus->put_data(sample); bHaveSample = false; have_data = 1; } } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } } } eList->clear(); delete eList; } //----------------- // end() // All of the stimulus' options have been entered. Now it's time // to create the stimulus. void cmd_stimulus::end() { if(!last_stimulus) { cout << "warning: Ignoring stimulus (string) option because there's no stimulus defined."; return; } switch( options_entered & (STIM_SQW | STIM_TRI | STIM_ASY | STIM_ATTRIBUTE)) { case STIM_SQW: if(verbose) cout << "created sqw stimulus\n"; break; case STIM_ASY: if(verbose) cout << "created asy stimulus\n"; last_stimulus->start(); break; case STIM_ATTRIBUTE: if(verbose) cout << "created attribute stimulus\n"; last_stimulus->start(); break; case STIM_TRI: if(verbose) cout << "creating tri stimulus\n"; break; } last_stimulus = 0; } gpsim-0.30.0/cli/cmd_help.cc0000664000076400007640000000440113041763642012502 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_help.h" #include "../src/value.h" static cmd_options cmd_help_options[] = { { 0, 0, 0 } }; cmd_help help; cmd_help::cmd_help() : command("help",0) { brief_doc = string("Type help \"command\" for more help on a command"); long_doc = string ("\n\tgpsim is a software simulator for the Microchip PIC microcontrollers\n\ \tPlease refer to the distributed README files and the ./doc subdirectory\n\ \tfor more information\n\ \n\tTo get help on a command, type help \"command\"\n\ \n\tIn addition, help on most symbols can be obtained by help\"symbol name\"\n\ \n\t(Use the symbol command to see the currently defined symbols\n\ " ); op = cmd_help_options; } void cmd_help::help(void) { for(int i=0; iname(); int l = 16 - strlen(pCmd->name()); if(pCmd->abbreviation() != 0) { cout << ":" << pCmd->abbreviation(); l -= strlen(pCmd->abbreviation()) + 1; } for(int k=0; kbrief_doc << '\n'; } } void cmd_help::help(const char *cmd) { command * pCmd = search_commands(cmd); if(pCmd != 0) { cout << pCmd->long_doc << '\n'; return; } cout << cmd << " is not a valid gpsim command. Try these instead:\n"; help(); } void cmd_help::help(gpsimObject *s) { if(s) { cout << s->toString() << endl; cout << s->description() << endl; } } gpsim-0.30.0/cli/cmd_reset.h0000664000076400007640000000161013041763642012535 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_RESET_H__ #define __CMD_RESET_H__ class cmd_reset : public command { public: cmd_reset(void); void reset(void); }; extern cmd_reset reset; #endif gpsim-0.30.0/cli/cmd_disasm.cc0000664000076400007640000000544213041763642013040 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_disasm.h" #include "../src/pic-processor.h" cmd_disassemble disassemble; static cmd_options cmd_disassemble_options[] = { {0,0,0} }; cmd_disassemble::cmd_disassemble() : command("disassemble", "da") { brief_doc = string("Disassemble the current cpu"); long_doc = string ("\ndisassemble [startCount : endCount] | [count]]\n\n\ \t startCount, endCount and count may all be expressions that evaluate\n\ \t to an integer value. The colon is used to indicate a range.\n\n\ \t startCount - Start list with the instruction startCount from the \n\ \t instruction at the PC.\n\ \t endCount - List instruction in the list is the endCount\n\ \t instruction from the PC.\n\ \t count - List count instructions from starting with the\n\ \t instruction at thePC.\n\n\ \t no arguments: disassembles 10 instructions before and 5 after the pc.\n\ \t one argument: disassemble [count] instructions after the pc.\n\ \t two arguments: disassemble from [startCount] to [endCount] relative\n\ \t to the PC.\n\ "); op = cmd_disassemble_options; } void cmd_disassemble::disassemble(Expression *expr) { Processor *cpu = GetActiveCPU(); if(cpu) { // Select a default range: int start = -10; int end = 5; if(expr) { try { Value *v = expr->evaluate(); AbstractRange *ar = dynamic_cast(v); if(ar) { start = ar->get_leftVal(); end = ar->get_rightVal(); } else if (v) { start = 0; gint64 i; v->get(i); end = (int) i; } } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } } if(cpu->pma) { int current_pc = cpu->pma->get_PC(); if(start<0) { start += current_pc; end += current_pc; } cout << hex << " current pc = 0x"<disassemble(start, end); } } } gpsim-0.30.0/cli/cmd_module.h0000664000076400007640000000221513041763642012702 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_MODULE_H__ #define __CMD_MODULE_H__ #include using namespace std; #include "command.h" class cmd_module : public command { public: cmd_module(void); void module(void); void module(cmd_options *opt); void module(cmd_options_str *cos, list *); private: void module(cmd_options_str *cos); void module(cmd_options_str *cos, const char *op1); }; extern cmd_module c_module; #endif gpsim-0.30.0/cli/scan.cc0000664000076400007640000024230513114656215011660 00000000000000 #line 3 "scan.cc" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 0 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ yy_size_t yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); #if defined(__GNUC__) && __GNUC__ >= 3 __attribute__((__noreturn__)) #endif static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 61 #define YY_END_OF_BUFFER 62 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[174] = { 0, 0, 0, 0, 0, 0, 0, 62, 60, 3, 4, 11, 60, 1, 60, 18, 60, 15, 13, 14, 59, 16, 32, 32, 10, 24, 7, 25, 59, 59, 59, 28, 60, 29, 17, 59, 59, 59, 59, 59, 59, 59, 19, 12, 11, 49, 48, 47, 49, 49, 61, 50, 61, 55, 55, 55, 55, 55, 3, 23, 0, 44, 1, 35, 8, 0, 44, 59, 59, 36, 36, 32, 0, 0, 0, 20, 26, 22, 27, 21, 0, 0, 0, 0, 59, 59, 59, 59, 59, 59, 0, 59, 59, 9, 43, 23, 0, 0, 0, 55, 55, 55, 55, 55, 55, 59, 59, 36, 30, 0, 36, 34, 0, 0, 0, 45, 0, 45, 59, 59, 58, 59, 40, 59, 5, 39, 59, 59, 0, 55, 55, 55, 51, 0, 59, 36, 31, 33, 59, 59, 58, 42, 59, 41, 59, 37, 46, 53, 54, 55, 36, 59, 0, 57, 0, 38, 59, 52, 59, 0, 56, 0, 2, 59, 56, 59, 59, 59, 59, 59, 59, 59, 6, 0 } ; static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 7, 8, 1, 9, 10, 1, 1, 11, 12, 1, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 1, 20, 21, 22, 1, 1, 23, 24, 23, 25, 26, 23, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 27, 27, 29, 30, 31, 32, 33, 1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 27, 27, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 27, 53, 28, 27, 27, 1, 54, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst YY_CHAR yy_meta[56] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 4, 5, 5, 5, 1, 1, 1, 1, 6, 6, 6, 6, 4, 4, 1, 1, 1, 1, 4, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 } ; static yyconst flex_uint16_t yy_base[188] = { 0, 0, 464, 53, 56, 94, 0, 468, 470, 465, 470, 445, 459, 0, 0, 455, 149, 470, 470, 470, 45, 0, 191, 50, 470, 49, 442, 50, 0, 452, 451, 470, 67, 470, 470, 425, 29, 425, 36, 456, 419, 407, 401, 470, 433, 470, 470, 470, 204, 408, 470, 470, 0, 0, 406, 410, 407, 404, 446, 470, 441, 440, 0, 0, 470, 435, 434, 242, 0, 195, 240, 265, 63, 73, 0, 470, 470, 470, 470, 470, 67, 206, 437, 432, 395, 399, 402, 395, 392, 387, 90, 174, 383, 470, 0, 0, 229, 389, 396, 0, 0, 386, 397, 384, 378, 303, 222, 301, 220, 252, 268, 0, 277, 282, 422, 411, 401, 393, 348, 344, 216, 334, 0, 321, 470, 0, 314, 318, 311, 311, 304, 318, 0, 312, 324, 327, 470, 470, 286, 344, 334, 0, 293, 0, 267, 0, 470, 0, 0, 255, 333, 268, 272, 470, 292, 0, 235, 0, 219, 285, 470, 317, 0, 208, 470, 195, 199, 186, 194, 165, 106, 28, 0, 470, 358, 364, 370, 372, 376, 382, 385, 389, 395, 401, 403, 409, 415, 421 } ; static yyconst flex_int16_t yy_def[188] = { 0, 173, 1, 174, 174, 173, 5, 173, 173, 173, 173, 173, 175, 176, 177, 173, 173, 173, 173, 173, 178, 178, 173, 173, 173, 173, 173, 173, 178, 178, 178, 173, 173, 173, 173, 178, 178, 178, 178, 178, 178, 178, 173, 173, 179, 173, 173, 173, 173, 173, 173, 173, 180, 181, 181, 181, 181, 181, 173, 173, 175, 175, 176, 177, 173, 182, 182, 183, 178, 178, 173, 173, 173, 173, 184, 173, 173, 173, 173, 173, 173, 173, 185, 186, 178, 178, 178, 178, 178, 178, 173, 178, 178, 173, 179, 179, 173, 173, 173, 181, 181, 181, 181, 181, 181, 183, 178, 173, 173, 173, 173, 184, 173, 173, 185, 185, 186, 186, 178, 178, 178, 178, 178, 178, 173, 178, 178, 178, 173, 181, 181, 181, 181, 173, 178, 178, 173, 173, 178, 178, 173, 178, 178, 178, 178, 178, 173, 181, 181, 181, 173, 178, 187, 173, 173, 178, 178, 181, 178, 187, 173, 187, 178, 178, 173, 178, 178, 178, 178, 178, 178, 178, 178, 0, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173 } ; static yyconst flex_uint16_t yy_nxt[526] = { 0, 8, 9, 10, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 28, 28, 28, 31, 32, 33, 34, 28, 35, 29, 28, 30, 36, 37, 28, 28, 28, 28, 28, 28, 28, 38, 39, 40, 28, 41, 28, 28, 42, 43, 46, 47, 48, 46, 47, 69, 69, 69, 70, 85, 71, 71, 71, 75, 76, 78, 79, 82, 86, 73, 73, 83, 88, 108, 108, 172, 89, 112, 112, 109, 109, 73, 73, 110, 110, 110, 90, 124, 49, 50, 50, 51, 50, 50, 50, 50, 50, 50, 52, 50, 50, 50, 53, 53, 50, 50, 50, 50, 50, 50, 50, 53, 53, 53, 53, 53, 53, 50, 50, 50, 50, 53, 53, 54, 55, 53, 53, 56, 53, 53, 57, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 50, 50, 65, 65, 171, 65, 65, 65, 65, 65, 65, 66, 65, 65, 65, 67, 67, 65, 65, 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 65, 65, 65, 65, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 65, 65, 70, 96, 71, 71, 71, 170, 69, 69, 69, 125, 72, 73, 73, 140, 74, 106, 106, 113, 113, 113, 126, 72, 169, 73, 73, 168, 96, 106, 106, 133, 134, 108, 108, 135, 135, 135, 167, 97, 65, 65, 166, 65, 65, 65, 65, 65, 65, 66, 65, 65, 165, 107, 107, 107, 163, 141, 65, 65, 65, 65, 73, 73, 97, 110, 110, 110, 65, 65, 65, 65, 160, 161, 73, 73, 70, 162, 71, 71, 71, 110, 110, 110, 136, 160, 161, 73, 73, 137, 112, 112, 153, 65, 65, 113, 113, 113, 158, 73, 73, 65, 65, 157, 65, 65, 65, 65, 65, 65, 66, 65, 65, 156, 107, 107, 107, 164, 161, 65, 65, 65, 65, 73, 73, 150, 150, 150, 155, 65, 65, 65, 65, 140, 151, 73, 73, 135, 135, 135, 135, 135, 135, 152, 153, 154, 150, 150, 150, 149, 148, 147, 146, 145, 65, 65, 45, 45, 45, 45, 45, 45, 60, 144, 60, 60, 60, 60, 62, 143, 62, 62, 62, 62, 63, 63, 68, 68, 68, 68, 94, 142, 94, 94, 94, 94, 99, 139, 99, 100, 100, 100, 100, 65, 138, 65, 65, 65, 65, 105, 117, 105, 105, 105, 105, 111, 111, 114, 117, 114, 114, 114, 114, 116, 115, 116, 116, 116, 116, 159, 159, 159, 159, 159, 159, 115, 132, 131, 130, 129, 128, 98, 127, 123, 122, 121, 120, 119, 118, 117, 115, 66, 66, 61, 61, 58, 104, 103, 102, 101, 98, 95, 93, 92, 91, 90, 87, 84, 81, 80, 77, 64, 61, 59, 58, 173, 44, 7, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173 } ; static yyconst flex_int16_t yy_chk[526] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 20, 20, 20, 23, 36, 23, 23, 23, 25, 25, 27, 27, 32, 36, 23, 23, 32, 38, 72, 72, 171, 38, 80, 80, 73, 73, 23, 23, 73, 73, 73, 90, 90, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 16, 16, 170, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 22, 48, 22, 22, 22, 169, 69, 69, 69, 91, 22, 22, 22, 120, 22, 69, 69, 81, 81, 81, 91, 22, 168, 22, 22, 167, 96, 69, 69, 106, 106, 108, 108, 106, 106, 106, 166, 48, 67, 67, 165, 67, 67, 67, 67, 67, 67, 67, 67, 67, 163, 70, 70, 70, 158, 120, 67, 67, 67, 67, 70, 70, 96, 109, 109, 109, 67, 67, 67, 67, 152, 152, 70, 70, 71, 156, 71, 71, 71, 110, 110, 110, 112, 159, 159, 71, 71, 113, 112, 112, 154, 67, 67, 113, 113, 113, 151, 71, 71, 105, 105, 149, 105, 105, 105, 105, 105, 105, 105, 105, 105, 144, 107, 107, 107, 161, 161, 105, 105, 105, 105, 107, 107, 133, 133, 133, 142, 105, 105, 105, 105, 140, 138, 107, 107, 134, 134, 134, 135, 135, 135, 139, 139, 139, 150, 150, 150, 131, 130, 129, 128, 127, 105, 105, 174, 174, 174, 174, 174, 174, 175, 126, 175, 175, 175, 175, 176, 123, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 179, 121, 179, 179, 179, 179, 180, 119, 180, 181, 181, 181, 181, 182, 118, 182, 182, 182, 182, 183, 117, 183, 183, 183, 183, 184, 184, 185, 116, 185, 185, 185, 185, 186, 115, 186, 186, 186, 186, 187, 187, 187, 187, 187, 187, 114, 104, 103, 102, 101, 98, 97, 92, 89, 88, 87, 86, 85, 84, 83, 82, 66, 65, 61, 60, 58, 57, 56, 55, 54, 49, 44, 42, 41, 40, 39, 37, 35, 30, 29, 26, 15, 12, 11, 9, 7, 2, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "scan.ll" #line 2 "scan.ll" /* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #ifdef _WIN32 /* declaration of isatty() */ #include #endif #include "../config.h" #include "../src/operator.h" #include "../src/symbol.h" #include "../src/stimuli.h" #include "../src/processor.h" #include "command.h" #include "cmd_macro.h" #include "parse.h" #include "input.h" #include "scan.h" /* Since our parser is reentrant, it needs to pass us a pointer * to the yylval that it would like us to use */ #ifdef YY_PROTO #define YY_DECL int yylex YY_PROTO(( YYSTYPE* yylvalP )) #else #define YY_DECL int yylex ( YYSTYPE* yylvalP ) #endif extern int yyparse(void); #define exit exit_gpsim /* This is the max length of a line within a macro definition */ static char macroBody[65536], *macroBodyPtr=0; static char* max_bodyPtr = ¯oBody[0] + sizeof(macroBody)-1; struct LexerStateStruct { struct cmd_options *options; command *cmd; int input_mode; int end_of_command; int have_parameters; int mode; struct LexerStateStruct *prev; struct LexerStateStruct *next; }; static char * m_pLastFullCommand = NULL; void SetLastFullCommand(const char *pCmd) { if (strlen(pCmd)>1) { if (m_pLastFullCommand) free (m_pLastFullCommand); m_pLastFullCommand = strdup(pCmd); } } const char * GetLastFullCommand() { return m_pLastFullCommand; } static LexerStateStruct *pLexerState = 0; static int sLevels=0; extern int quit_parse; extern int parser_spanning_lines; extern int last_command_is_repeatable; static string strip_trailing_whitespace (char *s); static int handle_identifier(YYSTYPE* yylvalP, string &tok, cmd_options **op ); static int process_intLiteral(YYSTYPE* yylvalP, char *buffer, int conversionBase); static int process_booleanLiteral(YYSTYPE* yylvalP, bool value); static int process_macroBody(YYSTYPE* yylvalP, const char *text); static int process_floatLiteral(YYSTYPE* yylvalP, char *buffer); static int process_stringLiteral(YYSTYPE* yylvalP, const char *buffer); static int process_quotedStringLiteral(YYSTYPE* yylvalP, char *buffer); static int process_shellLine(YYSTYPE* yylvalP, const char *buffer); static int recognize(int token,const char *); static void SetMode(int newmode); void scanPopMacroState(); int cli_corba_init (char *ior_id); extern Macro *isMacro(const string &s); static Macro *gCurrentMacro=0; #define YYDEBUG 1 //======================================================================== // MacroChain class // // class MacroChain { public: struct Link { Link *prev; Link *next; Macro *m; }; MacroChain() { head.prev = head.next =0; curr = &head; } void push(Macro *m) { if (verbose & 4 && m) { cout << "Pushing " << m->name() << " onto the macro chain\n"; } Link *pL = new Link(); pL->m = m; pL->prev = &head; pL->next = head.next; head.next = pL; param = pL; curr = &head; } void pop() { Link *pL = head.next; if (pL) { if (verbose & 4 && pL->m) { cout << "Popping " << pL->m->name() << " from the macro chain\n"; } head.next = pL->next; if (pL->next) pL->next->prev = &head; delete pL; } } Macro *nextParamSource() { if (curr) curr = curr->next; if (verbose & 4 && curr && curr->m ) { cout << " selecting parameter source " << curr->m->name() << endl; } if(curr) return curr->m; return 0; } void popParamSource() { if (verbose & 4 && curr && curr->m ) { cout << " popping parameter source " << curr->m->name() << endl; } if (curr) curr = curr->prev; } void resetParamSource() { if (verbose & 4) { cout << " resetparameter source\n"; } curr = &head; } private: Link *curr; Link head; Link *param; }; static MacroChain theMacroChain; #line 238 "scan.ll" /* Lexer States */ #line 244 "scan.ll" //************************************************************************ //************************************************************************ #line 854 "scan.cc" #define INITIAL 0 #define MACROBODY 1 #define DECLARATION 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * _in_str ); FILE *yyget_out (void ); void yyset_out (FILE * _out_str ); yy_size_t yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput (int c,char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 248 "scan.ll" // Comments. Ignore all text after a comment character #line 1084 "scan.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 174 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 470 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 254 "scan.ll" YY_BREAK case 2: YY_RULE_SETUP #line 256 "scan.ll" recognize(COMMENT_T,"comment"); YY_BREAK case 3: YY_RULE_SETUP #line 260 "scan.ll" { /* ignore white space */ } YY_BREAK case 4: /* rule 4 can match eol */ YY_RULE_SETUP #line 262 "scan.ll" { if(verbose) cout << "got EOL\n"; pLexerState->input_mode = 0; // assume that this is not a multi-line command. if(pLexerState->cmd && pLexerState->cmd->can_span_lines() && pLexerState->have_parameters && !pLexerState->end_of_command ) pLexerState->input_mode = CONTINUING_LINE; else { pLexerState->cmd = 0; return recognize(EOLN_T, " end of line"); } } YY_BREAK { // Got an eol. if(verbose) cout << "got INITIAL\n"; pLexerState->input_mode = 0; // assume that this is not a multi-line command. if(pLexerState->cmd && pLexerState->cmd->can_span_lines() && pLexerState->have_parameters && !pLexerState->end_of_command ) pLexerState->input_mode = CONTINUING_LINE; //else // return recognize(EOLN_T, " end of line"); } case 5: /* rule 5 can match eol */ YY_RULE_SETUP #line 297 "scan.ll" { /* short cut for quiting */ quit_parse =1; return QUIT; } YY_BREAK case 6: YY_RULE_SETUP #line 302 "scan.ll" { /* a sure way to abort a script */ return ABORT; } YY_BREAK case 7: YY_RULE_SETUP #line 307 "scan.ll" {return(recognize(EQU_T, "="));} YY_BREAK case 8: YY_RULE_SETUP #line 308 "scan.ll" {return(recognize(LAND_T, "&&"));} YY_BREAK case 9: YY_RULE_SETUP #line 309 "scan.ll" {return(recognize(LOR_T, "||"));} YY_BREAK case 10: YY_RULE_SETUP #line 311 "scan.ll" {return(recognize(COLON_T, ":"));} YY_BREAK case 11: YY_RULE_SETUP #line 312 "scan.ll" {return(recognize(LNOT_T,"!"));} YY_BREAK case 12: YY_RULE_SETUP #line 313 "scan.ll" {return(recognize(ONESCOMP_T,"~"));} YY_BREAK case 13: YY_RULE_SETUP #line 314 "scan.ll" {return(recognize(PLUS_T,"+"));} YY_BREAK case 14: YY_RULE_SETUP #line 315 "scan.ll" {return(recognize(MINUS_T,"-"));} YY_BREAK case 15: YY_RULE_SETUP #line 316 "scan.ll" {return(recognize(MPY_T,"*"));} YY_BREAK case 16: YY_RULE_SETUP #line 317 "scan.ll" {return(recognize(DIV_T,"/"));} YY_BREAK case 17: YY_RULE_SETUP #line 318 "scan.ll" {return(recognize(XOR_T,"^"));} YY_BREAK case 18: YY_RULE_SETUP #line 319 "scan.ll" {return(recognize(AND_T,"&"));} YY_BREAK case 19: YY_RULE_SETUP #line 320 "scan.ll" {return(recognize(OR_T,"|"));} YY_BREAK case 20: YY_RULE_SETUP #line 321 "scan.ll" {return(recognize(SHL_T,"<<"));} YY_BREAK case 21: YY_RULE_SETUP #line 322 "scan.ll" {return(recognize(SHR_T,">>"));} YY_BREAK case 22: YY_RULE_SETUP #line 324 "scan.ll" {return(recognize(EQ_T, "=="));} YY_BREAK case 23: YY_RULE_SETUP #line 325 "scan.ll" {return(recognize(NE_T, "!="));} YY_BREAK case 24: YY_RULE_SETUP #line 326 "scan.ll" {return(recognize(LT_T, "<"));} YY_BREAK case 25: YY_RULE_SETUP #line 327 "scan.ll" {return(recognize(GT_T, ">"));} YY_BREAK case 26: YY_RULE_SETUP #line 328 "scan.ll" {return(recognize(LE_T, "<="));} YY_BREAK case 27: YY_RULE_SETUP #line 329 "scan.ll" {return(recognize(GE_T, ">="));} YY_BREAK case 28: YY_RULE_SETUP #line 331 "scan.ll" {return(recognize(INDEXERLEFT_T, "["));} YY_BREAK case 29: YY_RULE_SETUP #line 332 "scan.ll" {return(recognize(INDEXERRIGHT_T, "]"));} YY_BREAK case 30: YY_RULE_SETUP #line 334 "scan.ll" {return(process_intLiteral(yylvalP,&yytext[2], 2));} YY_BREAK case 31: YY_RULE_SETUP #line 335 "scan.ll" {return(process_intLiteral(yylvalP,&yytext[2], 2));} YY_BREAK case 32: YY_RULE_SETUP #line 336 "scan.ll" {return(process_intLiteral(yylvalP,&yytext[0], 10));} YY_BREAK case 33: YY_RULE_SETUP #line 337 "scan.ll" {return(process_intLiteral(yylvalP,&yytext[2], 10));} YY_BREAK case 34: YY_RULE_SETUP #line 338 "scan.ll" {return(process_intLiteral(yylvalP,&yytext[2], 16));} YY_BREAK case 35: YY_RULE_SETUP #line 339 "scan.ll" {return(process_intLiteral(yylvalP,&yytext[1], 16));} YY_BREAK case 36: YY_RULE_SETUP #line 340 "scan.ll" {return process_floatLiteral(yylvalP,yytext);} YY_BREAK case 37: YY_RULE_SETUP #line 341 "scan.ll" {return(process_booleanLiteral(yylvalP,true));} YY_BREAK case 38: YY_RULE_SETUP #line 342 "scan.ll" {return(process_booleanLiteral(yylvalP,false));} YY_BREAK case 39: YY_RULE_SETUP #line 343 "scan.ll" {return(recognize(REG_T,"reg"));} YY_BREAK case 40: YY_RULE_SETUP #line 344 "scan.ll" {return(recognize(GPSIMOBJECT_T, "pin")); /*return(recognize(STIMULUS_T, "pin"));*/} YY_BREAK case 41: YY_RULE_SETUP #line 345 "scan.ll" {return(recognize(PORT_T, "port"));} YY_BREAK case 42: YY_RULE_SETUP #line 347 "scan.ll" {scanPopMacroState();} YY_BREAK case 43: YY_RULE_SETUP #line 349 "scan.ll" {return(process_shellLine(yylvalP,&yytext[1]));} YY_BREAK case 44: YY_RULE_SETUP #line 350 "scan.ll" {return(process_quotedStringLiteral(yylvalP,&yytext[1]));} YY_BREAK case 45: YY_RULE_SETUP #line 351 "scan.ll" {return(process_quotedStringLiteral(yylvalP,&yytext[2]));} YY_BREAK //======================================================================== // Macro processing case 46: YY_RULE_SETUP #line 359 "scan.ll" {SetMode(INITIAL); return(recognize(ENDM,"endm")); } YY_BREAK case 47: YY_RULE_SETUP #line 361 "scan.ll" {/*discard CR's*/} YY_BREAK case 48: /* rule 48 can match eol */ YY_RULE_SETUP #line 362 "scan.ll" {*macroBodyPtr++ = '\n'; *macroBodyPtr = 0; macroBodyPtr = macroBody; return(process_macroBody(yylvalP,macroBody));} YY_BREAK case 49: YY_RULE_SETUP #line 368 "scan.ll" { *macroBodyPtr++ = *yytext; if(verbose&4) printf("adding [%c]\n", *yytext); if (macroBodyPtr > max_bodyPtr) { cout << "buffer overflow in macro definition\n"; exit_gpsim(0); } } YY_BREAK //======================================================================== // Declaration Processing case 50: /* rule 50 can match eol */ YY_RULE_SETUP #line 383 "scan.ll" {SetMode(INITIAL); return(recognize(EOLN_T, "end of declaration")); } YY_BREAK case 51: YY_RULE_SETUP #line 384 "scan.ll" {return recognize(DECLARE_INT_T, "int type"); } YY_BREAK case 52: YY_RULE_SETUP #line 385 "scan.ll" {return recognize(DECLARE_FLOAT_T,"float type"); } YY_BREAK case 53: YY_RULE_SETUP #line 386 "scan.ll" {return recognize(DECLARE_BOOL_T, "bool type"); } YY_BREAK case 54: YY_RULE_SETUP #line 387 "scan.ll" {return recognize(DECLARE_FLOAT_T,"char type"); } YY_BREAK case 55: YY_RULE_SETUP #line 388 "scan.ll" { return process_stringLiteral(yylvalP, yytext); } YY_BREAK // The 'echo' command is handled by the lexer instead of the // parser (like the other commands). All it does is just display // the contents of yytext beyond the "echo". case 56: /* rule 56 can match eol */ YY_RULE_SETUP #line 397 "scan.ll" { fprintf(yyout,"%s",&yytext[5]); return recognize(EOLN_T, " end of line"); } YY_BREAK case 57: /* rule 57 can match eol */ YY_RULE_SETUP #line 403 "scan.ll" { fprintf(yyout,"\n"); return recognize(EOLN_T, " end of line"); } YY_BREAK // Indirect register access.... this should be an expression operator. /* {INDIRECT} { return INDIRECT; } */ // If this is a command that is spanning more than one line // then the 'end' command will finish it. case 58: YY_RULE_SETUP #line 428 "scan.ll" { if (pLexerState->cmd && pLexerState->cmd->can_span_lines() ) { pLexerState->end_of_command = 1; return(END_OF_COMMAND); } printf("Warning: found \"end\" while not in multiline mode\n"); } YY_BREAK // Identifiers. These are either gpsim commands or user macros. case 59: YY_RULE_SETUP #line 440 "scan.ll" { string tok = strip_trailing_whitespace (yytext); int ret=0; if(strlen(tok.c_str())) ret = handle_identifier (yylvalP, tok, &pLexerState->options); else ret = recognize(0,"invalid identifier"); if(ret) return ret; } YY_BREAK /* Default is to recognize the character we are looking at as a single char */ case 60: YY_RULE_SETUP #line 457 "scan.ll" {return(recognize(*yytext,"Single character"));} YY_BREAK case 61: YY_RULE_SETUP #line 459 "scan.ll" ECHO; YY_BREAK #line 1563 "scan.cc" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(MACROBODY): case YY_STATE_EOF(DECLARATION): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); yy_size_t number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 174 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; char *yy_cp = (yy_c_buf_p); YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 174 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 173); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp ) { char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ yy_size_t number_to_move = (yy_n_chars) + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ yy_size_t yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ yy_size_t yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 459 "scan.ll" /* make it work with flex 2.5.31 */ #ifndef yytext_ptr #define yytext_ptr yytext #endif #define MAX_STACK_LEVELS 16 static int input_stack_index=0; YY_BUFFER_STATE input_stack[MAX_STACK_LEVELS]; /************************************************************************ * yywrap() * * Revert to an old input stream if there is one. If there is not an old * old stream, then the lexer will try to get data from YY_INPUT which * is a macro that calls gpsim_read() (see scan.h). * An 'old' stream is one that was interrupted by a macro expansion. * */ #ifdef yywrap #undef yywrap #endif int yywrap (void) { if(input_stack_index) { yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(input_stack[--input_stack_index]); return 0; } return 1; } /************************************************************************ * push_input_stack * * called when macros are being expanded. */ static void push_input_stack(void) { if(input_stack_indexname() << endl; else cout << " but there is no current macro\n"; } if(currentMacro && currentMacro->substituteParameter(s,replaced)) if(replaced != s) { if (verbose & 4) cout << " -- found it and replaced it with " << replaced << endl; if (bTryMacroParameterExpansion (replaced)) return true; push_input_stack(); yy_scan_string(replaced.c_str()); theMacroChain.resetParamSource(); return true; } theMacroChain.popParamSource(); return false; } /************************************************************************* * * handle_identifier * * input string &s * cmd_options **op * output int * * 1 - If `op' is NULL, then handle identifier hasn't been called * for the current command that's being processed. So, the * the string `s' is compared to all of the valid commands. * If it is valid, then `op' is assigned a pointer to the * options associated with the command. If the string is not * found, then that's a syntax error and the string is ignored. * 2 - If `op' is non-NULL, then handle_identifier has been called * at least once before for the command that's being processed. * So the string `s' is then compared to the options associated * with the command. If an option is not found, then the string * is returned to the parser (as a type STRING). This places the * burden of syntax checking on the parser and/or the individual * command. * */ int handle_identifier(YYSTYPE* yylvalP, string &s, cmd_options **op ) { int retval = 0; // If no command has been found so far, then the options (*op) // haven't been selected either (and consequently *op is null). if(! *op) { // If the first character in the string is a ' (single quote character) then // this means that the user is explicitly trying to access a user defined symbol // (e.g. if there is variable named "help" in the user's symbol table, then the // only way to get access to it is by using the single quote character: // 'help if(s[0] == '\'') // Strip away the quote, we won't treat this as a command and the parser // doesn't want to know about it. s=s.erase(0,1); else { // Search the commands pLexerState->cmd = search_commands(s); if(pLexerState->cmd) { if(verbose&2) cout << "\n *******\nprocessing command " << (pLexerState->cmd->name()) << "\n token value " << (pLexerState->cmd->get_token()) << "\n *******\n"; *op = pLexerState->cmd->get_op(); pLexerState->have_parameters = 0; retval = pLexerState->cmd->get_token(); // ugh. This is problem when the parser becomes re-entrant. last_command_is_repeatable = pLexerState->cmd->is_repeatable(); return recognize(retval,"good command"); } } // Search the macros yylvalP->Macro_P = isMacro(s); if(yylvalP->Macro_P) { return MACROINVOCATION_T; } if (bTryMacroParameterExpansion(s)) return 0; } else { if(verbose&2) cout << "search options for command '" << (pLexerState->cmd ? pLexerState->cmd->name() : "?") << "'\n"; if (bTryMacroParameterExpansion(s)) return 0; // We already have the command, so search the options. struct cmd_options *opt = *op; // We also have one or more parameters now (though they // may not be correct, but that's the parser's job to determine). pLexerState->have_parameters = 1; while(opt->name) if(strcmp(opt->name, s.c_str()) == 0) { if(verbose&2) cout << "found option '" << opt->name << "'\n"; yylvalP->co = opt; return recognize(translate_token(opt->token_type),"option"); } else opt++; } // If we get here, then the option was not found. // So let's check the symbols Processor *cpu; if(s[0] == '.' && (cpu = get_active_cpu()) != 0) s.insert(0,cpu->name()); string s1(s); gpsimObject *obj = globalSymbolTable().find(s1); if(obj) { yylvalP->Symbol_P = obj; if(verbose&2) cout << "found symbol '" << obj->name() << "'\n"; return recognize(SYMBOL_T,"symbol"); } //cout << "didn't find it in the symbol list\n"; // Either 1) there's a typo or 2) the command is creating // a new symbol or node or something along those lines. // In either case, let's let the parser deal with it. if(verbose&2) cout << " returning unknown string: " << s << endl; return process_stringLiteral(yylvalP,s.c_str()); return 0; } /***************************************************************** * Process an integer literal. This routine constructs the * YYSTYPE object. The caller is responsible from returning the * LITERAL_INT_T token identifer to the parser. */ static int process_intLiteral(YYSTYPE* yylvalP, char *buffer, int conversionBase) { char c; char *pt = buffer; gint64 literalValue=0; gint64 nxtDigit; while (*pt) { c = toupper(*pt++); nxtDigit = (c) <= '9' ? c-'0' : c-'A'+10; if ((nxtDigit >= conversionBase) || (nxtDigit<0)) { if(!(c == '\'')) { cout << "Error conversion to integer " << buffer << endl; literalValue = 0; } break; } literalValue *= conversionBase; literalValue += nxtDigit; } yylvalP->Integer_P = new Integer(literalValue); return(recognize(LITERAL_INT_T,"literal int")); } /***************************************************************** * */ static int process_macroBody(YYSTYPE* yylvalP, const char *text) { yylvalP->s = strdup(text); return recognize(MACROBODY_T,"macro body"); } /***************************************************************** * */ static int process_booleanLiteral(YYSTYPE* yylvalP, bool value) { yylvalP->Boolean_P = new Boolean(value); return(recognize(LITERAL_BOOL_T, "boolean literal")); } /***************************************************************** * */ static int process_floatLiteral(YYSTYPE* yylvalP, char *buffer) { double floatValue; #if 0 errno = 0; floatValue = atof(buffer); if (errno != 0) { /* The conversion failed */ throw new Error("Bad floating point literal"); } #else char *endptr=0; floatValue = strtod(buffer, &endptr); if (endptr == buffer) throw new Error("Bad floating point literal"); #endif yylvalP->Float_P = new Float(floatValue); return(recognize(LITERAL_FLOAT_T, "float literal")); } /***************************************************************** * */ static int process_stringLiteral(YYSTYPE* yylvalP, const char *buffer) { yylvalP->String_P = new String(buffer); return(recognize(LITERAL_STRING_T, "string literal")); } static int process_quotedStringLiteral(YYSTYPE* yylvalP, char *buffer) { char * pCloseQuote = strrchr(buffer, '\"'); if(pCloseQuote == NULL) pCloseQuote = strrchr(buffer, '\''); *pCloseQuote = 0; if (*(pCloseQuote-1) == '\\') *(pCloseQuote-1) = 0; yylvalP->String_P = new String(buffer); return(recognize(LITERAL_STRING_T, "string literal")); } /***************************************************************** * */ static int process_shellLine(YYSTYPE* yylvalP, const char *buffer) { yylvalP->String_P = new String(buffer); return(recognize(SHELL, "shell line")); } static string strip_trailing_whitespace (char *s) { string retval = s; size_t pos = retval.find_first_of (" \t"); if (pos != string::npos) retval.resize (pos); return retval; } //------------------------------------------------------------------------ static void SetMode(int newmode) { BEGIN(newmode); if(pLexerState) pLexerState->mode = newmode; } void initialize_commands(void); void init_cmd_state(void) { if(pLexerState) { if (verbose) cout << "scan: clearing lexer state and flushing buffer\n"; pLexerState->cmd = 0; pLexerState->options = 0; pLexerState->input_mode = 0; pLexerState->end_of_command = 0; pLexerState->have_parameters = 0; pLexerState->mode = 0; } } void FlushLexerBuffer() { #ifdef YY_FLUSH_BUFFER YY_FLUSH_BUFFER; #else yy_flush_buffer(YY_CURRENT_BUFFER ); #endif } static void pushLexerState() { if(verbose) cout << "pushing lexer state: from level " << sLevels << " to " << (sLevels+1) << endl; sLevels++; LexerStateStruct *pLS = new LexerStateStruct(); if(pLexerState) pLexerState->next = pLS; pLS->prev = pLexerState; pLexerState = pLS; pLS->next = 0; init_cmd_state(); } static void popLexerState() { if(verbose) cout << "popping lexer state: from level " << sLevels << " to " << (sLevels-1) << endl; sLevels--; if(pLexerState) { LexerStateStruct *pLS = pLexerState; pLexerState = pLS->prev; if(pLexerState) { pLexerState->next = 0; pLexerState->cmd = 0; pLexerState->options = 0; } SetMode(pLS->mode); delete pLS; } } int scan_read (char *buf, unsigned max_size) { static int lastRet = -1; // hack int ret = gpsim_read(buf,max_size); if (lastRet == ret && ret == 0) { *buf = '\n'; ret = 1; } lastRet = ret; return ret; } int init_parser() { pushLexerState(); int ret = yyparse(); popLexerState(); return ret; } // Tell us what the current buffer is. YY_BUFFER_STATE current_buffer (void) { return YY_CURRENT_BUFFER; } // Create a new buffer. YY_BUFFER_STATE create_buffer (FILE *f) { return yy_create_buffer (f, YY_BUF_SIZE); } // Start reading a new buffer. void switch_to_buffer (YY_BUFFER_STATE buf) { yy_switch_to_buffer (buf); } // Delete a buffer. void delete_buffer (YY_BUFFER_STATE buf) { yy_delete_buffer (buf); } // Restore a buffer (for unwind-prot). void restore_input_buffer (void *buf) { switch_to_buffer ((YY_BUFFER_STATE) buf); } // Delete a buffer (for unwind-prot). void delete_input_buffer (void *buf) { delete_buffer ((YY_BUFFER_STATE) buf); } //------------------------------------------------------------------------ // called by the parser error handler. command *getLastKnownCommand() { if(pLexerState) return pLexerState->cmd; return 0; } //---------------------------------------- // void lexer_setMacroBodyMode(void) { macroBodyPtr = ¯oBody[0]; if(verbose&4) cout << "setting lexer MACROBODY mode\n"; SetMode(MACROBODY); } //---------------------------------------- // void lexer_setDeclarationMode() { if(verbose&4) cout << "setting lexer DECLARATION mode\n"; SetMode(DECLARATION); } //---------------------------------------- static bool isWhiteSpace(char c) { return (c==' ' || c == '\t'); } //---------------------------------------- // getNextMacroParameter(char *s, int l) // // returns true if a macro parameter can be extracted // from yyinput buffer. If it does return true, then the // extracted macro parameter will get copied to // the string 's'. // // This routine will lexically analyze a character string // and split it up into chunks that can be passed to a // macro invocation. It might be possible to add a new // lex state and do this work in the lexer... // // If input stream looks something like: // // expression1, expression2, expression3, ... // // then this function will return true and copies 'expression1' // to 's'. static bool getNextMacroParameter(char *s, int l) { char c; // delete all leading white space. do { c = yyinput(); } while(isWhiteSpace(c)); if(c==',') goto done; unput(c); if(!c) return false; { int nParen=0; bool bDone = false; do { c = yyinput(); if(c == '(') nParen++; if(c == ')' && --nParen < 0 ) bDone = true; if(c==',') break; if(c==0 || c=='\n' ) { bDone=true; unput(c); } else *s++ = c; } while(--l>0 && !bDone); } done: *s=0; return true; } void lexer_InvokeMacro(Macro *m) { if(!m) return; if(verbose &4) cout << "Invoking macro: " << m->name() << endl; theMacroChain.push(m); m->prepareForInvocation(); int i=0; bool bValidParameter = false; do { i++; char s[256]; bValidParameter = getNextMacroParameter(s,sizeof(s)); if(bValidParameter) { m->add_parameter(s); if(verbose &4) cout << "macro param: " << s << endl; } } while (bValidParameter && inParameters()); m->invoke(); } void scanPushMacroState(Macro *m) { gCurrentMacro = m; } void scanPopMacroState() { theMacroChain.pop(); } gpsim-0.30.0/cli/cmd_module.cc0000664000076400007640000001644013065573230013043 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_module.h" #include "../src/pic-processor.h" #include "../src/modules.h" #include "../src/symbol.h" #include "../src/cmd_manager.h" cmd_module c_module; #define CMD_MOD_LIST 1 #define CMD_MOD_LOAD 2 #define CMD_MOD_DUMP 3 #define CMD_MOD_LIB 4 #define CMD_MOD_PINS 5 static cmd_options cmd_module_options[] = { {"list", CMD_MOD_LIST, OPT_TT_BITFLAG}, {"load", CMD_MOD_LOAD, OPT_TT_STRING}, {"dump", CMD_MOD_DUMP, OPT_TT_BITFLAG}, {"pins", CMD_MOD_PINS, OPT_TT_STRING}, {"library", CMD_MOD_LIB , OPT_TT_STRING}, {"lib", CMD_MOD_LIB , OPT_TT_STRING}, {0,0,0} }; cmd_module::cmd_module() : command("module","mod") { brief_doc = string("Select & Display modules"); long_doc = string ( "module [ [load module_type [module_name]] | [lib lib_name] | [list] | \n" "[[dump | pins] module_name] ] \n" "\tIf no options are specified, then the currently defined module(s)\n" "\twill be displayed. This is the same as the `module list' command.\n" "\tThe `module load lib_name' tells gpsim to search for the module\n" "\tlibrary called `lib_name' and to load it. (Note that the format of\n" "\tmodule libraries is exactly the same as a Linux shared library. This\n" "\tmeans that the module library should reside in a path available to\n" "\tdlopen(). Please see the README.MODULES in the gpsim distribution.\n" "\tTo instantiate a new module, then type\n" "\t module module_type module_name\n" "\twhere module_type refers to a specific module in a module library\n" "\tand module_name is the user name assigned to it.\n" "\tInformation about a module can be displayed by the command\n" "\t module module_name [dump | pins]\n" "\twhere module_name is the name that you assigned when the module\n" "\twas instantiated. The optional dump and pins identifiers specify\n" "\tthe information you wish to display (dump is the default).\n" "\n" "\tDevelopers of gpsim and developers building libraries for use with\n" "\tgpsim may find it useful to set the GPSIM_MODULE_PATH environment variable\n" "\tto the target folder of the library module that is under development.\n" "\tMultiple folders may be delimited with a ':' for Linux and ';' for\n" "\tWindows.\n" "\n" "\texamples:\n" "\n" "\tmodule // Display the modules you've already defined.\n" "\tmodule lib my_mods.so // Load the module library called my_mods.\n" "\tmodule list // Display the list of modules supported.\n" "\tmodule load lcd my_lcd // Create an instance of an 'lcd'\n" "\tmodule pins my_lcd // Display the pin states of an instantiated module\n" "\tmodule load lcd lcd2x20 // Create a new module.\n" "\tmodule load pullup R1 // and another.\n" ); op = cmd_module_options; } static void dumpModules(const SymbolTableEntry_t &st) { cout << " Module: " << st.first << endl; } void cmd_module::module(void) { if(verbose) cout << "cmd_module: display modules\n"; #ifdef OLD_MODULE_LIBRARY cout << ModuleLibrary::DisplayModuleList(); #else globalSymbolTable().ForEachModule(dumpModules); #endif } void cmd_module::module(cmd_options *opt) { if(!opt) return; switch(opt->value) { case CMD_MOD_LIST: #ifdef OLD_MODULE_LIBRARY cout << ModuleLibrary::DisplayFileList(); #else ModuleLibrary::ListLoadableModules(); #endif break; default: cout << "cmd_module error:"; if(opt->name) cout << " no parameters with option: " << opt->name; cout << endl; } } void cmd_module::module(cmd_options_str *cos, list *strs) { // const int cMAX_PARAMETERS=2; // int nParameters=cMAX_PARAMETERS; // guint64 parameters[cMAX_PARAMETERS] = {0,0}; // evaluate(eList, parameters, &nParameters); list :: iterator si; std::string s1; int nStrings = 0; if (strs) { nStrings = strs->size(); si = strs->begin(); if (nStrings >= 1) { s1 = *si; if (nStrings >= 2) { ++si; } } } // Now choose the specific command based on the input parameters if(nStrings==0) module(cos); else if(nStrings==1) module(cos, s1.c_str()); //else if(nParameters==0 && nStrings==2) // module(cos, (char*)s1.c_str(), (char*)s2.c_str()); //else if(nParameters==1 && nStrings==1) // module(cos, (char*)s1.c_str(), parameters[0]); //else if(nParameters==2 && nStrings==0) // module(cos, parameters[0], parameters[1]); //else if(nParameters==1 && nStrings==2) // module(cos, (char*)s1.c_str(), (char*)s2.c_str(), parameters[0]); else cout << "module command error\n"; } void cmd_module::module(cmd_options_str *cos) { if(!cos) return; switch(cos->co->value) { case CMD_MOD_LIB: if(verbose) cout << "module command got the library " << cos->str << endl; try { string fname(cos->str); ModuleLibrary::LoadFile(fname); } catch(Error *pError) { cout << pError->get_errMsg(); } break; case CMD_MOD_LOAD: // Load a module from (an already loaded) library and let // gpsim assign the name. if(verbose) cout << "module command got the module " << cos->str << '\n'; #ifdef OLD_MODULE_LIBRARY if(ModuleLibrary::NewObject(cos->str) == NULL) { GetUserInterface().DisplayMessage("module type %s not created\n", cos->str); } #else { cout << "Fixme -- module NewObject\n"; } #endif break; case CMD_MOD_DUMP: cout << " is not supported yet\n"; break; case CMD_MOD_PINS: cout << "Fixme: display module pins is not supported...\n"; //ModuleLibrary::DisplayModulePins(cos->str); break; default: cout << "cmd_module error\n"; } } void cmd_module::module(cmd_options_str *cos, const char *op1) { switch(cos->co->value) { case CMD_MOD_LOAD: // Load a module from (an already loaded) library #ifdef OLD_MODULE_LIBRARY if(ModuleLibrary::NewObject(cos->str, op1) == NULL) { GetUserInterface().DisplayMessage("module type %s not created\n", cos->str); } #else { string mName(cos->str); string refDes(op1); if(!ModuleLibrary::InstantiateObject(mName,refDes)) GetUserInterface().DisplayMessage("module type %s not created\n", cos->str); } #endif break; default: cout << "Warning, ignoring module command\n"; } } gpsim-0.30.0/cli/socket.cc0000664000076400007640000007330413063451146012224 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #ifndef _WIN32 #include #endif #include #include #include #include //#include "../src/processor.h" #include "../src/symbol.h" #include "../src/protocol.h" #include "../src/gpsim_interface.h" #include "../src/breakpoints.h" #include "../src/gpsim_time.h" #ifndef _WIN32 #include #include #else #include #endif void exit_gpsim(int); //******** E X P E R I M E N T A L C O D E !!! ************************* // Here is an experimental attribute for testing the socket interface. // The purpose is to isolate socket testing from the rest of the simulator. // class TestInt32Array : public Value { public: TestInt32Array(const char *_name, int _sz) : Value(_name, " test array for testing sockets") { size = _sz; array = new int[size]; } ~TestInt32Array() { delete[] array; } virtual void set(const char *cP,int len=0) { std::cout << name() << " set\n"; } virtual void get(char *, int len) { std::cout << name() << " get\n"; } virtual string toString() { return name(); } private: int size; int *array; }; //************************* end of experimental code ******************** class SocketLink; class Socket; // in input.cc -- parse_string sends a string through the command parser extern int parse_string(const char * str); #ifdef WIN32 #define snprintf _snprintf #define socklen_t int bool server_started = false; void psocketerror(const char *str) { fprintf (stderr, "%s: %s\n", str, g_win32_error_message(WSAGetLastError())); } bool winsockets_init(void) { WSADATA wsaData; int err; if (0 != (err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData ))) return false; /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return false; } return true; } #else #define psocketerror(s) perror(s) #define closesocket(s) close(s) #define SOCKET int #define INVALID_SOCKET -1 #endif // /* gpsim sockets. The purpose of a socket interface into the simulator is to provide an external interface that only loosely depends upon gpsim's internals. Towards the bottom of this file is code that will start a server 'process' that will listen for clients. This 'process' is really a glib GIOChannel. The GIOChannel is a glib mechanism for handling things like sockets so that they work nicely when compiled for other platforms. Now, whenever a client connects to gpsim, another GIOChannel is created. This new channel has the client socket associated with it and is used to communicate with the client. Thus, like most socket server applications, gpsim creates a single socket to listen for clients. As clients come along, connections are established with them. gpsim uses GLIB's GIOChannels to facilitate the simultaneous multiple connections. Once a client has connected to gpsim, it can do just about everything a user sitting at a keyboard can do. In fact, the client can issue command line commands that are directed to the command line parser. Although, at the moment, the output of these commands still is sent to the terminal from which the gpsim executable was spawned (instead of being sent to the client socket...). Probably more powerful though is the ability for a client to establish 'links' to gpsim internal objects. These links are provide a client with an efficient access to gpsim's symbol table. There are two kinds of socket connection types that gpsim supports. I call them 'Simulator Source' and 'Simulator Sink' sockets. They're both similar in that they connect to a client through the normal mechanism. However, they're different in how they behave while the simulator is running. The Simulator Sink sockets are designed to be controlled by a GLIB GIOChannel. They are intended to receive unsolicited data from a client. In addition, since they're controlled by a GIOChannel, they can only be processed while the GTK main loop has control (which in the current implementation is all time except when the simulation is running). So the idea is that clients can send stuff to the simulator, and if the simulator is not running, the information is processed and a response is returned to the client. Simulator Sources are for sending unsolicited simulator data to a client. This is a blocking operation, i.e. it will not return until the client has sent a response. Now, the client is responsible for setting Simulator Source Sockets up. So during the socket connection and initialization the client specifies what it wants the simulator to send unsolicited. You might imagine a situation where a plugin module may be receiving data from a script. */ #define SIM_SINK_PORT 0x1234 #define SIM_SOURCE_PORT 0x1235 #define BUFSIZE 8192 //------------------------------------------------------------------------ bool ParseSocketLink(Packet *buffer, SocketLink **); //------------------------------------------------------------------------ //------------------------------------------------------------------------ // class SocketInterface : public Interface { private: // Socket *sock; public: virtual void SimulationHasStopped (gpointer object); virtual void Update (gpointer object); virtual ~SocketInterface(); SocketInterface(Socket *); }; //------------------------------------------------------------------------ // Socket wrapper class // // This class is a simple wrapper around the standard BSD socket calls. // class SocketBase { public: SocketBase(SOCKET s); ~SocketBase(); SOCKET getSocket(); void Close(); bool Send(const char *); void Service(); void ParseObject(); Packet *packet; private: SOCKET socket; }; //------------------------------------------------------------------------ // Socket class // This class is responsible for listening to clients. // class Socket { public: Socket(); ~Socket(); void init(int port); void AssignChannel(gboolean (*server_func)(GIOChannel *,GIOCondition,void *)); void Close(SocketBase**); void Bind(); void Listen(); SocketBase * Accept(); SocketBase *my_socket; struct sockaddr_in addr; }; class SocketLink { public: SocketLink(unsigned int _handle, SocketBase *); virtual ~SocketLink() { } /// Send a response back to the link. /// if the bTimeStamp is true, then the cycle counter is sent too. bool Send(bool bTimeStamp=false); bool Receive(); virtual void set(Packet &)=0; virtual void get(Packet &)=0; unsigned int getHandle() { return handle; } void setBlocking(bool bBlocking) { bWaitForResponse = bBlocking; } bool bBlocking() { return bWaitForResponse; } private: unsigned int handle; SocketBase *parent; bool bWaitForResponse; }; ///======================================================================== /// AttributeLink /// An attribute link is a link associated with a gpsim attribute. /// Clients will establish attribute links by providing the name /// of the gpsim object with which they wish to link. The over head /// for parsing the link name and looking it up in the table only /// has to be done once. class AttributeLink : public SocketLink { public: AttributeLink(unsigned int _handle, SocketBase *, Value *); virtual ~AttributeLink() { } void set(Packet &); void get(Packet &); Value *getValue() { return v; } private: /// This is a pointer to the gpsim Value object associated with /// this link. Value *v; }; ///======================================================================== /// NotifyLink /// A notify link is a link designed to be a sort of cross reference. It /// is associated with a gpsim attribute in such a way that whenever the /// gpsim attribute changes, the notify link will notify a client socket. class NotifyLink : public Value { public: virtual void set(gint64); NotifyLink(AttributeLink *); private: AttributeLink *sl; }; ///======================================================================== /// CyclicCallBackLink /// A cyclic call back link is a link that periodically sends a message /// to the client. class CyclicCallBackLink : public TriggerObject { public: CyclicCallBackLink(guint64 , SocketBase *); virtual void callback(); virtual void callback_print(void); private: guint64 interval; SocketBase *sb; }; //======================================================================== #define nSOCKET_LINKS 16 SocketLink *links[nSOCKET_LINKS]; AttributeLink *gCreateSocketLink(unsigned int, Packet &, SocketBase *); unsigned int FindFreeHandle() { unsigned int i; static unsigned int sequence = 0; for(i=0; iDecodeUInt32(handle)) { unsigned int index = handle & 0xffff; *sl = links[index&0x0f]; if( (*sl) && (*sl)->getHandle() != handle) *sl = 0; return true; } return false; } //======================================================================== void CloseSocketLink(SocketLink *sl) { if(!sl) return; unsigned int handle = sl->getHandle(); std::cout << " closing link with handle 0x" << hex << handle << endl; if(links[handle&0x000f] == sl) links[handle&0x000f] = 0; } //======================================================================== Socket::Socket() { my_socket = 0; for(int i=0; igetSocket() > 0) { GIOChannel *channel = g_io_channel_unix_new(my_socket->getSocket()); GIOCondition condition = (GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR); GError *err = NULL; g_io_channel_set_encoding (channel, NULL, &err); #if !defined _WIN32 || defined _DEBUG g_io_channel_set_flags (channel, G_IO_FLAG_SET_MASK, &err); #endif g_io_add_watch(channel, condition, server_function, (void*)this); } } void Socket::Close(SocketBase **sock) { if (sock && *sock) { (*sock)->Close(); *sock = 0; } } void Socket::Bind() { if(!my_socket) return; if (bind(my_socket->getSocket(), (struct sockaddr *) &addr, sizeof(addr)) != 0) { psocketerror("bind"); } } void Socket::Listen() { if(!my_socket) return; if (listen(my_socket->getSocket(), 5) != 0) { psocketerror("listen"); } } SocketBase *Socket::Accept() { socklen_t addrlen = sizeof(addr); SOCKET client_socket = accept(my_socket->getSocket(),(struct sockaddr *) &addr, &addrlen); if (client_socket == INVALID_SOCKET) { psocketerror("accept"); exit_gpsim(1); } return new SocketBase(client_socket); } bool SocketBase::Send(const char *b) { if(!socket) return false; //std::cout << "Sending sock="<DecodeObjectType(ObjectType)) return; switch (ObjectType) { case GPSIM_CMD_CREATE_SOCKET_LINK: { unsigned int handle = FindFreeHandle(); AttributeLink *sl = gCreateSocketLink(handle, *packet, this); if(sl) { links[handle&0x0f] = sl; packet->EncodeHeader(); packet->EncodeUInt32(handle); packet->txTerminate(); Send(packet->txBuff()); } } break; case GPSIM_CMD_CREATE_NOTIFY_LINK: { unsigned int handle = FindFreeHandle(); AttributeLink *sl = gCreateSocketLink(handle, *packet, this); if(sl) { unsigned int i=0; if(packet->DecodeUInt32(i) && i) sl->setBlocking(true); //NotifyLink *nl = new NotifyLink(sl); links[handle&0x0f] = sl; packet->EncodeHeader(); packet->EncodeUInt32(handle); packet->txTerminate(); Send(packet->txBuff()); } } break; case GPSIM_CMD_CREATE_CALLBACK_LINK: { unsigned int handle = FindFreeHandle(); guint64 interval=0; std::cout << "Creating callback link\n"; if(packet->DecodeUInt64(interval) && interval) { std::cout << "Creating callback link interval=" << interval << endl; //CyclicCallBackLink *cl = new CyclicCallBackLink(interval,this); //links[handle&0x0f] = sl; packet->EncodeHeader(); packet->EncodeUInt32(handle); packet->txTerminate(); Send(packet->txBuff()); } } break; case GPSIM_CMD_REMOVE_SOCKET_LINK: { SocketLink *sl=0; std::cout << "remove socket link command\n"; ParseSocketLink(packet, &sl); if(sl) CloseSocketLink(sl); Send("$"); } break; case GPSIM_CMD_QUERY_SOCKET_LINK: { SocketLink *sl=0; ParseSocketLink(packet, &sl); if(sl) sl->Send(); } break; case GPSIM_CMD_WRITE_TO_SOCKET_LINK: { SocketLink *sl=0; ParseSocketLink(packet, &sl); if(sl) { sl->set(*packet); Send("$"); } } break; case GPSIM_CMD_QUERY_SYMBOL: { char tmp[256]; if(packet->DecodeString(tmp,256)) { Value *sym = globalSymbolTable().findValue(tmp); if(sym) { packet->EncodeHeader(); sym->get(*packet); packet->txTerminate(); Send(packet->txBuff()); } else Send("-"); } } break; case GPSIM_CMD_WRITE_TO_SYMBOL: { // The client has requested to write directly to a symbol // (without using a SocketLink). So, we'll extract the symbol // name from the packet and look it up in the symbol table. // If the symbol is found then, it will get assigned the // value that's stored in the packet. char tmp[256]; if(packet->DecodeString(tmp,256)) { Value *sym = globalSymbolTable().findValue(tmp); if(sym) { // We'll define the response header before we decode // the rest of the packet. The reason for this is that // some symbols may wish to generate a response. packet->EncodeHeader(); sym->set(*packet); packet->txTerminate(); Send(packet->txBuff()); } else Send("-"); } } break; case GPSIM_CMD_RUN: { guint64 nCycles; guint64 startCycle = get_cycles().get(); // Extract from the packet the number of cycles we should run. // If the number of cycles is greater than 0, then we'll set // a cycle breakpoint; otherwise we'll run forever. if(packet->DecodeUInt64(nCycles)) { guint64 fc = startCycle + nCycles; if(nCycles) { get_bp().set_cycle_break(0,fc); } } // Start running... get_interface().start_simulation(); // The simulation has stopped. For the response (to the run // command) we'll send the current value of the cycle counter. // (A client can use this to determine if the break was due to // cycle break set above or to something else). packet->EncodeObjectType(GPSIM_CMD_RUN); packet->EncodeUInt64(get_cycles().get() - startCycle); packet->txTerminate(); Send(packet->txBuff()); } break; case GPSIM_CMD_RESET: get_interface().reset(); Send("-"); break; default: printf("Invalid object type: %u\n", ObjectType); Send("-"); } } //------------------------------------------------------------------------ // Service() // // A client has sent data to gpsim through the socket interface. It is here // where we validate that data and decide how to handle it. void SocketBase::Service() { if(packet->brxHasData()) { // If the data is a 'pure socket command', which is to say it begins // with a header as defined in ../src/protocol.h, then the data // will be further parsed by ParseObject(). If the data has an // invalid header, then we assume that the data is for the command // line and we let the CLI parse_string() function handle it. // FIXME gpsim poorly handles this CLI interface. We should send // the output of the CLI back to the client socket. if (packet->DecodeHeader()) { ParseObject(); } else { if(parse_string(packet->rxBuff()) >= 0) Send("+ACK"); else Send("+BUSY"); } } } //======================================================================== // Socket Interface SocketInterface::SocketInterface(Socket *new_socket) // : sock(new_socket) { } void SocketInterface::SimulationHasStopped (gpointer object) { } void SocketInterface::Update (gpointer object) { /* if(sock) sock->Service(); printf("socket update\n"); */ } SocketInterface::~SocketInterface() { /* if(sock) sock->Service(); */ } //======================================================================== SocketLink::SocketLink(unsigned int _handle, SocketBase *sb) : handle(_handle), parent(sb), bWaitForResponse(false) { } bool SocketLink::Send(bool bTimeStamp) { if(parent) { parent->packet->prepare(); parent->packet->EncodeHeader(); get(*parent->packet); if(bTimeStamp) parent->packet->EncodeUInt64(get_cycles().get()); parent->packet->txTerminate(); /* std::cout << "SocketLink::Send() " << " socket=" << parent->getSocket() << " sending " << parent->packet->txBuff() << endl; */ if(bWaitForResponse) { //std::cout << "SocketLink::Send waiting for response\n"; if(parent->Send(parent->packet->txBuff())) return Receive(); } else return parent->Send(parent->packet->txBuff()); } return false; } bool SocketLink::Receive() { if(parent) { //cout << "SocketLink is waiting for a client response\n"; parent->packet->prepare(); int bytes= recv(parent->getSocket(), parent->packet->rxBuff(), parent->packet->rxSize(), 0); if (bytes == -1) { perror("recv"); exit_gpsim(1); } parent->packet->rxTerminate(bytes); /* cout << "SocketLink got client response: " << parent->packet->rxBuff() << endl; */ return true; } return false; } //======================================================================== AttributeLink::AttributeLink(unsigned int _handle, SocketBase *_sb, Value *_v) : SocketLink(_handle,_sb), v(_v) { } void AttributeLink::set(Packet &p) { if(v) v->set(p); } void AttributeLink::get(Packet &p) { if(v) v->get(p); } //======================================================================== NotifyLink::NotifyLink(AttributeLink *_sl) : Value(), sl(_sl) { new_name("notifylink"); std::cout<< "Creating a notify link \n"; if(sl && sl->getValue()) { Value *v = sl->getValue(); std::cout<< "Creating a notify link and asoc with "<< v->name()<getValue()->set_xref(this); } } void NotifyLink::set(gint64 i) { //std::cout << "notify link is sending data back to client\n"; if(sl) sl->Send(true); } //======================================================================== CyclicCallBackLink::CyclicCallBackLink(guint64 i, SocketBase *_sb) : interval(i), sb(_sb) { std::cout << " cyclic callback object\n "; get_cycles().set_break(get_cycles().get() + interval, this); } void CyclicCallBackLink::callback(void) { std::cout << " cyclic callback\n "; if(sb) { static bool bfirst = true; static char st[5]; static int seq=0; if(bfirst) { bfirst = false; st[0] = 'h'; st[1] = 'e'; st[2] = 'y'; st[3] = '0'; st[4] = 0; } if(++st[3] > '9') st[3] = '0'; if(sb->Send(st)) get_cycles().set_break(get_cycles().get() + interval, this); else std::cout << "socket callback failed seq:" << seq++ << endl; } } void CyclicCallBackLink::callback_print(void) { std::cout << " cyclic callback\n "; } //======================================================================== AttributeLink *gCreateSocketLink(unsigned int handle, Packet &p, SocketBase *sb) { char tmp[256]; if(p.DecodeString(tmp,256)) { Value *sym = globalSymbolTable().findValue(tmp); if(sym) return new AttributeLink(handle,sb,sym); } return 0; } ////////////////////////////////////////////////////////////////////////// #ifdef USE_THREADS_BUT_NOT_RECOMMENDED_BECAUSE_OF_CROSS_PLATFORM_ISSUES void *server_thread(void *ignored) { std::cout << "running....\n"; Socket s; while ( true ) { s.receive(); } return 0; } pthread_t thSocketServer; pthread_attr_t thAttribute; int something=1; void start_server(void) { std::cout << "starting server....\n"; pthread_attr_init(&thAttribute); pthread_attr_setdetachstate(&thAttribute, PTHREAD_CREATE_JOINABLE); pthread_create(&thSocketServer, &thAttribute, server_thread, (void *)&something); std::cout << " started server\n"; } #else // if USE_THREADS static void debugPrintChannelStatus(GIOStatus stat) { switch (stat) { case G_IO_STATUS_ERROR: std::cout << "G_IO_STATUS_ERROR\n"; break; case G_IO_STATUS_NORMAL: std::cout << "G_IO_STATUS_NORMAL\n"; break; case G_IO_STATUS_EOF: std::cout << "G_IO_STATUS_EOF\n"; break; case G_IO_STATUS_AGAIN: std::cout << "G_IO_STATUS_AGAIN\n"; break; } } #if 0 // defined but not used static void debugPrintCondition(GIOCondition cond) { if(cond & G_IO_IN) std::cout << " G_IO_IN\n"; if(cond & G_IO_OUT) std::cout << " G_IO_OUT\n"; if(cond & G_IO_PRI) std::cout << " G_IO_PRI\n"; if(cond & G_IO_ERR) std::cout << " G_IO_ERR\n"; if(cond & G_IO_HUP) std::cout << " G_IO_HUP\n"; if(cond & G_IO_NVAL) std::cout << " G_IO_NVAL\n"; } #endif /*======================================================================== server_callback () This call back function is invoked from the GTK main loop whenever a client socket has sent something to send to gpsim. This callback will only be invoked for those clients that have already connected to gpsim. Those connected clients have associated with them a 'SocketBase' object. A pointer to that object is passed in the server_callback parameters. This function essentially will respond to the messages that clients send in much the same way the BSD socket command recv() does. Which is to say, the data that the clients send is read from the socket. The actual parsing of the data is done by the routine 'SocketBase::Service()'. */ static gboolean server_callback(GIOChannel *channel, GIOCondition condition, void *pSocketBase ) { SocketBase *s = (SocketBase *)pSocketBase; if(condition & G_IO_HUP) { std::cout<< "client has gone away\n"; GError *err=NULL; GIOStatus stat = g_io_channel_shutdown(channel, TRUE, &err); std::cout << "channel status " << hex << stat << " " ; debugPrintChannelStatus(stat); delete s; return FALSE; } if(condition & G_IO_IN) { gsize bytes_read=0; s->packet->prepare(); memset(s->packet->rxBuff(), 0, 256); GError *err=NULL; gsize b; #if !defined _WIN32 || defined _DEBUG g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, &err); #endif g_io_channel_read_chars(channel, s->packet->rxBuff(), s->packet->rxSize(), &b, &err); bytes_read = b; s->packet->rxAdvance(bytes_read); if(err) { std::cout << "GError:" << err->message << endl; } if(bytes_read) { if(get_interface().bSimulating()) { std::cout << "setting a socket break point because sim is running \n"; get_bp().set_socket_break(); } else s->Service(); } else return FALSE; return TRUE; } return FALSE; } /*======================================================================== server_accept( ) This call back function is invoked from the GTK loop whenever a client is attempting to establish a socket connection to gpsim. The purpose of this function is to accept a socket connection and to create a GLIB GIOChannel associated with it. This GIOChannel will listen to the client socket and will invoke the server_callback() callback whenever the client sends data. In addition, a new 'SocketBase' object will be created when the connection is accepted. This SocketBase object wraps the BSD socket and provides additional support for simplifying the socket communication. */ static gboolean sink_server_accept(GIOChannel *channel, GIOCondition condition, void *d ) { Socket *s = (Socket *)d; std::cout << " SourceSink accepting new client connect\n"; SocketBase *client = s->Accept(); if(!client) return FALSE; GIOChannel *new_channel = g_io_channel_unix_new(client->getSocket()); GIOCondition new_condition = (GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR); GError *err = NULL; g_io_channel_set_encoding (channel, NULL, &err); #if !defined _WIN32 || defined _DEBUG //stat = g_io_channel_set_flags (channel, G_IO_FLAG_SET_MASK, &err); g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, &err); #endif g_io_add_watch(new_channel, new_condition, server_callback, (void*)client); return TRUE; } static gboolean source_server_accept(GIOChannel *channel, GIOCondition condition, void *d ) { Socket *s = (Socket *)d; std::cout << " SourceServer accepting new client connect\n"; SocketBase *client = s->Accept(); std::cout << " SourceServer accepted connection\n"; if(!client) return FALSE; int bytes= recv(client->getSocket(), client->packet->rxBuff(), client->packet->rxSize(), 0); std::cout << " SourceServer received data" << client->packet->rxBuff() << endl; if (bytes == -1) { perror("recv"); exit_gpsim(1); } client->packet->rxAdvance(bytes); client->Service(); std::cout << " SourceServer serviced client\n"; // FIXME: SocketBase *client goes out of scope almost certainly leaking resources. return TRUE; } void start_server(void) { // TestInt32Array *test = new TestInt32Array("test",16); // symbol_table.add(test); std::cout << "starting server....\n"; #ifdef _WIN32 if (!winsockets_init()) { fprintf(stderr, "Could not find a usable WinSock DLL, sockets are disabled.\n"); server_started = false; return; } server_started = true; #endif // Create the Sink and Source servers static Socket sinkServer; sinkServer.init(SIM_SINK_PORT); sinkServer.AssignChannel(sink_server_accept); get_interface().add_interface(new SocketInterface(&sinkServer)); static Socket sourceServer; sourceServer.init(SIM_SOURCE_PORT); sourceServer.AssignChannel(source_server_accept); std::cout << " started server\n"; } void stop_server(void) { #ifdef _WIN32 if (server_started) WSACleanup(); #endif } #endif // if USE_THREADS gpsim-0.30.0/cli/cmd_symbol.cc0000664000076400007640000001075213041763642013065 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "command.h" #include "cmd_symbol.h" #include "../src/cmd_gpsim.h" #include "../src/modules.h" #include "../src/symbol.h" #include "../src/ValueCollections.h" #include "../src/pic-instructions.h" cmd_symbol c_symbol; static cmd_options cmd_symbol_options[] = { {0,0,0} }; cmd_symbol::cmd_symbol() : command("symbol",0) { brief_doc = string("Add or display symbols"); long_doc = string ("symbol []\n" "symbol =\n" "\n" "\tIf no options are supplied, the entire symbol table will be\n" "\tdisplayed. If only the symbol_name is provided, then only\n" "\tthat symbol will be displayed.\n" "\tIf a symbol_name that does not currently exist is equated\n" "\tto a value, then a new symbol will be added to the symbol table.\n" "\tThe type of symbol will be derived. To force a string value double\n" "\tdouble quote the value.\n" "\n" "\tValid symbol types:\n" "\t Integer, Float, Boolean and String\n" "\n" "Examples:\n" "\tsymbol // display the symbol table\n" "\tsymbol GpsimIsGreat=true // create a new constant symbol\n" "\n"); op = cmd_symbol_options; } static string table; void dumpOneSymbol(const SymbolEntry_t &sym) { string out; Value *pVal = dynamic_cast(sym.second); if (pVal != NULL && typeid(*pVal) == typeid(LineNumberSymbol)) return; if (table != "__global__") out = table + "." + sym.second->name(); else out = sym.second->name(); printf("%-25s Type: %s\n", out.c_str(), sym.second->showType().c_str()); } void dumpSymbolTables(const SymbolTableEntry_t &st) { table = st.first; (st.second)->ForEachSymbolTable(dumpOneSymbol); } void cmd_symbol::dump_all() { cout << "\nSymbol table\n"; globalSymbolTable().ForEachModule(dumpSymbolTables); } void cmd_symbol::dump_one(const char *sym_name) { string sName(sym_name); Module *pM = globalSymbolTable().findModule(sName); if (pM) pM->getSymbolTable().ForEachSymbolTable(dumpOneSymbol); else dump_one(globalSymbolTable().find(sName)); //get_symbol_table().dump_filtered(sName); } void cmd_symbol::dump_one(gpsimObject *s) { if(s) { Module *pM = dynamic_cast(s); if (pM) pM->getSymbolTable().ForEachSymbolTable(dumpOneSymbol); else cout << s->toString() << endl; } } void cmd_symbol::add_one(const char *sym_name, Expression *expr) { Value * pVal = expr->evaluate(); if (pVal) { pVal->new_name(sym_name); //pVal->setClearableSymbol(false); pVal->set_description("Derived from the command line."); if (!globalSymbolTable().addSymbol(pVal)) delete pVal; } } void cmd_symbol::EvaluateAndDisplay(Expression *pExpr) { try { Value * pValue = pExpr->evaluate(); GetUserInterface().DisplayMessage("%s\n", pValue->toString().c_str()); } catch(Error *pMessage) { GetUserInterface().DisplayMessage("%s\n", pMessage->toString().c_str()); } } void cmd_symbol::dump(gpsimObject *s, ExprList_t*e) { Value *pValue = dynamic_cast(s); if (pValue) { IndexedSymbol sym(pValue, e); cout << sym.toString() << endl; } } void cmd_symbol::Set(gpsimObject *s, ExprList_t*e, Expression *pExpr) { Value *pValue = dynamic_cast(s); if (pValue) { try { IIndexedCollection *pCollection = dynamic_cast(s); if(pCollection == NULL) { GetUserInterface().DisplayMessage("%s is not an indexed symbol\n", s->name().c_str()); } else { pCollection->SetAt(e, pExpr); } } catch(Error Message) { GetUserInterface().DisplayMessage("%s\n", Message.toString().c_str()); } } } gpsim-0.30.0/cli/cmd_quit.cc0000664000076400007640000000221013041763642012530 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_quit.h" cmd_quit quit; static struct cmd_options cmd_quit_options[] = { {0,0,0} }; cmd_quit::cmd_quit() : command("quit","q") { brief_doc = string("Quit gpsim"); long_doc = string ("Quit gpsim\n"); op = cmd_quit_options; } void cmd_quit::quit(int bit_flag) { cout << " cmd_quit::quit with bit flag\n"; } gpsim-0.30.0/cli/cmd_set.h0000664000076400007640000000167213041763642012216 00000000000000/* Copyright (C) 1999-2000 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_SET_H__ #define __CMD_SET_H__ class Expression; class cmd_set : public command { public: cmd_set(void); void set(void); void set(int bit_flag,Expression *); }; extern cmd_set c_set; #endif gpsim-0.30.0/cli/input.cc0000664000076400007640000005447313114656617012110 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #include "fd2raw.h" #define GETCWD _getcwd #else #include #include #if !defined(_MAX_PATH) #define _MAX_PATH 1024 #endif #define GETCWD getcwd // temp fix to over come 23jan05 changes to configure script that prevent // readline from being found on older systems. #define HAVE_READLINE #define HAVE_NSCLEAN_READLINE #endif #include "../config.h" #ifdef HAVE_GUI #include #include #include #endif #include "../src/exports.h" #include "../src/sim_context.h" #include "../src/gpsim_def.h" #include "../src/gpsim_classes.h" #include "../src/icd.h" #include "../src/pic-processor.h" #include "../src/breakpoints.h" #include "../src/cod.h" #include "command.h" #include "input.h" #include "cmd_macro.h" #include "cmd_run.h" #ifdef HAVE_LIBREADLINE #define HAVE_READLINE #endif #ifdef HAVE_READLINE /* See if we have namespace-clean readline or not */ #ifdef HAVE_RL_COMPLETION_MATCHES #define HAVE_NSCLEAN_READLINE #endif extern "C" { #include #include } static GIOChannel *channel; gint g_iWatchSourceID = 0; #endif /* HAVE_READLINE */ void simulation_cleanup(); extern const char *get_dir_delim(const char *path); int parse_string(const char * str); //------------------------------------------------------------------------ // LIBGPSIM_EXPORT bool gUsingThreads(); // in ../src/interface.cWatchSourceIDc void initialize_readline (void); void clear_input_buffer(void); #ifdef HAVE_GUI void quit_gui(void); #endif void redisplay_prompt(void); char *gnu_readline (char *s, unsigned int force_readline); int last_command_is_repeatable=0; //extern Macro *gCurrentMacro; extern void scanPushMacroState(Macro *); extern int quit_parse; #ifdef HAVE_SOCKETS extern void start_server(void); extern void stop_server(void); #endif // HAVE_SOCKETS static Boolean *s_bSTCEcho = 0; void EnableSTCEcho(bool bEnable) { *s_bSTCEcho = bEnable; } //------------------------------------------------------------------------ // Command Handler - create an interface to the CLI //------------------------------------------------------------------------ #include "../src/cmd_manager.h" //class ISimConsole; class CCliCommandHandler : public ICommandHandler { public: virtual const char *GetName(); virtual int Execute(const char * commandline, ISimConsole *out); virtual int ExecuteScript(list &script, ISimConsole *out); }; // This instantiation will get registered so that code // in ../src can get access to this class (and consequently the command line). static CCliCommandHandler sCliCommandHandler; //------------------------------------------------------------------------ // LLInput - A class for storing a command line command // This is private to input.cc //------------------------------------------------------------------------ class LLInput { public: LLInput(); LLInput(const char *,Macro *); ~LLInput(); Macro *macro; // macro generating this text char *data; LLInput *next_input; }; //------------------------------------------------------------------------ // LLStack - A class for storing a collection of command line commands. // This is private to input.cc //------------------------------------------------------------------------ class LLStack { public: LLStack(); ~LLStack(); void Push(); void Pop(); void Append(const char *, Macro *); LLInput *GetNext(); void print(); int level() { return msi_StackDepth; } LLInput *LLdata; LLStack *next_stack; private: static int msi_StackDepth; }; int LLStack::msi_StackDepth=0; //------------------------------------------------------------------------ // LLInput - linked list input for commands. LLInput::LLInput() : macro(0),data(0), next_input(0) { } LLInput::LLInput(const char *s,Macro *m) : macro(m), next_input(0) { data = strdup(s); } LLInput::~LLInput() { if(data) free(data); } //------------------------------------------------------------------------ // LLStack - linked list stack for commands. LLStack::LLStack() : LLdata(0), next_stack(0) { msi_StackDepth++; // cout << "Stack depth: " << level() << endl; } LLStack::~LLStack() { msi_StackDepth--; } static LLStack *Stack=0; //======================================================================== // // catch_control_c // // void catch_control_c(int sig) { #ifdef _WIN32 CSimulationContext::GetContext()->NotifyUserCanceled(); if(CSimulationContext::GetContext()->GetActiveCPU()->simulation_mode == eSM_RUNNING) { // If we get a CTRL->C while processing a command file // we should probably stop the command file processing. clear_input_buffer(); } ::signal(SIGINT, catch_control_c); #else // JRH - I'll let someone else try the above code under Linux. // The readline library appears to call ::signal() itself so // the call will not be needed here. I'm guessing that the CTRL->C // signal handling in readline did not work under Windows so // that is why it was originally ifdef'd out. //if(simulation_mode != STOPPED) // { cout << " break\n"; CSimulationContext::GetContext()->NotifyUserCanceled(); // } //else { // cout << "caught control c, but it doesn't seem gpsim was simulating\n"; // last_command_is_repeatable=0; // redisplay_prompt(); //} #endif } void initialize_threads(void) { if( !g_thread_supported() ) { #if GLIB_MINOR_VERSION < 32 g_thread_init(NULL); #endif #ifdef HAVE_GUI gdk_threads_init(); #endif } } void initialize_signals(void) { #ifdef _WIN32 ::signal(SIGINT, catch_control_c); #else static struct sigaction action; action.sa_handler = catch_control_c; sigemptyset(&action.sa_mask); action.sa_flags=0; sigaction(SIGINT, &action, 0); #endif } void initialize_CLI() { CCommandManager::GetManager().Register(&sCliCommandHandler); } //============================================================== // initialize_gpsim // // Not much initialization is needed now. // void initialize_gpsim(void) { s_bSTCEcho = new Boolean("CliTrace", false, "Enable echoing commands from STC files to the console."); globalSymbolTable().addSymbol(s_bSTCEcho); initialize_CLI(); if(gUsingThreads()) initialize_threads(); initialize_signals(); #ifdef HAVE_SOCKETS start_server(); #endif } void LLStack::print(void) { if(verbose & 4) { LLStack *s = Stack; cout << "Current state of input buffer:\n"; int stack_number=0; while (s) { LLInput *h = s->LLdata; int depth =0; while(h) { cout << " " <data; depth++; h = h->next_input; } stack_number++; s = s->next_stack; } cout << "\n ---Leaving dump \n"; } } void LLStack::Push() { LLStack *s = new LLStack(); s->next_stack = Stack; Stack = s; print(); } void LLStack::Pop() { if (Stack ) { if(Stack->next_stack != NULL) { LLStack *next = Stack->next_stack; delete Stack; Stack = next; } } } void LLStack::Append(const char *s, Macro *m) { LLInput *d = new LLInput(s,m); LLInput *h = LLdata; if (h) { /* go to the end of the list */ while(h->next_input) h = h->next_input; /* add d to the end */ h->next_input = d; } else LLdata = d; } LLInput *LLStack::GetNext() { if (Stack) { if (Stack->LLdata) { LLInput *d = Stack->LLdata; // remove this item from the list if(d) Stack->LLdata = d->next_input; return d; } if(Stack->next_stack != NULL) { Pop(); return GetNext(); } } return 0; } /******************************************************* */ void add_string_to_input_buffer(const char *s, Macro *m=0) { if(!Stack) Stack = new LLStack(); Stack->Append(s,m); } /******************************************************* */ void start_new_input_stream() { if(!Stack) Stack = new LLStack(); else Stack->Push(); } /******************************************************* */ void clear_input_buffer(void) { LLInput * pLine; if (Stack) while((pLine = Stack->GetNext()) != NULL) delete pLine; } /******************************************************* * start_parse * * This routine will run a string through the command parser *this is useful if you want to execute a command but do not *wish to go through the readline stuff. */ extern int init_parser(); int start_parse(void) { int retval = init_parser(); if(quit_parse) exit_gpsim(0); return retval; } int parse_string(const char * str) { add_string_to_input_buffer(str); int iReturn = start_parse(); if(iReturn == 1) { // If the str was a 'load c x.stc' file and the parsing // was aborted we need to remove the remaining // strings. clear_input_buffer(); } return iReturn; } int parse_string_only(const char * str) { LLStack *OldStack= Stack; Stack = 0; int iRet = parse_string(str); delete Stack; Stack = OldStack; return iRet; } void process_command_file(const char * file_name, bool bCanChangeDirectory) { FILE *cmd_file; char directory[256]; const char *dir_path_end; if(verbose&4) cout << __FUNCTION__ <<"()\n"; dir_path_end = get_dir_delim(file_name); if(dir_path_end && bCanChangeDirectory) { strncpy(directory,file_name,dir_path_end-file_name); directory[dir_path_end-file_name]=0; printf("directory is \"%s\"\n",directory); if(chdir(directory) < 0) perror(directory); file_name=dir_path_end+1; printf("file_name is \"%s\"\n",file_name); } cmd_file = fopen(file_name,"r"); if(cmd_file) { if(verbose) cout << "processing a command file\n"; start_new_input_stream(); //Stack.Push(); char *s; char str[256]; while( (s = fgets(str, 256, cmd_file)) != 0) { if(str[0] == 0 || str[0] == '\n' || ((str[1] == '\n' && str[0] == '\r'))) { // skip the blank lines continue; } #ifndef WIN32 // Let us be compatible with Windows EOLs // on Linux. int iLast = strlen(str) - 1; if(iLast >= 2 && str[iLast] == '\n' && str[iLast-1] == '\r' ) { // Windows type EOL // convert to str[iLast] = '\000'; str[iLast-1] = '\n'; } #endif add_string_to_input_buffer(s); } fclose(cmd_file); } else { cout << "failed to open command file "; cout << file_name; cout << endl; char cw[_MAX_PATH]; if (GETCWD(cw, _MAX_PATH) == 0) perror("getcwd()"); else cout << "current working directory is " << cw << endl; } if(Stack) Stack->print(); } /********************************************* Function: gpsim_open() Returns: 1 - success 0 - failure */ int gpsim_open(Processor *cpu, const char *pFileName, const char * pProcessorType, const char *pProcessorName) { if(!pFileName) return 0; if (verbose) printf (" gpsim_open file:%s proc name:%s\n", pFileName, (pProcessorName ? pProcessorName : "nil")); // Check for the command file, file extension. if(IsFileExtension(pFileName,"stc") || IsFileExtension(pFileName,"STC")) { process_command_file(pFileName,true); // A stc file could have any sequence of commands. // Just ignore the return value of parse_string(). parse_string("\n"); return 1; } else if (IsFileExtension(pFileName,"asm")) { fprintf(stderr, "File %s has extension .asm, not a suitable file\n", pFileName); return 0; } else { // Assume a Program file return CSimulationContext::GetContext()->LoadProgram(pFileName, pProcessorType, 0, pProcessorName); } return 0; } //********************************************* // gpsim_read // // This function is called from the parser. It will either read // a line of text from a command file or from stdin -- depending // on the current source for data. Once a string is obtained, it // is copied into a buffer that the parser has passed to us. int gpsim_read (char *buf, unsigned max_size) { LLInput *d = Stack ? Stack->GetNext() : 0; if (Stack && verbose) Stack->print(); if (!d || !d->data) { if(verbose&4) cout <<"gpsim_read -- no more data\n"; return 0; } scanPushMacroState(d->macro); //gCurrentMacro = d->macro; char *cPstr = d->data; unsigned int count = strlen(cPstr); count = (count < max_size) ? count : max_size-1; strncpy(buf, cPstr, count); buf[count] = 0; SetLastFullCommand(buf); if(*s_bSTCEcho) cout << cPstr; if(verbose&4) { cout <<"gpsim_read returning " << count << ":" << cPstr << endl; if (d->macro) { cout << " and it's a macro named:" << d->macro->name() << endl; } } delete (d); return count; } void have_line(char *); //************************************************** void cli_main(void) { do { #ifdef HAVE_READLINE #ifdef WIN32 if(channel->is_readable) { // Channel is not readable when a Windows // stdin is redirected. rl_callback_read_char (); } else { char line[256]; fgets(line, sizeof(line),stdin); have_line(line); } #else rl_callback_read_char (); #endif #else char line[256]; fgets(line, sizeof(line),stdin); have_line(line); #endif } while(!quit_parse); } /* **************************************************************** */ /* */ /* Interface to Readline Completion */ /* */ /* **************************************************************** */ /* Generator function for command completion. STATE lets us know whether to start from scratch; without any state (i.e. STATE == 0), then we start at the top of the list. */ char * command_generator (const char *text, int state) { //static char *empty=""; static int i = 0; const int cMaxStringLen = 64; /* If this is a new word to complete, initialize now. */ if (state == 0) i = 0; /* Return the next name which partially matches from the command list. */ while( iname(), text) == command_list[i]->name()) return(g_strndup(command_list[i++]->name(), cMaxStringLen)); i++; } // If no names matched, and this is the first item on a line (i.e. state==0) // then return a copy of the input text. (Note, it was emperically determined // that 'something' must be returned if there are no matches at all - // otherwise readline crashes on windows.) #ifdef _WIN32 if(state == 0) return g_strndup(text,cMaxStringLen); #endif return 0; } /* Attempt to complete on the contents of TEXT. START and END show the region of TEXT that contains the word to complete. We can use the entire line in case we want to do some simple parsing. Return the array of matches, or NULL if there aren't any. */ char ** gpsim_completion (const char *text, int start, int end) { char **matches; matches = 0; #ifdef HAVE_READLINE /* If this word is at the start of the line, then it is a command to complete. Otherwise it is the name of a file in the current directory. */ if (start == 0) #ifdef HAVE_NSCLEAN_READLINE matches = rl_completion_matches (text, command_generator); #else matches = completion_matches ((char *)text, (CPFunction *)command_generator); #endif #endif #if defined(_WIN32) || defined(WIN32) if (start) { char *empty = strdup(""); matches = (char **) malloc(2 * (sizeof(&empty))); matches[0] = empty; matches[1] = 0; } #endif return (matches); } //#ifdef HAVE_GUI //============================================================================ // // keypressed(). // // When the user presses a key, this function will get called. // If a simulation is running, then we'll pass the key to // the stimulus engine. static gboolean keypressed (GIOChannel *source, GIOCondition condition, gpointer data) { #ifdef HAVE_READLINE rl_callback_read_char (); #endif return TRUE; } //#endif //============================================================================ // // have_line // When is pressed at the command line, the text string on the command // is copied into a buffer and passed to the command parser. // void have_line(char *s) { if(!s) return; static char last_line[256] = {0}; if(strlen(s) == 0) { if(*last_line && last_command_is_repeatable) add_string_to_input_buffer(last_line); } else { // save a copy in the history buffer: strncpy(last_line,s,256); #ifdef HAVE_READLINE add_history (s); #endif add_string_to_input_buffer(s); } add_string_to_input_buffer("\n"); start_parse(); #if defined (_WIN32) || defined (HAS_RL_FREE) rl_free(s); #else free(s); #endif } /********************************************************************** **/ void exit_cli(void) { if(get_use_icd()) icd_disconnect(); #ifdef HAVE_GUI quit_gui(); #endif #ifdef HAVE_READLINE rl_callback_handler_remove(); #ifdef HAVE_GUI g_source_remove(g_iWatchSourceID); g_io_channel_unref(channel); #endif #endif CSimulationContext::GetContext()->GetContext()->Clear(); #ifdef HAVE_SOCKETS stop_server(); #endif globalSymbolTable().deleteSymbol("CliTrace"); cout << "Exiting gpsim\n"; simulation_cleanup(); } /* redisplay_prompt will redisplay the current data in the readline buffer. This function is used to restore a prompt that's been obliterated by diagnostic data. */ void redisplay_prompt(void) { #ifdef HAVE_READLINE rl_forced_update_display(); #endif } #if defined HAVE_READLINE && defined HAVE_GUI static int gpsim_rl_getc(FILE *in) { gchar buf[6]; gsize bytes_read; g_io_channel_read_chars(channel, buf, 1, &bytes_read, NULL); return buf[0]; // JRH, 7-1-2005 - I tried this but am not comfortable that it // is working as I intended. // return bytes_read == 0 ? EOF : (buf[0] & 0x000000ff); } #endif /* Tell the GNU Readline library how to complete. We want to try to complete on command names if this is the first word in the line, or on filenames if not. */ void initialize_readline (void) { const char *gpsim_prompt="gpsim> "; const char *gpsim_cli_prompt="**gpsim> "; const char *prompt = get_interface().bUsingGUI() ? gpsim_prompt : gpsim_cli_prompt; #ifdef HAVE_READLINE // Lets us have a gpsim section to .inputrc // JRH - not tested // rl_terminal_name = "gpsim"; #ifdef _WIN32 /* set console to raw mode */ win32_fd_to_raw(fileno(stdin)); #endif #if defined HAVE_READLINE && defined HAVE_GUI rl_getc_function = gpsim_rl_getc; channel = g_io_channel_unix_new (fileno(stdin)); #endif #ifdef _WIN32 // The channel is not readable if it is a redirected // standard input, in which case we will not be getting // any keypress events. if(channel->is_readable) { g_iWatchSourceID = g_io_add_watch (channel, G_IO_IN, keypressed, NULL); } #else #if defined HAVE_READLINE && defined HAVE_GUI g_iWatchSourceID = g_io_add_watch (channel, G_IO_IN, keypressed, NULL); #endif #endif rl_callback_handler_install (prompt, have_line); /* Tell the completer that we want a crack first. */ rl_attempted_completion_function = gpsim_completion; #endif //HAVE_READLINE } #if defined(HAVE_READLINE) && defined(HAVE_PERL) // JRH - An experiment void EnableKeypressHook(bool bEnable) { if (bEnable) { g_iWatchSourceID = g_io_add_watch (channel, G_IO_IN, keypressed, NULL); } else { // g_source_remove_by_funcs_user_data(keypressed, NULL); g_source_remove(g_iWatchSourceID); g_io_channel_unref(channel); } } #endif //------------------------------------------------------------------------ // CLI command handler // // The command handler is an interface that gets 'registered' with gpsim. // This means that clients interested in gpsim's cli can look up this // registered handler and get access to the command line. This is primarily // used by symbol files that embed gpsim scripts. See src/modules.cc. // const char *CCliCommandHandler::GetName() { return "gpsimCLI"; } int CCliCommandHandler::Execute(const char * commandline, ISimConsole *out) { add_string_to_input_buffer("\n"); start_new_input_stream(); parse_string_only(commandline); add_string_to_input_buffer("\n"); return 1; } int CCliCommandHandler::ExecuteScript(list &script, ISimConsole *out) { if (verbose & 4) cout << "GCLICommandHandler::Execute Script:" << endl; if (script.empty()) return CMD_ERR_OK; // We need to execute the script now. There may be other commands // currently pending, so a new command stream is created and the // commands that are in this script are placed there. The current // command stream is temporarily disabled and then re-enabled at // the end of this function. LLStack *saveStack = Stack; Stack = 0; start_new_input_stream(); add_string_to_input_buffer("\n"); list :: iterator command_iterator; for (command_iterator = script.begin(); command_iterator != script.end(); ++command_iterator) { string *cmd = *command_iterator; add_string_to_input_buffer((char *) cmd->c_str()); } // Start parsing the script that we just placed into the command stream start_parse(); delete Stack; // Restore the original command stream. Stack = saveStack; return CMD_ERR_OK; } gpsim-0.30.0/cli/cmd_log.h0000664000076400007640000000176613041763642012210 00000000000000/* Copyright (C) 1999,2000,2001,2002 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_LOG_H__ #define __CMD_LOG_H__ #include #include "command.h" class cmd_log : public command { public: cmd_log(); void log(); void log(cmd_options *opt); void log(cmd_options *opt, ExprList_t *el); }; extern cmd_log c_log; #endif gpsim-0.30.0/cli/cmd_node.cc0000664000076400007640000000461513041763642012506 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "command.h" #include "cmd_node.h" #include "../src/stimuli.h" #include "../src/symbol.h" cmd_node c_node; static cmd_options cmd_node_options[] = { {0,0,0} }; cmd_node::cmd_node() : command("node",0) { brief_doc = string("Add or display stimulus nodes"); long_doc = string ("node [new_node1 new_node2 ...]\n" "\t If no new_node is specified then all of the nodes that have been\n" "\tdefined are displayed. If a new_node is specified then it will be\n" "\tadded to the node list. See the \"attach\" and \"stimulus\" commands\n" "\tto see how stimuli are added to the nodes.\n" "\n" "\texamples:\n" "\n" "\tnode // display the node list\n" "\tnode n1 n2 n3 // create and add 3 new nodes to the list\n"); op = cmd_node_options; } void dumpOneNode(const SymbolEntry_t &sym) { Stimulus_Node *psn = dynamic_cast(sym.second); if (psn) { cout << psn->name() << " voltage = " << psn->get_nodeVoltage() << "V\n"; if (psn->stimuli) { stimulus *s = psn->stimuli; while (s) { cout << '\t' << s->name() << '\n'; s=s->next; } } } } void dumpNodes(const SymbolTableEntry_t &st) { cout << " Node Table: " << st.first << endl; (st.second)->ForEachSymbolTable(dumpOneNode); } void cmd_node::list_nodes() { globalSymbolTable().ForEachModule(dumpNodes); } void cmd_node::add_nodes(list * nodes) { if(nodes) { list :: iterator si; for (si = nodes->begin(); si != nodes->end(); ++si) { string &s = *si; Stimulus_Node::construct((char *)s.c_str()); } } } gpsim-0.30.0/cli/cmd_x.h0000664000076400007640000000206513041763642011667 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_X_H__ #define __CMD_X_H__ class Expression; class cmd_x : public command { public: cmd_x(void); void x(void); void x(int reg, Expression *pExpr = NULL); void x(char *reg_name, int val); void x(char *reg_name); void x(Expression *); virtual int is_repeatable(void) { return 1; }; }; extern cmd_x c_x; #endif gpsim-0.30.0/cli/cmd_attach.h0000664000076400007640000000252213041763642012662 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_ATTACH_H__ #define __CMD_ATTACH_H__ #include using namespace std; class Stimulus_Node; class stimulus; class gpsimObject; class LiteralInteger; typedef list gpsimObjectList_t; class cmd_attach : public command { public: cmd_attach(); void attach(gpsimObject*, gpsimObjectList_t *); }; extern cmd_attach attach; // Here are some helper functions for the parser. // These convert the pin() and port() operators into stimuli. // The attach command is the only one that uses them, thus // the code goes here. stimulus *toStimulus(gpsimObject *); stimulus *toStimulus(int); #endif gpsim-0.30.0/cli/cmd_trace.h0000664000076400007640000000225213041763642012514 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __CMD_TRACE_H__ #define __CMD_TRACE_H__ #include "command.h" class cmd_trace : public command { public: cmd_trace(void); void trace(void); void trace(cmd_options *co); void trace(cmd_options_expr *coe); void trace(Expression *); void trace(cmd_options_num *con); void trace(cmd_options_str *cos); void trace(int bit_flag, int force_bit_test); virtual int is_repeatable(void) { return 1; }; }; extern cmd_trace c_trace; #endif gpsim-0.30.0/plat/0000775000076400007640000000000013117465757010704 500000000000000gpsim-0.30.0/plat/win32/0000775000076400007640000000000013117465760011640 500000000000000gpsim-0.30.0/plat/win32/gpsim.def0000664000076400007640000000001013041763624013342 00000000000000EXPORTS gpsim-0.30.0/plat/win32/gpsim.nsi0000664000076400007640000007051713116657401013416 00000000000000# gpsim.nsi - NSIS installer script for gpsim # # Copyright (c) 2004-2013 Borut Razem # # This file is part of gpsim. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. # # Borut Razem # borut.razem@siol.net ; Script generated by the HM NIS Edit Script Wizard. ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "gpsim" ; Version !ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD !define PRODUCT_VERSION "${VER_MAJOR}.${VER_MINOR}.${VER_REVISION}" !else !define PRODUCT_VERSION "XX.XX.XX" !endif !ifndef PRODUCT_WEB_SITE !define PRODUCT_WEB_SITE "http://gpsim.sourceforge.net/gpsim.html" !endif !define PRODUCT_PUBLISHER "www.dattalo.com" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\gpsim.bat" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define GPSIM_ROOT "..\.." !ifndef SETUP_DIR !define SETUP_DIR "..\..\..\..\gpsim_snapshots" !endif !define PKG_ROOT "${SETUP_DIR}\gpsim_pkg" SetCompressor /SOLID lzma ;-------------------------------- ; Header Files !include "MUI2.nsh" !include "WordFunc.nsh" !include "WinVer.nsh" ;-------------------------------- ; Functions !ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD !insertmacro VersionCompare !endif ;-------------------------------- ; Configuration ; MUI Settings !define MUI_ABORTWARNING ;!define MUI_ICON "${PKG_ROOT}\gpsim.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !insertmacro MUI_PAGE_LICENSE "${GPSIM_ROOT}\COPYING" ; Uninstall/reinstall page !ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD Page custom PageReinstall PageLeaveReinstall !endif ; StartMenu page !define MUI_STARTMENUPAGE_DEFAULTFOLDER ${PRODUCT_NAME} !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY ${PRODUCT_UNINST_KEY} !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "NSIS:StartMenuDir" !define MUI_STARTMENUPAGE_NODISABLE Var MUI_STARTMENUPAGE_VARIABLE !insertmacro MUI_PAGE_STARTMENU Application $MUI_STARTMENUPAGE_VARIABLE ; Components page !define MUI_COMPONENTSPAGE_SMALLDESC !insertmacro MUI_PAGE_COMPONENTS ; Directory page !insertmacro MUI_PAGE_DIRECTORY ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_RUN "$INSTDIR\gpsim.bat" !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.TXT" !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English" !ifndef DATE !define DATE "YYYYMMDD" !endif Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "${SETUP_DIR}\gpsim-${PRODUCT_VERSION}-${DATE}-setup.exe" InstallDir "$PROGRAMFILES\gpsim" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on) ;;;;ShowInstDetails show ;;;;ShowUnInstDetails show !ifndef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD ; Old unistallation method Function .onInit ;Uninstall the old version, if present ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" StrCmp $R0 "" inst MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "${PRODUCT_NAME} is already installed. $\n$\nClick 'OK' to remove the \ previous version or 'Cancel' to cancel this upgrade." \ IDOK uninst Abort uninst: ; Run the uninstaller ClearErrors ExecWait '$R0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file Goto done inst: ; Install the new version MessageBox MB_YESNO|MB_ICONQUESTION "This will install $(^Name). Do you wish to continue?" IDYES +2 Abort done: FunctionEnd !endif InstType "gpsim + extras modules" InstType "gpsim" Section "gpim" SEC01 SectionIn 1 2 RO SetOutPath "$INSTDIR\bin" SetOverwrite ifnewer File "${GPSIM_ROOT}\gpsim\gpsim.exe" File "${GPSIM_ROOT}\src\libgpsim.dll" File "${GPSIM_ROOT}\modules\libgpsim_modules.dll" File "${PKG_ROOT}\bin\freetype6.dll" File "${PKG_ROOT}\bin\iconv.dll" File "${PKG_ROOT}\bin\libatk-1.0-0.dll" File "${PKG_ROOT}\bin\libcairo-2.dll" File "${PKG_ROOT}\bin\libcairo-gobject-2.dll" File "${PKG_ROOT}\bin\libcairo-script-interpreter-2.dll" File "${PKG_ROOT}\bin\libgailutil-18.dll" File "${PKG_ROOT}\bin\libexpat-1.dll" File "${PKG_ROOT}\bin\libfontconfig-1.dll" File "${PKG_ROOT}\bin\${LIBGCCDDL}" File "${PKG_ROOT}\bin\libgdk-win32-2.0-0.dll" File "${PKG_ROOT}\bin\libgdk_pixbuf-2.0-0.dll" File "${PKG_ROOT}\bin\libgio-2.0-0.dll" File "${PKG_ROOT}\bin\libglib-2.0-0.dll" File "${PKG_ROOT}\bin\libgmodule-2.0-0.dll" File "${PKG_ROOT}\bin\libgobject-2.0-0.dll" File "${PKG_ROOT}\bin\libgthread-2.0-0.dll" File "${PKG_ROOT}\bin\libgtk-win32-2.0-0.dll" File "${PKG_ROOT}\bin\intl.dll" File "${PKG_ROOT}\bin\libpango-1.0-0.dll" File "${PKG_ROOT}\bin\libpangocairo-1.0-0.dll" File "${PKG_ROOT}\bin\libpangoft2-1.0-0.dll" File "${PKG_ROOT}\bin\libpangowin32-1.0-0.dll" File "${PKG_ROOT}\bin\libpng14-14.dll" File "${PKG_ROOT}\bin\libstdc++-6.dll" File "${PKG_ROOT}\bin\libpopt-0.dll" File "${PKG_ROOT}\bin\pthreadGC2.dll" File "${PKG_ROOT}\bin\libwinpthread-1.dll" File "${PKG_ROOT}\bin\readline5.dll" File "${PKG_ROOT}\bin\zlib1.dll" File "${PKG_ROOT}\bin\ws2_32.dll" SetOutPath "$INSTDIR\doc" File "${GPSIM_ROOT}\doc\gpsim.lyx" File "${GPSIM_ROOT}\doc\gpsim.ps" File "${GPSIM_ROOT}\doc\gpsim.pdf" SetOutPath "$INSTDIR\doc\screenshots" File "${GPSIM_ROOT}\doc\screenshots\*.png" SetOutPath "$INSTDIR\etc\gtk-2.0" File "${PKG_ROOT}\share\themes\MS-Windows\gtk-2.0\gtkrc" SetOutPath "$INSTDIR\etc\pango" File "${PKG_ROOT}\etc\pango\pango.modules" SetOutPath "$INSTDIR\lib\gtk-2.0\2.10.0" File /r "${PKG_ROOT}\lib\gtk-2.0\2.10.0\engines" SetOutPath "$INSTDIR" File /r "${PKG_ROOT}\share" SetOutPath "$INSTDIR\lib\gpsim" File "${GPSIM_ROOT}\src\libgpsim.a" File "${GPSIM_ROOT}\plat\win32\modules.def" SetOutPath "$INSTDIR\" File "${GPSIM_ROOT}\ChangeLog.txt" File "${GPSIM_ROOT}\plat\win32\gpsim.ico" File "${GPSIM_ROOT}\COPYING.TXT" File "${GPSIM_ROOT}\README.TXT" SetOutPath "$INSTDIR\include\gpsim" File "${GPSIM_ROOT}\src\*.h" SetOutPath "$INSTDIR\examples\12bit" File "${GPSIM_ROOT}\examples\12bit\*.asm" File "${GPSIM_ROOT}\examples\12bit\*.inc" File "${GPSIM_ROOT}\examples\12bit\*.stc" SetOutPath "$INSTDIR\examples\14bit" File "${GPSIM_ROOT}\examples\14bit\*.asm" File "${GPSIM_ROOT}\examples\14bit\*.stc" SetOutPath "$INSTDIR\examples\16bit" File "${GPSIM_ROOT}\examples\16bit\*.asm" File "${GPSIM_ROOT}\examples\16bit\*.inc" SetOutPath "$INSTDIR\examples\modules\led_test" File "${GPSIM_ROOT}\examples\modules\led_test\README" File "${GPSIM_ROOT}\examples\modules\led_test\Makefile" File "${GPSIM_ROOT}\examples\modules\led_test\*.asm" File "${GPSIM_ROOT}\examples\modules\led_test\*.stc" SetOutPath "$INSTDIR\examples\modules\logic_test" File "${GPSIM_ROOT}\examples\modules\logic_test\README" File "${GPSIM_ROOT}\examples\modules\logic_test\Makefile" File "${GPSIM_ROOT}\examples\modules\logic_test\*.asm" File "${GPSIM_ROOT}\examples\modules\logic_test\*.stc" SetOutPath "$INSTDIR\examples\modules\mod_test" File "${GPSIM_ROOT}\examples\modules\mod_test\README" File "${GPSIM_ROOT}\examples\modules\mod_test\Makefile" File "${GPSIM_ROOT}\examples\modules\mod_test\*.asm" File "${GPSIM_ROOT}\examples\modules\mod_test\*.stc" SetOutPath "$INSTDIR\examples\modules\paraface_test" File "${GPSIM_ROOT}\examples\modules\paraface_test\Makefile" File "${GPSIM_ROOT}\examples\modules\paraface_test\*.asm" File "${GPSIM_ROOT}\examples\modules\paraface_test\*.stc" SetOutPath "$INSTDIR\examples\modules\usart_gui" File "${GPSIM_ROOT}\examples\modules\usart_gui\README" File "${GPSIM_ROOT}\examples\modules\usart_gui\Makefile" File "${GPSIM_ROOT}\examples\modules\usart_gui\*.asm" File "${GPSIM_ROOT}\examples\modules\usart_gui\*.stc" SetOutPath "$INSTDIR\examples\modules\usart_test" File "${GPSIM_ROOT}\examples\modules\usart_test\README" File "${GPSIM_ROOT}\examples\modules\usart_test\Makefile" File "${GPSIM_ROOT}\examples\modules\usart_test\*.asm" File "${GPSIM_ROOT}\examples\modules\usart_test\*.stc" SetOutPath "$INSTDIR\examples\projects" File "${GPSIM_ROOT}\examples\projects\README" SetOutPath "$INSTDIR\examples\projects\digital_stim" File "${GPSIM_ROOT}\examples\projects\digital_stim\Makefile" File "${GPSIM_ROOT}\examples\projects\digital_stim\ChangeLog" File "${GPSIM_ROOT}\examples\projects\digital_stim\README" File "${GPSIM_ROOT}\examples\projects\digital_stim\digital_stim.asm" File "${GPSIM_ROOT}\examples\projects\digital_stim\digital_stim.stc" SetOutPath "$INSTDIR\examples\projects\p16f628_test" File "${GPSIM_ROOT}\examples\projects\p16f628_test\ChangeLog" File "${GPSIM_ROOT}\examples\projects\p16f628_test\Makefile" File "${GPSIM_ROOT}\examples\projects\p16f628_test\README" File "${GPSIM_ROOT}\examples\projects\p16f628_test\f628.asm" File "${GPSIM_ROOT}\examples\projects\p16f628_test\f628.stc" SetOutPath "$INSTDIR\examples\projects\stack_test" File "${GPSIM_ROOT}\examples\projects\stack_test\ChangeLog" File "${GPSIM_ROOT}\examples\projects\stack_test\Makefile" File "${GPSIM_ROOT}\examples\projects\stack_test\README" File "${GPSIM_ROOT}\examples\projects\stack_test\stack_test.asm" File "${GPSIM_ROOT}\examples\projects\stack_test\stack_test.stc" SetOutPath "$INSTDIR\examples\scripts" File "${GPSIM_ROOT}\examples\scripts\makefile" File "${GPSIM_ROOT}\examples\scripts\README" File "${GPSIM_ROOT}\examples\scripts\*.cc" File "${GPSIM_ROOT}\examples\scripts\*.h" File "${GPSIM_ROOT}\examples\scripts\*.asm" File "${GPSIM_ROOT}\examples\scripts\*.py" SetOutPath "$INSTDIR\extras\lcd\examples" File "${GPSIM_ROOT}\extras\lcd\examples\Makefile" File "${GPSIM_ROOT}\extras\lcd\examples\README" File "${GPSIM_ROOT}\extras\lcd\examples\lcd.asm" File "${GPSIM_ROOT}\extras\lcd\examples\lcd.inc" File "${GPSIM_ROOT}\extras\lcd\examples\icons.inc" File "${GPSIM_ROOT}\extras\lcd\examples\lcd_916.asm" File "${GPSIM_ROOT}\extras\lcd\examples\lcd_917.asm" File "${GPSIM_ROOT}\extras\lcd\examples\lcd_mod.asm" File "${GPSIM_ROOT}\extras\lcd\examples\lcd_mod.stc" File "${GPSIM_ROOT}\extras\lcd\examples\lcdmemtest.c" File "${GPSIM_ROOT}\extras\lcd\examples\lcdmemtest.stc" File "${GPSIM_ROOT}\extras\lcd\examples\screen.asm" File "${GPSIM_ROOT}\extras\lcd\examples\screen.inc" SetOutPath "$INSTDIR\extras\graphic_lcd\examples\sed1520" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\18f452.lkr" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\Makefile" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\bitmaps.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\glcd_test.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\globalvars.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\lcd100X32.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\lcd100X32.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\portdef.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\processor.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\sed1520.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\sed1520\sed1520.inc" SetOutPath "$INSTDIR\extras\graphic_lcd\examples\ssd0323" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\18f452.lkr" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\Makefile" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\bitmaps.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\glcd_test.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\globalvars.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\osram128x64.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\osram128x64.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\portdef.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\processor.inc" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\ssd0323.asm" File "${GPSIM_ROOT}\extras\graphic_lcd\examples\ssd0323\ssd0323.inc" SetOutPath "$INSTDIR\extras\graphic_lcd\utils" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\README" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\custom.png" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\fontimage.png" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\gpsim1.png" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\konqueror.png" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\konqueror16X16.png" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\konqueror3.png" File "${GPSIM_ROOT}\extras\graphic_lcd\utils\pngtopic.c" SetOutPath "$INSTDIR\extras\graphic_lcd\doc" File "${GPSIM_ROOT}\extras\graphic_lcd\doc\*.pdf" SetOutPath "$INSTDIR\extras\rs232-gen\example" File "${GPSIM_ROOT}\extras\rs232-gen\example\Makefile" File "${GPSIM_ROOT}\extras\rs232-gen\example\README" File "${GPSIM_ROOT}\extras\rs232-gen\example\example.asm" File "${GPSIM_ROOT}\extras\rs232-gen\example\example.stc" SetOutPath "$INSTDIR\extras\rs232-gen" File "${GPSIM_ROOT}\extras\rs232-gen\Makefile" File "${GPSIM_ROOT}\extras\rs232-gen\README" File "${GPSIM_ROOT}\extras\rs232-gen\rs232-gen.c" SetOutPath "$INSTDIR\extras\ds1307\examples" File "${GPSIM_ROOT}\extras\ds1307\examples\ds1307.asm" File "${GPSIM_ROOT}\extras\ds1307\examples\i2c_low.inc" File "${GPSIM_ROOT}\extras\ds1307\examples\Makefile" File "${GPSIM_ROOT}\extras\ds1307\examples\README" SetOutPath "$INSTDIR\extras\ds1820\examples" File "${GPSIM_ROOT}\extras\ds1820\examples\ds1820.asm" File "${GPSIM_ROOT}\extras\ds1820\examples\ds18b20.asm" File "${GPSIM_ROOT}\extras\ds1820\examples\Makefile" File "${GPSIM_ROOT}\extras\ds1820\examples\README" SetOutPath "$INSTDIR\extras\dht11\examples" File "${GPSIM_ROOT}\extras\dht11\examples\dht11_example.asm" File "${GPSIM_ROOT}\extras\dht11\examples\Makefile" File "${GPSIM_ROOT}\extras\dht11\examples\README" SectionEnd Section "extras modules" SEC02 SectionIn 1 SetOutPath "$INSTDIR\bin" SetOverwrite ifnewer File "${GPSIM_ROOT}\extras\libgpsim_extras.dll" SectionEnd ;-------------------------------- ;Descriptions ;Language strings LangString DESC_SEC01 ${LANG_ENGLISH} "gpim" LangString DESC_SEC02 ${LANG_ENGLISH} "extras modules" ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} $(DESC_SEC01) !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} $(DESC_SEC02) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- Section -Icons Call CreateBatFile WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.bat" "" "$INSTDIR\gpsim.ico" "" "" "" "" ; CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.bat" "" "$INSTDIR\gpsim.ico" "" "" "" "" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\${PRODUCT_NAME} on the Web.lnk" "$INSTDIR\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\Documentation.lnk" "$INSTDIR\doc\gpsim.pdf" "" "$INSTDIR\gpsim.ico" "" "" "" "" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\Change Log.lnk" "$INSTDIR\ChangeLog.txt" "" "$INSTDIR\gpsim.ico" "" "" "" "" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\README.lnk" "$INSTDIR\README.TXT" "" "$INSTDIR\gpsim.ico" "" "" "" "" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\GPL 2 License.lnk" "$INSTDIR\COPYING.TXT" CreateShortCut "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\Uninstall.lnk" "$INSTDIR\uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd Section -Post WriteRegStr HKLM "Software\${PRODUCT_NAME}" "" $INSTDIR !ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD WriteRegDword HKLM "Software\${PRODUCT_NAME}" "VersionMajor" "${VER_MAJOR}" WriteRegDword HKLM "Software\${PRODUCT_NAME}" "VersionMinor" "${VER_MINOR}" WriteRegDword HKLM "Software\${PRODUCT_NAME}" "VersionRevision" "${VER_REVISION}" WriteRegDword HKLM "Software\${PRODUCT_NAME}" "VersionBuild" "${VER_BUILD}" !endif WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\gpsim.bat" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "Path" "$INSTDIR" WriteUninstaller "$INSTDIR\uninstall.exe" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninstall.exe" ; WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\gpsim.exe" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd Section Uninstall ; Remove StartMenu !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_STARTMENUPAGE_VARIABLE Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\${PRODUCT_NAME}.lnk" Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\${PRODUCT_NAME} on the Web.lnk" Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\Documentation.lnk" Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\Change Log.lnk" Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\README.lnk" Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\GPL 2 License.lnk" Delete "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE\Uninstall.lnk" RMDir "$SMPROGRAMS\$MUI_STARTMENUPAGE_VARIABLE" ; Remove installation directory Delete "$INSTDIR\${PRODUCT_NAME}.url" Delete "$INSTDIR\.gpsim" Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\README.TXT" Delete "$INSTDIR\COPYING.TXT" Delete "$INSTDIR\gpsim.bat" Delete "$INSTDIR\gpsim.ico" Delete "$INSTDIR\ChangeLog.txt" Delete "$INSTDIR\bin\libgpsim_modules.dll" Delete "$INSTDIR\bin\libgpsim_extras.dll" Delete "$INSTDIR\examples\12bit\*.*" Delete "$INSTDIR\examples\14bit\*.*" Delete "$INSTDIR\examples\16bit\*.*" Delete "$INSTDIR\examples\modules\led_test\*.*" Delete "$INSTDIR\examples\modules\logic_test\*.*" Delete "$INSTDIR\examples\modules\mod_test\*.*" Delete "$INSTDIR\examples\modules\paraface_test\*.*" Delete "$INSTDIR\examples\modules\usart_gui\*.*" Delete "$INSTDIR\examples\modules\usart_test\*.*" Delete "$INSTDIR\examples\projects\digital_stim\*.*" Delete "$INSTDIR\examples\projects\p16f628_test\*.*" Delete "$INSTDIR\examples\projects\stack_test\*.*" Delete "$INSTDIR\examples\projects\*.*" Delete "$INSTDIR\examples\scripts\*.*" Delete "$INSTDIR\extras\graphics_lcd\doc\*.*" Delete "$INSTDIR\extras\graphics_lcd\utils\*.*" Delete "$INSTDIR\extras\graphics_lcd\src\*.*" Delete "$INSTDIR\extras\graphics_lcd\examples\*.*" Delete "$INSTDIR\extras\graphics_lcd\*.*" Delete "$INSTDIR\extras\lcd\examples\*.*" Delete "$INSTDIR\extras\lcd\*.*" Delete "$INSTDIR\extras\rs232-gen\example\*.*" Delete "$INSTDIR\extras\rs232-gen\*.*" Delete "$INSTDIR\extras\ds1307\examples\*.*" Delete "$INSTDIR\extras\ds1307\*.*" Delete "$INSTDIR\extras\ds1820\examples\*.*" Delete "$INSTDIR\extras\ds1820\examples\*" Delete "$INSTDIR\extras\ds1820\*.*" Delete "$INSTDIR\extras\dht11\examples\*.*" Delete "$INSTDIR\extras\dht11\examples\README" Delete "$INSTDIR\extras\dht11\*.*" Delete "$INSTDIR\extras\dht11\README" Delete "$INSTDIR\extras\dht11\AUTHORS" Delete "$INSTDIR\lib\gpsim\libgpsim.a" Delete "$INSTDIR\lib\gpsim\modules.def" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-arabic-fc.dll" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-basic-fc.dll" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-basic-win32.dll" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-hangul-fc.dll" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-hebrew-fc.dll" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-indic-fc.dll" Delete "$INSTDIR\lib\pango\1.5.0\modules\pango-thai-fc.dll" Delete "$INSTDIR\etc\pango\pango.modules" Delete "$INSTDIR\etc\gtk-2.0\gtkrc" Delete "$INSTDIR\doc\gpsim.lyx" Delete "$INSTDIR\doc\gpsim.ps" Delete "$INSTDIR\doc\gpsim.pdf" Delete "$INSTDIR\doc\screenshots\*.png" Delete "$INSTDIR\bin\freetype6.dll" Delete "$INSTDIR\bin\gpsim.exe" Delete "$INSTDIR\bin\iconv.dll" Delete "$INSTDIR\bin\libatk-1.0-0.dll" Delete "$INSTDIR\bin\libcairo-2.dll" Delete "$INSTDIR\bin\libcairo-gobject-2.dll" Delete "$INSTDIR\bin\libcairo-script-interpreter-2.dll" Delete "$INSTDIR\bin\libgailutil-18.dll" Delete "$INSTDIR\bin\libexpat-1.dll" Delete "$INSTDIR\bin\libfontconfig-1.dll" Delete "$INSTDIR\bin\${LIBGCCDDL}" Delete "$INSTDIR\bin\libgdk_pixbuf-2.0-0.dll" Delete "$INSTDIR\bin\libgdk-win32-2.0-0.dll" Delete "$INSTDIR\bin\libgio-2.0-0.dll" Delete "$INSTDIR\bin\libglib-2.0-0.dll" Delete "$INSTDIR\bin\libgmodule-2.0-0.dll" Delete "$INSTDIR\bin\libgobject-2.0-0.dll" Delete "$INSTDIR\bin\libgpsim.dll" Delete "$INSTDIR\bin\libgthread-2.0-0.dll" Delete "$INSTDIR\bin\libgtk-win32-2.0-0.dll" Delete "$INSTDIR\bin\intl.dll" Delete "$INSTDIR\bin\gtkextra-win32-2.1.dll" Delete "$INSTDIR\bin\libpango-1.0-0.dll" Delete "$INSTDIR\bin\libpangocairo-1.0-0.dll" Delete "$INSTDIR\bin\libpangoft2-1.0-0.dll" Delete "$INSTDIR\bin\libpangowin32-1.0-0.dll" Delete "$INSTDIR\bin\libpng14-14.dll" Delete "$INSTDIR\bin\libstdc++-6.dll" Delete "$INSTDIR\bin\libpopt-0.dll" Delete "$INSTDIR\bin\pthreadGC2.dll" Delete "$INSTDIR\bin\libwinpthread-1.dll" Delete "$INSTDIR\bin\readline5.dll" Delete "$INSTDIR\bin\zlib1.dll" Delete "$INSTDIR\bin\libgcc_s_sjlj-1.dll" Delete "$INSTDIR\bin\ws2_32.dll" Delete "$SMPROGRAMS\gpsim\Uninstall.lnk" Delete "$SMPROGRAMS\gpsim\Website.lnk" Delete "$DESKTOP\gpsim.lnk" Delete "$SMPROGRAMS\gpsim\gpsim.lnk" Delete "$INSTDIR\include\gpsim\*.h" RMDir "$SMPROGRAMS\gpsim" RMDir "$INSTDIR\lib\gpsim" RMDir "$INSTDIR\lib\pango\1.5.0\modules" RMDir "$INSTDIR\lib\pango\1.5.0" RMDir "$INSTDIR\lib\pango" RMDir /r "$INSTDIR\lib\gtk-2.0\2.10.0\engines" RMDir "$INSTDIR\lib\gtk-2.0\2.10.0" RMDir "$INSTDIR\lib\gtk-2.0" RMDir "$INSTDIR\lib" RMDir /r "$INSTDIR\share" RMDir "$INSTDIR\etc\pango" RMDir "$INSTDIR\etc\gtk-2.0" RMDir "$INSTDIR\etc" RMDir "$INSTDIR\doc\screenshots" RMDir "$INSTDIR\doc" RMDir "$INSTDIR\bin" RMDir "$INSTDIR\modules" RMDir "$INSTDIR\examples\12bit" RMDir "$INSTDIR\examples\14bit" RMDir "$INSTDIR\examples\16bit" RMDir "$INSTDIR\examples\modules\led_test" RMDir "$INSTDIR\examples\modules\logic_test" RMDir "$INSTDIR\examples\modules\mod_test" RMDir "$INSTDIR\examples\modules\paraface_test" RMDir "$INSTDIR\examples\modules\usart_gui" RMDir "$INSTDIR\examples\modules\usart_test" RMDir "$INSTDIR\examples\modules" RMDir "$INSTDIR\examples\projects\digital_stim" RMDir "$INSTDIR\examples\projects\p16f628_test" RMDir "$INSTDIR\examples\projects\stack_test" RMDir "$INSTDIR\examples\projects" RMDir "$INSTDIR\examples\scripts" RMDir "$INSTDIR\examples" RMDir /r "$INSTDIR\extras\graphic_lcd" RMDir "$INSTDIR\extras\lcd\examples" RMDir "$INSTDIR\extras\lcd" RMDir "$INSTDIR\extras\rs232-gen\example" RMDir "$INSTDIR\extras\rs232-gen" RMDir "$INSTDIR\extras\ds1307\examples" RMDir "$INSTDIR\extras\ds1307" RMDir "$INSTDIR\extras\ds1820\examples" RMDir "$INSTDIR\extras\ds1820" RMDir "$INSTDIR\extras\dht11\examples" RMDir "$INSTDIR\extras\dht11" RMDir "$INSTDIR\extras" RMDir "$INSTDIR\include\gpsim" RMDir "$INSTDIR\include" RMDir "$INSTDIR" ; Clean the registry DeleteRegValue HKLM ${PRODUCT_UNINST_KEY} "NSIS:StartMenuDir" DeleteRegKey HKLM "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" DeleteRegKey HKLM "Software\${PRODUCT_NAME}" ;;;; SetAutoClose true SectionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Functions ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !verbose 4 ; CreateBatFile - Create gpsim.bat. Function CreateBatFile Push $0 FileOpen $0 "$INSTDIR\${PRODUCT_NAME}.bat$\r$\n" w FileWrite $0 "@echo off$\r$\n" FileWrite $0 "set PATH=$INSTDIR\bin;%PATH%$\r$\n" FileWrite $0 "$\"$INSTDIR\bin\${PRODUCT_NAME}$\" %1 %2 %3 %4 %5 %6 %7 %8 %9$\r$\n" FileClose $0 Pop $0 FunctionEnd ; Uninstall/Reinstall page !ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD Var ReinstallPageCheck Function PageReinstall ReadRegStr $R0 HKLM "Software\${PRODUCT_NAME}" "" ${If} $R0 == "" ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" ${If} $R0 == "" Abort ${EndIf} ${EndIf} ReadRegDWORD $R0 HKLM "Software\${PRODUCT_NAME}" "VersionMajor" ReadRegDWORD $R1 HKLM "Software\${PRODUCT_NAME}" "VersionMinor" ReadRegDWORD $R2 HKLM "Software\${PRODUCT_NAME}" "VersionRevision" ReadRegDWORD $R3 HKLM "Software\${PRODUCT_NAME}" "VersionBuild" StrCpy $R0 $R0.$R1.$R2.$R3 ${VersionCompare} ${VER_MAJOR}.${VER_MINOR}.${VER_REVISION}.${VER_BUILD} $R0 $R0 ${If} $R0 == 0 StrCpy $R1 "${PRODUCT_NAME} ${PRODUCT_VERSION} is already installed. Select the operation you want to perform and click Next to continue." StrCpy $R2 "Add/Reinstall components" StrCpy $R3 "Uninstall ${PRODUCT_NAME}" !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform." StrCpy $R0 "2" ${ElseIf} $R0 == 1 StrCpy $R1 "An older version of ${PRODUCT_NAME} is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue." StrCpy $R2 "Uninstall before installing" StrCpy $R3 "Do not uninstall" !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install ${PRODUCT_NAME}." StrCpy $R0 "1" ${ElseIf} $R0 == 2 StrCpy $R1 "A newer version of ${PRODUCT_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it's better to uninstall the current version first. Select the operation you want to perform and click Next to continue." StrCpy $R2 "Uninstall before installing" StrCpy $R3 "Do not uninstall" !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install ${PRODUCT_NAME}." StrCpy $R0 "1" ${Else} Abort ${EndIf} nsDialogs::Create /NOUNLOAD 1018 ${NSD_CreateLabel} 0 0 100% 24u $R1 Pop $R1 ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2 Pop $R2 ${NSD_OnClick} $R2 PageReinstallUpdateSelection ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3 Pop $R3 ${NSD_OnClick} $R3 PageReinstallUpdateSelection ${If} $ReinstallPageCheck != 2 SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0 ${Else} SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0 ${EndIf} nsDialogs::Show FunctionEnd Function PageReinstallUpdateSelection Pop $R1 ${NSD_GetState} $R2 $R1 ${If} $R1 == ${BST_CHECKED} StrCpy $ReinstallPageCheck 1 ${Else} StrCpy $ReinstallPageCheck 2 ${EndIf} FunctionEnd Function PageLeaveReinstall ${NSD_GetState} $R2 $R1 StrCmp $R0 "1" 0 +2 StrCmp $R1 "1" reinst_uninstall reinst_done StrCmp $R0 "2" 0 +3 StrCmp $R1 "1" reinst_done reinst_uninstall reinst_uninstall: ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" ;Run uninstaller HideWindow ClearErrors ExecWait '$R1 _?=$INSTDIR' IfErrors no_remove_uninstaller IfFileExists "$INSTDIR\bin\${PRODUCT_NAME}.exe" no_remove_uninstaller Delete $R1 RMDir $INSTDIR no_remove_uninstaller: StrCmp $R0 "2" 0 +2 Quit BringToFront reinst_done: FunctionEnd !endif # VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD gpsim-0.30.0/plat/win32/configure_win32.awk0000664000076400007640000000423513041763624015267 00000000000000#!/usr/bin/awk # configure_win32.awk - Genarate config.h using config_win32.h.in as template # and insert the version number definitions from configure.ac # # Written By - Borut Razem borut.razem@siol.net # # This file is part of gpsim. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2, or (at your option) any # later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. BEGIN { # get the values from configure.ac while (getline <"configure.ac" > 0) { if ($0 ~ "^AC_INIT\\(.*\\)") { package = gensub("^AC_INIT\\(\\[([^]]*)\\].*", "\\1", "1", $0); version = gensub("^AC_INIT\\(\\[[^]]*\\], \\[([^]]*)\\].*", "\\1", "1", $0); bugreport = gensub("^AC_INIT\\(\\[[^]]*\\], \\[[^]]*\\], \\[([^]]*)\\].*", "\\1", "1", $0); } } print("/* config.h */"); print("/* Generated automatically by configure_win32.awk, DO NOT EDIT! */"); print("/* To make changes to config.h edit config_win32.h.in instead. */"); print(""); } /^#undef PACKAGE_BUGREPORT/ { print("#define PACKAGE_BUGREPORT \"" bugreport "\""); next; } /^#undef PACKAGE_NAME/ { print("#define PACKAGE_NAME \"" package "\""); next; } /^#undef PACKAGE_STRING/ { print("#define PACKAGE_STRING \"" package " " version "\""); next; } /^#undef PACKAGE_TARNAME/ { print("#define PACKAGE_TARNAME \"" package "\""); next; } /^#undef PACKAGE_VERSION/ { print("#define PACKAGE_VERSION \"" version "\""); next } /^#undef PACKAGE/ { print("#define PACKAGE \"" package "\""); next; } /^#undef VERSION/ { print("#define VERSION \"" version "\""); next; } { print; } gpsim-0.30.0/plat/win32/gpsim.ico0000664000076400007640000000206613041763624013373 00000000000000 č&(( @€€€€€€€€€ŔŔŔ€€€˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙( €€€€€€€€€€ŔŔŔ€€€˙˙˙˙˙˙˙˙˙˙˙˙xxxxxxxxwwwwwwwwuÝ×]]w]www]]]w]ww]×]]]]wu×w]]ŐÝww]Ý]]w]wwwwwwwwwww]×]wwwwu×]]ÝwwwuŐÝ]u×wwu×w]u×www]Ý]Ýwwwwwwwwwwxxxxxxxx˙˙gpsim-0.30.0/plat/win32/modules.def0000664000076400007640000000003113041763624013676 00000000000000EXPORTS get_mod_list gpsim-0.30.0/plat/win32/uxsleep.cc0000664000076400007640000000407413041763624013555 00000000000000/* Copyright (C) 2003-2006 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Definitions, missing in MSVC libraries */ #include #include #include "uxtime.h" #ifdef __cplusplus extern "C" { #endif int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { int res = 0; HANDLE dummy_event; int rc; DWORD req, start_time, end_time, now, rem; if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec > 999999999) { errno = EINVAL; return -1; } dummy_event = CreateEvent (NULL, TRUE, FALSE, NULL); req = rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 500000) / 1000000; start_time = GetTickCount(); end_time = start_time + req; rc = WaitForSingleObject(dummy_event, req); now = GetTickCount(); CloseHandle(dummy_event); rem = (rc == WAIT_TIMEOUT || now >= end_time) ? 0 : end_time - now; if (rc == WAIT_OBJECT_0) { errno = EINTR; res = -1; } if (rmtp) { rmtp->tv_sec = rem / 1000; rmtp->tv_nsec = (rem % 1000) * 1000000; } return res; } unsigned int usleep(unsigned int useconds) { struct timespec req; req.tv_sec = useconds / 1000000; req.tv_nsec = (useconds % 1000000) * 1000; return nanosleep(&req, 0); } unsigned int sleep(unsigned int seconds) { Sleep(seconds * 1000); return 0; } #ifdef __cplusplus } #endif gpsim-0.30.0/plat/win32/fd2raw.h0000664000076400007640000000157413060754614013121 00000000000000/* Copyright (C) 2004 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _FD2RAW_H #define _FD2RAW_H #include #ifdef __cplusplus extern "C" { #endif bool win32_fd_to_raw(int fd); #ifdef __cplusplus } #endif #endif gpsim-0.30.0/plat/win32/settings_reg.h0000664000076400007640000000236013041763624014423 00000000000000/* Copyright (C) 2004 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SETTINGS_REG_H #define _SETTINGS_REG_H #include "settings.h" class SettingsReg: public Settings { public: SettingsReg(const char *appl_name); virtual bool set(const char *module, const char *entry, const char *str); virtual bool set(const char *module, const char *entry, int value); virtual bool get(const char *module, const char *entry, char **str); virtual bool get(const char *module, const char *entry, int *value); virtual bool remove(const char *module, const char *entry); }; #endif //_SETTINGS_REG_H gpsim-0.30.0/plat/win32/settings_reg.cpp0000664000076400007640000000606513041763624014764 00000000000000/* Copyright (C) 2004 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "settings_reg.h" #define REG_PATH_PREFIX_STR "Software\\" SettingsReg::SettingsReg(const char *appl_name) { name = string(REG_PATH_PREFIX_STR) + appl_name + "\\"; } bool SettingsReg::set(const char *module, const char *entry, const char *str) { HKEY key; bool ret = true; DWORD disposition; string reg_path = name + module; if (RegCreateKeyEx(HKEY_CURRENT_USER, reg_path.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &disposition) != ERROR_SUCCESS) return 0; if (RegSetValueEx(key, entry, 0, REG_SZ, (LPBYTE)str, strlen(str) + 1) != ERROR_SUCCESS) ret = 0; RegCloseKey(key); return ret; } bool SettingsReg::set(const char *module, const char *entry, int value) { HKEY key; bool ret = true; DWORD disposition; string reg_path = name + module; if (RegCreateKeyEx(HKEY_CURRENT_USER, reg_path.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &disposition) != ERROR_SUCCESS) return 0; if (RegSetValueEx(key, entry, 0, REG_BINARY, (LPBYTE)&value, sizeof value) != ERROR_SUCCESS) ret = 0; RegCloseKey(key); return ret; } bool SettingsReg::get(const char *module, const char *entry, char **str) { static char buf[256]; HKEY key; bool ret = true; DWORD size = sizeof buf; string reg_path = name + module; if (RegOpenKeyEx(HKEY_CURRENT_USER, reg_path.c_str(), 0, KEY_READ, &key) != ERROR_SUCCESS) return 0; if (RegQueryValueEx(key, entry, NULL, NULL, (LPBYTE)buf, &size) != ERROR_SUCCESS) ret = 0; else *str = buf; RegCloseKey(key); return ret; } bool SettingsReg::get(const char *module, const char *entry, int *value) { HKEY key; bool ret = true; DWORD size = sizeof *value; string reg_path = name + module; if (RegOpenKeyEx(HKEY_CURRENT_USER, reg_path.c_str(), 0, KEY_READ, &key) != ERROR_SUCCESS) return 0; if (RegQueryValueEx(key, entry, NULL, NULL, (LPBYTE)value, &size) != ERROR_SUCCESS) ret = 0; RegCloseKey(key); return ret; } bool SettingsReg::remove(const char *module, const char *entry) { HKEY key; bool ret = true; string reg_path = name + module; if (RegOpenKeyEx(HKEY_CURRENT_USER, reg_path.c_str(), 0, KEY_SET_VALUE, &key) != ERROR_SUCCESS) return 0; if (RegDeleteValue(key, entry) != ERROR_SUCCESS) ret = 0; RegCloseKey(key); return ret; } gpsim-0.30.0/plat/win32/unistd.h0000664000076400007640000000176113060754614013240 00000000000000/* Copyright (C) 2003 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Declarations, missing in MSVC header files, normaly defined in */ #ifndef __UNISTD_H #define __UNISTD_H #ifdef __cplusplus extern "C" { #endif unsigned int usleep(unsigned int usec); unsigned int sleep(unsigned int seconds); #ifdef __cplusplus } #endif #endif gpsim-0.30.0/plat/win32/icd.cc0000664000076400007640000000324413060754614012625 00000000000000/* Copyright (C) 2003 BorutRazem This is based on the program icdprog 0.3 made by Geir Thomassen gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpasm; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Dummy icd implementation for WIN32 platform. */ #include #include #include #include #include #include #include "icd.h" bool get_use_icd() { return false; } const char *icd_target() { return "no target"; } const char *icd_version() { return "%0.00.00"; } int icd_halt(void) { return 1; } float icd_vdd(void) { return 0.0; } float icd_vpp(void) { return 0.0; } int icd_clear_break(void) { return 1; } int icd_connect(const char *port) { return 1; } int icd_detected(void) { return 0; } int icd_disconnect(void) { return 1; } int icd_has_debug_module(void) { return 0; } int icd_reset(void) { return 1; } int icd_run(void) { return 1; } int icd_stopped(void) { return 0; } int icd_set_break(int address) { return 1; } int icd_step(void) { return 1; } void icd_set_bulk(int flag) { } gpsim-0.30.0/plat/win32/fd2raw.cpp0000664000076400007640000000526613060754614013456 00000000000000/* Copyright (C) 2004-2006 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "fd2raw.h" #if defined _MSC_VER && _MSC_VER >= 1300 /* * a hack to call _setmode() from MSVCRT.DLL: * glib runtime uses MSVCRT.DLL, while gpsim executable uses MSVCR71.DLL. * To set the mode of file handle, which is used in glib, the _setmode() * from MSVCRT.DLL should be called. */ static int win32_setmode(int fd, int mode) { int ret = -1; HINSTANCE hinst; /* get a handle to the DLL module */ hinst = LoadLibrary("MSVCRT.DLL"); /* if the handle is valid, try to get the function address */ if (NULL == hinst) { gchar *emsg = g_win32_error_message(GetLastError()); g_error("Error loading library MSVCRT.DLL: %s", emsg); g_free(emsg); } else { int (*proc_add)(int, int); proc_add = (int (*)(int, int)) GetProcAddress(hinst, "_setmode"); /* if the function address is valid, call the function */ if (NULL == proc_add) { gchar *emsg = g_win32_error_message(GetLastError()); g_error("Error retriving address of function _setmode: %s", emsg); g_free(emsg); } else ret = (proc_add) (fd, mode); /* free the DLL module */ if (0 == FreeLibrary(hinst)) { gchar *emsg = g_win32_error_message(GetLastError()); g_error("Error freeing the DLL module: %s", emsg); g_free(emsg); } } return ret; } #endif /* * set file descriptor to raw mode */ bool win32_fd_to_raw(int fd) { HANDLE handle = (HANDLE)_get_osfhandle(fd); /* if a console */ if (0 != (GetFileType(handle) & FILE_TYPE_CHAR)) { DWORD orig_mode; /* set it to raw mode */ GetConsoleMode(handle, &orig_mode); SetConsoleMode(handle, orig_mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)); #if defined _MSC_VER && _MSC_VER >= 1300 win32_setmode(0, _O_BINARY); #else setmode(0, _O_BINARY); #endif return true; } return false; } gpsim-0.30.0/plat/win32/uxtime.h0000664000076400007640000000276613041763624013253 00000000000000/* Copyright (C) 2003-2006 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Declarations, missing in MSVC header files, normaly defined in and */ #ifndef _UXTIME_H #define _UXTIME_H #include #ifdef __cplusplus extern "C" { #endif /* * Structure returned by gettimeofday(2) system call */ #ifdef _MSC_VER #ifndef _WINSOCKAPI_ struct timeval { unsigned long tv_sec; /* seconds */ long tv_usec; /* and microseconds */ }; struct timezone { int tz_minuteswest; int tz_dsttime; }; #endif int gettimeofday(struct timeval *tv, struct timezone *tz); #endif #ifndef _TIMESPEC_DEFINED #define _TIMESPEC_DEFINED struct timespec { time_t tv_sec; /* Seconds */ long tv_nsec; /* Nanoseconds */ }; #endif int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); #ifdef __cplusplus } #endif #endif gpsim-0.30.0/plat/win32/make.mingw0000664000076400007640000000620413113676536013543 00000000000000# Common makefile definitions for building gpsim with gcc # on Win32 for a mingw configuration (for a description of # what mingw is, see http://www.mingw.org) # The makefile.mingw files in the source directories (or # subdirectories) all include this file right at the top after # defining some macros used here. ifdef DEBUG ifndef OPTIMIZE OPTIMIZE = -O2 -g endif CLDFLAGS = DEFINES = -DDEBUG else ifndef OPTIMIZE OPTIMIZE = -O2 endif CLDFLAGS = -Wl,--strip-all # uncomment the following line to disable assertions # DEFINES = -DNDEBUG endif ifndef WARNINGS WARNINGS = -Wall -Wno-format endif ifndef TOP TOP = .. endif ################ # Paths to external libraries GTK_PATH = $(TOP)/gtk+ GLIB_PATH = $(TOP)/glib CAIRO_PATH = $(TOP)/cairo PANGO_PATH = $(TOP)/pango ATK_PATH = $(TOP)/atk POPT_PATH = $(TOP)/popt READLINE_PATH = $(TOP)/readline PTHREAD_PATH = $(TOP)/pthreads GDK_PIXBUF_PATH = $(TOP)/gdk-pixbuf ################ # Compiler to use. The -fnative-struct switch is important so that the # produced libraries are also callable from MSVC-compiled code. Only # gcc 2.95 or later for mingw (distributed by Mumit Khan) have the # -fnative-struct switch. # # ccache - Cache for gcc - saves time re-compiling # The ccache modifier is normally an empty string. However, if you # have ccache.exe install, then define # $ export CCACHE=ccache ## Cygwin / Mingw GCC 3.4.4 with -mno-cygwin support #CCOMPILER = $(CCACHE) gcc #CC = $(CCOMPILER) -mno-cygwin -mtune=pentium -mms-bitfields #CXXCOMPILER = $(CCACHE) c++ #CXX = $(CXXCOMPILER) -mno-cygwin -mtune=pentium -mms-bitfields # Mingw GCC 4.7.3 #CCOMPILER = $(CCACHE) i686-pc-mingw32-gcc #CC = $(CCOMPILER) -mtune=pentium -mms-bitfields #CXXCOMPILER = $(CCACHE) i686-pc-mingw32-c++ #CXX = $(CXXCOMPILER) -mtune=pentium -mms-bitfields # Mingw GCC 4.9.1 CCOMPILER = $(CCACHE) i686-w64-mingw32-gcc CC = $(CCOMPILER) -mtune=pentium -mms-bitfields CXXCOMPILER = $(CCACHE) i686-w64-mingw32-c++ CXX = $(CXXCOMPILER) -mtune=pentium -mms-bitfields ################ # Various other tools AR = ar ARFLAGS = rcs RM = rm -f MV = mv CP = cp AWK = gawk BISON = bison FLEX = flex ################ # The including makefile should define INCLUDES, DEFINES and # DEPCFLAGS. INCLUDES are the includes related to the module being # built. DEFINES similarly. DEPCFLAGS should be set to a set of # GLIB_CFLAGS, GTK_CFLAGS etc corresponding to what other modules we # depend on. CFLAGS = $(OPTIMIZE) $(INCLUDES) $(DEFINES) $(DEPCFLAGS) $(WARNINGS) ################ # name of auto-generated makefile MF=mf ################ # Useful rules .SUFFIXES: .c .cc .cpp .o .i .s .c.i: $(CC) $(CFLAGS) -E $< >$@ .c.s: $(CC) $(CFLAGS) -S $< -o $@ .cc.o: $(CXX) $(CFLAGS) -c $< -o $@ .cpp.o: $(CXX) $(CFLAGS) -c $< -o $@ # The default target should be "all" default: all clean:: -$(RM) *.o *.i *.exe *.dll *.a *.base *.exp *.lib *.def $(MF) depend: @echo Making dependencies @echo "# autogenerated dependency file" > depend $(CXX) $(CFLAGS) -E -MM *.cc >> depend @echo "# Automatically generated makefile" > ${MF} @echo "include makefile.mingw" >> ${MF} @echo "# dependency file" >> ${MF} @echo "include depend" >> ${MF} gpsim-0.30.0/plat/win32/makefile.mingw0000664000076400007640000000275313041763624014403 00000000000000## Makefile for building the gpsim setup executable on WIN32. ## The build uses tools running on cygwin. ## Use: make -f makefile.mingw UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Linux) MAKENSYS = makensis Z = - UNIX2DOS = unix2dos -n LIBGCCDLL = libgcc_s_sjlj-1.dll else MAKENSYS = "/cygdrive/c/Program Files/NSIS/makensis" Z = / UNIX2DOS = cp LIBGCCDLL = libgcc_s_dw2-1.dll endif DATE = $(shell date +%Y%m%d) VERSION = $(shell awk '/^AC_INIT\(\[[^]]*\], \[[^]]*\].*\).*/ {print(gensub("^AC_INIT\\(\\[[^]]*\\], \\[([^]]*)\\].*\\).*", "\\1", "1"))}' ../../configure.ac) VER_MAJOR = $(shell echo $(VERSION) | awk 'BEGIN { FS="."; getline; print $$1 }') VER_MINOR = $(shell echo $(VERSION) | awk 'BEGIN { FS="."; getline; print $$2 }') VER_REVISION = $(shell echo $(VERSION) | awk 'BEGIN { FS="."; getline; print $$3 }') VER_BUILD = 0 WEB_SITE = $(shell awk '/^AC_INIT\(\[[^]]*\], \[[^]]*\], \[<[^>]*>\].*\).*/ {print(gensub("^AC_INIT\\(\\[[^]]*\\], \\[[^]]*\\], \\[<([^>]*)>\\].*\\).*", "\\1", "1"))}' ../../configure.ac) all: doc $(MAKENSYS) $ZDDATE=$(DATE) $ZDVER_MAJOR=$(VER_MAJOR) $ZDVER_MINOR=$(VER_MINOR) $ZDVER_REVISION=$(VER_REVISION) $ZDVER_BUILD=$(VER_BUILD) $ZDPRODUCT_WEB_SITE=$(WEB_SITE) $ZDLIBGCCDDL=$(LIBGCCDDL) gpsim.nsi doc: ../../README.TXT ../../COPYING.TXT ../../ChangeLog.txt ../../README.TXT: ../../README $(UNIX2DOS) $< $@ ../../COPYING.TXT: ../../COPYING $(UNIX2DOS) $< $@ ../../ChangeLog.txt: ../../ChangeLog $(UNIX2DOS) $< $@ clean: gpsim-0.30.0/plat/win32/uxtime.cc0000664000076400007640000000254513041763624013404 00000000000000/* Copyright (C) 2003-2006 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Definitions, missing in MSVC libraries */ #include #include "uxtime.h" #ifdef __cplusplus extern "C" { #endif int gettimeofday(struct timeval *tv, struct timezone *tz) { ULARGE_INTEGER curr_time; FILETIME curr_file_time; /* get current system time as file time */ GetSystemTimeAsFileTime(&curr_file_time); curr_time.HighPart = curr_file_time.dwHighDateTime; curr_time.LowPart = curr_file_time.dwLowDateTime; curr_time.QuadPart -= 0x19db1ded53e8000LL; tv->tv_sec = (long)(curr_time.QuadPart / 10000000); tv->tv_usec = (long)((curr_time.QuadPart / 10) % 1000000); return 0; } #ifdef __cplusplus } #endif gpsim-0.30.0/plat/win32/libgpsim.def0000664000076400007640000007740313041763624014055 00000000000000EXPORTS ??0AbstractRange@@QAE@II@Z ??0AliasedInstruction@@QAE@XZ ??0AttributeStimulus@@QAE@PBD@Z ??0Bit@@QAE@AAVRegisterValue@@I@Z ??0BoolEventLogger@@QAE@I@Z ??0Boolean@@QAE@PBD_N0@Z ??0Boolean@@QAE@_N@Z ??0Breakpoint_Instruction@@QAE@PAVProcessor@@II@Z ??0ByteLogger@gpsim@@QAE@H@Z ??0CommandAssertion@@QAE@PAVProcessor@@IIPBD_N@Z ??0Error@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ??0Float@@QAE@N@Z ??0Float@@QAE@PBDN0@Z ??0I2C_EE@@QAE@PAVProcessor@@IIIIII@Z ??0IIndexedCollection@@QAE@H@Z ??0IIndexedCollection@@QAE@PBD0H@Z ??0IOPIN@@QAE@PBDNNNN@Z ??0IO_bi_directional@@QAE@PBDNNNNNN@Z ??0IO_bi_directional_pu@@QAE@PBDNNNNNNN@Z ??0IO_open_collector@@QAE@PBD@Z ??0IndexedSymbol@@QAE@PAVgpsimObject@@PAV?$list@PAVExpression@@V?$allocator@PAVExpression@@@std@@@std@@@Z ??0Integer@@QAE@ABV0@@Z ??0Integer@@QAE@PBD_J0@Z ??0Integer@@QAE@_J@Z ??0IntelHexProgramFileType@@QAE@XZ ??0Interface@@QAE@PAX@Z ??0LiteralArray@@QAE@PAV?$list@PAVExpression@@V?$allocator@PAVExpression@@@std@@@std@@@Z ??0LiteralBoolean@@QAE@PAVBoolean@@@Z ??0LiteralFloat@@QAE@PAVFloat@@@Z ??0LiteralInteger@@QAE@PAVInteger@@@Z ??0LiteralString@@QAE@PAVString@@@Z ??0LiteralSymbol@@QAE@PAVgpsimObject@@@Z ??0Module@@QAE@PBD0@Z ??0ModuleTraceType@@QAE@PAVModule@@IPBD@Z ??0OpAbstractRange@@QAE@PAVExpression@@0@Z ??0OpAdd@@QAE@PAVExpression@@0@Z ??0OpAddressOf@@QAE@PAVExpression@@@Z ??0OpAnd@@QAE@PAVExpression@@0@Z ??0OpDiv@@QAE@PAVExpression@@0@Z ??0OpEq@@QAE@PAVExpression@@0@Z ??0OpGe@@QAE@PAVExpression@@0@Z ??0OpGt@@QAE@PAVExpression@@0@Z ??0OpIndirect@@QAE@PAVExpression@@@Z ??0OpLe@@QAE@PAVExpression@@0@Z ??0OpLogicalAnd@@QAE@PAVExpression@@0@Z ??0OpLogicalNot@@QAE@PAVExpression@@@Z ??0OpLogicalOr@@QAE@PAVExpression@@0@Z ??0OpLt@@QAE@PAVExpression@@0@Z ??0OpMpy@@QAE@PAVExpression@@0@Z ??0OpNe@@QAE@PAVExpression@@0@Z ??0OpNegate@@QAE@PAVExpression@@@Z ??0OpOnescomp@@QAE@PAVExpression@@@Z ??0OpOr@@QAE@PAVExpression@@0@Z ??0OpPlus@@QAE@PAVExpression@@@Z ??0OpShl@@QAE@PAVExpression@@0@Z ??0OpShr@@QAE@PAVExpression@@0@Z ??0OpSub@@QAE@PAVExpression@@0@Z ??0OpXor@@QAE@PAVExpression@@0@Z ??0PCTraceObject@@QAE@PAVProcessor@@I@Z ??0PCTraceType@@QAE@PAVProcessor@@I@Z ??0Package@@QAE@I@Z ??0Packet@@QAE@II@Z ??0PicLatchRegister@@QAE@PAVProcessor@@PBD1PAVPortRegister@@I@Z ??0PicPortRegister@@QAE@PAVProcessor@@PBD1II@Z ??0PicTrisRegister@@QAE@PAVProcessor@@PBD1PAVPicPortRegister@@_NI@Z ??0PinModule@@QAE@PAVPortModule@@IPAVIOPIN@@@Z ??0Processor@@QAE@PBD0@Z ??0ProcessorConstructor@@QAE@P6APAVProcessor@@PBD@Z0000@Z ??0ProgramFileBuf@@QAE@PAU_iobuf@@@Z ??0ProgramMemoryAccess@@QAE@PAVProcessor@@@Z ??0PromAddress@@QAE@PAVI2C_EE@@PBD1@Z ??0RegisterAssertion@@QAE@PAVProcessor@@IIIIII_N@Z ??0RegisterAssertion@@QAE@PAVProcessor@@IIIII_N@Z ??0RegisterCollection@@QAE@PAVProcessor@@PBDPAPAVRegister@@I@Z ??0RegisterExpression@@QAE@I@Z ??0RegisterReadTraceObject@@QAE@PAVProcessor@@PAVRegister@@VRegisterValue@@@Z ??0RegisterReadTraceType@@QAE@PAVProcessor@@I@Z ??0RegisterWriteTraceObject@@QAE@PAVProcessor@@PAVRegister@@VRegisterValue@@@Z ??0RegisterWriteTraceType@@QAE@PAVProcessor@@I@Z ??0Stimulus_Node@@QAE@PBD@Z ??0String@@QAE@PBD00@Z ??0String@@QAE@PBD@Z ??0ThreeStateEventLogger@@QAE@I@Z ??0Token@gpsim@@QAE@XZ ??0TraceFrame@@QAE@XZ ??0TriggerObject@@QAE@XZ ??0TypeMismatch@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@00@Z ??0Value@@QAE@PBD0PAVModule@@@Z ??0Value@@QAE@XZ ??0ValueStimulus@@QAE@PBD@Z ??0gpsimObject@@QAE@XZ ??0instruction@@QAE@PAVProcessor@@II@Z ??0invalid_instruction@@QAE@PAVProcessor@@II@Z ??0sfr_register@@QAE@PAVModule@@PBD1@Z ??1AnError@@UAE@XZ ??1Boolean@@UAE@XZ ??1Error@@UAE@XZ ??1Float@@UAE@XZ ??1IOPIN@@UAE@XZ ??1IO_bi_directional_pu@@UAE@XZ ??1IndexedSymbol@@UAE@XZ ??1Integer@@UAE@XZ ??1Module@@UAE@XZ ??1OpNe@@UAE@XZ ??1PinMonitor@@UAE@XZ ??1PortModule@@UAE@XZ ??1Processor@@UAE@XZ ??1Register@@UAE@XZ ??1String@@UAE@XZ ??1TraceFrame@@UAE@XZ ??1TriggerObject@@UAE@XZ ??1Value@@UAE@XZ ??1gpsimObject@@UAE@XZ ??1stimulus@@UAE@XZ ??AFileContextList@@QAEPAVFileContext@@H@Z ??APortModule@@QAEAAVPinModule@@I@Z ??ARegisterMemoryAccess@@QAEAAVRegister@@I@Z ?AddModulePathFromFilePath@@YAXPAD@Z ?Clear@CSimulationContext@@QAEXXZ ?ConstructInvalidInstruction@Processor@@UAEPAVinstruction@@PAV1@II@Z ?Debug@Processor@@UAEXXZ ?DecodeHeader@Packet@@QAE_NXZ ?DecodeObjectType@Packet@@QAE_NAAI@Z ?DecodeString@Packet@@QAE_NPADH@Z ?DecodeUInt32@Packet@@QAE_NAAI@Z ?DecodeUInt64@Packet@@QAE_NAA_K@Z ?DisplayError@ProgramFileType@@UAEXHPBD0@Z ?DisplayString@ProcessorConstructorList@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?ElementIndexedName@IIndexedCollection@@MAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@I@Z ?EncodeHeader@Packet@@QAE_NXZ ?EncodeObjectType@Packet@@QAE_NI@Z ?EncodeUInt32@Packet@@QAE_NI@Z ?EncodeUInt64@Packet@@QAE_N_K@Z ?Execute@CCommandManager@@QAEHAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBD@Z ?Find@FileContextList@@QAEHAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?ForEachModule@SymbolTable@@QAEXP6AXABU?$pair@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVSymbolTable_t@@@std@@@Z@Z ?GUIname@IOPIN@@UBEAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?GetActiveCPU@CSimulationContext@@QAEPAVProcessor@@XZ ?GetBreakpoints@CSimulationContext@@QAEAAVBreakpoints@@XZ ?GetCapabilities@Processor@@QAEKXZ ?GetContext@CSimulationContext@@SAPAV1@XZ ?GetList@ProcessorConstructorList@@SAPAV1@XZ ?GetManager@CCommandManager@@SAAAV1@XZ ?GetSymbol@LiteralSymbol@@QAEPAVValue@@XZ ?Initialize@CSimulationContext@@QAEXXZ ?Initialize@Token@gpsim@@QAEXP6APAXPAX@Z0@Z ?InstantiateObject@ModuleLibrary@@SAHAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z ?ListLoadableModules@ModuleLibrary@@SAXXZ ?ListToConsole@CCommandManager@@QAEXXZ ?LoadFile@ModuleLibrary@@SAHAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?LoadProgramFile@IntelHexProgramFileType@@UAEHPAPAVProcessor@@PBDPAU_iobuf@@1@Z ?LoadProgram@CSimulationContext@@QAEHPBD0PAPAVProcessor@@0@Z ?ModuleLibraries@@3V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVDynamicModuleLibraryInfo@@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVDynamicModuleLibraryInfo@@@std@@@2@@std@@A ?NewObject@Float@@SAPAV1@PBD00@Z ?NewObject@Integer@@SAPAV1@PBD00@Z ?NotifyUserCanceled@CSimulationContext@@QAEXXZ ?Parse@Boolean@@SA_NPBDAA_N@Z ?Parse@Float@@SA_NPBDAAN@Z ?Parse@Integer@@SA_NPBDAA_J@Z ?PushValue@IIndexedCollection@@IAEXHHPAVValue@@AAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@1@Z ?ReadHLLLine@instruction@@UAEPADPADH@Z ?ReadLine@FileContextList@@QAEPADHHPADH@Z ?ReadLstLine@instruction@@UAEPADPADH@Z ?ReadSrcLine@instruction@@UAEPADPADH@Z ?Register@CCommandManager@@QAEHPAVICommandHandler@@@Z ?RegisterProgramFileType@@YAXPAVProgramFileType@@@Z ?Reset@CSimulationContext@@QAEXW4RESET_TYPE@@@Z ?Set@IIndexedCollection@@UAEXPAVValue@@@Z ?SetAddressRadix@IIndexedCollection@@QAEXH@Z ?SetAt@IIndexedCollection@@UAEXPAV?$list@PAVExpression@@V?$allocator@PAVExpression@@@std@@@std@@PAVExpression@@@Z ?SetAt@IIndexedCollection@@UAEXPAV?$list@PAVExpression@@V?$allocator@PAVExpression@@@std@@@std@@PAVExpression@@@Z ?SetDefaultProcessor@CSimulationContext@@QAE_NPBD0@Z ?SetProcessorByType@CSimulationContext@@QAEPAVProcessor@@PBD0@Z ?SetSourcePath@FileContextList@@QAEXPBD@Z ?TrimWhiteSpaceFromString@@YAPADPAD@Z ?add@TraceFrame@@UAEXPAVTraceObject@@@Z ?addFrame@Trace@@QAEXPAVTraceFrame@@@Z ?addPin@PortModule@@QAEPAVIOPIN@@PAV2@I@Z ?addPinModule@PortModule@@QAEXPAVPinModule@@I@Z ?addSink@PinMonitor@@QAEXPAVSignalSink@@@Z ?addSymbol@Module@@QAEHPAVgpsimObject@@PAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?addSymbol@SymbolTable@@QAEHPAVgpsimObject@@@Z ?addToCurrentFrame@Trace@@QAEXPAVTraceObject@@@Z ?add_command@Module@@QAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z ?add_interface@gpsimInterface@@QAEIPAVInterface@@@Z ?add_processor@CSimulationContext@@QAEPAVProcessor@@PAV2@@Z ?add_processor@CSimulationContext@@QAEPAVProcessor@@PBD0@Z ?add_xref@AliasedInstruction@@UAEXPAX@Z ?add_xref@Value@@UAEXPAX@Z ?address_has_break@ProgramMemoryAccess@@UAEHIW4INSTRUCTION_TYPES@instruction@@@Z ?address_has_notify@ProgramMemoryAccess@@UAEHI@Z ?address_has_profile_start@ProgramMemoryAccess@@UAEHI@Z ?address_has_profile_stop@ProgramMemoryAccess@@UAEHI@Z ?advance_simulation@gpsimInterface@@QAEXW4eAdvancementModes@1@@Z ?advanceIndex@PacketBuffer@@QAEXI@Z ?allocateTraceType@Trace@@QAEIPAVTraceType@@@Z ?assertValid@Integer@@SAPAV1@PAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_J2@Z ?assertValid@Integer@@SAPAV1@PAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_J@Z ?assign_pin@Module@@UAEXIPAVIOPIN@@@Z ?assign_pin@Package@@QAEXIPAVIOPIN@@_N@Z ?assign_xref@ProgramMemoryAccess@@QAEXIPAX@Z ?attach@IOPIN@@UAEXPAVStimulus_Node@@@Z ?attach_src_line@Processor@@QAEXIIII@Z ?attach_stimulus@Stimulus_Node@@QAEXPAVstimulus@@@Z ?bIsValid@Breakpoints@@QAE_NI@Z ?bSimulating@gpsimInterface@@QAE_NXZ ?bUsingGUI@gpsimInterface@@QAE_NXZ ?bp@@3VBreakpoints@@A ?breakpoint@Cycle_Counter@@AAEXXZ ?byte@ByteLogger@gpsim@@QAEXI@Z ?callback@ProgramMemoryAccess@@UAEXXZ ?callback@RealTimeBreakPoint@@UAEXXZ ?callback@TriggerObject@@UAEXXZ ?callback@source_stimulus@@UAEXXZ ?callback_print@TriggerObject@@UAEXXZ ?callback_print@source_stimulus@@UAEXXZ ?clear@Breakpoint_Instruction@@UAEXXZ ?clear@Breakpoints@@QAEXI@Z ?clear@TriggerObject@@UAEXXZ ?clear_all@Breakpoints@@QAEXPAVProcessor@@@Z ?clear_all_register@Breakpoints@@QAEXPAVProcessor@@I@Z ?clear_break@Cycle_Counter@@QAEXPAVTriggerObject@@@Z ?clear_break@Register@@UAEHXZ ?clear_break@gpsimObject@@UAEHXZ ?clear_break_at_address@ProgramMemoryAccess@@UAEHIPAVinstruction@@@Z ?clear_break_at_address@ProgramMemoryAccess@@UAEHIW4INSTRUCTION_TYPES@instruction@@@Z ?clear_break_at_line@ProgramMemoryAccess@@UAEXII@Z ?clear_notify_at_address@ProgramMemoryAccess@@UAEHI@Z ?clear_profile_start_at_address@ProgramMemoryAccess@@UAEHI@Z ?clear_profile_stop_at_address@ProgramMemoryAccess@@UAEHI@Z ?clear_trigger@TriggerObject@@UAEXXZ ?compare@Boolean@@UAE_NPAVComparisonOperator@@PAVValue@@@Z ?compare@Float@@UAE_NPAVComparisonOperator@@PAVValue@@@Z ?compare@Integer@@UAE_NPAVComparisonOperator@@PAVValue@@@Z ?compare@Value@@UAE_NPAVComparisonOperator@@PAV1@@Z ?computed_goto@Program_Counter@@UAEXI@Z ?construct@P12F1822@@SAPAVProcessor@@PBD@Z ?construct@P16F1823@@SAPAVProcessor@@PBD@Z ?construct@P16F631@@SAPAVProcessor@@PBD@Z ?construct@P16F631@@SAPAVProcessor@@PBD@Z ?construct@P16F677@@SAPAVProcessor@@PBD@Z ?construct@P16F677@@SAPAVProcessor@@PBD@Z ?construct@P16F684@@SAPAVProcessor@@PBD@Z ?construct@P16F684@@SAPAVProcessor@@PBD@Z ?construct@P16F685@@SAPAVProcessor@@PBD@Z ?construct@P16F685@@SAPAVProcessor@@PBD@Z ?construct@P16F687@@SAPAVProcessor@@PBD@Z ?construct@P16F687@@SAPAVProcessor@@PBD@Z ?construct@P16F689@@SAPAVProcessor@@PBD@Z ?construct@P16F689@@SAPAVProcessor@@PBD@Z ?construct@P16F690@@SAPAVProcessor@@PBD@Z ?construct@P16F690@@SAPAVProcessor@@PBD@Z ?construct@P16F882@@SAPAVProcessor@@PBD@Z ?construct@P16F882@@SAPAVProcessor@@PBD@Z ?construct@P16F883@@SAPAVProcessor@@PBD@Z ?construct@P16F883@@SAPAVProcessor@@PBD@Z ?construct@P16F884@@SAPAVProcessor@@PBD@Z ?construct@P16F884@@SAPAVProcessor@@PBD@Z ?construct@P16F886@@SAPAVProcessor@@PBD@Z ?construct@P16F886@@SAPAVProcessor@@PBD@Z ?construct@P16F887@@SAPAVProcessor@@PBD@Z ?construct@P16F887@@SAPAVProcessor@@PBD@Z ?construct@Stimulus_Node@@SAPAV1@PBD@Z ?convertToNew@PinGeometry@@QAEXXZ ?copy@Boolean@@UAEPAVValue@@XZ ?copy@Float@@UAEPAVValue@@XZ ?copy@Integer@@UAEPAVValue@@XZ ?copy@Register@@UAEPAVValue@@XZ ?copy@String@@UAEPAVValue@@XZ ?copy@Value@@UAEPAV1@XZ ?create@Processor@@UAEXXZ ?createProgramMemoryAccess@Processor@@UAEPAVProgramMemoryAccess@@PAV1@@Z ?create_invalid_registers@Processor@@QAEXXZ ?create_pkg@Module@@UAEXI@Z ?cycles@@3VCycle_Counter@@A ?cycles_used@Processor@@QAE_KI@Z ?debug@AliasedInstruction@@UAEXXZ ?decode@ModuleTraceType@@UAEPAVTraceObject@@I@Z ?decode@instruction@@QAEXPAVProcessor@@I@Z ?deleteSymbol@SymbolTable@@QAEHABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?description@gpsimObject@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?destroyProgramMemoryAccess@Processor@@UAEXPAVProgramMemoryAccess@@@Z ?detach@stimulus@@UAEXPAVStimulus_Node@@@Z ?detach_stimulus@Stimulus_Node@@QAEXPAVstimulus@@@Z ?disableLogging@Trace@@QAEXXZ ?disable_logging@TraceLog@@QAEXXZ ?disassemble@Processor@@UAEXHH@Z ?dump1@Breakpoints@@QAE_NIH@Z ?dump@Breakpoints@@QAEXH@Z ?dump@ThreeStateEventLogger@@QAEXHH@Z ?dump@Trace@@QAEHHPAU_iobuf@@@Z ?dump_ASCII_art@BoolEventLogger@@QAEX_K0H@Z ?dump_ASCII_art@ThreeStateEventLogger@@QAEX_K0H@Z ?dump_last_instruction@Trace@@QAEXXZ ?dump_processor_list@CSimulationContext@@QAEXXZ ?dump_raw@ModuleTraceType@@UAEHPAVTrace@@IPADH@Z ?dump_raw@PCTraceType@@UAEHPAVTrace@@IPADH@Z ?dump_raw@Trace@@QAEXH@Z ?dump_raw@TraceType@@UAEHPAVTrace@@IPADH@Z ?dump_registers@Processor@@UAEXXZ ?dump_stimulus_list@@YAXXZ ?enableLogging@Trace@@QAEXPBD@Z ?enable_logging@TraceLog@@QAEXPBDH@Z ?enable_profiling@ProfileKeeper@@QAEXXZ ?entriesUsed@TraceType@@UAEHPAVTrace@@I@Z ?eval_Expression@Breakpoint_Instruction@@UAE_NXZ ?eval_Expression@TriggerObject@@UAE_NXZ ?event@BoolEventLogger@@QAEX_N@Z ?event@ThreeStateEventLogger@@QAEXD@Z ?execute@AliasedInstruction@@UAEXXZ ?find@CCommandManager@@QAEPAVICommandHandler@@PBD@Z ?find@SymbolTable@@QAEPAVgpsimObject@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?findInteger@SymbolTable@@QAEPAVInteger@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?findModule@SymbolTable@@QAEPAVModule@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?findSymbol@Module@@QAEPAVgpsimObject@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?findValue@SymbolTable@@QAEPAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?find_address_from_line@ProgramMemoryAccess@@UAEHPAVFileContext@@H@Z ?find_closest_address_to_line@ProgramMemoryAccess@@UAEHHH@Z ?find_free@TriggerObject@@UAEHXZ ?find_instruction@ProgramMemoryAccess@@UAEPAVinstruction@@IW4INSTRUCTION_TYPES@2@@Z ?finish@ProgramMemoryAccess@@UAEXXZ ?forceDrivenState@IOPIN@@UAEXD@Z ?gUsingThreads@@YA_NXZ ?get@Boolean@@UAEXAAH@Z ?get@Boolean@@UAEXAAVPacket@@@Z ?get@Boolean@@UAEXAA_N@Z ?get@Boolean@@UAEXPADH@Z ?get@Float@@UAEXAAN@Z ?get@Float@@UAEXAAVPacket@@@Z ?get@Float@@UAEXAA_J@Z ?get@Float@@UAEXPADH@Z ?get@Integer@@UAEXAAN@Z ?get@Integer@@UAEXAAVPacket@@@Z ?get@Integer@@UAEXAA_J@Z ?get@Integer@@UAEXPADH@Z ?get@PortRegister@@UAEIXZ ?get@Register@@UAEIXZ ?get@Register@@UAEXAA_J@Z ?get@String@@UAEXAAVPacket@@@Z ?get@String@@UAEXPADH@Z ?get@Value@@UAEXAAH@Z ?get@Value@@UAEXAAN@Z ?get@Value@@UAEXAAVPacket@@@Z ?get@Value@@UAEXAA_J@Z ?get@Value@@UAEXAA_K@Z ?get@Value@@UAEXAA_N@Z ?get@Value@@UAEXPADH@Z ?getBitChar@IOPIN@@UAEDXZ ?getBitChar@IO_bi_directional@@UAEDXZ ?getBitChar@IO_bi_directional_pu@@UAEDXZ ?getBitChar@IO_open_collector@@UAEDXZ ?getDrivenState@IOPIN@@UAE_NXZ ?getDriving@PortRegister@@UAEIXZ ?getDrivingState@IOPIN@@UAE_NXZ ?getForcedDrivenState@IOPIN@@UAEDXZ ?getFromAddress@ProgramMemoryAccess@@QAEPAVinstruction@@I@Z ?getFromIndex@ProgramMemoryAccess@@QAEPAVinstruction@@I@Z ?getPin@PortModule@@QAEPAVIOPIN@@I@Z ?getPinGeometry@Package@@QAEPAUPinGeometry@@I@Z ?getReplaced@AliasedInstruction@@UAEPAVinstruction@@XZ ?getState@IOPIN@@UAE_NXZ ?getState@RegisterReadTraceObject@@UAEXPAVTraceFrame@@@Z ?getState@RegisterWriteTraceObject@@UAEXPAVTraceFrame@@@Z ?getState@TraceObject@@UAEXPAVTraceFrame@@@Z ?getThevenin@stimulus@@UAEXAAN00@Z ?getVal@String@@QAEPBDXZ ?get_OSCperiod@Processor@@UAENXZ ?get_PC@ProgramMemoryAccess@@UAEIXZ ?get_Vth@IOPIN@@UAENXZ ?get_Vth@IO_bi_directional@@UAENXZ ?get_Vth@IO_bi_directional_pu@@UAENXZ ?get_Vth@IO_open_collector@@UAENXZ ?get_Zth@IO_bi_directional@@UAENXZ ?get_Zth@IO_bi_directional_pu@@UAENXZ ?get_Zth@IO_open_collector@@UAENXZ ?get_active_cpu@@YAPAVProcessor@@XZ ?get_base_instruction@ProgramMemoryAccess@@QAEPAVinstruction@@I@Z ?get_bit@Register@@UAE_NI@Z ?get_bit_voltage@Register@@UAENI@Z ?get_bp@@YAAAVBreakpoints@@XZ ?get_cpu@Breakpoint_Instruction@@UAEPAVProcessor@@XZ ?get_cpu@MemoryAccess@@UAEPAVProcessor@@XZ ?get_cycles@@YAAAVCycle_Counter@@XZ ?get_dir_delim@@YAPBDPBD@Z ?get_errMsg@AnError@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?get_file_id@AliasedInstruction@@UAEHXZ ?get_file_id@ProgramMemoryAccess@@QAEHI@Z ?get_frequency@Processor@@UAENXZ ?get_hll_file_id@AliasedInstruction@@UAEHXZ ?get_hll_src_line@AliasedInstruction@@UAEHXZ ?get_index@BoolEventLogger@@QAEI_K@Z ?get_index@ThreeStateEventLogger@@QAEI_K@Z ?get_interface@@YAAAVgpsimInterface@@XZ ?get_lst_line@AliasedInstruction@@UAEHXZ ?get_nEvents@ThreeStateEventLogger@@QAEIII@Z ?get_nodeVoltage@Stimulus_Node@@QAENXZ ?get_opcode@AliasedInstruction@@UAEIXZ ?get_opcode@ProgramMemoryAccess@@QAEII@Z ?get_opcode_name@ProgramMemoryAccess@@QAEPADIPADI@Z ?get_pin@Module@@UAEPAVIOPIN@@I@Z ?get_pin@Package@@QAEPAVIOPIN@@I@Z ?get_pin_count@Module@@UAEHXZ ?get_pin_name@Module@@UAEAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@I@Z ?get_pin_state@Module@@UAEHI@Z ?get_program_memory_at_address@Processor@@UAEII@Z ?get_src_line@AliasedInstruction@@UAEHXZ ?get_src_line@ProgramMemoryAccess@@QAEHI@Z ?get_trace@@YAAAVTrace@@XZ ?get_update_rate@gpsimInterface@@QAE_KXZ ?get_value@AliasedInstruction@@UAEIXZ ?get_value@PortRegister@@UAEIXZ ?get_value@gpsimObject@@UAEIXZ ?gets@FileContext@@QAEPADPADI@Z ?gpsim_set_bulk_mode@@YAXH@Z ?grab@Token@gpsim@@QAEXXZ ?halt@Breakpoints@@QAEXXZ ?hasBreak@RegisterMemoryAccess@@QAE_NI@Z ?hasValid_opcode_at_address@ProgramMemoryAccess@@QAE_NI@Z ?hasValid_opcode_at_index@ProgramMemoryAccess@@QAE_NI@Z ?icd_connect@@YAHPBD@Z ?icd_detected@@YAHXZ ?icd_disconnect@@YAHXZ ?icd_has_debug_module@@YAHXZ ?icd_target@@YAPADXZ ?icd_vdd@@YAMXZ ?icd_version@@YAPADXZ ?icd_vpp@@YAMXZ ?init@ProgramMemoryAccess@@QAEXPAVProcessor@@@Z ?init_program_memory@Processor@@UAEXI@Z ?init_program_memory@Processor@@UAEXII@Z ?init_program_memory_at_index@Processor@@UAEXII@Z ?init_program_memory_at_index@Processor@@UAEXIPBEH@Z ?init_register_memory@Processor@@UAEXI@Z ?initialize@AliasedInstruction@@UAEX_N@Z ?insertRegister@RegisterMemoryAccess@@QAE_NIPAVRegister@@@Z ?instruction_size@AliasedInstruction@@UAEHXZ ?interrupt@Program_Counter@@UAEXI@Z ?invokeAction@TriggerObject@@UAEXXZ ?isBase@AliasedInstruction@@UAE_NXZ ?isModified@ProgramMemoryAccess@@QAE_NI@Z ?isValid@TraceType@@UAE_NPAVTrace@@I@Z ?isa@AliasedInstruction@@UAE?AW4INSTRUCTION_TYPES@instruction@@XZ ?list@Processor@@UAEXIIHH@Z ?list_id@FileContextList@@QAEXH@Z ?load_state@Processor@@UAEXPAU_iobuf@@@Z ?log@TraceRawLog@@QAEXXZ ?name@AliasedInstruction@@UAEPADPADH@Z ?name@gpsimObject@@UAEPADPADH@Z ?name@gpsimObject@@UBEAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?newGUIname@IOPIN@@UAEXPBD@Z ?new_address@Program_Counter@@UAEXI@Z ?new_message@TriggerObject@@UAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?new_message@TriggerObject@@UAEXPBD@Z ?new_name@Register@@UAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?new_name@Register@@UAEXPBD@Z ?new_name@gpsimObject@@UAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?new_name@gpsimObject@@UAEXPBD@Z ?new_name@stimulus@@UAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z ?new_name@stimulus@@UAEXPBD_N@Z ?new_program@gpsimInterface@@QAEXPAVProcessor@@@Z ?open@FileContext@@QAEXPBD@Z ?passToChild@Token@gpsim@@QAEXXZ ?passToParent@Token@gpsim@@QAEXXZ ?preset@Cycle_Counter@@QAEX_K@Z ?print@Breakpoint_Instruction@@UAEXXZ ?print@TriggerObject@@UAEXXZ ?printExpression@TriggerObject@@UAEHPADH@Z ?printTraced@Breakpoint_Instruction@@UAEHPAVTrace@@IPADH@Z ?printTraced@TriggerObject@@UAEHPAVTrace@@IPADH@Z ?print_frame@TraceObject@@UAEXPAVTraceFrame@@PAU_iobuf@@@Z ?profile_keeper@@3VProfileKeeper@@A ?put@PortRegister@@UAEXI@Z ?putDrive@PortRegister@@UAEXI@Z ?putState@IOPIN@@UAEX_N@Z ?putState@PinModule@@UAEXD@Z ?putToAddress@ProgramMemoryAccess@@UAEXIPAVinstruction@@@Z ?putToIndex@ProgramMemoryAccess@@UAEXIPAVinstruction@@@Z ?put_opcode@ProgramMemoryAccess@@QAEXII@Z ?put_value@AliasedInstruction@@UAEXI@Z ?put_value@PortRegister@@UAEXI@Z ?put_value@Register@@UAEXI@Z ?readihex16@IntelHexProgramFileType@@QAEHPAVProcessor@@PAU_iobuf@@@Z ?readihexN@IntelHexProgramFileType@@AAEHHPAPAVRegister@@HPAU_iobuf@@H@Z ?read_src_files@Processor@@QAEXXZ ?reassign_break@Cycle_Counter@@QAE_N_K0PAVTriggerObject@@@Z ?refreshPinOnUpdate@PinModule@@QAEX_N@Z ?register_size@Register@@UBEIXZ ?removeRegister@RegisterMemoryAccess@@QAE_NIPAVRegister@@@Z ?removeSink@PinMonitor@@QAEXPAVSignalSink@@@Z ?removeSymbol@Module@@QAEHPAVgpsimObject@@@Z ?remove_interface@gpsimInterface@@QAEXI@Z ?remove_xref@AliasedInstruction@@UAEXPAX@Z ?remove_xref@Value@@UAEXPAX@Z ?reset@Module@@UAEXW4RESET_TYPE@@@Z ?reset@Program_Counter@@QAEXXZ ?reset@gpsimInterface@@QAEXW4RESET_TYPE@@@Z ?reset@sfr_register@@UAEXW4RESET_TYPE@@@Z ?rewind@FileContext@@QAEXXZ ?rts@ByteLogger@gpsim@@QAEX_K@Z ?run_script@Module@@QAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?run_to_address@Processor@@UAEXI@Z ?save_state@Processor@@UAEXPAU_iobuf@@@Z ?save_state@Processor@@UAEXXZ ?set@Boolean@@UAEXAAVPacket@@@Z ?set@Boolean@@UAEXPAVValue@@@Z ?set@Boolean@@UAEXPBDH@Z ?set@Boolean@@UAEX_N@Z ?set@Float@@UAEXAAVPacket@@@Z ?set@Float@@UAEXN@Z ?set@Float@@UAEXPAVValue@@@Z ?set@Float@@UAEXPBDH@Z ?set@Float@@UAEX_J@Z ?set@Integer@@UAEXAAVPacket@@@Z ?set@Integer@@UAEXH@Z ?set@Integer@@UAEXN@Z ?set@Integer@@UAEXPAVValue@@@Z ?set@Integer@@UAEXPBDH@Z ?set@Integer@@UAEX_J@Z ?set@Register@@UAEXPAVValue@@@Z ?set@String@@UAEXAAVPacket@@@Z ?set@String@@UAEXPAVValue@@@Z ?set@String@@UAEXPBDH@Z ?set@Value@@UAEXAAVPacket@@@Z ?set@Value@@UAEXH@Z ?set@Value@@UAEXN@Z ?set@Value@@UAEXPAV1@@Z ?set@Value@@UAEXPAVExpression@@@Z ?set@Value@@UAEXPBDH@Z ?set@Value@@UAEX_J@Z ?set@Value@@UAEX_N@Z ?setBreakOnReset@Processor@@UAEX_N@Z ?setControl@PinModule@@QAEXPAVSignalControl@@@Z ?setDefaultBitmask@Integer@@SAX_J@Z ?setDefaultControl@PinModule@@QAEXPAVSignalControl@@@Z ?setDefaultPullupControl@PinModule@@QAEXPAVSignalControl@@@Z ?setDefaultSource@PinModule@@QAEXPAVSignalControl@@@Z ?setDirection@PinModule@@UAEXXZ ?setDrivenState@IOPIN@@UAEX_N@Z ?setDrivenState@PinModule@@UAEXD@Z ?setDrivingState@IOPIN@@UAEXD@Z ?setDrivingState@IOPIN@@UAEX_N@Z ?setDrivingState@PinModule@@UAEXD@Z ?setEnableMask@PortRegister@@UAEXI@Z ?setGUImode@gpsimInterface@@QAEX_N@Z ?setMonitor@IOPIN@@UAEXPAVPinMonitor@@@Z ?setPinGeometry@Package@@QAEXIMMH_N@Z ?setSafeMode@Processor@@UAEX_N@Z ?setUnknownMode@Processor@@UAEX_N@Z ?setWarnMode@Processor@@UAEX_N@Z ?set_Expression@TriggerObject@@UAEXPAVExpression@@@Z ?set_Expression@TriggerObject@@UAEXPAVExpression@@@Z ?set_PC@ProgramMemoryAccess@@UAEXI@Z ?set_break@Breakpoint_Instruction@@UAE_NXZ ?set_break@Cycle_Counter@@QAE_N_KPAVTriggerObject@@I@Z ?set_break@Integer@@UAEHW4ObjectBreakTypes@gpsimObject@@W4ObjectActionTypes@3@PAVExpression@@@Z ?set_break@Register@@UAEHW4ObjectBreakTypes@gpsimObject@@W4ObjectActionTypes@3@PAVExpression@@@Z ?set_break@gpsimObject@@UAEHW4ObjectBreakTypes@1@W4ObjectActionTypes@1@PAVExpression@@@Z ?set_break_at_address@ProgramMemoryAccess@@UAEII@Z ?set_break_at_line@ProgramMemoryAccess@@UAEXII@Z ?set_break_delta@Cycle_Counter@@QAE_N_KPAVTriggerObject@@I@Z ?set_change_break@Breakpoints@@QAEHPAVProcessor@@I@Z ?set_cpu@Value@@UAEXPAVProcessor@@@Z ?set_cycle_break@Breakpoints@@QAEHPAVProcessor@@_KPAVTriggerObject@@@Z ?set_description@gpsimObject@@QAEXPBD@Z ?set_execution_break@Breakpoints@@QAEHPAVProcessor@@IPAVExpression@@@Z ?set_expression@Breakpoints@@QAE_NIPAVExpression@@@Z ?set_frequency@Processor@@QAEXN@Z ?set_hll_mode@ProgramMemoryAccess@@QAEXI@Z ?set_is_analog@IO_bi_directional_pu@@UAEX_N@Z ?set_message@Breakpoints@@QAEXIAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?set_module@Value@@UAEXPAVModule@@@Z ?set_nodeVoltage@IOPIN@@UAEXN@Z ?set_nodeVoltage@IO_bi_directional@@UAEXN@Z ?set_nodeVoltage@PinModule@@UAEXN@Z ?set_nodeVoltage@Stimulus_Node@@QAEXN@Z ?set_notify_at_address@ProgramMemoryAccess@@UAEIIPAVTriggerObject@@@Z ?set_notify_read@Breakpoints@@QAEHPAVProcessor@@I@Z ?set_notify_read_value@Breakpoints@@QAEHPAVProcessor@@III@Z ?set_notify_write@Breakpoints@@QAEHPAVProcessor@@I@Z ?set_notify_write_value@Breakpoints@@QAEHPAVProcessor@@III@Z ?set_out_of_range_pm@Processor@@UAEXII@Z ?set_profile_start_at_address@ProgramMemoryAccess@@UAEIIPAVTriggerObject@@@Z ?set_profile_stop_at_address@ProgramMemoryAccess@@UAEIIPAVTriggerObject@@@Z ?set_read_break@Breakpoints@@QAEHPAVProcessor@@I@Z ?set_read_trace@Register@@UAEXAAVRegisterValue@@@Z ?set_read_value_break@Breakpoints@@QAEHPAVProcessor@@III@Z ?set_read_value_break@Breakpoints@@QAEHPAVProcessor@@IIII@Z ?set_stk_overflow_break@Breakpoints@@QAEHPAVProcessor@@@Z ?set_stk_underflow_break@Breakpoints@@QAEHPAVProcessor@@@Z ?set_update_rate@gpsimInterface@@QAEX_K@Z ?set_wdt_break@Breakpoints@@QAEHPAVProcessor@@@Z ?set_write_break@Breakpoints@@QAEHPAVProcessor@@I@Z ?set_write_trace@Register@@UAEXAAVRegisterValue@@@Z ?set_write_value_break@Breakpoints@@QAEHPAVProcessor@@III@Z ?set_write_value_break@Breakpoints@@QAEHPAVProcessor@@IIII@Z ?setbit@Register@@UAEXI_N@Z ?show@BinaryOperator@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?show@IOPIN@@UAEXXZ ?show@gpsimObject@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?showInfo@Trace@@QAEXXZ ?showType@BinaryOperator@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?showType@gpsimObject@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?simulation_cleanup@@YAXXZ ?simulation_has_stopped@gpsimInterface@@QAEXXZ ?simulation_start_cycle@@3_KA ?start@ByteLogger@gpsim@@QAEX_K@Z ?start_simulation@gpsimInterface@@QAEXN@Z ?status@TraceLog@@QAEXXZ ?step_over@Processor@@UAEX_N@Z ?step_simulation@gpsimInterface@@QAEXH@Z ?stimuli_attach@@YAXPAVgpsimObject@@PAV?$list@PAVgpsimObject@@V?$allocator@PAVgpsimObject@@@std@@@std@@@Z ?stop@ByteLogger@gpsim@@QAEX_K@Z ?stop@ProgramMemoryAccess@@UAEXXZ ?terminate@PacketBuffer@@QAEXXZ ?test_bits@@YAXXZ ?toBitStr@Boolean@@UAEPADPADH@Z ?toBitStr@Integer@@UAEPADPADH@Z ?toBitStr@Register@@UAEPADPADH@Z ?toBitStr@RegisterValue@@QBEPADPADHIPBD111@Z ?toBitStr@gpsimObject@@UAEPADPADH@Z ?toString@AnError@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@Boolean@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z ?toString@Boolean@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@Boolean@@UAEPADPADH@Z ?toString@Float@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@Float@@UAEPADPADH@Z ?toString@IIndexedCollection@@MAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HAAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@3@0@Z ?toString@IIndexedCollection@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAV?$list@PAVExpression@@V?$allocator@PAVExpression@@@std@@@3@@Z ?toString@IIndexedCollection@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@IIndexedCollection@@UAEPADPADH@Z ?toString@IndexedSymbol@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@Integer@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PBD@Z ?toString@Integer@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@Integer@@UAEPADPADH@Z ?toString@Register@@UAEPADPADH@Z ?toString@RegisterValue@@QBEPADPADHH@Z ?toString@String@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@String@@UAEPADPADH@Z ?toString@gpsimObject@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toString@gpsimObject@@UAEPADPADH@Z ?toString@stimulus@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ ?toggle@IOPIN@@UAEXXZ ?toggle_break_at_address@ProgramMemoryAccess@@UAEXI@Z ?toggle_break_at_line@ProgramMemoryAccess@@UAEXII@Z ?toupper@@YAAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAV12@@Z ?trace_dump1@Processor@@UAEHHPADH@Z ?typeCheck@AbstractRange@@SAPAV1@PAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?typeCheck@Boolean@@SAPAV1@PAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?typeCheck@Float@@SAPAV1@PAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?typeCheck@Integer@@SAPAV1@PAVValue@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ?update@AliasedInstruction@@UAEXXZ ?update@Stimulus_Node@@QAEXXZ ?update@Value@@UAEXXZ ?updatePin@PortModule@@UAEXI@Z ?updatePins@PortModule@@UAEXI@Z ?updatePort@PortModule@@UAEXXZ ?updateUI@PinModule@@UAEXXZ ?updateUI@PortRegister@@UAEXXZ ?update_direction@IO_bi_directional@@UAEXI_N@Z ?update_line_number@AliasedInstruction@@UAEXHHHHH@Z ?update_line_number@instruction@@UAEXHHHHH@Z ?update_pullup@IO_bi_directional_pu@@UAEXD_N@Z ?update_state@TraceFrame@@UAEXXZ ?verbose@@3VGlobalVerbosityAccessor@@A ?waitForChild@Token@gpsim@@QAEXXZ ?writeihexN@IntelHexProgramFileType@@AAEXHPAPAVRegister@@HPAU_iobuf@@H@Z GetUserInterface free_error_message free_library get_library_export load_library gpsim-0.30.0/plat/win32/glist.cpp0000664000076400007640000000517713041763624013414 00000000000000/* Copyright (C) 2003-2004 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Minimal implementation of glib: only slist functionality and g_win32_error_message is needed by gpsim with --disable-gui */ #include "glib.h" #include gpointer g_malloc0 (gulong n_bytes) { if (n_bytes) { return calloc (1, n_bytes); } return NULL; } void g_free (gpointer mem) { if (mem) free (mem); } #define _g_slist_alloc g_slist_alloc GSList* g_slist_alloc (void) { GSList *list; list = g_new0 (GSList, 1); return list; } void g_slist_free_1 (GSList *list) { g_free (list); } GSList* g_slist_append (GSList *list, gpointer data) { GSList *new_list; GSList *last; new_list = _g_slist_alloc (); new_list->data = data; if (list) { last = g_slist_last (list); /* g_assert (last != NULL); */ last->next = new_list; return list; } else return new_list; } GSList* g_slist_remove (GSList *list, gconstpointer data) { GSList *tmp, *prev = NULL; tmp = list; while (tmp) { if (tmp->data == data) { if (prev) prev->next = tmp->next; else list = tmp->next; g_slist_free_1 (tmp); break; } prev = tmp; tmp = prev->next; } return list; } GSList* g_slist_last (GSList *list) { if (list) { while (list->next) list = list->next; } return list; } gchar * g_win32_error_message (gint error) { gchar *msg; gchar *retval; int nbytes; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, (LPTSTR) &msg, 0, NULL); nbytes = strlen (msg); if (nbytes > 2 && msg[nbytes-1] == '\n' && msg[nbytes-2] == '\r') msg[nbytes-2] = '\0'; retval = strdup (msg); if (msg != NULL) LocalFree (msg); return retval; } gpsim-0.30.0/TODO0000664000076400007640000000377513041763642010356 00000000000000 TODO - In no particular order: o Provide option to disable the nop portion of two-word 18cxxx instructions in assembly dumps. o Parallel stimuli o High frequency stimuli (currently, the cpu frequency is the maximum stimulation frequency) o Support different clock types like variable frequency oscillators. o Gui support - Add an 'architecture' command for querying a pic's architecture - Provide a means for obtaining the current simulation state, saving the current simulation state, and finding the difference between two simulation states. - Memory management. gpsim is very cavalier with memory. In a few instances, I check for insufficient memory, however I need to be more thorough. Fortunately, gpsim very seldom deletes instantiated objects. So I suspect there are no leaks... o I2C Peripheral Support o I2C EEPROM Modules o Module call support - Other than attributes, there is no real good way to interface with modules. So the idea is to create infrastructure that defines how a module can expose an API that the simulation call. o dsPic support o High Level source (C and Jal) o Extended Stimuli - These are stimuli that are implemented as modules. Currently the PulseGen stimulus can replace most of what an asynchronous stimulus does. This needs to be finished. - Add a PWL - Add a File Stimulus GUI --- o Source Browser: - Provide a way of selecting which break to clear if multiple breaks are set at one address o Breakpoint Window - Add this to manage breakpoints. o Symbol Window - It's pretty much useless at the moment. o Program Memory - This is still using the GTK-1.x api. o Breadboard window -- Needs a major overhaul -- Create addition package types (like TQFP). Cairo allows text to be drawn in any direction. -- Allow pins to be queried. o Waveform viewer - add. -- The waveform viewer should allow the users to view I/O pin state and Attribute states. gpsim-0.30.0/src/0000775000076400007640000000000013117465762010527 500000000000000gpsim-0.30.0/src/bitlog.h0000664000076400007640000001203513063451152012065 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__BITLOG_H__) #define __BITLOG_H__ class Cycle_Counter; // include the absolute minimum portion of GLIB to get the definitions // for guint64, etc. #include /********************************************************************** * boolean event logging * * The boolean event logger is a simple class for logging the time * of boolean (i.e. 0/1) events. * * The event buffer is an array of 64-bit wide elements. Each element * stores the time at which an event occurs. The state of the event * is encoded in the position of the array. In other words, "high" * events are at the odd indices of the array and "low" ones at the * even ones. * * No effort is made to compress the 64-bit time entries into smaller * values. Consequently, a large amount of space is wasted. * * Repeated events are not logged. E.g.. if two 1's are logged, the * second one is ignored. * * The total number of events is defined when the class is instantiated. * The only requirement is that the number of events be an even power * of 2. A check for this is made, and */ class BoolEventLogger { private: Cycle_Counter *gcycles; // Point to gpsim's cycle counter. unsigned int index; // Index into the buffer guint64 *buffer; // Where the time is stored unsigned int max_events; // Size of the event buffer public: explicit BoolEventLogger(unsigned int _max_events = 4096); void event(bool state); /* get_index - return the current index This is used by the callers to record where in the event buffer a specific event is stored. (e.g. The start bit of a usart bit stream.) */ inline unsigned int get_index() { return index; } /// mod_index - get the index modulo buffer size (this /// exposes an implementation detail...) unsigned int mod_index(unsigned int unmodded_index) { return unmodded_index & max_events; } unsigned int get_index(guint64 event_time); void dump(int start_index, int end_index=-1); void dump_ASCII_art(guint64 time_step, guint64 start_time, int end_index=-1); unsigned int get_event(int index) { return index & 1; } bool get_state(guint64 event_time) { return (get_index(event_time) & 1) ? true : false; } int get_edges(guint64 start_time, guint64 end_time) { return ( get_index(end_time) - get_index(start_time) ) & max_events; } guint64 get_time(unsigned int index) { return buffer[mod_index(index)]; } }; /********************************************************************** * ThreeState event logging * * The ThreeState event logger is a simple class for logging the time * of 3-state events. (FixMe - the bitlog and bytelog classes should * be deprecated and merged into this class). * * The event buffer stores both the event state and the 64-bit time * at which it occurred. Event states are 'chars' so it is up to the * client of this class to interpret what the events mean. * * Repeated events are not logged. E.g.. if two 1's are logged, the * second one is ignored. * */ class ThreeStateEventLogger { private: Cycle_Counter *gcycles; // Point to gpsim's cycle counter. unsigned int index; // Index into the buffer guint64 *pTimeBuffer; // Where the time is stored char *pEventBuffer; // Where the events are stored unsigned int max_events; // Size of the event buffer bool bHaveEvents; // True if any events have been acquired public: explicit ThreeStateEventLogger(unsigned int _max_events = 4096); /// Log an Event void event(char state); inline unsigned int get_index() { return index; } unsigned int get_index(guint64 event_time); unsigned int get_nEvents(guint64 start_time,guint64 stop_time); unsigned int get_nEvents(unsigned int start_index, unsigned int stop_index); char get_state(unsigned int index) { return pEventBuffer[index & max_events]; } char get_state(guint64 event_time) { return get_state(get_index(event_time)); } guint64 get_time(unsigned int index) { return pTimeBuffer[index & max_events]; } void dump(int start_index, int end_index=-1); void dump_ASCII_art(guint64 time_step, guint64 start_time, int end_index=-1); }; #endif //!defined(__BITLOG_H__) gpsim-0.30.0/src/breakpoints.h0000664000076400007640000005114513063451152013133 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __BREAKPOINTS_H__ #define __BREAKPOINTS_H__ #include #include #include "trigger.h" #include "pic-instructions.h" #include "registers.h" #include "exports.h" #include "gpsim_object.h" // defines ObjectBreakTypes using namespace std; extern Integer *verbosity; // in ../src/init.cc class InvalidRegister; class TriggerGroup : public TriggerAction { public: protected: list triggerList; virtual ~TriggerGroup(){} }; #define MAX_BREAKPOINTS 0x400 #define BREAKPOINT_MASK (MAX_BREAKPOINTS-1) class Breakpoint_Instruction : public AliasedInstruction , public TriggerObject { public: unsigned int address; virtual bool set_break(); virtual Processor* get_cpu(); virtual void print(); virtual int printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf); virtual void clear(); virtual char const * bpName() { return "Execution"; } Breakpoint_Instruction(Processor *new_cpu, unsigned int new_address, unsigned int bp); virtual ~Breakpoint_Instruction(); virtual enum INSTRUCTION_TYPES isa() {return BREAKPOINT_INSTRUCTION;}; virtual void execute(); virtual bool isBase() { return false;} virtual bool eval_Expression(); }; class Notify_Instruction : public Breakpoint_Instruction { TriggerObject *callback; public: Notify_Instruction(Processor *cpu, unsigned int address, unsigned int bp, TriggerObject *cb); virtual ~Notify_Instruction(); virtual enum INSTRUCTION_TYPES isa() {return NOTIFY_INSTRUCTION;}; virtual void execute(); virtual char const * bpName() { return "Notify Execution"; } }; class Profile_Start_Instruction : public Notify_Instruction { public: Profile_Start_Instruction(Processor *cpu, unsigned int address, unsigned int bp, TriggerObject *cb); virtual enum INSTRUCTION_TYPES isa() {return PROFILE_START_INSTRUCTION;}; virtual char const * bpName() { return "Profile Start"; } }; class Profile_Stop_Instruction : public Notify_Instruction { public: Profile_Stop_Instruction(Processor *cpu, unsigned int address, unsigned int bp, TriggerObject *cb); virtual enum INSTRUCTION_TYPES isa() {return PROFILE_STOP_INSTRUCTION;}; virtual char const * bpName() { return "Profile Stop"; } }; // // Assertions // // Assertions are like breakpoints except that they're conditional. // For example, a user may wish to verify that the proper register // bank is selected while a variable is accessed. // class RegisterAssertion : public Breakpoint_Instruction { public: unsigned int regAddress; unsigned int regMask; unsigned int regValue; bool bPostAssertion; // True if assertion is checked after instruction simulates. typedef bool (*PFNISASSERTIONCONDITION)(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); PFNISASSERTIONCONDITION m_pfnIsAssertionBreak; enum { eRAEquals, eRANotEquals, eRAGreaterThen, eRALessThen, eRAGreaterThenEquals, eRALessThenEquals, }; static bool IsAssertionEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); static bool IsAssertionNotEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); static bool IsAssertionGreaterThenBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); static bool IsAssertionLessThenBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); static bool IsAssertionGreaterThenEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); static bool IsAssertionLessThenEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue); RegisterAssertion(Processor *new_cpu, unsigned int instAddress, unsigned int bp, unsigned int _regAddress, unsigned int _regMask, unsigned int _regValue, bool bPostAssertion=false ); RegisterAssertion(Processor *new_cpu, unsigned int instAddress, unsigned int bp, unsigned int _regAddress, unsigned int _regMask, unsigned int _operator, unsigned int _regValue, bool bPostAssertion=false ); virtual ~RegisterAssertion(); virtual void execute(); virtual void print(); virtual int printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf); virtual char const * bpName() { return "Register Assertion"; } }; class Breakpoints; #if defined(IN_MODULE) && defined(_WIN32) // we are in a module: don't access the Breakpoints object directly! LIBGPSIM_EXPORT Breakpoints & get_bp(); #else // we are in gpsim: use of get_bp() is recommended, // even if the bp object can be accessed directly. extern Breakpoints bp; inline Breakpoints &get_bp() { return bp; } #endif class Breakpoints { public: enum BREAKPOINT_TYPES { BREAK_DUMP_ALL = 0, BREAK_CLEAR = 0, BREAK_ON_EXECUTION = 1<<24, BREAK_ON_REG_READ = 2<<24, BREAK_ON_REG_WRITE = 3<<24, BREAK_ON_REG_READ_VALUE = 4<<24, BREAK_ON_REG_WRITE_VALUE = 5<<24, BREAK_ON_INVALID_FR = 6<<24, BREAK_ON_CYCLE = 7<<24, BREAK_ON_WDT_TIMEOUT = 8<<24, BREAK_ON_STK_OVERFLOW = 9<<24, BREAK_ON_STK_UNDERFLOW = 10<<24, NOTIFY_ON_EXECUTION = 11<<24, PROFILE_START_NOTIFY_ON_EXECUTION = 12<<24, PROFILE_STOP_NOTIFY_ON_EXECUTION = 13<<24, NOTIFY_ON_REG_READ = 14<<24, NOTIFY_ON_REG_WRITE = 15<<24, NOTIFY_ON_REG_READ_VALUE = 16<<24, NOTIFY_ON_REG_WRITE_VALUE = 17<<24, BREAK_ON_ASSERTION = 18<<24, BREAK_MASK = 0xff<<24 }; #define GLOBAL_CLEAR 0 #define GLOBAL_STOP_RUNNING (1<<0) #define GLOBAL_INTERRUPT (1<<1) #define GLOBAL_SLEEP (1<<2) #define GLOBAL_PM_WRITE (1<<3) #define GLOBAL_SOCKET (1<<4) #define GLOBAL_LOG (1<<5) struct BreakStatus { BREAKPOINT_TYPES type; Processor *cpu; unsigned int arg1; unsigned int arg2; TriggerObject *bpo; } break_status[MAX_BREAKPOINTS]; int m_iMaxAllocated; class iterator { public: explicit iterator(int index) : iIndex(index) { } int iIndex; iterator & operator++(int) { iIndex++; return *this; } BreakStatus * operator*() { return &get_bp().break_status[iIndex]; } bool operator!=(iterator &it) { return iIndex != it.iIndex; } }; iterator begin() { return iterator(0); } iterator end() { return iterator(m_iMaxAllocated); } BreakStatus *get(int index) { return (index>=0 && index #include #include #include #include #include #include #include "expr.h" #include "operator.h" #include "errors.h" #include "symbol.h" #include "ValueCollections.h" #include "processor.h" using namespace std; //------------------------------------------------------------------------ Expression::Expression(void) { } Expression:: ~Expression(void) { } /***************************************************************** * The LiteralArray class. */ LiteralArray::LiteralArray(ExprList_t *pExprList) { m_pExprList = pExprList; } LiteralArray::~LiteralArray() { } Value *LiteralArray::evaluate() { return new Boolean(true); } string LiteralArray::toString() { return string("FixMe"); } /***************************************************************** * The LiteralBoolean class. */ LiteralBoolean::LiteralBoolean(Boolean* value_) { //if (value_==0) { // throw new Internal ("LiteralBoolean::LiteralBoolean(): NULL value ptr"); //} assert(value_ != 0); value = value_; } LiteralBoolean::~LiteralBoolean() { delete value; } Value* LiteralBoolean::evaluate() { bool b; value->get(b); return new Boolean(b); } string LiteralBoolean::toString() { return value->toString(); } //------------------------------------------------------------------------ LiteralInteger::LiteralInteger(Integer* newValue) : Expression() { assert(newValue != 0); value = newValue; } LiteralInteger::~LiteralInteger() { delete value; } Value* LiteralInteger::evaluate() { gint64 i; value->get(i); return new Integer(i); } string LiteralInteger::toString() { //return value->toString("0x%x"); return value->toString(); } int LiteralInteger::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *expr) { return value ? value->set_break(bt,at,expr) : -1; } /***************************************************************** * The LiteralFloat class. */ LiteralFloat::LiteralFloat(Float* value_) { //if (value_==0) { // throw new Internal ("LiteralFloat::LiteralFloat(): NULL value ptr"); //} assert(value_ != 0); value = value_; } LiteralFloat::~LiteralFloat() { delete value; } Value* LiteralFloat::evaluate() { double d; value->get(d); return new Float(d); } string LiteralFloat::toString() { return value->toString(); } /***************************************************************** * The LiteralString class. */ LiteralString::LiteralString(String* value_) { //if (value_==0) { // throw new Internal ("LiteralString::LiteralString(): NULL value ptr"); //} value = value_; } LiteralString::~LiteralString() { delete value; } Value* LiteralString::evaluate() { return new String(value->getVal()); } string LiteralString::toString() { return value->toString(); } /***************************************************************** * The LiteralSymbol class * * The literal symbol is a thin 'literal' wrapper for the symbol class. * The command line parser uses LiteralSymbol whenever an expression * encounters a symbol. */ LiteralSymbol::LiteralSymbol(gpsimObject *_sym) { sym = dynamic_cast(_sym); if (!sym) { string s; if (_sym) s = "literal symbol '" + _sym->name() + "' does not have a value"; else s = "NULL pointer to literal symbol"; throw new Error(s); } } LiteralSymbol::~LiteralSymbol() { } Value* LiteralSymbol::evaluate() { if (sym) return sym->evaluate(); return 0; } Value *LiteralSymbol::GetSymbol() { return sym; } string LiteralSymbol::toString() { if(sym) return sym->name(); return string(""); } int LiteralSymbol::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *expr) { return sym ? sym->set_break(bt,at,expr) : -1; } int LiteralSymbol::clear_break() { return sym ? sym->clear_break() : -1; } /***************************************************************** * The LiteralSymbol class */ IndexedSymbol::IndexedSymbol(gpsimObject *pSymbol, ExprList_t*pExprList) : m_pExprList(pExprList) { m_pSymbol = dynamic_cast(pSymbol); assert(m_pSymbol != 0); assert(pExprList != 0); } IndexedSymbol::~IndexedSymbol() { } Value* IndexedSymbol::evaluate() { // Indexed symbols with more than one index expression // cannot be evaluated if(m_pExprList->size() > 1) { // Could return an AbstractRange throw Error("Indexed variable evaluates to more than one value"); } IIndexedCollection *pIndexedCollection = dynamic_cast(m_pSymbol); if (!pIndexedCollection) throw Error("Cannot index this variable"); else { Value *pV=m_pExprList->front()->evaluate(); unsigned int ui = *pV; return pIndexedCollection->GetAt(ui).copy(); } } string IndexedSymbol::toString() { IIndexedCollection *pIndexedCollection = dynamic_cast(m_pSymbol); if(pIndexedCollection == NULL) { return string("The symbol ") + m_pSymbol->name() + " is not an indexed variable"; } else { ostringstream sOut; sOut << pIndexedCollection->toString(m_pExprList) << ends; return sOut.str(); } return string("IndexedSymbol not initialized"); } /***************************************************************** * The RegisterExpression class * * The literal symbol is a thin 'literal' wrapper for the symbol class. * The command line parser uses RegisterExpression whenever an expression * encounters a symbol. */ RegisterExpression::RegisterExpression(unsigned int uAddress) : m_uAddress(uAddress) { } RegisterExpression::~RegisterExpression() { } Value* RegisterExpression::evaluate() { Register *pReg = get_active_cpu()->rma.get_register(m_uAddress); if(pReg) { return new Integer(pReg->get_value()); } else { static char sFormat[] = "reg(%u) is not a valid register"; char sBuffer[sizeof(sFormat) + 10]; snprintf(sBuffer, sizeof(sBuffer), sFormat, m_uAddress); throw Error(string(sBuffer)); } } string RegisterExpression::toString() { char sBuffer[10]; snprintf(sBuffer, sizeof(sBuffer), "%u", m_uAddress); return string(sBuffer); } gpsim-0.30.0/src/ctmu.h0000664000076400007640000001047313041763613011565 00000000000000/* Copyright (C) 2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __CTMU_H__ #define __CTMU_H__ #include "trace.h" class CTMU; class CTMUCONH : public sfr_register { public: CTMUCONH(Processor *pCpu, const char *pName, const char *pDesc=0, CTMU *_ctmu=0); enum { CTTRIG = 1<<0, // CTMU Special Event Trigger Control Bit IDISSEN = 1<<1, // Analog Current Source Control bit EDGSEQEN = 1<<2, // Edge Sequence Enable bit EDGEN = 1<<3, // Edge Enable bit TGEN = 1<<4, // Time Generation Enable bit CTMUSIDL = 1<<5, // Stop in Idle Mode bit CTMUEN = 1<<7 // CTMU Enable bit }; void put(unsigned int new_value); CTMU *ctmu; }; class CTMUCONL : public sfr_register { public: CTMUCONL(Processor *pCpu, const char *pName, const char *pDesc=0, CTMU *_ctmu=0); enum { EDG1STAT = 1<<0, // Edge 1 Status bit EDG2STAT = 1<<1, // Edge 2 Status bit EDG1SEL0 = 1<<2, // Edge 1 Source Select bit 0 EDG1SEL1 = 1<<3, // Edge 1 Source Select bit 1 EDG1POL = 1<<4, // Edge 1 Polarity Select bit EDG2SEL0 = 1<<5, // Edge 2 Source Select bit 0 EDG2SEL1 = 1<<6, // Edge 2 Source Select bit 1 EDG2POL = 1<<7 // Edge 2 Polarity Select bit }; void put(unsigned int new_value); CTMU *ctmu; }; class CTMUICON : public sfr_register { public: CTMUICON(Processor *pCpu, const char *pName, const char *pDesc=0, CTMU *_ctmu=0); void put(unsigned int new_value); enum { IRNG0 = 1<<0, // Current Source Range Select bit 0 IRNG1 = 1<<1, // Current Source Range Select bit 1 ITRIM0 = 1<<2, // Current Source Trim bit 0 ITRIM1 = 1<<3, // Current Source Trim bit 1 ITRIM2 = 1<<4, // Current Source Trim bit 2 ITRIM3 = 1<<5, // Current Source Trim bit 3 ITRIM4 = 1<<6, // Current Source Trim bit 4 ITRIM5 = 1<<7 // Current Source Trim bit 5 }; CTMU *ctmu; }; class ctmu_stimulus : public stimulus { public: ctmu_stimulus(Processor *pCpu, const char *n=0, double _Vth=5.0, double _Zth=1e3) : stimulus(n, _Vth, _Zth), cpu(pCpu) { } /* A current source is simulated by using a 200 V source so between 0-5 V the current should change < 2%. The maximum voltage to a pin is clamped to be below Vdd-0.5 volts. Thus when the node voltage >= Vdd-0.6 we drop the drive voltage is reduced to Vdd-0.6. This can cause an overshoot to the node voltage. */ virtual double get_Vth() { double max_volt = cpu->get_Vdd() - 0.6; if (get_nodeVoltage() >= max_volt) return max_volt; return Vth; } private: Processor *cpu; }; #define Vsrc 200. class CTMU_SignalSink; class CTMU { public: CTMU(Processor *pCpu); void new_current(double I); void enable(unsigned int value); void disable(); void current_off(); void stat_change(); void idissen(bool ground); void set_eepas(ECCPAS *_e1, ECCPAS *_e2) { m_eccpas1 = _e1; m_eccpas2=_e2;} void set_IOpins(PinModule *_pm1, PinModule *_pm2, PinModule *_pout) {m_cted1 = _pm1; m_cted2 = _pm2; m_ctpls = _pout;} void new_edge(); void tgen_on(); void tgen_off(); void syncC2out(bool high); double current; double resistance; bool cted1_state; bool cted2_state; ctmu_stimulus *ctmu_stim; PinModule *m_cted1; PinModule *m_cted2; PinModule *m_ctpls; ECCPAS *m_eccpas1; ECCPAS *m_eccpas2; CTMU_SignalSink *ctmu_cted1_sink; CTMU_SignalSink *ctmu_cted2_sink; PeripheralSignalSource *ctpls_source; CTMUCONH *ctmuconh; CTMUCONL *ctmuconl; CTMUICON *ctmuicon; ADCON0_V2 *adcon0; ADCON1_2B *adcon1; CM2CON1_V2 *cm2con1; Processor *cpu; }; #endif // __CTMU_H__ gpsim-0.30.0/src/cmd_manager.cc0000664000076400007640000000267713041763613013217 00000000000000#include "cmd_manager.h" #include #include // // CCommandManager ////////////////////////////////////////////////// CCommandManager::CCommandManager() { } int CCommandManager::Execute(string &sName, const char *cmdline) { ICommandHandler *handler = find(sName.c_str()); if (handler != NULL) { return handler->Execute(cmdline, &GetConsole()); } return CMD_ERR_PROCESSORNOTDEFINED; } int CCommandManager::Register(ICommandHandler * ch) { List::iterator it = lower_bound(m_HandlerList.begin( ), m_HandlerList.end( ), ch, lessThan()); if (it != m_HandlerList.end() && strcmp((*it)->GetName(), ch->GetName()) == 0) { return CMD_ERR_PROCESSORDEFINED; } m_HandlerList.insert(it, ch); return CMD_ERR_OK; } ICommandHandler * CCommandManager::find(const char *name) { CommandHandlerKey key(name); List::iterator it = lower_bound(m_HandlerList.begin( ), m_HandlerList.end( ), (ICommandHandler*)&key, lessThan()); if (it != m_HandlerList.end() && strcmp((*it)->GetName(), name) == 0) { return *it; } return NULL; } CCommandManager CCommandManager::m_CommandManger; CCommandManager &CCommandManager::GetManager() { return m_CommandManger; } void CCommandManager::ListToConsole() { ISimConsole &console = GetConsole(); List::iterator it; List::iterator itEnd = m_HandlerList.end(); for(it = m_HandlerList.begin( ); it != itEnd; ++it) { console.Printf("%s\n", (*it)->GetName()); } } gpsim-0.30.0/src/ValueCollections.h0000664000076400007640000002570213045306452014067 00000000000000/* Copyright (C) 1998-2004 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* This file originated by J.R. Heisey */ #ifndef __VALUECOLLECTIONS_H__ #define __VALUECOLLECTIONS_H__ #include #include #include #include #include "value.h" #include "expr.h" #include "operator.h" #include "errors.h" /* The IIndexedCollection class is an abstract class used to expose an array of values of a given name to the command prompt interface. These arrays are not dynamically resizable. The scripting language does not provide a way of allocating an array at gpsim runtime. These arrays are only definable at gpsim compile time. Values based on the class Value type are implemented via the template class IndexedCollection. The first class Value based array is implemented by CIndexedIntegerCollection. The CIndexedIntegerCollection class provides its own storage for the Integer values and is best used for Integer array based attributes. To derive your own arrays you will primarily need to derive from IIndexedCollection and define implementations for all the pure virutal functions. I (JR) have provided an example of an array implementation as an example. The class RegisterCollection is declared in register.h and is an example of how to expose data values that are not based on the Value class. The RegisterCollection exposes a gpsim command prompt array variable called ramData that exposes the data value in simulated RAM memory. When you type 'ramData' from the command prompt, all memory contents will be displayed. To display one data value type 'ramData[expr]' were expr may be an integer value or and expression that evaluates to an integer value. (i.e. To see the contents of the RAM where X contains the value of the RAM address type 'ramData[X] at the command prompt.) You may also type 'ramData[expr_list]' where expr_list are one or more expressions delimited by commas. all of the ConsolidateValues() */ class IIndexedCollection : public Value { public: IIndexedCollection(const char *pName, const char *pDesc, int iAddressRadix = 10); IIndexedCollection(int iAddressRadix = 10); virtual unsigned int GetSize() = 0; virtual Value &GetAt(unsigned int uIndex, Value *pValue=0) = 0; virtual void SetAt(unsigned int uIndex, Value *pValue) = 0; virtual void Set(Value *pValue); virtual void SetAt(ExprList_t* pIndexers, Expression *pExpr); virtual unsigned int GetLowerBound() = 0; virtual unsigned int GetUpperBound() = 0; virtual bool bIsIndexInRange(unsigned int uIndex) { return uIndex >= GetLowerBound() && uIndex <= GetUpperBound(); } void SetAddressRadix(int iRadix); virtual string toString(ExprList_t* pIndexerExprs); virtual char * toString(char *pBuffer, int len); virtual string toString(); inline Value & operator[](unsigned int uIndex) { return GetAt(uIndex); } protected: virtual void ConsolidateValues(int &iColumnWidth, vector &aList, vector &aValue) = 0; template void ConsolidateValues(int &iColumnWidth, vector &aList, vector &aValue, _ValueType *_V = 0) { unsigned int uFirstIndex = GetLowerBound(); unsigned int uIndex; unsigned int uUpper = GetUpperBound() + 1; _ValueType LastValue((_ValueType&)GetAt(uFirstIndex)); for(uIndex = uFirstIndex + 1; uIndex < uUpper; uIndex++) { _ValueType &curValue = (_ValueType&)GetAt(uIndex); if(LastValue != curValue) { PushValue(uFirstIndex, uIndex - 1, &LastValue, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); uFirstIndex = uIndex; LastValue = curValue; } } uIndex--; // Record the last set of elements if(uFirstIndex <= uIndex) { PushValue(uFirstIndex, uIndex, &LastValue, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); } } void PushValue(int iFirstIndex, int iCurrentIndex, Value *pValue, vector &asIndexes, vector &asValue); virtual string toString(int iColumnWidth, vector &asIndexes, vector &asValue); // virtual string toString(ExprList_t* pIndexers, Expression *pExpr); virtual string ElementIndexedName(unsigned int iIndex); Integer * FindInteger(const char *s); protected: char m_szPrefix[3]; int m_iAddressRadix; }; template class IndexedCollection : public IIndexedCollection { protected: typedef vector<_CT*> VectorType; typedef _CT* _ElementType; public: explicit IndexedCollection( const char * pName = NULL, const char *pDesc = 0) { m_uLower = 0; if(pName == NULL) pName = "unnamed"; new_name(pName); set_description(pDesc); } explicit IndexedCollection(unsigned int uSize, _ST stDefValue, const char * pName = NULL, const char *pDesc = 0) { m_uLower = 0; if(pName == NULL) pName = "unnamed"; Value::new_name(pName); set_description(pDesc); m_Array.reserve(uSize); string sName; char szIndex[12]; for(unsigned int uIndex = 0; uIndex < uSize; uIndex++) { sName = pName; snprintf(szIndex, sizeof(szIndex), "[%u]", uIndex + m_uLower); sName.append(szIndex); // Hmm... Do we really want to create new object for every array entry? m_Array.push_back(new _CT(sName.c_str(), stDefValue, pDesc)); } } virtual unsigned int GetSize() { return (unsigned int)m_Array.size(); } // void SetSize(unsigned int) { // } virtual Value &GetAt(unsigned int uIndex, Value * /*placeholder*/) { return GetAt(uIndex); } _CT &GetAt(unsigned int uIndex) { if(uIndex <= GetUpperBound() && uIndex >= m_uLower) { return static_cast<_CT&>(*(m_Array.at(uIndex - m_uLower))); } else { throw Error(string("Error: index out of range")); } } virtual void SetAt(unsigned int uIndex, Value *pValue) { _CT * pCTValue = dynamic_cast<_CT*>(pValue); if(pCTValue != NULL) { SetAt(uIndex, pCTValue); } else { } } void SetAt(unsigned int uIndex, _CT *pValue) { if((uIndex + 1 - m_uLower) < m_Array.size() && uIndex >= m_uLower) { _ST stValue; pValue->get(stValue); _CT * pElement = static_cast<_CT*>(m_Array.at(uIndex - m_uLower)); if (pElement) pElement->set(stValue); } else { char szIndex[10]; sprintf(szIndex, "%u", uIndex); string sMsg("invalid array index of "); sMsg.append(szIndex); throw Error(sMsg); } } inline _CT & operator[](unsigned int uIndex) { return GetAt(uIndex); } _CT & operator[](Expression *pIndexExpr) { Value *pIndex = pIndexExpr->evaluate(); String *pStr; if((pStr = dynamic_cast(pIndex)) != NULL) { // pIndex = get_symbol_table().findInteger(pStr->getVal()); pIndex = FindInteger(pStr->getVal()); } if(dynamic_cast(pIndex) != NULL) { unsigned int uIndex = (unsigned int)*pIndex; return GetAt(uIndex); } // else if(dynamic_cast(pIndex) != NULL) { // Future: Implement a indexed collection that accepts // strings where the string is used for a hashed based // collection. // } else { string sMsg; sMsg = "Indexer expression does not evaluate to an Integer for " + name(); throw Error(sMsg); } } virtual void ConsolidateValues(int &iColumnWidth, vector &aList, vector &aValue) { typename VectorType::iterator it; typename VectorType::iterator itLastEqualed; typename VectorType::iterator itEnd = m_Array.end(); unsigned int iCurrentIndex = m_uLower, iFirstIndex = m_uLower; itLastEqualed = itEnd; // The purpose of the two loops it to collapse consecutive // elements of equal value onto one display line. // This loop examines every element's value and records // the value in aValue. aList is used to record an // appropriate label for one or more elements. for(it = itLastEqualed = m_Array.begin(); it != itEnd; ++it) { if(*(_CT*)(*itLastEqualed) != *(_CT*)(*it)) { PushValue(iFirstIndex, iCurrentIndex - 1, *itLastEqualed, aList, aValue); iFirstIndex = iCurrentIndex; iColumnWidth = max(iColumnWidth, (int)aList.back().size()); itLastEqualed = it; } iCurrentIndex++; } iCurrentIndex--; // Record the last set of elements if(iFirstIndex <= iCurrentIndex) { PushValue(iFirstIndex, iCurrentIndex, *itLastEqualed, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); } } unsigned int GetLowerBound() { return m_uLower; } unsigned int GetUpperBound() { return (unsigned int)m_Array.size(); } /* --- This isn't used and I (Scott) don't understand the intent... void SetLowerBound(unsigned int uIndex) { m_uLower = uIndex; // Now iterate through the elements and change // and pre-formatted element names. typename VectorType::iterator it; typename VectorType::iterator itEnd = m_Array.end(); unsigned int iNameBufferLen = 256; char *pNameBuffer = (char*)malloc(iNameBufferLen); unsigned int uLoopIndex = m_uLower; for(it = m_Array.begin(); it != itEnd; it++) { if(iNameBufferLen < (*it)->name().size() + 2) { pNameBuffer = (char*)realloc(pNameBuffer, iNameBufferLen += 100); } sprintf(pNameBuffer, "%s[%d]", name().c_str(), uLoopIndex); (*it)->new_name(pNameBuffer); uLoopIndex++; } free(pNameBuffer); } */ protected: void push_back(_CT *p) { m_Array.push_back(p); } unsigned int m_uLower; private: VectorType m_Array; }; class CIndexedIntegerCollection : public IndexedCollection { public: CIndexedIntegerCollection(unsigned int uSize, gint64 stDefValue, const char * pName = NULL, const char *pDesc = 0) : IndexedCollection(uSize, stDefValue, pName, pDesc ) { } }; #endif // __VALUECOLLECTIONS_H__ gpsim-0.30.0/src/stimuli.cc0000664000076400007640000012600013115236716012434 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2006,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include #include #include #include #include #include "../config.h" #include "pic-processor.h" #include "stimuli.h" #include "symbol.h" #include "interface.h" #include "errors.h" #include "cmd_gpsim.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif static char num_nodes = 'a'; static int num_stimuli = 1; void gpsim_set_break_delta(guint64 delta, TriggerObject *f=0); extern Processor *active_cpu; /* * stimulus.cc * * This file contains some rudimentary infrastructure to support simulating * the environment outside of the pic. Simple net lists interconnecting pic * I/O pins and various signal generators may be created. * * Details: * There are two basic concepts behind the stimulus code: nodes and stimuli. * The nodes are like wires and the stimuli are like sources and loads. The * nodes define the interconnectivity between the stimuli. In most cases there * will be only two stimuli connected by one node. For example, you may wish * to simulate the effects of a clock input connected to porta.0 . In this case, * the stimuli would be the external clock and the pic I/O pin. */ //------------------------------------------------------------------ void Stimulus_Node::new_name(const char *cPname, bool bClearableSymbol) { cout << " Warning ignoring stimulus node name change from " << name() << " to " << cPname < cap_start_cycle) // RC calculation in progress, get current value callback(); return(voltage); } void dump_stimulus_list(void) { cout << "Stimulus List\n"; cout << " implement -- stimuli.cc dump_stimulus_list\n"; /* Symbol_Table &ST = get_symbol_table(); Symbol_Table::stimulus_symbol_iterator it; Symbol_Table::stimulus_symbol_iterator itEnd = ST.endStimulusSymbol(); for(it = ST.beginStimulusSymbol(); it != itEnd; it++) { stimulus *t = (*it)->getStimulus(); if(t) { cout << t->name(); //if(t->snode) // cout << " attached to " << t->snode->name(); t->show(); cout << '\n'; } } */ } string Stimulus_Node::toString() { string out = name() + " : " + showType(); for(stimulus *pt = stimuli; pt; pt = pt->next) { out += "\n\n " + pt->name() + pt->toString(); } return out; } //======================================================================== Stimulus_Node::Stimulus_Node(const char *n) : TriggerObject(0) { warned = 0; voltage = 0; Cth = 0.0; Zth = 0.0; current_time_constant = 0.0; delta_voltage = 0.0; minThreshold = 0.1; // volts cap_start_cycle = 0; future_cycle = 0; initial_voltage = 0.0; DCVoltage = 0.0; bSettling = false; stimuli = 0; nStimuli = 0; settlingTimeStep = 0; if(n) gpsimObject::new_name(n); else { char name_str[100]; snprintf(name_str,sizeof(name_str),"node%d",num_nodes); num_nodes++; // %%% FIX ME %%% gpsimObject::new_name(name_str); } globalSymbolTable().addSymbol(this); gi.node_configuration_changed(this); } Stimulus_Node::~Stimulus_Node() { //cout << "~Stimulus_Node\n"; stimulus *sptr; sptr = stimuli; while(sptr) { sptr->detach(this); sptr = sptr->next; } globalSymbolTable().removeSymbol(this); } Stimulus_Node * Stimulus_Node::construct(const char * psName) { gpsimObject *psn = globalSymbolTable().find(psName); //cout << "constructing stimulus node " << psName << endl; if(psn) { cout << "Warning ignoring node creation. A symbol with the name `" << psName << "' is already in the sybmol table.\n"; return 0; } return new Stimulus_Node(psName); } // // Add the stimulus 's' to the stimulus list for this node // void Stimulus_Node::attach_stimulus(stimulus *s) { if (!s) return; stimulus *sptr; warned = 0; if(stimuli) { sptr = stimuli; bool searching=1; int nTotalStimuliConnected = 1; while(searching) { if(s == sptr) return; // The stimulus is already attached to this node. nTotalStimuliConnected++; if(sptr->next == 0) { sptr->next = s; // s->next = 0; This is done below searching=0; } sptr = sptr->next; } nStimuli = nTotalStimuliConnected; } else { stimuli = s; // This is the first stimulus attached to this node. nStimuli = 1; } // If we reach this point, then it means that the stimulus that we're // trying to attach has just been placed at the end of the the stimulus // list for this node. So we need to 0 terminate the singly-linked list. s->next = 0; // Now tell the stimulus to attach itself to the node too // (If it hasn't already.) s->attach(this); gi.node_configuration_changed(this); } // // Search for the stimulus 's' in the stimulus list for this node. // If it is found, then remove it from the list. // void Stimulus_Node::detach_stimulus(stimulus *s) { stimulus *sptr; if(!s) // You can't remove a non-existant stimulus return; if(stimuli) { if(s == stimuli) { // This was the first stimulus in the list. stimuli = s->next; s->detach(this); nStimuli--; } else { sptr = stimuli; do { if(s == sptr->next) { sptr->next = s->next; s->detach(this); nStimuli--; //gi.node_configuration_changed(this); return; } sptr = sptr->next; } while(sptr); } } } //------------------------------------------------------------------------ // // Stimulus_Node::update(guint64 current_time) // // update() is called whenever a stimulus attached to this node changes // states. void Stimulus_Node::update(guint64 current_time) { // So far, 'update' only applies to the current time. update(); } //------------------------------------------------------------------------ // refresh() - compute the Thevenin voltage and Thevenin impedance // void Stimulus_Node::refresh() { if(stimuli) { stimulus *sptr = stimuli; initial_voltage = get_nodeVoltage(); switch (nStimuli) { case 0: // hmm, strange nStimuli is 0, but the stimuli pointer is non null. break; case 1: // Only one stimulus is attached. DCVoltage = sptr->get_Vth(); // RP - was just voltage Zth = sptr->get_Zth(); break; case 2: // 2 stimuli are attached to the node. This is the typical case // and we'll optimize for it. { stimulus *sptr2 = sptr ? sptr->next : 0; if(!sptr2) break; // error, nStimuli is two, but there aren't two stimuli double V1,Z1,C1; double V2,Z2,C2; sptr->getThevenin(V1,Z1,C1); sptr2->getThevenin(V2,Z2,C2); DCVoltage = (V1*Z2 + V2*Z1) / (Z1+Z2); Zth = Z1*Z2/(Z1+Z2); Cth = C1+C2; } break; default: { /* There are 3 or more stimuli connected to this node. Recall that these are all in parallel. The Thevenin voltage and impedance for this is: Thevenin impedance: Zt = 1 / sum(1/Zi) Thevenin voltage: Vt = sum( Vi / ( ((Zi - Zt)/Zt) + 1) ) = sum( Vi * Zt /Zi) = Zt * sum(Vi/Zi) */ double conductance=0.0; // Thevenin conductance. Cth=0; DCVoltage=0.0; //cout << "multi-node summing:\n"; while(sptr) { double V1,Z1,C1; sptr->getThevenin(V1,Z1,C1); /* cout << " N: " <name() << " V=" << V1 << " Z=" << Z1 << " C=" << C1 << endl; */ double Cs = 1 / Z1; DCVoltage += V1 * Cs; conductance += Cs; Cth += C1; sptr = sptr->next; } Zth = 1.0/conductance; DCVoltage *= Zth; } } current_time_constant = Cth * Zth; Dprintf(("%s DCVoltage %.3f voltage %.3f Cth=%.2e Zth=%2e time_constant %fsec or %" PRINTF_GINT64_MODIFIER "d cycles now=%" PRINTF_GINT64_MODIFIER "d \n",name().c_str(), DCVoltage, voltage, Cth, Zth, current_time_constant, (guint64)(current_time_constant*get_cycles().instruction_cps()), get_cycles().get())); if (((guint64)(current_time_constant*get_cycles().instruction_cps()) < 5) || (fabs(DCVoltage - voltage) < minThreshold)) { if (verbose) cout << "Stimulus_Node::refresh " << name() << " use DC " << DCVoltage << " as current_time_constant=" << current_time_constant << endl; if (future_cycle) // callback is active { get_cycles().clear_break(this); } voltage = DCVoltage; future_cycle = 0; } else { settlingTimeStep = calc_settlingTimeStep(); voltage = initial_voltage; if (verbose) cout << "Stimulus_Node::refresh " << name() << " settlingTimeStep=" << settlingTimeStep << " voltage=" << voltage << " Finalvoltage=" << DCVoltage << endl; /* If future_cycle is not 0 we are in the middle of an RC calculation, but an input condition has changed. */ if (future_cycle && (get_cycles().get() > cap_start_cycle)) { callback(); } else { if (future_cycle) get_cycles().clear_break(this); cap_start_cycle = get_cycles().get(); future_cycle = cap_start_cycle + settlingTimeStep; get_cycles().set_break(future_cycle,this); #ifdef DEBUG get_cycles().dump_breakpoints(); #endif } } } } guint64 Stimulus_Node::calc_settlingTimeStep() { /* Select a time interval where the voltage does not change more than about 0.125 volts in each step(unless timestep < 1). First we calculate dt_dv = CR/V with dt in cpu cycles to determine settling time step */ guint64 TimeStep; double dv = fabs(DCVoltage - voltage); // avoid divide by zero if (dv < 0.000001) dv = 0.000001; double dt_dv = get_cycles().instruction_cps()*current_time_constant/dv; TimeStep = (guint64) (0.125 * dt_dv); TimeStep = (TimeStep) ? TimeStep : 1; Dprintf(("%s dt_dv = %.2f TimeStep 0x%" PRINTF_GINT64_MODIFIER "x now 0x%" PRINTF_GINT64_MODIFIER "x\n", __FUNCTION__, dt_dv, TimeStep, get_cycles().get())); return(TimeStep); } //------------------------------------------------------------------------ // updateStimuli // // drive all the stimuli connected to this node. void Stimulus_Node::updateStimuli() { stimulus *sptr = stimuli; while(sptr) { sptr->set_nodeVoltage(voltage); sptr = sptr->next; } } void Stimulus_Node::update() { if(stimuli) { refresh(); updateStimuli(); } } void Stimulus_Node::set_nodeVoltage(double v) { voltage = v; updateStimuli(); } //------------------------------------------------------------------------ void Stimulus_Node::callback() { if (verbose) callback_print(); initial_voltage = voltage; double Time_Step; double expz; // // increase time step as capacitor charges more slowly as final // voltage is approached. // // // The following is an exact calculation, assuming no circuit // changes, regardless of time step. // Time_Step = (get_cycles().get() - cap_start_cycle)/ (get_cycles().instruction_cps()*current_time_constant); expz = exp(-Time_Step); voltage = DCVoltage - (DCVoltage - voltage)*expz; if (verbose) cout << "\tVoltage was " << initial_voltage << "V now " << voltage << "V\n"; if (fabs(DCVoltage - voltage) < minThreshold) { voltage = DCVoltage; if (future_cycle) get_cycles().clear_break(this); future_cycle = 0; if (verbose) cout << "\t" << name() << " Final voltage " << DCVoltage << " reached at " << get_cycles().get() << " cycles\n"; Dprintf(("%s DC Voltage %.2f reached at 0x%" PRINTF_GINT64_MODIFIER "x cycles\n", name().c_str(), DCVoltage, get_cycles().get())); } else if(get_cycles().get() >= future_cycle) // got here via break { settlingTimeStep = calc_settlingTimeStep(); cap_start_cycle = get_cycles().get(); get_cycles().clear_break(this); future_cycle = cap_start_cycle + settlingTimeStep; get_cycles().set_break(future_cycle, this); #ifdef DEBUG get_cycles().dump_breakpoints(); #endif if (verbose) cout << "\tBreak reached at " << cap_start_cycle << " cycles, next break set for " << future_cycle << " delta=" << settlingTimeStep << endl; } else // updating value before break don't increase step size { cap_start_cycle = get_cycles().get(); get_cycles().reassign_break(future_cycle, cap_start_cycle + settlingTimeStep, this); future_cycle = get_cycles().get() + settlingTimeStep; if (verbose) cout << "\tcallback called at " << cap_start_cycle << " cycles, next break set for " << future_cycle << " delta=" << settlingTimeStep << endl; } updateStimuli(); } //------------------------------------------------------------------------ void Stimulus_Node::callback_print() { cout << "Node: " << name() ; TriggerObject::callback_print(); } //------------------------------------------------------------------------ stimulus::stimulus(const char *cPname,double _Vth, double _Zth) : Value(cPname, "", 0),snode(0), next(0), bDrivingState(false), bDriving(false), Vth(_Vth), Zth(_Zth), Cth(0.0), // Farads nodeVoltage(0.0) // volts { } void stimulus::new_name(const char *cPname, bool bClearableSymbol) { globalSymbolTable().removeSymbol(this); gpsimObject::new_name(cPname); globalSymbolTable().addSymbol(this); stimulus *psn = dynamic_cast(globalSymbolTable().find(name())); if (psn) { if (psn == this) ; //cout << "Successfully added " << name() << " to symbol table\n"; else cout << "Successfully added " << name() << " but it's not equal to this node\n"; } else cout << "Failed to add " << name() << " to symbol table\n"; /* const char *cPoldName = name().c_str(); if(name_str.empty() && cPname != NULL && *cPname != 0) { // Assume never in symbol table. // Every named stimulus goes into the symbol table. gpsimObject::new_name(cPname); symbol_table.add_stimulus(this,bClearableSymbol); return; } if(symbol_table.Exist(cPoldName)) { // The symbol is in the symbol table. Since the // symbol table is ordered we need to let the // symbol table rename the object to maintain // ordering. Yuk. // Note that rename() will call stimulus::new_name() // after the symbol is removed. This recursive // call will then enter the branch that calls // gpsimObject::new_name(). The simulus with // its new name is added into the symbol table. symbol_table.rename(cPoldName,cPname); } else { gpsimObject::new_name(cPname); } */ } void stimulus::new_name(string &rName, bool bClearableSymbol) { new_name(rName.c_str(),bClearableSymbol); } stimulus::~stimulus(void) { if(snode) snode->detach_stimulus(this); globalSymbolTable().removeSymbol(this); //cout << "Removing " << name() << " from ST\n"; } void stimulus::show() { GetUserInterface().DisplayMessage(toString().c_str()); } string stimulus::toString() { ostringstream s; s << " stimulus "; if(snode) s << " attached to " << snode->name(); s << endl << " Vth=" << get_Vth() << "V" << " Zth=" << get_Zth() << " ohms" << " Cth=" << get_Cth() << "F" << " nodeVoltage= " << get_nodeVoltage() << "V" << endl << " Driving=" << getDriving() << " drivingState=" << getDrivingState() << " drivenState=" << getDrivenState() << " bitState=" << getBitChar(); return s.str(); } void stimulus::attach(Stimulus_Node *s) { detach(snode); snode = s; } void stimulus::detach(Stimulus_Node *s) { if(snode == s) snode = 0; } void stimulus::getThevenin(double &v, double &z, double &c) { v = get_Vth(); z = get_Zth(); c = get_Cth(); } //======================================================================== // PinMonitor::PinMonitor() { } PinMonitor::~PinMonitor() { // Release all of the sinks: list :: iterator ssi = sinks.begin(); while (ssi != sinks.end()) { Dprintf(("release sink %p\n", *ssi)); fflush(stdout); (*ssi)->release(); ++ssi; } list :: iterator asi = analogSinks.begin(); while (asi != analogSinks.end()) { (*asi)->release(); ++asi; } } void PinMonitor::addSink(SignalSink *new_sink) { if(new_sink) { //cout << "Adding sink: " << new_sink << endl; sinks.push_back(new_sink); } } void PinMonitor::removeSink(SignalSink *pSink) { if(pSink) { sinks.remove(pSink); } } void PinMonitor::addSink(AnalogSink *new_sink) { if(new_sink) analogSinks.push_back(new_sink); } void PinMonitor::removeSink(AnalogSink *pSink) { if(pSink) analogSinks.remove(pSink); } //======================================================================== square_wave::square_wave(unsigned int p, unsigned int dc, unsigned int ph, const char *n) { //cout << "creating sqw stimulus\n"; if(n) new_name(n,false); else { char name_str[100]; snprintf(name_str,sizeof(name_str),"s%d_square_wave",num_stimuli); num_stimuli++; new_name(name_str, false); } period = p; // cycles duty = dc; // # of cycles over the period for which the sq wave is high phase = ph; // phase of the sq wave wrt the cycle counter time = 0; // simulation time snode = 0; next = 0; } double square_wave::get_Vth() { guint64 current_time = get_cycles().get(); if(verbose & 1) cout << "Getting new state of the square wave.\n"; if( ((current_time+phase) % period) <= duty) return Vth; else return 0.0; } //======================================================================== // // triangle_wave triangle_wave::triangle_wave(unsigned int p, unsigned int dc, unsigned int ph, const char *n) { //cout << "creating sqw stimulus\n"; if(n) new_name(n,false); else { char name_str[100]; snprintf(name_str,sizeof(name_str),"s%d_triangle_wave",num_stimuli); num_stimuli++; new_name(name_str,false); } if(p==0) //error p = 1; // copy the square wave stuff period = p; // cycles duty = dc; // # of cycles over the period for which the sq wave is high phase = ph; // phase of the sq wave wrt the cycle counter time = 0; // simulation time snode = 0; next = 0; //cout << "duty cycle " << dc << " period " << p << " drive " << drive << '\n'; // calculate the slope and the intercept for the two lines comprising // the triangle wave: if(duty) m1 = Vth/duty; else m1 = Vth/period; // m1 will not be used if the duty cycle is zero b1 = 0; if(period != duty) m2 = Vth/(duty - period); else m2 = Vth; b2 = -m2 * period; //cout << "m1 = " << m1 << " b1 = " << b1 << '\n'; //cout << "m2 = " << m2 << " b2 = " << b2 << '\n'; } double triangle_wave::get_Vth() { guint64 current_time = get_cycles().get(); //cout << "Getting new state of the triangle wave.\n"; guint64 t = (current_time+phase) % period; double ret_val; if( t <= duty) ret_val = b1 + m1 * t; else ret_val = b2 + m2 * t; // cout << "Triangle wave: t = " << t << " value = " << ret_val << '\n'; return ret_val; } //======================================================================== // // Event Event::Event(void) { current_state = 0; } //======================================================================== // void Event::callback(void) { // If there's a node attached to this stimulus, then update it. if(snode) snode->update(); // If the event is inactive. if(current_state == 0) { get_cycles().set_break_delta(1,this); current_state = 1; } else { current_state = 0; } } void source_stimulus::callback_print(void) { cout << "stimulus " << name() << " CallBack ID " << CallBackID << '\n'; } void source_stimulus::callback(void) { cout << "shouldn't be called\n"; } void source_stimulus::show() { stimulus::show(); } void source_stimulus::put_period(Value *pValue) { if (pValue) pValue->get(period); } void source_stimulus::put_duty(Value *pValue) { if (pValue) pValue->get(duty); } void source_stimulus::put_phase(Value *pValue) { if (pValue) pValue->get(phase); } void source_stimulus::put_initial_state(Value *pValue) { if (pValue) pValue->get(initial_state); } void source_stimulus::put_start_cycle(Value *pValue) { if (pValue) pValue->get(start_cycle); } //======================================================================== // IOPIN::IOPIN(const char *_name, double _Vth, double _Zth, double _ZthWeak, double _ZthFloating ) : stimulus(_name,_Vth, _Zth), gui_name_updated(false), bDrivenState(false), cForcedDrivenState('Z'), m_monitor(0), ZthWeak(_ZthWeak), ZthFloating(_ZthFloating), l2h_threshold(2.0), // PICs are CMOS and use CMOS-like thresholds h2l_threshold(1.0), Vdrive_high(4.4), Vdrive_low(0.6) { if(verbose) cout << "IOPIN default constructor\n"; is_analog = false; } void IOPIN::set_digital_threshold(double vdd) { set_l2h_threshold(vdd > 4.5 ? 2.0 : 0.25 * vdd + 0.8); set_h2l_threshold(vdd > 4.5 ? 0.8 : 0.15 * vdd); Vdrive_high = vdd - 0.6; Vdrive_low = 0.6; } void IOPIN::setMonitor(PinMonitor *new_pinMonitor) { if (m_monitor && new_pinMonitor) cout << "IOPIN already has a monitor!" << endl; else m_monitor = new_pinMonitor; } IOPIN::~IOPIN() { if (m_monitor) ((PinModule *)m_monitor)->clrPin(); } void IOPIN::get(char *return_str, int len) { if (return_str) { if (get_direction() == DIR_OUTPUT) strncpy(return_str, IOPIN::getDrivingState()?"1": "0", len); else strncpy(return_str, IOPIN::getState()?"1": "0", len); } } void IOPIN::attach(Stimulus_Node *s) { snode = s; } void IOPIN::show() { stimulus::show(); } //-------------------- // set_nodeVoltage() // // void IOPIN::set_nodeVoltage(double new_nodeVoltage) { if(verbose & 1) cout << name()<< " set_nodeVoltage old="<update(); } if(m_monitor) m_monitor->putState(new_state?'1':'0'); } void IOPIN::putState(double new_Vth) { if(new_Vth != Vth) { Vth = new_Vth; if (Vth <= 0.3) bDrivingState = false; else bDrivingState = true; if(verbose & 1) cout << name()<< " putState=" << new_Vth << endl; // If this pin is tied to a node, then update the node. if(snode) snode->update(); } if(m_monitor) m_monitor->putState(bDrivingState?'1':'0'); } //------------------------------------------------------------ bool IOPIN::getState() { return getDriving() ? getDrivingState() : getDrivenState(); } void IOPIN::setDrivingState(bool new_state) { bDrivingState = new_state; if(m_monitor) m_monitor->setDrivingState(bDrivingState?'1':'0'); if(verbose & 1) cout << name()<< " setDrivingState= " << (new_state ? "high" : "low") << endl; } void IOPIN::setDrivingState(char new3State) { bDrivingState = (new3State=='1' || new3State=='W'); if(m_monitor) m_monitor->setDrivingState(new3State); } bool IOPIN::getDrivingState(void) { return bDrivingState; } bool IOPIN::getDrivenState() { return bDrivenState; } //------------------------------------------------------------------------ // setDrivenState // // An stimulus attached to this pin is driving us to a new state. // This state will be recorded and propagate up to anything // monitoring this pin. void IOPIN::setDrivenState(bool new_state) { bDrivenState = new_state; if(verbose & 1) cout << name()<< " setDrivenState= " << (new_state ? "high" : "low") << endl; // Propagate the new state to those things monitoring this pin. // (note that the 3-state value is what's propagated). if(m_monitor && !is_analog) { m_monitor->setDrivenState(getBitChar()); if(verbose & 16) cout << name() << " setting state of monitor to " << getBitChar() << endl; } } //------------------------------------------------------------------------ // forceDrivenState() - allows the 'driven state' to be manipulated whenever // there is no snode attached. The primary purpose of this is to allow the // UI to toggle I/O pin states. // void IOPIN::forceDrivenState(char newForcedState) { if (cForcedDrivenState != newForcedState) { cForcedDrivenState = newForcedState; bDrivenState = cForcedDrivenState=='1' || cForcedDrivenState=='W'; if(m_monitor) { m_monitor->setDrivenState(getBitChar()); m_monitor->updateUI(); } } } char IOPIN::getForcedDrivenState() { return cForcedDrivenState; } void IOPIN::toggle() { putState((bool) (getState() ^ true)); } /************************************* * int IOPIN::get_Vth() * * If this iopin has a stimulus attached to it then * the voltage will be dictated by the stimulus. Otherwise, * the voltage is determined by the state of the ioport register * that is inside the pic. For an input (like this), the pic code * that is being simulated can not change the state of the I/O pin. * However, the user has the ability to modify the state of * this register either by writing directly to it in the cli, * or by clicking in one of many places in the gui. */ double IOPIN::get_Vth() { return Vth; } char IOPIN::getBitChar() { if(!snode) return getForcedDrivenState(); // RCP - Changed to match IO_bi_directional // was return 'Z'; // High impedance - unknown state. if(snode->get_nodeZth() > ZthFloating) return 'Z'; if(snode->get_nodeZth() > ZthWeak) return getDrivenState() ? 'W' : 'w'; return getDrivenState() ? '1' : '0'; } void IOPIN::newGUIname(const char *s) { if(s) { gui_name_updated = true; gui_name = string(s); } } string &IOPIN::GUIname(void) const { return (string &)gui_name; } //======================================================================== // IO_bi_directional::IO_bi_directional(const char *_name, double _Vth, double _Zth, double _ZthWeak, double _ZthFloating, double _VthIn, double _ZthIn) : IOPIN(_name, _Vth, _Zth, _ZthWeak, _ZthFloating), ZthIn(_ZthIn), VthIn(_VthIn) { } void IO_bi_directional::set_nodeVoltage( double new_nodeVoltage) { IOPIN::set_nodeVoltage(new_nodeVoltage); } double IO_bi_directional::get_Vth() { if(getDriving()) return getDrivingState() ? Vth : 0; //return getDrivingState() ? VthIn : 0; return VthIn; } double IO_bi_directional::get_Zth() { return getDriving() ? Zth : ZthIn; } /* getBitChar() returns bit status as follows Input pin 1> Pin considered floating, return 'Z' 2> Weak Impedance on pin, return 'W" if high or 'w' if low 3> Pin being driven externally return '1' node voltage high '0' if low Output pin 1> Node voltage opposite driven value return 'X' if node voltage high or 'x' if inode voltage low 2> Node voltage same as driven value return '1' node voltage high '0' if low */ char IO_bi_directional::getBitChar() { if(!snode && !getDriving() ) return getForcedDrivenState(); if(snode) { if (!getDriving()) // input pin { if(snode->get_nodeZth() > ZthFloating) return 'Z'; if(snode->get_nodeZth() > ZthWeak) return getDrivenState() ? 'W' : 'w'; } else if(getDrivenState() != getDrivingState()) return getDrivenState() ? 'X' : 'x'; } return getDrivenState() ? '1' : '0'; } //--------------- //::update_direction(unsigned int new_direction) // // This is called when a new value is written to the tris register // with which this bi-direction pin is associated. void IO_bi_directional::update_direction(unsigned int new_direction, bool refresh) { setDriving(new_direction ? true : false); // If this pin is not associated with an IO Port, but it's tied // to a stimulus, then we need to update the stimulus. if(refresh && snode) snode->update(); } void IO_bi_directional::putState(bool new_state) { IOPIN::putState(new_state); } void IO_bi_directional::putState(double new_Vth) { VthIn = new_Vth; IOPIN::putState(new_Vth); } IO_bi_directional_pu::IO_bi_directional_pu(const char *_name, double _Vth, double _Zth, double _ZthWeak, double _ZthFloating, double _VthIn, double _ZthIn, double _Zpullup) : IO_bi_directional(_name, _Vth, _Zth, _ZthWeak, _ZthFloating, _VthIn, _ZthIn), Zpullup(_Zpullup) { Vpullup = Vth; bPullUp = false; } IO_bi_directional_pu::~IO_bi_directional_pu(void) { } void IO_bi_directional_pu::set_is_analog(bool flag) { if (is_analog != flag) { is_analog = flag; if (snode) snode->update(); else if (!getDriving()) setDrivenState(bPullUp && ! is_analog); } } void IO_bi_directional_pu::update_pullup(char new_state, bool refresh) { bool bNewPullupState = new_state == '1' || new_state == 'W'; if (bPullUp != bNewPullupState) { bPullUp = bNewPullupState; if (refresh) { // If there is a node attached to the pin, then we already // know the driven state. If there is no node attached and // this pin is configured as an input, then let the drivenState // be the same as the pullup state. if (snode) snode->update(); else if (!getDriving()) setDrivenState(bPullUp && ! is_analog); } } } double IO_bi_directional_pu::get_Zth() { return getDriving() ? Zth : ((bPullUp && ! is_analog)? Zpullup : ZthIn); } double IO_bi_directional_pu::get_Vth() { /**/ if(verbose & 1) cout << " " << name() << " get_Vth PU " << " driving=" << getDriving() << " DrivingState=" << getDrivingState() << " bDrivenState=" << bDrivenState << " Vth=" << Vth << " VthIn=" << VthIn << " bPullUp=" << bPullUp << " is_analog=" << is_analog << endl; /**/ // If the pin is configured as an output, then the driving voltage // depends on the pin state. If the pin is an input, and the pullup resistor // is enabled, then the pull-up resistor will 'drive' the output. The // open circuit voltage in this case will be Vth (the thevenin voltage, // which is assigned to be same as the processor's supply voltage). if(getDriving()) return getDrivingState() ? Vth : 0; else return (bPullUp && ! is_analog) ? Vpullup : VthIn; } /* getBitChar() returns bit status as follows Input pin 1> Pin considered floating, return 'Z' 2> Weak Impedance on pin, return 'W" if high or 'w' if low 3> Pin being driven externally return '1' node voltage high '0' if low Output pin 1> Node voltage opposite driven value return 'X' if node voltage high or 'x' if inode voltage low 2> Node voltage same as driven value return '1' node voltage high '0' if low */ char IO_bi_directional_pu::getBitChar() { if(!snode && !getDriving() ) { char cForced=getForcedDrivenState(); return (cForced=='Z' && bPullUp) ? 'W' : cForced; } if(snode) { if (!getDriving()) // input pin { if(snode->get_nodeZth() > ZthFloating) return 'Z'; if(snode->get_nodeZth() > ZthWeak) return getDrivenState() ? 'W' : 'w'; } else if(getDrivenState() != getDrivingState()) return getDrivenState() ? 'X' : 'x'; } return getDrivenState() ? '1' : '0'; } IO_open_collector::IO_open_collector(const char *_name) : IO_bi_directional_pu(_name) { } double IO_open_collector::get_Vth() { /**/ if(verbose & 1) cout << name() << " get_Vth OC" << " driving=" << getDriving() << " DrivingState=" << getDrivingState() << " bDrivenState=" << bDrivenState << " Vth=" << Vth << " VthIn=" << VthIn << " bPullUp=" << bPullUp << endl; /**/ if(getDriving() && !getDrivingState()) return 0.0; return bPullUp ? Vpullup : VthIn; } double IO_open_collector::get_Zth() { if(getDriving() && !getDrivingState()) return Zth; return bPullUp ? Zpullup : ZthIn; } char IO_open_collector::getBitChar() { if(!snode && !getDriving() ){ char cForced=getForcedDrivenState(); return (cForced=='Z' && bPullUp) ? 'W' : cForced; } if(snode) { if(snode->get_nodeZth() > ZthFloating) return bPullUp ? 'W' : 'Z'; if(getDriving() && getDrivenState() && !getDrivingState()) return 'X'; if(snode->get_nodeZth() > ZthWeak) return getDrivenState() ? 'W' : 'w'; else return getDrivenState() ? '1' : '0'; } return getDrivingState() ? 'W' : '0'; } //======================================================================== //======================================================================== // // ValueStimulus // // A Value stimulus is a stream of data that can change values at // arbitrary times. An array called 'transition_cycles' stores the times // and an array 'values' stores the values. // When first initialized, the stimulus is driven to its initial state. // A break point is set on the cycle counter for the next cpu cycle that // the stimulus is expected to change values. When the break occurs, // the current state is updated to the next value and then a break is set // for the next expect change. This cycle occurs until all of the values // have been generated. When the end is reached, the asynchronous stimulus // will restart from the beginning. The member variable 'period' describes // the magnitude of the rollover (if it's zero then there is no rollover). // ValueStimulus::ValueStimulus(const char *n) : source_stimulus() { initial.time = 0; initial.v = 0; current = 0; if(n) { new_name(n,false); } else { char name_str[100]; snprintf(name_str,sizeof(name_str),"s%d_asynchronous_stimulus",num_stimuli); num_stimuli++; new_name(name_str,false); } } void ValueStimulus::get(char *return_str, int len) { if (return_str) { double d = get_Vth(); snprintf(return_str,len,"%.2fV",d); } } ValueStimulus::~ValueStimulus() { delete initial.v; delete current; for(sample_iterator = samples.begin(); sample_iterator != samples.end(); ++sample_iterator) { delete (*sample_iterator).v; } } void ValueStimulus::show() { // print the electrical stuff stimulus::show(); cout << "\n states = " << samples.size() << '\n'; list::iterator si; for(si = samples.begin(); si != samples.end(); ++si) { //double d; //(*si).v->get(d); cout << " t=" << dec << (*si).time << ",v=" << (*si).v->toString() << '\n'; } if (initial.v) cout << " initial=" << initial.v->toString() << '\n'; cout << " period=" << period << '\n' << " start_cycle=" << start_cycle << '\n' << " Next break cycle=" << future_cycle << '\n'; } void ValueStimulus::callback() { guint64 current_cycle = future_cycle; current = next_sample.v; if(verbose & 1) cout << "asynchro cycle " << current_cycle << " state " << current->toString() << '\n'; // If there's a node attached to this stimulus, then update it. if(snode) snode->update(); ValueStimulusData *n = getNextSample(); if(n) { next_sample = *n; if(verbose & 1) { cout << " current_sample (" << next_sample.time << "," << next_sample.v->toString() << ")\n"; cout << " start cycle " << start_cycle << endl; } // get the cycle when the data will change next future_cycle = next_sample.time + start_cycle; if(future_cycle <= current_cycle) { // There's an error in the data. Set a break on the next simulation cycle // and see if it can be resolved. future_cycle = current_cycle+1; } get_cycles().set_break(future_cycle, this); } else future_cycle = 0; if(verbose & 1) cout <<" next transition = " << future_cycle << '\n'; } void ValueStimulus::put_initial_state(Value *pValue) { if (pValue && !initial.v) { initial.time = 0; initial.v = pValue->copy(); } } void ValueStimulus::put_data(ValueStimulusData &data_point) { ValueStimulusData *sample = new ValueStimulusData; sample->time = data_point.time; sample->v = data_point.v; samples.push_back(*sample); } double ValueStimulus::get_Vth() { double v=initial_state; if(current) { try { current->get(v); if(digital && v >0.0) v = 5.0; } catch (Error *err) { if(err) { cout << "Warning stimulus: " << name() << " failed on: "<< err->toString() << endl; delete err; } } } return v; } void ValueStimulus::start() { if(verbose & 1) cout << "Starting asynchronous stimulus\n"; if(period) { // Create a data point for the rollover condition. // If an initial value was supplied when the stimulus was created, then // that's what we'll use for the rollover. Otherwise, we'll create // a rollover based on 'initial_state' (which should be a default value). ValueStimulusData vSample; vSample.time = period; vSample.v = initial.v ? initial.v : new Float(initial_state); put_data(vSample); } sample_iterator = samples.begin(); if(sample_iterator != samples.end()) { if(digital) initial_state = (initial_state > 0.0) ? Vth : 0.0; current = initial.v; next_sample = *sample_iterator; future_cycle = next_sample.time + start_cycle; get_cycles().set_break(future_cycle, this); } if(verbose & 1) cout << "asy should've been started\n"; } ValueStimulusData *ValueStimulus::getNextSample() { ++sample_iterator; if(sample_iterator == samples.end()) { // We've gone through all of the data. Now let's try to start over sample_iterator = samples.begin(); // If the period is zero then we don't want to // regenerate the data stream. if(period == 0) return 0; start_cycle += period; if(verbose & 1) { cout << " asynchronous stimulus rolled over\n" << " next start_cycle " << start_cycle << " period " << period << '\n'; } } return &(*sample_iterator); } //------------------------------------------------------------------------ AttributeStimulus::AttributeStimulus(const char *n) : ValueStimulus(n), attr(0) { } /* AttributeStimulus::~AttributeStimulus() { ValueStimulus::~ValueStimulus(); } */ void AttributeStimulus::show() { if (attr) cout << "\nDriving Attribute:" << attr->name() << endl; ValueStimulus::show(); } void AttributeStimulus::callback() { guint64 current_cycle = future_cycle; current = next_sample.v; if(verbose & 1) cout << "asynchro cycle " << current_cycle << " state " << current->toString() << '\n'; // If there's a node attached to this stimulus, then update it. if(attr) attr->set(current); ValueStimulusData *n = getNextSample(); if(n) { next_sample = *n; if(verbose & 1) { cout << " current_sample (" << next_sample.time << "," << next_sample.v->toString() << ")\n"; cout << " start cycle " << start_cycle << endl; } // get the cycle when the data will change next future_cycle = next_sample.time + start_cycle; if(future_cycle <= current_cycle) { // There's an error in the data. Set a break on the next simulation cycle // and see if it can be resolved. future_cycle = current_cycle+1; } get_cycles().set_break(future_cycle, this); } else future_cycle = 0; if(verbose & 1) cout <<" next transition = " << future_cycle << '\n'; } void AttributeStimulus::setClientAttribute(Value *v) { if(attr) cout << "overwriting target attribute in AttributeStimulus\n"; attr = v; if((bool)verbose && v) cout << " attached " << name() << " to attribute: " << v->name() << endl; } //======================================================================== // // helper functions follow here void stimuli_attach(gpsimObject *pNode, gpsimObjectList_t *pPinList) { if (!pNode || !pPinList) return; if(verbose) cout << __FUNCTION__ << " pNode " << pNode->name() << "\n"; gpsimObjectList_t :: iterator si = pPinList->begin(); Stimulus_Node *psn = dynamic_cast(pNode); if (psn) { //cout << __FUNCTION__ << " pNode " << pNode->name() << " is a Stimulus_Node\n"; while (si != pPinList->end()) { stimulus *ps = dynamic_cast (*si); if (ps) psn->attach_stimulus(ps); ++si; } psn->update(); return; } AttributeStimulus *ast = dynamic_cast(pNode); if(ast) { Value *v = dynamic_cast(*si); if (v) ast->setClientAttribute(v); if (verbose) { cout << __FUNCTION__ << " pNode " << pNode->name() << " is an attribute stimulus\n"; if (v) cout << __FUNCTION__ << " connecting " << v->name() << endl; } } } gpsim-0.30.0/src/a2d_v2.h0000664000076400007640000002037213041763624011673 00000000000000/* Copyright (C) 2006 T. Scott Dattalo Copyright (C) 2008,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // For A2D modules which have ADCON0, ADCON1 and ADCON2 registers #ifndef __A2D_V2_H__ #define __A2D_v2_H__ #include "comparator.h" #include "a2dconverter.h" #include "registers.h" #include "trigger.h" #include "intcon.h" #include "pir.h" class PinModule; class pic_processor; class ADCON0_V2; //--------------------------------------------------------- // ADCON1 // class ADCON1_V2 : public sfr_register { public: enum PCFG_bits { PCFG0 = 1<<0, PCFG1 = 1<<1, PCFG2 = 1<<2, PCFG3 = 1<<3, VCFG0 = 1<<4, VCFG1 = 1<<5, }; ADCON1_V2(Processor *pCpu, const char *pName, const char *pDesc); ~ADCON1_V2(); virtual void put(unsigned int new_value); void setChanTable( unsigned int m0, unsigned int m1, unsigned int m2, unsigned int m3, unsigned int m4, unsigned int m5, unsigned int m6, unsigned int m7, unsigned int m8, unsigned int m9, unsigned int m10, unsigned int m11, unsigned int m12, unsigned int m13, unsigned int m14, unsigned int m15); void setChannelConfiguration(unsigned int cfg, unsigned int bitMask); virtual PinModule *get_A2Dpin(unsigned int channel); virtual double getChannelVoltage(unsigned int channel); virtual double getVrefHi(); virtual double getVrefLo(); void setVrefHiChannel(unsigned int channel); void setVrefLoChannel(unsigned int channel); void setValidCfgBits(unsigned int m, unsigned int s); void setNumberOfChannels(unsigned int); void setIOPin(unsigned int, PinModule *); void setAdcon0(ADCON0_V2 *adcon0){ m_adcon0 = adcon0;} virtual unsigned int get_adc_configmask(unsigned int); virtual void setVoltRef(double x) {;} virtual int getVrefHiChan() { return m_vrefHiChan;} virtual int getVrefLoChan() { return m_vrefLoChan;} private: protected: PinModule **m_AnalogPins; unsigned int m_nAnalogChannels; unsigned int mValidCfgBits; unsigned int mCfgBitShift; int m_vrefHiChan; int m_vrefLoChan; unsigned int mIoMask; ADCON0_V2 *m_adcon0; // if set use to get VCFG0 and VCFG1 static const unsigned int cMaxConfigurations=16; /* configuration bits is an array of 8-bit masks definining whether or not * a given channel is analog or digital */ unsigned int m_configuration_bits[cMaxConfigurations]; }; //--------------------------------------------------------- // ADCON2 // class ADCON2_V2 : public sfr_register, public TriggerObject { public: enum { ADCS0 = 1<<0, ADCS1 = 1<<1, ADCS2 = 1<<2, ACQT0 = 1<<3, ACQT1 = 1<<4, ACQT2 = 1<<5, ADFM = 1<<7 }; ADCON2_V2(Processor *pCpu, const char *pName, const char *pDesc); char get_nacq(); char get_tad(); bool get_adfm(); private: }; //--------------------------------------------------------- // ADCON0 // class ADCON0_V2 : public sfr_register, public TriggerObject { public: enum { ADON = 1<<0, GO = 1<<1, CHS0 = 1<<2, CHS1 = 1<<3, CHS2 = 1<<4, CHS3 = 1<<5, VCFG0 = 1<<6, // for 18f1220 VCFG1 = 1<<7, // for 18f1220 }; enum AD_states { AD_IDLE, AD_ACQUIRING, AD_CONVERTING }; ADCON0_V2(Processor *pCpu, const char *pName, const char *pDesc); void start_conversion(); void stop_conversion(); virtual void set_interrupt(); virtual void callback(); virtual void callback_print() {cout << name() << " has callback, ID = " << CallBackID << '\n';} void put(unsigned int new_value); void put_conversion(); void setAdres(sfr_register *); void setAdresLow(sfr_register *); void setAdcon1(ADCON1_V2 *); void setAdcon2(ADCON2_V2 *); void setIntcon(INTCON *); void setPir(PIR1v2 *); void setA2DBits(unsigned int); void setChannel_Mask(unsigned int ch_mask) { channel_mask = ch_mask; } void setRCtime(double); void set_ctmu_stim(stimulus *_ctmu_stim); void attach_ctmu_stim(); void detach_ctmu_stim(); private: sfr_register *adres; sfr_register *adresl; ADCON1_V2 *adcon1; ADCON2_V2 *adcon2; INTCON *intcon; PIR1v2 *pir1v2; double m_dSampledVoltage; double m_dSampledVrefHi; double m_dSampledVrefLo; double m_RCtime; unsigned int m_A2DScale; unsigned int m_nBits; guint64 future_cycle; unsigned int ad_state; unsigned int Tad; unsigned int Tacq; unsigned int channel_mask; stimulus *ctmu_stim; int active_stim; // channel with active stimulus }; // Channels defined in ANSEL rather than ADCON1 class ADCON1_2B : public ADCON1_V2 { public: enum { NVCFG0 = 1<<0, // Negative Voltage Reference Configuration bits NVCFG1 = 1<<1, PVCFG0 = 1<<2, // Positive Voltage Reference Configuration bits PVCFG1 = 1<<3, TRIGSEL = 1<<7, // Special Trigger Select bit // the following are special A/D channels CTMU = 0x1d, DAC = 0x1e, FVR_BUF2 = 0x1f }; ADCON1_2B(Processor *pCpu, const char *pName, const char *pDesc); virtual double getChannelVoltage(unsigned int channel); virtual void put(unsigned int new_value); virtual double getVrefHi(); virtual double getVrefLo(); void update_ctmu(double _Vctmu) { Vctmu = _Vctmu;} void update_dac(double _Vdac) { Vdac = _Vdac;} virtual void setVoltRef(double _Vfvr_buf2) { Vfvr_buf2 = _Vfvr_buf2;} virtual PinModule *get_A2Dpin(unsigned int channel); virtual void ctmu_trigger(); virtual void ccp_trigger(); private: double Vctmu; double Vdac; double Vfvr_buf2; }; // ANSEL register for ADCv2B with an ANSEL per I/O port class ANSEL_2B : public sfr_register { public: ANSEL_2B(Processor *pCpu, const char *pName, const char *pDesc); void put(unsigned int new_value); void put_value(unsigned int new_value); void setIOPin(unsigned int channel, PinModule *port, ADCON1_2B *adcon1); protected: PinModule *m_AnalogPins[8]; int analog_channel[8]; unsigned int mask; }; // ANSEL register for ADCv2 on devices where the ANSEL is mapped by ADC chan class ANSEL_2A : public ANSEL_2B { public: ANSEL_2A(Processor *pCpu, const char *pName, const char *pDesc); void setIOPin(unsigned int channel, PinModule *port, ADCON1_2B *adcon1); }; class FVRCON_V2 : public sfr_register, public TriggerObject { public: enum { FVRS0 = 1<<4, FVRS1 = 1<<5, FVRRDY = 1<<6, FVREN = 1<<7, }; FVRCON_V2(Processor *, const char *pName, const char *pDesc=0, unsigned int bitMask= 0xf0); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void set_adcon1(ADCON1_V2 *_adcon1) { adcon1 = _adcon1;} void set_cmModule(ComparatorModule2 *_cmModule) { cmModule = _cmModule;} void set_daccon0(DACCON0 *_daccon0) { daccon0_list.push_back(_daccon0);} void set_cpscon0(CPSCON0 *_cpscon0) { cpscon0 = _cpscon0;} private: unsigned int mask_writable; virtual void callback(); virtual void callback_print() {cout << name() << " has callback, ID = " << CallBackID << '\n';} guint64 future_cycle; double compute_FVR(unsigned int); ADCON1_V2 *adcon1; DACCON0 *daccon0; vector daccon0_list; ComparatorModule2 *cmModule; CPSCON0 *cpscon0; }; class DACCON0_V2 : public DACCON0 { public: DACCON0_V2(Processor *pCpu, const char *pName, const char *pDesc=0, unsigned int bitMask= 0xe6, unsigned int bit_res = 32) : DACCON0(pCpu, pName, pDesc, bitMask, bit_res) { adcon1 = 0;} virtual void set_adcon1(ADCON1_2B *_adcon1) { adcon1 = _adcon1;} virtual void compute_dac(unsigned int value); virtual double get_Vhigh(unsigned int value); private: ADCON1_2B *adcon1; }; #endif // __A2D_V2_H__ gpsim-0.30.0/src/cmd_gpsim.h0000664000076400007640000000011213041763624012546 00000000000000 #ifndef __CMD_GPSIM_H__ #define __CMD_GPSIM_H__ #include "ui.h" #endif gpsim-0.30.0/src/pic-processor.cc0000664000076400007640000015640313116645075013553 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #ifdef _WIN32 #include "uxtime.h" #include "unistd.h" #else #include #endif #ifndef _MSC_VER #include #endif #include #include #include #include #include "../config.h" #include "exports.h" #include "gpsim_def.h" #include "pic-processor.h" #include "pic-registers.h" #include "picdis.h" #include "symbol.h" #include "stimuli.h" #include "p16x5x.h" #include "p16f62x.h" #include "p16f8x.h" #include "p16f88x.h" #include "p16x8x.h" #include "p16f87x.h" #include "p16x6x.h" #include "p16x7x.h" #include "p16f91x.h" #include "p12x.h" #include "p12f6xx.h" #include "p1xf1xxx.h" #ifdef P17C7XX // code no longer works #include "p17c75x.h" #endif #include "p18x.h" #include "p18fk.h" #include "icd.h" #include "fopen-path.h" guint64 simulation_start_cycle; #include "cod.h" #include "clock_phase.h" //================================================================================ // // pic_processor // // This file contains all (most?) of the code that simulates those features // common to all pic microcontrollers. // // ProcessorConstructor pP10F200(P10F200::construct , "__10F200", "pic10f200", "p10f200", "10f200"); ProcessorConstructor pP10F202(P10F202::construct , "__10F202", "pic10f202", "p10f202", "10f202"); ProcessorConstructor pP10F204(P10F204::construct , "__10F204", "pic10f204", "p10f204", "10f204"); ProcessorConstructor pP10F220(P10F220::construct , "__10F220", "pic10f220", "p10f220", "10f220"); ProcessorConstructor pP10F222(P10F222::construct , "__10F222", "pic10f222", "p10f222", "10f222"); ProcessorConstructor pP12C508(P12C508::construct , "__12C508", "pic12c508", "p12c508", "12c508"); ProcessorConstructor pP12C509(P12C509::construct , "__12C509", "pic12c509", "p12c509", "12c509"); ProcessorConstructor pP12CE518(P12CE518::construct , "__12ce518", "pic12ce518", "p12ce518", "12ce518"); ProcessorConstructor pP12CE519(P12CE519::construct , "__12ce519", "pic12ce519", "p12ce519", "12ce519"); ProcessorConstructor pP12F508(P12F508::construct , "__12F508", "pic12f508", "p12f508", "12f508"); ProcessorConstructor pP12F509(P12F509::construct , "__12F509", "pic12f509", "p12f509", "12f509"); ProcessorConstructor pP12F510(P12F510::construct , "__12F510", "pic12f510", "p12f510", "12f510"); ProcessorConstructor pP12F629(P12F629::construct , "__12F629", "pic12f629", "p12f629", "12f629"); ProcessorConstructor pP12F675(P12F675::construct , "__12F675", "pic12f675", "p12f675", "12f675"); ProcessorConstructor pP12F683(P12F683::construct , "__12F683", "pic12f683", "p12f683", "12f683"); ProcessorConstructor pP12F1822(P12F1822::construct , "__12F1822", "pic12f1822", "p12f1822", "12f1822"); ProcessorConstructor pP12F1840(P12F1840::construct , "__12F1840", "pic12f1840", "p12f1840", "12f1840"); ProcessorConstructor pP16C54(P16C54::construct , "__16C54", "pic16c54", "p16c54", "16c54"); ProcessorConstructor pP16C55(P16C55::construct , "__16C55", "pic16c55", "p16c55", "16c55"); ProcessorConstructor pP16C56(P16C56::construct , "__16C56", "pic16c56", "p16c56", "16c56"); ProcessorConstructor pP16C61(P16C61::construct , "__16C61", "pic16c61", "p16c61", "16c61"); ProcessorConstructor pP16C62(P16C62::construct , "__16C62", "pic16c62", "p16c62", "16c62"); ProcessorConstructor pP16C62A(P16C62::construct , "__16C62A", "pic16c62a", "p16c62a", "16c62a"); ProcessorConstructor pP16CR62(P16C62::construct , "__16CR62", "pic16cr62", "p16cr62", "16cr62"); ProcessorConstructor pP16C63(P16C63::construct , "__16C63", "pic16c63", "p16c63", "16c63"); ProcessorConstructor pP16C64(P16C64::construct , "__16C64", "pic16c64", "p16c64", "16c64"); ProcessorConstructor pP16C65(P16C65::construct , "__16C65", "pic16c65", "p16c65", "16c65"); ProcessorConstructor pP16C65A(P16C65::construct , "__16C65A", "pic16c65a", "p16c65a", "16c65a"); ProcessorConstructor pP16C71(P16C71::construct , "__16C71", "pic16c71", "p16c71", "16c71"); ProcessorConstructor pP16C712(P16C712::construct , "__16C712", "pic16c712", "p16c712", "16c712"); ProcessorConstructor pP16C716(P16C716::construct , "__16C716", "pic16c716", "p16c716", "16c716"); ProcessorConstructor pP16C72(P16C72::construct , "__16C72", "pic16c72", "p16c72", "16c72"); ProcessorConstructor pP16C73(P16C73::construct , "__16C73", "pic16c73", "p16c73", "16c73"); ProcessorConstructor pP16C74(P16C74::construct , "__16C74", "pic16c74", "p16c74", "16c74"); ProcessorConstructor pP16C84(P16C84::construct , "__16C84", "pic16c84", "p16c84", "16c84"); ProcessorConstructor pP16CR83(P16CR83::construct , "__16CR83", "pic16cr83", "p16cr83", "16cr83"); ProcessorConstructor pP16CR84(P16CR84::construct , "__16CR84", "pic16cr84", "p16cr84", "16cr84"); ProcessorConstructor pP16F505(P16F505::construct , "__16F505", "pic16f505", "p16f505", "16f505"); ProcessorConstructor pP16F73(P16F73::construct , "__16F73", "pic16f73", "p16f73", "16f73"); ProcessorConstructor pP16F74(P16F74::construct , "__16F74", "pic16f74", "p16f74", "16f74"); ProcessorConstructor pP16F716(P16F716::construct , "__16F716", "pic16f716", "p16f716", "16f716"); ProcessorConstructor pP16F83(P16F83::construct , "__16F83", "pic16f83", "p16f83", "16f83"); ProcessorConstructor pP16F84(P16F84::construct , "__16F84", "pic16f84", "p16f84", "16f84"); ProcessorConstructor pP16F87(P16F87::construct , "__16F87", "pic16f87", "p16f87", "16f87"); ProcessorConstructor pP16F88(P16F88::construct , "__16F88", "pic16f88", "p16f88", "16f88"); ProcessorConstructor pP16F882(P16F882::construct , "__16F882", "pic16f882", "p16f882", "16f882"); ProcessorConstructor pP16F883(P16F883::construct , "__16F883", "pic16f883", "p16f883", "16f883"); ProcessorConstructor pP16F884(P16F884::construct , "__16F884", "pic16f884", "p16f884", "16f884"); ProcessorConstructor pP16F886(P16F886::construct , "__16F886", "pic16f886", "p16f886", "16f886"); ProcessorConstructor pP16F887(P16F887::construct , "__16F887", "pic16f887", "p16f887", "16f887"); ProcessorConstructor pP16F627(P16F627::construct , "__16F627", "pic16f627", "p16f627", "16f627"); ProcessorConstructor pP16F627A(P16F627::construct , "__16F627A", "pic16f627a", "p16f627a", "16f627a"); ProcessorConstructor pP16F628(P16F628::construct , "__16F628", "pic16f628", "p16f628", "16f628"); ProcessorConstructor pP16F628A(P16F628::construct , "__16F628A", "pic16f628a", "p16f628a", "16f628a"); ProcessorConstructor pP16F630(P16F630::construct , "__16F630", "pic16f630", "p16f630", "16f630"); ProcessorConstructor pP16F631(P16F631::construct , "__16F631", "pic16f631", "p16f631", "16f631"); ProcessorConstructor pP16F648(P16F648::construct , "__16F648", "pic16f648", "p16f648", "16f648"); ProcessorConstructor pP16F648A(P16F648::construct , "__16F648A", "pic16f648a", "p16f648a", "16f648a"); ProcessorConstructor pP16F676(P16F676::construct , "__16F676", "pic16f676", "p16f676", "16f676"); ProcessorConstructor pP16F677(P16F677::construct , "__16F677", "pic16f677", "p16f677", "16f677"); ProcessorConstructor pP16F684(P16F684::construct , "__16F684", "pic16f684", "p16f684", "16f684"); ProcessorConstructor pP16F685(P16F685::construct , "__16F685", "pic16f685", "p16f685", "16f685"); ProcessorConstructor pP16F687(P16F687::construct , "__16F687", "pic16f687", "p16f687", "16f687"); ProcessorConstructor pP16F689(P16F689::construct , "__16F689", "pic16f689", "p16f689", "16f689"); ProcessorConstructor pP16F690(P16F690::construct , "__16F690", "pic16f690", "p16f690", "16f690"); ProcessorConstructor pP16F818(P16F818::construct , "__16F818", "pic16f818", "p16f818", "16f818"); ProcessorConstructor pP16F819(P16F819::construct , "__16F819", "pic16f819", "p16f819", "16f819"); ProcessorConstructor pP16F871(P16F871::construct , "__16F871", "pic16f871", "p16f871", "16f871"); ProcessorConstructor pP16F873(P16F873::construct , "__16F873", "pic16f873", "p16f873", "16f873"); ProcessorConstructor pP16F874(P16F874::construct , "__16F874", "pic16f874", "p16f874", "16f874"); ProcessorConstructor pP16F876(P16F876::construct , "__16F876", "pic16f876", "p16f876", "16f876"); ProcessorConstructor pP16F877(P16F877::construct , "__16F877", "pic16f877", "p16f877", "16f877"); ProcessorConstructor pP16F873A(P16F873A::construct , "__16F873a", "pic16f873a", "p16f873a", "16f873a"); ProcessorConstructor pP16F874A(P16F874A::construct , "__16F874a", "pic16f874a", "p16f874a", "16f874a"); ProcessorConstructor pP16F876A(P16F876A::construct , "__16F876a", "pic16f876a", "p16f876a", "16f876a"); ProcessorConstructor pP16F877A(P16F877A::construct , "__16F877a", "pic16f877a", "p16f877a", "16f877a"); ProcessorConstructor pP16F913(P16F913::construct , "__16F913", "pic16f913", "p16f913", "16f913"); ProcessorConstructor pP16F914(P16F914::construct , "__16F914", "pic16f914", "p16f914", "16f914"); ProcessorConstructor pP16F916(P16F916::construct , "__16F916", "pic16f916", "p16f916", "16f916"); ProcessorConstructor pP16F917(P16F917::construct , "__16F917", "pic16f917", "p16f917", "16f917"); ProcessorConstructor pP16F1788(P16F1788::construct , "__16F1788", "pic16f1788", "p16f1788", "16f1788"); ProcessorConstructor pP16F1823(P16F1823::construct , "__16F1823", "pic16f1823", "p16f1823", "16f1823"); ProcessorConstructor pP16F1825(P16F1825::construct , "__16F1825", "pic16f1825", "p16f1825", "16f1825"); #ifdef P17C7XX // code no longer works ProcessorConstructor pP17C7xx(P17C7xx::construct , "__17C7xx", "pic17c7xx", "p17c7xx", "17c7xx"); ProcessorConstructor pP17C75x(P17C75x::construct , "__17C75x", "pic17c75x", "p17c75x", "17c75x"); ProcessorConstructor pP17C752(P17C752::construct , "__17C752", "pic17c752", "p17c752", "17c752"); ProcessorConstructor pP17C756(P17C756::construct , "__17C756", "pic17c756", "p17c756", "17c756"); ProcessorConstructor pP17C756A(P17C756A::construct , "__17C756A", "pic17c756a", "p17c756a", "17c756a"); ProcessorConstructor pP17C762(P17C762::construct , "__17C762", "pic17c762", "p17c762", "17c762"); ProcessorConstructor pP17C766(P17C766::construct , "__17C766", "pic17c766", "p17c766", "17c766"); #endif // P17C7XX ProcessorConstructor pP18C242(P18C242::construct , "__18C242", "pic18c242", "p18c242", "18c242"); ProcessorConstructor pP18C252(P18C252::construct , "__18C252", "pic18c252", "p18c252", "18c252"); ProcessorConstructor pP18C442(P18C442::construct , "__18C442", "pic18c442", "p18c442", "18c442"); ProcessorConstructor pP18C452(P18C452::construct , "__18C452", "pic18c452", "p18c452", "18c452"); ProcessorConstructor pP18F242(P18F242::construct , "__18F242", "pic18f242", "p18f242", "18f242"); ProcessorConstructor pP18F248(P18F248::construct , "__18F248", "pic18f248", "p18f248", "18f248"); ProcessorConstructor pP18F258(P18F258::construct , "__18F258", "pic18f258", "p18f258", "18f258"); ProcessorConstructor pP18F252(P18F252::construct , "__18F252", "pic18f252", "p18f252", "18f252"); ProcessorConstructor pP18F442(P18F442::construct , "__18F442", "pic18f442", "p18f442", "18f442"); ProcessorConstructor pP18F448(P18F448::construct , "__18F448", "pic18f448", "p18f448", "18f448"); ProcessorConstructor pP18F458(P18F458::construct , "__18F458", "pic18f458", "p18f458", "18f458"); ProcessorConstructor pP18F452(P18F452::construct, "__18F452", "pic18f452", "p18f452", "18f452"); ProcessorConstructor pP18F1220(P18F1220::construct, "__18F1220", "pic18f1220", "p18f1220", "18f1220"); ProcessorConstructor pP18F1320(P18F1320::construct, "__18F1320", "pic18f1320", "p18f1320", "18f1320"); ProcessorConstructor pP18F14K22(P18F14K22::construct, "__18F14K22", "pic18f14k22", "p18f14k22", "18f14k22"); ProcessorConstructor pP18F2221(P18F2221::construct, "__18F2221", "pic18f2221", "p18f2221", "18f2221"); ProcessorConstructor pP18F2321(P18F2321::construct, "__18F2321", "pic18f2321", "p18f2321", "18f2321"); ProcessorConstructor pP18F2420(P18F2420::construct, "__18F2420", "pic18f2420", "p18f2420", "18f2420"); ProcessorConstructor pP18F2455(P18F2455::construct, "__18F2455", "pic18f2455", "p18f2455", "18f2455"); ProcessorConstructor pP18F2520(P18F2520::construct, "__18F2520", "pic18f2520", "p18f2520", "18f2520"); ProcessorConstructor pP18F2525(P18F2525::construct, "__18F2525", "pic18f2525", "p18f2525", "18f2525"); ProcessorConstructor pP18F2550(P18F2550::construct, "__18F2550", "pic18f2550", "p18f2550", "18f2550"); ProcessorConstructor pP18F2620(P18F2620::construct, "__18F2620", "pic18f2620", "p18f2620", "18f2620"); ProcessorConstructor pP18F26K22(P18F26K22::construct, "__18F26K22", "pic18f26k22", "p18f26k22", "18f26k22"); ProcessorConstructor pP18F4221(P18F4221::construct, "__18F4221", "pic18f4221", "p18f4221", "18f4221"); ProcessorConstructor pP18F4321(P18F4321::construct, "__18F4321", "pic18f4321", "p18f4321", "18f4321"); ProcessorConstructor pP18F4420(P18F4420::construct, "__18F4420", "pic18f4420", "p18f4420", "18f4420"); ProcessorConstructor pP18F4520(P18F4520::construct, "__18F4520", "pic18f4520", "p18f4520", "18f4520"); ProcessorConstructor pP18F4550(P18F4550::construct, "__18F4550", "pic18f4550", "p18f4550", "18f4550"); ProcessorConstructor pP18F4455(P18F4455::construct, "__18F4455", "pic18f4455", "p18f4455", "18f4455"); ProcessorConstructor pP18F4620(P18F4620::construct, "__18F4620", "pic18f4620", "p18f4620", "18f4620"); ProcessorConstructor pP18F6520(P18F6520::construct, "__18F6520", "pic18f6520", "p18f6520", "18f6520"); //======================================================================== // Trace Type for Resets class InterruptTraceObject : public ProcessorTraceObject { public: InterruptTraceObject(Processor *_cpu); virtual void print(FILE *fp); }; class InterruptTraceType : public ProcessorTraceType { public: InterruptTraceType(Processor *_cpu); TraceObject *decode(unsigned int tbi); void record(); int dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize); unsigned int m_uiTT; }; //------------------------------------------------------------ InterruptTraceObject::InterruptTraceObject(Processor *_cpu) : ProcessorTraceObject(_cpu) { } void InterruptTraceObject::print(FILE *fp) { fprintf(fp, " %s *** Interrupt ***\n", (cpu ? cpu->name().c_str() : "")); } //------------------------------------------------------------ InterruptTraceType::InterruptTraceType(Processor *_cpu) : ProcessorTraceType(_cpu,1,"Interrupt") { m_uiTT = trace.allocateTraceType(this); } TraceObject *InterruptTraceType::decode(unsigned int tbi) { //unsigned int tv = trace.get(tbi); return new InterruptTraceObject(cpu); } void InterruptTraceType::record() { trace.raw(m_uiTT); } int InterruptTraceType::dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize) { if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; int m = snprintf(buf, bufsize, " %s *** Interrupt ***", (cpu ? cpu->name().c_str() : "")); return m > 0 ? (m+n) : n; } //------------------------------------------------------------------- void pic_processor::set_eeprom(EEPROM *e) { eeprom = e; if (e) ema.set_Registers(e->rom, e->rom_size); } //------------------------------------------------------------------- void pic_processor::BP_set_interrupt() { m_pInterruptTT->record(); mCaptureInterrupt->firstHalf(); } //------------------------------------------------------------------- // // sleep - Begin sleeping and stay asleep until something causes a wake // void pic_processor::sleep () { } //------------------------------------------------------------------- // // enter_sleep - The processor is about to go to sleep, so update // the status register. void pic_processor::enter_sleep() { status->put_TO(1); status->put_PD(0); wdt.update(); pc->increment(); mCurrentPhase->setNextPhase(mIdle); mCurrentPhase = mIdle; mCurrentPhase->setNextPhase(mIdle); m_ActivityState = ePASleeping; } //------------------------------------------------------------------- // // exit_sleep void pic_processor::exit_sleep() { m_ActivityState = ePAActive; mCurrentPhase->setNextPhase(mExecute1Cycle); } //------------------------------------------------------------------- // // is_sleeping bool pic_processor::is_sleeping() { return m_ActivityState == ePASleeping; } //------------------------------------------------------------------- // // pm_write - program memory write // void pic_processor::pm_write () { m_ActivityState = ePAPMWrite; do get_cycles().increment(); // burn cycles until we're through writing while(bp.have_pm_write()); simulation_mode = eSM_RUNNING; } static bool realtime_mode = false; static bool realtime_mode_with_gui = false; void EnableRealTimeMode(bool bEnable) { realtime_mode = bEnable; } void EnableRealTimeModeWithGui(bool bEnable) { realtime_mode_with_gui = bEnable; } extern void update_gui(); class RealTimeBreakPoint : public TriggerObject { public: Processor *cpu; struct timeval tv_start; guint64 cycle_start; guint64 future_cycle; int warntimer; guint64 period; // callback period in us //#define REALTIME_DEBUG guint64 diffmax; guint64 diffsum; int diffsumct; struct timeval stat_start; RealTimeBreakPoint() { cpu = 0; warntimer = 1; period = 1; future_cycle = 0; diffsum=0; diffsumct=0; diffmax=0; } void start(Processor *active_cpu) { if(!active_cpu) return; diffsum=0; diffsumct=0; diffmax=0; // Grab the system time and record the simulated pic's time. // We'll then set a break point a short time in the future // and compare how the two track. cpu = active_cpu; gettimeofday(&tv_start,0); stat_start=tv_start; cycle_start=get_cycles().get(); guint64 fc = cycle_start+100; //cout << "real time start : " << cycle_start << '\n'; if(future_cycle) get_cycles().reassign_break(future_cycle, fc, this); else get_cycles().set_break(fc, this); future_cycle = fc; } void stop() { //cout << "real time stop : " << future_cycle << '\n'; #ifdef REALTIME_DEBUG dump_stats(); #endif // Clear any pending break point. if(future_cycle) { cout << " real time clearing\n"; get_cycles().clear_break(this); future_cycle = 0; if(realtime_mode_with_gui) { update_gui(); } } } #ifdef REALTIME_DEBUG void dump_stats(void) { struct timeval tv; gettimeofday(&tv,0); double simulation_time = (tv.tv_sec-stat_start.tv_sec)+(tv.tv_usec-stat_start.tv_usec)/1000000.0; // in seconds if(diffsumct>0 && simulation_time>0) { cout << dec << "Average realtime error: " << diffsum/diffsumct << " microseconds. Max: "<get_OSCperiod()); if( simulation_time > system_time) { // we are simulating too fast diff_us = simulation_time - system_time; if(period > diff_us) period -= diff_us; else period=1; usleep((unsigned int)diff_us); } else { diff_us = system_time - simulation_time; period+=diff_us; if(period>1000000) period=1000000; // limit to a one second callback period if(diff_us>1000000) { // we are simulating too slow if(warntimer<10) warntimer++; else { warntimer=0; puts("Processor is too slow for realtime mode!"); } } else warntimer=0; } guint64 delta_cycles= (guint64)(period*cpu->get_frequency()/4000000); if(delta_cycles<1) delta_cycles=1; // Look at realtime_mode_with_gui and update the gui if true if(realtime_mode_with_gui) { update_gui(); } #ifdef REALTIME_DEBUG if(tv.tv_secdiffmax) diffmax=diff_us; static guint64 oldtime = 0; //cout<advance(); while(!bp.global_break); if(realtime_mode) realtime_cbp.stop(); bp.clear_global(); trace.cycle_counter(get_cycles().get()); simulation_mode = eSM_STOPPED; } //------------------------------------------------------------------- // // step - Simulate one (or more) instructions. If a breakpoint is set // at the current PC-> 'step' will go right through it. (That's supposed // to be a feature.) // void pic_processor::step (unsigned int steps, bool refresh) { if(!steps) return; if(get_use_icd()) { if(steps!=1) { cout << "Can only step one step in ICD mode"<get_value(); disassemble((signed int)pc->value, (signed int)pc->value); // FIXME, don't want this in HLL ICD mode. if(refresh) gi.simulation_has_stopped(); return; } if(simulation_mode != eSM_STOPPED) { if(verbose) cout << "Ignoring step request because simulation is not stopped\n"; return; } simulation_mode = eSM_SINGLE_STEPPING; mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle; do { mCurrentPhase = mCurrentPhase->advance(); } while(!bp.have_halt() && --steps>0); // complete the step if this is a multi-cycle instruction. if (mCurrentPhase == mExecute2ndHalf) while (mCurrentPhase != mExecute1Cycle) mCurrentPhase = mCurrentPhase->advance(); get_trace().cycle_counter(get_cycles().get()); if(refresh) trace_dump(0,1); bp.clear_halt(); simulation_mode = eSM_STOPPED; if(refresh) get_interface().simulation_has_stopped(); } //------------------------------------------------------------------- void pic_processor::step_cycle() { mCurrentPhase = mCurrentPhase->advance(); } // //------------------------------------------------------------------- // // step_over - In most cases, step_over will simulate just one instruction. // However, if the next instruction is a branching one (e.g. goto, call, // return, etc.) then a break point will be set after it and gpsim will // begin 'running'. This is useful for stepping over time-consuming calls. // void pic_processor::step_over (bool refresh) { if(simulation_mode != eSM_STOPPED) { if(verbose) cout << "Ignoring step-over request because simulation is not stopped\n"; return; } unsigned int saved_pc = pma->get_PC(); instruction *nextInstruction = pma->getFromAddress(saved_pc); if (!nextInstruction) { // this is really fatal... return; } unsigned int nextExpected_pc = saved_pc + map_pm_index2address(nextInstruction->instruction_size()); step(1,false); // Try one step -- without refresh // if the pc did not advance just one instruction, then some kind of branch occurred. unsigned int current_pc = pma->get_PC(); if( ! (current_pc >= saved_pc && current_pc <= nextExpected_pc)) { // If the branch is not a skip instruction then we'll set a break point and run. // (note, the test that's performed will treat a goto $+2 as a skip. instruction *nextNextInstruction = pma->getFromAddress(nextExpected_pc); unsigned int nextNextExpected_pc = nextExpected_pc + (nextNextInstruction ? map_pm_index2address(nextNextInstruction->instruction_size()) : 0); if (! (current_pc >= saved_pc && current_pc <= nextNextExpected_pc)) { unsigned int bp_num = pma->set_break_at_address(nextExpected_pc); if (bp_num != INVALID_VALUE) { run(); bp.clear(bp_num); } } } // note that we don't need to tell the gui to update its windows since // that is already done by step() or run(). if(refresh) get_interface().simulation_has_stopped(); } //------------------------------------------------------------------- // // finish // // this method really only applies to processors with stacks. void pic_processor::finish() { if(!stack) return; run_to_address( stack->contents[(stack->pointer-1) & stack->stack_mask]); get_interface().simulation_has_stopped(); } //------------------------------------------------------------------- // // reset - reset the pic based on the desired reset type. // void pic_processor::reset (RESET_TYPE r) { bool bHaltSimulation = getBreakOnReset(); if(get_use_icd()) { puts("RESET"); icd_reset(); disassemble((signed int)pc->get_value(), (signed int)pc->get_value()); gi.simulation_has_stopped(); return; } m_pResetTT->record(r); rma.reset(r); stack->reset(r); wdt.reset(r); pc->reset(); bp.clear_global(); switch (r) { case POR_RESET: if(verbose) { cout << "POR\n"; if(config_modes) config_modes->print(); } bHaltSimulation = false; mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle; m_ActivityState = ePAActive; break; case SOFT_RESET: cout << "Reset due to Software reset instruction\n"; mCurrentPhase = mExecute1Cycle; mCurrentPhase->setNextPhase(mExecute1Cycle); m_ActivityState = ePAActive; break; case MCLR_RESET: cout << "MCLR reset\n"; mCurrentPhase = mIdle; mCurrentPhase->setNextPhase(mIdle); m_ActivityState = ePAIdle; break; case IO_RESET: mCurrentPhase = mExecute1Cycle; mCurrentPhase->setNextPhase(mExecute1Cycle); m_ActivityState = ePAActive; break; case WDT_RESET: cout << "Reset on Watch Dog Timer expire\n"; mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle; mCurrentPhase->setNextPhase(mExecute1Cycle); m_ActivityState = ePAActive; break; case EXIT_RESET: // MCLR reset has cleared cout <<"MCLR low, resume execution\n"; mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle; mCurrentPhase->setNextPhase(mExecute1Cycle); m_ActivityState = ePAActive; return; break; case STKOVF_RESET: cout << "Reset on Stack overflow\n"; mCurrentPhase = mCurrentPhase ? mCurrentPhase : mIdle; mCurrentPhase->setNextPhase(mIdle); m_ActivityState = ePAActive; // mCurrentPhase->setNextPhase(mExecute1Cycle); // m_ActivityState = ePAActive; break; case STKUNF_RESET: cout << "Reset on Stack undeflow\n"; mCurrentPhase = mCurrentPhase ? mCurrentPhase : mIdle; mCurrentPhase->setNextPhase(mIdle); m_ActivityState = ePAActive; break; default: printf("pic_processor::reset unknow reset type %d\n", r); m_ActivityState = ePAActive; break; } if(bHaltSimulation || getBreakOnReset()) { bp.halt(); gi.simulation_has_stopped(); } } //------------------------------------------------------------------- // // pic_processor -- constructor // pic_processor::pic_processor(const char *_name, const char *_desc) : Processor(_name,_desc), wdt(this, 18.0e-3),indf(0),fsr(0), stack(0), status(0), Wreg(0), pcl(0), pclath(0),m_PCHelper(0), tmr0(this,"tmr0","Timer 0"), m_configMemory(0), m_MCLR(0), m_MCLR_Save(0), m_MCLRMonitor(0), PPLx4(false), clksource(0), clkcontrol(0) { mExecute1Cycle = new phaseExecute1Cycle(this); mExecute2ndHalf = new phaseExecute2ndHalf(this); mCaptureInterrupt = new phaseCaptureInterrupt(this); mIdle = new phaseIdle(this); mCurrentPhase = mExecute1Cycle; m_Capabilities = eSTACK | eWATCHDOGTIMER; if(verbose) cout << "pic_processor constructor\n"; eeprom = 0; config_modes = create_ConfigMode(); pll_factor = 0; Integer::setDefaultBitmask(0xff); // Test code for logging to disk: GetTraceLog().switch_cpus(this); m_pResetTT = new ResetTraceType(this); m_pInterruptTT = new InterruptTraceType(this); for(int i = 0; i < 4; i++) osc_pin_Number[i] = 254; } //------------------------------------------------------------------- pic_processor::~pic_processor() { if (pma) { while(!rma.SpecialRegisters.empty()) rma.SpecialRegisters.pop_back(); while(!pma->SpecialRegisters.empty()) pma->SpecialRegisters.pop_back(); } delete m_pResetTT; delete m_pInterruptTT; delete_sfr_register(Wreg); delete_sfr_register(pcl); delete_sfr_register(pclath); delete_sfr_register(status); delete_sfr_register(indf); delete m_PCHelper; delete stack; delete mExecute1Cycle; delete mExecute2ndHalf; delete mCaptureInterrupt; delete mIdle; delete config_modes; delete m_configMemory; if (m_MCLR) m_MCLR->setMonitor(0); if (m_MCLR_Save) m_MCLR_Save->setMonitor(0); if (m_MCLRMonitor) delete m_MCLRMonitor; if (clksource) delete clksource; if (clkcontrol) delete clkcontrol; } //------------------------------------------------------------------- // // // create // // The purpose of this member function is to 'create' a pic processor. // Since this is a base class member function, only those things that // are common to all pics are created. void pic_processor::create () { init_program_memory (program_memory_size()); init_register_memory (register_memory_size()); // Now, initialize the core stuff: pc->set_cpu(this); Wreg = new WREG(this,"W","Working Register"); pcl = new PCL(this,"pcl", "Program Counter Low"); pclath = new PCLATH(this,"pclath", "Program Counter Latch High"); status = new Status_register(this,"status", "Processor status"); indf = new INDF(this,"indf","Indirect register"); register_bank = ®isters[0]; // Define the active register bank if(pma) { m_PCHelper = new PCHelper(this,pma); rma.SpecialRegisters.push_back(m_PCHelper); rma.SpecialRegisters.push_back(status); rma.SpecialRegisters.push_back(Wreg); pma->SpecialRegisters.push_back(m_PCHelper); pma->SpecialRegisters.push_back(status); pma->SpecialRegisters.push_back(Wreg); } create_config_memory(); } //------------------------------------------------------------------- // // add_sfr_register // // The purpose of this routine is to add one special function register // to the file registers. If the sfr has a physical address (like the // status or tmr0 registers) then a pointer to that register will be // placed in the file register map. // FIXME It doesn't make any sense to initialize the por_value here! // FIXME The preferred way is to initialize all member data in their // FIXME parent's constructor. void pic_processor::add_sfr_register(Register *reg, unsigned int addr, RegisterValue por_value, const char *new_name, bool warn_dup) { reg->set_cpu(this); if(addr < register_memory_size()) { if (registers[addr]) { if (registers[addr]->isa() == Register::INVALID_REGISTER) { delete registers[addr]; registers[addr] = reg; } else if (warn_dup) printf("%s %s 0x%x Already register %s\n", __FUNCTION__, name().c_str(), addr, registers[addr]->name().c_str()); } else registers[addr] = reg; reg->address = addr; reg->alias_mask = 0; if(new_name) reg->new_name(new_name); RegisterValue rv = getWriteTT(addr); reg->set_write_trace(rv); rv = getReadTT(addr); reg->set_read_trace(rv); } reg->value = por_value; reg->por_value = por_value; /// FIXME why are we doing this? reg->initialize(); } //------------------------------------------------------------------- // // delete_sfr_register // This both deletes the register from the registers array, // but also deletes the register class. // void pic_processor::delete_sfr_register(Register *pReg) { if (pReg) { unsigned int a = pReg->getAddress(); if (0) cout << __FUNCTION__ << " addr = 0x"<name()<getAddress(); if (a == AN_INVALID_ADDRESS) return; if (registers[a] == ppReg) delete_file_registers(a,a,true); } } //------------------------------------------------------------------- // // init_program_memory // // The purpose of this member function is to allocate memory for the // pic's code space. The 'memory_size' parameter tells how much memory // is to be allocated AND it should be an integer of the form of 2^n. // If the memory size is not of the form of 2^n, then this routine will // round up to the next integer that is of the form 2^n. // Once the memory has been allocated, this routine will initialize // it with the 'bad_instruction'. The bad_instruction is an instantiation // of the instruction class that chokes gpsim if it is executed. Note that // each processor owns its own 'bad_instruction' object. void pic_processor::init_program_memory (unsigned int memory_size) { if(verbose) cout << "Initializing program memory: 0x"<memory_size = memory_size; Processor::init_program_memory(memory_size); } void pic_processor::create_symbols () { if(verbose) cout << __FUNCTION__ << " register memory size = " << register_memory_size() << '\n'; for(unsigned int i = 0; iisa()) { case Register::SFR_REGISTER: //if(!symbol_table.find((char *)registers[i]->name().c_str())) // symbol_table.add_register(registers[i]); // addSymbol(registers[i]); break; default: break; } } pc->set_description("Program Counter"); // Fixme put this in the pc constructor. addSymbol(pc); addSymbol(&wdt); } //------------------------------------------------------------------- bool pic_processor::set_config_word(unsigned int address,unsigned int cfg_word) { int i = get_config_index(address); if ( i >= 0) { m_configMemory->getConfigWord(i)->set((int)cfg_word); if (i == 0 && config_modes) { config_word = cfg_word; config_modes->config_mode = (config_modes->config_mode & ~7) | (cfg_word & 7); } return true; } return false; } unsigned int pic_processor::get_config_word(unsigned int address) { int i; if ((i = get_config_index(address)) >= 0) return m_configMemory->getConfigWord(i)->getVal(); return 0xffffffff; } int pic_processor::get_config_index(unsigned int address) { if (m_configMemory) { for(int i = 0; i < m_configMemory->getnConfigWords(); i++) { if (m_configMemory->getConfigWord(i)) { if (m_configMemory->getConfigWord(i)->ConfigWordAdd() == address) { return i; } } } } return -1; } //------------------------------------------------------------------- // // load_hex // bool pic_processor::LoadProgramFile(const char *pFilename, FILE *pFile, const char *pProcessorName) { Processor * pProcessor = this; // Tries the file type based on the file extension first. // If it fails tries the other type. This code will need // to change if pic_processor is moved to its own module // because then we cannot garrentee that these file types // will be the first two in the list. ProgramFileType * aFileTypes[] = { ProgramFileTypeList::GetList()[0], // IntelHexProgramFileType ProgramFileTypeList::GetList()[1] // PicCodProgramFileType }; if(IsFileExtension(pFilename,"cod")) { // If 'cod' file extension, try PicCodProgramFileType first swap(aFileTypes[0], aFileTypes[1]); } int iReturn = aFileTypes[0]->LoadProgramFile(&pProcessor, pFilename, pFile, pProcessorName); if (iReturn != ProgramFileType::SUCCESS) { fseek(pFile, 0, SEEK_SET); iReturn = aFileTypes[1]->LoadProgramFile(&pProcessor, pFilename, pFile, pProcessorName); } cout << "Leaving pic_processor::LoadProgramFile\n"; return iReturn == ProgramFileType::SUCCESS; } //------------------------------------------------------------------- //------------------------------------------------------------------- // ConfigMode // void ConfigMode::print() { if(config_mode & CM_FOSC1x) { // Internal Oscillator type processor switch(config_mode& (CM_FOSC0 | CM_FOSC1)) { // Lower two bits are the clock type case 0: cout << "LP"; break; case CM_FOSC0: cout << "XT"; break; case CM_FOSC1: cout << "Internal RC"; break; case (CM_FOSC0|CM_FOSC1): cout << "External RC"; break; } }else { switch(config_mode& (CM_FOSC0 | CM_FOSC1)) { // Lower two bits are the clock type case 0: cout << "LP"; break; case CM_FOSC0: cout << "XT"; break; case CM_FOSC1: cout << "HS"; break; case (CM_FOSC0|CM_FOSC1): cout << "RC"; break; } } cout << " oscillator\n"; if(valid_bits & CM_WDTE) cout << " WDT is " << (get_wdt() ? "enabled\n" : "disabled\n"); if(valid_bits & CM_MCLRE) cout << "MCLR is " << (get_mclre() ? "enabled\n" : "disabled\n"); if(valid_bits & CM_CP0) { if(valid_bits & CM_CP1) { cout << "CP0 is " << (get_cp0() ? "high\n" : "low\n"); cout << "CP1 is " << (get_cp1() ? "high\n" : "low\n"); } else { cout << "code protection is " << (get_cp0() ? "enabled\n" : "disabled\n"); } } } //------------------------------------------------------------------- //------------------------------------------------------------------- void ProgramMemoryAccess::callback() { if(_state) { _state = 0; //cout << __FUNCTION__ << " address= " << address << ", opcode= " << opcode << '\n'; //cpu->program_memory[address]->opcode = opcode; put_opcode(_address,_opcode); // FIXME trace.opcode_write(_address,_opcode); bp.clear_pm_write(); } } //-------------------------------------------------- WDT::WDT(pic_processor *p_cpu, double _timeout) : gpsimObject("WDT","Watch Dog Timer"), cpu(p_cpu), breakpoint(0),prescale(1), postscale(128), future_cycle(0), timeout(_timeout), wdte(false), cfgw_enable(false) { } //-------------------------------------------------- void WDT::update() { if(wdte) { // FIXME - the WDT should not be tied to the instruction counter... guint64 delta_cycles; delta_cycles = (guint64)(postscale*prescale*timeout/get_cycles().seconds_per_cycle()); if (verbose) { cout << "WDT::update timeout in " << (postscale*prescale*timeout); cout << " seconds (" << dec << delta_cycles << " cycles), "; cout << "CPU frequency " << (cpu->get_frequency()) << endl; } guint64 fc = get_cycles().get() + delta_cycles ; if(future_cycle) { if(verbose) cout << "WDT::update: moving break from " << future_cycle << " to " << fc << '\n'; get_cycles().reassign_break(future_cycle, fc, this); } else { get_cycles().set_break(fc, this); } future_cycle = fc; } } //-------------------------------------------------- // WDT::put - shouldn't be called? // void WDT::put(unsigned int new_value) { cout << "WDT::put should not be called\n"; } void WDT::set_timeout( double _timeout) { timeout = _timeout; update(); } // TMR0 prescale is WDT postscale void WDT::set_postscale(unsigned int newPostscale) { unsigned int value = 1<< newPostscale; if (verbose) cout << "WDT::set_postscale postscale = " << dec << value << endl; if (value != postscale) { postscale = value; update(); } } void WDT::swdten(bool enable) { if (cfgw_enable) return; if (wdte != enable) { wdte = enable; warned = 0; if(verbose) cout << " WDT swdten " << ( (enable) ? "enabling\n" : ", but disabling WDT\n"); if (wdte) { update(); } else { if (future_cycle) { cout << "Disabling WDT\n"; get_cycles().clear_break(this); future_cycle = 0; } } } } // For WDT period select 0-11 void WDT::set_prescale(unsigned int newPrescale) { unsigned int value = 1<< (5 + newPrescale); if (verbose) cout << "WDT::set_prescale prescale = " << dec << value << endl; if (value != prescale) { prescale = value; update(); } } void WDT::initialize(bool enable) { wdte = enable; cfgw_enable = enable; warned = 0; if(verbose) cout << " WDT init called "<< ( (enable) ? "enabling\n" :", but disabling WDT\n"); if(wdte) { update(); } else { if (future_cycle) { cout << "Disabling WDT\n"; get_cycles().clear_break(this); future_cycle = 0; } } } void WDT::reset(RESET_TYPE r) { switch (r) { case POR_RESET: case EXIT_RESET: update(); break; case MCLR_RESET: if (future_cycle) get_cycles().clear_break(this); future_cycle = 0; break; default: ; } } void WDT::set_breakpoint(unsigned int bpn) { breakpoint = bpn; } void WDT::callback() { if(wdte) { if(verbose) cout<<"WDT timeout: " << hex << get_cycles().get() << '\n'; if(breakpoint) bp.halt(); else if (cpu->is_sleeping() && cpu->exit_wdt_sleep()) { cout << "WDT expired during sleep\n"; update(); cpu->exit_sleep(); cpu->status->put_TO(0); } else { // The TO bit gets cleared when the WDT times out. cout << "WDT expired reset\n"; update(); cpu->status->put_TO(0); cpu->reset(WDT_RESET); } } } void WDT::clear() { if(wdte) update(); else if(!warned) { warned = 1; cout << "The WDT is not enabled - clrwdt has no effect!\n"; } } void WDT::callback_print() { cout << name() << " has callback, ID = " << CallBackID << '\n'; // cout << "WDT\n"; } //------------------------------------------------------------------------ // ConfigMemory - Base class ConfigWord::ConfigWord(const char *_name, unsigned int default_val, const char *desc, pic_processor *pCpu, unsigned int addr, bool EEw) : Integer(_name, default_val, desc), m_pCpu(pCpu), m_addr(addr), EEWritable(EEw) { /* if (m_pCpu) m_pCpu->addSymbol(this); */ } // this get controls the display format in the symbols window void ConfigWord::get(char *buffer, int buf_size) { if(buffer) { gint64 i; get(i); long long int j = i; snprintf(buffer,buf_size,"0x%" PRINTF_INT64_MODIFIER "x",j); } } void ConfigWord::get(gint64 &i) { Integer::get(i); } //------------------------------------------------------------------------ ConfigMemory::ConfigMemory(pic_processor *pCpu, unsigned int nWords) : m_pCpu(pCpu), m_nConfigWords(nWords) { if (nWords > 0 && nWords < 100) { m_ConfigWords = new ConfigWord *[nWords]; for (unsigned int i = 0; i < nWords; i++) m_ConfigWords[i] = 0; } } ConfigMemory::~ConfigMemory() { for (unsigned int i = 0; i < m_nConfigWords; i++) if (m_ConfigWords[i]) m_pCpu->deleteSymbol(m_ConfigWords[i]); delete [] m_ConfigWords; } int ConfigMemory::addConfigWord(unsigned int addr, ConfigWord *pConfigWord) { if (addr < m_nConfigWords) { if (m_ConfigWords[addr]) m_pCpu->deleteSymbol(m_ConfigWords[addr]); m_ConfigWords[addr] = pConfigWord; m_pCpu->addSymbol(pConfigWord); return 1; } delete pConfigWord; return 0; } ConfigWord *ConfigMemory::getConfigWord(unsigned int addr) { return addr < m_nConfigWords ? m_ConfigWords[addr] : 0; } //------------------------------------------------------------------- class MCLRPinMonitor : public PinMonitor { public: MCLRPinMonitor(pic_processor *pCpu); ~MCLRPinMonitor() {} virtual void setDrivenState(char); virtual void setDrivingState(char) {} virtual void set_nodeVoltage(double) {} virtual void putState(char) {} virtual void setDirection() {} private: pic_processor *m_pCpu; char m_cLastResetState; }; MCLRPinMonitor::MCLRPinMonitor(pic_processor *pCpu) : m_pCpu(pCpu), m_cLastResetState('I') // I is not a valid state. It's used here for 'I'nitialization { } void MCLRPinMonitor::setDrivenState(char newState) { if (newState =='0' || newState =='w') { m_cLastResetState = '0'; m_pCpu->reset(MCLR_RESET); } if (newState =='1' || newState =='W') { if (m_cLastResetState == '0') m_pCpu->reset(EXIT_RESET); m_cLastResetState = '1'; } } //------------------------------------------------------------------- void pic_processor::createMCLRPin(int pkgPinNumber) { if (m_MCLR) { cout << "BUG?: assigning multiple MCLR pins: " << __FILE__ << dec << " " << __LINE__ << endl; } if(package) { m_MCLR = new IO_open_collector("MCLR"); package->assign_pin(pkgPinNumber,m_MCLR); addSymbol(m_MCLR); m_MCLRMonitor = new MCLRPinMonitor(this); m_MCLR->setMonitor(m_MCLRMonitor); } } //------------------------------------------------------------------- // This function is called instead of createMCLRPin where the pin // is already defined, but the configuration word has set the function // to MCLR void pic_processor::assignMCLRPin(int pkgPinNumber) { if (package) { if (m_MCLR == NULL) { m_MCLR_pin = pkgPinNumber; m_MCLR = new IO_open_collector("MCLR"); addSymbol(m_MCLR); m_MCLR_Save = package->get_pin(pkgPinNumber); package->assign_pin(pkgPinNumber,m_MCLR, false); m_MCLRMonitor = new MCLRPinMonitor(this); m_MCLR->setMonitor(m_MCLRMonitor); m_MCLR->newGUIname("MCLR"); } else if (m_MCLR != package->get_pin(pkgPinNumber)) { cout << "BUG?: assigning multiple MCLR pins: " << dec << pkgPinNumber << " " << __FILE__ << " " << __LINE__ << endl; } } } //------------------------------------------------------------------- // This function sets the pin currently set as MCLR back to its original function void pic_processor::unassignMCLRPin() { if (package && m_MCLR_Save) { size_t l = m_MCLR_Save->name().find_first_of('.'); package->assign_pin(m_MCLR_pin,m_MCLR_Save, false); if (l == string::npos) m_MCLR_Save->newGUIname(m_MCLR_Save->name().c_str()); else m_MCLR_Save->newGUIname(m_MCLR_Save->name().substr(l+1).c_str()); if (m_MCLR) { m_MCLR->setMonitor(0); deleteSymbol(m_MCLR); m_MCLR = NULL; if (m_MCLRMonitor) { delete m_MCLRMonitor; m_MCLRMonitor = NULL; } } } } //-------------------------------------------------- // class IO_SignalControl : public SignalControl { public: IO_SignalControl(char _dir){ direction = _dir; } ~IO_SignalControl(){} virtual char getState() { return direction; } virtual void release() {} void setState(char _dir) { direction = _dir; } private: char direction; }; // This function sets a label on a pin and if PinMod is defined // removes its control from it's port register // void pic_processor::set_clk_pin(unsigned int pkg_Pin_Number, PinModule *PinMod, const char * name, bool in, PicPortRegister *m_port, PicTrisRegister *m_tris, PicLatchRegister *m_lat) { IOPIN *m_pin = package->get_pin(pkg_Pin_Number); if (name) m_pin->newGUIname(name); else m_pin->newGUIname(package->get_pin_name(pkg_Pin_Number).c_str()); if (PinMod) { if (m_port) { unsigned int mask = m_port->getEnableMask(); mask &= ~(1<< PinMod->getPinNumber()); m_port->setEnableMask(mask); if (m_tris) m_tris->setEnableMask(mask); if (m_lat) m_lat->setEnableMask(mask); } if (!clksource) { clksource = new PeripheralSignalSource(PinMod); clkcontrol = new IO_SignalControl(in ? '1' : '0'); } PinMod->setSource(clksource); PinMod->setControl(clkcontrol); PinMod->updatePinModule(); } } // This function reverses the effects of the previous function void pic_processor::clr_clk_pin(unsigned int pkg_Pin_Number, PinModule *PinMod, PicPortRegister *m_port, PicTrisRegister *m_tris, PicLatchRegister *m_lat) { IOPIN *m_pin = package->get_pin(pkg_Pin_Number); m_pin->newGUIname(package->get_pin_name(pkg_Pin_Number).c_str()); if (PinMod) { if (m_port) { unsigned int mask = m_port->getEnableMask(); mask |= (1<< PinMod->getPinNumber()); m_port->setEnableMask(mask); if (m_tris) m_tris->setEnableMask(mask); if (m_lat) m_lat->setEnableMask(mask); } PinMod->setSource(0); PinMod->setControl(0); PinMod->updatePinModule(); } } void pic_processor::osc_mode(unsigned int value) { IOPIN *m_pin; unsigned int pin_Number = get_osc_pin_Number(0); if (pin_Number < 253) { m_pin = package->get_pin(pin_Number); } if ( (pin_Number = get_osc_pin_Number(1)) < 253 && (m_pin = package->get_pin(pin_Number))) { pll_factor = 0; if (value < 5) { set_clk_pin(pin_Number, m_osc_Monitor[1], "OSC2", true); } else if(value == 6 ) { pll_factor = 2; set_clk_pin(pin_Number, m_osc_Monitor[1], "CLKO", false); } else { clr_clk_pin(pin_Number, m_osc_Monitor[1]); } } } void pic_processor::Wput(unsigned int value) { Wreg->put(value); } unsigned int pic_processor::Wget() { return Wreg->get(); } gpsim-0.30.0/src/14bit-tmrs.cc0000664000076400007640000021613013111502052012641 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2006,2009,2010,2013,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "14bit-tmrs.h" #include "stimuli.h" #include "a2dconverter.h" // // 14bit-tmrs.cc // // Timer 1&2 modules for the 14bit core pic processors. // //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //-------------------------------------------------- // CCPRL //-------------------------------------------------- CCPRL::CCPRL(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), ccprh(0), ccpcon(0), tmrl(0) { } bool CCPRL::test_compare_mode() { return tmrl && ccpcon && ccpcon->test_compare_mode(); } void CCPRL::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); if(test_compare_mode()) start_compare_mode(); // Actually, re-start with new capture value. } void CCPRL::capture_tmr() { tmrl->get_low_and_high(); trace.raw(write_trace.get() | value.get()); value.put(tmrl->value.get()); trace.raw(ccprh->write_trace.get() | ccprh->value.get()); ccprh->value.put(tmrl->tmrh->value.get()); int c = value.get() + 256*ccprh->value.get(); if(verbose & 4) cout << "CCPRL captured: " << c << '\n'; } void CCPRL::start_compare_mode(CCPCON *ref) { int capture_value = value.get() + 256*ccprh->value.get(); if(verbose & 4) cout << "start compare mode with capture value = " << capture_value << '\n'; if ( ref ) { ccpcon = ref; } if ( ccpcon ) tmrl->set_compare_event ( capture_value, ccpcon ); else cout << "CPRL: Attempting to set a compare callback with no CCPCON\n"; } void CCPRL::stop_compare_mode() { // If this CCP is in the compare mode, then change to non-compare and cancel // the tmr breakpoint. if(test_compare_mode()) { tmrl->clear_compare_event ( ccpcon ); } ccpcon = 0; } void CCPRL::start_pwm_mode() { //cout << "CCPRL: starting pwm mode\n"; ccprh->pwm_mode = 1; } void CCPRL::stop_pwm_mode() { //cout << "CCPRL: stopping pwm mode\n"; ccprh->pwm_mode = 0; } //-------------------------------------------------- // assign_tmr - assign a new timer to the capture compare module // // This was created for the 18f family where it's possible to dynamically // choose which clock is captured during an event. // void CCPRL::assign_tmr(TMRL *ptmr) { if(ptmr) { cout << "Reassigning CCPRL clock source\n"; tmrl = ptmr; } } //-------------------------------------------------- // CCPRH //-------------------------------------------------- CCPRH::CCPRH(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), ccprl(0),pwm_mode(0),pwm_value(0) { } // put_value allows PWM code to put data void CCPRH::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } void CCPRH::put(unsigned int new_value) { //cout << "CCPRH put \n"; if(pwm_mode == 0) // In pwm_mode, CCPRH is a read-only register. { put_value(new_value); if(ccprl && ccprl->test_compare_mode()) ccprl->start_compare_mode(); // Actually, re-start with new capture value. } } unsigned int CCPRH::get() { //cout << "CCPRH get\n"; trace.raw(read_trace.get() | value.get()); return value.get(); } //-------------------------------------------------- // //-------------------------------------------------- class CCPSignalSource : public SignalControl { public: CCPSignalSource(CCPCON *_ccp, int _index) : m_ccp(_ccp), state('?'), index(_index) { assert(m_ccp); } virtual ~CCPSignalSource() { } void setState(char m_state) { state = m_state; } virtual char getState() { return state; } virtual void release() { m_ccp->releasePins(index); } private: CCPCON *m_ccp; char state; int index; }; //-------------------------------------------------- // //-------------------------------------------------- class CCPSignalSink : public SignalSink { public: CCPSignalSink(CCPCON *_ccp, int _index) : m_ccp(_ccp), index(_index) { assert(_ccp); } virtual ~CCPSignalSink(){} virtual void release() { m_ccp->releaseSink(); } void setSinkState(char new3State) { m_ccp->new_edge( new3State=='1' || new3State=='W'); } private: CCPCON *m_ccp; int index; }; class Tristate : public SignalControl { public: Tristate() { } ~Tristate() { } char getState() { return '1'; } // set port to high impedance by setting it to input virtual void release() { } }; //-------------------------------------------------- // CCPCON //-------------------------------------------------- CCPCON::CCPCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), pstrcon(0), pwm1con(0), eccpas(0), m_sink(0), m_tristate(0), m_bInputEnabled(false), m_bOutputEnabled(false), m_cOutputState('?'), edges(0), bridge_shutdown(false), ccprl(0), pir(0), tmr2(0), adcon0(0) { for(int i=0; i<4; i++) { m_PinModule[i] = 0; m_source[i] = 0; source_active[i] = false; } mValidBits = 0x3f; } CCPCON::~CCPCON() { for(int i = 0; i<4; i++) { if (m_source[i]) { if ( source_active[i] && m_PinModule[i] ) { m_PinModule[i]->setSource(0); } delete m_source[i]; } } if (m_tristate) delete m_tristate; if (m_PinModule[0] && m_sink) m_PinModule[0]->removeSink(m_sink); if (m_sink) delete m_sink; } void CCPCON::setIOPin1(PinModule *p1) { if (p1 && &(p1->getPin())) { if (m_PinModule[0]) { if (m_PinModule[0] != p1) { m_PinModule[0]->removeSink(m_sink); m_PinModule[0] = p1; p1->addSink(m_sink); } } else { m_PinModule[0] = p1; m_sink = new CCPSignalSink(this, 0); m_tristate = new Tristate(); m_source[0] = new CCPSignalSource(this, 0); p1->addSink(m_sink); } } } void CCPCON::setIOPin2(PinModule *p2) { if (p2) { m_PinModule[1] = p2; if (!m_source[1]) m_source[1] = new CCPSignalSource(this, 1); } else { if (m_source[1]) { delete m_source[1]; m_source[1] = 0; } m_PinModule[1] = 0; } } // EPWM has four outputs PWM 1 void CCPCON::setIOpin(PinModule *p1, PinModule *p2, PinModule *p3, PinModule *p4) { Dprintf(("%s::setIOpin %s\n", name().c_str(), (p1 && &(p1->getPin())) ? p1->getPin().name().c_str():"unknown")); if (p1 && !&(p1->getPin())) { Dprintf(("FIXME %s::setIOpin called where p1 has unassigned pin\n", name().c_str())); return; } setIOPin1(p1); setIOPin2(p2); if (p3) { m_PinModule[2] = p3; if (!m_source[2]) m_source[2] = new CCPSignalSource(this, 2); } else { if (m_source[2]) { delete m_source[2]; m_source[2] = 0; } m_PinModule[2] = 0; } if (p4) { m_PinModule[3] = p4; if (!m_source[3]) m_source[3] = new CCPSignalSource(this, 3); } else { if (m_source[3]) { delete m_source[3]; m_source[3] = 0; } } } void CCPCON::setCrosslinks ( CCPRL *_ccprl, PIR *_pir, unsigned int _mask, TMR2 *_tmr2, ECCPAS *_eccpas ) { ccprl = _ccprl; pir = _pir; tmr2 = _tmr2; eccpas = _eccpas; pir_mask = _mask; } void CCPCON::setADCON(ADCON0 *_adcon0) { adcon0 = _adcon0; } char CCPCON::getState() { return m_bOutputEnabled ? m_cOutputState : '?'; } void CCPCON::new_edge(unsigned int level) { Dprintf(("%s::new_edge() level=%u\n",name().c_str(), level)); switch(value.get() & (CCPM3 | CCPM2 | CCPM1 | CCPM0)) { case ALL_OFF0: case ALL_OFF1: case ALL_OFF2: case ALL_OFF3: Dprintf(("--CCPCON not enabled\n")); return; case CAP_FALLING_EDGE: if (level == 0 && ccprl) { ccprl->capture_tmr(); pir->set(pir_mask); Dprintf(("--CCPCON caught falling edge\n")); } break; case CAP_RISING_EDGE: if (level && ccprl) { ccprl->capture_tmr(); pir->set(pir_mask); Dprintf(("--CCPCON caught rising edge\n")); } break; case CAP_RISING_EDGE4: if (level && --edges <= 0) { ccprl->capture_tmr(); pir->set(pir_mask); edges = 4; Dprintf(("--CCPCON caught 4th rising edge\n")); } //else cout << "Saw rising edge, but skipped\n"; break; case CAP_RISING_EDGE16: if (level && --edges <= 0) { ccprl->capture_tmr(); pir->set(pir_mask); edges = 16; Dprintf(("--CCPCON caught 4th rising edge\n")); } //else cout << "Saw rising edge, but skipped\n"; break; case COM_SET_OUT: case COM_CLEAR_OUT: case COM_INTERRUPT: case COM_TRIGGER: case PWM0: case PWM1: case PWM2: case PWM3: //cout << "CCPCON is set up as an output\n"; return; } } void CCPCON::compare_match() { Dprintf(("%s::compare_match()\n", name().c_str())); switch(value.get() & (CCPM3 | CCPM2 | CCPM1 | CCPM0)) { case ALL_OFF0: case ALL_OFF1: case ALL_OFF2: case ALL_OFF3: Dprintf(("-- CCPCON not enabled\n")); return; case CAP_FALLING_EDGE: case CAP_RISING_EDGE: case CAP_RISING_EDGE4: case CAP_RISING_EDGE16: Dprintf(("-- CCPCON is programmed for capture. bug?\n")); break; case COM_SET_OUT: m_cOutputState = '1'; m_source[0]->setState('1'); m_PinModule[0]->updatePinModule(); if (pir) pir->set(pir_mask); Dprintf(("-- CCPCON setting compare output to 1\n")); break; case COM_CLEAR_OUT: m_cOutputState = '0'; m_source[0]->setState('0'); m_PinModule[0]->updatePinModule(); if (pir) pir->set(pir_mask); Dprintf(("-- CCPCON setting compare output to 0\n")); break; case COM_INTERRUPT: if (pir) pir->set(pir_mask); Dprintf(("-- CCPCON setting interrupt\n")); break; case COM_TRIGGER: if (ccprl) ccprl->tmrl->clear_timer(); if (pir) pir->set(pir_mask); if(adcon0) adcon0->start_conversion(); Dprintf(("-- CCPCON triggering an A/D conversion ccprl %p\n", ccprl)); break; case PWM0: case PWM1: case PWM2: case PWM3: //cout << "CCPCON is set up as an output\n"; return; } } // handle dead-band delay in half-bridge mode void CCPCON::callback() { if(delay_source0) { m_source[0]->setState('1'); m_PinModule[0]->updatePinModule(); delay_source0 = false; } if(delay_source1) { m_source[1]->setState('1'); m_PinModule[1]->updatePinModule(); delay_source1 = false; } } void CCPCON::releaseSink() { delete m_sink; m_sink = 0; } void CCPCON::releasePins(int i) { source_active[i] = false; } void CCPCON::pwm_match(int level) { unsigned int new_value = value.get(); Dprintf(("%s::pwm_match() level=%d now=0x%" PRINTF_GINT64_MODIFIER "x\n", name().c_str(), level, get_cycles().get())); // if the level is 1, then tmr2 == pr2 and the pwm cycle // is starting over. In which case, we need to update the duty // cycle by reading ccprl and the ccp X & Y and caching them // in ccprh's pwm slave register. if(level == 1) { // Auto shutdown comes off at start of PWM if ECCPASE clear if (bridge_shutdown && (!eccpas || !(eccpas->get_value() & ECCPAS::ECCPASE))) { Dprintf(("bridge_shutdown=%d eccpas=%p ECCPAS=%x\n", bridge_shutdown, eccpas, eccpas ? eccpas->get_value() & ECCPAS::ECCPASE: 0)); for(int i = 0; i < 4; i++) { if(m_PinModule[i]) { m_PinModule[i]->setControl(0); //restore default pin direction source_active[i] = false; m_PinModule[i]->updatePinModule(); } } bridge_shutdown = false; } ccprl->ccprh->pwm_value = ((value.get()>>4) & 3) | 4*ccprl->value.get(); tmr2->pwm_dc(ccprl->ccprh->pwm_value, address); ccprl->ccprh->put_value(ccprl->value.get()); } if( !pwm1con) { // simple PWM if (bridge_shutdown == false) // some processors use shutdown and simple PWM { m_cOutputState = level ? '1' : '0'; m_source[0]->setState(level ? '1' : '0'); m_PinModule[0]->setSource(m_source[0]); source_active[0] = true; if(level && !ccprl->ccprh->pwm_value) // if duty cycle == 0 output stays low m_source[0]->setState('0'); m_PinModule[0]->updatePinModule(); //cout << "iopin should change\n"; } } else // EPWM { if (!bridge_shutdown) drive_bridge(level, new_value); } } // // Drive PWM bridge // void CCPCON::drive_bridge(int level, int new_value) { unsigned int pstrcon_value; // pstrcon allows port steering for "single output" // if it is not defined, just use the first port if (pstrcon) pstrcon_value = pstrcon->value.get(); else pstrcon_value = 1; int pwm_width; int delay = pwm1con->value.get() & ~PWM1CON::PRSEN; bool active_high[4]; switch (new_value & (CCPM3|CCPM2|CCPM1|CCPM0)) { case PWM0: //P1A, P1C, P1B, P1D active high active_high[0] = true; active_high[1] = true; active_high[2] = true; active_high[3] = true; break; case PWM1: // P1A P1C active high P1B P1D active low active_high[0] = true; active_high[1] = false; active_high[2] = true; active_high[3] = false; break; case PWM2: // P1A P1C active low P1B P1D active high active_high[0] = false; active_high[1] = true; active_high[2] = false; active_high[3] = true; break; case PWM3: // //P1A, P1C, P1B, P1D active low active_high[0] = false; active_high[1] = false; active_high[2] = false; active_high[3] = false; break; default: cout << "not pwm mode. bug?\n"; return; break; } switch((new_value & (P1M1|P1M0))>>6) // ECCP bridge mode { case 0: // Single Dprintf(("Single bridge %s pstrcon=0x%x\n", name().c_str(), pstrcon_value)); for (int i = 0; i <4; i++) { if (pstrcon_value & (1<setSource(m_source[i]); source_active[i] = true; // follow level except where duty cycle = 0 if (level && ccprl->ccprh->pwm_value) m_source[i]->setState(active_high[i]?'1':'0'); else m_source[i]->setState(active_high[i]?'0':'1'); m_PinModule[i]->updatePinModule(); } else if (m_PinModule[i]) { m_PinModule[i]->setSource(0); source_active[i] = false; } } break; case 2: // Half-Bridge Dprintf(("half-bridge %s\n", name().c_str())); m_PinModule[0]->setSource(m_source[0]); source_active[0] = true; m_PinModule[1]->setSource(m_source[1]); source_active[1] = true; if (m_PinModule[2]) { m_PinModule[2]->setSource(0); source_active[2] = false; } if (m_PinModule[3]) { m_PinModule[3]->setSource(0); source_active[3] = false; } delay_source0 = false; delay_source1 = false; // FIXME need to add deadband // follow level except where duty cycle = 0 pwm_width = level ? ccprl->ccprh->pwm_value : ((tmr2->pr2->value.get()+1)*4)-ccprl->ccprh->pwm_value; if (!(level^active_high[0]) && ccprl->ccprh->pwm_value) { // No delay, change state if (delay == 0) m_source[0]->setState('1'); else if (delay < pwm_width) // there is a delay { future_cycle = get_cycles().get() + delay; get_cycles().set_break(future_cycle, this); delay_source0 = true; } } else { m_source[0]->setState('0'); } if (!(level^active_high[1]) && ccprl->ccprh->pwm_value) { m_source[1]->setState('0'); } else { // No delay, change state if (delay == 0) m_source[1]->setState('1'); else if (delay < pwm_width) // there is a delay { future_cycle = get_cycles().get() + delay; get_cycles().set_break(future_cycle, this); delay_source1 = true; } } m_PinModule[0]->updatePinModule(); m_PinModule[1]->updatePinModule(); break; case 1: // Full bidge Forward Dprintf(("full-bridge %s, forward\n", name().c_str())); if (m_PinModule[0]) { m_PinModule[0]->setSource(m_source[0]); source_active[0] = true; // P1A High (if active high) m_source[0]->setState(active_high[0]?'1':'0'); m_PinModule[0]->updatePinModule(); } if (m_PinModule[1]) { m_PinModule[1]->setSource(m_source[1]); source_active[1] = true; // P1B, P1C low (if active high) m_source[1]->setState(active_high[1]?'0':'1'); m_PinModule[1]->updatePinModule(); } if (m_PinModule[2]) { m_PinModule[2]->setSource(m_source[2]); source_active[2] = true; // P1B, P1C low (if active high) m_source[2]->setState(active_high[2]?'0':'1'); m_PinModule[2]->updatePinModule(); } if (m_PinModule[3]) { m_PinModule[3]->setSource(m_source[3]); source_active[3] = true; // P1D toggles if (level && ccprl->ccprh->pwm_value) m_source[3]->setState(active_high[3]?'1':'0'); else m_source[3]->setState(active_high[3]?'0':'1'); m_PinModule[3]->updatePinModule(); } break; case 3: // Full bridge reverse Dprintf(("full-bridge reverse %s\n", name().c_str())); if (m_PinModule[0]) { m_PinModule[0]->setSource(m_source[0]); source_active[0] = true; // P1A, P1D low (if active high) m_source[0]->setState(active_high[0]?'0':'1'); m_PinModule[0]->updatePinModule(); } if (m_PinModule[1]) { m_PinModule[1]->setSource(m_source[1]); source_active[1] = true; // P1B toggles if (level && ccprl->ccprh->pwm_value) m_source[1]->setState(active_high[1]?'1':'0'); else m_source[1]->setState(active_high[1]?'0':'1'); m_PinModule[1]->updatePinModule(); } if (m_PinModule[2]) { m_PinModule[2]->setSource(m_source[2]); source_active[2] = true; // P1C High (if active high) m_source[2]->setState(active_high[2]?'1':'0'); m_PinModule[2]->updatePinModule(); } if (m_PinModule[3]) { m_PinModule[3]->setSource(m_source[3]); source_active[3] = true; // P1A, P1D low (if active high) m_source[3]->setState(active_high[3]?'0':'1'); m_PinModule[3]->updatePinModule(); } break; default: printf("%s::pwm_match impossible ECCP bridge mode\n", name().c_str()); break; } } // // Set PWM bridge into shutdown mode // void CCPCON::shutdown_bridge(int eccpas) { bridge_shutdown = true; Dprintf(("eccpas=0x%x\n", eccpas)); switch(eccpas & (ECCPAS::PSSBD0 | ECCPAS::PSSBD1)) { case 0: // B D output 0 if (m_source[1]) m_source[1]->setState('0'); if (m_source[3]) m_source[3]->setState('0'); break; case 1: // B, D output 1 if (m_source[1]) m_source[1]->setState('1'); if (m_source[3]) m_source[3]->setState('1'); break; default: // Tristate B & D if(m_PinModule[1]) m_PinModule[1]->setControl(m_tristate); if(m_PinModule[3]) m_PinModule[3]->setControl(m_tristate); break; } switch(eccpas & ((ECCPAS::PSSAC0 | ECCPAS::PSSAC1) >> 2)) { case 0: // A, C output 0 m_source[0]->setState('0'); if (m_source[2]) m_source[2]->setState('0'); break; case 1: // A, C output 1 m_source[0]->setState('1'); if (m_source[2]) m_source[2]->setState('1'); break; default: // Tristate A & C m_PinModule[0]->setControl(m_tristate); if(m_PinModule[2]) m_PinModule[2]->setControl(m_tristate); break; } m_PinModule[0]->updatePinModule(); if (m_PinModule[1]) m_PinModule[1]->updatePinModule(); if (m_PinModule[2]) m_PinModule[2]->updatePinModule(); if (m_PinModule[3]) m_PinModule[3]->updatePinModule(); } void CCPCON::put(unsigned int new_value) { unsigned int old_value = value.get(); new_value &= mValidBits; Dprintf(("%s::put() new_value=0x%x\n",name().c_str(), new_value)); trace.raw(write_trace.get() | value.get()); value.put(new_value); if (!ccprl || !tmr2) return; // Return if no change other than possibly the duty cycle if (((new_value ^ old_value) & ~(CCPY|CCPX)) == 0) return; bool oldbInEn = m_bInputEnabled; bool oldbOutEn = m_bOutputEnabled; switch(value.get() & (CCPM3 | CCPM2 | CCPM1 | CCPM0)) { case ALL_OFF0: case ALL_OFF1: case ALL_OFF2: case ALL_OFF3: if (ccprl) { ccprl->stop_compare_mode(); ccprl->stop_pwm_mode(); } if (tmr2) tmr2->stop_pwm(address); m_bInputEnabled = false; m_bOutputEnabled = false; // RP - According to 16F87x data sheet section 8.2.1 clearing CCPxCON also clears the latch m_cOutputState = '0'; m_source[0]->setState('0'); break; case CAP_FALLING_EDGE: case CAP_RISING_EDGE: edges = 0; ccprl->stop_compare_mode(); ccprl->stop_pwm_mode(); tmr2->stop_pwm(address); m_bInputEnabled = true; m_bOutputEnabled = false; break; case CAP_RISING_EDGE4: edges &= 3; ccprl->stop_compare_mode(); ccprl->stop_pwm_mode(); tmr2->stop_pwm(address); m_bInputEnabled = true; m_bOutputEnabled = false; break; case CAP_RISING_EDGE16: ccprl->stop_compare_mode(); ccprl->stop_pwm_mode(); tmr2->stop_pwm(address); m_bInputEnabled = true; m_bOutputEnabled = false; break; case COM_SET_OUT: case COM_CLEAR_OUT: m_bOutputEnabled = true; case COM_INTERRUPT: case COM_TRIGGER: ccprl->start_compare_mode(this); ccprl->stop_pwm_mode(); tmr2->stop_pwm(address); // RP - just writing CCP2CON doesn't trigger the ADC; that only happens on a match //if(adcon0) // adcon0->start_conversion(); m_bInputEnabled = false; //if(adcon0) cout << "CCP triggering an A/D\n"; break; case PWM0: case PWM1: case PWM2: case PWM3: ccprl->stop_compare_mode(); /* do this when TMR2 == PR2 ccprl->start_pwm_mode(); tmr2->pwm_dc( ccprl->ccprh->pwm_value, address); */ m_bInputEnabled = false; m_bOutputEnabled = false; // this is done in pwm_match m_cOutputState = '0'; if ((old_value & P1M0) && (new_value & P1M0)) // old and new full-bridge { // need to adjust timer if P1M1 also changed Dprintf(("full bridge repeat old=0x%x new=%x\n", old_value, new_value)); } else pwm_match(2); return; break; } if (oldbOutEn != m_bOutputEnabled && m_PinModule) { if (m_bOutputEnabled) { m_PinModule[0]->setSource(m_source[0]); source_active[0] = true; } else { m_PinModule[0]->setSource(0); m_source[0]->setState('?'); source_active[0] = false; } } if ((oldbInEn != m_bInputEnabled || oldbOutEn != m_bOutputEnabled) && m_PinModule[0]) m_PinModule[0]->updatePinModule(); } bool CCPCON::test_compare_mode() { switch(value.get() & (CCPM3 | CCPM2 | CCPM1 | CCPM0)) { case ALL_OFF0: case ALL_OFF1: case ALL_OFF2: case ALL_OFF3: case CAP_FALLING_EDGE: case CAP_RISING_EDGE: case CAP_RISING_EDGE4: case CAP_RISING_EDGE16: case PWM0: case PWM1: case PWM2: case PWM3: return false; break; case COM_SET_OUT: case COM_CLEAR_OUT: case COM_INTERRUPT: case COM_TRIGGER: return true; break; } return false; } TRISCCP::TRISCCP(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName), first(true) { } void TRISCCP::put(unsigned int new_value) { if (first) { first = false; cout << name() << " not implemented, if required, file feature request\n"; } trace.raw(write_trace.get() | value.get()); value.put(new_value); } DATACCP::DATACCP(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName), first(true) { } void DATACCP::put(unsigned int new_value) { if (first) { first = false; cout << name() << " not implemented, if required, file feature request\n"; } trace.raw(write_trace.get() | value.get()); value.put(new_value); } class TMR1_Interface : public Interface { public: TMR1_Interface(TMRL *_tmr1) : Interface((gpointer *)_tmr1) { tmr1 = _tmr1; } virtual void SimulationHasStopped (gpointer object) { tmr1->current_value(); } virtual void Update (gpointer object) { SimulationHasStopped(object); } private: TMRL *tmr1; }; // Attribute for frequency of external Timer1 oscillator class TMR1_Freq_Attribute : public Float { public: TMR1_Freq_Attribute(Processor * _cpu, double freq, const char *name = "tmr1_freq"); virtual void set(double d); double get_freq(); private: Processor * cpu; }; TMR1_Freq_Attribute::TMR1_Freq_Attribute(Processor * _cpu, double freq, const char *name) : Float(name, freq, " Tmr oscillator frequency."), cpu(_cpu) { } double TMR1_Freq_Attribute::get_freq() { double d; Float::get(d); return(d); } void TMR1_Freq_Attribute::set(double d) { Float::set ( d ); } //-------------------------------------------------- // T1CON //-------------------------------------------------- T1CON::T1CON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), tmrl(0), cpu(pCpu) { char freq_name[] = "tmr1_freq"; if (*(pName+1) >= '1' && *(pName+1) <= '9') freq_name[3] = *(pName+1); cpu->addSymbol(freq_attribute = new TMR1_Freq_Attribute(pCpu, 32768., freq_name)); } T1CON::~T1CON() { cpu->removeSymbol(freq_attribute); delete freq_attribute; } void T1CON::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); unsigned int diff = value.get() ^ new_value; value.put(new_value); if (!tmrl) return; // First, check the tmr1 clock source bit to see if we are changing from // internal to external (or vice versa) clocks. if( diff & (TMR1CS | T1OSCEN)) tmrl->new_clock_source(); if( diff & TMR1ON) tmrl->on_or_off(value.get() & TMR1ON); else if( diff & (T1CKPS0 | T1CKPS1 | TMR1GE | T1GINV)) tmrl->update(); } unsigned int T1CON::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } unsigned int T1CON::get_prescale() { return( ((value.get() &(T1CKPS0 | T1CKPS1)) >> 4) ); } double T1CON::t1osc() { return (value.get() & T1OSCEN) ? freq_attribute->get_freq() : 0.; } //-------------------------------------------------- // //-------------------------------------------------- // // Signal T1GCon on change of state of Gate pin // class T1GCon_GateSignalSink : public SignalSink { public: T1GCon_GateSignalSink(T1GCON *_t1gcon) : m_t1gcon(_t1gcon) { assert(_t1gcon); } virtual ~T1GCon_GateSignalSink() { } virtual void release() {delete this; } virtual void setSinkState(char new3State) { m_t1gcon->PIN_gate( new3State=='1' || new3State=='W'); } private: T1GCON *m_t1gcon; }; T1GCON::T1GCON(Processor *pCpu, const char *pName, const char *pDesc, T1CON_G *_t1con_g) : sfr_register(pCpu, pName, pDesc), sink(0), write_mask(0xfb), tmrl(0), t1con_g(_t1con_g), m_Interrupt(0), PIN_gate_state(false), T0_gate_state(false), CM1_gate_state(false), CM2_gate_state(false), last_t1g_in(false), gate_pin(0) { } T1GCON::~T1GCON() { if (m_Interrupt) m_Interrupt->release(); } bool T1GCON::tmr1_isON() { if (t1con_g) return t1con_g->get_tmr1on(); if (tmrl->t1con) return tmrl->t1con->get_tmr1on(); cerr << "Error " << name() << " get_tmr1on() not found\n"; return false; } void T1GCON::put(unsigned int new_value) { unsigned int old_value = value.get(); new_value = (new_value & write_mask) | (old_value & ~write_mask); unsigned int diff = new_value ^ old_value; bool t1ggo = new_value & T1GGO; assert(m_Interrupt); assert(tmrl); if (!diff) return; trace.raw(write_trace.get() | value.get()); value.put(new_value); if (diff & (T1GSS1 | T1GSS0 | T1GPOL | TMR1GE)) { switch(new_value & (T1GSS1 | T1GSS0)) { case 0: new_gate(PIN_gate_state); break; case 1: new_gate(T0_gate_state); break; case 2: new_gate(CM1_gate_state); break; case 3: new_gate(CM2_gate_state); break; } // Dont't allow gate change to clear new T1GG0 if((diff & T1GGO) && t1ggo) value.put(value.get() | T1GGO); } // T1GGO set and Single pulse mode if ((diff & T1GGO) && (value.get() & (T1GGO | T1GSPM))) { //tmrl->IO_gate(true); if (value.get() & T1GVAL) { value.put(value.get() & ~T1GVAL); //tmrl->IO_gate(true); tmrl->IO_gate(false); } } if (diff & T1GTM) { if ((value.get() & T1GTM)) // T1GTM going high, set t1g_in to 0 { if(value.get() & T1GVAL) { value.put(value.get() & ~(T1GVAL)); m_Interrupt->Trigger(); } tmrl->IO_gate(false); // Counting should be stopped } } tmrl->update(); } void T1GCON::setGatepin(PinModule *pin) { if (pin != gate_pin) { if(sink) { gate_pin->removeSink(sink); } else sink = new T1GCon_GateSignalSink(this); gate_pin = pin; Dprintf(("T1GCON::setGatepin %s\n", pin->getPin().name().c_str())); pin->addSink(sink); } } // The following 4 functions are called on a state change. // They pass the state to new_gate if that input is selected. void T1GCON::PIN_gate(bool state) { PIN_gate_state = state; if((value.get() & (T1GSS0|T1GSS1)) == 0) new_gate(state); } void T1GCON::T0_gate(bool state) { T0_gate_state = state; if((value.get() & (T1GSS0|T1GSS1)) == 1) new_gate(state); } // T[246] = PR[246] // overloads T0_gate_state void T1GCON::T2_gate(bool state) { T0_gate_state = state; if((value.get() & (T1GSS0|T1GSS1)) == 1) new_gate(state); } void T1GCON::CM1_gate(bool state) { CM1_gate_state = state; if((value.get() & (T1GSS0|T1GSS1)) == 2) { new_gate(state); } } void T1GCON::CM2_gate(bool state) { CM2_gate_state = state; if((value.get() & (T1GSS0|T1GSS1)) == 3) { new_gate(state); } } void T1GCON::new_gate(bool state) { // TMR1 counts when state low (unless t1gpol is set) // t1g_in is inverted as per XOR in spec sheet flow chart bool t1g_in = (!get_t1GPOL()) ^ state ; bool t1g_val = value.get() & T1GVAL; unsigned int reg_value = value.get(); if ((t1g_in == last_t1g_in) && (t1g_in == t1g_val)) // no state change, do nothing { // tmrl->IO_gate(t1g_val); return; } last_t1g_in = t1g_in; if ( reg_value & T1GTM) // Toggle mode { t1g_val = reg_value & T1GVAL; if (t1g_in) // rising edge { t1g_val = ! t1g_val; // t1gval changes state } else { return; } } else // Gate directly in control { t1g_val = t1g_in; } if (reg_value & T1GSPM) // Single pulse mode { if (!(reg_value & T1GGO)) // do nothing if T1GGO clear return; if (!t1g_val) // End of gate { reg_value &= ~T1GGO; //set done } else // Start of gate { } //t1g_val = t1g_in; } if (t1g_val) { reg_value |= T1GVAL; } else { if (reg_value & T1GVAL) // interrupt on T1GVAL negative edge { m_Interrupt->Trigger(); } reg_value &= ~T1GVAL; } value.put(reg_value); tmrl->IO_gate(t1g_val); } //-------------------------------------------------- // T1CON_G //-------------------------------------------------- T1CON_G::T1CON_G(Processor *pCpu, const char *pName, const char *pDesc) //: sfr_register(pCpu, pName, pDesc), : T1CON(pCpu, pName, pDesc), tmrl(0), t1gcon(pCpu, "t1gcon", "TM1 Gate Control Register", this) { new_name("T1CON"); } T1CON_G::~T1CON_G() { delete freq_attribute; } void T1CON_G::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); unsigned int diff = value.get() ^ new_value; value.put(new_value); if (!tmrl) return; // First, check the tmr1 clock source bit to see if we are changing from // internal to external (or vice versa) clocks. if( diff & (TMR1CS0 | TMR1CS1 | T1OSCEN)) tmrl->new_clock_source(); if( diff & TMR1ON) tmrl->on_or_off(value.get() & TMR1ON); else if( diff & (T1CKPS0 | T1CKPS1 )) tmrl->update(); } // If Cap. sensing oscillator T1 clock source, pass to T1 void T1CON_G::t1_cap_increment() { if (get_tmr1cs() == 3) // T1 input Cap. sensing oscillator tmrl->increment(); } //-------------------------------------------------- // member functions for the TMRH base class //-------------------------------------------------- TMRH::TMRH(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), tmrl(0) { value.put(0); } void TMRH::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); if(!tmrl) { value.put(new_value & 0xff); return; } tmrl->set_ext_scale(); value.put(new_value & 0xff); tmrl->synchronized_cycle = get_cycles().get(); tmrl->last_cycle = tmrl->synchronized_cycle - (gint64)((tmrl->value.get() + (value.get()<<8) * tmrl->prescale * tmrl->ext_scale) +0.5); if(tmrl->t1con->get_tmr1on()) tmrl->update(); } unsigned int TMRH::get() { trace.raw(read_trace.get() | value.get()); return get_value(); } // For the gui and CLI unsigned int TMRH::get_value() { // If the TMR1 is being read immediately after being written, then // it hasn't had enough time to synchronize with the PIC's clock. if(get_cycles().get() <= tmrl->synchronized_cycle) return value.get(); // If the TMR is not running then return. if(!tmrl->t1con->get_tmr1on()) return value.get(); tmrl->current_value(); return(value.get()); } //-------------------------------------------------- // //-------------------------------------------------- class TMRl_GateSignalSink : public SignalSink { public: TMRl_GateSignalSink(TMRL *_tmr1l) : m_tmr1l(_tmr1l) { assert(_tmr1l); } virtual void release() { delete this; } void setSinkState(char new3State) { m_tmr1l->IO_gate( new3State=='1' || new3State=='W'); } private: TMRL *m_tmr1l; }; //-------------------------------------------------- // trivial class to represent a compare event reference //-------------------------------------------------- class TMR1CapComRef { public: TMR1CapComRef * next; CCPCON * ccpcon; unsigned int value; TMR1CapComRef ( CCPCON * c, unsigned int v ) : ccpcon(c), value(v) {}; }; //-------------------------------------------------- // member functions for the TMRL base class //-------------------------------------------------- TMRL::TMRL(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), tmr1_interface(0), m_cState('?'), m_GateState(false), m_compare_GateState(true), m_io_GateState(true), m_bExtClkEnabled(false), m_sleeping(false), m_t1gss(true), m_Interrupt(0) { value.put(0); synchronized_cycle=0; prescale_counter=prescale=1; break_value = 0x10000; last_cycle = 0; future_cycle = 0; ext_scale = 1.; tmrh = 0; t1con = 0; compare_queue = 0; } TMRL::~TMRL() { if (m_Interrupt) m_Interrupt->release(); } /* * If we are similating an external RTC crystal for timer1, * compute scale factor between crsytal speed and processor * instruction cycle rate * * If tmr1cs = 1 Fosc is 4 x normal speed so reduce ticks by 1/4 */ void TMRL::set_ext_scale() { current_value(); if (t1con->get_t1oscen() && (t1con->get_tmr1cs() == 2)) // external clock { ext_scale = get_cycles().instruction_cps()/ t1con->freq_attribute->get_freq(); } else if (t1con->get_tmr1cs() == 1) // Fosc ext_scale = 0.25; else ext_scale = 1.; if (future_cycle) { last_cycle = get_cycles().get() - (gint64)(value_16bit *( prescale * ext_scale) + 0.5); } } void TMRL::release() { } void TMRL::setIOpin(PinModule *extClkSource) { Dprintf(("%s::setIOpin %s\n", name().c_str(), extClkSource?extClkSource->getPin().name().c_str():"")); Dprintf(("TMRL::setIOpin\n")); if (extClkSource) extClkSource->addSink(this); } void TMRL::setSinkState(char new3State) { if (new3State != m_cState) { m_cState = new3State; if (m_bExtClkEnabled && (m_cState == '1' || m_cState == 'W')) increment(); } } void TMRL::set_compare_event ( unsigned int value, CCPCON *host ) { TMR1CapComRef * event = compare_queue; if ( host ) { while ( event ) { if ( event->ccpcon == host ) { event->value = value; update(); return; } event = event->next; } event = new TMR1CapComRef ( host, value ); event->next = compare_queue; compare_queue = event; update(); } else cout << "TMRL::set_compare_event called with no CAPCOM\n"; } void TMRL::clear_compare_event ( CCPCON *host ) { TMR1CapComRef * event = compare_queue; TMR1CapComRef * * eptr = &compare_queue; while ( event ) { if ( event->ccpcon == host ) { *eptr = event->next; delete event; update(); return; } eptr = &event->next; event = event->next; } } void TMRL::setGatepin(PinModule *extGateSource) { Dprintf(("TMRL::setGatepin\n")); if (extGateSource) extGateSource->addSink(new TMRl_GateSignalSink(this)); } void TMRL::set_T1GSS(bool arg) { m_t1gss = arg; if (m_t1gss) IO_gate(m_io_GateState); else compare_gate(m_compare_GateState); } void TMRL::compare_gate(bool state) { m_compare_GateState = state; if (!m_t1gss && m_GateState != state) { m_GateState = state; Dprintf(("TMRL::compare_gate state %d \n", state)); if (t1con->get_tmr1GE()) { update(); } } } void TMRL::IO_gate(bool state) { m_io_GateState = state; if (m_t1gss && (m_GateState != state)) { m_GateState = state; Dprintf(("TMRL::IO_gate state %d \n", state)); if (t1con->get_tmr1GE()) { update(); } } } //------------------------------------------------------------ // setInterruptSource() // // This Timer can be an interrupt source. When the interrupt // needs to be generated, then the InterruptSource object will // direct the interrupt to where it needs to go (usually this // is the Peripheral Interrupt Register). void TMRL::setInterruptSource(InterruptSource *_int) { m_Interrupt = _int; } void TMRL::increment() { Dprintf(("TMRL increment because of external clock\n")); if(--prescale_counter == 0) { prescale_counter = prescale; // In synchronous counter mode prescaler works but rest of tmr1 does not if (t1con->get_t1sync() == 0 && m_sleeping) return; // prescaler works but rest of timer turned off if (!t1con->get_tmr1on()) return; // If TMRH/TMRL have been manually changed, we'll want to // get the up-to-date values; trace.raw(write_trace.get() | value.get()); current_value(); value_16bit = 0xffff & ( value_16bit + 1); tmrh->value.put((value_16bit >> 8) & 0xff); value.put(value_16bit & 0xff); if(value_16bit == 0 && m_Interrupt) { if (verbose & 4) cout << "TMRL:increment interrupt now=" << dec << get_cycles().get() << " value_16bit " << value_16bit << endl; m_Interrupt->Trigger(); } } } void TMRL::on_or_off(int new_state) { if(new_state) { Dprintf(("%s is being turned on\n", name().c_str())); // turn on the timer // Effective last cycle // Compute the "effective last cycle", i.e. the cycle // at which TMR1 was last 0 had it always been counting. last_cycle = (gint64)(get_cycles().get() - (value.get() + (tmrh->value.get()<<8)) * prescale * ext_scale + 0.5); update(); } else { Dprintf(("%s is being turned off\n", name().c_str())); // turn off the timer and save the current value current_value(); if (future_cycle) { get_cycles().clear_break(this); future_cycle = 0; } } } // // If anything has changed to affect when the next TMR1 break point // will occur, this routine will make sure the break point is moved // correctly. // void TMRL::update() { Dprintf(("TMR1 %s update now=0x%" PRINTF_GINT64_MODIFIER "x\n",name().c_str(), get_cycles().get())); // if t1con->get_t1GINV() is false, timer can run if m_GateState == 0 bool gate = t1con->get_t1GINV() ? m_GateState : !m_GateState; Dprintf(("TMRL::update gate %d GateState %d inv %d get_tmr1on %x tmr1GE %x tmr1cs %x t1oscen %x\n", gate, m_GateState, t1con->get_t1GINV(), t1con->get_tmr1on(), t1con->get_tmr1GE(), t1con->get_tmr1cs(), t1con->get_t1oscen())); /* When tmr1 is on, and t1con->get_tmr1GE() is true, gate == 1 allows timer to run, gate == 0 stops timer. However, if t1con->get_tmr1GE() is false gate has no effect on timer running or not. */ if(t1con->get_tmr1on() && (t1con->get_tmr1GE() ? gate : true)) { switch(t1con->get_tmr1cs()) { case 0: // internal clock Fosc/4 if(verbose & 0x4) cout << "Tmr1 Internal clock\n"; break; case 1: // internal clock Fosc break; case 2: // External clock if (t1con->get_t1oscen()) // External clock enabled { /* external timer1 clock runs off a crystal which is typically 32768 Hz and is independant on the instruction clock, but gpsim runs on the instruction clock. Ext_scale is the ratio of these two clocks so the breakpoint can be adjusted to be triggered at the correct time. */ if(verbose & 0x4) cout << "Tmr1 External clock\n"; } else // External stimuli(pin) { prescale = 1 << t1con->get_prescale(); prescale_counter = prescale; set_ext_scale(); return; } break; case 3: // Cap. sensing oscillator prescale = 1 << t1con->get_prescale(); prescale_counter = prescale; set_ext_scale(); return; break; default: cout << "TMR1SC reserved value " << t1con->get_tmr1cs() << endl; break; } set_ext_scale(); // Note, unlike TMR0, anytime something is written to TMRL, the // prescaler is unaffected on the P18 processors. However, it is // reset on the p16f88 processor, which is how the current code // works. This only effects the external drive mode. prescale = 1 << t1con->get_prescale(); prescale_counter = prescale; if(verbose & 0x4) cout << "TMRL: Current prescale " << prescale << ", ext scale " << ext_scale << '\n'; // synchronized_cycle = cycles.get() + 2; synchronized_cycle = get_cycles().get(); last_cycle = synchronized_cycle - (gint64)(value_16bit *( prescale * ext_scale) + 0.5); break_value = 0x10000; // Assume that a rollover will happen first. for ( TMR1CapComRef * event = compare_queue; event; event = event->next ) { if(verbose & 0x4) cout << "compare mode on " << event->ccpcon << ", value = " << event->value << '\n'; if ( event->value > value_16bit && event->value < break_value ) { // A compare interrupt is going to happen before the timer // will rollover. break_value = event->value; } } if(verbose & 0x4) cout << "TMR1 now at " << value_16bit << ", next event at " << break_value << '\n'; guint64 fc = get_cycles().get() + (guint64)((break_value - value_16bit) * prescale * ext_scale); if(future_cycle) get_cycles().reassign_break(future_cycle, fc, this); else get_cycles().set_break(fc, this); future_cycle = fc; // Setup to update for GUI breaks if (tmr1_interface == 0) { tmr1_interface = new TMR1_Interface(this); get_interface().prepend_interface(tmr1_interface); } } else { // turn off the timer and save the current value if (future_cycle) { current_value(); get_cycles().clear_break(this); future_cycle = 0; } } } void TMRL::put(unsigned int new_value) { set_ext_scale(); trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); if (!tmrh || !t1con) return; synchronized_cycle = get_cycles().get(); last_cycle = synchronized_cycle - (gint64)(( value.get() + (tmrh->value.get()<<8)) * prescale * ext_scale + 0.5); current_value(); if(t1con->get_tmr1on()) update(); } unsigned int TMRL::get() { trace.raw(read_trace.get() | value.get()); return get_value(); } // For the gui and CLI unsigned int TMRL::get_value() { // If the TMRL is being read immediately after being written, then // it hasn't had enough time to synchronize with the PIC's clock. if(get_cycles().get() <= synchronized_cycle) return value.get(); // If TMRL is not on, then return the current value if(!t1con->get_tmr1on()) return value.get(); current_value(); return(value.get()); } //%%%FIXME%%% inline this // if break inactive (future_cycle == 0), just read the TMR1H and TMR1L // registers otherwise compute what the register should be and then // update TMR1H and TMR1L. // RP: Using future_cycle here is not strictly right. What we really want is // the condition "TMR1 is running on a GPSIM-generated clock" (as opposed // to being off, or externally clocked by a stimulus). The presence of a // breakpoint is _usually_ a good indication of this, but not while we're // actually processing that breakpoint. For the time being, we work around // this by calling current_value "redundantly" in callback() // void TMRL::current_value() { if (!tmrh) return; if (future_cycle == 0) value_16bit = tmrh->value.get() * 256 + value.get(); else { value_16bit = (guint64)((get_cycles().get() - last_cycle)/ (prescale* ext_scale)); if (value_16bit > 0x10000) cerr << "overflow TMRL " << name() << " " << value_16bit << endl; value.put(value_16bit & 0xff); tmrh->value.put((value_16bit>>8) & 0xff); } } unsigned int TMRL::get_low_and_high() { // If the TMRL is being read immediately after being written, then // it hasn't had enough time to synchronize with the PIC's clock. if(get_cycles().get() <= synchronized_cycle) return value.get(); current_value(); trace.raw(read_trace.get() | value.get()); trace.raw(tmrh->read_trace.get() | tmrh->value.get()); return(value_16bit); } // set m_bExtClkEnable is tmr1 is being clocked by an external stimulus void TMRL::new_clock_source() { m_bExtClkEnabled = false; current_value(); switch(t1con->get_tmr1cs()) { case 0: // Fosc/4 if(verbose & 0x4) cout << "Tmr1 Fosc/4 \n"; put(value.get()); break; case 1: // Fosc if(verbose & 0x4) cout << "Tmr1 Fosc \n"; put(value.get()); break; case 2: // External pin or crystal if(t1con->get_t1oscen()) // External crystal, simulate { if(verbose & 0x4) cout << "Tmr1 External Crystal\n"; put(value.get()); // let TMRL::put() set a cycle counter break point } else // external pin { if(verbose & 0x4) cout << "Tmr1 External Stimuli\n"; if (future_cycle) { // Compute value_16bit with old prescale and ext_scale current_value(); get_cycles().clear_break(this); future_cycle = 0; } prescale = 1 << t1con->get_prescale(); prescale_counter = prescale; set_ext_scale(); m_bExtClkEnabled = true; } break; case 3: // Capacitor sense oscillator if(verbose & 0x4) cout << "Tmr1 Cap. sensing oscillator\n"; if (future_cycle) { // Compute value_16bit with old prescale and ext_scale current_value(); get_cycles().clear_break(this); future_cycle = 0; } prescale = 1 << t1con->get_prescale(); prescale_counter = prescale; set_ext_scale(); break; } } // // clear_timer - This is called by either the CCP or PWM modules to // reset the timer to zero. This is rather easy since the current TMR // value is always referenced to the cpu cycle counter. // void TMRL::clear_timer() { synchronized_cycle = get_cycles().get(); last_cycle = synchronized_cycle; value.put(0); tmrh->value.put(0); if(verbose & 0x4) cout << "TMR1 has been cleared\n"; } // TMRL callback is called when the cycle counter hits the break point that // was set in TMRL::put. The cycle counter will clear the break point, so // we don't need to worry about it. At this point, TMRL is rolling over. void TMRL::callback() { if(verbose & 4) cout << "TMRL::callback\n"; // If TMRL is being clocked by the external clock, then at some point // the simulate code must have switched from the internal clock to // external clock. The cycle break point was still set, so just ignore it. if((t1con->get_tmr1cs() == 2) && ! t1con->get_t1oscen()) { if(verbose & 4) cout << "TMRL:callback No oscillator\n"; value.put(0); tmrh->value.put(0); future_cycle = 0; // indicates that TMRL no longer has a break point return; } current_value(); // Because this relies on future_cycle, we must call it before clearing that future_cycle = 0; // indicate that there's no break currently set if(break_value < 0x10000) { // The break was due to a "compare" if ( value_16bit != break_value ) cout << "TMR1 compare break: value=" << value_16bit << " but break_value=" << break_value << '\n'; if(verbose & 4) cout << "TMR1 break due to compare " << hex << get_cycles().get() << '\n'; for ( TMR1CapComRef * event = compare_queue; event; event = event->next ) { if ( event->value == break_value ) { // This CCP channel has a compare at this time event->ccpcon->compare_match(); } } } else { // The break was due to a roll-over //cout<<"TMRL rollover: " << hex << cycles.get() << '\n'; if (m_Interrupt) m_Interrupt->Trigger(); // Reset the timer to 0. synchronized_cycle = get_cycles().get(); last_cycle = synchronized_cycle; value.put(0); tmrh->value.put(0); } update(); } //--------------------------- void TMRL::callback_print() { cout << "TMRL " << name() << " CallBack ID " << CallBackID << '\n'; } //--------------------------- void TMRL::sleep() { m_sleeping = true; Dprintf(("TMRL::sleep t1sysc %d\n", t1con->get_t1sync())); // If tmr1 is running off Fosc/4 or Fosc this assumes Fosc stops during sleep if ( t1con->get_tmr1on() && t1con->get_tmr1cs() < 2) { if (future_cycle) { current_value(); get_cycles().clear_break(this); future_cycle = 0; } } } //--------------------------- void TMRL::wake() { m_sleeping = false; Dprintf(("TMRL::wake\n")); if ( t1con->get_tmr1on() && t1con->get_tmr1cs() < 2) { update(); } } //-------------------------------------------------- // member functions for the PR2 base class //-------------------------------------------------- PR2::PR2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), tmr2(0) { } void PR2::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); Dprintf(("PR2:: put %x\n", new_value)); if(value.get() != new_value) { if (tmr2) tmr2->new_pr2(new_value); value.put(new_value); } else value.put(new_value); } //-------------------------------------------------- // member functions for the T2CON base class //-------------------------------------------------- T2CON::T2CON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), tmr2(0) { } void T2CON::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); unsigned int diff = value.get() ^ new_value; value.put(new_value); if (tmr2) { tmr2->new_pre_post_scale(); if( diff & TMR2ON) tmr2->on_or_off(value.get() & TMR2ON); } } //-------------------------------------------------- // member functions for the TMR2 base class //-------------------------------------------------- TMR2::TMR2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), pwm_mode(0), update_state(TMR2_ANY_PWM_UPDATE | TMR2_PR2_UPDATE), last_update(0), prescale(1), prescale_counter(0), last_cycle(0), pr2(0), pir_set(0), t2con(0), m_txgcon(0), m_Interrupt(0) { ssp_module[0] = ssp_module[1] = 0; value.put(0); future_cycle = 0; for ( int cc=0; ccrelease(); } void TMR2::callback_print() { cout << "TMR2 " << name() << " CallBack ID " << CallBackID << '\n'; } void TMR2::start() { value.put(0); prescale = 0; last_cycle = 0; future_cycle = 0; } bool TMR2::add_ccp ( CCPCON * _ccp ) { int cc; for ( cc=0; ccaddress ) ) { //cout << "TMR2: pwm mode with ccp1. duty cycle = " << hex << dc << '\n'; duty_cycle[cc] = dc; pwm_mode |= modeMask; return; } modeMask <<= 1; } if ( ! found ) { cout << name() <<": error bad ccpxcon address while in pwm_dc()\n"; cout << "ccp_address = " << ccp_address << " expected one of"; for ( cc=0; ccaddress; cout << '\n'; } } // // stop_pwm // void TMR2::stop_pwm(unsigned int ccp_address) { int modeMask = TMR2_PWM1_UPDATE; int cc; int old_pwm = pwm_mode; for ( cc=0; ccaddress ) ) { // cout << "TMR2: stopping pwm mode with ccp" << cc+1 << ".\n"; pwm_mode &= ~modeMask; if(last_update & modeMask) update_state &= (~modeMask); } modeMask <<= 1; } if((pwm_mode ^ old_pwm) && future_cycle && t2con->get_tmr2on()) update(update_state); } // // update // This member function will determine if/when there is a TMR2 break point // that needs to be set and will set/move it if so. // There are two different types of break sources: // 1) TMR2 matching PR2 // 2) TMR2 matching one of the ccp registers in pwm mode // void TMR2::update(int ut) { int modeMask = TMR2_PWM1_UPDATE; int cc; //cout << "TMR2 update. cpu cycle " << hex << cycles.get() <<'\n'; if(t2con->get_tmr2on()) { if(future_cycle) { // If TMR2 is enabled (i.e. counting) then 'future_cycle' is non-zero, // which means there's a cycle break point set on TMR2 that needs to // be moved to a new cycle. current_value(); // Assume that we are not in pwm mode (and hence the next break will // be due to tmr2 matching pr2) break_value = 1 + pr2->value.get(); guint64 fc = get_cycles().get() + (break_value - value.get()) * prescale; last_update = TMR2_PR2_UPDATE; // RP - I strongly suspect this is now entirely redundant, as I think the // result comes out the same as above. if (pwm_mode) { fc = last_cycle + break_value * prescale; } for ( cc=0; cc (value.get()*4) ) && ( duty_cycle[cc] < break_value*4 ) ) { guint64 nc = last_cycle + ( duty_cycle[cc] * prescale ) / 4; // cout << "TMR2:PWM" << cc+1 << " update at " << hex << nc << // ", dc=" << duty_cycle[cc] << "\n"; if ( nc < fc ) /// @bug not robust against wrap-around of guint64 { last_update = modeMask; fc = nc; } else if ( nc == fc ) { last_update |= modeMask; } } } modeMask <<= 1; } if(fc < future_cycle && verbose & 0x04) cout << "TMR2: update note: new breakpoint=" << hex << fc << " before old breakpoint " << future_cycle << " now " << get_cycles().get() << endl; if (fc != future_cycle) { // cout << "TMR2: update new break at cycle "< TMR2 is still before the next break point. Adjust the breakpoint to occur at correct TMR2 value 2> TMR2 is now greater the PR2 Assume TMR2 must count up to 0xff, roll-over and then we are back in business. High CCP outputs stay high. 3> TMR2 is now less than PR2 but greater than a CCP duty cycle point. The CCP output stays as the duty cycle comparator does not match on this cycle. */ if (now < delta) // easy case, just shift break. { fc = last_cycle + delta; // printf ( " now < delta (0x%X), set future_cycle to 0x%" PRINTF_INT64_MODIFIER "X\n", delta, fc ); get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } else if (now >= break_value * prescale) // TMR2 now greater than PR2 { // set break to when TMR2 will overflow last_update |= TMR2_WRAP; fc = last_cycle + 0x100 * prescale; // printf ( " now > break (0x%X), set future_cycle to 0x%" PRINTF_INT64_MODIFIER "X\n", break_value * prescale, fc ); get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } else // new break < PR2 but > duty cycle break { // printf ( " new break < PR2 but > duty cycle\n" ); update(update_state); } /* 'clear' the post scale counter. (I've actually implemented the post scale counter as a count-down counter, so 'clearing it' means resetting it to the starting point. */ if (t2con) post_scale = t2con->get_post_scale(); } } unsigned int TMR2::get() { if(t2con->get_tmr2on()) { current_value(); } trace.raw(read_trace.get() | value.get()); return(value.get()); } unsigned int TMR2::get_value() { if(t2con->get_tmr2on()) { current_value(); } return(value.get()); } void TMR2::new_pre_post_scale() { //cout << "T2CON was written to, so update TMR2 " << t2con->get_tmr2on() << "\n"; if(!t2con->get_tmr2on()) { // TMR2 is not on. If has just been turned off, clear the callback breakpoint. if(future_cycle) { get_cycles().clear_break(this); future_cycle = 0; } return; } unsigned int old_prescale = prescale; prescale = t2con->get_pre_scale(); post_scale = t2con->get_post_scale(); if(future_cycle) { // If TMR2 is enabled (i.e. counting) then 'future_cycle' is non-zero, // which means there's a cycle break point set on TMR2 that needs to // be moved to a new cycle. if (prescale != old_prescale) // prescaler value change { // togo is number of cycles to next callback based on new prescaler. guint64 togo = (future_cycle - get_cycles().get()) * prescale / old_prescale; if (!togo) // I am not sure this can happen RRR callback(); else { guint64 fc = togo + get_cycles().get(); get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } } } else { //cout << "TMR2 was off, but now it's on.\n"; if (value.get() == pr2->value.get()) // TMR2 == PR2 { future_cycle = get_cycles().get(); get_cycles().set_break(future_cycle, this); callback(); } else if (value.get() > pr2->value.get()) // TMR2 > PR2 { cout << "Warning TMR2 turned on with TMR2 greater than PR2\n"; // this will cause TMR2 to wrap future_cycle = get_cycles().get() + (1 + pr2->value.get() + (0x100 - value.get())) * prescale; get_cycles().set_break(future_cycle, this); } else { future_cycle = get_cycles().get() + 1; get_cycles().set_break(future_cycle, this); last_cycle = get_cycles().get() - value.get(); update(update_state); } } } void TMR2::new_pr2(unsigned int new_value) { Dprintf(("TMR2::new_pr2 on=%u\n", t2con->get_tmr2on())); if(t2con->get_tmr2on()) { Dprintf(( "TMR2::new_pr2(0x%02X) with timer at 0x%02X -\n", new_value, value.get() )); unsigned int cur_break = (future_cycle - last_cycle)/prescale; unsigned int new_break = 1 + new_value; unsigned int now_cycle = (get_cycles().get() - last_cycle) / prescale; guint64 fc = last_cycle; Dprintf(( " cur_break = 0x%X, new_break = 0x%X, now = 0x%X\n", cur_break, new_break, now_cycle )); Dprintf(( " last_cycle = 0x%" PRINTF_GINT64_MODIFIER "X\n", fc )); /* PR2 change cases 1> TMR2 greater than new PR2 TMR2 wraps through 0xff 2> New PR2 breakpoint less than current breakpoint or current break point due to PR2 Change breakpoint to new value based on PR2 3> Other breakpoint < PR2 breakpoint No need to do anything. */ if (now_cycle > new_break) // TMR2 > PR2 do wrap { // set break to when TMR2 will overflow last_update |= TMR2_WRAP; fc += 0x100 * prescale; Dprintf(( " now > new, set future_cycle to 0x%" PRINTF_GINT64_MODIFIER "X\n", fc )); get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } else if (cur_break == break_value || // breakpoint due to pr2 new_break < cur_break) // new break less than current { fc += new_break * prescale; Dprintf(( " new= max_counts()) // Can get to max_counts during transition { cerr << "TMR2 BUG!! value = 0x" << tmr2_val << " which is greater than 0x"; cerr << max_counts() << endl; } } // TMR2 callback is called when the cycle counter hits the break point that // was set in TMR2::put. The cycle counter will clear the break point, so // we don't need to worry about it. At this point, TMR2 is equal to PR2. void TMR2::callback() { int cc; //cout<<"TMR2 callback cycle: " << hex << cycles.value << '\n'; // If tmr2 is still enabled, then set up for the next break. // If tmr2 was disabled then ignore this break point. if(t2con->get_tmr2on()) { // What caused the callback: PR2 match or duty cyle match ? if (last_update & TMR2_WRAP) // TMR2 > PR2 { last_update &= ~TMR2_WRAP; // This (implicitly) resets the timer to zero: last_cycle = get_cycles().get(); } else if ( last_update & TMR2_ANY_PWM_UPDATE ) { int modeMask = TMR2_PWM1_UPDATE; for ( cc=0; ccpwm_match(0); else cout << "TMR2::callback() found update of non-existent CCP\n"; } modeMask <<= 1; } } else { // matches PR2 //cout << "TMR2: PR2 match. pwm_mode is " << pwm_mode <<'\n'; // This (implicitly) resets the timer to zero: last_cycle = get_cycles().get(); if (ssp_module[0]) ssp_module[0]->tmr2_clock(); if (ssp_module[1]) ssp_module[1]->tmr2_clock(); if (m_txgcon) // toggle T2_gate, if present { m_txgcon->T2_gate(1); m_txgcon->T2_gate(0); } for ( cc=0; ccvalue.get() & (CCPCON::PWM0 | CCPCON::PWM1 ))) { ccp[cc]->pwm_match(1); } } if(--post_scale < 0) { //cout << "setting IF\n"; if (pir_set) pir_set->set_tmr2if(); else if (m_Interrupt) // for multiple T2 (T2, T4, T6) m_Interrupt->Trigger(); post_scale = t2con->get_post_scale(); } update_state = TMR2_ANY_PWM_UPDATE | TMR2_PR2_UPDATE; } update(update_state); } else future_cycle = 0; } //------------------------------------------------------------------------ // TMR2_MODULE // // TMR2_MODULE::TMR2_MODULE() { t2con = 0; pr2 = 0; tmr2 = 0; cpu = 0; name_str = 0; } void TMR2_MODULE::initialize(T2CON *t2con_, PR2 *pr2_, TMR2 *tmr2_) { t2con = t2con_; pr2 = pr2_; tmr2 = tmr2_; } //-------------------------------------------------- // //-------------------------------------------------- class INT_SignalSink : public SignalSink { public: INT_SignalSink(ECCPAS *_eccpas, int _index) : m_eccpas(_eccpas), m_index(_index) { assert(_eccpas); } virtual void release() { delete this; } void setSinkState(char new3State) { m_eccpas->set_trig_state( m_index, new3State=='0' || new3State=='w'); } private: ECCPAS *m_eccpas; int m_index; }; //-------------------------------------------------- // ECCPAS //-------------------------------------------------- ECCPAS::ECCPAS(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), pwm1con(0), ccp1con(0), m_PinModule(0) { trig_state[0] = trig_state[1] = trig_state[2] = false; mValidBits = 0xff; } ECCPAS::~ECCPAS() { } void ECCPAS::link_registers(PWM1CON *_pwm1con, CCPCON *_ccp1con) { pwm1con = _pwm1con; ccp1con = _ccp1con; } void ECCPAS::put(unsigned int new_value) { Dprintf(("ECCPAS::put() new_value=0x%x\n",new_value)); trace.raw(write_trace.get() | value.get()); put_value(new_value); } void ECCPAS::put_value(unsigned int new_value) { int old_value = value.get(); new_value &= mValidBits; // Auto-shutdown trigger active // make sure ECCPASE is set // if change in shutdown status, drive bridge outputs as per current flags if (shutdown_trigger(new_value)) { new_value |= ECCPASE; if ((new_value ^ old_value) & (ECCPASE|PSSAC1|PSSAC0|PSSBD1|PSSBD0)) ccp1con->shutdown_bridge(new_value); } else // no Auto-shutdown triggers active { if (pwm1con->value.get() & PWM1CON::PRSEN) // clear ECCPASE bit new_value &= ~ ECCPASE; } value.put(new_value); } // Return true is shutdown trigger is active bool ECCPAS::shutdown_trigger(int key) { if ((key & ECCPAS0) && trig_state[0]) return true; if ((key & ECCPAS1) && trig_state[1]) return true; if ((key & ECCPAS2) && trig_state[2]) return true; return false; } // connect IO pins to shutdown trigger source void ECCPAS::setIOpin(PinModule *p0, PinModule *p1, PinModule *p2) { if (p0) { m_PinModule = p0; m_sink = new INT_SignalSink(this, 0); p0->addSink(m_sink); } if (p1) { m_PinModule = p1; m_sink = new INT_SignalSink(this, 1); p1->addSink(m_sink); } if (p2) { m_PinModule = p2; m_sink = new INT_SignalSink(this, 2); p2->addSink(m_sink); } } // set shutdown trigger states void ECCPAS::set_trig_state(int index, bool state) { if (trig_state[index] != state) { Dprintf(("index=%d state=%d old=%d\n", index, state, trig_state[index])); trig_state[index] = state; put_value(value.get()); } } // Trigger state from comparator 1 void ECCPAS::c1_output(int state) { set_trig_state(0, state); } // Trigger state from comparator 2 void ECCPAS::c2_output(int state) { set_trig_state(1, state); } //-------------------------------------------------- // PWM1CON //-------------------------------------------------- PWM1CON::PWM1CON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { mValidBits = 0xff; } PWM1CON::~PWM1CON() { } void PWM1CON::put(unsigned int new_value) { new_value &= mValidBits; Dprintf(("PWM1CON::put() new_value=0x%x\n",new_value)); trace.raw(write_trace.get() | value.get()); value.put(new_value); } //-------------------------------------------------- // PSTRCON //-------------------------------------------------- PSTRCON::PSTRCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } PSTRCON::~PSTRCON() { } void PSTRCON::put(unsigned int new_value) { Dprintf(("PSTRCON::put() new_value=0x%x\n",new_value)); new_value &= STRSYNC|STRD|STRC|STRB|STRA; trace.raw(write_trace.get() | value.get()); value.put(new_value); } gpsim-0.30.0/src/pir.cc0000664000076400007640000003375313103351646011551 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include "trace.h" #include "pir.h" #include "intcon.h" #include "processor.h" PIR::PIR(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie, int _valid_bits) : sfr_register(pCpu,pName,pDesc), intcon(_intcon),pie(_pie),ipr(0),valid_bits(_valid_bits),writable_bits(0) { } void PIR::put(unsigned int new_value) { // Only the "writable bits" can be written with put. // The "read-only" ones (such as TXIF) are written // through the set_/clear_ member functions. trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); value.put((new_value & writable_bits) | (value.get() & ~writable_bits)); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR::set_intcon(INTCON *_intcon) { intcon = _intcon; } void PIR::set_pie(PIE *_pie) { pie = _pie; } void PIR::set_ipr(sfr_register *_ipr) { ipr = _ipr; } void PIR::setInterrupt(unsigned int bitMask) { value.put(value.get() | bitMask); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR::setPeripheralInterrupt() { if (intcon) intcon->peripheral_interrupt ( ipr && (value.get() & valid_bits & ipr->value.get() & pie->value.get()) ); } int PIR::interrupt_status() { assert(pie); if ( ipr ) { int result = 0; if ( value.get() & valid_bits & pie->value.get() & ~(ipr->value.get()) ) result |= 1; if ( value.get() & valid_bits & pie->value.get() & ipr->value.get() ) result |= 2; return result; } else return ( value.get() & valid_bits & pie->value.get() ) ? 1 : 0; } //======================================================================== InterruptSource::InterruptSource(PIR *_pir, unsigned int bitMask) : m_pir(_pir), m_bitMask(bitMask) { assert(m_pir); // Only one bit in the bit mask should be set. assert(m_bitMask && ((m_bitMask & (m_bitMask-1)) == 0)); } void InterruptSource::Trigger() { m_pir->setInterrupt(m_bitMask); } void InterruptSource::Clear() { m_pir->value.put(m_pir->value.get() & ~m_bitMask); } void InterruptSource::release() { delete this; } //------------------------------------------------------------------------ PIR1v1::PIR1v1(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { // Even though TXIF is a valid bit, it can't be written by the PIC // source code. Its state reflects whether the usart txreg is full // or not. Similarly for RCIF valid_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | TXIF | RCIF | CMIF | EEIF; writable_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | CMIF | EEIF; } void PIR1v1::clear_sspif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~SSPIF); } void PIR1v1::set_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TXIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v1::clear_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~TXIF); } void PIR1v1::set_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | RCIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v1::clear_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~RCIF); } void PIR1v1::set_cmif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CMIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v1::set_eeif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } //------------------------------------------------------------------------ // PIR1v2::PIR1v2(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { // Even though TXIF is a valid bit, it can't be written by the PIC // source code. Its state reflects whether the usart txreg is full // or not. Similarly for RCIF valid_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | TXIF | RCIF | ADIF | PSPIF; writable_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | ADIF | PSPIF; } void PIR1v2::clear_sspif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~SSPIF); } void PIR1v2::set_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TXIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v2::set_pspif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | PSPIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v2::set_sppif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | SPPIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v2::set_sspif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | SSPIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v2::clear_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~TXIF); } void PIR1v2::set_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | RCIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v2::clear_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~RCIF); } //------------------------------------------------------------------------ PIR1v3::PIR1v3(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = TMR1IF | ADIF | CMIF | EEIF; writable_bits = TMR1IF | ADIF | CMIF | EEIF; } void PIR1v3::set_tmr1if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TMR1IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v3::set_tmr2if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TMR2IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v3::set_cmif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CMIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v3::set_eeif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v3::set_adif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | ADIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v3::set_c1if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C1IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v3::set_c2if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C2IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } //------------------------------------------------------------------------ PIR1v4::PIR1v4(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { writable_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | ADIF | EEIF; valid_bits = 0xff; } void PIR1v4::set_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TXIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v4::clear_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~TXIF); } void PIR1v4::set_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | RCIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR1v4::clear_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~RCIF); } //------------------------------------------------------------------------ PIR2v1::PIR2v1(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = CCP2IF; writable_bits = valid_bits; } //------------------------------------------------------------------------ PIR2v2::PIR2v2(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = ECCP1IF | TMR3IF | LVDIF | BCLIF | EEIF | CMIF; writable_bits = valid_bits; } void PIR2v2::set_cmif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CMIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v2::set_eeif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v2::set_bclif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | BCLIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } //------------------------------------------------------------------------ PIR2v3::PIR2v3(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = CCP2IF | ULPWUIF | BCLIF | EEIF | C1IF | C2IF | OSFIF; writable_bits = valid_bits; } void PIR2v3::set_c1if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C1IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v3::set_c2if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C2IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v3::set_eeif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v3::set_bclif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | BCLIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } PIR2v4::PIR2v4(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = OSCFIF | CMIF | USBIF | EEIF | BCLIF | HLVDIF | TMR3IF | CCP2IF; writable_bits = valid_bits; } void PIR2v4::set_usbif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | USBIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v4::set_cmif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CMIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v4::set_eeif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR2v4::set_bclif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | BCLIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } PIR2v5::PIR2v5(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = OSFIF | LVDIF | LCDIF | C1IF | C2IF |CCP2IF; writable_bits = valid_bits; } //------------------------------------------------------------------------ PIR3v1::PIR3v1(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { // Even though TXIF is a valid bit, it can't be written by the PIC // source code. Its state reflects whether the usart txreg is full // or not. Similarly for RCIF valid_bits = CCP3IF | CCP4IF | CCP5IF | TMR4IF | TXIF | RCIF; writable_bits = CCP3IF | CCP4IF | CCP5IF | TMR4IF; } void PIR3v1::set_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TXIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR3v1::clear_txif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~TXIF); } void PIR3v1::set_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | RCIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void PIR3v1::clear_rcif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~RCIF); } //------------------------------------------------------------------------ PIR3v2::PIR3v2(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = RXB0IF | RXB1IF | TXB0IF | TXB1IF | TXB2IF | ERRIF | WAKIF | IRXIF; writable_bits = valid_bits; } PIR3v3::PIR3v3(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = TMR3GIF | TMR5GIF | TMR1GIF | CTMUIF | TX2IF | RC2IF | BCL2IF | SSP2IF; writable_bits = valid_bits; } PIR4v1::PIR4v1(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = CCP3IF | CCP4IF | CCP5IF ; writable_bits = CCP3IF | CCP4IF | CCP5IF; } PIR5v1::PIR5v1(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = TMR4IF | TMR5IF | TMR6IF ; writable_bits = TMR4IF | TMR5IF | TMR6IF ; } gpsim-0.30.0/src/modules.cc0000664000076400007640000003270513114656747012437 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "modules.h" #include #include #include #include #include #include #include #include #include "../config.h" #ifndef _WIN32 #include #if !defined(_MAX_PATH) #define _MAX_PATH 1024 #endif #include // for getcwd #else #include #include /* * interface is a Module class member variable in gpsim, * in WIN32 Platform SDK it is a macro, defined in BaseTypes.h * the WIN32 Platform SDK definition should be undefined */ #undef interface #endif #include "pic-processor.h" #include "stimuli.h" #include "symbol.h" #include "xref.h" #include "value.h" #include "packages.h" #include "cmd_manager.h" // When a new library is loaded, all of the module types // it supports are placed into the ModuleTypes map. This // object is private to this file. typedef map ModuleTypeInfo_t; ModuleTypeInfo_t ModuleTypes; //------------------------------------------------------------------------ // Add a new type to the ModuleTypes map if the name for that type // does not exist already. static void AddModuleType(const char *pName, Module_Types *pType) { string sName(pName); ModuleTypeInfo_t::iterator mti = ModuleTypes.find(sName); if (mti == ModuleTypes.end()) ModuleTypes[sName] = pType; } DynamicModuleLibraryInfo::DynamicModuleLibraryInfo(string &sCanonicalName, string &sUserSuppliedName, void *pHandle) : m_sCanonicalName(sCanonicalName), m_sUserSuppliedName(sUserSuppliedName), m_pHandle(pHandle), get_mod_list(0) { const char * error; if (m_pHandle) get_mod_list = (Module_Types_FPTR)get_library_export("get_mod_list", m_pHandle, &error); if (!get_mod_list) { cout << "WARNING: non-conforming module library\n" << " gpsim libraries should have the get_mod_list() function defined\n"; fprintf(stderr, "%s\n",error); free_error_message(error); } else { // Get a pointer to the list of modules that this library file supports. Module_Types *pLibModList = get_mod_list(); // Loop through the list of modules supported by the library and an entry // ModuleTypes map for each one. if(pLibModList) for(Module_Types *pModTypes = pLibModList; pModTypes->names[0]; pModTypes++) { AddModuleType(pModTypes->names[0], pModTypes); AddModuleType(pModTypes->names[1], pModTypes); } // If the module has an "initialize" function, then call it now. typedef void * (*void_FPTR)(void); void * (*initialize)(void) = (void_FPTR)get_library_export("initialize", m_pHandle, NULL); if(initialize) initialize(); /* ICommandHandler * pCliHandler = ml->GetCli(); if (pCliHandler != NULL) CCommandManager::GetManager().Register(pCliHandler); */ } } ModuleLibraries_t ModuleLibraries; //======================================================================== void MakeCanonicalName(string &sPath, string &sName) { #ifdef _WIN32 sName = sPath; #else GetFileName(sPath, sName); #endif } int ModuleLibrary::LoadFile(string &fName) { void *handle; const char *pszError; bool bReturn = false; string sPath= fName; FixupLibraryName(sPath); string sName; MakeCanonicalName(sPath, sName); ModuleLibraries_t::iterator mli = ModuleLibraries.find(sName); if (mli == ModuleLibraries.end()) { if ((handle = ::load_library(sPath.c_str(), &pszError)) == NULL) { #ifdef THROW ostringstream stream; stream << "failed to open library module "; stream << sPath; stream << ": "; stream << pszError; stream << endl; char cw[_MAX_PATH]; getcwd(cw, sizeof(cw)); stream << "current working directory is "; stream << cw; stream << endl << ends; free_error_message(pszError); throw new Error(stream.str()); #endif //THROW } else { ModuleLibraries[sName] = new DynamicModuleLibraryInfo(fName, sName, handle); bReturn = true; } } /* if(verbose) DisplayFileList(); */ return bReturn; } int ModuleLibrary::InstantiateObject(string &sObjectName, string &sInstantiatedName) { ModuleTypeInfo_t::iterator mti = ModuleTypes.find(sObjectName); if (mti != ModuleTypes.end()) { Module *pModule = mti->second->module_constructor(sInstantiatedName.c_str()); pModule->set_module_type(sObjectName); globalSymbolTable().addModule(pModule); // Tell the gui or any modules that are interfaced to gpsim // that a new module has been added. gi.new_module(pModule); return pModule!=0; } return 0; } void ModuleLibrary::ListLoadableModules() { ModuleTypeInfo_t::iterator mti = ModuleTypes.begin(); while (mti != ModuleTypes.end()) { cout << " " << mti->first << endl; ++mti; } } /***************************************************************************** * * Module.cc * * Here's where much of the infrastructure of gpsim is defined. * * A Module is define to be something that gpsim knows how to simulate. * When gpsim was originally designed, a module was simple a pic processor. * This concept was expanded to accomodate devices like LEDs, switches, * LCDs and so on. */ Module::Module(const char *_name, const char *desc) : gpsimObject(_name, desc), package(0), interface(0), simulation_mode(eSM_STOPPED), widget(0), Vdd(5.0), version(0) { xref = new XrefObject; if (_name) { // If there is a module symbol already with this // name, then print a warning before deleting. gpsimObject *pOldModule = globalSymbolTable().find(name()); if (pOldModule) { cout << "Warning: There already is a symbol in the symbol table named " << _name << endl; return; } } globalSymbolTable().addModule(this); // Create position attribute place holders if we're not using the gui if(!get_interface().bUsingGUI()) { addSymbol(new Float("xpos",80.0)); addSymbol(new Float("ypos",80.0)); } } #if 0 // warning: 'void dumpOneSymbol(const SymbolEntry_t&)' defined but not used static void dumpOneSymbol(const SymbolEntry_t &sym) { cout << " " << sym.second << " stored as " << sym.first << endl; } #endif Module::~Module(void) { map::iterator si; for (si = m_scripts.begin(); si != m_scripts.end(); ++si) { ModuleScript *pMS = (*si).second; delete pMS; } m_scripts.clear(); deleteSymbol("xpos"); deleteSymbol("ypos"); /* cout << "Stuff still in the symbol table:\n"; mSymbolTable.ForEachSymbolTable(dumpOneSymbol); */ delete package; delete xref; package = 0; xref = 0; globalSymbolTable().removeModule(this); } void Module::reset(RESET_TYPE r) { cout << " resetting module " << name() << endl; } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::addSymbol(gpsimObject *pSym, string *ps_AliasedName) { return mSymbolTable.addSymbol(pSym, ps_AliasedName); } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::removeSymbol(gpsimObject *pSym) { return mSymbolTable.removeSymbol(pSym); } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::removeSymbol(const string &s) { return mSymbolTable.removeSymbol(s); } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::deleteSymbol(const string &s) { return mSymbolTable.deleteSymbol(s); } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::deleteSymbol(gpsimObject *pSym) { if (!pSym) return 0; if (!removeSymbol(pSym)) return 0; delete pSym; return 1; } //------------------------------------------------------------------- //------------------------------------------------------------------- gpsimObject *Module::findSymbol(const string &searchString) { return mSymbolTable.findSymbol(searchString); } //------------------------------------------------------------------- //------------------------------------------------------------------- void Module::create_pkg(unsigned int number_of_pins) { if(package) delete package; package = new Package(number_of_pins); } //------------------------------------------------------------------- //------------------------------------------------------------------- void Module::assign_pin(unsigned int pin_number, IOPIN *pin) { if(package) package->assign_pin(pin_number, pin); } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::get_pin_count(void) { if(package) return package->get_pin_count(); return 0; } //------------------------------------------------------------------- //------------------------------------------------------------------- string &Module::get_pin_name(unsigned int pin_number) { static string invalid(""); if(package) return package->get_pin_name(pin_number); return invalid; //FIXME } //------------------------------------------------------------------- //------------------------------------------------------------------- int Module::get_pin_state(unsigned int pin_number) { if(package) return package->get_pin_state(pin_number); return 0; } //------------------------------------------------------------------- //------------------------------------------------------------------- IOPIN *Module::get_pin(unsigned int pin_number) { if(package) return package->get_pin(pin_number); return 0; } //------------------------------------------------------------------- // Module Scripts // // Module command line scripts are named scripts created by symbol // files. For example, with PIC cod files, it's possible to // create assertions and simulation commands using the '.assert' // and '.sim' directives. These commands are ASCII strings that // are collected together. // //------------------------------------------------------------------- // Module::add_command // // Add a command line command to a Module Script. //------------------------------------------------------------------- void Module::add_command(string &script_name, string &command) { ModuleScript *script = m_scripts[script_name]; if (!script) { script = new ModuleScript(script_name); m_scripts[script_name] = script; } script->add_command(command); } //------------------------------------------------------------------- // Module::run_script - execute a gpsim command line script // //------------------------------------------------------------------- void Module::run_script(string &script_name) { ModuleScript *script = m_scripts[script_name]; if (script) { ICommandHandler *pCli = CCommandManager::GetManager().find("gpsimCLI"); if(pCli) { script->run(pCli); } } } //------------------------------------------------------------------- //------------------------------------------------------------------- Module::ModuleScript::ModuleScript(string &name_) : name(name_) { } //------------------------------------------------------------------- //------------------------------------------------------------------- Module::ModuleScript::~ModuleScript() { list :: iterator command_iterator; for (command_iterator = m_commands.begin(); command_iterator != m_commands.end(); ++command_iterator) delete *command_iterator; m_commands.clear(); } //------------------------------------------------------------------- //------------------------------------------------------------------- void Module::ModuleScript::add_command(string &command) { string *new_command = new string(command); m_commands.push_back(new_command); } //------------------------------------------------------------------- //------------------------------------------------------------------- void Module::ModuleScript::run(ICommandHandler *pCommandHandler) { if (!pCommandHandler) return; pCommandHandler->ExecuteScript(m_commands,0); } //------------------------------------------------------------------- //------------------------------------------------------------------- void Module::ModuleScript::concatenate(ModuleScript *pOtherScript) { if (!pOtherScript) return; list :: iterator command_iterator; for (command_iterator = pOtherScript->m_commands.begin(); command_iterator != pOtherScript->m_commands.end(); ++command_iterator) m_commands.push_back(*command_iterator); } gpsim-0.30.0/src/pthread-wrap.h0000664000076400007640000000241713041763613013212 00000000000000 /* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__PTHREAD_WRAP_H__) #define __PTHREAD_WRAP_H__ #include namespace gpsim { /// ThreadWrapper /// a private implementation of pthread variables for the /// Token class. This is not intended to be used directly /// by modules. struct ThreadWrapper { /// pthread variables. pthread_t thHostInterface; pthread_attr_t thAttribute; pthread_mutex_t mutex; pthread_cond_t cvWaitOnParent; pthread_cond_t cvWaitOnChild; }; } // end of namespace gpsim #endif // !defined(__PTHREAD_WRAP_H__) gpsim-0.30.0/src/12bit-instructions.h0000664000076400007640000003204513041763624014301 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __12BIT_INSTRUCTIONS_H__ #define __12BIT_INSTRUCTIONS_H__ #include "pic-instructions.h" //--------------------------------------------------------- class ADDWF : public Register_op { public: ADDWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ADDWF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ANDLW : public Literal_op { public: ANDLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ANDLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ANDWF : public Register_op { public: ANDWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ANDWF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BCF : public Bit_op { public: BCF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode,unsigned int address) {return new BCF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BSF : public Bit_op { public: BSF(Processor *new_cpu, unsigned int new_opcode,unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode,unsigned int address) {return new BSF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BTFSC : public Bit_op { public: BTFSC(Processor *new_cpu, unsigned int new_opcode,unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode,unsigned int address) {return new BTFSC(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BTFSS : public Bit_op { public: BTFSS(Processor *new_cpu, unsigned int new_opcode,unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode,unsigned int address) {return new BTFSS(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CALL : public instruction { public: unsigned int destination; CALL(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *str,int len); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CALL(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CLRF : public Register_op { public: CLRF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *str,int len); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CLRF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CLRW : public instruction { public: CLRW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CLRW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CLRWDT : public instruction { public: CLRWDT(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CLRWDT(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class COMF : public Register_op { public: COMF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new COMF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class DECF : public Register_op { public: DECF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new DECF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class DECFSZ : public Register_op { public: DECFSZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new DECFSZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class GOTO : public instruction { public: unsigned int destination; GOTO(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} virtual char *name(char *str,int len); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new GOTO(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class INCF : public Register_op { public: INCF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new INCF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class INCFSZ : public Register_op { public: INCFSZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new INCFSZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class IORLW : public Literal_op { public: IORLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new IORLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class IORWF : public Register_op { public: IORWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new IORWF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVF : public Register_op { public: MOVF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual void debug(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVLW : public Literal_op { public: MOVLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVWF : public Register_op { public: MOVWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *str,int len); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVWF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class NOP : public instruction { public: NOP(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new NOP(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class OPTION : public instruction { public: OPTION(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new OPTION(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RETLW : public Literal_op { public: RETLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RETLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RLF : public Register_op { public: RLF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RLF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RRF : public Register_op { public: RRF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RRF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SLEEP : public instruction { public: SLEEP(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SLEEP(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBWF : public Register_op { public: SUBWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBWF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SWAPF : public Register_op { public: SWAPF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SWAPF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class TRIS : public Register_op { public: Register *reg; TRIS(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *str,int len); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new TRIS(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class XORLW : public Literal_op { public: XORLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new XORLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class XORWF : public Register_op { public: XORWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new XORWF(new_cpu,new_opcode,address);} }; #endif /* __12BIT_INSTRUCTIONS_H__ */ gpsim-0.30.0/src/14bit-hexdecode.cc0000664000076400007640000001172713041763613013627 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2013 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // T. Scott Dattalo 14bit core routines // Portions of this file are from: // /* pic14.c - pic 14bit core routines */ /* version 0.1 */ /* (c) I.King 1994 */ #include #include "../config.h" #include "14bit-processors.h" #include "14bit-instructions.h" struct instruction_constructor op_16ext[] = { { 0x3f80, 0x3100, ADDFSR::construct }, { 0x3f00, 0x3d00, ADDWFC::construct }, { 0x3f00, 0x3700, ASRF::construct }, { 0x3e00, 0x3200, BRA::construct }, { 0x3fff, 0x000b, BRW::construct }, { 0x3fff, 0x000a, CALLW::construct }, { 0x3ff8, 0x0010, MOVIW::construct }, { 0x3f80, 0x3f00, MOVIW::construct }, { 0x3fe0, 0x0020, MOVLB::construct }, { 0x3f80, 0x3180, MOVLP::construct }, { 0x3ff8, 0x0018, MOVWI::construct }, { 0x3f80, 0x3f80, MOVWI::construct }, { 0x3f00, 0x3500, LSLF::construct }, { 0x3f00, 0x3600, LSRF::construct }, { 0x3fff, 0x0001, RESET::construct }, { 0x3f00, 0x3b00, SUBWFB::construct }, }; struct instruction_constructor op_16cxx[] = { { 0x3f00, 0x3e00, ADDLW::construct }, { 0x3f00, 0x3f00, ADDLW::construct }, // Accomdate don't care bit { 0x3f00, 0x0700, ADDWF::construct }, { 0x3f00, 0x3900, ANDLW::construct }, { 0x3f00, 0x0500, ANDWF::construct }, { 0x3c00, 0x1000, BCF::construct }, { 0x3c00, 0x1400, BSF::construct }, { 0x3c00, 0x1800, BTFSC::construct }, { 0x3c00, 0x1c00, BTFSS::construct }, { 0x3800, 0x2000, CALL::construct }, { 0x3f80, 0x0180, CLRF::construct }, { 0x3fff, 0x0103, CLRW::construct }, { 0x3fff, 0x0064, CLRWDT::construct }, { 0x3f00, 0x0900, COMF::construct }, { 0x3f00, 0x0300, DECF::construct }, { 0x3f00, 0x0b00, DECFSZ::construct }, { 0x3800, 0x2800, GOTO::construct }, { 0x3f00, 0x0a00, INCF::construct }, { 0x3f00, 0x0f00, INCFSZ::construct }, { 0x3f00, 0x3800, IORLW::construct }, { 0x3f00, 0x0400, IORWF::construct }, { 0x3f00, 0x0800, MOVF::construct }, { 0x3f00, 0x3000, MOVLW::construct }, { 0x3f00, 0x3100, MOVLW::construct }, { 0x3f00, 0x3200, MOVLW::construct }, { 0x3f00, 0x3300, MOVLW::construct }, { 0x3f80, 0x0080, MOVWF::construct }, { 0x3fff, 0x0000, NOP::construct }, { 0x3fff, 0x0020, NOP::construct }, { 0x3fff, 0x0040, NOP::construct }, { 0x3fff, 0x0060, NOP::construct }, { 0x3fff, 0x0062, OPTION::construct }, { 0x3fff, 0x0009, RETFIE::construct }, { 0x3f00, 0x3400, RETLW::construct }, { 0x3f00, 0x3500, RETLW::construct }, { 0x3f00, 0x3600, RETLW::construct }, { 0x3f00, 0x3700, RETLW::construct }, { 0x3fff, 0x0008, RETURN::construct }, { 0x3f00, 0x0d00, RLF::construct }, { 0x3f00, 0x0c00, RRF::construct }, { 0x3fff, 0x0063, SLEEP::construct }, { 0x3f00, 0x3c00, SUBLW::construct }, { 0x3f00, 0x3d00, SUBLW::construct }, { 0x3f00, 0x0200, SUBWF::construct }, { 0x3fff, 0x0065, TRIS::construct }, { 0x3fff, 0x0066, TRIS::construct }, { 0x3fff, 0x0067, TRIS::construct }, { 0x3f00, 0x0e00, SWAPF::construct }, { 0x3f00, 0x3a00, XORLW::construct }, { 0x3f00, 0x0600, XORWF::construct }, }; const int NUM_OP_16CXX = sizeof(op_16cxx) / sizeof(op_16cxx[0]); const int NUM_OP_16EXT = sizeof(op_16ext) / sizeof(op_16ext[0]); instruction * disasm14 (_14bit_processor *cpu, unsigned int addr, unsigned int inst) { instruction *pi; pi = 0; for(int i =0; i. */ #include #include #include #include "symbol.h" #include "../config.h" #include "p17c75x.h" #if 0 void _68pins::create_iopin_map(void) { // ---- This is probably going to be moved: porta = new PORTA; portb = new PORTB; portc = new PORTC; portd = new PORTD; porte = new PORTE; portf = new PORTF; portg = new PORTG; if(verbose) cout << "Create i/o pin map\n"; // Build the links between the I/O Ports and their tris registers. porta->tris = &ddra; portb->tris = &ddrb; ddrb.port = portb; portc->tris = &ddrc; ddrc.port = portc; portd->tris = &ddrd; ddrd.port = portd; porte->tris = &ddre; ddre.port = porte; portf->tris = &ddrf; ddrf.port = portf; portg->tris = &ddrg; ddrg.port = portg; // And give them a more meaningful name. ddrb.new_name("ddrb"); ddrc.new_name("ddrc"); ddrd.new_name("ddrd"); ddre.new_name("ddre"); ddrf.new_name("ddrf"); ddrg.new_name("ddrg"); // Define the valid I/O pins. porta->valid_iopins = 0x3f; portb->valid_iopins = 0xff; portc->valid_iopins = 0xff; portd->valid_iopins = 0xff; porte->valid_iopins = 0x0f; portf->valid_iopins = 0xff; portg->valid_iopins = 0xff; // Now Create the package and place the I/O pins create_pkg(68); // Vdd and Vss pins assign_pin(2, 0); assign_pin(20, 0); assign_pin(37, 0); assign_pin(49, 0); assign_pin(19, 0); assign_pin(36, 0); assign_pin(53, 0); assign_pin(68, 0); // AVdd and AVss pins assign_pin(29, 0); assign_pin(30, 0); // NC pins assign_pin(1, 0); assign_pin(18, 0); assign_pin(35, 0); assign_pin(52, 0); // Test pin assign_pin(17, 0); // Reset pin assign_pin(16, 0); // Oscillator pins assign_pin(50, 0); assign_pin(51, 0); assign_pin(60, new IOPIN(porta, 0)); assign_pin(44, new IOPIN(porta, 1)); assign_pin(45, new IO_bi_directional_pu(porta, 2)); assign_pin(46, new IO_bi_directional_pu(porta, 3)); assign_pin(43, new IO_bi_directional(porta, 4)); assign_pin(42, new IO_bi_directional(porta, 5)); assign_pin(59, new IO_bi_directional(portb, 0)); assign_pin(58, new IO_bi_directional(portb, 1)); assign_pin(54, new IO_bi_directional(portb, 2)); assign_pin(57, new IO_bi_directional(portb, 3)); assign_pin(56, new IO_bi_directional(portb, 4)); assign_pin(55, new IO_bi_directional(portb, 5)); assign_pin(47, new IO_bi_directional(portb, 6)); assign_pin(48, new IO_bi_directional(portb, 7)); assign_pin(3, new IO_bi_directional(portc, 0)); assign_pin(67, new IO_bi_directional(portc, 1)); assign_pin(66, new IO_bi_directional(portc, 2)); assign_pin(65, new IO_bi_directional(portc, 3)); assign_pin(64, new IO_bi_directional(portc, 4)); assign_pin(63, new IO_bi_directional(portc, 5)); assign_pin(62, new IO_bi_directional(portc, 6)); assign_pin(61, new IO_bi_directional(portc, 7)); assign_pin(11, new IO_bi_directional(portd, 0)); assign_pin(10, new IO_bi_directional(portd, 1)); assign_pin(9, new IO_bi_directional(portd, 2)); assign_pin(8, new IO_bi_directional(portd, 3)); assign_pin(7, new IO_bi_directional(portd, 4)); assign_pin(6, new IO_bi_directional(portd, 5)); assign_pin(5, new IO_bi_directional(portd, 6)); assign_pin(4, new IO_bi_directional(portd, 7)); assign_pin(12, new IO_bi_directional(porte, 0)); assign_pin(13, new IO_bi_directional(porte, 1)); assign_pin(14, new IO_bi_directional(porte, 2)); assign_pin(15, new IO_bi_directional(porte, 3)); assign_pin(28, new IO_bi_directional(portf, 0)); assign_pin(27, new IO_bi_directional(portf, 1)); assign_pin(26, new IO_bi_directional(portf, 2)); assign_pin(25, new IO_bi_directional(portf, 3)); assign_pin(24, new IO_bi_directional(portf, 4)); assign_pin(23, new IO_bi_directional(portf, 5)); assign_pin(22, new IO_bi_directional(portf, 6)); assign_pin(21, new IO_bi_directional(portf, 7)); assign_pin(34, new IO_bi_directional(portg, 0)); assign_pin(33, new IO_bi_directional(portg, 1)); assign_pin(32, new IO_bi_directional(portg, 2)); assign_pin(31, new IO_bi_directional(portg, 3)); assign_pin(38, new IO_bi_directional(portg, 4)); assign_pin(39, new IO_bi_directional(portg, 5)); assign_pin(41, new IO_bi_directional(portg, 6)); assign_pin(40, new IO_bi_directional(portg, 7)); } #endif //======================================================================== // // Pic 17C7xx // Processor * P17C7xx::construct(const char *name) { P17C7xx *p = new P17C7xx; cout << " 17c7xx construct\n"; p->create(0x1fff); p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c7xx"); return p; } P17C7xx::P17C7xx() : cpusta(this,"cpusta","") { if(verbose) cout << "17c7xx constructor, type = " << isa() << '\n'; //_16bit_processor::create(); // create_iopins(iopin_map, num_of_iopins); name_str = "p17c7xx"; } void P17C7xx::create(int ram_top) { cout << "p17c7xx create\n"; create_iopin_map(); //_16bit_processor::create(); // FIXME - TSD the 17c7xx is derived from the 16bit_processor, // but it can call the _16bit_processor::create member function // (because it assumes the 16bit processor is an 18cxxx device) pic_processor::create(); fast_stack.init(this); /* ind0.init(this); ind1.init(this); ind2.init(this); */ tmr0l.initialize(); intcon.initialize(); //usart.initialize(this); //tbl.initialize(this); //tmr0l.start(0); // create_iopin_map(); // create_sfr_map(); add_file_registers(0x0, ram_top, 0); } void P17C7xx::create_symbols() { } void P17C7xx::create_sfr_map() { if(verbose) cout << "creating 17c7xx common registers\n"; cout << "create_sfr_map P17C7xx\n"; } //======================================================================== // // Pic 17C75x // Processor * P17C75x::construct(const char *name) { cout << " 17c75x construct\n"; P17C75x *p = new P17C75x; p->create(0x1fff); p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c75x"); return p; } void P17C75x::create(int ram_top) { cout << "p17c75x create\n"; P17C7xx::create(ram_top); // create_iopin_map(); // _16bit_processor::create(); cout << "p17c75x parent created\n"; P17C75x::create_sfr_map(); cout << "p17c75x sfr map created\n"; P17C75x::create_symbols(); cout << "p17c75x parent created\n"; } P17C75x::P17C75x() { //if(verbose) cout << "17c75x constructor, type = " << isa() << '\n'; } void P17C75x::create_symbols() { if(verbose) cout << "p17c75x create symbols\n"; return; } void P17C75x::create_sfr_map() { #if 0 if (verbose) cout << "creating p17c75x common registers\n"; add_file_registers(0x01A, 0x01f, 0x100); alias_file_registers(0x1A, 0x1f, 0x200); alias_file_registers(0x1A, 0x1f, 0x300); alias_file_registers(0x1A, 0x1f, 0x400); alias_file_registers(0x1A, 0x1f, 0x500); alias_file_registers(0x1A, 0x1f, 0x600); alias_file_registers(0x1A, 0x1f, 0x700); add_file_registers(0x020, 0x0ff, 0); add_file_registers(0x120, 0x1ff, 0); add_file_registers(0x220, 0x2ff, 0); add_file_registers(0x320, 0x3ff, 0); //Unbanked registers add_sfr_register(&ind0.indf, 0x00, 0, "indf0"); add_sfr_register(&ind0.fsrl, 0x01, 0, "fsr0"); // Indirect addressing add_sfr_register(&pcl, 0x02, 0, "pcl"); add_sfr_register(&pclath, 0x03, 0, "pclath"); // Program counter add_sfr_register(&status, 0x04, 0xf0, "alusta"); // ALU status // add_sfr_register(&t0sta, 0x05, 0, "t0sta"); // Timer0 Status add_sfr_register(&cpusta, 0x06, 0x3C, "cpusta"); // CPU status // add_sfr_register(&intsta, 0x07, 0, "intsta"); add_sfr_register(&ind1.indf, 0x08, 0, "indf1"); add_sfr_register(&ind1.fsrl, 0x09, 0, "fsr1"); add_sfr_register(&W, 0x0a, 0, "wreg"); // add_sfr_register(&tmr0l, 0x0b, 0, "tmr0l"); // Timer0 registers // add_sfr_register(&tmr0h, 0x0c, 0, "tmr0h"); // add_sfr_register(&tblptrl, 0x0d, 0, "tblptrl"); // Program memory table pointer // add_sfr_register(&tblptrh, 0x0e, 0, "tblptrh"); add_sfr_register(&bsr, 0x0f, 0, "bsr"); // Bank select register add_sfr_register(&prodl, 0x18, 0, "prodl"); // 16 bit product registers add_sfr_register(&prodh, 0x19, 0, "prodh"); alias_file_registers(0x18, 0x19, 0x100); alias_file_registers(0x18, 0x19, 0x200); alias_file_registers(0x18, 0x19, 0x300); alias_file_registers(0x18, 0x19, 0x400); alias_file_registers(0x18, 0x19, 0x500); alias_file_registers(0x18, 0x19, 0x600); alias_file_registers(0x18, 0x19, 0x700); // Bank 0 add_sfr_register(porta, 0x10, 0, "porta"); // PortA bits add_sfr_register(&ddrb, 0x11, 0xff, "ddrb"); // Data direction register of portA add_sfr_register(portb, 0x12, 0, "portb"); /* add_sfr_register(&rcsta1, 0x13, 0, "rcsta1"); // Serial port 1 rec. status register add_sfr_register(&rcreg1, 0x14, 0, "rcreg1"); // Serial port 1 receive register add_sfr_register(&txsta1, 0x15, 0, "txsta1"); add_sfr_register(&txreg1, 0x16, 0, "txreg1"); add_sfr_register(&spbrg1, 0x17, 0, "spbrg1"); */ // Bank 1 add_sfr_register(&ddrc, 0x110, 0xff, "ddrc"); add_sfr_register(portc, 0x111, 0, "portc"); add_sfr_register(&ddrd, 0x112, 0xff, "ddrd"); add_sfr_register(portd, 0x113, 0, "portd"); add_sfr_register(&ddre, 0x114, 0x0f, "ddre"); add_sfr_register(porte, 0x115, 0, "porte"); add_sfr_register(&pir1, 0x116, 0x02, "pir1"); add_sfr_register(&pie1, 0x117, 0, "pie1"); // Bank 2 /* add_sfr_register(&tmr1, 0x210, 0, "tmr1"); add_sfr_register(&tmr2, 0x211, 0, "tmr2"); add_sfr_register(&tmr3l, 0x212, 0, "tmr3l"); add_sfr_register(&tmr3h, 0x213, 0, "tmr3h"); add_sfr_register(&pr1, 0x214, 0, "pr1"); // Timer1's period register add_sfr_register(&pr2, 0x215, 0, "pr2"); // Timer2's period register add_sfr_register(&pr3l, 0x216, 0, "pr3l"); // Timer3's period registers add_sfr_register(&pr3h, 0x217, 0, "pr3h"); // Bank 3 add_sfr_register(&pw1dcl, 0x310, 0, "pw1dcl"); add_sfr_register(&pw2dcl, 0x311, 0, "pw2dcl"); add_sfr_register(&pw1dch, 0x312, 0, "pw1dch"); add_sfr_register(&pw2dch, 0x313, 0, "pw2dch"); add_sfr_register(&ca2l, 0x314, 0, "ca2l"); // Capture2 registers add_sfr_register(&ca2h, 0x315, 0, "ca2h"); add_sfr_register(&tcon1, 0x316, 0, "tcon1"); add_sfr_register(&tcon2, 0x317, 0, "tcon2"); */ // Bank 4 add_sfr_register(&pir2, 0x410, 0, "pir2"); add_sfr_register(&pie2, 0x411, 0, "pie2"); //add_sfr_register(& , 0x412); /* add_sfr_register(&rcsta2, 0x413, 0, "rcsta2"); add_sfr_register(&rcreg2, 0x414, 0, "rcreg2"); add_sfr_register(&txsta2, 0x415, 0x02, "txsta2"); add_sfr_register(&txreg2, 0x416, 0, "txreg2"); add_sfr_register(&spbrg2, 0x417, 0, "spbrg2"); */ // Bank 5 add_sfr_register(&ddrf, 0x510, 0xff, "ddrf"); add_sfr_register(portf, 0x511, 0, "portf"); add_sfr_register(&ddrg, 0x512, 0xff, "ddrg"); add_sfr_register(portg, 0x513, 0, "portg"); /* add_sfr_register(&adcon0, 0x514, 0, "adcon0"); add_sfr_register(&adcon1, 0x515, 0, "adcon1"); add_sfr_register(&adresl, 0x516, 0, "adresl"); add_sfr_register(&adresh, 0x517, 0, "adresh"); */ // Bank 6 /* add_sfr_register(&sspadd, 0x610, 0, "sspadd"); // Synchronous serial port registers add_sfr_register(&sspcon1, 0x611, 0, "sspcon1"); add_sfr_register(&sspcon2, 0x612, 0, "sspcon2"); add_sfr_register(&sspstat, 0x613, 0, "sspstat"); add_sfr_register(&sspbuf, 0x614, 0, "sspbuf"); */ //add_sfr_register(& 0x615); //add_sfr_register(& 0x616); //add_sfr_register(& 0x617); // Bank 7 /* add_sfr_register(&pw3dcl, 0x710, 0, "pw3dcl"); add_sfr_register(&pw3dch, 0x711, 0, "pw3dch"); add_sfr_register(&ca3l, 0x712, 0, "ca3l"); add_sfr_register(&ca3h, 0x713, 0, "ca3h"); add_sfr_register(&ca4l, 0x714, 0, "ca4l"); add_sfr_register(&ca4h, 0x715, 0, "ca4h"); add_sfr_register(&tcon3, 0x716, 0, "tcon3"); //add_sfr_register(& 0x717); */ // Initialize all of the register cross linkages // All of the status bits on the 16bit core are writable status.write_mask = 0xff; #endif } //======================================================================== // // Pic 17C756 // Processor * P17C756::construct(const char *name) { P17C756 *p = new P17C756; cout << " 17c756 construct\n"; p->P17C7xx::create(0x1fff); p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c756"); return p; } void P17C756::create() { create_iopin_map(); P17C756::create_sfr_map(); // create_iopin_map(&iopin_map, &num_of_iopins); _16bit_processor::create(); // create_iopins(iopin_map, num_of_iopins); } void P17C756::create_sfr_map() { cout << "create_sfr_map P17C756\n"; } void P17C756::create_symbols() { cout << "P17C756 create symbols\n"; } P17C756::P17C756() { if(verbose) cout << "17c756 constructor, type = " << isa() << '\n'; } //------------------------------------------------------------------------ // // P17C756A // Processor * P17C756A::construct(const char *name) { P17C756A *p = new P17C756A; cout << " 17c756a construct\n"; p->P17C7xx::create(0x1fff); //p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c756a"); return p; } P17C756A::P17C756A() { if(verbose) cout << "17c756a constructor, type = " << isa() << '\n'; } void P17C756A::create() { create_iopin_map(); P17C756A::create_sfr_map(); // create_iopin_map(&iopin_map, &num_of_iopins); _16bit_processor::create(); // create_iopins(iopin_map, num_of_iopins); cout << " 17c756a create \n"; } void P17C756A::create_sfr_map() { cout << "create_sfr_map P17C756A\n"; } void P17C756A::create_symbols() { cout << "P17C756A create symbols\n"; } //======================================================================== // // Pic 17C752 // Processor * P17C752::construct(const char *name) { P17C752 *p = new P17C752; cout << " 17c752 construct\n"; p->P17C7xx::create(0x1fff); p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c752"); return p; } void P17C752::create() { create_iopin_map(); P17C752::create_sfr_map(); // create_iopin_map(&iopin_map, &num_of_iopins); _16bit_processor::create(); // create_iopins(iopin_map, num_of_iopins); } void P17C752::create_sfr_map() { cout << "create_sfr_map P17C752\n"; } void P17C752::create_symbols() { cout << "P17C752 create symbols\n"; } P17C752::P17C752() { if(verbose) cout << "17c752 constructor, type = " << isa() << '\n'; } //======================================================================== // // Pic 17C762 // Processor * P17C762::construct(const char *name) { P17C762 *p = new P17C762; cout << " 17c762 construct\n"; p->P17C7xx::create(0x1fff); p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c762"); return p; } void P17C762::create() { create_iopin_map(); P17C762::create_sfr_map(); // create_iopin_map(&iopin_map, &num_of_iopins); _16bit_processor::create(); // create_iopins(iopin_map, num_of_iopins); } void P17C762::create_sfr_map() { cout << "create_sfr_map P17C762\n"; } void P17C762::create_symbols() { cout << "P17C762 create symbols\n"; } P17C762::P17C762() { if(verbose) cout << "17c762 constructor, type = " << isa() << '\n'; } //======================================================================== // // Pic 17C766 // Processor * P17C766::construct(const char *name) { P17C766 *p = new P17C766; cout << " 17c75x construct\n"; p->P17C7xx::create(0x1fff); p->create_invalid_registers (); p->pic_processor::create_symbols(); p->new_name("p17c766"); return p; } void P17C766::create() { create_iopin_map(); P17C766::create_sfr_map(); // create_iopin_map(&iopin_map, &num_of_iopins); _16bit_processor::create(); // create_iopins(iopin_map, num_of_iopins); } void P17C766::create_sfr_map() { cout << "create_sfr_map P17C766\n"; } void P17C766::create_symbols() { cout << "P17C766 create symbols\n"; } P17C766::P17C766() { if(verbose) cout << "17c766 constructor, type = " << isa() << '\n'; } gpsim-0.30.0/src/bytelog.cc0000664000076400007640000000377413041763624012430 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "bytelog.h" namespace gpsim { ByteLogger::ByteLogger(int _bufsize) : bufsize(_bufsize) { index = 0; buffer = (TimedByte *) new char[bufsize * sizeof(TimedByte)]; } int ByteLogger::modIndex(int i) { if(i<0) { i+=bufsize; if(i<0) return index; } else if(i>=bufsize) return index; return i; } void ByteLogger::start(unsigned long long t) { buffer[index].start = t; } void ByteLogger::stop(unsigned long long t) { buffer[index].stop = t; if(++index > bufsize) index = 0; } void ByteLogger::byte(unsigned int b) { buffer[index].b = b&0xff; } void ByteLogger::rts(unsigned long long r) { buffer[index].rts = r; } /* void ByteLogger::statistics(int i=-1) { i = modIndex(i+index); unsigned long long t = (buffer[i].stop-buffer[i].start); double td= t/2.0; cout << "0x" << hex << buffer[i].b << " start time: 0x" << buffer[i].start << " byte time: 0x" << t << " cycles = " << td << " uS\n"; } */ unsigned long long ByteLogger::getStart(int i) { return buffer[modIndex(i+index)].start; } void ByteLogger::get(int i, TimedByte &b) { b = buffer[modIndex(i+index)]; } } // end of namespace gpsim gpsim-0.30.0/src/gpsim_interface.h0000664000076400007640000001662613063451152013756 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __GPSIM_INTERFACE_H__ #define __GPSIM_INTERFACE_H__ #include "gpsim_classes.h" #include "interface.h" #include "trigger.h" class Stimulus; class Stimulus_Node; class ISimConsole; //--------------------------------------------------------------------------- // // struct Interface // // Here's a structure containing all of the information for gpsim // and an external interface like the GUI to communicate. There are // two major functions. First, a GUI can provide pointers to callback // functions that the simulator can invoke upon certain conditions. // For example, if the contents of a register change, the simulator // can notify the GUI and thus save the gui having to continuously // poll. (This may occur when the command line interface changes // something; such changes need to be propogated up to the gui.) // // FIXME -- shouldn't this be a pure virtual class? class Interface { public: unsigned int interface_id; gpointer objectPTR; /* * UpdateObject - Invoked when an object changes * * If an object, like the contents of a register, changes then this function * will be called. There are two parameters: * xref - this is a pointer to some structure in the client's data space. * new_value - this is the new value to which the object has changed. * */ virtual void UpdateObject (gpointer xref,int new_value){}; /* * remove_object - Invoked when gpsim has removed something. * * If an object, like a register, is deleted then this function * will be called. There is one parameter: * xref - this is a pointer to some structure in the client's data space. * */ virtual void RemoveObject (gpointer xref) {}; /* * simulation_has_stopped - invoked when gpsim has stopped simulating (e.g. * when a breakpoint is encountered). * * Some interfaces have more than one instance, so the 'object' parameter * allows the interface to uniquely identify the particular one. */ virtual void SimulationHasStopped (gpointer object) {}; /* * new_processor - Invoked when a new processor is added to gpsim */ virtual void NewProcessor (Processor *new_cpu) {}; /* * new_module - Invoked when a new module is instantiated. * */ virtual void NewModule (Module *module) {}; /* * node_configuration_changed - invoked when stimulus configuration has changed */ virtual void NodeConfigurationChanged (Stimulus_Node *node) {}; /* * new_program - Invoked when a new program is loaded into gpsim * */ virtual void NewProgram (Processor *new_cpu) { }; /* * Update - Invoked when the interface should update itself */ virtual void Update (gpointer object) {}; /* * destructor - called when the interface is destroyed - this gives * the interface object a chance to save state information. */ virtual ~Interface() { } unsigned int get_id(void) { return interface_id;}; void set_id(unsigned int new_id) { interface_id = new_id;}; explicit Interface(gpointer new_object = NULL); }; class gpsimInterface : public TriggerObject { public: gpsimInterface(); /* * start_simulation -begin simulating. Simulation stops whenever * a breakpoint is encountered or the specified duration has expired. */ void start_simulation (double duration=0.0); /* * step_simulation - run the simulation for one or more simulation cycles. */ void step_simulation(int nSteps); /* * advance_simulation - run simulation until advancement condition is met. */ enum eAdvancementModes { eAdvanceNextInstruction, // processors - step over call instructions eAdvanceNextCycle, // system - eAdvanceNextCall, // processors - run until call instruction eAdvanceNextReturn, // processors - run until next return }; void advance_simulation(eAdvancementModes nAdvancement); void reset (RESET_TYPE resetType=SIM_RESET); void simulation_has_stopped (); bool bSimulating(); bool bUsingGUI(); void setGUImode(bool); // gpsim will call these functions to notify gui and/or modules // that something has changed. void update_object (gpointer xref,int new_value); void remove_object (gpointer xref); void update (); void new_processor (Processor *); void new_module (Module *module); void node_configuration_changed (Stimulus_Node *node); void new_program (Processor *); void set_update_rate(guint64 rate); guint64 get_update_rate(); unsigned int add_interface(Interface *new_interface); unsigned int prepend_interface(Interface *new_interface); unsigned int add_socket_interface(Interface *new_interface); Interface *get_socket_interface() { return socket_interface;} void remove_interface(unsigned int interface_id); virtual bool set_break() {return false;} virtual void callback(); virtual void callback_print(); virtual void print(); virtual void clear(); virtual char const * bpName() { return "gpsim interface"; } virtual ISimConsole &GetConsole(); private: GSList *interfaces; Interface *socket_interface; unsigned int interface_seq_number; guint64 update_rate; guint64 future_cycle; bool mbSimulating; // Set true if the simulation is running. bool mbUseGUI; // Set true if gui is being used. }; #if defined(IN_MODULE) && defined(_WIN32) // we are in a module: don't access gi object directly! LIBGPSIM_EXPORT gpsimInterface & get_interface(); #else // we are in gpsim: use of get_interface() is recommended, // even if gi object can be accessed directly. extern gpsimInterface gi; inline gpsimInterface &get_interface() { return gi; } #endif //------------------------------------------------------------------------ class Module; class ModuleInterface { public: Module *module; // The module we're interfacing with. explicit ModuleInterface(Module *new_module); }; //------------------------------------------------------------------------ class Processor; class ProcessorInterface : public ModuleInterface { public: explicit ProcessorInterface(Processor *cpu); }; class ISimConsole; #define CMD_ERR_OK 0 #define CMD_ERR_ABORTED 1 #define CMD_ERR_ERROR 2 #define CMD_ERR_PROCESSORDEFINED 3 #define CMD_ERR_PROCESSORNOTDEFINED 4 #define CMD_ERR_COMMANDNOTDEFINED 5 #define CMD_ERR_NOTIMPLEMENTED 6 #define GPSIM_GETCOMMANDHANDLER "GetCommandHandler" class ICommandHandler { public: virtual ~ICommandHandler() { } virtual const char *GetName(void) = 0; // Fixme: should Execute be renamed ExecuteCommand? virtual int Execute(const char * commandline, ISimConsole *out) = 0; virtual int ExecuteScript(list &script, ISimConsole *out) = 0; }; #endif // __GPSIM_INTERFACE_H__ gpsim-0.30.0/src/symbol.h0000664000076400007640000001326413041763613012123 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // symbol.h // // gpsim Symbol Table // // The symbol table provides an interface to all named gpsim objects. // Symbols can be added either automatically (i.e. gpsim adds global // symbols for its own use), by Modules and Processors, or by users. // In all cases, symbols placed into the symbol table are available // for expressions, breakpoints, or querying. // // Implementation details: // // The gpsim symbol table relies heavily on the STL map. A map is // created for each gpsim Module. An additional map is created for the // global symbols. Each one of these maps can be accessed via the // Module or via the Module name. The global symbols belong to no // Module, however the map holding them is named '__global__'. // // In addition, there is another map for holding all of the // Modules. This map together with all of the Module symbol tables // form a two-level hierarchical symbol table. // // At the global scope (e.g. the command line), symbols are referred // to by: // // ModuleName.ModuleSymbolName // // For example, p16f873.foo refers to the symbol 'foo' in the p16f873 // module. // // A notion of a 'current module' exists. This feature is not fully // implemented, but currently the most recently loaded Processor is // designated as the current module. Symbols in the current module can // be referenced with just the '.' scoping operator. For example, if // p16f873 is the current module, then typing '.foo' will display // p16f873.foo. // // The symbol table avoids interpreting or operating on the data it // stores. For example, only the object's name is ever // referenced. Clients wishing for specialized symbol manipulation are // required to do the appropriate type casting. A mechanism based on // the STL 'for_each' algorithm is provided to assist iterating // through all of the symbols. #ifndef __SYMBOL_H__ #define __SYMBOL_H__ #include #include #include #include "exports.h" using namespace std; // Forward definitions class gpsimObject; class Integer; class Value; class Module; class SymbolTable_t; class SymbolTable; typedef map ModuleList_t; typedef map MSymbolTable_t; typedef void (*PFN_ForEachModule)(const pair &st); typedef void (*PFN_ForEachSymbol)(const pair &sym); typedef pair SymbolTableEntry_t; typedef pair SymbolEntry_t; //************************************************************************ // SymbolTable_t // // A gpsim symbol table is an STL map of gpsimObject pointers that are keyed with // by the object's name. // class SymbolTable_t : protected map { // The SymbolTable class has access to all map<>'s methods. friend class SymbolTable; public: int addSymbol(gpsimObject *, string *AliasedName=0); int removeSymbol(gpsimObject *); int removeSymbol(const string &); int deleteSymbol(const string &); gpsimObject *findSymbol(const string &); /// ForEachModuleSymbolTable -- thin wrapper around map<>'s for_each() algorithm. /// The pointer to the function passed must be declared like: /// void MyForEach(const SymbolEntry_t &sym) { /* do something with sym */ } /// Then invoked the algorithm by: /// ASymbolTable.ForEachModuleSymbolTable(MyForEach); inline void ForEachSymbolTable(PFN_ForEachSymbol forEach) { for_each(begin(), end(), forEach); } protected: // stiFound an iterator that points to the most recently found symbol. SymbolTable_t::iterator stiFound; }; //************************************************************************ // class SymbolTable { public: SymbolTable(); ~SymbolTable(); /// Globally scoped symbols are added and removed here int addSymbol(gpsimObject *); int removeSymbol(gpsimObject *); int removeSymbol(const string &); int deleteSymbol(const string &); /// Each Module maintains its own symbol table. If the module wants /// its symbols to be accessed at the global scope, then the module /// has to add itself to the table. void addModule(Module *); void removeModule(Module *); void listModules(); // ugh /// find - search for a particular symbol gpsimObject *find(string); gpsimObject *findObject(gpsimObject *); /// void ForEachModule(PFN_ForEachModule forEach); /// Convenience functions for finding a symbol of a particular type: Value *findValue(string); Integer *findInteger(string); Module *findModule(string); protected: MSymbolTable_t MSymbolTables; }; #if defined(_WIN32) #if !defined(IN_MODULE) extern SymbolTable gSymbolTable; #endif // we are in Windows: don't access the symbol table object directly! LIBGPSIM_EXPORT SymbolTable & globalSymbolTable(); #else // we are in gpsim: use of getSymbolTable() is recommended, // even if it can be accessed directly. extern SymbolTable gSymbolTable; inline SymbolTable &globalSymbolTable() { return gSymbolTable; } #endif #endif // __SYMBOL_H__ gpsim-0.30.0/src/p12f6xx.h0000775000076400007640000000637413041763624012045 00000000000000/* Copyright (C) 2009 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P12F629_H__ #define __P12F629_H__ #include "14bit-processors.h" #include "14bit-tmrs.h" #include "intcon.h" #include "pir.h" #include "pie.h" #include "eeprom.h" #include "comparator.h" #include "a2dconverter.h" class WPU; class IOC; class PicPortGRegister; class P12F629 : public _14bit_processor { public: INTCON_14_PIR intcon_reg; ComparatorModule comparator; PIR_SET_1 pir_set_def; PIE pie1; PIR *pir1; T1CON t1con; TMRL tmr1l; TMRH tmr1h; PCON pcon; OSCCAL osccal; EEPROM_PIR *e; PicPortGRegister *m_gpio; PicTrisRegister *m_trisio; WPU *m_wpu; IOC *m_ioc; virtual PIR *get_pir2() { return (NULL); } virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_def); } virtual PROCESSOR_TYPE isa(){return _P12F629_;}; P12F629(const char *_name=0, const char *desc=0); ~P12F629(); static Processor *construct(const char *name); virtual void create_sfr_map(); virtual void create_symbols(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create_iopin_map(); virtual void create(int ram_top, int eeprom_size); virtual unsigned int register_memory_size () const { return 0x100; } virtual void option_new_bits_6_7(unsigned int bits); virtual unsigned int program_memory_size() const { return 0x400; } virtual void create_config_memory(); virtual bool set_config_word(unsigned int address,unsigned int cfg_word); virtual void enter_sleep(); virtual void exit_sleep(); }; class P12F675 : public P12F629 { public: ANSEL_12F ansel; ADCON0_12F adcon0; ADCON1 adcon1; sfr_register adresh; sfr_register adresl; virtual PROCESSOR_TYPE isa(){return _P12F675_;}; virtual void create(int ram_top, int eeprom_size); virtual unsigned int program_memory_size() const { return 0x400; }; P12F675(const char *_name=0, const char *desc=0); ~P12F675(); static Processor *construct(const char *name); virtual void create_sfr_map(); }; class P12F683 : public P12F675 { public: T2CON t2con; PR2 pr2; TMR2 tmr2; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; WDTCON wdtcon; OSCCON *osccon; OSCTUNE osctune; virtual PROCESSOR_TYPE isa(){return _P12F683_;}; virtual void create(int ram_top, int eeprom_size); virtual unsigned int program_memory_size() const { return 0x800; }; P12F683(const char *_name=0, const char *desc=0); ~P12F683(); static Processor *construct(const char *name); virtual void create_sfr_map(); }; #endif gpsim-0.30.0/src/p16x6x.cc0000664000076400007640000010645013041763613012030 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16x6x // // This file supports: // P16C61 #include #include #include #include "packages.h" #include "stimuli.h" #include "symbol.h" #include "p16x6x.h" #include "pic-ioports.h" #include "intcon.h" void P16C61::create(void) { create_iopin_map(); _14bit_processor::create(); add_file_registers(0x0c, 0x2f, 0x80); Pic14Bit::create_sfr_map(); } Processor * P16C61::construct(const char *name) { P16C61 *p = new P16C61(name); if(verbose) cout << " c61 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } P16C61::P16C61(const char *_name, const char *desc) : P16X8X(_name,desc) { ram_top = 0x2f; } P16C61::~P16C61() { if (verbose) cout << __FUNCTION__ << endl; } //------------------------------------------------------------------------ // // void P16C62::create_iopin_map(void) { package = new Package(28); if(!package) return; package->assign_pin(1, 0); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(8, 0); //VSS package->assign_pin(9, 0); // OSC package->assign_pin(10, 0); // OSC package->assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, 0); //VSS package->assign_pin(20, 0); //VDD package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); if (hasSSP()) { ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // I2C port SSP_TYPE_BSSP ); } tmr1l.setIOpin(&(*m_portc)[0]); } //------------------------------------------------------------------------ // // void P16C64::create_iopin_map(void) { package = new Package(40); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(1, 0); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin( 8, m_porte->addPin(new IO_bi_directional("porte0"),0)); package->assign_pin( 9, m_porte->addPin(new IO_bi_directional("porte1"),1)); package->assign_pin(10, m_porte->addPin(new IO_bi_directional("porte2"),2)); package->assign_pin(11, 0); package->assign_pin(12, 0); package->assign_pin(13, 0); package->assign_pin(14, 0); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(23, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(24, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(25, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(26, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, m_portd->addPin(new IO_bi_directional("portd0"),0)); package->assign_pin(20, m_portd->addPin(new IO_bi_directional("portd1"),1)); package->assign_pin(21, m_portd->addPin(new IO_bi_directional("portd2"),2)); package->assign_pin(22, m_portd->addPin(new IO_bi_directional("portd3"),3)); package->assign_pin(27, m_portd->addPin(new IO_bi_directional("portd4"),4)); package->assign_pin(28, m_portd->addPin(new IO_bi_directional("portd5"),5)); package->assign_pin(29, m_portd->addPin(new IO_bi_directional("portd6"),6)); package->assign_pin(30, m_portd->addPin(new IO_bi_directional("portd7"),7)); package->assign_pin(31, 0); package->assign_pin(32, 0); package->assign_pin(33, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(34, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(35, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(36, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(38, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(39, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(40, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); if (hasSSP()) { ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // I2C port SSP_TYPE_BSSP ); } psp.initialize(get_pir_set(), // PIR m_portd, // Parallel port m_trisd, // Parallel tris m_trise, // Control tris &(*m_porte)[0], // NOT RD &(*m_porte)[1], // NOT WR &(*m_porte)[2]); // NOT CS tmr1l.setIOpin(&(*m_portc)[0]); } //--------------------------------------------------------- // // P16x6x::create_sfr_map(void) - Here's where all of the // registers are defined for a p16c63 and greater... void P16X6X_processor::create_sfr_map() { if(verbose) cout << "P16X6X_processor::create_sfr_map\n"; Pic14Bit::create_sfr_map(); // P16x63 and higher have porta5 m_porta->setEnableMask(0x3f); m_porta->setTris(m_trisa); // The 16c62,c64 have general purpose registers // at addresses 20-7f and a0-bf add_file_registers(0x20, 0x7f, 0); add_file_registers(0xa0, 0xbf, 0); add_sfr_register(pir1, 0x0c, RegisterValue(0,0),"pir1"); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0),"tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0),"tmr1h"); add_sfr_register(&pcon, 0x8e, RegisterValue(0,0),"pcon"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); if( hasSSP() ) { add_sfr_register(&ssp.sspbuf, 0x13, RegisterValue(0,0),"sspbuf"); add_sfr_register(&ssp.sspcon, 0x14, RegisterValue(0,0),"sspcon"); add_sfr_register(&ssp.sspadd, 0x93, RegisterValue(0,0),"sspadd"); add_sfr_register(&ssp.sspstat, 0x94, RegisterValue(0,0),"sspstat"); tmr2.ssp_module[0] = &ssp; } add_sfr_register(&ccpr1l, 0x15, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x16, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x17, RegisterValue(0,0)); // get_pir_set()->set_pir1(get_pir1()); pir_set_def.set_pir1(pir1); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); // Maybe there's a better place for this, but let's go ahead and link all // of the registers together (there's probably a better way too) : tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; // FIXME -- can't delete this new'd item tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF)); // tmr1l.ccpcon = &ccp1con; tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); tmr2.add_ccp ( &ccp2con ); pr2.tmr2 = &tmr2; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v1::CCP1IF, &tmr2); ccp1con.setIOpin(&((*m_portc)[2])); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; // portc->ccp1con = &ccp1con; ccpr1l.new_name("ccpr1l"); ccpr1h.new_name("ccpr1h"); ccp1con.new_name("ccp1con"); if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); } //-------------------------------------------------- void P16X6X_processor::create_symbols() { Pic14Bit::create_symbols(); } //-------------------------------------------------- P16X6X_processor::P16X6X_processor(const char *_name, const char *_desc) : Pic14Bit(_name,_desc), t1con(this, "t1con", "TMR1 Control"), pie1(this,"PIE1", "Peripheral Interrupt Enable"), pie2(this,"PIE2", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), ccp2con(this, "ccp2con", "Capture Compare Control"), ccpr2l(this, "ccpr2l", "Capture Compare 2 Low"), ccpr2h(this, "ccpr2h", "Capture Compare 2 High"), pcon(this, "pcon", "pcon"), ssp(this) { if(verbose) cout << "generic 16X6X constructor, type = " << isa() << '\n'; m_portc = new PicPortRegister(this,"portc","",8,0xff); m_trisc = new PicTrisRegister(this,"trisc","",m_portc, false); pir1 = new PIR1v1(this,"pir1","Peripheral Interrupt Register",&intcon_reg, &pie1); pir2 = new PIR2v1(this,"pir2","Peripheral Interrupt Register",&intcon_reg, &pie2); } P16X6X_processor::~P16X6X_processor() { remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&pcon); remove_sfr_register(&t1con); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&pr2); if( hasSSP()) { remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspstat); } remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pie1); delete_file_registers(0x20,0x7f); delete_file_registers(0xa0,0xbf); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); if(verbose) cout << "deleting PIR2:\n"; delete_sfr_register(pir2); if(verbose) cout << "deleting PIR1:\n"; delete_sfr_register(pir1); } /******************************************************************* * * Definitions for the various P16x6x processors * */ P16C62::P16C62(const char *_name, const char *desc) : P16X6X_processor(_name,desc) { if(verbose) cout << "c62 constructor, type = " << isa() << '\n'; set_hasSSP(); } void P16C62::create_sfr_map() { if(verbose) cout << "creating c62 registers\n"; P16X6X_processor::create_sfr_map(); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); //1((PORTC*)portc)->ccp1con = &ccp1con; } void P16C62::create_symbols(void) { if(verbose) cout << "creating c62 symbols\n"; P16X6X_processor::create_symbols(); } void P16C62::create(void) { if(verbose) cout << " c62 create \n"; create_iopin_map(); _14bit_processor::create(); P16C62::create_sfr_map(); // Build the links between the I/O Pins and the internal peripherals //1ccp1con.iopin = portc->pins[2]; } Processor * P16C62::construct(const char *name) { P16C62 *p = new P16C62(name); cout << " c62 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // void P16C63::create_sfr_map(void) { if(verbose) cout << "creating c63 registers\n"; add_file_registers(0xc0, 0xff, 0); add_sfr_register(pir2, 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); add_sfr_register(&ccpr2l, 0x1b, RegisterValue(0,0)); add_sfr_register(&ccpr2h, 0x1c, RegisterValue(0,0)); add_sfr_register(&ccp2con, 0x1d, RegisterValue(0,0)); // get_pir_set()->set_pir2(get_pir2()); pir_set_def.set_pir2(pir2); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v1::CCP2IF, &tmr2); ccp2con.setIOpin(&((*m_portc)[1])); ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; usart.initialize(pir1,&(*m_portc)[6], &(*m_portc)[7], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),0); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); if (pir2) { pir2->set_intcon(&intcon_reg); pir2->set_pie(&pie2); } pie2.setPir(get_pir2()); } void P16C63::create_symbols(void) { if(verbose) cout << "creating c63 symbols\n"; // There's nothing to create... } //------------------------------------------------------------------------ // // P16C63 constructor // // Note: Since the 'C63 is derived from the 'C62. So before this constructor // is called, the C62 constructor will be called. Most of the initialization // is done within the 'C62 constructor. P16C63::P16C63(const char *_name, const char *desc) : P16C62(_name,desc), usart(this) { if(verbose) cout << "c63 constructor, type = " << isa() << '\n'; } P16C63::~P16C63() { if (verbose) cout << __FUNCTION__ << endl; remove_sfr_register(&pie2); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccp2con); if (registers[0xf0]->alias_mask & 0x80) delete_file_registers(0xc0, 0xef); else delete_file_registers(0xc0, 0xff); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); //delete_sfr_register(pir2,0x0d); } void P16C63::create(void) { if(verbose) cout << " c63 create \n"; P16C62::create(); P16C63::create_sfr_map(); // Build the links between the I/O Pins and the internal peripherals //1ccp2con.iopin = portc->pins[1]; } Processor * P16C63::construct(const char *name) { P16C63 *p = new P16C63(name); if(verbose) cout << " c63 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } //---------------------------------------------------------- // // void P16C64::create_sfr_map(void) { if(verbose) cout << "creating c64 registers\n"; pir_set_2_def.set_pir1(pir1_2_reg); P16X6X_processor::create_sfr_map(); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); add_sfr_register(m_portd, 0x08); add_sfr_register(m_trisd, 0x88, RegisterValue(0xff,0)); add_sfr_register(m_porte, 0x09); add_sfr_register(m_trise, 0x89, RegisterValue(0x07,0)); //1((PORTC*)portc)->ccp1con = &ccp1con; } void P16C64::create_symbols(void) { if(verbose) cout << "creating c64 symbols\n"; P16X6X_processor::create_symbols(); addSymbol(m_portd); addSymbol(m_porte); addSymbol(m_trisd); addSymbol(m_trise); } void P16C64::create(void) { if(verbose) cout << " c64 create \n"; create_iopin_map(); _14bit_processor::create(); //P16X6X_processor::create_sfr_map(); P16C64::create_sfr_map(); // Build the links between the I/O Pins and the internal peripherals //1ccp1con.iopin = portc->pins[2]; } Processor * P16C64::construct(const char *name) { P16C64 *p = new P16C64(name); p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } P16C64::P16C64(const char *_name, const char *desc) : P16X6X_processor(_name,desc) { if(verbose) cout << "c64 constructor, type = " << isa() << '\n'; set_hasSSP(); pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); delete pir1; pir1 = pir1_2_reg; m_portd = new PicPSP_PortRegister(this,"portd","",8,0xff); m_trisd = new PicTrisRegister(this,"trisd","",(PicPortRegister *)m_portd, false); m_porte = new PicPortRegister(this,"porte","",8,0x07); m_trise = new PicPSP_TrisRegister(this,"trise","",m_porte, false); } P16C64::~P16C64() { if (verbose) cout << __FUNCTION__ << endl; delete_sfr_register(m_portd); delete_sfr_register(m_trisd); delete_sfr_register(m_porte); delete_sfr_register(m_trise); } //------------------------------------------------------------------------ // // void P16C65::create_sfr_map(void) { if(verbose) cout << "creating c65 registers\n"; //P16C64::create_sfr_map(); add_file_registers(0xc0, 0xff, 0); add_sfr_register(pir2, 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); add_sfr_register(&ccpr2l, 0x1b, RegisterValue(0,0)); add_sfr_register(&ccpr2h, 0x1c, RegisterValue(0,0)); add_sfr_register(&ccp2con, 0x1d, RegisterValue(0,0)); // get_pir_set()->set_pir2(&get_pir2()); pir_set_def.set_pir2(pir2); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v2::CCP2IF, &tmr2); ccp2con.setIOpin(&((*m_portc)[1])); ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; usart.initialize(pir1,&(*m_portc)[6], &(*m_portc)[7], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); if (pir2) { pir2->set_intcon(&intcon_reg); pir2->set_pie(&pie2); } pie2.setPir(get_pir2()); } void P16C65::create_symbols(void) { if(verbose) cout << "creating c65 symbols\n"; // There's nothing to create... } //------------------------------------------------------------------------ // // P16C65 constructor // // Note: Since the 'C65 is derived from the 'C64. So before this constructor // is called, the C64 constructor will be called. Most of the initialization // is done within the 'C64 constructor. P16C65::P16C65(const char *_name, const char *desc) : P16C64(_name,desc), usart(this) { if(verbose) cout << "c65 constructor, type = " << isa() << '\n'; } P16C65::~P16C65() { if (verbose) cout << __FUNCTION__ << endl; if (registers[0xf0]->alias_mask & 0x80) delete_file_registers(0xc0, 0xef); else delete_file_registers(0xc0, 0xff); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccp2con); remove_sfr_register(&pie2); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); } void P16C65::create(void) { if(verbose) cout << " c65 create \n"; P16C64::create(); P16C65::create_sfr_map(); // Build the links between the I/O Pins and the internal peripherals // ccp1con.iopin = portc.pins[2]; //1ccp2con.iopin = portc->pins[1]; } Processor * P16C65::construct(const char *name) { P16C65 *p = new P16C65(name); if(verbose) cout << " c65 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } //======================================================================== // // Configuration Memory for 16F630/676 class ConfigF630 : public ConfigWord { public: ConfigF630(P16F630 *pCpu) : ConfigWord("CONFIG", 0x3fff, "Configuration Word", pCpu, 0x2007) { //Dprintf(("ConfigF630::ConfigF630 %p\n", m_pCpu)); if (m_pCpu) { m_pCpu->set_config_word(0x2007, 0x3fff); } } enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN = 1<<3, PWRTEN = 1<<4, MCLRE = 1<<5, BODEN = 1<<6, CP = 1<<7, CPD = 1<<8 }; string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[356]; const char *OSCdesc[8] = { "LP oscillator", "XT oscillator", "HS oscillator", "EC oscillator w/ OSC2 configured as I/O", "INTOSC oscillator: I/O on RA4 pin, I/O on RA5", "INTOSC oscillator: CLKOUT on RA4 pin, I/O on RA5", "RC oscillator: I/O on RA4 pin, RC on RA5", "RC oscillator: CLKOUT on RA4 pin, RC on RA5" }; snprintf(buff,sizeof(buff), " $%04x\n" " FOSC=%d - Clk source = %s\n" " WDTEN=%d - WDT is %s\n" " PWRTEN=%d - Power up timer is %s\n" " MCLRE=%d - RA3 Pin %s\n" " BODEN=%d - Brown-out Detect %s\n" " CP=%d - Code Protection %s\n" " CPD=%d - Data Code Protection %s\n", i, i&(FOSC0|FOSC1|FOSC2), OSCdesc[i&(FOSC0|FOSC1|FOSC2)], ((i&WDTE) ? 1 : 0), ((i&WDTE) ? "enabled" : "disabled"), ((i&PWRTEN) ? 1 : 0), ((i&PWRTEN) ? "disabled" : "enabled"), ((i&MCLRE) ? 1 : 0), ((i&MCLRE) ? "MCLR" : "Input"), ((i&BODEN) ? 1 : 0), ((i&BODEN) ? "enabled" : "disabled"), ((i&CP) ? 1 : 0), ((i&CP) ? "disabled" : "enabled"), ((i&CPD) ? 1 : 0), ((i&CPD) ? "disabled" : "enabled") ); return string(buff); } }; //------------------------------------------------------------------------ // // P16F630::P16F630(const char *_name, const char *desc) : _14bit_processor(_name, desc), t1con(this, "t1con", "TMR1 Control"), pie1(this,"PIE1", "Peripheral Interrupt Enable"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), osccal(this, "osccal", "Oscillator Calibration Register", 0xfc), intcon_reg(this,"intcon","Interrupt Control"), comparator(this) { if(verbose) cout << "P16F630 constructor, type = " << isa() << '\n'; pir1_3_reg = new PIR1v3(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir1 = pir1_3_reg; m_ioc = new IOC(this, "ioc", "Interrupt-On-Change GPIO Register"); m_porta = new PicPortGRegister(this,"porta","",&intcon_reg, m_ioc, 8,0x3f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); m_wpu = new WPU(this, "wpu", "Weak Pull-up Register", m_porta, 0x37); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); m_portc = new PicPortRegister(this,"portc","",8,0x3f); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false); } P16F630::~P16F630() { if (verbose) cout << __FUNCTION__ << endl; unassignMCLRPin(); delete_file_registers(0x20, 0x5f); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); delete_sfr_register(m_ioc); delete_sfr_register(m_wpu); delete_sfr_register(pir1_3_reg); remove_sfr_register(&tmr0); remove_sfr_register(&intcon_reg); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&t1con); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); remove_sfr_register(&osccal); remove_sfr_register(&pie1); delete e; } void P16F630::create_iopin_map(void) { package = new Package(14); if(!package) return; package->assign_pin(1, 0); // Vdd package->assign_pin( 2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IOPIN("porta3"),3)); package->assign_pin( 5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5)); package->assign_pin( 6, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin( 7, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin( 8, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin( 9, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(10, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(11, m_porta->addPin(new IO_bi_directional_pu("porta2"),2)); package->assign_pin(12, m_porta->addPin(new IO_bi_directional_pu("porta1"),1)); package->assign_pin(13, m_porta->addPin(new IO_bi_directional_pu("porta0"),0)); package->assign_pin(14, 0); //VSS tmr1l.setIOpin(&(*m_portc)[0]); } Processor * P16F630::construct(const char *name) { P16F630 *p = new P16F630(name); if(verbose) cout << " P16F630 construct\n"; p->create(128); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F630::create(int eesize) { create_iopin_map(); _14bit_processor::create(); e = new EEPROM_WIDE(this,pir1); e->initialize(eesize); e->set_intcon(&intcon_reg); set_eeprom_wide(e); P16F630::create_sfr_map(); } void P16F630::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } //------------------------------------------------------------------- void P16F630::create_sfr_map() { pir_set_def.set_pir1(pir1); add_file_registers(0x20, 0x5f, 0); alias_file_registers(0x20, 0x5f, 0x80); add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); add_sfr_register(&tmr0, 0x01); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); add_sfr_register(m_porta, 0x05); add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0)); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); add_sfr_register(pir1, 0x0c, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0), "tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0), "tmr1h"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; // FIXME -- can't delete this new'd item tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v3::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; tmr1l.setIOpin(&(*m_porta)[5]); tmr1l.setGatepin(&(*m_porta)[4]); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), NULL, &(*m_porta)[0], &(*m_porta)[1], NULL, NULL, &(*m_porta)[2], NULL); comparator.cmcon.set_configuration(1, 0, AN0, AN1, AN0, AN1, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN1, AN0, AN1, OUT0); comparator.cmcon.set_configuration(1, 2, AN0, AN1, AN0, AN1, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN1, VREF, AN1, VREF, OUT0); comparator.cmcon.set_configuration(1, 4, AN1, VREF, AN1, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN1, VREF, AN0, VREF, OUT0); comparator.cmcon.set_configuration(1, 6, AN1, VREF, AN0, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 0, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 2, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 3, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 4, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 6, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0x19, RegisterValue(0,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0x99, RegisterValue(0,0),"cvrcon"); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x9a); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x9b); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x9c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x9d); add_sfr_register(m_wpu, 0x95, RegisterValue(0x37,0),"wpua"); add_sfr_register(m_ioc, 0x96, RegisterValue(0,0),"ioca"); add_sfr_register(&osccal, 0x90, RegisterValue(0x80,0)); } //------------------------------------------------------------------- void P16F630::option_new_bits_6_7(unsigned int bits) { m_wpu->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); m_porta->setIntEdge((bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); } //------------------------------------------------------------------- void P16F630::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new ConfigF630(this)); }; //------------------------------------------------------------------- bool P16F630::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<2, CFG_WDTE = 1<<3, CFG_MCLRE = 1<<5, }; if(address == config_word_address()) { unsigned int valid_pins = m_porta->getEnableMask(); if ((cfg_word & CFG_MCLRE) == CFG_MCLRE) { assignMCLRPin(4); } else { unassignMCLRPin(); } wdt.initialize((cfg_word & CFG_WDTE) == CFG_WDTE); set_int_osc(false); // AnalogReq is used so ADC does not change clock names // set_config_word is first called with default and then // often called a second time. the following call is to // reset porta so next call to AnalogReq sill set the pin name // (&(*m_porta)[4])->AnalogReq((Register *)this, false, "porta4"); valid_pins |= 0x20; switch(cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2)) { case 0: // LP oscillator: low power crystal is on RA4 and RA5 case 1: // XT oscillator: crystal/resonator is on RA4 and RA5 case 2: // HS oscillator: crystal/resonator is on RA4 and RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "OSC2"); (m_porta->getPin(5))->newGUIname("OSC1"); valid_pins &= 0xcf; break; case 3: // EC I/O on RA4 pin, CLKIN on RA5 (m_porta->getPin(5))->newGUIname("CLKIN"); valid_pins &= 0xef; break; case 5: // INTOSC CLKOUT on RA4 pin (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); case 4: // INTOSC (m_porta->getPin(5))->newGUIname("porta5"); set_int_osc(true); osccal.set_freq(4e6); break; case 6: //RC oscillator: I/O on RA4 pin, RC on RA5 (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; case 7: // RC oscillator: CLKOUT on RA4 pin, RC on RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; }; if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_trisa->setEnableMask(valid_pins); } return(true); } return false; } //------------------------------------------------------------------------ // // P16F676::P16F676(const char *_name, const char *desc) : P16F630(_name, desc), ansel(this,"ansel", "Analog Select"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low") { } P16F676::~P16F676() { if (verbose) cout << __FUNCTION__ << endl; remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&ansel); } Processor * P16F676::construct(const char *name) { P16F676 *p = new P16F676(name); if(verbose) cout << " P16F676 construct\n"; p->create(128); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F676::create(int ram_top) { P16F630::create(ram_top); create_sfr_map(); } void P16F676::create_sfr_map() { add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&ansel, 0x91, RegisterValue(0xff,0)); ansel.setAdcon1(&adcon1); // ansel.setAdcon0(&adcon0); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(7); adcon0.setChannel_shift(2); adcon1.setAdcon0(&adcon0); adcon1.setNumberOfChannels(8); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[4]); adcon1.setIOPin(4, &(*m_portc)[0]); adcon1.setIOPin(5, &(*m_portc)[1]); adcon1.setIOPin(6, &(*m_portc)[2]); adcon1.setIOPin(7, &(*m_portc)[3]); adcon1.setVrefHiConfiguration(2, 1); /* Channel Configuration done dynamiclly based on ansel */ } gpsim-0.30.0/src/p16f88x.cc0000664000076400007640000022047013115237705012077 00000000000000/* * Copyright (C) 2010,2015 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16f88x // // This file supports: // PIC16F882 // PIC16F883 // PIC16F884 // PIC16F885 // PIC16F886 // PIC16F887 // #include #include #include //#include "../config.h" #include "stimuli.h" #include "p16f88x.h" #include "pic-ioports.h" #include "packages.h" #include "symbol.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__, __FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //======================================================================== // // Configuration Memory for the 16F8X devices. class Config188x : public ConfigWord { public: Config188x(P16F88x *pCpu) : ConfigWord("CONFIG188x", 0x3fff, "Configuration Word", pCpu, 0x2007) { } enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN = 1<<3, PWRTEN = 1<<4, MCLRE = 1<<5, BOREN = 1<<8, BOREN1 = 1<<9, LVP = 1<<12, CPD = 1<<8, WRT0 = 1<<9, WRT1 = 1<<10, NOT_DEBUG = 1<<11, }; virtual void set(gint64 v) { Integer::set(v); Dprintf(("Config188x set %x\n", (int)v)); if (m_pCpu) { m_pCpu->wdt.initialize((v & WDTEN) == WDTEN); } } }; //======================================================================== P16F88x::P16F88x(const char *_name, const char *desc) : _14bit_processor(_name,desc), intcon_reg(this,"intcon","Interrupt Control"), t1con(this, "t1con", "TMR1 Control"), pie1(this,"PIE1", "Peripheral Interrupt Enable"), pie2(this,"PIE2", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), ccp2con(this, "ccp2con", "Capture Compare Control"), ccpr2l(this, "ccpr2l", "Capture Compare 2 Low"), ccpr2h(this, "ccpr2h", "Capture Compare 2 High"), pcon(this, "pcon", "pcon"), ssp(this), osccon(0), osctune(this, "osctune", "OSC Tune"), wdtcon(this, "wdtcon", "WDT Control", 1), usart(this), comparator(this), vrcon(this, "vrcon", "Voltage Reference Control Register"), srcon(this, "srcon", "SR Latch Control Resgister"), ansel(this,"ansel", "Analog Select"), anselh(this,"anselh", "Analog Select high"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), eccpas(this, "eccpas", "ECCP Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register"), pstrcon(this, "pstrcon", "Pulse Sterring Control Register"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low") { m_porta = new PicPortRegister(this,"porta","", 8,0x1f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); m_ioc = new IOC(this, "iocb", "Interrupt-On-Change B Register"); m_portb = new PicPortGRegister(this,"portb","", &intcon_reg, m_ioc,8,0xff); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false); m_portc = new PicPortRegister(this,"portc","",8,0xff); m_trisc = new PicTrisRegister(this,"trisc","",m_portc, false); m_porte = new PicPortRegister(this,"porte","",8,0x0f); m_trise = new PicPSP_TrisRegister(this,"trise","",m_porte, false); pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir2_2_reg = new PIR2v3(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); pir1 = pir1_2_reg; pir2 = pir2_2_reg; m_wpu = new WPU(this, "wpub", "Weak Pull-up Register", m_portb, 0xff); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); comparator.cmxcon0[0] = new CMxCON0_V2(this, "cm1con0", " Comparator C1 Control Register 0", 0, &comparator); comparator.cmxcon0[1] = new CMxCON0_V2(this, "cm2con0", " Comparator C2 Control Register 0", 1, &comparator); comparator.cmxcon1[0] = new CM2CON1_V3(this, "cm2con1", " Comparator C1 Control Register 1", 0, &comparator); comparator.cmxcon1[1] = comparator.cmxcon1[0]; } P16F88x::~P16F88x() { unassignMCLRPin(); delete_file_registers(0x20, 0x7f); delete_file_registers(0xa0, 0xbf); remove_sfr_register(&tmr0); remove_sfr_register(&intcon_reg); remove_sfr_register(&pie2); remove_sfr_register(&pie1); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&pcon); remove_sfr_register(&t1con); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&pr2); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); delete get_eeprom(); remove_sfr_register(&intcon_reg); remove_sfr_register(osccon); remove_sfr_register(&osctune); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); remove_sfr_register(&vrcon); remove_sfr_register(&srcon); remove_sfr_register(&wdtcon); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccp2con); remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&ansel); remove_sfr_register(&anselh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccp2con); remove_sfr_register(&pwm1con); remove_sfr_register(&pstrcon); remove_sfr_register(&eccpas); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspstat); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); remove_sfr_register(comparator.cmxcon0[0]); remove_sfr_register(comparator.cmxcon0[1]); remove_sfr_register(comparator.cmxcon1[1]); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); delete_sfr_register(m_portb); delete_sfr_register(m_trisb); delete_sfr_register(m_porte); delete_sfr_register(m_trise); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(pir1); delete_sfr_register(pir2); delete_sfr_register(m_wpu); delete_sfr_register(m_ioc); } void P16F88x::create_iopin_map() { fprintf(stderr, "%s should be defined at a higer level\n", __FUNCTION__); } void P16F88x::create_sfr_map() { add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); add_sfr_register(&tmr0, 0x01); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); add_sfr_register(m_porta, 0x05); add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0)); add_sfr_register(m_portb, 0x06); add_sfr_register(m_trisb, 0x86, RegisterValue(0xff,0)); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); //alias_file_registers(0x0a,0x0b,0x80); //Already donw intcon = &intcon_reg; pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); add_sfr_register(m_porte, 0x09); add_sfr_register(m_trise, 0x89, RegisterValue(0xff,0)); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); add_file_registers(0x20, 0x7f, 0); add_file_registers(0xa0, 0xbf, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); add_sfr_register(get_pir2(), 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); pir_set_2_def.set_pir2(pir2); pie2.setPir(get_pir2()); alias_file_registers(0x00,0x04,0x100); alias_file_registers(0x80,0x84,0x100); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x86,0x86,0x100); add_sfr_register(pir1, 0x0c, RegisterValue(0,0),"pir1"); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0),"tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0),"tmr1h"); add_sfr_register(&pcon, 0x8e, RegisterValue(0,0),"pcon"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); get_eeprom()->get_reg_eedata()->new_name("eedat"); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); alias_file_registers(0x0a,0x0b,0x080); alias_file_registers(0x0a,0x0b,0x100); alias_file_registers(0x0a,0x0b,0x180); intcon_reg.set_pir_set(get_pir_set()); add_sfr_register(osccon, 0x8f, RegisterValue(0x60,0),"osccon"); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); usart.initialize(pir1,&(*m_portc)[6], &(*m_portc)[7], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(&usart.spbrgh, 0x9a, RegisterValue(0,0),"spbrgh"); add_sfr_register(&usart.baudcon, 0x187,RegisterValue(0x40,0),"baudctl"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); usart.set_eusart(true); comparator.assign_tmr1l(&tmr1l); comparator.cmxcon1[1]->set_vrcon(&vrcon); add_sfr_register(comparator.cmxcon0[0], 0x107, RegisterValue(0,0), "cm1con0"); add_sfr_register(comparator.cmxcon0[1], 0x108, RegisterValue(0,0), "cm2con0"); add_sfr_register(comparator.cmxcon1[1], 0x109, RegisterValue(2,0), "cm2con1"); add_sfr_register(&vrcon, 0x97, RegisterValue(0,0),"vrcon"); add_sfr_register(&srcon, 0x185, RegisterValue(0,0),"srcon"); add_sfr_register(&wdtcon, 0x105, RegisterValue(0x08,0),"wdtcon"); add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&ansel, 0x188, RegisterValue(0xff,0)); add_sfr_register(&anselh, 0x189, RegisterValue(0xff,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(m_wpu, 0x95, RegisterValue(0xff,0)); add_sfr_register(m_ioc, 0x96, RegisterValue(0,0)); ansel.setAdcon1(&adcon1); ansel.setAnselh(&anselh); anselh.setAdcon1(&adcon1); anselh.setAnsel(&ansel); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(0xf); adcon0.setChannel_shift(2); adcon0.setGo(1); adcon1.setValidBits(0xb0); adcon1.setNumberOfChannels(14); adcon1.setValidCfgBits(ADCON1::VCFG0 | ADCON1::VCFG1 , 4); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[4]); adcon1.setIOPin(8, &(*m_portb)[2]); adcon1.setIOPin(9, &(*m_portb)[3]); adcon1.setIOPin(10, &(*m_portb)[1]); adcon1.setIOPin(11, &(*m_portb)[4]); adcon1.setIOPin(12, &(*m_portb)[0]); adcon1.setIOPin(13, &(*m_portb)[5]); // set a2d modes where an3 is Vref+ adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); // set a2d modes where an2 is Vref- adcon1.setVrefLoConfiguration(2, 2); adcon1.setVrefLoConfiguration(3, 2); vrcon.setValidBits(0xff); // All bits settable add_sfr_register(&ccpr1l, 0x15, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x16, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x17, RegisterValue(0,0)); add_sfr_register(&ccpr2l, 0x1b, RegisterValue(0,0)); add_sfr_register(&ccpr2h, 0x1c, RegisterValue(0,0)); add_sfr_register(&ccp2con, 0x1d, RegisterValue(0,0)); add_sfr_register(&pwm1con, 0x9b, RegisterValue(0,0)); add_sfr_register(&pstrcon, 0x9d, RegisterValue(1,0)); add_sfr_register(&eccpas, 0x9c, RegisterValue(0,0)); eccpas.setIOpin(0, 0, &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); ssp.sspmsk = new _SSPMSK(this, "ssp1msk"); add_sfr_register(&ssp.sspbuf, 0x13, RegisterValue(0,0),"sspbuf"); add_sfr_register(&ssp.sspcon, 0x14, RegisterValue(0,0),"sspcon"); add_sfr_register(&ssp.sspcon2, 0x91, RegisterValue(0,0),"sspcon2"); add_sfr_register(&ssp.sspadd, 0x93, RegisterValue(0,0),"sspadd"); add_sfr_register(ssp.sspmsk, 0x93, RegisterValue(0xff,0), "sspmsk", false); add_sfr_register(&ssp.sspstat, 0x94, RegisterValue(0,0),"sspstat"); tmr2.ssp_module[0] = &ssp; ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_SSP ); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); tmr2.add_ccp ( &ccp2con ); pr2.tmr2 = &tmr2; tmr1l.setIOpin(&(*m_portc)[0]); ccp1con.setBitMask(0xff); ccp1con.pstrcon = &pstrcon; ccp1con.pwm1con = &pwm1con; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; ccp2con.setIOpin(&(*m_portc)[1]); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v3::CCP2IF, &tmr2); ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[4], &(*m_porta)[5]); comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1], &(*m_portb)[3],&(*m_portb)[1]); comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[3], &(*m_porta)[2]); comparator.cmxcon1[0]->setBitMask(0x33); comparator.cmxcon0[0]->setBitMask(0xb7); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, PIR2v2::C1IF)); comparator.cmxcon0[1]->setBitMask(0xb7); comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, PIR2v2::C2IF)); } //------------------------------------------------------------------- void P16F88x::option_new_bits_6_7(unsigned int bits) { Dprintf(("P18F88x::option_new_bits_6_7 bits=%x\n", bits)); m_portb->setIntEdge ( (bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); m_wpu->set_wpu_pu ( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); } void P16F88x::create_symbols() { if(verbose) cout << "88x create symbols\n"; pic_processor::create_symbols(); addSymbol(Wreg); } void P16F88x::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } //======================================================================== bool P16F88x::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<4, CFG_MCLRE = 1<<5, CFG_CCPMX = 1<<12 }; // Let the base class do most of the work: if (address == 0x2007) { pic_processor::set_config_word(address, cfg_word); if (verbose) cout << "p16f88 0x" << hex << address << " setting config word 0x" << cfg_word << '\n'; unsigned int valid_pins = m_porta->getEnableMask(); set_int_osc(false); // Careful these bits not adjacent switch(cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2)) { case 0: // LP oscillator: low power crystal is on RA6 and RA7 case 1: // XT oscillator: crystal/resonator is on RA6 and RA7 case 2: // HS oscillator: crystal/resonator is on RA6 and RA7 (m_porta->getPin(6))->newGUIname("OSC2"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 0x13: // ER oscillator: RA6 is CLKOUT, resistor (?) on RA7 (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 3: // EC: RA6 is an I/O, RA7 is a CLKIN case 0x12: // ER oscillator: RA6 is an I/O, RA7 is a CLKIN (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("CLKIN"); valid_pins = (valid_pins & 0x7f)|0x40; break; case 0x10: // INTRC: Internal Oscillator, RA6 and RA7 are I/O's set_int_osc(true); (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins |= 0xc0; break; case 0x11: // INTRC: Internal Oscillator, RA7 is an I/O, RA6 is CLKOUT set_int_osc(true); (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins = (valid_pins & 0xbf)|0x80; break; } // If the /MCLRE bit is set then RE3 is the MCLR pin, otherwise it's // a general purpose I/O pin. if ((cfg_word & CFG_MCLRE)) { assignMCLRPin(1); } else { unassignMCLRPin(); } if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_porta->setTris(m_trisa); } return true; } else if (address == 0x2008 ) { //cout << "p16f88x 0x" << hex << address << " config word2 0x" << cfg_word << '\n'; } return false; } //======================================================================== void P16F88x::create_config_memory() { m_configMemory = new ConfigMemory(this,2); m_configMemory->addConfigWord(0,new Config188x(this)); m_configMemory->addConfigWord(1,new ConfigWord("CONFIG2", 0,"Configuration Word",this,0x2008)); wdt.initialize(true); // default WDT enabled wdt.set_timeout(0.000035); set_config_word(0x2007, 0x3fff); } //======================================================================== void P16F88x::create(int eesize) { create_iopin_map(); _14bit_processor::create(); osccon = new OSCCON(this, "osccon", "OSC Control"); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eesize); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F88x::create_sfr_map(); } //======================================================================== // // Pic 16F882 // Processor * P16F882::construct(const char *name) { P16F882 *p = new P16F882(name); p->P16F88x::create(128); p->P16F882::create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F882::P16F882(const char *_name, const char *desc) : P16F88x(_name,desc) { if(verbose) cout << "f882 constructor, type = " << isa() << '\n'; m_porta->setEnableMask(0xff); } //------------------------------------------------------------------------ // // void P16F882::create_iopin_map(void) { package = new Package(28); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(8, 0); package->assign_pin( 9, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin( 10, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, 0); package->assign_pin(20, 0); package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); } void P16F882::create_symbols(void) { if(verbose) cout << "creating f882 symbols\n"; P16F88x::create_symbols(); addSymbol(m_porte); addSymbol(m_trise); } void P16F882::create_sfr_map() { ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]); } //======================================================================== // // Pic 16F883 // Processor * P16F883::construct(const char *name) { P16F883 *p = new P16F883(name); p->P16F88x::create(256); p->P16F883::create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F883::P16F883(const char *_name, const char *desc) : P16F882(_name,desc) { if(verbose) cout << "f883 constructor, type = " << isa() << '\n'; m_porta->setEnableMask(0xff); } P16F883::~P16F883() { delete_file_registers(0xc0,0xef); delete_file_registers(0x120,0x16f); } void P16F883::create_symbols(void) { if(verbose) cout << "creating f883 symbols\n"; P16F88x::create_symbols(); addSymbol(m_porte); addSymbol(m_trise); } void P16F883::create_sfr_map() { add_file_registers(0xc0,0xef,0); add_file_registers(0x120,0x16f,0); ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]); } //======================================================================== // // Pic 16F886 // Processor * P16F886::construct(const char *name) { P16F886 *p = new P16F886(name); p->P16F88x::create(256); p->P16F886::create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F886::P16F886(const char *_name, const char *desc) : P16F882(_name,desc) { if(verbose) cout << "f886 constructor, type = " << isa() << '\n'; m_porta->setEnableMask(0xff); } P16F886::~P16F886() { delete_file_registers(0xc0,0xef); delete_file_registers(0x120,0x16f); delete_file_registers(0x190,0x1ef); } void P16F886::create_symbols(void) { if(verbose) cout << "creating f886 symbols\n"; P16F88x::create_symbols(); addSymbol(m_porte); addSymbol(m_trise); } void P16F886::create_sfr_map() { add_file_registers(0xc0,0xef,0); add_file_registers(0x120,0x16f,0); add_file_registers(0x190,0x1ef,0); ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]); } //======================================================================== // // Pic 16F887 // Processor * P16F887::construct(const char *name) { P16F887 *p = new P16F887(name); p->P16F88x::create(256); p->P16F887::create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F887::P16F887(const char *_name, const char *desc) : P16F884(_name,desc) { if(verbose) cout << "f887 constructor, type = " << isa() << '\n'; } P16F887::~P16F887() { delete_file_registers(0x110,0x11f); delete_file_registers(0x190,0x1ef); } void P16F887::create_symbols(void) { if(verbose) cout << "creating f887 symbols\n"; P16F88x::create_symbols(); addSymbol(m_portd); addSymbol(m_trisd); } void P16F887::create_sfr_map() { add_file_registers(0xc0,0xef,0); add_file_registers(0x110,0x16f,0); //add_file_registers(0x110,0x11f,0); add_file_registers(0x190,0x1ef,0); add_sfr_register(m_portd, 0x08); add_sfr_register(m_trisd, 0x88, RegisterValue(0xff,0)); ccp1con.setIOpin(&(*m_portc)[2], &(*m_portd)[5], &(*m_portd)[6], &(*m_portd)[7]); adcon1.setIOPin(5, &(*m_porte)[0]); adcon1.setIOPin(6, &(*m_porte)[1]); adcon1.setIOPin(7, &(*m_porte)[2]); } //======================================================================== // // Pic 16F884 // Processor * P16F884::construct(const char *name) { P16F884 *p = new P16F884(name); p->P16F88x::create(256); p->P16F884::create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F884::P16F884(const char *_name, const char *desc) : P16F88x(_name,desc) { if(verbose) cout << "f884 constructor, type = " << isa() << '\n'; m_porta->setEnableMask(0xff); // trisa5 is an input only pin m_trisa->setEnableMask(0xdf); m_portd = new PicPSP_PortRegister(this,"portd","",8,0xff); m_trisd = new PicTrisRegister(this,"trisd","",(PicPortRegister *)m_portd, false); } P16F884::~P16F884() { delete_file_registers(0xc0,0xef); delete_file_registers(0x120,0x16f); delete_sfr_register(m_portd); delete_sfr_register(m_trisd); } //------------------------------------------------------------------------ // // void P16F884::create_iopin_map(void) { package = new Package(40); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin( 8, m_porte->addPin(new IO_bi_directional("porte0"),0)); package->assign_pin( 9, m_porte->addPin(new IO_bi_directional("porte1"),1)); package->assign_pin(10, m_porte->addPin(new IO_bi_directional("porte2"),2)); package->assign_pin(11, 0); package->assign_pin(12, 0); package->assign_pin( 13, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin( 14, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(23, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(24, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(25, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(26, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, m_portd->addPin(new IO_bi_directional("portd0"),0)); package->assign_pin(20, m_portd->addPin(new IO_bi_directional("portd1"),1)); package->assign_pin(21, m_portd->addPin(new IO_bi_directional("portd2"),2)); package->assign_pin(22, m_portd->addPin(new IO_bi_directional("portd3"),3)); package->assign_pin(27, m_portd->addPin(new IO_bi_directional("portd4"),4)); package->assign_pin(28, m_portd->addPin(new IO_bi_directional("portd5"),5)); package->assign_pin(29, m_portd->addPin(new IO_bi_directional("portd6"),6)); package->assign_pin(30, m_portd->addPin(new IO_bi_directional("portd7"),7)); package->assign_pin(31, 0); package->assign_pin(32, 0); package->assign_pin(33, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(34, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(35, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(36, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(38, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(39, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(40, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); } void P16F884::create_symbols(void) { if(verbose) cout << "creating f884 symbols\n"; P16F88x::create_symbols(); addSymbol(m_portd); addSymbol(m_trisd); } void P16F884::create_sfr_map() { add_file_registers(0xc0,0xef,0); add_file_registers(0x120,0x16f,0); add_sfr_register(m_portd, 0x08); add_sfr_register(m_trisd, 0x88, RegisterValue(0xff,0)); ccp1con.setIOpin(&(*m_portc)[2], &(*m_portd)[5], &(*m_portd)[6], &(*m_portd)[7]); adcon1.setIOPin(5, &(*m_porte)[0]); adcon1.setIOPin(6, &(*m_porte)[1]); adcon1.setIOPin(7, &(*m_porte)[2]); } //------------------------------------------------------------------------ // // class ConfigF631 : public ConfigWord { public: ConfigF631(P16F631 *pCpu) : ConfigWord("CONFIG", 0x3fff, "Configuration Word", pCpu, 0x2007) { Dprintf(("ConfigF631::ConfigF631 %p\n", m_pCpu)); } enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN = 1<<3, PWRTEN = 1<<4, MCLRE = 1<<5, BODEN = 1<<6, CP = 1<<7, CPD = 1<<8 }; string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[356]; const char *OSCdesc[8] = { "LP oscillator", "XT oscillator", "HS oscillator", "EC oscillator w/ OSC2 configured as I/O", "INTOSC oscillator: I/O on RA4 pin, I/O on RA5", "INTOSC oscillator: CLKOUT on RA4 pin, I/O on RA5", "RC oscillator: I/O on RA4 pin, RC on RA5", "RC oscillator: CLKOUT on RA4 pin, RC on RA5" }; snprintf(buff,sizeof(buff), " $%04x\n" " FOSC=%d - Clk source = %s\n" " WDTEN=%d - WDT is %s\n" " PWRTEN=%d - Power up timer is %s\n" " MCLRE=%d - RA3 Pin %s\n" " BODEN=%d - Brown-out Detect %s\n" " CP=%d - Code Protection %s\n" " CPD=%d - Data Code Protection %s\n", i, i&(FOSC0|FOSC1|FOSC2), OSCdesc[i&(FOSC0|FOSC1|FOSC2)], ((i&WDTE) ? 1 : 0), ((i&WDTE) ? "enabled" : "disabled"), ((i&PWRTEN) ? 1 : 0), ((i&PWRTEN) ? "disabled" : "enabled"), ((i&MCLRE) ? 1 : 0), ((i&MCLRE) ? "MCLR" : "Input"), ((i&BODEN) ? 1 : 0), ((i&BODEN) ? "enabled" : "disabled"), ((i&CP) ? 1 : 0), ((i&CP) ? "disabled" : "enabled"), ((i&CPD) ? 1 : 0), ((i&CPD) ? "disabled" : "enabled") ); return string(buff); } }; P16F631::P16F631(const char *_name, const char *desc) : _14bit_processor(_name, desc), t1con(this, "t1con", "TMR1 Control"), pie1(this,"pie1", "Peripheral Interrupt Enable"), pie2(this,"pie2", "Peripheral Interrupt Enable"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), osctune(this, "osctune", "OSC Tune"), pcon(this, "pcon", "pcon"), wdtcon(this, "wdtcon", "WDT Control", 0x1f), osccon(0), vrcon(this, "vrcon", "Voltage Reference Control Register"), srcon(this, "srcon", "SR Latch Control Resgister"), ansel(this,"ansel", "Analog Select"), comparator(this), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), intcon_reg(this,"intcon","Interrupt Control") { if(verbose) cout << "P16F631 constructor, type = " << isa() << '\n'; pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir1 = pir1_2_reg; pir2_3_reg = new PIR2v3(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); pir2 = pir2_3_reg; m_ioca = new IOC(this, "ioca", "Interrupt-On-Change GPIO Register"); m_iocb = new IOC(this, "iocb", "Interrupt-On-Change GPIO Register"); m_porta = new PicPortGRegister(this,"porta","",&intcon_reg, m_ioca, 8,0x3f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false, 0x37); m_portb = new PicPortGRegister(this,"portb","",&intcon_reg, m_iocb, 8,0xf0); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false); m_wpua = new WPU(this, "wpua", "Weak Pull-up Register", m_porta, 0x37); m_wpub = new WPU(this, "wpub", "Weak Pull-up Register", m_portb, 0xf0); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); m_portc = new PicPortRegister(this,"portc","",8,0xff); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false); comparator.cmxcon0[0] = new CMxCON0_V2(this, "cm1con0", " Comparator C1 Control Register 0", 0, &comparator); comparator.cmxcon0[1] = new CMxCON0_V2(this, "cm2con0", " Comparator C2 Control Register 0", 1, &comparator); comparator.cmxcon1[0] = new CM2CON1_V4(this, "cm2con1", " Comparator C1 Control Register 1", 0, &comparator); comparator.cmxcon1[1] = comparator.cmxcon1[0]; } P16F631::~P16F631() { if (verbose) cout << __FUNCTION__ << endl; unassignMCLRPin(); delete_file_registers(0x40, 0x7f); remove_sfr_register(comparator.cmxcon0[0]); remove_sfr_register(comparator.cmxcon0[1]); remove_sfr_register(comparator.cmxcon1[1]); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&tmr0); remove_sfr_register(&vrcon); remove_sfr_register(&ansel); remove_sfr_register(&srcon); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&t1con); remove_sfr_register(&pcon); remove_sfr_register(&wdtcon); remove_sfr_register(osccon); remove_sfr_register(&pie1); remove_sfr_register(&pie2); remove_sfr_register(&intcon_reg); remove_sfr_register(&osctune); delete_sfr_register(pir2); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(m_portb); delete_sfr_register(m_trisb); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); delete_sfr_register(m_ioca); delete_sfr_register(m_iocb); delete_sfr_register(m_wpua); delete_sfr_register(m_wpub); delete_sfr_register(pir1_2_reg); delete e; } void P16F631::create_iopin_map(void) { package = new Package(20); if(!package) return; package->assign_pin(1, 0); // Vdd package->assign_pin( 2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IOPIN("porta3"),3)); package->assign_pin( 5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5)); package->assign_pin( 6, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin( 7, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin( 8, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin( 9, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional("portb7"),7)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional_pu("portc2"),2)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional_pu("portc1"),1)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional_pu("portc0"),0)); package->assign_pin(17, m_porta->addPin(new IO_bi_directional_pu("porta2"),2)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional_pu("porta1"),1)); package->assign_pin(19, m_porta->addPin(new IO_bi_directional_pu("porta0"),0)); package->assign_pin(20, 0); //VSS tmr1l.setIOpin(&(*m_portc)[0]); } Processor * P16F631::construct(const char *name) { P16F631 *p = new P16F631(name); if(verbose) cout << " P16F631 construct\n"; p->create(128); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F631::create(int eesize) { create_iopin_map(); _14bit_processor::create(); osccon = new OSCCON(this, "osccon", "OSC Control"); e = new EEPROM_WIDE(this,pir2); e->initialize(eesize); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F631::create_sfr_map(); } void P16F631::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } //------------------------------------------------------------------- void P16F631::create_sfr_map() { pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); add_file_registers(0x40, 0x7f, 0); alias_file_registers(0x70, 0x7f, 0x80); alias_file_registers(0x70, 0x7f, 0x100); alias_file_registers(0x70, 0x7f, 0x180); add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); alias_file_registers(0x00,0x00,0x100); alias_file_registers(0x00,0x00,0x180); add_sfr_register(&tmr0, 0x01); alias_file_registers(0x01,0x01,0x100); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); alias_file_registers(0x81,0x81,0x100); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); alias_file_registers(0x02,0x04,0x100); alias_file_registers(0x02,0x04,0x180); add_sfr_register(m_porta, 0x05); add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0)); add_sfr_register(m_portb, 0x06); add_sfr_register(m_trisb, 0x86, RegisterValue(0xf0,0)); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); alias_file_registers(0x05,0x07,0x100); alias_file_registers(0x85,0x87,0x100); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x00b, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); alias_file_registers(0x0a,0x0b,0x100); alias_file_registers(0x0a,0x0b,0x180); add_sfr_register(pir1, 0x0c, RegisterValue(0,0)); add_sfr_register(pir2, 0x0d, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0), "tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0), "tmr1h"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); add_sfr_register(&pcon, 0x8e, RegisterValue(0,0)); add_sfr_register(&wdtcon, 0x97, RegisterValue(0x08,0)); add_sfr_register(osccon, 0x8f, RegisterValue(0x60,0)); add_sfr_register(&vrcon, 0x118, RegisterValue(0,0),"vrcon"); add_sfr_register(comparator.cmxcon0[0], 0x119, RegisterValue(0,0), "cm1con0"); add_sfr_register(comparator.cmxcon0[1], 0x11a, RegisterValue(0,0), "cm2con0"); add_sfr_register(comparator.cmxcon1[1], 0x11b, RegisterValue(2,0), "cm2con1"); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[2], &(*m_portc)[4]); comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[1], &(*m_portc)[1], &(*m_portc)[2], &(*m_portc)[3]); comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[0], &(*m_portc)[0]); comparator.cmxcon1[0]->setBitMask(0x03); comparator.cmxcon0[0]->setBitMask(0xb7); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, PIR2v2::C1IF)); comparator.cmxcon0[1]->setBitMask(0xb7); comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, PIR2v2::C2IF)); comparator.cmxcon1[0]->set_vrcon(&vrcon); comparator.cmxcon1[1] = comparator.cmxcon1[0]; comparator.assign_tmr1l(&tmr1l); add_sfr_register(&ansel, 0x11e, RegisterValue(0xff,0)); add_sfr_register(&srcon, 0x19e, RegisterValue(0,0),"srcon"); ansel.setAdcon1(&adcon1); ansel.setValidBits(0xff); adcon1.setNumberOfChannels(12); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(4, &(*m_portc)[0]); adcon1.setIOPin(5, &(*m_portc)[1]); adcon1.setIOPin(6, &(*m_portc)[2]); adcon1.setIOPin(7, &(*m_portc)[3]); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; // FIXME -- can't delete this new'd item tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v3::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; tmr1l.setIOpin(&(*m_porta)[5]); tmr1l.setGatepin(&(*m_porta)[4]); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); pie2.setPir(pir2); get_eeprom()->get_reg_eedata()->new_name("eedat"); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); add_sfr_register(m_wpua, 0x95, RegisterValue(0x37,0),"wpua"); add_sfr_register(m_wpub, 0x115, RegisterValue(0xf0,0),"wpub"); add_sfr_register(m_ioca, 0x96, RegisterValue(0,0),"ioca"); add_sfr_register(m_iocb, 0x116, RegisterValue(0,0),"iocb"); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); } //------------------------------------------------------------------- void P16F631::option_new_bits_6_7(unsigned int bits) { m_wpua->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); m_wpub->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); m_porta->setIntEdge((bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); } //------------------------------------------------------------------- void P16F631::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new ConfigF631(this)); wdt.initialize(true); // default WDT enabled wdt.set_timeout(0.000035); set_config_word(0x2007, 0x3fff); }; //------------------------------------------------------------------- bool P16F631::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<2, CFG_WDTE = 1<<3, CFG_MCLRE = 1<<5, CFG_IESO = 1<<10, }; if(address == config_word_address()) { unsigned int valid_pins = m_porta->getEnableMask(); if ((cfg_word & CFG_MCLRE) == CFG_MCLRE) { assignMCLRPin(4); } else { unassignMCLRPin(); } wdt.initialize((cfg_word & CFG_WDTE) == CFG_WDTE); set_int_osc(false); // AnalogReq is used so ADC does not change clock names // set_config_word is first called with default and then // often called a second time. the following call is to // reset porta so next call to AnalogReq sill set the pin name // (&(*m_porta)[4])->AnalogReq((Register *)this, false, "porta4"); valid_pins |= 0x20; unsigned int fosc = cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2); if (osccon) { osccon->set_config_xosc(fosc < 3); osccon->set_config_irc(fosc == 4 || fosc == 5); osccon->set_config_ieso(cfg_word & CFG_IESO); } switch(fosc) { case 0: // LP oscillator: low power crystal is on RA4 and RA5 case 1: // XT oscillator: crystal/resonator is on RA4 and RA5 case 2: // HS oscillator: crystal/resonator is on RA4 and RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "OSC2"); (m_porta->getPin(5))->newGUIname("OSC1"); valid_pins &= 0xcf; break; case 3: // EC I/O on RA4 pin, CLKIN on RA5 (m_porta->getPin(5))->newGUIname("CLKIN"); valid_pins &= 0xef; break; case 5: // INTOSC CLKOUT on RA4 pin (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); case 4: // INTOSC (m_porta->getPin(5))->newGUIname("porta5"); set_int_osc(true); osccon->set_rc_frequency(); break; case 6: //RC oscillator: I/O on RA4 pin, RC on RA5 (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; case 7: // RC oscillator: CLKOUT on RA4 pin, RC on RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; }; if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_trisa->setEnableMask(valid_pins & 0xf7); } return(true); } return false; } //======================================================================== // // Pic 16F684 // P16F684::P16F684(const char *_name, const char *desc) : _14bit_processor(_name, desc), comparator(this), t1con(this, "t1con", "TMR1 Control"), t2con(this, "t2con", "TMR2 Control"), pie1(this,"pie1", "Peripheral Interrupt Enable"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), osctune(this, "osctune", "OSC Tune"), pcon(this, "pcon", "pcon"), wdtcon(this, "wdtcon", "WDT Control", 0x1f), osccon(0), ansel(this,"ansel", "Analog Select"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), eccpas(this, "eccpas", "ECCP Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register"), pstrcon(this, "pstrcon", "Pulse Sterring Control Register"), intcon_reg(this,"intcon","Interrupt Control") { if(verbose) cout << "P16F684 constructor, type = " << isa() << '\n'; pir1_3_reg = new PIR1v3(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir1 = pir1_3_reg; pir1->valid_bits = pir1->writable_bits = 0xff; m_ioca = new IOC(this, "ioca", "Interrupt-On-Change GPIO Register"); m_porta = new PicPortGRegister(this,"porta","",&intcon_reg, m_ioca, 8,0x3f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); m_wpua = new WPU(this, "wpua", "Weak Pull-up Register", m_porta, 0x37); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); m_portc = new PicPortRegister(this,"portc","",8,0x3f); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false); } P16F684::~P16F684() { if (verbose) cout << __FUNCTION__ << endl; unassignMCLRPin(); delete_file_registers(0x20, 0x7f); delete_file_registers(0xa0, 0xbf); remove_sfr_register(&tmr0); remove_sfr_register(&intcon_reg); remove_sfr_register(pir1); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&t1con); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pwm1con); remove_sfr_register(&eccpas); remove_sfr_register(&wdtcon); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.cmcon1); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&pie1); remove_sfr_register(&pcon); remove_sfr_register(osccon); remove_sfr_register(&osctune); remove_sfr_register(&ansel); remove_sfr_register(&pr2); remove_sfr_register(&comparator.vrcon); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&adresl); remove_sfr_register(&adcon1); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); delete_sfr_register(m_ioca); delete_sfr_register(m_wpua); delete_sfr_register(pir1_3_reg); delete e; } void P16F684::create_iopin_map(void) { package = new Package(14); if(!package) return; package->assign_pin(1, 0); // Vdd package->assign_pin( 2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IOPIN("porta3"),3)); package->assign_pin( 5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5)); package->assign_pin( 6, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin( 7, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin( 8, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin( 9, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(10, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(11, m_porta->addPin(new IO_bi_directional_pu("porta2"),2)); package->assign_pin(12, m_porta->addPin(new IO_bi_directional_pu("porta1"),1)); package->assign_pin(13, m_porta->addPin(new IO_bi_directional_pu("porta0"),0)); package->assign_pin(14, 0); //VSS tmr1l.setIOpin(&(*m_portc)[0]); } Processor * P16F684::construct(const char *name) { P16F684 *p = new P16F684(name); if(verbose) cout << " P16F684 construct\n"; p->create(256); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F684::create(int eesize) { create_iopin_map(); _14bit_processor::create(); osccon = new OSCCON(this, "osccon", "OSC Control"); e = new EEPROM_WIDE(this,pir1); e->initialize(eesize); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F684::create_sfr_map(); } void P16F684::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } //------------------------------------------------------------------- void P16F684::create_sfr_map() { pir_set_def.set_pir1(pir1); add_file_registers(0x20, 0x7f, 0); add_file_registers(0xa0, 0xbf, 0); alias_file_registers(0x70, 0x7f, 0x80); add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); add_sfr_register(&tmr0, 0x01); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); add_sfr_register(m_porta, 0x05); add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0)); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x00b, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); add_sfr_register(pir1, 0x0c, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0), "tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0), "tmr1h"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&ccpr1l, 0x13, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x14, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x15, RegisterValue(0,0)); add_sfr_register(&pwm1con, 0x16, RegisterValue(0,0)); add_sfr_register(&eccpas, 0x17, RegisterValue(0,0)); add_sfr_register(&wdtcon, 0x18, RegisterValue(0x08,0)); add_sfr_register(&comparator.cmcon, 0x19, RegisterValue(0,0), "cmcon0"); add_sfr_register(&comparator.cmcon1, 0x1a, RegisterValue(0,0), "cmcon1"); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); add_sfr_register(&pcon, 0x8e, RegisterValue(0,0)); add_sfr_register(osccon, 0x8f, RegisterValue(0x60,0)); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); add_sfr_register(&ansel, 0x91, RegisterValue(0xff,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); add_sfr_register(m_wpua, 0x95, RegisterValue(0x37,0),"wpua"); add_sfr_register(m_ioca, 0x96, RegisterValue(0,0),"ioca"); add_sfr_register(&comparator.vrcon, 0x99, RegisterValue(0,0),"vrcon"); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x9a); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x9b); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x9c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x9d); add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); ansel.setAdcon1(&adcon1); ansel.setValidBits(0xff); // Link the comparator and voltage ref to porta comparator.initialize(&pir_set_def, NULL, &(*m_porta)[0], &(*m_porta)[1], // AN0 AN1 0, 0, &(*m_porta)[2], &(*m_portc)[4]); //OUT0 OUT1 comparator.cmcon.setINpin(2, &(*m_portc)[0], "an4"); //AN4 comparator.cmcon.setINpin(3, &(*m_portc)[1], "an5"); //AN5 comparator.cmcon.set_tmrl(&tmr1l); comparator.cmcon1.set_tmrl(&tmr1l); comparator.cmcon.set_configuration(1, 0, AN0, AN1, AN0, AN1, ZERO); comparator.cmcon.set_configuration(2, 0, AN2, AN3, AN2, AN3, ZERO); comparator.cmcon.set_configuration(1, 1, AN1, AN2, AN0, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 1, AN3, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 2, AN1, VREF, AN0, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN3, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 3, AN3, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 4, AN1, AN0, AN1, AN0, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN3, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 5, AN3, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 6, AN1, AN2, AN1, AN2, OUT0); comparator.cmcon.set_configuration(2, 6, AN3, AN2, AN3, AN2, OUT1); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.vrcon.setValidBits(0xaf); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(7); adcon0.setChannel_shift(2); adcon1.setAdcon0(&adcon0); // VCFG0, VCFG1 in adcon0 adcon1.setNumberOfChannels(8); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[4]); adcon1.setIOPin(4, &(*m_portc)[0]); adcon1.setIOPin(5, &(*m_portc)[1]); adcon1.setIOPin(6, &(*m_portc)[2]); adcon1.setIOPin(7, &(*m_portc)[3]); adcon1.setVrefHiConfiguration(2, 1); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; // FIXME -- can't delete this new'd item tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v3::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; tmr1l.setIOpin(&(*m_porta)[5]); tmr1l.setGatepin(&(*m_porta)[4]); if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); pr2.tmr2 = &tmr2; eccpas.setIOpin(0, 0, &(*m_portc)[5]); eccpas.link_registers(&pwm1con, &ccp1con); ccp1con.setIOpin(&(*m_portc)[5], &(*m_portc)[4], &(*m_portc)[3], &(*m_portc)[2]); ccp1con.setBitMask(0xff); ccp1con.pstrcon = &pstrcon; ccp1con.pwm1con = &pwm1con; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; osccon->set_osctune(&osctune); osctune.set_osccon(osccon); } //------------------------------------------------------------------- void P16F684::option_new_bits_6_7(unsigned int bits) { m_wpua->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); m_porta->setIntEdge((bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); } //------------------------------------------------------------------- void P16F684::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new ConfigF631((P16F631*)this)); wdt.initialize(true); // default WDT enabled wdt.set_timeout(0.000035); set_config_word(0x2007, 0x3fff); }; //------------------------------------------------------------------- bool P16F684::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<2, CFG_WDTE = 1<<3, CFG_MCLRE = 1<<5, CFG_IESO = 1<<11, }; if(address == config_word_address()) { config_clock_mode = (cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2)); if (osccon) { osccon->set_config_xosc(config_clock_mode < 3); osccon->set_config_irc(config_clock_mode == 4 || config_clock_mode == 5); osccon->set_config_ieso(cfg_word & CFG_IESO); } unsigned int valid_pins = m_porta->getEnableMask(); if ((cfg_word & CFG_MCLRE) == CFG_MCLRE) { assignMCLRPin(4); } else { unassignMCLRPin(); } wdt.initialize((cfg_word & CFG_WDTE) == CFG_WDTE); set_int_osc(false); // AnalogReq is used so ADC does not change clock names // set_config_word is first called with default and then // often called a second time. the following call is to // reset porta so next call to AnalogReq sill set the pin name // (&(*m_porta)[4])->AnalogReq((Register *)this, false, "porta4"); valid_pins |= 0x20; switch(config_clock_mode) { case 0: // LP oscillator: low power crystal is on RA4 and RA5 case 1: // XT oscillator: crystal/resonator is on RA4 and RA5 case 2: // HS oscillator: crystal/resonator is on RA4 and RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "OSC2"); (m_porta->getPin(5))->newGUIname("OSC1"); valid_pins &= 0xcf; break; case 3: // EC I/O on RA4 pin, CLKIN on RA5 (m_porta->getPin(5))->newGUIname("CLKIN"); valid_pins &= 0xef; break; case 5: // INTOSC CLKOUT on RA4 pin (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); case 4: // INTOSC (m_porta->getPin(5))->newGUIname("porta5"); set_int_osc(true); osccon->set_rc_frequency(); break; case 6: //RC oscillator: I/O on RA4 pin, RC on RA5 (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; case 7: // RC oscillator: CLKOUT on RA4 pin, RC on RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; }; if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_trisa->setEnableMask(valid_pins); } return(true); } return false; } //======================================================================== // // Pic 16F677 // Processor * P16F677::construct(const char *name) { P16F677 *p = new P16F677(name); p->create(256); p->set_hasSSP(); p->create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F677::P16F677(const char *_name, const char *desc) : P16F631(_name,desc), ssp(this), anselh(this,"anselh", "Analog Select high"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low") { if(verbose) cout << "f677 constructor, type = " << isa() << '\n'; } P16F677::~P16F677() { delete_file_registers(0x20,0x3f); delete_file_registers(0xa0,0xbf); remove_sfr_register(&anselh); if (hasSSP()) { remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspstat); } remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); delete m_cvref; delete m_v06ref; } void P16F677::create_symbols(void) { if(verbose) cout << "creating f677 symbols\n"; P16F631::create_symbols(); } void P16F677::create_sfr_map() { ansel.setAdcon1(&adcon1); ansel.setAnselh(&anselh); anselh.setAdcon1(&adcon1); anselh.setAnsel(&ansel); anselh.setValidBits(0x0f); ansel.setValidBits(0xff); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(0xf); adcon0.setChannel_shift(2); adcon0.setGo(1); adcon0.setValidBits(0xff); adcon1.setValidBits(0xb0); adcon1.setAdcon0(&adcon0); adcon1.setNumberOfChannels(14); adcon1.setValidCfgBits(ADCON1::VCFG0 , 6); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[4]); adcon1.setIOPin(8, &(*m_portc)[6]); adcon1.setIOPin(9, &(*m_portc)[7]); adcon1.setIOPin(10, &(*m_portb)[4]); adcon1.setIOPin(11, &(*m_portb)[5]); adcon1.setVoltRef(12, 0.0); adcon1.setVoltRef(13, 0.0); m_cvref = new a2d_stimulus(&adcon1, 12, "a2d_cvref"); m_v06ref = new a2d_stimulus(&adcon1, 13, "a2d_v06ref"); ((Processor *)this)->CVREF->attach_stimulus(m_cvref); ((Processor *)this)->V06REF->attach_stimulus(m_v06ref); // set a2d modes where an1 is Vref+ adcon1.setVrefHiConfiguration(2, 1); add_sfr_register(&anselh, 0x11f, RegisterValue(0x0f,0)); add_file_registers(0x20,0x3f,0); add_file_registers(0xa0,0xbf,0); // ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]); if (hasSSP()) { add_sfr_register(&ssp.sspbuf, 0x13, RegisterValue(0,0),"sspbuf"); add_sfr_register(&ssp.sspcon, 0x14, RegisterValue(0,0),"sspcon"); add_sfr_register(&ssp.sspadd, 0x93, RegisterValue(0,0),"sspadd"); add_sfr_register(&ssp.sspstat, 0x94, RegisterValue(0,0),"sspstat"); ssp.initialize( get_pir_set(), // PIR &(*m_portb)[6], // SCK &(*m_portc)[6], // SS &(*m_portc)[7], // SDO &(*m_portb)[4], // SDI m_trisb, // i2c tris port SSP_TYPE_SSP ); } add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); } //======================================================================== // // Pic 16F685 // Processor * P16F685::construct(const char *name) { P16F685 *p = new P16F685(name); p->create(256); p->create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F685::P16F685(const char *_name, const char *desc) : P16F677(_name,desc), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), pcon(this, "pcon", "pcon"), eccpas(this, "eccpas", "ECCP Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register"), pstrcon(this, "pstrcon", "Pulse Sterring Control Register") { if(verbose) cout << "f685 constructor, type = " << isa() << '\n'; set_hasSSP(); } P16F685::~P16F685() { delete_file_registers(0xc0,0xef); delete_file_registers(0x120,0x16f); remove_sfr_register(&pstrcon); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&pr2); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pwm1con); remove_sfr_register(&eccpas); } void P16F685::create_symbols(void) { if(verbose) cout << "creating f685 symbols\n"; P16F677::create_symbols(); } void P16F685::create_sfr_map() { P16F677::create_sfr_map(); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e ); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); // Enable program memory reads and writes. get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); pr2.tmr2 = &tmr2; eccpas.setIOpin(0, 0, &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); add_sfr_register(&pstrcon, 0x19d, RegisterValue(1,0)); ccp1con.setIOpin(&(*m_portc)[5], &(*m_portc)[4], &(*m_portc)[3], &(*m_portc)[2]); ccp1con.setBitMask(0xff); ccp1con.pstrcon = &pstrcon; ccp1con.pwm1con = &pwm1con; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; add_sfr_register(&ccpr1l, 0x15, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x16, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x17, RegisterValue(0,0)); add_sfr_register(&pwm1con, 0x1c, RegisterValue(0,0)); add_sfr_register(&eccpas, 0x1d, RegisterValue(0,0)); // add_file_registers(0x20,0x3f,0); // add_file_registers(0xa0,0xef,0); add_file_registers(0xc0,0xef,0); add_file_registers(0x120,0x16f,0); } //======================================================================== // // Pic 16F687 // Processor * P16F687::construct(const char *name) { P16F687 *p = new P16F687(name); p->create(256); p->create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F687::P16F687(const char *_name, const char *desc) : P16F677(_name,desc), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), pcon(this, "pcon", "pcon"), usart(this) { if(verbose) cout << "f687 constructor, type = " << isa() << '\n'; set_hasSSP(); } P16F687::~P16F687() { remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); } void P16F687::create_symbols(void) { if(verbose) cout << "creating f687 symbols\n"; P16F677::create_symbols(); } void P16F687::create_sfr_map() { P16F677::create_sfr_map(); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); // add_file_registers(0x20,0x3f,0); // add_file_registers(0xa0,0xbf,0); usart.initialize(pir1,&(*m_portb)[7], &(*m_portb)[5], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(&usart.spbrgh, 0x9a, RegisterValue(0,0),"spbrgh"); add_sfr_register(&usart.baudcon, 0x9b,RegisterValue(0x40,0),"baudctl"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); usart.set_eusart(true); } //======================================================================== // // Pic 16F689 // Processor * P16F689::construct(const char *name) { P16F689 *p = new P16F689(name); p->create(256); p->create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F689::P16F689(const char *_name, const char *desc) : P16F687(_name,desc) { if(verbose) cout << "f689 constructor, type = " << isa() << '\n'; set_hasSSP(); } //======================================================================== // // Pic 16F690 // Processor * P16F690::construct(const char *name) { P16F690 *p = new P16F690(name); p->create(256); p->create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F690::P16F690(const char *_name, const char *desc) : P16F685(_name,desc), ccp2con(this, "ccp2con", "Capture Compare Control"), ccpr2l(this, "ccpr2l", "Capture Compare 2 Low"), ccpr2h(this, "ccpr2h", "Capture Compare 2 High"), usart(this) { if(verbose) cout << "f690 constructor, type = " << isa() << '\n'; set_hasSSP(); } P16F690::~P16F690() { remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); } void P16F690::create_symbols(void) { if(verbose) cout << "creating f690 symbols\n"; P16F685::create_symbols(); } void P16F690::create_sfr_map() { P16F685::create_sfr_map(); tmr2.ssp_module[0] = &ssp; eccpas.setIOpin(0, 0, &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); usart.initialize(pir1,&(*m_portb)[7], &(*m_portb)[5], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(&usart.spbrgh, 0x9a, RegisterValue(0,0),"spbrgh"); add_sfr_register(&usart.baudcon, 0x9b,RegisterValue(0x40,0),"baudctl"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); usart.set_eusart(true); // add_sfr_register(&pstrcon, 0x19d, RegisterValue(1,0)); } gpsim-0.30.0/src/14bit-tmrs.h0000664000076400007640000004260613111502042012507 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2009,2010,2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __14_BIT_TMRS_H__ #define __14_BIT_TMRS_H__ #include "gpsim_classes.h" #include "registers.h" #include "breakpoints.h" #include "ioports.h" #include "ssp.h" #include "interface.h" class TMRL; class TMRH; class TMR2; class CCPRL; class CCPCON; class PWM1CON; class ADCON0; class PIR_SET; class InterruptSource; class TMR1_Interface; class _14bit_processor; //--------------------------------------------------------- // Todo // // The timer base classes need to be abstracted one more // layer. The 18fxxx parts have a new timer, TMR3, that's // almost but not quite, identical to the 16fxx's TMR1. //--------------------------------------------------------- // CCPCON - Capture and Compare registers //--------------------------------------------------------- class CCPRH : public sfr_register { public: CCPRL *ccprl; bool pwm_mode; unsigned int pwm_value; CCPRH(Processor *pCpu, const char *pName, const char *pDesc=0); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); }; class CCPRL : public sfr_register { public: CCPRH *ccprh; CCPCON *ccpcon; TMRL *tmrl; void put(unsigned int new_value); void capture_tmr(); void start_compare_mode(CCPCON *ref=0); void stop_compare_mode(); bool test_compare_mode(); void start_pwm_mode(); void stop_pwm_mode(); void assign_tmr(TMRL *ptmr); CCPRL(Processor *pCpu, const char *pName, const char *pDesc=0); }; class INT_SignalSink; // I/O pin interface class PinModule; // // Enhanced Capture/Compare/PWM Auto-Shutdown control register // class ECCPAS : public sfr_register { public: /* Bit definitions for the register */ enum { PSSBD0 = 1 << 0, // Pins P1B and P1D Shutdown control bits PSSBD1 = 1 << 1, PSSAC0 = 1 << 2, // Pins P1A and P1C Shutdown control bits PSSAC1 = 1 << 3, ECCPAS0 = 1 << 4, // ECCP Auto-shutdown Source Select bits ECCPAS1 = 1 << 5, ECCPAS2 = 1 << 6, ECCPASE = 1 << 7 // ECCP Auto-Shutdown Event Status bit }; ECCPAS(Processor *pCpu, const char *pName, const char *pDesc=0); ~ECCPAS(); void put(unsigned int new_value); void put_value(unsigned int new_value); void setBitMask(unsigned int bm) { mValidBits = bm; } void setIOpin(PinModule *p0, PinModule *p1, PinModule *p2); void c1_output(int value); void c2_output(int value); void set_trig_state(int index, bool state); bool shutdown_trigger(int); void link_registers(PWM1CON *_pwm1con, CCPCON *_ccp1con); private: PWM1CON *pwm1con; CCPCON *ccp1con; PinModule *m_PinModule; INT_SignalSink *m_sink; bool trig_state[3]; int c1_state; int c2_state; int int_state; }; // // Enhanced PWM control register // class PWM1CON : public sfr_register { public: /* Bit definitions for the register */ enum { PDC0 = 1 << 0, // PWM delay count bits PDC1 = 1 << 1, PDC2 = 1 << 2, PDC3 = 1 << 3, PDC4 = 1 << 4, PDC5 = 1 << 5, PDC6 = 1 << 6, PRSEN = 1 << 7 // PWM Restart Enable bit }; PWM1CON(Processor *pCpu, const char *pName, const char *pDesc=0); ~PWM1CON(); void put(unsigned int new_value); void setBitMask(unsigned int bm) { mValidBits = bm; } private: }; // // Enhanced PWM Pulse Steering control register // class PSTRCON : public sfr_register { public: /* Bit definitions for the register */ enum { STRA = 1 << 0, // Steering enable bit A STRB = 1 << 1, // Steering enable bit B STRC = 1 << 2, // Steering enable bit C STRD = 1 << 3, // Steering enable bit D STRSYNC = 1 << 4, // Steering Sync bit }; PSTRCON(Processor *pCpu, const char *pName, const char *pDesc=0); ~PSTRCON(); void put(unsigned int new_value); private: }; //--------------------------------------------------------- // CCPCON - Capture and Compare Control register //--------------------------------------------------------- class CCPSignalSource; // I/O pin interface class CCPSignalSink; // I/O pin interface class Tristate; // I/O pin high impedance class CCP12CON; class CCPCON : public sfr_register, public TriggerObject { public: /* Bit definitions for the register */ enum { CCPM0 = 1 << 0, CCPM1 = 1 << 1, CCPM2 = 1 << 2, CCPM3 = 1 << 3, CCPY = 1 << 4, CCPX = 1 << 5, P1M0 = 1 << 6, // CCP1 EPWM Output config bits 16f88x P1M1 = 1 << 7 }; /* Define the Modes (based on the CCPM bits) */ enum { ALL_OFF0 = 0, ALL_OFF1 = 1, ALL_OFF2 = 2, ALL_OFF3 = 3, CAP_FALLING_EDGE = 4, CAP_RISING_EDGE = 5, CAP_RISING_EDGE4 = 6, CAP_RISING_EDGE16 = 7, COM_SET_OUT = 8, COM_CLEAR_OUT = 9, COM_INTERRUPT = 0xa, COM_TRIGGER = 0xb, PWM0 = 0xc, PWM1 = 0xd, PWM2 = 0xe, PWM3 = 0xf }; void setBitMask(unsigned int bv) { mValidBits = bv; } void new_edge(unsigned int level); void compare_match(); void pwm_match(int new_state); void drive_bridge(int level, int new_value); void shutdown_bridge(int eccpas); void put(unsigned int new_value); char getState(); bool test_compare_mode(); void callback(); void releasePins(int); void releaseSink(); void setCrosslinks(CCPRL *, PIR *, unsigned int _mask, TMR2 *, ECCPAS *_eccpas=0); void setADCON(ADCON0 *); CCPCON(Processor *pCpu, const char *pName, const char *pDesc=0); ~CCPCON(); void setIOpin(PinModule *p1, PinModule *p2=0, PinModule *p3=0, PinModule *p4=0); void setIOPin1(PinModule *p1); void setIOPin2(PinModule *p2); void set_tmr2(TMR2 *_tmr2) { tmr2 = _tmr2;} PSTRCON *pstrcon; PWM1CON *pwm1con; ECCPAS *eccpas; protected: PinModule *m_PinModule[4]; CCPSignalSource *m_source[4]; bool source_active[4]; CCPSignalSink *m_sink; Tristate *m_tristate; bool m_bInputEnabled; // Input mode for capture/compare bool m_bOutputEnabled; // Output mode for PWM char m_cOutputState; int edges; guint64 future_cycle; bool delay_source0, delay_source1; bool bridge_shutdown; CCPRL *ccprl; PIR *pir; TMR2 *tmr2; ADCON0 *adcon0; unsigned int pir_mask; }; class TRISCCP : public sfr_register { public: TRISCCP(Processor *pCpu, const char *pName, const char *pDesc=0); enum { TT1CK = 1<<0, TCCP = 1<<2 }; void put(unsigned int value); private: bool first; }; class DATACCP : public sfr_register { public: DATACCP(Processor *pCpu, const char *pName, const char *pDesc=0); enum { TT1CK = 1<<0, DCCP = 1<<2 }; void put(unsigned int value); private: bool first; }; class TMR1_Freq_Attribute; //--------------------------------------------------------- // T1CON - Timer 1 control register class T1CON : public sfr_register { public: enum { TMR1ON = 1<<0, TMR1CS = 1<<1, T1SYNC = 1<<2, T1OSCEN = 1<<3, T1CKPS0 = 1<<4, T1CKPS1 = 1<<5, T1RD16 = 1<<6, TMR1GE = 1<<6, // TMR1 Gate Enable used if TMR1L::setGatepin() has been called T1GINV = 1<<7 }; TMRL *tmrl; TMR1_Freq_Attribute *freq_attribute; Processor *cpu; T1CON(Processor *pCpu, const char *pName, const char *pDesc=0); ~T1CON(); unsigned int get(); // For (at least) the 18f family, there's a 4X PLL that effects the // the relative timing between gpsim's cycle counter (which is equivalent // to the cumulative instruction count) and the external oscillator. In // all parts, the clock source for the timer is fosc, the external oscillator. // However, for the 18f parts, the instructions execute 4 times faster when // the PLL is selected. virtual unsigned int get_prescale(); virtual unsigned int get_tmr1cs() { return((value.get() & TMR1CS)?2:0); } virtual bool get_tmr1on() { return(value.get() & TMR1ON); } virtual bool get_t1oscen() { return(value.get() & T1OSCEN); } virtual bool get_tmr1GE() { return(value.get() & TMR1GE); } virtual bool get_t1GINV() { return(value.get() & T1GINV); } virtual bool get_t1sync() { return(value.get() & T1SYNC); } virtual void put(unsigned int new_value); double t1osc(); }; class T1GCon_GateSignalSink; class T1CON_G; // Timer 1 gate control Register class T1GCON : public sfr_register { public: enum { T1GSS0 = 1<<0, // Gate source select bits T1GSS1 = 1<<1, T1GVAL = 1<<2, // Current state bit T1GGO = 1<<3, // Gate Single-Pulse Acquisition Status bit T1GSPM = 1<<4, // Gate Single-Pulse Mode bit T1GTM = 1<<5, // Gate Toggle Mode bit T1GPOL = 1<<6, // Gate Polarity bit TMR1GE = 1<<7, // Gate Enable bit }; void put(unsigned int new_value); virtual void setGatepin(PinModule *); virtual void PIN_gate(bool); virtual void T0_gate(bool); virtual void T2_gate(bool); virtual void CM1_gate(bool); virtual void CM2_gate(bool); virtual void new_gate(bool); void set_WRmask(unsigned int mask) { write_mask = mask;} void set_tmrl(TMRL *_tmrl) { tmrl = _tmrl;} virtual void setInterruptSource(InterruptSource * _int) { m_Interrupt = _int;} virtual InterruptSource * getInterruptSource() { return m_Interrupt; } virtual bool get_tmr1GE() { return(value.get() & TMR1GE); } bool get_t1GPOL() { return (value.get() & T1GPOL); } virtual bool tmr1_isON(); T1GCON(Processor *pCpu, const char *pName, const char *pDesc=0, T1CON_G *t1con_g=0); ~T1GCON(); private: T1GCon_GateSignalSink *sink; unsigned int write_mask; TMRL *tmrl; T1CON_G *t1con_g; InterruptSource *m_Interrupt; bool PIN_gate_state; bool T0_gate_state; // can also be Tx = PRx where x=2,4,6 bool CM1_gate_state; bool CM2_gate_state; bool last_t1g_in; PinModule *gate_pin; }; // // T1CON_G combines T1CON and T1GCON into one virtual register // class T1CON_G : public T1CON { public: enum { TMR1ON = 1<<0, T1SYNC = 1<<2, T1OSCEN = 1<<3, T1CKPS0 = 1<<4, T1CKPS1 = 1<<5, TMR1CS0 = 1<<6, TMR1CS1 = 1<<7, }; TMRL *tmrl; TMR1_Freq_Attribute *freq_attribute; T1CON_G(Processor *pCpu, const char *pName, const char *pDesc=0); ~T1CON_G(); void t1_cap_increment(); // RRR unsigned int get(); // For (at least) the 18f family, there's a 4X PLL that effects the // the relative timing between gpsim's cycle counter (which is equivalent // to the cumulative instruction count) and the external oscillator. In // all parts, the clock source for the timer is fosc, the external oscillator. // However, for the 18f parts, the instructions execute 4 times faster when // the PLL is selected. virtual unsigned int get_prescale() { return( ((value.get() &(T1CKPS0 | T1CKPS1)) >> 4) );} virtual unsigned int get_tmr1cs() { return((value.get() & (TMR1CS1 | TMR1CS0))>>6); } virtual bool get_tmr1on() { return(value.get() & TMR1ON); } virtual bool get_t1oscen() { return(value.get() & T1OSCEN); } virtual bool get_t1sync() { return(value.get() & T1SYNC); } virtual void put(unsigned int new_value); virtual bool get_tmr1GE() { return t1gcon.get_tmr1GE(); } virtual bool get_t1GINV() { return true;} T1GCON t1gcon; }; //--------------------------------------------------------- // TMRL & TMRH - Timer 1 class TMRH : public sfr_register { public: TMRL *tmrl; void put(unsigned int new_value); unsigned int get(); virtual unsigned int get_value(); TMRH(Processor *pCpu, const char *pName, const char *pDesc=0); }; class TMR1CapComRef; class TMRL : public sfr_register, public TriggerObject, public SignalSink { public: TMRH *tmrh; T1CON *t1con; unsigned int prescale, prescale_counter, break_value, value_16bit; /* Low and high concatenated */ double ext_scale; TMR1CapComRef * compare_queue; guint64 synchronized_cycle, future_cycle; gint64 last_cycle; // last_cycle can be negative for small cycle counts virtual void callback(); virtual void callback_print(); TMRL(Processor *pCpu, const char *pName, const char *pDesc=0); ~TMRL(); void set_ext_scale(); virtual void release(); virtual void put(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); virtual unsigned int get_low_and_high(); virtual void on_or_off(int new_state); virtual void current_value(); virtual void new_clock_source(); virtual void update(); virtual void clear_timer(); virtual void setSinkState(char); virtual void setIOpin(PinModule *); virtual void setGatepin(PinModule *); virtual void IO_gate(bool); virtual void compare_gate(bool); virtual void setInterruptSource(InterruptSource *); virtual InterruptSource * getInterruptSource() { return m_Interrupt; } virtual void sleep(); virtual void wake(); void set_compare_event ( unsigned int value, CCPCON *host ); void clear_compare_event ( CCPCON *host ); void set_T1GSS(bool arg); virtual void increment(); // Used when TMR1 is attached to an external clock private: TMR1_Interface *tmr1_interface; char m_cState; bool m_GateState; // Only changes state if setGatepin() has been called bool m_compare_GateState; bool m_io_GateState; bool m_bExtClkEnabled; bool m_sleeping; bool m_t1gss; // T1 gate source // true - IO pin controls gate, // false - compare controls gate InterruptSource *m_Interrupt; }; class PR2 : public sfr_register { public: TMR2 *tmr2; PR2(Processor *pCpu, const char *pName, const char *pDesc=0); void put(unsigned int new_value); }; //--------------------------------------------------------- // T2CON - Timer 2 control register class T2CON : public sfr_register { public: enum { T2CKPS0 = 1<<0, T2CKPS1 = 1<<1, TMR2ON = 1<<2, TOUTPS0 = 1<<3, TOUTPS1 = 1<<4, TOUTPS2 = 1<<5, TOUTPS3 = 1<<6 }; TMR2 *tmr2; T2CON(Processor *pCpu, const char *pName, const char *pDesc=0); inline unsigned int get_t2ckps0() { return(value.get() & T2CKPS0); } inline unsigned int get_t2ckps1() { return(value.get() & T2CKPS1); } inline unsigned int get_tmr2on() { return(value.get() & TMR2ON); } inline unsigned int get_post_scale() { return( (value.get() & (TOUTPS0 | TOUTPS1 | TOUTPS2 | TOUTPS3)) >> 3 ); } inline unsigned int get_pre_scale() { // ps1:ps0 prescale // 0 0 1 // 0 1 4 // 1 x 16 if(value.get() & T2CKPS1) return 16; else if(value.get() & T2CKPS0) return 4; else return 1; } void put(unsigned int new_value); }; #define MAX_PWM_CHANS 5 //--------------------------------------------------------- // TMR2 - Timer class TMR2 : public sfr_register, public TriggerObject { protected: CCPCON * ccp[MAX_PWM_CHANS]; public: /* Define the way in which the tmr2 callback function may be updated. */ enum TMR2_UPDATE_TYPES { TMR2_WRAP = 1<<0, // wrap TMR2 TMR2_PR2_UPDATE = 1<<1, // update pr2 match TMR2_PWM1_UPDATE = 1<<2, // wrt ccp1 // TMR2_PWM2_UPDATE = 1<<3, // wrt ccp2 // PWM must be last as a variable number of channels follows TMR2_ANY_PWM_UPDATE = 0xfc, // up to six PWM channels TMR2_DONTCARE_UPDATE = 0xff // whatever comes next }; int pwm_mode; int update_state; int last_update; unsigned int prescale, prescale_counter, break_value, duty_cycle[MAX_PWM_CHANS]; /* for ccp channels */ int post_scale; guint64 last_cycle; guint64 future_cycle; PR2 *pr2; PIR_SET *pir_set; T2CON *t2con; SSP_MODULE *ssp_module[2]; T1GCON *m_txgcon; virtual void callback(); virtual void callback_print(); TMR2(Processor *pCpu, const char *pName, const char *pDesc=0); ~TMR2(); virtual unsigned int max_counts() {return 256;}; void put(unsigned int new_value); unsigned int get(); void on_or_off(int new_state); void start(); void new_pre_post_scale(); void new_pr2(unsigned int new_value); void current_value(); void update(int ut = TMR2_DONTCARE_UPDATE); void pwm_dc(unsigned int dc, unsigned int ccp_address); void stop_pwm(unsigned int ccp_address); virtual unsigned int get_value(); virtual void setInterruptSource(InterruptSource * _int) { m_Interrupt = _int;} virtual InterruptSource * getInterruptSource() { return m_Interrupt; } bool add_ccp ( CCPCON * _ccp ); bool rm_ccp(CCPCON *_ccp); InterruptSource *m_Interrupt; }; //--------------------------------------------------------- // // TMR2_MODULE // // class TMR2_MODULE { public: _14bit_processor *cpu; char * name_str; T2CON *t2con; PR2 *pr2; TMR2 *tmr2; TMR2_MODULE(); void initialize(T2CON *t2con, PR2 *pr2, TMR2 *tmr2); }; //--------------------------------------------------------- // // TMR1_MODULE // // class TMR1_MODULE { public: _14bit_processor *cpu; char * name_str; T1CON *t1con; PIR_SET *pir_set; TMR1_MODULE(); void initialize(T1CON *t1con, PIR_SET *pir_set); }; #endif gpsim-0.30.0/src/lxt_write.h0000664000076400007640000001075013041763613012634 00000000000000/* * Copyright (c) 2001 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_LXT_H #define DEFS_LXT_H #include #include #include #include #include #define LT_HDRID (0x0138) #define LT_VERSION (0x0001) #define LT_TRLID (0xB4) #define LT_CLKPACK (4) #define LT_MVL_2 (1<<0) #define LT_MVL_4 (1<<1) #define LT_MVL_9 (1<<2) struct lt_timetrail { struct lt_timetrail *next; int timeval; unsigned int position; }; #define LT_SYMPRIME 65519 #define LT_SECTION_END (0) #define LT_SECTION_CHG (1) #define LT_SECTION_SYNC_TABLE (2) #define LT_SECTION_FACNAME (3) #define LT_SECTION_FACNAME_GEOMETRY (4) #define LT_SECTION_TIMESCALE (5) #define LT_SECTION_TIME_TABLE (6) #define LT_SECTION_INITIAL_VALUE (7) #define LT_SECTION_DOUBLE_TEST (8) struct lt_trace { FILE *handle; unsigned int position; struct lt_symbol *sym[LT_SYMPRIME]; struct lt_symbol **sorted_facs; struct lt_symbol *symchain; int numfacs; int numfacbytes; int longestname; int mintime, maxtime; int timescale; int initial_value; struct lt_timetrail *timehead, *timecurr, *timebuff; int timechangecount; char double_used; char do_strip_brackets; char clock_compress; unsigned int change_field_offset; unsigned int facname_offset; unsigned int facgeometry_offset; unsigned int time_table_offset; unsigned int sync_table_offset; unsigned int initial_value_offset; unsigned int timescale_offset; unsigned int double_test_offset; char *compress_fac_str; int compress_fac_len; int timeval; /* for clock induction */ }; struct lt_symbol { struct lt_symbol *next; struct lt_symbol *symchain; char *name; int namlen; int facnum; struct lt_symbol *aliased_to; unsigned int rows; int msb, lsb; int len; int flags; unsigned int last_change; int clk_delta; int clk_prevtrans; int clk_numtrans; char clk_prevval; }; #define LT_SYM_F_BITS (0) #define LT_SYM_F_INTEGER (1<<0) #define LT_SYM_F_DOUBLE (1<<1) #define LT_SYM_F_STRING (1<<2) #define LT_SYM_F_ALIAS (1<<3) struct lt_trace * lt_init(const char *name); void lt_close(struct lt_trace *lt); struct lt_symbol * lt_symbol_find(struct lt_trace *lt, const char *name); struct lt_symbol * lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags); struct lt_symbol * lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb); void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit); void lt_set_timescale(struct lt_trace *lt, int timescale); void lt_set_initial_value(struct lt_trace *lt, char value); int lt_set_time(struct lt_trace *lt, int timeval); void lt_set_clock_compress(struct lt_trace *lt); /* * value change functions..note that if the value string len for * lt_emit_value_bit_string() is shorter than the symbol length * it will be left justified with the rightmost character used as * a repeat value that will be propagated to pad the value string out: * * "10x" for 8 bits becomes "10xxxxxx" * "z" for 8 bits becomes "zzzzzzzz" */ int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value); int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value); int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value); int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value); #endif gpsim-0.30.0/src/tmr0.h0000664000076400007640000000523013041763624011474 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __TMR0_H__ #define __TMR0_H__ #include "ioports.h" #include "interface.h" class TMR0_Interface; class T1GCON; //--------------------------------------------------------- // TMR0 - Timer class TMR0 : public sfr_register, public TriggerObject, public SignalSink { public: unsigned int prescale, prescale_counter, old_option, // Save option register contents here. state; // Either on or off right now. guint64 synchronized_cycle, future_cycle; gint64 last_cycle; // can be negative ... OPTION_REG *m_pOptionReg; virtual void callback(); TMR0(Processor *, const char *pName, const char *pDesc=0); virtual void release(); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); virtual void start(int new_value,int sync=0); virtual void stop(); virtual void increment(); // Used when tmr0 is attached to an external clock virtual void new_prescale(); virtual unsigned int get_prescale(); virtual unsigned int max_counts() {return 256;}; virtual bool get_t0cs(); virtual bool get_t0se(); virtual void set_t0if(); virtual void set_t0xcs(bool _t0xcs){t0xcs = _t0xcs;} virtual bool get_t0xcs() {return t0xcs;} virtual void reset(RESET_TYPE r); virtual void callback_print(); virtual void clear_trigger(); virtual void set_cpu(Processor *, PortRegister *, unsigned int pin,OPTION_REG *); virtual void set_cpu(Processor *new_cpu, PinModule *pin,OPTION_REG *); virtual void setSinkState(char); virtual void sleep(); virtual void wake(); void set_t1gcon(T1GCON *_t1gcon) { m_t1gcon = _t1gcon; } enum { STOPPED = 0, RUNNING = 1, SLEEPING = 2 }; protected: T1GCON *m_t1gcon; private: bool m_bLastClockedState; bool t0xcs; // clock source is the capacitive sensing oscillator TMR0_Interface *tmr0_interface; }; #endif gpsim-0.30.0/src/ui.h0000664000076400007640000001073613041763624011236 00000000000000 #ifndef __UI_H__ #define __UI_H__ #include #include #include "exports.h" #include "glib.h" #ifndef __REGISTERS_H__ #include "registers.h" #endif #include "value.h" class ISimConsole { public: virtual ~ISimConsole() { } virtual void Printf(const char *fmt, ...) = 0; virtual void VPrintf(const char *fmt, va_list argptr) = 0; virtual void Puts(const char*) = 0; virtual void Putc(const char) = 0; virtual const char* Gets(char *, int) = 0; }; class IUserInterface { public: enum { eHex, eDec, eOct, }; IUserInterface() : m_uVerbose(0) {} virtual ~IUserInterface() { } virtual ISimConsole &GetConsole() = 0; virtual void SetConsole(ISimConsole *pConsole) = 0; virtual void DisplayMessage(unsigned int uStringID, ...) = 0; virtual void DisplayMessage(FILE * pOut, unsigned int uStringID, ...) = 0; virtual void DisplayMessage(const char *fmt, ...) = 0; virtual void DisplayMessage(FILE * pOut, const char *fmt, ...) = 0; // To be implemented to test on GetVerbosity() // virtual void TraceMessage(unsigned int uStringID, ...) = 0; // virtual void TraceMessage(const char *fmt, ...) = 0; virtual const char * FormatProgramAddress(unsigned int uAddress, unsigned int uMask) = 0; virtual const char * FormatProgramAddress(unsigned int uAddress, unsigned int uMask, int iRadix) = 0; virtual const char * FormatRegisterAddress(unsigned int uAddress, unsigned int uMask) = 0; virtual const char * FormatRegisterAddress(Register *) = 0; virtual const char * FormatLabeledValue(const char * pLabel, unsigned int uValue) = 0; virtual const char * FormatValue(unsigned int uValue) = 0; virtual const char * FormatValue(gint64 uValue) = 0; virtual const char * FormatValue(gint64 uValue, guint64 uMask) = 0; virtual const char * FormatValue(gint64 uValue, guint64 uMask, int iRadix) = 0; virtual const char * FormatValue(char *str, int len, int iRegisterSize, RegisterValue value) = 0; virtual void SetProgramAddressRadix(int iRadix) = 0; virtual void SetRegisterAddressRadix(int iRadix) = 0; virtual void SetValueRadix(int iRadix) = 0; virtual void SetProgramAddressMask(unsigned int uMask) = 0; virtual void SetRegisterAddressMask(unsigned int uMask) = 0; virtual void SetValueMask(unsigned int uMask) = 0; typedef void (*FNNOTIFYEXITONBREAK)(int); virtual void SetExitOnBreak(FNNOTIFYEXITONBREAK) = 0; virtual void NotifyExitOnBreak(int iExitCode) = 0; FNNOTIFYEXITONBREAK m_pfnNotifyOnExit; inline void SetVerbosity(unsigned int uVerbose) { m_uVerbose = uVerbose; } inline unsigned int GetVerbosity() { return m_uVerbose; } inline unsigned int &GetVerbosityReference() { return m_uVerbose; } private: unsigned int m_uVerbose; }; // extern "C" IUserInterface & GetUserInterface(void); LIBGPSIM_EXPORT IUserInterface & GetUserInterface(void); LIBGPSIM_EXPORT void SetUserInterface(IUserInterface * rGpsimUI); LIBGPSIM_EXPORT void SetUserInterface(std::streambuf* pOutStreamBuf); class GlobalVerbosityAccessor { public: GlobalVerbosityAccessor() { } inline operator unsigned int() { return GetUserInterface().GetVerbosity(); } // This gives the statements if(verbose) access inline operator bool() { return GetUserInterface().GetVerbosity() != 0; } friend unsigned int operator&(const GlobalVerbosityAccessor& rVerbosity, int iValue); }; // This gives the statements if(verbose & 4) access inline unsigned int operator&(const GlobalVerbosityAccessor& rVerbosity, int iValue) { return (GetUserInterface().GetVerbosity() & iValue) != 0; } extern GlobalVerbosityAccessor verbose; /// /// Gpsim string IDs #define IDS_BREAK_READING_REG 1 #define IDS_BREAK_READING_REG_VALUE 2 #define IDS_BREAK_READING_REG_OP_VALUE 3 #define IDS_BREAK_WRITING_REG 4 #define IDS_BREAK_WRITING_REG_VALUE 5 #define IDS_BREAK_WRITING_REG_OP_VALUE 6 #define IDS_BREAK_ON_EXEC_ADDRESS 7 #define IDS_PROGRAM_FILE_PROCESSOR_NOT_KNOWN 8 #define IDS_FILE_NAME_TOO_LONG 9 #define IDS_FILE_NOT_FOUND 10 #define IDS_FILE_BAD_FORMAT 11 #define IDS_NO_PROCESSOR_SPECIFIED 12 #define IDS_PROCESSOR_INIT_FAILED 13 #define IDS_FILE_NEED_PROCESSOR_SPECIFIED 14 #define IDS_LIST_FILE_NOT_FOUND 15 #define IDS_HIT_BREAK 16 #define IDS_LAST_VALID_GPSIM_ID 17 #endif gpsim-0.30.0/src/16bit-tmrs.h0000664000076400007640000000704413041763624012527 00000000000000/* Copyright (C) 2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __16_BIT_TMRS_H__ #define __16_BIT_TMRS_H__ #include "14bit-tmrs.h" //--------------------------------------------------------- // T5CON - Timer 1,3,5 control register class T5CON : public T1CON { public: enum { TMRxON = 1<<0, TxRD16 = 1<<1, TxSYNC = 1<<2, TxSOSCEN = 1<<3, TxCKPS0 = 1<<4, TxCKPS1 = 1<<5, TMRxCS0 = 1<<6, TMRxCS1 = 1<<7, }; T5CON(Processor *pCpu, const char *pName, const char *pDesc=0); ~T5CON(); //RRR unsigned int get(); // For (at least) the 18f family, there's a 4X PLL that effects the // the relative timing between gpsim's cycle counter (which is equivalent // to the cumulative instruction count) and the external oscillator. In // all parts, the clock source for the timer is fosc, the external oscillator. // However, for the 18f parts, the instructions execute 4 times faster when // the PLL is selected. virtual unsigned int get_prescale() { return(((value.get() &(TxCKPS0 | TxCKPS1)) >> 4) ); } virtual unsigned int get_tmr1cs() { return((value.get() & (TMRxCS0 | TMRxCS1)) >> 6); } virtual bool get_tmr1on() { return(value.get() & TMRxON); } virtual bool get_t1oscen() { return(value.get() & TxSOSCEN); } virtual bool get_tmr1GE() { return t1gcon->get_tmr1GE(); } virtual bool get_t1sync() { return(value.get() & TxSYNC); } virtual void put(unsigned int new_value); virtual bool get_t1GINV() {return true;} T1GCON *t1gcon; }; class CCPTMRS; class CCPTMRS0 : public sfr_register { public: CCPTMRS0(CCPTMRS *_ccptmrs, Processor *pCpu, const char *pName, const char *pDesc=0); ~CCPTMRS0(); virtual void put(unsigned int new_value); unsigned int bit_mask; CCPTMRS *ccptmrs; }; class CCPTMRS1 : public sfr_register { public: CCPTMRS1(CCPTMRS * _ccptmrs, Processor *pCpu, const char *pName, const char *pDesc=0); ~CCPTMRS1(); virtual void put(unsigned int new_value); unsigned int bit_mask; CCPTMRS *ccptmrs; }; class CCPTMRS { public: enum { C1TSEL0 = 1<<0, C1TSEL1 = 1<<1, C2TSEL0 = 1<<3, C2TSEL1 = 1<<4, C3TSEL0 = 1<<6, C3TSEL1 = 1<<7, C4TSEL0 = 1<<0, C4TSEL1 = 1<<1, C5TSEL0 = 1<<2, C5TSEL1 = 1<<3, }; CCPTMRS(Processor *pCpu); ~CCPTMRS(); void update0(unsigned int reg_value); void update1(unsigned int reg_value); //void set_tmr135(TMR5 *t1, TMR5 *t3, TMR5 *t5); void set_tmr246(TMR2 *t2, TMR2 *t4, TMR2 *t6); void set_ccp(CCPCON *_c1, CCPCON *_c2, CCPCON *_c3, CCPCON *_c4, CCPCON *_c5); void change(CCPCON *c, unsigned int old, unsigned int val); CCPTMRS0 ccptmrs0; CCPTMRS1 ccptmrs1; //TMR5 *t1, *t3, *t5; TMR2 *t2, *t4, *t6; CCPCON *ccp1, *ccp2, *ccp3, *ccp4, *ccp5; unsigned int last_value0; unsigned int last_value1; }; #endif // __16_BIT_TMRS_H__ gpsim-0.30.0/src/tmr0.cc0000664000076400007640000002651113045306452011633 00000000000000/* Copyright (C) 1998 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "14bit-processors.h" #include "14bit-tmrs.h" #include "interface.h" #include #include "stimuli.h" #include "xref.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif class TMR0_Interface : public Interface { public: TMR0_Interface(TMR0 *_tmr0) : Interface((gpointer *)_tmr0) { tmr0 = _tmr0; } virtual void SimulationHasStopped (gpointer object) { tmr0->update(); } virtual void Update (gpointer object) { SimulationHasStopped(object); } private: TMR0 *tmr0; }; //-------------------------------------------------- // member functions for the TMR0 base class //-------------------------------------------------- TMR0::TMR0(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), m_pOptionReg(0), m_t1gcon(0), t0xcs(false), tmr0_interface(0) { value.put(0); synchronized_cycle=0; future_cycle=0; last_cycle=0; state=STOPPED; // start disabled (will change to enabled by other init code) prescale=1; m_bLastClockedState=false; new_name("tmr0"); } //------------------------------------------------------------------------ void TMR0::release() { } //------------------------------------------------------------------------ // setSinkState // // Called when the I/O pin driving TMR0 changes states. void TMR0::setSinkState(char new3State) { bool bNewState = new3State == '1'; if (m_bLastClockedState != bNewState) { m_bLastClockedState = bNewState; if ( verbose & 2 ) printf("TMR0::setSinkState:%d cs:%d se:%d\n",bNewState,get_t0cs(),get_t0se()); if (get_t0cs() && !get_t0xcs() && bNewState != get_t0se()) increment(); } } void TMR0::set_cpu(Processor *new_cpu, PortRegister *reg, unsigned int pin, OPTION_REG *pOption) { cpu = new_cpu; m_pOptionReg = pOption; reg->addSink(this,pin); } // RCP - add an alternate way to connect to a CPU void TMR0::set_cpu(Processor *new_cpu, PinModule *pin,OPTION_REG *pOption) { cpu = new_cpu; m_pOptionReg = pOption; pin->addSink(this); } //------------------------------------------------------------ // Stop the tmr. // void TMR0::stop() { Dprintf(("\n")); // If tmr0 is running, then stop it: if (state & RUNNING) { // refresh the current value. get_value(); state &= (~RUNNING); // the timer is disabled. clear_trigger(); } } void TMR0::start(int restart_value, int sync) { Dprintf(("restart_value=%d(0x%x) sync=%d\n",restart_value, restart_value, sync)); state |= RUNNING; // the timer is on value.put(restart_value&0xff); //old_option = cpu_pic->option_reg.value.get(); old_option = m_pOptionReg->get_value(); prescale = 1 << get_prescale(); prescale_counter = prescale; if(get_t0cs()) { Dprintf(("External clock\n")); } else { synchronized_cycle = get_cycles().get() + sync; last_cycle = (restart_value % max_counts()) * prescale; last_cycle = synchronized_cycle - last_cycle; guint64 fc = last_cycle + max_counts() * prescale; if(future_cycle) get_cycles().reassign_break(future_cycle, fc, this); else get_cycles().set_break(fc, this); future_cycle = fc; if (tmr0_interface == 0) { tmr0_interface = new TMR0_Interface(this); get_interface().prepend_interface(tmr0_interface); } Dprintf(("last_cycle:0x%" PRINTF_GINT64_MODIFIER "x future_cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle,future_cycle)); } } void TMR0::clear_trigger() { Dprintf(("\n")); if (future_cycle) { future_cycle = 0; get_cycles().clear_break(this); } last_cycle = 0; } unsigned int TMR0::get_prescale() { Dprintf(("OPTION::PSA=%u\n", m_pOptionReg->get_psa())); //return (cpu_pic->option_reg.get_psa() ? 0 : (1+cpu_pic->option_reg.get_prescale())); return (m_pOptionReg->get_psa() ? 0 : (1+m_pOptionReg->get_prescale())); } // This is used to drive timer ias counter of IO port if T0CS is true // void TMR0::increment() { Dprintf(("\n")); if((state & RUNNING) == 0) return; if(--prescale_counter == 0) { trace.raw(write_trace.get() | value.get()); prescale_counter = prescale; if(value.get() >= (max_counts()-1)) { //cout << "TMR0 rollover because of external clock "; value.put(0); set_t0if(); } else value.put(value.get() + 1); } // cout << "TMR0 value ="<= (int)max_counts()) { cout << "TMR0: bug TMR0 is larger than " << max_counts() - 1 << "...\n"; cout << "cycles.value = " << get_cycles().get() << " last_cycle = " << last_cycle << " prescale = " << prescale << " calculated value = " << new_value << '\n'; // cop out. tmr0 has a bug. So rather than annoy // the user with an infinite number of messages, // let's just go ahead and reset the logic. new_value &= 0xff; last_cycle = new_value*prescale; last_cycle = get_cycles().get() - last_cycle; synchronized_cycle = last_cycle; } value.put(new_value); return(value.get()); } unsigned int TMR0::get() { value.put(get_value()); trace.raw(read_trace.get() | value.get()); return value.get(); } void TMR0::new_prescale() { Dprintf(("\n")); unsigned int new_value; int option_diff = old_option ^ m_pOptionReg->get_value(); old_option ^= option_diff; // save old option value. ( (a^b) ^b = a) if(option_diff & OPTION_REG::T0CS) { // TMR0's clock source has changed. if(verbose) cout << "T0CS has changed to "; if(m_pOptionReg->get_t0cs()) { // External clock if(verbose) cout << "external clock\n"; if (future_cycle) { future_cycle = 0; get_cycles().clear_break(this); } } else { // Internal Clock if(verbose) cout << "internal clock\n"; } start(value.get()); } else { // Refresh the current tmr0 value. The current tmr0 value is used // below to recompute the value for 'last_cycle' get_value(); if(get_t0cs() || ((state & RUNNING)==0)) { prescale = 1 << get_prescale(); prescale_counter = prescale; } else { if(last_cycle < (gint64)get_cycles().get()) new_value = (unsigned int)((get_cycles().get() - last_cycle)/prescale); else new_value = 0; if(new_value>=max_counts()) { cout << "TMR0 bug (new_prescale): exceeded max count"<< max_counts() <<'\n'; cout << " last_cycle = 0x" << hex << last_cycle << endl; cout << " cpu cycle = 0x" << hex << (get_cycles().get()) << endl; cout << " prescale = 0x" << hex << prescale << endl; } // Get the current value of TMR0 // cout << "cycles " << cycles.value << " old prescale " << prescale; prescale = 1 << get_prescale(); prescale_counter = prescale; last_cycle = value.get() * prescale; last_cycle = get_cycles().get() - last_cycle; synchronized_cycle = last_cycle; guint64 fc = last_cycle + max_counts() * prescale; // cout << "moving break from " << future_cycle << " to " << fc << '\n'; get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } } } bool TMR0::get_t0cs() { //return cpu_pic->option_reg.get_t0cs() != 0; return m_pOptionReg->get_t0cs() != 0; } bool TMR0::get_t0se() { //return cpu_pic->option_reg.get_t0se() != 0; return m_pOptionReg->get_t0se() != 0; } void TMR0::set_t0if() { if(cpu_pic->base_isa() == _14BIT_PROCESSOR_ || cpu_pic->base_isa() == _14BIT_E_PROCESSOR_) { cpu14->intcon->set_t0if(); } if (m_t1gcon) { m_t1gcon->T0_gate(true); // Spec sheet does not indicate when the overflow signal // is cleared, so I am assuming it is just a pulse. RRR m_t1gcon->T0_gate(false); } } // TMR0 callback is called when the cycle counter hits the break point that // was set in TMR0::put. The cycle counter will clear the break point, so // we don't need to worry about it. At this point, TMR0 is rolling over. void TMR0::callback() { Dprintf(("now=0x%" PRINTF_GINT64_MODIFIER "x\n",get_cycles().get())); if((state & RUNNING) == 0) { cout << "TMR0 callback ignored because timer is disabled\n"; } // If tmr0 is being clocked by the external clock, then at some point // the simulate code must have switched from the internal clock to // external clock. The cycle break point was still set, so just ignore it. if(get_t0cs()) { future_cycle = 0; // indicates that tmr0 no longer has a break point return; } value.put(0); synchronized_cycle = get_cycles().get(); last_cycle = synchronized_cycle; future_cycle = last_cycle + max_counts()*prescale; get_cycles().set_break(future_cycle, this); set_t0if(); } void TMR0::reset(RESET_TYPE r) { switch(r) { case POR_RESET: value = por_value; break; default: break; } } void TMR0::callback_print() { cout << "TMR0\n"; } // Suspend TMR0 for sleep void TMR0::sleep() { if(verbose) printf("TMR0::sleep state=%u\n", state); if((state & RUNNING)) { stop(); state = SLEEPING; } } // wake up TMR0 when sleep command terminates void TMR0::wake() { if(verbose) printf("TMR0::wake state=%u\n", state); if ((state & SLEEPING)) { if (! (state & RUNNING)) { state = STOPPED; start(value.get(), 0); } else state &= ~SLEEPING; } } gpsim-0.30.0/src/sim_context.h0000664000076400007640000000716013041763624013152 00000000000000/* Copyright (C) 1998-2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __SIM_CONTEXT_H__ #define __SIM_CONTEXT_H__ #include #include #include "processor.h" class Processor; //------------------------------------------------------------------- // // Define a list for keeping track of the processors being simulated. // (Recall, gpsim can simultaneously simulate more than one processor.) class CSimulationContext { class CProcessorList : public map { public: iterator findByType(const key_type& _Keyval); }; public: CSimulationContext(); ~CSimulationContext(); Processor * add_processor( const char * processor_type, const char * processor_new_name = NULL); Processor * add_processor( ProcessorConstructor *pc, const char * processor_new_name = NULL); Processor * SetProcessorByType( const char * processor_type, const char * processor_new_name); Processor * add_processor( Processor * p); int LoadProgram( const char *filename, const char *pProcessorType = NULL, Processor **ppProcessor = NULL, const char * processor_new_name=NULL); void dump_processor_list(void); bool SetDefaultProcessor( const char * processor_type, const char * processor_new_name); void Clear(); void Reset(RESET_TYPE r); void Initialize(); SymbolTable & GetSymbolTable(); Breakpoints & GetBreakpoints(); Processor * GetActiveCPU(); Cycle_Counter * GetCycleCounter(); bool IsSourceEnabled() { return m_bEnableLoadSource; } void NotifyUserCanceled(); void SetUserCanceledFlag(bool *pbUserCanceled) { m_pbUserCanceled = pbUserCanceled ; } static CSimulationContext *GetContext(); protected: CProcessorList processor_list; string m_DefProcessorName; string m_DefProcessorNameNew; bool * m_pbUserCanceled; // active_cpu_id is the id of the currently active cpu. In other words: // active_cpu_id == active_cpu->processor_id // It's redundant to define this id in addition to the *active_cpu pointer. // However, if there ever comes a day when the cli is truely separate from // the simulator, then it would be more convenient to deal with ints than // pointers. int active_cpu_id; // cpu_ids is a counter that increments everytime a processor is added by the // user. If the user deletes a processor, this counter will not be affected. // The value of this counter will be assigned to the processor's id when a // new processor is added. It's purpose is to uniquely identifier user // processors. int cpu_ids; Boolean &m_bEnableLoadSource; // deleted by Symbol_Table static CSimulationContext *s_SimulationContext; }; #endif gpsim-0.30.0/src/icd.h0000664000076400007640000000556013060754614011357 00000000000000#ifndef __ICD_H__ #define __ICD_H__ #include "gpsim_classes.h" #include "exports.h" #define ID_LOC_ADDR 0x2000 #define DEVICE_ID_ADDR 0x2006 #define CONF_WORD_ADDR 0x2007 #define ID_LOC_LEN 8 #define MAX_PROG_MEM_SIZE 0x2000 /* 16F877 has 8K word flash */ #define MAX_MEM_SIZE (MAX_PROG_MEM_SIZE + 0x200) /* + ID location + EEPROM */ #define UNINITIALIZED -1 /* Used to flag that a memory location isn't used */ LIBGPSIM_EXPORT bool get_use_icd(); int icd_connect(const char *dev); int icd_reconnect(void); int icd_disconnect(void); int icd_detected(void); const char *icd_version(void); const char *icd_target(void); float icd_vdd(void); float icd_vpp(void); int icd_reset(void); int icd_erase(void); int icd_prog(int *mem); int icd_has_debug_module(void); int icd_step(void); int icd_run(void); int icd_halt(void); int icd_stopped(void); int icd_get_state(); int icd_get_file(); int icd_set_break(int address); int icd_clear_break(void); int icd_read_file(int address); int icd_write_file(int address, int data); void icd_set_bulk(int flag); int icd_read_eeprom(int address); int icd_write_eeprom(int address, int data); /* class icd_Register : public file_register { public: file_register *replaced; // A pointer to the register that this break replaces int is_stale; icd_Register(); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual char *name(void) {return replaced->name();}; virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_statusReg : public Status_register { public: Status_register *replaced; // A pointer to the register that this break replaces int is_stale; icd_statusReg(); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual char *name(void) {return replaced->name();}; virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_WREG : public WREG { public: WREG *replaced; // A pointer to the register that this break replaces int is_stale; icd_WREG(); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual char *name(void) {return replaced->name();}; virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_PC : public Program_Counter { Program_Counter *replaced; int is_stale; icd_PC(); virtual void put_value(unsigned int new_value); virtual unsigned int get_value(void); }; */ #endif gpsim-0.30.0/src/gpsim_object.h0000664000076400007640000000671113063451152013256 00000000000000 /* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __GPSIM_OBJECT_H__ #define __GPSIM_OBJECT_H__ #include using namespace std; class BreakType; class Expression; /// gpsimObject - base class for most of gpsim's objects /// class gpsimObject { public: gpsimObject(); gpsimObject(const char *_name, const char *desc=0); virtual ~gpsimObject(); /// Get the name of the object virtual string &name(void) const; /// copy the name to a user char array virtual char *name(char *, int len); /// copy the object value to a user char array virtual char *toString(char *, int len); virtual char *toBitStr(char *, int len); /// Assign a new name to the object /// FIXME why have two ways of naming ??? virtual void new_name(const char *); virtual void new_name(string &); /// TEMPORARY -- remove after gpsimValue and Value have been merged. virtual unsigned int get_value(); /// description - get a description of this object. If the object has /// a name, then 'help value_name' at the command line will display /// the description. virtual string description(); void set_description(const char *); /// Access object-specific information string show(); string showType(); virtual string toString(); // Breakpoint types supported by Value enum ObjectBreakTypes { eBreakAny, // ??? eBreakWrite, // Register write eBreakRead, // Register read eBreakChange, // Register change eBreakExecute // Program memory execute }; // Breakpoint types supported by Value enum ObjectActionTypes { eActionHalt, eActionLog, }; /// breakpoints /// set a break point on a gpsim object. The BreakType specifies the /// the condition for which the break will trigger when this value /// is accessed. In addition, the optional expr is a boolean expression /// that is evaluated when the Object is accessed. The expression must /// evaluate to true for the break to trigger. If the break is successfully /// set then a non-negative number (the break point number) will be returned. /// If the break fails, then -1 is returned. /// The ActionType specifies the action to take when the break is triggered. virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); virtual int clear_break(); protected: string name_str; // A unique name to describe the object const char *cpDescription; // A desciption of the object }; //------------------------------------------------------------------------ // BreakTypes // class BreakType { public: explicit BreakType(int _type) : m_type(_type) { } virtual ~BreakType() { } virtual int type() { return m_type; } protected: int m_type; }; #endif // __GPSIM_OBJECT_H__ gpsim-0.30.0/src/14bit-processors.h0000664000076400007640000001603713041637777013755 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2009,2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "pic-processor.h" #include "intcon.h" #include "uart.h" #include "ssp.h" #ifndef __14_BIT_PROCESSORS_H__ #define __14_BIT_PROCESSORS_H__ // forward references class _14bit_processor; class _14bit_e_processor; class PicPortRegister; class PicTrisRegister; class PicPortBRegister; class PicTrisRegister; class PortBSink; class IOPIN; class IO_open_collector; class PinMonitor; extern instruction *disasm14 (_14bit_processor *cpu,unsigned int inst, unsigned int address); extern instruction *disasm14E (_14bit_e_processor *cpu,unsigned int inst, unsigned int address); class _14bit_processor : public pic_processor { public: #define EEPROM_SIZE 0x40 #define INTERRUPT_VECTOR 4 #define WDTE 4 unsigned int eeprom_size; INTCON *intcon; virtual void interrupt(); virtual void save_state(); virtual void create(); virtual PROCESSOR_TYPE isa(){return _14BIT_PROCESSOR_;}; virtual PROCESSOR_TYPE base_isa(){return _14BIT_PROCESSOR_;}; virtual instruction * disasm (unsigned int address, unsigned int inst) { return disasm14(this, address, inst); } // Declare a set of functions that will allow the base class to // get information about the derived classes. NOTE, the values returned here // will cause errors if they are used -- the derived classes must define their // parameters appropriately. virtual void create_sfr_map()=0; virtual void option_new_bits_6_7(unsigned int)=0; virtual void put_option_reg(unsigned int); virtual void create_symbols()=0; virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void create_config_memory(); virtual void oscillator_select(unsigned int mode, bool clkout); // Return the portion of pclath that is used during branching instructions virtual unsigned int get_pclath_branching_jump() { return ((pclath->value.get() & 0x18)<<8); } // Return the portion of pclath that is used during modify PCL instructions virtual unsigned int get_pclath_branching_modpcl() { return((pclath->value.get() & 0x1f)<<8); } virtual unsigned int map_fsr_indf ( void ) { return ( this->fsr->value.get() ); } virtual unsigned int eeprom_get_size() {return 0;}; virtual unsigned int eeprom_get_value(unsigned int address) {return 0;}; virtual void eeprom_put_value(unsigned int value, unsigned int address) {return;} virtual unsigned int program_memory_size() const = 0; virtual unsigned int get_program_memory_at_address(unsigned int address); virtual void enter_sleep(); virtual void exit_sleep(); virtual bool hasSSP() {return has_SSP;} virtual void set_hasSSP() { has_SSP = true;} _14bit_processor(const char *_name=0, const char *desc=0); virtual ~_14bit_processor(); bool two_speed_clock; unsigned int config_clock_mode; protected: bool has_SSP; OPTION_REG *option_reg; unsigned int ram_top; }; #define cpu14 ( (_14bit_processor *)cpu) /*************************************************************************** * * Include file for: P16C84, P16F84, P16F83, P16CR83, P16CR84 * * The x84 processors have a 14-bit core, eeprom, and are in an 18-pin * package. The class taxonomy is: * * pic_processor * |-> 14bit_processor * | * |----------\ * | * |- P16C8x * |->P16C84 * |->P16F84 * |->P16C83 * |->P16CR83 * |->P16CR84 * ***************************************************************************/ class PortBSink; class Pic14Bit : public _14bit_processor { public: Pic14Bit(const char *_name=0, const char *desc=0); virtual ~Pic14Bit(); INTCON_14_PIR intcon_reg; PicPortRegister *m_porta; PicTrisRegister *m_trisa; PicPortBRegister *m_portb; PicTrisRegister *m_trisb; virtual PROCESSOR_TYPE isa(){return _14BIT_PROCESSOR_;}; virtual void create_symbols(); virtual void create_sfr_map(); virtual void option_new_bits_6_7(unsigned int bits); }; class CPU_Temp : public Float { public: CPU_Temp(const char *_name, double temp, const char *desc) : Float(_name, temp, desc) {} }; // 14 bit processors with extended instructions // class _14bit_e_processor : public _14bit_processor { public: unsigned int mclr_pin; INTCON_14_PIR intcon_reg; OPTION_REG_2 option_reg; BSR bsr; PCON pcon; WDTCON wdtcon; Indirect_Addressing14 ind0; Indirect_Addressing14 ind1; sfr_register status_shad; sfr_register wreg_shad; sfr_register bsr_shad; sfr_register pclath_shad; sfr_register fsr0l_shad; sfr_register fsr0h_shad; sfr_register fsr1l_shad; sfr_register fsr1h_shad; CPU_Temp *m_cpu_temp; void set_mclr_pin(unsigned int pin) { mclr_pin = pin;} virtual PROCESSOR_TYPE isa(){return _14BIT_PROCESSOR_;}; virtual PROCESSOR_TYPE base_isa(){return _14BIT_E_PROCESSOR_;}; virtual instruction * disasm (unsigned int address, unsigned int inst) { return disasm14E(this, address, inst); } _14bit_e_processor(const char *_name=0, const char *desc=0); virtual ~_14bit_e_processor(); virtual void create_symbols(); virtual void create_sfr_map(); virtual void interrupt(); virtual bool exit_wdt_sleep(); virtual bool swdten_active() {return(wdt_flag == 1);} // WDTCON can enable WDT virtual void enter_sleep(); virtual void exit_sleep(); virtual void reset(RESET_TYPE r); virtual void create_config_memory(); virtual bool set_config_word(unsigned int address,unsigned int cfg_word); virtual void oscillator_select(unsigned int mode, bool clkout); virtual void program_memory_wp(unsigned int mode); // Return the portion of pclath that is used during branching instructions virtual unsigned int get_pclath_branching_jump() { return ((pclath->value.get() & 0x18)<<8); } // Return the portion of pclath that is used during modify PCL instructions virtual unsigned int get_pclath_branching_modpcl() { return((pclath->value.get() & 0x1f)<<8); } virtual void Wput(unsigned int); virtual unsigned int Wget(); protected: unsigned int wdt_flag; }; #define cpu14e ( (_14bit_e_processor *)cpu) #endif gpsim-0.30.0/src/pie.h0000664000076400007640000000063613041763613011372 00000000000000#ifndef PIE_H #define PIE_H class PIR; #include "registers.h" //--------------------------------------------------------- // PIE Peripheral Interrupt Enable register base class // for PIE1 & PIE2 class PIE : public sfr_register { public: PIE(Processor *pCpu, const char *pName, const char *pDesc); void put(unsigned int new_value); void setPir(PIR *pPir); protected: PIR *pir; }; #endif /* PIE_H */ gpsim-0.30.0/src/fopen-path.h0000664000076400007640000000216313041763613012653 00000000000000/* -*- Mode: C++; c-file-style: "bsd"; comment-column: 40 -*- */ /* Copyright (C) 2000 Daniel Christian, T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "exports.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ LIBGPSIM_EXPORT void InitSourceSearchAsSymbol(); LIBGPSIM_EXPORT void set_search_path (const char *path); LIBGPSIM_EXPORT FILE *fopen_path (const char *filename, const char *perms); #ifdef __cplusplus } #endif /* __cplusplus */ gpsim-0.30.0/src/bit.h0000664000076400007640000000515513041763624011376 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__BIT_H__) #define __BIT_H__ // Function to test the Bit Class: extern void test_bits(); // Bit // // The Bit object is like a bool except that it supports 3-state // logic. class RegisterValue; class Bit { public: Bit(RegisterValue &rv, unsigned int bit_mask); Bit(bool nd=false, bool ni=false) : d(nd), i(ni) { } inline void operator = (const Bit &bv) { d = bv.d; i = bv.i; } inline bool operator == (const Bit &bv) const { return d==bv.d && i==bv.i; } inline void operator |= (const Bit &bv) { i = (i&bv.i) || (i&d) || (bv.d&bv.i); d |= bv.d; } inline void operator &= (const Bit &bv) { i = i&bv.i || (i&!bv.d) || (!d&bv.i); d &= bv.d; } inline void operator ^= (const Bit &bv) { d ^= bv.d; i &= bv.i; } inline Bit operator & (const Bit &r) { Bit bLv = *this; bLv.i = bLv.i&r.i || (r.i&!r.d) || (!bLv.d&bLv.i); bLv.d &= r.d; return bLv; } inline Bit operator | (const Bit &bv) { Bit bLv = *this; bLv |= bv; return bLv; } inline Bit operator ^ (const Bit &bv) { Bit bLv = *this; bLv ^= bv; return bLv; } inline bool isZero() { return d==false && i==true; } inline bool isOne() { return d==true && i==true; } inline bool isKnown() { return i==true; } inline bool isUnKnown() { return i==false; } inline void set(bool nd, bool ni) { d = nd; i = ni; } inline void clear() { d=false; i=true; } inline void set() { d = true; i = true; } inline void setUnknown() { i = false; } inline char val() { return !isKnown() ? '?' : (isOne() ? '1' : '0'); } friend Bit operator ! (Bit b); private: bool d; // The data bool i; // i=true if d is valid }; inline Bit operator ! (Bit b) { Bit bLv = b; bLv.d = !bLv.d; return bLv; } #endif gpsim-0.30.0/src/14bit-processors.cc0000664000076400007640000004276213115237601014077 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2009,2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "14bit-processors.h" #include "pic-ioports.h" #include "pic-registers.h" #include #include "stimuli.h" #include "packages.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("0x%06X %s() ",cycles.get(),__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //======================================================================== // Generic Configuration word for the midrange family. class Generic14bitConfigWord : public ConfigWord { public: Generic14bitConfigWord(_14bit_processor *pCpu) : ConfigWord("CONFIG", 0x3fff, "Configuration Word", pCpu, 0x2007) { assert(pCpu); pCpu->wdt.initialize(true); } enum { FOSC0 = 1<<0, FOSC1 = 1<<1, WDTEN = 1<<2, PWRTEN = 1<<3 }; virtual void set(gint64 v) { gint64 oldV = getVal(); Integer::set(v); if (m_pCpu) { gint64 diff = oldV ^ v; if (diff & WDTEN) m_pCpu->wdt.initialize((v & WDTEN) == WDTEN); m_pCpu->config_modes->set_fosc01(v & (FOSC0 | FOSC1)); m_pCpu->config_modes->set_wdte((v&WDTEN)==WDTEN); m_pCpu->config_modes->set_pwrte((v&PWRTEN)==PWRTEN); } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; snprintf(buff,sizeof(buff), "$%3x\n" " FOSC=%d - Clk source = %s\n" " WDTEN=%d - WDT is %s\n" " PWRTEN=%d - Power up timer is %s\n", i, i & (FOSC0 | FOSC1), ((i & FOSC0) ? ((i & FOSC1) ? "EXTRC":"XT") :((i & FOSC1) ? "INTRC":"LP")), ((i & WDTEN) ? 1 : 0), ((i & WDTEN) ? "enabled" : "disabled"), ((i & PWRTEN) ? 1 : 0), ((i & PWRTEN) ? "disabled" : "enabled")); return string(buff); } }; //------------------------------------------------------------------- _14bit_processor::_14bit_processor(const char *_name, const char *_desc) : pic_processor(_name,_desc), intcon(0), two_speed_clock(false), config_clock_mode(0), has_SSP(false) { pc = new Program_Counter("pc", "Program Counter", this); pc->set_trace_command(); //trace.allocateTraceType(new PCTraceType(this,1))); option_reg = new OPTION_REG(this,"option_reg"); stack = new Stack(this); } _14bit_processor::~_14bit_processor() { unassignMCLRPin(); delete_sfr_register(fsr); delete_sfr_register(option_reg); delete pc; pc=0; } //------------------------------------------------------------------- // // // create // // The purpose of this member function is to 'create' those things // that are unique to the 14-bit core processors. void _14bit_processor :: create () { if(verbose) cout << "_14bit_processor create, type = " << isa() << '\n'; pic_processor::create(); fsr = new FSR(this, "fsr", "File Select Register for indirect addressing"); } //------------------------------------------------------------------- void _14bit_processor::interrupt () { //bp.clear_interrupt(); intcon->in_interrupt = true; bp.clear_interrupt(); stack->push(pc->value); pc->interrupt(INTERRUPT_VECTOR); } //------------------------------------------------------------------- void _14bit_processor::save_state() { pic_processor::save_state(); option_reg->put_trace_state(option_reg->value); } //------------------------------------------------------------------- void _14bit_processor::option_new_bits_6_7(unsigned int bits) { cout << "14bit, option bits 6 and/or 7 changed\n"; } //------------------------------------------------------------------- void _14bit_processor::put_option_reg(unsigned int val) { option_reg->put(val); } //------------------------------------------------------------------ // Fetch the rom contents at a particular address. unsigned int _14bit_processor::get_program_memory_at_address(unsigned int address) { unsigned int uIndex = map_pm_address2index(address); if (uIndex < program_memory_size()) return program_memory[uIndex] ? program_memory[uIndex]->get_opcode() : 0xffffffff; return get_config_word(address); } //------------------------------------------------------------------- void _14bit_processor::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new Generic14bitConfigWord(this)); } //------------------------------------------------------------------- bool _14bit_processor::set_config_word(unsigned int address,unsigned int cfg_word) { if((address == config_word_address()) && config_modes) { config_word = cfg_word; oscillator_select(cfg_word, false); if (m_configMemory && m_configMemory->getConfigWord(0)) m_configMemory->getConfigWord(0)->set((int)cfg_word); return true; } return false; } // The working version of oscillator_select should be called at a higher level // where the IO pins are defined // void _14bit_processor::oscillator_select(unsigned int mode, bool not_clkout) { // printf("Error _14bit_processor::oscillator_select called\n"); } //------------------------------------------------------------------- void _14bit_processor::enter_sleep() { tmr0.sleep(); pic_processor::enter_sleep(); } //------------------------------------------------------------------- void _14bit_processor::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr0.wake(); pic_processor::exit_sleep(); } } //------------------------------------------------------------------- Pic14Bit::Pic14Bit(const char *_name, const char *_desc) : _14bit_processor(_name,_desc), intcon_reg(this,"intcon","Interrupt Control") { m_porta = new PicPortRegister(this,"porta","", 8,0x1f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); m_portb = new PicPortBRegister(this,"portb","",&intcon_reg,8,0xff); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false); } //------------------------------------------------------------------- Pic14Bit::~Pic14Bit() { unassignMCLRPin(); remove_sfr_register(&tmr0); remove_sfr_register(&intcon_reg); delete_sfr_register(m_portb); delete_sfr_register(m_trisb); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); } //------------------------------------------------------------------- void Pic14Bit::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } //------------------------------------------------------------------- void Pic14Bit::create_sfr_map() { add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); add_sfr_register(&tmr0, 0x01); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); add_sfr_register(m_porta, 0x05); add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0)); add_sfr_register(m_portb, 0x06); add_sfr_register(m_trisb, 0x86, RegisterValue(0xff,0)); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); //add_sfr_register(pclath, 0x8a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); //add_sfr_register(&intcon_reg, 0x8b, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); intcon = &intcon_reg; } //------------------------------------------------------------------- void Pic14Bit::option_new_bits_6_7(unsigned int bits) { //1 ((PORTB *)portb)->rbpu_intedg_update(bits); m_portb->setRBPU( (bits & (1<<7)) == (1<<7)); m_portb->setIntEdge((bits & (1<<6)) == (1<<6)); } _14bit_e_processor::_14bit_e_processor(const char *_name, const char *_desc) : _14bit_processor(_name,_desc), mclr_pin(4), intcon_reg(this,"intcon","Interrupt Control"), option_reg(this,"option_reg","Option Register"), bsr(this, "bsr", "Bank Select Register"), pcon(this, "pcon", "Power Control Register", 0xcf), wdtcon(this, "wdtcon", "WDT Control", 0x3f), ind0(this,string("0")), ind1(this,string("1")), status_shad(this, "status_shad", "Status shadow register"), wreg_shad(this, "wreg_shad", "wreg shadow register"), bsr_shad(this, "bsr_shad", "bsr shadow register"), pclath_shad(this, "pclath_shad", "pclath shadow register"), fsr0l_shad(this, "fsr0l_shad", "fsr0l shadow register"), fsr0h_shad(this, "fsr0h_shad", "fsr0h shadow register"), fsr1l_shad(this, "fsr1l_shad", "fsr1l shadow register"), fsr1h_shad(this, "fsr1h_shad", "fsr1h shadow register"), m_cpu_temp(0) { delete stack; stack = new Stack14E(this); stack->stack_mask = 0xf; // ehanced has stack 16 high intcon = &intcon_reg; }; _14bit_e_processor::~_14bit_e_processor() { remove_sfr_register(&ind0.indf); remove_sfr_register(&ind1.indf); remove_sfr_register(&ind0.fsrl); remove_sfr_register(&ind0.fsrh); remove_sfr_register(&ind1.fsrl); remove_sfr_register(&ind1.fsrh); remove_sfr_register(&bsr); remove_sfr_register(&intcon_reg); remove_sfr_register(&pcon); remove_sfr_register(&wdtcon); // These are copies taken at an interrupt remove_sfr_register(&status_shad); remove_sfr_register(&wreg_shad); remove_sfr_register(&bsr_shad); remove_sfr_register(&pclath_shad); remove_sfr_register(&fsr0l_shad); remove_sfr_register(&fsr0h_shad); remove_sfr_register(&fsr1l_shad); remove_sfr_register(&fsr1h_shad); Stack14E *stack14E = static_cast(stack); remove_sfr_register(&stack14E->stkptr); remove_sfr_register(&stack14E->tosl); remove_sfr_register(&stack14E->tosh); } void _14bit_e_processor::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } void _14bit_e_processor::create_sfr_map() { int bank; add_sfr_register(&ind0.indf, 0x00, RegisterValue(0,0), "indf0"); add_sfr_register(&ind1.indf, 0x01, RegisterValue(0,0), "indf1"); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(&ind0.fsrl, 0x04, RegisterValue(0,0), "fsr0l"); add_sfr_register(&ind0.fsrh, 0x05, RegisterValue(0,0), "fsr0h"); add_sfr_register(&ind1.fsrl, 0x06, RegisterValue(0,0), "fsr1l"); add_sfr_register(&ind1.fsrh, 0x07, RegisterValue(0,0), "fsr1h"); add_sfr_register(&bsr, 0x08); add_sfr_register(Wreg, 0x09); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); add_sfr_register(&pcon, 0x96, RegisterValue(0x0c,0),"pcon"); wdt.set_postscale(0); wdt.set_timeout(1./32000.); add_sfr_register(&wdtcon, 0x97, RegisterValue(0x16,0),"wdtcon"); // These are copies taken at an interrupt add_sfr_register(&status_shad, 0xfe4); add_sfr_register(&wreg_shad, 0xfe5); add_sfr_register(&bsr_shad, 0xfe6); add_sfr_register(&pclath_shad, 0xfe7); add_sfr_register(&fsr0l_shad, 0xfe8); add_sfr_register(&fsr0h_shad, 0xfe9); add_sfr_register(&fsr1l_shad, 0xfea); add_sfr_register(&fsr1h_shad, 0xfeb); Stack14E *stack14E = static_cast(stack); add_sfr_register(&stack14E->stkptr, 0xfed,RegisterValue(0,0),"stkptr"); add_sfr_register(&stack14E->tosl, 0xfee,RegisterValue(0,0),"tosl"); add_sfr_register(&stack14E->tosh, 0xfef,RegisterValue(0,0),"tosh"); for (bank = 1; bank < 32; bank++) { alias_file_registers(0x00,0x0b,bank*0x80); // Duplicate core registers alias_file_registers(0x70,0x7f,bank*0x80); // Duplicate shadow ram } stack->stack_mask = 15; // enhanced has stack 16 high } //------------------------------------------------------------------- // Similar to pic_processoer version except sets PCON flags // void _14bit_e_processor::reset (RESET_TYPE r) { switch(r) { case POR_RESET: pcon.put(0x0d); break; case SOFT_RESET: pcon.put(pcon.get() & ~PCON::RI); break; case MCLR_RESET: cout << "Reset due to MCLR\n"; pcon.put(pcon.get() & ~PCON::RMCLR); break; case STKOVF_RESET: pcon.put(pcon.get() | PCON::STKOVF); break; case STKUNF_RESET: pcon.put(pcon.get() | PCON::STKUNF); break; default: break; }; pic_processor::reset(r); return; } //------------------------------------------------------------------- // The enhanced processors save a number of registers into // their shadow registers on interrupt // void _14bit_e_processor::interrupt () { bp.clear_interrupt(); if (bp.have_sleep()) { bp.clear_sleep(); stack->push(pc->value+1); } else { stack->push(pc->value); } status_shad.value = status->value; wreg_shad.value = Wreg->value; bsr_shad.value = bsr.value; pclath_shad.value = pclath->value; fsr0l_shad.value = ind0.fsrl.value; fsr0h_shad.value = ind0.fsrh.value; fsr1l_shad.value = ind1.fsrl.value; fsr1h_shad.value = ind1.fsrh.value; intcon->in_interrupt = true; pc->interrupt(INTERRUPT_VECTOR); } //------------------------------------------------------------------- void _14bit_e_processor::enter_sleep() { tmr0.sleep(); if (wdt_flag == 2) // WDT is suspended during sleep wdt.initialize(false); pic_processor::enter_sleep(); } //------------------------------------------------------------------- bool _14bit_e_processor::exit_wdt_sleep() { return true; } //------------------------------------------------------------------- void _14bit_e_processor::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr0.wake(); if (wdt_flag == 2) wdt.initialize(true); pic_processor::exit_sleep(); } } //======================================================================== // // Configuration Memory word 1for the enhanced 14 bit processors class Config_E : public ConfigWord { public: Config_E(_14bit_e_processor *pCpu, const char *name, unsigned int address, bool EEw=false) : ConfigWord(name, 0x3fff, "Configuration Word", pCpu, address, EEw) { if (m_pCpu) { m_pCpu->set_config_word(address, 0x3fff); } } }; void _14bit_e_processor::create_config_memory() { m_configMemory = new ConfigMemory(this,9); m_configMemory->addConfigWord(0,new Config_E(this, "UserID1", 0x8000, true)); m_configMemory->addConfigWord(1,new Config_E(this, "UserID2", 0x8001, true)); m_configMemory->addConfigWord(2,new Config_E(this, "UserID3", 0x8002, true)); m_configMemory->addConfigWord(3,new Config_E(this, "UserID4", 0x8003, true)); m_configMemory->addConfigWord(6,new Config_E(this, "DeviceID", 0x8006)); m_configMemory->addConfigWord(7,new Config_E(this, "ConfigW1", 0x8007)); m_configMemory->addConfigWord(8,new Config_E(this, "ConfigW2", 0x8008)); }; bool _14bit_e_processor::set_config_word(unsigned int address,unsigned int cfg_word) { enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN0 = 1<<3, WDTEN1 = 1<<4, PWRTEN = 1<<5, MCLRE = 1<<6, CP = 1<<7, CPD = 1<<8, BOREN0 = 1<<9, BOREN1 = 1<<10, NOT_CLKOUTEN = 1<<11, // IESO = 1<<12, // Config word 2 WRT0 = 1<<0, WRT1 = 1<<1, PLLEN = 1<<8, STVREN = 1<<9, }; Dprintf((" add %x word %x\n", address, cfg_word)); if(address == 0x8007) // Config Word 1 { wdt_flag = (cfg_word & (WDTEN0|WDTEN1)) >> 3; Dprintf((" cfg_word %x MCLRE %x\n", cfg_word, cfg_word & MCLRE)); if ((cfg_word & MCLRE) == MCLRE) assignMCLRPin(mclr_pin); else unassignMCLRPin(); wdt.initialize(wdt_flag & 2); oscillator_select(cfg_word, (cfg_word & NOT_CLKOUTEN) != NOT_CLKOUTEN); } else if (address == 0x8008) { // stack over/under reset flag stack->STVREN = ((cfg_word & STVREN) == STVREN); Dprintf((" STVREN %x flag %d\n", cfg_word&STVREN, stack->STVREN)); // Program memory write protect (eeprom) program_memory_wp(cfg_word & (WRT1|WRT0)); set_pplx4_osc(cfg_word & PLLEN); } return(pic_processor::set_config_word(address, cfg_word)); } // The working version of oscillator_select should be called at a higher level // where the IO pins are defined // void _14bit_e_processor::oscillator_select(unsigned int mode, bool not_clkout) { printf("Error _14bit_e_processor::oscillator_select called\n"); } // The working version of program_memory_wp should be called at a higher level // where the eeprom is defined // void _14bit_e_processor::program_memory_wp(unsigned int mode) { printf("Error _14bit_e_processor::program_memory_wp called\n"); } // This function routes Wreg put requests through registers (if possible) // for breaking and logging void _14bit_e_processor::Wput(unsigned int value) { if(Wreg->address) registers[Wreg->address]->put(value); else Wreg->put(value); } // This function routes Wreg get requests through registers (if possible) // for breaking and logging unsigned int _14bit_e_processor::Wget() { if(Wreg->address) return registers[Wreg->address]->get(); else return Wreg->get(); } gpsim-0.30.0/src/processor.cc0000664000076400007640000022005013065573230012764 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* stuff that needs to be fixed: Register aliasing The "invalid instruction" in program memory. */ #include #ifdef _WIN32 #include "uxtime.h" #endif #include #include #include #include #include #include "../config.h" #include "gpsim_def.h" #include #include "gpsim_classes.h" #include "modules.h" #include "processor.h" #include "pic-processor.h" #include "xref.h" #include "attributes.h" #include "fopen-path.h" #include "cmd_gpsim.h" #include "sim_context.h" #include "clock_phase.h" #include //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------------------------ // active_cpu is a pointer to the pic processor that is currently 'active'. // 'active' means that it's the one currently being simulated or the one // currently being manipulated by the user (e.g. register dumps, break settings) Processor *active_cpu = 0; // create instances of inline get_active_cpu() and set_active_cpu() methods // by taking theirs address Processor *(*dummy_get_active_cpu)(void) = get_active_cpu; void (*dummy_set_active_cpu)(Processor *act_cpu) = set_active_cpu; static char pkg_version[] = PACKAGE_VERSION; class CPU_Freq : public Float { public: CPU_Freq(Processor * _cpu, double freq); //const char *_name, double newValue, const char *desc); virtual void set(double d); void set_rc_freq(double d); virtual void get(double &); void set_rc_active(bool _use_rc_freq) { use_rc_freq = _use_rc_freq;} private: Processor * cpu; double RCfreq; bool use_rc_freq; }; CPU_Freq::CPU_Freq(Processor * _cpu, double freq) : Float("frequency",freq, " oscillator frequency."), cpu(_cpu), use_rc_freq(false) { } void CPU_Freq::set_rc_freq(double d) { RCfreq = d; } void CPU_Freq::get(double &d) { if (use_rc_freq) d = RCfreq; else { double x; Float::get(x); d = x; } } void CPU_Freq::set(double d) { pic_processor *pCpu = dynamic_cast(cpu); Float::set ( d ); if ( cpu ) cpu->update_cps(); if ( pCpu ) pCpu->wdt.update(); } CPU_Vdd::CPU_Vdd(Processor * _cpu, double vdd) : Float("Vdd", vdd , "Processor supply voltage"), cpu(_cpu) { } void CPU_Vdd::set(double d) { Float::set ( d ); if ( cpu ) cpu->update_vdd(); } //------------------------------------------------------------------------ // // Processor - Constructor // Processor::Processor(const char *_name, const char *_desc) : Module(_name, _desc), pma(0), rma(this), ema(this), pc(0), bad_instruction(0, 0x3fff, 0) { registers = 0; m_pConstructorObject = 0; m_Capabilities = 0; m_ProgramMemoryAllocationSize = 0; if(verbose) cout << "processor constructor\n"; addSymbol(mFrequency = new CPU_Freq(this,20e6)); set_ClockCycles_per_Instruction(4); update_cps(); setWarnMode(true); setSafeMode(true); setUnknownMode(true); setBreakOnReset(true); // derived classes need to override these values m_uPageMask = 0x00; m_uAddrMask = 0xff; readTT = 0; writeTT = 0; interface = new ProcessorInterface(this); // let the processor version number simply be gpsim's version number. version = &pkg_version[0]; get_trace().cycle_counter(get_cycles().get()); addSymbol(m_pWarnMode = new WarnModeAttribute(this)); addSymbol(m_pSafeMode = new SafeModeAttribute(this)); addSymbol(m_pUnknownMode = new UnknownModeAttribute(this)); addSymbol(m_pBreakOnReset = new BreakOnResetAttribute(this)); m_vdd = new CPU_Vdd(this, 5.0); addSymbol(m_vdd); m_pbBreakOnInvalidRegisterRead = new Boolean("BreakOnInvalidRegisterRead", true, "Halt simulation when an invalid register is read from."); addSymbol(m_pbBreakOnInvalidRegisterRead); m_pbBreakOnInvalidRegisterWrite = new Boolean("BreakOnInvalidRegisterWrite", true, "Halt simulation when an invalid register is written to."); addSymbol(m_pbBreakOnInvalidRegisterWrite); set_Vdd(5.0); } //------------------------------------------------------------------- Processor::~Processor() { deleteSymbol(m_pbBreakOnInvalidRegisterRead); deleteSymbol(m_pbBreakOnInvalidRegisterWrite); deleteSymbol(m_pWarnMode); deleteSymbol(m_pSafeMode); deleteSymbol(m_pUnknownMode); deleteSymbol(m_pBreakOnReset); deleteSymbol(mFrequency); deleteSymbol(m_vdd); delete interface; delete_invalid_registers(); delete m_UiAccessOfRegisters; delete []registers; delete readTT; delete writeTT; destroyProgramMemoryAccess(pma); for (unsigned int i = 0; i < m_ProgramMemoryAllocationSize; i++) { if (program_memory[i] != &bad_instruction) { delete program_memory[i]; } } delete []program_memory; } unsigned long Processor::GetCapabilities() { return m_Capabilities; } //------------------------------------------------------------------- // Simulation modes: void Processor::setWarnMode(bool newWarnMode) { bWarnMode = newWarnMode; } void Processor::setSafeMode(bool newSafeMode) { bSafeMode = newSafeMode; } void Processor::setUnknownMode(bool newUnknownMode) { bUnknownMode = newUnknownMode; } void Processor::setBreakOnReset(bool newBreakOnReset) { bBreakOnReset = newBreakOnReset; } //------------------------------------------------------------------------ // Attributes void Processor::set_RCfreq_active(bool state) { if (mFrequency) mFrequency->set_rc_active(state); update_cps(); } void Processor::set_frequency(double f) { if(mFrequency) mFrequency->set(f); update_cps(); } void Processor::set_frequency_rc(double f) { if(mFrequency) mFrequency->set_rc_freq(f); update_cps(); } double Processor::get_frequency() { double d=0.0; if(mFrequency) mFrequency->get(d); return d; } void Processor::update_cps(void) { get_cycles().set_instruction_cps((guint64)(get_frequency()/clocks_per_inst)); } double Processor::get_OSCperiod() { double f = get_frequency(); if(f>0.0) return 1/f; else return 0.0; } /* void Processor::set(const char *cP,int len) { } void Processor::get(char *cP, int len) { cP[0] = 0; } */ //------------------------------------------------------------------- // // init_register_memory (unsigned int memory_size) // // Allocate an array for holding register objects. // void Processor::init_register_memory (unsigned int memory_size) { if(verbose) cout << __FUNCTION__ << " memory size: " << memory_size << '\n'; registers = new Register *[memory_size]; m_UiAccessOfRegisters = new RegisterCollection(this, "ramData", registers, memory_size); if (registers == 0) { throw new FatalError("Out of memory - PIC register space"); } // For processors with banked memory, the register_bank corresponds to the // active bank. Let this point to the beginning of the register array for // now. register_bank = registers; rma.set_Registers(registers, memory_size); // Make all of the file registers 'undefined' (each processor derived from this base // class defines its own register mapping). for (unsigned int i = 0; i < memory_size; i++) registers[i] = 0; } //------------------------------------------------------------------- // // // create_invalid_registers // // The purpose of this function is to complete the initialization // of the file register memory by placing an instance of an 'invalid // file register' at each 'invalid' memory location. Most of PIC's // do not use the entire address space available, so this routine // fills the voids. // void Processor::create_invalid_registers () { unsigned int addr; if(verbose) cout << "Creating invalid registers " << register_memory_size()<<"\n"; // Now, initialize any undefined register as an 'invalid register' // Note, each invalid register is given its own object. This enables // the simulation code to efficiently capture any invalid register // access. Furthermore, it's possible to set break points on // individual invalid file registers. By default, gpsim halts whenever // there is an invalid file register access. for (addr = 0; addr < register_memory_size(); addr+=map_rm_index2address(1)) { unsigned int index = map_rm_address2index(addr); if (!registers[index]) { char nameBuff[100]; snprintf(nameBuff,sizeof(nameBuff), "INVREG_%X",addr); registers[index] = new InvalidRegister(this, nameBuff); registers[index]->setAddress(addr); } } } //------------------------------------------------------------------- // // Delete invalid registers // void Processor::delete_invalid_registers () { unsigned int i=0; for (i = 0; i < rma.get_size(); i++) { // cout << __FUNCTION__ << " reg: 0x"< (registers[i]); if (pReg) { delete registers[i]; registers[i]= 0; } else if (registers[i]) { char reg_name[11]; cout << __FUNCTION__ << " reg: 0x"<name().c_str(), 10); reg_name[10] = 0; cout << " " << reg_name <isa() == Register::INVALID_REGISTER)) delete registers[j]; else if (registers[j]) cout << __FUNCTION__ << " Already register " << registers[j]->name() << " at 0x" << hex << j <alias_mask = alias_offset; } else registers[j]->alias_mask = 0; registers[j]->setAddress(j); RegisterValue rv = getWriteTT(j); registers[j]->set_write_trace(rv); rv = getReadTT(j); registers[j]->set_read_trace(rv); } } //------------------------------------------------------------------- // delete_file_registers // // The purpose of this member function is to delete file registers // void Processor::delete_file_registers(unsigned int start_address, unsigned int end_address, bool bRemoveWithoutDelete) { #define DFR_DEBUG 0 if (DFR_DEBUG) cout << __FUNCTION__ << " start:" << hex << start_address << " end:" << hex << end_address << endl; // FIXME - this function is bogus. // The aliased registers do not need to be searched for - the alias mask // can tell at what addresses a register is aliased. #define SMALLEST_ALIAS_DISTANCE 32 #define ALIAS_MASK (SMALLEST_ALIAS_DISTANCE-1) unsigned int i,j; if (start_address != end_address) Dprintf(("from 0x%x to 0x%x\n", start_address, end_address)); for (j = start_address; j <= end_address; j++) { if(registers[j]) { Register *thisReg = registers[j]; Register *replaced = thisReg->getReplaced(); if(thisReg->alias_mask) { // This register appears in more than one place. Let's find all // of its aliases. for(i=j&ALIAS_MASK; iname().c_str(), j, j+alias_offset); } else { delete registers[j + alias_offset]; } } registers[j + alias_offset] = registers[j]; if (registers[j]) registers[j]->alias_mask = alias_offset; } } } //------------------------------------------------------------------- // // init_program_memory(unsigned int memory_size) // // The purpose of this member function is to allocate memory for the // pic's code space. The 'memory_size' parameter tells how much memory // is to be allocated // // The following is not correct for 18f2455 and 18f4455 processors // so test has been disabled (RRR) // // AND it should be an integer of the form of 2^n. // If the memory size is not of the form of 2^n, then this routine will // round up to the next integer that is of the form 2^n. // // Once the memory has been allocated, this routine will initialize // it with the 'bad_instruction'. The bad_instruction is an instantiation // of the instruction class that chokes gpsim if it is executed. Note that // each processor owns its own 'bad_instruction' object. void Processor::init_program_memory (unsigned int memory_size) { if(verbose) cout << "Initializing program memory: 0x"<name(); } ProgramMemoryAccess * Processor::createProgramMemoryAccess(Processor *processor) { return new ProgramMemoryAccess(processor); } void Processor::destroyProgramMemoryAccess(ProgramMemoryAccess *pma) { delete pma; } //------------------------------------------------------------------- // init_program_memory(int address, int value) // // The purpose of this member fucntion is to instantiate an Instruction // object in the program memory. If the opcode is invalid, then a 'bad_instruction' // is inserted into the program memory instead. If the address is beyond // the program memory address space, then it may be that the 'opcode' is // is in fact a configuration word. // void Processor::init_program_memory(unsigned int address, unsigned int value) { unsigned int uIndex = map_pm_address2index(address); if (!program_memory) { std::stringstream buf; buf << "ERROR: internal bug " << __FILE__ << ":" << __LINE__; throw new FatalError(buf.str()); } if(uIndex < program_memory_size()) { if(program_memory[uIndex] != 0 && program_memory[uIndex]->isa() != instruction::INVALID_INSTRUCTION) { // this should not happen delete program_memory[uIndex]; } program_memory[uIndex] = disasm(address,value); if(program_memory[uIndex] == 0) program_memory[uIndex] = &bad_instruction; //program_memory[uIndex]->add_line_number_symbol(); } else if (set_config_word(address, value)) ; else set_out_of_range_pm(address,value); // could be e2prom } //------------------------------------------------------------------- //erase_program_memory(unsigned int address) // // Checks if a program memory location contains an instruction // and deletes it if it does. // void Processor::erase_program_memory(unsigned int address) { unsigned int uIndex = map_pm_address2index(address); if (!program_memory) { std::stringstream buf; buf << "ERROR: internal bug " << __FILE__ << ":" << __LINE__; throw new FatalError(buf.str()); } if(uIndex < program_memory_size()) { if(program_memory[uIndex] != 0 && program_memory[uIndex]->isa() != instruction::INVALID_INSTRUCTION) { delete program_memory[uIndex]; program_memory[uIndex] = &bad_instruction; } } else { cout << "Erase Program memory\n"; cout << "Warning::Out of range address " << hex << address << endl; cout << "Max allowed address is 0x" << hex << (program_address_limit()-1) << '\n'; } } void Processor::init_program_memory_at_index(unsigned int uIndex, unsigned int value) { init_program_memory(map_pm_index2address(uIndex), value); } void Processor::init_program_memory_at_index(unsigned int uIndex, const unsigned char *bytes, int nBytes) { for (int i =0; iget_opcode() : 0xffffffff; } //------------------------------------------------------------------- // build_program_memory - given an array of opcodes this function // will convert them into instructions and insert them into the // simulated program memory. // void Processor::build_program_memory(unsigned int *memory, unsigned int minaddr, unsigned int maxaddr) { for (unsigned int i = minaddr; i <= maxaddr; i++) if(memory[i] != 0xffffffff) init_program_memory(i, memory[i]); } //------------------------------------------------------------------- /** @brief Write a word of data into memory outside flash * * This method is called when loading data from the COD or HEX file * and the address is not in the program ROM or normal config space. * In this base class, there is no such memory. Real processors, * particularly those with EEPROM, will need to override this method. * * @param address Memory address to set. Byte address on 18F * @param value Word data to write in. */ void Processor::set_out_of_range_pm(unsigned int address, unsigned int value) { cout << "Warning::Out of range address " << address << " value " << value << endl; cout << "Max allowed address is 0x" << hex << (program_address_limit()-1) << '\n'; } //------------------------------------------------------------------- // // attach_src_line - This member function establishes the one-to-one link // between instructions and the source code that create them. void Processor::attach_src_line(unsigned int address, unsigned int file_id, unsigned int sline, unsigned int lst_line) { unsigned int uIndex = map_pm_address2index(address); if(uIndex < program_memory_size()) program_memory[uIndex]->update_line_number(file_id,sline,lst_line,-1,-1); else printf ( "%s:Address %03X out of range\n", __FUNCTION__, uIndex ); } //------------------------------------------------------------------- // read_src_files - this routine will open all of the source files // associated with the project and associate their line numbers // with the addresses of the opcodes they generated. // void Processor::read_src_files(void) { int i; // Are there any src files ? for(i=0; imax_line() > 0) { // Create an array whose index corresponds to the // line number of a source file line and whose data // is the offset (in bytes) from the beginning of the // file. (e.g. files[3].line_seek[20] references the // 20th line of the third source file.) fc->ReadSource(); } } // Associate source files with the instructions they generated. unsigned int addr; for(addr = 0; addrisa() != instruction::INVALID_INSTRUCTION) && (program_memory[addr]->get_file_id() >= 0)) { FileContext *fc = files[program_memory[addr]->get_file_id()]; if(fc) fc->put_address(program_memory[addr]->get_src_line(), map_pm_index2address(addr)); } } // Associate the list file with if (files.list_id() >= 0) { // Parse the list file. //printf("read_src_files List file:%d %d\n",files.list_id(),files.nsrc_files()); FileContext *fc = files[files.list_id()]; if (!fc) return; fc->ReadSource(); fc->rewind(); char buf[256]; int line = 1; while(fc->gets(buf,sizeof(buf))) { unsigned int address; unsigned int opcode; if (sscanf(buf,"%x %x",&address, &opcode) == 2) { unsigned int uIndex = map_pm_address2index(address); if (uIndex < program_memory_size()) { program_memory[uIndex]->update_line_number(-1,-1,line,-1,-1); fc->put_address(line,address); } } line++; } } } //------------------------------------------------------------------- // // processor -- list // // Display the contents of either a source or list file // void Processor::list(unsigned int file_id, unsigned int pc_val, int start_line, int end_line) { if(files.nsrc_files() == 0) return; if(pc_val > program_memory_size()) return; if(program_memory[pc_val]->isa() == instruction::INVALID_INSTRUCTION) { cout << "There's no code at address 0x" << hex << pc_val << '\n'; return; } unsigned int line,pc_line; if(file_id) { file_id = files.list_id(); line = program_memory[pc_val]->get_lst_line(); pc_line = program_memory[pc->value]->get_lst_line(); } else { file_id = program_memory[pc_val]->get_file_id(); line = program_memory[pc_val]->get_src_line(); pc_line = program_memory[pc->value]->get_src_line(); } start_line += line; end_line += line; FileContext *fc = files[file_id]; if(fc == NULL) return; start_line = (start_line < 0) ? 0 : start_line; end_line = (end_line <= start_line) ? (start_line + 5) : end_line; end_line = (end_line > (int)fc->max_line()) ? fc->max_line() : end_line; cout << " listing " << fc->name() << " Starting line " << start_line << " Ending line " << end_line << '\n'; if (end_line == start_line) return; for(unsigned int i=start_line; i<=(unsigned int)end_line; i++) { char buf[256]; fc->ReadLine(i, buf, sizeof(buf)); if (pc_line == i) cout << "==>"; else cout << " "; cout << buf; } } static void trim(char * pBuffer) { size_t iPos = 0; char * pChar = pBuffer; while(*pChar != 0 && ::isspace(*pChar)) { pChar++; } if(pBuffer != pChar) { memmove(pBuffer, pChar, strlen(pBuffer) - iPos); } iPos = strlen(pBuffer); pChar = pBuffer + iPos - 1; while( pChar > pBuffer && ::isspace(*pChar)) { *pChar = 0; pChar--; } } //------------------------------------------------------------------- // // disassemble - Disassemble the contents of program memory from // 'start_address' to 'end_address'. The instruction at the current // PC is marked with an arrow '==>'. If an instruction has a break // point set on it then it will be marked with a 'B'. The instruction // mnemonics come from the class declarations for each instruction. // However, it is possible to modify this on a per instruction basis. // In other words, each instruction in the program memory has it's // own instantiation. So a MOVWF at address 0x20 is different than // one at address 0x21. It is possible to change the mnemonic of // one without affecting the other. As of version 0.0.7 though, this // is not implemented. // void Processor::disassemble (signed int s, signed int e) { instruction *inst; int use_src_to_disasm = 0; if(s > e) return; unsigned int start_PMindex = map_pm_address2index(s); unsigned int end_PMindex = map_pm_address2index(e); if(start_PMindex >= program_memory_size()) { if(s <0) start_PMindex = 0; else return; } if(end_PMindex >= program_memory_size()) { if(e<0) return; else end_PMindex = program_memory_size()-1; } const int iConsoleWidth = 80; char str[iConsoleWidth]; char str2[iConsoleWidth]; if (!pc) { std::stringstream buf; buf << "ERROR: internal bug " << __FILE__ << ":" << __LINE__; throw new FatalError(buf.str()); } unsigned uPCAddress = pc->get_value(); const char *pszPC; char cBreak; ISimConsole &Console = GetUserInterface().GetConsole(); int iLastFileId = -1; FileContext *fc = NULL; for(unsigned int PMindex = start_PMindex; PMindex<=end_PMindex; PMindex++) { unsigned int uAddress = map_pm_index2address(PMindex); str[0] = 0; pszPC = (uPCAddress == uAddress) ? "==>" : " "; inst = program_memory[PMindex]; // If this is not a "base" instruction then it has been replaced // with something like a break point. cBreak = ' '; if(!inst->isBase()) { cBreak = 'B'; inst = pma->get_base_instruction(PMindex); } if(inst->get_file_id() != -1) { fc = files[inst->get_file_id()]; if(iLastFileId != inst->get_file_id()) Console.Printf("%s\n", fc->name().c_str()); iLastFileId = inst->get_file_id(); } else fc = 0; //const char *pLabel = get_symbol_table().findProgramAddressLabel(uAddress); //if(*pLabel != 0) // cout << pLabel << ":" << endl; AddressSymbol *pAddr = dynamic_cast(inst->getLineSymbol()); if (pAddr) cout << pAddr->name() << ':' << endl; if(fc && files.nsrc_files() && use_src_to_disasm) { char buf[256]; files.ReadLine(inst->get_file_id(), inst->get_src_line() - 1, buf, sizeof(buf)); cout << buf; } else { if(fc != NULL && inst->get_src_line() != -1) { if(fc->ReadLine(inst->get_src_line(), str2, iConsoleWidth - 33) != NULL) { trim(str2); } else { str2[0] = 0; } } else { str2[0] = 0; } inst->name(str, sizeof(str)); char *pAfterNumonic = strchr(str, '\t'); int iNumonicWidth = pAfterNumonic ? pAfterNumonic - str : 5; int iOperandsWidth = 14; int iSrc = iOperandsWidth - (strlen(str) - iNumonicWidth - 1); // Console.Printf("0.........1.........2.........3.........4.........5.........6.........7........."); // Console.Printf("%d, strlen(str)=%d\n", iNumonicWidth, strlen(str)); const char *pFormat = (opcode_size() <=2) ? "% 3s%c%04x %04x %s %*s%s\n" : "% 3s%c%04x %06x %s %*s%s\n"; Console.Printf(pFormat, pszPC, cBreak, uAddress, inst->get_opcode(), str, iSrc, "", str2); } } } //------------------------------------------------------------------- void Processor::save_state(FILE *fp) { if(!fp) return; unsigned int i; fprintf(fp,"PROCESSOR:%s\n",name().c_str()); for(i=1; iisa() != Register::INVALID_REGISTER) { fprintf(fp,"R:%X:%s:(%X,%X)\n", reg->address, reg->name().c_str(), reg->value.get(), reg->value.geti()); } } if(pc) fprintf(fp,"P:0:PC:%X\n",pc->value); } //------------------------------------------------------------------- void Processor::save_state(void) { unsigned int i; for(i=0; iisa() != Register::INVALID_REGISTER) { reg->put_trace_state(reg->getRV_notrace()); } } if(pc) pc->put_trace_state(pc->value); } //------------------------------------------------------------------- void Processor::load_state(FILE *fp) { if(!fp) return; cout << "Not implemented\n"; } /* If Vdd is changed, fix up the digital high low thresholds */ void Processor::update_vdd() { IOPIN *pin; for(int i=1; i <= get_pin_count(); i++) { pin = get_pin(i); if (pin) { pin->set_digital_threshold(get_Vdd()); } } } //------------------------------------------------------------------- int ProgramMemoryAccess::find_closest_address_to_line(int file_id, int src_line) { int closest_address = -1; if ((!cpu) || (file_id == -1)) return closest_address; FileContext *fc = cpu->files[file_id]; if(fc) { int offset=0; while((unsigned int)(src_line+offset)max_line()) { closest_address = fc->get_address(src_line+offset); if(closest_address>=0) return closest_address; offset++; } offset=-1; while(src_line+offset>=0) { closest_address = fc->get_address(src_line+offset); if(closest_address>=0) return closest_address; offset--; } } return closest_address; } //------------------------------------------------------------------- int ProgramMemoryAccess::find_address_from_line(FileContext *fc, int src_line) { return (cpu && fc) ? fc->get_address(src_line) : -1; } //-------------------------------------------------------------------------- // // temporary - this could is going to get deleted as soon as file related // stuff gets put into its own object/class. void ProgramMemoryAccess::set_hll_mode(unsigned int new_hll_mode) { switch(new_hll_mode) { case ASM_MODE: hll_mode = ASM_MODE; break; case HLL_MODE: hll_mode = HLL_MODE; } } //-------------------------------------------------------------------------- int ProgramMemoryAccess::get_src_line(unsigned int address) { unsigned int line=0; if(!cpu || !cpu->IsAddressInRange(address)) return INVALID_VALUE; switch(get_hll_mode()) { case ASM_MODE: line = getFromAddress(address)->get_src_line(); break; case HLL_MODE: line = getFromAddress(address)->get_hll_src_line(); break; } return line; } //-------------------------------------------------------------------------- int ProgramMemoryAccess::get_file_id(unsigned int address) { if(!cpu) return INVALID_VALUE; switch(get_hll_mode()) { case ASM_MODE: return getFromAddress(address)->get_file_id(); break; case HLL_MODE: return getFromAddress(address)->get_hll_file_id(); break; } return INVALID_VALUE; } //------------------------------------------------------------------- unsigned int ProgramMemoryAccess::set_break_at_address(unsigned int address) { if(hasValid_opcode_at_address(address)) return bp.set_execution_break(cpu, address); return INVALID_VALUE; } //------------------------------------------------------------------- unsigned int ProgramMemoryAccess::set_notify_at_address(unsigned int address, TriggerObject *cb) { if(hasValid_opcode_at_address(address)) return bp.set_notify_break(cpu, address, cb); return INVALID_VALUE; } //------------------------------------------------------------------- unsigned int ProgramMemoryAccess::set_profile_start_at_address(unsigned int address, TriggerObject *cb) { unsigned int pm_index = cpu->map_pm_address2index(address); if(pm_indexprogram_memory_size()) if (cpu->program_memory[pm_index]->isa() != instruction::INVALID_INSTRUCTION) return bp.set_profile_start_break(cpu, address, cb); return INVALID_VALUE; } //------------------------------------------------------------------- unsigned int ProgramMemoryAccess::set_profile_stop_at_address(unsigned int address, TriggerObject *cb) { if(hasValid_opcode_at_address(address)) return bp.set_profile_stop_break(cpu, address, cb); return INVALID_VALUE; } //------------------------------------------------------------------- int ProgramMemoryAccess::clear_break_at_address(unsigned int address, enum instruction::INSTRUCTION_TYPES type = instruction::BREAKPOINT_INSTRUCTION) { unsigned int uIndex = cpu->map_pm_address2index(address); if ( uIndexprogram_memory_size() ) { instruction *instr = find_instruction(address,type); if(instr!=0) { int b = ((Breakpoint_Instruction *)instr)->bpn & BREAKPOINT_MASK; // this actually removes the object bp.clear( b ); return 1; } } return 0; } //------------------------------------------------------------------- int ProgramMemoryAccess::clear_break_at_address(unsigned int address, instruction * pInstruction) { if(!cpu || !cpu->IsAddressInRange(address)) return -1; instruction **ppAddressLocation = &cpu->program_memory[cpu->map_pm_address2index(address)]; Breakpoint_Instruction *br = dynamic_cast(*ppAddressLocation); if (br == pInstruction) { // at the head of the chain *ppAddressLocation = br->getReplaced(); br->setReplaced(0); } else { Breakpoint_Instruction *pLast = br; // Find myself in the chain while(br != NULL) { if (br == pInstruction) { // found -- remove from the chain pLast->setReplaced(br->getReplaced()); br->setReplaced(0); return 1; } else { pLast = br; br = dynamic_cast(br->getReplaced()); } } } return 0; } //------------------------------------------------------------------- int ProgramMemoryAccess::clear_notify_at_address(unsigned int address) { return clear_break_at_address(address,instruction::NOTIFY_INSTRUCTION); } //------------------------------------------------------------------- int ProgramMemoryAccess::clear_profile_start_at_address(unsigned int address) { return clear_break_at_address(address,instruction::PROFILE_START_INSTRUCTION); } //------------------------------------------------------------------- int ProgramMemoryAccess::clear_profile_stop_at_address(unsigned int address) { return clear_break_at_address(address,instruction::PROFILE_STOP_INSTRUCTION); } //------------------------------------------------------------------- int ProgramMemoryAccess::address_has_break(unsigned int address, enum instruction::INSTRUCTION_TYPES type) { if(find_instruction(address,type)!=0) return 1; return 0; } //------------------------------------------------------------------- int ProgramMemoryAccess::address_has_notify(unsigned int address) { return address_has_break(address,instruction::NOTIFY_INSTRUCTION); } //------------------------------------------------------------------- int ProgramMemoryAccess::address_has_profile_start(unsigned int address) { return address_has_break(address,instruction::PROFILE_START_INSTRUCTION); } //------------------------------------------------------------------- int ProgramMemoryAccess::address_has_profile_stop(unsigned int address) { return address_has_break(address,instruction::PROFILE_STOP_INSTRUCTION); } //------------------------------------------------------------------- void ProgramMemoryAccess::toggle_break_at_address(unsigned int address) { if(address_has_break(address)) clear_break_at_address(address); else set_break_at_address(address); } //------------------------------------------------------------------- void ProgramMemoryAccess::set_break_at_line(unsigned int file_id, unsigned int src_line) { int address; if( (address = find_closest_address_to_line(file_id, src_line)) >= 0) set_break_at_address(address); } void ProgramMemoryAccess::clear_break_at_line(unsigned int file_id, unsigned int src_line) { int address; if( (address = find_closest_address_to_line(file_id, src_line)) >= 0) clear_break_at_address(address); } void ProgramMemoryAccess::toggle_break_at_line(unsigned int file_id, unsigned int src_line) { toggle_break_at_address(find_closest_address_to_line(file_id, src_line)); } //------------------------------------------------------------------- // Processor * Processor::construct(void) { cout << " Can't create a generic processor\n"; return 0; } //------------------------------------------------------------------- void Processor::trace_dump(int type, int amount) { trace.dump(amount, stdout); } //------------------------------------------------------------------- // Decode a single trace item int Processor::trace_dump1(int type, char *buffer, int bufsize) { snprintf(buffer, bufsize,"*** INVALID TRACE *** 0x%x",type); return 1; } //------------------------------------------------------------------- // getWriteTT // // For devices with more than 64k of registers (which are not supported // at the moment), we can enhance this function to return different Trace // type objects base on the upper address bits. RegisterValue Processor::getWriteTT(unsigned int j) { if(!writeTT) { writeTT = new RegisterWriteTraceType(this,2); trace.allocateTraceType(writeTT); } // The upper 8-bits define the dynamically allocated trace type // The lower 8-bits will record the register value that is written. // The middle 16-bits are the register address unsigned int tt = (writeTT->type() & 0xff000000) | ((j & 0xffff) << 8); return RegisterValue(tt, tt + (1<<24) ); } RegisterValue Processor::getReadTT(unsigned int j) { if(!readTT) { readTT = new RegisterReadTraceType(this,2); trace.allocateTraceType(readTT); } // The upper 8-bits define the dynamically allocated trace type // The lower 8-bits will record the register value that is written. // The middle 16-bits are the register address unsigned int tt = (readTT->type() & 0xff000000) | ((j & 0xffff) << 8); return RegisterValue(tt, tt + (1<<24) ); } //------------------------------------------------------------------- // // step_over - In most cases, step_over will simulate just one instruction. // However, if the next instruction is a branching one (e.g. goto, call, // return, etc.) then a break point will be set after it and gpsim will // begin 'running'. This is useful for stepping over time-consuming calls. // void Processor::step_over (bool refresh) { step(1,refresh); // Try one step } //------------------------------------------------------------------- void Processor::run_to_address (unsigned int destination) { if(simulation_mode != eSM_STOPPED) { if(verbose) cout << "Ignoring run-to-address request because simulation is not stopped\n"; return; } // Set a temporary break point unsigned int bp_num = bp.set_execution_break(this, destination); run(); bp.clear(bp_num); } //------------------------------------------------------------------- // // // create // // The purpose of this member function is to 'create' a pic processor. // Since this is a base class member function, only those things that // are common to all pics are created. void Processor::create (void) { std::stringstream buf; buf << " a generic processor cannot be created " << __FILE__ << ":" << __LINE__; throw new FatalError(buf.str()); } //------------------------------------------------------------------- void Processor::dump_registers (void) { // parse_string("dump"); } //------------------------------------------------------------------- void Processor::Debug() { cout << " === Debug === \n"; if(pc) cout << "PC=0x"<value << endl; } //------------------------------------------------------------------- instruction *ProgramMemoryAccess::find_instruction(unsigned int address, enum instruction::INSTRUCTION_TYPES type) { unsigned int uIndex = cpu->map_pm_address2index(address); if(cpu->program_memory_size()<=uIndex) return 0; instruction *p = getFromIndex(uIndex); if(p->isa()==instruction::INVALID_INSTRUCTION) return 0; for(;;) { if(p->isa()==type) return p; switch(p->isa()) { case instruction::MULTIWORD_INSTRUCTION: case instruction::INVALID_INSTRUCTION: case instruction::NORMAL_INSTRUCTION: return 0; case instruction::BREAKPOINT_INSTRUCTION: case instruction::NOTIFY_INSTRUCTION: case instruction::PROFILE_START_INSTRUCTION: case instruction::PROFILE_STOP_INSTRUCTION: case instruction::ASSERTION_INSTRUCTION: p=((Breakpoint_Instruction *)p)->getReplaced(); break; } } return 0; } //------------------------------------------------------------------- guint64 Processor::cycles_used(unsigned int address) { return program_memory[address]->getCyclesUsed(); } //------------------------------------------------------------------- MemoryAccess::MemoryAccess(Processor *new_cpu) { cpu = new_cpu; } MemoryAccess::~MemoryAccess() { } Processor *MemoryAccess::get_cpu(void) { return cpu; } //------------------------------------------------------------------- //------------------------------------------------------------------- // Program memory interface used by the command line class ProgramMemoryCollection : public IIndexedCollection { public: ProgramMemoryCollection(Processor *pProcessor, const char *collection_name, ProgramMemoryAccess *pPma); ~ProgramMemoryCollection(); virtual unsigned int GetSize(); virtual Value &GetAt(unsigned int uAddress, Value *pValue=0); virtual void SetAt(unsigned int uAddress, Value *pValue); virtual void ConsolidateValues(int &iColumnWidth, vector &aList, vector &aValue); virtual unsigned int GetLowerBound(); virtual unsigned int GetUpperBound(); virtual bool bIsIndexInRange(unsigned int uIndex); virtual void get(char *return_str, int len); private: Processor * m_pProcessor; ProgramMemoryAccess *m_pPma; Integer m_ReturnValue; }; ProgramMemoryCollection::ProgramMemoryCollection (Processor *pProcessor, const char *pC_collection_name, ProgramMemoryAccess *pPma) : IIndexedCollection(16), m_ReturnValue(0) { m_pProcessor = pProcessor; Value::new_name(pC_collection_name); m_pPma = pPma; pProcessor->addSymbol(this); } ProgramMemoryCollection::~ProgramMemoryCollection() { if (m_pProcessor) m_pProcessor->removeSymbol(this); } void ProgramMemoryCollection::get(char *return_str, int len) { if (return_str) strncpy(return_str, "", len); } unsigned int ProgramMemoryCollection::GetSize() { return m_pProcessor->program_memory_size(); } Value &ProgramMemoryCollection::GetAt(unsigned int uAddress, Value *) { //m_pProcessor->map_pm_address2index m_ReturnValue.set((int)m_pPma->get_rom(uAddress)); m_ReturnValue.setBitmask( (1<<(m_pProcessor->opcode_size()*8)) - 1); ostringstream sIndex; sIndex << Value::name() << "[" << hex << m_szPrefix << uAddress << "]" << '\000'; m_ReturnValue.new_name(sIndex.str().c_str()); return m_ReturnValue; } void ProgramMemoryCollection::SetAt(unsigned int uAddress, Value *pValue) { Integer *pInt = dynamic_cast(pValue); if(pInt == NULL) { throw new Error("rValue is not an Integer"); } else { m_pPma->put_rom(uAddress, (unsigned int)(int)*pInt); } } void ProgramMemoryCollection::ConsolidateValues(int &iColumnWidth, std::vector &aList, std::vector &aValue) { unsigned int uFirstAddress = 0; unsigned int uAddress; //Register * pReg = m_ppRegisters[0]; //Integer uLastValue(pReg->getRV_notrace().data); Integer uLastValue(m_pPma->get_opcode(0)); uLastValue.setBitmask((1 << (m_pProcessor->opcode_size() * 8)) - 1); unsigned int uSize = GetSize(); for (uAddress = 0; uAddress < uSize; uAddress++) { unsigned int ui_opcode = m_pPma->get_opcode(uAddress); if ((unsigned int)uLastValue != ui_opcode) { PushValue(uFirstAddress, uAddress, &uLastValue, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); uFirstAddress = uAddress; uLastValue = ui_opcode; } } uAddress--; // Record the last set of elements if (uFirstAddress <= uAddress) { PushValue(uFirstAddress, uAddress, &uLastValue, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); } } //void RegisterCollection::SetAt(ExprList_t* pIndexers, Expression *pExpr) { // throw Error("RegisterCollection::SetAt() not implemented"); //} unsigned int ProgramMemoryCollection::GetLowerBound() { return 0; } unsigned int ProgramMemoryCollection::GetUpperBound() { return GetSize() - 1; } bool ProgramMemoryCollection::bIsIndexInRange(unsigned int uAddress) { return m_pPma->get_rom(uAddress) != 0xffffffff; // (uIndex >= GetLowerBound() && uIndex <= GetUpperBound()) || } //------------------------------------------------------------------- //------------------------------------------------------------------- // // ProgramMemoryAccess // // The ProgramMemoryAccess class provides an interface to the processor's // program memory. On Pic processors, this is the memory where instructions // are stored. // ProgramMemoryAccess::ProgramMemoryAccess(Processor *new_cpu) : MemoryAccess(new_cpu) { init(new_cpu); m_pRomCollection = new ProgramMemoryCollection(new_cpu, "romData", this); } ProgramMemoryAccess::~ProgramMemoryAccess() { delete m_pRomCollection; } void ProgramMemoryAccess::init(Processor *new_cpu) { _address = _opcode = _state = 0; hll_mode = ASM_MODE; // add the 'main' pma to the list pma context's. Processors may // choose to add multiple pma's to the context list. The gui // will build a source browser for each one of these. The purpose // is to provide more than one way of debugging the code. (e.g. // this is useful for debugging interrupt versus non-interrupt code). if(cpu) cpu->pma_context.push_back(this); } /* void ProgramMemoryAccess::name(string & new_name) { name_str = new_name; } */ void ProgramMemoryAccess::putToAddress(unsigned int address, instruction *new_instruction) { putToIndex(cpu->map_pm_address2index(address), new_instruction); } void ProgramMemoryAccess::putToIndex(unsigned int uIndex, instruction *new_instruction) { if(!new_instruction) return; cpu->program_memory[uIndex] = new_instruction; new_instruction->update(); } void ProgramMemoryAccess::remove(unsigned int address, instruction *bp_instruction) { if(!bp_instruction) return; instruction *instr = cpu->program_memory[cpu->map_pm_address2index(address)]; if (typeid(Breakpoint_Instruction) == typeid(*instr) || typeid(RegisterAssertion) == typeid(*instr)) { Breakpoint_Instruction* toRemove = (Breakpoint_Instruction*)bp_instruction; Breakpoint_Instruction *last = (Breakpoint_Instruction*)instr; if (toRemove == last) { cpu->program_memory[cpu->map_pm_address2index(address)] = last->getReplaced(); return; } do { if(typeid(Breakpoint_Instruction) != typeid(*last->getReplaced()) && typeid(RegisterAssertion) != typeid(*last->getReplaced())) // not found return; Breakpoint_Instruction *replaced = (Breakpoint_Instruction*)last->getReplaced(); if(toRemove == replaced) { // remove from the chain last->setReplaced(replaced->getReplaced()); return; } last = replaced; } while(typeid(Breakpoint_Instruction) != typeid(*last)); } // if we get here the object was not in the list or was // not a Breakpoint_Instruction // assert(typeid(*instr) != typeid(Breakpoint_Instruction)); } instruction *ProgramMemoryAccess::getFromAddress(unsigned int address) { if(!cpu || !cpu->IsAddressInRange(address)) return &cpu->bad_instruction; unsigned int uIndex = cpu->map_pm_address2index(address); return getFromIndex(uIndex); } instruction *ProgramMemoryAccess::getFromIndex(unsigned int uIndex) { if(uIndex < cpu->program_memory_size()) return cpu->program_memory[uIndex]; else return 0; } // like get, but will ignore instruction break points instruction *ProgramMemoryAccess::get_base_instruction(unsigned int uIndex) { instruction *p; p=getFromIndex(uIndex); if(p==0) return 0; for(;;) { switch(p->isa()) { case instruction::MULTIWORD_INSTRUCTION: case instruction::INVALID_INSTRUCTION: case instruction::NORMAL_INSTRUCTION: return p; case instruction::BREAKPOINT_INSTRUCTION: case instruction::NOTIFY_INSTRUCTION: case instruction::PROFILE_START_INSTRUCTION: case instruction::PROFILE_STOP_INSTRUCTION: case instruction::ASSERTION_INSTRUCTION: p=((Breakpoint_Instruction *)p)->getReplaced(); break; } } return 0; } //---------------------------------------- // get_rom - return the rom contents from program memory // If the address is normal program memory, then the opcode // of the instruction at that address is returned. // If the address is some other special memory (like configuration // memory in a PIC) then that data is returned instead. unsigned int ProgramMemoryAccess::get_rom(unsigned int addr) { return cpu->get_program_memory_at_address(addr); } //---------------------------------------- // put_rom - write new data to the program memory. // If the address is in normal program memory, then a new instruction // will be generated (if possible). If the address is some other // special memory (like configuration memory), then that area will // be updated. // void ProgramMemoryAccess::put_rom(unsigned int addr,unsigned int value) { return cpu->init_program_memory(addr,value); } //---------------------------------------- // get_opcode - return an opcode from program memory. // If the address is out of range return 0. unsigned int ProgramMemoryAccess::get_opcode(unsigned int addr) { instruction * pInstr = getFromAddress(addr); if(pInstr != 0) return pInstr->get_opcode(); else return 0; } //---------------------------------------- // get_opcode_name - return an opcode name from program memory. // If the address is out of range return 0; char *ProgramMemoryAccess::get_opcode_name(unsigned int addr, char *buffer, unsigned int size) { unsigned int uIndex = cpu->map_pm_address2index(addr); if(uIndex < cpu->program_memory_size()) return cpu->program_memory[uIndex]->name(buffer,size); *buffer = 0; return 0; } //---------------------------------------- // Get the current value of the program counter. unsigned int ProgramMemoryAccess::get_PC(void) { if(cpu && cpu->pc) return cpu->pc->get_value(); return 0; } //---------------------------------------- // Get the current value of the program counter. void ProgramMemoryAccess::set_PC(unsigned int new_pc) { if(cpu && cpu->pc) return cpu->pc->put_value(new_pc); } Program_Counter *ProgramMemoryAccess::GetProgramCounter(void) { if(cpu) return cpu->pc; return 0; } void ProgramMemoryAccess::put_opcode_start(unsigned int addr, unsigned int new_opcode) { unsigned int uIndex = cpu->map_pm_address2index(addr); if( (uIndex < cpu->program_memory_size()) && (_state == 0)) { _state = 1; _address = addr; _opcode = new_opcode; get_cycles().set_break_delta(40000, this); bp.set_pm_write(); } } void ProgramMemoryAccess::put_opcode(unsigned int addr, unsigned int new_opcode) { unsigned int uIndex = cpu->map_pm_address2index(addr); if(uIndex >= cpu->program_memory_size()) return; instruction *old_inst = get_base_instruction(uIndex); instruction *new_inst = cpu->disasm(addr,new_opcode); if(new_inst==0) { puts("FIXME, in ProgramMemoryAccess::put_opcode"); return; } if(!old_inst) { putToIndex(uIndex,new_inst); return; } if(old_inst->isa() == instruction::INVALID_INSTRUCTION) { putToIndex(uIndex,new_inst); return; } // Now we need to make sure that the instruction we are replacing is // not a multi-word instruction. The 12 and 14 bit cores don't have // multi-word instructions, but the 16 bit cores do. If we are replacing // the second word of a multiword instruction, then we only need to // 'uninitialize' it. // if there was a breakpoint set at addr, save a pointer to the breakpoint. Breakpoint_Instruction *b=bpi; instruction *prev = get_base_instruction(cpu->map_pm_address2index(addr-1)); if(prev) prev->initialize(false); new_inst->update_line_number(old_inst->get_file_id(), old_inst->get_src_line(), old_inst->get_lst_line(), old_inst->get_hll_src_line(), old_inst->get_hll_file_id()); if(b) b->setReplaced(new_inst); else cpu->program_memory[uIndex] = new_inst; cpu->program_memory[uIndex]->setModified(true); cpu->program_memory[uIndex]->update(); delete(old_inst); } //-------------------------------------------------------------------------- void ProgramMemoryAccess::assign_xref(unsigned int address, XrefObject * xref) { instruction &q = *getFromAddress(address); if(q.isa()==instruction::INVALID_INSTRUCTION) { delete (int *)xref->data; delete xref; return; } q.add_xref(xref); } //-------------------------------------------------------------------------- void ProgramMemoryAccess::step(unsigned int steps,bool refresh) { if(!cpu) return; switch(get_hll_mode()) { case ASM_MODE: cpu->step(steps,refresh); break; case HLL_MODE: unsigned int initial_pc = cpu->pc->get_value(); int initial_line = cpu->pma->get_src_line(initial_pc); int initial_file = cpu->pma->get_file_id(initial_pc); while(1) { cpu->step(1,false); unsigned int current_pc = cpu->pc->get_value(); int current_line = cpu->pma->get_src_line(current_pc); int current_file = cpu->pma->get_file_id(current_pc); if(current_line<0 || current_file<0) continue; if(current_pc == initial_pc || current_line != initial_line || current_file != initial_file) { if(refresh) get_interface().simulation_has_stopped(); break; } } break; } } //-------------------------------------------------------------------------- void ProgramMemoryAccess::step_over(bool refresh) { if(!cpu) return; switch(get_hll_mode()) { case ASM_MODE: cpu->step_over(refresh); break; case HLL_MODE: pic_processor *pic = dynamic_cast(cpu); if(!pic) { cout << "step-over is not supported for non-PIC processors\n"; return; } unsigned int initial_pc = cpu->pc->get_value(); int initial_line = cpu->pma->get_src_line(initial_pc); int initial_file = cpu->pma->get_file_id(initial_pc); unsigned int initial_stack_depth = pic->stack->pointer&pic->stack->stack_mask; while(1) { cpu->step(1,false); if(initial_stack_depth < (pic->stack->pointer&pic->stack->stack_mask)) cpu->finish(); unsigned int current_pc = cpu->pc->get_value(); int current_line = cpu->pma->get_src_line(current_pc); int current_file = cpu->pma->get_file_id(current_pc); if(current_line<0 || current_file<0) continue; if(current_pc == initial_pc || current_line != initial_line || current_file != initial_file) { if(refresh) get_interface().simulation_has_stopped(); break; } } break; } } //-------------------------------------------------------------------------- void ProgramMemoryAccess::run(bool refresh) { cpu->run(refresh); } //-------------------------------------------------------------------------- void ProgramMemoryAccess::stop(void) { bp.halt(); } //-------------------------------------------------------------------------- void ProgramMemoryAccess::finish(void) { cpu->finish(); } //-------------------------------------------------------------------------- bool ProgramMemoryAccess::hasValid_opcode_at_address(unsigned int address) { if(getFromAddress(address)->isa() != instruction::INVALID_INSTRUCTION) return true; return false; } bool ProgramMemoryAccess::hasValid_opcode_at_index(unsigned int uIndex) { if((getFromIndex(uIndex))->isa() != instruction::INVALID_INSTRUCTION) return true; return false; } //-------------------------------------------------------------------------- bool ProgramMemoryAccess::isModified(unsigned int address) // ***FIXME*** - address or index? { unsigned int uIndex = cpu->map_pm_address2index(address); if((uIndex < cpu->program_memory_size()) && cpu->program_memory[uIndex]->bIsModified()) return true; return false; } //======================================================================== // Register Memory Access RegisterMemoryAccess::RegisterMemoryAccess(Processor *new_cpu) : MemoryAccess(new_cpu) { registers = 0; nRegisters = 0; } RegisterMemoryAccess::~RegisterMemoryAccess() { } //-------------------------------------------------------------------------- Register *RegisterMemoryAccess::get_register(unsigned int address) { if(!cpu || !registers || nRegisters<=address) return 0; Register *reg = registers[address]; // If there are breakpoints set on the register, then drill down // through them until we get to the real register. return reg ? reg->getReg() : 0; } //-------------------------------------------------------------------------- void RegisterMemoryAccess::set_Registers(Register **_registers, int _nRegisters) { nRegisters = _nRegisters; registers = _registers; } //------------------------------------------------------------------------ // insertRegister - Each register address may contain a linked list of registers. // The top most register is the one that is referenced whenever a processor // accesses the register memory. The primary purpose of the linked list is to // support register breakpoints. For example, a write breakpoint is implemented // with a breakpoint class derived from the register class. Setting a write // breakpoint involves creating the write breakpoint object and placing it // at the top of the register linked list. Then, when a processor attempts // to write to this register, the breakpoint object will capture this and // halt the simulation. bool RegisterMemoryAccess::insertRegister(unsigned int address, Register *pReg) { if(!cpu || !registers || nRegisters <= address ||!pReg) return false; Register *ptop = registers[address]; pReg->setReplaced(ptop); registers[address] = pReg; return true; } //------------------------------------------------------------------------ // removeRegister - see comment on insertRegister. This method removes // a register object from the breakpoint linked list. bool RegisterMemoryAccess::removeRegister(unsigned int address, Register *pReg) { if(!cpu || !registers || nRegisters <= address ||!pReg) return false; Register *ptop = registers[address]; if (ptop == pReg && pReg->getReplaced()) registers[address] = pReg->getReplaced(); else while (ptop) { Register *pNext = ptop->getReplaced(); if (pNext == pReg) { ptop->setReplaced(pNext->getReplaced()); return true; } ptop = pNext; } return false; } //------------------------------------------------------------------- bool RegisterMemoryAccess::hasBreak(unsigned int address) { if(!cpu || !registers || nRegisters <= address) return false; return registers[address]->isa() == Register::BP_REGISTER; } static InvalidRegister AnInvalidRegister(0,"AnInvalidRegister"); //------------------------------------------------------------------- Register &RegisterMemoryAccess::operator [] (unsigned int address) { if(!registers || get_size() <= address) return AnInvalidRegister; return *registers[address]; } void RegisterMemoryAccess::reset (RESET_TYPE r) { for(unsigned int i=0; ipush_back(this); } //------------------------------------------------------------ Processor * ProcessorConstructor::ConstructProcessor(const char *opt_name) { // Instantiate a specific processor. If a name is provided, then that // will be used. Otherwise, the third name in the list of aliases for // this processor will be used instead. (Why 3rd?... Before optional // processor names were allowed, the default name matched what is now // the third alias; this maintains a backward compatibility). if (opt_name && strlen(opt_name)) return cpu_constructor(opt_name); return cpu_constructor(names[2]); } ProcessorConstructorList * ProcessorConstructor::processor_list; ProcessorConstructorList * ProcessorConstructor::GetList() { if(processor_list == NULL) { processor_list = new ProcessorConstructorList(); } return processor_list; } //------------------------------------------------------------ // findByType -- search through the list of supported processors for // the one matching 'name'. ProcessorConstructor *ProcessorConstructorList::findByType(const char *name) { ProcessorConstructorList::iterator processor_iterator; ProcessorConstructorList *pl = ProcessorConstructor::GetList(); for (processor_iterator = pl->begin(); processor_iterator != pl->end(); ++processor_iterator) { ProcessorConstructor *p = *processor_iterator; for(int j=0; jnames[j] && strcmp(name,p->names[j]) == 0) return p; } return 0; } //------------------------------------------------------------ // dump() -- Print out a list of all of the processors // string ProcessorConstructorList::DisplayString(void) { ostringstream stream; list :: iterator processor_iterator; const int nPerRow = 4; // Number of names to print per row. int i,j,k,longest; ProcessorConstructorList *pl = ProcessorConstructor::GetList(); ProcessorConstructor *p; // loop through all of the processors and find the // one with the longest name longest = 0; for (processor_iterator = pl->begin(); processor_iterator != pl->end(); ++processor_iterator) { p = *processor_iterator; k = strlen(p->names[1]); if(k>longest) longest = k; } // Print the name of each processor. for (processor_iterator = pl->begin(); processor_iterator != pl->end(); ) { for(i=0; iend(); i++) { p = *processor_iterator++; stream << p->names[1]; if(inames[1]); for(j=0; j line_number) return pm_address[line_number]; return -1; } //---------------------------------------- void FileContext::put_address(unsigned int line_number, unsigned int address) { if(line_number <= max_line() && pm_address.size() > line_number && pm_address[line_number]<0) pm_address[line_number] = address; } //------------------------------------------------------------------------ FileContextList::FileContextList() { lastFile=0; list_file_id = -1; // assume that no list file is present. } FileContextList::~FileContextList(void) { FileContextList::iterator it; FileContextList::iterator itEnd = end(); for (it = begin(); it != itEnd; ++it) it->close(); } static bool EndsWith(string &sSubject, string &sSubstring) { if(sSubject.size() < sSubstring.size()) { return false; } else { string sSubjectEnding = sSubject.substr(sSubject.size() - sSubstring.size()); return sSubjectEnding == sSubstring; } } int FileContextList::Find(string &fname) { if(lastFile) { for (int i = 0; i < lastFile; i++) { if(EndsWith((*this)[i]->name(), fname)) { return i; } } } return -1; } extern bool bHasAbsolutePath(string &fname); int FileContextList::Add(string &new_name, bool hll) { string sFull = bHasAbsolutePath(new_name) ? new_name : (sSourcePath + new_name); push_back(FileContext(sFull)); back().setHLLId(hll); lastFile++; if(CSimulationContext::GetContext()->IsSourceEnabled()) { back().open("r"); if(verbose) cout << "Added new file named: " << new_name << " id = " << lastFile << endl; } return lastFile-1; } int FileContextList::Add(const char *new_name, bool hll) { string sNewName(new_name); return Add (sNewName, hll); } FileContext *FileContextList::operator [] (int file_id) { if(file_id<0 || file_id >= lastFile) return 0; return &this->_Myt::at(file_id); } char *FileContextList::ReadLine(int file_id, int line_number, char *buf, int nBytes) { FileContext *fc = operator[](file_id); if(fc) return fc->ReadLine(line_number, buf, nBytes); buf[0] = '\0'; return buf; } //---------------------------------------- // char *FileContextList::gets(int file_id, char *buf, int nBytes) { FileContext *fc = operator[](file_id); if(fc) return fc->gets(buf, nBytes); return 0; } //---------------------------------------- void FileContextList::rewind(int file_id) { FileContext *fc = operator[](file_id); if(fc) return fc->rewind(); } extern void EnsureTrailingFolderDelimiter(string &sPath); extern void SplitPathAndFile(string &sSource, string &sFolder, string &sFile); //---------------------------------------- void FileContextList::SetSourcePath(const char *pPath) { std::string sPath(pPath); std::string sFile; SplitPathAndFile(sPath, sSourcePath, sFile); EnsureTrailingFolderDelimiter(sSourcePath); } //---------------------------------------- // void FileContextList::list_id(int new_list_id) { FileContext *fc = operator[](list_file_id); if (fc) fc->setListId(false); list_file_id = new_list_id; fc = operator[](list_file_id); if (fc) fc->setListId(true); } gpsim-0.30.0/src/Makefile.in0000664000076400007640000011365513117441635012520 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(gpsiminclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(gpsimincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsim_la_DEPENDENCIES = am_libgpsim_la_OBJECTS = 12bit-hexdecode.lo 12bit-processors.lo \ 14bit-instructions.lo 14bit-processors.lo 14bit-registers.lo \ 14bit-tmrs.lo 14bit-hexdecode.lo 16bit-instructions.lo \ 16bit-processors.lo 16bit-registers.lo 16bit-hexdecode.lo \ 16bit-tmrs.lo attributes.lo a2dconverter.lo a2d_v2.lo ctmu.lo \ bitlog.lo bit.lo bytelog.lo breakpoints.lo clock_phase.lo \ cod.lo comparator.lo cmd_manager.lo eeprom.lo errors.lo \ i2c-ee.lo fopen-path.lo gpsim_object.lo gpsim_time.lo \ hexutils.lo init.lo intcon.lo interface.lo ioports.lo \ lcd_module.lo lxt_write.lo modules.lo os_dependent.lo \ p1xf1xxx.lo p12f6xx.lo p12x.lo p16f62x.lo p16x8x.lo p16f8x.lo \ p16f88x.lo p16f87x.lo p16x7x.lo p16x5x.lo p16x6x.lo p16f91x.lo \ p17c75x.lo p18x.lo p18fk.lo packages.lo pic-processor.lo \ pic-registers.lo pic-instructions.lo pic-ioports.lo pie.lo \ pir.lo pm_rd.lo processor.lo program_files.lo protocol.lo \ registers.lo sim_context.lo stimuli.lo symbol.lo tmr0.lo \ trace.lo trigger.lo ttoken.lo uart.lo ssp.lo psp.lo xref.lo \ spp.lo dsm_module.lo icd.lo expr.lo operator.lo ui.lo value.lo \ ValueCollections.lo libgpsim_la_OBJECTS = $(am_libgpsim_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgpsim_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libgpsim_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libgpsim_la_SOURCES) DIST_SOURCES = $(libgpsim_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(gpsiminclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim.la gpsimincludedir = $(includedir)/gpsim libgpsim_la_SOURCES = \ 12bit-hexdecode.cc \ 12bit-processors.cc \ 14bit-instructions.cc \ 14bit-processors.cc \ 14bit-registers.cc \ 14bit-tmrs.cc \ 14bit-hexdecode.cc \ 16bit-instructions.cc \ 16bit-processors.cc \ 16bit-registers.cc \ 16bit-hexdecode.cc \ 16bit-tmrs.cc \ attributes.cc \ a2dconverter.cc \ a2d_v2.cc \ ctmu.cc \ bitlog.cc \ bit.cc \ bytelog.cc \ breakpoints.cc \ clock_phase.cc \ cod.cc \ comparator.cc \ cmd_manager.cc \ eeprom.cc \ errors.cc \ i2c-ee.cc \ fopen-path.cc \ gpsim_object.cc \ gpsim_time.cc \ hexutils.cc \ init.cc \ intcon.cc \ interface.cc \ ioports.cc \ lcd_module.cc \ lxt_write.c \ modules.cc \ os_dependent.cc \ p1xf1xxx.cc \ p12f6xx.cc \ p12x.cc \ p16f62x.cc \ p16x8x.cc \ p16f8x.cc \ p16f88x.cc \ p16f87x.cc \ p16x7x.cc \ p16x5x.cc \ p16x6x.cc \ p16f91x.cc \ p17c75x.cc \ p18x.cc \ p18fk.cc \ packages.cc \ pic-processor.cc \ pic-registers.cc \ pic-instructions.cc \ pic-ioports.cc \ pie.cc \ pir.cc \ pm_rd.cc \ processor.cc \ program_files.cc \ protocol.cc \ registers.cc \ sim_context.cc \ stimuli.cc \ symbol.cc \ tmr0.cc \ trace.cc \ trigger.cc \ ttoken.cc \ uart.cc \ ssp.cc \ psp.cc \ xref.cc \ spp.cc \ dsm_module.cc \ icd.cc \ expr.cc \ operator.cc \ ui.cc \ value.cc \ ValueCollections.cc gpsiminclude_HEADERS = \ 12bit-instructions.h \ 12bit-processors.h \ 14bit-instructions.h \ 14bit-processors.h \ 14bit-registers.h \ 14bit-tmrs.h \ 16bit-instructions.h \ 16bit-processors.h \ 16bit-registers.h \ 16bit-tmrs.h \ a2dconverter.h \ a2d_v2.h \ ctmu.h \ attributes.h \ bit.h \ bitlog.h \ breakpoints.h \ bytelog.h \ clock_phase.h \ cmd_gpsim.h \ cmd_manager.h \ cod.h \ comparator.h \ eeprom.h \ exports.h \ hexutils.h \ i2c-ee.h \ fopen-path.h \ gpsim_classes.h \ gpsim_def.h \ gpsim_interface.h \ gpsim_object.h \ gpsim_time.h \ intcon.h \ interface.h \ ioports.h \ lcd_module.h \ lxt_write.h \ modules.h \ operator.h \ p12f6xx.h \ p12x.h \ p1xf1xxx.h \ p16x5x.h \ p16f62x.h \ p16x6x.h \ p16x7x.h \ p16x8x.h \ p16f8x.h \ p16f88x.h \ p16f87x.h \ p16f91x.h \ p17c75x.h \ p18x.h \ p18fk.h \ packages.h \ pic-instructions.h \ pic-packages.h \ pic-processor.h \ pic-registers.h \ pic-ioports.h \ picdis.h \ pie.h \ pir.h \ pm_rd.h \ processor.h \ program_files.h \ protocol.h \ pthread-wrap.h \ registers.h \ rcon.h \ sim_context.h \ stimuli.h \ symbol.h \ tmr0.h \ trace.h \ trigger.h \ trace_orb.h \ ttoken.h \ uart.h \ xref.h \ icd.h \ ssp.h \ psp.h \ spp.h \ dsm_module.h \ errors.h \ expr.h \ ui.h \ value.h \ ValueCollections.h #libgpsim_la_LDFLAGS = $(shell gtk-config --libs) libgpsim_la_LIBADD = @X_LDFLAGS@ libgpsim_la_LDFLAGS = -lpthread SUBDIRS = dspic EXTRA_DIST = makefile.mingw all: all-recursive .SUFFIXES: .SUFFIXES: .c .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgpsim.la: $(libgpsim_la_OBJECTS) $(libgpsim_la_DEPENDENCIES) $(EXTRA_libgpsim_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgpsim_la_LINK) -rpath $(libdir) $(libgpsim_la_OBJECTS) $(libgpsim_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/12bit-hexdecode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/12bit-processors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/14bit-hexdecode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/14bit-instructions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/14bit-processors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/14bit-registers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/14bit-tmrs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/16bit-hexdecode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/16bit-instructions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/16bit-processors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/16bit-registers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/16bit-tmrs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ValueCollections.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a2d_v2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a2dconverter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attributes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitlog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoints.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bytelog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock_phase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cod.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comparator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctmu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsm_module.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eeprom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fopen-path.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsim_object.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsim_time.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hexutils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i2c-ee.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intcon.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ioports.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lcd_module.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt_write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modules.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/operator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_dependent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p12f6xx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p12x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16f62x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16f87x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16f88x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16f8x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16f91x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16x5x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16x6x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16x7x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p16x8x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p17c75x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p18fk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p18x.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p1xf1xxx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packages.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pic-instructions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pic-ioports.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pic-processor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pic-registers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pie.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pm_rd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/program_files.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/registers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sim_context.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimuli.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmr0.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trigger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttoken.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uart.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/value.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xref.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-gpsimincludeHEADERS: $(gpsiminclude_HEADERS) @$(NORMAL_INSTALL) @list='$(gpsiminclude_HEADERS)'; test -n "$(gpsimincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(gpsimincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(gpsimincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(gpsimincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(gpsimincludedir)" || exit $$?; \ done uninstall-gpsimincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(gpsiminclude_HEADERS)'; test -n "$(gpsimincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(gpsimincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(gpsimincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-gpsimincludeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-gpsimincludeHEADERS uninstall-libLTLIBRARIES .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libLTLIBRARIES \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am \ install-gpsimincludeHEADERS install-html install-html-am \ install-info install-info-am install-libLTLIBRARIES \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ uninstall-gpsimincludeHEADERS uninstall-libLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/src/p16f62x.h0000664000076400007640000000603713041763624011734 00000000000000/* Copyright (C) 1998-2002 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P16F62X_H__ #define __P16F62X_H__ #include "p16x6x.h" #include "eeprom.h" #include "comparator.h" /*************************************************************************** * * Include file for: P16F627, P16F628, P16F648 * * * The F62x devices are quite a bit different from the other PICs. The class * heirarchy is similar to the 16F84. * * ***************************************************************************/ class P16F62x : public P16X6X_processor { public: P16F62x(const char *_name=0, const char *desc=0); ~P16F62x(); USART_MODULE usart; ComparatorModule comparator; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F627_;}; virtual void create_symbols(); virtual unsigned int register_memory_size () const { return 0x200;}; virtual unsigned int program_memory_size() { return 0; }; virtual void create_sfr_map(); // The f628 (at least) I/O pins depend on the Fosc Configuration bits. virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void create(int ram_top, unsigned int eeprom_size); virtual void create_iopin_map(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F62x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } }; class P16F627 : public P16F62x { public: virtual PROCESSOR_TYPE isa(){return _P16F627_;}; virtual unsigned int program_memory_size() const { return 0x400; }; P16F627(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16F628 : public P16F627 { public: virtual PROCESSOR_TYPE isa(){return _P16F628_;}; virtual unsigned int program_memory_size() const { return 0x800; }; P16F628(const char *_name=0, const char *desc=0); ~P16F628(); static Processor *construct(const char *name); }; class P16F648 : public P16F628 { public: virtual PROCESSOR_TYPE isa(){return _P16F648_;}; virtual unsigned int program_memory_size() const { return 0x1000; }; virtual void create_sfr_map(); P16F648(const char *_name=0, const char *desc=0); ~P16F648(); static Processor *construct(const char *name); }; #endif gpsim-0.30.0/src/protocol.cc0000664000076400007640000001437713041763613012623 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "protocol.h" unsigned int a2i(char b) { if( b>='0' && b<='9') return b-'0'; if( b>='A' && b<='F') return b-'A'+10; if( b>='a' && b<='f') return b-'a'+10; return 0; } char i2a(unsigned int i) { i &= 0x0f; if(i < 10) return '0' + i; return 'A'+ i- 10; } unsigned int ascii2uint(char **buffer, int digits) { unsigned int ret = 0; char *b = *buffer; for(int i=0; i (size - index)) { ulen = size-index; } if(ulen) { memcpy(&buffer[index],s, ulen); index += ulen; } } void PacketBuffer::advanceIndex(unsigned int amount) { if(index + amount < size) index += amount; else index = size-1; } void PacketBuffer::terminate() { if(index < size) buffer[index]=0; } //======================================================================== Packet::Packet(unsigned int rxsize, unsigned int txsize) { rxBuffer = new PacketBuffer(rxsize); txBuffer = new PacketBuffer(txsize); } bool Packet::DecodeHeader() { if(*rxBuffer->buffer == '$') { rxBuffer->index = 1; return true; } rxBuffer->index = 0; return false; } bool Packet::DecodeChar(char c) { if(*rxBuffer->getBuffer() == c) { rxBuffer->index++; return true; } return false; } bool Packet::DecodeUInt32(unsigned int &i) { char *b = rxBuffer->getBuffer(); if(ascii2uint(&b,2) == eGPSIM_TYPE_UINT32) { i = ascii2uint(b,8); rxBuffer->index += 2+8; return true; } return false; } bool Packet::DecodeUInt64(guint64 &i) { char *b = rxBuffer->getBuffer(); if(ascii2uint(&b,2) == eGPSIM_TYPE_UINT64) { i = ascii2uint64(b,16); rxBuffer->index += 2+16; return true; } return false; } bool Packet::DecodeBool(bool &b) { char *buff = rxBuffer->getBuffer(); if(ascii2uint(&buff,2) == eGPSIM_TYPE_BOOLEAN) { if(*buff == '0') b = false; else if(*buff == '1') b = true; else return false; rxBuffer->index += 2+1; return true; } return false; } bool Packet::DecodeFloat(double &d) { char *b = rxBuffer->getBuffer(); if(ascii2uint(&b,2) == eGPSIM_TYPE_FLOAT) { double dtry = strtod(b, &b); unsigned int len = b - rxBuffer->buffer; if( len < rxBuffer->size - rxBuffer->index) { rxBuffer->index += len; d = dtry; return true; } } return false; } bool Packet::DecodeObjectType(unsigned int &i) { i = ascii2uint(rxBuffer->getBuffer(),2); rxBuffer->index += 2; return true; } bool Packet::DecodeString(char *retStr, int maxLen) { char *b = rxBuffer->getBuffer(); if(ascii2uint(&b,2) == eGPSIM_TYPE_STRING) { int length = ascii2uint(&b,2); maxLen--; // reserve space for a terminating 0. length = (maxLen < length) ? maxLen : length; strncpy(retStr, b, length); retStr[length] = 0; //*buffer = b + length; rxBuffer->index += 2+2+length; return true; } return false; } bool Packet::EncodeHeader() { txBuffer->putc('$'); txBuffer->terminate(); return true; } bool Packet::EncodeUInt32(unsigned int i) { txBuffer->putc(i2a(eGPSIM_TYPE_UINT32 /16)); txBuffer->putc(i2a(eGPSIM_TYPE_UINT32 )); for(int j=7; j>=0; j--) txBuffer->putc ( i2a ( i>> (4*j))); return true; } bool Packet::EncodeUInt64(guint64 i) { txBuffer->putc(i2a(eGPSIM_TYPE_UINT64 /16)); txBuffer->putc(i2a(eGPSIM_TYPE_UINT64 )); for(int j=15; j>=0; j--) txBuffer->putc ( i2a ( i>> (4*j))); return true; } bool Packet::EncodeObjectType(unsigned int i) { EncodeHeader(); //txBuffer->putc(i2a(eGPSIM_TYPE_OBJECT /16)); //txBuffer->putc(i2a(eGPSIM_TYPE_OBJECT )); txBuffer->putc ( i2a ( i>> (4*1))); txBuffer->putc ( i2a ( i>> (4*0))); return true; } bool Packet::EncodeBool(bool b) { txBuffer->putc(i2a(eGPSIM_TYPE_BOOLEAN /16)); txBuffer->putc(i2a(eGPSIM_TYPE_BOOLEAN )); if(b) txBuffer->putc('1'); else txBuffer->putc('0'); return true; } bool Packet::EncodeFloat(double d) { txBuffer->putc(i2a(eGPSIM_TYPE_FLOAT /16)); txBuffer->putc(i2a(eGPSIM_TYPE_FLOAT )); char buff[256]; snprintf(buff,sizeof(buff),"%8E~",d); txBuffer->puts(buff,strlen(buff)); return true; } bool Packet::EncodeString(const char *str, int len) { if(!str) return false; txBuffer->putc(i2a(eGPSIM_TYPE_STRING /16)); txBuffer->putc(i2a(eGPSIM_TYPE_STRING )); if(len < 0) len = strlen(str); txBuffer->putc(i2a(len>>4)); txBuffer->putc(i2a(len)); txBuffer->puts(str, len); return true; } bool Packet::EncodeCustom(const char *str, int len) { if(!str) return false; txBuffer->putc(i2a(eGPSIM_TYPE_CUSTOM /16)); txBuffer->putc(i2a(eGPSIM_TYPE_CUSTOM )); txBuffer->putc(i2a(len>>4)); txBuffer->putc(i2a(len)); txBuffer->puts(str, len); return true; } gpsim-0.30.0/src/Makefile.am0000664000076400007640000000566013076746754012521 00000000000000## Process this file with automake to produce Makefile.in AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim.la gpsimincludedir = $(includedir)/gpsim libgpsim_la_SOURCES = \ 12bit-hexdecode.cc \ 12bit-processors.cc \ 14bit-instructions.cc \ 14bit-processors.cc \ 14bit-registers.cc \ 14bit-tmrs.cc \ 14bit-hexdecode.cc \ 16bit-instructions.cc \ 16bit-processors.cc \ 16bit-registers.cc \ 16bit-hexdecode.cc \ 16bit-tmrs.cc \ attributes.cc \ a2dconverter.cc \ a2d_v2.cc \ ctmu.cc \ bitlog.cc \ bit.cc \ bytelog.cc \ breakpoints.cc \ clock_phase.cc \ cod.cc \ comparator.cc \ cmd_manager.cc \ eeprom.cc \ errors.cc \ i2c-ee.cc \ fopen-path.cc \ gpsim_object.cc \ gpsim_time.cc \ hexutils.cc \ init.cc \ intcon.cc \ interface.cc \ ioports.cc \ lcd_module.cc \ lxt_write.c \ modules.cc \ os_dependent.cc \ p1xf1xxx.cc \ p12f6xx.cc \ p12x.cc \ p16f62x.cc \ p16x8x.cc \ p16f8x.cc \ p16f88x.cc \ p16f87x.cc \ p16x7x.cc \ p16x5x.cc \ p16x6x.cc \ p16f91x.cc \ p17c75x.cc \ p18x.cc \ p18fk.cc \ packages.cc \ pic-processor.cc \ pic-registers.cc \ pic-instructions.cc \ pic-ioports.cc \ pie.cc \ pir.cc \ pm_rd.cc \ processor.cc \ program_files.cc \ protocol.cc \ registers.cc \ sim_context.cc \ stimuli.cc \ symbol.cc \ tmr0.cc \ trace.cc \ trigger.cc \ ttoken.cc \ uart.cc \ ssp.cc \ psp.cc \ xref.cc \ spp.cc \ dsm_module.cc \ icd.cc \ expr.cc \ operator.cc \ ui.cc \ value.cc \ ValueCollections.cc gpsiminclude_HEADERS = \ 12bit-instructions.h \ 12bit-processors.h \ 14bit-instructions.h \ 14bit-processors.h \ 14bit-registers.h \ 14bit-tmrs.h \ 16bit-instructions.h \ 16bit-processors.h \ 16bit-registers.h \ 16bit-tmrs.h \ a2dconverter.h \ a2d_v2.h \ ctmu.h \ attributes.h \ bit.h \ bitlog.h \ breakpoints.h \ bytelog.h \ clock_phase.h \ cmd_gpsim.h \ cmd_manager.h \ cod.h \ comparator.h \ eeprom.h \ exports.h \ hexutils.h \ i2c-ee.h \ fopen-path.h \ gpsim_classes.h \ gpsim_def.h \ gpsim_interface.h \ gpsim_object.h \ gpsim_time.h \ intcon.h \ interface.h \ ioports.h \ lcd_module.h \ lxt_write.h \ modules.h \ operator.h \ p12f6xx.h \ p12x.h \ p1xf1xxx.h \ p16x5x.h \ p16f62x.h \ p16x6x.h \ p16x7x.h \ p16x8x.h \ p16f8x.h \ p16f88x.h \ p16f87x.h \ p16f91x.h \ p17c75x.h \ p18x.h \ p18fk.h \ packages.h \ pic-instructions.h \ pic-packages.h \ pic-processor.h \ pic-registers.h \ pic-ioports.h \ picdis.h \ pie.h \ pir.h \ pm_rd.h \ processor.h \ program_files.h \ protocol.h \ pthread-wrap.h \ registers.h \ rcon.h \ sim_context.h \ stimuli.h \ symbol.h \ tmr0.h \ trace.h \ trigger.h \ trace_orb.h \ ttoken.h \ uart.h \ xref.h \ icd.h \ ssp.h \ psp.h \ spp.h \ dsm_module.h \ errors.h \ expr.h \ ui.h \ value.h \ ValueCollections.h #libgpsim_la_LDFLAGS = $(shell gtk-config --libs) libgpsim_la_LIBADD = @X_LDFLAGS@ libgpsim_la_LDFLAGS = -lpthread SUBDIRS = dspic EXTRA_DIST = makefile.mingw gpsim-0.30.0/src/psp.cc0000664000076400007640000001274013041763624011556 00000000000000/* Copyright (C) 2006 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include "../config.h" #include "stimuli.h" #include "psp.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //-------------------------------------------------- // //-------------------------------------------------- class CS_SignalSink : public SignalSink { public: CS_SignalSink(PSP *_psp) : m_psp(_psp) { assert(_psp); } virtual void release(){ delete this;} void setSinkState(char new3State) { m_psp->setCS_State(new3State); } private: PSP *m_psp; }; class RD_SignalSink : public SignalSink { public: RD_SignalSink(PSP *_psp) : m_psp(_psp) { assert(_psp); } virtual void release(){ delete this;} void setSinkState(char new3State) { m_psp->setRD_State(new3State); } private: PSP *m_psp; }; class WR_SignalSink : public SignalSink { public: WR_SignalSink(PSP *_psp) : m_psp(_psp) { assert(_psp); } virtual void release(){delete this;} void setSinkState(char new3State) { m_psp->setWR_State(new3State); } private: PSP *m_psp; }; /* * Some devices use high bits of a TRIS register, but others * have a dedicated PSPCON register which is defined here */ PSPCON::PSPCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } void PSPCON::put(unsigned int new_value) { unsigned int mask = (PSP::OBF | PSP::IBF | 0x0f); unsigned int fixed; trace.raw(write_trace.get() | value.data); if (! (new_value & PSP::PSPMODE)) fixed = 0; else fixed = value.data & mask; value.data = (new_value & ~mask) | fixed; } void PSPCON::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; } // // setup information for PSP module // void PSP::initialize( PIR_SET *_pir_set, PicPSP_PortRegister *_port_set, PicTrisRegister *_port_tris, sfr_register *_pspcon, PinModule *pin_RD, PinModule *pin_WR, PinModule *pin_CS) { if (verbose & 2) cout << "PSP::initialize called\n"; pir_set = _pir_set; parallel_port = _port_set; parallel_port->setPSP(this); parallel_tris = _port_tris; cntl_tris = _pspcon; // // The rest of this function allows catching of changes to PSP contol signals // if (!m_rd_sink) { m_rd_sink = new RD_SignalSink(this); Not_RD = pin_RD; if (Not_RD) Not_RD->addSink(m_rd_sink); } if (!m_cs_sink) { m_cs_sink = new CS_SignalSink(this); Not_CS = pin_CS; if (Not_CS) Not_CS->addSink(m_cs_sink); } if (!m_wr_sink) { m_wr_sink = new WR_SignalSink(this); Not_WR = pin_WR; if (Not_WR) Not_WR->addSink(m_wr_sink); } } // // process changes on the control pins // void PSP::state_control() { if (! pspmode()) return; if (verbose & 2) cout << "PSP state change cs=" << cs << " wr=" << wr << " rd=" << rd <put(0xff); state = ST_INACTIVE; return; } else if (cs && rd) { parallel_tris->put(0); parallel_port->put_value(put_value); cntl_tris->put_value(cntl_tris->get() & ~OBF); state = ST_READ; } else if (cs && wr) { parallel_tris->put(0xff); get_value = parallel_port->get_value(); state = ST_WRITE; } else { if (state != ST_INACTIVE) { pir_set->set_pspif(); } // // On first bus write set IBF flag. // if a second bus write occurs prior to read of pic port (portd) // IBOV flag is also set. // if (state == ST_WRITE) { unsigned int trise_val = cntl_tris->get(); if (trise_val & IBF) cntl_tris->put_value(trise_val | IBOV); else cntl_tris->put_value(trise_val | IBF); } parallel_tris->put(0xff); state = ST_INACTIVE; } return; } // // The next three functions are called when their control pin change state // The control pins are active low which is converted to active high signals void PSP::setRD_State(char new3State) { rd = new3State == '0'; state_control(); } void PSP::setCS_State(char new3State) { cs = new3State == '0'; state_control(); } void PSP::setWR_State(char new3State) { wr = new3State == '0'; state_control(); } // // psp_put is called on write to portd when pspmode is active // set OBF register bit and save value for next bus read // void PSP::psp_put(unsigned int new_value) { cntl_tris->put_value(cntl_tris->get() | OBF); put_value = new_value; } // // psp_get is called on read of portd when pspmode is active so // we can clear the IBF flag // unsigned int PSP::psp_get(void) { cntl_tris->put_value(cntl_tris->get() & ~IBF); return(get_value); } gpsim-0.30.0/src/os_dependent.cc0000664000076400007640000002377213065573230013430 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* os_dependent.cc - */ /* version 0.1 */ #include #include #include #include "../config.h" #include "exports.h" #include "modules.h" #ifdef _WIN32 #define G_PLATFORM_WIN32 #define G_OS_WIN32 #include #include #include #include #define STRICMP stricmp #else #include #include #define STRICMP strcasecmp #endif // _WIN32 using namespace std; #ifdef _WIN32 #define MODULE_EXT ".dll" #define FOLDERDELIMITER '\\' #define FOLDERDELIMITERALTERNATIVE '/' #define PATHDELIMITER ";" #else #ifdef __APPLE__ #define MODULE_EXT ".dylib" #else #define MODULE_EXT ".so" #endif #define MODULE_VER ".0" #define FOLDERDELIMITER '/' #define FOLDERDELIMITERALTERNATIVE '\\' #define PATHDELIMITER ":" #endif #ifdef _WIN32 #define OS_E_FILENOTFOUND 0x0000007E #define OS_E_MEMORYACCESS 0x000003E6 #else // JRH - just made a guess #define OS_E_FILENOTFOUND ENOENT #define OS_E_MEMORYACCESS EADDRNOTAVAIL #include #endif //------------------------------------------------------------------------ // Convert forward slashes and backslashes into the os-dependent // slash void translatePath(string &sPath) { string::size_type nPos; while ( (nPos = sPath.find(FOLDERDELIMITERALTERNATIVE)) != string::npos) sPath[nPos] = FOLDERDELIMITER; } //------------------------------------------------------------------------ // EnsureTrailingFolderDelimiter -- append a directory delimeter (slash) // to the string if one is not present already. void EnsureTrailingFolderDelimiter(string &sPath) { string::reference rLast = sPath.at(sPath.size() - 1); if(rLast == FOLDERDELIMITERALTERNATIVE) rLast = FOLDERDELIMITER; else if(rLast != FOLDERDELIMITER) sPath.push_back(FOLDERDELIMITER); } //------------------------------------------------------------------------ bool LIBGPSIM_EXPORT IsFileExtension(const char *pszFile, const char *pFileExt) { string s(pszFile); string::size_type i = s.rfind('.') ; return (i != string::npos) && (s.substr(i+1)==pFileExt); } //------------------------------------------------------------------------ /// SplitPathAndFile() /// Note this function does not verify whether the trailing /// is actually a file component. void SplitPathAndFile(string &sSource, string &sFolder, string &sFile) { translatePath(sSource); string::size_type LastDelimiter = sSource.find_last_of(FOLDERDELIMITER); if (LastDelimiter == string::npos) { // JRH - I'm not sure this is a good assumption. // It will do for the one place it is currently being used. static char sCurrentFolder[] = { '.', FOLDERDELIMITER , '\0'}; sFolder.append(sCurrentFolder); sFile = sSource; } else { sFolder = sSource.substr(0, LastDelimiter + 1); sFile = sSource.substr(LastDelimiter + 1); } } const char * CFileSearchPath::Find(string &path) { const_iterator it = find(begin(), end(), path); if (it != end()) { return (*it).c_str(); } return NULL; } static CFileSearchPath asDllSearchPath; #if defined(_DEBUG) static bool bAltPaths = false; #endif //void AddModulePathFromFilePath(string &sFolder) { void AddModulePathFromFilePath(char *arg) { string sFile; string sFolder = arg; asDllSearchPath.AddPathFromFilePath(sFolder, sFile); char * pszGpsimModulePath; if((pszGpsimModulePath = getenv("GPSIM_MODULE_PATH")) != NULL) { char * pLast = pszGpsimModulePath; char * pChar = strchr(pszGpsimModulePath, PATHDELIMITER[0]); string sFolder; while(true) { if(pChar != NULL) { *pChar = '\0'; } if(*pLast != '\0') { // only add non empty folders sFolder = pLast; translatePath(sFolder); if(sFolder[sFolder.size() - 1] != FOLDERDELIMITER) { sFolder.push_back(FOLDERDELIMITER); } asDllSearchPath.push_back(sFolder); } if(pChar == NULL) { break; } pChar++; pLast = pChar; pChar = strchr(pChar, PATHDELIMITER[0]); } } #if defined(_DEBUG) if(!bAltPaths) { bAltPaths = true; string sPath; int iPos = sFolder.find_last_of(FOLDERDELIMITER); if(iPos != string::npos) { char szLine[1024]; sPath = sFolder.substr(0, iPos + 1); sPath.append("altpaths.txt"); FILE *pFile = fopen(sPath.c_str(), "r"); if(pFile) { while(fgets(szLine, 1024, pFile) != NULL) { char *pChar = &szLine[strlen(szLine) - 1]; while((*pChar == '\n') && pChar != szLine) *pChar-- = 0; if(*pChar != FOLDERDELIMITER) { pChar++; *pChar = FOLDERDELIMITER; pChar++; *pChar = 0; } asDllSearchPath.push_back(string(szLine)); } fclose(pFile); } } } #endif } void CFileSearchPath::AddPathFromFilePath(string &sFolder, string &sFile) { string::size_type LastDelimiter = sFolder.find_last_of(FOLDERDELIMITER); if (LastDelimiter == string::npos) { sFile = sFolder; } else { string sNewFolder; sNewFolder = sFolder.substr(0, LastDelimiter + 1); sFile = sFolder.substr(LastDelimiter + 1); iterator it = find(asDllSearchPath.begin(), asDllSearchPath.end(), sNewFolder); if (it == asDllSearchPath.end()) { asDllSearchPath.insert(asDllSearchPath.begin(), sNewFolder); } } } //------------------------------------------------------------------------ bool bHasAbsolutePath(string &fname) { return fname[0] == FOLDERDELIMITER; } //--------------------------- //OS agnostic library loader static void * sLoad(const char *library_name) { if(!library_name) return 0; void *handle; #ifdef _WIN32 handle = (void *)LoadLibrary((LPCSTR)library_name); #else // According to the man page for dlopen, the RTLD_GLOBAL flag can // be or'd with the second pararmeter of the function call. However, // under Linux at least, this apparently cause *all* symbols to // disappear. handle = dlopen (library_name, RTLD_NOW); // | RTLD_GLOBAL); #endif return handle; } void FixupLibraryName(string &sPath) { translatePath(sPath); } void GetFileName(string &sPath, string &sName) { string::size_type pos = sPath.find_last_of(FOLDERDELIMITER); if(pos != string::npos) { sName = sPath.substr(pos + 1); } else if(&sName != &sPath) { sName = sPath; } } void GetFileNameBase(string &sPath, string &sName) { GetFileName(sPath, sName); string::size_type pos = sName.find_last_of('.'); if(pos != string::npos) { sName = sName.substr(0, sName.size() - pos + 1); } else { sName = sPath; } } const char * get_error_message() { #ifdef _WIN32 return g_win32_error_message(GetLastError()); #else return dlerror(); #endif } void free_error_message(const char * pszError) { #ifdef _WIN32 g_free((char *) pszError); #endif } unsigned long get_error(const char *err_str) { #ifdef _WIN32 return GetLastError(); #else /* ** In Linux and likely all Unix like OSs, dlopen leaves errno as 0 ** even after failure, If so, look in error string returned by dlerror ** to try to determine if file was not found. RRR */ unsigned long ret = errno; // in Linux errno is 0 if (! ret && err_str && strstr(err_str, "No such file")) ret = OS_E_FILENOTFOUND; return ret; #endif } void * load_library(const char *library_name, const char **pszError) { void *handle; string sFile; string sPath(library_name); FixupLibraryName(sPath); asDllSearchPath.AddPathFromFilePath(sPath, sFile); // loop twice: first time take the file name as is, // the second time append the os-dependent library extension. for (int i=0; i<2; i++) { // First, see if we can load the library from where ever the // system thinks libraries are located. if( (handle = sLoad(sPath.c_str())) != 0) return handle; *pszError = get_error_message(); unsigned long uError = get_error(*pszError); if (uError == OS_E_FILENOTFOUND) { // Failed to find the library in the system paths, so try to load // from one of our paths. free_error_message(*pszError); CFileSearchPath::iterator itSearchPath; for (itSearchPath = asDllSearchPath.begin(); itSearchPath != asDllSearchPath.end(); ++itSearchPath) { sPath = *itSearchPath + sFile; handle = sLoad(sPath.c_str()); if (NULL != handle) { return handle; } *pszError = get_error_message(); } } // Append the module extension and try again. string::size_type nPos = sFile.find(MODULE_EXT,0); if( nPos == string::npos) { sFile.append(MODULE_EXT); } #ifndef _WIN32 else if( sFile.find(MODULE_VER, nPos) == string::npos) { i--; sFile.append(MODULE_VER); } #endif sPath = sFile; } // Should there be a free? if (*pszError) printf("Failed loading %s: %s\n", sPath.c_str(), *pszError); return NULL; } void free_library(void *handle) { #ifdef _WIN32 FreeLibrary((HMODULE)handle); #else dlclose (handle); #endif } void * get_library_export(const char *name, void *library_handle, const char ** pszError) { void * pExport; #ifdef _WIN32 pExport = (void*)GetProcAddress((HMODULE)library_handle, name); #else dlerror(); // Clear possible previous errors pExport = dlsym(library_handle, name); #endif if (NULL == pExport && pszError != NULL) { *pszError = get_error_message(); } return pExport; } gpsim-0.30.0/src/14bit-instructions.cc0000664000076400007640000002037313045306452014436 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "14bit-processors.h" #include "14bit-instructions.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("0x%06X %s() ",cycles.get(),__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //--------------------------------------------------------- ADDFSR::ADDFSR(Processor *new_cpu, unsigned int new_opcode, const char *pName, unsigned int address) : instruction(new_cpu, new_opcode,address) { m_fsr = (opcode>>6)&1; m_lit = opcode & 0x3f; if (m_lit & 0x20) m_lit -= 0x40; switch(m_fsr) { case 0: ia = &cpu14e->ind0; break; case 1: ia = &cpu14e->ind1; break; } new_name(pName); } char *ADDFSR::name(char *return_str,int len) { snprintf(return_str,len,"%s\t%u,0x%x", gpsimObject::name().c_str(), m_fsr, m_lit); return(return_str); } void ADDFSR::execute() { ia->put_fsr(ia->fsr_value + m_lit); //ADDFSR cpu_pic->pc->increment(); } //-------------------------------------------------- ADDLW::ADDLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("addlw"); } void ADDLW::execute(void) { unsigned int old_value,new_value; new_value = (old_value = cpu14->Wget()) + L; cpu14->Wput(new_value & 0xff); cpu14->status->put_Z_C_DC(new_value, old_value, L); cpu14->pc->increment(); } //--------------------------------------------------------- MOVIW::MOVIW(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode,address) { if (opcode & 0x3f00) // Index indirect { m_fsr = (opcode>>6)&1; m_lit = opcode & 0x3f; if (m_lit & 0x20) m_lit -= 0x40; m_op = DELTA; Dprintf((" shift op %x fsr %u data %d raw %u\n", opcode >> 6, m_fsr, m_lit, opcode & 0x3f)); } else { m_fsr = (opcode>>2)&1; m_op = opcode & 0x3; } switch(m_fsr) { case 0: ia = &cpu14e->ind0; break; case 1: ia = &cpu14e->ind1; break; } new_name("moviw"); } char *MOVIW::name(char *return_str,int len) { switch(m_op) { case PREINC: snprintf(return_str,len,"%s\t++FSR%u", gpsimObject::name().c_str(), m_fsr); break; case PREDEC: snprintf(return_str,len,"%s\t--FSR%u", gpsimObject::name().c_str(), m_fsr); break; case POSTINC: snprintf(return_str,len,"%s\tFSR%u++", gpsimObject::name().c_str(), m_fsr); break; case POSTDEC: snprintf(return_str,len,"%s\tFSR%u--", gpsimObject::name().c_str(), m_fsr); break; case DELTA: snprintf(return_str,len,"%s\t%d[FSR%u]", gpsimObject::name().c_str(), m_lit, m_fsr); break; } return(return_str); } void MOVIW::execute() { unsigned int new_value = 0; if (m_op == PREINC) { ia->put_fsr(ia->fsr_value + 1); new_value = ia->indf.get(); cpu14->Wput(new_value); } else if (m_op == PREDEC) { ia->put_fsr(ia->fsr_value - 1); new_value = ia->indf.get(); cpu14->Wput(new_value); } else if (m_op == POSTINC) { new_value = ia->indf.get(); cpu14->Wput(new_value); ia->put_fsr(ia->fsr_value + 1); } else if (m_op == POSTDEC) { new_value = ia->indf.get(); cpu14->Wput(new_value); ia->put_fsr(ia->fsr_value - 1); } else if (m_op == DELTA) { ia->fsr_delta = m_lit; new_value = ia->indf.get(); cpu14->Wput(new_value); } cpu14->status->put_Z(new_value==0); cpu_pic->pc->increment(); } //--------------------------------------------------------- MOVWI::MOVWI(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode,address) { if (opcode & 0x3f00) // Index indirect { m_fsr = (opcode>>6)&1; m_lit = opcode & 0x3f; if (m_lit & 0x20) m_lit -= 0x40; m_op = DELTA; Dprintf((" shift op %x fsr %u data %d\n", opcode>>6, m_fsr, m_lit)); } else { m_fsr = (opcode>>2)&1; m_op = opcode & 0x3; } switch(m_fsr) { case 0: ia = &cpu14e->ind0; break; case 1: ia = &cpu14e->ind1; break; } new_name("movwi"); } char *MOVWI::name(char *return_str,int len) { switch(m_op) { case PREINC: snprintf(return_str,len,"%s\t++FSR%u", gpsimObject::name().c_str(), m_fsr); break; case PREDEC: snprintf(return_str,len,"%s\t--FSR%u", gpsimObject::name().c_str(), m_fsr); break; case POSTINC: snprintf(return_str,len,"%s\tFSR%u++", gpsimObject::name().c_str(), m_fsr); break; case POSTDEC: snprintf(return_str,len,"%s\tFSR%u--", gpsimObject::name().c_str(), m_fsr); break; case DELTA: snprintf(return_str,len,"%s\t%d[FSR%u]", gpsimObject::name().c_str(), m_lit, m_fsr); break; } return(return_str); } void MOVWI::execute() { if (m_op == PREINC) { ia->put_fsr(ia->fsr_value + 1); ia->indf.put(cpu14->Wget()); } else if (m_op == PREDEC) { ia->put_fsr(ia->fsr_value - 1); ia->indf.put(cpu14->Wget()); } else if (m_op == POSTINC) { ia->indf.put(cpu14->Wget()); ia->put_fsr(ia->fsr_value + 1); } else if (m_op == POSTDEC) { ia->indf.put(cpu14->Wget()); ia->put_fsr(ia->fsr_value - 1); } else if (m_op == DELTA) { Dprintf((" DELTA fsr %u delta %d\n", m_fsr, m_lit)); ia->fsr_delta = m_lit; ia->indf.put(cpu14->Wget()); } cpu_pic->pc->increment(); } //-------------------------------------------------- MOVLB::MOVLB (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("movlb"); } void MOVLB::execute() { cpu_pic->registers[cpu14e->bsr.address]->put(L); cpu_pic->pc->increment(); } char *MOVLB::name(char *return_str,int len) { snprintf(return_str,len,"%s\t0x%02x", gpsimObject::name().c_str(),L&0x1f); return(return_str); } //-------------------------------------------------- RETFIE::RETFIE (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu,new_opcode,address) { decode(new_cpu, new_opcode); new_name("retfie"); } void RETFIE::execute(void) { cpu14->pc->new_address(cpu14->stack->pop()); cpu14->intcon->in_interrupt = false; // test for pending intterrupts cpu14->intcon->put_value(cpu14->intcon->value.get()); if(cpu_pic->base_isa() == _14BIT_E_PROCESSOR_) { cpu14e->status->put(cpu14e->status_shad.get()); cpu14e->Wput(cpu14e->wreg_shad.get()); cpu14e->bsr.put(cpu14e->bsr_shad.get()); cpu14e->pclath->put(cpu14e->pclath_shad.get()); cpu14e->ind0.fsrl.put(cpu14e->fsr0l_shad.get()); cpu14e->ind0.fsrh.put(cpu14e->fsr0h_shad.get()); cpu14e->ind1.fsrl.put(cpu14e->fsr1l_shad.get()); cpu14e->ind1.fsrh.put(cpu14e->fsr1h_shad.get()); } } //-------------------------------------------------- RETURN::RETURN (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu,new_opcode,address) { decode(new_cpu, new_opcode); new_name("return"); } void RETURN::execute(void) { cpu14->pc->new_address(cpu14->stack->pop()); } //-------------------------------------------------- SUBLW::SUBLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("sublw"); } void SUBLW::execute(void) { unsigned int old_value,new_value; new_value = L - (old_value = cpu14->Wget()); cpu14->Wput(new_value & 0xff); cpu14->status->put_Z_C_DC_for_sub(new_value, old_value, L); cpu14->pc->increment(); } gpsim-0.30.0/src/lcd_module.h0000664000076400007640000001107313113654676012731 00000000000000/* Copyright (C) 2017 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __LCD_H__ #define __LCD_H__ class LCD_MODULE; class pic_processor; // LCDCON - LIQUID CRYSTAL DISPLAY CONTROL REGISTER class LCDCON : public sfr_register { public: enum { LMUX0 = 1<<0, //LMUX<1:0> Commons Select bits LMUX1 = 1<<1, CS0 = 1<<2, //CS<1:0> Clock Source Select bits CS1 = 1<<3, VLCDEN = 1<<4, // LCD Bias Voltage Pins Enable bit WERR = 1<<5, // LCD Write Failed Error bit SLPEN = 1<<6, // LCD Driver Enable in Sleep mode bit LCDEN = 1<<7 // LCD Driver Enable bit }; LCDCON(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); LCD_MODULE *lcd_module; }; // LCDPS - LCD PRESCALER SELECT REGISTER class LCDPS : public sfr_register { public: enum { LP0 = 1<<0, //LP<3:0>: LCD Prescaler Select bits LP1 = 1<<1, LP2 = 1<<2, LP3 = 1<<3, WA = 1<<4, // LCD Write Allow Status bit LCDA = 1<<5, // LCD Active Status bit BIASMD = 1<<6, // Bias Mode Select bit WFT = 1<<7, // Waveform Type Select bit LPMASK = (LP0 | LP1 | LP2 | LP3) }; LCDPS(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *, unsigned int); virtual void put(unsigned int new_value); LCD_MODULE *lcd_module; unsigned int mask_writeable; }; // LCDSEn - LCD SEGMENT REGISTERS class LCDSEn : public sfr_register { public: LCDSEn(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *, unsigned int _n); virtual void put(unsigned int new_value); LCD_MODULE *lcd_module; unsigned int n; }; // LCDDATAx - LCD DATA REGISTERS class LCDDATAx : public sfr_register { public: LCDDATAx(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *, unsigned int _n); virtual void put(unsigned int new_value); LCD_MODULE *lcd_module; unsigned int n; // bypass put for Power On Reset so WERR flag not set virtual void putRV(RegisterValue rv) { value.init = rv.init; value.put(rv.data); } }; class LCD_MODULE: public TriggerObject { public: LCD_MODULE(Processor *pCpu, bool p16f917); void set_Vlcd(PinModule *, PinModule *, PinModule *); void set_LCDcom(PinModule *, PinModule *, PinModule *, PinModule *); void set_LCDsegn(unsigned int, PinModule *, PinModule *, PinModule *, PinModule *); void set_t1con(T1CON *t1c) {t1con = t1c;} void lcd_on_off(bool lcdOn); void set_bias(unsigned int lmux); void lcd_set_com(bool lcdOn, unsigned int lmux); void lcd_set_segPins(unsigned int regno, unsigned int old, unsigned int diff); void clear_bias(); void set_lcdcon_werr() { lcdcon->value.put(lcdcon->value.get() | LCDCON::WERR); } bool get_lcdps_wa() { return lcdps->value.get() & LCDPS::WA; } bool get_lcdcon_lcden() { return lcdcon->value.get() & LCDCON::LCDEN;} bool typeB() {return (lcdps->value.get() & LCDPS::WFT) && mux_now;} virtual void callback(); virtual void setIntSrc(InterruptSource *_IntSrc) { IntSrc = _IntSrc;} void start_clock(); void stop_clock(); void drive_lcd(); void save_hold_data(); void start_typeA(); void start_typeB(); virtual void sleep(); virtual void wake(); Processor *cpu; InterruptSource *IntSrc; bool Vlcd1_on, Vlcd2_on, Vlcd3_on; bool is_sleeping; PinModule *Vlcd1, *Vlcd2, *Vlcd3; PinModule *LCDsegn[24]; PinModule *LCDcom[4]; unsigned char LCDsegDirection[3]; unsigned char LCDcomDirection; unsigned char hold_data[12]; unsigned char bias_now; unsigned char mux_now; unsigned char phase; unsigned char num_phases; unsigned int clock_tick; guint64 future_cycle; guint64 map_com[4]; guint64 map_on; guint64 map_off; LCDCON *lcdcon; LCDPS *lcdps; LCDSEn *lcdSEn[3]; LCDDATAx *lcddatax[12]; T1CON *t1con; }; #endif // __LCD_H__ gpsim-0.30.0/src/init.cc0000664000076400007640000000262313041763613011714 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "../config.h" #include "trace.h" #include "gpsim_interface.h" #include "sim_context.h" // in attribute.cc: extern void init_attributes(); extern void destroy_attributes(); //============================================================== // simulation_cleanup() // // Called just before gpsim exits. // void simulation_cleanup(void) { // Flush the log file (if there is one). GetTraceLog().close_logfile(); destroy_attributes(); } //======================================================================== // initialize_gpsim_core() // int initialize_gpsim_core() { init_attributes(); CSimulationContext::GetContext()->Initialize(); return 0; } gpsim-0.30.0/src/pic-instructions.cc0000664000076400007640000011761413047736577014314 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "pic-processor.h" #include "14bit-instructions.h" #include "registers.h" #include "symbol.h" #include "xref.h" //------------------------------------------------------------------------ AddressSymbol::AddressSymbol(Processor *pCpu, const char *_name, unsigned int _val) : Integer(_val) { new_name(_name); cpu = pCpu; } string AddressSymbol::toString() { char buf[256]; int i = (int)getVal(); snprintf(buf,sizeof(buf), " at address %d = 0x%X",i,i); return string(buf); } Value* AddressSymbol::evaluate() { return copy(); } int AddressSymbol::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *pExpr) { if (bt == gpsimObject::eBreakExecute && cpu) return get_bp().set_execution_break((Processor*)cpu,getVal(),pExpr); return -1; } LineNumberSymbol::LineNumberSymbol(Processor *pCpu, const char *_name, unsigned int _val) : AddressSymbol(pCpu,_name,_val) { if(!_name) { char buf[64]; snprintf(buf,sizeof(buf), "line_%04x",_val); new_name(buf); } } instruction::instruction(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr) : Value("","",pProcessor), m_bIsModified(false), cycle_count(0), opcode(uOpCode), m_uAddrOfInstr(uAddrOfInstr), pLineSymbol(0), file_id(-1), hll_file_id(-1), src_line(-1), lst_line(-1), hll_src_line(-1) { if (cpu) { pLineSymbol = new LineNumberSymbol((Processor*)cpu,0, m_uAddrOfInstr); if (!cpu->addSymbol(pLineSymbol)) { delete pLineSymbol; pLineSymbol = 0; } } } instruction::~instruction() { // cout << __FUNCTION__<first_xref())) { pt->clear(pt_xref); delete (int *)pt_xref->data; delete pt_xref; } } if (cpu) cpu->deleteSymbol(pLineSymbol); } void instruction::decode(Processor *new_cpu, unsigned int new_opcode) { cpu = new_cpu; opcode = new_opcode; } int instruction::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *pExpr) { if (bt == gpsimObject::eBreakExecute) return get_bp().set_execution_break(get_cpu(),m_uAddrOfInstr,pExpr); return -1; } void instruction::addLabel(string &rLabel) { if (cpu) { addName(rLabel); cpu->addSymbol(this, &rLabel); } } //------------------------------------------------------------------------ invalid_instruction::invalid_instruction(Processor *new_cpu,unsigned int new_opcode, unsigned int address) : instruction(new_cpu,new_opcode,address) { new_name("INVALID"); } void invalid_instruction::execute() { //cout << "*** INVALID INSTRUCTION ***\n"; #ifdef __DEBUG_VERBOSE__ debug(); #endif /* Don't know what to do, so just plow through like nothing happened */ if(cpu_pic) cpu_pic->pc->increment(); }; void invalid_instruction::addLabel(string &rLabel) { cout << "*** WARNING: adding label '"<files.ReadLine(file_id,src_line,buf,nBytes); return buf; } char *instruction::ReadHLLLine(char *buf, int nBytes) { if (buf && nBytes && cpu) return ((Processor *)cpu)->files.ReadLine(hll_file_id,hll_src_line,buf,nBytes); return buf; } char *instruction::ReadLstLine(char *buf, int nBytes) { if (buf && nBytes && cpu) return ((Processor *)cpu)->files.ReadLine(((Processor *)cpu)->files.list_id(),lst_line,buf,nBytes); return buf; } //------------------------------------------------------------------------ AliasedInstruction::AliasedInstruction(instruction *_replaced) : instruction(0,0,0), m_replaced(_replaced) { } AliasedInstruction::AliasedInstruction() : instruction(0,0,0), m_replaced(0) { } AliasedInstruction::AliasedInstruction(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr) : instruction(pProcessor, uOpCode, uAddrOfInstr), m_replaced(0) { } AliasedInstruction::~AliasedInstruction() { } void AliasedInstruction::setReplaced(instruction *_replaced) { m_replaced = _replaced; } instruction * AliasedInstruction::getReplaced() { return m_replaced ? m_replaced : &dynamic_cast(cpu)->bad_instruction; } void AliasedInstruction::execute() { getReplaced()->execute(); } void AliasedInstruction::debug() { getReplaced()->debug(); } int AliasedInstruction::instruction_size() { return getReplaced()->instruction_size(); } unsigned int AliasedInstruction::get_opcode() { return getReplaced()->get_opcode(); } unsigned int AliasedInstruction::get_value() { return getReplaced()->get_value(); } void AliasedInstruction::put_value(unsigned int new_value) { getReplaced()->put_value(new_value); } int AliasedInstruction::get_src_line() { return getReplaced()->get_src_line(); } int AliasedInstruction::get_hll_src_line() { return getReplaced()->get_hll_src_line(); } void AliasedInstruction::update_line_number(int file, int sline, int lline, int hllfile, int hllsline) { if (m_replaced) m_replaced->update_line_number(file, sline, lline, hllfile, hllsline); } int AliasedInstruction::get_lst_line() { return getReplaced()->get_lst_line(); } int AliasedInstruction::get_file_id() { return getReplaced()->get_file_id(); } int AliasedInstruction::get_hll_file_id() { return getReplaced()->get_hll_file_id(); } enum instruction::INSTRUCTION_TYPES AliasedInstruction::isa() { return getReplaced()->isa(); } void AliasedInstruction::initialize(bool init_state) { getReplaced()->initialize(init_state); } char *AliasedInstruction::name(char *cPtr,int len) { return getReplaced()->name(cPtr,len); } void AliasedInstruction::update() { getReplaced()->update(); } void AliasedInstruction::add_xref(void *an_xref) { getReplaced()->add_xref(an_xref); } void AliasedInstruction::remove_xref(void *an_xref) { getReplaced()->remove_xref(an_xref); } bool AliasedInstruction::isBase() { return getReplaced()->isBase(); } //------------------------------------------------------------------------ Literal_op::Literal_op(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr) : instruction(pProcessor, uOpCode, uAddrOfInstr), L(uOpCode&0xff) { } char *Literal_op::name(char *return_str,int len) { snprintf(return_str,len,"%s\t0x%02x", gpsimObject::name().c_str(),L); return(return_str); } void Literal_op::decode(Processor *new_cpu, unsigned int new_opcode) { opcode = new_opcode; cpu = new_cpu; L = opcode & 0xff; } Bit_op::Bit_op(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr) : instruction(pProcessor, uOpCode, uAddrOfInstr), mask(0),register_address(0), access(false), reg(0) { } void Bit_op::decode(Processor *new_cpu, unsigned int new_opcode) { opcode = new_opcode; cpu = new_cpu; switch(cpu_pic->base_isa()) { case _PIC17_PROCESSOR_: mask = 1 << ((opcode >> 8) & 7); register_address = opcode & REG_MASK_16BIT; access = 0; break; case _PIC18_PROCESSOR_: mask = 1 << ((opcode >> 9) & 7); register_address = opcode & REG_MASK_16BIT; access = (opcode & ACCESS_MASK_16BIT) ? true : false; if((!access) && (register_address >= cpu_pic->access_gprs())) // some 18f devices split at 0x60 register_address |= 0xf00; break; case _14BIT_PROCESSOR_: case _14BIT_E_PROCESSOR_: mask = 1 << ((opcode >> 7) & 7); register_address = opcode & REG_MASK_14BIT; access = 1; break; case _12BIT_PROCESSOR_: mask = 1 << ((opcode >> 5) & 7); register_address = opcode & REG_MASK_12BIT; access = 1; break; default: cout << "ERROR: (Bit_op) the processor has a bad base type\n"; } } char * Bit_op::name(char *return_str,int len) { // %%% FIX ME %%% Actually just a slight dilemma - the source register will always be in // the lower bank of memory... reg = get_cpu()->registers[register_address]; unsigned int bit; switch(cpu_pic->base_isa()) { case _PIC17_PROCESSOR_: cout << "Bit_op::name %%% FIX ME %%% treating 17x as 18x\n"; case _PIC18_PROCESSOR_: bit = ((opcode >> 9) & 7); snprintf(return_str,len,"%s\t%s,%u,%c", gpsimObject::name().c_str(), reg->name().c_str(), bit, access ? '1' : '0'); return(return_str); break; case _14BIT_E_PROCESSOR_: case _14BIT_PROCESSOR_: if(access) reg = get_cpu()->register_bank[register_address]; bit = ((opcode >> 7) & 7); break; case _12BIT_PROCESSOR_: bit = ((opcode >> 5) & 7); break; default: bit = 0; } snprintf(return_str,len,"%s\t%s,%u", gpsimObject::name().c_str(), reg->name().c_str(), bit); return(return_str); } //---------------------------------------------------------------- Register_op::Register_op(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr) : instruction(pProcessor, uOpCode, uAddrOfInstr), register_address(0), destination(false), access(false) { } //---------------------------------------------------------------- // // Register_op::name // char * Register_op::name(char *return_str,int len) { // %%% FIX ME %%% Actually just a slight dilemma - the source register will always be in // the lower bank of memory (for the 12 and 14 bit cores). source = get_cpu()->registers[register_address]; if ( cpu_pic->base_isa() == _14BIT_E_PROCESSOR_ || cpu_pic->base_isa() == _14BIT_PROCESSOR_ ) { if (access) source = cpu_pic->register_bank[register_address]; snprintf(return_str,len,"%s\t%s,%c", gpsimObject::name().c_str(), source->name().c_str(), destination ? 'f' : 'w'); } else if ( cpu_pic->base_isa() != _PIC18_PROCESSOR_ ) { snprintf(return_str,len,"%s\t%s,%c", gpsimObject::name().c_str(), source->name().c_str(), destination ? 'f' : 'w'); } else snprintf(return_str,len,"%s\t%s,%c,%c", gpsimObject::name().c_str(), source->name().c_str(), destination ? 'f' : 'w', access ? '1' : '0'); return(return_str); } //---------------------------------------------------------------- // // Register_op::decode // // Base class to decode all 'register' type instructions. The main thing // it does is obtains the register's address from the opcode. Note that this // is processor dependent: in the 12-bit core processors, the register address // is the lower 5 bits while in the 14-bit core it's the lower 7. void Register_op::decode(Processor *new_cpu, unsigned int new_opcode) { opcode = new_opcode; cpu = new_cpu; switch(cpu_pic->base_isa()) { case _PIC17_PROCESSOR_: cout << "Register_op::decode %%% FIXME %%% - PIC17 core is not the same as PIC18\n"; case _PIC18_PROCESSOR_: destination = (opcode & DESTINATION_MASK_16BIT) ? true : false; access = (opcode & ACCESS_MASK_16BIT) ? true : false; register_address = opcode & REG_MASK_16BIT; if((!access) && (register_address >= cpu_pic->access_gprs())) // some 18f devices split at 0x60 register_address |= 0xf00; break; case _14BIT_PROCESSOR_: case _14BIT_E_PROCESSOR_: register_address = opcode & REG_MASK_14BIT; destination = (opcode & DESTINATION_MASK_14BIT) ? true : false; access = 1; break; case _12BIT_PROCESSOR_: register_address = opcode & REG_MASK_12BIT; destination = (opcode & DESTINATION_MASK_12BIT) ? true : false; access = 1; break; default: cout << "ERROR: (Register_op) the processor has a bad base type\n"; } } Register * Register_op::source = 0; //-------------------------------------------------- ADDWF::ADDWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("addwf"); } void ADDWF::execute() { unsigned int new_value,src_value,w_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (src_value = source->get()) + (w_value = cpu_pic->Wget()); // Store the result if(destination) source->put(new_value & 0xff); // Result goes to source else cpu_pic->Wput(new_value & 0xff); cpu_pic->status->put_Z_C_DC(new_value, src_value, w_value); cpu_pic->pc->increment(); } //-------------------------------------------------- ADDWFC::ADDWFC (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("addwfc"); } void ADDWFC::execute() { unsigned int new_value,src_value,w_value; source = ((!access) ? cpu_pic->registers[register_address] : cpu_pic->register_bank[register_address] ); new_value = (src_value = source->get()) + (w_value = cpu_pic->Wget()) + ((cpu_pic->status->value.get() & STATUS_C) ? 1 : 0); // Store the result if(destination) source->put(new_value & 0xff); // Result goes to source else cpu_pic->Wput(new_value & 0xff); cpu_pic->status->put_Z_C_DC(new_value, src_value, w_value); cpu_pic->pc->increment(); } //-------------------------------------------------- ANDLW::ANDLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("andlw"); } void ANDLW::execute() { unsigned int new_value; new_value = cpu_pic->Wget() & L; cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- ANDWF::ANDWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("andwf"); } void ANDWF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = source->get() & cpu_pic->Wget(); if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- ASRF::ASRF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("asrf"); } void ASRF::execute() { unsigned int new_value,src_value, carry, msb; source = ((!access) ? cpu_pic->registers[register_address] : cpu_pic->register_bank[register_address] ); carry = (src_value = source->get()) & 1; msb = src_value & 0x80; new_value = ((src_value & 0xff) >> 1) | msb; // Store the result if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(new_value==0); cpu_pic->status->put_C(carry); cpu_pic->pc->increment(); } //-------------------------------------------------- BCF::BCF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Bit_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); mask ^= 0xff; // decode initializes the mask to 1<registers[register_address]; else reg = cpu_pic->register_bank[register_address]; reg->put(reg->get_value() & mask); // Must not use reg->value.get() as it breaks indirects cpu_pic->pc->increment(); } //-------------------------------------------------- BRA::BRA (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { destination_index = (new_opcode & 0x1ff)+1; absolute_destination_index = (address + destination_index) & 0xfffff; if(new_opcode & 0x100) { absolute_destination_index -= 0x200; destination_index = 0x200 - destination_index; } new_name("bra"); } void BRA::execute() { cpu_pic->pc->jump(absolute_destination_index); } char * BRA::name(char *return_str,int len) { sprintf(return_str,"%s\t$%c0x%x\t;(0x%05x)", gpsimObject::name().c_str(), (opcode & 0x100) ? '-' : '+', (destination_index & 0x1ff)<<1, absolute_destination_index<<1); return(return_str); } //-------------------------------------------------- BRW::BRW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { current_address = address; new_name("brw"); } void BRW::execute() { destination_index = cpu_pic->Wget(); cpu_pic->pc->jump(current_address + destination_index +1); } char * BRW::name(char *return_str,int len) { sprintf(return_str,"%s\t$%c0x%x\t;(0x%05x)", gpsimObject::name().c_str(), (opcode & 0x100) ? '-' : '+', (destination_index & 0x1ff), current_address + destination_index +1); return(return_str); } //-------------------------------------------------- BSF::BSF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Bit_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bsf"); } void BSF::execute() { if(!access) reg = cpu_pic->registers[register_address]; else reg = cpu_pic->register_bank[register_address]; reg->put(reg->get_value() | mask); // Must not use reg->value.get() as it breaks indirects cpu_pic->pc->increment(); } //-------------------------------------------------- BTFSC::BTFSC (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Bit_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("btfsc"); } void BTFSC::execute() { if(!access) reg = cpu_pic->registers[register_address]; else reg = cpu_pic->register_bank[register_address]; unsigned int result = mask & reg->get(); if(!result) cpu_pic->pc->skip(); // Skip next instruction else cpu_pic->pc->increment(); } //-------------------------------------------------- BTFSS::BTFSS (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Bit_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("btfss"); } void BTFSS::execute() { if(!access) reg = cpu_pic->registers[register_address]; else reg = cpu_pic->register_bank[register_address]; unsigned int result = mask & reg->get(); if(result) cpu_pic->pc->skip(); // Skip next instruction else cpu_pic->pc->increment(); } //-------------------------------------------------- CALL::CALL (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { switch(cpu_pic->base_isa()) { case _14BIT_PROCESSOR_: case _14BIT_E_PROCESSOR_: destination = opcode&0x7ff; break; case _12BIT_PROCESSOR_: destination = opcode&0xff; break; default: cout << "ERROR: (Bit_op) the processor has a bad base type\n"; } new_name("call"); } void CALL::execute() { // do not jump if the push fails if (cpu_pic->stack->push(cpu_pic->pc->get_next())) cpu_pic->pc->jump(cpu_pic->get_pclath_branching_jump() | destination); } char * CALL::name(char *return_str,int len) { snprintf(return_str,len,"%s\t0x%04x", gpsimObject::name().c_str(), destination); return(return_str); } //-------------------------------------------------- CALLW::CALLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address) :instruction (new_cpu, new_opcode, address) { new_name("callw"); } char *CALLW::name(char *return_str,int len) { snprintf(return_str,len,"%s", gpsimObject::name().c_str()); return(return_str); } void CALLW::execute() { if (cpu_pic->stack->push(cpu_pic->pc->get_next())) { cpu_pic->pcl->put(cpu_pic->Wget()); cpu_pic->pc->increment(); } } //-------------------------------------------------- CLRF::CLRF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("clrf"); } void CLRF::execute() { if(!access) cpu_pic->registers[register_address]->put(0); else cpu_pic->register_bank[register_address]->put(0); cpu_pic->status->put_Z(1); cpu_pic->pc->increment(); } char * CLRF::name(char *return_str,int len) { source = get_cpu()->registers[register_address]; if (access) source = cpu_pic->register_bank[register_address]; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), source->name().c_str()); return(return_str); } //-------------------------------------------------- CLRW::CLRW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("clrw"); } void CLRW::execute() { cpu_pic->Wput(0); cpu_pic->status->put_Z(1); cpu_pic->pc->increment(); } //-------------------------------------------------- CLRWDT::CLRWDT (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("clrwdt"); } void CLRWDT::execute() { cpu_pic->wdt.clear(); cpu_pic->status->put_TO(1); cpu_pic->status->put_PD(1); cpu_pic->pc->increment(); } //-------------------------------------------------- COMF::COMF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("comf"); } void COMF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = source->get() ^ 0xff; if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- DECF::DECF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("decf"); } void DECF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (source->get() - 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- DECFSZ::DECFSZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("decfsz"); } void DECFSZ::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (source->get() - 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); if(0==new_value) cpu_pic->pc->skip(); // Skip next instruction else cpu_pic->pc->increment(); } //-------------------------------------------------- GOTO::GOTO (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { switch(cpu_pic->base_isa()) { case _14BIT_PROCESSOR_: case _14BIT_E_PROCESSOR_: destination = opcode&0x7ff; break; case _12BIT_PROCESSOR_: destination = opcode&0x1ff; break; default: cout << "ERROR: (Bit_op) the processor has a bad base type\n"; } new_name("goto"); } void GOTO::execute() { cpu_pic->pc->jump(cpu_pic->get_pclath_branching_jump() | destination); } char * GOTO::name(char *return_str,int len) { snprintf(return_str,len,"%s\t0x%04x", gpsimObject::name().c_str(),destination); return(return_str); } //-------------------------------------------------- INCF::INCF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("incf"); } void INCF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (source->get() + 1)&0xff; // Store the result if(destination) source->put(new_value); else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- INCFSZ::INCFSZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("incfsz"); } void INCFSZ::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (source->get() + 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); if(0==new_value) cpu_pic->pc->skip(); // Skip next instruction else cpu_pic->pc->increment(); } //-------------------------------------------------- IORLW::IORLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("iorlw"); } void IORLW::execute() { unsigned int new_value; new_value = cpu_pic->Wget() | L; cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- IORWF::IORWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("iorwf"); } void IORWF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = source->get() | cpu_pic->Wget(); if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- LSLF::LSLF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("lslf"); } void LSLF::execute() { unsigned int new_value,src_value, carry; source = ((!access) ? cpu_pic->registers[register_address] : cpu_pic->register_bank[register_address] ); carry = (src_value = source->get()) & 0x80; new_value = (src_value << 1) & 0xff; // Store the result if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(new_value==0); cpu_pic->status->put_C(carry); cpu_pic->pc->increment(); } //-------------------------------------------------- LSRF::LSRF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("lsrf"); } void LSRF::execute() { unsigned int new_value,src_value, carry; source = ((!access) ? cpu_pic->registers[register_address] : cpu_pic->register_bank[register_address] ); carry = (src_value = source->get()) & 1; new_value = (src_value & 0xff) >> 1; // Store the result if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(new_value==0); cpu_pic->status->put_C(carry); cpu_pic->pc->increment(); } //-------------------------------------------------- MOVLP::MOVLP (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("movlp"); } void MOVLP::execute() { if (cpu_pic->pclath->address) cpu_pic->registers[cpu_pic->pclath->address]->put(L); else cpu_pic->pclath->put(L); cpu_pic->pc->increment(); } char * MOVLP::name(char *return_str, int len) { snprintf(return_str, len, "%s\t%u", gpsimObject::name().c_str(), L & 0x7f); return(return_str); } //-------------------------------------------------- MOVLW::MOVLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("movlw"); } void MOVLW::execute() { cpu_pic->Wput(L); cpu_pic->pc->increment(); } //-------------------------------------------------- MOVF::MOVF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("movf"); } void MOVF::execute() { unsigned int source_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; source_value = source->get(); // Store the result if(destination) source->put(source_value); else cpu_pic->Wput(source_value); cpu_pic->status->put_Z(0==source_value); cpu_pic->pc->increment(); } void MOVF::debug() { cout << "MOVF: "; } //-------------------------------------------------- MOVWF::MOVWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("movwf"); } void MOVWF::execute() { if(!access) cpu_pic->registers[register_address]->put(cpu_pic->Wget()); else cpu_pic->register_bank[register_address]->put(cpu_pic->Wget()); cpu_pic->pc->increment(); } char * MOVWF::name(char *return_str, int len) { source = get_cpu()->registers[register_address]; if (access) source = cpu_pic->register_bank[register_address]; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), source->name().c_str()); return(return_str); } //-------------------------------------------------- NOP::NOP (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu,new_opcode,address) { decode(new_cpu,new_opcode); new_name("nop"); // For the 18cxxx family, this 'nop' may in fact be the // 2nd word in a 2-word opcode. So just to be safe, let's // initialize the cross references to the source file. // (Subsequent initialization code will overwrite this, // but there is a chance that this info will be accessed // before that occurs). /* file_id = 0; src_line = 0; lst_line = 0; */ } void NOP::execute() { cpu_pic->pc->increment(); } //-------------------------------------------------- OPTION::OPTION (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu,new_opcode,address) { decode(new_cpu, new_opcode); new_name("option"); } void OPTION::execute() { cpu_pic->put_option_reg(cpu_pic->Wget()); cpu_pic->pc->increment(); } //-------------------------------------------------- RESET::RESET (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("reset"); } void RESET::execute() { cpu_pic->reset(SOFT_RESET); } //-------------------------------------------------- RETLW::RETLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("retlw"); } void RETLW::execute() { cpu_pic->Wput(L); cpu_pic->pc->new_address(cpu_pic->stack->pop()); } //-------------------------------------------------- RLF::RLF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("rlf"); } void RLF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (source->get() << 1) | cpu_pic->status->get_C(); if(destination) source->put(new_value&0xff); // Result goes to source else cpu_pic->Wput(new_value&0xff); cpu_pic->status->put_C(new_value>0xff); cpu_pic->pc->increment(); } //-------------------------------------------------- RRF::RRF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("rrf"); } void RRF::execute() { unsigned int new_value,old_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; old_value = source->get(); new_value = (old_value >> 1) | (cpu_pic->status->get_C() ? 0x80 : 0); if(destination) source->put(new_value&0xff); // Result goes to source else cpu_pic->Wput(new_value&0xff); cpu_pic->status->put_C(old_value&0x01); cpu_pic->pc->increment(); } //-------------------------------------------------- SLEEP::SLEEP (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu,new_opcode,address) { decode(new_cpu, new_opcode); new_name("sleep"); } void SLEEP::execute() { cpu_pic->enter_sleep(); } //-------------------------------------------------- SUBWF::SUBWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("subwf"); } void SUBWF::execute() { unsigned int new_value,src_value,w_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = (src_value = source->get()) - (w_value = cpu_pic->Wget()); // Store the result if(destination) source->put(new_value & 0xff); // Result goes to source else cpu_pic->Wput(new_value & 0xff); cpu_pic->status->put_Z_C_DC_for_sub(new_value, src_value, w_value); cpu_pic->pc->increment(); } //-------------------------------------------------- SUBWFB::SUBWFB (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("subwfb"); } void SUBWFB::execute() { unsigned int new_value,src_value,w_value; source = ((!access) ? cpu_pic->registers[register_address] : cpu_pic->register_bank[register_address] ); new_value = (src_value = source->get()) - (w_value = cpu_pic->Wget()) - (1 - cpu_pic->status->get_C()); if(destination) source->put(new_value & 0xff); else cpu_pic->Wput(new_value & 0xff); cpu_pic->status->put_Z_C_DC_for_sub(new_value, src_value, w_value); cpu_pic->pc->increment(); } //-------------------------------------------------- SWAPF::SWAPF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("swapf"); } void SWAPF::execute() { unsigned int src_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; src_value = source->get(); if(destination) source->put( ((src_value >> 4) & 0x0f) | ( (src_value << 4) & 0xf0) ); else cpu_pic->Wput( ((src_value >> 4) & 0x0f) | ( (src_value << 4) & 0xf0) ); cpu_pic->pc->increment(); } //-------------------------------------------------- TRIS::TRIS (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); // The TRIS instruction only uses the lower three bits to determine // the destination register register_address &= 7; // Furthermore, those three bits can only be 5,6, or 7 if( (register_address > 7) || (register_address < 5)) { cout << "Warning: TRIS address '" << register_address << "' is out of range\n"; // set the address to a 'bad value' that's // easy to detect at run time: register_address = 0; } else { if(cpu_pic->base_isa() == _14BIT_PROCESSOR_ || cpu_pic->base_isa() == _14BIT_PROCESSOR_) register_address |= 0x80; // The destination register is the TRIS } new_name("tris"); } void TRIS::execute() { if(register_address) { // Execute the instruction only if the register is valid. if(cpu_pic->base_isa() == _14BIT_PROCESSOR_ || cpu_pic->base_isa() == _14BIT_PROCESSOR_) cpu_pic->registers[register_address]->put(cpu_pic->Wget()); else cpu_pic->tris_instruction(register_address); } cpu_pic->pc->increment(); } char * TRIS::name(char *return_str,int len) { source = get_cpu()->registers[register_address]; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), source->name().c_str()); return(return_str); } //-------------------------------------------------- XORLW::XORLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("xorlw"); } void XORLW::execute() { unsigned int new_value; new_value = cpu_pic->Wget() ^ L; cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } //-------------------------------------------------- XORWF::XORWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("xorwf"); } void XORWF::execute() { unsigned int new_value; if(!access) source = cpu_pic->registers[register_address]; else source = cpu_pic->register_bank[register_address]; new_value = source->get() ^ cpu_pic->Wget(); if(destination) source->put(new_value); // Result goes to source else cpu_pic->Wput(new_value); cpu_pic->status->put_Z(0==new_value); cpu_pic->pc->increment(); } gpsim-0.30.0/src/attributes.h0000664000076400007640000000335413041763624013005 00000000000000/* Copyright (C) 1998-2005 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__ATTRIBUTES_H__) #define __ATTRIBUTES_H__ #include "value.h" class Processor; /// gpsim attributes /// /// WarnModeAttribute class WarnModeAttribute : public Boolean { protected: Processor *cpu; public: WarnModeAttribute(Processor *_cpu); virtual void set(Value *v); virtual void get(bool &b); }; /// SafeModeAttribute class SafeModeAttribute : public Boolean { protected: Processor *cpu; public: SafeModeAttribute(Processor *_cpu); ~SafeModeAttribute(); virtual void set(Value *v); virtual void get(bool &b); }; /// UnknownModeAttribute class UnknownModeAttribute : public Boolean { protected: Processor *cpu; public: UnknownModeAttribute(Processor *_cpu); virtual void set(Value *v); virtual void get(bool &b); }; /// BreakOnResetAttribute class BreakOnResetAttribute : public Boolean { protected: Processor *cpu; public: BreakOnResetAttribute(Processor *_cpu); virtual void set(Value *v); virtual void get(bool &b); }; #endif //if !defined(__ATTRIBUTES_H__) gpsim-0.30.0/src/14bit-registers.cc0000664000076400007640000020012113115237646013676 00000000000000/* Copyright (C) 1998-2000 Scott Dattalo Copyright (C) 2013-2017 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "14bit-processors.h" #include "14bit-registers.h" #include "psp.h" // needed for operator[] on WPU::wpu_gpio (not sure why) #include "14bit-tmrs.h" #include #include "stimuli.h" #include "xref.h" #define PCLATH_MASK 0x1f //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("0x%06" PRINTF_GINT64_MODIFIER "X %s() ", cycles.get(), __FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif // Debug OSCCON //#define CDEBUG #if defined(CDEBUG) #define CDprintf(arg) {printf("0x%06" PRINTF_GINT64_MODIFIER "X %s() ", cycles.get(), __FUNCTION__); printf arg; } #else #define CDprintf(arg) {} #endif pic_processor *temp_cpu; // FIXME file_register::put_value has a useful feature... // #if 0 //----------------------------------------------------------- // void file_register::put_value(unsigned int new_value) // // put_value is used by the gui to change the contents of // file registers. We could've let the gui use the normal // 'put' member function to change the contents, however // there are instances where 'put' has a cascading affect. // For example, changing the value of an i/o port's tris // could cause i/o pins to change states. In these cases, // we'd like the gui to be notified of all of the cascaded // changes. So rather than burden the real-time simulation // with notifying the gui, I decided to create the 'put_value' // function instead. // Since this is a virtual function, derived classes have // the option to override the default behavior. // // inputs: // unsigned int new_value - The new value that's to be // written to this register // returns: // nothing // //----------------------------------------------------------- void file_register::put_value(unsigned int new_value) { // go ahead and use the regular put to write the data. // note that this is a 'virtual' function. Consequently, // all objects derived from a file_register should // automagically be correctly updated. put(new_value); // Even though we just wrote a value to this register, // it's possible that the register did not get fully // updated (e.g. porta on many pics has only 5 valid // pins, so the upper three bits of a write are meaningless) // So we should explicitly tell the gui (if it's // present) to update its display. if(xref) { xref->update(); if(cpu && address == cpu_pic->fsr->value) { if(cpu_pic->indf->xref) cpu_pic->indf->xref->update(); } } } #endif //-------------------------------------------------- // member functions for the BORCON class // currently does not do anything //-------------------------------------------------- // BORCON::BORCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { } void BORCON::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0x80); } void BORCON::put_value(unsigned int new_value) { put(new_value&0x80); } //-------------------------------------------------- // member functions for the BSR class //-------------------------------------------------- // BSR::BSR(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), register_page_bits(0) { } void BSR::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0x01f); //value.put(new_value & 0x01f); if(cpu_pic->base_isa() == _14BIT_E_PROCESSOR_) cpu_pic->register_bank = &cpu_pic->registers[ value.get() << 7 ]; else cpu_pic->register_bank = &cpu_pic->registers[ value.get() << 8 ]; } void BSR::put_value(unsigned int new_value) { put(new_value); update(); cpu_pic->indf->update(); } void IOCxF::put(unsigned int new_value) { unsigned int masked_value = new_value & mValidBits; Dprintf((" %s value %x masked %x\n", name().c_str(), new_value, masked_value)); get_trace().raw(write_trace.get() | value.get()); value.put(masked_value); if (intcon) { ((INTCON_14_PIR *)intcon)->set_rbif(masked_value != 0); ((INTCON_14_PIR *)intcon)->aocxf_val(this, masked_value); } } // Adjust internal RC oscillator frequency as per 12f675/629 // Spec sheet does not give range so assume +/- 12.5% as per 16f88 // The fact that base_freq is not 0. indicates the RC oscillator is being used // and thus an adjustment should be made. // // This will work for any number of adjustment bits in byte but must be left justified // and 1000000 centre frequency and 11111111 highest frequency void OSCCAL::put(unsigned int new_value) { int adj = new_value & mValidBits; float tune; trace.raw(write_trace.get() | value.get()); value.put(adj); if (base_freq > 0.) { adj = adj - 0x80; // A hook to honour configured frequency - if we're going to change it now if(cpu_pic->get_frequency() > base_freq*0.875 && base_freq*1.125 > cpu_pic->get_frequency()) { base_freq=cpu_pic->get_frequency(); if (verbose) cout << "Adjusting base frequency for INTOSC calibration: " << base_freq << "\n"; } tune = (1. + 0.125 * adj / 0x80) * base_freq; cpu_pic->set_frequency(tune); if (verbose) cout << "Calibrating INTOSC by " << adj << " to " << tune << "\n"; } } void OSCCAL::set_freq(float new_base_freq) { base_freq = new_base_freq; put(value.get()); } void OSCTUNE::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); osccon->set_rc_frequency(); } // Clock is stable void OSCCON::callback() { unsigned int new_value = value.get(); if (future_cycle <= get_cycles().get()) future_cycle = 0; CDprintf(("OSCCON clock_state=%d\n", clock_state)); switch(clock_state) { case OST: CDprintf(("OSCCON switch clock\n")); if (has_iofs_bit) new_value &= ~IOFS; else new_value &= ~(HTS|LTS); new_value |= OSTS; value.put(new_value); clock_state = EXCSTABLE; cpu_pic->set_RCfreq_active(false); return; case LFINTOSC: if (has_iofs_bit) new_value |= IOFS; else { new_value &= ~HTS; new_value |= LTS; } value.put(new_value); CDprintf(("OSCCON HF osccon=0x%x\n", value.get())); return; case HFINTOSC: if (!has_iofs_bit) new_value &= ~LTS; new_value |= HTS; value.put(new_value); CDprintf(("OSCCON HF osccon=0x%x\n", value.get())); return; case INTOSC: new_value |= IOFS; value.put(new_value); return; case EXCSTABLE: if (!has_iofs_bit) new_value &= ~LTS; new_value &= ~HTS; value.put(new_value); return; default: fprintf(stderr, "OSCCON::callback unexpexted clock state %d\n", clock_state); return; } } // Is internal RC clock selected? bool OSCCON::internal_RC() { unsigned int scs = (value.get() & (SCS0|SCS1)) & write_mask; bool ret = false; if (scs == 0 && config_irc) ret = true; else if ((SCS1 & write_mask) && scs == 2) // using SCS1 and SCS0 ret = true; else if (scs == 1) ret = true; CDprintf(("OSCCON internal_RC ret %d osccon=0x%x\n", ret, value.get())); return ret; } void OSCCON::reset(RESET_TYPE r) { switch(r) { case POR_RESET: value.put(por_value.data); por_wake(); break; default: CDprintf(("OSCCON default %x\n", r)); break; } } void OSCCON::sleep() { is_sleeping = true; } void OSCCON::wake() { if (!is_sleeping) return; is_sleeping = false; CDprintf(("OSCCON config_ieso %d int RC %d two_speed_clock=%d cpu=%s\n", config_ieso, internal_RC(), (config_xosc && config_ieso), cpu_pic->name().c_str())); por_wake(); } void OSCCON::por_wake() { bool two_speed_clock = config_xosc && config_ieso; unsigned int new_value = value.get(); CDprintf(("OSCCON config_xosc=%d config_ieso=%d\n", config_xosc,config_ieso)); CDprintf(("OSCCON POR two_speed_clock=%d f=%4.1e osccon=0x%x por_value=0x%x\n", two_speed_clock, cpu_pic->get_frequency(), new_value, por_value.data)); if (future_cycle) { get_cycles().clear_break(future_cycle); future_cycle = 0; } // internal RC osc if (internal_RC()) { if (has_iofs_bit) { new_value &= ~IOFS; clock_state = INTOSC; } else if (new_value & (IRCF0 | IRCF1 | IRCF2 )) { new_value &= ~(HTS|LTS); clock_state = HFINTOSC; } else { new_value &= ~(HTS|LTS); clock_state = LFINTOSC; } new_value |= OSTS; value.put(new_value); CDprintf(("OSCCON internal RC clock_state %d osccon %x\n", clock_state, new_value)); //RRR set_rc_frequency(); if (future_cycle) get_cycles().clear_break(future_cycle); future_cycle = get_cycles().get() + irc_por_time(); get_cycles().set_break(future_cycle, this); return; } if (two_speed_clock) { if (has_iofs_bit) new_value &= ~(IOFS | OSTS); else new_value &= ~( HTS | LTS | OSTS); value.put(new_value); set_rc_frequency(true); CDprintf(("OSCCON 2 speed, set osccon 0x%x \n", value.get())); clock_state = OST; future_cycle = 1024 + get_cycles().get(); get_cycles().set_break(future_cycle, this); return; } } /* * * */ bool OSCCON::set_rc_frequency(bool override) { double base_frequency = 31.e3; unsigned int old_clock_state = clock_state; unsigned int new_IRCF = (value.get() & ( IRCF0 | IRCF1 | IRCF2 )) >> 4; if (!internal_RC() && !override) return false; switch (new_IRCF) { case 0: base_frequency = 31.e3; break; case 1: base_frequency = 125e3; break; case 2: base_frequency = 250e3; break; case 3: base_frequency = 500e3; break; case 4: base_frequency = 1e6; break; case 5: base_frequency = 2e6; break; case 6: base_frequency = 4e6; break; case 7: base_frequency = 8e6; break; } if (osctune) { int tune; unsigned int osctune_value = osctune->value.get(); tune = osctune_value & (OSCTUNE::TUN5-1); tune = (OSCTUNE::TUN5 & osctune_value) ? -tune : tune; base_frequency *= 1. + 0.125 * tune / 31.; } cpu_pic->set_RCfreq_active(true); cpu_pic->set_frequency_rc(base_frequency); clock_state = new_IRCF ? HFINTOSC : LFINTOSC; if (old_clock_state != clock_state) { if ((old_clock_state == LFINTOSC) && clock_state != LFINTOSC) { if (has_iofs_bit) value.put(value.get() & ~(IOFS)); else value.put(value.get() & ~(LTS|HTS)); if (future_cycle) get_cycles().clear_break(future_cycle); future_cycle = get_cycles().get() + irc_lh_time(); get_cycles().set_break(future_cycle, this); CDprintf(("OSCCON future_cycle %" PRINTF_GINT64_MODIFIER "d now %" PRINTF_GINT64_MODIFIER "d\n", future_cycle, get_cycles().get())); } else { /*RRR unsigned int current = value.get(); if (clock_state == HFINTOSC) { if (has_iofs_bit) current &= ~LTS; current |= HTS; value.put(current); } */ callback(); } } CDprintf(("OSCCON new_ircf %d %4.1f \n", new_IRCF, cpu_pic->get_frequency())); if ((bool)verbose) { cout << "set_rc_frequency() : osccon=" << hex << value.get(); if (osctune) cout << " osctune=" << osctune->value.get(); cout << " new frequency=" << base_frequency << endl; } return true; } void OSCCON::put(unsigned int new_value) { unsigned int org_value = value.get(); new_value = (new_value & write_mask) | (org_value & ~write_mask); value.put(new_value); unsigned int diff = (new_value ^ org_value); trace.raw(write_trace.get() | org_value); value.put(new_value); CDprintf(("OSCCON org_value=0x%02x new_value=0x%02x diff=0x%02x state %d\n", org_value, new_value, diff, clock_state)); if (diff == 0) return; if(internal_RC()) { #ifdef CDEBUG unsigned int old_clock_state = clock_state; #endif if ((diff & (IRCF0 | IRCF1 | IRCF2))) // freq change { set_rc_frequency(); CDprintf(("OSCCON change of IRCF old_clock %d new_clock %d\n", old_clock_state, clock_state)); } // switching to intrc else if (diff & (SCS0 | SCS1)) // still OK if SCS1 is non-writtabe LTS { set_rc_frequency(true); CDprintf(("OSCCON diff 0x%x old_clock_state %d clock_state %d\n", (diff & (SCS0 | SCS1)), old_clock_state, clock_state)); } } else // not Internal RC clock { clock_state = EXCSTABLE; cpu_pic->set_RCfreq_active(false); callback(); CDprintf(("OSCCON not RC osccon=0x%x\n", new_value)); } } // Time required for stable clock after transition between high and low // irc frequencies guint64 OSCCON::irc_lh_time() { guint64 delay = (get_cycles().instruction_cps() * 1e-6) + 1; return delay; } // Time required for stable irc clock after POR guint64 OSCCON::irc_por_time() { return (guint64) 2; } guint64 OSCCON_1::irc_lh_time() { guint64 delay = get_cycles().instruction_cps() * 4e-3; CDprintf(("OSCCON_1 LH irc time 4ms %" PRINTF_GINT64_MODIFIER "d cycles\n", delay)); return delay; } // Time required for stable irc clock after POR (4 ms) guint64 OSCCON_1::irc_por_time() { guint64 delay = get_cycles().instruction_cps() * 4e-3; CDprintf(("OSCCON_1 POR irc time 4ms %" PRINTF_GINT64_MODIFIER "d cycles\n", delay)); return delay; } // Clock is stable void OSCCON_2::callback() { unsigned int add_bits = 0; unsigned int val; future_cycle = 0; if (!oscstat) return; val = oscstat->value.get(); CDprintf(("OSCCON_2 oscstat = 0x%x\n", val)); if (clock_state & PLL) add_bits = OSCSTAT::PLLR; switch(clock_state & ~PLL) { case OST: add_bits = OSCSTAT::OSTS; cpu_pic->set_RCfreq_active(false); break; case LFINTOSC: add_bits = OSCSTAT::LFIOFR; val &= ~(OSCSTAT::HFIOFL | OSCSTAT::HFIOFR | OSCSTAT::HFIOFS | OSCSTAT::MFIOFR); break; case MFINTOSC: add_bits = OSCSTAT::MFIOFR; val &= ~(OSCSTAT::HFIOFL | OSCSTAT::HFIOFR | OSCSTAT::HFIOFS | OSCSTAT::LFIOFR); break; case HFINTOSC: add_bits = OSCSTAT::HFIOFL | OSCSTAT::HFIOFR | OSCSTAT::HFIOFS; val &= ~(OSCSTAT::MFIOFR | OSCSTAT::LFIOFR); break; case T1OSC: break; } val |= add_bits; oscstat->value.put(val); } bool OSCCON_2::set_rc_frequency(bool override) { double base_frequency = 31.25e3; unsigned int sys_clock = value.get() & (SCS0 | SCS1); bool osccon_pplx4 = value.get() & SPLLEN; bool config_pplx4 = cpu_pic->get_pplx4_osc(); CDprintf(("OSCCON_2 new_IRCF 0x%x\n", (value.get() & ( IRCF0 | IRCF1 | IRCF2 |IRCF3)) >> 3)); if ((sys_clock == 0) && !config_irc) // Not internal oscillator { if (!config_xosc ) // always run at full speed { unsigned int oscstat_reg = (oscstat->value.get() & 0x1f); oscstat->value.put(oscstat_reg | OSCSTAT::OSTS); clock_state = EC; } else if (config_ieso) // internal/external switchover { clock_state = OST; } } if((osccon_pplx4 && !config_pplx4) && sys_clock == 0) { clock_state |= PLL; return true; } if (!cpu_pic->get_int_osc() && (sys_clock == 0) && !override) return false; if (sys_clock == 1) // T1OSC { base_frequency = 32.e3; clock_state = T1OSC; } else if (sys_clock > 1 || config_irc || override) { unsigned int new_IRCF = (value.get() & ( IRCF0 | IRCF1 | IRCF2 |IRCF3)) >> 3; switch (new_IRCF) { case 0: case 1: base_frequency = 30.e3; clock_state = LFINTOSC; break; case 2: clock_state = MFINTOSC; base_frequency = 31.25e3; break; case 3: clock_state = HFINTOSC; base_frequency = 31.25e3; break; case 4: clock_state = HFINTOSC; base_frequency = 62.5e3; break; case 5: clock_state = HFINTOSC; base_frequency = 125e3; break; case 6: clock_state = HFINTOSC; base_frequency = 250e3; break; case 7: clock_state = HFINTOSC; base_frequency = 500e3; break; case 8: clock_state = HFINTOSC; base_frequency = 125e3; break; case 9: clock_state = HFINTOSC; base_frequency = 250e3; break; case 10: clock_state = HFINTOSC; base_frequency = 500e3; break; case 11: clock_state = HFINTOSC; base_frequency = 1e6; break; case 12: clock_state = HFINTOSC; base_frequency = 2e6; break; case 13: clock_state = HFINTOSC; base_frequency = 4e6; break; case 14: // The treatment for PPL based on Fig 5-1 of P12f1822 ref manual if (osccon_pplx4 || config_pplx4) { clock_state = PLL; base_frequency = 32e6; } else { clock_state = HFINTOSC; base_frequency = 8e6; } break; case 15: clock_state = HFINTOSC; base_frequency = 16e6; break; } } if (osctune) { int tune; unsigned int osctune_value = osctune->value.get(); tune = osctune_value & (OSCTUNE::TUN5-1); tune = (OSCTUNE::TUN5 & osctune_value) ? -tune : tune; base_frequency *= 1. + 0.125 * tune / 31.; } cpu_pic->set_RCfreq_active(true); cpu_pic->set_frequency_rc(base_frequency); if ((bool)verbose) { cout << "set_rc_frequency() : osccon=" << hex << value.get(); if (osctune) cout << " osctune=" << osctune->value.get(); cout << " new frequency=" << base_frequency << endl; } return true; } void OSCCON_2::por_wake() { bool two_speed_clock = config_xosc && config_ieso; CDprintf(("OSCCON_2 two_speed_clock=%d f=%4.1e\n", two_speed_clock, cpu_pic->get_frequency())); if (future_cycle) { get_cycles().clear_break(future_cycle); future_cycle = 0; clock_state = UNDEF; } // internal RC osc if (internal_RC()) { CDprintf(("OSCCON_2 internal RC clock_state %d\n", clock_state)); oscstat->value.put(OSCSTAT::OSTS); set_rc_frequency(); future_cycle = get_cycles().get() + irc_por_time(); get_cycles().set_break(future_cycle, this); return; } if (two_speed_clock) { bool config_pplx4 = cpu_pic->get_pplx4_osc(); oscstat->value.put(0); set_rc_frequency(true); clock_state = OST; if (config_pplx4) clock_state |= PLL; CDprintf(("OSCCON_2 2 speed, set osccon 0x%x \n", value.get())); future_cycle = 1024 + get_cycles().get(); get_cycles().set_break(future_cycle, this); return; } oscstat->value.put(0); } void OSCCON_2::put_value(unsigned int new_value) { CDprintf(("OSCCON_2 0x%x\n", new_value)); value.put(new_value); } void OSCCON_2::put(unsigned int new_value) { unsigned int old_value = value.get(); new_value = (new_value & write_mask); unsigned int oscstat_reg = 0; unsigned int oscstat_new = 0; trace.raw(write_trace.get() | value.get()); value.put(new_value); if (old_value == new_value) return; assert(oscstat); oscstat_reg = oscstat->value.get(); oscstat_new = oscstat_reg; if (((new_value & (SCS0 | SCS1))==0) && !cpu_pic->get_int_osc()) oscstat_new |= OSCSTAT::OSTS; else oscstat_new &= ~OSCSTAT::OSTS; CDprintf(("OSCCON_2 0x%x\n", new_value)); if (set_rc_frequency()) // using internal RC Oscillator set_callback(); } void OSCCON_2::set_callback() { unsigned int oscstat_reg = oscstat->value.get();; unsigned int oscstat_new = oscstat_reg; guint64 settle = 0; CDprintf(("OSCCON_2 clock_state 0x%x\n", clock_state)); switch(clock_state &~ PLL) { case LFINTOSC: oscstat_new &= ~(OSCSTAT::OSTS | OSCSTAT::PLLR | OSCSTAT::T1OSCR); settle = get_cycles().get() + 2; break; case MFINTOSC: oscstat_new &= ~(OSCSTAT::OSTS | OSCSTAT::PLLR | OSCSTAT::T1OSCR); settle = get_cycles().get(2e-6); // 2us settle time break; case HFINTOSC: oscstat_new &= ~(OSCSTAT::OSTS | OSCSTAT::PLLR | OSCSTAT::T1OSCR); settle = get_cycles().get(2e-6); // 2us settle time CDprintf(("OSCCON_2 settle %" PRINTF_GINT64_MODIFIER "d\n", settle)); break; case T1OSC: settle = get_cycles().get() + 1024/4; break; } if((clock_state & PLL) && (oscstat_reg & OSCSTAT::PLLR) == 0) settle = get_cycles().get(2e-3); // 2ms if (settle) { settle += get_cycles().get(); if (future_cycle > get_cycles().get()) get_cycles().clear_break(future_cycle); get_cycles().set_break(settle, this); future_cycle = settle; } if(oscstat && (oscstat_new != oscstat_reg)) oscstat->put(oscstat_new); } void OSCCON2::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); new_value = (new_value & write_mask) | (new_value & ~write_mask); value.put(new_value); assert(osccon); osccon->set_rc_frequency(); } void OSCCON_HS::callback() { assert(osccon2); unsigned int val_osccon2 = osccon2->value.get(); unsigned int val_osccon = value.get(); if (future_cycle <= get_cycles().get()) future_cycle = 0; CDprintf(("OSCCON_HS clock_state=%d osccon=0x%x osccon2=0x%x\n", clock_state, val_osccon, val_osccon2)); switch(clock_state) { case OST: val_osccon &= ~ HFIOFS; val_osccon |= OSTS; val_osccon2 &= ~(OSCCON2::LFIOFS | OSCCON2::MFIOFS); cpu_pic->set_RCfreq_active(false); clock_state = EXCSTABLE; break; case LFINTOSC: val_osccon &= ~HFIOFS; val_osccon2 &= ~OSCCON2::MFIOFS; val_osccon2 |= OSCCON2::LFIOFS; break; case MFINTOSC: val_osccon &= ~HFIOFS; val_osccon2 &= ~OSCCON2::LFIOFS; val_osccon2 |= OSCCON2::MFIOFS; break; case HFINTOSC: val_osccon |= HFIOFS; val_osccon2 &= ~(OSCCON2::LFIOFS|OSCCON2::MFIOFS); break; case T1OSC: break; case EXCSTABLE: val_osccon &= ~HFIOFS; val_osccon |= OSTS; val_osccon2 &= ~(OSCCON2::LFIOFS|OSCCON2::MFIOFS); break; } value.put(val_osccon); CDprintf(("OSCCON_HS osccon 0x%x val_osccon 0x%x\n", value.get(), val_osccon)); osccon2->value.put(val_osccon2); } bool OSCCON_HS::set_rc_frequency(bool override) { double base_frequency = 31.e3; bool config_pplx4 = cpu_pic->get_pplx4_osc(); bool osccon_pplx4 = (osctune)?osctune->value.get() & OSCTUNE::PLLEN:0; bool intsrc = (osctune) ? osctune->value.get() & OSCTUNE::INTSRC : false; bool mfiosel = (osccon2) ? osccon2->value.get() & OSCCON2::MFIOSEL : false; unsigned int old_clock_state = clock_state; CDprintf(("OSCCON_HS override=%d int_osc=%d osccon=0x%x\n", override, cpu_pic->get_int_osc(), value.get())); if (!cpu_pic->get_int_osc() && !(value.get() & SCS1) && !override) return false; unsigned int new_IRCF = (value.get() & ( IRCF0 | IRCF1 | IRCF2)) >> 4; switch (new_IRCF) { case 0: base_frequency = 31.e3; if (mfiosel) clock_state = intsrc ? MFINTOSC : LFINTOSC; else clock_state = intsrc ? HFINTOSC : LFINTOSC; break; case 1: clock_state = mfiosel ? MFINTOSC : HFINTOSC; base_frequency = 125e3; break; case 2: clock_state = mfiosel ? MFINTOSC : HFINTOSC; base_frequency = 250e3; break; case 3: clock_state = HFINTOSC; base_frequency = 1e6; break; case 4: clock_state = HFINTOSC; base_frequency = 2e6; break; case 5: clock_state = HFINTOSC; base_frequency = 4e6; break; case 6: clock_state = HFINTOSC; base_frequency = 8e6; break; case 7: clock_state = HFINTOSC; base_frequency = 16e6; break; } if ( (new_IRCF>=minValPLL) && (osccon_pplx4 || config_pplx4) ) base_frequency *= 4; if (osctune) { int tune; unsigned int osctune_value = osctune->value.get(); tune = osctune_value & (OSCTUNE::TUN5-1); tune = (OSCTUNE::TUN5 & osctune_value) ? -tune : tune; base_frequency *= 1. + 0.125 * tune / 31.; } cpu_pic->set_frequency_rc(base_frequency); if (cpu_pic->get_int_osc() || (value.get() & SCS1)) { CDprintf(("OSCCON_HS clock_state %d->%d f=%.1e osccon=0x%x\n", old_clock_state, clock_state, base_frequency, value.get())); cpu_pic->set_RCfreq_active(true); if (old_clock_state != clock_state) { if ((old_clock_state == LFINTOSC) && clock_state != LFINTOSC) { if (future_cycle) get_cycles().clear_break(future_cycle); future_cycle = get_cycles().get() + irc_lh_time(); get_cycles().set_break(future_cycle, this); CDprintf(("OSCCON_HS future_cycle %" PRINTF_GINT64_MODIFIER "d now %" PRINTF_GINT64_MODIFIER "d\n", future_cycle, get_cycles().get())); } else callback(); } } if ((bool)verbose) { cout << "set_rc_frequency() : osccon=" << hex << value.get(); if (osctune) cout << " osctune=" << osctune->value.get(); cout << " new frequency=" << base_frequency << endl; } return true; } // Is internal RC clock selected? bool OSCCON_HS::internal_RC() { bool ret = false; if ((value.get() & SCS1) || config_irc) ret = true; return ret; } void OSCCON_HS::por_wake() { bool two_speed_clock = config_xosc && config_ieso; unsigned int val_osccon2 = osccon2->value.get(); unsigned int val_osccon = value.get(); CDprintf(("OSCCON_HS config_xosc=%d config_ieso=%d\n", config_xosc,config_ieso)); CDprintf(("OSCCON_HS POR two_speed_clock=%d f=%4.1e osccon=0x%x por_value=0x%x\n", two_speed_clock, cpu_pic->get_frequency(), val_osccon, por_value.data)); if (future_cycle) { get_cycles().clear_break(future_cycle); future_cycle = 0; } // internal RC osc if (internal_RC()) { CDprintf(("OSCCON_HS internal RC clock_state %d osccon %x osccon2 %x\n", clock_state, val_osccon, val_osccon2)); set_rc_frequency(); if (future_cycle) get_cycles().clear_break(future_cycle); future_cycle = get_cycles().get() + irc_por_time(); get_cycles().set_break(future_cycle, this); return; } if (two_speed_clock) { val_osccon &= ~ (HFIOFS | OSTS); val_osccon2 &= ~(OSCCON2::LFIOFS | OSCCON2::MFIOFS); value.put(val_osccon); osccon2->value.put(val_osccon2); set_rc_frequency(true); cpu_pic->set_RCfreq_active(true); CDprintf(("OSCCON_HS 2 speed, set osccon 0x%x \n", value.get())); if (future_cycle) get_cycles().clear_break(future_cycle); clock_state = OST; future_cycle = 1024 + get_cycles().get(); get_cycles().set_break(future_cycle, this); return; } } void WDTCON::put(unsigned int new_value) { unsigned int masked_value = new_value & valid_bits; trace.raw(write_trace.get() | value.get()); value.put(masked_value); if (valid_bits > 1) cpu_pic->wdt.set_prescale(masked_value >> 1); if (cpu_pic->swdten_active()) cpu_pic->wdt.swdten((masked_value & SWDTEN) == SWDTEN); } void WDTCON::reset(RESET_TYPE r) { putRV(por_value); } // //-------------------------------------------------- // member functions for the FSR class //-------------------------------------------------- // FSR::FSR(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) {} void FSR::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } void FSR::put_value(unsigned int new_value) { put(new_value); update(); cpu_pic->indf->update(); } unsigned int FSR::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } unsigned int FSR::get_value() { return(value.get()); } // //-------------------------------------------------- // member functions for the FSR_12 class //-------------------------------------------------- // FSR_12::FSR_12(Processor *pCpu, const char *pName, unsigned int _rpb, unsigned int _valid_bits) : FSR(pCpu, pName, ""), valid_bits(_valid_bits), register_page_bits(_rpb) {} void FSR_12::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); /* The 12-bit core selects the register page using the fsr */ cpu_pic->register_bank = &cpu_pic->registers[ value.get() & register_page_bits ]; } void FSR_12::put_value(unsigned int new_value) { put(new_value); update(); cpu_pic->indf->update(); } unsigned int FSR_12::get() { unsigned int v = get_value(); trace.raw(read_trace.get() | value.get()); return(v); } unsigned int FSR_12::get_value() { // adjust for missing bits //cout << "FSR_12:get_value - valid_bits 0x" << hex << valid_bits << endl; return ((value.get() & valid_bits) | (~valid_bits & 0xff)); } // //-------------------------------------------------- // member functions for the Status_register class //-------------------------------------------------- // //-------------------------------------------------- Status_register::Status_register(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { rcon = NULL; break_point = 0; break_on_z =0; break_on_c =0; address = 3; rp_mask = RP_MASK; write_mask = 0xff & ~STATUS_TO & ~STATUS_PD; new_name("status"); } //-------------------------------------------------- void Status_register::reset(RESET_TYPE r) { switch (r) { case POR_RESET: putRV(por_value); put_TO(1); put_PD(1); break; case WDT_RESET: put_TO(0); break; default: break; } } //-------------------------------------------------- // put void Status_register::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put((value.get() & ~write_mask) | (new_value & write_mask)); if(cpu_pic->base_isa() == _14BIT_PROCESSOR_) { cpu_pic->register_bank = &cpu_pic->registers[(value.get() & rp_mask) << 2]; } } //-------------------------------------------------- // get //unsigned int Status_register::get() //-------------------------------------------------- // put_Z //void Status_register::put_Z(unsigned int new_z) //-------------------------------------------------- // get_Z //unsigned int Status_register::get_Z() //-------------------------------------------------- // put_C //void Status_register::put_C(unsigned int new_c) //-------------------------------------------------- // get_C //unsigned int Status_register::get_C() //-------------------------------------------------- // put_Z_C_DC //-------------------------------------------------- // member functions for the INDF class //-------------------------------------------------- INDF::INDF(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { fsr_mask = 0x7f; // assume a 14bit core base_address_mask1 = 0; // " " base_address_mask2 = 0xff; // " " } void INDF::initialize() { switch(cpu_pic->base_isa()) { case _12BIT_PROCESSOR_: fsr_mask = 0x1f; base_address_mask1 = 0x0; base_address_mask2 = 0x1f; break; case _14BIT_PROCESSOR_: fsr_mask = 0x7f; break; case _PIC17_PROCESSOR_: case _PIC18_PROCESSOR_: cout << "BUG: INDF::"<<__FUNCTION__<<". 16bit core uses a different class for indf."; break; default: cout << " BUG - invalid processor type INDF::initialize\n"; } } void INDF::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); int reg = (cpu_pic->fsr->get_value() + //cpu_pic->fsr->value + ((cpu_pic->status->value.get() & base_address_mask1)<<1) ) & base_address_mask2; // if the fsr is 0x00 or 0x80, then it points to the indf if(reg & fsr_mask){ cpu_pic->registers[reg]->put(new_value); //(cpu_pic->fsr->value & base_address_mask2) + ((cpu_pic->status->value & base_address_mask1)<<1) } } void INDF::put_value(unsigned int new_value) { // go ahead and use the regular put to write the data. // note that this is a 'virtual' function. Consequently, // all objects derived from a file_register should // automagically be correctly updated (which isn't // necessarily true if we just write new_value on top // of the current register value). put(new_value); update(); int r = (cpu_pic->fsr->get_value() + //cpu_pic->fsr->value + (((cpu_pic->status->value.get() & base_address_mask1)<<1)& base_address_mask2)); if(r & fsr_mask) cpu_pic->registers[r]->update(); } unsigned int INDF::get() { trace.raw(read_trace.get() | value.get()); //trace.register_read(address,value.get()); int reg = (cpu_pic->fsr->get_value() + ((cpu_pic->status->value.get() & base_address_mask1)<<1) ) & base_address_mask2; if(reg & fsr_mask) return(cpu_pic->registers[reg]->get()); else return(0); // avoid infinite loop if fsr points to the indf } unsigned int INDF::get_value() { int reg = (cpu_pic->fsr->get_value() + ((cpu_pic->status->value.get() & base_address_mask1)<<1) ) & base_address_mask2; if(reg & fsr_mask) return(cpu_pic->registers[reg]->get_value()); else return(0); // avoid infinite loop if fsr points to the indf } //-------------------------------------------------- // member functions for the PCL base class //-------------------------------------------------- PCL::PCL(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { por_value = RegisterValue(0,0); } // %%% FIX ME %%% breaks are different void PCL::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); cpu_pic->pc->computed_goto(new_value); //trace.register_write(address,value.get()); } void PCL::put_value(unsigned int new_value) { value.put(new_value & 0xff); cpu_pic->pc->put_value( (cpu_pic->pc->get_value() & 0xffffff00) | value.get()); // The gui (if present) will be updated in the pc->put_value call. } unsigned int PCL::get() { return((value.get()+1) & 0xff); } unsigned int PCL::get_value() { value.put(cpu_pic->pc->get_value() & 0xff); return(value.get()); } //------------------------------------------------------------ // PCL reset // void PCL::reset(RESET_TYPE r) { trace.raw(write_trace.get() | value.get()); putRV_notrace(por_value); } //-------------------------------------------------- // member functions for the PCLATH base class //-------------------------------------------------- PCLATH::PCLATH(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { mValidBits = PCLATH_MASK; } void PCLATH::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); value.put(new_value & mValidBits); } void PCLATH::put_value(unsigned int new_value) { cout << "PCLATH::put_value(" << new_value << ")\n"; value.put(new_value & mValidBits); // RP - I cannot think of a single possible reason I'd want to affect the real PC here! // cpu_pic->pc->put_value( (cpu_pic->pc->get_value() & 0xffff00ff) | (value.get()<<8) ); // The gui (if present) will be updated in the pc->put_value call. } unsigned int PCLATH::get() { trace.raw(read_trace.get() | value.get()); //trace.register_read(address,value.get()); return(value.get() & mValidBits); } //-------------------------------------------------- // member functions for the PCON base class //-------------------------------------------------- // PCON::PCON(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bitMask) : sfr_register(pCpu, pName, pDesc) { valid_bits = bitMask; } void PCON::put(unsigned int new_value) { Dprintf((" value %x add %x\n", new_value, new_value&valid_bits)); trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); value.put(new_value&valid_bits); } //------------------------------------------------ Indirect_Addressing14::Indirect_Addressing14(pic_processor *pCpu, const string &n) : fsrl(pCpu, (string("fsrl")+n).c_str(), "FSR Low", this), fsrh(pCpu, (string("fsrh")+n).c_str(), "FSR High", this), indf(pCpu, (string("indf")+n).c_str(), "Indirect Register", this) { current_cycle = (guint64)(-1); // Not zero! See bug #3311944 fsr_value = 0; fsr_state = 0; fsr_delta = 0; cpu = pCpu; } /* * put - Each of the indirect registers associated with this * indirect addressing class will call this routine to indirectly * write data. */ void Indirect_Addressing14::put(unsigned int new_value) { unsigned int fsr_adj = fsr_value + fsr_delta; if (fsr_adj < 0x1000) // Traditional Data Memory { if(is_indirect_register(fsr_adj)) return; cpu_pic->registers[fsr_adj]->put(new_value); } else if (fsr_adj >= 0x2000 && fsr_adj < 0x29b0) // Linear GPR region { unsigned int bank = (fsr_adj & 0xfff) / 0x50; unsigned int low_bits = ((fsr_adj & 0xfff) % 0x50) + 0x20; Dprintf(("fsr_adj %x bank %x low_bits %x add %x\n", fsr_adj, bank, low_bits, (bank*0x80 + low_bits))); cpu_pic->registers[bank * 0x80 + low_bits]->put(new_value); } else if (fsr_adj >= 0x8000 && fsr_adj <= 0xffff) // program memory { cout << "WARNING cannot write via FSR/INDF to program memory address 0x" <registers[fsr_adj]->get(); } else if (fsr_adj >= 0x2000 && fsr_adj < 0x29b0) // Linear GPR region { unsigned int bank = (fsr_adj & 0xfff) / 0x50; unsigned int low_bits = ((fsr_adj & 0xfff) % 0x50) + 0x20; return(cpu_pic->registers[bank * 0x80 + low_bits]->get()); } else if (fsr_adj >= 0x8000 && fsr_adj <= 0xffff) // program memory { unsigned int pm; unsigned address = fsr_adj - 0x8000; if (address <= cpu_pic->program_memory_size()) { pm = cpu_pic->get_program_memory_at_address(address); Dprintf((" address %x max %x value %x\n",address, cpu_pic->program_memory_size(), pm)); return pm & 0xff; } } return 0; } /* * get - Each of the indirect registers associated with this * indirect addressing class will call this routine to indirectly * retrieve data. */ unsigned int Indirect_Addressing14::get_value() { unsigned int fsr_adj = fsr_value + fsr_delta; if (fsr_adj < 0x1000) // Traditional Data Memory { if(is_indirect_register(fsr_adj)) return 0; return cpu_pic->registers[fsr_adj]->get_value(); } else if (fsr_adj >= 0x2000 && fsr_adj < 0x29b0) // Linear GPR region { unsigned int bank = (fsr_adj & 0xfff) / 0x50; unsigned int low_bits = ((fsr_adj & 0xfff) % 0x50) + 0x20; return(cpu_pic->registers[bank * 0x80 + low_bits]->get_value()); } else if (fsr_adj >= 0x8000 && fsr_adj <= 0xffff) // program memory { unsigned int pm; unsigned address = fsr_adj - 0x8000; if (address <= cpu_pic->program_memory_size()) { pm = cpu_pic->get_program_memory_at_address(address); return pm & 0xff; } } return 0; } void Indirect_Addressing14::put_fsr(unsigned int new_fsr) { fsrl.put(new_fsr & 0xff); fsrh.put((new_fsr>>8) & 0xff); } /* * update_fsr_value - This routine is called by the FSRL and FSRH * classes. It's purpose is to update the 16-bit * address formed by the concatenation of FSRL and FSRH. * */ void Indirect_Addressing14::update_fsr_value() { if(current_cycle != get_cycles().get()) { fsr_value = (fsrh.value.get() << 8) | fsrl.value.get(); fsr_delta = 0; } } //-------------------------------------------------- // member functions for the FSR class //-------------------------------------------------- // FSRL14::FSRL14(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing14 *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } void FSRL14::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); iam->fsr_delta = 0; iam->update_fsr_value(); } void FSRL14::put_value(unsigned int new_value) { value.put(new_value & 0xff); iam->fsr_delta = 0; iam->update_fsr_value(); update(); cpu14->indf->update(); } FSRH14::FSRH14(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing14 *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } void FSRH14::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); iam->update_fsr_value(); } void FSRH14::put_value(unsigned int new_value) { value.put(new_value & 0xff); iam->update_fsr_value(); update(); cpu14->indf->update(); } // INDF14 used by 14bit enhanced indirect addressing INDF14::INDF14(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing14 *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } void INDF14::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); if(iam->fsr_value & 0x8000) // extra cycle for program memory access get_cycles().increment(); iam->put(new_value); iam->fsr_delta = 0; } void INDF14::put_value(unsigned int new_value) { iam->put(new_value); iam->fsr_delta = 0; update(); } unsigned int INDF14::get() { unsigned int ret; Dprintf((" get val %x delta %x \n", iam->fsr_value, iam->fsr_delta)); trace.raw(read_trace.get() | value.get()); if(iam->fsr_value & 0x8000) get_cycles().increment(); ret = iam->get(); iam->fsr_delta = 0; return ret; } unsigned int INDF14::get_value() { return(iam->get_value()); } //-------------------------------------------------- Stack::Stack(Processor *pCpu) : cpu(pCpu) { stack_warnings_flag = 0; // Do not display over/under flow stack warnings break_on_overflow = true; // Do not break if the stack over flows break_on_underflow = 0; // Do not break if the stack under flows stack_mask = 7; // Assume a 14 bit core. pointer = 0; for(int i=0; i<31; i++) contents[i] = 0; STVREN = 0; } // // Stack::push // // push the passed address onto the stack by storing it at the current // bool Stack::push(unsigned int address) { Dprintf(("pointer=%d address 0x%x\n",pointer,address)); // Write the address at the current point location. Note that the '& stack_mask' // implicitly handles the stack wrap around. // If the stack pointer is too big, then the stack has definitely over flowed. // However, some pic programs take advantage of this 'feature', so provide a means // for them to ignore the warnings. if(pointer > (int)stack_mask) { stack_overflow(); return false; } contents[pointer++ & stack_mask] = address; return true; } bool Stack::stack_overflow() { Dprintf(("stack_warnings_flag=%d break_on_overflow=%d\n", stack_warnings_flag,break_on_overflow)); if(stack_warnings_flag || break_on_overflow) cout << "stack overflow \n"; if(break_on_overflow) bp.halt(); return true; } // // Stack::pop // unsigned int Stack::pop() { // First decrement the stack pointer. if(--pointer < 0) { stack_underflow(); return 0; } Dprintf(("pointer=%d address 0x%x\n",pointer,contents[pointer & stack_mask])); return(contents[pointer & stack_mask]); } bool Stack::stack_underflow() { pointer = 0; if(stack_warnings_flag || break_on_underflow) cout << "stack underflow "; if(break_on_underflow) bp.halt(); return true; } // // bool Stack::set_break_on_overflow(bool clear_or_set) // // Set or clear the break on overflow flag bool Stack::set_break_on_overflow(bool clear_or_set) { if(break_on_overflow == clear_or_set) return 0; break_on_overflow = clear_or_set; return 1; } // // bool Stack::set_break_on_underflow(bool clear_or_set) // // Set or clear the break on underflow flag bool Stack::set_break_on_underflow(bool clear_or_set) { if(break_on_underflow == clear_or_set) return 0; break_on_underflow = clear_or_set; return 1; } // Read value at top of stack // unsigned int Stack::get_tos() { if (pointer > 0) return (contents[pointer-1]); else return (0); } // Modify value at top of stack; // void Stack::put_tos(unsigned int new_tos) { if (pointer > 0) contents[pointer-1] = new_tos; } // Stack14E for extended 14bit processors // This stack implementation differs from both the other 14bit // and 16bit stacks as a dummy empty location is used so a // stack with 16 slots can hold 16 values. The other implementaion // of the stack hold n-1 values for an n slot stack. // This stack also supports stkptr, tosl, and tosh like the 16bit // (p18) processors Stack14E::Stack14E(Processor *pCpu) : Stack(pCpu), stkptr(pCpu, "stkptr", "Stack pointer"), tosl(pCpu, "tosl", "Top of Stack low byte"), tosh(pCpu, "tosh", "Top of Stack high byte") { stkptr.stack = this; tosl.stack = this; tosh.stack = this; STVREN = 1; } Stack14E::~Stack14E() { pic_processor *pCpu = dynamic_cast(cpu); if (pCpu) { pCpu->remove_sfr_register(&stkptr); pCpu->remove_sfr_register(&tosl); pCpu->remove_sfr_register(&tosh); } } void Stack14E::reset(RESET_TYPE r) { pointer = NO_ENTRY; if (STVREN) contents[stack_mask] = 0; else contents[pointer-1] = contents[stack_mask]; Dprintf((" pointer 0x%x\n", pointer)); stkptr.put(pointer-1); } bool Stack14E::push(unsigned int address) { Dprintf(("pointer=%d address 0x%x\n",pointer,address)); // Write the address at the current point location. Note that the '& stack_mask' // implicitly handles the stack wrap around. if(pointer == NO_ENTRY) pointer = 0; contents[pointer & stack_mask] = address; // If the stack pointer is too big, then the stack has definitely over flowed. // However, some pic programs take advantage of this 'feature', so provide a means // for them to ignore the warnings. if(pointer++ > (int)stack_mask) { return stack_overflow(); } stkptr.put(pointer-1); return true; } unsigned int Stack14E::pop() { unsigned int ret = 0; if (pointer == NO_ENTRY) { return stack_underflow(); } pointer--; ret = contents[pointer]; if (pointer <= 0) pointer = NO_ENTRY; stkptr.put(pointer-1); return(ret); } bool Stack14E::stack_overflow() { cpu14e->pcon.put(cpu14e->pcon.get() | PCON::STKOVF); if(STVREN) { cpu->reset(STKOVF_RESET); return false; } else { cout << "Stack overflow\n"; } return true; } bool Stack14E::stack_underflow() { Dprintf((" cpu %p STVREN %d\n", cpu, STVREN)); cpu14e->pcon.put(cpu14e->pcon.get() | PCON::STKUNF); if(STVREN) { cpu->reset(STKUNF_RESET); return false; } else { cout << "Stack underflow\n"; } return true; } //------------------------------------------------ // TOSL TOSL::TOSL(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) {} unsigned int TOSL::get() { value.put(stack->get_tos() & 0xff); trace.raw(read_trace.get() | value.get()); return(value.get()); } unsigned int TOSL::get_value() { value.put(stack->get_tos() & 0xff); return(value.get()); } void TOSL::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); stack->put_tos( (stack->get_tos() & 0xffffff00) | (new_value & 0xff)); value.put(new_value & 0xff); } void TOSL::put_value(unsigned int new_value) { stack->put_tos( (stack->get_tos() & 0xffffff00) | (new_value & 0xff)); value.put(new_value & 0xff); update(); } //------------------------------------------------ // TOSH TOSH::TOSH(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) {} unsigned int TOSH::get() { value.put((stack->get_tos() >> 8) & 0xff); trace.raw(read_trace.get() | value.get()); return(value.get()); } unsigned int TOSH::get_value() { value.put((stack->get_tos() >> 8) & 0xff); return(value.get()); } void TOSH::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); stack->put_tos( (stack->get_tos() & 0xffff00ff) | ( (new_value & 0xff) << 8)); value.put(new_value & 0xff); } void TOSH::put_value(unsigned int new_value) { stack->put_tos( (stack->get_tos() & 0xffff00ff) | ( (new_value & 0xff) << 8)); value.put(new_value & 0xff); update(); } STKPTR::STKPTR(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) {} void STKPTR::put_value(unsigned int new_value) { stack->pointer = (new_value & 0x1f) + 1; value.put(new_value); update(); } void STKPTR::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } //======================================================================== class WReadTraceObject : public RegisterReadTraceObject { public: WReadTraceObject(Processor *_cpu, RegisterValue trv); virtual void print(FILE *fp); }; class WWriteTraceObject : public RegisterWriteTraceObject { public: WWriteTraceObject(Processor *_cpu, RegisterValue trv); virtual void print(FILE *fp); }; class WTraceType : public ProcessorTraceType { public: WTraceType(Processor *_cpu, unsigned int s) : ProcessorTraceType(_cpu,s,"W reg") {} TraceObject *decode(unsigned int tbi); }; //======================================================================== WWriteTraceObject::WWriteTraceObject(Processor *_cpu, RegisterValue trv) : RegisterWriteTraceObject(_cpu,0,trv) { pic_processor *pcpu = dynamic_cast(cpu); if(pcpu) { to = cpu_pic->Wreg->trace_state; cpu_pic->Wreg->trace_state = from; } } void WWriteTraceObject::print(FILE *fp) { char sFrom[16]; char sTo[16]; fprintf(fp, " Wrote: 0x%s to W was 0x%s\n", to.toString(sTo,sizeof(sTo)), from.toString(sFrom,sizeof(sFrom))); } //======================================================================== WReadTraceObject::WReadTraceObject(Processor *_cpu, RegisterValue trv) : RegisterReadTraceObject(_cpu,0,trv) { pic_processor *pcpu = dynamic_cast(cpu); if(pcpu) { to = cpu_pic->Wreg->trace_state; cpu_pic->Wreg->trace_state = from; } } void WReadTraceObject::print(FILE *fp) { char sFrom[16]; fprintf(fp, " Read: 0x%s from W\n", from.toString(sFrom,sizeof(sFrom))); } //======================================================================== TraceObject * WTraceType::decode(unsigned int tbi) { unsigned int tv = trace.get(tbi); RegisterValue rv = RegisterValue(tv & 0xff,0); TraceObject *wto; if (tv & (1<<22)) wto = new WReadTraceObject(cpu, rv); else wto = new WWriteTraceObject(cpu, rv); return wto; } WREG::WREG(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { if(cpu) { unsigned int trace_command = trace.allocateTraceType(m_tt = new WTraceType(get_cpu(),1)); RegisterValue rv(trace_command+(0<<22), trace_command+(2<<22)); set_write_trace(rv); rv = RegisterValue(trace_command+(1<<22), trace_command+(3<<22)); set_read_trace (rv); } } WREG::~WREG() { delete m_tt; } void WPU::put(unsigned int new_value) { unsigned int masked_value = new_value & mValidBits; int i; trace.raw(write_trace.get() | value.get()); value.put(masked_value); for(i = 0; i < 8; i++) { if((1<getPin().update_pullup((((1<set_t0xcs(masked_value & T0XCS); calculate_freq(); } #define p_cpu ((Processor *)cpu) void CPSCON0::calculate_freq() { if (!(value.get() & CPSON)) // not active, return return; if (!pin[chan] || !pin[chan]->getPin().snode) { return; } double cap = pin[chan]->getPin().snode->Cth; double current = 0; double deltat; switch((value.get() & (CPSRNG0 | CPSRNG1)) >> 2) { case 1: current = (value.get() & CPSRM) ? 9e-6 : 0.1e-6; break; case 2: current = (value.get() & CPSRM) ? 30e-6 : 1.2e-6; break; case 3: current = (value.get() & CPSRM) ? 100e-6 : 18e-6; break; }; if (current < 1e-12) return; // deltat is the time required to charge the capacitance on the pin // from a constant current source for the specified voltage swing. // The voltage swing for the internal reference is not specified // and it is just a guess that it is Vdd - 2 diode drops. // // This implimentation does not work if capacitor oscillator // runs faster than Fosc/4 // if (value.get() & CPSRM) { deltat = (FVR_voltage - DAC_voltage)*cap/current; if (deltat <= 0.) { cout << "CPSCON FVR must be greater than DAC for high range to work\n"; return; } } else { deltat = (p_cpu->get_Vdd() - 1.2) * cap / current; } period = (p_cpu->get_frequency() * deltat + 2) / 4; if (period <= 0) { cout << "CPSCON Oscillator > Fosc/4, setting to Fosc/4\n"; period = 1; } guint64 fc = get_cycles().get() + period; if (future_cycle > get_cycles().get()) { get_cycles().reassign_break(future_cycle, fc, this); } else get_cycles().set_break(fc, this); future_cycle = fc; } void CPSCON0::callback_print() { cout << name() << " has callback, ID = " << CallBackID << '\n'; } void CPSCON0::callback() { Dprintf(("now=0x%" PRINTF_GINT64_MODIFIER "x\n",get_cycles().get())); if (!(value.get() & CPSON)) return; if (value.get() & CPSOUT) // High to low transition { value.put(value.get() & ~CPSOUT); if (m_tmr0 && (value.get() & T0XCS) && m_tmr0->get_t0se() && m_tmr0->get_t0cs()) { m_tmr0->increment(); } } else // Low to high transition { value.put(value.get() | CPSOUT); if (m_tmr0 && (value.get() & T0XCS) && !m_tmr0->get_t0se() && m_tmr0->get_t0cs()) { m_tmr0->increment(); } if (m_t1con_g) m_t1con_g->t1_cap_increment(); } calculate_freq(); } void CPSCON0::set_chan(unsigned int _chan) { if (_chan == chan) return; if (!pin[_chan]) { cout << "CPSCON Channel " << _chan << " reserved\n"; return; } if (!pin[_chan]->getPin().snode) { cout << "CPSCON Channel " << pin[_chan]->getPin().name() << " requires a node attached\n"; chan = _chan; return; } if (!cps_stimulus) cps_stimulus = new CPS_stimulus(this, "cps_stimulus"); else if (pin[_chan]->getPin().snode) { (pin[_chan]->getPin().snode)->detach_stimulus(cps_stimulus); } chan = _chan; (pin[_chan]->getPin().snode)->attach_stimulus(cps_stimulus); calculate_freq(); } void CPSCON0::set_DAC_volt(double volt) { DAC_voltage = volt; if ((value.get() & (CPSON|CPSRM)) == (CPSON|CPSRM)) calculate_freq(); } void CPSCON0::set_FVR_volt(double volt) { FVR_voltage = volt; if ((value.get() & (CPSON|CPSRM)) == (CPSON|CPSRM)) calculate_freq(); } CPS_stimulus::CPS_stimulus(CPSCON0 * arg, const char *cPname,double _Vth, double _Zth) : stimulus(cPname, _Vth, _Zth) { m_cpscon0 = arg; } // Thisvis also called when the capacitance chages, // not just when the voltage changes void CPS_stimulus::set_nodeVoltage(double v) { Dprintf(("set_nodeVoltage =%.1f\n", v)); nodeVoltage = v; m_cpscon0->calculate_freq(); } void CPSCON1::put(unsigned int new_value) { unsigned int masked_value = new_value & mValidBits; trace.raw(write_trace.get() | value.get()); value.put(masked_value); assert(m_cpscon0); m_cpscon0->set_chan(masked_value); } SRCON0::SRCON0(Processor *pCpu, const char *pName, const char *pDesc, SR_MODULE *_sr_module) : sfr_register(pCpu, pName, pDesc), m_sr_module(_sr_module) { } void SRCON0::put(unsigned int new_value) { unsigned int diff = new_value ^ value.get(); if (!diff) return; trace.raw(write_trace.get() | value.get()); value.put(new_value & ~(SRPR|SRPS)); // SRPR AND SRPS not saved if ((diff & SRPS) && (new_value & SRPS)) m_sr_module->pulse_set(); if ((diff & SRPR) && (new_value & SRPR)) m_sr_module->pulse_reset(); if (diff & CLKMASK) m_sr_module->clock_diff((new_value & CLKMASK) >> CLKSHIFT); if (diff & (SRQEN | SRLEN)) m_sr_module->Qoutput(); if (diff & (SRNQEN | SRLEN)) m_sr_module->NQoutput(); m_sr_module->update(); } SRCON1::SRCON1(Processor *pCpu, const char *pName, const char *pDesc, SR_MODULE *_sr_module) : sfr_register(pCpu, pName, pDesc), m_sr_module(_sr_module), mValidBits(0xdd) { } void SRCON1::put(unsigned int new_value) { unsigned int masked_value = new_value & mValidBits; unsigned int diff = masked_value ^ value.get(); trace.raw(write_trace.get() | value.get()); value.put(masked_value); if (!diff) return; if (diff & (SRRCKE | SRSCKE)) { if (!(new_value & (SRRCKE | SRSCKE))) // all clocks off m_sr_module->clock_disable(); // turn off clock else m_sr_module->clock_enable(); // turn on clock } m_sr_module->update(); } class SRinSink : public SignalSink { public: SRinSink(SR_MODULE *_sr_module) : sr_module(_sr_module) {} virtual void setSinkState(char new3State) { sr_module->setState(new3State); } virtual void release() { delete this; } private: SR_MODULE *sr_module; }; class SRnSource : public PeripheralSignalSource { public: SRnSource(PinModule *_pin, SR_MODULE *_sr_module, int _index) : PeripheralSignalSource(_pin), sr_module(_sr_module), index(_index) { ;} virtual void release() { sr_module->releasePin(index); } private: SR_MODULE *sr_module; int index; }; enum { SRQ = 0, SRNQ }; SR_MODULE::SR_MODULE(Processor *_cpu) : srcon0(_cpu, "srcon0", "SR Latch Control 0 Register", this), srcon1(_cpu, "srcon1", "SR Latch Control 1 Register", this), cpu(_cpu), future_cycle(0), state_set(false), state_reset(false), state_Q(false), srclk(0), syncc1out(false), syncc2out(false), SRI_pin(0), SRQ_pin(0), SRNQ_pin(0), m_SRinSink(0), m_SRQsource(0), m_SRNQsource(0), m_SRQsource_active(false), m_SRNQsource_active(false) { } SR_MODULE::~SR_MODULE() { if (m_SRQsource_active) SRQ_pin->setSource(0); if ( m_SRQsource) delete m_SRQsource; if (m_SRNQsource_active) SRNQ_pin->setSource(0); if ( m_SRNQsource) delete m_SRNQsource; } // determine output state of RS flip-flop // If both state_set and state_reset are true, Q output is 0 // SPR[SP] and clocked inputs maybe set outside the update // function prior to its call. void SR_MODULE::update() { if ((srcon1.value.get() & SRCON1::SRSC1E) && syncc1out) state_set = true; if ((srcon1.value.get() & SRCON1::SRSC2E) && syncc2out) state_set = true; if ((srcon1.value.get() & SRCON1::SRSPE) && SRI_pin->getPin().getState()) state_set = true; if ((srcon1.value.get() & SRCON1::SRRC1E) && syncc1out) state_reset = true; if ((srcon1.value.get() & SRCON1::SRRC2E) && syncc2out) state_reset = true; if ((srcon1.value.get() & SRCON1::SRRPE) && SRI_pin->getPin().getState()) state_reset = true; if (state_set) state_Q = true; // reset overrides a set if (state_reset) state_Q = false; state_set = state_reset = false; if (!(srcon0.value.get() & SRCON0::SRLEN)) return; if ((srcon0.value.get() & SRCON0::SRQEN)) m_SRQsource->putState(state_Q ? '1' : '0'); if ((srcon0.value.get() & SRCON0::SRNQEN)) m_SRNQsource->putState(!state_Q ? '1' : '0'); } // Stop clock if currently running void SR_MODULE::clock_disable() { if (future_cycle> get_cycles().get()) { get_cycles().clear_break(this); future_cycle = 0; } future_cycle = 0; } // Start clock if not running // As break works on instruction cycles, clock runs every 1-128 // instructions which is 1 << srclk // void SR_MODULE::clock_enable() { if (!future_cycle) { future_cycle = get_cycles().get() + (1 << srclk); get_cycles().set_break(future_cycle, this); } } // Called for clock rate change void SR_MODULE::clock_diff(unsigned int _srclk) { srclk = _srclk; clock_disable(); if (srcon1.value.get() & (SRCON1::SRSCKE | SRCON1::SRRCKE)) { clock_enable(); } } void SR_MODULE::callback() { bool active = false; if (srcon1.value.get() & (SRCON1::SRSCKE)) //Set clock enabled { active = true; pulse_set(); } if (srcon1.value.get() & (SRCON1::SRRCKE)) //Reset clock enabled { active = true; pulse_reset(); } if (active) { future_cycle = 0; clock_enable(); } update(); } void SR_MODULE::setPins(PinModule *sri, PinModule *srq, PinModule *srnq) { if(!SRI_pin) { m_SRinSink = new SRinSink(this); sri->addSink(m_SRinSink); } else if (SRI_pin != sri) { SRI_pin->removeSink(m_SRinSink); sri->addSink(m_SRinSink); } SRI_pin = sri; SRQ_pin = srq; SRNQ_pin = srnq; } // If pin chnages and we are looking at it, call update void SR_MODULE::setState(char IOin) { if (srcon1.value.get() & (SRCON1::SRSPE | SRCON1::SRRPE)) update(); } void SR_MODULE::syncC1out(bool val) { if (syncc1out != val) { syncc1out = val; if (srcon1.value.get() & (SRCON1::SRSC1E | SRCON1::SRRC1E)) { update(); } } } void SR_MODULE::syncC2out(bool val) { if (syncc2out != val) { syncc2out = val; if (srcon1.value.get() & (SRCON1::SRSC2E | SRCON1::SRRC2E)) { update(); } } } // Setup or tear down RSQ output pin // This is only call if SRLEN OR SRQEN has changed void SR_MODULE::Qoutput() { if ((srcon0.value.get() & (SRCON0::SRLEN | SRCON0::SRQEN)) == (SRCON0::SRLEN | SRCON0::SRQEN)) { if (!m_SRQsource) m_SRQsource = new SRnSource(SRQ_pin, this, SRQ); SRQ_pin->setSource(m_SRQsource); SRQ_pin->getPin().newGUIname("SRQ"); m_SRQsource_active = true; } else { SRQ_pin->setSource(0); if (strcmp("SRQ", SRQ_pin->getPin().GUIname().c_str()) == 0) { SRQ_pin->getPin().newGUIname(SRQ_pin->getPin().name().c_str()); } } } // Setup or tear down RSNQ output pin // This is only call if SRLEN OR SRNQEN has changed void SR_MODULE::NQoutput() { if ((srcon0.value.get() & (SRCON0::SRLEN | SRCON0::SRNQEN)) == (SRCON0::SRLEN | SRCON0::SRNQEN)) { if (!m_SRNQsource) m_SRNQsource = new SRnSource(SRNQ_pin, this, SRNQ); SRNQ_pin->setSource(m_SRNQsource); SRNQ_pin->getPin().newGUIname("SRNQ"); m_SRNQsource_active = true; } else { SRNQ_pin->setSource(0); if (strcmp("SRNQ", SRNQ_pin->getPin().GUIname().c_str()) == 0) { SRNQ_pin->getPin().newGUIname(SRNQ_pin->getPin().name().c_str()); } } } void SR_MODULE::releasePin(int index) { switch(index) { case SRQ: m_SRQsource_active = false; break; case SRNQ: m_SRNQsource_active = false; break; } } //------------------------------------------------------------------- LVDCON_14::LVDCON_14(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName,pDesc), write_mask(0x17), IntSrc(0) { } double ldv_volts[] = {1.9, 2.0, 2.1, 2.2, 2.3, 4.0, 4.2, 4.5}; void LVDCON_14::check_lvd() { unsigned int reg = value.get(); if (!(reg & IRVST)) return; double voltage = ldv_volts[reg & (LVDL0|LVDL1|LVDL2)]; Processor *Cpu = (Processor *)cpu; if (Cpu->get_Vdd() <= voltage) IntSrc->Trigger(); } void LVDCON_14::callback() { value.put(value.get() | IRVST); check_lvd(); } void LVDCON_14::put(unsigned int new_value) { new_value &= write_mask; unsigned int diff = value.get() ^ new_value; if (!diff) return; trace.raw(write_trace.get() | value.get()); value.put(new_value); if ((diff & LVDEN) && (new_value & LVDEN)) // Turning on { // wait before doing anything get_cycles().set_break( get_cycles().get() + 50e-6 * get_cycles().instruction_cps(), this); } return; } gpsim-0.30.0/src/p16f62x.cc0000664000076400007640000002661513041763624012076 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16f62x // // This file supports: // PIC16F627 // PIC16F628 // PIC16F648 // #include #include #include //#include "../config.h" #include "stimuli.h" #include "p16f62x.h" #include "pic-ioports.h" #include "packages.h" #include "symbol.h" P16F62x::P16F62x(const char *_name, const char *desc) : P16X6X_processor(_name,desc), usart(this), comparator(this) { } P16F62x::~P16F62x() { delete_file_registers(0xc0, 0xef); delete_file_registers(0x120,0x14f); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); delete eeprom; eeprom = 0; } void P16F62x::create_iopin_map() { package = new Package(18); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 3, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(15, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(16, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin(5, 0); // Vss package->assign_pin( 6, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin( 7, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(14, 0); // Vdd } void P16F62x::create_sfr_map() { add_file_registers(0xc0, 0xef, 0); // 0xa0 - 0xbf are created in the P16X6X_processor class add_file_registers(0x120,0x14f,0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); alias_file_registers(0x0,0x0,0x100); // INDF exists in all four pages, 16x6x did the first two alias_file_registers(0x0,0x0,0x180); alias_file_registers(0x01,0x04,0x100); alias_file_registers(0x81,0x84,0x100); remove_sfr_register(m_trisa); add_sfr_register(m_trisa, 0x85, RegisterValue(0xff,0)); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x86,0x86,0x100); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x9a); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x9b); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x9c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x9d); // PCLATH alias_file_registers(0x0a,0x0a,0x100); alias_file_registers(0x0a,0x0a,0x180); alias_file_registers(0x0b,0x0b,0x100); alias_file_registers(0x0b,0x0b,0x180); usart.initialize(pir1,&(*m_portb)[2], &(*m_portb)[1], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), &(*m_porta)[2], &(*m_porta)[0], &(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[3], &(*m_porta)[3], &(*m_porta)[4]); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN2, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 1, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 2, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN2, AN0, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 5, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 6, AN0, AN2, AN0, AN2, OUT0); comparator.cmcon.set_configuration(2, 6, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0x1f, RegisterValue(0,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0x9f, RegisterValue(0,0),"vrcon"); comparator.cmcon.put(0); // Link ccp1 onto portb ccp1con.setIOpin(&((*m_portb)[3])); } void P16F62x::create_symbols() { if(verbose) cout << "62x create symbols\n"; Pic14Bit::create_symbols(); } void P16F62x::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } //======================================================================== bool P16F62x::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<4, CFG_MCLRE = 1<<5 }; // Let the base class do most of the work: if (pic_processor::set_config_word(address, cfg_word)) { if (verbose) cout << "p16f628 setting config word 0x" << hex << cfg_word << '\n'; unsigned int valid_pins = m_porta->getEnableMask(); set_int_osc(false); // Careful these bits not adjacent switch(cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2)) { case 0: // LP oscillator: low power crystal is on RA6 and RA7 case 1: // XT oscillator: crystal/resonator is on RA6 and RA7 case 2: // HS oscillator: crystal/resonator is on RA6 and RA7 (m_porta->getPin(6))->newGUIname("OSC2"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 0x13: // ER oscillator: RA6 is CLKOUT, resistor (?) on RA7 (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 3: // EC: RA6 is an I/O, RA7 is a CLKIN case 0x12: // ER oscillator: RA6 is an I/O, RA7 is a CLKIN (m_porta->getPin(7))->newGUIname("CLKIN"); valid_pins = (valid_pins & 0x7f)|0x40; break; case 0x10: // INTRC: Internal Oscillator, RA6 and RA7 are I/O's set_int_osc(true); (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins |= 0xc0; break; case 0x11: // INTRC: Internal Oscillator, RA7 is an I/O, RA6 is CLKOUT set_int_osc(true); (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins = (valid_pins & 0xbf)|0x80; break; } // If the /MCLRE bit is set then RA5 is the MCLR pin, otherwise it's // a general purpose I/O pin. if (! (cfg_word & CFG_MCLRE)) { unassignMCLRPin(); valid_pins |= ( 1<< 5); // porta5 IO port } else { assignMCLRPin(4); // pin 4 } //cout << " porta valid_iopins " << porta->valid_iopins << // " tris valid io " << trisa.valid_iopins << '\n'; if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_porta->setTris(m_trisa); } return true; } return false; } //======================================================================== void P16F62x::create(int ram_top, unsigned int eeprom_size) { EEPROM_PIR *e; create_iopin_map(); _14bit_processor::create(); e = new EEPROM_PIR(this,pir1); e->initialize(eeprom_size); //e->set_pir_set(get_pir_set()); e->set_intcon(&intcon_reg); // assign this eeprom to the processor set_eeprom_pir(e); P16X6X_processor::create_sfr_map(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F62x::create_sfr_map(); // Build the links between the I/O Pins and the internal peripherals //1ccp1con.iopin = portb->pins[3]; } //======================================================================== // // Pic 16F627 // Processor * P16F627::construct(const char *name) { P16F627 *p = new P16F627(name); p->P16F62x::create(0x2f, 128); p->create_invalid_registers (); p->create_symbols(); return p; } P16F627::P16F627(const char *_name, const char *desc) : P16F62x(_name,desc) { if(verbose) cout << "f627 constructor, type = " << isa() << '\n'; } //======================================================================== // // Pic 16F628 // Processor * P16F628::construct(const char *name) { P16F628 *p = new P16F628(name); p->P16F62x::create(0x2f, 128); p->create_invalid_registers (); p->create_symbols(); return p; } P16F628::P16F628(const char *_name, const char *desc) : P16F627(_name,desc) { if(verbose) cout << "f628 constructor, type = " << isa() << '\n'; } P16F628::~P16F628() { if (verbose) cout << "'628 destructor\n"; } //======================================================================== // // Pic 16F648 // Processor * P16F648::construct(const char *name) { P16F648 *p = new P16F648(name); p->P16F62x::create(0x2f, 256); p->create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F648::P16F648(const char *_name, const char *desc) : P16F628(_name,desc) { if(verbose) cout << "f648 constructor, type = " << isa() << '\n'; } P16F648::~P16F648() { delete_file_registers(0x150,0x16f); } void P16F648::create_sfr_map() { add_file_registers(0x150,0x16f,0); } gpsim-0.30.0/src/trace.cc0000664000076400007640000014364713065711301012054 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "pic-processor.h" #include "14bit-processors.h" #include "trace.h" #include "trace_orb.h" #include "xref.h" #define NEWTRACE //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif #define MODE "0x" << hex Trace trace; /* Instantiate the trace buffer class. * This is where *everything* including the * kitchen sink gets stored in a trace buffer. * Since everything is stored here, it gets * rather difficult to post process traced info * efficiently. So this buffer is primarily used * to record program flow that the user may post * analyze by dumping its contents. */ // create an instance of inline get_trace() method by taking its address Trace &(*dummy_trace)() = get_trace; TraceLog trace_log; ProfileKeeper profile_keeper; #if defined(_WIN32) TraceLog &GetTraceLog() { return trace_log; } #endif //======================================================================== traceValue::traceValue() { } unsigned int traceValue::get_value() { return trace.trace_index; } /**************************************************************************** * * gpsim Trace * General: gpsim traces almost everything simulated: instructions executed, register reads/writes, clock cycles, special register accesses break points, instruction skips, external modules, and a few other miscellaneous things. The tracing subsystem is implemented as a C++ class. In theory, multiple traces could be instantiated, but (currently) there is one global trace instantiated and all the pieces of gpsim make direct references to it. How can gpsim trace every thing and still be the fastest microcontroller simulator? Well, gpsim writes trace information into a giant circular buffer. So one optimization is that there are no array bounds to check. Another optimization is that most of the trace operations are C++ inline functions. A third optimization is that the trace operations are efficiently encoded into 32-bit words. The one exception is the cycle counter trace, it takes two 32-bit words (see the cycle counter trace comment below). The upper 8-bits of the trace word are reserved for describing the trace type. The upper two bits of these 8-bits are reservered for encoding the cycle counter. The lower 6-bits allow 64 enumerated types to be encoded. Only a small portion of these are currently used. The lower 24-bits of the 32-bit trace word store the information we wish to trace. For example, for register reads and writes, there are 8-bits of data and (upto) 16-bits of address. Details Each trace takes exactly one 32-bit word. The upper 8-bits define the trace type and the lower 24 are the trace value. For example, a register write will get traced with a 32 bit encoded like: TTAAAAVV TT - Register write trace type AAAA - 4-hexdigit address VV - 2-hexdigit (8-bit) value The cycle counter is treated slightly differently. Since it is a 64-bit object, it has to be split across at least two trace entries. The upper few bits of the cycle counter aren't traced. (This is a bug for simulations that run for several centuries!) The trace member function is_cycle_trace() describes the cycle counter encoding in detail. Trace Types. gpsim differentiates individually traced items by the TT field (upper 8 bits of the 32-bit trace word). Except for the cycle counter trace, these trace types are dynamically allocated whenever a TraceType class is instantiated. As described above, the other gpsim classes use this dynamically allocated 32-bit trace word as a handle for efficiently storing information into the trace buffer. In addition to allocating the 32-bit word for tracing, the TraceType class will use it as a hash index into the 'trace_map'. The trace_map is a locally (to trace.cc) instantiated STL map that cross references the 32-bit trace types to the instantiated TraceType class that create them. When the trace buffer is decoded, the trace type (upper 8-bits) of the 32-bit trace word is extracted and used to look up the TraceType object in the trace_map map. The lower 24-bits of the trace word are then passed to the TraceType object's decode() method. Continuing with the example from above, TTAAAAVV TT - Used to look up the TraceType object in the trace_map AAAAVV - Passed to the decode() method of the object. The TraceType decode() method will usually create a TraceObject and place it on a TraceFrame. Trace Frames and Trace Objects A trace frame is defined to be the decoded contents of the trace buffer corresponding to a single time quantum (i.e. single simulation cycle). Each frame has an STL list to hold the TraceObjects. The TraceObjects are created by the TraceType classes. This happens when the 32-bit trace word is decoded by the TraceType class. The TraceObject has several purposes. First, unique TraceObjects are created for the variety of things gpsim traces. For example, when the simulated processor writes to a register, a corresponding RegisterWriteTraceObject will get created when the trace buffer is decoded. Another purpose of the TraceObject is to record the system state. Take for example the register write trace. When a register write occurs, the register has a value before the write and a value after the write. When the register write is traced, only the value *before* the write is recorded. When the trace buffer is decoded, the simulation is effectively run backwards. The current state is known before trace decoding commences. Then as the decoding steps backwards through the trace history, the state change at each trace event is recorded in the trace object. So the register write trace event gets decoded into a TraceObject. This trace object knows the current state of the register; that's simply the register's current contents. The trace object knows the contents of the register prior to the register write operation; that's stored in the trace buffer. ****************************************************************************/ /* Trace Logging gpsim supports two modes of trace logging. The first mode is the "log all" mode. In this mode, the entire trace buffer is periodically written to a file. The second mode is a "log selective". In this mode individual trace operations are written to a file. */ TraceRawLog::TraceRawLog() { log_filename = 0; log_file = 0; } TraceRawLog::~TraceRawLog() { if(log_file) { log(); fclose(log_file); } } void TraceRawLog::log() { if(log_file) { unsigned int i; for(i=0; isave_state(log_file); if(log_filename) { free(log_filename); log_filename = 0; } if (log_file != NULL) fclose(log_file); log_file = NULL; cout << "Trace logging disabled\n"; trace.bLogging = false; } //======================================================================== // TraceFrame // // A TraceFrame is a collection of traced items that belong to a single // simulation cycle. The TraceFrame is only built up whenever the user // requests trace history. Each frame contains a list of traceObjects // that describe the specific information that the simulation has traced. TraceFrame::TraceFrame( ) { cycle_time = 0; } TraceFrame::~TraceFrame() { list :: iterator toIter; toIter = traceObjects.begin(); while(toIter != traceObjects.end()) { delete *toIter; ++toIter; } } void TraceFrame::add(TraceObject *to) { traceObjects.push_back(to); } void TraceFrame::print(FILE *fp) { list :: iterator toIter; for(toIter = traceObjects.begin(); toIter != traceObjects.end(); ++toIter) (*toIter)->print_frame(this,fp); } void TraceFrame::update_state() { list :: iterator toIter; for(toIter = traceObjects.begin(); toIter != traceObjects.end(); ++toIter) (*toIter)->getState(this); } //============================================================ // Trace::addFrame // // The Trace class maintains a list of traceFrames. Here is where // a new one gets added. Note that traceFrames are created only // when a user requests to see the trace history. void Trace::addFrame(TraceFrame *newFrame) { current_frame = newFrame; traceFrames.push_back(newFrame); } void Trace::addToCurrentFrame(TraceObject *to) { if(current_frame) current_frame->add(to); else delete to; } void Trace::deleteTraceFrame() { if (!current_frame) return; std::list :: iterator tfIter; for(tfIter = traceFrames.begin(); tfIter != traceFrames.end(); ++tfIter) { TraceFrame *tf = *tfIter; delete tf; } traceFrames.clear(); current_frame = 0; current_cycle_time = 0; } void Trace::printTraceFrame(FILE *fp) { list :: reverse_iterator tfIter; for(tfIter = traceFrames.rbegin(); tfIter != traceFrames.rend(); ++tfIter) { (*tfIter)->print(fp); } } //======================================================================== // TraceObject // // A TraceObject is a base class for decoded traces. TraceObjects are only // created when the user requests to see the TraceHistory. // TraceObject::TraceObject() { } void TraceObject::print_frame(TraceFrame *tf,FILE *fp) { // by default, a trace object doesn't know how to print a frame // special trace objects derived from this class will be designated // printers. } void TraceObject::getState(TraceFrame *tf) { // Provide an opportunity for derived classes to copy specific state // information to the TraceFrame. } //======================================================================== // InvalidTraceObject // InvalidTraceObject::InvalidTraceObject(int type) : mType(type) { } void InvalidTraceObject::print(FILE *fp) { fprintf(fp, " Invalid Trace entry: 0x%x\n",mType); } //======================================================================== // ModuleTraceObject void ModuleTraceObject::print(FILE *fp) { fprintf(fp, " Module Trace: "); if (pModule) fprintf(fp, "%s ", pModule->name().c_str()); if (pModuleTraceType && pModuleTraceType->cpDescription()) fprintf(fp, "%s ", pModuleTraceType->cpDescription()); fprintf (fp, "0x%x\n", mTracedData & 0xffffff); } //======================================================================== // RegisterTraceObject // RegisterWriteTraceObject::RegisterWriteTraceObject(Processor *_cpu, Register *_reg, RegisterValue trv) : ProcessorTraceObject(_cpu), reg(_reg), from(trv) { if(reg) { to = reg->get_trace_state(); reg->put_trace_state(from); } } void RegisterWriteTraceObject::getState(TraceFrame *tf) { } void RegisterWriteTraceObject::print(FILE *fp) { char sFrom[16]; char sTo[16]; if(reg) fprintf(fp, " Wrote: 0x%s to %s(0x%04X) was 0x%s\n", to.toString(sTo,sizeof(sTo)), reg->name().c_str(), reg->address, from.toString(sFrom,sizeof(sFrom))); } RegisterReadTraceObject::RegisterReadTraceObject(Processor *_cpu, Register *_reg, RegisterValue trv) : RegisterWriteTraceObject(_cpu, _reg, trv) { if(reg) { reg->put_trace_state(from); } } void RegisterReadTraceObject::print(FILE *fp) { char sFrom[16]; if(reg) fprintf(fp, " Read: 0x%s from %s(0x%04X)\n", from.toString(sFrom,sizeof(sFrom)), reg->name().c_str(), reg->address); } void RegisterReadTraceObject::getState(TraceFrame *tf) { } //======================================================================== PCTraceObject::PCTraceObject(Processor *_cpu, unsigned int _address) : ProcessorTraceObject(_cpu), address(_address) { } void PCTraceObject::print(FILE *fp) { char a_string[200]; unsigned addr = cpu->map_pm_index2address(address &0xffff); fprintf(fp,"0x%04X 0x%04X %s\n", addr, (cpu->pma->getFromAddress(addr))->get_opcode(), (cpu->pma->getFromAddress(addr))->name(a_string,sizeof(a_string))); instruction * pInstr = cpu->pma->getFromAddress(addr); int srcLine = pInstr->get_src_line(); if (srcLine >=0) fprintf(fp,"%d: %s", srcLine, cpu->files.ReadLine(pInstr->get_file_id(), pInstr->get_src_line(), a_string,sizeof(a_string))); } void PCTraceObject::print_frame(TraceFrame *tf,FILE *fp) { if(!tf) return; list :: reverse_iterator toIter; fprintf(fp,"0x%016" PRINTF_GINT64_MODIFIER "X %s ", tf->cycle_time,cpu->name().c_str()); print(fp); for(toIter = tf->traceObjects.rbegin(); toIter != tf->traceObjects.rend(); ++toIter) if(*toIter != this) (*toIter)->print(fp); } //======================================================================== // Trace Type for Resets //------------------------------------------------------------------------ const char * resetName(RESET_TYPE r) { switch (r) { case POR_RESET: return "POR_RESET"; case WDT_RESET: return "WDT_RESET"; case IO_RESET: return "IO_RESET"; case MCLR_RESET: return "MCLR_RESET"; case SOFT_RESET: return "SOFT_RESET"; case BOD_RESET: return "BOD_RESET"; case SIM_RESET: return "SIM_RESET"; case EXIT_RESET: return "EXIT_RESET"; case STKUNF_RESET: return "STKUNF_RESET"; case STKOVF_RESET: return "STKOVF_RESET"; case OTHER_RESET: return "OTHER_RESET"; } return "unknown reset"; } //------------------------------------------------------------ ResetTraceObject::ResetTraceObject(Processor *_cpu, RESET_TYPE r) : ProcessorTraceObject(_cpu), m_reset(r) { } void ResetTraceObject::print(FILE *fp) { fprintf(fp, " Reset: %s\n", resetName(m_reset)); } //======================================================================== TraceType::TraceType(unsigned int nTraceEntries, const char *desc) : mType(0), mSize(nTraceEntries), mpDescription(desc) { } void TraceType::showInfo() { cout << cpDescription() << endl; cout << " Type: 0x" << hex << mType << endl << " Size: " << mSize << endl; } const char *TraceType::cpDescription() { return mpDescription ? mpDescription : "No Description"; } //---------------------------------------- // // isValid // // If the trace record starting at the trace buffer index 'tbi' is of the // same type as this trace object, then return true. // bool TraceType::isValid(Trace *pTrace, unsigned int tbi) { if (!pTrace) return false; unsigned int i; // The upper 8-bits of the 'type' specify the trace type for this object. // This is assigned whenever Trace::allocateTraceType() is called. Multi- // sized trace records occupy consecutive types. for(i=0; itype(tbi + i) != (type() + (i<<24))) if(!isValid(pTrace->get(tbi+i))) return false; } return true; } int TraceType::dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize) { if (!pTrace || !buf) return 0; int total_chars=0; int iUsed = entriesUsed(pTrace,tbi); for(int i = 0; i < iUsed; i++) { int n = snprintf(buf,bufsize," %08X:", pTrace->get(tbi+i)); if(n < 0) break; total_chars += n; buf += n; bufsize -= n; } return total_chars; } //============================================================ // // entriesUsed // // given a trace buffer and an index into it, return the number // of trace buffer entries at that point that match the type of // this trace. int TraceType::entriesUsed(Trace *pTrace,unsigned int tbi) { int iUsed=0; if (pTrace) while (pTrace->type(tbi+iUsed) == (mType + (iUsed<<24))) iUsed++; return iUsed; } //======================================================================== ModuleTraceType::ModuleTraceType(Module *_pModule, unsigned int nTraceEntries, const char *desc) : TraceType(nTraceEntries,desc), pModule(_pModule) { } TraceObject *ModuleTraceType::decode(unsigned int tbi) { ModuleTraceObject *mto = new ModuleTraceObject(pModule, this, trace.get(tbi)&0xffffff); return mto; } int ModuleTraceType::dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize) { if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int tv = pTrace->get(tbi); int m = snprintf(buf, bufsize, " Module: %s 0x%x", (pModule ? pModule->name().c_str() : "no name"), (tv & 0xffffff)); return m > 0 ? (m+n) : n; } //======================================================================== CycleTraceType::CycleTraceType(unsigned int s) : TraceType(s, "Cycle") { } TraceObject *CycleTraceType::decode(unsigned int tbi) { return 0; } bool CycleTraceType::isFrameBoundary() { return false; } int CycleTraceType::dump_raw(Trace *pTrace,unsigned tbi, char *buf, int bufsize) { int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; int m=0; if (pTrace) { guint64 cycle; if (pTrace->is_cycle_trace(tbi,&cycle) == 2) m = snprintf(buf,bufsize," Cycle 0x%016" PRINTF_GINT64_MODIFIER "X",cycle); } return m > 0 ? (m+n) : n; } int CycleTraceType::entriesUsed(Trace *pTrace,unsigned int tbi) { return pTrace ? pTrace->is_cycle_trace(tbi,0) : 0; } //======================================================================== ProcessorTraceType::ProcessorTraceType(Processor *_cpu, unsigned int nTraceEntries, const char *pDesc) : TraceType(nTraceEntries,pDesc), cpu(_cpu) { } //======================================================================== RegisterWriteTraceType::RegisterWriteTraceType(Processor *_cpu, unsigned int s) : ProcessorTraceType(_cpu,s,"Reg Write") { } TraceObject *RegisterWriteTraceType::decode(unsigned int tbi) { unsigned int tv = trace.get(tbi); RegisterValue rv = RegisterValue(tv & 0xff, 0); unsigned int address = (tv >> 8) & 0xfff; RegisterWriteTraceObject *rto = new RegisterWriteTraceObject(cpu, cpu->rma.get_register(address), rv); return rto; } int RegisterWriteTraceType::dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize) { unsigned int val = 0; if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int tv = pTrace->get(tbi); unsigned int address = (tv >> 8) & 0xfff; Register *reg = cpu->rma.get_register(address); if(reg) val = reg->get_value(); int m = snprintf(buf, bufsize, " Reg Write: 0x%0x to %s(0x%04X) was 0x%0X ", val&0xff, (reg ? reg->name().c_str() : ""), address, tv & 0xff); Dprintf(("dump_raw %s %x\n", buf, tv&0xff)); if(m>0) n += m; return n; } //======================================================================== RegisterReadTraceType::RegisterReadTraceType(Processor *_cpu, unsigned int s) : ProcessorTraceType(_cpu,s,"Reg Read") { } TraceObject *RegisterReadTraceType::decode(unsigned int tbi) { unsigned int tv = trace.get(tbi); RegisterValue rv = RegisterValue(tv & 0xff, 0); unsigned int address = (tv >> 8) & 0xfff; RegisterReadTraceObject *rto = new RegisterReadTraceObject(cpu, cpu->rma.get_register(address), rv); return rto; } int RegisterReadTraceType::dump_raw(Trace *pTrace, unsigned int tbi, char *buf, int bufsize) { if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int tv = pTrace->get(tbi); unsigned int address = (tv >> 8) & 0xfff; Register *reg = cpu->rma.get_register(address); int m = snprintf(buf, bufsize, " Reg Read: %s(0x%04X) was 0x%0X", (reg ? reg->name().c_str() : ""), address, tv & 0xff); if(m>0) n += m; return n; } //======================================================================== PCTraceType::PCTraceType(Processor *_cpu, unsigned int s) : ProcessorTraceType(_cpu,s,"PC") { } TraceObject *PCTraceType::decode(unsigned int tbi) { unsigned int tv = trace.get(tbi); trace.addFrame(new TraceFrame( )); PCTraceObject *pcto = new PCTraceObject(cpu, tv); if((tv & (3<<22)) == (1<<22)) trace.current_cycle_time -= 2; else trace.current_cycle_time -= 1; trace.current_frame->cycle_time = trace.current_cycle_time; return pcto; } int PCTraceType::dump_raw(Trace *pTrace, unsigned int tbi, char *buf, int bufsize) { if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace,tbi,buf,bufsize); buf += n; bufsize -= n; int m = snprintf(buf, bufsize,"FRAME ============== PC: %04X", cpu->map_pm_index2address(pTrace->get(tbi) & 0xffff)); if(m>0) n += m; return n; } //------------------------------------------------------------ ResetTraceType::ResetTraceType(Processor *_cpu) : ProcessorTraceType(_cpu,1,"Reset") { m_uiTT = trace.allocateTraceType(this); } TraceObject *ResetTraceType::decode(unsigned int tbi) { unsigned int tv = trace.get(tbi); return new ResetTraceObject(cpu, (RESET_TYPE) (tv&0xff)); } void ResetTraceType::record(RESET_TYPE r) { trace.raw(m_uiTT | r); } int ResetTraceType::dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize) { if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; RESET_TYPE r = (RESET_TYPE) (pTrace->get(tbi) & 0xff); int m = snprintf(buf, bufsize, " %s Reset: %s", (cpu ? cpu->name().c_str() : ""), resetName(r)); return m > 0 ? (m+n) : n; } //======================================================================== #define TRACE_ALL (0xffffffff) // // The trace_map is an STL map object that associates dynamically // created trace types with a unique number. The simulation engine // uses the number as a 'command' for tracing information of a // specific type. This number along with information specific to // to the trace type is written into the trace buffer. When the // simulation is halted and the trace buffer is parsed, the // trace type can be extracted. This can then be used as an input // to the trace_map to access an object that can further process // the traced information. // // Here's an example: // // The pic_processor class during construction will request a trace // type for tracing 8-bit register writes. // map trace_map; CycleTraceType *pCycleTrace=0; Trace::Trace() : cpu(0), current_frame(0), lastTraceType(LAST_TRACE_TYPE), lastSubTraceType(1<<16) { for(trace_index = 0; trace_index < TRACE_BUFFER_SIZE; trace_index++) trace_buffer[trace_index] = NOTHING; trace_index = 0; string_cycle = 0; traceFrames.clear(); xref = new XrefObject(&trace_value); } Trace::~Trace() { if(xref) delete xref; xref = 0; } //-------------------------------------------------------------- // void Trace::showInfo() { map::iterator tti; for (unsigned int index=0; index<0x3f000000; index+=0x1000000) { tti = trace_map.find(index); if(tti != trace_map.end()) { TraceType *tt = (*tti).second; tt->showInfo(); } } } //-------------------------------------------------------------- // unsigned int Trace::type(unsigned int index) { unsigned int traceType = operator[](index) & TYPE_MASK; unsigned int cycleType = traceType & (CYCLE_COUNTER_LO | CYCLE_COUNTER_MI); return cycleType ? cycleType : traceType; } //-------------------------------------------------------------- // is_cycle_trace(unsigned int index) // // Given an index into the trace buffer, this function determines // if the trace is a cycle counter trace. // // INPUT: index - index into the trace buffer // *cvt_cycle - a pointer to where the cycle will be decoded // if the trace entry is a cycle trace. // RETURN: 0 - trace is not a cycle counter // 1 - trace is the middle or high integer of a cycle trace // 2 - trace is the low integer of a cycle trace int Trace::is_cycle_trace(unsigned int index, guint64 *cvt_cycle) { if(!(get(index) & (CYCLE_COUNTER_LO | CYCLE_COUNTER_MI))) return 0; // Cycle counter // A cycle counter occupies three consecutive trace buffer entries. // We have to determine if the current entry (pointed to by index) is // the high or low integer of the cycle counter. // // The upper two bits of the trace are used to decode the two 32-bit // integers that comprise the cycle counter. The encoding algorithm is // optimized for speed: // CYCLE_COUNTER_LO is defined as 2<<30 // CYCLE_COUNTER_MI is defined as 1<<30 // CYCLE_COUNTER_HI is defined as 3<<30 // // trace[i ] = low 24 bits of cycle counter | CYCLE_COUNTER_LO // trace[i+1] = middle 24 bits of " " | CYCLE_COUNTER_MI // trace[i+2] = upper 16 bits of " " | CYCLE_COUNTER_HI // // The low 24-bits are always saved in the trace buffer with the msb (CYCLE_COUNTER_LO) // set. // Looking at the upper two bits of trace buffer, we can make these // observations: // // 00 - not a cycle counter trace // 10 - current index points at the low int of a cycle counter // 01 - current index points at the middle int of a cycle counter // 11 - current index points at the high int of a cycle counter int j = index; // Assume that the index is pointing to the low int. int k = (j + 1) & TRACE_BUFFER_MASK; // and that the next entry is the middle int. int l = (j + 2) & TRACE_BUFFER_MASK; // and that the next entry is the high int. if( (get(j) & CYCLE_COUNTER_LO) && (get(k) & CYCLE_COUNTER_MI) && (get(l) & CYCLE_COUNTER_HI) ) { // extract the ~64bit cycle counter from the trace buffer. if(cvt_cycle) { *cvt_cycle = get(l)&0xffff; *cvt_cycle = (*cvt_cycle << 16) | (get(k) & 0xffffff); *cvt_cycle = (*cvt_cycle << 24) | (get(j) & 0xffffff); } return 2; } Dprintf(("trace index %d does not point to lower part (0x%x)\n", j, get(j))); return 1; } //------------------------------------------------------------------------ // // dump1 - decode a single trace buffer item. // // // RETURNS 2 if the trace item takes two trace entries, otherwise returns 1. int Trace::dump1(unsigned index, char *buffer, int bufsize) { guint64 cycle; int return_value = is_cycle_trace(index,&cycle); if(bufsize) buffer[0] = 0; // 0 terminate just in case no string is created if(return_value == 2) return(return_value); return_value = 1; switch (type(index)) { case NOTHING: snprintf(buffer, bufsize," empty trace cycle"); break; /* case WRITE_TRIS: snprintf(buffer, bufsize," wrote: 0x%02x to TRIS", get(index)&0xff); break; case BREAKPOINT: snprintf(buffer, bufsize,"BREAK: "); bp.dump_traced(get(index) & 0xffffff); break; case _RESET: switch( (RESET_TYPE) (get(index)&0xff)) { case POR_RESET: snprintf(buffer, bufsize," POR"); break; case WDT_RESET: snprintf(buffer, bufsize," WDT reset"); break; case SOFT_RESET: snprintf(buffer, bufsize,"SOFT reset"); break; default: snprintf(buffer, bufsize,"unknown reset"); } break; case OPCODE_WRITE: if(type(index-1) == OPCODE_WRITE) snprintf(buffer, bufsize," wrote opcode: 0x%04x to pgm memory: 0x%05x", get(index)&0xffff, get(index - 1) & 0xffffff); break; */ default: if ((type(index) != (unsigned) CYCLE_COUNTER_HI) && (type(index) != CYCLE_COUNTER_MI)) { map::iterator tti = trace_map.find(type(index)); if(tti != trace_map.end()) { TraceType *tt = (*tti).second; if(tt) { tt->dump_raw(this,index,buffer,bufsize); return_value = tt->entriesUsed(this, index); } break; } if(cpu) return_value = cpu->trace_dump1(get(index),buffer,bufsize); } } return return_value; } //------------------------------------------------------------------ void Trace::enableLogging(const char *fname) { if(fname) logger.enable(fname); } void Trace::disableLogging() { logger.disable(); } //------------------------------------------------------------------ // int Trace::dump(int n, FILE *out_stream) // int Trace::dump(int n, FILE *out_stream) { if(!cpu) return 0; if(n<0) n = TRACE_BUFFER_SIZE-1; if(!n) n = 5; if(!out_stream) return 0; if (!pCycleTrace) { // ugh // the trace_map needs to be a member of Trace, other wise // there's a global constructor initialization race condition. pCycleTrace = new CycleTraceType(2); trace_map[CYCLE_COUNTER_LO] = pCycleTrace; trace_map[CYCLE_COUNTER_MI] = pCycleTrace; trace_map[CYCLE_COUNTER_HI] = pCycleTrace; } unsigned int frames = n+1; unsigned int frame_start = tbi(trace_index-3); guint64 cycle=0; if(trace.is_cycle_trace(frame_start,&cycle) != 2) return 0; unsigned int frame_end = trace_index; unsigned int k = frame_start; // Save the state of the CPU here. cpu->save_state(); // // Decode the trace buffer // // Starting at the end of the trace buffer, step backwards // and count 'n' trace frames. A trace frame describes a // boundary. All of the traced information between frames // describe what happened at the boundary. For example, // when a movf temp,W executes, the Program counter creates // the frame boundary and the write to temp and read from W // are stored in it. The frame boundary is recorded at the // end of the frame. current_frame = 0; while(traceFrames.size()::iterator tti = trace_map.find(type(k)); if(tti != trace_map.end()) { // The trace type was found in the trace map // Now decode it. Note that this is where things // like trace frames are created (e.g. for PCTraceType // decode() creates a new trace frame). // If we're on the last frame, and this trace type is a // new frame, then we're done. TraceType *tt = (*tti).second; if(tt) { if (tt->isFrameBoundary() && traceFrames.size()==frames-1) break; // We're done! TraceObject *pTO = tt->decode(k); if (pTO) { addToCurrentFrame(pTO); } } if(is_cycle_trace(k,&cycle) == 2) current_cycle_time = cycle; } else if (get(k) != NOTHING) { cout << " could not decode trace type: 0x" << hex << get(k) << endl; addToCurrentFrame(new InvalidTraceObject(get(k))); } k = tbi(k-1); } printTraceFrame(out_stream); deleteTraceFrame(); fflush(out_stream); return n; } //------------------------------------------------------------------------ // allocateTraceType - allocate one or more trace commands // // unsigned int Trace::allocateTraceType(TraceType *tt) { if(tt) { unsigned int i; unsigned int *ltt = &lastTraceType; unsigned int n = 1<<24; if(tt->bitsTraced() < 24) { if(lastSubTraceType == 0) { lastSubTraceType = lastTraceType; lastTraceType += n; } ltt = &lastSubTraceType; n = 1<<16; } tt->setType(*ltt);; for(i=0; isize(); i++) { trace_map[*ltt] = tt; *ltt += n; } return tt->type(); } return 0; } //--------------------------------------------------------- // dump_raw // mostly for debugging, void Trace::dump_raw(int n) { if(!n) return; FILE *out_stream = stdout; const int BUFFER_SIZE = 256; char buffer[BUFFER_SIZE]; unsigned int i = (trace_index - n) & TRACE_BUFFER_MASK; trace_flag = TRACE_ALL; do { fprintf(out_stream,"%04X:",i); map::iterator tti = trace_map.find(type(i)); unsigned int tSize = 1; TraceType *tt = tti != trace_map.end() ? (*tti).second : 0; buffer[0]=0; tSize = 0; if(tt) { tSize = tt->entriesUsed(this,i); /* fprintf(out_stream, "%02X:",tSize); for (unsigned int ii=0; iidump_raw(this,i,buffer,sizeof(buffer)); } if(!tSize) fprintf(out_stream, "%08X: ??",get(i)); if(buffer[0]) fprintf(out_stream,"%s",buffer); tSize = tSize ? tSize : 1; i = (i + tSize) & TRACE_BUFFER_MASK; putc('\n',out_stream); } while((i!=trace_index) && (i!=((trace_index+1)&TRACE_BUFFER_MASK))); putc('\n',out_stream); putc('\n',out_stream); } // // dump_last_instruction() void Trace::dump_last_instruction() { if (trace_log.log_file) dump(1, trace_log.log_file); dump(1,stdout); } /***************************************************************** * * Logging */ TraceLog::TraceLog() { logging = 0; log_filename = 0; cpu = 0; log_file = 0; lxtp=0; last_trace_index = 0; items_logged = 0; buffer.trace_flag = TRACE_ALL; } TraceLog::~TraceLog() { disable_logging(); close_logfile(); } void TraceLog::callback() { /* int n = 0; get_trace().cycle_counter(get_cycles().get()); if((log_file||lxtp) && logging) { if(last_trace_index < get_trace().trace_index) { for (unsigned int c=last_trace_index; cregisters[address]->name().c_str(); items_logged++; lt_set_time(lxtp, (int)(get_cycles().get()*4.0e8*cpu->get_OSCperiod())); symp=lt_symbol_find(lxtp, name); if(symp==0) { symp=lt_symbol_add(lxtp, name, // name 0, // rows 7, // msb 0, // lsb LT_SYM_F_BITS //flags ); assert(symp!=0); } lt_emit_value_int(lxtp, symp, 0, value); } void TraceLog::register_read(Register *pReg, guint64 cc) { if (!pReg) return; switch(file_format) { case TRACE_FILE_FORMAT_ASCII: Dprintf(("cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%02x) value 0x%02x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); #ifdef NEWTRACE bp.set_logging(); return; #else buffer.cycle_counter(cc); buffer.raw(pReg->read_trace.get() | pReg->get_value()); if(buffer.near_full()) write_logfile(); #endif //NEWTRACE break; case TRACE_FILE_FORMAT_LXT: Dprintf(("LXT cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%02x) value 0x%02x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); lxt_trace(pReg->getAddress(), pReg->get_value(), cc); break; } } void TraceLog::register_write(Register *pReg, guint64 cc) { if (!pReg) return; switch(file_format) { case TRACE_FILE_FORMAT_ASCII: Dprintf(("cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%02x) value 0x%02x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); #ifdef NEWTRACE bp.set_logging(); return; #else buffer.cycle_counter(cc); buffer.raw(pReg->write_trace.get() | pReg->get_value()); if(buffer.near_full()) write_logfile(); #endif //NEWTRACE break; case TRACE_FILE_FORMAT_LXT: Dprintf(("LXT cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%02x) value 0x%02x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); lxt_trace(pReg->getAddress(), pReg->get_value(), cc); break; } } void TraceLog::register_read_value(Register *pReg, guint64 cc) { if (!pReg) return; switch(file_format) { case TRACE_FILE_FORMAT_ASCII: Dprintf(("cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%02x) value 0x%02x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); #ifdef NEWTRACE bp.set_logging(); return; #else buffer.cycle_counter(cc); buffer.raw(pReg->read_trace.get() | pReg->get_value()); if(buffer.near_full()) write_logfile(); #endif //NEWTRACE break; case TRACE_FILE_FORMAT_LXT: Dprintf(("LXT cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%02x) value 0x%02x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); lxt_trace(pReg->getAddress(), pReg->get_value(), cc); break; } } void TraceLog::register_write_value(Register *pReg, guint64 cc) { if (!pReg) return; switch(file_format) { case TRACE_FILE_FORMAT_ASCII: Dprintf(("cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%x) value %x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); #ifdef NEWTRACE bp.set_logging(); return; #else buffer.cycle_counter(cc); buffer.raw(pReg->write_trace.get() | pReg->get_value()); if(buffer.near_full()) write_logfile(); #endif //NEWTRACE break; case TRACE_FILE_FORMAT_LXT: Dprintf(("LXT cycle=%" PRINTF_GINT64_MODIFIER "x %s(0x%x) value %x\n", cc, pReg->name().c_str(), pReg->getAddress(), pReg->get_value())); lxt_trace(pReg->getAddress(), pReg->get_value(), cc); break; } } /***************************************************************** * * Profiling */ ProfileKeeper::ProfileKeeper() { enabled = 0; cpu = 0; last_trace_index = 0; } ProfileKeeper::~ProfileKeeper() { disable_profiling(); } void ProfileKeeper::catchup() { //Register *r; if(!enabled) return; for(unsigned int i=last_trace_index; i!=trace.trace_index; i = (i+1)& TRACE_BUFFER_MASK) { /* switch (trace.trace_buffer[i] & 0xff000000) { case Trace::INSTRUCTION: instruction_address=trace_pc_value; cpu->program_memory[instruction_address]->cycle_count++; trace_pc_value++; break; case Trace::PROGRAM_COUNTER: case Trace::PC_SKIP: trace_pc_value=trace.trace_buffer[i]&0xffff; break; case Trace::CYCLE_INCREMENT: cpu->program_memory[instruction_address]->cycle_count++; break; case Trace::REGISTER_READ: r = cpu->registers[(trace.trace_buffer[i]>>8) & 0xfff]; if(r->isa() == Register::FILE_REGISTER) { r->read_access_count++; } break; case Trace::REGISTER_WRITE: r = cpu->registers[(trace.trace_buffer[i]>>8) & 0xfff]; if(r->isa() == Register::FILE_REGISTER) { r->write_access_count++; } break; break; } */ } last_trace_index = trace.trace_index; } void ProfileKeeper::callback() { if(enabled) { catchup(); get_cycles().set_break(get_cycles().get() + 1000,this); } } void ProfileKeeper::enable_profiling() { if(enabled) return; if(!cpu) { if(get_active_cpu()) cpu = get_active_cpu(); else cout << "Warning: Profiling can't be enabled until a cpu has been selected."; } last_trace_index = trace.trace_index; get_cycles().set_break(get_cycles().get() + 1000,this); enabled = 1; } void ProfileKeeper::disable_profiling() { if(!enabled) return; enabled = 0; } void ProfileKeeper::switch_cpus(Processor *pcpu) { cpu = pcpu; } //***************************************************************** // *** KNOWN CHANGE *** // Support functions that will get replaced by the CORBA interface. // //-------------------------------------------- void trace_dump_all() { trace.dump(0, stdout); } //-------------------------------------------- void trace_dump_n(int numberof) { trace.dump(numberof,stdout); } //-------------------------------------------- void trace_dump_raw(int numberof) { trace.dump_raw(numberof); } //-------------------------------------------- void trace_enable_logging(char *file, int format) { if (file) trace_log.enable_logging(file, format); else trace_log.disable_logging(); } void trace_watch_register(int reg) { //trace_log.watch_reg = reg; } //-------------------------------------------------- // BoolEventBuffer::event(bool state) // // Record a 0/1 event (e.g. the state of an I/O line). // returns false if this event has filled the buffer // or if the buffer is full. Note, an event will get lost // if the callee attempts to save it in a full buffer. inline bool BoolEventBuffer::event(bool state) { // If the new event is different than the most recently logged one // then we need to log this event. (Note that the event is implicitly // logged in the "index". I.e. 1 events are at odd indices. if(state ^ (index & 1) ^ !bInitialState) { if(index < max_events) { buffer[index++] = get_cycles().get() - start_time; return true; } return false; } return true; } //-------------------------------------------------- // // BoolEventBuffer::get_index // // given an event time, get_index will perform a binary // search for it in the event buffer. // unsigned int BoolEventBuffer::get_index(guint64 event_time) { guint32 start_index, search_index, bstep; guint64 time_offset; start_index = 0; bstep = (max_events+1) >> 1; search_index = start_index + bstep; bstep >>= 1; time_offset = event_time - start_time; // Binary search for the event time: do { if(time_offset == buffer[search_index]) return search_index; if(time_offset < buffer[search_index]) search_index = search_index - bstep; else search_index = search_index + bstep; //cout << hex << "search index "<< search_index << " buffer[search_index] " << buffer[search_index] << '\n'; bstep >>= 1; } while(bstep); if(time_offset >= buffer[search_index]) return search_index; else return (--search_index); } //-------------------------------------------------- // // BoolEventBuffer::activate // // void BoolEventBuffer::activate(bool _initial_state) { // If the buffer is activated already or the buffer is full, // then we can't activate it. if(isActive() || isFull()) return; // Save the time for this initial event start_time = get_cycles().get(); bInitialState = _initial_state; index = 0; // next state gets stored at the first position in the buffer. bActive = true; future_cycle = start_time + (1<<31); get_cycles().set_break(future_cycle, this); } //-------------------------------------------------- void BoolEventBuffer::deactivate() { bActive = false; if(future_cycle) get_cycles().clear_break(this); future_cycle = 0; } //-------------------------------------------------- void BoolEventBuffer::callback() { future_cycle = 0; if(isActive()) deactivate(); } void BoolEventBuffer::callback_print() { cout << "BoolEventBuffer\n"; } //-------------------------------------------------- // BoolEventBuffer -- constructor // BoolEventBuffer::BoolEventBuffer(bool _initial_state, guint32 _max_events) { max_events = _max_events; // Make sure that max_events is an even power of 2 if(max_events & (max_events - 1)) { max_events <<= 1; while(1) { if(max_events && (max_events & (max_events-1))) max_events &= max_events - 1; else break; } } else if(!max_events) max_events = 4096; max_events--; // make the max_events a mask buffer = new guint64[max_events]; activate(_initial_state); } BoolEventBuffer::~BoolEventBuffer() { delete [] buffer; } gpsim-0.30.0/src/stimuli.h0000664000076400007640000004425613063451152012305 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __STIMULI_H__ #define __STIMULI_H__ #include #include using namespace std; #include #include "gpsim_classes.h" #include "breakpoints.h" /* forward references: */ class Stimulus_Node; class stimulus; class IOPIN; class symbol; /* typedefs */ typedef list SymbolList_t; typedef list StringList_t; typedef list StimulusList_t; typedef list gpsimObjectList_t; /* Support functions */ extern void dump_stimulus_list(void); /**************************************************************************** * * Include file support stimuli. * * stimulus TriggerObject * | \ / * | -----------------+---- * | | * |- IOPIN |- source_stimulus * | | * |- IO_input |- square_wave * | |- triangle_wave * |- IO_open_collector |- asynchronous_stimulus * |- IO_bi_directional |- dc_supply * | |- open_collector * |- IO_bi_directional_pu * * A stimulus is used to stimulate stimuli. What's that mean? Well, * in gpsim, the pic I/O pins are derived from the stimulus base class * (as can be seen from above). The I/O pins are what interface to the * 'external' world. In some cases, I/O pins are inputs and others they're * outputs. The stimulus base class defines the basic functionality of * a stimulus and how this interface to the outside world is to occur. * */ #define MAX_DRIVE 0x100000 #define MAX_ANALOG_DRIVE 0x1000 class Stimulus_Node : public gpsimObject, public TriggerObject { public: bool warned; // keeps track of node warnings (e.g. floating node, contention) double voltage; // The most recent target voltage of this node double Cth; // The most recent capacitance (to ground) measured on this node. double Zth; // The most recent thevenin resistance computed on this node. double current_time_constant; // The most recent time constant for the attached stimuli. double delta_voltage; // Amplitude of initial change double minThreshold; // Use DC value when voltage this close guint64 cap_start_cycle; // cycles when RC value last calculated guint64 future_cycle; // cycles when next callback expected double initial_voltage; // node voltage at the instant of change double DCVoltage; // Target voltage when settling bool bSettling; // true when the voltage is settling stimulus *stimuli; // Pointer to the first stimulus connected to this node. int nStimuli; // number of stimuli attached to this node. explicit Stimulus_Node(const char *n = 0); virtual ~Stimulus_Node(); void set_nodeVoltage(double v); double get_nodeVoltage(); double get_nodeZth() { return Zth;} double get_nodeCth() { return Cth; } void update(); void attach_stimulus(stimulus *); void detach_stimulus(stimulus *); // When a node is given a name, it is also added to the symbol // table. If bClearableSymbol is true, then the symbol can be // automatically removed when the symbol table is cleared. virtual void new_name(const char *, bool bClearableSymbol=false); virtual void new_name(string &, bool bClearableSymbol=false); // When the node is settling (due to RC charging/discharging) // it's voltage is periodically updated by invoking callback() virtual void callback(void); virtual void callback_print(void); // factory function static Stimulus_Node * construct(const char * psName); virtual string toString(); protected: void update(guint64 current_time); // deprecated void refresh(); void updateStimuli(); guint64 calc_settlingTimeStep(); guint64 settlingTimeStep; }; //======================================================================== // // stimulus // // The stimulus class is the base class for all of the analog interfaces // between modules. A stimulus is a 1-node device that has a characteristic // impedance and voltage. If you're familiar with circuit analysis, these // are the Thevenin voltage and impedance. // // gpsim is not a spice simulator. So complex devices like transistors or // opamps are not modeled. In fact, even simple devices like capacitors and // inductors are not modeled. // class stimulus : public Value { public: Stimulus_Node *snode; // Node to which this stimulus is attached stimulus *next; // next stimulus that's on the snode stimulus(const char *n=0, double _Vth=5.0, double _Zth=1e3 ); virtual ~stimulus(); // When a stimulus is given a name, it is also added to the symbol // table. If bClearableSymbol is true, then the symbol can be // automatically removed when the symbol table is cleared. virtual void new_name(const char *, bool bClearableSymbol=true); virtual void new_name(string &, bool bClearableSymbol=true); // Functions for accessing/manipulating the thevenin voltage and impedance. virtual void getThevenin(double &v, double &z, double &c); virtual double get_Vth() { return Vth; } virtual void set_Vth(double v) { Vth = v; } virtual double get_Zth() { return Zth; } virtual void set_Zth(double z) { Zth = z; } virtual double get_Cth() { return Cth; } virtual void set_Cth(double c) { Cth = c; } virtual double get_nodeVoltage() { return nodeVoltage; } virtual void set_nodeVoltage(double v) { nodeVoltage = v; } virtual bool getDriving() { return bDriving; } virtual void setDriving(bool bNewDriving) { bDriving=bNewDriving; } // Functions for accessing/manipulating the stimulus state // Control the driving state, i.e. the state this stimulus wishes to drive virtual bool getDrivingState(void) {return bDrivingState;}; virtual void setDrivingState(bool new_dstate) { bDrivingState = new_dstate;}; virtual void setDrivingState(char new3State) { bDrivingState = new3State=='1';}; // Control the driven state, i.e. the state some external node wishes to // drive this stimulus. virtual bool getDrivenState(void) { return getDrivingState(); } virtual void setDrivenState(bool new_dstate) { setDrivingState(new_dstate);} // Control the 'state' of the node. virtual bool getState() { return getDrivingState(); } virtual void putState(bool new_dstate) { setDrivingState(new_dstate);} // getBitChar - this complements the Register class' getBitStr function virtual char getBitChar() { return getState() ? '1':'0'; } virtual void attach(Stimulus_Node *s); virtual void detach(Stimulus_Node *s); // If a stimulus changes its state, it can signal this change to // any other stimuli that are connected to it. virtual void updateNode(void) { if(snode) snode->update();} // Display info about the stimulus. virtual void show(); virtual string toString(); protected: bool bDrivingState; // 0/1 digitization of the analog state we're driving bool bDriving; // True if this stimulus is a driver double Vth; // Open-circuit or Thevenin voltage double Zth; // Input or Thevenin resistance double Cth; // Stimulus capacitance. double nodeVoltage; // The voltage driven on to this stimulus by the snode // These are only here because they're pure virtual functions in the parent class. virtual unsigned int get_value(void) { return 0;} virtual void put_value(unsigned int new_value) {} // factory function static stimulus * construct(const char * psName); }; class source_stimulus : public stimulus, public TriggerObject { public: enum SOURCE_TYPE { DC, SQW, ASY, TRI, RESISTOR, OPEN_COLLECTOR, EVENT }; source_stimulus() { period = 0; duty = 0; phase = 0; initial_state = 0; start_cycle = 0; time = 0; digital = true; }; virtual void callback(void); virtual void callback_print(void); virtual void put_period(Value *); virtual void put_duty(Value *); virtual void put_phase(Value *); virtual void put_initial_state(Value *); virtual void put_start_cycle(Value *); virtual void set_digital(void) { digital = true;} virtual void set_analog(void) { digital = false;} virtual void start(void) { }; virtual void show(); protected: bool digital; guint64 start_cycle, time, period, duty, phase; double initial_state; }; ///------------------------------------------------------------ /// /// SignalSink - A pure virtual class that allows signals driven by external /// stimuli to be routed to one or more objects monitoring them (e.g. one /// sink may be a bit in a port register while another may be a peripheral) class SignalSink { public: virtual ~SignalSink() { } virtual void setSinkState(char)=0; virtual void release()=0; }; ///------------------------------------------------------------- /// /// AnalogSink - An analog sink is similar to a digital sink. The primary /// difference is that an analog sink redirects an analog signal to one /// or more objects. A signal sink only redirects digital signals. class AnalogSink { public: virtual ~AnalogSink() { } virtual void setSinkState(double)=0; virtual void release()=0; }; ///------------------------------------------------------------ /// The PinMonitor class allows other objects to be notified whenever /// a Pin changes states. /// (Note: In older versions of gpsim, iopins notified the Port registers /// in which they were contained by direcly calling the register setbit() /// method. This is deprecated - and eventually will cause compile time errors.) class PinMonitor { public: PinMonitor(); virtual ~PinMonitor(); void addSink(SignalSink *); void removeSink(SignalSink *); void addSink(AnalogSink *); void removeSink(AnalogSink *); virtual void setDrivenState(char)=0; virtual void setDrivingState(char)=0; virtual void set_nodeVoltage(double)=0; virtual void putState(char)=0; virtual void setDirection()=0; virtual void updateUI() {} // FIXME - make this pure virtual too. protected: /// The SignalSink list is a list of all sinks that can receive digital data list sinks; /// The AnalogSink list is a list of all sinks that can receive analog data list analogSinks; }; class IOPIN : public stimulus { public: enum IOPIN_TYPE { INPUT_ONLY, // e.g. MCLR BI_DIRECTIONAL, // most iopins BI_DIRECTIONAL_PU, // same as bi_directional, but with pullup resistor. e.g. portb OPEN_COLLECTOR // bit4 in porta on the 18 pin midrange devices. }; enum IOPIN_DIRECTION { DIR_INPUT, DIR_OUTPUT }; IOPIN(const char *n=0, double _Vth=5.0, double _Zth=1e8, double _ZthWeak = 1e6, double _ZthFloating = 1e7 ); ~IOPIN(); virtual void setMonitor(PinMonitor *); virtual PinMonitor *getMonitor() { return m_monitor; } virtual void set_nodeVoltage(double v); virtual bool getDrivingState(void); virtual void setDrivingState(bool new_dstate); virtual void setDrivingState(char); virtual bool getDrivenState(void); virtual void setDrivenState(bool new_dstate); virtual void forceDrivenState(char); virtual char getForcedDrivenState(); virtual bool getState(); virtual void putState(bool new_dstate); virtual void putState(double new_Vth); virtual void set_digital_threshold(double vdd); virtual void get(char *return_str, int len); virtual void set_ZthWeak(double Z) { ZthWeak=Z;} virtual double get_ZthWeak() { return ZthWeak;} virtual void set_ZthFloating(double Z) { ZthFloating=Z;} virtual double get_ZthFloating() { return ZthFloating;} virtual void set_l2h_threshold(double V) {l2h_threshold=V;} virtual double get_l2h_threshold() { return l2h_threshold;} virtual void set_h2l_threshold(double V) {h2l_threshold=V;} virtual double get_h2l_threshold() { return h2l_threshold;} virtual void toggle(void); virtual void attach(Stimulus_Node *s); // These functions don't apply to Inputs, but provide an // interface for the derived classes. virtual void update_direction(unsigned int x, bool refresh){ }; virtual IOPIN_DIRECTION get_direction(void) {return DIR_INPUT; }; virtual void update_pullup(char new_state, bool refresh) {} virtual void set_is_analog(bool flag) {} virtual double get_Vth(); virtual char getBitChar(); virtual void show(); /// Change object name without affecting stimulus virtual void newGUIname(const char *); virtual string &GUIname(void) const; virtual bool is_newGUIname(void) { return gui_name_updated; } virtual void clr_is_newGUIname(void) { gui_name_updated = false; } protected: bool is_analog; // Pin is in analog mode bool gui_name_updated; // True if object name has changed string gui_name; // bool bDrivenState; // binary state we're being driven to char cForcedDrivenState; // forced state when no snode is attached. PinMonitor *m_monitor; // When connected to a node, these are thresholds used to determine whether // we're being driven by a weak driver or not. double ZthWeak; double ZthFloating; // These are the low to high and high to low input thresholds. The // units are volts. double l2h_threshold; double h2l_threshold; double Vdrive_high; double Vdrive_low; }; class IO_bi_directional : public IOPIN { public: IO_bi_directional(const char *n=0, double _Vth=5.0, double _Zth=150, double _ZthWeak = 1e6, double _ZthFloating = 1e7, double _VthIn = 0.3, double _ZthIn = 1e10); virtual double get_Zth(); virtual double get_Vth(); virtual double get_VthIn() { return VthIn;} virtual double get_ZthIn() { return ZthIn;} virtual void set_VthIn(double _VthIn) { VthIn = _VthIn;} virtual void set_ZthIn(double _ZthIn) { ZthIn = _ZthIn;} virtual char getBitChar(); virtual void set_nodeVoltage(double new_nodeVoltage); virtual void putState(bool new_state); virtual void putState(double new_Vth); virtual void update_direction(unsigned int,bool refresh); virtual IOPIN_DIRECTION get_direction(void) {return ((getDriving()) ? DIR_OUTPUT : DIR_INPUT);} protected: /// Impedance of the IOPIN when it's not driving. double ZthIn; /// Voltage of the IOPIN when it's not driving /// (this is the voltage the I/O pin floats to when there's /// nothing connected to it) double VthIn; }; class IO_bi_directional_pu : public IO_bi_directional { public: IO_bi_directional_pu(const char *n=0, double _Vth=5.0, double _Zth=150, double _ZthWeak = 1e6, double _ZthFloating = 1e7, double _VthIn = 0.3, double _ZthIn = 1e8, double _Zpullup = 20e3 ); ~IO_bi_directional_pu(); virtual double get_Vth(); virtual double get_Zth(); virtual void set_Zpullup(double Z) { Zpullup = Z; } virtual double get_Zpullup() { return Zpullup; } virtual void set_Vpullup(double V) { Vpullup = V; } virtual double get_Vpullup() { return Vpullup; } virtual char getBitChar(); virtual void update_pullup(char new3State, bool refresh); virtual void set_is_analog(bool flag); protected: bool bPullUp; // True when pullup is enabled double Zpullup; // resistance of the pullup double Vpullup; // Voltage the pullup resistor is tied to. }; class IO_open_collector : public IO_bi_directional_pu { public: explicit IO_open_collector(const char *n = 0); virtual double get_Vth(); virtual double get_Zth(); virtual char getBitChar(); }; class square_wave : public source_stimulus { public: square_wave(unsigned int _period, unsigned int _duty, unsigned int _phase, const char *n=0); virtual double get_Vth(); }; class triangle_wave : public source_stimulus { public: double m1,b1,m2,b2; triangle_wave(unsigned int _period, unsigned int _duty, unsigned int _phase, const char *n=0); virtual double get_Vth(); }; class StimulusData { public: guint64 time; double value; }; class ValueStimulusData { public: guint64 time; Value *v; }; /// ValueStimulus /// class ValueStimulus : public source_stimulus { protected: ValueStimulusData initial; Value *current; guint64 future_cycle; ValueStimulusData next_sample; list samples; list::iterator sample_iterator; public: virtual void callback(); virtual void put_data(ValueStimulusData &data_point); virtual void put_initial_state(Value *); virtual void get(char *return_str, int len); virtual double get_Vth(); virtual void start(); explicit ValueStimulus(const char *n = 0); virtual ~ValueStimulus(); virtual void show(); protected: ValueStimulusData *getNextSample(); }; class AttributeStimulus : public ValueStimulus { Value *attr; public: explicit AttributeStimulus(const char *n = 0); // virtual ~AttributeStimulus(); virtual void callback(); void setClientAttribute(Value *); virtual void show(); }; /* * An "Event" is a special stimulus that will assert for a single clock * cycle. * * Since Events are derived from the source_stimulus class, they can * be either single shot or repetitive. * */ class Event : public source_stimulus { public: unsigned int current_state; virtual void callback(void); Event(void); }; #endif // __STIMULI_H__ gpsim-0.30.0/src/12bit-hexdecode.cc0000664000076400007640000000714113041763613013620 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // T. Scott Dattalo 12bit core routines /* pic12.c - pic 12bit core routines */ /* version 0.1 */ /* (c) I.King 1994 */ #include #include "../config.h" #include "12bit-processors.h" #include "12bit-instructions.h" instruction * disasm12 (pic_processor *cpu, unsigned int address, unsigned int inst) { unsigned char topnibble; unsigned char midnibble; unsigned char lownibble; unsigned char bbyte; unsigned char bits6and7; topnibble = (inst & 0x0f00) >> 8; midnibble = (inst & 0x00f0) >> 4; lownibble = (inst & 0x000f); bbyte = (inst & 0x00ff); bits6and7 = (unsigned char)((int) (bbyte & 0xc0) >> 6); switch(topnibble) { case 0x00: if (midnibble == 0) switch(lownibble) { case 0x00: return(new NOP(cpu,inst,address)); case 0x02: return(new OPTION(cpu,inst,address)); case 0x03: return(new SLEEP(cpu,inst,address)); case 0x04: return(new CLRWDT(cpu,inst,address)); default: return(new TRIS(cpu,inst,address)); } else switch(bits6and7) { case 0x00: return(new MOVWF(cpu,inst,address)); case 0x01: if(midnibble & 0x02) return(new CLRF(cpu,inst,address)); else return(new CLRW(cpu,inst,address)); case 0x02: return(new SUBWF(cpu,inst,address)); case 0x03: return(new DECF(cpu,inst,address)); } break; case 0x01: switch(bits6and7) { case 0x00: return(new IORWF(cpu,inst,address)); case 0x01: return(new ANDWF(cpu,inst,address)); case 0x02: return(new XORWF(cpu,inst,address)); case 0x03: return(new ADDWF(cpu,inst,address)); } break; case 0x02: switch(bits6and7) { case 0x00: return(new MOVF(cpu,inst,address)); case 0x01: return(new COMF(cpu,inst,address)); case 0x02: return(new INCF(cpu,inst,address)); case 0x03: return(new DECFSZ(cpu,inst,address)); } break; case 0x03: switch(bits6and7) { case 0x00: return(new RRF(cpu,inst,address)); case 0x01: return(new RLF(cpu,inst,address)); case 0x02: return(new SWAPF(cpu,inst,address)); case 0x03: return(new INCFSZ(cpu,inst,address)); } break; case 0x04: return(new BCF(cpu,inst,address)); case 0x05: return(new BSF(cpu,inst,address)); case 0x06: return(new BTFSC(cpu,inst,address)); case 0x07: return(new BTFSS(cpu,inst,address)); case 0x08: return(new RETLW(cpu,inst,address)); case 0x09: return(new CALL(cpu,inst,address)); case 0x0a: case 0x0b: return(new GOTO(cpu,inst,address)); case 0x0c: return(new MOVLW(cpu,inst,address)); case 0x0d: return(new IORLW(cpu,inst,address)); case 0x0e: return(new ANDLW(cpu,inst,address)); case 0x0f: return(new XORLW(cpu,inst,address)); } // shouldn't get here return 0; } /* ... The End ... */ gpsim-0.30.0/src/16bit-instructions.cc0000664000076400007640000015074013045306452014442 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include #include "../config.h" #include "pic-processor.h" #include "14bit-registers.h" //#include "symbol.h" #include "pic-instructions.h" #include "12bit-instructions.h" #include "16bit-instructions.h" #include "16bit-processors.h" #include "16bit-registers.h" //-------------------------------------------------- Branching::Branching(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode,address), destination_index(0), absolute_destination_index(0) { } void Branching::decode(Processor *new_cpu, unsigned int new_opcode) { opcode = new_opcode; cpu = new_cpu; switch(cpu16->base_isa()) { case _PIC18_PROCESSOR_: destination_index = (new_opcode & 0xff)+1; absolute_destination_index = (cpu16->getCurrentDisasmIndex() + destination_index) & 0xfffff; if(new_opcode & 0x80) { absolute_destination_index -= 0x100; destination_index = 0x100 - destination_index; } break; case _PIC17_PROCESSOR_: cout << "Which instructions go here?\n"; break; default: cout << "ERROR: (Branching) the processor is not defined\n"; break; } } char *Branching::name(char *return_str, int len) { snprintf(return_str, len,"%s\t$%c0x%x\t;(0x%x)", gpsimObject::name().c_str(), (opcode & 0x80) ? '-' : '+', (destination_index & 0x7f)<<1, absolute_destination_index<<1); return(return_str); } //-------------------------------------------------- multi_word_instruction::multi_word_instruction(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode,address), word2_opcode(0), PMaddress(0), PMindex(0), initialized(false) { } multi_word_branch::multi_word_branch(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_instruction(new_cpu, new_opcode, address), destination_index(0) { } void multi_word_branch::runtime_initialize() { if(cpu16->program_memory[PMindex+1] != &cpu16->bad_instruction) { word2_opcode = cpu16->program_memory[PMindex+1]->get_opcode(); if((word2_opcode & 0xf000) != 0xf000) { cout << "16bit-instructions.cc multiword instruction error\n"; return; } cpu16->program_memory[PMindex+1]->update_line_number( file_id, src_line, lst_line, 0, 0); // extract the destination address from the two-word opcode destination_index = ((word2_opcode & 0xfff)<<8) | (opcode & 0xff); initialized = true; } } char * multi_word_branch::name(char *return_str,int len) { if(!initialized) runtime_initialize(); snprintf(return_str,len,"%s\t0x%05x", gpsimObject::name().c_str(), destination_index<<1); return(return_str); } //--------------------------------------------------------- ADDULNK::ADDULNK(Processor *new_cpu, unsigned int new_opcode, const char *pName, unsigned int address) : instruction(new_cpu, new_opcode,address) { m_lit = opcode & 0x3f; new_name(pName); } char *ADDULNK::name(char *return_str,int len) { snprintf(return_str,len,"%s\t0x%x", gpsimObject::name().c_str(), m_lit); return(return_str); } void ADDULNK::execute() { if (cpu16->extended_instruction()) { if (opcode & 0x100) cpu16->ind2.put_fsr(cpu16->ind2.get_fsr_value() - m_lit); // SUBULNK else cpu16->ind2.put_fsr(cpu16->ind2.get_fsr_value() + m_lit); // ADDULNK } else { printf("Error %s extended instruction not supported, check XINST\n", (opcode&0x100)?"SUBULNK":"ADDULNK"); bp.halt(); } cpu16->pc->new_address(cpu16->stack->pop()); } //--------------------------------------------------------- ADDFSR16::ADDFSR16(Processor *new_cpu, unsigned int new_opcode, const char *pName, unsigned int address) : instruction(new_cpu, new_opcode,address) { m_fsr = (opcode>>6)&3; m_lit = opcode & 0x3f; switch(m_fsr) { case 0: ia = &cpu16->ind0; break; case 1: ia = &cpu16->ind1; break; case 2: ia = &cpu16->ind2; break; case 3: ia = &cpu16->ind2; } new_name(pName); } char *ADDFSR16::name(char *return_str,int len) { snprintf(return_str,len,"%s\t%u,0x%x", gpsimObject::name().c_str(), m_fsr, m_lit); return(return_str); } void ADDFSR16::execute() { if (cpu16->extended_instruction()) { // Apply pending update. ia->fsr_value += ia->fsr_delta; ia->fsr_delta = 0; if (opcode & 0x100) ia->put_fsr(ia->get_fsr_value() - m_lit); //SUBFSR else ia->put_fsr(ia->get_fsr_value() + m_lit); //ADDFSR } else { printf("Error %s extended instruction not supported, check XINST\n", (opcode&0x100)?"SUBFSR":"ADDFSR"); bp.halt(); } cpu16->pc->increment(); } //-------------------------------------------------- void CALLW16::execute() { if (cpu16->extended_instruction()) { if(cpu16->stack->push(cpu16->pc->get_next())) { cpu16->pcl->put(cpu16->Wget()); cpu16->pc->increment(); } else // stack overflow reset { cpu16->pc->jump(0); } } else { printf("Error %s extended instruction not supported, check XINST\n", "CALLW"); bp.halt(); } } //-------------------------------------------------- PUSHL::PUSHL(Processor *new_cpu, unsigned int new_opcode, unsigned int address) :instruction (new_cpu, new_opcode, address), m_lit(new_opcode & 0xff) { new_name("pushl"); } char *PUSHL::name(char *return_str,int len) { snprintf(return_str,len,"%s\t0x%x", gpsimObject::name().c_str(),m_lit); return(return_str); } void PUSHL::execute() { // cpu16->ind2.put(m_lit); // cpu16->ind2.put_fsr(cpu16->ind2.get_fsr_value() -1); if (cpu16->extended_instruction()) { cpu16->ind2.postdec.put(m_lit); } else { printf("Error %s extended instruction not supported, check XINST\n", "PUSHL"); bp.halt(); } cpu16->pc->increment(); } //-------------------------------------------------- MOVSF::MOVSF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_instruction(new_cpu, new_opcode,address) { opcode = new_opcode; cpu = new_cpu; PMaddress = cpu16->getCurrentDisasmAddress(); PMindex = cpu16->getCurrentDisasmIndex(); initialized = false; destination = 0; source = opcode & 0x7f; if (opcode & 0x80) new_name("movss"); else new_name("movsf"); } void MOVSF::runtime_initialize() { if(cpu_pic->program_memory[PMindex+1]) { word2_opcode = cpu_pic->program_memory[PMindex+1]->get_opcode(); if((word2_opcode & 0xf000) != 0xf000) { cout << "16bit-instructions.cc MOVSF error\n"; return; } cpu_pic->program_memory[PMindex+1]->update_line_number( file_id, src_line, lst_line, 0, 0); destination = word2_opcode & ((opcode & 0x80) ? 0x7f : 0xfff); initialized = true; } } char *MOVSF::name(char *return_str,int len) { if(!initialized) runtime_initialize(); if (opcode & 0x80) snprintf(return_str,len,"%s\t[0x%x],[0x%x]", gpsimObject::name().c_str(), source, destination); else snprintf(return_str,len,"%s\t[0x%x],%s", gpsimObject::name().c_str(), source, cpu_pic->registers[destination]->name().c_str()); return(return_str); } void MOVSF::execute() { if (cpu16->extended_instruction()) { if(!initialized) runtime_initialize(); unsigned int source_addr = cpu16->ind2.plusk_fsr_value(source); unsigned int r = cpu_pic->registers[source_addr]->get(); cpu16->pc->skip(); unsigned int destination_addr = (opcode & 0x80) ? cpu16->ind2.plusk_fsr_value(destination) : destination; cpu_pic->registers[destination_addr]->put(r); } else { printf("Error %s extended instruction not supported, check XINST\n", (opcode & 0x80)?"MOVSS":"MOVSF"); bp.halt(); } //cpu16->pc->increment(); } //-------------------------------------------------- void ADDLW16::execute() { unsigned int old_value,new_value; new_value = (old_value = cpu16->Wget()) + L; cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N(new_value, old_value, L); cpu16->pc->increment(); } //-------------------------------------------------- void ADDWF16::execute() { unsigned int new_value,src_value,w_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (src_value = source->get()) + (w_value = cpu16->Wget()); // Store the result if(destination) { source->put(new_value & 0xff); // Result goes to source cpu16->status->put_Z_C_DC_OV_N(new_value, src_value, w_value); } else { cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N(new_value, w_value, src_value); } cpu16->pc->increment(); } //-------------------------------------------------- void ADDWFC16::execute() { unsigned int new_value,src_value,w_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (src_value = source->get()) + (w_value = cpu16->Wget()) + ((cpu16->status->value.get() & STATUS_C) ? 1 : 0); // Store the result if(destination) source->put(new_value & 0xff); // Result goes to source else cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N(new_value, src_value, w_value); cpu16->pc->increment(); } //-------------------------------------------------- void ANDLW16::execute() { unsigned int new_value; new_value = cpu16->Wget() & L; cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- void ANDWF16::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = source->get() & cpu16->Wget(); if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- BC::BC (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bc"); } void BC::execute() { if(cpu16->status->value.get() & STATUS_C) cpu16->pc->jump(absolute_destination_index); else cpu16->pc->increment(); } //-------------------------------------------------- BN::BN (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bn"); } void BN::execute() { if(cpu16->status->value.get() & STATUS_N) cpu16->pc->jump(absolute_destination_index); else cpu16->pc->increment(); } //-------------------------------------------------- BNC::BNC (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bnc"); } void BNC::execute() { if(cpu16->status->value.get() & STATUS_C) cpu16->pc->increment(); else cpu16->pc->jump(absolute_destination_index); } //-------------------------------------------------- BNN::BNN (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bnn"); } void BNN::execute() { if(cpu16->status->value.get() & STATUS_N) cpu16->pc->increment(); else cpu16->pc->jump(absolute_destination_index); } //-------------------------------------------------- BNOV::BNOV (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bnov"); } void BNOV::execute() { if(cpu16->status->value.get() & STATUS_OV) cpu16->pc->increment(); else cpu16->pc->jump(absolute_destination_index); } //-------------------------------------------------- BNZ::BNZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bnz"); } void BNZ::execute() { if(cpu16->status->value.get() & STATUS_Z) cpu16->pc->increment(); else cpu16->pc->jump(absolute_destination_index); } //-------------------------------------------------- BOV::BOV (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bov"); } void BOV::execute() { if(cpu16->status->value.get() & STATUS_OV) cpu16->pc->jump(absolute_destination_index); else cpu16->pc->increment(); } //-------------------------------------------------- BRA16::BRA16 (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { destination_index = (new_opcode & 0x7ff)+1; absolute_destination_index = (cpu16->getCurrentDisasmIndex() + destination_index) & 0xfffff; if(new_opcode & 0x400) { absolute_destination_index -= 0x800; destination_index = 0x800 - destination_index; } new_name("bra"); } void BRA16::execute() { cpu16->pc->jump(absolute_destination_index); } char * BRA16::name(char *return_str,int len) { sprintf(return_str,"%s\t$%c0x%x\t;(0x%05x)", gpsimObject::name().c_str(), (opcode & 0x400) ? '-' : '+', (destination_index & 0x7ff)<<1, absolute_destination_index<<1); return(return_str); } //-------------------------------------------------- void BSF16::execute() { if (access) reg = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) reg = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else reg = cpu_pic->registers[register_address]; reg->put(reg->get_value() | mask); // Must not use reg->value.get() as it breaks indirects cpu16->pc->increment(); } //-------------------------------------------------- void BCF16::execute() { if (access) reg = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) reg = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else reg = cpu_pic->registers[register_address]; reg->put(reg->get_value() & mask); // Must not use reg->value.get() as it breaks indirects cpu16->pc->increment(); } //-------------------------------------------------- void BTFSC16::execute() { if (access) reg = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) reg = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else reg = cpu_pic->registers[register_address]; unsigned int result = mask & reg->get(); if(!result) cpu_pic->pc->skip(); // Skip next instruction else cpu_pic->pc->increment(); } //-------------------------------------------------- void BTFSS16::execute() { if (access) reg = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) reg = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else reg = cpu_pic->registers[register_address]; unsigned int result = mask & reg->get(); if(result) cpu_pic->pc->skip(); // Skip next instruction else cpu_pic->pc->increment(); } //-------------------------------------------------- BTG::BTG (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Bit_op(new_cpu, new_opcode,address) { decode(new_cpu, new_opcode); new_name("btg"); } void BTG::execute() { if (access) reg = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) reg = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else reg = cpu_pic->registers[register_address]; reg->put(reg->get() ^ mask); cpu16->pc->increment(); } //-------------------------------------------------- BZ::BZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Branching(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("bz"); } void BZ::execute() { if(cpu16->status->value.get() & STATUS_Z) cpu16->pc->jump(absolute_destination_index); else cpu16->pc->increment(); } //-------------------------------------------------- CALL16::CALL16 (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_branch(new_cpu, new_opcode, address) { fast = (new_opcode & 0x100) ? true : false; cpu = new_cpu; PMaddress = cpu16->getCurrentDisasmAddress(); PMindex = cpu16->getCurrentDisasmIndex(); initialized = false; new_name("call"); } void CALL16::execute() { if(!initialized) runtime_initialize(); if (cpu16->stack->push(cpu16->pc->get_next())) { if(fast) cpu16->fast_stack.push(); cpu16->pc->jump(destination_index); } else // stack overflow reset cpu16->pc->jump(0); } char *CALL16::name(char *return_str,int len) { if(!initialized) runtime_initialize(); snprintf(return_str,len,"call\t0x%05x%s", destination_index<<1, ((fast) ? ",f" : " ")); return(return_str); } //-------------------------------------------------- void COMF16::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = source->get() ^ 0xff; // Store the result if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- CPFSEQ::CPFSEQ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("cpfseq"); } void CPFSEQ::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; if(source->get() == cpu16->Wget()) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- CPFSGT::CPFSGT (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("cpfsgt"); } void CPFSGT::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; if(source->get() > cpu16->Wget()) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- CPFSLT::CPFSLT (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("cpfslt"); } void CPFSLT::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; if(source->get() < cpu16->Wget()) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } void CLRF16::execute() { if (access) cpu_pic->register_bank[register_address]->put(0); else if (cpu16->extended_instruction() && register_address < 0x60) cpu_pic->registers[register_address + cpu16->ind2.fsr_value]->put(0); else cpu_pic->registers[register_address]->put(0); cpu16->status->put_Z(1); cpu16->pc->increment(); } //-------------------------------------------------- DAW::DAW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("daw"); } void DAW::execute() { unsigned int new_value; new_value = cpu16->Wget(); if(((new_value & 0x0f) > 0x9) || (cpu16->status->value.get() & STATUS_DC)) new_value += 0x6; if(((new_value & 0xf0) > 0x90) || (cpu16->status->value.get() & STATUS_C)) new_value += 0x60; cpu16->Wput(new_value & 0xff); if ( new_value>0xff ) cpu16->status->put_C(1); else if ( cpu16->bugs() & BUG_DAW ) cpu16->status->put_C(0); cpu16->pc->increment(); } //-------------------------------------------------- void DECF16::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; unsigned int src_value = source->get(); unsigned int new_value = src_value - 1; if(destination) source->put(new_value & 0xff); // Result goes to source else cpu16->Wput(new_value & 0xff); // cpu16->status->put_N_Z(new_value); cpu16->status->put_Z_C_DC_OV_N_for_sub(new_value,src_value,1); cpu16->pc->increment(); } //-------------------------------------------------- void DECFSZ16::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (source->get() - 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); if(0==new_value) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- DCFSNZ::DCFSNZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("dcfsnz"); } void DCFSNZ::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (source->get() - 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); if(0!=new_value) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- GOTO16::GOTO16 (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_branch(new_cpu, new_opcode, address) { PMaddress = cpu16->getCurrentDisasmAddress(); PMindex = cpu16->getCurrentDisasmIndex(); initialized = false; new_name("goto"); } void GOTO16::execute() { if(!initialized) runtime_initialize(); cpu16->pc->jump(destination_index); } //-------------------------------------------------- void INCF16::execute() { unsigned int new_value, src_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; src_value = source->get(); new_value = (src_value + 1); if(destination) { source->put(new_value & 0xff); // Result goes to source cpu16->status->put_Z_C_DC_OV_N(new_value, src_value, 1); } else { cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N(new_value, 1, src_value); } cpu16->pc->increment(); } //-------------------------------------------------- void INCFSZ16::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (source->get() + 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); if(0==new_value) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- INFSNZ::INFSNZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("infsnz"); } void INFSNZ::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (source->get() + 1)&0xff; if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); if(0!=new_value) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- void IORLW16::execute() { unsigned int new_value; new_value = cpu16->Wget() | L; cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- void IORWF16::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = source->get() | cpu16->Wget(); if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- LCALL16::LCALL16 (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_branch(new_cpu, new_opcode, address) { // opcode = new_opcode; // fast = new_opcode & 0x100; // cpu = new_cpu; // address = cpu16->current_disasm_address; // initialized = 0; new_name("lcall"); } void LCALL16::execute() { // if(!initialized) // runtime_initialize(); // cpu16->stack->push(cpu16->pc->get_next()); // if(fast) // cpu16->fast_stack.push(); // cpu16->pc->jump(destination); } char *LCALL16::name(char *return_str,int len) { // if(!initialized) // runtime_initialize(); snprintf(return_str,len,"lcall\t0x%05x%s", destination_index<<1, ((fast) ? ",f" : " ")); return(return_str); } //-------------------------------------------------- LFSR::LFSR (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_instruction(new_cpu, new_opcode, address) { PMaddress = cpu16->getCurrentDisasmAddress(); PMindex = cpu16->getCurrentDisasmIndex(); initialized = false; fsr = (opcode & 0x30)>>4; switch(fsr) { case 0: ia = &cpu16->ind0; break; case 1: ia = &cpu16->ind1; break; case 2: ia = &cpu16->ind2; break; case 3: cout << "LFSR decode error, fsr is 3 and should only be 0,1, or 2\n"; ia = &cpu16->ind0; } new_name("lfsr"); } void LFSR::runtime_initialize() { if(cpu_pic->program_memory[PMindex+1]) { word2_opcode = cpu_pic->program_memory[PMindex+1]->get_opcode(); if((word2_opcode & 0xff00) != 0xf000) { cout << "16bit-instructions.cc LFSR error\n"; return; } cpu_pic->program_memory[PMindex+1]->update_line_number( file_id, src_line, lst_line, 0, 0); k = ( (opcode & 0xf)<<8) | (word2_opcode & 0xff); initialized = true; } } char *LFSR::name(char *return_str,int len) { if(!initialized) runtime_initialize(); snprintf(return_str,len,"%s\t%u,0x%x", gpsimObject::name().c_str(), fsr, k); return(return_str); } void LFSR::execute() { if(!initialized) runtime_initialize(); ia->put_fsr(k); cpu16->pc->skip(); //cpu16->pc->increment(); } //-------------------------------------------------- void MOVF16::execute() { unsigned int source_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; source_value = source->get(); // Store the result if(destination) source->put(source_value); else cpu16->Wput(source_value); cpu16->status->put_N_Z(source_value); cpu16->pc->increment(); } //-------------------------------------------------- MOVFF::MOVFF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_instruction(new_cpu, new_opcode, address) { PMaddress = cpu16->getCurrentDisasmAddress(); PMindex = cpu16->getCurrentDisasmIndex(); initialized = false; destination = 0; source = opcode & 0xfff; new_name("movff"); } void MOVFF::runtime_initialize() { if(cpu_pic->program_memory[PMindex+1]) { word2_opcode = cpu_pic->program_memory[PMindex+1]->get_opcode(); if((word2_opcode & 0xf000) != 0xf000) { cout << "16bit-instructions.cc MOVFF error\n"; return; } cpu_pic->program_memory[PMindex+1]->update_line_number( file_id, src_line, lst_line, 0, 0); destination = word2_opcode & 0xfff; initialized = true; } } char *MOVFF::name(char *return_str,int len) { if(!initialized) runtime_initialize(); snprintf(return_str,len,"%s\t%s,%s", gpsimObject::name().c_str(), cpu_pic->registers[source]->name().c_str(), cpu_pic->registers[destination]->name().c_str()); return(return_str); } void MOVFF::execute() { if(!initialized) runtime_initialize(); unsigned int r = cpu_pic->registers[source]->get(); cpu_pic->registers[destination]->put(r); cpu16->pc->skip(); //cpu16->pc->increment(); } //-------------------------------------------------- MOVFP::MOVFP (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : multi_word_instruction(new_cpu, new_opcode, address) { new_name("movfp"); } void MOVFP::runtime_initialize() { // if(cpu_pic->program_memory[address+1]) // { // word2_opcode = cpu_pic->program_memory[address+1]->get_opcode(); // if((word2_opcode & 0xf000) != 0xf000) // { // cout << "16bit-instructions.cc MOVFP error\n"; // return; // } // cpu_pic->program_memory[address+1]->update_line_number( file_id, src_line, lst_line); // destination = word2_opcode & 0xfff; // initialized = 1; // } } char *MOVFP::name(char *return_str, int len) { // if(!initialized) // runtime_initialize(); snprintf(return_str,len,"%s\t%s,%s", gpsimObject::name().c_str(), cpu_pic->registers[source]->name().c_str(), cpu_pic->registers[destination]->name().c_str()); return(return_str); } void MOVFP::execute() { // if(!initialized) // runtime_initialize(); // unsigned int r = cpu_pic->registers[source]->get(); // cpu_pic->pc->skip(); // cpu_pic->registers[destination]->put(r); // cpu_pic->pc->increment(); } //-------------------------------------------------- MOVLB16::MOVLB16 (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("movlb"); } void MOVLB16::execute() { cpu16->registers[cpu16->bsr.address]->put(L); cpu16->pc->increment(); } //-------------------------------------------------- MOVLR::MOVLR (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode, address) { // decode(new_cpu, new_opcode); new_name("movlr"); } void MOVLR::execute() { // unsigned int source_value; // cpu16->bsr.put(L); // cpu_pic->pc->increment(); } //-------------------------------------------------- MOVPF::MOVPF (Processor *new_cpu, unsigned int new_opcode,unsigned int address) : multi_word_instruction(new_cpu, new_opcode,address) { // opcode = new_opcode; // cpu = new_cpu; // address = cpu16->current_disasm_address; // initialized = 0; // destination = 0; // source = opcode & 0xfff; new_name("movpf"); } void MOVPF::runtime_initialize() { // if(cpu_pic->program_memory[address+1]) // { // word2_opcode = cpu_pic->program_memory[address+1]->get_opcode(); // if((word2_opcode & 0xf000) != 0xf000) // { // cout << "16bit-instructions.cc MOVFP error\n"; // return; // } // cpu_pic->program_memory[address+1]->update_line_number( file_id, src_line, lst_line); // destination = word2_opcode & 0xfff; // initialized = 1; // } } char *MOVPF::name(char *return_str,int len) { // if(!initialized) // runtime_initialize(); snprintf(return_str,len,"%s\t%s,%s", gpsimObject::name().c_str(), cpu_pic->registers[source]->name().c_str(), cpu_pic->registers[destination]->name().c_str()); return(return_str); } void MOVPF::execute() { // if(!initialized) // runtime_initialize(); // unsigned int r = cpu_pic->registers[source]->get(); // cpu_pic->pc->skip(); // cpu_pic->registers[destination]->put(r); // cpu_pic->pc->increment(); } //-------------------------------------------------- MOVWF16::MOVWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : MOVWF(new_cpu,new_opcode, address) { } void MOVWF16::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; source->put(cpu16->Wget()); cpu16->pc->increment(); } #ifdef RRR //-------------------------------------------------- MOVWF16a::MOVWF16a(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : MOVWF(new_cpu,new_opcode, address) { // pic_processor * cpu = (pic_processor*) new_cpu; register_address = (new_opcode & 0xff); if ( register_address >= (cpu_pic->access_gprs()) ) // some 18f devices split at 0x60 register_address |= 0xf00; } void MOVWF16a::execute() { source = cpu_pic->registers[register_address]; source->put(cpu16->Wget()); cpu16->pc->increment(); } #endif //RRR //-------------------------------------------------- MULLW::MULLW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Literal_op(new_cpu, new_opcode,address) { decode(new_cpu, new_opcode); new_name("mullw"); } void MULLW::execute() { unsigned int value; value = (0xff & cpu16->Wget()) * L; cpu16->prodl.put(value &0xff); cpu16->prodh.put((value>>8) &0xff); cpu16->pc->increment(); } //-------------------------------------------------- MULWF::MULWF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("mulwf"); } void MULWF::execute() { unsigned int value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; //It's not necessary to '&' the get()'s with 0xff, but it doesn't //hurt either. value = (0xff & cpu16->Wget()) * (0xff & source->get()); cpu16->prodl.put(value &0xff); cpu16->prodh.put((value>>8) &0xff); cpu16->pc->increment(); } //-------------------------------------------------- NEGF::NEGF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("negf"); } void NEGF::execute() { unsigned int new_value,src_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; src_value = source->get(); new_value = 1 + ~src_value; // two's complement source->put(new_value&0xff); cpu16->status->put_Z_C_DC_OV_N_for_sub(new_value,0,src_value); cpu16->pc->increment(); } //-------------------------------------------------- NEGW::NEGW (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode,address) { // decode(new_cpu, new_opcode); new_name("negw"); } void NEGW::execute() { cout << "negw is not implemented???"; } //-------------------------------------------------- POP::POP (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("pop"); } void POP::execute() { cpu16->stack->pop(); // discard TOS cpu16->pc->increment(); } //-------------------------------------------------- PUSH::PUSH (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("push"); } void PUSH::execute() { if (cpu16->stack->push(cpu16->pc->get_next())) cpu16->pc->increment(); else // stack overflow reset cpu16->pc->jump(0); } //-------------------------------------------------- RCALL::RCALL (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { destination_index = (new_opcode & 0x7ff)+1; if(new_opcode & 0x400) destination_index -= 0x800; absolute_destination_index = (cpu16->getCurrentDisasmIndex() + destination_index) & 0xfffff; new_name("rcall"); } void RCALL::execute() { if(cpu16->stack->push(cpu16->pc->get_next())) cpu16->pc->jump(absolute_destination_index); else // stack overflow reset cpu16->pc->jump(0); } char * RCALL::name(char *return_str,int len) { snprintf(return_str,len,"%s\t$%c0x%x\t;(0x%05x)", gpsimObject::name().c_str(), (destination_index < 0) ? '-' : '+', (destination_index & 0x7ff)<<1, absolute_destination_index<<1); return(return_str); } //-------------------------------------------------- void RETFIE16::execute() { cpu16->pc->new_address(cpu16->stack->pop()); if(fast) cpu16->fast_stack.pop(); //cout << "retfie: need to enable interrupts\n"; cpu16->intcon.in_interrupt = false; cpu16->intcon.put_value(cpu16->intcon.value.get()); //test for new interrupts } char *RETFIE16::name(char *return_str,int len) { if(fast) snprintf(return_str,len,"retfie\tfast"); else snprintf(return_str,len,"retfie"); return(return_str); } //-------------------------------------------------- void RETURN16::execute() { cpu16->pc->new_address(cpu16->stack->pop()); if(fast) cpu16->fast_stack.pop(); } char *RETURN16::name(char *return_str,int len) { if(fast) snprintf(return_str,len,"return\tfast"); else snprintf(return_str,len,"return"); return(return_str); } //-------------------------------------------------- RLCF::RLCF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("rlcf"); } void RLCF::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (source->get() << 1) | cpu16->status->get_C(); if(destination) source->put(new_value&0xff); // Result goes to source else cpu16->Wput(new_value&0xff); cpu16->status->put_Z_C_N(new_value); cpu16->pc->increment(); } //-------------------------------------------------- RLNCF::RLNCF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("rlncf"); } void RLNCF::execute() { unsigned int new_value,src_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; src_value = source->get(); new_value = (src_value << 1) | ( (src_value & 0x80) ? 1 : 0); if(destination) source->put(new_value&0xff); // Result goes to source else cpu16->Wput(new_value&0xff); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- RRCF::RRCF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("rrcf"); } void RRCF::execute() { unsigned int new_value,src_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; src_value = source->get() & 0xff; new_value = (src_value >> 1) | (cpu16->status->get_C() ? 0x80 : 0); if(destination) source->put(new_value&0xff); // Result goes to source else cpu16->Wput(new_value&0xff); cpu16->status->put_Z_C_N(new_value | ((src_value & 1) ? 0x100 : 0) ); cpu16->pc->increment(); } //-------------------------------------------------- RRNCF::RRNCF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("rrncf"); } void RRNCF::execute() { unsigned int new_value,src_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; src_value = source->get() & 0xff; new_value = (src_value >> 1) | ( (src_value & 1) ? 0x80 : 0); if(destination) source->put(new_value&0xff); // Result goes to source else cpu16->Wput(new_value&0xff); cpu16->status->put_N_Z(new_value | ((src_value & 1) ? 0x100 : 0) ); cpu16->pc->increment(); } //-------------------------------------------------- SETF::SETF (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("setf"); } void SETF::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; source->put(0xff); cpu16->pc->increment(); } //-------------------------------------------------- void SLEEP16::execute() { cpu_pic->enter_sleep(); } //-------------------------------------------------- void SUBLW16::execute() { unsigned int new_value,old_value; new_value = L - (old_value = cpu16->Wget()); cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N_for_sub(new_value, L, old_value); cpu16->pc->increment(); } //-------------------------------------------------- SUBFWB::SUBFWB (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("subfwb"); } void SUBFWB::execute() { unsigned int new_value,src_value,w_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (w_value = cpu16->Wget()) - (src_value = source->get()) - (1 - cpu16->status->get_C()); if(destination) source->put(new_value & 0xff); else cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N_for_sub(new_value, w_value, src_value); cpu16->pc->increment(); } //-------------------------------------------------- void SUBWF16::execute() { unsigned int new_value,src_value,w_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (src_value = source->get()) - (w_value = cpu16->Wget()); if(destination) source->put(new_value & 0xff); else cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N_for_sub(new_value, src_value, w_value); cpu16->pc->increment(); } //-------------------------------------------------- void SUBWFB16::execute() { unsigned int new_value,src_value,w_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = (src_value = source->get()) - (w_value = cpu16->Wget()) - (1 - cpu16->status->get_C()); if(destination) source->put(new_value & 0xff); else cpu16->Wput(new_value & 0xff); cpu16->status->put_Z_C_DC_OV_N_for_sub(new_value, src_value, w_value); cpu16->pc->increment(); } //-------------------------------------------------- void SWAPF16::execute() { unsigned int src_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; src_value = source->get(); if(destination) source->put( ((src_value >> 4) & 0x0f) | ( (src_value << 4) & 0xf0) ); else cpu_pic->Wput( ((src_value >> 4) & 0x0f) | ( (src_value << 4) & 0xf0) ); cpu16->pc->increment(); } //-------------------------------------------------- TBLRD::TBLRD (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("tblrd"); } char *TBLRD::name(char *return_str,int len) { const char *index_modes[4] = {"*","*+","*-","+*"}; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), index_modes[opcode&0x3]); return(return_str); } void TBLRD::execute() { if((opcode & 3)==3) cpu16->tbl.increment(); cpu16->tbl.read(); if((opcode & 3)==1) cpu16->tbl.increment(); else if((opcode & 3)==2) cpu16->tbl.decrement(); cpu16->pc->increment(); } //-------------------------------------------------- TBLWT::TBLWT (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("tblwt"); } char *TBLWT::name(char *return_str,int len) { const char *index_modes[4] = {"*","*+","*-","+*"}; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), index_modes[opcode&0x3]); return(return_str); } void TBLWT::execute() { if((opcode & 3)==3) cpu16->tbl.increment(); cpu16->tbl.write(); if((opcode & 3)==1) cpu16->tbl.increment(); else if((opcode & 3)==2) cpu16->tbl.decrement(); cpu16->pc->increment(); } //-------------------------------------------------- TLRD::TLRD (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { // decode(new_cpu, new_opcode); new_name("tlrd"); } char *TLRD::name(char *return_str,int len) { const char *index_modes[4] = {"*","*+","*-","+*"}; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), index_modes[opcode&0x3]); return(return_str); } void TLRD::execute() { // unsigned int pm_opcode; // if((opcode & 3)==3) // cpu16->tbl.increment(); // cpu16->tbl.read(); // if((opcode & 3)==1) // cpu16->tbl.increment(); // else if((opcode & 3)==2) // cpu16->tbl.decrement(); // cpu_pic->pc->increment(); } //-------------------------------------------------- TLWT::TLWT (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : instruction(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("tlwt"); } char *TLWT::name(char *return_str,int len) { const char *index_modes[4] = {"*","*+","*-","+*"}; snprintf(return_str,len,"%s\t%s", gpsimObject::name().c_str(), index_modes[opcode&0x3]); return(return_str); } void TLWT::execute() { // unsigned int pm_opcode; // if((opcode & 3)==3) // cpu16->tbl.increment(); // cpu16->tbl.write(); // if((opcode & 3)==1) // cpu16->tbl.increment(); // else if((opcode & 3)==2) // cpu16->tbl.decrement(); // cpu_pic->pc->increment(); } //-------------------------------------------------- TSTFSZ::TSTFSZ (Processor *new_cpu, unsigned int new_opcode, unsigned int address) : Register_op(new_cpu, new_opcode, address) { decode(new_cpu, new_opcode); new_name("tstfsz"); } void TSTFSZ::execute() { if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; if( 0 == (source->get() & 0xff) ) cpu16->pc->skip(); // Skip next instruction else cpu16->pc->increment(); } //-------------------------------------------------- void XORLW16::execute() { unsigned int new_value; new_value = cpu16->Wget() ^ L; cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } //-------------------------------------------------- void XORWF16::execute() { unsigned int new_value; if (access) source = cpu_pic->register_bank[register_address]; else if (cpu16->extended_instruction() && register_address < 0x60) source = cpu_pic->registers[register_address + cpu16->ind2.fsr_value]; else source = cpu_pic->registers[register_address]; new_value = source->get() ^ cpu16->Wget(); if(destination) source->put(new_value); // Result goes to source else cpu16->Wput(new_value); cpu16->status->put_N_Z(new_value); cpu16->pc->increment(); } gpsim-0.30.0/src/gpsim_classes.h0000664000076400007640000000332113041763613013443 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* * gpsim_classes.h * * This include file contains most of the class names defined in gpsim * It's used to define forward references to classes and help alleviate * include file dependencies. */ #ifndef __GPSIM_CLASSES_H__ #define __GPSIM_CLASSES_H__ /*================================================================== * * Here are a few enum definitions */ /* * Define all of the different types of reset conditions: */ enum RESET_TYPE { POR_RESET, // Power-on reset WDT_RESET, // Watch Dog timer timeout reset IO_RESET, // I/O pin reset MCLR_RESET, // MCLR (Master Clear) reset SOFT_RESET, // Software initiated reset BOD_RESET, // Brown out detection reset SIM_RESET, // Simulation Reset EXIT_RESET, // Leaving Reset, resuming normal execution. OTHER_RESET, // STKUNF_RESET, // Stack undeflow reset STKOVF_RESET // Statck overflow reset }; #endif // __GPSIM_CLASSES_H__ gpsim-0.30.0/src/dsm_module.cc0000664000076400007640000003034413115237526013103 00000000000000#include "dsm_module.h" class minSink : public SignalSink { public: minSink(DSM_MODULE *dsm) : m_dsm(dsm) {} virtual void setSinkState(char new3State) { m_dsm->minEdge(new3State);} virtual void release() {} private: DSM_MODULE *m_dsm; }; class carhSink : public SignalSink { public: carhSink(DSM_MODULE *dsm) : m_dsm(dsm) {} virtual void setSinkState(char new3State) { m_dsm->carhEdge(new3State);} virtual void release() { delete this;} private: DSM_MODULE *m_dsm; }; class carlSink : public SignalSink { public: carlSink(DSM_MODULE *dsm) : m_dsm(dsm) {} virtual void setSinkState(char new3State) { m_dsm->carlEdge(new3State);} virtual void release() { delete this;} private: DSM_MODULE *m_dsm; }; class MDoutSignalSource : public SignalControl { public: MDoutSignalSource(DSM_MODULE *dsm) : m_dsm(dsm) {} virtual char getState() { return m_dsm->mdout; } virtual void release() {} private: DSM_MODULE *m_dsm; }; DSM_MODULE::DSM_MODULE(Processor *pCpu) : mdcon(pCpu, "mdcon", "Modulation Control Register", this), mdsrc(pCpu, "mdsrc", "Modulation Source Control Register", this), mdcarh(pCpu, "mdcarh", "Modulation High Carrier Control Register", this), mdcarl(pCpu, "mdcarl", "Modulation Low Carrier Control Register", this), m_mdout(0), m_mdmin(0), m_minSink(0), m_mdcin1(0), cin1Sink_cnt(0), m_carlSink(0), m_mdcin2(0), m_carhSink(0), out_source(0), mdout('?'), usart_mod(0), ssp_mod1(0), ssp_mod2(0), mdmin_state(false), mdcarl_state(false), mdcarh_state(false), dflipflopH(false), dflipflopL(false), dsmSrc_pin(0), monitor_pin(0), monitor_mod(0) { } DSM_MODULE::~DSM_MODULE() { if (monitor_pin) { delete monitor_mod; delete monitor_pin; monitor_pin = 0; if (m_carhSink) { /*RRR if (m_mdcin1) { m_mdcin1->removeSink(m_carhSink); } if (m_mdcin2) { m_mdcin2->removeSink(m_carhSink); } RRR */ delete m_carhSink; } } } void DSM_MODULE::dsm_logic(bool carl_neg_edge, bool carh_neg_edge) { bool out, outh, outl; unsigned int con_reg = mdcon.get_value(); if (carl_neg_edge && carl_neg_edge) { dflipflopL = !mdmin_state & !mdcarh_state; dflipflopH = mdmin_state & !mdcarl_state; } else if (carl_neg_edge) { dflipflopL = !mdmin_state & !dflipflopH; } else if (carh_neg_edge) { dflipflopH = mdmin_state & !dflipflopL; } if (mdcarl.get_value() & MDCLSYNC) { outl = mdcarl_state && dflipflopL; } else { outl = !mdmin_state && mdcarl_state; } if (mdcarh.get_value() & MDCHSYNC) { outh = mdcarh_state && dflipflopH; } else { outh = mdmin_state && mdcarh_state; } out = outl || outh; out = (con_reg & MDOPOL)? !out : out; if (out) { con_reg |= MDOUT; } else { con_reg &= ~MDOUT; } mdcon.put_value(con_reg); putMDout(out); } void DSM_MODULE::putMDout(bool out) { mdout = out? '1' : '0'; m_mdout->updatePinModule(); } void DSM_MODULE::releaseMDout() { if (out_source) { // m_mdout->setSource(0); delete out_source; out_source = 0; } } void DSM_MODULE::new_mdcon(unsigned int old_value, unsigned int new_value) { if (((old_value ^ new_value) & MDOE) && m_mdout) { if (new_value & MDOE) { m_mdout->getPin().newGUIname("MDOUT"); if (!out_source) { out_source = new MDoutSignalSource(this); } m_mdout->setSource(out_source); } else { m_mdout->setSource(0); out_source = 0; m_mdout->getPin().newGUIname(m_mdout->getPin().name().c_str()); } } if (((old_value ^ new_value) & MDBIT) && (mdsrc.get_value() & 0x0f) == 0) { mdmin_state = new_value & MDBIT; if (new_value & MDEN) dsm_logic(false, false); } else if (((old_value ^ new_value) & MDOPOL)) dsm_logic(false, false); } // remove Old modulator source void DSM_MODULE::rmModSrc(unsigned int old_value) { switch (old_value & 0x0f) { case 1: // MDMIN port pin if (m_minSink) m_mdmin->removeSink(m_minSink); m_mdmin->getPin().newGUIname(m_mdmin->getPin().name().c_str()); break; case 0x8: //MSSP1 if (m_minSink && dsmSrc_pin) dsmSrc_pin->removeSink(m_minSink); break; case 0xa: // USART if (m_minSink && dsmSrc_pin) dsmSrc_pin->removeSink(m_minSink); break; default: break; } } // set new modulator source void DSM_MODULE::setModSrc(unsigned int new_value, unsigned int diff) { bool old = mdmin_state; switch (new_value & 0x0f) { case 0: mdmin_state = mdcon.get_value() & MDBIT; break; case 1: // MDMIN port pin if (!m_minSink) m_minSink = new minSink(this); m_mdmin->addSink(m_minSink); m_mdmin->getPin().newGUIname("MDMIN"); mdmin_state = m_mdmin->getPin().getState(); break; case 0x8: // MSSP1 if (ssp_mod1) { } else //printf("%s MSSP1 not defined\n", name().c_str(); break; case 0x9: // MSSP2 if (ssp_mod2) { } else //printf("%s MSSP2 not defined\n", name().c_str(); break; case 0xa: // USART TX if (usart_mod) { if (diff & MDMSODIS) { if (new_value & MDMSODIS) { if (!dsmSrc_pin) dsmSrc_pin = usart_mod->txsta.getIOpin(); if (!monitor_pin) { monitor_mod = new PinModule(); monitor_pin = new IOPIN("mds"); monitor_mod->setPin(monitor_pin); } if (!m_minSink) m_minSink = new minSink(this); monitor_mod->addSink(m_minSink); usart_mod->txsta.setIOpin(monitor_mod); //mdmin_state = monitor_mod->getPin().getState(); } else { if (m_minSink && monitor_mod) monitor_mod->removeSink(m_minSink); usart_mod->txsta.setIOpin(dsmSrc_pin); } } if (new_value & MDMSODIS) { } else { dsmSrc_pin = usart_mod->txsta.getIOpin(); if (!m_minSink) m_minSink = new minSink(this); dsmSrc_pin->addSink(m_minSink); mdmin_state = dsmSrc_pin->getPin().getState(); } } break; default: break; } if (old != mdmin_state) dsm_logic(false, false); } void DSM_MODULE::minEdge(char new3State) { bool old = mdmin_state; mdmin_state = (new3State == '1' || new3State == 'W'); if (old != mdmin_state) dsm_logic(false, false); } void DSM_MODULE::new_mdsrc(unsigned int old_value, unsigned int new_value) { unsigned int diff = new_value ^ old_value; if (!diff) return; if (diff & 0x0f) { // change modulator source, first remove old source rmModSrc(old_value); // change modulator source, new source setModSrc(new_value, diff); } else // Change Source Output Disable bit { // handle output disable bit TODO setModSrc(new_value, diff); } } void DSM_MODULE::new_mdcarh(unsigned int old_value, unsigned int new_value) { unsigned int diff = new_value ^ old_value; bool old = mdcarh_state; if (!diff) return; if (diff & 0x0f) { // change carrier high source, first remove old source switch (old_value & 0x0f) { case 1: // MDCIN1 port pin if (m_carhSink) m_mdcin1->removeSink(m_carhSink); if (cin1Sink_cnt && cin1Sink_cnt-- == 1) m_mdcin1->getPin().newGUIname(m_mdcin1->getPin().name().c_str()); break; case 2: // MDCIN2 port pin if (m_carhSink) m_mdcin2->removeSink(m_carhSink); m_mdcin2->getPin().newGUIname(m_mdcin2->getPin().name().c_str()); break; default: break; } // change carrier high source, new source switch (new_value & 0x0f) { case 0: // Vss mdcarh_state = false; break; case 1: // MDCIN1 port pin if (cin1Sink_cnt++ == 0) m_mdcin1->getPin().newGUIname("MDCIN1"); if (!m_carhSink) m_carhSink = new carhSink(this); m_mdcin1->addSink(m_carhSink); mdcarh_state = m_mdcin1->getPin().getState(); break; case 2: // MDCIN2 port pin m_mdcin2->getPin().newGUIname("MDCIN2"); if (!m_carhSink) m_carhSink = new carhSink(this); m_mdcin2->addSink(m_carhSink); mdcarh_state = m_mdcin2->getPin().getState(); break; default: break; } mdcarh_state = (new_value & MDCHPOL) ? ! mdcarh_state : mdcarh_state; } else if (diff & MDCHPOL) { mdcarh_state = ! mdcarh_state; } if (diff & MDCHODIS) // Change Source Output Disable bit { // handle output disable bit TODO } if (old != mdcarh_state ) { dsm_logic(false, old); } } void DSM_MODULE::carhEdge(char new3State) { unsigned int old_state = mdcarh_state; mdcarh_state = (new3State == '1' || new3State == 'W'); mdcarh_state = (mdcarh.get_value() & MDCHPOL) ? ! mdcarh_state : mdcarh_state; if (old_state != mdcarh_state) dsm_logic(old_state, false); // Old_state == true on falling edge } void DSM_MODULE::new_mdcarl(unsigned int old_value, unsigned int new_value) { unsigned int diff = new_value ^ old_value; bool old = mdcarl_state; if (diff & 0x0f) { // change carrier low source, first remove old source switch (old_value & 0x0f) { case 1: // MDCIN1 port pin if (m_carlSink) m_mdcin1->removeSink(m_carlSink); if (cin1Sink_cnt && cin1Sink_cnt-- == 1) m_mdcin1->getPin().newGUIname(m_mdcin1->getPin().name().c_str()); break; default: break; } // change carrier low source, new source switch (new_value & 0x0f) { case 0: // Vss mdcarl_state = false; break; case 1: // MDCIN1 port pin if (cin1Sink_cnt++ == 0) m_mdcin1->getPin().newGUIname("MDCIN1"); if (!m_carlSink) m_carlSink = new carlSink(this); m_mdcin1->addSink(m_carlSink); mdcarl_state = m_mdcin1->getPin().getState(); break; default: break; } mdcarl_state = (new_value & MDCLPOL) ? ! mdcarl_state : mdcarl_state; } else if (diff & MDCLPOL) { mdcarl_state = ! mdcarl_state; } else // Change Source Output Disable bit { // handle output disable bit TODO } if (mdcarl_state != old) dsm_logic(old, false); } void DSM_MODULE::carlEdge(char new3State) { bool old_state = mdcarl_state; mdcarl_state = (new3State == '1' || new3State == 'W'); mdcarl_state = (mdcarl.get_value() & MDCLPOL) ? ! mdcarl_state : mdcarl_state; if (old_state != mdcarl_state) dsm_logic(false, old_state); // old_state true on falling edge } _MDCON::_MDCON(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *_mDSM): sfr_register(pCpu, pName, pDesc), mask(0xf1), mDSM(_mDSM) { } void _MDCON::put(unsigned int new_value) { new_value &= mask; trace.raw(write_trace.get() | value.get()); put_value(new_value); } void _MDCON::put_value(unsigned int new_value) { unsigned int old_value = value.get(); new_value &= (mask | DSM_MODULE::MDOUT); value.put(new_value); mDSM->new_mdcon(old_value, new_value); } _MDSRC::_MDSRC(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *_mDSM): sfr_register(pCpu, pName, pDesc),mask(0x8f), mDSM(_mDSM) { } void _MDSRC::put(unsigned int new_value) { new_value &= mask; trace.raw(write_trace.get() | value.get()); put_value(new_value); } void _MDSRC::put_value(unsigned int new_value) { unsigned int old_value = value.get(); value.put(new_value); mDSM->new_mdsrc(old_value, new_value); } _MDCARH::_MDCARH(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *_mDSM): sfr_register(pCpu, pName, pDesc), mask(0xef), mDSM(_mDSM) { } void _MDCARH::put(unsigned int new_value) { new_value &= mask; trace.raw(write_trace.get() | value.get()); put_value(new_value); } void _MDCARH::put_value(unsigned int new_value) { unsigned int old_value = value.get(); value.put(new_value); mDSM->new_mdcarh(old_value, new_value); } _MDCARL::_MDCARL(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *_mDSM): sfr_register(pCpu, pName, pDesc), mask(0xef), mDSM(_mDSM) { } void _MDCARL::put(unsigned int new_value) { new_value &= mask; trace.raw(write_trace.get() | value.get()); put_value(new_value); } void _MDCARL::put_value(unsigned int new_value) { unsigned int old_value = value.get(); value.put(new_value); mDSM->new_mdcarl(old_value, new_value); } gpsim-0.30.0/src/pic-ioports.h0000664000076400007640000001373413041763613013070 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2009 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PIC_IOPORTS_H__ #define __PIC_IOPORTS_H__ #include "ioports.h" ///------------------------------------------------------------ class PicTrisRegister; class PicPortRegister : public PortRegister { public: PicPortRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *port_name, */ unsigned int numIopins, unsigned int enableMask=0xff); void setTris(PicTrisRegister *new_tris); Register *getTris(); protected: PicTrisRegister *m_tris; }; class PicTrisRegister : public sfr_register { public: PicTrisRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *tris_name, */ PicPortRegister *,bool bIgnoreWDTResets, unsigned int nEnableMask=0xff); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual char get3StateBit(unsigned int bitMask); void setEnableMask(unsigned int); unsigned int getEnableMask() { return m_EnableMask; } void reset(RESET_TYPE r); protected: PicPortRegister *m_port; unsigned int m_EnableMask; bool m_bIgnoreWDTResets; }; class INTCON; class INTCON2; class INTCON3; // PicPortBRegister is usually used for portb and interrupts on selected edge // of bit 0 and sleep wakeup and interrupt on level changes for bits 4-7. class PicPortBRegister : public PicPortRegister { public: PicPortBRegister(Processor *pCpu, const char *pName, const char *pDesc, INTCON *pIntcon, unsigned int numIopins, unsigned int enableMask=0xff, INTCON2 *pIntcon2 = NULL, INTCON3 *pIntcon3 = NULL ); ~PicPortBRegister(); virtual void put(unsigned int new_value); virtual unsigned int get(); virtual void setbit(unsigned int bit_number, char new_value); void setRBPU(bool); void setIntEdge(bool); void assignRBPUSink(unsigned int bitPos, sfr_register *); protected: enum { eIntEdge = 1<<6, eRBPU = 1<<7 }; bool m_bRBPU; bool m_bIntEdge; BitSink *m_bsRBPU; INTCON *m_pIntcon; INTCON2 *m_pIntcon2; INTCON3 *m_pIntcon3; RegisterValue lastDrivenValue; }; class IOC; class IOCxF; // Like PicPortBRegister, PicPortGRegister allows wakeup from sleep // and interrupt on pin level change. However, PicPortGRegister // uses IOC to determine which of any of the bits will do this. // Note: as GPIF,GPIE are the same bits as RBIF,RBIE in INTCON we can // use the existing set_rbif function to set the GPIF bit. // // class PicPortGRegister : public PicPortBRegister { public: INTCON *m_pIntcon; IOC *m_pIoc; unsigned int intf_bit; // port bit that can trigger intf interrupt PicPortGRegister(Processor *pCpu, const char *pName, const char *pDesc, INTCON *pIntcon, IOC *pIoc, unsigned int numIopins, unsigned int enableMask=0x3f); virtual void setbit(unsigned int bit_number, char new3State); virtual void setIOCif(); }; class PicPortIOCRegister : public PicPortBRegister { public: INTCON *m_pIntcon; IOC *m_Iocap; // pins which can cause interrupts on positive edge IOC *m_Iocan; // pins which can cause interrupts on negative edge IOCxF *m_Iocaf; // which pins triggered interrupt PicPortIOCRegister(Processor *pCpu, const char *pName, const char *pDesc, INTCON *pIntcon, IOC *pIocap, IOC *pIocan, IOCxF *pIocaf, unsigned int numIopins, unsigned int enableMask=0x3f) : PicPortBRegister(pCpu, pName, pDesc, pIntcon, numIopins, enableMask), m_pIntcon(pIntcon), m_Iocap(pIocap), m_Iocan(pIocan), m_Iocaf(pIocaf) { } virtual void setbit(unsigned int bit_number, char new3State); }; class PSP; class PicPSP_PortRegister : public PortRegister { public: PicPSP_PortRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *port_name, */ unsigned int numIopins, unsigned int enableMask); virtual void put(unsigned int new_value); virtual unsigned int get(); void setPSP(PSP *pspReg) { m_psp = pspReg;} void setTris(PicTrisRegister *new_tris); Register *getTris(); protected: PicTrisRegister *m_tris; PSP *m_psp; }; class PicPSP_TrisRegister : public PicTrisRegister { public: PicPSP_TrisRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *tris_name, */ PicPortRegister *,bool bIgnoreWDTResets); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); }; //------------------------------------------------------------------------ // PicLatchRegister - 16bit-core devices class PicLatchRegister : public sfr_register { public: virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual void setbit(unsigned int bit_number, char new_value); virtual void setEnableMask(unsigned int nEnableMask); PicLatchRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *, */ PortRegister *,unsigned int nEnableMask=0xff); protected: PortRegister *m_port; unsigned int m_EnableMask; }; #endif // __PIC_IOPORTS_H__ gpsim-0.30.0/src/sim_context.cc0000664000076400007640000002407613041763624013315 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #ifdef _WIN32 #include "uxtime.h" #endif #ifndef _MSC_VER #include #endif #include #include #include #include #include #ifndef _WIN32 #if !defined(_MAX_PATH) #define _MAX_PATH 1024 #endif #include #else #include #endif #include "../config.h" #include "errors.h" #include "fopen-path.h" #include "program_files.h" #include "sim_context.h" #include "breakpoints.h" #include "trace.h" #include "symbol.h" //================================================================================ // Global Declarations // FIXME - move these global references somewhere else // don't print out a bunch of garbage while initializing //================================================================================ // // pic_processor // // This file contains all (most?) of the code that simulates those features // common to all pic microcontrollers. // // CSimulationContext::CSimulationContext() : m_bEnableLoadSource(*new Boolean("EnableSourceLoad", true, "Enables and disables loading of source code")) { active_cpu_id = 0; cpu_ids = 0; m_pbUserCanceled = NULL; globalSymbolTable().addSymbol(&m_bEnableLoadSource); } CSimulationContext::~CSimulationContext() { globalSymbolTable().deleteSymbol("EnableSourceLoad"); } void CSimulationContext::Initialize() { } //------------------------------------------------------------ // The static pointer 's_SimulationContext' in CSimulationContext // is initialized to 0 here, but initialized to something valid // when GetContext is called. CSimulationContext *CSimulationContext::s_SimulationContext = 0; CSimulationContext *CSimulationContext::GetContext() { // Declare static CSimulationContext and return a pointer to it. // Note, we could 'new' an object, but there's no way to call the // destructor in that case. static CSimulationContext sContext; s_SimulationContext = &sContext; return s_SimulationContext; } bool CSimulationContext::SetDefaultProcessor(const char * processor_type, const char * processor_new_name) { if (processor_type) { ProcessorConstructor *pc = ProcessorConstructorList::GetList()->findByType(processor_type); if (pc) { m_DefProcessorName = processor_type; if(processor_new_name == NULL) m_DefProcessorNameNew.clear(); else m_DefProcessorNameNew = processor_new_name; return true; } } else { m_DefProcessorNameNew = processor_new_name; } return false; } //------------------------------------------------------------------- Processor * CSimulationContext::SetProcessorByType(const char * processor_type, const char * processor_new_name) { Processor *p; CProcessorList::iterator it = processor_list.findByType(string(processor_type)); GetBreakpoints().clear_all(GetActiveCPU()); cout << __FUNCTION__ << " FIXME \n"; // GetSymbolTable().Reinitialize(); if(processor_list.end() == it) { p = add_processor(processor_type,processor_new_name); } else { p = it->second; delete p; p = add_processor(processor_type,processor_new_name); // p->init } return p; } //------------------------------------------------------------------- Processor * CSimulationContext::add_processor(const char * processor_type, const char * processor_new_name) { if(verbose) cout << "Trying to add new processor '" << processor_type << "' named '" << processor_new_name << "'\n"; ProcessorConstructor *pc = ProcessorConstructorList::GetList()->findByType(processor_type); if(pc) { return add_processor(pc,processor_new_name ? processor_new_name : m_DefProcessorNameNew.c_str()); } else cout << processor_type << " is not a valid processor.\n" "(try 'processor list' to see a list of valid processors.\n"; return 0; } Processor * CSimulationContext::add_processor(ProcessorConstructor *pc, const char * processor_new_name) { Processor * p = pc->ConstructProcessor(processor_new_name); if(p) { add_processor(p); p->m_pConstructorObject = pc; } else cout << " unable to add a processor (BUG?)\n"; return p; } Processor * CSimulationContext::add_processor(Processor *p) { processor_list.insert(CProcessorList::value_type(p->name(), p)); //p->initializeAttributes(); active_cpu = p; //p->processor_id = active_cpu_id = ++cpu_ids; if(verbose) { cout << p->name() << '\n'; cout << "Program Memory size " << p->program_memory_size() << " words\n"; cout << "Register Memory size " << p->register_memory_size() << '\n'; } trace.switch_cpus(p); // Tell the gui or any modules that are interfaced to gpsim // that a new processor has been declared. gi.new_processor(p); return p; return 0; } int CSimulationContext::LoadProgram(const char *filename, const char *pProcessorType, Processor **ppProcessor, const char *pProcessorName) { bool bReturn = false; Processor *pProcessor; FILE * pFile = fopen_path (filename, "rb"); if(pFile == NULL) { char cw[_MAX_PATH]; perror((string("failed to open program file ") + filename).c_str()); if (!getcwd(cw, sizeof(cw))) perror("getcwd failed: "); else { cerr << "current working directory is " << cw << endl; } return false; } if(pProcessorType != NULL) { pProcessor = SetProcessorByType(pProcessorType, NULL); if(pProcessor != NULL) { bReturn = pProcessor->LoadProgramFile(filename, pFile, pProcessorName); } } else if(!m_DefProcessorName.empty()) { pProcessor = SetProcessorByType(m_DefProcessorName.c_str(), NULL); if(pProcessor != NULL) { bReturn = pProcessor->LoadProgramFile(filename, pFile, pProcessorName); } } else { pProcessor = NULL; if (!m_DefProcessorNameNew.empty()) pProcessorName = m_DefProcessorNameNew.c_str(); // use processor defined in program file bReturn = ProgramFileTypeList::GetList().LoadProgramFile( &pProcessor, filename, pFile, pProcessorName); } fclose(pFile); if(bReturn) { // Tell all of the interfaces that a new program exists. gi.new_program(pProcessor); } if(ppProcessor != NULL) { *ppProcessor = pProcessor; } return bReturn; } //------------------------------------------------------------------------ // dump_processor_list - print out all of the processors a user is // simulating. void CSimulationContext::dump_processor_list(void) { cout << "Processor List\n"; bool have_processors = 0; CProcessorList::iterator processor_iterator; for (processor_iterator = processor_list.begin(); processor_iterator != processor_list.end(); ++processor_iterator) { CProcessorList::value_type vt = *processor_iterator; Processor *p = vt.second; cout << p->name() << '\n'; have_processors = 1; } if(!have_processors) cout << "(empty)\n"; } void CSimulationContext::Clear() { CProcessorList::iterator processor_iterator; for (processor_iterator = processor_list.begin(); processor_iterator != processor_list.end(); ++processor_iterator) { CProcessorList::value_type vt = *processor_iterator; Processor *p = vt.second; GetBreakpoints().clear_all(p); delete p; } processor_list.clear(); } void CSimulationContext::Reset(RESET_TYPE r) { /* Symbol_Table &ST = get_symbol_table(); Symbol_Table::module_symbol_iterator it; Symbol_Table::module_symbol_iterator itEnd = ST.endModuleSymbol(); for(it = ST.beginModuleSymbol(); it != itEnd; it++) { Module *m = (*it)->get_module(); if(m) { m->reset(r); } } */ cout << __FUNCTION__ << " FIXME \n"; } void CSimulationContext::NotifyUserCanceled() { if(m_pbUserCanceled != NULL) { *m_pbUserCanceled = true; m_pbUserCanceled = NULL; return; } if(CSimulationContext::GetContext()->GetActiveCPU() && CSimulationContext::GetContext()->GetActiveCPU()->simulation_mode == eSM_RUNNING) { // If we get a CTRL->C while processing a command file // we should probably stop the command file processing. CSimulationContext::GetContext()->GetBreakpoints().halt(); } } SymbolTable & CSimulationContext::GetSymbolTable() { return gSymbolTable; } Breakpoints & CSimulationContext::GetBreakpoints() { return get_bp(); } Processor * CSimulationContext::GetActiveCPU() { return get_active_cpu(); } Cycle_Counter * CSimulationContext::GetCycleCounter() { return &cycles; } CSimulationContext::CProcessorList::iterator CSimulationContext::CProcessorList::findByType(const key_type& _Keyval) { // First find a ProcessorConstructor that matches the // processor type we are looking for. This should handle // naming variations. ProcessorConstructorList * pcl = ProcessorConstructorList::GetList(); ProcessorConstructor * pc = pcl->findByType(_Keyval.c_str()); if(pc == NULL) return end(); // Now find the specific allocated processor that // was created with the ProcessorConstructor object // we found above. iterator it; iterator itEnd = end(); for(it = begin(); it != itEnd; ++it) { if(it->second->m_pConstructorObject == pc) { return it; } } return itEnd; } gpsim-0.30.0/src/p12f6xx.cc0000775000076400007640000003744213041763613012201 00000000000000/* Copyright (C) 2009 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p12f6xx // // This file supports: // PIC12F629 // PIC12F675 // PIC12F683 // //Note: unlike most other 12F processors these have 14bit instructions #include #include #include #include "../config.h" #include "symbol.h" #include "stimuli.h" #include "eeprom.h" #include "p12f6xx.h" #include "pic-ioports.h" #include "packages.h" //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //======================================================================== // // Configuration Memory for the 12F6XX devices. class Config12F6 : public ConfigWord { public: Config12F6(P12F629 *pCpu) : ConfigWord("CONFIG12F6", 0x3fff, "Configuration Word", pCpu, 0x2007) { Dprintf(("Config12F6::Config12F6 %p\n", m_pCpu)); if (m_pCpu) { m_pCpu->set_config_word(0x2007, 0x3fff); } } }; // Does not match any of 3 versions in pir.h, pir.cc // If required by any other porcessors should be moved there // class PIR1v12f : public PIR { public: enum { TMR1IF = 1 << 0, TMR2IF = 1 << 1, //For 12F683 CMIF = 1 << 3, ADIF = 1 << 6, EEIF = 1 << 7 }; //------------------------------------------------------------------------ PIR1v12f(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = TMR1IF | CMIF | ADIF | EEIF; writable_bits = TMR1IF | CMIF | ADIF | EEIF; } virtual void set_tmr1if() { put(get() | TMR1IF); } virtual void set_tmr2if() { put(get() | TMR2IF); } virtual void set_cmif() { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CMIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } virtual void set_c1if() { set_cmif(); } virtual void set_eeif() { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } virtual void set_adif() { trace.raw(write_trace.get() | value.get()); value.put(value.get() | ADIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } }; //======================================================================== void P12F629::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new Config12F6(this)); }; class MCLRPinMonitor; bool P12F629::set_config_word(unsigned int address,unsigned int cfg_word) { enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN = 1<<3, PWRTEN = 1<<4, MCLRE = 1<<5, BOREN = 1<<6, CP = 1<<7, CPD = 1<<8, BG0 = 1<<12, BG1 = 1<<13 }; if(address == config_word_address()) { if ((cfg_word & MCLRE) == MCLRE) assignMCLRPin(4); // package pin 4 else unassignMCLRPin(); wdt.initialize((cfg_word & WDTEN) == WDTEN); if ((cfg_word & (FOSC2 | FOSC1 )) == 0x04) // internal RC OSC osccal.set_freq(4e6); return(_14bit_processor::set_config_word(address, cfg_word)); } return false; } P12F629::P12F629(const char *_name, const char *desc) : _14bit_processor(_name,desc), intcon_reg(this,"intcon","Interrupt Control"), comparator(this), pie1(this,"PIE1", "Peripheral Interrupt Enable"), t1con(this, "t1con", "TMR1 Control"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), pcon(this, "pcon", "pcon"), osccal(this, "osccal", "Oscillator Calibration Register", 0xfc) { m_ioc = new IOC(this, "ioc", "Interrupt-On-Change GPIO Register"); m_gpio = new PicPortGRegister(this,"gpio","", &intcon_reg, m_ioc,8,0x3f); m_trisio = new PicTrisRegister(this,"trisio","", m_gpio, false); m_wpu = new WPU(this, "wpu", "Weak Pull-up Register", m_gpio, 0x37); pir1 = new PIR1v12f(this,"pir1","Peripheral Interrupt Register",&intcon_reg, &pie1); tmr0.set_cpu(this, m_gpio, 4, option_reg); tmr0.start(0); if(config_modes) config_modes->valid_bits = ConfigMode::CM_FOSC0 | ConfigMode::CM_FOSC1 | ConfigMode::CM_FOSC1x | ConfigMode::CM_WDTE | ConfigMode::CM_PWRTE; } P12F629::~P12F629() { delete_file_registers(0x20, ram_top); remove_sfr_register(&tmr0); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&pcon); remove_sfr_register(&t1con); remove_sfr_register(&intcon_reg); remove_sfr_register(&pie1); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&osccal); delete_sfr_register(m_gpio); delete_sfr_register(m_trisio); delete_sfr_register(m_wpu); delete_sfr_register(m_ioc); delete_sfr_register(pir1); delete e; } Processor * P12F629::construct(const char *name) { P12F629 *p = new P12F629(name); p->create(0x5f, 128); p->create_invalid_registers (); p->create_symbols(); return p; } void P12F629::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } void P12F629::create_sfr_map() { pir_set_def.set_pir1(pir1); add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); add_sfr_register(&tmr0, 0x01, RegisterValue(0xff,0)); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0),"tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0),"tmr1h"); add_sfr_register(&pcon, 0x8e, RegisterValue(0,0),"pcon"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); add_sfr_register(m_gpio, 0x05); add_sfr_register(m_trisio, 0x85, RegisterValue(0x3f,0)); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); add_sfr_register(pir1, 0x0c, RegisterValue(0,0),"pir1"); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; tmr1l.setIOpin(&(*m_gpio)[5]); tmr1l.setGatepin(&(*m_gpio)[4]); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), NULL, &(*m_gpio)[0], &(*m_gpio)[1], NULL, NULL, &(*m_gpio)[2], NULL); comparator.cmcon.set_configuration(1, 0, AN0, AN1, AN0, AN1, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN1, AN0, AN1, OUT0); comparator.cmcon.set_configuration(1, 2, AN0, AN1, AN0, AN1, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN1, VREF, AN1, VREF, OUT0); comparator.cmcon.set_configuration(1, 4, AN1, VREF, AN1, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN1, VREF, AN0, VREF, OUT0); comparator.cmcon.set_configuration(1, 6, AN1, VREF, AN0, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 0, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 2, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 3, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 4, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 6, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0x19, RegisterValue(0,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0x99, RegisterValue(0,0),"cvrcon"); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x9a); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x9b); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x9c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x9d); add_sfr_register(m_wpu, 0x95, RegisterValue(0x37,0),"wpu"); add_sfr_register(m_ioc, 0x96, RegisterValue(0,0),"ioc"); add_sfr_register(&osccal, 0x90, RegisterValue(0x80,0)); } //------------------------------------------------------------------- void P12F629::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) get_eeprom()->change_rom(address - 0x2100, value); } void P12F629::create_iopin_map() { package = new Package(8); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin( 7, m_gpio->addPin(new IO_bi_directional_pu("gpio0"),0)); package->assign_pin( 6, m_gpio->addPin(new IO_bi_directional_pu("gpio1"),1)); package->assign_pin( 5, m_gpio->addPin(new IO_bi_directional_pu("gpio2"),2)); package->assign_pin( 4, m_gpio->addPin(new IOPIN("gpio3"),3)); package->assign_pin( 3, m_gpio->addPin(new IO_bi_directional_pu("gpio4"),4)); package->assign_pin( 2, m_gpio->addPin(new IO_bi_directional_pu("gpio5"),5)); package->assign_pin( 1, 0); package->assign_pin( 8, 0); } void P12F629::create(int _ram_top, int eeprom_size) { ram_top = _ram_top; create_iopin_map(); _14bit_processor::create(); e = new EEPROM_PIR(this, pir1); e->initialize(eeprom_size); e->set_intcon(&intcon_reg); set_eeprom(e); add_file_registers(0x20, ram_top, 0x80); P12F629::create_sfr_map(); } //------------------------------------------------------------------- void P12F629::enter_sleep() { tmr1l.sleep(); _14bit_processor::enter_sleep(); } //------------------------------------------------------------------- void P12F629::exit_sleep() { tmr1l.wake(); _14bit_processor::exit_sleep(); } //------------------------------------------------------------------- void P12F629::option_new_bits_6_7(unsigned int bits) { Dprintf(("P12F629::option_new_bits_6_7 bits=%x\n", bits)); m_gpio->setIntEdge ( (bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); m_wpu->set_wpu_pu ( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); } //======================================================================== // // Pic 16F675 // Processor * P12F675::construct(const char *name) { P12F675 *p = new P12F675(name); p->create(0x5f, 128); p->create_invalid_registers (); p->create_symbols(); return p; } P12F675::P12F675(const char *_name, const char *desc) : P12F629(_name,desc), ansel(this,"ansel", "Analog Select"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low") { } P12F675::~P12F675() { remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&ansel); } void P12F675::create(int ram_top, int eeprom_size) { P12F629::create(ram_top, eeprom_size); create_sfr_map(); } void P12F675::create_sfr_map() { // // adcon1 is not a register on the 12f675, but it is used internally // to perform the ADC conversions // add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&ansel, 0x9f, RegisterValue(0x0f,0)); ansel.setAdcon1(&adcon1); ansel.setAdcon0(&adcon0); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(3); adcon0.setChannel_shift(2); adcon1.setNumberOfChannels(4); adcon1.setIOPin(0, &(*m_gpio)[0]); adcon1.setIOPin(1, &(*m_gpio)[1]); adcon1.setIOPin(2, &(*m_gpio)[2]); adcon1.setIOPin(3, &(*m_gpio)[4]); adcon1.setVrefHiConfiguration(2, 1); /* Channel Configuration done dynamiclly based on ansel */ adcon1.setValidCfgBits(ADCON1::VCFG0 | ADCON1::VCFG1 , 4); } //======================================================================== // // Pic 16F683 // Processor * P12F683::construct(const char *name) { P12F683 *p = new P12F683(name); p->create(0x7f, 256); p->create_invalid_registers (); p->create_symbols(); return p; } P12F683::P12F683(const char *_name, const char *desc) : P12F675(_name,desc), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), wdtcon(this, "wdtcon", "WDT Control", 0x1f), osccon(0), osctune(this, "osctune", "OSC Tune") { internal_osc = false; pir1->valid_bits |= PIR1v12f::TMR2IF; pir1->writable_bits |= PIR1v12f::TMR2IF; } P12F683::~P12F683() { delete_file_registers(0x20, 0x7f); delete_file_registers(0xa0, 0xbf); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&pr2); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&wdtcon); remove_sfr_register(osccon); remove_sfr_register(&osctune); remove_sfr_register(&comparator.cmcon1); } void P12F683::create(int _ram_top, int eeprom_size) { P12F629::create(0, eeprom_size); osccon = new OSCCON(this, "osccon", "OSC Control"); add_file_registers(0x20, 0x6f, 0); add_file_registers(0xa0, 0xbf, 0); add_file_registers(0x70, 0x7f, 0x80); create_sfr_map(); } void P12F683::create_sfr_map() { P12F675::create_sfr_map(); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); add_sfr_register(&ccpr1l, 0x13, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x14, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x15, RegisterValue(0,0)); add_sfr_register(&wdtcon, 0x18, RegisterValue(0x08,0),"wdtcon"); add_sfr_register(osccon, 0x8f, RegisterValue(0,0),"osccon"); remove_sfr_register(&osccal); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); pr2.tmr2 = &tmr2; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v1::CCP1IF, &tmr2); ccp1con.setIOpin(&((*m_gpio)[2])); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; comparator.cmcon.new_name("cmcon0"); comparator.cmcon.set_tmrl(&tmr1l); comparator.cmcon1.set_tmrl(&tmr1l); add_sfr_register(&comparator.cmcon1, 0x1a, RegisterValue(2,0),"cmcon1"); wdt.set_timeout(1./31000.); } gpsim-0.30.0/src/uart.h0000664000076400007640000002260513112421672011563 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include class InvalidRegister; // Forward reference #ifndef __USART_H__ #define __USART_H__ #include "pic-processor.h" #include "14bit-registers.h" #include "pir.h" class _TXSTA; // Forward references class _SPBRG; class _RCSTA; class _SPBRGH; class _BAUDCON; class _14bit_processor; class RXSignalSink; class CLKSignalSink; class TXSignalSource; class TXSignalControl; class RCSignalSource; class RCSignalControl; class USART_MODULE; // USART Data Transmit Register class _TXREG : public sfr_register, public TriggerObject { public: _TXREG(Processor *pCpu, const char *pName, const char *pDesc,USART_MODULE *); virtual void put(unsigned int); virtual void put_value(unsigned int); virtual void assign_txsta(_TXSTA *new_txsta) { m_txsta = new_txsta; }; virtual void assign_rcsta(_RCSTA *new_rcsta) { m_rcsta = new_rcsta; }; virtual void callback(); virtual void callback_print(); private: _TXSTA *m_txsta; _RCSTA *m_rcsta; USART_MODULE *mUSART; bool full; }; // Transmit Status and Control register class _TXSTA : public sfr_register, public TriggerObject { public: _TXREG *txreg; _SPBRG *spbrg; _RCSTA *rcsta; unsigned int tsr; unsigned int bit_count; enum { TX9D = 1<<0, TRMT = 1<<1, BRGH = 1<<2, SENDB = 1<<3, SYNC = 1<<4, TXEN = 1<<5, TX9 = 1<<6, CSRC = 1<<7 }; _TXSTA(Processor *pCpu, const char *pName, const char *pDesc,USART_MODULE *); ~_TXSTA(); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual void transmit_a_bit(); virtual void start_transmitting(); virtual void stop_transmitting(); virtual void transmit_break(); virtual void callback(); virtual void callback_print(); virtual char getState(); virtual void enableTXPin(); virtual void disableTXPin(); virtual void setIOpin(PinModule *); virtual PinModule *getIOpin() { return m_PinModule; } virtual void putTXState(char newTXState); bool bTXEN() { return (value.get() & TXEN) != 0; } bool bSYNC() { return (value.get() & SYNC) != 0; } bool bTRMT() { return (value.get() & TRMT) != 0; } bool bCSRC() { return (value.get() & CSRC) != 0; } bool bTX9() { return (value.get() & TX9) != 0; } int bTX9D() { return (value.get() & TX9D) ? 1 : 0; } void set_pin_pol ( bool invert ) { bInvertPin = invert; }; void releasePin(); protected: USART_MODULE *mUSART; PinModule *m_PinModule; TXSignalSource *m_source; TXSignalControl *m_control; CLKSignalSink *m_clkSink; bool SourceActive; char m_cTxState; bool bInvertPin; }; // USART Data Receive Register class _RCREG : public sfr_register { public: unsigned int oldest_value; /* rcreg has a 2-deep fifo. The oldest received * value is stored here, while the most recent * is stored in sfr_register.value . */ unsigned int fifo_sp; /* fifo stack pointer */ _RCREG(Processor *pCpu, const char *pName, const char *pDesc,USART_MODULE *); virtual unsigned int get(); virtual unsigned int get_value(); virtual void push(unsigned int); virtual void pop(); virtual void assign_rcsta(_RCSTA *new_rcsta) { m_rcsta = new_rcsta; }; private: USART_MODULE *mUSART; _RCSTA *m_rcsta; }; // Receive Status and Control Register class _RCSTA : public sfr_register, public TriggerObject { public: enum { RX9D = 1<<0, OERR = 1<<1, FERR = 1<<2, ADDEN = 1<<3, CREN = 1<<4, SREN = 1<<5, RX9 = 1<<6, SPEN = 1<<7 }; enum { RCSTA_DISABLED, RCSTA_WAITING_FOR_START, RCSTA_MAYBE_START, RCSTA_WAITING_MID1, RCSTA_WAITING_MID2, RCSTA_WAITING_MID3, RCSTA_RECEIVING }; // The usart samples the middle of the bit three times and // produces a sample based on majority averaging. // #define TOTAL_SAMPLE_STATES 16 #define BRGH_FIRST_MID_SAMPLE 4 #define BRGH_SECOND_MID_SAMPLE 8 #define BRGH_THIRD_MID_SAMPLE 12 #define BRGL_FIRST_MID_SAMPLE 7 #define BRGL_SECOND_MID_SAMPLE 8 #define BRGL_THIRD_MID_SAMPLE 9 _RCREG *rcreg; _SPBRG *spbrg; _TXSTA *txsta; _TXREG *txreg; bool sync_next_clock_edge_high; unsigned int rsr; unsigned int bit_count; unsigned int rx_bit; unsigned int sample,state, sample_state; guint64 future_cycle, last_cycle; _RCSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *); ~_RCSTA(); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void receive_a_bit(unsigned); void receive_start_bit(); virtual void start_receiving(); virtual void stop_receiving(); virtual void overrun(); virtual void callback(); virtual void callback_print(); void setState(char new_RxState); //RRR char getDir() { return m_DTdirection;} bool bSPEN() { return (value.get() & SPEN); } bool bSREN() { return (value.get() & SREN); } bool bCREN() { return (value.get() & CREN); } bool bRX9() { return (value.get() & RX9); } virtual void setIOpin(PinModule *); bool rc_is_idle(void) { return ( state <= RCSTA_WAITING_FOR_START ); }; virtual void enableRCPin(char direction = DIR_OUT); virtual void disableRCPin(); void releasePin(); virtual char getState() { return m_cTxState;} virtual void putRCState(char newRCState); virtual void sync_start_transmitting(); virtual void clock_edge(char new3State); void set_old_clock_state(char new3State); protected: enum { DIR_OUT, DIR_IN }; void set_callback_break(unsigned int spbrg_edge); USART_MODULE *mUSART; PinModule *m_PinModule; RXSignalSink *m_sink; char m_cRxState; bool SourceActive; RCSignalControl *m_control; RCSignalSource *m_source; char m_cTxState; char m_DTdirection; bool bInvertPin; bool old_clock_state; }; // BAUD Rate Control Register class _BAUDCON : public sfr_register { public: enum { ABDEN = 1<<0, WUE = 1<<1, BRG16 = 1<<3, TXCKP = 1<<4, SCKP = 1<<4, // synchronous clock polarity Select bit (16f88x) RXDTP = 1<<5, RCIDL = 1<<6, ABDOVF = 1<<7 }; _TXSTA *txsta; _RCSTA *rcsta; _BAUDCON(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int); virtual void put_value(unsigned int); bool brg16(void) { return ( value.get() & BRG16 ) != 0; }; bool txckp() { return ( value.get() & TXCKP) != 0; } bool rxdtp() { return ( value.get() & RXDTP) != 0; } // private: }; // USART Baud Rate Generator, High Byte class _SPBRGH : public sfr_register { public: _SPBRGH(Processor *pCpu, const char *pName, const char *pDesc); virtual void assign_spbrg(_SPBRG *new_spbrg) { m_spbrg = new_spbrg; }; virtual void put(unsigned int); virtual void put_value(unsigned int); private: _SPBRG *m_spbrg; }; // USART Baud Rate Generator, Low Byte class _SPBRG : public sfr_register, public TriggerObject { public: _TXSTA *txsta; _RCSTA *rcsta; _SPBRGH *brgh; _BAUDCON *baudcon; guint64 start_cycle, // The cycle the SPBRG was started last_cycle, // The cycle when the spbrg clock last changed future_cycle; // The next cycle spbrg is predicted to change bool running; _SPBRG(Processor *pCpu, const char *pName, const char *pDesc); virtual void callback(); virtual void callback_print() { cout << "_SPBRG " << name() << " CallBack ID " << CallBackID << '\n'; } virtual void start(); virtual void get_next_cycle_break(); virtual guint64 get_cpu_cycle(unsigned int edges_from_now); virtual guint64 get_last_cycle(); virtual void put(unsigned int); virtual void put_value(unsigned int); void set_start_cycle(); // protected: virtual unsigned int get_cycles_per_tick(); private: guint64 skip; }; //--------------------------------------------------------------- //--------------------------------------------------------------- class USART_MODULE { public: _TXSTA txsta; _RCSTA rcsta; _SPBRG spbrg; _TXREG *txreg; _RCREG *rcreg; PIR *pir; // Extra registers for when it's an EUSART _SPBRGH spbrgh; _BAUDCON baudcon; USART_MODULE(Processor *pCpu); ~USART_MODULE(); void initialize(PIR *, PinModule *tx_pin, PinModule *rx_pin, _TXREG *, _RCREG *); void set_TXpin(PinModule *tx_pin); void set_RXpin(PinModule *rx_pin); bool bIsTXempty(); void emptyTX(); void full(); void set_rcif(); void clear_rcif(); void mk_rcif_int(PIR *reg, unsigned int bit) { m_rcif = new InterruptSource(reg, bit);} void mk_txif_int(PIR *reg, unsigned int bit) { m_txif = new InterruptSource(reg, bit);} bool IsEUSART ( void ) { return is_eusart; }; void set_eusart ( bool is_it ); private: bool is_eusart; InterruptSource *m_rcif; InterruptSource *m_txif; }; #endif gpsim-0.30.0/src/bit.cc0000664000076400007640000000647313045306452011534 00000000000000 /* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include "bit.h" #include "registers.h" Bit::Bit(RegisterValue &rv, unsigned int bit_mask) { d = (rv.get() & bit_mask) ? true : false; i = (rv.geti() & bit_mask) ? false : true; } static void pr(const char *s,Bit &bv) { printf("%s:%d,%d\n",s,bv.isOne(), bv.isKnown()); } ///-- Class test void test_bits() { static bool tested =false; if(tested) return; tested = true; Bit bOne(true,true); pr("one",bOne); Bit a = bOne; Bit b = bOne; Bit c = bOne; b.clear(); pr("a",a); pr("b",b); for (int i=0; i < 4; i++) { switch (i) { case 0: printf("Both known\n"); a.set(true,true); b.set(false,true); break; case 1: printf("a is unknown\n"); a.set(true,false); b.set(false,true); break; case 2: printf("b is unknown\n"); a.set(true,true); b.set(false,false); break; case 3: printf("a and b are unknown\n"); a.set(true,false); b.set(false,false); break; } pr("a",a); pr("b",b); c = a; pr("c=a ->c",c); c = b; pr("c=b ->c",c); c |= a; pr("c|=a ->c",c); c &= a; pr("c&=a ->c",c); c |= b; pr("c|=b ->c",c); c &= b; pr("c&=b ->c",c); c = b; if (c == b) pr("c=b ->c",c); else pr("assignment failed c=b ->c",c); c = a; if (c == a) pr("c=a ->c",c); else pr("assignment failed c=a ->c",c); c = a | a; pr("c=a|a ->c",c); c = a | b; pr("c=a|b ->c",c); c = b | a; pr("c=b|a ->c",c); c = b | b; pr("c=b|b ->c",c); c = !b; pr("c=!b ->c",c); pr(" ->b",b); c = a & a; pr("c=a&a ->c",c); c = a & b; pr("c=a&b ->c",c); c = b & a; pr("c=b&a ->c",c); c = b & b; pr("c=b&b ->c",c); c = a & !a; pr("c=a&!a ->c",c); c = a & !b; pr("c=a&!b ->c",c); c = b & !a; pr("c=b&!a ->c",c); c = b & !b; pr("c=b&!b ->c",c); } Bit d(false,true); a.set(false,false); b.set(false,false); c = a & b & d; pr("a",a); pr("b",b); pr("d",d); pr("c=a&b&d ->c",c); c = (!a) & (!b); pr("c=!a & !b ->c",c); a.set(true,false); b.set(false,true); Bit e = a & !b; pr("a",a); pr("b",b); pr("e=a & !b ->e",e); a.set(false,false); b.set(false,true); e = a & !b; pr("a",a); pr("b",b); pr("e=a & !b ->e",e); a.set(false,false); b.set(true,true); e = a & !b; pr("a",a); pr("b",b); pr("e=a & !b ->e",e); a.set(true,false); b.set(true,true); e = a & !b; pr("a",a); pr("b",b); pr("e=a & !b ->e",e); } gpsim-0.30.0/src/ssp.h0000664000076400007640000002675613041763613011435 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo 2006,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include class InvalidRegister; // Forward reference #ifndef __SSP_H__ #define __SSP_H__ #include "pic-processor.h" #include "14bit-registers.h" #include "ioports.h" #include "pir.h" class PinModule; class PIR1; class PIR_SET; class _14bit_processor; class PicTrisRegister; class _SSPBUF; class _SSPSTAT; class SDI_SignalSink; class SCL_SignalSink; class SS_SignalSink; class SDO_SignalSource; class SDI_SignalSource; class SCK_SignalSource; enum SSP_TYPE { SSP_TYPE_BSSP = 1, SSP_TYPE_SSP, SSP_TYPE_MSSP, SSP_TYPE_MSSP1 }; class SSP_MODULE; class SSP1_MODULE; class _SSPCON : public sfr_register, public TriggerObject { public: enum { SSPM_SPImaster4 = 0x0, // SPI master mode, clock = FOSC/4 SSPM_SPImaster16 = 0x1, // SPI master mode, clock = FOSC/16 SSPM_SPImaster64 = 0x2, // SPI master mode, clock = FOSC/64 SSPM_SPImasterTMR2 = 0x3, // SPI master mode, clock = TMR2/2 SSPM_SPIslaveSS = 0x4, // SPI slave mode, clock = SCK, /SS controlled SSPM_SPIslave = 0x5, // SPI slave mode, clock = SCK, not /SS controlled SSPM_SPImasterAdd = 0xa, // SPI master mode, clock = FOSC/4*(sspadd+1) SSPM_I2Cslave_7bitaddr = 0x6, SSPM_I2Cslave_10bitaddr = 0x7, SSPM_MSSPI2Cmaster = 0x8, SSPM_LoadMaskFunction = 0x9, SSPM_I2Cfirmwaremaster = 0xb, SSPM_I2Cslave_7bitaddr_ints = 0xe, SSPM_I2Cslave_10bitaddr_ints = 0xf, /* None of the documentation I have seen show these, but Scott? thought they were the good name RRR SSPM_I2Cfirmwaremultimaster_7bitaddr_ints = 0xe, SSPM_I2Cfirmwaremaster_10bitaddr_ints = 0xf, */ }; _SSPCON(Processor *pCpu, SSP_MODULE *); // Register bit definitions enum { SSPM0 = 1<<0, SSPM1 = 1<<1, SSPM2 = 1<<2, SSPM3 = 1<<3, CKP = 1<<4, SSPEN = 1<<5, SSPOV = 1<<6, WCOL = 1<<7 }; static const unsigned int SSPM_mask = (SSPM0|SSPM1|SSPM2|SSPM3); virtual void put(unsigned int); virtual void put_value(unsigned int); bool isSSPEnabled() { return (value.get() & SSPEN) == SSPEN; } bool isI2CActive(unsigned int); bool isI2CSlave(unsigned int); bool isI2CMaster(unsigned int); bool isSPIActive(unsigned int); bool isSPIMaster(); void setWCOL(); void setSSPOV() { put_value(value.get() | SSPOV);} void setSSPMODULE(SSP_MODULE *); private: SSP_MODULE *m_sspmod; }; class _SSPCON2 : public sfr_register { public: enum { SEN = 1<<0, // Start or Stretch enable RSEN = 1<<1, // Repeated Start PEN = 1<<2, // Stop condition enable RCEN = 1<<3, // Receive enable bit ACKEN = 1<<4, // Acknowledge Sequence enable bit ACKDT = 1<<5, // Acknowledge Data bit ACKSTAT = 1<<6, // Acknowledge status bit GCEN = 1<<7 // General call enable }; void put(unsigned int new_value); void put_value(unsigned int new_value); _SSPCON2(Processor *pCpu, SSP_MODULE *); private: SSP_MODULE *m_sspmod; }; class _SSP1CON3 : public sfr_register { public: enum { DHEN = 1<<0, // Data hold enable AHEN = 1<<1, // Address hold enable SBCDE = 1<<2, // Slave Mode Bus Collision Detect Enable bit SDAHT = 1<<3, // SDA Hold Time Selection bit BOEN = 1<<4, // Buffer Overwrite Enable bit SCIE = 1<<5, // Start Condition Interrupt Enable bit PCIE = 1<<6, // Stop Condition Interrupt Enable bit ACKTIM = 1<<7 // Acknowledge Time Status bit }; void put(unsigned int new_value); void put_value(unsigned int new_value); _SSP1CON3(Processor *pCpu, SSP1_MODULE *); private: SSP1_MODULE *m_sspmod; }; class _SSPSTAT : public sfr_register { public: // Register bit definitions enum { BF = 1<<0, // Buffer Full UA = 1<<1, // Update Address RW = 1<<2, // Read/Write info S = 1<<3, // Start bit (I2C mode) P = 1<<4, // Stop bit (I2C mode) DA = 1<<5, // Data/Address bit (I2C mode) // below are SSP and MSSP only. This class will force them to // always be 0 if ssptype == SSP_TYPE_BSSP. This will give the // corrent behavior. CKE = 1<<6, // SPI clock edge select SMP = 1<<7 // SPI data input sample phase }; _SSPSTAT(Processor *pCpu, SSP_MODULE *); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); private: SSP_MODULE *m_sspmod; }; class _SSPBUF : public sfr_register { public: SSP_TYPE ssptype; _SSPBUF(Processor *pCpu, SSP_MODULE *); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); bool isFull() { return m_bIsFull; } void setFullFlag(bool bNewFull) { m_bIsFull = bNewFull; } private: SSP_MODULE *m_sspmod; bool m_bIsFull; }; class _SSPMSK : public sfr_register { public: _SSPMSK(Processor *pCpu, const char *_name); virtual void put(unsigned int new_value); }; class _SSPADD : public sfr_register { public: _SSPADD(Processor *pCpu, SSP_MODULE *); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); private: SSP_MODULE *m_sspmod; }; class SPI: public TriggerObject { public: SSP_MODULE *m_sspmod; _SSPBUF *m_sspbuf; _SSPCON *m_sspcon; _SSPSTAT *m_sspstat; SPI(SSP_MODULE *, _SSPCON *, _SSPSTAT *, _SSPBUF *); bool isIdle() { return m_state==eIDLE;} virtual void clock(bool); virtual void start_transfer(); virtual void stop_transfer(); virtual void set_halfclock_break(); virtual void callback(); void newSSPBUF(unsigned int); virtual void startSPI(); protected: unsigned int m_SSPsr; // internal Shift Register enum SSPStateMachine { eIDLE, eACTIVE, eWAITING_FOR_LAST_SMP } m_state; int bits_transfered; Processor *cpu; }; class SPI_1: public SPI { public: _SSP1CON3 *m_ssp1con3; _SSPADD *m_sspadd; SPI_1(SSP1_MODULE *, _SSPCON *, _SSPSTAT *, _SSPBUF *, _SSP1CON3 *, _SSPADD *); virtual void stop_transfer(); virtual void set_halfclock_break(); }; class I2C: public TriggerObject { public: SSP_MODULE *m_sspmod; _SSPBUF *m_sspbuf; _SSPCON *m_sspcon; _SSPSTAT *m_sspstat; _SSPCON2 *m_sspcon2; _SSPADD *m_sspadd; I2C(SSP_MODULE *, _SSPCON *, _SSPSTAT *, _SSPBUF *, _SSPCON2 *, _SSPADD *); virtual void clock(bool); virtual void sda(bool); virtual void callback(); virtual void set_idle(); virtual void newSSPBUF(unsigned int value); virtual void newSSPADD(unsigned int value); virtual void start_bit(); virtual void rstart_bit(); virtual void stop_bit(); virtual void master_rx(); virtual void ack_bit(); virtual bool isIdle(); virtual void setBRG(); virtual void clrBRG(); virtual bool rx_byte(); virtual void bus_collide(); virtual void slave_command(); virtual bool end_ack(); virtual bool match_address(unsigned int sspsr); protected: unsigned int m_SSPsr; // internal Shift Register enum I2CStateMachine { eIDLE, RX_CMD, RX_CMD2, RX_DATA, TX_DATA, CLK_TX_BYTE, CLK_RX_BYTE, CLK_ACKEN, CLK_RSTART, CLK_STOP, CLK_START } i2c_state; int bits_transfered; int phase; guint64 future_cycle; Processor *cpu; }; class I2C_1: public I2C { public: SSP_MODULE *m_sspmod; _SSP1CON3 *m_sspcon3; virtual void clock(bool); virtual void sda(bool); virtual void bus_collide(); I2C_1(SSP_MODULE *, _SSPCON *, _SSPSTAT *, _SSPBUF *, _SSPCON2 *, _SSPADD *, _SSP1CON3 *); }; class SSP_MODULE { public: _SSPBUF sspbuf; _SSPCON sspcon; _SSPSTAT sspstat; _SSPCON2 sspcon2; // MSSP // set to NULL for BSSP (It doesn't have this register) _SSPADD sspadd; _SSPMSK *sspmsk; SSP_MODULE(Processor *); virtual ~SSP_MODULE(); virtual void initialize(PIR_SET *ps, PinModule *_SckPin, PinModule *_SdiPin, PinModule *_SdoPin, PinModule *_SsPin, PicTrisRegister *_i2ctris, SSP_TYPE ssptype = SSP_TYPE_BSSP); virtual void SDI_SinkState(char); virtual void SS_SinkState(char); virtual void SCL_SinkState(char); virtual bool get_SDI_State() { return m_SDI_State;} virtual bool get_SCL_State() { return m_SCL_State;} virtual bool get_SS_State() { return m_SS_State;} virtual void Sck_toggle(); virtual void putStateSDO(char _state); virtual void putStateSCK(char _state); virtual void mk_ssp_int(PIR *reg, unsigned int bit) { m_ssp_if = new InterruptSource(reg, bit);} virtual void mk_bcl_int(PIR *reg, unsigned int bit) { m_bcl_if = new InterruptSource(reg, bit);} virtual void set_sspif(); virtual void set_bclif(); virtual void startSSP(unsigned int value); virtual void stopSSP(unsigned int value); virtual void changeSSP(unsigned int new_value, unsigned int old_value); virtual void ckpSPI(unsigned int value); virtual void newSSPBUF(unsigned int value); virtual void newSSPADD(unsigned int value); virtual void newSSPCON2(unsigned int value); virtual void rdSSPBUF(); virtual void tmr2_clock(); virtual SSP_TYPE ssp_type() { return m_ssptype; } virtual void setSCL(bool); virtual void setSDA(bool); virtual bool SaveSSPsr(unsigned int value); virtual bool isI2CIdle() { return m_i2c->isIdle();} virtual bool isI2CMaster() { return sspcon.isI2CMaster(sspcon.value.get());} virtual bool isI2CSlave() { return sspcon.isI2CSlave(sspcon.value.get());} virtual void releaseSDIpin(); virtual void releaseSDOpin(); virtual void releaseSCLpin(); virtual void releaseSSpin(); virtual void releaseSCKpin(); Processor *cpu; protected: InterruptSource *m_ssp_if; InterruptSource *m_bcl_if; PIR_SET *m_pirset; SPI *m_spi; I2C *m_i2c; PinModule *m_sck; PinModule *m_ss; PinModule *m_sdo; PinModule *m_sdi; PicTrisRegister *m_i2c_tris; SSP_TYPE m_ssptype; bool m_SDI_State; bool m_SCL_State; bool m_SS_State; SCK_SignalSource *m_SckSource; SDO_SignalSource *m_SdoSource; SDI_SignalSource *m_SdiSource; SDI_SignalSink *m_SDI_Sink; SCL_SignalSink *m_SCL_Sink; SS_SignalSink *m_SS_Sink; bool m_sink_set; bool m_sdo_active; bool m_sdi_active; bool m_sck_active; }; class SSP1_MODULE : public SSP_MODULE //MSSP1 { public: SSP1_MODULE(Processor *); ~SSP1_MODULE(); _SSP1CON3 ssp1con3; virtual void initialize(PIR_SET *ps, PinModule *_SckPin, PinModule *_SdiPin, PinModule *_SdoPin, PinModule *_SsPin, PicTrisRegister *_i2ctris, SSP_TYPE ssptype = SSP_TYPE_MSSP1); void set_sckPin(PinModule *_sckPin); void set_sdiPin(PinModule *_sdiPin); void set_sdoPin(PinModule *_sdoPin); PinModule *get_sdoPin() { return m_sdo;} void set_ssPin(PinModule *_ssPin); void set_tris(PicTrisRegister *_i2ctris) { m_i2c_tris = _i2ctris;} virtual void changeSSP(unsigned int new_value, unsigned int old_value); virtual bool SaveSSPsr(unsigned int value); }; #endif // __SSP_H__ gpsim-0.30.0/src/p16x8x.h0000664000076400007640000000476613041763624011705 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P16X8X_H__ #define __P16X8X_H__ #include "14bit-processors.h" #include "intcon.h" class P16X8X : public Pic14Bit { public: P16X8X(const char *_name=0, const char *desc=0); ~P16X8X(); virtual void create_sfr_map(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create_iopin_map(); virtual void create(int ram_top); virtual unsigned int register_memory_size () const { return 0x100; } protected: unsigned int ram_top; }; class P16C84 : public P16X8X { public: P16C84(const char *_name=0, const char *desc=0); virtual PROCESSOR_TYPE isa(){return _P16C84_;}; virtual void create(int ram_top); virtual unsigned int program_memory_size() const { return 0x400; } static Processor *construct(const char *name); }; class P16F84 : public P16X8X { public: virtual PROCESSOR_TYPE isa(){return _P16F84_;}; virtual void create(int ram_top); virtual unsigned int program_memory_size() const { return 0x400; }; P16F84(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16CR84 : public P16F84 { public: virtual PROCESSOR_TYPE isa(){return _P16CR84_;}; P16CR84(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16F83 : public P16X8X { public: virtual PROCESSOR_TYPE isa(){return _P16F83_;}; virtual unsigned int program_memory_size() const { return 0x200; }; virtual void create(int ram_top); P16F83(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16CR83 : public P16F83 { public: virtual PROCESSOR_TYPE isa(){return _P16CR83_;}; P16CR83(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; #endif gpsim-0.30.0/src/registers.cc0000664000076400007640000003777013077523203012771 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "xref.h" #include "processor.h" #include "registers.h" #include "trace.h" unsigned int count_bits(unsigned int ui) { unsigned int bits=0; while (ui) { ui &= (ui-1); bits++; } return bits; } //======================================================================== // toString // // Convert a RegisterValue type to a string. // // A RegisterValue type allows the bits of a register to take on three // values: High, Low, or undefined. If all of the bits are defined, // then this routine will convert register value to a hexadecimal string. // Any undefined bits within a nibble will cause the associated nibble to // be undefined and will get converted to a question mark. // char * RegisterValue::toString(char *str, int len, int regsize) const { if(str && len) { RegisterValue rv = *this; char hex2ascii[] = "0123456789ABCDEF"; char undefNibble = '?'; int i; int m = regsize * 2 + 1; if(len < m) m = len; m--; for(i=0; i < m; i++) { if(rv.init & 0x0f) str[m-i-1] = undefNibble; else str[m-i-1] = hex2ascii[rv.data & 0x0f]; rv.init >>= 4; rv.data >>= 4; } str[m] = 0; } return str; } //======================================================================== // SplitBitString // // The purpose of this routine is to convert a string of bitnames into // an array of names. The string is formatted like: // // b1.b2.b3 // // In other words, a period is the delimeter between the names. // This gets converted to: // // b1 // b2 // b2 // // INPUTS // n - number of names // in - input string formatted as described // in2 - if 'in' is NULL, then all 'n' names will be 'in2' // // OUTPUTS // out - an array to hold the strings. // // Note, the input string 'in' will be modified such that all of the '.'s will // get turned into string terminating 0's. // static void SplitBitString(int n, const char **out, char *in, const char *in2) { if(!in) { for(int i=0; i " << out[i] << endl; } } } //======================================================================== // toBitStr // // Convert a RegisterValue type to a bit string // // Given a pointer to a string, this function will convert a register // value into a string of ASCII characters. If no names are given // for the bits, then the default values of 'H', 'L', and '?' are // used for high, low and undefined. // // The input 'BitPos' is a bit mask that has a bit set for each bit that // the user wishes to display. // char * RegisterValue::toBitStr(char *s, int len, unsigned int BitPos, const char *cByteSeparator, const char *HiBitNames, const char *LoBitNames, const char *UndefBitNames) const { unsigned int i,mask,max; if(!s || len<=0) return 0; max = 32; unsigned int nBits = count_bits(BitPos); if(nBits >= max) nBits = max; const char *HiNames[32]; const char *LoNames[32]; const char *UndefNames[32]; char *cHi = HiBitNames ? strdup(HiBitNames) : 0; char *cLo = LoBitNames ? strdup(LoBitNames) : 0; char *cUn = UndefBitNames ? strdup(UndefBitNames) : 0; SplitBitString(nBits, HiNames, cHi, "1"); SplitBitString(nBits, LoNames, cLo, "0"); SplitBitString(nBits, UndefNames, cUn, "?"); char *dest = s; int bitNumber=31; for(i=0,mask=1<<31; mask; mask>>=1,bitNumber--) { if(BitPos & mask) { const char *H = HiNames[i]; const char *L = LoNames[i]; const char *U = UndefNames[i]; const char *c = (init & mask) ? U : ((data & mask) ? H : L); strncpy(dest, c, len); int l = strlen(c); len -= l; dest += l; *dest = 0; if(i++>nBits || len < 0) break; if(cByteSeparator && bitNumber && ((bitNumber%8)==0)) { strncpy(dest, cByteSeparator, len); int l = strlen(cByteSeparator); len -= l; dest += l; *dest = 0; if(len < 0) break; } } } free(cHi); free(cLo); free(cUn); return s; } //-------------------------------------------------- // Member functions for the file_register base class //-------------------------------------------------- // // For now, initialize the register with valid data and set that data equal to 0. // Eventually, the initial value will be marked as 'uninitialized. Register::Register(Module *_cpu, const char *pName, const char *pDesc) : Value(pName,pDesc,_cpu), value(RegisterValue(0, 0)), address(AN_INVALID_ADDRESS), alias_mask(0), por_value(RegisterValue(0, 0)), m_replaced(0) { set_xref(new XrefObject(this)); read_access_count=0; write_access_count=0; mValidBits = 0xFF; } Register::~Register() { if (cpu) { //cout << "Removing register from ST:" << name_str << " addr "<< this << endl; cpu->removeSymbol(this); } } //------------------------------------------------------------ int Register::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *expr) { return get_bp().set_break(bt, at, this, expr); } int Register::clear_break() { return -1; } //------------------------------------------------------------ // get() // // Return the contents of the file register. // (note - breakpoints on file register reads // are not checked here. Instead, a breakpoint // object replaces those instances of file // registers for which we wish to monitor. // So a file_register::get call will invoke // the breakpoint::get member function. Depending // on the type of break point, this get() may // or may not get called). unsigned int Register::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } //------------------------------------------------------------ // put() // // Update the contents of the register. // See the comment above in file_register::get() // with respect to break points // void Register::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } bool Register::get_bit(unsigned int bit_number) { return (value.get() & (1<register_size(); } //----------------------------------------------------------- // set_write_trace // set_read_trace // // These functions initialize the trace type to be used for // register reads and writes. // void Register::set_write_trace(RegisterValue &rv) { write_trace = rv; } void Register::set_read_trace(RegisterValue &rv) { read_trace = rv; } //------------------------------------------------------------ char * Register::toString(char *str, int len) { return getRV_notrace().toString(str, len, register_size()*2); } char * Register::toBitStr(char *s, int len) { unsigned int bit_length = register_size() * 8; unsigned int bits = (1<addSymbol(this, &new_name); } } } //------------------------------------------------------------------------ // set -- assgin the value of some other object to this Register // // This is used (primarily) during Register stimuli processing. If // a register stimulus is attached to this register, then it will // call ::set() and supply a Value pointer. void Register::set(Value * pVal) { Register *pReg = dynamic_cast(pVal); if (pReg) { putRV(pReg->getRV()); return; } if (pVal) { put_value( (unsigned int)*pVal); } } //------------------------------------------------------------------------ // copy - create a new Value object that's a 'copy' of this object // // We really don't perform a true copy. Instead, an Integer object // is created containing the same numeric value of this object. // This code is called during expression parsing. *NOTE* this copied // object can be assigned a new value, however that value will not // propagate to the Register! Value *Register::copy() { Value *val = new ValueWrapper(this); return val; } void Register::get(gint64 &i) { i = get_value(); } //-------------------------------------------------- //-------------------------------------------------- //-------------------------------------------------- sfr_register::sfr_register(Module *pCpu, const char *pName, const char *pDesc) : Register(pCpu,pName,pDesc), wdtr_value(0,0) {} void sfr_register::reset(RESET_TYPE r) { switch (r) { case POR_RESET: putRV(por_value); break; case WDT_RESET: // Most registers simply retain their value across WDT resets. //putRV(wdtr_value); break; default: break; } } //-------------------------------------------------- //-------------------------------------------------- //-------------------------------------------------- // member functions for the InvalidRegister class //-------------------------------------------------- void InvalidRegister::put(unsigned int new_value) { cout << "attempt write to invalid file register\n"; if (address != AN_INVALID_ADDRESS) cout << " address 0x" << hex << address << ','; cout << " value 0x" << hex << new_value << endl; if(((Processor*)cpu)->getBreakOnInvalidRegisterWrite()) { bp.halt(); } trace.raw(write_trace.get() | value.get()); return; } unsigned int InvalidRegister::get() { cout << "attempt read from invalid file register\n"; if (address != AN_INVALID_ADDRESS) cout << " address 0x" << hex << address << endl; trace.raw(read_trace.get() | value.get()); if(((Processor*)cpu)->getBreakOnInvalidRegisterRead()) { bp.halt(); } return(0); } InvalidRegister::InvalidRegister(Processor *pCpu, const char *pName, const char *pDesc) : Register(pCpu,pName,pDesc) {} RegisterCollection::RegisterCollection (Processor *pProcessor, const char *pC_collection_name, Register **ppRegisters, unsigned int uiSize) : IIndexedCollection(16), m_ReturnValue(0) { m_pProcessor = pProcessor; gpsimObject::new_name(pC_collection_name); m_ppRegisters = ppRegisters; m_uSize = uiSize; pProcessor->addSymbol(this); } RegisterCollection:: ~RegisterCollection() { if (m_pProcessor) m_pProcessor->removeSymbol(this); } // Displays in symbol GUI void RegisterCollection::get(char *return_str, int len) { if (return_str) { strncpy(return_str, "", len); } } unsigned int RegisterCollection::GetSize() { return m_uSize; } Value &RegisterCollection::GetAt(unsigned int uIndex, Value *) { if(uIndex > m_uSize) { throw Error("index is out of range"); } m_ReturnValue.set((int)m_ppRegisters[uIndex]->get_value()); m_ReturnValue.setBitmask(m_pProcessor->register_mask()); ostringstream sIndex; if (m_pProcessor) sIndex << m_pProcessor->name() << "." ; sIndex << Value::name() << "[" << hex << m_szPrefix << uIndex << "]" << '\000'; m_ReturnValue.new_name(sIndex.str().c_str()); return m_ReturnValue; } void RegisterCollection::SetAt(unsigned int uIndex, Value *pValue) { if(uIndex > m_uSize) { throw Error("index is out of range"); } Integer *pInt = dynamic_cast(pValue); if(pInt == NULL) { throw Error("rValue is not an Integer"); } else { m_ppRegisters[uIndex]->put((unsigned int)(int)*pInt); } } void RegisterCollection::ConsolidateValues(int &iColumnWidth, vector &aList, vector &aValue) { unsigned int uFirstIndex = 0; unsigned int uIndex; Register * pReg = m_ppRegisters[0]; Integer uLastValue(pReg->getRV_notrace().data); uLastValue.setBitmask(m_pProcessor->register_mask()); for(uIndex = 0; uIndex < m_uSize; uIndex++) { pReg = m_ppRegisters[uIndex]; RegisterValue rvValue = pReg->getRV_notrace(); if((unsigned int)uLastValue != rvValue.data) { PushValue(uFirstIndex, uIndex, &uLastValue, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); uFirstIndex = uIndex; uLastValue = rvValue.data; } } uIndex--; // Record the last set of elements if(uFirstIndex <= uIndex) { PushValue(uFirstIndex, uIndex, &uLastValue, aList, aValue); iColumnWidth = max(iColumnWidth, (int)aList.back().size()); } } //void RegisterCollection::SetAt(ExprList_t* pIndexers, Expression *pExpr) { // throw Error("RegisterCollection::SetAt() not implemented"); //} unsigned int RegisterCollection::GetLowerBound() { return 0; } unsigned int RegisterCollection::GetUpperBound() { return m_uSize - 1; } gpsim-0.30.0/src/uart.cc0000664000076400007640000012560113112422505011715 00000000000000/* Copyright (C) 1998,1999 Scott Dattalo Copyright (C) 2014 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include "../config.h" #include "stimuli.h" #include "uart.h" #include "14bit-processors.h" #include "14bit-tmrs.h" #define p_cpu ((Processor *)cpu) // defining EUSART_PIN causes TX pin direction to be set for EUSART devices //#define EUSART_PIN //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //-------------------------------------------------- // //-------------------------------------------------- // Drive output for TX pin class TXSignalSource : public SignalControl { public: TXSignalSource(_TXSTA *_txsta) : m_txsta(_txsta) { assert(m_txsta); } ~TXSignalSource() { } virtual char getState() { return m_txsta->getState(); } virtual void release() { m_txsta->releasePin(); } private: _TXSTA *m_txsta; }; // Set TX pin to output class TXSignalControl : public SignalControl { public: TXSignalControl(_TXSTA *_txsta) : m_txsta(_txsta) { } ~TXSignalControl() { } virtual char getState() { return '0'; } virtual void release() { m_txsta->releasePin(); } private: _TXSTA *m_txsta; }; // set Synchronous DT pin direction class RCSignalControl : public SignalControl { public: RCSignalControl(_RCSTA *_rcsta) : m_rcsta(_rcsta) { } ~RCSignalControl() { } virtual char getState() { return '0'; } //virtual char getState() { return m_rcsta->getDir(); } virtual void release() { m_rcsta->releasePin(); } private: _RCSTA *m_rcsta; }; // Drive date of DT pin when transmitting class RCSignalSource : public SignalControl { public: RCSignalSource(_RCSTA *_rcsta) : m_rcsta(_rcsta) { assert(m_rcsta); } ~RCSignalSource() { } virtual char getState() { return m_rcsta->getState(); } virtual void release() { m_rcsta->releasePin(); } private: _RCSTA *m_rcsta; }; //-------------------------------------------------- // //-------------------------------------------------- // Report state changes on incoming RX pin class RXSignalSink : public SignalSink { public: RXSignalSink(_RCSTA *_rcsta) : m_rcsta(_rcsta) { assert(_rcsta); } virtual void setSinkState(char new3State) { m_rcsta->setState(new3State); } virtual void release() {delete this; } private: _RCSTA *m_rcsta; }; //-------------------------------------------------- // //-------------------------------------------------- // Report state changes on incoming Clock pin for Synchronous slave mode class CLKSignalSink : public SignalSink { public: CLKSignalSink(_RCSTA *_rcsta) : m_rcsta(_rcsta) { assert(_rcsta); } virtual void setSinkState(char new3State) { m_rcsta->clock_edge(new3State); } // virtual void release() { delete this; } virtual void release() {delete this; } private: _RCSTA *m_rcsta; }; //----------------------------------------------------------- _RCSTA::_RCSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART) : sfr_register(pCpu, pName, pDesc), rcreg(0), spbrg(0), txsta(0), state(_RCSTA::RCSTA_DISABLED), mUSART(pUSART), m_PinModule(0), m_sink(0), m_cRxState('?'), SourceActive(false), m_control(0), m_source(0), m_DTdirection('0'), old_clock_state('?') { assert(mUSART); } _RCSTA::~_RCSTA() { if (SourceActive && m_PinModule) { m_PinModule->setSource(0); m_PinModule->setControl(0); } if (m_control) { delete m_source; delete m_control; } } //----------------------------------------------------------- _TXSTA::_TXSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART) : sfr_register(pCpu, pName, pDesc), txreg(0), spbrg(0), mUSART(pUSART), m_PinModule(0), m_source(0), m_control(0), SourceActive(false), m_cTxState('?'), bInvertPin(0) { assert(mUSART); } _TXSTA::~_TXSTA() { if (SourceActive && m_PinModule) { m_PinModule->setSource(0); m_PinModule->setControl(0); } if (m_control) { delete m_source; delete m_control; } } //----------------------------------------------------------- _RCREG::_RCREG(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART) : sfr_register(pCpu, pName, pDesc), fifo_sp(0), mUSART(pUSART), m_rcsta(0) { assert(mUSART); } _TXREG::_TXREG(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART) : sfr_register(pCpu, pName, pDesc), m_txsta(0), mUSART(pUSART) { assert(mUSART); } _BAUDCON::_BAUDCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } _SPBRG::_SPBRG(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), txsta(0), rcsta(0), brgh(0), baudcon(0), start_cycle(0), last_cycle(0), future_cycle(0), running(false), skip(0) { } _SPBRGH::_SPBRGH(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), m_spbrg(0) { } //----------------------------------------------------------- // TXREG - USART Transmit Register // // writing to this register causes the PIR1::TXIF bit to clear. // my reading of the spec is this happens at the end of the next pic // instruction. If the shift register is empty the bit will then be set // one pic instruction later. Otherwise the bit is set when the shift // register empties. RRR 10/2014 void _TXREG::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); Dprintf(("txreg just got a new value:0x%x\n",new_value)); assert(m_txsta); assert(m_rcsta); // The transmit register has data, // so clear the TXIF flag full = true; get_cycles().set_break(get_cycles().get() + 1, this); if(m_txsta->bTRMT() && m_txsta->bTXEN()) { // If the transmit buffer is empty and the transmitter is enabled // then transmit this new data now... get_cycles().set_break(get_cycles().get() + 2, this); if (m_txsta->bSYNC()) m_rcsta->sync_start_transmitting(); else m_txsta->start_transmitting(); } else if(m_txsta->bTRMT() && m_txsta->bSYNC()) { m_txsta->value.put(m_txsta->value.get() & ~ _TXSTA::TRMT); } } void _TXREG::put_value(unsigned int new_value) { put(new_value); update(); } void _TXREG::callback() { Dprintf(("TXREG callback - time:%" PRINTF_GINT64_MODIFIER "x full %d\n",get_cycles().get(), full)); if (full) { mUSART->full(); full = false; } else { mUSART->emptyTX(); } } void _TXREG::callback_print() { cout << "TXREG " << name() << " CallBack ID " << CallBackID << '\n'; } //----------------------------------------------------------- // TXSTA - setIOpin - assign the I/O pin associated with the // the transmitter. void _TXSTA::setIOpin(PinModule *newPinModule) { if (!m_source) { m_source = new TXSignalSource(this); m_control = new TXSignalControl(this); } else if (m_PinModule) // disconnect old pin { disableTXPin(); } m_PinModule = newPinModule; if(bTXEN() && rcsta->bSPEN()) { enableTXPin(); } } void _TXSTA::disableTXPin() { if (m_PinModule) { m_PinModule->setSource(0); m_PinModule->setControl(0); m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str()); if (m_clkSink) { m_PinModule->removeSink(m_clkSink); m_clkSink->release(); m_clkSink = 0; } } } void _TXSTA::enableTXPin() { char out; assert(m_PinModule); if (m_PinModule && !SourceActive) { char reg_no = *(name().c_str() + 5); if (bSYNC()) { char ck[4] = "CK"; if (reg_no) { ck[2] = reg_no; ck[3] = 0; } m_PinModule->getPin().newGUIname(ck); out = '0'; if (!bCSRC()) // slave clock { if (!m_clkSink) { m_clkSink = new CLKSignalSink(rcsta); m_PinModule->addSink(m_clkSink); rcsta->set_old_clock_state(m_PinModule->getPin().getState()); } mUSART->emptyTX(); return; } } else { char tx[4] = "TX"; if (reg_no) { tx[2] = reg_no; tx[3] = 0; } m_PinModule->getPin().newGUIname(tx); out = '1'; } m_PinModule->setSource(m_source); #ifdef EUSART_PIN if(mUSART->IsEUSART()) m_PinModule->setControl(m_control); #else m_PinModule->setControl(m_control); #endif putTXState(out); SourceActive = true; } mUSART->emptyTX(); } void _TXSTA::releasePin() { if (m_PinModule && SourceActive) { m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str()); m_PinModule->setControl(0); SourceActive = false; } } //----------------------------------------------------------- // TXSTA - putTXState - update the state of the TX output pin // void _TXSTA::putTXState(char newTXState) { m_cTxState = bInvertPin ? newTXState ^ 1 : newTXState; if (m_PinModule) m_PinModule->updatePinModule(); } //----------------------------------------------------------- // TXSTA - Transmit Register Status and Control void _TXSTA::put_value(unsigned int new_value) { put(new_value); update(); } void _TXSTA::put(unsigned int new_value) { unsigned int old_value = value.get(); trace.raw(write_trace.get() | value.get()); if ( ! mUSART->IsEUSART() ) new_value &= ~SENDB; // send break only supported on EUSART // The TRMT bit is controlled entirely by hardware. // It is high if the TSR has any data. //RRRvalue.put((new_value & ~TRMT) | ( (bit_count) ? 0 : TRMT)); value.put((new_value & ~TRMT) | (old_value & TRMT)); Dprintf(("%s TXSTA value=0x%x\n",name().c_str(), value.get())); if( (old_value ^ value.get()) & TXEN) { // The TXEN bit has changed states. // // If transmitter is being enabled and the transmit register // has some data that needs to be sent, then start a // transmission. // If the transmitter is being disabled, then abort any // transmission. if(value.get() & TXEN) { Dprintf(("TXSTA - enabling transmitter\n")); if (rcsta->bSPEN()) { if (bSYNC() && ! bTRMT() && !rcsta->bSREN() && !rcsta->bCREN()) { // need to check bTRMT before calling enableTXPin enableTXPin(); rcsta->sync_start_transmitting(); } else enableTXPin(); } } else { stop_transmitting(); mUSART->full(); // Turn off TXIF disableTXPin(); } } } //------------------------------------------------------------ // char _TXSTA::getState() { return m_cTxState; } // _TXSTA::stop_transmitting() // void _TXSTA::stop_transmitting() { Dprintf(("stopping a USART transmission\n")); bit_count = 0; value.put(value.get() | TRMT); // It's not clear from the documentation as to what happens // to the TXIF when we are aborting a transmission. According // to the documentation, the TXIF is set when the TXEN bit // is set. In other words, when the Transmitter is enabled // the txreg is emptied (and hence TXIF set). But what happens // when TXEN is cleared? Should we clear TXIF too? // // There is one sentence that says when the transmitter is // disabled that the whole transmitter is reset. So I interpret // this to mean that the TXIF gets cleared. I could be wrong // (and I don't have a way to test it on a real device). // // Another interpretation is that TXIF retains it state // through changing TXEN. However, when SPEN (serial port) is // set then the whole usart is reinitialized and TXIF will // get set. // // txreg->full(); // Clear TXIF } void _TXSTA::start_transmitting() { Dprintf(("starting a USART transmission\n")); // Build the serial byte that's about to be transmitted. // I doubt the pic really does this way, but gpsim builds // the entire bit stream including the start bit, 8 data // bits, optional 9th data bit and the stop, and places // this into the tsr register. But since the contents of // the tsr are inaccessible, I guess we'll never know. // // (BTW, if you look carefully you may puzzle over why // there appear to be 2 stop bits in the packet built // below. Well, it's because the way gpsim implements // the transmit logic. The second stop bit doesn't // actually get transmitted - it merely causes the first // stop bit to get transmitted before the TRMT bit is set. // // RRR I believe the above paragraph is a mis-understanding // The tsr register becomes empty, and the TRMT flag goes high, // when we start to transmit the stop bit. Note that transmision // is synchronous with the baud clock, so the start of transmision // of a new character waits for the next callback. This delay maybe, // in fact, the stop bit of the previous transmision, // // [Recall that the TRMT bit indicates when the tsr // {transmit shift register} is empty. It's not tied to // an interrupt pin, so the pic application software // most poll this bit. // // RRR Also The following is wrong: // This bit is set after the STOP // bit is transmitted.] This is a cheap trick that saves // one comparison in the callback code.) // The start bit, which is always low, occupies bit position // zero. The next 8 bits come from the txreg. assert(txreg); if(!txreg) return; if (value.get() & SENDB) { transmit_break(); return; } tsr = txreg->value.get() << 1; // Is this a 9-bit data transmission? if(value.get() & TX9) { // Copy the stop bit and the 9th data bit to the tsr. // (See note above for the reason why two stop bits // are appended to the packet.) tsr |= ( (value.get() & TX9D) ? (3<<9) : (2<<9)); bit_count = 11; // 1 start, 9 data, 1 stop } else { // The stop bit is always high. (See note above // for the reason why two stop bits are appended to // the packet.) tsr |= (1<<9); bit_count = 10; // 1 start, 8 data, 1 stop } // Set a callback breakpoint at the next SPBRG edge if(cpu) get_cycles().set_break(spbrg->get_cpu_cycle(1), this); // The TSR now has data, so clear the Transmit Shift // Register Status bit. trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~TRMT); } void _TXSTA::transmit_break() { Dprintf(("starting a USART sync-break transmission\n")); // A sync-break is 13 consecutive low bits and one stop bit. Use the // standard transmit logic to achieve this if(!txreg) return; tsr = 1<<13; bit_count = 14; // 13 break, 1 stop // The TSR now has data, so clear the Transmit Shift // Register Status bit. trace.raw(write_trace.get() | value.get()); value.put(value.get() & ~TRMT); callback(); // sent start bit } void _TXSTA::transmit_a_bit() { if(bit_count) { Dprintf(("Transmit bit #%x: bit val:%u time:0x%" PRINTF_GINT64_MODIFIER "x\n", bit_count, (tsr & 1), get_cycles().get())); putTXState((tsr & 1) ? '1' : '0'); tsr >>= 1; --bit_count; } } void _TXSTA::callback() { Dprintf(("TXSTA callback - time:%" PRINTF_GINT64_MODIFIER "x\n",get_cycles().get())); transmit_a_bit(); if(!bit_count) { value.put(value.get() & ~SENDB); // tsr is empty. // If there is any more data in the TXREG, then move it to // the tsr and continue transmitting other wise set the TRMT bit // (See the note above about the 'extra' stop bit that was stuffed // into the tsr register. if(mUSART->bIsTXempty()) value.put(value.get() | TRMT); else { start_transmitting(); mUSART->emptyTX(); } } else { // bit_count is non zero which means there is still // data in the tsr that needs to be sent. if(cpu) { get_cycles().set_break(spbrg->get_cpu_cycle(1),this); } } } void _TXSTA::callback_print() { cout << "TXSTA " << name() << " CallBack ID " << CallBackID << '\n'; } //----------------------------------------------------------- // Receiver portion of the USART //----------------------------------------------------------- // // First RCSTA -- Receiver Control and Status // The RCSTA class controls the usart reception. The PIC usarts have // two modes: synchronous and asynchronous. // Asynchronous reception: // Asynchronous reception means that there is no external clock // available for telling the usart when to sample the data. Sampling // timing is all based upon the PIC's oscillator. The SPBRG divides // this clock down to a frequency that's appropriate to the data // being received. (e.g. 9600 baud defines the rate at which data // will be sent to the pic - 9600 bits per second.) The start bit, // which is a high to low transition on the receive line, defines // when the usart should start sampling the incoming data. // The pic usarts sample asynchronous data three times in "approximately // the middle" of each bit. The data sheet is not exactly specific // on what's the middle. Consequently, gpsim takes a stab/ educated // guess on when these three samples are to be taken. Once the // three samples are taken, then simple majority summing determines // the sample e.g. if two out of three of the samples are high, then // then the data bit is considered high. // //----------------------------------------------------------- // RCSTA::put // void _RCSTA::put(unsigned int new_value) { unsigned int diff; unsigned int readonly = value.get() & (RX9D | OERR | FERR); diff = new_value ^ value.get(); trace.raw(write_trace.get() | value.get()); assert(txsta); assert(txsta->txreg); assert(rcreg); // If SPEN being turned off, clear all readonly bits if (diff & SPEN && !(new_value & SPEN)) { readonly = 0; // clear receive stack (and rxif) rcreg->pop(); rcreg->pop(); } // if CREN is being cleared, make sure OERR is clear else if (diff & CREN && !(new_value & CREN)) readonly &= (RX9D | FERR); value.put( readonly | (new_value & ~(RX9D | OERR | FERR))); if (!txsta->bSYNC()) // Asynchronous case { if (diff & (SPEN | CREN)) // RX status change { if ((value.get() & (SPEN | CREN)) == (SPEN | CREN)) { enableRCPin(); if (txsta->bTXEN()) txsta->enableTXPin(); spbrg->start(); start_receiving(); // If the rx line is low, then go ahead and start receiving now. if (m_cRxState == '0' || m_cRxState == 'w') receive_start_bit(); // Clear overrun error when turning on RX value.put( value.get() & (~OERR) ); } else // RX off, check TX { if (m_PinModule) m_PinModule->getPin().newGUIname( m_PinModule->getPin().name().c_str()); stop_receiving(); state = RCSTA_DISABLED; if (bSPEN()) // RX off but TX may still be active { if (txsta->bTXEN()) //TX output active txsta->enableTXPin(); else // TX off txsta->disableTXPin(); } return; } } } else // synchronous case { if (diff & RX9) { if (bRX9()) bit_count = 9; else bit_count = 8; } if (diff & (SPEN | CREN | SREN )) // RX status change { // Synchronous transmit (SREN & CREN == 0) if ((value.get() & (SPEN | SREN | CREN)) == SPEN) { enableRCPin(DIR_OUT); if (txsta->bTXEN()) txsta->enableTXPin(); return; } // Synchronous receive (SREN | CREN != 0) else if (value.get() & (SPEN)) { enableRCPin(DIR_IN); txsta->enableTXPin(); rsr = 0; if (bRX9()) bit_count = 9; else bit_count = 8; if (txsta->bCSRC()) // Master mode { sync_next_clock_edge_high = true; txsta->putTXState('0'); // clock low callback(); } return; } else // turn off UART { if (m_PinModule) { m_PinModule->getPin().newGUIname( m_PinModule->getPin().name().c_str()); if (m_sink) { m_PinModule->removeSink(m_sink); m_sink->release(); m_sink = 0; } } txsta->disableTXPin(); } } } } void _RCSTA::enableRCPin(char direction) { if (m_PinModule) { char reg_no = *(name().c_str() + 5); if (txsta->bSYNC()) // Synchronous case { if (!m_source) { m_source = new RCSignalSource(this); m_control = new RCSignalControl(this); } if (direction == DIR_OUT) { m_DTdirection = '0'; if (SourceActive == false) { m_PinModule->setSource(m_source); m_PinModule->setControl(m_control); SourceActive = true; } putRCState('0'); } else { m_DTdirection = '1'; if (SourceActive == true) { m_PinModule->setSource(0); m_PinModule->setControl(0); m_PinModule->updatePinModule(); } } char dt[4] = "DT"; dt[2] = reg_no; dt[3] = 0; m_PinModule->getPin().newGUIname(dt); } else // Asynchronous case { char rx[4] = "RX"; rx[2] = reg_no; rx[3] = 0; m_PinModule->getPin().newGUIname(rx); } } } void _RCSTA::disableRCPin() { } void _RCSTA::releasePin() { if (m_PinModule && SourceActive) { m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str()); m_PinModule->setControl(0); SourceActive = false; } } void _RCSTA::put_value(unsigned int new_value) { put(new_value); update(); } //----------------------------------------------------------- // RCSTA - putRCState - update the state of the DTx output pin // only used for Synchronous mode // void _RCSTA::putRCState(char newRCState) { bInvertPin = mUSART->baudcon.rxdtp(); m_cTxState = bInvertPin ? newRCState ^ 1 : newRCState; if (m_PinModule) m_PinModule->updatePinModule(); } //----------------------------------------------------------- // RCSTA - setIOpin - assign the I/O pin associated with the // the receiver. void _RCSTA::setIOpin(PinModule *newPinModule) { if (m_sink) { if (m_PinModule) { m_PinModule->removeSink(m_sink); if(value.get() & SPEN) m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str()); } } else m_sink = new RXSignalSink(this); m_PinModule = newPinModule; if (m_PinModule) { m_PinModule->addSink(m_sink); old_clock_state = m_PinModule->getPin().getState(); if(value.get() & SPEN) m_PinModule->getPin().newGUIname("RX/DT"); } } //----------------------------------------------------------- // RCSTA - setState // This gets called whenever there's a change detected on the RX pin. // The usart is only interested in those changes when it is waiting // for the start bit. Otherwise, the rcsta callback function will sample // the rx pin (if we're receiving). void _RCSTA::setState(char new_RxState) { Dprintf((" %s setState:%c\n",name().c_str(), new_RxState)); m_cRxState = new_RxState; if( (state == RCSTA_WAITING_FOR_START) && (m_cRxState =='0' || m_cRxState=='w')) receive_start_bit(); } // Transmit in synchronous mode // void _RCSTA::sync_start_transmitting() { assert(txreg); rsr = txreg->value.get(); if (txsta->bTX9()) { rsr |= (txsta->bTX9D() << 8); bit_count = 9; } else bit_count = 8; txsta->value.put(txsta->value.get() & ~ _TXSTA::TRMT); if (txsta->bCSRC()) { sync_next_clock_edge_high = true; txsta->putTXState('0'); // clock low callback(); } } void _RCSTA::set_old_clock_state(char new3State) { bool state = (new3State == '1' || new3State == 'W'); state = mUSART->baudcon.txckp() ? !state : state; old_clock_state = state; } void _RCSTA::clock_edge(char new3State) { bool state = (new3State == '1' || new3State == 'W'); // invert clock, if requested state = mUSART->baudcon.txckp() ? !state : state; if (old_clock_state == state) return; old_clock_state = state; if (value.get() & SPEN) { // Transmitting ? if ((value.get() & ( CREN | SREN)) == 0) { if (state) // clock high, output data { if (bit_count) { putRCState((rsr & 1) ? '1' : '0'); rsr >>= 1; bit_count--; } } else { if(mUSART->bIsTXempty()) { txsta->value.put(txsta->value.get() | _TXSTA::TRMT); } else { sync_start_transmitting(); mUSART->emptyTX(); } } } else // receiving { if (!state) // read data as clock goes low { bool data = m_PinModule->getPin().getState(); data = mUSART->baudcon.rxdtp() ? !data : data; if (bRX9()) rsr |= data << 9; else rsr |= data << 8; rsr >>= 1; if (--bit_count == 0) { rcreg->push(rsr); if (bRX9()) bit_count = 9; else bit_count = 8; rsr = 0; } } } } } //----------------------------------------------------------- // RCSTA::receive_a_bit(unsigned int bit) // // A new bit needs to be copied to the the Receive Shift Register. // If the receiver is receiving data, then this routine will copy // the incoming bit to the rsr. If this is the last bit, then a // check will be made to see if we need to set up for the next // serial byte. // If this is not the last bit, then the receive state machine. void _RCSTA::receive_a_bit(unsigned int bit) { // If we're waiting for the start bit and this isn't it then // we don't need to look any further Dprintf(("%s receive_a_bit state:%u bit:%u time:0x%" PRINTF_GINT64_MODIFIER "x\n", name().c_str(), state, bit, get_cycles().get())); if( state == RCSTA_MAYBE_START) { if (bit) state = RCSTA_WAITING_FOR_START; else state = RCSTA_RECEIVING; return; } if (bit_count == 0) { // we should now have the stop bit if (bit) { // got the stop bit // If the rxreg has data from a previous reception then // we have a receiver overrun error. // cout << "rcsta.rsr is full\n"; if((value.get() & RX9) == 0) rsr >>= 1; // Clear any framing error value.put(value.get() & (~FERR) ); // copy the rsr to the fifo if(rcreg) rcreg->push( rsr & 0x1ff); Dprintf(("%s _RCSTA::receive_a_bit received 0x%02X\n",name().c_str(), rsr & 0x1ff)); } else { //no stop bit; framing error value.put(value.get() | FERR); // copy the rsr to the fifo if(rcreg) rcreg->push( rsr & 0x1ff); } // If we're continuously receiving, then set up for the next byte. // FIXME -- may want to set a half bit delay before re-starting... if(value.get() & CREN) start_receiving(); else state = RCSTA_DISABLED; return; } // Copy the bit into the Receive Shift Register if(bit) rsr |= 1<<9; //cout << "Receive bit #" << bit_count << ": " << (rsr&(1<<9)) << '\n'; rsr >>= 1; bit_count--; } void _RCSTA::stop_receiving() { rsr = 0; bit_count = 0; state = RCSTA_DISABLED; } void _RCSTA::start_receiving() { Dprintf(("%s The USART is starting to receive data\n", name().c_str())); rsr = 0; sample = 0; // Is this a 9-bit data reception? bit_count = (value.get() & RX9) ? 9 : 8; state = RCSTA_WAITING_FOR_START; } void _RCSTA::overrun() { value.put(value.get() | _RCSTA::OERR); } void _RCSTA::set_callback_break(unsigned int spbrg_edge) { unsigned int time_to_event; if(cpu && spbrg) { time_to_event = ( spbrg->get_cycles_per_tick() * spbrg_edge ) / TOTAL_SAMPLE_STATES; get_cycles().set_break(get_cycles().get() + time_to_event, this); } } void _RCSTA::receive_start_bit() { Dprintf(("%s USART received a start bit\n", name().c_str())); if((value.get() & (CREN | SREN)) == 0) { Dprintf((" but not enabled\n")); return; } if(txsta && (txsta->value.get() & _TXSTA::BRGH)) set_callback_break(BRGH_FIRST_MID_SAMPLE); else set_callback_break(BRGL_FIRST_MID_SAMPLE); sample = 0; sample_state = RCSTA_WAITING_MID1; state = RCSTA_MAYBE_START; } //------------------------------------------------------------ void _RCSTA::callback() { //RRR Dprintf(("RCSTA callback. %s time:0x%" PRINTF_GINT64_MODIFIER "x\n", name().c_str(), get_cycles().get())); if (txsta->bSYNC()) // Synchronous mode RX/DT is data, TX/CK is clock { if (sync_next_clock_edge_high) // + edge of clock { sync_next_clock_edge_high = false; txsta->putTXState('1'); // Clock high // Transmit if ((value.get() & (SPEN | SREN | CREN)) == SPEN) { if (bit_count) { putRCState((rsr & 1) ? '1' : '0'); rsr >>= 1; bit_count--; } } } else // - clock edge { sync_next_clock_edge_high = true; txsta->putTXState('0'); //clock low // Receive Master mode if ((value.get() & (SPEN | SREN | CREN)) != SPEN) { if (value.get() & OERR) return; bool data = m_PinModule->getPin().getState(); data = mUSART->baudcon.rxdtp() ? !data : data; if (bRX9()) rsr |= data << 9; else rsr |= data << 8; rsr >>= 1; if (--bit_count == 0) { rcreg->push(rsr); if (bRX9()) bit_count = 9; else bit_count = 8; rsr = 0; value.put(value.get() & ~SREN); if ((value.get() & (SPEN | SREN | CREN)) == SPEN ) { enableRCPin(DIR_OUT); return; } } } else // Transmit, clock low { if (bit_count == 0 && !mUSART->bIsTXempty()) { sync_start_transmitting(); mUSART->emptyTX(); return; } else if(bit_count == 0 && mUSART->bIsTXempty()) { txsta->value.put(txsta->value.get() | _TXSTA::TRMT); putRCState('0'); return; } } } if (cpu && (value.get() & SPEN)) { future_cycle = get_cycles().get() + spbrg->get_cycles_per_tick(); get_cycles().set_break(future_cycle, this); } } else { // A bit is sampled 3 times. switch(sample_state) { case RCSTA_WAITING_MID1: if (m_cRxState == '1' || m_cRxState == 'W') sample++; if(txsta && (txsta->value.get() & _TXSTA::BRGH)) set_callback_break(BRGH_SECOND_MID_SAMPLE - BRGH_FIRST_MID_SAMPLE); else set_callback_break(BRGL_SECOND_MID_SAMPLE - BRGL_FIRST_MID_SAMPLE); sample_state = RCSTA_WAITING_MID2; break; case RCSTA_WAITING_MID2: if (m_cRxState == '1' || m_cRxState == 'W') sample++; if(txsta && (txsta->value.get() & _TXSTA::BRGH)) set_callback_break(BRGH_THIRD_MID_SAMPLE - BRGH_SECOND_MID_SAMPLE); else set_callback_break(BRGL_THIRD_MID_SAMPLE - BRGL_SECOND_MID_SAMPLE); sample_state = RCSTA_WAITING_MID3; break; case RCSTA_WAITING_MID3: if (m_cRxState == '1' || m_cRxState == 'W') sample++; receive_a_bit( (sample>=2)); sample = 0; // If this wasn't the last bit then go ahead and set a break for the next bit. if(state==RCSTA_RECEIVING) { if(txsta && (txsta->value.get() & _TXSTA::BRGH)) set_callback_break(TOTAL_SAMPLE_STATES -(BRGH_THIRD_MID_SAMPLE - BRGH_FIRST_MID_SAMPLE)); else set_callback_break(TOTAL_SAMPLE_STATES -(BRGL_THIRD_MID_SAMPLE - BRGL_FIRST_MID_SAMPLE)); sample_state = RCSTA_WAITING_MID1; } break; default: //cout << "Error RCSTA callback with bad state\n"; // The receiver was probably disabled in the middle of a reception. ; } } } //----------------------------------------------------------- void _RCSTA::callback_print() { cout << "RCSTA " << name() << " CallBack ID " << CallBackID << '\n'; } //----------------------------------------------------------- // RCREG // void _RCREG::push(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); if(fifo_sp >= 2) { if (m_rcsta) m_rcsta->overrun(); Dprintf(("%s receive overrun\n", name().c_str())); } else { Dprintf(("%s pushing uart reception onto rcreg stack, value received=0x%x\n",name().c_str(), new_value)); fifo_sp++; oldest_value = value.get(); value.put(new_value & 0xff); if (m_rcsta) { unsigned int rcsta = m_rcsta->value.get(); if (new_value & 0x100) rcsta |= _RCSTA::RX9D; else rcsta &= ~ _RCSTA::RX9D; m_rcsta->value.put(rcsta); } } mUSART->set_rcif(); } void _RCREG::pop() { if(fifo_sp == 0) return; if(--fifo_sp == 1) { value.put(oldest_value & 0xff); if (m_rcsta) { unsigned int rcsta = m_rcsta->value.get(); if (oldest_value & 0x100) rcsta |= _RCSTA::RX9D; else rcsta &= ~ _RCSTA::RX9D; m_rcsta->value.put(rcsta); } } if(fifo_sp == 0) mUSART->clear_rcif(); } unsigned int _RCREG::get_value() { return value.get(); } unsigned int _RCREG::get() { pop(); trace.raw(read_trace.get() | value.get()); return value.get(); } //----------------------------------------------------------- // SPBRG - Serial Port Baud Rate Generator // // The SPBRG is essentially a continuously running programmable // clock. (Note that this will slow the simulation down if the // serial port is not used. Perhaps gpsim needs some kind of // pragma type thing to disable cpu intensive peripherals...) void _SPBRG::get_next_cycle_break() { future_cycle = last_cycle + get_cycles_per_tick(); if(cpu) { if (future_cycle <= get_cycles().get()) { Dprintf(("%s future %" PRINTF_GINT64_MODIFIER "d <= now %" PRINTF_GINT64_MODIFIER "d\n", name().c_str(), future_cycle, get_cycles().get())); last_cycle = get_cycles().get(); future_cycle = last_cycle + get_cycles_per_tick(); } get_cycles().set_break(future_cycle, this); } //Dprintf(("SPBRG::callback next break at 0x%" PRINTF_GINT64_MODIFIER "x\n",future_cycle)); } unsigned int _SPBRG::get_cycles_per_tick() { unsigned int cpi = (cpu) ? p_cpu->get_ClockCycles_per_Instruction() : 4; unsigned int brgval, cpt, ret; if ( baudcon && baudcon->brg16() ) { brgval = ( brgh ? brgh->value.get() * 256 : 0 ) + value.get(); cpt = 4; // hi-speed divisor in 16-bit mode is 4 } else { brgval = value.get(); cpt = 16; // hi-speed divisor in 8-bit mode is 16 } if ( txsta && (txsta->value.get() & _TXSTA::SYNC) ) { // Synchronous mode - divisor is always 4 // However, code wants two transitions per bit // to generate clock for master mode, so use 2 cpt = 2; } else { // Asynchronous mode if(txsta && !(txsta->value.get() & _TXSTA::BRGH)) { cpt *= 4; // lo-speed divisor is 4 times hi-speed } } ret = ((brgval+1)*cpt)/cpi; ret = ret ? ret : 1; return ret; } void _SPBRG::start() { if (running) return; if(! skip || get_cycles().get() >= skip) { if(cpu) last_cycle = get_cycles().get(); skip = 0; } running = true; start_cycle = last_cycle; get_next_cycle_break(); Dprintf((" SPBRG::start last_cycle:0x%" PRINTF_GINT64_MODIFIER "x: future_cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle,future_cycle)); } void _SPBRG::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); Dprintf((" SPBRG value=0x%x\n",value.get())); //Prevent updating last_cycle until all current breakpoints have expired //Otherwise we see that rx/tx periods get screwed up from now until future_cycle future_cycle = last_cycle + get_cycles_per_tick(); skip = future_cycle; Dprintf((" SPBRG value=0x%x skip=0x%" PRINTF_GINT64_MODIFIER "x last=0x%" PRINTF_GINT64_MODIFIER "x cycles/tick=0x%x\n",value.get(), skip, last_cycle, get_cycles_per_tick())); } void _SPBRG::put_value(unsigned int new_value) { put(new_value); update(); } void _SPBRGH::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); if(m_spbrg) m_spbrg->set_start_cycle(); } void _SPBRG::set_start_cycle() { //Prevent updating last_cycle until all current breakpoints have expired //Otherwise we see that rx/tx persiods get screwed up from now until future_cycle future_cycle = last_cycle + get_cycles_per_tick(); skip = future_cycle; } void _SPBRGH::put_value(unsigned int new_value) { put(new_value); update(); } //-------------------------- //guint64 _SPBRG::get_last_cycle() // // Get the cpu cycle corresponding to the last edge of the SPBRG // guint64 _SPBRG::get_last_cycle() { // There's a chance that a SPBRG break point exists on the current // cpu cycle, but has not yet been serviced. if(cpu) return( (get_cycles().get() == future_cycle) ? future_cycle : last_cycle); else return 0; } //-------------------------- //guint64 _SPBRG::get_cpu_cycle(unsigned int edges_from_now) // // When the SPBRG is enabled, it becomes a free running counter // that's synchronous with the cpu clock. The frequency of the // counter depends on the mode of the usart: // // Synchronous mode: // baud = cpu frequency / 4 / (spbrg.value + 1) // // Asynchronous mode: // high frequency: // baud = cpu frequency / 16 / (spbrg.value + 1) // low frequency: // baud = cpu frequency / 64 / (spbrg.value + 1) // // What this routine will do is return the cpu cycle corresponding // to a (rising) edge of the spbrg clock. guint64 _SPBRG::get_cpu_cycle(unsigned int edges_from_now) { // There's a chance that a SPBRG break point exists on the current // cpu cycle, but has not yet been serviced. guint64 cycle = (get_cycles().get() == future_cycle) ? future_cycle : last_cycle; return ( edges_from_now * get_cycles_per_tick() + cycle ); } void _SPBRG::callback() { if (skip) { Dprintf((" SPBRG skip=0x%" PRINTF_GINT64_MODIFIER "x, cycle=0x%" PRINTF_GINT64_MODIFIER "x\n", skip, get_cycles().get())); } if(! skip || get_cycles().get() >= skip) { last_cycle = get_cycles().get(); skip = 0; } //Dprintf(("SPBRG rollover at cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle)); if((rcsta && rcsta->bSPEN()) || (txsta && txsta->bTXEN())) { // If the serial port is enabled, then set another // break point for the next clock edge. get_next_cycle_break(); } else { running = false; } } //----------------------------------------------------------- // TXSTA - Transmit Register Status and Control void _BAUDCON::put_value(unsigned int new_value) { put(new_value); update(); } void _BAUDCON::put(unsigned int new_value) { unsigned int old_value = value.get(); trace.raw(write_trace.get() | value.get()); // The RCIDL bit is controlled entirely by hardware. new_value &= ~RCIDL; if ( rcsta->rc_is_idle() ) new_value |= RCIDL; value.put(new_value); Dprintf(("%s BAUDCON value=0x%x\n",name().c_str(), value.get())); if( (old_value ^ value.get()) & TXCKP) { // The TXCKP bit has changed states. // txsta->set_pin_pol ((value.get() & TXCKP) ? true : false); } } //-------------------------------------------------- // member functions for the USART //-------------------------------------------------- void USART_MODULE::initialize(PIR *_pir, PinModule *tx_pin, PinModule *rx_pin, _TXREG *_txreg, _RCREG *_rcreg) { assert(_txreg && _rcreg); pir = _pir; spbrg.txsta = &txsta; spbrg.rcsta = &rcsta; txreg = _txreg; txreg->assign_rcsta(&rcsta); txreg->assign_txsta(&txsta); rcreg = _rcreg; rcreg->assign_rcsta(&rcsta); txsta.txreg = txreg; txsta.rcsta = &rcsta; txsta.spbrg = &spbrg; txsta.bit_count = 0; txsta.setIOpin(tx_pin); rcsta.rcreg = rcreg; rcsta.spbrg = &spbrg; rcsta.txsta = &txsta; rcsta.txreg = txreg; rcsta.setIOpin(rx_pin); } void USART_MODULE::set_TXpin(PinModule *tx_pin) { txsta.setIOpin(tx_pin); } void USART_MODULE::set_RXpin(PinModule *rx_pin) { rcsta.setIOpin(rx_pin); } bool USART_MODULE::bIsTXempty() { if (m_txif) return m_txif->Get(); return pir ? pir->get_txif() : true; } void USART_MODULE::emptyTX() { Dprintf(("usart::empty - setting TXIF %s\n", txsta.name().c_str())); if (txsta.bTXEN()) { if (m_txif) m_txif->Trigger(); else if (pir) pir->set_txif(); else assert(pir); } } void USART_MODULE::full() { Dprintf((" txreg::full - clearing TXIF\n")); if (m_txif) m_txif->Clear(); else if(pir) pir->clear_txif(); else assert(pir); } void USART_MODULE::set_rcif() { Dprintf((" - setting RCIF\n")); if (m_rcif) m_rcif->Trigger(); else if(pir) pir->set_rcif(); } void USART_MODULE::clear_rcif() { Dprintf((" - clearing RCIF\n")); if (m_rcif) m_rcif->Clear(); else if(pir) pir->clear_rcif(); } //-------------------------------------------------- USART_MODULE::USART_MODULE(Processor *pCpu) : txsta(pCpu,"","USART Transmit Status",this), // Don't set names incase there are two UARTS rcsta(pCpu,"","USART Receive Status",this), spbrg(pCpu,"","Serial Port Baud Rate Generator"), spbrgh(pCpu,"spbrgh","Serial Port Baud Rate high byte"), baudcon(pCpu,"baudcon","Serial Port Baud Rate Control"), is_eusart(false), m_rcif(0), m_txif(0) { baudcon.txsta = &txsta; baudcon.rcsta = &rcsta; } USART_MODULE::~USART_MODULE() { if (m_rcif) delete m_rcif; if (m_txif) delete m_txif; } //-------------------------------------------------- void USART_MODULE::set_eusart ( bool is_it ) { if ( is_it ) { spbrgh.assign_spbrg ( &spbrg ); spbrg.baudcon = &baudcon; spbrg.brgh = &spbrgh; is_eusart = true; } else { spbrgh.assign_spbrg ( 0 ); spbrg.baudcon = 0; spbrg.brgh = 0; is_eusart = false; } } gpsim-0.30.0/src/dspic/0000775000076400007640000000000013117465763011632 500000000000000gpsim-0.30.0/src/dspic/dspic-registers.cc0000664000076400007640000001477213041763613015172 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "dspic-registers.h" #include "dspic-processors.h" #include "../trace.h" #if defined(PROPAGATE_UNKNOWNS) bool gbPropagateUnknown=false; #endif namespace dspic { extern Trace *gTrace; // Points to gpsim's global trace object. extern Cycle_Counter *gCycles; // Points to gpsim's global cycle counter. } namespace dspic_registers { //------------------------------------------------------------------------ // dsPicRegister unsigned int dsPicRegister::iMask = 0xffff; //-------------------------------------------------- bool dsPicRegister::get_bit(unsigned int bit_number) { return( ((value.get() >> (bit_number & 0x0f)) & 1 ) ? true : false); } dsPicRegister::dsPicRegister(Processor *pCpu, const char *pName, const char *pDesc) : Register(pCpu, pName, pDesc) { value.data = 0; value.init = 0xffff; por_value.data = 0; por_value.init = 0xffff; } //-------------------------------------------------- // PCL - low word of program counter. //-------------------------------------------------- PCL::PCL(Processor *pCpu, const char *pName, const char *pDesc) : dsPicRegister(pCpu,pName,pDesc) { value = RegisterValue(0,0); por_value = value; } void PCL::put(unsigned int new_value) { dspic::gTrace->raw(write_trace.get() | value.get()); cpu_dsPic->pc->computed_goto(new_value); } void PCL::put_value(unsigned int new_value) { value.put(new_value & 0xffff); cpu_dsPic->pc->put_value( (cpu_dsPic->pc->get_value() & 0xffff0000) | value.get()); } unsigned int PCL::get() { return((value.get()+1) & 0xffff); } unsigned int PCL::get_value() { value.put(cpu_dsPic->pc->get_value() & 0xffff); return(value.get()); } //------------------------------------------------------------------------ // // Program Counter // dsPicProgramCounter::dsPicProgramCounter(dspic::dsPicProcessor *pcpu, PCL *pPCL) : Program_Counter("pc", "Program Counter", pcpu), m_pcl(pPCL), m_cpu(pcpu) { printf("dspic program counter.\n"); set_trace_command(); //dspic::gTrace->allocateTraceType(new PCTraceType(pcpu,1))); } //-------------------------------------------------- // jump - update the program counter. All branching instructions // except computed gotos and returns go through here. void dsPicProgramCounter::jump(unsigned int new_address) { dspic::gTrace->raw(trace_other | (value<<1)); value = new_address; value = (value >= memory_size) ? value - memory_size : value; m_pcl->value.put(value & 0xffff); dspic::gCycles->increment(); dspic::gCycles->increment(); } void dsPicProgramCounter::computed_goto(unsigned int new_address) { printf("dspic %s.\n",__FUNCTION__); dspic::gTrace->raw(trace_other | (value<<1)); // Use the new_address and the cached pclath (or page select bits // for 12 bit cores) to generate the destination address: value = (new_address >>1); value = (value >= memory_size) ? value - memory_size : value; // see Update pcl comment in Program_Counter::increment() m_pcl->value.put((value<<1) & 0xffff); // The instruction modifying the PCL will also increment the // program counter. So, pre-compensate the increment with a // decrement: value--; dspic::gCycles->increment(); } void dsPicProgramCounter::put_value(unsigned int new_value) { printf("dspic program counter::%s. (0x%x)\n",__FUNCTION__,new_value); dspic::gTrace->raw(trace_other | (value<<1)); value = new_value; value = (value >= memory_size) ? value - memory_size : value; m_pcl->value.put(value & 0xff); //m_cpu->pclath->value.put((value >> 8) & 0xff); m_pcl->update(); //cpu_pic->pclath->update(); update(); } unsigned int dsPicProgramCounter::get_value() { printf("dspic program counter::%s.\n",__FUNCTION__); return value*2; } //-------------------------------------------------- // increment - update the program counter. All non-branching // instructions pass through here. void dsPicProgramCounter::increment() { // Trace the value of the program counter before it gets changed. dspic::gTrace->raw(trace_increment | value); value = (value + 1); value = (value >= memory_size) ? value - memory_size : value; // Update pcl. Note that we don't want to pcl.put() because that // will trigger a break point if there's one set on pcl. (A read/write // break point on pcl should not be triggered by advancing the program // counter). m_pcl->value.put(value & 0xffff); dspic::gCycles->increment(); } //---------------------------------------------------------------------- // Stack //---------------------------------------------------------------------- Stack::Stack(dspic::dsPicProcessor *pCpu) : m_cpu(pCpu) { } void Stack::push() { unsigned int pc = m_cpu->pc->get_value(); unsigned int rm_size = m_cpu->register_memory_size()>>1; unsigned int tos = m_cpu->W[15].get_value(); unsigned int tos_index = tos>>1; // Push the current PC onto the stack m_cpu->registers[tos_index %rm_size]->put(pc & 0xffff); m_cpu->registers[(tos_index+1)%rm_size]->put((pc>>16) & 0xffff); m_cpu->W[15].put(tos + 4); } void Stack::pop() { } //---------------------------------------------------------------------- // Status //---------------------------------------------------------------------- Status::Status(Processor *pCpu, const char *pName, const char *pDesc) : dsPicRegister(pCpu,pName,pDesc) { } //---------------------------------------------------------------------- // WRegister //---------------------------------------------------------------------- WRegister::WRegister() : dsPicRegister(0, 0, 0) { } } gpsim-0.30.0/src/dspic/Makefile.in0000664000076400007640000005360013117441635013613 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/dspic ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsim_dspic_la_LIBADD = am_libgpsim_dspic_la_OBJECTS = gpsim_modules.lo dspic-processors.lo \ dspic-instructions.lo dspic-registers.lo libgpsim_dspic_la_OBJECTS = $(am_libgpsim_dspic_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgpsim_dspic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libgpsim_dspic_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgpsim_dspic_la_SOURCES) DIST_SOURCES = $(libgpsim_dspic_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim_dspic.la libgpsim_dspic_la_SOURCES = \ gpsim_modules.cc \ dspic-processors.cc dspic-processors.h \ dspic-instructions.cc dspic-instructions.h \ dspic-registers.cc dspic-registers.h libgpsim_dspic_la_LDFLAGS = @X_LDFLAGS@ EXTRA_DIST = makefile.mingw all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/dspic/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/dspic/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgpsim_dspic.la: $(libgpsim_dspic_la_OBJECTS) $(libgpsim_dspic_la_DEPENDENCIES) $(EXTRA_libgpsim_dspic_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgpsim_dspic_la_LINK) -rpath $(libdir) $(libgpsim_dspic_la_OBJECTS) $(libgpsim_dspic_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dspic-instructions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dspic-processors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dspic-registers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsim_modules.Plo@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/src/dspic/Makefile.am0000664000076400007640000000056513041763613013603 00000000000000## Process this file with automake to produce Makefile.in AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim_dspic.la libgpsim_dspic_la_SOURCES = \ gpsim_modules.cc \ dspic-processors.cc dspic-processors.h \ dspic-instructions.cc dspic-instructions.h \ dspic-registers.cc dspic-registers.h libgpsim_dspic_la_LDFLAGS = @X_LDFLAGS@ EXTRA_DIST = makefile.mingw gpsim-0.30.0/src/dspic/dspic-processors.cc0000664000076400007640000001412113045306452015347 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "dspic-processors.h" #include "dspic-registers.h" #include #include "../symbol.h" #include "../program_files.h" #include "../packages.h" #include "../trace.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Globals // using namespace dspic; using namespace dspic_registers; ProcessorConstructor pdsPic30F6010(dsPic30F6010::construct , "__30f6010", "dspic30f6010", "30f6010", "30f610"); namespace dspic { Trace *gTrace=0; // Points to gpsim's global trace object. Cycle_Counter *gCycles=0; // Points to gpsim's global cycle counter. //------------------------------------------------------------------- // // dsPicProcessor -- constructor. dsPicProcessor::dsPicProcessor(const char *_name, const char *desc) : Processor(_name, desc), m_stack(this), m_status(this, "status") { gTrace = &get_trace(); gCycles = &get_cycles(); pcl = new PCL(this, "PCL"); pc = new dsPicProgramCounter(this,pcl); } //------------------------------------------------------------------- // // create // // Build the basic dsPicProcessor elements. void dsPicProcessor::create() { init_program_memory (program_memory_size()); init_register_memory (register_memory_size()/2); create_sfr_map(); create_invalid_registers(); } //------------------------------------------------------------------- // void dsPicProcessor::add_sfr_register(dspic_registers::dsPicRegister *pReg, unsigned int addr, const char *pName, RegisterValue *rv ) { if (!pReg) return; printf("adding sfr %s\n",pReg->name().c_str()); pReg->set_cpu(this); if (addr < register_memory_size()) { registers[map_rm_address2index(addr)] = pReg; if (pName) pReg->new_name(pName); pReg->address = addr; pReg->alias_mask = 0; addSymbol(pReg); if (rv) { pReg->value = *rv; pReg->por_value = *rv; } RegisterValue rv = getWriteTT(addr); pReg->set_write_trace(rv); rv = getReadTT(addr); pReg->set_read_trace(rv); } } //------------------------------------------------------------------- // // load_hex // bool dsPicProcessor::LoadProgramFile(const char *pFilename, FILE *pFile, const char *pProcessorName) { Processor * pProcessor = this; ProgramFileType *pPFT = ProgramFileTypeList::GetList()[0]; // IntelHexProgramFileType if (pPFT) return pPFT->LoadProgramFile(&pProcessor, pFilename, pFile, pProcessorName); return false; } //------------------------------------------------------------------------ void dsPicProcessor::create_sfr_map() { unsigned int j; // Initialize the General Purpose Registers: //add_file_registers(0xf80, 0xf7f, 0); unsigned int start_address = 0x0800/2; unsigned int end_address = 0x27ff/2; char str[100]; for (j = start_address; j <= end_address; j++) { //The default register name is simply its address snprintf (str, sizeof(str), "R%03X", j); registers[j] = new dsPicRegister(this,str); registers[j]->address = j; RegisterValue rv = getWriteTT(j); registers[j]->set_write_trace(rv); rv = getReadTT(j); registers[j]->set_read_trace(rv); } RegisterValue porv(0,0); for (j=0; j<16; j++) { char buff[16]; snprintf(buff, 16, "W%u", j); // add_sfr_register(&W[j], j*2, buff,&porv); } add_sfr_register(pcl, 0x02e); } //------------------------------------------------------------------------ void dsPicProcessor::init_program_memory_at_index(unsigned int uIndex, const unsigned char *bytes, int nBytes) { unsigned int unBytes = nBytes; for (unsigned int i =0; ivalue]->execute(); } void dsPicProcessor::step(unsigned int, bool refresh) { program_memory[pc->value]->execute(); } void dsPicProcessor::run(bool refresh) { } void dsPicProcessor::finish() { } void dsPicProcessor::step_cycle() { } void dsPicProcessor::interrupt() { } unsigned int dsPicProcessor::get_config_word(unsigned int) { return 0xffffffff; } void dsPicProcessor::reset(RESET_TYPE r) { } //------------------------------------------------------------------------ // dsPIC30F6010 //------------------------------------------------------------------------ dsPic30F6010::dsPic30F6010(const char *_name, const char *desc) { } Processor * dsPic30F6010::construct(const char *name) { dsPic30F6010 *p = new dsPic30F6010(name); printf ("Constructing a dspic 6010\n"); p->create(); globalSymbolTable().addModule(p); return p; } //------------------------------------------------------------ // void dsPic30F6010::create() { create_iopin_map(); dsPicProcessor::create(); } //------------------------------------------------------------ // void dsPic30F6010::create_iopin_map() { package = new Package(80); if(!package) return; } }; gpsim-0.30.0/src/dspic/dspic-registers.h0000664000076400007640000001366613041763613015035 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__DSPIC_REGISTERS_H__) #define __DSPIC_REGISTERS_H__ #include "../registers.h" #include "../trace.h" namespace dspic { extern Trace *gTrace; class dsPicProcessor; }; namespace dspic_registers { //------------------------------------------------------------ // dspic Registers // // The dspic registers are natively 16-bit wide. We'll overide // most of the Register base class methods because of this. class dsPicRegister : public Register { public: /// The 'iMask' member is used to inhibit/enable three state logic /// (the i in iMask stands for init, which is the name of the variable /// holding the stated of the initialized bits). static unsigned int iMask; dsPicRegister(Processor *, const char *pName, const char *pDesc=0); /* dsPicRegister() { value.data = 0; value.init = 0xffff; por_value.data = 0; por_value.init = 0xffff; } dsPicRegister(RegisterValue &rv) { value = rv; } */ virtual bool get_bit(unsigned int bit_number); virtual void put(unsigned int new_value) { RegisterValue rv = getRV_notrace(); rv.data = new_value&0xffff; putRV(rv); } virtual unsigned int get() { RegisterValue rv = getRV(); return rv.data; } virtual unsigned int get_value() { RegisterValue rv = getRV_notrace(); return rv.data; } virtual void putRV_notrace(RegisterValue rv) { #if defined(PROPAGATE_UNKNOWNS) if(gbPropagateUnknown) { unsigned int diff = value.data ^ rv.data; value.init |= (rv.init | diff); value.data &= ~diff; } else #endif { value.data = rv.data; value.init = (rv.init & iMask); } } virtual void putRV(RegisterValue rv) { dspic::gTrace->raw(write_trace.get() | value.get()); dspic::gTrace->raw( write_trace.geti() | value.geti()); putRV_notrace(rv); } virtual RegisterValue getRV(void) { dspic::gTrace->raw(read_trace.get() | value.get()); dspic::gTrace->raw(read_trace.geti() | value.geti()); return getRV_notrace(); } virtual RegisterValue getRV_notrace(void) { return RegisterValue(value.get(),value.geti()&iMask); } // getRVN is the same as getRV and is only overidden by the // status register(s). This method is used by certain instructions // that might have the status register as the destination. // The 'N' means that the flags will be cleared. virtual RegisterValue getRVN(void) { dspic::gTrace->raw(read_trace.get() | value.get()); dspic::gTrace->raw(read_trace.geti() | value.geti()); return getRVN_notrace(); } virtual RegisterValue getRVN_notrace(void) { return getRV_notrace(); } virtual unsigned int register_size () const { return 2; // bytes } }; //------------------------------------------------------------ // class Status : public dsPicRegister { public: enum { eC = 1<<0, eZ = 1<<1, eOV = 1<<2, eN = 1<<3, eRA = 1<<4, eIPLD = 1<<5, eIPL1 = 1<<6, eIPL2 = 1<<7, eDC = 1<<8, eDA = 1<<9, eSAB = 1<<10, eOAB = 1<<11, eSB = 1<<12, eSA = 1<<13, eOB = 1<<14, eOA = 1<<15 }; Status(Processor *, const char *pName, const char *pDesc=0); inline void traceWrite() { dspic::gTrace->raw(write_trace.get() | value.get()); dspic::gTrace->raw(write_trace.geti() | value.geti()); } inline void putFlags(unsigned int flags, unsigned int mask, unsigned int uninit) { traceWrite(); value.data = (value.data & ~mask) | flags; value.init &= ~mask; value.init |= uninit; } }; //------------------------------------------------------------ // class WRegister : public dsPicRegister { public: WRegister(); }; //------------------------------------------------------------ // class PCL : public dsPicRegister { public: virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); PCL(Processor *, const char *pName, const char *pDesc=0); }; //------------------------------------------------------------ // dspic Program Counter // class dsPicProgramCounter : public Program_Counter { public: dsPicProgramCounter(dspic::dsPicProcessor *, PCL *); virtual void increment(); //virtual void skip(); virtual void jump(unsigned int new_address); //virtual void interrupt(unsigned int new_value); virtual void computed_goto(unsigned int new_value); //virtual void new_address(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get_value(); //virtual unsigned int get_next(); protected: PCL *m_pcl; dspic::dsPicProcessor *m_cpu; }; //------------------------------------------------------------ // dspic Stack // class Stack { public: Stack(dspic::dsPicProcessor *pCpu); void push(); void pop(); protected: dspic::dsPicProcessor *m_cpu; }; } #endif // !defined(__DSPIC_REGISTERS_H__) gpsim-0.30.0/src/dspic/dspic-instructions.h0000664000076400007640000010462613041763613015567 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__DSPIC_INSTRUCTIONS_H__) #define __DSPIC_INSTRUCTIONS_H__ #include "../pic-instructions.h" namespace dspic { class dsPicProcessor; }; namespace dspic_instructions { // Fix me - duplicate of the status register bit definitions. enum { eC = 1<<0, eZ = 1<<1, eOV = 1<<2, eN = 1<<3, eRA = 1<<4, eIPLD = 1<<5, eIPL1 = 1<<6, eIPL2 = 1<<7, eDC = 1<<8, eDA = 1<<9, eSAB = 1<<10, eOAB = 1<<11, eSB = 1<<12, eSA = 1<<13, eOB = 1<<14, eOA = 1<<15 }; //--------------------------------------------------------- class MultiWordInstruction : public instruction { public: MultiWordInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual int instruction_size(void) { return 2;} virtual enum INSTRUCTION_TYPES isa(void) {return MULTIWORD_INSTRUCTION;}; virtual bool isBase() { return true;} virtual void initialize(bool init_state) { initialized = init_state; } protected: unsigned int word2_opcode; unsigned int PMaddress; unsigned int PMindex; bool initialized; }; //--------------------------------------------------------- class MultiWordBranch : public MultiWordInstruction { public: MultiWordBranch(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); unsigned int destination_index; void runtime_initialize(void); virtual void execute(void){}; virtual char *name(char *,int); }; //--------------------------------------------------------- class LiteralBranch : public instruction { public: LiteralBranch(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name); virtual bool isBase() { return true;} virtual char *name(char *,int); protected: unsigned int m_destination; const char *mcP_conditionName; }; //---------------------------------------------------------------------- class ImmediateInstruction : public instruction { public: ImmediateInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual char *name(char *,int len); virtual bool isBase() { return true;} protected: unsigned int m_L; }; //---------------------------------------------------------------------- class AddressingMode { public: AddressingMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~AddressingMode() { } virtual RegisterValue get()=0; virtual void put(RegisterValue &)=0; virtual char *name(char *buff, int len)=0; /**/ static AddressingMode *construct(dspic::dsPicProcessor *new_cpu, unsigned int new_mode, unsigned int addr); /**/ enum { eDirect = 0, eIndirect, eIndirectPostDec, eIndirectPostInc, eIndirectPreDec, eIndirectPreInc, eIndirectRegOffset, eIndirectRegOffset_, eLiteral=6, eLiteral_=7, }; protected: dspic::dsPicProcessor *m_cpu; unsigned int m_mode; unsigned int m_addr; static const RegisterValue m_unknown; }; //---------------------------------------------------------------------- class LiteralAddressingMode : public AddressingMode { public: LiteralAddressingMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~LiteralAddressingMode() { } virtual RegisterValue get() {return m_rv;} virtual void put(RegisterValue &) {} // maybe we should throw an error? virtual char *name(char *buff, int len); private: RegisterValue m_rv; }; //---------------------------------------------------------------------- class RegisterAddressingMode : public AddressingMode { public: RegisterAddressingMode(dspic::dsPicProcessor *cpu, unsigned int addr, const char *format); virtual ~RegisterAddressingMode() { } virtual char *name(char *buff, int len); protected: const char *m_cPformat; }; //---------------------------------------------------------------------- class RegDirectAddrMode : public RegisterAddressingMode { public: RegDirectAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~RegDirectAddrMode() { } virtual RegisterValue get(); virtual void put(RegisterValue &); }; //---------------------------------------------------------------------- class RegIndirectAddrMode : public RegisterAddressingMode { public: RegIndirectAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~RegIndirectAddrMode() { } virtual RegisterValue get(); virtual void put(RegisterValue &); }; //---------------------------------------------------------------------- class RegIndirectPostDecAddrMode : public RegisterAddressingMode { public: RegIndirectPostDecAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~RegIndirectPostDecAddrMode() { } virtual RegisterValue get(); virtual void put(RegisterValue &); }; //---------------------------------------------------------------------- class RegIndirectPostIncAddrMode : public RegisterAddressingMode { public: RegIndirectPostIncAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~RegIndirectPostIncAddrMode() { } virtual RegisterValue get(); virtual void put(RegisterValue &); }; //---------------------------------------------------------------------- class RegIndirectPreDecAddrMode : public RegisterAddressingMode { public: RegIndirectPreDecAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~RegIndirectPreDecAddrMode() { } virtual RegisterValue get(); virtual void put(RegisterValue &); }; //---------------------------------------------------------------------- class RegIndirectPreIncAddrMode : public RegisterAddressingMode { public: RegIndirectPreIncAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr); virtual ~RegIndirectPreIncAddrMode() { } virtual RegisterValue get(); virtual void put(RegisterValue &); }; //---------------------------------------------------------------------- class RegisterInstruction : public instruction { public: RegisterInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name); virtual bool isBase() { return true;} protected: bool m_bByteOperation; AddressingMode *m_base; AddressingMode *m_source; AddressingMode *m_destination; }; //++++++++++++++++++++++++++++++++++++++++ enum eAddressingModes { eRegisterDirect, eRegisterIndirect }; //---------------------------------------------------------------------- class RegisterToRegisterInstruction : public RegisterInstruction { public: RegisterToRegisterInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *new_name, eAddressingModes addrMode); virtual char *name(char *,int len); protected: eAddressingModes m_addrMode; //bool m_bHasBase; // true for instructions with 3 operands. }; //---------------------------------------------------------------------- class ADDR : public RegisterToRegisterInstruction { public: ADDR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, eAddressingModes addrMode); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) { if ((new_opcode & 0xf00000) == 0x400000) return new ADDR(new_cpu,new_opcode,addr,eRegisterIndirect); return new ADDR(new_cpu,new_opcode,addr,eRegisterDirect); } }; //---------------------------------------------------------------------- class ADD : public instruction { public: ADD(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ADD(new_cpu,new_opcode,addr);} }; //---------------------------------------------------------------------- class ADDC : public instruction { public: ADDC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ADDC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class AND : public instruction { public: AND(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new AND(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class ASR : public instruction { public: ASR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ASR(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BCLR : public instruction { public: BCLR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BCLR(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BRA : public LiteralBranch { public: BRA(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BRA(new_cpu,new_opcode, addr);} protected: unsigned int m_condition; enum eConditions { OV=0, // Overflow C, // Carry and GEU Z, // Zero N, // Negative LE, // Less than or equal to LT, // Less than LEU, // Less than or equal unsigned UN, // Unconditionally NOV, // No overflow NC, // No Carry and LTU (less than unsigned) NZ, // Not zero NN, // Not Negative GT, // Greater than GE, // Greater than or equal GTU, // Greater than unsigned NU // not used... }; }; //---------------------------------------------------------------------- class BSET : public instruction { public: BSET(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BSET(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BSW : public instruction { public: BSW(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BSW(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BTG : public instruction { public: BTG(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BTG(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BTS : public instruction { public: BTS(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BTS(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BTST : public instruction { public: BTST(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BTST(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class BTSTS : public instruction { public: BTSTS(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new BTSTS(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CALL : public instruction { public: CALL(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CALL(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CLR : public instruction { public: CLR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CLR(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CLRWDT : public instruction { public: CLRWDT(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CLRWDT(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class COM : public instruction { public: COM(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new COM(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CP : public instruction { public: CP(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CP(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CP0 : public instruction { public: CP0(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CP0(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CPB : public instruction { public: CPB(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CPB(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class CPS : public instruction { public: CPS(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new CPS(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class DAW : public instruction { public: DAW(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new DAW(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class DEC : public instruction { public: DEC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new DEC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class DISI : public instruction { public: DISI(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new DISI(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class DIV : public instruction { public: DIV(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new DIV(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class DO : public instruction { public: DO(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new DO(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class ED : public instruction { public: ED(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ED(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class EXCH : public instruction { public: EXCH(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new EXCH(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class FB : public instruction { public: FB(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new FB(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class GOTO : public MultiWordBranch { public: GOTO(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new GOTO(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class INC : public instruction { public: INC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new INC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class IOR : public instruction { public: IOR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new IOR(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class LAC : public instruction { public: LAC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new LAC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class LNK : public ImmediateInstruction { public: LNK(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new LNK(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class LSR : public instruction { public: LSR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new LSR(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class MAC : public instruction { public: MAC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new MAC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- //---------------------------------------------------------------------- class MOV : public RegisterToRegisterInstruction { public: MOV(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, eAddressingModes addrMode); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) { if ((new_opcode & 0xf78000) == 0xb78000) return new MOV(new_cpu,new_opcode,addr,eRegisterDirect); return new MOV(new_cpu,new_opcode,addr,eRegisterIndirect); } }; //---------------------------------------------------------------------- class MOVSAC : public instruction { public: MOVSAC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new MOVSAC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class MPY : public instruction { public: MPY(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new MPY(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class MUL : public instruction { public: MUL(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new MUL(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class NEG : public instruction { public: NEG(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new NEG(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class NOP : public instruction { public: NOP(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new NOP(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class POP : public instruction { public: POP(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new POP(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class PUSH : public instruction { public: PUSH(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new PUSH(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class PWRSAV : public instruction { public: PWRSAV(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new PWRSAV(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class RCALL : public LiteralBranch { public: RCALL(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new RCALL(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class REPEAT : public instruction { public: REPEAT(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new REPEAT(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class RESET : public instruction { public: RESET(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new RESET(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class RET : public instruction { public: RET(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new RET(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class ROT : public instruction { public: ROT(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ROT(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SAC : public instruction { public: SAC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SAC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SE : public instruction { public: SE(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SE(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SETM : public instruction { public: SETM(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SETM(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SFTAC : public instruction { public: SFTAC(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SFTAC(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SL : public instruction { public: SL(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SL(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SUB : public instruction { public: SUB(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SUB(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class SWAP : public instruction { public: SWAP(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new SWAP(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class TBLRD : public instruction { public: TBLRD(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new TBLRD(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class TBLWT : public instruction { public: TBLWT(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new TBLWT(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class ULNK : public instruction { public: ULNK(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ULNK(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class XOR : public instruction { public: XOR(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new XOR(new_cpu,new_opcode, addr);} }; //---------------------------------------------------------------------- class ZE : public instruction { public: ZE(Processor *new_cpu, unsigned int new_opcode, unsigned int addr); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) {return new ZE(new_cpu,new_opcode, addr);} }; }; #endif // __DSPIC_INSTRUCTIONS_H__ gpsim-0.30.0/src/dspic/dspic-processors.h0000664000076400007640000000705213041763613015220 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __DSPIC_PROCESSOR_H__ #define __DSPIC_PROCESSOR_H__ #include "../processor.h" #include "dspic-registers.h" /* namespace dspic_registers { class PCL; class dsPicRegister; }; */ namespace dspic { class dsPicProcessor : public Processor { public: dsPicProcessor(const char *_name=0, const char *desc=0); // create - build the dsPic virtual void create (); virtual void create_sfr_map(); virtual unsigned int program_memory_size() const { return 0x1000; }; virtual unsigned int register_memory_size () const { return 0x2800;}; virtual int map_pm_address2index(int address) {return address/2;} virtual int map_pm_index2address(int index) {return index*2;} // Register details virtual unsigned int register_size () const { return 2;} virtual unsigned int register_mask () const { return 0xffff;} virtual unsigned int YDataRamEnd () const { return 0x27ff;} virtual int map_rm_address2index(int address) {return address/2;} virtual int map_rm_index2address(int index) {return index*2;} void add_sfr_register(dspic_registers::dsPicRegister *reg, unsigned int addr, const char*pName=0, RegisterValue *rv=0); // opcode_size - number of bytes for an opcode. // The opcode's are really only 3 bytes, however in // hex files they're encoded in 4 bytes. virtual int opcode_size() { return 4;} // Load a hex file: bool LoadProgramFile(const char *pFilename, FILE *pFile, const char *pProcessorName); virtual void init_program_memory_at_index(unsigned int address, const unsigned char *, int nBytes); // disasm -- turn an opcode into an instruction // (this function resides dspic-instructions.cc) virtual instruction * disasm ( unsigned int address,unsigned int inst); // Execution control virtual void step_one(bool refresh=true); virtual void step(unsigned int steps,bool refresh=true); virtual void step_cycle(); virtual void interrupt(); virtual void run(bool refresh=true); virtual void finish(); // Configuration control virtual unsigned int get_config_word(unsigned int); // Reset control // por = Power On Reset virtual void reset(RESET_TYPE r); // Public Data members: dspic_registers::WRegister W[16]; dspic_registers::Stack m_stack; dspic_registers::Status m_status; protected: unsigned int m_current_disasm_address; // Used only when .hex files are loaded dspic_registers::PCL *pcl; }; class dsPic30F6010 : public dsPicProcessor { public: dsPic30F6010(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual void create (); void create_iopin_map(); }; } // end of namespace dspic #define cpu_dsPic ((dspic::dsPicProcessor *)cpu) #endif // __DSPIC_PROCESSOR_H__ gpsim-0.30.0/src/dspic/makefile.mingw0000664000076400007640000000177013041763613014366 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw TOP = ../../.. include ../../plat/win32/make.mingw ################################################################ # Nothing much configurable below INCLUDES = -I ../../.. -I ../../plat/win32 \ -I $(GLIB_PATH)/include/glib-2.0 -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GTK_PATH)/include/gtk-2.0 -I $(GTK_PATH)/lib/gtk-2.0/include \ -I $(PANGO_PATH)/include/pango-1.0 DEFINES += -DHAVE_READLINE -DHAVE_GUI -DHAVE_NSCLEAN_READLINE # -DREADLINE_STATIC all : \ ../../config.h \ libgpsim_dspic.a dspic_OBJECTS = \ gpsim_modules.o \ dspic-processors.o \ dspic-instructions.o \ dspic-registers.o ../../config.h : ../../config_win32.h.in (cd ../.. ; $(AWK) -f plat/win32/configure_win32.awk config_win32.h.in > config.h) ################ The libgpsim_dspic LIB libgpsim_dspic.a : $(dspic_OBJECTS) $(RM) -f $@ $(AR) $(ARFLAGS) $@ $(dspic_OBJECTS) gpsim-0.30.0/src/dspic/dspic-instructions.cc0000664000076400007640000012552713045306452015726 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "../pic-instructions.h" #include "dspic-processors.h" #include "dspic-instructions.h" using namespace dspic; using namespace dspic_instructions; namespace dspic { extern Trace *gTrace; // Points to gpsim's global trace object. extern Cycle_Counter *gCycles; // Points to gpsim's global cycle counter. } struct dsPicInstructionConstructor { unsigned int inst_mask; unsigned int opcode; instruction * (*inst_constructor) (Processor *cpu, unsigned int inst,unsigned int addr); }; struct dsPicInstructionConstructor op_dsPic[] = { { 0xff8000, 0xb00000, ADDR::construct }, // Lit { 0xf80000, 0x400000, ADDR::construct }, // Wb + Lit -> Wd { 0xff7fff, 0xcb0000, ADD::construct }, // add accumulators { 0xff8000, 0xb48000, ADDC::construct }, // f to W { 0xff8000, 0xb08000, ADDC::construct }, // Lit { 0xf80000, 0x480000, ADDC::construct }, // Wb + Lit -> Wd { 0xff8000, 0xb60000, AND::construct }, // f to W { 0xff8000, 0xb20000, AND::construct }, // Lit { 0xf80000, 0x600060, AND::construct }, // Wb + Lit -> Wd { 0xf80000, 0x600000, AND::construct }, { 0xff8000, 0xd58000, ASR::construct }, // f to W { 0xff8000, 0xd18000, ASR::construct }, // Lit { 0xff8070, 0xde8000, ASR::construct }, // Wb + Lit -> Wd { 0xff0000, 0xa90000, BCLR::construct }, { 0xff0b80, 0xa10000, BCLR::construct }, { 0xf00000, 0x300000, BRA::construct }, // branch literal offset { 0xfffff0, 0x016000, BRA::construct }, // computed branch { 0xfc0000, 0x0c0000, BRA::construct }, // branch on accumulator state { 0xff0000, 0xa80000, BSET::construct }, { 0xff0b80, 0xa00000, BSET::construct }, { 0xff0780, 0xad0000, BSW::construct }, { 0xff0000, 0xaa0000, BTG::construct }, { 0xff0000, 0xaf0000, BTS::construct }, { 0xff0000, 0xab0000, BTST::construct }, { 0xff0780, 0xa30000, BTST::construct }, { 0xff0780, 0xa50000, BTST::construct }, { 0xff0000, 0xac0000, BTSTS::construct }, { 0xff0780, 0xa40000, BTSTS::construct }, { 0xff0001, 0x020000, CALL::construct }, { 0xfffff0, 0x010000, CALL::construct }, { 0xff8000, 0xef0000, CLR::construct }, { 0xff807f, 0xeb0000, CLR::construct }, { 0xff4000, 0xc30000, CLR::construct }, { 0xffffff, 0xfe6000, CLRWDT::construct }, { 0xff8000, 0xee8000, COM::construct }, { 0xff8000, 0xea8000, COM::construct }, { 0xffa000, 0xe30000, CP::construct }, { 0xff83e0, 0xe10060, CP::construct }, { 0xff8380, 0xe10000, CP::construct }, { 0xffa000, 0xe20000, CP0::construct }, { 0xfffb80, 0xe00000, CP0::construct }, { 0xffa000, 0xe38000, CPB::construct }, { 0xff83e0, 0xe18060, CPB::construct }, { 0xff8380, 0xe18000, CPB::construct }, { 0xfe03f0, 0xe60000, CPS::construct }, { 0xfffff0, 0xfd4000, DAW::construct }, { 0xff8000, 0xed0000, DEC::construct }, { 0xff8000, 0xe90000, DEC::construct }, { 0xff8000, 0xed8000, DEC::construct }, // DEC2 { 0xff8000, 0xe98000, DEC::construct }, // DEC2 { 0xffc000, 0xfc0000, DISI::construct }, { 0xff8030, 0xd80000, DIV::construct }, { 0xff8030, 0xd88000, DIV::construct }, { 0xff87f0, 0xd90000, DIV::construct }, { 0xffc000, 0x080000, DO::construct }, { 0xfffff0, 0x088000, DO::construct }, { 0xfc4c03, 0xf04003, ED::construct }, { 0xfc4c03, 0xf04002, ED::construct }, { 0xfff870, 0xfd0000, EXCH::construct }, { 0xfff800, 0xdf0000, FB::construct }, // FBCL { 0xfff800, 0xcf8000, FB::construct }, // FF1L { 0xfff800, 0xcf0000, FB::construct }, // FF1R { 0xff0000, 0x040000, GOTO::construct }, { 0xfffff0, 0x014000, GOTO::construct }, { 0xff8000, 0xec0000, DEC::construct }, { 0xff8000, 0xe80000, DEC::construct }, { 0xff8000, 0xec8000, DEC::construct }, // INC2 { 0xff8000, 0xe88000, DEC::construct }, // DEC2 { 0xff8000, 0xb70000, IOR::construct }, // f to W { 0xff8000, 0xb30000, IOR::construct }, // Lit { 0xf80000, 0x700000, IOR::construct }, // Wb + Lit -> Wd { 0xff0000, 0xca0000, LAC::construct }, { 0xffc001, 0xfa0000, LNK::construct }, { 0xff8000, 0xd50000, LSR::construct }, // Note LSR is similar to ASR { 0xff8000, 0xd10000, LSR::construct }, // Lit { 0xff8070, 0xde0000, LSR::construct }, // Wb + Lit -> Wd { 0xf84000, 0xc00000, MAC::construct }, { 0xfc4003, 0xf00000, MAC::construct }, { 0xff8000, 0xbf8000, MOV::construct }, { 0xffa000, 0xb7a000, MOV::construct }, { 0xf80000, 0x800000, MOV::construct }, { 0xf80000, 0x880000, MOV::construct }, { 0xfff000, 0xb3c000, MOV::construct }, //MOV.B { 0xf00000, 0x200000, MOV::construct }, { 0xf80000, 0x900000, MOV::construct }, { 0xf80000, 0x980000, MOV::construct }, { 0xf80000, 0x780000, MOV::construct }, { 0xfff880, 0xbe0000, MOV::construct }, //MOV.D { 0xffc071, 0xbe8000, MOV::construct }, //MOV.D { 0xff4000, 0xc70000, MOVSAC::construct }, { 0xf84003, 0xc00003, MPY::construct }, // degenerate to MAC { 0xf84003, 0xc04003, MPY::construct }, // MPY.N and MSC { 0xffa000, 0xbc0000, MUL::construct }, { 0xff8000, 0xb98000, MUL::construct }, //MUL.SS { 0xff8060, 0xb90000, MUL::construct }, //MUL.SU { 0xff8000, 0xb88000, MUL::construct }, //MUL.US { 0xff8060, 0xb80000, MUL::construct }, //MUL.UU { 0xff8000, 0xee0000, NEG::construct }, { 0xff8000, 0xea0000, NEG::construct }, { 0xff7fff, 0xcb1000, NEG::construct }, { 0xff0000, 0x000000, NOP::construct }, { 0xff0000, 0xff0000, NOP::construct }, { 0xff0001, 0xf90000, POP::construct }, { 0xf8407f, 0x78004f, POP::construct }, { 0xfff8ff, 0xbe004f, POP::construct }, { 0xffffff, 0xfe8000, POP::construct }, // POP.S { 0xff0001, 0xf80000, PUSH::construct }, { 0xf87f80, 0x781f80, PUSH::construct }, { 0xfffff1, 0xbe9f80, PUSH::construct }, { 0xffffff, 0xfea000, PUSH::construct }, // PUSH.S { 0xfffffe, 0xfe4000, PWRSAV::construct }, { 0xff0000, 0x070000, RCALL::construct }, { 0xfffff0, 0x012000, RCALL::construct }, { 0xffc000, 0x090000, REPEAT::construct }, { 0xfffff0, 0x098000, REPEAT::construct }, { 0xffffff, 0xfe0000, RESET::construct }, { 0xffffff, 0x064000, RET::construct }, // RETFIE { 0xff8000, 0x050000, RET::construct }, // RETLW { 0xffffff, 0x060000, RET::construct }, // RETURN { 0xff8000, 0xd68000, ROT::construct }, // RLC { 0xff8000, 0xd28000, ROT::construct }, // RLC { 0xff8000, 0xd60000, ROT::construct }, // RLNC { 0xff8000, 0xd20000, ROT::construct }, // RLNC { 0xff8000, 0xd78000, ROT::construct }, // RRC { 0xff8000, 0xd38000, ROT::construct }, // RRC { 0xff8000, 0xd70000, ROT::construct }, // RNC { 0xff8000, 0xd30000, ROT::construct }, // RNC { 0xff0000, 0xcc0000, SAC::construct }, { 0xff0000, 0xcd0000, SAC::construct }, // SAC.R { 0xfff800, 0xfb0000, SE::construct }, { 0xff8000, 0xef8000, SETM::construct }, { 0xff807f, 0xeb8000, SETM::construct }, { 0xff7fc0, 0xc80040, SFTAC::construct }, { 0xff7ff0, 0xc80000, SFTAC::construct }, { 0xff8000, 0xd40000, SL::construct }, { 0xff8000, 0xd00000, SL::construct }, { 0xff8070, 0xdd0040, SL::construct }, { 0xff8070, 0xdd0000, SL::construct }, { 0xff8000, 0xb50000, SUB::construct }, { 0xff8000, 0xb10000, SUB::construct }, { 0xf80000, 0x500000, SUB::construct }, { 0xff7fff, 0xcb3000, SUB::construct }, { 0xff8000, 0xb58000, SUB::construct }, //SUBB { 0xff8000, 0xb18000, SUB::construct }, { 0xf80000, 0x580000, SUB::construct }, { 0xff8000, 0xbd8000, SUB::construct }, //SUBBR { 0xf80000, 0x180000, SUB::construct }, { 0xff8000, 0xbd0000, SUB::construct }, //SUBR { 0xf80000, 0x100000, SUB::construct }, { 0xffbff0, 0xfd8000, SWAP::construct }, { 0xff8000, 0xba8000, TBLRD::construct }, //TBLRDH { 0xff8000, 0xba0000, TBLRD::construct }, //TBLRDL { 0xff8000, 0xbb8000, TBLWT::construct }, //TBLWTH { 0xff8000, 0xbb0000, TBLWT::construct }, //TBLWTL { 0xffffff, 0xfa8000, ULNK::construct }, { 0xff8000, 0xb68000, XOR::construct }, // f to W { 0xff8000, 0xb28000, XOR::construct }, // Lit { 0xf80000, 0x680000, XOR::construct }, // Wb + Lit -> Wd { 0xffc000, 0xfb8000, ZE::construct } }; const int NUM_OP_DSPIC = sizeof(op_dsPic) / sizeof(op_dsPic[0]); instruction * dsPicProcessor::disasm (unsigned int address, unsigned int inst) { //printf("dspic disasm addr 0x%x, opcode 0x%x\n",address,inst); instruction *pi; pi = 0; for(int i =0; iregisters[m_addr]->name().c_str()); return buff; } //-------------------------------------------------- RegDirectAddrMode::RegDirectAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"%s") { } RegisterValue RegDirectAddrMode::get() { return m_cpu->registers[m_addr]->getRV(); } void RegDirectAddrMode::put(RegisterValue &n_rv) { m_cpu->registers[m_addr]->putRV(n_rv); } //-------------------------------------------------- RegIndirectAddrMode::RegIndirectAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[%s]") { } RegisterValue RegIndirectAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); return rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); } void RegIndirectAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); } //-------------------------------------------------- RegIndirectPostDecAddrMode::RegIndirectPostDecAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[%s--]") { } RegisterValue RegIndirectPostDecAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); return retRV; } void RegIndirectPostDecAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); } //-------------------------------------------------- RegIndirectPostIncAddrMode::RegIndirectPostIncAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[%s++]") { } RegisterValue RegIndirectPostIncAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); return retRV; } void RegIndirectPostIncAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); } //-------------------------------------------------- RegIndirectPreDecAddrMode::RegIndirectPreDecAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[--%s]") { } RegisterValue RegIndirectPreDecAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); return retRV; } void RegIndirectPreDecAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data-2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); } //-------------------------------------------------- RegIndirectPreIncAddrMode::RegIndirectPreIncAddrMode(dspic::dsPicProcessor *cpu, unsigned int addr) : RegisterAddressingMode(cpu, addr,"[++%s]") { } RegisterValue RegIndirectPreIncAddrMode::get() { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); RegisterValue retRV = rv.init ? m_unknown : m_cpu->registers[rv.data]->getRV(); return retRV; } void RegIndirectPreIncAddrMode::put(RegisterValue &n_rv) { RegisterValue rv = m_cpu->registers[m_addr]->getRV(); rv.data = (rv.data+2) & 0xffff; m_cpu->registers[m_addr]->putRV(rv); if (rv.init == 0) m_cpu->registers[rv.data]->putRV(n_rv); } //-------------------------------------------------- MultiWordInstruction::MultiWordInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr), word2_opcode(0), PMaddress(addr), PMindex(addr/2), initialized(false) { } //-------------------------------------------------- MultiWordBranch::MultiWordBranch(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : MultiWordInstruction(new_cpu, new_opcode, addr) { } void MultiWordBranch::runtime_initialize() { if(cpu_dsPic->program_memory[PMindex+1] != &cpu_dsPic->bad_instruction) { word2_opcode = cpu_dsPic->program_memory[PMindex+1]->get_opcode(); cpu_dsPic->program_memory[PMindex+1]-> update_line_number(file_id,src_line, lst_line, 0, 0); // extract the destination address from the two-word opcode destination_index = ((word2_opcode & 0x7f)<<15) | ((opcode>>1) & 0x7fff); initialized = true; } } char * MultiWordBranch::name(char *return_str,int len) { if(!initialized) runtime_initialize(); snprintf(return_str,len,"%s\t0x%05x", gpsimObject::name().c_str(), destination_index<<1); return(return_str); } //-------------------------------------------------- LiteralBranch::LiteralBranch(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name) : instruction(new_cpu, new_opcode, addr), mcP_conditionName("") { new_name(_name); unsigned int signExtendedOffset = ((new_opcode&0xffff)<<1) | ((new_opcode & (1<<15)) ? 0xfffe0000 : 0); m_destination = (addr + 2 + signExtendedOffset) & 0xfffffe; } char *LiteralBranch::name(char *buff,int len) { if (buff) { char sign = (opcode & (1<<15)) ? '-' : '+'; int offset= (((sign=='-') ? ((opcode^0xffff)+1) : opcode) << 1) & 0x1fffe; snprintf(buff, len, "%s\t%s#0x%06x\t; $%c0x%x", instruction::name().c_str(), mcP_conditionName, m_destination, sign, offset); } return buff; } //-------------------------------------------------- ImmediateInstruction::ImmediateInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr), m_L(new_opcode & 0xfffe) { } char *ImmediateInstruction::name(char *buff,int len) { if (buff) { snprintf(buff, len, "%s\t#0x%04x", instruction::name().c_str(),m_L); } return buff; } //-------------------------------------------------- RegisterInstruction::RegisterInstruction(Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name) : instruction(new_cpu, new_opcode, addr), m_bByteOperation((new_opcode & (1<<14)) != 0), m_base(0), m_source(0), m_destination(0) { new_name(_name); } //-------------------------------------------------- //-------------------------------------------------- RegisterToRegisterInstruction::RegisterToRegisterInstruction (Processor *new_cpu, unsigned int new_opcode, unsigned int addr, const char *_name, eAddressingModes addrMode ) : RegisterInstruction(new_cpu, new_opcode, addr, _name), m_addrMode(addrMode) { switch(m_addrMode) { case eRegisterDirect: m_base = new RegDirectAddrMode(cpu_dsPic,opcode & 0xf); m_destination = new RegDirectAddrMode(cpu_dsPic,opcode & 0xf); m_source = new LiteralAddressingMode(cpu_dsPic, (opcode >> 4) & ((opcode & (1 << 14)) ? 0xff : 0x3ff)); break; case eRegisterIndirect: m_base = new RegDirectAddrMode(cpu_dsPic, (opcode>>15) & 0xf); m_source = AddressingMode::construct(cpu_dsPic, (opcode >> 4) & 0x7, opcode & 0x1f); m_destination = AddressingMode::construct(cpu_dsPic, (opcode >> 11) & 0x7, (opcode >> 7) & 0xf); break; default: assert(0); } } char *RegisterToRegisterInstruction::name(char *buff,int len) { if (!buff) return buff; char cpBase[256]; char cpSource[256]; char cpDestination[256]; switch(m_addrMode) { case eRegisterDirect: snprintf(buff, len, "%s%s\t%s, %s", instruction::name().c_str(), (m_bByteOperation ? ".b" :""), m_source->name(cpBase,sizeof(cpBase)), m_destination->name(cpDestination,sizeof(cpDestination)) ); break; case eRegisterIndirect: snprintf(buff, len, "%s%s\t%s,%s,%s", instruction::name().c_str(), (m_bByteOperation ? ".b" :""), m_base->name(cpBase,sizeof(cpBase)), m_source->name(cpSource,sizeof(cpSource)), m_destination->name(cpDestination,sizeof(cpDestination)) ); break; default: break; } return buff; } //-------------------------------------------------- ADDR::ADDR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr, eAddressingModes addrMode) : RegisterToRegisterInstruction(new_cpu, new_opcode, addr,"add",addrMode) { } void ADDR::execute() { RegisterValue baseRV(m_base ? m_base->get() : m_destination->get()); RegisterValue srcRV (m_source->get()); RegisterValue resRV (srcRV); resRV.data += baseRV.data; resRV.init |= baseRV.init; m_destination->put(resRV); unsigned flags = ((resRV.data & 0xffff ) ? 0 : eZ) | ((resRV.data & 0x10000 ) ? eC : 0) | (((resRV.data ^ baseRV.data ^ srcRV.data)&0x10) ? eDC : 0) | ((((resRV.data & ~baseRV.data & ~srcRV.data) | (~resRV.data & baseRV.data & srcRV.data)) & 0x8000) ? eOV : 0) | ((resRV.data & 0x8000 ) ? eN : 0); cpu_dsPic->m_status.putFlags(flags, eC|eZ|eOV|eN|eDC, 0); cpu_dsPic->pc->increment(); } //-------------------------------------------------- /* ADDL::ADDL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : RegisterDirectLiteralInstruction(new_cpu, new_opcode, addr,"add") { } void ADDL::execute() { cpu_dsPic->pc->increment(); } */ //-------------------------------------------------- ADD::ADD (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("add"); printf("constructing a ADD\n"); } void ADD::execute() { cpu_dsPic->pc->increment(); } //-------------------------------------------------- ADDC::ADDC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("addc"); printf("constructing a ADDC\n"); } void ADDC::execute() { } //-------------------------------------------------- AND::AND (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("and"); printf("constructing a AND\n"); } void AND::execute() { } //-------------------------------------------------- ASR::ASR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("asr"); printf("constructing a ASR\n"); } void ASR::execute() { } //-------------------------------------------------- BCLR::BCLR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bclr"); printf("constructing a BCLR\n"); } void BCLR::execute() { } //-------------------------------------------------- BRA::BRA (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : LiteralBranch(new_cpu, new_opcode, addr, "bra") { new_name("bra"); switch ((opcode>>16) & 0x0f) { case OV: // Overflow mcP_conditionName = "OV,"; break; case C: // Carry and GEU mcP_conditionName = "C,"; break; case Z: // Zero mcP_conditionName = "Z,"; break; case N: // Negative mcP_conditionName = "N,"; break; case LE: // Less than or equal to mcP_conditionName = "LE,"; break; case LT: // Less than mcP_conditionName = "LT,"; break; case LEU: // Less than or equal unsigned mcP_conditionName = "LEU,"; break; case UN: // Unconditionally mcP_conditionName = ""; break; case NOV: // No overflow mcP_conditionName = "NOV,"; break; case NC: // No Carry and LTU (less than unsigned) mcP_conditionName = "NC,"; break; case NZ: // Not zero mcP_conditionName = "NZ,"; break; case NN: // Not Negative mcP_conditionName = "NN,"; break; case GT: // Greater than mcP_conditionName = "GT,"; break; case GE: // Greater than or equal mcP_conditionName = "GE,"; break; case GTU: // Greater than unsigned mcP_conditionName = "GTU,"; break; case NU: // not used... default: break; } } void BRA::execute() { if (m_condition) cpu_dsPic->pc->jump(m_destination>>1); else cpu_dsPic->pc->increment(); } //-------------------------------------------------- BSET::BSET (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bset"); printf("constructing a BSET\n"); } void BSET::execute() { } //-------------------------------------------------- BSW::BSW (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bsw "); printf("constructing a BSW\n"); } void BSW::execute() { } //-------------------------------------------------- BTG::BTG (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("btg "); printf("constructing a BTG\n"); } void BTG::execute() { } //-------------------------------------------------- BTS::BTS (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("bts"); printf("constructing a BTS\n"); } void BTS::execute() { } //-------------------------------------------------- BTST::BTST (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("btst"); printf("constructing a BTST\n"); } void BTST::execute() { } //-------------------------------------------------- BTSTS::BTSTS (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("btsts"); printf("constructing a BTSTS\n"); } void BTSTS::execute() { } //-------------------------------------------------- CALL::CALL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("call"); printf("constructing a CALL\n"); } void CALL::execute() { } //-------------------------------------------------- CLR::CLR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("clr"); printf("constructing a CLR\n"); } void CLR::execute() { } //-------------------------------------------------- CLRWDT::CLRWDT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("clrwdt"); printf("constructing a CLRWDT\n"); } void CLRWDT::execute() { } //-------------------------------------------------- COM::COM (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("com"); printf("constructing a COM\n"); } void COM::execute() { } //-------------------------------------------------- CP::CP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cp"); printf("constructing a CP\n"); } void CP::execute() { } //-------------------------------------------------- CP0::CP0 (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cp0"); printf("constructing a CP0\n"); } void CP0::execute() { } //-------------------------------------------------- CPB::CPB (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cpb"); printf("constructing a CPB\n"); } void CPB::execute() { } //-------------------------------------------------- CPS::CPS (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("cps"); printf("constructing a CPS\n"); } void CPS::execute() { } //-------------------------------------------------- DAW::DAW (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("daw"); printf("constructing a DAW\n"); } void DAW::execute() { } //-------------------------------------------------- DEC::DEC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("dec"); printf("constructing a DEC\n"); } void DEC::execute() { } //-------------------------------------------------- DISI::DISI (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("disi"); printf("constructing a DISI\n"); } void DISI::execute() { } //-------------------------------------------------- DIV::DIV (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("div"); printf("constructing a DIV\n"); } void DIV::execute() { } //-------------------------------------------------- DO::DO (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("do"); printf("constructing a DO\n"); } void DO::execute() { } //-------------------------------------------------- ED::ED (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ed"); printf("constructing a ED\n"); } void ED::execute() { } //-------------------------------------------------- EXCH::EXCH (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("exch"); printf("constructing a EXCH\n"); } void EXCH::execute() { } //-------------------------------------------------- FB::FB (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("fb"); printf("constructing a FB\n"); } void FB::execute() { } //-------------------------------------------------- GOTO::GOTO (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : MultiWordBranch(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("goto"); printf("constructing a GOTO\n"); } void GOTO::execute() { if(!initialized) runtime_initialize(); cpu_dsPic->pc->jump(destination_index); } //-------------------------------------------------- INC::INC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("inc"); printf("constructing a INC\n"); } void INC::execute() { } //-------------------------------------------------- IOR::IOR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ior"); printf("constructing a IOR\n"); } void IOR::execute() { } //-------------------------------------------------- LAC::LAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("lac"); printf("constructing a LAC\n"); } void LAC::execute() { } //-------------------------------------------------- LNK::LNK (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : ImmediateInstruction(new_cpu, new_opcode, addr) { new_name("lnk"); } void LNK::execute() { unsigned int tos = cpu_dsPic->W[15].get_value(); unsigned int tos_index = tos>>1; cpu_dsPic->registers[tos_index]->put(cpu_dsPic->W[14].get()); cpu_dsPic->W[14].put(tos+2); cpu_dsPic->W[15].put(tos+2+m_L); cpu_dsPic->pc->increment(); } //-------------------------------------------------- LSR::LSR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("lsr"); printf("constructing a LSR\n"); } void LSR::execute() { } //-------------------------------------------------- MAC::MAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("mac"); printf("constructing a MAC\n"); } void MAC::execute() { } //-------------------------------------------------- MOV::MOV (Processor *new_cpu, unsigned int new_opcode, unsigned int addr, eAddressingModes addrMode) : RegisterToRegisterInstruction(new_cpu, new_opcode, addr,"mov",addrMode) { printf("MOV instruction opcode:0x%x mode=%d\n",opcode,m_addrMode); } void MOV::execute() { RegisterValue baseRV(m_base ? m_base->get() : m_destination->get()); RegisterValue srcRV (m_source->get()); RegisterValue resRV (srcRV); resRV.data += baseRV.data; resRV.init |= baseRV.init; m_destination->put(resRV); unsigned flags = ((resRV.data & 0xffff ) ? 0 : eZ) | ((resRV.data & 0x10000 ) ? eC : 0) | (((resRV.data ^ baseRV.data ^ srcRV.data)&0x10) ? eDC : 0) | ((((resRV.data & ~baseRV.data & ~srcRV.data) | (~resRV.data & baseRV.data & srcRV.data)) & 0x8000) ? eOV : 0) | ((resRV.data & 0x8000 ) ? eN : 0); cpu_dsPic->m_status.putFlags(flags, eC|eZ|eOV|eN|eDC, 0); cpu_dsPic->pc->increment(); } //-------------------------------------------------- MOVSAC::MOVSAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("movsac"); printf("constructing a MOVSAC\n"); } void MOVSAC::execute() { } //-------------------------------------------------- MPY::MPY (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("mpy"); printf("constructing a MPY\n"); } void MPY::execute() { } //-------------------------------------------------- MUL::MUL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("mul"); printf("constructing a MUL\n"); } void MUL::execute() { } //-------------------------------------------------- NEG::NEG (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("neg"); printf("constructing a NEG\n"); } void NEG::execute() { } //-------------------------------------------------- NOP::NOP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("nop"); // For the 18cxxx family, this 'nop' may in fact be the // 2nd word in a 2-word opcode. So just to be safe, let's // initialize the cross references to the source file. // (Subsequent initialization code will overwrite this, // but there is a chance that this info will be accessed // before that occurs). //printf("constructing a NOP\n"); } void NOP::execute() { //cpu_pic->pc->increment(); } //-------------------------------------------------- POP::POP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("pop"); printf("constructing a POP\n"); } void POP::execute() { } //-------------------------------------------------- PUSH::PUSH (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("push"); printf("constructing a PUSH\n"); } void PUSH::execute() { } //-------------------------------------------------- PWRSAV::PWRSAV (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("pwrsav"); printf("constructing a PWRSAV\n"); } void PWRSAV::execute() { } //-------------------------------------------------- RCALL::RCALL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : LiteralBranch(new_cpu, new_opcode, addr,"rcall") { } void RCALL::execute() { cpu_dsPic->m_stack.push(); cpu_dsPic->pc->jump(m_destination>>1); } //-------------------------------------------------- REPEAT::REPEAT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("repeat"); printf("constructing a REPEAT\n"); } void REPEAT::execute() { } //-------------------------------------------------- RESET::RESET (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("reset"); printf("constructing a RESET\n"); } void RESET::execute() { } //-------------------------------------------------- RET::RET (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ret"); printf("constructing a RET\n"); } void RET::execute() { } //-------------------------------------------------- ROT::ROT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("rot"); printf("constructing a ROT\n"); } void ROT::execute() { } //-------------------------------------------------- SAC::SAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sac"); printf("constructing a SAC\n"); } void SAC::execute() { } //-------------------------------------------------- SE::SE (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("se"); printf("constructing a SE\n"); } void SE::execute() { } //-------------------------------------------------- SETM::SETM (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("setm"); printf("constructing a SETM\n"); } void SETM::execute() { } //-------------------------------------------------- SFTAC::SFTAC (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sftac"); printf("constructing a SFTAC\n"); } void SFTAC::execute() { } //-------------------------------------------------- SL::SL (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sl"); printf("constructing a SL\n"); } void SL::execute() { } //-------------------------------------------------- SUB::SUB (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("sub"); printf("constructing a SUB\n"); } void SUB::execute() { } //-------------------------------------------------- SWAP::SWAP (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("swap"); printf("constructing a SWAP\n"); } void SWAP::execute() { } //-------------------------------------------------- TBLRD::TBLRD (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("tblrd"); printf("constructing a TBLRD\n"); } void TBLRD::execute() { } //-------------------------------------------------- TBLWT::TBLWT (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("tblwt"); printf("constructing a TBLWT\n"); } void TBLWT::execute() { } //-------------------------------------------------- ULNK::ULNK (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ulnk"); printf("constructing a ULNK\n"); } void ULNK::execute() { } //-------------------------------------------------- XOR::XOR (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("xor"); printf("constructing a XOR\n"); } void XOR::execute() { } //-------------------------------------------------- ZE::ZE (Processor *new_cpu, unsigned int new_opcode, unsigned int addr) : instruction(new_cpu, new_opcode, addr) { decode(new_cpu,new_opcode); new_name("ZE"); printf("constructing a ZE\n"); } void ZE::execute() { } }; gpsim-0.30.0/src/dspic/gpsim_modules.cc0000664000076400007640000000504513041763613014723 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_dspic library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include "../../config.h" // get the definition for HAVE_GUI #include "../modules.h" //#include "dspic-processors.h" /* class Module_Types { public: char *names[2]; Module * (*module_constructor) (void); }; */ Module_Types available_modules[] = { // No more modules { {0,0},0} }; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /******************************************************************************** * mod_list - Display all of the modules in this library. * * This is a required function for gpsim compliant libraries. */ Module_Types * get_mod_list(void) { return available_modules; } /******************************************************************************** * mod_list - Display all of the modules in this library. * * This is a required function for gpsim compliant libraries. */ void mod_list(void) { unsigned int number_of = sizeof(available_modules) / sizeof(Module_Types); unsigned int i,j,l; unsigned int k,longest; for(i=0,longest=0; ilongest) longest = k; } k=0; do { for(i=0; (i<4) && (k. */ #ifndef __P16X6X_H__ #define __P16X6X_H__ #include "14bit-processors.h" #include "p16x8x.h" #include "14bit-tmrs.h" #include "intcon.h" #include "pir.h" #include "ssp.h" #include "psp.h" #include "eeprom.h" #include "comparator.h" #include "a2dconverter.h" class P16C61 : public P16X8X { public: P16C61(const char *_name=0, const char *desc=0); virtual ~P16C61(); virtual PROCESSOR_TYPE isa(){return _P16C61_;}; virtual unsigned int program_memory_size() const { return 0x400; }; virtual void create(); static Processor *construct(const char *name); }; // // -- Define a class to contain most of the registers/peripherals // of a 16x6x device (where the second `x' is >= 3 // class P16X6X_processor : public Pic14Bit { public: PicPortRegister *m_portc; PicTrisRegister *m_trisc; T1CON t1con; PIR *pir1; PIE pie1; PIR *pir2; PIE pie2; T2CON t2con; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; CCPCON ccp2con; CCPRL ccpr2l; CCPRH ccpr2h; PCON pcon; PIR_SET_1 pir_set_def; SSP_MODULE ssp; virtual unsigned int program_memory_size() const { return 0x800; }; virtual unsigned int register_memory_size () const { return 0x100; } virtual void create_symbols(); virtual void create_sfr_map(); virtual PIR *get_pir2() { return (pir2); } virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_def); } P16X6X_processor(const char *_name=0, const char *desc=0); virtual ~P16X6X_processor(); }; /********************************************************************* * class definitions for the 16c6x family of processors */ class P16C62 : public P16X6X_processor { public: P16C62(const char *_name=0, const char *desc=0); virtual ~P16C62() { } static Processor *construct(const char *name); TMR2_MODULE tmr2_module; virtual PROCESSOR_TYPE isa(){return _P16C62_;}; virtual void create_symbols(); virtual void create_sfr_map(); virtual unsigned int program_memory_size() const { return 0x800; }; virtual void create_iopin_map(); virtual void create(); }; class P16C63 : public P16C62 { public: USART_MODULE usart; virtual PROCESSOR_TYPE isa(){return _P16C63_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x1000; }; P16C63(const char *_name=0, const char *desc=0); virtual ~P16C63(); static Processor *construct(const char *name); void create(); void create_sfr_map(); }; class P16C64 : public P16X6X_processor { public: // XXX // This pir1_2, pir2_2 stuff is not particularly pretty. It would be // better to just tell C++ to redefine pir1 and pir2 and PIR1v2 and // PIR2v2, but C++ only supports covariance in member function return // values. PIR1v2 *pir1_2_reg; PIR_SET_2 pir_set_2_def; virtual PIR *get_pir1() { return (pir1_2_reg); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } PicPSP_PortRegister *m_portd; PicTrisRegister *m_trisd; PicPortRegister *m_porte; PicPSP_TrisRegister *m_trise; PSP psp; P16C64(const char *_name=0, const char *desc=0); virtual ~P16C64(); static Processor *construct(const char *name); TMR2_MODULE tmr2_module; virtual PROCESSOR_TYPE isa(){return _P16C64_;}; virtual void create_symbols(); void create_sfr_map(); virtual unsigned int program_memory_size() const { return 0x800; }; virtual void create(); virtual void create_iopin_map(); virtual bool hasSPS() {return false;} }; class P16C65 : public P16C64 { public: USART_MODULE usart; virtual PROCESSOR_TYPE isa(){return _P16C65_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x1000; }; P16C65(const char *_name=0, const char *desc=0); virtual ~P16C65(); static Processor *construct(const char *name); void create(); void create_sfr_map(); }; class P16F630 : public _14bit_processor { public: P16F630(const char *_name=0, const char *desc=0); virtual ~P16F630(); T1CON t1con; PIR *pir1; PIE pie1; TMRL tmr1l; TMRH tmr1h; OSCCAL osccal; EEPROM_WIDE *e; PIR1v3 *pir1_3_reg; INTCON_14_PIR intcon_reg; ComparatorModule comparator; PIR_SET_1 pir_set_def; WPU *m_wpu; IOC *m_ioc; virtual PIR *get_pir2() { return (NULL); } virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_def); } PicPortGRegister *m_porta; PicTrisRegister *m_trisa; PicPortRegister *m_portc; PicTrisRegister *m_trisc; virtual PROCESSOR_TYPE isa(){return _P16F630_;} static Processor *construct(const char *name); void create(int); virtual void create_symbols(); virtual void create_sfr_map(); virtual void create_iopin_map(); virtual void option_new_bits_6_7(unsigned int bits); virtual unsigned int program_memory_size() const { return 0x400; }; virtual unsigned int register_memory_size () const { return 0x100; } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual void create_config_memory(); virtual bool set_config_word(unsigned int address, unsigned int cfg_word); }; class P16F676 : public P16F630 { public: ANSEL ansel; ADCON0_12F adcon0; ADCON1_16F adcon1; sfr_register adresh; sfr_register adresl; P16F676(const char *_name=0, const char *desc=0); virtual ~P16F676(); virtual PROCESSOR_TYPE isa(){return _P16F676_;} static Processor *construct(const char *name); virtual void create(int); virtual void create_sfr_map(); }; #endif gpsim-0.30.0/src/comparator.h0000664000076400007640000004154713116643560012773 00000000000000/* Copyright (C) 1998-2002 T. Scott Dattalo Copyright (C) 2006,2010,2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __COMPARATOR_H__ #define __COMPARATOR_H__ #include "14bit-tmrs.h" #include #include /*************************************************************************** * * Include file for: Processors with dual comparators and Voltage Refarence * * * ***************************************************************************/ #define CFG_MASK 0xf #define CFG_SHIFT 4 class CMSignalSource; class CMxSignalSource; class VRSignalSource; class CMCON; class TMRL; enum compare_inputs { AN0 = 0, AN1, AN2, AN3, AN4, AN5, VREF = 6, // use reference voltage NO_IN = 7, // no input port V06 = 8 // Reference voltage 0.6 }; enum compare_outputs { OUT0 = 0, OUT1, ZERO = 6, // register value == 0 NO_OUT = 7 // no ouput port }; class VRCON : public sfr_register { public: CMCON *_cmcon; enum VRCON_bits { VR0 = 1<<0, // VR0-3 Value selection VR1 = 1<<1, VR2 = 1<<2, VR3 = 1<<3, VRSS = 1<<4, // Use external references (16f88x) VRR = 1<<5, // Range select VROE = 1<<6, // Output Reference to external pin VREN = 1<<7 // Enable Vref }; VRCON(Processor *pCpu, const char *pName, const char *pDesc); ~VRCON(); virtual void put(unsigned int new_value); virtual void setIOpin(PinModule *); virtual double get_Vref(); void setValidBits(unsigned int mask) { valid_bits = mask;} protected: unsigned int valid_bits; PinModule *vr_PinModule; double vr_Vref; stimulus *vr_pu; stimulus *vr_pd; stimulus *vr_06v; double vr_Rhigh; double vr_Rlow; double Vref_high; // usually VDD double Vref_low; // usually VSS char *pin_name; // original name of pin }; // VSCOM class with two comparators as per 16f690 // class VRCON_2 : public sfr_register { public: CMCON *_cmcon; enum VRCON_bits { VR0 = 1<<0, // VR0-3 Value selection VR1 = 1<<1, VR2 = 1<<2, VR3 = 1<<3, VP6EN = 1<<4, // 0.6V reference enable VRR = 1<<5, // Range select C2VREN = 1<<6, // Comparator 2 Reference enable C1VREN = 1<<7 // Comparator 1 Reference enable }; VRCON_2(Processor *pCpu, const char *pName, const char *pDesc); ~VRCON_2(); virtual void put(unsigned int new_value); protected: unsigned int valid_bits; PinModule *vr_PinModule; double vr_Vref; stimulus *vr_pu; stimulus *vr_pd; stimulus *vr_06v; char *pin_name; // original name of pin }; class CM_stimulus : public stimulus { public: CM_stimulus(CMCON *arg, const char *n=0, double _Vth=0.0, double _Zth=1e12 ); ~CM_stimulus(); CMCON *_cmcon; virtual void set_nodeVoltage(double v); }; class CM2CON1_V2; class CMv2_stimulus : public stimulus { public: CMv2_stimulus(CM2CON1_V2 *arg, const char *n=0, double _Vth=0.0, double _Zth=1e12 ); ~CMv2_stimulus(); CM2CON1_V2 *_cm2con1; virtual void set_nodeVoltage(double v); }; class CMCON1 : public sfr_register { public: enum CMCON1_bits { CMSYNC = 1<<0, T1GSS = 1<<1 }; virtual void put(unsigned int); void set_tmrl(TMRL *arg) { m_tmrl = arg; } CMCON1(Processor *pCpu, const char *pName, const char *pDesc); ~CMCON1(); private: TMRL *m_tmrl; unsigned int valid_bits; }; class CMCON : public sfr_register { public: VRCON *_vrcon; enum CMCON_bits { CM0 = 1<<0, CM1 = 1<<1, CM2 = 1<<2, CIS = 1<<3, C1INV = 1<<4, C2INV = 1<<5, C1OUT = 1<<6, C2OUT = 1<<7, }; virtual void setINpin(int i, PinModule *, const char *an); virtual void setOUTpin(int i, PinModule *); virtual void assign_pir_set(PIR_SET *new_pir_set); virtual unsigned int get(); virtual void rename_pins(unsigned int) { puts("CMCON::rename_pins() should not be called");} virtual void put(unsigned int); virtual void set_configuration(int comp, int mode, int il1, int ih1, int il2, int ih2, int out); virtual double comp_voltage(int ind, int invert); void releasePin(int); void set_tmrl(TMRL *arg) { m_tmrl = arg; } void set_eccpas(ECCPAS *_eccpas) { m_eccpas = _eccpas; } CMCON(Processor *pCpu, const char *pName, const char *pDesc); ~CMCON(); protected: PinModule *cm_input[4]; PinModule *cm_output[2]; char *cm_input_pin[4]; char *cm_an[4]; char *cm_output_pin[2]; CMSignalSource *cm_source[2]; bool cm_source_active[2]; unsigned int m_CMval[2]; PIR_SET *pir_set; TMRL *m_tmrl; CM_stimulus *cm_stimulus[6]; ECCPAS *m_eccpas; static const int cMaxConfigurations=8; static const int cMaxComparators=2; guint32 m_configuration_bits[cMaxComparators][cMaxConfigurations]; }; class ComparatorModule { public: ComparatorModule(Processor *); void initialize( PIR_SET *pir_set, PinModule *pin_vr0, PinModule *pin_cm0, PinModule *pin_cm1, PinModule *pin_cm2, PinModule *pin_cm3, PinModule *pin_cm4, PinModule *pin_cm5); //protected: CMCON cmcon; CMCON1 cmcon1; VRCON vrcon; }; /* * Compare module for 16f88x processors */ class CM1CON0; class CM1CON0_2; class CM2CON0; /* * SRCON SR Latch Control Register */ class SRCON : public sfr_register { public: enum SRCON_bits { FVREN = 1<<0, // Fixed Voltage Reference Enable PULSR = 1<<2, // Pulse Reset of SR latch PULSS = 1<<3, // Pulse set of SR Latch C2REN = 1<<4, // C2OUT resets SR latch C1SEN = 1<<5, // C1OUT sets SR latch SR0 = 1<<6, // MUX SR Q out and C1OUT SR1 = 1<<7 // MUX SR -Q out and C2OUT }; int writable_bits; bool SR_Q; bool set; bool reset; virtual void put(unsigned int new_value); SRCON(Processor *pCpu, const char *pName, const char *pDesc); ~SRCON(){} }; /* * CM2CON1 Comparator control register 1 */ class CM2CON1 : public sfr_register { public: enum CM2CON1_bits { C2SYNC = 1<<0, //C2 Output sync bit T1GSS = 1<<1, // Timer1 Gate Source Select bit C2RSEL = 1<<4, // C2 Reference Select bit C1RSEL = 1<<5, // C1 Reference Select bit MC2OUT = 1<<6, // Mirror C2OUT bit MC1OUT = 1<<7 // Mirror C1OUT bit }; int writable_bits; CM1CON0 *m_cm1con0; CM2CON0 *m_cm2con0; virtual void put(unsigned int new_value); void link_cm12con0(CM1CON0 *_cm1con0, CM2CON0 *_cm2con0); CM2CON1(Processor *pCpu, const char *pName, const char *pDesc); ~CM2CON1(){} }; class CM12SignalSource; // The following classes are for comparators which have 3 registers // class CMxCON1; class ComparatorModule2; class CMxCON0_base : public sfr_register { public: enum { ON = 1<<7, OE = 1<<5 }; virtual unsigned int get(); virtual double get_Vpos(){return 0.;} virtual double get_Vneg(){return 0.;} virtual void put(unsigned int) { puts("Help");} // virtual int get(){return 0;} virtual void setBitMask(unsigned int bm) { mValidBits = bm; } virtual void setIntSrc(InterruptSource *_IntSrc) { IntSrc = _IntSrc;} virtual double CVref(){return 0.;} virtual void notify(){;} virtual bool output_active() { return value.get() & (ON | OE); } virtual double get_hysteresis(){ return 0.;} virtual bool output_high() { return false;} virtual void set_output(bool output) { ;} virtual bool is_on(){return false;} virtual bool out_invert(){ return true;} virtual void releasePin(){ cm_source_active = false;} CMxCON0_base(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *cmModule); ~CMxCON0_base(); unsigned int mValidBits; PinModule *cm_input[5]; PinModule *cm_output; CM2CON1 *m_cm2con1; SRCON *m_srcon; // PIR_SET *pir_set; InterruptSource *IntSrc; // TMRL *m_tmrl; CM_stimulus *cm_stimulus[2]; Stimulus_Node *cm_snode[2]; ECCPAS *m_eccpas; unsigned int cm; // comparator number CMxCON1 *m_cmxcon1; ComparatorModule2 *m_cmModule; CMxSignalSource *cm_source; bool cm_source_active; }; class CMxCON0 : public CMxCON0_base { public: enum { CxSYNC = 1<<0, // Output Synchronous Mode bit CxHYS = 1<<1, // Hysteresis Enable bit CxSP = 1<<2, // Speed/Power Select bit CxZLF = 1<<3, // Zero Latency Filter Enable bit CxPOL = 1<<4, // Output polarity select bit CxOE = 1<<5, // Output enable CxOUT = 1<<6, // Output bit CxON = 1<<7, // Enable bit }; CMxCON0(Processor *pCpu, const char *pName, const char *pDesc, unsigned int x, ComparatorModule2 *); ~CMxCON0(); void put(unsigned int); virtual double get_Vpos(); virtual double get_Vneg(); void setBitMask(unsigned int bm) { mValidBits = bm; } virtual bool is_on() { return (value.get() & CxON);} virtual bool out_invert() { return value.get() & CxPOL;} virtual double get_hysteresis(); virtual void set_output(bool output); virtual bool output_high() { return value.get() & CxOUT; } }; class CMxCON0_V2 : public CMxCON0_base { public: enum { CxCH0 = 1<<0, // Channel select bit 0 CxCH1 = 1<<1, // Channel select bit 1 CxR = 1<<2, // Reference select bit (non-inverting input) CxPOL = 1<<4, // Output polarity select bit CxOE = 1<<5, // Output enable CxOUT = 1<<6, // Output bit CxON = 1<<7, // Enable bit NEG = 0, POS = 1, }; CMxCON0_V2(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *cmModule); ~CMxCON0_V2(); virtual void put(unsigned int); virtual double get_Vpos(); virtual double get_Vneg(); void setBitMask(unsigned int bm) { mValidBits = bm; } virtual bool is_on() { return (value.get() & CxON);} virtual bool out_invert() { return value.get() & CxPOL;} virtual double get_hysteresis(); virtual void set_output(bool output); virtual bool output_high() { return value.get() & CxOUT; } PinModule *stimulus_pin[2]; }; class CMxCON1_base : public sfr_register { public: enum { NEG = 0, POS = 1 }; CMxCON1_base(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *); ~CMxCON1_base(); void setBitMask(unsigned int bm) { mValidBits = bm; } PinModule *output_pin(int cm=0) { return cm_output[cm]; } virtual void put(unsigned int new_value){} virtual double get_Vpos(unsigned int arg=0, unsigned int arg2=0){ return 0.;} virtual double get_Vneg(unsigned int arg=0, unsigned int arg2=0){ return 0.;} virtual void setPinStimulus(PinModule *, int); virtual void set_INpinNeg(PinModule *pin_cm0, PinModule *pin_cm1, PinModule *pin_cm2=0, PinModule *pin_cm3=0, PinModule *pin_cm4=0); virtual void set_OUTpin(PinModule *pin_cm0, PinModule *pin_cm1=0); virtual void set_INpinPos(PinModule *pin_cm0, PinModule *pin_cm1=0); virtual bool hyst_active(unsigned int cm) { return false;} virtual void set_vrcon(VRCON *vrcon) {;} virtual void set_vrcon(VRCON_2 *vrcon) {;} virtual void tmr_gate(unsigned int cm, bool output) {;} protected: unsigned int cm; // comparator number CM_stimulus *cm_stimulus[4]; // stimuli to monitor input pin PinModule *stimulus_pin[4]; // monitor stimulus loaded on this pin PinModule *ctmu_stimulus_pin; // ctmu stimulus pin ComparatorModule2 *m_cmModule; PinModule *cm_inputNeg[5]; PinModule *cm_inputPos[2]; PinModule *cm_output[2]; }; // CMxCON1 only uses 1 0r 2 of Negative select bits and 2 Positive select bits class CMxCON1 : public CMxCON1_base { public: enum { CxNCH0 = 1<<0, // Negative Input Channel Select bits CxNCH1 = 1<<1, // Negative Input Channel Select bits CxNCH2 = 1<<2, // Negative Input Channel Select bits CxPCH0 = 1<<3, // Positive Input Channel Select bits CxPCH1 = 1<<4, // Positive Input Channel Select bits CxPCH2 = 1<<5, // Positive Input Channel Select bits CxINTN = 1<<6, // Interrupt on Negative Going Edge Enable bits CxINTP = 1<<7, // Interrupt on Positive Going Edge Enable bits CxNMASK = (CxNCH0 | CxNCH1 | CxNCH2), CxPMASK = (CxPCH0 | CxPCH1 | CxPCH2) }; CMxCON1(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _x, ComparatorModule2 *); ~CMxCON1(); virtual void put(unsigned int new_value); virtual double get_Vpos(unsigned int arg=0, unsigned int arg2=0); virtual double get_Vneg(unsigned int arg=0, unsigned int arg2 = 0); }; class CTMU; /* two comparators with common CM2CON1 and no COUT register, hyteresis, C1, C2 possible T1,3,5 gate, FVR or DAC for voltage reference, used by 18f26k22. */ class CM2CON1_V2 : public CMxCON1_base { public: enum { C2SYNC = 1<<0, C1SYNC = 1<<1, C2HYS = 1<<2, C1HYS = 1<<3, C2RSEL = 1<<4, C1RSEL = 1<<5, MC2OUT = 1<<6, MC1OUT = 1<<7 }; CM2CON1_V2(Processor *pCpu, const char *pName, const char *pDesc, ComparatorModule2 * cmModule); ~CM2CON1_V2(); virtual void put(unsigned int new_value); virtual double get_Vpos(unsigned int cm, unsigned int cmxcon0); virtual double get_Vneg(unsigned int cm, unsigned int cmxcon0); virtual bool hyst_active(unsigned int cm); virtual void tmr_gate(unsigned int cm, bool output); void set_ctmu_stim(stimulus *_ctmu_stim, CTMU *_ctmu_module); void attach_ctmu_stim(); void detach_ctmu_stim(); private: stimulus *ctmu_stim; stimulus *comp_input_cap; bool ctmu_attached; }; /* two comparators, no hyteresis, cm2con1 controls t1 gate, C2 possible T1 gate, vrcon for voltage reference used by 16f882. */ class CM2CON1_V3 : public CMxCON1_base { public: enum { C2SYNC = 1<<0, T1GSS = 1<<1, C2RSEL = 1<<4, C1RSEL = 1<<5, MC2OUT = 1<<6, MC1OUT = 1<<7 }; CM2CON1_V3(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 * cmModule) : CMxCON1_base(pCpu, pName, pDesc, _cm, cmModule), m_vrcon(0){} ~CM2CON1_V3(){} virtual void put(unsigned int new_value); virtual double get_Vpos(unsigned int cm, unsigned int cmxcon0); virtual double get_Vneg(unsigned int cm, unsigned int cmxcon0); virtual bool hyst_active(unsigned int cm) { return false;} void set_vrcon(VRCON * _vrcon) { m_vrcon = _vrcon; } virtual void tmr_gate(unsigned int cm, bool output); protected: VRCON *m_vrcon; }; /* two comparators, no hyteresis, cm2con1 controls t1 gate, C2 possible T1 gate, VRCON for voltage reference Like CM2CON1_V3 without C1RSEL, C2RSEL used by 16f690. */ class CM2CON1_V4 : public CM2CON1_V3 { public: CM2CON1_V4(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 * cmModule) ; ~CM2CON1_V4(); virtual void put(unsigned int new_value); virtual double get_Vpos(unsigned int cm, unsigned int cmxcon0); void set_vrcon(VRCON_2 * _vrcon) { m_vrcon = _vrcon; } protected: VRCON_2 *m_vrcon; CM_stimulus *cm1_cvref; CM_stimulus *cm1_v06ref; CM_stimulus *cm2_cvref; CM_stimulus *cm2_v06ref; }; class CMOUT : public sfr_register { public: void put(unsigned int val) { return;} // Read only by user CMOUT(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) {} }; // uses CMxCON0, CMxCON1, CMOUT class ComparatorModule2 { public: ComparatorModule2(Processor *); ~ComparatorModule2(); void run_get(unsigned int comp) { cmxcon0[comp]->get();} void set_DAC_volt(double); void set_FVR_volt(double); void set_cmout(unsigned int bit, bool value); void set_if(unsigned int); void assign_pir_set(PIR_SET *new_pir_set){ pir_set = new_pir_set;} void assign_tmr1l(TMRL *t1, TMRL *t3 = 0, TMRL *t5 = 0) { tmr1l[0] = t1; tmr1l[1] = t3; tmr1l[2] = t5; } void assign_t1gcon(T1GCON *t1g, T1GCON *t3g = 0, T1GCON *t5g = 0) { t1gcon[0] = t1g; t1gcon[1] = t3g; t1gcon[2] = t5g; } void assign_sr_module(SR_MODULE *_sr_module) { sr_module = _sr_module;} void assign_eccpsas(ECCPAS *a1, ECCPAS *a2=0, ECCPAS *a3=0) { eccpas[0] = a1; eccpas[1] = a2; eccpas[2] = a3; } CMxCON0_base *cmxcon0[4]; CMxCON1_base *cmxcon1[4]; CMOUT *cmout; //protected: double DAC_voltage; double FVR_voltage; PIR_SET *pir_set; TMRL *tmr1l[3]; T1GCON *t1gcon[3]; SR_MODULE *sr_module; CTMU *ctmu_module; ECCPAS *eccpas[3]; }; #endif // __COMPARATOR_H__ gpsim-0.30.0/src/xref.h0000664000076400007640000000240513063451152011551 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __XREF_H__ #define __XREF_H__ //------------------------------------------------------------------- #include using namespace std; class gpsimObject; class XrefObject { private: list xrefs; public: gpsimObject *data; XrefObject(); explicit XrefObject(gpsimObject *value); virtual ~XrefObject(); virtual void _add(void *xref); virtual void clear(void *xref); virtual void *first_xref(); virtual void _update(); virtual int get_val(void); virtual void assign_data(gpsimObject *); }; #endif gpsim-0.30.0/src/a2d_v2.cc0000664000076400007640000005772113112023067012026 00000000000000/* Copyright (C) 2008,2015 Roy R Rankin Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "ioports.h" #include "trace.h" #include "gpsim_time.h" #include "ui.h" #include "pic-processor.h" #include "a2d_v2.h" #define p_cpu ((Processor *)cpu) static PinModule AnInvalidAnalogInput; //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------ // ADCON0 // ADCON0_V2::ADCON0_V2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), adres(0), adresl(0), adcon1(0), adcon2(0), intcon(0), pir1v2(0), ad_state(AD_IDLE), channel_mask(15), ctmu_stim(0), active_stim(-1) { } /* * Link PIC register for High Byte A/D result */ void ADCON0_V2::setAdres(sfr_register *new_adres) { adres = new_adres; } /* * Link PIC register for Low Byte A/D result */ void ADCON0_V2::setAdresLow(sfr_register *new_adresl) { adresl = new_adresl; } /* * Link PIC register for ADCON1 */ void ADCON0_V2::setAdcon1(ADCON1_V2 *new_adcon1) { adcon1 = new_adcon1; } /* * Link PIC register for ADCON2 */ void ADCON0_V2::setAdcon2(ADCON2_V2 *new_adcon2) { adcon2 = new_adcon2; } /* * Link PIC register for PIR1 */ void ADCON0_V2::setPir(PIR1v2 *new_pir1) { pir1v2 = new_pir1; } /* * Link PIC register for INTCON */ void ADCON0_V2::setIntcon(INTCON *new_intcon) { intcon = new_intcon; } /* * Set Tad time for RC source */ void ADCON0_V2::setRCtime(double time) { m_RCtime = time; } /* * Set resolution of A2D converter */ void ADCON0_V2::setA2DBits(unsigned int nBits) { m_A2DScale = (1<get_tad(); Tacq = adcon2->get_nacq(); Dprintf(("\tTad = %u Tacq = %u\n", Tad, Tacq)); if (Tad == 0) // RC time source { if (cpu) { Tad = (m_RCtime * p_cpu->get_frequency()); Tad = Tad < 2 ? 2 : Tad; } else Tad = 6; } if (Tacq == 0) fc += 1; // if Tacq is 0, go to acqusition on next clock cycle else fc += (Tacq * Tad) / p_cpu->get_ClockCycles_per_Instruction(); if(ad_state != AD_IDLE) { // The A/D converter is either 'converting' or 'acquiring' // in either case, there is callback break that needs to be moved. stop_conversion(); get_cycles().reassign_break(future_cycle, fc, this); } else get_cycles().set_break(fc, this); future_cycle = fc; ad_state = AD_ACQUIRING; } void ADCON0_V2::stop_conversion(void) { Dprintf(("stopping A/D conversion\n")); ad_state = AD_IDLE; } void ADCON0_V2::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); unsigned int old_value=value.get(); // SET: Reflect it first! value.put(new_value); if(new_value & ADON) { // The A/D converter is being turned on (or maybe left on) if (ctmu_stim) { // deal with ctmu stimulus for channel change or ON/OFF if ((old_value ^ new_value) & (ADON|CHS0|CHS1|CHS2|CHS3)) { if (new_value & ADON) // A/D is on attach_ctmu_stim(); else if(!(new_value & ADON)) // A/D is off detach_ctmu_stim(); } } if((new_value & ~old_value) & GO) { if (verbose) printf("starting A2D conversion\n"); // The 'GO' bit is being turned on, which is request to initiate // and A/D conversion start_conversion(); } } else stop_conversion(); } void ADCON0_V2::set_ctmu_stim(stimulus *_ctmu_stim) { ctmu_stim = _ctmu_stim; if (value.get() & ADON) attach_ctmu_stim(); } void ADCON0_V2::put_conversion(void) { double dRefSep = m_dSampledVrefHi - m_dSampledVrefLo; double dNormalizedVoltage; dNormalizedVoltage = (dRefSep>0.0) ? (m_dSampledVoltage - m_dSampledVrefLo)/dRefSep : 0.0; dNormalizedVoltage = dNormalizedVoltage>1.0 ? 1.0 : dNormalizedVoltage; unsigned int converted = (unsigned int)(m_A2DScale*dNormalizedVoltage + 0.5); Dprintf(("put_conversion: Vrefhi:%g Vreflo:%g conversion:%u normV:%g\n", m_dSampledVrefHi,m_dSampledVrefLo,converted,dNormalizedVoltage)); if (verbose) printf ("result=0x%02x\n", converted); Dprintf(("%u-bit result 0x%x\n", m_nBits, converted)); if(adresl) { // non-null for more than 8 bit conversion if(adcon2->value.get() & ADCON2_V2::ADFM) { adresl->put(converted & 0xff); adres->put( (converted >> 8) & 0x3); } else { adresl->put((converted << 6) & 0xc0); adres->put( (converted >> 2) & 0xff); } } else { adres->put((converted ) & 0xff); } } // ADCON0_V2 callback is called when the cycle counter hits the break point that // was set in ADCON0_V2::put. void ADCON0_V2::callback(void) { int channel; Dprintf((" ADCON0_V2 Callback: 0x%" PRINTF_GINT64_MODIFIER "x\n",get_cycles().get())); // // The a/d converter is simulated with a state machine. // switch(ad_state) { case AD_IDLE: Dprintf(("ignoring ad callback since ad_state is idle\n")); break; case AD_ACQUIRING: channel = (value.get() >> 2) & channel_mask; m_dSampledVoltage = adcon1->getChannelVoltage(channel); m_dSampledVrefHi = adcon1->getVrefHi(); m_dSampledVrefLo = adcon1->getVrefLo(); Dprintf(("Acquiring channel:%d V=%g reflo=%g refhi=%g\n", channel,m_dSampledVoltage,m_dSampledVrefLo,m_dSampledVrefHi)); future_cycle = get_cycles().get() + ((m_nBits + 1) * Tad)/p_cpu->get_ClockCycles_per_Instruction(); get_cycles().set_break(future_cycle, this); if (verbose) printf("A/D %u bits channel:%d Vin=%.2g Refhi=%.2g Reflo=%.2g ", m_nBits, channel,m_dSampledVoltage,m_dSampledVrefHi,m_dSampledVrefLo); ad_state = AD_CONVERTING; break; case AD_CONVERTING: put_conversion(); // Clear the GO/!DONE flag. value.put(value.get() & (~GO)); set_interrupt(); ad_state = AD_IDLE; } } //------------------------------------------------------ // void ADCON0_V2::set_interrupt(void) { pir1v2->set_adif(); intcon->peripheral_interrupt(); } void ADCON0_V2::detach_ctmu_stim() { if (active_stim >=0 && ctmu_stim) { PinModule *pm=adcon1->get_A2Dpin(active_stim); if (pm && pm->getPin().snode && ctmu_stim) { pm->getPin().snode->detach_stimulus(ctmu_stim); pm->getPin().snode->update(); } } active_stim = -1; } /* Move ctmu_stim onto currently selected A/D channel input pin. if channel has not changed, just return. Stimulus can only be attached if pin is connected to a node. */ void ADCON0_V2::attach_ctmu_stim() { int channel = (value.get() >> 2) & channel_mask; if (channel == active_stim) return; else if (active_stim >= 0) detach_ctmu_stim(); PinModule *pm=adcon1->get_A2Dpin(channel); if (pm) { if (!(pm->getPin().snode)) { printf("Warning ADCON0_V2::attach_ctmu_stim %s has no node attached CTMU will not work properly\n", pm->getPin().name().c_str()); } else if (ctmu_stim) { pm->getPin().snode->attach_stimulus(ctmu_stim); pm->getPin().snode->update(); active_stim = channel; } } } //------------------------------------------------------ // ADCON1 // ADCON1_V2::ADCON1_V2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), m_AnalogPins(0), m_nAnalogChannels(0), mValidCfgBits(0), mCfgBitShift(0), m_vrefHiChan(-1), m_vrefLoChan(-1), mIoMask(0), m_adcon0(0) { for (int i=0; i<(int)cMaxConfigurations; i++) { setChannelConfiguration(i, 0); } } ADCON1_V2::~ADCON1_V2() { delete [] m_AnalogPins; } void ADCON1_V2::put(unsigned int new_value) { unsigned int new_mask = get_adc_configmask(new_value); unsigned int diff = mIoMask ^ new_mask; Dprintf (( "ADCON1_V2::put ( %02X ) - new_mask %02X\n", new_value, new_mask )); trace.raw(write_trace.get() | value.get()); char newname[20]; for(unsigned int i = 0; i < m_nAnalogChannels; i++) { if ((diff & (1 << i)) && m_AnalogPins[i] != &AnInvalidAnalogInput) { if (new_mask & (1<AnalogReq(this, true, newname); } else { m_AnalogPins[i]->AnalogReq(this, false, m_AnalogPins[i]->getPin().name().c_str()); } } } mIoMask = new_mask; value.put(new_value); } /* * Set the channel used for Vref+ when VCFG0 is set */ void ADCON1_V2::setVrefHiChannel(unsigned int channel) { m_vrefHiChan = channel; } /* * Set the channel used for Vref- when VCFG1 is set */ void ADCON1_V2::setVrefLoChannel(unsigned int channel) { m_vrefLoChan = channel; } /* * If A2D uses PCFG, call for each PCFG value (cfg 0 to 15) with * each set bit of bitMask indicating port is an analog port * (either A2D input port or Vref). Processors which use an A2D * method that uses ANSEL register will not call this. * * As an example, for the following Port Configuration Control bit: * PCFG AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 * ---- ---- ----- ----- ----- ----- ----- ----- ----- * 1100 D D D A Vref+ Vref- A A * * then call setChannelConfiguration with cfg = 12 , bitMask = 0x1f * */ void ADCON1_V2::setChannelConfiguration(unsigned int cfg, unsigned int bitMask) { if (cfg < cMaxConfigurations) m_configuration_bits[cfg] = bitMask; } /* * Performs same function as setChannelConfiguration, but defines * all entiries in configuration table in one call. */ void ADCON1_V2::setChanTable( unsigned int m0, unsigned int m1, unsigned int m2, unsigned int m3, unsigned int m4, unsigned int m5, unsigned int m6, unsigned int m7, unsigned int m8, unsigned int m9, unsigned int m10, unsigned int m11, unsigned int m12, unsigned int m13, unsigned int m14, unsigned int m15) { m_configuration_bits[0] = m0; m_configuration_bits[1] = m1; m_configuration_bits[2] = m2; m_configuration_bits[3] = m3; m_configuration_bits[4] = m4; m_configuration_bits[5] = m5; m_configuration_bits[6] = m6; m_configuration_bits[7] = m7; m_configuration_bits[8] = m8; m_configuration_bits[9] = m9; m_configuration_bits[10] = m10; m_configuration_bits[11] = m11; m_configuration_bits[12] = m12; m_configuration_bits[13] = m13; m_configuration_bits[14] = m14; m_configuration_bits[15] = m15; } /* * Number of A2D channels processor supports */ void ADCON1_V2::setNumberOfChannels(unsigned int nChannels) { PinModule **save = NULL; if (!nChannels || nChannels <= m_nAnalogChannels) return; if (m_nAnalogChannels && nChannels > m_nAnalogChannels ) save = m_AnalogPins; m_AnalogPins = new PinModule *[nChannels]; for (unsigned int i=0; i> mCfgBitShift) & mValidCfgBits]); } else // register directly gives Analog ports (18f1220) { return (~(reg >> mCfgBitShift) & mValidCfgBits); } } /* * Associate a processor I/O pin with an A2D channel */ void ADCON1_V2::setIOPin(unsigned int channel, PinModule *newPin) { if (channel < m_nAnalogChannels && m_AnalogPins[channel] == &AnInvalidAnalogInput && newPin!=0) { m_AnalogPins[channel] = newPin; } else { printf("WARNING %s channel %u, cannot set IOpin\n",__FUNCTION__, channel); if (m_AnalogPins[channel] != &AnInvalidAnalogInput) printf("Pin Already assigned\n"); else if (channel > m_nAnalogChannels) printf("channel %u >= number of channels %u\n", channel, m_nAnalogChannels); } } //------------------------------------------------------ PinModule *ADCON1_V2::get_A2Dpin(unsigned int channel) { if ( (1<getPin().snode) pm->getPin().snode->update(); voltage = pm->getPin().get_nodeVoltage(); } else { cout << "ADCON1_V2::getChannelVoltage channel " << channel << " not a valid pin\n"; voltage = 0.; } } else { cout << "ADCON1_V2::getChannelVoltage channel " << channel << " > m_nAnalogChannels " << m_nAnalogChannels << "\n"; } return voltage; } double ADCON1_V2::getVrefHi() { assert(m_vrefHiChan >= 0); // m_vrefHiChan has not been set if ( (m_adcon0 && (m_adcon0->value.data & ADCON0_V2::VCFG0)) || ( !m_adcon0 && (value.data & VCFG0))) // Use Vref+ return(getChannelVoltage(m_vrefHiChan)); return ((Processor *)cpu)->get_Vdd(); } double ADCON1_V2::getVrefLo() { assert(m_vrefLoChan >= 0); // m_vrefLoChan has not been set if ( (m_adcon0 && (m_adcon0->value.data & ADCON0_V2::VCFG1)) || ( !m_adcon0 && (value.data & VCFG1))) // Use Vref- return getChannelVoltage(m_vrefLoChan); return 0.0; } //------------------------------------------------------ // ADCON2_V2 // ADCON2_V2::ADCON2_V2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } char ADCON2_V2::get_nacq() { static char acq_tab[8] = { 0, 2, 4, 6, 8, 12, 16, 20}; return(acq_tab[((value.get() & (ACQT2 | ACQT1 | ACQT0)) >> 3) ]); } char ADCON2_V2::get_tad() { static char adcs_tab[8] = { 2, 8, 32, 0, 4, 16, 64, 0}; return(adcs_tab[(value.get() & (ADCS2 | ADCS1 | ADCS0)) ]); } bool ADCON2_V2::get_adfm() { return((value.get() & ADFM) == ADFM); } ADCON1_2B::ADCON1_2B(Processor *pCpu, const char *pName, const char *pDesc) : ADCON1_V2(pCpu, pName, pDesc), Vctmu(0.0), Vdac(0.0), Vfvr_buf2(0) { } //------------------------------------------------------ PinModule *ADCON1_2B::get_A2Dpin(unsigned int channel) { if(channel <= m_nAnalogChannels) { PinModule *pm = m_AnalogPins[channel]; if (pm != &AnInvalidAnalogInput) return pm; cout << "ADCON1_V2::getChannelVoltage channel " << channel << " not analog\n"; } return 0; } double ADCON1_2B::getChannelVoltage(unsigned int channel) { double voltage=0.0; if(channel <= m_nAnalogChannels) { PinModule *pm = get_A2Dpin(channel); if (pm) voltage = pm->getPin().get_nodeVoltage(); else { cout << "ADCON1_2B::getChannelVoltage channel " << channel << " not valid for A2D\n"; } } else if (channel == CTMU) voltage = Vctmu; else if (channel == DAC) { voltage = Vdac; } else if (channel == FVR_BUF2) voltage = Vfvr_buf2; else { cout << "ADCON1_2B::getChannelVoltage channel " << channel << " not valid for A2D\n"; } return voltage; } double ADCON1_2B::getVrefHi() { assert(m_vrefHiChan >= 0); // m_vrefHiChan has not been set switch (value.data & (PVCFG1 | PVCFG0)) { case 0: // use Vdd case (PVCFG1 | PVCFG0): // reserved use Vdd return ((Processor *)cpu)->get_Vdd(); break; case PVCFG0: // use external pin Vref+ return(getChannelVoltage(m_vrefHiChan)); break; case PVCFG1: // use FVR buf2 return Vfvr_buf2; break; } return 0.0; } double ADCON1_2B::getVrefLo() { assert(m_vrefLoChan >= 0); // m_vrefLoChan has not been set // external pin Vref- ? if ((value.data & (NVCFG1 | NVCFG0)) == NVCFG1) return getChannelVoltage(m_vrefLoChan); // else AVss (0) return 0.0; } void ADCON1_2B::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } // Special trigger from ctmu module void ADCON1_2B::ctmu_trigger() { if (value.data & TRIGSEL) // special trigger from CTMU active? { assert(m_adcon0); unsigned int value = m_adcon0->value.data; if ((value & ADCON0_V2::ADON)) { value |= ADCON0_V2::GO; m_adcon0->put(value); } } } // Special trigger from cpp module void ADCON1_2B::ccp_trigger() { if (!(value.data & TRIGSEL)) // special trigger from ccp active? { unsigned int value = m_adcon0->value.data; if ((value & ADCON0_V2::ADON)) { value |= ADCON0_V2::GO; m_adcon0->put(value); } } } ANSEL_2B::ANSEL_2B(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), mask(0) { for(int i=0; i<8; i++) { analog_channel[i] = -1; m_AnalogPins[i] = &AnInvalidAnalogInput; } } void ANSEL_2B::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } void ANSEL_2B::put_value(unsigned int new_value) { char newname[20]; new_value &= mask; unsigned int diff = value.get() ^ new_value; value.put(new_value); for(int i = 0; i < 8; i++) { if (((1<AnalogReq(this, true, newname); } else { m_AnalogPins[i]->AnalogReq(this, false, m_AnalogPins[i]->getPin().name().c_str()); } } } } void ANSEL_2B::setIOPin(unsigned int channel, PinModule *port, ADCON1_2B *adcon1) { char newname[20]; unsigned int pin = port->getPinNumber(); m_AnalogPins[pin] = port; analog_channel[pin] = channel; adcon1->setIOPin(channel, port); mask |= 1<AnalogReq(this, true, newname); } } ANSEL_2A::ANSEL_2A(Processor *pCpu, const char *pName, const char *pDesc) : ANSEL_2B(pCpu, pName, pDesc) { } void ANSEL_2A::setIOPin(unsigned int channel, PinModule *port, ADCON1_2B *adcon1) { char newname[20]; unsigned int bit = channel & 7; m_AnalogPins[bit] = port; analog_channel[bit] = channel; adcon1->setIOPin(channel, port); mask |= 1<AnalogReq(this, true, newname); } } // //-------------------------------------------------- // member functions for the FVRCON_V2 class // with one set of gains and FVRST set after delay //-------------------------------------------------- // FVRCON_V2::FVRCON_V2(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bitMask) : sfr_register(pCpu, pName, pDesc), future_cycle(0), adcon1(0), daccon0(0), cmModule(0), cpscon0(0) { mask_writable = bitMask; } void FVRCON_V2::put(unsigned int new_value) { unsigned int masked_value = (new_value & mask_writable); trace.raw(write_trace.get() | value.get()); put_value(masked_value); } void FVRCON_V2::put_value(unsigned int new_value) { unsigned int diff = value.get() ^ new_value; if (diff) { if (diff & FVREN) new_value &= ~FVRRDY; // Clear FVRRDY regardless of ON or OFF if (new_value & FVREN) // Enable ON? { future_cycle = get_cycles().get() + 25e-6 /get_cycles().seconds_per_cycle(); get_cycles().set_break(future_cycle, this); } else if (future_cycle) { get_cycles().clear_break(this); future_cycle = 0; } } value.put(new_value); compute_FVR(new_value); update(); } // Set FVRRDY bit after timeout void FVRCON_V2::callback() { future_cycle = 0; put_value(value.get() | FVRRDY); } double FVRCON_V2::compute_FVR(unsigned int fvrcon) { double ret = -1.; if (fvrcon & FVRRDY) { switch(fvrcon & (FVRS0 | FVRS1)) { case 0: // output is off ret = 0.0; break; case FVRS0: // Gain = 1 ret = 1.024; break; case FVRS1: // Gain = 2 ret = 2.048; break; case (FVRS0|FVRS1): // Gain = 4 ret = 4.096; break; } } if (ret > ((Processor *)cpu)->get_Vdd()) { cerr << "warning FVRCON FVRAD("<< ret <<") > Vdd(" <<((Processor *)cpu)->get_Vdd() << ")\n"; ret = -1.; } for (unsigned int i= 0; i < daccon0_list.size(); i++) { daccon0_list[i]->set_FVR_CDA_volt(ret); } if(adcon1)adcon1->setVoltRef(ret); if(cmModule) cmModule->set_FVR_volt(ret); if(cpscon0) cpscon0->set_FVR_volt(ret); return ret; } void DACCON0_V2::compute_dac(unsigned int value) { double Vhigh = get_Vhigh(value); double Vlow = 0.; double Vout; if(value & DACEN) // DAC is enabled { Dprintf(("DACCON0_V2::compute_dac Vhigh %.2f daccon1_reg %x\n", Vhigh, daccon1_reg)); Vout = (Vhigh - Vlow) * daccon1_reg/bit_resolution - Vlow; } else if (value & DACLPS) Vout = Vhigh; else Vout = Vlow; Dprintf(("DACCON0_V2::compute_dac value=%x Vout=%.2f adcon1 %p\n", value, Vout, adcon1)); set_dacoutpin(value & DACOE, 0, Vout); if (verbose) printf("%s-%d adcon1 %p FVRCDA_AD_chan %u Vout %.2f\n", __FUNCTION__, __LINE__, adcon1, FVRCDA_AD_chan, Vout); if(adcon1) adcon1->update_dac(Vout); if(cmModule) cmModule->set_DAC_volt(Vout); if(cpscon0) cpscon0->set_DAC_volt(Vout); } double DACCON0_V2::get_Vhigh(unsigned int value) { unsigned int mode = (value & (DACPSS0|DACPSS1)) >> 2; switch(mode) { case 0: // Vdd return ((Processor *)cpu)->get_Vdd(); case 1: // Vref+ pin, get is from A2D setup if(adcon1) return(adcon1->getChannelVoltage(adcon1->getVrefHiChan())); cerr << "ERROR DACCON0 DACPSS=01b adcon1 not set\n"; return 0.; case 2: // Fixed Voltage Reference return FVR_CDA_volt; case 3: // Reserved value cerr << "ERROR DACCON0 DACPSS=11b is reserved value\n"; return 0.; } return 0.; // cant get here } gpsim-0.30.0/src/operator.h0000664000076400007640000002144713063451152012447 00000000000000/* Parser for gpsim Copyright (C) 2004 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #if !defined(__OPERATOR_H__) #define __OPERATOR_H__ #include "expr.h" using namespace std; class Operator : public Expression { public: explicit Operator(const std::string & newOpString) : opString(newOpString) {} virtual ~Operator() { } std::string showOp() { return opString; } private: std::string opString; }; class BinaryOperator : public Operator { public: BinaryOperator(const std::string & opString, Expression* leftExpr, Expression* rightExpr); virtual ~BinaryOperator(); virtual Value* shortCircuit(Value* leftValue); virtual Value* applyOp(Value* leftValue, Value* rightValue)=0; virtual Value* evaluate(); virtual Expression *getLeft(); virtual Expression *getRight(); string show(); string showType(); string toString(); protected: Expression* leftExpr; Expression* rightExpr; Value* value; }; class UnaryOperator : public Operator { public: UnaryOperator(const std::string & opString, Expression* expr); virtual ~UnaryOperator(); virtual Value* applyOp(Value* value)=0; virtual Value* evaluate(); string show(); string showType(); string toString(); protected: Expression* expr; Value* value; }; class ComparisonOperator : public BinaryOperator { public: enum ComparisonTypes { eOpEq, eOpGe, eOpGt, eOpLe, eOpLt, eOpNe }; ComparisonOperator(const std::string & opString, Expression*, Expression*); virtual ~ComparisonOperator(); virtual Value* applyOp(Value* leftValue, Value* rightValue); bool less() { return bLess;} bool equal() { return bEqual;} bool greater() { return bGreater;} virtual ComparisonTypes isa()=0; virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); protected: bool bLess; bool bEqual; bool bGreater; }; //----------------------------------------------------------------- class OpAbstractRange : public BinaryOperator { public: OpAbstractRange(Expression *leftExpr, Expression *rightExpr); virtual ~OpAbstractRange(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpAdd : public BinaryOperator { public: OpAdd(Expression* leftExpr, Expression* rightExpr); virtual ~OpAdd(); virtual Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpAnd : public BinaryOperator { public: OpAnd(Expression* leftExpr, Expression* rightExpr); virtual ~OpAnd(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpDiv : public BinaryOperator { public: OpDiv(Expression* leftExpr, Expression* rightExpr); virtual ~OpDiv(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpEq : public ComparisonOperator { public: OpEq(Expression* leftExpr, Expression* rightExpr); virtual ~OpEq(); ComparisonOperator::ComparisonTypes isa() {return ComparisonOperator::eOpEq;} }; //----------------------------------------------------------------- class OpGe : public ComparisonOperator { public: OpGe(Expression* leftExpr, Expression* rightExpr); virtual ~OpGe(); ComparisonOperator::ComparisonTypes isa() {return ComparisonOperator::eOpGe;} }; //----------------------------------------------------------------- class OpGt : public ComparisonOperator { public: OpGt(Expression* leftExpr, Expression* rightExpr); virtual ~OpGt(); ComparisonOperator::ComparisonTypes isa() {return ComparisonOperator::eOpGt;} }; //----------------------------------------------------------------- class OpLe : public ComparisonOperator { public: OpLe(Expression* leftExpr, Expression* rightExpr); virtual ~OpLe(); ComparisonOperator::ComparisonTypes isa() {return ComparisonOperator::eOpLe;} }; //----------------------------------------------------------------- class OpLogicalAnd : public BinaryOperator { public: OpLogicalAnd(Expression* leftExpr, Expression* rightExpr); virtual ~OpLogicalAnd(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpLogicalOr : public BinaryOperator { public: OpLogicalOr(Expression* leftExpr, Expression* rightExpr); virtual ~OpLogicalOr(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpLt : public ComparisonOperator { public: OpLt(Expression* leftExpr, Expression* rightExpr); virtual ~OpLt(); ComparisonOperator::ComparisonTypes isa() {return ComparisonOperator::eOpLt;} }; //----------------------------------------------------------------- class OpMpy : public BinaryOperator { public: OpMpy(Expression* leftExpr, Expression* rightExpr); virtual ~OpMpy(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpNe : public ComparisonOperator { public: OpNe(Expression* leftExpr, Expression* rightExpr); virtual ~OpNe(); ComparisonOperator::ComparisonTypes isa() {return ComparisonOperator::eOpNe;} }; //----------------------------------------------------------------- class OpOr : public BinaryOperator { public: OpOr(Expression* leftExpr, Expression* rightExpr); virtual ~OpOr(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpShl : public BinaryOperator { public: OpShl(Expression* leftExpr, Expression* rightExpr); virtual ~OpShl(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpShr : public BinaryOperator { public: OpShr(Expression* leftExpr, Expression* rightExpr); virtual ~OpShr(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpSub : public BinaryOperator { public: OpSub(Expression* leftExpr, Expression* rightExpr); virtual ~OpSub(); Value* applyOp(Value* leftValue, Value* rightValue); }; //----------------------------------------------------------------- class OpXor : public BinaryOperator { public: OpXor(Expression* leftExpr, Expression* rightExpr); virtual ~OpXor(); Value* applyOp(Value* leftValue, Value* rightValue); }; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Unary objects //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // ----------------------------------------------------------------- class OpLogicalNot : public UnaryOperator { public: explicit OpLogicalNot(Expression* expr); virtual ~OpLogicalNot(); Value* applyOp(Value* value); }; // ----------------------------------------------------------------- class OpNegate : public UnaryOperator { public: explicit OpNegate(Expression* expr); virtual ~OpNegate(); Value* applyOp(Value* value); }; // ----------------------------------------------------------------- class OpOnescomp : public UnaryOperator { public: explicit OpOnescomp(Expression* expr); virtual ~OpOnescomp(); Value* applyOp(Value* value); }; // ----------------------------------------------------------------- class OpPlus : public UnaryOperator { public: explicit OpPlus(Expression* expr); virtual ~OpPlus(); Value* applyOp(Value* value); }; // ----------------------------------------------------------------- class OpIndirect : public UnaryOperator { public: explicit OpIndirect(Expression* expr); virtual ~OpIndirect(); Value* applyOp(Value* value); }; // ----------------------------------------------------------------- class OpAddressOf : public UnaryOperator { public: explicit OpAddressOf(Expression* expr); virtual ~OpAddressOf(); Value* evaluate(); Value* applyOp(Value* value); }; #endif // __OPERATOR_H__ gpsim-0.30.0/src/symbol.cc0000664000076400007640000002203413077526636012267 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // symbol.cc // // The file contains the code that controls all of the symbol // stuff for gpsim. Most of the work is handled by the C++ map // container class. // #include "symbol.h" #include #include #include #include #include #include #include "value.h" #include "modules.h" SymbolTable gSymbolTable; SymbolTable_t globalSymbols; static SymbolTable_t *currentSymbolTable=0; #define DEBUG 0 #if defined(_WIN32) SymbolTable &globalSymbolTable() { return gSymbolTable; } #endif //------------------------------------------------------------------- //------------------------------------------------------------------- int SymbolTable_t::addSymbol(gpsimObject *pSym, string *ps_AliasedName) { if (pSym) { ps_AliasedName = (ps_AliasedName && !ps_AliasedName->empty()) ? ps_AliasedName : &pSym->name(); SymbolTable_t::iterator sti = find(*ps_AliasedName); if (sti == end()) { operator[](*ps_AliasedName) = pSym; return 1; } else if (pSym != sti->second) { cout << "SymbolTable_t::addSymbol " << *ps_AliasedName << " exists " << pSym << " " << sti->second << "\n"; return 0; } } return 0; } static gpsimObject *pSearchObject=0; static gpsimObject *pFoundObject=0; static bool spred(const SymbolEntry_t &se) { pFoundObject = se.second == pSearchObject ? pSearchObject : 0; return pFoundObject != 0; } int SymbolTable_t::removeSymbol(gpsimObject *pSym) { if (pSym) { pSearchObject = pSym; pFoundObject = 0; SymbolTable_t::iterator it = find_if (begin(), end(), spred); if (it != end()) { if (DEBUG) { cout << __FUNCTION__ <<':' << __LINE__ << " removing symbol "; if (pSym) cout << pSym->name() << endl; } erase (it); return 1; } } return 0; } int SymbolTable_t::removeSymbol(const string &s) { SymbolTable_t::iterator sti = find(s); if (sti != end()) { if (DEBUG) cout << __FUNCTION__ <<':' << __LINE__ << " Removing symbol " << s << endl; erase(sti); return 1; } return 0; } int SymbolTable_t::deleteSymbol(const string &s) { SymbolTable_t::iterator sti = find(s); if (sti != end()) { if (DEBUG) cout << __FUNCTION__ <<':' << __LINE__ << " Deleting symbol " << s << endl; delete sti->second; erase(sti); return 1; } return 0; } gpsimObject *SymbolTable_t::findSymbol(const string &searchString) { stiFound = find(searchString); return stiFound != end() ? stiFound->second : 0; } //------------------------------------------------------------------- //------------------------------------------------------------------- SymbolTable::SymbolTable() { MSymbolTables[string("__global__")] = &globalSymbols; currentSymbolTable = &globalSymbols; } static void dumpOneSymbol(const SymbolEntry_t &sym) { cout << " " //<< sym.second->name() // name may not be valid. << " stored as " << sym.first << " pointer:" << sym.second << " Type:" << sym.second->showType() << endl; } static void dumpSymbolTables(const SymbolTableEntry_t &st) { cout << " Symbol Table: " << st.first << endl; (st.second)->ForEachSymbolTable(dumpOneSymbol); } SymbolTable::~SymbolTable() { if (DEBUG) { cout << "Deleting the symbol table, here's what is still left in it:\n"; ForEachModule(dumpSymbolTables); } } int SymbolTable::addSymbol(gpsimObject *pSym) { /* if (pSym) cout << "Adding " << pSym->name() << " to the global symbol table\n"; */ return globalSymbols.addSymbol(pSym); } int SymbolTable::removeSymbol(gpsimObject *pSym) { /* cout << __FUNCTION__ <<':' << __LINE__ << " Removing symbol "; if (pSym) cout << " -- " << pSym->name() << " from the global symbol table\n"; */ return globalSymbols.removeSymbol(pSym); } void SymbolTable::addModule(Module *pModule) { if (pModule) { MSymbolTables[pModule->name()] = &pModule->getSymbolTable(); globalSymbols.addSymbol(pModule); } } void SymbolTable::removeModule(Module *pModule) { if (pModule) { //cout << "Removing " << pModule->name() << " from the global symbol table\n"; MSymbolTable_t::iterator mi = MSymbolTables.find(pModule->name()); if (mi != MSymbolTables.end()) MSymbolTables.erase(mi); globalSymbols.removeSymbol(pModule); } } /* class SymbolFinder { string searchString; public: gpsimObject *pFound; SymbolFinder(string s) : searchString(s) {} bool tpred(const pair &st) { cout << "searching " << st.first << endl; SymbolTable_t::iterator sti = st.second->find(searchString); pFound = sti != st.second->end() ? sti->second : 0; return pFound != 0; } }; */ static SymbolTable_t *searchTable=0; static string searchString; static gpsimObject *pFound=0; bool tpred(const pair &st) { //cout << "searching " << st.first << endl; pFound = st.second->findSymbol(searchString); return pFound != 0; } gpsimObject *SymbolTable::find(string s) { // First check scoping // // SymbolTableName.SymbolName // ^ // | // +--- scoping operator // // If the search string contains the scoping operator (i.e. '.') // then the symbol table specified by the scope. In other words, // if the search string begins with a period, then search the // current symbol table. // If the search string contains a period, then search for the // symbol table named with the string to the left of the period // and if that table is found search in it for the string to // the right of the period. const char scopeOperator = '.'; size_t scopeOperatorPosition = s.find_first_of(scopeOperator); if (scopeOperatorPosition != string::npos) { searchTable = &globalSymbols; if (scopeOperatorPosition == 0) { // Select the current symbol table searchTable = currentSymbolTable; scopeOperatorPosition++; } else { // Find the symbol table with the scoped name: string moduleName = s.substr(0, scopeOperatorPosition); //,string::npos); MSymbolTable_t::iterator mti = MSymbolTables.find(moduleName); if (mti != MSymbolTables.end()) { searchTable = mti->second; scopeOperatorPosition++; } } SymbolTable_t::iterator sti = searchTable->find(s.substr(scopeOperatorPosition,string::npos)); if (sti != searchTable->end()) return sti->second; } pFound = 0; // assume the symbol is not found. searchString = s; MSymbolTable_t::iterator mti = find_if (MSymbolTables.begin(), MSymbolTables.end(), tpred); if (mti != MSymbolTables.end()) searchTable = mti->second; return pFound; } int SymbolTable::removeSymbol(const string &s) { gpsimObject *pObj = find(s); if (pObj && searchTable) { if (searchTable->stiFound != searchTable->end()) { //cout << "Removing symbol " << s << endl; searchTable->erase(searchTable->stiFound); return 1; } } return 0; } int SymbolTable::deleteSymbol(const string &s) { gpsimObject *pObj = find(s); if (pObj && searchTable) { if (searchTable->stiFound != searchTable->end()) { //cout << "Deleting symbol " << s << endl; searchTable->erase(searchTable->stiFound); delete pObj; return 1; } } /* gpsimObject *pObj = find(s); if (pObj && searchTable) { if (*stiFound != searchTable->end()) { searchTable->erase(*stiFound); delete pObj; return 1; } } */ return 0; } //------------------------------------------------------------------------ // Convenience find functions // All these do is call SymbolTable::find and cast the found symbol into // another type gpsimObject *SymbolTable::findObject(gpsimObject *pObj) { return pObj ? find(pObj->name()) : 0; } Integer *SymbolTable::findInteger(string s) { return dynamic_cast(find(s)); } Value *SymbolTable::findValue(string s) { return dynamic_cast(find(s)); } Module *SymbolTable::findModule(string s) { return dynamic_cast(find(s)); } static void dumpModules(const SymbolTableEntry_t &st) { cout << " Module: " << st.first << endl; } void SymbolTable::listModules() { ForEachModule(dumpModules); } void SymbolTable::ForEachModule(PFN_ForEachModule forEach) { for_each(MSymbolTables.begin(), MSymbolTables.end(), forEach); } gpsim-0.30.0/src/interface.cc0000664000076400007640000003342513107202217012704 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ //------------------------------------------------------------------- // interface.cc // // interface.cc provides a layer of code on top of the simulator // portion of gpsim. It's purpose is to provide an abstract interface // that hides the details of the simulator. Currently only the gui // interfaces to gpsim through this layer. However, since the simulator // 'engine' is built as a library, it's possible for other code to // interface through here as well. // //------------------------------------------------------------------- #include #include "../config.h" #define GPSIM_VERSION VERSION #include "gpsim_def.h" #include "sim_context.h" #include "processor.h" #include "xref.h" #include "interface.h" #include "trace.h" #include "eeprom.h" #include "icd.h" #include "cmd_manager.h" #include "clock_phase.h" #include extern Integer *verbosity; // in ../src/init.cc // Flag to tell us when all of the init stuff is done. unsigned int gpsim_is_initialized = 0; /************************************************************************** * * Here's the gpsim interface class instantiation. It's through this class * that gpsim will notify the gui and/or modules of internal gpsim changes. * **************************************************************************/ gpsimInterface gi; // create an instance of inline get_interface() method by taking its address gpsimInterface &(*dummy_gi)(void) = get_interface; //------------------------------------------------------------------------ // Temporary -- provide a flag to inihibit multithreaded support. bool gUsingThreads() { return false; } //--------------------------------------------------------------------------- // void gpsim_set_bulk_mode(int flag) //--------------------------------------------------------------------------- void gpsim_set_bulk_mode(int flag) { if(get_use_icd()) { icd_set_bulk(flag); } } void initialization_is_complete(void) { gpsim_is_initialized = 1; } //======================================================================== //======================================================================== //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- /* * Module Interface * * */ //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- ModuleInterface::ModuleInterface(Module *new_module) { module = new_module; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- /* * Processor Interface * * */ //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- ProcessorInterface::ProcessorInterface(Processor *new_cpu) : ModuleInterface(new_cpu) { } //-------------------------------------------------------------------------- // // callback registration functions // // //-------------------------------------------------------------------------- Interface::Interface(gpointer new_object) { objectPTR = new_object; } //-------------------------------------------------------------------------- // // gpsimInterface // // Here are where the member functions for the gpsimInterface class are // defined. // // The gpsimInterface class contains a singly-linked-list of Interface objects. // Interface objects are structures that primarily contain pointers to a whole // bunch of functions. The purpose is to have some external entity, like the // gui code, define where these functions point. gpsim will then use these // functions as a means of notifying the gui when something has changed. // In addition to the gui, this class also provides the support for interfacing // to modules. When a module is loaded from a module library, a new Interface // object is created for it. The module will be given the opportunity to // register functions (e.g. provide pointers to functions) that gpsim can // then call. // //-------------------------------------------------------------------------- void gpsimInterface::update (void) { GSList *external_interfaces = interfaces; while(external_interfaces) { if(external_interfaces->data) { Interface *an_interface = (Interface *)(external_interfaces->data); an_interface->Update(an_interface->objectPTR); } external_interfaces = external_interfaces->next; } } void gpsimInterface::callback(void) { if(update_rate) { future_cycle = get_cycles().get() + update_rate; get_cycles().set_break(future_cycle, this); } update(); } void gpsimInterface::clear(void) { } void gpsimInterface::print(void) { cout << "Interface update rate " << update_rate << endl; } void gpsimInterface::callback_print(void) { cout << "gpsim Interface callback\n"; } void update_gui(void) { gi.update(); } gpsimInterface::gpsimInterface (void ) { interfaces = 0; future_cycle = 0; interface_seq_number = 0; socket_interface = 0; mbSimulating = false; mbUseGUI = false; } ISimConsole & gpsimInterface::GetConsole() { // The static ISimConsole object is currently in the // CCommandManger class because it initially was used // to enable external modules to write to the console. // We may want to put it somewhere else someday. return CCommandManager::m_CommandManger.GetConsole(); } //-------------------------------------------------------------------------- // // A xref, or cross reference, object is an arbitrary thing that gpsim // will pass back to the gui or module. The gui (or module) will then // interpret the contents of the xref and possibly update some state // with 'new_value'. An example is when one of the pic registers changes; // if there's a xref object associated with the register gpsim will // then notify the gui (or module) through the xref. void gpsimInterface::update_object (gpointer xref,int new_value) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->UpdateObject(xref, new_value); } interface_list = interface_list->next; } } void gpsimInterface::remove_object (gpointer xref) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->RemoveObject(xref); } interface_list = interface_list->next; } } void gpsimInterface::simulation_has_stopped (void) { GSList *interface_list = interfaces; profile_keeper.catchup(); // FIXME: remove this! while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->SimulationHasStopped(an_interface->objectPTR); } interface_list = interface_list->next; } } // This code is not used anywhere, but uses currently depreciated calls RRR #ifdef GPSIM_THREAD GMutex *muRunMutex; GCond *cvRunCondition; static Processor *tcpu=0; static void run_thread( void *ptr ) { printf("run thread\n"); while(1) { g_mutex_lock(muRunMutex); printf("running waiting for condition\n"); g_cond_wait(cvRunCondition, muRunMutex); if(tcpu) { printf("running\n"); tcpu->run(); printf("stopped running\n"); } g_mutex_unlock(muRunMutex); } } void start_run_thread(void) { std::cout << "starting run thread....\n"; muRunMutex = g_mutex_new (); cvRunCondition = g_cond_new (); g_mutex_lock (muRunMutex); GError *err = NULL ; if( g_thread_create((GThreadFunc)run_thread, (void *)0, TRUE, &err) == NULL) { printf("Thread create failed: %s!!\n", err->message ); g_error_free ( err ) ; } g_mutex_unlock (muRunMutex); std::cout << " started thread\n"; } #endif //GPSIM_THREAD //======================================================================== // void gpsimInterface::start_simulation (double duration) { Processor *cpu = get_active_cpu(); if (cpu) { mbSimulating = true; cout << "running...\n"; cpu->run(true); mbSimulating = false; trace.dump_last_instruction(); simulation_has_stopped(); } } void gpsimInterface::step_simulation (int nSteps) { Processor *cpu = get_active_cpu(); if (cpu) cpu->step(nSteps); } void gpsimInterface::advance_simulation(eAdvancementModes nAdvancement) { switch (nAdvancement) { case eAdvanceNextInstruction: { Processor *cpu = get_active_cpu(); if (cpu) cpu->step_over(); } break; case eAdvanceNextCycle: case eAdvanceNextCall: case eAdvanceNextReturn: break; } } void gpsimInterface::reset (RESET_TYPE resetType) { CSimulationContext::GetContext()->Reset(resetType); } bool gpsimInterface::bSimulating() { return mbSimulating; } bool gpsimInterface::bUsingGUI() { return mbUseGUI; } void gpsimInterface::setGUImode(bool bnewGUImode) { // We can only turn the gui on we can't turn it off. mbUseGUI |= bnewGUImode; } void gpsimInterface::new_processor (Processor *new_cpu) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->NewProcessor(new_cpu); } interface_list = interface_list->next; } } void gpsimInterface::new_module (Module *module) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->NewModule(module); } interface_list = interface_list->next; } } void gpsimInterface::node_configuration_changed (Stimulus_Node *node) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->NodeConfigurationChanged(node); } interface_list = interface_list->next; } } void gpsimInterface::new_program (Processor *cpu) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); an_interface->NewProgram(cpu); } interface_list = interface_list->next; } } unsigned int gpsimInterface::add_interface (Interface *new_interface) { interface_seq_number++; new_interface->set_id(interface_seq_number); gi.interfaces = g_slist_append(gi.interfaces, new_interface); return interface_seq_number; } unsigned int gpsimInterface::prepend_interface (Interface *new_interface) { interface_seq_number++; new_interface->set_id(interface_seq_number); gi.interfaces = g_slist_prepend(gi.interfaces, new_interface); return interface_seq_number; } unsigned int gpsimInterface::add_socket_interface (Interface *new_interface) { if(!socket_interface) return add_interface(new_interface); return 0; } void gpsimInterface::remove_interface (unsigned int interface_id) { GSList *interface_list = interfaces; while(interface_list) { if(interface_list->data) { Interface *an_interface = (Interface *)(interface_list->data); if(an_interface->get_id()==interface_id) { gi.interfaces = g_slist_remove(gi.interfaces, an_interface); if(an_interface == socket_interface) socket_interface = 0; delete an_interface; return; } } interface_list = interface_list->next; } return; } void gpsimInterface::set_update_rate (guint64 _update_rate) { update_rate = _update_rate; if(update_rate) { guint64 fc = get_cycles().get() + _update_rate; if(fc) { if(future_cycle) get_cycles().reassign_break(future_cycle, fc, this); else get_cycles().set_break(fc, this); future_cycle = fc; } } } guint64 gpsimInterface::get_update_rate() { return update_rate; } const char *get_dir_delim(const char *path) { #ifdef _WIN32 const char *p = path + strlen(path); do { if (--p < path) return 0; } while (*p != '/' && *p != '\\'); return p; #else return strrchr(path, '/'); #endif } // For libgpsim.dll // The console now owns the verbose flags. At some point as set // of functions called TraceDisplayXXX() the conditionally // display message depending on the verbose flags. // I'll leave this it as it for now because I'm in the middle // of making the src project its own DLL on windows and I have // enough changes for now. // Replaced the int verbose = 0; with GlobalVerbosityAccessor verbose. // GlobalVerbosityAccessor that has overridden operators for 'if(verbose)' // and 'if(verbose&4)' to still work as desired. // The purpose was to decouple verbose from cli and gui. Now these // modules (acutally gpsim.exe) will allocate there own // GlobalVerbosityAccessor verbose object to gain access to the // verbose flags and for the overridden operators. GlobalVerbosityAccessor verbose; gpsim-0.30.0/src/lxt_write.c0000664000076400007640000007033013063451152012623 00000000000000/* * Copyright (c) 2001 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "lxt_write.h" /* * functions which emit various big endian * data to a file */ static int lt_emit_u8(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u16(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u24(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 3, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u32(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, lt->handle); lt->position+=nmemb; return(nmemb); } #if 0 //warning: 'lt_emit_u64' defined but not used static int lt_emit_u64(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32(lt, valueh))) { rc=lt_emit_u32(lt, valuel); } return(rc); } #endif static int lt_emit_double(struct lt_trace *lt, double value) { int nmemb; nmemb=fwrite(&value, sizeof(char), sizeof(double)/sizeof(char), lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_string(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8(lt, *value); } while(*(value++)); return(rc); } /* * hash/symtable manipulation */ static int lt_hash(const char *s) { const char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ return(h%LT_SYMPRIME); } static struct lt_symbol *lt_symadd(struct lt_trace *lt, const char *name, int hv) { struct lt_symbol *s; s=(struct lt_symbol *)calloc(1,sizeof(struct lt_symbol)); strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name); s->next=lt->sym[hv]; lt->sym[hv]=s; return(s); } static struct lt_symbol *lt_symfind(struct lt_trace *lt, const char *s) { int hv; struct lt_symbol *temp; hv=lt_hash(s); if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } /* * compress facs to a prefix count + string + 0x00 */ static void lt_compress_fac(struct lt_trace *lt, char *str) { int i; int len = strlen(str); int minlen = (lencompress_fac_len) ? len : lt->compress_fac_len; if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */ if(lt->compress_fac_str) { for(i=0;icompress_fac_str[i]!=str[i]) break; } lt_emit_u16(lt, i); lt_emit_string(lt, str+i); free(lt->compress_fac_str); } else { lt_emit_u16(lt, 0); lt_emit_string(lt, str); } lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1); strcpy(lt->compress_fac_str, str); } /* * emit facs in sorted order along with geometry * and sync table info */ static int lt_compare(const void *v1, const void *v2) { struct lt_symbol *s1 = *(struct lt_symbol **)v1; struct lt_symbol *s2 = *(struct lt_symbol **)v2; int rc = strcmp(s1->name, s2->name); if(rc) { return(rc); } else { return(s1->msb - s2->msb); } } static void strip_brack(struct lt_symbol *s) { char *lastch = s->name+s->namlen - 1; if(*lastch!=']') return; if(s->namlen<3) return; lastch--; while(lastch!=s->name) { if(*lastch=='[') { *lastch=0x00; return; } lastch--; } return; } static void lt_emitfacs(struct lt_trace *lt) { int i; if((lt)&&(lt->numfacs)) { struct lt_symbol *s = lt->symchain; if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *)))) { if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[i] = s; strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[i] = s; s=s->symchain; } qsort((void *)lt->sorted_facs, lt->numfacs, sizeof(struct lt_symbol *), lt_compare); lt->facname_offset=lt->position; lt_emit_u32(lt, lt->numfacs); lt_emit_u32(lt, lt->numfacbytes); for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; lt_compress_fac(lt, lt->sorted_facs[i]->name); } free(lt->compress_fac_str); lt->compress_fac_str=NULL; lt->compress_fac_len=0; lt->facgeometry_offset = lt->position; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags<_SYM_F_ALIAS)==0) { lt_emit_u32(lt, lt->sorted_facs[i]->rows); lt_emit_u32(lt, lt->sorted_facs[i]->msb); lt_emit_u32(lt, lt->sorted_facs[i]->lsb); lt_emit_u32(lt, lt->sorted_facs[i]->flags); } else { lt_emit_u32(lt, lt->sorted_facs[i]->aliased_to->facnum); lt_emit_u32(lt, lt->sorted_facs[i]->msb); lt_emit_u32(lt, lt->sorted_facs[i]->lsb); lt_emit_u32(lt, LT_SYM_F_ALIAS); } } lt->sync_table_offset = lt->position; for(i=0;inumfacs;i++) { lt_emit_u32(lt, lt->sorted_facs[i]->last_change); } } } } /* * initialize the trace and get back and lt context */ struct lt_trace *lt_init(const char *name) { struct lt_trace *lt=(struct lt_trace *)calloc(1, sizeof(struct lt_trace)); if(!(lt->handle=fopen(name, "wb"))) { free(lt); lt=NULL; } else { lt_emit_u16(lt, LT_HDRID); lt_emit_u16(lt, LT_VERSION); lt->change_field_offset = lt->position; lt->initial_value = -1; /* if a user sets this it will have a different POSITIVE val */ lt->timescale = -256; /* will be in range of -128<=x<=127 if set */ } return(lt); } /* * clock flushing.. */ static void lt_flushclock(struct lt_trace *lt, struct lt_symbol *s) { unsigned int last_change_delta = lt->position - s->last_change - 2; unsigned int start_position = lt->position; int tag; int numbytes, numbytes_trans; int numtrans = s->clk_numtrans - LT_CLKPACK - 1; if(numtrans<0) { /* it never got around to caching */ fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans); return; } if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } if(numtrans >= 256*65536) { numbytes_trans = 3; } else if(numtrans >= 65536) { numbytes_trans = 2; } else if(numtrans >= 256) { numbytes_trans = 1; } else { numbytes_trans = 0; } tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */ lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt_emit_u8(lt, last_change_delta); break; case 1: lt_emit_u16(lt, last_change_delta); break; case 2: lt_emit_u24(lt, last_change_delta); break; case 3: lt_emit_u32(lt, last_change_delta); break; } s->last_change = start_position; /* s->clk_prevval CAN BE INFERRED! */ /* s->clk_prevtrans CAN BE INFERRED! */ /* s->clk_delta CAN BE INFERRED! */ switch(numbytes_trans&3) { case 0: lt_emit_u8(lt, numtrans); break; case 1: lt_emit_u16(lt, numtrans); break; case 2: lt_emit_u24(lt, numtrans); break; case 3: lt_emit_u32(lt, numtrans); break; } /* printf("Clock finish for '%s' at %d ending with '%c' for %d repeats over a switch delta of %d\n", s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK, s->clk_delta); */ s->clk_prevtrans = -1; s->clk_numtrans = 0; } /* * close out the trace and fixate it */ void lt_close(struct lt_trace *lt) { int lasttime=0; int lastposition=0; if(lt) { struct lt_symbol *s = lt->symchain; if(lt->clock_compress) while(s) { if((s->clk_prevtrans!=-1)&&(s->clk_numtrans > LT_CLKPACK)) lt_flushclock(lt, s); s=s->symchain; } lt_emitfacs(lt); if(lt->timebuff) { free(lt->timebuff); lt->timebuff=NULL; } if(lt->timehead) { struct lt_timetrail *t=lt->timehead; struct lt_timetrail *t2; lt->time_table_offset = lt->position; lt_emit_u32(lt, lt->timechangecount); lt_emit_u32(lt, lt->mintime); lt_emit_u32(lt, lt->maxtime); while(t) { lt_emit_u32(lt, t->position - lastposition); lastposition = t->position; t=t->next; } t=lt->timehead; while(t) { lt_emit_u32(lt, t->timeval - lasttime); lasttime = t->timeval; t2=t->next; free(t); t=t2; } lt->timehead = lt->timecurr = NULL; } if(lt->initial_value>=0) { lt->initial_value_offset = lt->position; lt_emit_u8(lt, lt->initial_value); } if((lt->timescale>-129)&(lt->timescale<128)) { lt->timescale_offset = lt->position; lt_emit_u8(lt, lt->timescale); } if(lt->double_used) { lt->double_test_offset = lt->position; lt_emit_double(lt, 3.14159); } lt_emit_u8(lt, LT_SECTION_END); if(lt->change_field_offset) { lt_emit_u32(lt, lt->change_field_offset); lt_emit_u8(lt, LT_SECTION_CHG); } if(lt->sync_table_offset) { lt_emit_u32(lt, lt->sync_table_offset); lt_emit_u8(lt, LT_SECTION_SYNC_TABLE); } if(lt->facname_offset) { lt_emit_u32(lt, lt->facname_offset); lt_emit_u8(lt, LT_SECTION_FACNAME); } if(lt->facgeometry_offset) { lt_emit_u32(lt, lt->facgeometry_offset); lt_emit_u8(lt, LT_SECTION_FACNAME_GEOMETRY); } if(lt->timescale_offset) { lt_emit_u32(lt, lt->timescale_offset); lt_emit_u8(lt, LT_SECTION_TIMESCALE); } if(lt->time_table_offset) { lt_emit_u32(lt, lt->time_table_offset); lt_emit_u8(lt, LT_SECTION_TIME_TABLE); } if(lt->initial_value_offset) { lt_emit_u32(lt, lt->initial_value_offset); lt_emit_u8(lt, LT_SECTION_INITIAL_VALUE); } if(lt->double_test_offset) { lt_emit_u32(lt, lt->double_test_offset); lt_emit_u8(lt, LT_SECTION_DOUBLE_TEST); } lt_emit_u8(lt, LT_TRLID); if(lt->symchain) { struct lt_symbol *s = lt->symchain; struct lt_symbol *s2; while(s) { free(s->name); s2=s->next; free(s); s=s2; } } fclose(lt->handle); free(lt); } } /* * maint function for finding a symbol if it exists */ struct lt_symbol *lt_symbol_find(struct lt_trace *lt, const char *name) { struct lt_symbol *s=NULL; if((lt)&&(name)) s=lt_symfind(lt, name); return(s); } /* * add a trace (if it doesn't exist already) */ struct lt_symbol *lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags) { struct lt_symbol *s; int len; int flagcnt; flagcnt = ((flags<_SYM_F_INTEGER)!=0) + ((flags<_SYM_F_DOUBLE)!=0) + ((flags<_SYM_F_STRING)!=0); if((flagcnt>1)||(!lt)||(!name)||(lt_symfind(lt, name))) return (NULL); lt->double_used |= ((flags<_SYM_F_DOUBLE)!=0); s=lt_symadd(lt, name, lt_hash(name)); s->rows = rows; s->flags = flags&(~LT_SYM_F_ALIAS); /* aliasing makes no sense here.. */ if(!flagcnt) { s->msb = msb; s->lsb = lsb; s->len = (msblen==1)&&(s->rows==0)) s->clk_prevtrans = -1; } s->symchain = lt->symchain; lt->symchain = s; lt->numfacs++; if((len=strlen(name)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(s); } /* * add an alias trace (if it doesn't exist already and orig is found) */ struct lt_symbol *lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb) { struct lt_symbol *s, *sa; int len; int bitlen; int flagcnt; if((!lt)||(!existing_name)||(!alias)||(!(s=lt_symfind(lt, existing_name)))||(lt_symfind(lt, alias))) return (NULL); while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } flagcnt = ((s->flags<_SYM_F_INTEGER)!=0) + ((s->flags<_SYM_F_DOUBLE)!=0) + ((s->flags<_SYM_F_STRING)!=0); bitlen = (msblen)) return(NULL); sa=lt_symadd(lt, alias, lt_hash(alias)); sa->flags = LT_SYM_F_ALIAS; /* only point this can get set */ sa->aliased_to = s; if(!flagcnt) { sa->msb = msb; sa->lsb = lsb; sa->len = bitlen; } sa->symchain = lt->symchain; lt->symchain = sa; lt->numfacs++; if((len=strlen(alias)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(sa); } /* * set current time */ int lt_set_time(struct lt_trace *lt, int timeval) { int rc=0; if(timeval>=0) if(lt) { struct lt_timetrail *trl=(struct lt_timetrail *)calloc(1, sizeof(struct lt_timetrail)); if(trl) { trl->timeval = timeval; trl->position = lt->position; if((lt->timecurr)||(lt->timebuff)) { if((timeval>lt->mintime)&&(timeval>lt->maxtime)) { lt->maxtime = timeval; } else { free(trl); goto bail; } } else { lt->mintime = lt->maxtime = timeval; } if(lt->timebuff) { free(lt->timebuff); } lt->timebuff = trl; lt->timeval = timeval; rc=1; } } bail: return(rc); } /* * sets trace timescale as 10**x seconds */ void lt_set_timescale(struct lt_trace *lt, int timescale) { if(lt) { lt->timescale = timescale; } } /* * sets clock compression heuristic */ void lt_set_clock_compress(struct lt_trace *lt) { if(lt) { lt->clock_compress = 1; } } /* * sets trace initial value */ void lt_set_initial_value(struct lt_trace *lt, char value) { if(lt) { int tag; switch(value) { case '0': tag = 0; break; case '1': tag = 1; break; case 'Z': case 'z': tag = 2; break; case 'X': case 'x': tag = 3; break; case 'H': case 'h': tag = 4; break; case 'U': case 'u': tag = 5; break; case 'W': case 'w': tag = 6; break; case 'L': case 'l': tag = 0x7; break; case '-': tag = 0x8; break; default: tag = -1; break; } lt->initial_value = tag; } } /* * Sets bracket stripping (useful for VCD conversions of * bitblasted nets) */ void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit) { if(lt) { lt->do_strip_brackets = (doit!=0); } } /* * emission for trace values.. */ static int lt_optimask[]= { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value) { int rc=0; if((!lt)||(!s)) return(rc); while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { int numbytes; /* number of bytes to store value minus one */ int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; unsigned int last_change_delta; if(lt->clock_compress) if((s->len==1)&&(s->rows==0)) /* possible clock handling */ { int ivalue = value&1; if(((s->clk_prevval == '1') && (ivalue==0)) || ((s->clk_prevval == '0') && (ivalue==1))) { if(s->clk_prevtrans==-1) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK) { s->clk_prevval = ivalue + '0'; /* printf("Clock value '%d' for '%s' at %d (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=-1; } } } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=-1; } } s->clk_prevval = ivalue + '0'; } /* normal trace handling */ last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } if(len<=32) { int start_position = lt->position; int tag; int optimized0 = ((value<_optimask[len])==0); int optimized1 = ((value<_optimask[len])==lt_optimask[len]); int optimized = optimized0|optimized1; if(optimized) { tag = (numbytes<<4) | (3+optimized1); /* for x3 and x4 cases */ } else { tag = (numbytes<<4); } lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt_emit_u8(lt, last_change_delta); break; case 1: lt_emit_u16(lt, last_change_delta); break; case 2: lt_emit_u24(lt, last_change_delta); break; case 3: lt_emit_u32(lt, last_change_delta); break; } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt_emit_u8(lt, row); break; case 1: lt_emit_u16(lt, row); break; case 2: lt_emit_u24(lt, row); break; case 3: lt_emit_u32(lt, row); break; } } if(!optimized) { if(len<9) { value <<= (8-len); rc=lt_emit_u8(lt, value); } else if(len<17) { value <<= (16-len); rc=lt_emit_u16(lt, value); } else if(len<25) { value <<= (24-len); rc=lt_emit_u24(lt, value); } else { value <<= (32-len); rc=lt_emit_u32(lt, value); } } } if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value) { int rc=0; int start_position; int tag; if((!lt)||(!s)) return(rc); while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if((s->flags)<_SYM_F_DOUBLE) { int numbytes; /* number of bytes to store value minus one */ unsigned int last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } start_position = lt->position; tag = (numbytes<<4); lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt_emit_u8(lt, last_change_delta); break; case 1: lt_emit_u16(lt, last_change_delta); break; case 2: lt_emit_u24(lt, last_change_delta); break; case 3: lt_emit_u32(lt, last_change_delta); break; } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt_emit_u8(lt, row); break; case 1: lt_emit_u16(lt, row); break; case 2: lt_emit_u24(lt, row); break; case 3: lt_emit_u32(lt, row); break; } } rc=lt_emit_double(lt, value); if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value) { int rc=0; int start_position; int tag; if((!lt)||(!s)||(!value)) return(rc); while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if((s->flags)<_SYM_F_STRING) { int numbytes; /* number of bytes to store value minus one */ unsigned int last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } start_position = lt->position; tag = (numbytes<<4); lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt_emit_u8(lt, last_change_delta); break; case 1: lt_emit_u16(lt, last_change_delta); break; case 2: lt_emit_u24(lt, last_change_delta); break; case 3: lt_emit_u32(lt, last_change_delta); break; } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt_emit_u8(lt, row); break; case 1: lt_emit_u16(lt, row); break; case 2: lt_emit_u24(lt, row); break; case 3: lt_emit_u32(lt, row); break; } } rc=lt_emit_string(lt, value); if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value) { int rc=0; int start_position; int tag, tagadd; if((!lt)||(!s)||(!value)) return(rc); while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { int numbytes; /* number of bytes to store value minus one */ char *pnt; int mvl=0; char ch; char prevch; unsigned int last_change_delta; if(lt->clock_compress) if((s->len==1)&&(s->rows==0)) /* possible clock handling */ { if(((s->clk_prevval == '1') && (value[0]=='0')) || ((s->clk_prevval == '0') && (value[0]=='1'))) { if(s->clk_prevtrans==-1) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK) { s->clk_prevval = value[0]; /* printf("Clock value '%c' for '%s' at %d (#%d)\n", value[0], s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=-1; } } } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=-1; } } s->clk_prevval = value[0]; } /* normal trace handling */ last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } pnt = value; prevch = *pnt; while((ch=*(pnt++))) { switch(ch) { case '0': case '1': mvl|=LT_MVL_2; break; case 'Z': case 'z': case 'X': case 'x': mvl|=LT_MVL_4; break; default: mvl|=LT_MVL_9; break; } if(prevch!=ch) prevch = 0; } switch(prevch) { case 0x00: tagadd = 0; break; case '0': tagadd = 3; break; case '1': tagadd = 4; break; case 'Z': case 'z': tagadd = 5; break; case 'X': case 'x': tagadd = 6; break; case 'H': case 'h': tagadd = 7; break; case 'U': case 'u': tagadd = 8; break; case 'W': case 'w': tagadd = 9; break; case 'L': case 'l': tagadd = 0xa; break; default: tagadd = 0xb; break; } if(mvl) { start_position = lt->position; if(tagadd) { tag = (numbytes<<4) + tagadd; } else { tag = (numbytes<<4) + ((mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0)); } lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt_emit_u8(lt, last_change_delta); break; case 1: lt_emit_u16(lt, last_change_delta); break; case 2: lt_emit_u24(lt, last_change_delta); break; case 3: lt_emit_u32(lt, last_change_delta); break; } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt_emit_u8(lt, row); break; case 1: lt_emit_u16(lt, row); break; case 2: lt_emit_u24(lt, row); break; case 3: lt_emit_u32(lt, row); break; } } if(!tagadd) { int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if((mvl & (LT_MVL_2|LT_MVL_4|LT_MVL_9)) == LT_MVL_2) { int i; int bitpos = 7; int outval = 0; int thisval= 0; pnt = value; for(i=0;itimebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } gpsim-0.30.0/src/pic-ioports.cc0000664000076400007640000004237213045306452013224 00000000000000/* Copyright (C) 1998 Scott Dattalo Copyright (C) 2009 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "pic-processor.h" #include "14bit-processors.h" // %%% FIXME %%% remove the dependencies on this #include "pic-ioports.h" #include "interface.h" #include "psp.h" #include "xref.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------------------- // // ioports.cc // // The ioport infrastructure for gpsim is provided here. The class // taxonomy for the IOPORT class is: // // file_register // |-> sfr_register // |-> IOPORT // |-> PORTA // |-> PORTB // |-> PORTC // |-> PORTD // |-> PORTE // |-> PORTF // // Each I/O port has an associated array of I/O pins which provide an // interface to the virtual external world of the stimuli. // //------------------------------------------------------------------- class PicSignalSource : public SignalControl { public: PicSignalSource(PortRegister *_reg, unsigned int bitPosition) : m_register(_reg), m_bitMask(1<getDriving()&m_bitMask)!=0)?'1':'0') : 'Z'; /**/ Dprintf(("PicSignalSource::getState() %s bitmask:0x%x state:%c\n", (m_register?m_register->name().c_str():"NULL"), m_bitMask,r)); /**/ return r; } void release() { delete this; } private: PortRegister *m_register; unsigned int m_bitMask; }; //------------------------------------------------------------------------ PicPortRegister::PicPortRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *port_name,*/ unsigned int numIopins, unsigned int enableMask) : PortRegister(pCpu, pName, pDesc,numIopins, false), m_tris(0) { setEnableMask(enableMask); } class PicSignalControl : public SignalControl { public: PicSignalControl(PicTrisRegister *_reg, unsigned int bitPosition) : m_register(_reg), m_bitMask(1<get3StateBit(m_bitMask) : '?'; } virtual void release() { delete this; } private: PicTrisRegister *m_register; unsigned int m_bitMask; }; void PicPortRegister::setTris(PicTrisRegister *new_tris) { if (!m_tris) m_tris = new_tris; unsigned int mask = getEnableMask(); for (unsigned int i=0, m = 1; isetTris(this); } void PicTrisRegister::put(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.put((value.get() & ~m_EnableMask) | (new_value & m_EnableMask)); if (m_port) m_port->updatePort(); } void PicTrisRegister::put_value(unsigned int new_value) { value.put(new_value & m_EnableMask); if (m_port) m_port->updatePort(); } unsigned int PicTrisRegister::get() { trace.raw(read_trace.get() | value.data); return value.data; } void PicTrisRegister::setEnableMask(unsigned int enableMask) { m_EnableMask = enableMask; } char PicTrisRegister::get3StateBit(unsigned int bitMask) { RegisterValue rv = getRV_notrace(); unsigned int enabled = bitMask & m_EnableMask; if (!enabled) return '1'; return (rv.init & enabled) ? '?' : ((rv.data & enabled) ? '1': '0'); } void PicTrisRegister::reset(RESET_TYPE r) { if (!(m_bIgnoreWDTResets && r==WDT_RESET)) putRV(por_value); } //------------------------------------------------------------------------ PicPSP_TrisRegister::PicPSP_TrisRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *tris_name, */ PicPortRegister *_port, bool bIgnoreWDTResets) : PicTrisRegister(pCpu, pName, pDesc,_port,bIgnoreWDTResets) { } // If not in PSPMODE, OBF and IBF are always clear // When in PSPMODE, OBF and IBF can only be cleared by reading and writing // to the PSP parallel port and are set by bus transfers. // void PicPSP_TrisRegister::put(unsigned int new_value) { unsigned int mask = (PSP::OBF | PSP::IBF); unsigned int fixed; trace.raw(write_trace.get() | value.data); if (! (new_value & PSP::PSPMODE)) fixed = 0; else fixed = value.data & mask; value.data = (new_value & ~mask) | fixed; if (m_port) m_port->updatePort(); } // used by gpsim to change register value void PicPSP_TrisRegister::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; if (m_port) m_port->updatePort(); } unsigned int PicPSP_TrisRegister::get(void) { return value.data; } //------------------------------------------------------------------------ PicPortBRegister::PicPortBRegister(Processor *pCpu, const char *pName, const char *pDesc, INTCON *pIntcon, unsigned int numIopins, unsigned int enableMask, INTCON2 *pIntcon2, INTCON3 *pIntcon3) : PicPortRegister(pCpu, pName, pDesc, numIopins, enableMask), m_bRBPU(false), m_bIntEdge(true), m_bsRBPU(0), m_pIntcon(pIntcon), m_pIntcon2(pIntcon2), m_pIntcon3(pIntcon3) { assert(m_pIntcon); } PicPortBRegister::~PicPortBRegister() { delete m_bsRBPU; } //------------------------------------------------------------------------ void PicPortBRegister::put(unsigned int new_value) { trace.raw(write_trace.get() | value.data); // unsigned int diff = mEnableMask & (new_value ^ value.data); drivingValue = new_value & mEnableMask; value.data = drivingValue; // If no stimuli are connected to the Port pins, then the driving // value and the driven value are the same. If there are external // stimuli (or perhaps internal peripherals) overdriving or overriding // this port, then the call to updatePort() will update 'drivenValue' // to its proper value. updatePort(); lastDrivenValue = rvDrivenValue; } unsigned int PicPortBRegister::get() { lastDrivenValue = rvDrivenValue; return mOutputMask & rvDrivenValue.data; } //------------------------------------------------------------------------ // setbit // FIXME - a sink should be created for the intf and rbif functions. void PicPortBRegister::setbit(unsigned int bit_number, char new3State) { Dprintf(("PicPortBRegister::setbit() bit=%u,val=%c bIntEdge=%d\n", bit_number, new3State, m_bIntEdge)); // interrupt bit 0 on specified edge bool bNewValue = new3State=='1' || new3State=='W'; lastDrivenValue = rvDrivenValue; PortRegister::setbit(bit_number, new3State); if (m_pIntcon3) { bool drive = (lastDrivenValue.data&(1 << bit_number)) ; bool level; int intcon2 = m_pIntcon2->value.get(); int intcon3 = m_pIntcon3->value.get(); switch(bit_number) { case 0: level = intcon2 & INTCON2::INTEDG0; if ((drive != level) && (bNewValue == level)) { cpu_pic->exit_sleep(); m_pIntcon->set_intf(true); // if (((intcon3 & INTCON::INTE) == 0) || // (m_pIntcon->value.get() & INTCON_16::GIEH) == 0) // return; // Interrupts are disabled // ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_HI); // cpu_pic->BP_set_interrupt(); } return; break; case 1: level = intcon2 & INTCON2::INTEDG1; if ((drive != level) && (bNewValue == level)) { cpu_pic->exit_sleep(); m_pIntcon3->set_int1f(true); if (((intcon3 & INTCON3::INT1IE) == 0) || (m_pIntcon->value.get() & INTCON_16::GIEH) == 0) return; // Interrupts are disabled if (intcon3 & INTCON3::INT1IP) //priority interrupt { ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_HI); cpu_pic->BP_set_interrupt(); } else if ((m_pIntcon->value.get() & INTCON_16::GIEL) != 0) { ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_LO); cpu_pic->BP_set_interrupt(); } } return; break; case 2: level = intcon2 & INTCON2::INTEDG2; if ((drive != level) && (bNewValue == level)) { cpu_pic->exit_sleep(); m_pIntcon3->set_int2f(true); if (((intcon3 & INTCON3::INT2IE) == 0) || (m_pIntcon->value.get() & INTCON_16::GIEH) == 0) return; // Interrupts are disabled if (intcon3 & INTCON3::INT2IP) //priority interrupt { ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_HI); cpu_pic->BP_set_interrupt(); } else if ((m_pIntcon->value.get() & INTCON_16::GIEL) != 0) { ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_LO); cpu_pic->BP_set_interrupt(); } } return; break; case 3: level = intcon2 & INTCON2::INTEDG3; if ((drive != level) && (bNewValue == level)) { cpu_pic->exit_sleep(); m_pIntcon3->set_int3f(true); if (((intcon3 & INTCON3::INT3IE) == 0) || (m_pIntcon->value.get() & INTCON_16::GIEH) == 0) return; // Interrupts are disabled if (intcon2 & INTCON2::INT3IP) //priority interrupt { ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_HI); cpu_pic->BP_set_interrupt(); } else if ((m_pIntcon->value.get() & INTCON_16::GIEL) != 0) { ((INTCON_16 *)m_pIntcon)->set_interrupt_vector(INTERRUPT_VECTOR_LO); cpu_pic->BP_set_interrupt(); } } return; break; } } if (bit_number == 0 && (((lastDrivenValue.data&1)==1)!=m_bIntEdge) && (bNewValue == m_bIntEdge)) { if ((m_pIntcon->get() & (INTCON::GIE | INTCON::INTE)) == INTCON::INTE) { cpu_pic->exit_sleep(); } m_pIntcon->set_intf(true); } // interrupt and exit sleep level change top 4 bits on input unsigned int bitMask = (1<get_value() & bitMask ) { if ((m_pIntcon->get() & (INTCON::GIE | INTCON::RBIE)) == INTCON::RBIE) cpu_pic->exit_sleep(); m_pIntcon->set_rbif(true); } } class RBPUBitSink : public BitSink { PicPortBRegister *m_pPortB; public: RBPUBitSink(PicPortBRegister *pPortB) : m_pPortB(pPortB) {} void setSink(bool b) { if (m_pPortB) m_pPortB->setRBPU(b); } }; void PicPortBRegister::assignRBPUSink(unsigned int bitPos, sfr_register *pSFR) { if (pSFR && !m_bsRBPU) { m_bsRBPU = new RBPUBitSink(this); if (!pSFR->assignBitSink(bitPos, m_bsRBPU)) { delete m_bsRBPU; m_bsRBPU = 0; } } } void PicPortBRegister::setRBPU(bool bNewRBPU) { m_bRBPU = !bNewRBPU; Dprintf(("PicPortBRegister::setRBPU() =%d\n",(m_bRBPU?1:0))); unsigned int mask = getEnableMask(); for (unsigned int i=0, m=1; mask; i++, m<<= 1) if (mask & m) { mask ^= m; operator[](i).getPin().update_pullup(m_bRBPU ? '1' : '0',true); } } void PicPortBRegister::setIntEdge(bool bNewIntEdge) { m_bIntEdge = bNewIntEdge; } PicPortGRegister::PicPortGRegister(Processor *pCpu, const char *pName, const char *pDesc, INTCON *pIntcon, IOC *pIoc, unsigned int numIopins, unsigned int enableMask) : PicPortBRegister(pCpu, pName, pDesc, pIntcon, numIopins, enableMask), m_pIntcon(pIntcon), m_pIoc(pIoc), intf_bit(2) { m_pIntcon->set_portGReg(this); } // set_rbif involves RBIF,RBIE in INTCON which are the same bits as GPIF,GPIE void PicPortGRegister::setIOCif() { // interrupt and exit sleep for level change on bits where IOC set int bitMask = m_pIoc->get_value(); if ( (lastDrivenValue.data ^ rvDrivenValue.data) & m_tris->get_value() & bitMask ) { cpu_pic->exit_sleep(); m_pIntcon->set_rbif(true); } } void PicPortGRegister::setbit(unsigned int bit_number, char new3State) { // interrupt bit intf_bit (default 2) on specified edge bool bOldValue = (rvDrivenValue.data & (1<set_intf(true); } lastDrivenValue = rvDrivenValue; PortRegister::setbit(bit_number, new3State); setIOCif(); // interrupt and exit sleep for level change on bits where IOC set int bitMask = m_pIoc->get_value() & (1 << bit_number); if (verbose) printf("PicPortGRegister::setbit() bit=%u,val=%c IOC_bit=%x\n",bit_number,new3State, bitMask); } void PicPortIOCRegister::setbit(unsigned int bit_number, char new3State) { int lastDrivenValue = rvDrivenValue.data & (1 << bit_number); PortRegister::setbit(bit_number, new3State); int newDrivenValue = rvDrivenValue.data & (1 << bit_number); if (verbose) printf("PicPortIOCRegister::setbit() bit=%u,val=%c IOC_+=%x IOC_-=%x\n",bit_number,new3State, m_Iocap->get_value() & (1<get_value() & (1< lastDrivenValue) // positive edge { if ( m_tris->get_value() & (m_Iocap->get_value() & (1 << bit_number))) { cpu_pic->exit_sleep(); m_pIntcon->set_rbif(true); if (m_Iocaf) m_Iocaf->put(m_Iocaf->get_value() | (1 << bit_number)); } } else if ( newDrivenValue < lastDrivenValue) // negative edge { if ( m_tris->get_value() & (m_Iocan->get_value() & (1 << bit_number))) { cpu_pic->exit_sleep(); m_pIntcon->set_rbif(true); if (m_Iocaf) m_Iocaf->put(m_Iocaf->get_value() | (1 << bit_number)); } } } PicPSP_PortRegister::PicPSP_PortRegister(Processor *pCpu, const char *pName, const char *pDesc, /*const char *port_name,*/ unsigned int numIopins, unsigned int enableMask) : PortRegister(pCpu, pName, pDesc,numIopins, false), m_tris(0), m_psp(0) { setEnableMask(enableMask); } void PicPSP_PortRegister::put(unsigned int new_value) { trace.raw(write_trace.get() | value.data); unsigned int diff = mEnableMask & (new_value ^ value.data); if (m_psp && m_psp->pspmode()) { m_psp->psp_put(new_value); } else if(diff) { drivingValue = new_value & mEnableMask; value.data = drivingValue; // If no stimuli are connected to the Port pins, then the driving // value and the driven value are the same. If there are external // stimuli (or perhaps internal peripherals) overdriving or overriding // this port, then the call to updatePort() will update 'drivenValue' // to its proper value. updatePort(); } } unsigned int PicPSP_PortRegister::get() { if (m_psp && m_psp->pspmode()) return(m_psp->psp_get()); return rvDrivenValue.data; } void PicPSP_PortRegister::setTris(PicTrisRegister *new_tris) { if (!m_tris) m_tris = new_tris; unsigned int mask = getEnableMask(); for (unsigned int i=0, m = 1; iput_value(value.data); } void PicLatchRegister::put_value(unsigned int new_value) { value.data = new_value & m_EnableMask; m_port->put_value(value.data); } unsigned int PicLatchRegister::get() { value.data = m_port->getDriving(); trace.raw(read_trace.get() | value.data); trace.raw(read_trace.geti() | value.init); return value.data; } void PicLatchRegister::setbit(unsigned int bit_number, char new_value) { printf("PicLatchRegister::setbit() -- shouldn't be called\n"); } void PicLatchRegister::setEnableMask(unsigned int nEnableMask) { m_EnableMask = nEnableMask; } gpsim-0.30.0/src/p16f87x.h0000664000076400007640000001610513041763613011736 00000000000000/* Copyright (C) 1998-2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P16F87X_H__ #define __P16F87X_H__ #include "p16x7x.h" #include "eeprom.h" #include "comparator.h" class IOPORT; class P16F871 : public P16C64 // The 74 has too much RAM and too many CCPs { public: // XXX // This pir1_2, pir2_2 stuff is not particularly pretty. It would be // better to just tell C++ to redefine pir1 and pir2 and PIR1v2 and // PIR2v2, but C++ only supports covariance in member function return // values. PIR2v2 *pir2_2_reg; virtual PIR *get_pir2() { return (pir2_2_reg); } ADCON0 adcon0; ADCON1 adcon1; sfr_register adres; sfr_register adresl; USART_MODULE usart; // That now brings us up to spec with the 74 as far as we need to be virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F871_;}; virtual unsigned int program_memory_size() const { return 0x0800; }; virtual unsigned int eeprom_memory_size() const { return 64; }; virtual void create_symbols(); void create_sfr_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; P16F871(const char *_name=0, const char *desc=0); ~P16F871(); static Processor *construct(const char *name); virtual void set_eeprom(EEPROM *ep) { // use set_eeprom_wide as P16F871 expect a wide EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } private: }; class P16F873 : public P16C73 { public: sfr_register adresl; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F873_;}; virtual unsigned int program_memory_size() const { return 0x1000; }; virtual void create_symbols(); void create_sfr_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; P16F873(const char *_name=0, const char *desc=0); ~P16F873(); virtual void set_eeprom(EEPROM *ep) { // use set_eeprom_wide as P16F873 expect a wide EEPROM assert(0); } virtual unsigned int eeprom_memory_size() const { return 128; }; virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } static Processor *construct(const char *name); private: }; class P16F873A : public P16F873 { public: ComparatorModule comparator; virtual PROCESSOR_TYPE isa(){return _P16F873A_;}; void create_sfr_map(); void create(); P16F873A(const char *_name=0, const char *desc=0); ~P16F873A(); static Processor *construct(const char *name); }; class P16F876 : public P16C73 { public: sfr_register adresl; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F876_;}; virtual unsigned int program_memory_size() const { return 0x2000; }; virtual void create_symbols(); void create_sfr_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; P16F876(const char *_name=0, const char *desc=0); ~P16F876(); static Processor *construct(const char *name); virtual void set_eeprom(EEPROM *ep) { // use set_eeprom_wide as P16F873 expect a wide EEPROM assert(0); } virtual unsigned int eeprom_memory_size() const { return 256; }; virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } }; class P16F876A : public P16F873A { public: ComparatorModule comparator; virtual PROCESSOR_TYPE isa(){return _P16F876A_;}; virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; void create_sfr_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; P16F876A(const char *_name=0, const char *desc=0); ~P16F876A(); static Processor *construct(const char *name); }; class P16F874 : public P16C74 { public: ComparatorModule comparator; sfr_register adresl; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F874_;}; virtual unsigned int program_memory_size() const { return 0x1000; }; virtual void create_symbols(); void create_sfr_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; P16F874(const char *_name=0, const char *desc=0); ~P16F874(); static Processor *construct(const char *name); virtual unsigned int eeprom_memory_size() const { return 128; }; virtual void set_eeprom(EEPROM *ep) { // use set_eeprom_wide as P16F873 expect a wide EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } //virtual bool hasSSP() { return true;} }; class P16F877 : public P16F874 { public: virtual PROCESSOR_TYPE isa(){return _P16F877_;}; virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual void create_symbols(); void create_sfr_map(); void create(); P16F877(const char *_name=0, const char *desc=0); ~P16F877(); static Processor *construct(const char *name); }; class P16F874A : public P16F874 { public: ComparatorModule comparator; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F874A_;}; virtual unsigned int program_memory_size() const { return 0x1000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual void create_symbols(); void create_sfr_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; P16F874A(const char *_name=0, const char *desc=0); ~P16F874A(); static Processor *construct(const char *name); }; class P16F877A : public P16F874A { public: ComparatorModule comparator; virtual PROCESSOR_TYPE isa(){return _P16F877A_;}; virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual void create_symbols(); void create_sfr_map(); void create(); P16F877A(const char *_name=0, const char *desc=0); ~P16F877A(); static Processor *construct(const char *name); }; #endif gpsim-0.30.0/src/gpsim_object.cc0000664000076400007640000001027213041763624013417 00000000000000 /* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "gpsim_object.h" //======================================================================== gpsimObject::gpsimObject() : cpDescription(0) { } gpsimObject::gpsimObject(const char *_name, const char *desc) : cpDescription(desc) { if (_name) name_str = _name; } gpsimObject::~gpsimObject() { name_str.clear(); cpDescription = 0; } // The 'type' of any Viewable object is equivalent to the class name. string gpsimObject::showType() { const char* name; name = typeid(*this).name(); /* Unfortunately, the class name string returned by typeid() is * implementation-specific. If a particular compiler produces * ugly output, this is your chance to clean it up. */ #if defined __GNUC__ /* GNU C++ puts the length of the class name in front of the actual class name. We will skip over it for clarity. */ if (*name == 'N') // Class names with format N nn name nn name E { char buf[256]; int cnt; name++; buf[0] = 0; while (isdigit(*name)) { for(cnt = 0; isdigit(*name); name++) cnt = cnt * 10 + *name - '0'; strncat(buf, name, cnt); name += cnt; if (isdigit(*name)) strcat(buf, "::"); } name = buf; } else // just nn name { while (isdigit(*name)) name++; } #elif defined _MSC_VER /* From Visual C++ on line documentation The type_info::name member function returns a const char* to a null-terminated string representing the human-readable name of the type. The memory pointed to is cached and should never be directly deallocated. */ // Skip over the word 'class '. name += 6; #else #warning --->You might want to clean up the result of typeid() here... #endif return string(name); } string gpsimObject::show() { return showType() + ":" + toString(); } void gpsimObject::new_name(const char *s) { if(s) name_str = string(s); } void gpsimObject::new_name(string &new_name) { name_str = new_name; } char *gpsimObject::name(char *return_str, int len) { if(return_str) snprintf(return_str,len,"%s",name_str.c_str()); return return_str; } /// TEMPORARY -- remove after gpsimValue and Value have been merged. unsigned int gpsimObject::get_value() { return 0; } char *gpsimObject::toString(char *return_str, int len) { if(return_str) snprintf(return_str,len,"%s",toString().c_str()); return return_str; } char *gpsimObject::toBitStr(char *return_str, int len) { if(return_str) *return_str = 0; return return_str; } string &gpsimObject::name(void) const { return (string &)name_str; } string gpsimObject::toString() { //return showType(); char buff[64]; snprintf(buff,sizeof(buff), " = 0x%x",get_value()); string s = name() + string(buff); return s; } // If derived classes don't redefine set_break and clear_break then // the default behavior is to not support these capabilities. int gpsimObject::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *expr) { //cout << showType() << " objects do not support break points\n"; return -1; } int gpsimObject::clear_break() { //cout << showType() << " objects do not support break points\n"; return -1; } string gpsimObject::description() { if(cpDescription) return string(cpDescription); else return string("no description"); } void gpsimObject::set_description(const char *new_description) { cpDescription = new_description; } gpsim-0.30.0/src/ValueCollections.cc0000664000076400007640000001613213041763613014224 00000000000000/* Copyright (C) 1998-2004 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "ValueCollections.h" #include "symbol.h" #include "registers.h" //#include #include IIndexedCollection::IIndexedCollection(const char *pName, const char *pDesc, int iAddressRadix) : Value(pName, pDesc) { SetAddressRadix(iAddressRadix); } IIndexedCollection::IIndexedCollection(int iAddressRadix) { SetAddressRadix(iAddressRadix); } void IIndexedCollection::SetAddressRadix(int iRadix) { m_iAddressRadix = iRadix; if(iRadix == 16) { strcpy(m_szPrefix, "$"); } else { m_szPrefix[0] = 0; } } void IIndexedCollection::Set(Value * pValue) { unsigned int uUpper = GetUpperBound() + 1; for(unsigned int uIndex = GetLowerBound(); uIndex < uUpper; uIndex++) { SetAt(uIndex, pValue); } } void IIndexedCollection::SetAt(ExprList_t* pIndexers, Expression *pExpr) { ExprList_t::iterator it; ExprList_t::iterator itEnd = pIndexers->end(); Value * pValue = pExpr->evaluate(); // _CT * pCTValue = dynamic_cast<_CT*>(pValue); // if(pCTValue != NULL) { for(it = pIndexers->begin(); it != itEnd; ++it) { Value * pIndex = (*it)->evaluate(); Integer *pIntIndex = dynamic_cast(pIndex); if(pIntIndex != NULL) { SetAt(int(*pIntIndex), pValue); } else { AbstractRange *pRange = dynamic_cast(pIndex); if(pRange) { unsigned uEnd = pRange->get_rightVal() + 1; for(unsigned int uIndex = pRange->get_leftVal(); uIndex < uEnd; uIndex++) { SetAt(uIndex, pValue); } } else { /* register_symbol *pReg = dynamic_cast(pIndex); if(pReg) { SetAt(pReg->getReg()->address, pValue); } else { throw Error("indexer not valid"); } */ Register *pReg = dynamic_cast(pIndex); if (pReg) SetAt(pReg->getAddress(), pValue); else throw Error("indexer not valid"); } } if(pIndex != NULL) { delete pIndex; } } // } // else { // } delete pValue; } char *IIndexedCollection::toString(char *pBuffer, int len) { return strncpy(pBuffer, toString().c_str(), len); } string IIndexedCollection::toString() { int iColumnWidth = 0; vector asIndexes; vector asValue; ConsolidateValues(iColumnWidth, asIndexes, asValue); return toString(iColumnWidth, asIndexes, asValue); } string IIndexedCollection::toString(ExprList_t* pIndexerExprs) { try { ostringstream sOut; if(pIndexerExprs==NULL) { sOut << toString() << ends; return sOut.str(); } else { ExprList_t::iterator it; ExprList_t::iterator itEnd = pIndexerExprs->end(); for(it = pIndexerExprs->begin(); it != itEnd; ++it) { Value * pIndex = (*it)->evaluate(); AbstractRange *pRange = dynamic_cast(pIndex); if(pRange) { unsigned uEnd = pRange->get_rightVal() + 1; for(unsigned int uIndex = pRange->get_leftVal(); uIndex < uEnd; uIndex++) { Value &Value = GetAt(uIndex); sOut << Value.name() << " = " << Value.toString() << endl; } continue; } String *pName = dynamic_cast(pIndex); Integer *pInt = pName ? globalSymbolTable().findInteger(pName->getVal()) : dynamic_cast(pIndex); Integer temp(0); if(pInt == NULL) { // This is a temp workaround. I (JR) would expect a register symbol // evaluate to an Integer object containing the value of the // register. It currently returns an object that is a copy // of the register_symbol object. /* register_symbol *pReg = dynamic_cast(pIndex); if(pReg) { gint64 i; pReg->get(i); temp.set(i); pInt = &temp; } */ Register *pReg = dynamic_cast(pIndex); if(pReg) { gint64 i = pReg->get_value(); temp.set(i); pInt = &temp; } } if(pInt) { unsigned int uIndex = (unsigned int)pInt->getVal(); if(bIsIndexInRange(uIndex)) { Value &Value = GetAt(uIndex); sOut << Value.name() << " = " << Value.toString() << endl; } else { sOut << "Error: Index " << uIndex << " is out of range" << endl; } } else { sOut << "Error: The index specified for '" << name() << "' does not contain a valid index." << endl; } delete pIndex; } } sOut << ends; return sOut.str(); } catch(Error e) { return e.toString(); } } void IIndexedCollection::PushValue(int iFirstIndex, int iCurrentIndex, Value *pValue, vector &asIndexes, vector &asValue) { ostringstream sIndex; if(m_iAddressRadix == 16) { sIndex << hex; } sIndex << Value::name() << "[" << m_szPrefix << iFirstIndex; if(iFirstIndex != iCurrentIndex) { sIndex << ".." << m_szPrefix << iCurrentIndex; } sIndex << "]" << ends; asIndexes.push_back(string(sIndex.str())); asValue.push_back(pValue->toString()); } string IIndexedCollection::ElementIndexedName(unsigned int iIndex) { ostringstream sIndex; if(m_iAddressRadix == 16) { sIndex << hex; } sIndex << Value::name() << "[" << m_szPrefix << iIndex; sIndex << "]" << ends; return sIndex.str(); } string IIndexedCollection::toString(int iColumnWidth, vector &asIndexes, vector &asValue) { ostringstream sOut; vector::iterator itValue; vector::iterator itElement; vector::iterator itElementEnd = asIndexes.end(); // Dump the consolidated element list for(itElement = asIndexes.begin(), itValue = asValue.begin(); itElement != itElementEnd; ++itElement, ++itValue) { sOut.width(iColumnWidth); sOut.setf(ios_base::left); sOut << (*itElement); sOut << " = "; sOut << (*itValue); if(itElement + 1 != itElementEnd) sOut << endl; } sOut << ends; return sOut.str(); } Integer * IIndexedCollection::FindInteger(const char *s) { return globalSymbolTable().findInteger(s); } gpsim-0.30.0/src/eeprom.h0000664000076400007640000002010713041763624012101 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 2013 Roy Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef EEPROM_H #define EEPROM_H #include #include "gpsim_classes.h" #include "registers.h" #include "breakpoints.h" #include class pic_processor; class EEPROM; class PIR_SET; class INTCON; class PIR; //--------------------------------------------------------- // EECON1 - EE control register 1 // class EECON1 : public sfr_register { public: enum { RD = (1<<0), WR = (1<<1), WREN = (1<<2), WRERR = (1<<3), EEIF = (1<<4), FREE = (1<<4), // 14 bit Extended LWLO = (1<<5), // "" CFGS = (1<<6), // "" EEPGD = (1<<7) }; EECON1(Processor *pCpu, const char *pName, const char *pDesc); void put(unsigned int new_value); unsigned int get(); inline void set_eeprom(EEPROM *ee) { eeprom = ee; } inline void set_valid_bits(unsigned int vb) { valid_bits = vb; } inline unsigned int get_valid_bits() { return (valid_bits); } inline void set_bits(unsigned int b) { valid_bits |= b; } inline void clear_bits(unsigned int b) { valid_bits &= ~b; } //private: unsigned int valid_bits; EEPROM *eeprom; }; const unsigned int EECON1_VALID_BITS = (EECON1::RD | EECON1::WR | EECON1::WREN | EECON1::EEIF); // // EECON2 - EE control register 2 // class EECON2 : public sfr_register { public: enum EE_STATES { EENOT_READY, EEHAVE_0x55, EEREADY_FOR_WRITE, EEWRITE_IN_PROGRESS, EEUNARMED, EEREAD }; EECON2(Processor *pCpu, const char *pName, const char *pDesc); void put(unsigned int new_value); unsigned int get(); void ee_reset() { eestate = EENOT_READY;}; inline virtual void set_eeprom(EEPROM *ee) { eeprom = ee; } inline enum EE_STATES get_eestate() { return (eestate); } inline void unarm() { eestate = EEUNARMED; } inline void unready() { eestate = EENOT_READY; } inline void read() { eestate = EEREAD; } inline void start_write() { eestate = EEWRITE_IN_PROGRESS; } inline bool is_unarmed() { return (eestate == EEUNARMED); } inline bool is_not_ready() { return (eestate == EENOT_READY); } inline bool is_ready_for_write() { return (eestate == EEREADY_FOR_WRITE); } inline bool is_writing() { return (eestate == EEWRITE_IN_PROGRESS); } //private: EEPROM *eeprom; enum EE_STATES eestate; }; // // EEDATA - EE data register // class EEDATA : public sfr_register { public: EEDATA(Processor *pCpu, const char *pName, const char *pDesc); void put(unsigned int new_value); unsigned int get(); virtual void set_eeprom(EEPROM *ee) { eeprom = ee; } //private: EEPROM *eeprom; }; // // EEADR - EE address register // class EEADR : public sfr_register { public: EEADR(Processor *pCpu, const char *pName, const char *pDesc); void put(unsigned int new_value); unsigned int get(); virtual void set_eeprom(EEPROM *ee) { eeprom = ee; } //private: EEPROM *eeprom; }; //------------------------------------------------------------------------ //------------------------------------------------------------------------ const int EPROM_WRITE_TIME = 20; class EEPROM : public TriggerObject { public: EEPROM(Processor *pCpu); ~EEPROM(); void reset(RESET_TYPE); virtual void set_intcon(INTCON *ic); virtual void callback(); virtual void callback_print(){ puts(" EEPROM");} virtual void start_write(); virtual void write_is_complete(); virtual void start_program_memory_read(); virtual void initialize(unsigned int new_rom_size); virtual Register *get_register(unsigned int address); virtual void save_state(); inline virtual void change_rom(unsigned int offset, unsigned int val) { assert(offset < rom_size); rom[offset]->value.put(val); } inline int register_size() { return (rom_data_size); } inline void set_resister_size(int bytes) { rom_data_size = bytes; } inline virtual unsigned int get_rom_size() { return (rom_size); } // XXX might want to make get_rom a friend only to cli_dump inline virtual Register **get_rom() { return (rom); } inline virtual EECON1 *get_reg_eecon1() { return (&eecon1); } inline virtual EECON2 *get_reg_eecon2() { return (&eecon2); } inline virtual EEDATA *get_reg_eedata() { return (&eedata); } inline virtual EEADR *get_reg_eeadr() { return (&eeadr); } inline virtual EEADR *get_reg_eeadrh() { return 0; } // No eeadrh on basic EEPROM void dump(); //protected: char *name_str; Processor *cpu; INTCON *intcon; EECON1 eecon1; // The EEPROM consists of 4 control registers EECON2 eecon2; // on the F84 and 6 on the F877 EEDATA eedata; EEADR eeadr; Register **rom; // and the data area. RegisterCollection *m_UiAccessOfRom; // User access to the rom. int rom_data_size; // data width in bytes unsigned int rom_size; unsigned int wr_adr,wr_data; // latched adr and data for eewrites. unsigned int rd_adr; // latched adr for eereads. unsigned int abp; // break point number that's set during eewrites protected: virtual unsigned int get_address(void) { return eeadr.value.get(); }; }; /** * A class for the EEPROM in later devices with PIR-mapped status. Some of * these devices (e.g. 18F4620) have more than 256 bytes of EEPROM so this * class implements the eeadrh register too. This will not be used if the * EEPROM size is 256 or less. */ class EEPROM_PIR : public EEPROM { public: EEPROM_PIR(Processor *pCpu, PIR *); ~EEPROM_PIR(); // the 16f628 eeprom is identical to the 16f84 eeprom except // for the size and the location of EEIF. The size is taken // care of when the '628 is constructed, the EEIF is taken // care of here: virtual void start_write(); virtual void write_is_complete(); virtual void callback(); virtual void set_pir(PIR *pir) {m_pir = pir;} inline virtual EEADR *get_reg_eeadrh() { return (rom_size>256) ? (&eeadrh) : 0; } virtual void initialize(unsigned int new_rom_size); virtual void callback_print(){ puts(" EEPROM_PIR");} protected: PIR *m_pir; EEADR eeadrh; virtual unsigned int get_address(void) { return (rom_size <= 256 ) ? eeadr.value.get() : (eeadrh.value.get()<<8)+eeadr.value.get(); }; }; class EEPROM_WIDE : public EEPROM_PIR { public: EEPROM_WIDE(Processor *pCpu, PIR *); ~EEPROM_WIDE(); virtual void start_write(); virtual void callback(); virtual void callback_print(){ puts(" EEPROM_WIDE");} virtual void start_program_memory_read(); virtual void initialize(unsigned int new_rom_size); inline virtual EEADR *get_reg_eeadrh() { return (&eeadrh); } inline virtual EEDATA *get_reg_eedatah() { return (&eedatah); } //protected: EEDATA eedatah; }; class EEPROM_EXTND : public EEPROM_WIDE { public: EEPROM_EXTND(Processor *pCpu, PIR *); ~EEPROM_EXTND(); inline virtual EEADR *get_reg_eeadrh() { return (has_eeadrh) ? (&eeadrh) : 0; } virtual void start_write(); virtual void start_program_memory_read(); virtual void callback(); virtual void callback_print(){ puts(" EEPROM_EXTND");} void initialize(unsigned int new_rom_size, int block_size, int num_latches, unsigned int cfg_word_base, bool _has_eeadrh = true); void set_prog_wp(unsigned int adr) { prog_wp = adr;} #define LATCH_MT 0x7fff protected: int erase_block_size; int num_write_latches; unsigned int *write_latches; unsigned int config_word_base; unsigned int prog_wp; // program memory below this address is write protected bool has_eeadrh; }; #endif /* EEPROM_H */ gpsim-0.30.0/src/lcd_module.cc0000664000076400007640000003662413116521767013075 00000000000000/* Copyright (C) 2017 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "../config.h" #include "14bit-processors.h" #include "14bit-registers.h" #include "a2d_v2.h" #include "lcd_module.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif LCD_MODULE::LCD_MODULE(Processor *pCpu, bool p16f917) : cpu(pCpu), IntSrc(0) { char lcdsex[] = "lcdsex"; char lcddataX[10]; int i; Vlcd1 = Vlcd2 = Vlcd3 = 0; Vlcd1_on = Vlcd2_on = Vlcd3_on = false; bias_now = 0; future_cycle = 0; is_sleeping = false; lcdcon = new LCDCON(pCpu, "lcdcon", "LCD control register", this); lcdps = new LCDPS(pCpu, "lcdps", "LCD prescaler select register", this, 0xcf); for (i = 0; i < 3 ; i++) { lcdsex[5] = '0' + i; if ( i < 2 || p16f917) lcdSEn[i] = new LCDSEn(pCpu, (const char *)lcdsex, "LCD Segment register", this, i); else lcdSEn[i] = 0; } printf("\n"); for (i=0; i < 12; i++) { sprintf(lcddataX, "lcddata%d", i); if (((i+1)%3 != 0) || p16f917) { lcddatax[i] = new LCDDATAx(pCpu, (const char *)lcddataX, "LCD Data register", this, i); } else { lcddatax[i] = 0; } } for(i=0; i < 24; i++) LCDsegn[i] = 0; for(i=0; i<4; i++) LCDcom[i] = 0; } // set LCD bias pins void LCD_MODULE::set_Vlcd(PinModule *_Vlcd1, PinModule *_Vlcd2, PinModule *_Vlcd3) { Vlcd1 = _Vlcd1; Vlcd2 = _Vlcd2; Vlcd3 = _Vlcd3; } // set LCD common pins void LCD_MODULE::set_LCDcom(PinModule *c0, PinModule *c1, PinModule *c2, PinModule *c3) { LCDcom[0] = c0; LCDcom[1] = c1; LCDcom[2] = c2; LCDcom[3] = c3; } // set 4 LCD segment pins (at a time) void LCD_MODULE::set_LCDsegn(unsigned int i, PinModule *c0, PinModule *c1, PinModule *c2, PinModule *c3) { assert(i <= 20); LCDsegn[i+0] = c0; LCDsegn[i+1] = c1; LCDsegn[i+2] = c2; LCDsegn[i+3] = c3; } void LCD_MODULE::clear_bias() { Dprintf(("LCD_MODULE::clear_bias()\n")); bias_now = 0; if (Vlcd1_on) { Vlcd1->AnalogReq(lcdps, false, Vlcd1->getPin().name().c_str()); Vlcd1_on = false; } if (Vlcd2_on) { Vlcd2->AnalogReq(lcdps, false, Vlcd2->getPin().name().c_str()); Vlcd2_on = false; } if (Vlcd3_on) { Vlcd3->AnalogReq(lcdps, false, Vlcd3->getPin().name().c_str()); Vlcd3_on = false; } } void LCD_MODULE::set_bias(unsigned int lmux) { bool biasmode = (lcdps->value.get() & LCDPS::BIASMD); unsigned char bias = 0; Dprintf(("LCD_MODULE::set_bias Vlcd1=%p\n", Vlcd1)); switch(lmux) { case 0: bias = 1; break; case 1: bias = biasmode ? 2 : 3; break; case 2: bias = biasmode ? 2 : 3; break; case 3: bias = 3; break; } if (bias == bias_now) return; switch(bias) { case 1: //Static bias if (lcdcon->value.get() & LCDCON::VLCDEN) { if (Vlcd1_on) { Vlcd1->AnalogReq(lcdps, false, Vlcd1->getPin().name().c_str()); Vlcd1_on = false; } if (Vlcd2_on) { Vlcd2->AnalogReq(lcdps, false, Vlcd2->getPin().name().c_str()); Vlcd2_on = false; } if (!Vlcd3_on) { Vlcd3->AnalogReq(lcdps, true, "vlcd3"); Vlcd3_on = true; } } break; case 2: // 1/2 bias case 3: // 1>/3 bias if (!Vlcd1_on) { Vlcd1->AnalogReq(lcdps, true, "vlcd1"); Vlcd1_on = true; } if (!Vlcd2_on) { Vlcd2->AnalogReq(lcdps, true, "vlcd2"); Vlcd2_on = true; } if (!Vlcd3_on) { Vlcd3->AnalogReq(lcdps, true, "vlcd3"); Vlcd3_on = true; } break; } bias_now = bias; } void LCD_MODULE::lcd_on_off(bool lcdOn) { unsigned int i; if (lcdOn) { for (i=0; i < 3; i++) { if (lcdSEn[i]) lcd_set_segPins(i, lcdSEn[i]->value.get(), lcdSEn[i]->value.get()^0); } lcd_set_com(lcdOn, lcdcon->value.get() & (LCDCON::LMUX0| LCDCON::LMUX1)); start_clock(); } else { } } void LCD_MODULE::lcd_set_com(bool lcdOn, unsigned int lmux) { unsigned int i; Dprintf(("LCD_MODULE::lcd_set_com on %d lmux %d\n", lcdOn, lmux)); if (lcdOn) { for(i=0; i < 4; i++) { mux_now = lmux; if (i <= lmux) { char name[5]; sprintf(name, "COM%d", i); LCDcom[i]->getPin().newGUIname(name); if (LCDcom[i]->getPin().get_direction()) LCDcomDirection |= (1<getPin().update_direction(1,true); } else { LCDcom[i]->getPin().newGUIname(LCDcom[i]->getPin().name().c_str()); LCDcom[i]->getPin().update_direction(LCDcomDirection & (1<getPin().newGUIname(LCDcom[i]->getPin().name().c_str()); LCDcom[i]->getPin().update_direction(LCDcomDirection & (1<value.get(); Dprintf(("LCD_MODULE::sleep()\n")); if (!(lcdps->value.get() & LCDPS::LCDA)) return; // Stop during sleep if ((con_reg & LCDCON::SLPEN) || !(con_reg & (LCDCON::CS0 | LCDCON::CS1))) { Dprintf(("LCD_MODULE::sleep() stop during sleep fc=%" PRINTF_GINT64_MODIFIER "d now=%" PRINTF_GINT64_MODIFIER "d\n", future_cycle, get_cycles().get())); if (future_cycle >= get_cycles().get()) { get_cycles().clear_break(future_cycle); future_cycle = 0; phase = 0; } is_sleeping = true; // Set all LCD outputs to zero for(int l=0; l <= mux_now; l++) // scan across com related output { LCDcom[l]->getPin().putState(0.); } for(int k = 0; (k < 3) && lcdSEn[k]; k++) { unsigned int enable = lcdSEn[k]->value.get(); if (enable) { for(int i=0; i< 8; i++) { if (enable & (1<getPin().putState(0.); } } } } } void LCD_MODULE::wake() { unsigned int con_reg = lcdcon->value.get(); if (!(lcdps->value.get() & LCDPS::LCDA) || !is_sleeping) return; is_sleeping = false; Dprintf(("LCD_MODULE::wake() fc=%" PRINTF_GINT64_MODIFIER "d\n", future_cycle)); // Stop during sleep if ((con_reg & LCDCON::SLPEN) || !(con_reg & (LCDCON::CS0 | LCDCON::CS1))) { Dprintf(("LCD_MODULE::wake() restart after sleep\n")); start_clock(); } } void LCD_MODULE::lcd_set_segPins(unsigned int regno, unsigned int new_value, unsigned int diff) { unsigned char *pt = &LCDsegDirection[regno]; for (int i = 0; i < 8; i++) { unsigned int mask = 1<getPin().get_direction()) *pt |= mask; else *pt &= ~mask; port->getPin().newGUIname((const char *)name); port->getPin().update_direction(1,true); } else { port->getPin().update_direction(*pt&mask, true); port->getPin().newGUIname(port->getPin().name().c_str()); } } } } void LCD_MODULE::start_clock() { unsigned int prescale = (lcdps->value.get() & (LCDPS::LPMASK)) +1; unsigned int clock_source, frame_rate; double freq; clock_source = 0; Dprintf(("LCD_MODULE::start_clock() mux_now %x lmux %x\n", mux_now, lcdcon->value.get() & 0x3)); switch((lcdcon->value.get() & (LCDCON::CS0 | LCDCON::CS1)) >> 2) { case 0: // Fosc/8102 or instruction/sec / 2048; clock_source = 2048; break; case 1: //T1OSC(32kHz) (Timer1)/32 freq = t1con->t1osc(); if (freq > 1.) clock_source = get_cycles().instruction_cps() * 32 /freq; else { fprintf(stderr, "LCD_MODULE::start_clock() t1osc not enabled\n"); return; } break; case 2: //LFINTOSC (31 kHz) /32 case 3: clock_source = get_cycles().instruction_cps() * 32 /31e3; Dprintf(("LFINTOSC %d \n", clock_source)); break; } if (mux_now != 3) frame_rate = clock_source * (4 * prescale); else frame_rate = clock_source * (3 * prescale); num_phases = 2 * (mux_now + 1); phase = 0; if (typeB()) // Type B wave form { clock_tick = frame_rate / (mux_now + 1); start_typeB(); } else { clock_tick = frame_rate / num_phases; start_typeA(); } Dprintf(("frame rate %d clock_tick %d %.1f\n", frame_rate, clock_tick, get_cycles().instruction_cps()/frame_rate)); if (future_cycle >= get_cycles().get()) { get_cycles().clear_break(future_cycle); future_cycle = 0; } save_hold_data(); lcdps->value.put(lcdps->value.get() | LCDPS::LCDA); if ((lcdps->value.get() & LCDPS::WFT) == 0) lcdps->value.put(lcdps->value.get() | LCDPS::WA); callback(); } void LCD_MODULE::start_typeA() { switch(mux_now) { case 0: // static map_com[0] = 003; map_on = 030; map_off = 003; break; case 1: // 1/2 map_com[0] = 00321; map_com[1] = 02103; map_on = 03030; map_off = 01212; break; case 2: // 1/3 map_com[0] = 0032121; map_com[1] = 0210321; map_com[2] = 0212103; map_on = 0303030; map_off = 0121212; break; case 3: // 1/4 map_com[0] = 003212121; map_com[1] = 021032121; map_com[2] = 021210321; map_com[3] = 021212103; map_on = 030303030; map_off = 012121212;; break; }; } void LCD_MODULE::start_typeB() { switch(mux_now) { case 0: // static - use type A for this break; case 1: // 1/2 map_com[0] = 00231; map_com[1] = 02013; map_on = 030; map_off = 012; break; case 2: // 1/3 map_com[0] = 0122311; map_com[1] = 0202131; map_com[2] = 0220113; map_on = 003; map_off = 021; break; case 3: // 1/4 map_com[0] = 002223111; map_com[1] = 020221311; map_com[2] = 022021131; map_com[3] = 022201113; map_on = 033330000; map_off = 011112222;; break; }; } // shutdown LCD void LCD_MODULE::stop_clock() { for (int i=0; i < 3; i++) { if (lcdSEn[i]) lcd_set_segPins(i, 0, lcdSEn[i]->value.get()); } lcd_set_com(false, lcdcon->value.get() & (LCDCON::LMUX0| LCDCON::LMUX1)); lcdps->value.put(lcdps->value.get() & ~LCDPS::LCDA); } void LCD_MODULE::callback() { Dprintf(("LCD_MODULE::callback() %" PRINTF_GINT64_MODIFIER "d phase=%d bias_now=%d\n", future_cycle, phase, bias_now)); drive_lcd(); if (typeB() && (phase == (mux_now + 1))) { IntSrc->Trigger(); lcdps->value.put(lcdps->value.get() | LCDPS::WA); } phase++; if (phase == num_phases) { phase = 0; save_hold_data(); if (!(lcdcon->value.get() & LCDCON::LCDEN)) stop_clock(); if (typeB()) lcdps->value.put(lcdps->value.get() & ~LCDPS::WA); } if (lcdps->value.get() & LCDPS::LCDA) { future_cycle = get_cycles().get() + clock_tick; get_cycles().set_break(future_cycle, this); } } void LCD_MODULE::save_hold_data() { for(int i = 0; i < 12; i++) { if (lcddatax[i]) hold_data[i] = lcddatax[i]->value.get(); } } void LCD_MODULE::drive_lcd() { double vlcd[4]; double com_volt[4]; unsigned int subphase; unsigned int shift = 3 * (num_phases - phase - 1); guint64 mask = 07 << shift; vlcd[0] = 0; vlcd[3] = Vlcd3->getPin().get_nodeVoltage(); if (bias_now != 1) { vlcd[1] = Vlcd1->getPin().get_nodeVoltage(); vlcd[2] = Vlcd2->getPin().get_nodeVoltage(); } for(int l=0; l <= mux_now; l++) // scan across com related output { unsigned int index= (map_com[l] & mask)>> shift; com_volt[l] = vlcd[index]; Dprintf(("com%d mask %" PRINTF_GINT64_MODIFIER "o index %d %.1f\n", l, mask, index, com_volt[l])); LCDcom[l]->getPin().putState(com_volt[l]); } if (typeB()) subphase = phase % (mux_now + 1); else subphase = phase / 2; double Von = vlcd[(map_on & mask) >> shift]; double Voff = vlcd[(map_off & mask) >> shift]; Dprintf(("phase %d mask %" PRINTF_GINT64_MODIFIER "o subphase %d\n",phase, mask, subphase)); for(int k = 0; (k < 3) && lcdSEn[k]; k++) { unsigned int enable = lcdSEn[k]->value.get(); unsigned int data = hold_data[k+3*subphase]; if (enable) { #ifdef DEBUG printf("\t0x%x", data); #endif for(int i=0; i< 8; i++) { bool bit = (1<getPin().putState(seg_volt); } } #ifdef DEBUG printf("\n"); #endif } } } LCDCON::LCDCON(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *_lcd_module) : sfr_register(pCpu, pName, pDesc) { lcd_module = _lcd_module; } void LCDCON::put_value(unsigned int new_value) { unsigned int diff = value.get() ^ new_value; Dprintf(("LCDCON::put_value new=0x%x old=0x%x \n", new_value, value.get())); value.put(new_value); // Are LCD Bias Voltage Pins Enabled if (new_value & VLCDEN) { lcd_module->set_bias(new_value & (LMUX0 | LMUX1)); } else if (diff & VLCDEN) // disable Vlcd { lcd_module->clear_bias(); } // LCD on/off if (diff & LCDEN) lcd_module->lcd_on_off(new_value & LCDEN); } void LCDCON::put(unsigned int new_value) { Dprintf(("LCDCON::put 0x%x\n", new_value)); trace.raw(write_trace.get() | value.get()); put_value(new_value); } LCDPS::LCDPS(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *_lcd_module, unsigned int bitmask) : sfr_register(pCpu, pName, pDesc), lcd_module(_lcd_module), mask_writeable(bitmask) { } void LCDPS::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value & mask_writeable); } LCDSEn::LCDSEn(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *_lcd_module, unsigned int _n) : sfr_register(pCpu, pName, pDesc) { lcd_module = _lcd_module; n = _n; } void LCDSEn::put(unsigned int new_value) { unsigned int diff = new_value ^ value.get(); trace.raw(write_trace.get() | value.get()); put_value(new_value); if (lcd_module->get_lcdcon_lcden()) lcd_module->lcd_set_segPins(n, new_value, diff); } LCDDATAx::LCDDATAx(Processor *pCpu, const char *pName, const char *pDesc, LCD_MODULE *_lcd_module, unsigned int _n) : sfr_register(pCpu, pName, pDesc) { lcd_module = _lcd_module; n =_n; } void LCDDATAx::put(unsigned int new_value) { // set error if lcdps:WA not set if (!lcd_module->get_lcdps_wa()) { fprintf(stderr, "%s ERROR write with WA == 0\n", name().c_str()); lcd_module->set_lcdcon_werr(); return; } trace.raw(write_trace.get() | value.get()); put_value(new_value); } gpsim-0.30.0/src/interface.h0000664000076400007640000000276413041763624012563 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __INTERFACE_H__ #define __INTERFACE_H__ /* * interface.h */ #include #include #include "modules.h" #include "symbol.h" typedef enum _REGISTER_TYPE { REGISTER_RAM, REGISTER_EEPROM } REGISTER_TYPE; struct file_context { char *name; /* file name */ FILE *file_ptr; int *line_seek; /* an array of offsets into the file that point to * the start of the source lines. */ int max_line; }; #include "cmd_gpsim.h" extern unsigned int gpsim_is_initialized; LIBGPSIM_EXPORT void initialization_is_complete(void); #define INVALID_VALUE 0xffffffff void gpsim_set_bulk_mode(int flag); extern const char *get_dir_delim(const char *path); LIBGPSIM_EXPORT int initialize_gpsim_core(); #endif /* __INTERFACE_H__ */ gpsim-0.30.0/src/ttoken.h0000664000076400007640000000401013041763624012111 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__TTOKEN_H__) #define __TTOKEN_H__ namespace gpsim { /// Token - a class used to synchronize two threads. /// Token will spawn a new thread and keep it synchronized /// with the thread that called it. In gpsim, the simulation /// engine is a single thread application. However, it's /// sometimes quite difficult to implement modules within the /// context of this thread. So modules that are instantiated /// from within the context of the simulator can use the Token /// class to spawn a new thread. /// /// Note - the underlying implementation depends on pthreads. /// However, that implementation is completely hidden with an /// opaque pointer to the PThreadWrapper object. This way, /// if it turns out that pthreads are not installed or there's /// another implementation preferred for the synchronization /// then it's easy to change with impacting the whole system. struct ThreadWrapper; class Token { public: Token(); /// Initialize - a wrapper for pthread create. void Initialize(void *(*child) (void *), void *data); /// void waitForChild(); void passToChild(); void passToParent(); void grab(); private: ThreadWrapper *thread; }; } // end of namespace gpsim #endif // !defined(__TTOKEN_H__) gpsim-0.30.0/src/pic-registers.cc0000664000076400007640000003355213116644445013542 00000000000000/* Copyright (C) 1998-2000 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "14bit-processors.h" #include "interface.h" #include "pic-registers.h" #include "clock_phase.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("0x%06" PRINTF_GINT64_MODIFIER "X %s() ",cycles.get(),__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------------------------ // member functions for the Program_Counter base class //------------------------------------------------------------------------ // //-------------------------------------------------- Program_Counter::Program_Counter(const char *name, const char *desc, Module *pM) : Value(name,desc,pM) { if(verbose) cout << "pc constructor\n"; reset_address = 0; value = 0; pclath_mask = 0x1800; // valid pclath bits for branching in 14-bit cores instruction_phase = 0; set_xref(new XrefObject(this)); trace_state = 0; trace_increment = 0; trace_branch = 0; trace_skip = 0; trace_other = 0; } Program_Counter::~Program_Counter() { if (cpu) cpu->removeSymbol(this); XrefObject *pt_xref; XrefObject *pt = xref(); if (pt) { while((pt_xref = (XrefObject *)pt->first_xref())) { pt->clear(pt_xref); if (pt_xref->data) delete (int *)pt_xref->data; delete pt_xref; } } delete m_pPCTraceType; } //-------------------------------------------------- void Program_Counter::set_trace_command() { m_pPCTraceType = new PCTraceType(get_cpu(),1); unsigned int new_command = trace.allocateTraceType(m_pPCTraceType); trace_increment = new_command | (0<<16); trace_branch = new_command | (1<<16); trace_skip = new_command | (2<<16); trace_other = new_command | (3<<16); } //-------------------------------------------------- // increment - update the program counter. All non-branching instructions pass through here. // void Program_Counter::increment() { Dprintf(("PC=0x%x\n",value)); // Trace the value of the program counter before it gets changed. trace.raw(trace_increment | value); value = (value + 1); if (value == memory_size) // Some processors start at highest memory and roll over { printf("%s PC=0x%x == memory size 0x%x\n", __FUNCTION__, value, memory_size); value = 0; } else if (value > memory_size) // assume this is a mistake { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, value, memory_size); bp.halt(); } // Update PCL sfr to reflect current PC update_pcl(); cpu_pic->mCurrentPhase->setNextPhase(cpu_pic->mExecute1Cycle); } //-------------------------------------------------- // update_pcl - Updates the PCL from within the Program_Counter class. // There is a separate method for this as the Program_Counter counts // instructions (words) while the PCL can also point to bytes on // 16 bit devices. So the PCL on 16-bit devices is always the double // as the current Program_Counter // void Program_Counter::update_pcl() { // For 12/14 bit devices the PCL will simply get set to the // current "value" of Program_Counter // Update pcl. Note that we don't want to pcl.put() because that // will trigger a break point if there's one set on pcl. (A read/write // break point on pcl should not be triggered by advancing the program // counter). cpu_pic->pcl->value.put(value & 0xff); } //-------------------------------------------------- // skip - Does the same thing that increment does, except that it records the operation // in the trace buffer as a 'skip' instead of a 'pc update'. // void Program_Counter::skip() { Dprintf(("PC=0x%x\n",value)); // Trace the value of the program counter before it gets changed. trace.raw(trace_skip | value); if ((value + 2) >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, value, memory_size); bp.halt(); } else cpu_pic->mExecute2ndHalf->firstHalf( value + 2); } //-------------------------------------------------- // start_skip - The next instruction is going to be skipped // void Program_Counter::start_skip() { } //-------------------------------------------------- // set - The next instruction is at an arbitrary location. This method is used // by the command line parser--the GUI uses put_value directly. // void Program_Counter::set(Value *v) { int i; v->get(i); //printf ( "Assign %d to PC\n", i ); put_value ( i ); } void Program_Counter::get(char *buffer, int buf_size) { if (buffer) snprintf(buffer, buf_size, "%d (0x%x)", value, value); } //======================================================================== phaseExecute2ndHalf::phaseExecute2ndHalf(Processor *pcpu) : ProcessorPhase(pcpu), m_uiPC(0) { } phaseExecute2ndHalf::~phaseExecute2ndHalf() { } ClockPhase *phaseExecute2ndHalf::firstHalf(unsigned int uiPC) { Dprintf(("first half of 2 cycle instruction new PC=0x%x\n",uiPC)); ((pic_processor *)m_pcpu)->pc->value = uiPC; ((pic_processor *)m_pcpu)->pc->update_pcl(); m_pcpu->mCurrentPhase->setNextPhase(this); return this; } ClockPhase *phaseExecute2ndHalf::advance() { Dprintf(("second half of 2 cycle instruction\n")); m_pcpu->mCurrentPhase->setNextPhase(m_pcpu->mExecute1Cycle); get_cycles().increment(); return m_pNextPhase; } //-------------------------------------------------- // jump - update the program counter. All branching instructions except computed gotos // and returns go through here. void Program_Counter::jump(unsigned int new_address) { Dprintf(("PC=0x%x new 0x%x\n",value,new_address)); // Trace the value of the program counter before it gets changed. trace.raw(trace_branch | value); // Use the new_address and the cached pclath (or page select bits for 12 bit cores) // to generate the destination address: // see Update pcl comment in Program_Counter::increment() if (new_address >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, new_address, memory_size); bp.halt(); } else cpu_pic->mExecute2ndHalf->firstHalf(new_address); } //-------------------------------------------------- // interrupt - update the program counter. Like a jump, except pclath is ignored. // void Program_Counter::interrupt(unsigned int new_address) { Dprintf(("PC=0x%x 0x%x\n",value,new_address)); // Trace the value of the program counter before it gets changed. trace.raw(trace_branch | value); if (new_address >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, new_address, memory_size); bp.halt(); } else cpu_pic->mExecute2ndHalf->firstHalf(new_address); } //-------------------------------------------------- // computed_goto - update the program counter. Anytime the pcl register is written to // by the source code we'll pass through here. // void Program_Counter::computed_goto(unsigned int new_address) { Dprintf(("PC=0x%x new=0x%x\n",value,new_address)); // Trace the value of the program counter before it gets changed. trace.raw(trace_other | value); // Use the new_address and the cached pclath (or page select bits for 12 bit cores) // to generate the destination address: value = new_address | cpu_pic->get_pclath_branching_modpcl() ; if (value >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, value, memory_size); bp.halt(); } // Update PCL. As this is different for 12/14 and 16 bit devices // this will get handled by a method on its own so it is possible // to cope with different mappings PC-->PCL (direct, <<1, etc.) update_pcl(); // The instruction modifying the PCL will also increment the program counter. // So, pre-compensate the increment with a decrement: value--; // The computed goto is a 2-cycle operation. The first cycle occurs within // the instruction (i.e. via the ::increment() method). The second cycle occurs // here: cpu_pic->mExecute2ndHalf->advance(); } //-------------------------------------------------- // new_address - write a new value to the program counter. All returns pass through here. // void Program_Counter::new_address(unsigned int new_address) { Dprintf(("PC=0x%x new 0x%x\n",value, new_address&0xffff)); // Trace the value of the program counter before it gets changed. trace.raw(trace_branch | value); if (new_address >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, new_address, memory_size); bp.halt(); } else cpu_pic->mExecute2ndHalf->firstHalf(new_address); } //-------------------------------------------------- // get_next - get the next address that is just pass the current one // (used by 'call' to obtain the return address) unsigned int Program_Counter::get_next() { unsigned int new_address = value + cpu_pic->program_memory[value]->instruction_size(); if (new_address >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, new_address, memory_size); bp.halt(); } return( new_address); } //-------------------------------------------------- // put_value - Change the program counter without affecting the cycle counter // (This is what's called if the user changes the pc.) void Program_Counter::put_value(unsigned int new_value) { // FIXME #define PCLATH_MASK 0x1f Dprintf(("PC=0x%x new 0x%x\n",value, new_value&0xffff)); trace.raw(trace_other | value); if (new_value >= memory_size) { printf("%s PC=0x%x >= memory size 0x%x\n", __FUNCTION__, new_value, memory_size); bp.halt(); } value = new_value; cpu_pic->pcl->value.put(value & 0xff); cpu_pic->pclath->value.put((new_value >> 8) & PCLATH_MASK); cpu_pic->pcl->update(); cpu_pic->pclath->update(); update(); } void Program_Counter::reset() { //trace.program_counter(value); //FIXME value = reset_address; value = (value >= memory_size) ? value - memory_size : value; cpu_pic->mExecute2ndHalf->firstHalf(value); } //======================================================================== // // Helper registers // PCHelper::PCHelper(Processor *pCpu,ProgramMemoryAccess *new_pma) : Register(pCpu, "PC", "Program Counter"), pma(new_pma) { assert(pma); } void PCHelper::put_value(unsigned int new_value) { // if(pma) pma->set_PC(new_value); } unsigned int PCHelper::get_value() { // if(pma) return pma->get_PC(); //return 0; } //-------------------------------------------------- // member functions for the OPTION base class //-------------------------------------------------- OPTION_REG::OPTION_REG(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { por_value = RegisterValue(0xff,0); wdtr_value = RegisterValue(0xff,0); // The chip reset will place the proper value here. value = RegisterValue(0,0); // por_value; } // make sure intial por_value does it's stuff void OPTION_REG::initialize() { cpu_pic->tmr0.new_prescale(); cpu_pic->wdt.set_postscale( (value.get() & PSA) ? (value.get() & ( PS2 | PS1 | PS0 )) : 0); cpu_pic->option_new_bits_6_7(value.get() & (T0CS | BIT6 | BIT7)); } void OPTION_REG::put(unsigned int new_value) { //FIXME trace OPTION for 12bit processors is broken. trace.raw(write_trace.get() | value.get()); unsigned int old_value = value.get(); value.put(new_value); // First, check the tmr0 clock source bit to see if we are changing from // internal to external (or vice versa) clocks. //if( (value ^ old_value) & T0CS) // cpu_pic->tmr0.new_clock_source(); // %%%FIX ME%%% - can changing the state of TOSE cause the timer to // increment if tmr0 is being clocked by an external clock? // Now check the rest of the tmr0 bits. if( (value.get() ^ old_value) & (T0CS | T0SE | PSA | PS2 | PS1 | PS0)) cpu_pic->tmr0.new_prescale(); if( (value.get() ^ old_value) & (PSA | PS2 | PS1 | PS0)) cpu_pic->wdt.set_postscale( (value.get() & PSA) ? (value.get() & ( PS2 | PS1 | PS0 )) : 0); if( (value.get() ^ old_value) & (T0CS | BIT6 | BIT7)) cpu_pic->option_new_bits_6_7(value.get() & (T0CS | BIT6 | BIT7)); } void OPTION_REG::reset(RESET_TYPE r) { putRV(por_value); } // On 14bit enhanced cores the prescaler does not affect the watchdog OPTION_REG_2::OPTION_REG_2(Processor *pCpu, const char *pName, const char *pDesc) : OPTION_REG(pCpu, pName, pDesc) { } void OPTION_REG_2::initialize() { cpu_pic->tmr0.new_prescale(); cpu_pic->option_new_bits_6_7(value.get() & (T0CS | BIT6 | BIT7)); } void OPTION_REG_2::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); unsigned int old_value = value.get(); value.put(new_value); // First, check the tmr0 clock source bit to see if we are changing from // internal to external (or vice versa) clocks. //if( (value ^ old_value) & T0CS) // cpu_pic->tmr0.new_clock_source(); // %%%FIX ME%%% - can changing the state of TOSE cause the timer to // increment if tmr0 is being clocked by an external clock? // Now check the rest of the tmr0 bits. if( (value.get() ^ old_value) & (T0CS | T0SE | PSA | PS2 | PS1 | PS0)) cpu_pic->tmr0.new_prescale(); if( (value.get() ^ old_value) & (T0CS | BIT6 | BIT7)) cpu_pic->option_new_bits_6_7(value.get() & (T0CS | BIT6 | BIT7)); } gpsim-0.30.0/src/14bit-instructions.h0000664000076400007640000002120413047736577014313 00000000000000/* Copyright (C) 1998 T. Scott Dattalo 2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ class instruction; // forward declaration for the include files that follow #ifndef __14BIT_INSTRUCTIONS_H__ #define __14BIT_INSTRUCTIONS_H__ #define REG_IN_INSTRUCTION_MASK 0x7f #define DESTINATION_MASK 0x80 #include "pic-instructions.h" #include "12bit-instructions.h" #include "14bit-registers.h" //--------------------------------------------------------- class ADDFSR : public instruction { public: ADDFSR(Processor *new_cpu, unsigned int new_opcode,const char *, unsigned int address); virtual bool isBase() { return true;} virtual void execute(); virtual char *name(char *,int); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) { return new ADDFSR(new_cpu,new_opcode,"addfsr", address); } protected: unsigned int m_fsr; int m_lit; Indirect_Addressing14 *ia; }; //--------------------------------------------------------- class ADDLW : public Literal_op { public: ADDLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(void); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ADDLW(new_cpu,new_opcode, address);} }; //--------------------------------------------------------- class ADDWFC : public Register_op { public: ADDWFC(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ADDWFC(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BRA : public instruction { public: int destination_index; unsigned int absolute_destination_index; BRA(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BRA(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BRW : public instruction { public: int destination_index; unsigned int current_address; BRW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BRW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ASRF : public Register_op { public: ASRF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ASRF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CALLW : public instruction { public: CALLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual bool isBase() { return true;} virtual void execute(); virtual char *name(char *,int); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) { return new CALLW(new_cpu,new_opcode,address); } }; //--------------------------------------------------------- class LSLF : public Register_op { public: LSLF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new LSLF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class LSRF : public Register_op { public: LSRF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new LSRF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVIW : public instruction { public: MOVIW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVIW(new_cpu,new_opcode,address);} virtual char *name(char *,int); enum { PREINC, PREDEC, POSTINC, POSTDEC, DELTA }; protected: unsigned int m_fsr; int m_lit; unsigned int m_op; Indirect_Addressing14 *ia; }; //--------------------------------------------------------- class MOVWI : public instruction { public: MOVWI(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVWI(new_cpu,new_opcode,address);} virtual char *name(char *,int); enum { PREINC, PREDEC, POSTINC, POSTDEC, DELTA }; protected: unsigned int m_fsr; int m_lit; unsigned int m_op; Indirect_Addressing14 *ia; }; //--------------------------------------------------------- class MOVLB : public Literal_op { public: MOVLB(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *return_str,int len); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVLB(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVLP : public Literal_op { public: MOVLP(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *return_str,int len); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVLP(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RESET : public instruction { public: RESET(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RESET(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RETFIE : public instruction { public: RETFIE(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(void); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RETFIE(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RETURN : public instruction { public: RETURN(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(void); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RETURN(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBLW : public Literal_op { public: SUBLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(void); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBWFB : public Register_op { public: SUBWFB(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBWFB(new_cpu,new_opcode,address);} }; #endif // __14BIT_INSTRUCTIONS_H__ gpsim-0.30.0/src/pic-registers.h0000664000076400007640000000510313041763624013371 00000000000000 /* Copyright (C) 1998-2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PIC_REGISTERS_H__ #define __PIC_REGISTERS_H__ #include "gpsim_classes.h" #include "registers.h" #include "breakpoints.h" //------------------------------------------------------------------------ // // PCHelper // // The purpose of this class is to provide a register wrapper around the // program counter. On the low and mid range pics, the program counter spans // two registers. On the high end ones it spans 3. This class allows the // gui to treat the program counter as though if it's a single register. class PCHelper : public Register { public: PCHelper(Processor *pCpu, ProgramMemoryAccess *); virtual void put_value(unsigned int new_value); virtual unsigned int get_value(); virtual unsigned int register_size () const { return 2; } ProgramMemoryAccess *pma; }; //--------------------------------------------------------- // OPTION_REG - class OPTION_REG : public sfr_register { public: enum { PS0 = 1<<0, PS1 = 1<<1, PS2 = 1<<2, PSA = 1<<3, T0SE = 1<<4, T0CS = 1<<5, BIT6 = 1<<6, BIT7 = 1<<7 }; unsigned int prescale; OPTION_REG(Processor *pCpu, const char *pName, const char *pDesc=0); inline unsigned int get_prescale() { return value.get() & (PS0 | PS1 | PS2); } inline unsigned int get_psa() { return value.get() & PSA; } inline unsigned int get_t0cs() { return value.get() & T0CS; } inline unsigned int get_t0se() { return value.get() & T0SE; } virtual void put(unsigned int new_value); virtual void reset(RESET_TYPE r); virtual void initialize(); }; // For use on 14bit enhanced cores class OPTION_REG_2 : public OPTION_REG { public: OPTION_REG_2(Processor *pCpu, const char *pName, const char *pDesc=0); virtual void put(unsigned int new_value); virtual void initialize(); }; #endif gpsim-0.30.0/src/protocol.h0000664000076400007640000001006413041763624012454 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // protocol.h // #include #ifndef __PROTCOL_H__ #define __PROTCOL_H__ #ifdef putc #undef putc #endif /// gpsim protocol /// /// gpsim's protocol interface is designed to provide a way for clients /// that are not linked with gpsim to interface with gpsim. /// Basic types /// These are the fundamental types the protocol interface /// supports. enum eGPSIMObjectTypes { eGPSIM_TYPE_CHAR = 1, eGPSIM_TYPE_STRING, eGPSIM_TYPE_UINT32, eGPSIM_TYPE_UCHAR, eGPSIM_TYPE_BOOLEAN, eGPSIM_TYPE_INT32, eGPSIM_TYPE_INT64, eGPSIM_TYPE_UINT64, eGPSIM_TYPE_FLOAT, eGPSIM_TYPE_DOUBLE, eGPSIM_TYPE_OBJECT, eGPSIM_TYPE_CUSTOM, }; /// Socket Commands /// FIXME - document how these are used. /// enum eGPSIMSocketCommands { GPSIM_CMD_CREATE_NOTIFY_LINK = 0xE0, GPSIM_CMD_CREATE_CALLBACK_LINK = 0xE1, GPSIM_CMD_CREATE_SOCKET_LINK = 0xF0, GPSIM_CMD_REMOVE_SOCKET_LINK = 0xF1, GPSIM_CMD_QUERY_SOCKET_LINK = 0xF2, GPSIM_CMD_WRITE_TO_SOCKET_LINK = 0xF3, GPSIM_CMD_QUERY_SYMBOL = 0xF4, GPSIM_CMD_WRITE_TO_SYMBOL = 0xF5, GPSIM_CMD_RUN = 0xF6, GPSIM_CMD_RESET = 0xF7, }; /// PacketBuffer /// A packet buffer is an area of memory that gpsim and a client /// use to exchange information. The buffer consists of a sequence /// encoded GPSIMObjectTypes. Member functions for encoding and /// decoding each type. class PacketBuffer { public: PacketBuffer(unsigned int _size); ~PacketBuffer(); char * getBuffer() { return &buffer[index]; } unsigned int getSize() { return size-index; } void terminate(); void putc(char c) { if(index < size) buffer[index++] = c; } void putAt(int pos, char c) { if(pos >=0 && pos < (int) size) buffer[pos] = c; } void puts(const char *, int); /// advanceIndex() will move the index pointer forward void advanceIndex(unsigned int amount); bool bHasData() { return index!=0; } //private: char *buffer; unsigned int index; unsigned int size; }; class Packet { public: Packet(unsigned int rxsize, unsigned int txsize); bool DecodeHeader(); bool DecodeObjectType(unsigned int &); bool DecodeChar(char); bool DecodeUInt32(unsigned int &); bool DecodeUInt64(guint64 &); bool DecodeString(char *, int); bool DecodeBool(bool &); bool DecodeFloat(double &); bool EncodeHeader(); bool EncodeUInt32(unsigned int); bool EncodeUInt64(guint64); bool EncodeObjectType(unsigned int); bool EncodeString(const char *str, int len=-1); bool EncodeCustom(const char *str, int len); bool EncodeBool(bool); bool EncodeFloat(double); char *rxBuff() { return rxBuffer->getBuffer(); } unsigned int rxSize() { return rxBuffer->getSize(); } void rxTerminate(int pos) { rxBuffer->putAt(pos,0); } void rxAdvance(unsigned int amount) { rxBuffer->advanceIndex(amount); } bool brxHasData() { return rxBuffer->bHasData(); } char *txBuff() { return txBuffer->buffer; } unsigned int txBytesBuffered() { return txBuffer->index; } void txTerminate() { txBuffer->terminate(); } void prepare() { rxBuffer->index = 0; txBuffer->index = 0; } private: PacketBuffer *rxBuffer; PacketBuffer *txBuffer; }; #endif gpsim-0.30.0/src/dsm_module.h0000664000076400007640000000755513041763624012756 00000000000000#ifndef __DSM_MODULE_H__ #define __DSM_MODULE_H__ #include "pic-processor.h" #include "14bit-registers.h" #include "uart.h" #include "ssp.h" class _MDCON; class _MDSRC; class _MDCARH; class _MDCARL; class DSM_MODULE; class minSink; class carhSink; class carlSink; class MDoutSignalSource; //_MDCON: MODULATION CONTROL REGISTER class _MDCON : public sfr_register { public: _MDCON(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *); virtual void put(unsigned int); virtual void put_value(unsigned int); unsigned int mask; private: DSM_MODULE *mDSM; }; // MODULATION SOURCE CONTROL REGISTER class _MDSRC : public sfr_register { public: _MDSRC(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *); virtual void put(unsigned int); virtual void put_value(unsigned int); unsigned int mask; private: DSM_MODULE *mDSM; }; // _MDCARH: MODULATION HIGH CARRIER CONTROL REGISTER class _MDCARH : public sfr_register { public: _MDCARH(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *); virtual void put(unsigned int); virtual void put_value(unsigned int); unsigned int mask; private: DSM_MODULE *mDSM; }; // _MDCARL: MODULATION LOW CARRIER CONTROL REGISTER class _MDCARL : public sfr_register { public: _MDCARL(Processor *pCpu, const char *pName, const char *pDesc, DSM_MODULE *); virtual void put(unsigned int); virtual void put_value(unsigned int); unsigned int mask; private: DSM_MODULE *mDSM; }; class DSM_MODULE { public: enum { MDBIT = 1<<0, // Allows software to manually set modulation source input to module MDOUT = 1<<3, // Modulator Output bit (read only) MDOPOL = 1<<4, // Modulator Output Polarity Select bit MDSLR = 1<<5, // MDOUT Pin Slew Rate Limiting bit MDOE = 1<<6, // Modulator Module Pin Output Enable bit MDEN = 1<<7, // Modulator Module Enable bit MDCHSYNC = 1<<5, // Modulator High Carrier Synchronization Enable bit MDCHPOL = 1<<6, // Modulator High Carrier Polarity Select bit MDCHODIS = 1<<7, //Modulator High Carrier Output Disable bit MDCLSYNC = 1<<5, // Modulator Low Carrier Synchronization Enable bit MDCLPOL = 1<<6, // Modulator Low Carrier Polarity Select bit MDCLODIS = 1<<7, //Modulator Low Carrier Output Disable bit MDMSODIS = 1<<7, // Modulation Source Output Disable bit }; DSM_MODULE(Processor *pCpu); ~DSM_MODULE(); _MDCON mdcon; _MDSRC mdsrc; _MDCARH mdcarh; _MDCARL mdcarl; virtual void setOUTpin(PinModule *pm) {m_mdout = pm;} virtual void setMINpin(PinModule *pm) {m_mdmin = pm;} virtual void setCIN1pin(PinModule *pm) {m_mdcin1 = pm;} virtual void setCIN2pin(PinModule *pm) {m_mdcin2 = pm;} virtual void rmModSrc(unsigned int); virtual void setModSrc(unsigned int, unsigned int); virtual void minEdge(char new3State); virtual void carhEdge(char new3State); virtual void carlEdge(char new3State); virtual void releaseMDout(); void new_mdcon(unsigned int, unsigned int); void new_mdsrc(unsigned int, unsigned int); void new_mdcarh(unsigned int, unsigned int); void new_mdcarl(unsigned int, unsigned int); void dsm_logic(bool carl_neg_edge, bool carh_new_edge); void putMDout(bool); PinModule *m_mdout; PinModule *m_mdmin; minSink *m_minSink; PinModule *m_mdcin1; int cin1Sink_cnt; carlSink *m_carlSink; PinModule *m_mdcin2; carhSink *m_carhSink; MDoutSignalSource *out_source; char mdout; USART_MODULE *usart_mod; SSP1_MODULE *ssp_mod1; SSP1_MODULE *ssp_mod2; private: bool mdmin_state; //value of min bool mdcarl_state; //value of carl bool mdcarh_state; //value of carh bool dflipflopH; bool dflipflopL; PinModule *dsmSrc_pin; IOPIN *monitor_pin; PinModule *monitor_mod; }; #endif gpsim-0.30.0/src/spp.cc0000664000076400007640000003112613041763613011553 00000000000000/* Copyright (C) 2014 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include "../config.h" #include "stimuli.h" #include "spp.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif /* * Streaming Parallel Port */ //-------------------------------------------------- // //-------------------------------------------------- class SppSignalSource : public SignalControl { public: SppSignalSource() { state = '?'; } ~SppSignalSource() { } virtual char getState() { return state; } void setState(char _state){ state = _state;} virtual void release() { delete this; } private: char state; }; //-------------------------------------------------- // //-------------------------------------------------- SPPCON::SPPCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } void SPPCON::put(unsigned int new_value) { unsigned int mask = (SPP::SPPOWN | SPP::SPPEN ); unsigned int old = value.data; trace.raw(write_trace.get() | value.data); value.data = (new_value & mask); if ((old ^ value.data) && value.data == mask) cout << "Warning USB functionality of SPP not supported\n"; else spp->enabled(value.data & SPP::SPPEN); } void SPPCON::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; } SPPCFG::SPPCFG(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } void SPPCFG::put(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; if (spp) spp->cfg_write(value.data); } void SPPCFG::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; } SPPEPS::SPPEPS(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } void SPPEPS::put(unsigned int new_value) { unsigned int mask = 0x0f; unsigned int fixed = value.data & 0xd0; // Read only part of register trace.raw(write_trace.get() | value.data); value.data = ((new_value & mask) | fixed); if (verbose) printf("SPPEPS::put new %x fixed %x set %x\n", new_value, fixed, value.data); if (spp) spp->eps_write(value.data); } void SPPEPS::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; if (spp) spp->eps_write(new_value); } SPPDATA::SPPDATA(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { spp = 0; } void SPPDATA::put(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; if (spp) spp->data_write(new_value); } void SPPDATA::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.data); value.data = new_value; } unsigned int SPPDATA::get() { value.data = spp->data_read(); return(value.data); } void SPP::initialize( PIR_SET *_pir_set, PicPSP_PortRegister *_port_set, PicTrisRegister *_port_tris, SPPCON *_sppcon, SPPCFG *_sppcfg, SPPEPS *_sppeps, SPPDATA *_sppdata, PinModule *_clk1spp, PinModule *_clk2spp, PinModule *_oespp, PinModule *_csspp ) { if (verbose & 2) cout << "SPP::initialize called\n"; pir_set = _pir_set; parallel_port = _port_set; parallel_tris = _port_tris; sppcon = _sppcon; sppcfg = _sppcfg; sppeps = _sppeps; sppdata= _sppdata; sppdata->set_spp(this); sppeps->set_spp(this); sppcfg->set_spp(this); sppcon->set_spp(this); pin_clk1spp = _clk1spp; pin_clk2spp = _clk2spp; pin_oespp = _oespp; pin_csspp = _csspp; } SPP::~SPP() { if (verbose) cout << "SPP::~SPP\n"; if (active_sig_oe) pin_oespp->setSource(0); if (active_sig_cs) pin_csspp->setSource(0); if (active_sig_clk2) pin_clk2spp->setSource(0); if (active_sig_clk1) pin_clk1spp->setSource(0); if (sig_oespp) delete sig_oespp; if (sig_csspp) delete sig_csspp; if (sig_clk2spp) delete sig_clk2spp; if (sig_clk1spp) delete sig_clk1spp; } // SSPDATA register has been written to void SPP::data_write(unsigned int data) { if((sppcon->get_value() & SPPEN) == 0) return; if (verbose) cout << "SPP::data_write data=0x" << hex << data << endl; parallel_tris->put(0); // set port for write data_value = data; parallel_port->put_value(data); eps_value |= SPPBUSY; sppeps->put_value(eps_value); cycle_state = ST_CYCLE1; io_operation = DATA_WRITE; sig_oespp->setState('0'); pin_oespp->updatePinModule(); if (cfg_value & CSEN) { sig_csspp->setState('1'); pin_csspp->updatePinModule(); } get_cycles().set_break(get_cycles().get() + (cfg_value & 0x0f) + 1 , this); } // SPPEPS register has been written to void SPP::eps_write(unsigned int data) { unsigned int old = eps_value; eps_value = data; if((sppcon->get_value() & SPPEN) == 0 || !(old ^ eps_value)) return; if (verbose) cout << "SPP::eps_write data=0x" << hex << data << endl; parallel_tris->put(0); // set port for write parallel_port->put_value(data & 0x0f); eps_value |= SPPBUSY; sppeps->put_value(eps_value); cycle_state = ST_CYCLE1; io_operation = ADDR_WRITE; sig_oespp->setState('0'); pin_oespp->updatePinModule(); if (cfg_value & CSEN) { sig_csspp->setState('1'); pin_csspp->updatePinModule(); } get_cycles().set_break(get_cycles().get() + (cfg_value & 0x0f) + 1 , this); } // SPPCFG register has been written to void SPP::cfg_write(unsigned int data) { unsigned int diff = cfg_value ^ data; cfg_value = data; if((sppcon->get_value() & SPPEN) == 0) return; if (diff & CLK1EN) // CLK1EN state change { if (cfg_value & CLK1EN) { pin_clk1spp->getPin().newGUIname("CK1SPP"); if (!sig_clk1spp) sig_clk1spp = new SppSignalSource(); pin_clk1spp->setSource(sig_clk1spp); active_sig_clk1 = true; sig_clk1spp->setState('0'); pin_clk1spp->updatePinModule(); } else { pin_clk1spp->setSource(0); active_sig_clk1 = false; pin_clk1spp->getPin().newGUIname( pin_clk1spp->getPin().name().c_str()); } } if (diff & CSEN) // CSEN state change { if (cfg_value & CSEN) { pin_csspp->getPin().newGUIname("CSSPP"); if (!sig_csspp) sig_csspp = new SppSignalSource(); pin_csspp->setSource(sig_csspp); active_sig_cs = true; sig_csspp->setState('0'); pin_csspp->updatePinModule(); } else { active_sig_cs = false; pin_csspp->setSource(0); pin_csspp->getPin().newGUIname( pin_csspp->getPin().name().c_str()); } } } // SPPDATA register has been read from unsigned int SPP::data_read() { if((sppcon->get_value() & SPPEN) == 0) return(0); if (verbose) cout << "SPP::data_read\n"; parallel_tris->put(0xff); // set port for read eps_value |= SPPBUSY; sppeps->put_value(eps_value); cycle_state = ST_CYCLE1; io_operation = DATA_READ; sig_oespp->setState('1'); pin_oespp->updatePinModule(); if (cfg_value & CSEN) { sig_csspp->setState('1'); pin_csspp->updatePinModule(); } get_cycles().set_break(get_cycles().get() + (cfg_value & 0x0f) + 1 , this); return data_value; } void SPP::enabled(bool _enabled) { if (state_enabled ^ _enabled) { if (verbose) cout << "SPP::enabled state " << _enabled << endl; state_enabled = _enabled; if (state_enabled) { (parallel_port->getPin(0))->newGUIname("SPP0"); (parallel_port->getPin(1))->newGUIname("SPP1"); (parallel_port->getPin(2))->newGUIname("SPP2"); (parallel_port->getPin(3))->newGUIname("SPP3"); (parallel_port->getPin(4))->newGUIname("SPP4"); (parallel_port->getPin(5))->newGUIname("SPP5"); (parallel_port->getPin(6))->newGUIname("SPP6"); (parallel_port->getPin(7))->newGUIname("SPP7"); pin_oespp->getPin().newGUIname("OESPP"); if (!sig_oespp) sig_oespp = new SppSignalSource(); pin_oespp->setSource(sig_oespp); active_sig_oe = true; sig_oespp->setState('1'); pin_oespp->updatePinModule(); pin_clk2spp->getPin().newGUIname("CK2SPP"); if (!sig_clk2spp) sig_clk2spp = new SppSignalSource(); pin_clk2spp->setSource(sig_clk2spp); active_sig_clk2 = true; sig_clk2spp->setState('0'); pin_clk2spp->updatePinModule(); if (cfg_value & CLK1EN) { pin_clk1spp->getPin().newGUIname("CK1SPP"); if (!sig_clk1spp) sig_clk1spp = new SppSignalSource(); pin_clk1spp->setSource(sig_clk1spp); active_sig_clk1 = true; sig_clk1spp->setState('0'); pin_clk1spp->updatePinModule(); } if (cfg_value & CSEN) { pin_csspp->getPin().newGUIname("CSSPP"); if (!sig_csspp) sig_csspp = new SppSignalSource(); pin_csspp->setSource(sig_csspp); active_sig_cs = true; sig_csspp->setState('0'); pin_csspp->updatePinModule(); } cycle_state = ST_IDLE; } else { for(int i = 0; i < 8; i++) { (parallel_port->getPin(i))->newGUIname( (parallel_port->getPin(i))->name().c_str()); } pin_oespp->getPin().newGUIname(pin_oespp->getPin().name().c_str()); if (active_sig_oe) { pin_oespp->setSource(0); active_sig_oe = false; } pin_clk2spp->getPin().newGUIname( pin_clk2spp->getPin().name().c_str()); if (active_sig_clk2) { pin_clk2spp->setSource(0); active_sig_clk2 = false; } if (cfg_value & CLK1EN) { pin_clk1spp->getPin().newGUIname( pin_clk1spp->getPin().name().c_str()); } if (active_sig_clk1) { pin_clk1spp->setSource(0); active_sig_clk1 = false; } if (cfg_value & CSEN) { pin_csspp->getPin().newGUIname( pin_csspp->getPin().name().c_str()); } if (active_sig_cs) { pin_csspp->setSource(0); active_sig_cs = false; } } } } void SPP::callback() { if (verbose & 2) cout << "callback state " << cycle_state << " IO operation " << io_operation << endl; switch(cycle_state) { case ST_CYCLE1: cycle_state = ST_CYCLE2; if(io_operation == DATA_READ) data_value = parallel_port->get(); switch ((cfg_value & (CLKCFG1|CLKCFG0)) >> 6) { case 3: case 2: if (eps_value & ADDR0) // odd address { if (cfg_value & CLK1EN) { sig_clk1spp->setState('1'); pin_clk1spp->updatePinModule(); } } else { sig_clk2spp->setState('1'); pin_clk2spp->updatePinModule(); } break; case 1: if (io_operation == ADDR_WRITE || io_operation == DATA_WRITE) { if (cfg_value & CLK1EN) { sig_clk1spp->setState('1'); pin_clk1spp->updatePinModule(); } } else if (io_operation == DATA_READ) { sig_clk2spp->setState('1'); pin_clk2spp->updatePinModule(); } break; case 0: if ((cfg_value & CLK1EN) && io_operation == ADDR_WRITE) { sig_clk1spp->setState('1'); pin_clk1spp->updatePinModule(); } if (io_operation == DATA_WRITE || io_operation == DATA_READ) { sig_clk2spp->setState('1'); pin_clk2spp->updatePinModule(); } break; } get_cycles().set_break(get_cycles().get() + (cfg_value & 0x0f) + 1 , this); break; case ST_CYCLE2: cycle_state = ST_IDLE; eps_value &= ~SPPBUSY; sppeps->put_value(eps_value); sig_oespp->setState('1'); pin_oespp->updatePinModule(); sig_clk2spp->setState('0'); pin_clk2spp->updatePinModule(); if (cfg_value & CSEN) { sig_csspp->setState('0'); pin_csspp->updatePinModule(); } if (cfg_value & CLK1EN) { sig_clk1spp->setState('0'); pin_clk1spp->updatePinModule(); } if (!(sppcon->get_value() & SPPOWN)) pir_set->set_sppif(); break; case ST_IDLE: default: printf("SPP::callback unexpected callback state=%d\n", cycle_state); break; } } gpsim-0.30.0/src/16bit-processors.h0000664000076400007640000002232713043351757013747 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __16_BIT_PROCESSORS_H__ #define __16_BIT_PROCESSORS_H__ #include "pic-processor.h" #include "pic-ioports.h" #include "intcon.h" #include "16bit-registers.h" #include "16bit-tmrs.h" #include "pir.h" #include "uart.h" #include "a2dconverter.h" #include "a2d_v2.h" #include "value.h" // forward references extern instruction *disasm16 (pic_processor *cpu, unsigned int address, unsigned int inst); class ConfigMemory; //------------------------------------------------------------------------ // // pic_processor // | // \__ _16bit_processor // // Base class for the 16bit PIC processors // class _16bit_processor : public pic_processor { public: static const unsigned int CONFIG1L = 0x300000; static const unsigned int CONFIG1H = 0x300001; static const unsigned int CONFIG2L = 0x300002; static const unsigned int CONFIG2H = 0x300003; static const unsigned int CONFIG3L = 0x300004; static const unsigned int CONFIG3H = 0x300005; static const unsigned int CONFIG4L = 0x300006; static const unsigned int CONFIG4H = 0x300007; static const unsigned int CONFIG5L = 0x300008; static const unsigned int CONFIG5H = 0x300009; static const unsigned int CONFIG6L = 0x30000A; static const unsigned int CONFIG6H = 0x30000B; static const unsigned int CONFIG7L = 0x30000C; static const unsigned int CONFIG7H = 0x30000D; // The early 18xxx parts all contain ports A,B,C PicPortRegister *m_porta; PicTrisRegister *m_trisa; PicLatchRegister *m_lata; PicPortBRegister *m_portb; PicTrisRegister *m_trisb; PicLatchRegister *m_latb; PicPortRegister *m_portc; PicTrisRegister *m_trisc; PicLatchRegister *m_latc; sfr_register adresl; sfr_register adresh; INTCON_16 intcon; INTCON2 intcon2; INTCON3 intcon3; BSR bsr; TMR0_16 tmr0l; TMR0H tmr0h; T0CON t0con; RCON rcon; PIR1v2 pir1; sfr_register ipr1; sfr_register ipr2; T1CON *t1con; PIE pie1; PIR2v2 *pir2; PIE pie2; T2CON t2con; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; CCPCON ccp2con; CCPRL ccpr2l; CCPRH ccpr2h; TMRL tmr3l; TMRH tmr3h; T3CON *t3con; PIR_SET_2 pir_set_def; OSCCON *osccon; LVDCON lvdcon; WDTCON wdtcon; sfr_register prodh,prodl; sfr_register pclatu; Fast_Stack fast_stack; Indirect_Addressing ind0; Indirect_Addressing ind1; Indirect_Addressing ind2; USART_MODULE usart; //Stack16 stack16; TBL_MODULE tbl; TMR2_MODULE tmr2_module; TMR3_MODULE tmr3_module; SSP_MODULE ssp; // Some configuration stuff for stripping down where needed virtual bool HasPortC(void) { return true; }; virtual bool HasCCP2(void) { return true; }; virtual bool MovedReg() { return false;} virtual bool T3HasCCP() { return true;} virtual OSCCON * getOSCCON(void) { return new OSCCON(this, "osccon", "OSC Control"); } virtual void create_symbols(); void interrupt(); virtual void create();// {return;}; virtual PROCESSOR_TYPE isa(){return _PIC17_PROCESSOR_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC17_PROCESSOR_;}; virtual unsigned int access_gprs() { return 0x80; }; virtual instruction * disasm (unsigned int address, unsigned int inst) { return disasm16(this, address, inst); } virtual void create_sfr_map(); virtual void delete_sfr_map(); virtual void create_config_memory(); // Return the portion of pclath that is used during branching instructions virtual unsigned int get_pclath_branching_jump() { return ((pclatu.value.get()<<16) | ((pclath->value.get() & 0xf8)<<8)); } // Return the portion of pclath that is used during modify PCL instructions virtual unsigned int get_pclath_branching_modpcl() { return ((pclatu.value.get()<<16) | ((pclath->value.get() & 0xff)<<8)); } virtual void option_new_bits_6_7(unsigned int); // Declare a set of functions that will allow the base class to // get information about the derived classes. NOTE, the values returned here // will cause errors if they are used (in some cases) // -- the derived classes must define their parameters appropriately. virtual unsigned int register_memory_size () const { return 0x1000;}; virtual unsigned int last_actual_register () const { return 0x0F7F;}; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create_iopin_map(); virtual int map_pm_address2index(int address) const {return address/2;}; virtual int map_pm_index2address(int index) const {return index*2;}; virtual unsigned int get_program_memory_at_address(unsigned int address); virtual unsigned int get_config_word(unsigned int address); virtual unsigned int get_device_id() { return 0;} virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual unsigned int configMemorySize() { return CONFIG7H-CONFIG1L+1; } virtual unsigned int IdentMemorySize() const { return 4; } // four words default (18F) virtual void enter_sleep(); virtual void exit_sleep(); virtual void osc_mode(unsigned int ); virtual void set_extended_instruction(bool); virtual bool extended_instruction() {return extended_instruction_flag;} static pic_processor *construct(); _16bit_processor(const char *_name=0, const char *desc=0); virtual ~_16bit_processor(); unsigned int getCurrentDisasmAddress() { return m_current_disasm_address;} unsigned int getCurrentDisasmIndex() { return m_current_disasm_address/2;} void setCurrentDisasmAddress(unsigned a) { m_current_disasm_address =a; } virtual void init_pir2(PIR *pir2, unsigned int bitMask); protected: unsigned int m_current_disasm_address; // Used only when .hex/.cod files are loaded unsigned int idloc[4]; ///< ID locations - not all 16-bit CPUs have 8 bytes bool extended_instruction_flag; // Instruction set extension and Indexed Addressing unsigned int last_register; }; class _16bit_compat_adc : public _16bit_processor { public: ADCON0 *adcon0; ADCON1 *adcon1; _16bit_compat_adc(const char *_name=0, const char *desc=0); ~_16bit_compat_adc(); virtual void create_symbols(); virtual void create(); virtual void create_sfr_map(); virtual void a2d_compat(); }; class _16bit_v2_adc : public _16bit_processor { public: ADCON0_V2 *adcon0; ADCON1_V2 *adcon1; ADCON2_V2 *adcon2; _16bit_v2_adc(const char *_name=0, const char *desc=0); ~_16bit_v2_adc(); virtual void create(int nChannels); }; #define cpu16 ( (_16bit_processor *)cpu) #define FOSC0 (1<<0) #define FOSC1 (1<<1) #define FOSC2 (1<<2) // FOSC3 may not be used #define FOSC3 (1<<3) #define PLLCFG (1<<4) #define OSCEN (1<<5) //RRR#define IESO (1<<7) //------------------------------------------------------------------------ // Config1H - default 3 bits FOSC class Config1H : public ConfigWord { #define CONFIG1H_default (OSCEN | FOSC2 | FOSC1 | FOSC0) public: Config1H(_16bit_processor *pCpu, unsigned int addr) : ConfigWord("CONFIG1H", CONFIG1H_default, "Oscillator configuration", pCpu, addr) { set(CONFIG1H_default); } virtual void set(gint64 v) { Integer::set(v); if (m_pCpu) { //RRRm_pCpu->osc_mode(v & ( FOSC2 | FOSC1 | FOSC0)); m_pCpu->osc_mode(v); } } virtual string toString(); }; //------------------------------------------------------------------------ // Config1H - 4 bits FOSC class Config1H_4bits : public ConfigWord { public: Config1H_4bits(_16bit_processor *pCpu, unsigned int addr, unsigned int def_val) : ConfigWord("CONFIG1H", def_val, "Oscillator configuration", pCpu, addr) { set(def_val); } virtual void set(gint64 v) { Integer::set(v); if (m_pCpu) { //m_pCpu->osc_mode(v & ( FOSC3 | FOSC2 | FOSC1 | FOSC0)); m_pCpu->osc_mode(v); } } virtual string toString(); }; class Config3H : public ConfigWord { public: Config3H(_16bit_processor *pCpu, unsigned int addr, unsigned int def_val) : ConfigWord("CONFIG3H", def_val, "Configuration Register 3 High", pCpu, addr) { set(def_val); } virtual void set(gint64 v) { Integer::set(v); if (m_pCpu) { m_pCpu->set_config3h(v); } } virtual string toString() { gint64 i64; get(i64); if (m_pCpu) return(m_pCpu->string_config3h(i64)); else return string ("m_PCpu not defined"); } }; #endif gpsim-0.30.0/src/12bit-processors.cc0000664000076400007640000001476613041763624014107 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "12bit-processors.h" #include #include "stimuli.h" #include "trace.h" extern unsigned int config_word; //======================================================================== // class OptionTraceObject : public RegisterWriteTraceObject { public: OptionTraceObject(Processor *_cpu, OPTION_REG *pOptionReg, RegisterValue trv) : RegisterWriteTraceObject(_cpu, pOptionReg, trv) { } void print(FILE *fp) { char sFrom[16]; char sTo[16]; if(reg) fprintf(fp, " Option: from 0x%s to 0x%s\n", from.toString(sFrom,sizeof(sFrom)), to.toString(sTo,sizeof(sTo))); } }; //======================================================================== class OptionTraceType : public TraceType { public: OptionTraceType(Processor *_cpu, OPTION_REG *pOptionReg) : TraceType(1,"Option reg"), m_cpu(_cpu),m_pOptionReg(pOptionReg) { } TraceObject *decode(unsigned int tbi) { unsigned int tv = trace.get(tbi); RegisterValue rv = RegisterValue(tv&0xff,0); OptionTraceObject *oto = new OptionTraceObject(m_cpu, m_pOptionReg, rv); return oto; } int dump_raw(Trace *pTrace, unsigned int tbi, char *buf, int bufsize) { if (!pTrace) return 0; int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int tv = pTrace->get(tbi); //unsigned int subtype = (tv >> 8) & 0xfff; int m = snprintf(buf, bufsize, " Option Reg: was 0x%0X ", tv & 0xff); return m>0 ? (m+n) : n; } protected: Processor *m_cpu; OPTION_REG *m_pOptionReg; }; //------------------------------------------------------------------- _12bit_processor::_12bit_processor(const char *_name, const char *desc) : pic_processor(_name, desc) { pc = new Program_Counter("pc", "Program Counter", this); pc->set_trace_command();// trace.allocateTraceType(new PCTraceType(this,1))); option_reg = new OPTION_REG(this, "option_reg"); mOptionTT = new OptionTraceType(this,option_reg); trace.allocateTraceType(mOptionTT); RegisterValue rv( (mOptionTT->type() & 0xff000000) | 0, 0); option_reg->set_write_trace(rv); option_reg->set_read_trace(rv); stack = new Stack(this); } _12bit_processor::~_12bit_processor() { delete pc; delete mOptionTT; delete_sfr_register(fsr); delete_sfr_register(option_reg); } void _12bit_processor::create_symbols() { pic_processor::create_symbols(); addSymbol(option_reg); // Create an alias for the option_reg option_reg->new_name("option"); addSymbol(Wreg); } void _12bit_processor::reset(RESET_TYPE r) { option_reg->reset(r); pic_processor::reset(r); } //------------------------------------------------------------------- void _12bit_processor::save_state() { pic_processor::save_state(); option_reg->put_trace_state(option_reg->value); } //------------------------------------------------------------------- bool _12bit_processor::set_config_word(unsigned int address,unsigned int cfg_word) { // Clear all of the configuration bits in config_modes and then // reset each of them based on the config bits in cfg_word: //config_modes &= ~(CM_WDTE); //config_modes |= ( (cfg_word & WDTE) ? CM_WDTE : 0); //cout << " setting cfg_word and cfg_modes " << hex << config_word << " " << config_modes << '\n'; if((address == config_word_address()) && config_modes) { config_word = cfg_word; if (m_configMemory && m_configMemory->getConfigWord(0)) m_configMemory->getConfigWord(0)->set((int)cfg_word); /* config_modes->config_mode = (config_modes->config_mode & ~7) | (cfg_word & 7); config_word = cfg_word; if((bool)verbose && config_modes) config_modes->print(); */ return true; } return false; } void _12bit_processor::create() { if(verbose) cout << "_12bit_processor create, type = " << isa() << '\n'; pa_bits = 0; // Assume only one code page (page select bits in status) pic_processor::create(); fsr = new FSR_12(this,"fsr",fsr_register_page_bits(), fsr_valid_bits()); // Sigh. Hack, hack,... manually assign indf bits indf->fsr_mask = 0x1f; indf->base_address_mask1 = 0x0; indf->base_address_mask2 = 0x1f; stack->stack_mask = 1; // The 12bit core only has 2 stack positions //1 tmr0.set_cpu(this); //1 tmr0.start(0); } //------------------------------------------------------------------- void _12bit_processor::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new ConfigWord("CONFIG", 0xfff,"Configuration Word",this,0xfff)); /* m_configMemory = new ConfigMemory *[1]; *m_configMemory = new ConfigMemory("CONFIG", 0xfff,"Configuration Word",this,0xfff); addSymbol(*m_configMemory); */ } //------------------------------------------------------------------- void _12bit_processor::option_new_bits_6_7(unsigned int bits) { //portb.rbpu_intedg_update(bits); cout << "12bit, option bits 6 and/or 7 changed\n"; } //------------------------------------------------------------------- void _12bit_processor::put_option_reg(unsigned int val) { option_reg->put(val); } //------------------------------------------------------------------- void _12bit_processor::dump_registers () { pic_processor::dump_registers(); cout << "option = " << option_reg->value.get() << '\n'; } //------------------------------------------------------------------- void _12bit_processor::enter_sleep() { tmr0.sleep(); pic_processor::enter_sleep(); } //------------------------------------------------------------------- void _12bit_processor::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr0.wake(); pic_processor::exit_sleep(); } } gpsim-0.30.0/src/errors.cc0000664000076400007640000000352013045306452012260 00000000000000 #include "errors.h" /***************************************************************** * The primordial Assembler Error class. */ AnError::AnError(const std::string & _severity, const std::string & _errMsg) : severity(_severity), errMsg(_errMsg) { // Pretty gross, but the lexer makes sure that this global // always describes the current source line. //this->sourceRef = thisLine; } AnError::~AnError() { } string AnError::toString() { return string("\"" + errMsg + "\""); } string AnError::get_errMsg() { return errMsg; } /***************************************************************** * Generate assembler errors of severity "ERROR" */ int Error::count; Error::Error(const std::string & errMsg) : AnError(string("ERROR"), errMsg) { } Error::~Error() { } /***************************************************************** * Generate assembler errors of severity "FATAL_ERROR" */ FatalError::FatalError(const std::string & errMsg) : AnError(string("FATAL_ERROR"), errMsg) { } FatalError::~FatalError() { } /***************************************************************** * Generate a generic Type Mismatch error of the "expected xx, * observed yy" variety. */ TypeMismatch::TypeMismatch(const std::string &theOperator, const std::string &expectedType, const std::string &observedType) : Error(" Type mismatch for " + theOperator + " operator. Type expected " + expectedType + ", found " + observedType) { } /***************************************************************** * Generate a generic Type Mismatch error of the "operator x * cannot be applied to type y" variety. */ TypeMismatch::TypeMismatch(const std::string &theOperator, const std::string &observedType) : Error("Operator <" + theOperator + "> cannot be applied to type " + observedType) { } TypeMismatch::~TypeMismatch() { } gpsim-0.30.0/src/pic-processor.h0000664000076400007640000003636313116645075013417 00000000000000/* Copyright (C) 1998-2000 T. Scott Dattalo Copyright (C) 2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PIC_PROCESSORS_H__ #define __PIC_PROCESSORS_H__ #include #include #include #include "gpsim_classes.h" #include "modules.h" #include "processor.h" #include "program_files.h" #include "pic-registers.h" #include "14bit-registers.h" #include "trigger.h" class EEPROM; class instruction; class Register; class sfr_register; class pic_register; class ConfigMemory; class ResetTraceType; class InterruptTraceType; enum PROCESSOR_TYPE { _PIC_PROCESSOR_, _14BIT_PROCESSOR_, _14BIT_E_PROCESSOR_, // 14bit enhanced processor _12BIT_PROCESSOR_, _PIC17_PROCESSOR_, _PIC18_PROCESSOR_, _P10F200_, _P10F202_, _P10F204_, _P10F206_, _P10F220_, _P10F222_, _P12C508_, _P12C509_, _P12F508_, _P12F509_, _P12F510_, _P12F629_, _P12F675_, _P12F683_, _P12F1822_, _P12F1840_, _P16C84_, _P16CR83_, _P16CR84_, _P12CE518_, _P12CE519_, _P16F83_, _P16F84_, _P16C71_, _P16C712_, _P16C716_, _P16C54_, _P16C55_, _P16C56_, _P16C61_, _P16C62_, _P16C62A_, _P16CR62_, _P16F505_, _P16F627_, _P16F628_, _P16F630_, _P16F631_, _P16F648_, _P16F676_, _P16F677_, _P16F684_, _P16F685_, _P16F687_, _P16F689_, _P16F690_, _P16C63_, _P16C64_, _P16C64A_, _P16CR64_, _P16C65_, _P16C65A_, _P16C72_, _P16C73_, _P16C74_, _P16F73_, _P16F74_, _P16F716_, _P16F87_, _P16F88_, _P16F818_, _P16F819_, _P16F871_, _P16F873_, _P16F873A_, _P16F874_, _P16F874A_, _P16F876_, _P16F876A_, _P16F877_, _P16F877A_, _P16F882_, _P16F883_, _P16F884_, _P16F886_, _P16F887_, _P16F913_, _P16F914_, _P16F916_, _P16F917_, _P16F1788_, _P16F1789_, _P16F1823_, _P16F1825_, _P17C7xx_, _P17C75x_, _P17C752_, _P17C756_, _P17C756A_, _P17C762_, _P17C766_, _P18Cxx2_, _P18C2x2_, _P18C242_, _P18F242_, _P18F248_, _P18F258_, _P18F448_, _P18F458_, _P18C252_, _P18F252_, _P18C442_, _P18C452_, _P18F442_, _P18F452_, _P18F1220_, _P18F1320_, _P18F14K22_, _P18F2221_, _P18F2321_, _P18F2420_, _P18F2455_, _P18F2520_, _P18F2525_, _P18F2550_, _P18F26K22_, _P18F2620_, _P18F4221_, _P18F4321_, _P18F4420_, _P18F4455_, _P18F4520_, _P18F4550_, _P18F4620_, _P18F6520_, }; // Configuration modes. DELETE THIS... // The configuration mode bits are the config word bits remapped. // The remapping removes processor dependent bit definitions. class ConfigMode { public: enum { CM_FOSC0 = 1<<0, // FOSC0 and FOSC1 together define the PIC clock CM_FOSC1 = 1<<1, // All PICs todate have these two bits, but the // ones with internal oscillators use them differently CM_WDTE = 1<<2, // Watch dog timer enable CM_CP0 = 1<<3, // Code Protection CM_CP1 = 1<<4, CM_PWRTE = 1<<5, // Power on/Reset timer enable CM_BODEN = 1<<6, // Brown out detection enable CM_CPD = 1<<7, CM_MCLRE = 1<<8, // MCLR enable CM_FOSC1x = 1<<31, // Hack for internal oscillators }; int config_mode; int valid_bits; ConfigMode() { config_mode = 0xffff; valid_bits = CM_FOSC0 | CM_FOSC1 | CM_WDTE; }; virtual ~ConfigMode() { } virtual void set_config_mode(int new_value) { config_mode = new_value & valid_bits;}; virtual void set_valid_bits(int new_value) { valid_bits = new_value;}; void set_fosc0(){config_mode |= CM_FOSC0;}; void clear_fosc0(){config_mode &= ~CM_FOSC0;}; bool get_fosc0(){return (config_mode & CM_FOSC0);}; void set_fosc1(){config_mode |= CM_FOSC1;}; void clear_fosc1(){config_mode &= ~CM_FOSC1;}; bool get_fosc1(){return (0 != (config_mode & CM_FOSC1));}; bool get_fosc1x(){return (0 != (config_mode & CM_FOSC1x));}; void set_fosc01(int v) { config_mode = (config_mode & ~(CM_FOSC0 | CM_FOSC1)) | (v & (CM_FOSC0 | CM_FOSC1)); } void set_cp0() {config_mode |= CM_CP0; valid_bits |= CM_CP0;}; void clear_cp0(){config_mode &= ~CM_CP0; valid_bits |= CM_CP0;}; bool get_cp0() {return (0 != (config_mode & CM_CP0));}; void set_cp1() {config_mode |= CM_CP1; valid_bits |= CM_CP1;}; void clear_cp1(){config_mode &= ~CM_CP1; valid_bits |= CM_CP1;}; bool get_cp1() {return (0 != (config_mode & CM_CP1));}; void enable_wdt() {config_mode |= CM_WDTE;}; void disable_wdt() {config_mode &= ~CM_WDTE;}; void set_wdte(bool b) { config_mode = b ? (config_mode | CM_WDTE) : (config_mode & ~CM_WDTE); } bool get_wdt() {return (0 != (config_mode & CM_WDTE));}; void set_mclre(bool b) { config_mode = b ? (config_mode | CM_MCLRE) : (config_mode & ~CM_MCLRE); } bool get_mclre() {return (0 != (config_mode & CM_MCLRE));}; void enable_pwrte() {config_mode |= CM_PWRTE; valid_bits |= CM_PWRTE;}; void disable_pwrte() {config_mode &= ~CM_PWRTE; valid_bits |= CM_PWRTE;}; void set_pwrte(bool b) { config_mode = b ? (config_mode | CM_PWRTE) : (config_mode & ~CM_PWRTE); } bool get_pwrte() {return (0 != (config_mode & CM_PWRTE));}; bool is_valid_pwrte() {return (0 != (valid_bits & CM_PWRTE));}; virtual void print(); }; //--------------------------------------------------------- // Watch Dog Timer // class WDT : public TriggerObject, public gpsimObject { public: WDT(pic_processor *, double _timeout); void put(unsigned int new_value); virtual void initialize(bool enable); virtual void swdten(bool enable); void set_timeout(double); virtual void set_prescale(unsigned int); virtual void set_postscale(unsigned int); virtual void reset(RESET_TYPE r); void clear(); virtual void callback(); virtual void update(); virtual void callback_print(); void set_breakpoint(unsigned int bpn); bool hasBreak() { return breakpoint != 0;} protected: pic_processor *cpu; // The cpu to which this wdt belongs. unsigned int breakpoint, prescale, postscale; guint64 future_cycle; double timeout; // When no prescaler is assigned bool wdte; bool warned; bool cfgw_enable; // Enabled from Configureation word }; /*================================================================== * FIXME - move these global references somewhere else */ #include "cmd_gpsim.h" extern guint64 gui_update_rate; // The rate (in simulation cycles) at which the gui is updated /*================================================================== * * Here are the base class declarations for the pic processors */ /* * First, forward-declare a few class references */ enum IOPIN_TYPES { INPUT_ONLY, // e.g. MCLR BI_DIRECTIONAL, // most iopins BI_DIRECTIONAL_PU, // same as bi_directional, but with pullup resistor. e.g. portb OPEN_COLLECTOR // bit4 in porta on the 18 pin midrange devices. }; /* * Define a base class processor for the pic processor family * * All pic processors are derived from this class. */ class PicTrisRegister; class PicLatchRegister; class IO_SignalControl; class pic_processor : public Processor { public: unsigned int config_word; // as read from hex or cod file ConfigMode *config_modes; // processor dependent configuration bits. unsigned int pll_factor; // 2^pll_factor is the speed boost the PLL adds // to the instruction execution rate. WDT wdt; INDF *indf; FSR *fsr; Stack *stack; Status_register *status; WREG *Wreg; // Used when W is a normal register PCL *pcl; PCLATH *pclath; PCHelper *m_PCHelper; TMR0 tmr0; int num_of_gprs; EEPROM *eeprom; // set to NULL for PIC's that don't have a data EEPROM bool LoadProgramFile(const char *pFilename, FILE *pFile, const char *pProcessorName ); void add_sfr_register(Register *reg, unsigned int addr, RegisterValue por_value=RegisterValue(0,0), const char *new_name=0, bool warn_dup = true); void delete_sfr_register(Register *pReg); void remove_sfr_register(Register *pReg); void init_program_memory(unsigned int memory_size); void build_program_memory(int *memory,int minaddr, int maxaddr); virtual instruction * disasm ( unsigned int address,unsigned int inst)=0; virtual void create_config_memory() = 0; virtual void tris_instruction(unsigned int tris_register) {return;}; virtual void create_symbols(); virtual void run(bool refresh=true); virtual void finish(); void sleep(); virtual void enter_sleep(); virtual void exit_sleep(); virtual bool exit_wdt_sleep() { return true; } // WDT wakes sleep virtual bool swdten_active() { return true; } // WDTCON can enable WDT bool is_sleeping(); virtual void step(unsigned int steps,bool refresh=true); virtual void step_over(bool refresh=true); virtual void step_cycle(); virtual void step_one(bool refresh=true) { if (pc->value < program_memory_size()) program_memory[pc->value]->execute(); else { cout << "Program counter not valid " << hex << pc->value << endl; get_bp().halt(); } } // Take a snap shot of the internal state. virtual void save_state(); virtual void interrupt() { return; }; //// TEMPORARY - consolidate the various bp.set_interrupt() calls to one function: void BP_set_interrupt(); void pm_write(); virtual ConfigMemory * getConfigMemory(){ return m_configMemory;} virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual unsigned int get_config_word(unsigned int address); virtual int get_config_index(unsigned int address); virtual unsigned int config_word_address() const {return 0x2007;}; virtual ConfigMode *create_ConfigMode() { return new ConfigMode; }; virtual void reset(RESET_TYPE r); virtual void create(); virtual PROCESSOR_TYPE isa(){return _PIC_PROCESSOR_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC_PROCESSOR_;}; virtual unsigned int access_gprs() { return 0; }; virtual unsigned int bugs() { return 0; }; // default is no errata /* The program_counter class calls these two functions to get the upper bits of the PC * for branching (e.g. goto) or modify PCL instructions (e.g. addwf pcl,f) */ virtual unsigned int get_pclath_branching_jump()=0; virtual unsigned int get_pclath_branching_modpcl()=0; virtual void option_new_bits_6_7(unsigned int)=0; virtual void put_option_reg(unsigned int) {} virtual void set_eeprom(EEPROM *e); virtual EEPROM *get_eeprom() { return (eeprom); } virtual void createMCLRPin(int pkgPinNumber); virtual void assignMCLRPin(int pkgPinNumber); virtual void unassignMCLRPin(); virtual void osc_mode(unsigned int ); virtual void set_config3h(gint64 x){;} virtual string string_config3h(gint64 x){return string("fix string_config3h");} // Activity States reflect what the processor is currently doing // (The breakpoint class formally implemented this functionality). enum eProcessorActivityStates { ePAActive, // Normal state ePAIdle, // Processor is held in reset ePASleeping, // Processor is sleeping ePAInterrupt, // do we need this? ePAPMWrite // Processor is busy performing a program memory write }; eProcessorActivityStates getActivityState() { return m_ActivityState; } pic_processor(const char *_name=0, const char *desc=0); virtual ~pic_processor(); void set_osc_pin_Number(unsigned int i, unsigned int val, PinModule *pm) {if (i < 4){osc_pin_Number[i] = val; m_osc_Monitor[i] = pm;}} unsigned char get_osc_pin_Number(unsigned int i) {return (i<4)?osc_pin_Number[i]:253;} PinModule * get_osc_PinMonitor(unsigned int i) { return (i<4)?m_osc_Monitor[i]:0; } void set_clk_pin(unsigned int pkg_Pin_Number, PinModule *PinMod, const char * name, bool in, PicPortRegister *m_port = 0, PicTrisRegister *m_tris = 0, PicLatchRegister *m_lat = 0 ); void clr_clk_pin(unsigned int pkg_Pin_Number, PinModule *PinMod, PicPortRegister *m_port = 0, PicTrisRegister *m_tris = 0, PicLatchRegister *m_lat = 0 ); virtual void set_int_osc(bool val){ internal_osc = val;} virtual bool get_int_osc(){ return internal_osc; } virtual void set_pplx4_osc(bool val){ PPLx4 = val;} virtual bool get_pplx4_osc(){ return PPLx4; } virtual void Wput(unsigned int); virtual unsigned int Wget(); protected: ConfigMemory *m_configMemory; eProcessorActivityStates m_ActivityState; ResetTraceType *m_pResetTT; InterruptTraceType *m_pInterruptTT; // Most midrange PIC's have a dedicated MCLR pin. // For the ones that don't, m_MCLR will be null. IOPIN *m_MCLR; IOPIN *m_MCLR_Save; int m_MCLR_pin; PinMonitor *m_MCLRMonitor; string m_mclr_pin_name; unsigned char osc_pin_Number[4]; PinModule *m_osc_Monitor[4]; bool internal_osc; // internal RC oscilator enabled on Config Word bool PPLx4; // 4x PPL enabled on Config Word PeripheralSignalSource *clksource; SignalControl *clkcontrol; }; #define cpu_pic ( (pic_processor *)cpu) // Bit field of known silicon bugs #define BUG_NONE 0 #define BUG_DAW 0x00000001 //------------------------------------------------------------------------ // Base Class for configuration memory // // The configuration memory is only a tiny portion of the overall processor // program memory space (only 1-word on the mid range devices). So, explicit // attributes are created for each memory configuration word. Since the meaning // of configuration memory varies from processor to processor, it is up to // each process to derive from this class. class ConfigWord : public Integer { public: ConfigWord(const char *_name, unsigned int default_val, const char *desc, pic_processor *pCpu, unsigned int addr, bool EEw=true); virtual void get(char *buffer, int buf_size); virtual void get(gint64 &i); unsigned int ConfigWordAdd() { return m_addr; } bool isEEWritable() { return EEWritable;} protected: pic_processor *m_pCpu; unsigned int m_addr; bool EEWritable; }; class ConfigMemory { public: ConfigMemory(pic_processor *pCpu, unsigned int nWords); ~ConfigMemory(); int addConfigWord(unsigned int addr, ConfigWord *); ConfigWord *getConfigWord(unsigned int addr); int getnConfigWords() { return m_nConfigWords; } protected: pic_processor *m_pCpu; ConfigWord **m_ConfigWords; unsigned int m_nConfigWords; }; /* class ConfigMemory : public Integer { public: ConfigMemory(const char *_name, unsigned int default_val, const char *desc, pic_processor *pCpu, unsigned int addr); protected: pic_processor *m_pCpu; unsigned int m_addr; }; */ #endif gpsim-0.30.0/src/p18x.h0000664000076400007640000005061513116645075011423 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2010,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P18X_H__ #define __P18X_H__ #include "16bit-processors.h" #include "eeprom.h" #include "psp.h" #include "pir.h" #include "comparator.h" #include "spp.h" #include "ctmu.h" #define IESO (1<<12) class PicPortRegister; class PicTrisRegister; class PicLatchRegister; class ADCON0_V2; class ADCON1_V2; class ADCON2_V2; class P18C2x2 : public _16bit_compat_adc { public: P18C2x2(const char *_name=0, const char *desc=0); void create(); virtual PROCESSOR_TYPE isa(){return _P18Cxx2_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x400; }; virtual unsigned int IdentMemorySize() const { return 2; } // only two words on 18C virtual void create_iopin_map(); }; class P18C242 : public P18C2x2 { public: virtual PROCESSOR_TYPE isa(){return _P18C242_;}; P18C242(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int last_actual_register () const { return 0x01FF;}; }; class P18C252 : public P18C242 { public: virtual PROCESSOR_TYPE isa(){return _P18C252_;}; P18C252(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; }; /********************************************************************* * class definitions for the 18C4x2 family */ //class P18C4x2 : public _16bit_processor class P18C4x2 : public _16bit_compat_adc { public: PicPSP_PortRegister *m_portd; PicTrisRegister *m_trisd; PicLatchRegister *m_latd; PicPortRegister *m_porte; PicPSP_TrisRegister *m_trise; PicLatchRegister *m_late; PSP psp; P18C4x2(const char *_name=0, const char *desc=0); ~P18C4x2(); void create(); virtual PROCESSOR_TYPE isa(){return _P18Cxx2_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x400; }; virtual unsigned int IdentMemorySize() const { return 2; } // only two words on 18C virtual void create_sfr_map(); virtual void create_iopin_map(); }; class P18C442 : public P18C4x2 { public: virtual PROCESSOR_TYPE isa(){return _P18C442_;}; P18C442(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual unsigned int last_actual_register () const { return 0x01FF;}; }; class P18C452 : public P18C442 { public: virtual PROCESSOR_TYPE isa(){return _P18C452_;}; P18C452(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; }; class P18F242 : public P18C242 { public: virtual PROCESSOR_TYPE isa(){return _P18F242_;}; P18F242(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual unsigned int IdentMemorySize() const { return 4; } virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } }; class P18F252 : public P18F242 { public: virtual PROCESSOR_TYPE isa(){return _P18F252_;}; P18F252(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; }; class P18F442 : public P18C442 { public: virtual PROCESSOR_TYPE isa(){return _P18F442_;}; P18F442(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int IdentMemorySize() const { return 4; } virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } }; // // The P18F248 is the same as the P18F242 except it has CAN, one fewer // CCP module and a 5/10 ADC. For now just assume it is identical. class P18F248 : public P18F242 { public: virtual PROCESSOR_TYPE isa(){return _P18F248_;}; P18F248(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); }; // // The P18F258 is the same as the P18F252 except it has CAN, one fewer // CCP module and a 5/10 ADC. For now just assume it is identical. class P18F258 : public P18F252 { public: virtual PROCESSOR_TYPE isa(){return _P18F258_;}; P18F258(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); }; // // The P18F448 is the same as the P18F442 except it has CAN, one fewer // CCP module and a 5/10 ADC. For now just assume it is identical. class P18F448 : public P18F442 { public: virtual PROCESSOR_TYPE isa(){return _P18F448_;}; P18F448(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); }; class P18F452 : public P18F442 { public: virtual PROCESSOR_TYPE isa(){return _P18F452_;}; P18F452(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; }; // // The P18F458 is the same as the P18F452 except it has CAN and one // fewer CCP module. For now just assume it is identical. class P18F458 : public P18F452 { public: virtual PROCESSOR_TYPE isa(){return _P18F458_;}; P18F458(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); }; class P18F1220 : public _16bit_v2_adc { public: OSCTUNE osctune; ECCPAS eccpas; PWM1CON pwm1con; virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual PROCESSOR_TYPE isa(){return _P18F1220_;}; P18F1220(const char *_name=0, const char *desc=0); ~P18F1220(); static Processor *construct(const char *name); void create(); virtual void create_iopin_map(); virtual unsigned int program_memory_size() const { return 0x1000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual void osc_mode(unsigned int value); virtual unsigned int last_actual_register () const { return 0x00FF;}; // Strip down from base class virtual bool HasPortC(void) { return false; }; virtual bool HasCCP2(void) { return false; }; virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } virtual unsigned int get_device_id() { return (0x07 << 8)|(0x7 <<5); } }; class P18F1320 : public P18F1220 { public: virtual PROCESSOR_TYPE isa(){return _P18F1320_;}; P18F1320(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int get_device_id() { return (0x07 << 8)|(0x6 <<5); } }; class P18F2x21 : public _16bit_v2_adc { public: PicPortRegister *m_porte; PicPSP_TrisRegister *m_trise; PicLatchRegister *m_late; ECCPAS eccpas; PWM1CON pwm1con; OSCTUNE osctune; ComparatorModule comparator; P18F2x21(const char *_name=0, const char *desc=0); ~P18F2x21(); void create(); virtual PROCESSOR_TYPE isa(){return _P18Cxx2_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x400; }; virtual unsigned int eeprom_memory_size() const { return 0x100; }; // Setting the correct register memory size breaks things // virtual unsigned int register_memory_size () const { return 0x200;}; virtual unsigned int last_actual_register () const { return 0x01FF;}; virtual void create_iopin_map(); virtual void create_sfr_map(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } virtual void osc_mode(unsigned int value); }; class P18F2221 : public P18F2x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F2221_;}; P18F2221(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x800; }; virtual unsigned int get_device_id() { return (0x21 << 8)|(0x3 <<5); } }; class P18F2321 : public P18F2x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F2321_;}; P18F2321(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x1000; }; virtual unsigned int get_device_id() { return (0x21 << 8)|(0x1 <<5); } }; class P18F2420 : public P18F2x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F2420_;}; P18F2420(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual unsigned int last_actual_register () const { return 0x02FF;}; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x6 <<5); } }; class P18F2455 : public P18F2x21 { public: sfr_register ufrml, ufrmh, uir, uie, ueir, ueie, ustat, ucon, uaddr, ucfg, uep0, uep1, uep2, uep3, uep4, uep5, uep6, uep7, uep8, uep9, uep10, uep11, uep12, uep13, uep14, uep15; virtual PROCESSOR_TYPE isa(){return _P18F2455_;}; P18F2455(const char *_name=0, const char *desc=0); ~P18F2455(); static Processor *construct(const char *name); void create_sfr_map(); virtual unsigned int access_gprs() { return 0x60; }; // USB peripheral moves access split virtual unsigned int program_memory_size() const { return 0x3000; }; virtual unsigned int last_actual_register () const { return 0x07FF;}; virtual unsigned int get_device_id() { return (0x12 << 8)|(0x3 <<5); } }; class P18F2550 : public P18F2x21 { public: sfr_register ufrml, ufrmh, uir, uie, ueir, ueie, ustat, ucon, uaddr, ucfg, uep0, uep1, uep2, uep3, uep4, uep5, uep6, uep7, uep8, uep9, uep10, uep11, uep12, uep13, uep14, uep15; virtual PROCESSOR_TYPE isa(){return _P18F2550_;}; P18F2550(const char *_name=0, const char *desc=0); ~P18F2550(); static Processor *construct(const char *name); void create_sfr_map(); virtual unsigned int access_gprs() { return 0x60; }; // USB peripheral moves access split virtual unsigned int program_memory_size() const { return 16384; }; virtual unsigned int last_actual_register () const { return 0x07FF;}; virtual unsigned int get_device_id() { return (0x12 << 8)|(0x2 <<5); } }; class P18F2520 : public P18F2x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F2520_;}; P18F2520(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x4 <<5); } }; class P18F2525 : public P18F2x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F2525_;}; P18F2525(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 24576; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x6 <<5); } }; class P18F2620 : public P18F2x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F2620_;}; P18F2620(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x8000; }; virtual unsigned int last_actual_register () const { return 0x0F7F;}; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x4 <<5); } }; class RegZero : public Register { public: RegZero(Module *_cpu, const char *_name=0, const char *desc=0): Register(_cpu, _name, desc) {} virtual void put(unsigned int new_value) { value.put(0);} virtual void put_value(unsigned int new_value) { value.put(0);} }; class P18F4x21 : public P18F2x21 { public: PicPSP_PortRegister *m_portd; PicTrisRegister *m_trisd; PicLatchRegister *m_latd; P18F4x21(const char *_name=0, const char *desc=0); ~P18F4x21(); void create(); virtual void create_symbols(); virtual void create_iopin_map(); virtual void create_sfr_map(); }; class P18F4221 : public P18F4x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F4221_;}; P18F4221(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x800; }; virtual unsigned int get_device_id() { return (0x21 << 8)|(0x2 <<5); } }; class P18F4321 : public P18F4x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F4321_;}; P18F4321(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x1000; }; virtual unsigned int get_device_id() { return (0x21 << 8)|(0x0 <<5); } }; class P18F4420 : public P18F4x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F4420_;}; P18F4420(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x2 <<5); } }; class P18F4455 : public P18F4x21 { public: sfr_register ufrml, ufrmh, uir, uie, ueir, ueie, ustat, ucon, uaddr, ucfg, uep0, uep1, uep2, uep3, uep4, uep5, uep6, uep7, uep8, uep9, uep10, uep11, uep12, uep13, uep14, uep15; SPP spp; SPPCON sppcon; SPPCFG sppcfg; SPPEPS sppeps; SPPDATA sppdata; virtual PROCESSOR_TYPE isa(){return _P18F4455_;}; P18F4455(const char *_name=0, const char *desc=0); ~P18F4455(); static Processor *construct(const char *name); void create(); virtual unsigned int access_gprs() { return 0x60; }; // USB peripheral moves access split virtual unsigned int program_memory_size() const { return 0x3000; }; virtual unsigned int last_actual_register () const { return 0x07FF;}; virtual unsigned int get_device_id() { return (0x12 << 8)|(0x1 <<5); } }; class P18F4550 : public P18F4x21 { public: sfr_register ufrml, ufrmh, uir, uie, ueir, ueie, ustat, ucon, uaddr, ucfg, uep0, uep1, uep2, uep3, uep4, uep5, uep6, uep7, uep8, uep9, uep10, uep11, uep12, uep13, uep14, uep15; SPP spp; SPPCON sppcon; SPPCFG sppcfg; SPPEPS sppeps; SPPDATA sppdata; virtual PROCESSOR_TYPE isa(){return _P18F4550_;}; P18F4550(const char *_name=0, const char *desc=0); ~P18F4550(); static Processor *construct(const char *name); void create(); virtual unsigned int access_gprs() { return 0x60; }; // USB peripheral moves access split virtual unsigned int program_memory_size() const { return 16384; }; virtual unsigned int last_actual_register () const { return 0x07FF;}; virtual unsigned int get_device_id() { return (0x12 << 8)|(0x0 <<5); } }; class P18F4520 : public P18F4x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F4520_;}; P18F4520(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x05FF;}; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x0 <<5); } }; /*** PIC18F4620 Not implemented: OSCFIF bit in peripheral interrupt register 2 (PIR2v2 pir2)(And Enable Bit) ***/ class P18F4620 : public P18F4x21 { public: virtual PROCESSOR_TYPE isa(){return _P18F4620_;}; P18F4620(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 0x8000; }; virtual unsigned int eeprom_memory_size() const { return 1024; }; virtual unsigned int last_actual_register () const { return 0x0F7F;}; virtual unsigned int get_device_id() { return (0x0c << 8)|(0x4 <<5); } }; class P18F6x20 : public _16bit_v2_adc { public: PicPSP_PortRegister *m_portd; PicTrisRegister *m_trisd; PicLatchRegister *m_latd; PicPortRegister *m_porte; PicTrisRegister *m_trise; PicLatchRegister *m_late; PicPortRegister *m_portf; PicTrisRegister *m_trisf; PicLatchRegister *m_latf; PicPortRegister *m_portg; PicTrisRegister *m_trisg; PicLatchRegister *m_latg; PSP psp; PSPCON *pspcon; // ECCPAS eccpas; // PWM1CON pwm1con; T2CON t4con; PR2 pr4; TMR2 tmr4; PIR3v1 pir3; PIE pie3; sfr_register ipr3; CCPCON ccp3con; CCPRL ccpr3l; CCPRH ccpr3h; CCPCON ccp4con; CCPRL ccpr4l; CCPRH ccpr4h; CCPCON ccp5con; CCPRL ccpr5l; CCPRH ccpr5h; USART_MODULE usart2; // OSCTUNE osctune; ComparatorModule comparator; P18F6x20(const char *_name=0, const char *desc=0); ~P18F6x20(); void create(); virtual PROCESSOR_TYPE isa(){return _P18Cxx2_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual unsigned int access_gprs() { return 0x60; }; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int eeprom_memory_size() const { return 1024; }; // Setting the correct register memory size breaks things // virtual unsigned int register_memory_size () const { return 0x800;}; virtual unsigned int last_actual_register () const { return 0x07FF;}; virtual void create_iopin_map(); virtual void create_sfr_map(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } }; class P18F6520 : public P18F6x20 { public: virtual PROCESSOR_TYPE isa(){return _P18F6520_;}; P18F6520(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); // virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int bugs() { return BUG_DAW; }; virtual unsigned int get_device_id() { return (0x0b << 8)|(0x1 <<5); } }; #endif gpsim-0.30.0/src/ssp.cc0000664000076400007640000020320213045306452011550 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002 Scott Dattalo 2006,2011 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include "../config.h" #include "ssp.h" #include "pic-ioports.h" #include "stimuli.h" #include "14bit-processors.h" #include "14bit-tmrs.h" #include "xref.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() %s ",__FILE__,__LINE__,__FUNCTION__,cpu->name().c_str()); printf arg; } #else #define Dprintf(arg) {} #endif //#define I2C_PROTO #if defined(I2C_PROTO) #define I2Cproto(arg) {printf("I2C %s %d ",cpu->name().c_str(), __LINE__); printf arg;} #else #define I2Cproto(arg) {} #endif //#define SPI_PROTO #if defined(SPI_PROTO) #define SPIproto(arg) {printf("SPI %s %d ", cpu->name().c_str(), __LINE__); printf arg;} #else #define SPIproto(arg) {} #endif //#warning only supports SPI mode. //----------------------------------------------------------- // SSPSTAT - Synchronous Serial Port Status register. _SSPSTAT::_SSPSTAT(Processor *pCpu, SSP_MODULE *pSSP) : sfr_register(pCpu, "sspstat","Synchronous Serial Port Status"), m_sspmod(pSSP) { } /* only CKE and SMP is writable */ void _SSPSTAT::put(unsigned int new_value) { unsigned int old6 = value.get() & ~(CKE|SMP); // For BSSP register is read only otherwise // only CKE and SMP are writable if (!m_sspmod || m_sspmod->ssp_type() == SSP_TYPE_BSSP) return; put_value(old6 | (new_value & (CKE|SMP))); } void _SSPSTAT::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } class SCK_SignalSource : public SignalControl { public: SCK_SignalSource(SSP_MODULE *_ssp_mod, PinModule *_pin) : m_pin(_pin), m_ssp_mod(_ssp_mod), m_cState('?') {} ~SCK_SignalSource(){} virtual void release(){m_ssp_mod->releaseSCKpin();} virtual char getState() { return m_cState;} virtual void putState(const char new3State) { if (new3State != m_cState) { m_cState = new3State; m_pin->updatePinModule(); } } virtual void toggle() { switch (m_cState) { case '1': case 'W': putState('0'); break; case '0': case 'w': putState('1'); break; } } private: PinModule *m_pin; SSP_MODULE *m_ssp_mod; char m_cState; }; class SDO_SignalSource : public SignalControl { public: SDO_SignalSource(SSP_MODULE *_ssp_mod, PinModule *_pin) : m_pin(_pin), m_ssp_mod(_ssp_mod), m_cState('?') {} virtual void release(){m_ssp_mod->releaseSDOpin();} virtual char getState() { return m_cState;} virtual void putState(const char new3State) { if (new3State != m_cState) { m_cState = new3State; m_pin->updatePinModule(); } } private: PinModule *m_pin; SSP_MODULE *m_ssp_mod; char m_cState; }; class SDI_SignalSource : public SignalControl { public: SDI_SignalSource(SSP_MODULE *_ssp_mod, PinModule *_pin) : m_pin(_pin), m_ssp_mod(_ssp_mod), m_cState('?') {} virtual void release(){m_ssp_mod->releaseSDIpin();} virtual char getState() { return m_cState;} virtual void putState(const char new3State) { if (new3State != m_cState) { m_cState = new3State; m_pin->updatePinModule(); } } private: PinModule *m_pin; SSP_MODULE *m_ssp_mod; char m_cState; }; class SDI_SignalSink : public SignalSink { public: SDI_SignalSink(SSP_MODULE *_ssp_mod) : m_ssp_mod(_ssp_mod) { assert(_ssp_mod); } virtual ~SDI_SignalSink(){} virtual void release(){delete this;} void setSinkState(char new3State) { m_ssp_mod->SDI_SinkState(new3State); } private: SSP_MODULE *m_ssp_mod; }; class SCL_SignalSink : public SignalSink { public: SCL_SignalSink(SSP_MODULE *_ssp_mod) : m_ssp_mod(_ssp_mod) { assert(_ssp_mod); } virtual ~SCL_SignalSink(){} virtual void release(){delete this; } void setSinkState(char new3State) { m_ssp_mod->SCL_SinkState(new3State); } private: SSP_MODULE *m_ssp_mod; }; class SS_SignalSink : public SignalSink { public: SS_SignalSink(SSP_MODULE *_ssp_mod) : m_ssp_mod(_ssp_mod) { assert(_ssp_mod); } virtual ~SS_SignalSink(){} virtual void release(){delete this; } void setSinkState(char new3State) { m_ssp_mod->SS_SinkState(new3State); } private: SSP_MODULE *m_ssp_mod; }; //----------------------------------------------------------- // SSPCON - Synchronous Serial Port Control register. //----------------------------------------------------------- _SSPCON::_SSPCON(Processor *pCpu, SSP_MODULE *pSSP) : sfr_register(pCpu, "sspcon","Synchronous Serial Port Control"), m_sspmod(pSSP) { } bool _SSPCON::isSPIActive(unsigned int value) { if (value & SSPEN) { switch(value & SSPM_mask) { case SSPM_SPImaster4: case SSPM_SPImaster16: case SSPM_SPImaster64: case SSPM_SPImasterTMR2: case SSPM_SPIslaveSS: case SSPM_SPIslave: return(true); case SSPM_SPImasterAdd: if ((m_sspmod->ssp_type() == SSP_TYPE_MSSP1)) return(true); } } return(false); } bool _SSPCON::isSPIMaster() { unsigned int reg_value = value.get(); if (reg_value & SSPEN) { switch(reg_value & SSPM_mask) { case SSPM_SPImaster4: case SSPM_SPImaster16: case SSPM_SPImaster64: case SSPM_SPImasterTMR2: return(true); case SSPM_SPImasterAdd: if ((m_sspmod->ssp_type() == SSP_TYPE_MSSP1)) return(true); break; } } return(false); } /* process write to SSPCON */ void _SSPCON::put(unsigned int new_value) { unsigned int old_value = value.get(); put_value(new_value); Dprintf(("SSPCON new %x old %x\n", new_value, old_value)); if ((new_value & SSPEN) && ! (old_value & SSPEN)) // Turn on SSP m_sspmod->startSSP(new_value); else if (!(new_value & SSPEN) && (old_value & SSPEN)) // Turn off SSP m_sspmod->stopSSP(old_value); else if (new_value != old_value ) // change while active m_sspmod->changeSSP(new_value, old_value); } /* update SSPCON without action */ void _SSPCON::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); } /* Set WCOL bit of SSPCON */ void _SSPCON::setWCOL() { if (value.get() & WCOL) return; put_value(value.get() | WCOL); } /* return true if a I2C mode is enabled in SSPCON */ bool _SSPCON::isI2CActive(unsigned int val) { if ( (val & SSPEN) != SSPEN) return(false); switch(val & SSPM_mask) { case SSPM_I2Cslave_7bitaddr: case SSPM_I2Cslave_10bitaddr: case SSPM_MSSPI2Cmaster: case SSPM_I2Cfirmwaremaster: case SSPM_I2Cslave_7bitaddr_ints: case SSPM_I2Cslave_10bitaddr_ints: return(true); break; } return(false); } bool _SSPCON::isI2CMaster(unsigned int val) { if ( (val & SSPEN) != SSPEN) return(false); switch(val & SSPM_mask) { case SSPM_MSSPI2Cmaster: case SSPM_I2Cfirmwaremaster: return(true); break; } return(false); } /* return true if an I2C slave mode is enabled in SSPCON */ bool _SSPCON::isI2CSlave(unsigned int val) { if ( (val & SSPEN) != SSPEN) return(false); switch(val & SSPM_mask) { case SSPM_I2Cslave_7bitaddr: case SSPM_I2Cslave_10bitaddr: case SSPM_I2Cslave_7bitaddr_ints: case SSPM_I2Cslave_10bitaddr_ints: return(true); break; } return(false); } //----------------------------------------------------------- // SSPBUF - Synchronous Serial Port Control register. //----------------------------------------------------------- _SSPBUF::_SSPBUF(Processor *pCpu, SSP_MODULE *pSSP) : sfr_register(pCpu, "sspbuf","Synchronous Serial Port Buffer"), m_sspmod(pSSP), m_bIsFull(false) { } /* process write to SSPBUF */ void _SSPBUF::put(unsigned int new_value) { put_value(new_value); m_sspmod->newSSPBUF(value.get()); m_bIsFull = false; } /* update SSPBUF without processing data */ void _SSPBUF::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); } /* void _SSPBUF::setSSPMODULE( SSP_MODULE *_sspmod) { m_sspmod = _sspmod; } */ unsigned int _SSPBUF::get() { if( m_sspmod ) m_sspmod->rdSSPBUF(); trace.raw(read_trace.get() | value.get()); m_bIsFull = false; return value.get(); } unsigned int _SSPBUF::get_value() { return value.get(); } //----------------------------------------------------------- // SSPMSK - Synchronous Serial Port Address mask(for I2C) //----------------------------------------------------------- _SSPMSK::_SSPMSK(Processor *pCpu, const char *_name) : sfr_register(pCpu, _name,"Synchronous I2C Address mask") { put_value(0xff); } void _SSPMSK::put(unsigned int new_value) { // trace cannot handle 2 registers at same address RRR trace.raw(write_trace.get() | value.get()); put_value(new_value); } //----------------------------------------------------------- // SSPADD - Synchronous Serial Port Address (for I2C) //----------------------------------------------------------- _SSPADD::_SSPADD(Processor *pCpu, SSP_MODULE *pSSP) : sfr_register(pCpu, "sspadd","Synchronous Serial Port Address (I2C)"), m_sspmod(pSSP) { } /* On some processors SSPMSK is accessed through SSPADD lt is assummed that SSPM_LoadMaskFunction bits of SSPCON are reserved on those processors which have seperate addresses for SSPMSK and SSPADD */ void _SSPADD::put(unsigned int new_value) { if (m_sspmod && m_sspmod->sspmsk && ((m_sspmod->sspcon.value.get() & _SSPCON::SSPM_mask) == _SSPCON::SSPM_LoadMaskFunction)) { m_sspmod->sspmsk->put(new_value); return; } trace.raw(write_trace.get() | value.get()); put_value(new_value); if( m_sspmod ) { if (m_sspmod->sspmsk) { m_sspmod->newSSPADD(m_sspmod->sspmsk->value.get() &new_value); } else m_sspmod->newSSPADD(new_value); } } void _SSPADD::put_value(unsigned int new_value) { value.put(new_value & 0xff); } unsigned int _SSPADD::get() { unsigned int val = value.get(); if (m_sspmod->sspmsk) { unsigned int con_val = m_sspmod->sspcon.value.get() & _SSPCON::SSPM_mask; if (con_val == _SSPCON::SSPM_LoadMaskFunction) return m_sspmod->sspmsk->value.get(); } return val; } SPI::SPI(SSP_MODULE *_ssp_mod, _SSPCON *_sspcon, _SSPSTAT *_sspstat, _SSPBUF *_sspbuf) : m_state(eIDLE) { m_sspmod = _ssp_mod; m_sspcon = _sspcon; m_sspstat = _sspstat; m_sspbuf = _sspbuf; cpu = m_sspmod->cpu; } void SPI::clock( bool ClockState ) { // A clock has happened. Either we sent one or we recieved one. bool onbeat; bool allDone = false; if( !m_sspstat || ! m_sspcon) return; unsigned int sspstat_val = m_sspstat->value.get(); unsigned int sspcon_val = m_sspcon->value.get(); //cout << "SPi clock " << ClockState << " m_state=" << m_state << endl; if( ClockState ) // rising edge { if( ( (sspcon_val & _SSPCON::CKP) && !(sspstat_val & _SSPSTAT::CKE) ) || ( !(sspcon_val & _SSPCON::CKP) && (sspstat_val & _SSPSTAT::CKE) ) ) onbeat = true; else onbeat = false; } else // falling edge { if( ( !(sspcon_val & _SSPCON::CKP) && !(sspstat_val & _SSPSTAT::CKE) ) || ( (sspcon_val & _SSPCON::CKP) && (sspstat_val & _SSPSTAT::CKE))) onbeat = true; else onbeat = false; } if( m_state == eIDLE ){ SPIproto(("Idle clock %d CKE %d CKP %d onbeat %d\n", ClockState, (sspstat_val & _SSPSTAT::CKE), (sspcon_val & _SSPCON::CKP), onbeat)); if( sspstat_val & _SSPSTAT::CKE ) { // FIX: I have NOT verified that PICs actually behave like this. cout << "SSP: I can't handle a non-started transfer with CKE = 1." << endl; return; } else if( onbeat ) { // FIX: I have NOT verified that PICs actually behave like this. cout << "SSP: " << cpu->name() << " Ignoring clock transition to neutral in state IDLE." << endl; return; } else { // RP: This is only relevant in slave mode? I think clock is never called // while idle in master mode. if (verbose) cout << "SPI clock called start_transfer\n"; SPIproto(("Clock called start transfer\n")); start_transfer(); } } if (!m_sspmod) return; if( onbeat ) { // on beat: data is read in if SMP = 0 if( !(sspstat_val & _SSPSTAT::SMP) ) { m_SSPsr <<= 1; if (m_sspmod->get_SDI_State()) m_SSPsr |= 1; if (verbose) cout << "SSP: SPI Received bit = " << (m_SSPsr & 1) << ". onbeat(SMP=0)" << endl; SPIproto(("In Bit %u byte count=%d onbeat m_SSPsr=0x%02x\n", (m_SSPsr & 1), bits_transfered+1, m_SSPsr)); } } else { // off beat: data is shifted out, data is read in if SMP = 1 if( sspstat_val & _SSPSTAT::SMP ) { m_SSPsr <<= 1; if (m_sspmod->get_SDI_State()) m_SSPsr |= 1; if (verbose) cout << "SSP: SPI Received bit = " << (m_SSPsr & 1) << ". offbeat(SMP=1)" << endl; SPIproto(("In Bit %u byte count=%d offbeat\n", (m_SSPsr & 1), bits_transfered+1)); } char nextSDO = (m_SSPsr&(1<<7)) ? '1' : '0'; m_sspmod->putStateSDO(nextSDO); if (verbose) cout << "SSP: SPI Sent bit = " << nextSDO << "." << endl; SPIproto(("\tSent bit %c m_SSPsr 0x%x\n", nextSDO, m_SSPsr)); } bool bSSPCONValue = (sspcon_val & _SSPCON::CKP) ? true : false; if(bSSPCONValue == ClockState) { bits_transfered++; if( bits_transfered == 8 ) { if( (sspstat_val & _SSPSTAT::SMP) && !(sspstat_val & _SSPSTAT::CKE) ) { m_state = eWAITING_FOR_LAST_SMP; } else { stop_transfer(); allDone = true; } } } if ( !allDone && m_sspcon->isSPIMaster() ) set_halfclock_break(); } void SPI::set_halfclock_break() { int clock_in_cycles = 1; if( !m_sspstat || ! m_sspcon) return; unsigned int sspcon_val = m_sspcon->value.get(); switch( sspcon_val & _SSPCON::SSPM_mask ) { // Simulation requires Fosc/4 to be run at Fosc/8 case _SSPCON::SSPM_SPImaster4: clock_in_cycles = 1; break; case _SSPCON::SSPM_SPImaster16: clock_in_cycles = 2; break; case _SSPCON::SSPM_SPImaster64: clock_in_cycles = 8; break; case _SSPCON::SSPM_SPImasterTMR2: break; } get_cycles().set_break(get_cycles().get() + clock_in_cycles, this); } void SPI::callback() { if (!m_sspmod) return; if (verbose) cout << "SPI callback m_state=" << m_state << endl; SPIproto(("callback m_state=%d\n", m_state)); switch( m_state ) { case eIDLE: break; case eACTIVE: m_sspmod->Sck_toggle(); clock( m_sspmod->get_SCL_State() ); break; case eWAITING_FOR_LAST_SMP: if( m_sspstat && m_sspstat->value.get() & _SSPSTAT::SMP ) { m_SSPsr <<= 1; if (m_sspmod->get_SDI_State()) m_SSPsr |= 1; if (verbose) cout << "SSP: Received bit = " << (m_SSPsr & 1) << ". (SMP=1)" << endl; } m_state = eACTIVE; stop_transfer(); break; } } //----------------------------------------------------------- void SPI::startSPI() { m_state = eIDLE; bits_transfered = 0; } SPI_1::SPI_1(SSP1_MODULE *_ssp_mod, _SSPCON *_sspcon, _SSPSTAT *_sspstat, _SSPBUF *_sspbuf, _SSP1CON3 *_ssp1con3, _SSPADD *_sspadd) : SPI(_ssp_mod, _sspcon, _sspstat, _sspbuf) { m_ssp1con3 = _ssp1con3; m_sspadd = _sspadd; } void SPI_1::set_halfclock_break() { int clock_in_cycles = 1; if( !m_sspstat || ! m_sspcon) return; unsigned int sspcon_val = m_sspcon->value.get(); switch( sspcon_val & _SSPCON::SSPM_mask ) { // Simulation requires Fosc/4 to be run at Fosc/8 case _SSPCON::SSPM_SPImaster4: clock_in_cycles = 1; break; case _SSPCON::SSPM_SPImaster16: clock_in_cycles = 2; break; case _SSPCON::SSPM_SPImaster64: clock_in_cycles = 8; break; case _SSPCON::SSPM_SPImasterAdd: // Note, this will be low by 1 cycle/clock when sspadd is even clock_in_cycles = (m_sspadd->get() + 1)>>1; if (clock_in_cycles < 2) { cout << "WARNING for SPI sspadd must be >= 3\n"; clock_in_cycles = 2; } break; case _SSPCON::SSPM_SPImasterTMR2: break; } get_cycles().set_break(get_cycles().get() + clock_in_cycles, this); } void SPI_1::stop_transfer() { Dprintf(("stop_transfer SPI_1\n")); if (!m_sspcon || !m_sspstat || !m_sspbuf || !m_sspmod || !m_ssp1con3) return; if( m_state == eACTIVE ) { if (bits_transfered == 8 ) Dprintf(("BOEN %x\n", m_ssp1con3->value.get() & _SSP1CON3::BOEN)); if( bits_transfered == 8 && m_ssp1con3->value.get() & _SSP1CON3::BOEN) { if (verbose) cout << "SPI: Stoping transfer. Normal finish. Setting sspif but not BF as BOEN set\n"; m_sspbuf->put_value(m_SSPsr & 0xff); m_sspmod->set_sspif(); } else if( bits_transfered == 8 && !m_sspbuf->isFull() ) { if (verbose) cout << "SPI: Stoping transfer. Normal finish. Setting sspif and BF\n"; m_sspbuf->put_value(m_SSPsr & 0xff); m_sspbuf->setFullFlag(true); m_sspmod->set_sspif(); m_sspstat->put_value(m_sspstat->value.get() | _SSPSTAT::BF); } else if( bits_transfered == 8 && m_sspbuf->isFull() ) { if (verbose) cout << "SPI: Stopping transfer. SSPBUF Overflow setting SSPOV." << endl; m_sspcon->setSSPOV(); m_sspmod->set_sspif(); // The real PIC sets sspif even with overflow } else { cout << "SPI: Stopping transfer. Cancel finish." << endl; // The transfer was canceled in some way } } else { if (verbose) cout << "SSP: Stopping transfer. State != ACTIVE." << endl; } m_state = eIDLE; } SSP_MODULE::SSP_MODULE(Processor *pCpu) : sspbuf(pCpu,this), sspcon(pCpu,this), sspstat(pCpu,this), sspcon2(pCpu,this), sspadd(pCpu,this), sspmsk(0), cpu(pCpu), m_ssp_if(0), m_bcl_if(0), m_pirset(0), m_spi(0), m_i2c(0), m_sck(0), m_ss(0), m_sdo(0), m_sdi(0), m_i2c_tris(0), m_SDI_State(false), m_SCL_State(false), m_SS_State(false), m_SckSource(0), m_SdoSource(0), m_SdiSource(0), m_SDI_Sink(0), m_SCL_Sink(0), m_SS_Sink(0), m_sink_set(false), m_sdo_active(false), m_sdi_active(false), m_sck_active(false) { } SSP_MODULE::~SSP_MODULE() { if (!m_sink_set) { delete m_SDI_Sink; delete m_SCL_Sink; delete m_SS_Sink; } if (m_sdi_active && m_sdi) m_sdi->setSource(0); if (m_SdiSource) delete m_SdiSource; if (m_sdo_active && m_sdo) m_sdo->setSource(0); if (m_SdoSource) delete m_SdoSource; if (m_sck_active && m_sck) m_sck->setSource(0); if (m_SckSource) delete m_SckSource; if (m_spi) { delete m_spi; delete m_i2c; } if (m_ssp_if) delete m_ssp_if; if (m_bcl_if) delete m_bcl_if; } /* SSP1_MODULE adds SSPCON3 and SSPMSK to SSP_MODULE */ SSP1_MODULE::SSP1_MODULE(Processor *pCpu) : SSP_MODULE(pCpu), ssp1con3(pCpu, this) { sspmsk = new _SSPMSK(pCpu, "ssp1msk"); } SSP1_MODULE::~SSP1_MODULE() { delete sspmsk; } void SSP1_MODULE::set_sckPin(PinModule *_sckPin) { if (m_sck == _sckPin) return; // No change, do nothing m_sck = _sckPin; if(m_SckSource) delete m_SckSource; m_SckSource = new SCK_SignalSource(this, m_sck); } void SSP1_MODULE::set_sdoPin(PinModule *_sdoPin) { if (m_sdo == _sdoPin) return; // No change, do nothing m_sdo = _sdoPin; if(m_SdoSource) delete m_SdoSource; m_SdoSource = new SDO_SignalSource(this, m_sdo); } void SSP1_MODULE::set_sdiPin(PinModule *_sdiPin) { if (m_sdi == _sdiPin) return; // No change, do nothing m_sdi = _sdiPin; if(m_SdiSource) delete m_SdiSource; m_SdiSource = new SDI_SignalSource(this, m_sdi); } void SSP1_MODULE::set_ssPin(PinModule *_ssPin) { if (m_ss == _ssPin) return; // No change, do nothing m_ss = _ssPin; } void SSP1_MODULE::initialize( PIR_SET *ps, PinModule *SckPin, PinModule *SsPin, PinModule *SdoPin, PinModule *SdiPin, PicTrisRegister *_i2ctris, SSP_TYPE _ssptype ) { m_pirset = ps; m_sck = SckPin; m_ss = SsPin; m_sdo = SdoPin; m_sdi = SdiPin; m_i2c_tris = _i2ctris; m_ssptype = _ssptype; m_SckSource = new SCK_SignalSource(this, m_sck); m_SdoSource = new SDO_SignalSource(this, m_sdo); m_SdiSource = new SDI_SignalSource(this, m_sdi); if (! m_spi) { m_spi = new SPI_1(this, &sspcon, &sspstat, &sspbuf, &ssp1con3, &sspadd); m_i2c = new I2C_1(this, &sspcon, &sspstat, &sspbuf, &sspcon2, &sspadd, &ssp1con3); m_SDI_Sink = new SDI_SignalSink(this); m_SCL_Sink = new SCL_SignalSink(this); m_SS_Sink = new SS_SignalSink(this); } } void SPI::newSSPBUF(unsigned int newTxByte) { Dprintf(("enabled %d state %d\n", m_sspcon->isSSPEnabled(), m_state)); if (m_sspcon->isSSPEnabled()) { if (m_state == eIDLE || bits_transfered == 0) { m_SSPsr = newTxByte; SPIproto(("newSSPBUF send 0x%02x\n", m_SSPsr)); start_transfer(); } else { // Collision SPIproto(("newSSPBUF 0x%02x collision\n", m_SSPsr)); m_sspcon->setWCOL(); } } else { SPIproto(("newSSPBUF !SSPenabled m_SSPsr 0x%02x\n", m_SSPsr)); } } void SPI::start_transfer() { if (!m_sspcon || !m_sspstat) return; // load the shift register m_state = eACTIVE; bits_transfered = 0; unsigned int sspcon_val = m_sspcon->value.get(); unsigned int sspstat_val = m_sspstat->value.get(); if (verbose) cout << "SSP: SPI Starting transfer. byte=0x" << hex << m_SSPsr << endl; switch( sspcon_val & _SSPCON::SSPM_mask ) { case _SSPCON::SSPM_SPImaster4: case _SSPCON::SSPM_SPImaster16: case _SSPCON::SSPM_SPImaster64: case _SSPCON::SSPM_SPImasterAdd: // In master mode, the SDO line is always set at the start of the transfer m_sspmod->putStateSDO((m_SSPsr &(1<<7)) ? '1' : '0'); // Setup callbacks for clocks set_halfclock_break(); break; case _SSPCON::SSPM_SPImasterTMR2: m_sspmod->putStateSDO((m_SSPsr &(1<<7)) ? '1' : '0'); break; case _SSPCON::SSPM_SPIslaveSS: // The SS pin was pulled low if( sspstat_val & _SSPSTAT::CKE ) m_sspmod->putStateSDO((m_SSPsr &(1<<7)) ? '1' : '0'); break; case _SSPCON::SSPM_SPIslave: // I don't do any thing until first clock edge SPIproto(("SSPM_SPIslave start_transfer 0x%02x\n", m_SSPsr)); if( sspstat_val & _SSPSTAT::CKE ) m_sspmod->putStateSDO((m_SSPsr &(1<<7)) ? '1' : '0'); break; default: cout << "start_transfer: The selected SPI mode is unimplemented. mode=" << hex <<(sspcon_val & _SSPCON::SSPM_mask) << endl; } } void SPI::stop_transfer() { if (!m_sspcon || !m_sspstat || !m_sspbuf || !m_sspmod) return; if( m_state == eACTIVE ) { if( bits_transfered == 8 && !m_sspbuf->isFull() ) { m_SSPsr &= 0xff; if (verbose) cout << "SPI: Stoping transfer. Normal finish. Setting sspif and BF got=" << (m_SSPsr & 0xff) << endl; SPIproto(("Stoping transfer. Normal finish. Setting sspif and BF got=0x%02x\n" , (m_SSPsr & 0xff))); m_sspbuf->put_value(m_SSPsr & 0xff); m_sspbuf->setFullFlag(true); m_sspmod->set_sspif(); m_sspstat->put_value(m_sspstat->value.get() | _SSPSTAT::BF); } else if( bits_transfered == 8 && m_sspbuf->isFull() ) { if (verbose) cout << "SPI: Stopping transfer. SSPBUF Overflow setting SSPOV." << endl; SPIproto(("Stopping transfer. SSPBUF Overflow setting SSPOV.\n")); m_sspcon->setSSPOV(); m_sspmod->set_sspif(); // The real PIC sets sspif even with overflow } else { cout << "SPI: Stopping transfer. Cancel finish." << endl; // The transfer was canceled in some way } } else { if (verbose) cout << "SSP: Stopping transfer. State != ACTIVE." << endl; SPIproto(("Stopping transfer. State != ACTIVE.")); } m_state = eIDLE; } I2C::I2C(SSP_MODULE *_ssp_mod, _SSPCON *_sspcon, _SSPSTAT *_sspstat, _SSPBUF *_sspbuf, _SSPCON2 *_sspcon2, _SSPADD *_sspadd) : i2c_state(eIDLE) { m_sspmod = _ssp_mod; m_sspcon = _sspcon; m_sspstat = _sspstat; m_sspbuf = _sspbuf; m_sspcon2 = _sspcon2; m_sspadd = _sspadd; future_cycle = 0; cpu = m_sspmod->cpu; } I2C_1::I2C_1(SSP_MODULE *_ssp_mod, _SSPCON *_sspcon, _SSPSTAT *_sspstat, _SSPBUF *_sspbuf, _SSPCON2 *_sspcon2, _SSPADD *_sspadd, _SSP1CON3 *_ssp1con3) : I2C(_ssp_mod, _sspcon, _sspstat, _sspbuf, _sspcon2, _sspadd) { m_sspmod = _ssp_mod; m_sspcon3 = _ssp1con3; } void I2C::set_idle() { i2c_state = eIDLE; I2Cproto(("%s i2c_state = eIDLE\n", __FUNCTION__)); } bool I2C::isIdle() { return(i2c_state == eIDLE); return( (m_sspstat->value.get() & _SSPSTAT::RW) == 0 && (m_sspcon2->value.get() & ( _SSPCON2::ACKEN || _SSPCON2::RCEN || _SSPCON2::PEN || _SSPCON2::RSEN || _SSPCON2::SEN )) == 0 ); } bool I2C::rx_byte() { m_SSPsr = ( m_SSPsr << 1 ) | (m_sspmod->get_SDI_State()?1:0); bits_transfered++; if (bits_transfered == 8) { m_sspcon2->put_value(m_sspcon2->value.get() & ~_SSPCON2::RCEN); if (verbose & 2) cout << "CLK_RX_BYTE got byte=" << hex << m_SSPsr << endl; m_sspmod->SaveSSPsr(m_SSPsr & 0xff); m_sspmod->set_sspif(); set_idle(); return(true); } return(false); } void I2C::callback() { if (verbose & 2) cout << "I2C::callback i2c_state " << i2c_state << " phase=" << phase <setSDA(false); setBRG(); } else { m_sspcon2->value.put(m_sspcon2->value.get() & ~(_SSPCON2::SEN | _SSPCON2::RSEN)); m_sspmod->setSCL(false); m_sspmod->set_sspif(); set_idle(); } break; case CLK_RSTART: if (phase == 0) { m_sspmod->setSCL(true); } break; case CLK_STOP: if (phase == 0) { phase++; if (m_sspmod->get_SCL_State()) { setBRG(); } m_sspmod->setSCL(true); } else if (phase == 1) { phase++; setBRG(); m_sspmod->setSDA(true); } else { if (m_sspstat->value.get() & _SSPSTAT::P) { if (verbose & 2) cout << "I2C::callback stop finish\n"; m_sspmod->set_sspif(); } else { if (verbose & 2) cout << "I2C::callback stop fail\n"; m_sspmod->set_bclif(); } set_idle(); m_sspcon2->value.put(m_sspcon2->value.get() & ~_SSPCON2::PEN ); } break; case CLK_TX_BYTE: if(m_sspmod->get_SCL_State()) { bool n_ack = m_sspmod->get_SDI_State(); bits_transfered++; if (bits_transfered < 8) { m_SSPsr <<= 1; m_sspmod->setSCL(false); m_sspmod->setSDA((m_SSPsr & 0x80) == 0x80); } else if(bits_transfered == 8) { m_sspmod->setSCL(false); m_sspmod->setSDA(true); m_sspstat->put_value(m_sspstat->value.get() & ~_SSPSTAT::BF); if (verbose & 2) cout << "I2C::callback CLK_TX_BYTE sent\n"; } else { if (verbose & 2) { cout << "I2C::callback CLK_TX_BYTE _ACK=" << n_ack << " clock=" << get_cycles().get() << endl; } if (n_ack) m_sspcon2->put_value(m_sspcon2->value.get() | _SSPCON2::ACKSTAT); else m_sspcon2->put_value(m_sspcon2->value.get() & ~_SSPCON2::ACKSTAT); m_sspstat->put_value(m_sspstat->value.get() & ~_SSPSTAT::RW); m_sspmod->set_sspif(); set_idle(); m_sspmod->setSCL(false); } } else m_sspmod->setSCL(true); break; case CLK_RX_BYTE: if(m_sspmod->get_SCL_State()) { rx_byte(); m_sspmod->setSCL(false); } else m_sspmod->setSCL(true); break; default: cout << "I2C::callback unxpected i2c_state=" << dec << i2c_state << endl; break; } } void I2C::clock(bool clock_state) { unsigned int sspcon_val = m_sspcon->value.get(); unsigned int sspstat_val = m_sspstat->value.get(); if (verbose & 2) cout << "I2C::clock SCL=" << clock_state << " SDI=" << m_sspmod->get_SDI_State() << " i2c_state=" << i2c_state << " phase=" << phase << endl; if (clock_state) // Do read on clock high transition { switch(i2c_state) { case CLK_STOP: if (phase == 1) setBRG(); break; case CLK_ACKEN: if (phase == 1) { phase++; setBRG(); } break; case CLK_RSTART: if (phase == 0) { if (!m_sspmod->get_SDI_State()) { if (verbose) cout << "I2C::clock CLK_RSTART bus collision\n"; bus_collide(); m_sspmod->setSDA(true); } else { clrBRG(); start_bit(); } } else if (phase == 1) { setBRG(); } break; case RX_CMD: case RX_CMD2: case RX_DATA: if (bits_transfered < 8) { m_SSPsr = (m_SSPsr << 1) | (m_sspmod->get_SDI_State()?1:0); bits_transfered++; } break; case CLK_TX_BYTE: case CLK_RX_BYTE: setBRG(); break; default: break; } } else // Do writes of clock low transition { switch(i2c_state) { case CLK_ACKEN: clrBRG(); if (phase) { m_sspmod->setSCL(false); m_sspcon2->value.put( m_sspcon2->value.get() & ~(_SSPCON2::ACKEN )); m_sspmod->set_sspif(); set_idle(); } break; case CLK_START: clrBRG(); if (phase == 0 ) { if (verbose) cout << "I2C::clock CLK_START Bus collision\n"; bus_collide(); } else if (phase == 1) { m_sspcon2->value.put(m_sspcon2->value.get() & ~(_SSPCON2::SEN | _SSPCON2::RSEN)); } break; case CLK_RSTART: if (phase == 0) m_sspmod->setSDA(true); break; case RX_CMD: case RX_CMD2: if (bits_transfered == 8) { if ( ( m_SSPsr == 0 && (m_sspcon2->value.get() & _SSPCON2::GCEN) ) || match_address(m_SSPsr)) { I2Cproto(("got address sspsr=0x%2x\n", m_SSPsr)); } else { I2Cproto(("address not a match sspsr=0x%02x\n",m_SSPsr)); set_idle(); return; } } else if (bits_transfered == 9) { I2Cproto(("9 bits RXCMD\n")); if(end_ack()) { m_sspstat->put_value(sspstat_val & ~_SSPSTAT::DA); slave_command(); } return; } // Fall Through case RX_DATA: if (bits_transfered == 8) { I2Cproto(("RX_DATA 0x%02x\n", m_SSPsr&0xff)); if (verbose) cout << "I2C::clock RX_DATA or CMD m_SSPsr=" << hex << (m_SSPsr & 0xff) << endl; if (m_sspmod->SaveSSPsr(m_SSPsr & 0xff) ) // ACK ? { if (verbose) cout << "I2C::clock RX_DATA or CMD Send ACK\n"; m_sspmod->setSDA(false); } else { if (verbose) cout << "I2C::clock RX_DATA or CMD Send NACK\n"; m_sspmod->setSDA(true); } bits_transfered++; } else if (bits_transfered == 9) { end_ack(); m_sspstat->put_value(sspstat_val | _SSPSTAT::DA); } break; case CLK_TX_BYTE: case CLK_RX_BYTE: setBRG(); break; case TX_DATA: bits_transfered++; if (bits_transfered < 8) { m_SSPsr <<= 1; m_sspmod->setSDA((m_SSPsr & 0x80) == 0x80); } else if(bits_transfered == 8) { m_sspmod->setSDA(true); m_sspstat->put_value(sspstat_val & ~_SSPSTAT::BF); if (verbose) cout << "I2C::clock TX_DATA sent byte\n"; } else if(bits_transfered == 9) { m_sspmod->set_sspif(); if (m_sspmod->get_SDI_State()) // NACK { if (verbose) cout << "I2C::clock TX_DATA got NACK\n"; m_sspstat->put_value(sspstat_val & _SSPSTAT::BF); set_idle(); return; } m_sspstat->put_value(sspstat_val | _SSPSTAT::DA); if (sspstat_val & _SSPSTAT::RW) { sspcon_val &= ~ _SSPCON::CKP; m_sspcon->put_value(sspcon_val); if (verbose) cout << "I2C::clock TX_DATA Strech clock sspcon=" << hex << sspcon_val << endl; m_sspmod->setSCL(false); } } break; default: break; } } } bool I2C::match_address(unsigned int sspsr) { unsigned int mask = 0xfe; unsigned int sspm = m_sspcon->value.get() & _SSPCON::SSPM_mask; bool slave_10 = (sspm == _SSPCON::SSPM_I2Cslave_10bitaddr) || (sspm == _SSPCON::SSPM_I2Cslave_10bitaddr_ints); if (slave_10) { unsigned int ret = (sspsr & 0xff) ^ m_sspadd->get(); if ((sspsr & 0xf9) == 0xf0) // 1st byte 10 bit address { mask = 0x6; } else { mask = (m_sspmod->sspmsk) ? m_sspmod->sspmsk->value.get() : 0xff; } ret &= mask; return !(bool)ret; } if (m_sspmod->sspmsk) mask &= m_sspmod->sspmsk->value.get(); return !((sspsr ^ m_sspadd->get()) & mask); } void I2C_1::clock(bool clock_state) { unsigned int sspcon_val = m_sspcon->value.get(); unsigned int sspstat_val = m_sspstat->value.get(); if (verbose & 2) cout << "I2c_1::clock SCL=" << clock_state << " SDI=" << m_sspmod->get_SDI_State() << " i2c_state=" << i2c_state << " phase=" << phase << endl; if (clock_state) // Do read on clock high transition { switch(i2c_state) { case CLK_STOP: if (phase == 1) setBRG(); break; case CLK_ACKEN: if (phase == 1) { phase++; setBRG(); } break; case CLK_RSTART: if (phase == 0) { if (!m_sspmod->get_SDI_State()) { if (verbose) cout << "I2c_1::clock CLK_RSTART bus collision\n"; bus_collide(); m_sspmod->setSDA(true); } else { clrBRG(); start_bit(); } } else if (phase == 1) { setBRG(); } break; case RX_CMD: case RX_CMD2: case RX_DATA: if (bits_transfered < 8) { m_SSPsr = (m_SSPsr << 1) | (m_sspmod->get_SDI_State()?1:0); bits_transfered++; } else if (bits_transfered == 9 && m_sspcon3->value.get() & (_SSP1CON3::AHEN | _SSP1CON3::DHEN)) { m_sspcon3->put(m_sspcon3->value.get() & ~_SSP1CON3::ACKTIM); } break; case TX_DATA: if (bits_transfered == 9 && m_sspcon3->value.get() & (_SSP1CON3::AHEN | _SSP1CON3::DHEN)) { m_sspcon3->put(m_sspcon3->value.get() & ~_SSP1CON3::ACKTIM); } break; case CLK_TX_BYTE: case CLK_RX_BYTE: setBRG(); break; default: break; } } else // Do writes of clock low transition { switch(i2c_state) { case CLK_ACKEN: clrBRG(); if (phase) { m_sspmod->setSCL(false); m_sspcon2->value.put( m_sspcon2->value.get() & ~(_SSPCON2::ACKEN )); m_sspmod->set_sspif(); set_idle(); } break; case CLK_START: clrBRG(); if (phase == 0 ) { if (verbose) cout << "I2c_1::clock CLK_START Bus collision\n"; bus_collide(); } else if (phase == 1) { m_sspcon2->value.put(m_sspcon2->value.get() & ~(_SSPCON2::SEN | _SSPCON2::RSEN)); } break; case CLK_RSTART: if (phase == 0) m_sspmod->setSDA(true); break; case RX_CMD: case RX_CMD2: if (bits_transfered == 8) { if ( ( m_SSPsr == 0 && (m_sspcon2->value.get() & _SSPCON2::GCEN) ) || match_address(m_SSPsr)) { } else { cout << "READ_CMD address missmatch " << hex << m_SSPsr << " != " << m_sspadd->get() << endl; set_idle(); return; } } else if (bits_transfered == 9) { if(end_ack()) { m_sspstat->put_value(sspstat_val & ~_SSPSTAT::DA); slave_command(); } return; } // Fall Through case RX_DATA: if (bits_transfered == 8) { if (verbose) cout << "I2c_1::clock RX_DATA or CMD m_SSPsr=" << hex << (m_SSPsr & 0xff) << endl; if (m_sspcon->isI2CSlave(m_sspcon->value.get()) && ( (m_sspcon3->value.get() & _SSP1CON3::DHEN && i2c_state == RX_DATA) || (m_sspcon3->value.get() & _SSP1CON3::AHEN && (i2c_state == RX_CMD || i2c_state == RX_CMD2)) )) { unsigned int sspcon3_val = m_sspcon3->value.get(); m_sspmod->SaveSSPsr(m_SSPsr & 0xff); m_sspcon->value.put(m_sspcon->value.get() & ~_SSPCON::CKP); m_sspcon3->value.put(sspcon3_val | _SSP1CON3::ACKTIM); m_sspmod->setSCL(false); // clock low m_sspmod->set_sspif(); } else if (m_sspmod->SaveSSPsr(m_SSPsr & 0xff) ) // ACK ? { if (verbose) cout << "I2c_1::clock RX_DATA or CMD Send ACK\n"; m_sspmod->setSDA(false); } else { if (verbose) cout << "I2c_1::clock RX_DATA or CMD Send NACK\n"; m_sspmod->setSDA(true); } bits_transfered++; } else if (bits_transfered == 9) { m_sspstat->put_value(sspstat_val | _SSPSTAT::DA); if(end_ack() && m_sspmod->isI2CSlave() && (m_sspcon2->value.get() & _SSPCON2::SEN)) { m_sspcon->put(m_sspcon->value.get() & ~_SSPCON::CKP); } } break; case CLK_TX_BYTE: case CLK_RX_BYTE: setBRG(); break; case TX_DATA: bits_transfered++; if (bits_transfered < 8) { m_SSPsr <<= 1; m_sspmod->setSDA((m_SSPsr & 0x80) == 0x80); } else if(bits_transfered == 8) { m_sspmod->setSDA(true); m_sspstat->put_value(sspstat_val & ~_SSPSTAT::BF); if (verbose) cout << "I2c_1::clock TX_DATA sent byte\n"; if(m_sspcon3->value.get() & _SSP1CON3::AHEN) { m_sspcon3->value.put(m_sspcon3->value.get() | _SSP1CON3::ACKTIM); } } else if(bits_transfered == 9) { m_sspmod->set_sspif(); if (m_sspmod->get_SDI_State()) // NACK { if (verbose) cout << "I2c_1::clock TX_DATA got NACK\n"; m_sspcon2->put(m_sspcon2->value.get() | _SSPCON2::ACKSTAT); m_sspstat->put_value(sspstat_val & _SSPSTAT::BF); set_idle(); return; } m_sspstat->put_value(sspstat_val | _SSPSTAT::DA); if (sspstat_val & _SSPSTAT::RW) { m_sspcon2->put(m_sspcon2->value.get() & ~_SSPCON2::ACKSTAT); sspcon_val &= ~ _SSPCON::CKP; m_sspcon->put_value(sspcon_val); if (verbose) cout << "I2c_1::clock TX_DATA Strech clock sspcon=" << hex << sspcon_val << endl; m_sspmod->setSCL(false); } } break; default: break; } } } void I2C::slave_command() { unsigned int sspcon_val = m_sspcon->value.get(); unsigned int sspstat_val = m_sspstat->value.get(); if (verbose) cout << "I2C::slave_command m_SSPsr=" << hex << m_SSPsr << endl; if ( m_SSPsr == 0 && (m_sspcon2->value.get() & _SSPCON2::GCEN)) { i2c_state = RX_DATA; I2Cproto(("slave_command i2c_state = RX_DATA\n")); } else { if (verbose) cout << "I2c::slave_command i2c_state=" << i2c_state << " sspcon=" << sspcon_val << endl; switch( sspcon_val & _SSPCON::SSPM_mask ) { case _SSPCON::SSPM_I2Cslave_10bitaddr_ints: case _SSPCON::SSPM_I2Cslave_10bitaddr: if (i2c_state == RX_CMD && (m_SSPsr & 1)) { sspstat_val |= _SSPSTAT::RW; i2c_state = TX_DATA; I2Cproto(("slave_command i2c_state = TX_DATA\n")); m_sspmod->setSCL(false); // clock low sspcon_val &= ~ _SSPCON::CKP; m_sspcon->put_value(sspcon_val); } else { sspstat_val |= _SSPSTAT::UA; i2c_state = (i2c_state == RX_CMD2) ? RX_DATA : RX_CMD2; I2Cproto(("slave_command i2c_state = %s\n", i2c_state ==RX_DATA?"RX_DATA":"RX_CMD2")); } break; case _SSPCON::SSPM_I2Cslave_7bitaddr: case _SSPCON::SSPM_I2Cslave_7bitaddr_ints: if (i2c_state == RX_CMD && (m_SSPsr & 1)) { sspstat_val |= _SSPSTAT::RW; sspstat_val &= ~_SSPSTAT::BF; i2c_state = TX_DATA; I2Cproto(("slave_command i2c_state = TX_DATA\n")); sspcon_val &= ~ _SSPCON::CKP; m_sspcon->put_value(sspcon_val); m_sspmod->setSCL(false); // clock low } else { i2c_state = RX_DATA; I2Cproto(("slave_command i2c_state = RX_DATA\n")); } break; } m_sspstat->put_value(sspstat_val); } } bool I2C::end_ack() { m_sspmod->set_sspif(); bits_transfered = 0; if (m_sspmod->get_SDI_State()) // NACK { I2Cproto(("end_ack NACK\n")); if (verbose & 2) cout << "I2C::end_ack NACK\n"; set_idle(); return(false); } else { m_sspmod->setSDA(true); I2Cproto(("end_ack ACK\n")); if (verbose & 2) cout << "I2C::end_ack ACK\n"; return(true); } } void I2C::bus_collide() { m_sspcon2->value.put(m_sspcon2->value.get() & ~ (_SSPCON2::SEN | _SSPCON2::RSEN | _SSPCON2::PEN | _SSPCON2::RCEN | _SSPCON2::ACKEN)); m_sspmod->set_bclif(); set_idle(); } void I2C_1::bus_collide() { if (m_sspmod->isI2CMaster()) { m_sspcon2->value.put(m_sspcon2->value.get() & ~ (_SSPCON2::SEN | _SSPCON2::RSEN | _SSPCON2::PEN | _SSPCON2::RCEN | _SSPCON2::ACKEN)); m_sspmod->set_bclif(); } else if (m_sspmod->isI2CSlave() && (m_sspcon3->value.get() & _SSP1CON3::SBCDE)) m_sspmod->set_bclif(); set_idle(); } void I2C::newSSPADD(unsigned int newTxByte) { unsigned int sspstat_val = m_sspstat->value.get(); if (sspstat_val & _SSPSTAT::UA) { m_sspstat->put_value(sspstat_val & ~_SSPSTAT::UA); m_sspmod->setSCL(true); // turn off clock stretch } } void I2C::setBRG() { if (future_cycle) cout << "ERROR I2C::setBRG called with future_cycle=" << future_cycle << endl; future_cycle = get_cycles().get() + ((m_sspadd->get() &0x7f)/ 2) + 1; get_cycles().set_break(future_cycle, this); } void I2C::clrBRG() { if (future_cycle) { get_cycles().clear_break(this); future_cycle = 0; } } void I2C::newSSPBUF(unsigned int newTxByte) { if (!m_sspstat || !m_sspcon) return; unsigned int sspstat_val = m_sspstat->value.get(); unsigned int sspcon_val = m_sspcon->value.get(); if (m_sspcon2 && (sspcon_val & _SSPCON::SSPM_mask) == _SSPCON::SSPM_MSSPI2Cmaster) { if (isIdle()) { if (verbose) cout << "I2C::newSSPBUF send " << hex << newTxByte << endl; m_sspmod->setSCL(false); m_sspstat->put_value(sspstat_val | _SSPSTAT::BF | _SSPSTAT::RW); m_SSPsr = newTxByte; m_sspmod->setSDA((m_SSPsr & 0x80) == 0x80); bits_transfered = 0; i2c_state = CLK_TX_BYTE; I2Cproto(("%s i2c_state = CLK_TX_BYTE data %x\n", __FUNCTION__, newTxByte)); setBRG(); } else { cout << "I2C::newSSPBUF I2C not idle on write data=" << hex << newTxByte << endl; // Collision m_sspcon->setWCOL(); } } else { if (sspstat_val & _SSPSTAT::RW) { if (!(sspstat_val & _SSPSTAT::BF)) { if (verbose) cout << "I2C::newSSPBUF send " << hex << newTxByte << endl; m_SSPsr = newTxByte; m_sspstat->put_value(sspstat_val | _SSPSTAT::BF); m_sspmod->setSDA((m_SSPsr & 0x80) == 0x80); bits_transfered = 0; I2Cproto(("%s TX 0x%x\n", __FUNCTION__, newTxByte)); } else // Collision { cout << "I2C::newSSPBUF I2C not idle on write data=" << hex << newTxByte << endl; m_sspcon->setWCOL(); } } else cout << "I2C::newSSPBUF write SSPSTAT::RW not set\n"; } } void I2C::sda(bool data_val) { if (m_sspmod->get_SCL_State()) // Clock is high { unsigned int stat_val = m_sspstat->value.get(); unsigned int sspm = (m_sspcon->value.get() & _SSPCON::SSPM_mask); if (data_val) // Data going high - STOP { stat_val = (stat_val & _SSPSTAT::BF) | _SSPSTAT::P; if (! future_cycle) set_idle(); if (verbose) cout << "I2C::sda got STOP future_cycle=" << future_cycle << endl; } else // Data going low - START { switch (i2c_state) { case CLK_STOP: break; case CLK_START: if (phase == 0) { guint64 fc = get_cycles().get() + ((m_sspadd->get() &0x7f)/ 2) + 1; if (future_cycle) { phase++; if (verbose) cout << "I2C::sda BUS_CHECK fc=" << fc << " future_cycle=" << future_cycle << endl; get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } else { get_cycles().set_break(fc, this); future_cycle = fc; } } break; default: i2c_state = RX_CMD; I2Cproto(("%s i2c_state = RX_CMD\n", __FUNCTION__)); break; } stat_val = (stat_val & _SSPSTAT::BF) | _SSPSTAT::S; bits_transfered = 0; m_SSPsr = 0; if (verbose) cout << "I2C::sda got START "; } m_sspstat->put_value(stat_val); // interrupt ? if (sspm == _SSPCON::SSPM_I2Cslave_7bitaddr_ints || sspm == _SSPCON::SSPM_I2Cslave_10bitaddr_ints) { m_sspmod->set_sspif(); } } else // clock low { if (i2c_state == CLK_STOP) { if (verbose) cout << "I2C::sda CLK_STOP SDA low CLOCK low\n"; // setBRG(); } } } // uses sspcon3 void I2C_1::sda(bool data_val) { if (m_sspmod->get_SCL_State()) // Clock is high { unsigned int stat_val = m_sspstat->value.get(); unsigned int con3_val = m_sspcon3->value.get(); unsigned int sspm = (m_sspcon->value.get() & _SSPCON::SSPM_mask); if (data_val) // Data going high - STOP { stat_val = (stat_val & _SSPSTAT::BF) | _SSPSTAT::P; if (! future_cycle) set_idle(); if(con3_val & _SSP1CON3::PCIE && (sspm == _SSPCON::SSPM_I2Cslave_7bitaddr || sspm == _SSPCON::SSPM_I2Cslave_10bitaddr)) { m_sspmod->set_sspif(); } if (sspm == _SSPCON::SSPM_I2Cslave_7bitaddr_ints || sspm == _SSPCON::SSPM_I2Cslave_10bitaddr_ints) { m_sspmod->set_sspif(); } if (verbose) cout << "I2C::sda got STOP future_cycle=" << future_cycle << endl; } else // Data going low - START { switch (i2c_state) { case CLK_STOP: break; case CLK_START: if (phase == 0) { guint64 fc = get_cycles().get() + ((m_sspadd->get() &0x7f)/ 2) + 1; if (future_cycle) { phase++; if (verbose) cout << "I2C::sda BUS_CHECK fc=" << fc << " future_cycle=" << future_cycle << endl; get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } else { get_cycles().set_break(fc, this); future_cycle = fc; } } break; default: i2c_state = RX_CMD; I2Cproto(("%s i2c_state = RX_CMD\n", __FUNCTION__)); break; } stat_val = (stat_val & _SSPSTAT::BF) | _SSPSTAT::S; bits_transfered = 0; m_SSPsr = 0; if(con3_val & _SSP1CON3::SCIE && (sspm == _SSPCON::SSPM_I2Cslave_7bitaddr || sspm == _SSPCON::SSPM_I2Cslave_10bitaddr)) { m_sspmod->set_sspif(); } if (verbose) cout << "I2C::sda got START "; } m_sspstat->put_value(stat_val); // interrupt ? if (sspm == _SSPCON::SSPM_I2Cslave_7bitaddr_ints || sspm == _SSPCON::SSPM_I2Cslave_10bitaddr_ints) { m_sspmod->set_sspif(); } } else // clock low { if (i2c_state == CLK_STOP) { if (verbose) cout << "I2C::sda CLK_STOP SDA low CLOCK low\n"; // setBRG(); } } } /* master mode, begin reading a byte */ void I2C::master_rx() { if (verbose) cout << "I2C::master_rx SCL=" << m_sspmod->get_SCL_State() << " SDI=" << m_sspmod->get_SDI_State() << endl; m_sspmod->setSCL(false); m_sspmod->setSDA(true); bits_transfered = 0; m_SSPsr = 0; i2c_state = CLK_RX_BYTE; setBRG(); } /* master, begin start sequence SCL and SDA must be high, then force SDA low */ void I2C::start_bit() { if (m_sspmod->get_SCL_State() && m_sspmod->get_SDI_State()) { i2c_state = CLK_START; I2Cproto(("%s i2c_state = CLK_START\n", __FUNCTION__)); phase = 0; setBRG(); } else { if (verbose & 2) cout << "I2C::start_bit bus collision " << " SCL=" << m_sspmod->get_SCL_State() << " SDI=" << m_sspmod->get_SDI_State() << endl; bus_collide(); } } /* Master mode, begin rstart sequence bring SDA and SCL high, then SDA low with SCL high (start) */ void I2C::rstart_bit() { if (verbose) cout << "I2C::rstart_bit SCL=" << m_sspmod->get_SCL_State() << " SDI=" << m_sspmod->get_SDI_State() << endl; i2c_state = CLK_RSTART; I2Cproto(("%s i2c_state = CLK_RSTART\n", __FUNCTION__)); phase = 0; m_sspmod->setSCL(false); if (!m_sspmod->get_SCL_State()) { setBRG(); m_sspmod->setSDA(true); } else bus_collide(); } /* master, begin stop sequence drop SDA (mught cause start if SCL high) when SCL high, raise SDA (stop condition) */ void I2C::stop_bit() { i2c_state = CLK_STOP; I2Cproto(("%s i2c_state = CLK_STOP\n", __FUNCTION__)); phase = 0; m_sspmod->setSDA(false); if (!m_sspmod->get_SDI_State()) { setBRG(); } else bus_collide(); } /* master, begin ack sequence clock SCL low, set SDA as per ACKDT, clock SCL high */ void I2C::ack_bit() { if (verbose) cout << "I2C::ack_bit ACKDT=" << (m_sspcon2->value.get() & _SSPCON2::ACKDT) << endl; i2c_state = CLK_ACKEN; I2Cproto(("%s i2c_state = CLK_ACKEN\n", __FUNCTION__)); phase = 0; m_sspmod->setSCL(false); if (!m_sspmod->get_SCL_State()) { phase++; setBRG(); m_sspmod->setSDA((m_sspcon2->value.get() & _SSPCON2::ACKDT) ? true : false); } else bus_collide(); } void SSP_MODULE::initialize( PIR_SET *ps, PinModule *SckPin, PinModule *SsPin, PinModule *SdoPin, PinModule *SdiPin, PicTrisRegister *_i2ctris, SSP_TYPE _ssptype ) { m_pirset = ps; m_sck = SckPin; m_ss = SsPin; m_sdo = SdoPin; m_sdi = SdiPin; m_i2c_tris = _i2ctris; m_ssptype = _ssptype; if (! m_spi) { m_spi = new SPI(this, &sspcon, &sspstat, &sspbuf); m_i2c = new I2C(this, &sspcon, &sspstat, &sspbuf, &sspcon2, &sspadd); m_SDI_Sink = new SDI_SignalSink(this); m_SCL_Sink = new SCL_SignalSink(this); m_SS_Sink = new SS_SignalSink(this); m_SckSource = new SCK_SignalSource(this, m_sck); m_SdoSource = new SDO_SignalSource(this, m_sdo); m_SdiSource = new SDI_SignalSource(this, m_sdi); } } // this allows backward compatibility void SSP_MODULE::set_sspif() { if (m_ssp_if) m_ssp_if->Trigger(); else m_pirset->set_sspif(); } // this allows backward compatibility void SSP_MODULE::set_bclif() { if (m_bcl_if) m_bcl_if->Trigger(); else m_pirset->set_bclif(); } void SSP_MODULE::ckpSPI(unsigned int value) { if(m_spi && !m_spi->isIdle()) cout << "SPI: You just changed CKP in the middle of a transfer." << endl; switch( value & _SSPCON::SSPM_mask ) { case _SSPCON::SSPM_SPImaster4: case _SSPCON::SSPM_SPImaster16: case _SSPCON::SSPM_SPImaster64: case _SSPCON::SSPM_SPImasterAdd: if (m_SckSource) m_SckSource->putState( (value & _SSPCON::CKP) ? '1' : '0' ); break; case _SSPCON::SSPM_SPImasterTMR2: break; } } /* drive SCL by changing pin direction (with data low) */ void SSP_MODULE::setSCL(bool direction) { if (!m_sck || !m_i2c_tris) return; unsigned int pin = m_sck->getPinNumber(); unsigned int tris_val = m_i2c_tris->get_value(); if (!direction) tris_val &= ~(1<put(tris_val); } /* drive SDA by changing pin direction (with data low) */ void SSP_MODULE::setSDA(bool direction) { unsigned int pin = m_sdi->getPinNumber(); unsigned int tris_val = m_i2c_tris->get_value(); if (!direction) tris_val &= ~(1<put(tris_val); } /* deactivate SPI and I2C mode */ void SSP_MODULE::stopSSP(unsigned int old_value) { if (sspcon.isSPIActive(old_value)) { m_spi->stop_transfer(); m_sck->setSource(0); m_sdo->setSource(0); m_ss->getPin().newGUIname(m_ss->getPin().name().c_str()); m_sdo->getPin().newGUIname(m_sdo->getPin().name().c_str()); m_sdi->getPin().newGUIname(m_sdi->getPin().name().c_str()); m_sck->getPin().newGUIname(m_sck->getPin().name().c_str()); if (verbose) cout << "SSP: SPI turned off" << endl; } else if (sspcon.isI2CActive(old_value)) { m_i2c->set_idle(); m_sck->setSource(0); m_sdi->setSource(0); m_sck_active = false; m_sdi_active = false; m_sdi->getPin().newGUIname(m_sdi->getPin().name().c_str()); m_sck->getPin().newGUIname(m_sck->getPin().name().c_str()); if (verbose) cout << "SSP: I2C turned off" << endl; } } void SSP_MODULE::putStateSDO(char _state) { m_SdoSource->putState(_state); } void SSP_MODULE::putStateSCK(char _state) { m_SckSource->putState(_state); } /* activate SPI module */ void SSP_MODULE::startSSP(unsigned int value) { if (verbose) cout << "SSP: SPI turning on 0x" <addSink(m_SDI_Sink); m_SDI_State = m_sdi->getPin().getState(); } if (m_sck) { m_sck->addSink(m_SCL_Sink); m_SCL_State = m_sck->getPin().getState(); } if (m_ss) { m_ss->addSink(m_SS_Sink); m_SS_State = m_ss->getPin().getState(); } m_sink_set = true; } if (m_ss) { if ((value & _SSPCON::SSPM_mask) == _SSPCON::SSPM_SPIslaveSS) m_ss->getPin().newGUIname("SS"); else if (m_ss->getPin().GUIname() == string("SS")) m_ss->getPin().newGUIname(m_ss->getPin().name().c_str()); } switch( value & _SSPCON::SSPM_mask ) { case _SSPCON::SSPM_SPImasterTMR2: case _SSPCON::SSPM_SPImaster4: case _SSPCON::SSPM_SPImaster16: case _SSPCON::SSPM_SPImaster64: case _SSPCON::SSPM_SPImasterAdd: Dprintf(("SSP_MODULE case cmd %x\n", value & _SSPCON::SSPM_mask )); if (m_sck) { m_sck->setSource(m_SckSource); m_sck_active = true; m_sck->getPin().newGUIname("SCK"); } if (m_sdo) { m_sdo->setSource(m_SdoSource); m_sdo_active = true; m_sdo->getPin().newGUIname("SDO"); } if (m_sdi) m_sdi->getPin().newGUIname("SDI"); if (m_SckSource) m_SckSource->putState( (value & _SSPCON::CKP) ? '1' : '0' ); if (m_SdoSource) m_SdoSource->putState('0'); // BUG, required to put SDO in know state break; case _SSPCON::SSPM_SPIslave: case _SSPCON::SSPM_SPIslaveSS: if (m_sdo) { m_sdo->setSource(m_SdoSource); m_sdo_active = true; m_sdo->getPin().newGUIname("SDO"); } if (m_sdi) m_sdi->getPin().newGUIname("SDI"); if (m_sck) m_sck->getPin().newGUIname("SCK"); if (m_SdoSource) m_SdoSource->putState('0'); // BUG, required to put SDO in know state newSSPBUF(sspbuf.get_value()); break; case _SSPCON::SSPM_I2Cslave_7bitaddr: case _SSPCON::SSPM_I2Cslave_10bitaddr: case _SSPCON::SSPM_MSSPI2Cmaster: case _SSPCON::SSPM_I2Cfirmwaremaster: case _SSPCON::SSPM_I2Cslave_7bitaddr_ints: case _SSPCON::SSPM_I2Cslave_10bitaddr_ints: if (m_sdi) m_sdi->getPin().newGUIname("SDA"); if (m_sck) m_sck->getPin().newGUIname("SCL"); m_i2c->set_idle(); m_sck->setSource(m_SckSource); m_sdi->setSource(m_SdiSource); m_sck_active = true; m_sdi_active = true; m_sck->refreshPinOnUpdate(true); m_sdi->refreshPinOnUpdate(true); m_SdiSource->putState('0'); m_SckSource->putState('0'); m_sck->refreshPinOnUpdate(false); m_sdi->refreshPinOnUpdate(false); break; case _SSPCON::SSPM_LoadMaskFunction: break; default: cout << "SSP: start, unexpected SSPM select bits SSPM=" << hex << (value & _SSPCON::SSPM_mask) << endl;; break; } } /* process mode change or clock edge due to write to SSPCON */ void SSP_MODULE::changeSSP(unsigned int new_value, unsigned int old_value) { unsigned int diff = new_value ^ old_value; if (verbose) cout << "SSP_MODULE::changeSSP CKP new=" << hex << new_value << " old=" << old_value << endl; if (diff & _SSPCON::SSPM_mask) // mode changed { Dprintf(("SSP_MODULE stop %x start %x\n", old_value, new_value)); stopSSP(old_value); startSSP(new_value); } else if (diff & _SSPCON::CKP) { if (sspcon.isSPIActive(new_value)) ckpSPI(new_value); else if (sspcon.isI2CActive(new_value) && new_value & _SSPCON::CKP) { setSCL(true); } } } void SSP_MODULE::releaseSDIpin() { m_sdi_active = false; } void SSP_MODULE::releaseSDOpin() { m_sdo_active = false; } void SSP_MODULE::releaseSCKpin() { m_sck_active = false; } void SSP_MODULE::releaseSCLpin() { if (m_sck) { m_sck->setSource(0); m_sck_active = false; } m_sck = 0; } void SSP_MODULE::releaseSSpin() { if (m_SS_Sink) { delete m_SS_Sink; m_SS_Sink = 0; } m_ss = 0; } void SSP_MODULE::Sck_toggle() { m_SckSource->toggle();} /* process mode change or clock edge due to write to SSPCON */ void SSP1_MODULE::changeSSP(unsigned int new_value, unsigned int old_value) { unsigned int diff = new_value ^ old_value; if (verbose) cout << "SSP_MODULE::changeSSP CKP new=" << hex << new_value << " old=" << old_value << endl; if (diff & _SSPCON::SSPM_mask) // mode changed { Dprintf(("SSP_MODULE stop %x start %x\n", old_value, new_value)); stopSSP(old_value); startSSP(new_value); } else if (diff & _SSPCON::CKP) { if (sspcon.isSPIActive(new_value)) ckpSPI(new_value); else if (sspcon.isI2CActive(new_value) && (new_value & _SSPCON::CKP)) { if(ssp1con3.value.get() & (_SSP1CON3::AHEN | _SSP1CON3::DHEN)) { // set ack(yes = 0) if writing and release clock if ((sspstat.value.get() & _SSPSTAT::RW) == 0) setSDA(sspcon2.value.get() & _SSPCON2::ACKDT); setSCL(true); } else // RRRif(sspcon2.value.get() & _SSPCON2::SEN) { // release clock setSCL(true); } } } } //------------------------------------------------------------ // Called whenever the SDI/SDA input changes states. // void SSP_MODULE::SDI_SinkState(char new3State) { bool new_SDI_State = (new3State == '1' || new3State == 'W'); if (new_SDI_State == m_SDI_State) return; m_SDI_State = new_SDI_State; if(sspcon.isI2CActive(sspcon.value.get())) { if(m_i2c) m_i2c->sda(m_SDI_State); } } // Called when the SCK/SDI input changes state void SSP_MODULE::SCL_SinkState(char new3State) { bool new_SCL_State = (new3State == '1' || new3State == 'W'); SPIproto(("SCL_SinkState new %d old %d enabled %d m_SS_State %d\n", new_SCL_State, m_SCL_State, sspcon.isSSPEnabled(), m_SS_State)); if (new_SCL_State == m_SCL_State) return; m_SCL_State = new_SCL_State; if (!sspcon.isSSPEnabled() ) return; switch( sspcon.value.get() & _SSPCON::SSPM_mask ) { case _SSPCON::SSPM_SPIslaveSS: /* SS high during transfer for BSSP, suspends transfers which continues when SS goes low. None BSSP interfaces handled when SS goes high */ if (m_SS_State) return; // suspend transfer // Fall through case _SSPCON::SSPM_SPIslave: if (m_spi) m_spi->clock(m_SCL_State); break; case _SSPCON::SSPM_I2Cslave_7bitaddr: case _SSPCON::SSPM_I2Cslave_10bitaddr: case _SSPCON::SSPM_MSSPI2Cmaster: case _SSPCON::SSPM_I2Cfirmwaremaster: case _SSPCON::SSPM_I2Cslave_7bitaddr_ints: case _SSPCON::SSPM_I2Cslave_10bitaddr_ints: m_i2c->clock(m_SCL_State); } } /* on write to SSPBUF, pass on to either SPI or I2C if active */ void SSP_MODULE::newSSPBUF(unsigned int value) { if (!m_spi) { cout << "Warning bug, SPI initialization error " << __FILE__ << ":" << dec << __LINE__<newSSPBUF(value); else if(sspcon.isI2CActive(sspcon.value.get())) m_i2c->newSSPBUF(value); } /* on write to SSPADD, pass onto I2C if active */ void SSP_MODULE::newSSPADD(unsigned int value) { if(sspcon.isI2CActive(sspcon.value.get())) m_i2c->newSSPADD(value); } // clear BF flag void SSP_MODULE::rdSSPBUF() { sspstat.put_value(sspstat.value.get() & ~_SSPSTAT::BF); } void SSP_MODULE::SS_SinkState(char new3State) { m_SS_State = (new3State == '1' || new3State == 'W'); // If SS goes high in the middle of an SPI transfer while in slave_SS mode, // transfer is aborted unless BSSP which streches the clocking #ifdef SPI_PROTO if (sspcon.isSSPEnabled() && ((sspcon.value.get() & _SSPCON::SSPM_mask) == _SSPCON::SSPM_SPIslaveSS) ) { SPIproto(("SS State change to %d\n", m_SS_State)); } #endif if (!sspcon.isSSPEnabled() || ! m_SS_State || (sspcon.value.get() & _SSPCON::SSPM_mask) != _SSPCON::SSPM_SPIslaveSS || ! m_spi->isIdle() || ssp_type() == SSP_TYPE_BSSP) return; m_spi->stop_transfer(); } void SSP_MODULE::tmr2_clock() { unsigned int sspcon_val = sspcon.value.get(); if (! (sspcon_val & _SSPCON::SSPEN) || ((sspcon_val & _SSPCON::SSPM_mask) != _SSPCON::SSPM_SPImasterTMR2) || (m_spi && m_spi->isIdle())) return; Sck_toggle(); if (m_spi) m_spi->clock( get_SCL_State() ); } /* on write to SSPCON2 select master operation to initiate */ void SSP_MODULE::newSSPCON2(unsigned int value) { if (!m_i2c) return; if(value & _SSPCON2::SEN) m_i2c->start_bit(); else if(value & _SSPCON2::RSEN) m_i2c->rstart_bit(); else if (value & _SSPCON2::PEN) m_i2c->stop_bit(); else if (value & _SSPCON2::RCEN) m_i2c->master_rx(); else if (value & _SSPCON2::ACKEN) m_i2c->ack_bit(); } /* Process a received data byte if BF == 0 and SSPOV == 0 return true otherwise false if BF == 0 transfer data to SSPBUF and set BF if BF == 1 set SSPOV set SSPIF */ bool SSP_MODULE::SaveSSPsr(unsigned int value) { bool ret = false; unsigned int stat_val = sspstat.value.get(); unsigned int con_val = sspcon.value.get(); if ((stat_val & _SSPSTAT::BF) == 0) { if (verbose) cout << "SSP receive transfer " << hex << (value & 0xff) << " to SSPBUF\n"; sspbuf.put_value(value); sspstat.put_value(stat_val | _SSPSTAT::BF); if ((con_val & _SSPCON::SSPOV) == 0) ret = true; } else { sspcon.put_value(con_val | _SSPCON::SSPOV); cout << "SSP receive overflow\n"; } return(ret); } /* Process a received data byte if BF == 0 and SSPOV == 0 return true otherwise false if BF == 0 transfer data to SSPBUF and set BF if BF == 1 set SSPOV set SSPIF */ bool SSP1_MODULE::SaveSSPsr(unsigned int value) { bool ret = false; unsigned int stat_val = sspstat.value.get(); unsigned int con_val = sspcon.value.get(); if ((stat_val & _SSPSTAT::BF) == 0) { if (verbose) cout << "SSP receive transfer " << hex << (value & 0xff) << " to SSPBUF\n"; if ((con_val & _SSPCON::SSPOV) == 0 || (isI2CSlave() && ssp1con3.value.get() & _SSP1CON3::BOEN)) { sspstat.put_value(stat_val | _SSPSTAT::BF); sspbuf.put_value(value); ret = true; } } else { sspcon.put_value(con_val | _SSPCON::SSPOV); cout << "SSP receive overflow\n"; } return(ret); } //----------------------------------------------------------- //------------------------------------------------------------------- _SSPCON2::_SSPCON2(Processor *pCpu, SSP_MODULE *pSSP) : sfr_register(pCpu, "sspcon2","Synchronous Serial Port Control"), m_sspmod(pSSP) { } /* write to SSPCON2 without processing data */ void _SSPCON2::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } /* If a command is currently active, lower 5 bits of register cannot be changed if no command is currently active, activate command and write data */ void _SSPCON2::put(unsigned int new_value) { unsigned int old_value = value.get(); unsigned int diff = old_value ^ new_value; unsigned int mask = (ACKEN|RCEN|PEN|RSEN|SEN); unsigned int old_active; //Allow SEN to change unless I2CMaster (required for slave) if (!m_sspmod->isI2CMaster()) mask &= ~SEN; old_active = old_value & mask; if (verbose & 2) cout << "_SSPCON2::put " << hex << new_value << endl; if (!diff) return; // nothing to do // if I2C not idle, do not change bits in mask if (!m_sspmod->isI2CIdle() && (diff & mask)) { cout << "Warrning SSPCON::put I2C not idle and new value " << hex << new_value << " changes one of following bits " << mask << endl; put_value((new_value & ~mask) | old_active); } // Master and only a new command bit to process else if (!old_active && m_sspmod->isI2CMaster()) { switch (new_value & (ACKEN|RCEN|PEN|RSEN|SEN)) { case ACKEN: case RCEN: case PEN: case RSEN: case SEN: put_value(new_value); m_sspmod->newSSPCON2(new_value); break; case 0: // just write value put_value(new_value); break; default: cout << "SSPCON2 cannot select more than one function at a time\n"; break; } } else put_value(new_value); } //----------------------------------------------------------- //------------------------------------------------------------------- _SSP1CON3::_SSP1CON3(Processor *pCpu, SSP1_MODULE *pSSP) : sfr_register(pCpu, "ssp1con3","Synchronous Serial Port Control 3"), m_sspmod(pSSP) { } /* write to SSP1CON3 without processing data */ void _SSP1CON3::put_value(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } void _SSP1CON3::put(unsigned int new_value) { if (verbose & 2) cout << "_SSP1CON3::put " << hex << new_value << endl; put_value(new_value & ~ACKTIM); // ACKTIM not writable by user } gpsim-0.30.0/src/16bit-registers.cc0000664000076400007640000010001113117352060013663 00000000000000/* Copyright (C) 1998 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "16bit-registers.h" #include "16bit-processors.h" #include "interface.h" #include "stimuli.h" #include "clock_phase.h" //-------------------------------------------------- // member functions for the FSR class //-------------------------------------------------- // FSRL::FSRL(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } void FSRL::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); value.put(new_value & 0xff); // iam->fsr_delta = 0; iam->update_fsr_value(); } void FSRL::put_value(unsigned int new_value) { put(new_value); update(); cpu16->indf->update(); } FSRH::FSRH(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } void FSRH::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0x0f); iam->update_fsr_value(); } void FSRH::put_value(unsigned int new_value) { put(new_value); update(); cpu16->indf->update(); } INDF16::INDF16(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } void INDF16::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); iam->fsr_value += iam->fsr_delta; iam->fsr_delta = 0; iam->put(new_value); } void INDF16::put_value(unsigned int new_value) { put(new_value); update(); } unsigned int INDF16::get() { trace.raw(read_trace.get() | value.get()); iam->fsr_value += iam->fsr_delta; iam->fsr_delta = 0; return(iam->get()); } unsigned int INDF16::get_value() { return(iam->get_value()); } //------------------------------------------------ // PREINC PREINC::PREINC(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } unsigned int PREINC::get() { trace.raw(read_trace.get() | value.get()); //trace.register_read(address,value.get()); iam->preinc_fsr_value(); return(iam->get()); } unsigned int PREINC::get_value() { return(iam->get_value()); } void PREINC::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); //trace.register_write(address,new_value); iam->preinc_fsr_value(); iam->put(new_value); } void PREINC::put_value(unsigned int new_value) { put(new_value); update(); } //------------------------------------------------ // POSTINC POSTINC::POSTINC(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } unsigned int POSTINC::get() { trace.raw(read_trace.get() | value.get()); iam->postinc_fsr_value(); return(iam->get()); } unsigned int POSTINC::get_value() { return(iam->get_value()); } void POSTINC::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); iam->postinc_fsr_value(); iam->put(new_value); } void POSTINC::put_value(unsigned int new_value) { put(new_value); update(); } //------------------------------------------------ // POSTDEC POSTDEC::POSTDEC(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } unsigned int POSTDEC::get() { trace.raw(read_trace.get() | value.get()); iam->postdec_fsr_value(); return(iam->get()); } unsigned int POSTDEC::get_value() { return(iam->get_value()); } void POSTDEC::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); iam->postdec_fsr_value(); iam->put(new_value); } void POSTDEC::put_value(unsigned int new_value) { put(new_value); update(); } //------------------------------------------------ // PLUSW PLUSW::PLUSW(Processor *pCpu, const char *pName, const char *pDesc, Indirect_Addressing *pIAM) : sfr_register(pCpu,pName,pDesc), iam(pIAM) { } unsigned int PLUSW::get() { trace.raw(read_trace.get() | value.get()); int destination = iam->plusw_fsr_value(); if(destination >= 0) return (cpu_pic->registers[destination]->get()); else return 0; } unsigned int PLUSW::get_value() { int destination = iam->plusw_fsr_value(); if(destination >= 0) return (cpu_pic->registers[destination]->get_value()); else return 0; } void PLUSW::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); //trace.register_write(address,new_value); int destination = iam->plusw_fsr_value(); if(destination >= 0) cpu_pic->registers[destination]->put(new_value); } void PLUSW::put_value(unsigned int new_value) { int destination = iam->plusw_fsr_value(); if(destination >= 0) cpu_pic->registers[destination]->put_value(new_value); update(); if(destination >= 0) cpu_pic->registers[destination]->update(); } //------------------------------------------------ Indirect_Addressing::Indirect_Addressing(pic_processor *pCpu, const string &n) : fsrl(pCpu, (string("fsrl")+n).c_str(), "FSR Low", this), fsrh(pCpu, (string("fsrh")+n).c_str(), "FSR High", this), indf(pCpu, (string("indf")+n).c_str(), "Indirect Register", this), preinc(pCpu, (string("preinc")+n).c_str(), "Pre Increment Indirect", this), postinc(pCpu, (string("postinc")+n).c_str(), "Post Increment Indirect", this), postdec(pCpu, (string("postdec")+n).c_str(), "Post Decrement Indirect", this), plusw(pCpu, (string("plusw")+n).c_str(), "Literal Offset Indirect", this) { /* fsrl.iam = this; fsrh.iam = this; indf.iam = this; preinc.iam = this; postinc.iam = this; postdec.iam = this; plusw.iam = this; */ current_cycle = (guint64)(-1); // Not zero! See bug #3311944 fsr_value = 0; fsr_state = 0; fsr_delta = 0; cpu = pCpu; } /* * put - Each of the indirect registers associated with this * indirect addressing class will call this routine to indirectly * write data. */ void Indirect_Addressing::put(unsigned int new_value) { /* unsigned int midbits; if( ((fsr_value & 0xfc7) == 0xfc3) || ((fsr_value & 0xfc4) == 0xfc4)) { midbits = (fsr_value >> 3) & 0x7; if(midbits >= 3 && midbits <= 5) return; } */ if(is_indirect_register(fsr_value)) return; cpu_pic->registers[get_fsr_value()]->put(new_value); } /* * get - Each of the indirect registers associated with this * indirect addressing class will call this routine to indirectly * retrieve data. */ unsigned int Indirect_Addressing::get() { // unsigned int midbits; // See the comment in Indirect_Addressing::put about fsr address checking if(is_indirect_register(fsr_value)) return 0; else /* if( ((fsr_value & 0xfc7) == 0xfc3) || ((fsr_value & 0xfc4) == 0xfc4)) { midbits = (fsr_value >> 3) & 0x7; if(midbits >= 3 && midbits <= 5) return 0; } */ return cpu_pic->registers[get_fsr_value()]->get(); } /* * get - Each of the indirect registers associated with this * indirect addressing class will call this routine to indirectly * retrieve data. */ unsigned int Indirect_Addressing::get_value() { /* unsigned int midbits; See the comment in Indirect_Addressing::put about fsr address checking if( ((fsr_value & 0xfc7) == 0xfc3) || ((fsr_value & 0xfc4) == 0xfc4)) { midbits = (fsr_value >> 3) & 0x7; if(midbits >= 3 && midbits <= 5) return 0; } */ if(is_indirect_register(fsr_value)) return 0; else return cpu_pic->registers[get_fsr_value()]->get_value(); } void Indirect_Addressing::put_fsr(unsigned int new_fsr) { fsrl.put(new_fsr & 0xff); fsrh.put((new_fsr>>8) & 0x0f); } /* * update_fsr_value - This routine is called by the FSRL and FSRH * classes. It's purpose is to update the 16-bit (actually 12-bit) * address formed by the concatenation of FSRL and FSRH. * */ void Indirect_Addressing::update_fsr_value() { if(current_cycle != get_cycles().get()) { fsr_value = (fsrh.value.get() << 8) | fsrl.value.get(); fsr_delta = 0; } } /* * preinc_fsr_value - This member function pre-increments the current * fsr_value. If the preinc access is a read-modify-write instruction * (e.g. bcf preinc0,1 ) then the increment operation should occur * only once. */ void Indirect_Addressing::preinc_fsr_value() { if(current_cycle != get_cycles().get()) { fsr_value += (fsr_delta+1); fsr_delta = 0; current_cycle = get_cycles().get(); put_fsr(fsr_value); } } void Indirect_Addressing::postinc_fsr_value() { if(current_cycle != get_cycles().get()) { fsr_value += fsr_delta; fsr_delta = 1; current_cycle = get_cycles().get(); put_fsr(fsr_value+1); } } void Indirect_Addressing::postdec_fsr_value() { if(current_cycle != get_cycles().get()) { fsr_value += fsr_delta; fsr_delta = -1; current_cycle = get_cycles().get(); put_fsr(fsr_value-1); } } int Indirect_Addressing::plusw_fsr_value() { fsr_value += fsr_delta; fsr_delta = 0; int signExtendedW = cpu_pic->Wreg->value.get() | ((cpu_pic->Wreg->value.get() > 127) ? 0xf00 : 0); unsigned int destination = (fsr_value + signExtendedW) & _16BIT_REGISTER_MASK; if(is_indirect_register(destination)) return -1; else return destination; } int Indirect_Addressing::plusk_fsr_value(int k) { fsr_value += fsr_delta; fsr_delta = 0; unsigned int destination = (fsr_value + k) & _16BIT_REGISTER_MASK; if(is_indirect_register(destination)) return -1; else return destination; } //------------------------------------------------ void Fast_Stack::init(_16bit_processor *new_cpu) { cpu = new_cpu; } void Fast_Stack::push() { w = cpu->Wreg->value.get(); status = cpu->status->value.get(); bsr = cpu->bsr.value.get(); } void Fast_Stack::pop() { //cout << "popping fast stack\n"; cpu->Wreg->put(w); cpu->status->put(status); cpu->bsr.put(bsr); } //-------------------------------------------------- // member functions for the PCL base class //-------------------------------------------------- PCL16::PCL16(Processor *pCpu, const char *pName, const char *pDesc) : PCL(pCpu,pName,pDesc) { } unsigned int PCL16::get() { value.put(cpu_pic->pc->get_value() & 0xff); return((value.get()+2) & 0xff); } unsigned int PCL16::get_value() { value.put(cpu_pic->pc->get_value() & 0xff); return((value.get()) & 0xff); } //-------------------------------------------------- // Program_Counter16 // The Program_Counter16 is almost identical to Program_Counter. // The major difference is that the PC counts by 2 in the 16bit core. Program_Counter16::Program_Counter16(Processor *pCpu) : Program_Counter("pc","Program Counter", pCpu) { if(verbose) cout << "pc constructor 16\n"; } //-------------------------------------------------- // computed_goto - update the program counter. Anytime the pcl register is written to // by the source code we'll pass through here. // // void Program_Counter16::computed_goto(unsigned int new_address) { // cout << "Program_Counter16::computed_goto \n"; trace.raw(trace_other | (value<<1)); // Use the new_address and the cached pclath // to generate the destination address: value = ( (new_address | cpu_pic->get_pclath_branching_modpcl() )>>1); if (value >= memory_size) value -= memory_size; update_pcl(); // The instruction modifying the PCL will also increment the program counter. // So, pre-compensate the increment with a decrement: value--; // The computed goto is a 2-cycle operation. The first cycle occurs within // the instruction (i.e. via the ::increment() method). The second cycle occurs // here: cpu_pic->mExecute2ndHalf->advance(); } //-------------------------------------------------- // put_value - Change the program counter without affecting the cycle counter // (This is what's called if the user changes the pc.) void Program_Counter16::put_value(unsigned int new_value) { if (verbose) cout << "Program_Counter16::put_value 0x" << hex << new_value << '\n'; trace.raw(trace_other | (value<<1)); // RP - The new_value passed in is a byte address, but the Program_Counter16 // class's internal value is a word address value = (new_value/2); if (value >= memory_size) value -= memory_size; cpu_pic->pcl->value.put(new_value & 0xfe); // RP - removed these lines as setting the actual PC should not affect the latches // cpu_pic->pclath->value.put((new_value >> 8) & 0xff); // cpu16->pclatu.value.put((new_value >> 16) & 0xff); cpu_pic->pcl->update(); cpu_pic->pclath->update(); update(); } //------------------------------------------------ // get_value() // unsigned int Program_Counter16::get_value() { return value << 1; } //-------------------------------------------------- // update_pcl - Updates the PCL from within the Program_Counter class. // void Program_Counter16::update_pcl() { // For 16 bit devices the PCL will be Program_Counter*2 cpu_pic->pcl->value.put((value<<1) & 0xff); } //------------------------------------------------ // TOSU TOSU::TOSU(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) {} unsigned int TOSU::get() { value.put((stack->get_tos() >> 16) & 0x1f); trace.raw(read_trace.get() | value.get()); return(value.get()); } unsigned int TOSU::get_value() { value.put((stack->get_tos() >> 16) & 0x1f); return(value.get()); } void TOSU::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); stack->put_tos( (stack->get_tos() & 0xffe0ffff) | ( (new_value & 0x1f) << 16)); } void TOSU::put_value(unsigned int new_value) { stack->put_tos( (stack->get_tos() & 0xffe0ffff) | ( (new_value & 0x1f) << 16)); update(); } //------------------------------------------------ // STKPTR STKPTR16::STKPTR16(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) {} void STKPTR16::put_value(unsigned int new_value) { stack->pointer = new_value & stack->stack_mask; value.put(new_value); update(); } void STKPTR16::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } //-------------------------------------------------- // Stack16::Stack16(Processor *pCpu) : Stack(pCpu), stkptr(pCpu, "stkptr", "Stack pointer"), tosl(pCpu, "tosl", "Top of Stack low byte"), tosh(pCpu, "tosh", "Top of Stack high byte"), tosu(pCpu, "tosu", "Top of Stack upper byte") { stkptr.stack = this; tosl.stack = this; tosh.stack = this; tosu.stack = this; } Stack16::~Stack16() { pic_processor *pCpu = dynamic_cast(cpu); if (pCpu) { pCpu->remove_sfr_register(&stkptr); pCpu->remove_sfr_register(&tosl); pCpu->remove_sfr_register(&tosh); pCpu->remove_sfr_register(&tosu); } } // pop of empty stack sets undeflow and returns 0 unsigned int Stack16::pop() { if(pointer <= 0) { pointer = 0; stack_underflow(); return(0); } --pointer; unsigned int stkptr_status = stkptr.value.get() & ~stack_mask; stkptr.value.put((pointer & stack_mask) | stkptr_status); return(contents[pointer & stack_mask] >> 1); } // When stack is full last(top) entry is overwritten bool Stack16::push(unsigned int address) { contents[pointer & stack_mask] = address << 1; if(pointer >= (int)stack_mask) { pointer = stack_mask; return stack_overflow(); } pointer++; stkptr.value.put((pointer & stack_mask) | (stkptr.value.get() & ~stack_mask)); return true; } void Stack16::reset(RESET_TYPE r) { unsigned int reg_value; if (r != POR_RESET && r != BOD_RESET) reg_value = stkptr.value.get() & ~stack_mask; else reg_value = 0; pointer = 0; stkptr.value.put( reg_value); } bool Stack16::stack_underflow() { stkptr.value.put(STKPTR::STKUNF); // don't decrement past 0, signalize STKUNF if(STVREN) { cpu->reset(STKUNF_RESET); return false; } cout <<"Stack undeflow\n"; return true; } bool Stack16::stack_overflow() { stkptr.value.put( STKPTR::STKOVF | (pointer & stack_mask)); if(STVREN) { cpu->reset(STKOVF_RESET); return false; } cout << "Stack overflow\n"; return true; } //-------------------------------------------------- // member functions for the RCON base class //-------------------------------------------------- RCON::RCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { } //-------------------------------------------------- // member functions for the CPUSTA base class //-------------------------------------------------- CPUSTA::CPUSTA(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { } //-------------------------------------------------- // member functions for the T0CON base class //-------------------------------------------------- T0CON::T0CON(Processor *pCpu, const char *pName, const char *pDesc) : OPTION_REG(pCpu,pName,pDesc) { por_value = RegisterValue(0xff,0); wdtr_value = RegisterValue(0xff,0); } void T0CON::put(unsigned int new_value) { unsigned int old_value = value.get(); trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); value.put(new_value); if (new_value == old_value) return; // new_prescale causes issues in 16 bit mode, so save current tmr0l and // tmr0h values , call new_prescale (if required), and then restart timer // using saved values // unsigned int initialTmr0value = (cpu16->tmr0l.value.get() & 0xff) | (( (value.get() & T08BIT)) ? 0: ((cpu16->tmr0h.value.get() & 0xff)<<8)); cpu16->option_new_bits_6_7(value.get() & (BIT6 | BIT7)); // %%%FIX ME%%% - can changing the state of TOSE cause the timer to // increment if tmr0 is being clocked by an external clock? // if( (value.get() ^ old_value) & (T0CS | T0SE | PSA | PS2 | PS1 | PS0)) cpu16->tmr0l.new_prescale(); if(value.get() & TMR0ON) { cpu16->tmr0l.start(initialTmr0value); } else cpu16->tmr0l.stop(); } //-------------------------------------------------- void T0CON::initialize() { // cpu16->tmr0l.new_prescale(); cpu16->wdt.set_postscale( (value.get() & PSA) ? (value.get() & ( PS2 | PS1 | PS0 )) : 0); cpu16->option_new_bits_6_7(value.get() & (T0CS | BIT6 | BIT7)); } //-------------------------------------------------- TMR0H::TMR0H(Processor *pCpu, const char *pName, const char *pDesc) :sfr_register(pCpu,pName,pDesc) { } //-------------------------------------------------- void TMR0H::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & 0xff); } //-------------------------------------------------- void TMR0H::put_value(unsigned int new_value) { value.put(new_value & 0xff); } unsigned int TMR0H::get() { trace.raw(read_trace.get() | value.get()); //trace.register_read(address,value.get()); return(value.get()); } unsigned int TMR0H::get_value() { return(value.get()); } //-------------------------------------------------- // TMR0_16 member functions // TMR0_16::TMR0_16(Processor *pCpu, const char *pName, const char *pDesc) : TMR0(pCpu,pName,pDesc), t0con(0), intcon(0), tmr0h(0), value16(0) { } //-------------------------------------------------- // TMR0_16::get_prescale // // If the prescaler is assigned to the WDT (and not TMR0) // then return 0 // other wise // then return the Prescale select bits (plus 1) // unsigned int TMR0_16::get_prescale() { if(t0con->value.get() & 0x8) return 0; else return ((t0con->value.get() & 7) + 1); } void TMR0_16::set_t0if() { intcon->set_t0if(); if (m_t1gcon) { m_t1gcon->T0_gate(true); // Spec sheet does not indicate when the overflow signal // is cleared, so I am assuming it is just a pulse. RRR m_t1gcon->T0_gate(false); } } bool TMR0_16::get_t0cs() { return (t0con->value.get() & 0x20) != 0; } void TMR0_16::initialize() { t0con = &cpu16->t0con; intcon = &cpu16->intcon; tmr0h = &cpu16->tmr0h; } unsigned int TMR0_16::max_counts() { if(t0con->value.get() & T0CON::T08BIT) return 0x100; else return 0x10000; } void TMR0_16::start(int restart_value, int sync) { m_pOptionReg = t0con; TMR0::start(restart_value, sync); } void TMR0_16::put_value(unsigned int new_value) { value.put(new_value & 0xff); value16 = (new_value & 0xff) | (tmr0h ? (tmr0h->get_value()<<8) : 0); if(t0con->value.get() & T0CON::TMR0ON) { if(t0con->value.get() & T0CON::T08BIT) TMR0::put_value(new_value); else start(value16); } else { // TMR0 is not enabled } } // %%%FIX ME%%% void TMR0_16::increment() { // cout << "_TMR0 increment because of external clock "; trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); if(--prescale_counter == 0) { prescale_counter = prescale; if(t0con->value.get() & T0CON::T08BIT) { if(value.get() == 255) { value.put(0); set_t0if(); } else value.put(value.get()+1); } else { if(value.get() == 255) { value.put(0); if(tmr0h->value.get() == 255) { tmr0h->put(0); set_t0if(); } else tmr0h->value.put(tmr0h->value.get()+1); } else { value.put(value.get()+1); } } } // cout << value << '\n'; } unsigned int TMR0_16::get_value() { if(t0con->value.get() & T0CON::TMR0ON) { // If TMR0L:H is configured as an 8-bit timer, then treat as an 8-bit timer if(t0con->value.get() & T0CON::T08BIT) { if (tmr0h) tmr0h->put_value( (value16>>8)&0xff); return(TMR0::get_value()); } value16 = (int) ((get_cycles().get() - last_cycle)/ prescale); value.put(value16 & 0xff); } return(value.get()); } unsigned int TMR0_16::get() { trace.raw(read_trace.get() | value.get()); get_value(); if(t0con->value.get() & T0CON::T08BIT) return value.get(); // reading the low byte of tmr0 latches in the high byte. tmr0h->put_value((value16 >> 8)&0xff); return value.get(); } void TMR0_16::callback() { //cout<<"_TMR0 rollover: " << hex << cycles.value << '\n'; if((t0con->value.get() & T0CON::TMR0ON) == 0) { cout << " tmr0 isn't turned on\n"; return; } TMR0::callback(); // Let the parent class handle the lower eight bits //Now handle the upper 8 bits: if(future_cycle && !(t0con->value.get() & T0CON::T08BIT)) { // 16-bit mode tmr0h->put_value(0); } } void TMR0_16::callback_print() { cout << "TMR0_16 " << name() << " CallBack ID " << CallBackID << '\n'; } void TMR0_16::sleep() { if (verbose) cout << "TMR0_16::sleep state=" << state << "\n"; if((state & RUNNING)) { TMR0::stop(); state = SLEEPING; } } void TMR0_16::wake() { if (verbose) cout << "TMR0_16::wake state=" << state << "\n"; if ((state & SLEEPING)) { if (! (state & RUNNING)) { state = STOPPED; start(value.get(), 0); } else state &= ~SLEEPING; } } //-------------------------------------------------- // T3CON T3CON::T3CON(Processor *pCpu, const char *pName, const char *pDesc) : T1CON(pCpu,pName,pDesc), ccpr1l(0),ccpr2l(0),tmr1l(0), t1con(0) {} void T3CON::put(unsigned int new_value) { int diff = (value.get() ^ new_value); if(diff & (T3CCP1 | T3CCP2)) { switch(new_value & (T3CCP1 | T3CCP2)) { case 0: ccpr1l->assign_tmr(tmr1l); // Both CCP modules use TMR1 as their source ccpr2l->assign_tmr(tmr1l); break; case T3CCP1: ccpr1l->assign_tmr(tmr1l); // CCP1 uses TMR1 ccpr2l->assign_tmr(tmrl); // CCP2 uses TMR3 break; default: ccpr1l->assign_tmr(tmrl); // Both CCP modules use TMR3 as their source ccpr2l->assign_tmr(tmrl); } } // Let the T1CON class deal with everything else. T1CON::put(new_value & ~(T3CCP1 | T3CCP2)); } //-------------------------------------------------- // TMR3_MODULE // // TMR3_MODULE::TMR3_MODULE() { t3con = 0; pir_set = 0; } void TMR3_MODULE::initialize(T3CON *t3con_, PIR_SET *pir_set_) { t3con = t3con_; pir_set = pir_set_; } //------------------------------------------------------------------- // // Table Reads and Writes // // The 18cxxx family provides a peripheral that will allow the program // memory to read and write to itself. // //------------------------------------------------------------------- TBL_MODULE::TBL_MODULE(_16bit_processor *pCpu) : EEPROM_EXTND(pCpu, 0), cpu(pCpu), tablat(pCpu,"tablat"), tblptrl(pCpu,"tblptrl"), tblptrh(pCpu,"tblptrh"), tblptru(pCpu,"tblptru") { } //void TBL_MODULE::initialize(_16bit_processor *new_cpu) //{ // cpu = new_cpu; //} //------------------------------------------------------------------- // void TBL_MODULE::increment() // // This function increments the 24-bit ptr that is formed by the // concatenation of tabptrl,tabptrh, and tabptru. It is called by // the TBLRD and TBLWT pic instructions when the auto-increment // operand is specified (e.g. TBLWT *+ ) // // // Inputs: none // Outputs: none // //------------------------------------------------------------------- void TBL_MODULE::increment() { if(tblptrl.value.get() >= 0xff) { tblptrl.put(0); if(tblptrh.value.get() >= 0xff) { tblptrh.put(0); tblptru.put(tblptru.value.get() + 1); } else { tblptrh.put(tblptrh.value.get() + 1); } } else tblptrl.put(tblptrl.value.get() + 1); } //------------------------------------------------------------------- //------------------------------------------------------------------- void TBL_MODULE::decrement() { if(tblptrl.value.get() == 0) { tblptrl.put(0xff); if(tblptrh.value.get() == 0) { tblptrh.put(0xff); tblptru.put(tblptru.value.get() - 1); } else { tblptrh.put(tblptrh.value.get() - 1); } } else tblptrl.put(tblptrl.value.get() - 1); } //------------------------------------------------------------------- //------------------------------------------------------------------- void TBL_MODULE::read() { unsigned int tblptr,opcode; // tblptr is 12 bit address pointer tblptr = ( (tblptru.value.get() & 0xff) << 16 ) | ( (tblptrh.value.get() & 0xff) << 8 ) | ( (tblptrl.value.get() & 0xff) << 0 ); // read 16 bits of program memory from even address opcode = cpu_pic->pma->get_rom(tblptr & 0xfffffe); // return high or low byte depending on lsb of address if(tblptr & 1) { tablat.put((opcode >> 8) & 0xff); internal_latch = (internal_latch & 0x00ff) | (opcode & 0xff00); } else { tablat.put((opcode >> 0) & 0xff); internal_latch = (internal_latch & 0xff00) | (opcode & 0x00ff); } } //------------------------------------------------------------------- //------------------------------------------------------------------- void TBL_MODULE::write() { unsigned int tblptr; unsigned int latch_index; unsigned int *pt; tblptr = ( (tblptru.value.get() & 0xff) << 16 ) | ( (tblptrh.value.get() & 0xff) << 8 ) | ( (tblptrl.value.get() & 0xff) << 0 ); latch_index = (tblptr >> 1) % num_write_latches; pt = &write_latches[latch_index]; if(tblptr & 1) { *pt = (*pt & 0x00ff) | ((tablat.value.get()<<8) & 0xff00); } else { *pt = (*pt & 0xff00) | (tablat.value.get() & 0x00ff); } } void TBL_MODULE::start_write() { eecon1.value.put( eecon1.value.get() | eecon1.WRERR); if (eecon1.value.get() & (EECON1::EEPGD|EECON1::CFGS)) { int index; wr_adr = ( (tblptru.value.get() & 0xff) << 16 ) | ( (tblptrh.value.get() & 0xff) << 8 ) | ( (tblptrl.value.get() & 0xff) << 0 ); wr_adr = cpu->map_pm_address2index(wr_adr); index = wr_adr % num_write_latches; wr_data = write_latches[index]; eecon2.start_write(); // stop execution fo 2 ms get_cycles().set_break(get_cycles().get() + (guint64)(.002*get_cycles().instruction_cps()), this); bp.set_pm_write(); cpu_pic->pm_write(); } else { get_cycles().set_break(get_cycles().get() + EPROM_WRITE_TIME, this); wr_adr = eeadr.value.get() + (eeadrh.value.get() << 8); wr_data = eedata.value.get() + (eedatah.value.get() << 8); eecon2.start_write(); } } //------------------------------------------------------------------- //------------------------------------------------------------------- LVDCON::LVDCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName,pDesc), valid_bits(0x3f) { } /******************************************************************* HLVDCON - High/Low-Voltage Detect Module */ HLVD_stimulus::HLVD_stimulus(HLVDCON *_hlvd, const char *cPname): stimulus(cPname, 2.5, 1e12), hlvd(_hlvd) { } HLVD_stimulus::~HLVD_stimulus() { } void HLVD_stimulus::set_nodeVoltage(double v) { nodeVoltage = v; hlvd->check_hlvd(); } HLVDCON::HLVDCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), hlvdin(0), hlvdin_stimulus(0), stimulus_active(false),write_mask(0x9f), IntSrc(0) {} HLVDCON::~HLVDCON() { if (IntSrc) delete IntSrc; if (stimulus_active) { hlvdin->getPin().snode->detach_stimulus(hlvdin_stimulus); stimulus_active = false; } if (hlvdin_stimulus) delete hlvdin_stimulus; } void HLVDCON::put(unsigned int new_value) { double tivrst = 20e-6; // typical time for IVR stable unsigned int diff = value.get() ^ new_value; trace.raw(write_trace.get() | value.get()); if (!diff) return; if (diff & HLVDEN) { if (new_value & HLVDEN) // Turning on { // wait tivrst before doing anything value.put(new_value & write_mask); get_cycles().set_break( get_cycles().get() + tivrst * get_cycles().instruction_cps(), this); return; } else // Turning off { value.put(new_value & write_mask); if (stimulus_active) { hlvdin->getPin().snode->detach_stimulus(hlvdin_stimulus); stimulus_active = false; } return; } } value.put((new_value & write_mask) | (value.get() & ~write_mask)); if (!(value.get() & IRVST)) // Just return if voltage not stable return; check_hlvd(); } void HLVDCON::callback() { unsigned int reg = value.get(); reg |= (BGVST | IRVST); value.put(reg); check_hlvd(); } double hldv_volts[] = { 1.84, 2.07, 2.28, 2.44, 2.54, 2.74, 2.87, 3.01, 3.30, 3.48, 3.69, 3.91, 4.15, 4.41, 4.74}; void HLVDCON::check_hlvd() { unsigned int reg = value.get(); assert(IntSrc); assert(hlvdin); if (!(reg & IRVST)) return; if ((reg & HLVDL_MASK) == HLVDL_MASK) // using HLVDIN pin { if (!hlvdin_stimulus) hlvdin_stimulus = new HLVD_stimulus(this, "hlvd_stim"); if (!stimulus_active && hlvdin->getPin().snode) { hlvdin->getPin().snode->attach_stimulus(hlvdin_stimulus); stimulus_active = true; hlvdin->getPin().snode->update(); } double voltage = hlvdin->getPin().get_nodeVoltage(); // High voltage trip ? if ((reg & VDIRMAG) && (voltage >= 1.024)) { IntSrc->Trigger(); } // Low voltage trip ? else if (!(reg & VDIRMAG) && (voltage <= 1.024)) IntSrc->Trigger(); } else // Voltage divider on Vdd { double voltage = hldv_volts[reg & HLVDL_MASK]; Processor *Cpu = (Processor *)cpu; if ((reg & VDIRMAG) && (Cpu->get_Vdd() >= voltage)) IntSrc->Trigger(); else if (!(reg & VDIRMAG) && (Cpu->get_Vdd() <= voltage)) IntSrc->Trigger(); } } gpsim-0.30.0/src/ui.cc0000664000076400007640000003375413041763624011401 00000000000000#include #include #include #include #include "cmd_gpsim.h" #include "sim_context.h" #include "symbol.h" #include "cmd_manager.h" const char * s_psEnglishMessages[] = { "", // Place holder so we don't have a zero "break reading register %s\n", // IDS_BREAK_READING_REG "break reading register %s with value %u\n", // IDS_BREAK_READING_REG_VALUE "break reading register %s %s %u\n", // IDS_BREAK_READING_REG_OP_VALUE "break writing register %s\n", // IDS_BREAK_WRITING_REG "break writing register %s with value %u\n", // IDS_BREAK_WRITING_REG_VALUE "break writing register %s %s %u\n", // IDS_BREAK_WRITING_REG_OP_VALUE "execution break at address %s\n", // IDS_BREAK_ON_EXEC_ADDRESS "unrecognized processor in the program file\n", // IDS_PROGRAM_FILE_PROCESSOR_NOT_KNOWN "file name '%s' is too long\n", // IDS_FILE_NAME_TOO_LONG "file %s not found\n", // IDS_FILE_NOT_FOUND "file %s is not formatted properly\n", // IDS_FILE_BAD_FORMAT "no processor has been specified\n", // IDS_NO_PROCESSOR_SPECIFIED "processor %s initialization failed\n", // IDS_PROCESSOR_INIT_FAILED "the program file type does not contain processor\n" // first part of IDS_FILE_NEED_PROCESSOR_SPECIFIED "you need to specify processor with the processor command\n", // IDS_FILE_NEED_PROCESSOR_SPECIFIED "an appropriate list file for %s was not found\n", // IDS_LIST_FILE_NOT_FOUND "Hit breakpoint %d\n", // IDS_HIT_BREAK NULL, // IDS_ }; class CGpsimUserInterface : public IUserInterface { public: CGpsimUserInterface(const char *paStrings[]); virtual ~CGpsimUserInterface() {} void SetStreams(FILE *in, FILE *out); virtual ISimConsole &GetConsole(); virtual void SetConsole(ISimConsole *pConsole); virtual void DisplayMessage(unsigned int uStringID, ...); virtual void DisplayMessage(FILE * pOut, unsigned int uStringID, ...); virtual void DisplayMessage(const char *fmt, ...); virtual void DisplayMessage(FILE * pOut, const char *fmt, ...); virtual const char * FormatProgramAddress(unsigned int uAddress, unsigned int uMask); virtual const char * FormatProgramAddress(unsigned int uAddress, unsigned int uMask, int iRadix); virtual const char * FormatRegisterAddress(Register *); virtual const char * FormatRegisterAddress(unsigned int uAddress, unsigned int uMask); virtual const char * FormatLabeledValue(const char * pLabel, unsigned int uValue); virtual const char * FormatLabeledValue(const char * pLabel, unsigned int uValue, unsigned int uMask, int iRadix, const char *pHexPrefix); virtual const char * FormatValue(unsigned int uValue); virtual const char * FormatValue(gint64 uValue); virtual const char * FormatValue(gint64 uValue, guint64 uMask); virtual const char * FormatValue(gint64 uValue, guint64 uMask, int iRadix); virtual const char * FormatValue(gint64 uValue, guint64 uMask, int iRadix, const char * pHexPrefix); virtual const char * FormatValue(char *str, int len, int iRegisterSize, RegisterValue value); // virtual char * FormatValueAsBinary(char *str, int len, // int iRegisterSize, RegisterValue value); virtual void SetProgramAddressRadix(int iRadix); virtual void SetRegisterAddressRadix(int iRadix); virtual void SetValueRadix(int iRadix); virtual void SetProgramAddressMask(unsigned int uMask); virtual void SetRegisterAddressMask(unsigned int uMask); virtual void SetValueMask(unsigned int uMask); virtual void SetExitOnBreak(FNNOTIFYEXITONBREAK); virtual void NotifyExitOnBreak(int iExitCode); static Integer s_iValueRadix; static String s_sValueHexPrefix; static Integer s_iProgAddrRadix; static String s_sProgAddrHexPrefix; static Integer s_iRAMAddrRadix; static String s_sRAMAddrHexPrefix; static Integer s_iValueMask; static Integer s_iProgAddrMask; static Integer s_iRAMAddrMask; protected: string m_sLabeledAddr; string m_sFormatValueGint64; const char ** m_paStrings; // CGpsimConsole m_Console; }; Integer CGpsimUserInterface::s_iValueRadix( "UIValueRadix", IUserInterface::eHex); String CGpsimUserInterface::s_sValueHexPrefix( "UIValueHexPrefix", "$"); Integer CGpsimUserInterface::s_iProgAddrRadix( "UIProgamAddressRadix", IUserInterface::eHex); String CGpsimUserInterface::s_sProgAddrHexPrefix("UIProgamAddressHexPrefix", "$"); Integer CGpsimUserInterface::s_iRAMAddrRadix( "UIRAMAddressRadix", IUserInterface::eHex); String CGpsimUserInterface::s_sRAMAddrHexPrefix( "UIRAMAddressHexPrefix", "$"); Integer CGpsimUserInterface::s_iValueMask( "UIValueMask", 0xff); Integer CGpsimUserInterface::s_iProgAddrMask( "UIProgamAddressMask", 0xff); Integer CGpsimUserInterface::s_iRAMAddrMask( "UIRAMAddressMask", 0xff); class NullConsole : public ISimConsole { public: virtual void Printf(const char *fmt, ...) {} virtual void VPrintf(const char *fmt, va_list argptr) {} virtual void Puts(const char*) {} virtual void Putc(const char) {} virtual const char * Gets(char *, int) { return "";} }; NullConsole g_NullConsole; static ISimConsole *g_pConsole = &g_NullConsole; class NullUserInterface : public IUserInterface { // NullConsole m_Console; public: virtual ISimConsole &GetConsole() { return *g_pConsole; } virtual void SetConsole(ISimConsole *pConsole) { g_pConsole = pConsole; } virtual void DisplayMessage(unsigned int uStringID, ...) {} virtual void DisplayMessage(FILE * pOut, unsigned int uStringID, ...) {} virtual void DisplayMessage(const char *fmt, ...) {} virtual void DisplayMessage(FILE * pOut, const char *fmt, ...) {} virtual const char * FormatProgramAddress(unsigned int uAddress, unsigned int uMask) {return "";} virtual const char * FormatProgramAddress(unsigned int uAddress, unsigned int uMask, int iRadix) {return "";} virtual const char * FormatRegisterAddress(Register *) { return ""; } virtual const char * FormatRegisterAddress(unsigned int uAddress, unsigned int uMask) {return "";} virtual const char * FormatLabeledValue(const char * pLabel, unsigned int uValue) {return "";} virtual const char * FormatValue(unsigned int uValue) {return "";} virtual const char * FormatValue(gint64 uValue) {return "";} virtual const char * FormatValue(gint64 uValue, guint64 uMask) {return "";} virtual const char * FormatValue(gint64 uValue, guint64 uMask, int iRadix) {return "";} virtual const char * FormatValue(char *str, int len, int iRegisterSize, RegisterValue value) {return "";} virtual void SetProgramAddressRadix(int iRadix) {} virtual void SetRegisterAddressRadix(int iRadix) {} virtual void SetValueRadix(int iRadix) {} virtual void SetProgramAddressMask(unsigned int uMask) {} virtual void SetRegisterAddressMask(unsigned int uMask) {} virtual void SetValueMask(unsigned int uMask) {} virtual void SetExitOnBreak(FNNOTIFYEXITONBREAK) {} virtual void NotifyExitOnBreak(int iExitCode) {} }; CGpsimUserInterface g_DefaultUI(s_psEnglishMessages); static IUserInterface *g_GpsimUI = &g_DefaultUI; LIBGPSIM_EXPORT IUserInterface & GetUserInterface(void) { return *g_GpsimUI; } LIBGPSIM_EXPORT void SetUserInterface(IUserInterface * pGpsimUI) { if(pGpsimUI) { g_GpsimUI = pGpsimUI; } else { g_GpsimUI = &g_DefaultUI; } } static streambuf *s_pSavedCout = 0; LIBGPSIM_EXPORT void SetUserInterface(std::streambuf * pOutStreamBuf) { if(pOutStreamBuf == NULL && s_pSavedCout != 0) { cout.rdbuf(s_pSavedCout); s_pSavedCout = 0; } else { s_pSavedCout = cout.rdbuf(pOutStreamBuf);; } } /// /// CGpsimUserInterface /// CGpsimUserInterface::CGpsimUserInterface(const char *paStrings[]) { m_paStrings = paStrings; m_pfnNotifyOnExit = NULL; } void CGpsimUserInterface::SetStreams(FILE *in, FILE *out) { // m_Console.SetOut(out); // m_Console.SetIn(in); } ISimConsole &CGpsimUserInterface::GetConsole(void) { return *g_pConsole; } void CGpsimUserInterface::SetConsole(ISimConsole *pConsole) { g_pConsole = pConsole; } void CGpsimUserInterface::DisplayMessage(unsigned int uStringID, ...) { va_list ap; va_start(ap,uStringID); g_pConsole->VPrintf(m_paStrings[uStringID], ap); va_end(ap); } void CGpsimUserInterface::DisplayMessage(FILE * pOut, unsigned int uStringID, ...) { va_list ap; va_start(ap,uStringID); if (pOut == NULL || pOut == stdout) { g_pConsole->VPrintf(m_paStrings[uStringID], ap); } else { vfprintf(pOut, m_paStrings[uStringID], ap); } va_end(ap); } void CGpsimUserInterface::DisplayMessage(const char *fmt, ...) { va_list ap; va_start(ap,fmt); g_pConsole->VPrintf(fmt, ap); va_end(ap); } void CGpsimUserInterface::DisplayMessage(FILE * pOut, const char *fmt, ...) { va_list ap; va_start(ap,fmt); if (pOut == NULL || pOut == stdout) { g_pConsole->VPrintf(fmt, ap); } else { vfprintf(pOut, fmt, ap); } va_end(ap); } void CGpsimUserInterface::SetProgramAddressRadix(int iRadix) { s_iProgAddrRadix = iRadix; } void CGpsimUserInterface::SetRegisterAddressRadix(int iRadix) { s_iRAMAddrRadix = iRadix; } void CGpsimUserInterface::SetValueRadix(int iRadix) { s_iValueRadix = iRadix; } void CGpsimUserInterface::SetProgramAddressMask(unsigned int uMask) { s_iProgAddrMask = uMask; } void CGpsimUserInterface::SetRegisterAddressMask(unsigned int uMask) { s_iRAMAddrMask = uMask; } void CGpsimUserInterface::SetValueMask(unsigned int uMask) { s_iValueMask = uMask; } void CGpsimUserInterface::SetExitOnBreak(FNNOTIFYEXITONBREAK pFunc) { m_pfnNotifyOnExit = pFunc; } void CGpsimUserInterface::NotifyExitOnBreak(int iExitCode) { if(m_pfnNotifyOnExit != NULL) { m_pfnNotifyOnExit(iExitCode); } } const char * CGpsimUserInterface::FormatProgramAddress(unsigned int uAddress, unsigned int uMask) { //const char * pLabel = get_symbol_table().findProgramAddressLabel(uAddress); const char *pLabel = "FIXME-ui.cc"; return FormatLabeledValue(pLabel, uAddress, uMask, s_iProgAddrRadix, s_sProgAddrHexPrefix); } const char * CGpsimUserInterface::FormatProgramAddress(unsigned int uAddress, unsigned int uMask, int iRadix) { return FormatValue((gint64)uAddress, uMask, iRadix, s_sProgAddrHexPrefix); } const char * CGpsimUserInterface::FormatRegisterAddress(Register *pReg) { if (!pReg) return ""; return FormatLabeledValue(pReg->name().c_str(), pReg->address, s_iRAMAddrMask, s_iRAMAddrRadix, s_sRAMAddrHexPrefix); } const char * CGpsimUserInterface::FormatRegisterAddress(unsigned int uAddress, unsigned int uMask) { //register_symbol * pRegSym = get_symbol_table().findRegisterSymbol(uAddress, uMask); //const char * pLabel = pRegSym == NULL ? "" : pRegSym->name().c_str(); const char *pLabel = "FIXME-ui.cc"; return FormatLabeledValue(pLabel, uAddress, s_iRAMAddrMask, s_iRAMAddrRadix, s_sRAMAddrHexPrefix); } const char * CGpsimUserInterface::FormatLabeledValue(const char * pLabel, unsigned int uValue) { return FormatLabeledValue(pLabel, uValue, s_iValueMask, s_iValueRadix, s_sValueHexPrefix); } const char * CGpsimUserInterface::FormatLabeledValue(const char * pLabel, unsigned int uValue, unsigned int uMask, int iRadix, const char * pHexPrefix) { m_sLabeledAddr.clear(); const char *pValue = FormatValue(uValue, uMask, iRadix, pHexPrefix); if(pLabel != NULL && *pLabel != 0) { m_sLabeledAddr.append(pLabel); m_sLabeledAddr.append("("); m_sLabeledAddr.append(pValue); m_sLabeledAddr.append(")"); } else { m_sLabeledAddr = pValue; } return m_sLabeledAddr.c_str(); } const char * CGpsimUserInterface::FormatValue(unsigned int uValue) { return FormatLabeledValue(NULL, uValue, s_iValueMask, s_iValueRadix, s_sValueHexPrefix); } const char * CGpsimUserInterface::FormatValue(gint64 uValue) { return FormatValue(uValue, s_iValueMask, s_iValueRadix); } const char * CGpsimUserInterface::FormatValue(gint64 uValue, guint64 uMask) { return FormatValue(uValue, uMask, s_iValueRadix, s_sValueHexPrefix); } const char * CGpsimUserInterface::FormatValue(gint64 uValue, guint64 uMask, int iRadix) { return FormatValue(uValue, uMask, iRadix, s_sValueHexPrefix); } const char * CGpsimUserInterface::FormatValue(gint64 uValue, guint64 uMask, int iRadix, const char * pHexPrefix) { ostringstream osValue; string sPrefix; int iBytes = 0; guint64 l_uMask = uMask; int iDigits; while(l_uMask) { iBytes++; l_uMask >>= 8; } switch(iRadix) { case eHex: iDigits = iBytes * 2; osValue << pHexPrefix; osValue << hex << setw(iDigits) << setfill('0'); break; case eDec: osValue << dec; break; case eOct: iDigits = iBytes * 3; osValue << "0"; osValue << oct << setw(iDigits) << setfill('0'); break; } osValue << (uValue & uMask); m_sFormatValueGint64 = osValue.str(); return m_sFormatValueGint64.c_str(); } const char * CGpsimUserInterface::FormatValue(char *str, int len, int iRegisterSize, RegisterValue value) { if(!str || !len) return 0; char hex2ascii[] = "0123456789ABCDEF"; int i; int min = (len < iRegisterSize*2) ? len : iRegisterSize*2; if(value.data == INVALID_VALUE) value.init = 0xfffffff; for(i=0; i < min; i++) { if(value.init & 0x0f) str[min-i-1] = '?'; else str[min-i-1] = hex2ascii[value.data & 0x0f]; value >>= 4; } str[min] = 0; return str; } gpsim-0.30.0/src/p12x.cc0000664000076400007640000011603613045306452011545 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p12x // // This file supports: // PIC12C508 PIC12C509 // PIC12CE518 PIC12CE519 // PIC10F200 PIC10F202 PIC10F204 // PIC10F220 PIC10F222 // #include #include #include #include "../config.h" #include "packages.h" #include "stimuli.h" #include "i2c-ee.h" #include "p12x.h" #include "symbol.h" //======================================================================== // Generic Configuration word for the midrange family. class Generic12bitConfigWord : public ConfigWord { public: Generic12bitConfigWord(P12bitBase *pCpu) : ConfigWord("CONFIG", 0xfff, "Configuration Word", pCpu, 0xfff), m_pCpu(pCpu) { assert(pCpu); pCpu->wdt.initialize(true); } enum { FOSC0 = 1<<0, FOSC1 = 1<<1, WDTEN = 1<<2, CP = 1<<3, MCLRE = 1<<4 }; virtual void set(gint64 v) { gint64 oldV = getVal(); Integer::set(v); if (m_pCpu) { gint64 diff = oldV ^ v; m_pCpu->setConfigWord(v & 0x3ff, diff & 0x3ff); } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; snprintf(buff,sizeof(buff), "$%3x\n" " FOSC=%d - Clk source = %s\n" " WDTEN=%d - WDT is %s\n" " CP=%d - Code protect is %s\n" " MCLRE=%d - /MCLR is %s", i, i & (FOSC0 | FOSC1), ((i & FOSC0) ? ((i & FOSC1) ? "EXTRC" : "XT") : ((i & FOSC1) ? "INTRC" : "LP")), ((i & WDTEN) ? 1 : 0), ((i & WDTEN) ? "enabled" : "disabled"), ((i & CP) ? 1 : 0), ((i & CP) ? "enabled" : "disabled"), ((i & MCLRE) ? 1 : 0), ((i & MCLRE) ? "enabled" : "disabled")); return string(buff); } private: P12bitBase *m_pCpu; }; void P12_OSCCON::put(unsigned int new_value) { unsigned int old = value.get(); if (verbose) printf("P12_OSCCON::put new_value=%x old=%x\n", new_value, value.get()); trace.raw(write_trace.get() | value.get()); value.put(new_value); if((new_value ^ old) & FOSC4 && m_CPU) m_CPU->updateGP2Source(); if ((new_value ^ old) & 0xfe && m_CPU) m_CPU->freqCalibration(); } //======================================================================== // The P12 devices with an EEPROM contain two die. One is the 12C core and // the other is an I2C EEPROM (Actually, it is not know if there are two // physical die. However, it is known that there are two functional layouts // in the same package.) These two devices are connected internally. class P12_I2C_EE : public I2C_EE { public: P12_I2C_EE(pic_processor *, unsigned int _rom_size); ~P12_I2C_EE(); protected: RegisterCollection *m_UiAccessOfRom; // User access to the rom. }; P12_I2C_EE::P12_I2C_EE(pic_processor *pcpu, unsigned int _rom_size) : I2C_EE(pcpu,_rom_size) { if(pcpu) { pcpu->ema.set_Registers(rom, rom_size); } } P12_I2C_EE::~P12_I2C_EE() { } //------------------------------------------------------------------- P12bitBase::P12bitBase(const char *_name, const char *desc) : _12bit_processor(_name,desc), m_gpio(0), m_tris(0), osccal(this,"osccal","Oscillator Calibration") { configWord = 0; set_frequency(4e6); if(config_modes) config_modes->valid_bits = config_modes->CM_FOSC0 | config_modes->CM_FOSC1 | config_modes->CM_FOSC1x | config_modes->CM_WDTE | config_modes->CM_MCLRE; } P12bitBase::~P12bitBase() { // printf("P12bitBase::~P12bitBase\n"); if (m_gpio) { (&(*m_gpio)[3])->setControl(0); (&(*m_gpio)[2])->setControl(0); } delete m_IN_SignalControl; delete_sfr_register(m_gpio); delete_sfr_register(m_tris); remove_sfr_register(&tmr0); remove_sfr_register(&osccal); } void P12bitBase::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new Generic12bitConfigWord(this)); } //======================================================================== void P12bitBase::create_iopin_map() { package = new Package(8); if(!package) return; package->assign_pin(7, m_gpio->addPin(new IO_bi_directional_pu("gpio0"),0)); package->assign_pin(6, m_gpio->addPin(new IO_bi_directional_pu("gpio1"),1)); package->assign_pin(5, m_gpio->addPin(new IO_bi_directional("gpio2"),2)); package->assign_pin(4, m_gpio->addPin(new IO_bi_directional_pu("gpio3"),3)); package->assign_pin(3, m_gpio->addPin(new IO_bi_directional("gpio4"),4)); package->assign_pin(2, m_gpio->addPin(new IO_bi_directional("gpio5"),5)); package->assign_pin(1, 0); package->assign_pin(8, 0); // gpio3 is input only, but we want pullup, so use IO_bi_directional_pu // but force as input pin disableing TRIS control m_IN_SignalControl = new IN_SignalControl; (&(*m_gpio)[3])->setControl(m_IN_SignalControl); } //-------------------------------------------------------- void P12bitBase::reset(RESET_TYPE r) { m_tris->reset(r); switch (r) { case IO_RESET: // Set GPWUF flag status->put(status->value.get() | 0x80); // fall through... default: _12bit_processor::reset(r); } } //------------------------------------------------------------------------ #define STATUS_GPWUF 0x80 void P12bitBase::enter_sleep() { pic_processor::enter_sleep(); status->put( status->value.get() & ~STATUS_GPWUF); cout << "enter sleep status="<get()<value.get() & OPTION_REG::T0CS) { printf("OPTION_REG::T0CS forcing GPIO2 as input, TRIS disabled\n"); pmGP2->setControl(m_IN_SignalControl); pmGP2->getPin().newGUIname("T0CS"); } else { cout << "TRIS now controlling gpio2\n"; pmGP2->getPin().newGUIname("gpio2"); pmGP2->setControl(0); } } // freqCalibrate modifies the internal RC frequency // the base varsion is for the 12C508 and 12C509 Processors // the spec sheet does not indicate the range or step size of corrections // so this is based on +/- 12.5 % as per 16f88 void P12bitBase::freqCalibration() { // If internal RC oscilator if((configWord & (FOSC0 | FOSC1)) == FOSC1) { int osccal_val = (osccal.get() >> 4) - 0x07; double freq = get_frequency(); freq *= 1. + 0.125 * osccal_val / 0x08; set_frequency(freq); if (verbose) printf("P12bitBase::freqCalibration new freq %g\n", freq); } } // option_new_bits_6_7 is called from class OPTION_REG when // bits 5, 6, or 7 of OPTION_REG change state // void P12bitBase::option_new_bits_6_7(unsigned int bits) { if(verbose) cout << "P12bitBase::option_new_bits_6_7 bits=" << hex << bits << "\n"; // Weak pullup if NOT_GPPU == 0 m_gpio->setPullUp ( (bits & OPTION_REG::BIT6) != OPTION_REG::BIT6 , (configWord & MCLRE)); updateGP2Source(); } void P12bitBase::create_sfr_map() { RegisterValue porVal(0,0); add_sfr_register(indf, 0, porVal); add_sfr_register(&tmr0, 1, porVal); add_sfr_register(pcl, 2, RegisterValue(0xff,0)); add_sfr_register(status, 3, porVal); add_sfr_register(fsr, 4, porVal); add_sfr_register(&osccal,5, RegisterValue(0x70,0)); add_sfr_register(m_gpio, 6, porVal); add_sfr_register(m_tris, 0xffffffff, RegisterValue(0x3f,0)); add_sfr_register(Wreg, 0xffffffff, porVal); option_reg->set_cpu(this); osccal.set_cpu(this); } void P12bitBase::create_symbols() { _12bit_processor::create_symbols(); addSymbol(m_tris); } void P12bitBase::dump_registers () { _12bit_processor::dump_registers(); cout << "tris = 0x" << hex << m_tris->value.get() << '\n'; cout << "osccal = 0x" << osccal.value.get() << '\n'; } void P12bitBase::setConfigWord(unsigned int val, unsigned int diff) { PinModule *pmGP3 = &(*m_gpio)[3]; configWord = val; if (verbose) printf("P12bitBase::setConfigWord val=%x diff=%x\n", val, diff); if (diff & WDTEN) wdt.initialize((val & WDTEN) == WDTEN); if ((val & MCLRE) == MCLRE) { pmGP3->getPin().update_pullup('1', true); pmGP3->getPin().newGUIname("MCLR"); } else pmGP3->getPin().newGUIname("gpio3"); } void P12bitBase::tris_instruction(unsigned int tris_register) { m_tris->put(Wget()); } void P12C508::create() { create_iopin_map(); _12bit_processor::create(); add_file_registers(0x07, 0x1f, 0); P12bitBase::create_sfr_map(); create_invalid_registers (); tmr0.set_cpu(this,m_gpio,2,option_reg); tmr0.start(0); pc->reset(); } Processor * P12C508::construct(const char *name) { P12C508 *p = new P12C508(name); p->pc->set_reset_address(0x1ff); p->create(); p->create_symbols(); return p; } P12C508::P12C508(const char *_name, const char *desc) : P12bitBase(_name,desc) { m_gpio = new GPIO(this,"gpio","I/O port",8,0x3f); m_tris = new PicTrisRegister(this,"tris","Port Direction Control", m_gpio, false); m_tris->wdtr_value=RegisterValue(0x3f,0); } P12C508::~P12C508() { delete_file_registers(0x07, 0x1f); } P12F508::P12F508(const char *_name, const char *desc) : P12C508(_name,desc) { } P12F508::~P12F508() { } Processor * P12F508::construct(const char *name) { P12F508 *p = new P12F508(name); p->pc->set_reset_address(0x1ff); p->create(); p->create_symbols(); return p; } //-------------------------------------------------------- void P12C509::create_sfr_map() { } Processor * P12C509::construct(const char *name) { P12C509 *p = new P12C509(name); if (verbose) cout << " 12c508 construct\n"; p->pc->set_reset_address(0x3ff); p->create(); p->create_symbols(); return p; } void P12C509::create() { if ( verbose ) cout << " 12c509 create \n"; P12C508::create(); alias_file_registers(0x00,0x0f,0x20); add_file_registers(0x30, 0x3f, 0); pa_bits = PA0; // the 509 has two code pages (i.e. PAO in status is used) indf->base_address_mask2 = 0x3F; // RP - need this or INDF won't work right } P12C509::P12C509(const char *_name, const char *desc) : P12C508(_name,desc) { } P12C509::~P12C509() { delete_file_registers(0x30, 0x3f); } P12F509::P12F509(const char *_name, const char *desc) : P12C509(_name,desc) { } P12F509::~P12F509() { } Processor * P12F509::construct(const char *name) { P12F509 *p = new P12F509(name); p->pc->set_reset_address(0x3ff); p->create(); p->create_symbols(); return p; } // P12F510::P12F510(const char *_name, const char *desc) : P12F509(_name,desc) { } P12F510::~P12F510() { } Processor * P12F510::construct(const char *name) { P12F510 *p = new P12F510(name); p->pc->set_reset_address(0x3ff); p->create(); p->create_symbols(); return p; } //-------------------------------------------------------- // construct function is identical to 12C508 version ?? Processor * P12CE518::construct(const char *name) { P12CE518 *p = new P12CE518(name); if(verbose) cout << " 12ce518 construct\n"; p->pc->set_reset_address(0x1ff); p->create(); if(verbose) cout << " ... create symbols\n"; p->create_symbols(); return p; } void P12CE518::create_iopin_map() { P12C508::create_iopin_map(); // Define the valid I/O pins. //gpio.valid_iopins = 0xff; } void P12CE518::create() { if(verbose) cout << " 12ce518 create \n"; P12C508::create(); if(verbose) cout << " adding serial EE\n"; m_eeprom = new P12_I2C_EE(this, 0x10); m_eeprom->debug(); // GPIO bits 6 and 7 are not bonded to physical pins, but are tied // to the internal I2C device. m_gpio->setEnableMask(0xc0 | m_gpio->getEnableMask()); RegisterValue por_value(0xc0,0x00); m_gpio->value = por_value; m_gpio->por_value = por_value; m_gpio->wdtr_value = por_value; m_gpio->put(0xc0); osccal.por_value = RegisterValue(0x80,0); // Kludge to force top two bits to be outputs m_tris->put(0x3f); { scl = new Stimulus_Node ( "EE_SCL" ); io_scl = new IO_bi_directional_pu("gpio7"); io_scl->update_pullup('1',true); io_scl->setDrivingState(true); io_scl->setDriving(true); scl->attach_stimulus( m_gpio->addPin(io_scl,7)); scl->update(); } { sda = new Stimulus_Node ( "EE_SDA" ); io_sda = new IO_open_collector("gpio6"); // enable the pullup resistor. io_sda->update_pullup('1',true); io_sda->setDrivingState(true); io_sda->setDriving(true); m_gpio->addPin(io_sda,6); sda->attach_stimulus (io_sda); sda->update(); } m_eeprom->attach ( scl, sda ); /* ema.set_cpu(this); ema.set_Registers(m_eeprom->rom, m_eeprom->rom_size); */ } P12CE518::P12CE518(const char *_name, const char *desc) : P12C508(_name,desc) { if(verbose) cout << "12CE518 constructor, type = " << isa() << '\n'; if(config_modes) config_modes->valid_bits = config_modes->CM_FOSC0 | config_modes->CM_FOSC1 | config_modes->CM_FOSC1x | config_modes->CM_WDTE | config_modes->CM_MCLRE; } P12CE518::~P12CE518() { delete m_eeprom; delete io_scl; delete io_sda; delete scl; delete sda; } void P12CE518::tris_instruction(unsigned int tris_register) { unsigned int w_val; w_val = Wget(); m_tris->put ( w_val & 0x3F ); // top two bits always output // trace.write_TRIS(w_val); } // freqCalibrate modifies the internal RC frequency // this version is for the 12CE518 and 12CE519 Processors but would also // be correct for 12C508A/C509A/CR509A // the spec sheet does not indicate the range or step size of corrections // so this is based on +/- 12.5 % as per 16f88 void P12CE518::freqCalibration() { // If internal RC oscilator if((configWord & (FOSC0 | FOSC1)) == FOSC1) { int osccal_val = (osccal.get() >> 2) - 0x20; double freq = 4e6; freq *= 1. + 0.125 * osccal_val / 0x20; set_frequency(freq); if(verbose) printf("P12CE518::freqCalibration new freq %g\n", freq); } } //-------------------------------------------------------- void P12CE519::create_sfr_map() { } Processor * P12CE519::construct(const char *name) { P12CE519 *p = new P12CE519(name); cout << " 12ce519 construct\n"; p->pc->set_reset_address(0x3ff); p->create(); p->create_symbols(); return p; } void P12CE519::create() { if ( verbose ) cout << " 12ce519 create \n"; P12CE518::create(); alias_file_registers(0x00,0x0f,0x20); add_file_registers(0x30, 0x3f, 0); pa_bits = PA0; // the 519 has two code pages (i.e. PAO in status is used) indf->base_address_mask2 = 0x3F; // RP - need this or INDF won't work right } P12CE519::P12CE519(const char *_name, const char *desc) : P12CE518(_name,desc) { if(verbose) cout << "12ce519 constructor, type = " << isa() << '\n'; } P12CE519::~P12CE519() { delete_file_registers(0x30, 0x3f); } //-------------------------------------------------------- // // GPIO Port GPIO::GPIO(P12bitBase *pCpu, const char *pName, const char *pDesc, unsigned int numIopins, unsigned int enableMask, unsigned int resetMask, unsigned int wakeupMask, unsigned int configMaskMCLRE) : PicPortRegister (pCpu,pName,pDesc, numIopins, enableMask), m_CPU(pCpu) , m_resetMask(resetMask) , m_wakeupMask(wakeupMask) , m_configMaskMCLRE(configMaskMCLRE) { } void GPIO::setbit(unsigned int bit_number, char new_value) { unsigned int lastDrivenValue = rvDrivenValue.data; PortRegister::setbit(bit_number, new_value); // If gpio bit 0,1 or 3 changed states AND // ~GPWU is low (wake up on change is enabled) AND // the processor is sleeping. // Then wake unsigned int diff = lastDrivenValue ^ rvDrivenValue.data; //if ((diff & (1<<3)) && cpu_pic->config_modes->get_mclre()) { // GP3 is the reset pin if ((diff & m_resetMask) && (m_CPU->configWord & m_configMaskMCLRE)) { cpu->reset( (rvDrivenValue.data & m_resetMask) ? EXIT_RESET : MCLR_RESET); return; } if (diff & m_wakeupMask) { // If /GPWU is 0 (i.e. enabled) and the processor is currently sleeping // then wake up the processor by resetting it. if( ((cpu12->option_reg->value.get() & 0x80) == 0) && cpu12->getActivityState() == pic_processor::ePASleeping) { if(verbose) cout << "IO bit changed while the processor was sleeping,\n\ so the processor is waking up\n"; cpu->reset(IO_RESET); } } } // if bNewPU == true set weak pullups otherwise clear weak pullups void GPIO::setPullUp ( bool bNewPU , bool mclr) { m_bPU = bNewPU; if ( verbose & 16 ) printf("GPIO::setPullUp() =%d\n",(m_bPU?1:0)); // In the following do not change pullup state of internal pins unsigned int mask = getEnableMask() & 0x3f; // If mclr active do not change pullup on gpio3 if (mclr) mask &= 0x37; for (unsigned int i=0, m = 1; mask; i++, m <<= 1) { if (mask & m) { mask ^= m; getPin(i)->update_pullup ( m_bPU ? '1' : '0', true ); } } } //------------------------------------------------------------------------ void P10F200::create_iopin_map() { package = new Package(6); if(!package) return; package->assign_pin(1, m_gpio->addPin(new IO_bi_directional_pu("gpio0"),0)); package->assign_pin(3, m_gpio->addPin(new IO_bi_directional_pu("gpio1"),1)); package->assign_pin(4, m_gpio->addPin(new IO_bi_directional("gpio2"),2)); package->assign_pin(6, m_gpio->addPin(new IO_bi_directional_pu("gpio3"),3)); package->assign_pin(2, 0); package->assign_pin(5, 0); // gpio3 is input only, but we want pullup, so use IO_bi_directional_pu // but force as input pin disableing TRIS control m_IN_SignalControl = new IN_SignalControl; m_OUT_SignalControl = new OUT_SignalControl; m_OUT_DriveControl = new OUT_DriveControl; (&(*m_gpio)[3])->setControl(m_IN_SignalControl); } void P10F200::create() { create_iopin_map(); _12bit_processor::create(); add_file_registers(0x10, 0x1f, 0); // 10F200 only has 16 bytes RAM P12bitBase::create_sfr_map(); create_invalid_registers (); tmr0.set_cpu(this,m_gpio,2,option_reg); tmr0.start(0); osccal.set_cpu(this); osccal.por_value = RegisterValue(0xfe,0); pc->reset(); } Processor * P10F200::construct(const char *name) { P10F200 *p = new P10F200(name); p->pc->set_reset_address(0x0ff); p->create(); p->create_symbols(); return p; } P10F200::P10F200(const char *_name, const char *desc) : P12bitBase(_name,desc) { if(verbose) cout << "10f200 constructor, type = " << isa() << '\n'; m_gpio = new GPIO(this,"gpio","I/O port",8,0x0f); m_tris = new PicTrisRegister(this, "tris", "Port Direction Control",m_gpio, false); m_tris->wdtr_value=RegisterValue(0x3f,0); if(config_modes) config_modes->valid_bits = config_modes->CM_WDTE | config_modes->CM_MCLRE; } P10F200::~P10F200() { (&(*m_gpio)[3])->setControl(0); (&(*m_gpio)[2])->setControl(0); delete m_OUT_SignalControl; delete m_OUT_DriveControl; delete_file_registers(0x10, 0x1f); } void P10F200::updateGP2Source() { PinModule *pmGP2 = &(*m_gpio)[2]; if (osccal.value.get() & P12_OSCCON::FOSC4 ) { pmGP2->setSource(m_OUT_DriveControl); printf("OSCCON::FOSC4 forcing GPIO2 high on output, TODO FOSC4 toggle output\n"); pmGP2->getPin().newGUIname("FOSC4"); } else if(option_reg->value.get() & OPTION_REG::T0CS) { printf("OPTION_REG::T0CS forcing GPIO2 as input, TRIS disabled\n"); pmGP2->setControl(m_IN_SignalControl); pmGP2->setSource(0); pmGP2->getPin().newGUIname("T0CS"); } else { // revert to default control, i.e. let TRIS control the output pmGP2->setControl(0); pmGP2->setSource(0); cout << "TRIS now controlling gpio2\n"; pmGP2->getPin().newGUIname("gpio2"); } pmGP2->updatePinModule(); } // freqCalibrate modifies the internal RC frequency // this version is for the 10F2xx Processors // the spec sheet does not indicate the range or step size of corrections // so this is based on +/- 12.5 % as per 16f88 void P10F200::freqCalibration() { // If internal RC oscilator char osccal_val = (osccal.value.get() & 0xfe); double freq = (configWord & 1)? 8e6 : 4e6; freq *= 1. + (0.125 * osccal_val) / 0x80; set_frequency(freq); if (verbose) printf("P10F200::freqCalibration new freq %g\n", freq); } //------------------------------------------------------------------------ void P10F202::create() { create_iopin_map(); _12bit_processor::create(); add_file_registers(0x08, 0x1f, 0); // 10F202 has 24 bytes RAM P12bitBase::create_sfr_map(); create_invalid_registers (); tmr0.set_cpu(this,m_gpio,2,option_reg); tmr0.start(0); pc->reset(); } Processor * P10F202::construct(const char *name) { P10F202 *p = new P10F202(name); p->pc->set_reset_address(0x1ff); p->create(); p->create_symbols(); return p; } P10F202::P10F202(const char *_name, const char *desc) : P10F200(_name,desc) { if(verbose) cout << "10f202 constructor, type = " << isa() << '\n'; } P10F202::~P10F202() { delete_file_registers(0x08, 0x0f); // Rest is deleted by P10F200 } //======================================================================== // Comparator module for the 10c204 and 10c206 // class Comparator10C20x { public: Comparator10C20x(); ~Comparator10C20x(); }; class COUT_SignalSource; //======================================================================== // COUT_SignalControl -- controls GPIO2's direction when the comparator is // enabled. When the comparator is enabled, GPIO2 is an output. class COUT_SignalControl : public SignalControl { public: COUT_SignalControl(){} ~COUT_SignalControl(){ } virtual char getState() { return '0'; } virtual void release() { delete this; } }; class CIN_SignalSink; class CMCON0 : public sfr_register { public: enum { CWU = 1<<0, CPREF = 1<<1, CNREF = 1<<2, CMPON = 1<<3, CMPTOCS = 1<<4, POL = 1<<5, COUTEN = 1<<6, CMPOUT = 1<<7 }; CMCON0(P10F204 *pCpu, const char *pName, const char *pDesc, PinModule *CInP, PinModule *CInM, PinModule *COut); ~CMCON0(); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); bool isEnabled() { return ((value.get() & COUTEN) == 0); } char getState() { char ret='Z'; if ( (value.get() & (COUTEN | CMPON)) == CMPON) ret = (((value.get() & CMPOUT)==CMPOUT) ^ ((value.get() & POL)==POL)) ? '0' : '1'; if (verbose) cout <<"CMCON0::getState-->"<getState(); } virtual void release() { } private: CMCON0 *m_cmcon0; }; class CIN_SignalSink : public SignalSink { public: CIN_SignalSink(CMCON0 *pcmcon0, bool binput) : m_cmcon0(pcmcon0), m_binput(binput) // true==+input {} virtual void setSinkState(char new3State) { if (verbose) cout << "CIN_SignalSink::setSinkState "<< (m_binput ? "POS ":"NEG ") <<"set sink:"<setInputState(new3State, m_binput); } virtual void release() {delete this; } private: CMCON0 *m_cmcon0; bool m_binput; }; //----------------------------------------------------------- CMCON0::CMCON0(P10F204 *pCpu, const char *pName, const char *pDesc, PinModule *CInP, PinModule *CInM, PinModule *COut) : sfr_register(pCpu, pName, pDesc), p_F204(pCpu), m_CInP(CInP), m_CInM(CInM), m_COut(COut) { // assign the I/O pin associated with the // the comparator output. m_source = new COUT_SignalSource(this); m_control = new COUT_SignalControl(); m_PosInput = new CIN_SignalSink(this,true); m_NegInput = new CIN_SignalSink(this,false); active_source = false; active_control = false; CInP->addSink(m_PosInput); CInM->addSink(m_NegInput); //COut->setSource(m_source); m_pV = m_nV = 0.0; } CMCON0::~CMCON0() { if (!isEnabled()) { delete m_source; delete m_control; } } void CMCON0::put(unsigned int new_value) { unsigned old_value = value.get(); trace.raw(write_trace.get() | old_value); value.put((new_value & 0x7f ) | (old_value & CMPOUT) ); // If any of the control bits that afffect CMPOUT have changed, // then refresh CMPOUT if ((old_value ^ new_value) & (CPREF | CNREF | CMPON | CMPTOCS | POL)) refresh(); // If the output enable changed states. if ((old_value ^ new_value) & COUTEN) p_F204->updateGP2Source(); // If the comparator output state has changed or the polarity changed: if ((old_value ^ value.get()) & (CMPOUT | POL)) m_COut->updatePinModule(); } void CMCON0::refresh() { if (value.get() & CMPON) { if (value.get() & CPREF) m_pV = m_CInP->getPin().get_nodeVoltage(); else m_pV = m_CInM->getPin().get_nodeVoltage(); if (value.get() & CNREF) m_nV = m_CInM->getPin().get_nodeVoltage(); else m_nV = 0.6; value.put( (value.get() & 0x7f) | ((m_pV>m_nV)? CMPOUT : 0)); } } void CMCON0::put_value(unsigned int new_value) { } void CMCON0::setInputState(char newState, bool bInput) { if (bInput) { if (value.get() & CPREF) m_pV = m_CInP->getPin().get_nodeVoltage(); } else { if ((value.get() & CPREF) == 0) m_pV = m_CInM->getPin().get_nodeVoltage(); if (value.get() & CNREF) m_nV = m_CInM->getPin().get_nodeVoltage(); else m_nV = 0.6; } if(verbose) cout << "CMCON0::setInputState: pV="<m_nV) ? CMPOUT : 0)); m_COut->updatePinModule(); } //======================================================================== P10F204::P10F204(const char *_name, const char *desc) : P10F200(_name,desc) { } P10F204::~P10F204() { delete_sfr_register(m_cmcon0); } void P10F204::create() { P10F200::create(); m_cmcon0 = new CMCON0(this, "cmcon0", "Comparator Control", &(*m_gpio)[0], &(*m_gpio)[1], &(*m_gpio)[2]); RegisterValue porVal = RegisterValue(0xff,0); add_sfr_register(m_cmcon0, 7, porVal); } void P10F204::updateGP2Source() { // m_gpio->getIOpins(2)->setSource(m_cmcon0->getSource()); PinModule *pmGP2 = &(*m_gpio)[2]; if (osccal.get() & P12_OSCCON::FOSC4 ) { pmGP2->setSource(m_OUT_DriveControl); printf("OSCCON::FOSC4 forcing GPIO2 high on output, TODO FOSC4 toggle output\n"); pmGP2->getPin().newGUIname("FOSC4"); } else if (m_cmcon0->isEnabled()) { pmGP2->setControl(m_cmcon0->getGPDirectionControl()); pmGP2->setSource(m_cmcon0->getSource()); cout << "comparator is controlling the output of GPIO2\n"; pmGP2->getPin().newGUIname("COUT"); } else if(option_reg->get() & OPTION_REG::T0CS) { printf("OPTION_REG::T0CS forcing GPIO2 as input, TRIS disabled\n"); pmGP2->setControl(m_IN_SignalControl); pmGP2->setSource(0); pmGP2->getPin().newGUIname("T0CS"); } else { pmGP2->setControl(0); pmGP2->setSource(0); pmGP2->getPin().newGUIname("gpio2"); } pmGP2->updatePinModule(); } //======================================================================== Processor * P10F204::construct(const char *name) { P10F204 *p = new P10F204(name); p->pc->set_reset_address(0x1ff); p->create(); p->create_symbols(); return p; } //======================================================================== P10F220::P10F220(const char *_name, const char *desc) : P10F200(_name,desc), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result") { } P10F220::~P10F220() { remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); } void P10F220::create() { P10F200::create(); add_sfr_register(&adcon0, 0x07, RegisterValue(0xcc,0)); add_sfr_register(&adres, 0x08, RegisterValue(0,0)); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1,0); adcon1.setNumberOfChannels(4); adcon1.setIOPin(0, &(*m_gpio)[0]); adcon1.setIOPin(1, &(*m_gpio)[1]); adcon1.setVoltRef(2, 0.6); adcon1.setVoltRef(3, 0.6); adcon1.setChannelConfiguration(0, 0x03); adcon1.setChannelConfiguration(1, 0x03); adcon1.setChannelConfiguration(2, 0x00); adcon1.setChannelConfiguration(3, 0x00); adcon0.setChannel_Mask(3); adcon0.setChannel_shift(2); adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setA2DBits(8); } //======================================================================== Processor * P10F220::construct(const char *name) { P10F220 *p = new P10F220(name); p->pc->set_reset_address(0xff); p->create(); p->create_symbols(); return p; } void P10F220::enter_sleep() { unsigned int val; _12bit_processor::enter_sleep(); status->put( status->get() & ~STATUS_GPWUF); val = (adcon0.get() & ~(ADCON0_10::ADON|ADCON0_10::GO)) | ADCON0_10::CHS1 | ADCON0_10::CHS0; adcon0.put(val); } void P10F220::exit_sleep() { _12bit_processor::exit_sleep(); adcon0.put(adcon0.get() | ADCON0_10::ANS1 | ADCON0_10::ANS0); } void P10F220::setConfigWord(unsigned int val, unsigned int diff) { PinModule *pmGP3 = &(*m_gpio)[3]; configWord = val; if (verbose) printf("P10F220::setConfigWord val=%x diff=%x\n", val, diff); if (diff & WDTEN) wdt.initialize((val & WDTEN) == WDTEN); if ((val & MCLRE)) { if (!(val & NOT_MCPU)) pmGP3->getPin().update_pullup('1', true); pmGP3->getPin().newGUIname("MCLR"); } else pmGP3->getPin().newGUIname("gpio3"); if ((val & IOSCFS)) set_frequency(8e6); } //======================================================================== P10F222::P10F222(const char *_name, const char *desc) : P10F220(_name,desc) { } P10F222::~P10F222() { delete_file_registers(0x09, 0x0f); } void P10F222::create() { P10F220::create(); add_file_registers(0x09, 0x0f, 0); // 10F222 has 23 bytes RAM } //======================================================================== Processor * P10F222::construct(const char *name) { P10F222 *p = new P10F222(name); p->pc->set_reset_address(0x1ff); p->create(); p->create_symbols(); return p; } //======================================================================== // P16F505 Config Word class P16F505ConfigWord : public ConfigWord { public: enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN = 1<<3, CP = 1<<4, MCLRE = 1<<5 }; P16F505ConfigWord(P12bitBase *pCpu) : ConfigWord("CONFIG", 0xfff, "Configuration Word", pCpu, 0xfff), m_pCpu(pCpu) { assert(pCpu); pCpu->wdt.initialize(true); } virtual void set(gint64 v) { gint64 oldV = getVal(); Integer::set(v); if (m_pCpu) { gint64 diff = oldV ^ v; m_pCpu->setConfigWord(v & 0x3ff, diff & 0x3ff); } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; const char *src; switch(i&(FOSC0|FOSC1|FOSC2)) { case 0: src = "LP"; break; case 1: src = "XT"; break; case 2: src = "HS"; break; case 3: src = "EC"; break; case 4: src = "INTRCRB4"; break; case 5: src = "INTRCCLK"; break; case 6: src = "EXTRCRB4"; break; case 7: src = "EXTRCCLK"; break; } snprintf(buff, sizeof(buff), "$%3x\n" " FOSC=%d - Clk source = %s\n" " WDTEN=%d - WDT is %s\n" " CP=%d - Code protect is %s\n" " MCLRE=%d - /MCLR is %s", i, i & (FOSC0 | FOSC1), src, ((i & WDTEN) ? 1 : 0), ((i & WDTEN) ? "enabled" : "disabled"), ((i & CP) ? 1 : 0), ((i & CP) ? "enabled" : "disabled"), ((i & MCLRE) ? 1 : 0), ((i & MCLRE) ? "enabled" : "disabled")); return string(buff); } private: P12bitBase *m_pCpu; }; //======================================================================== // P16F505 Implementation P16F505::P16F505(const char *_name, const char *desc) : P12bitBase(_name,desc) { m_portb = new GPIO(this,"portb","I/O port",8,0x3f, 1<<3, 0x1B, 1<<5); m_portc = new GPIO(this,"portc","I/O port",8,0x3f, 0, 0); m_trisb = new PicTrisRegister(this,"trisb","Port Direction Control", m_portb, false); m_trisc = new PicTrisRegister(this,"trisc","Port Direction Control", m_portc, false); m_trisb->wdtr_value=RegisterValue(0x3f,0); m_trisc->wdtr_value=RegisterValue(0x3f,0); if (config_modes) config_modes->valid_bits = config_modes->CM_FOSC0 | config_modes->CM_FOSC1 | config_modes->CM_FOSC1x | config_modes->CM_WDTE | config_modes->CM_MCLRE; } P16F505::~P16F505() { delete_sfr_register(m_portb); delete_sfr_register(m_portc); delete_sfr_register(m_trisb); delete_sfr_register(m_trisc); delete_file_registers(0x08, 0x1f); delete_file_registers(0x30, 0x3f); delete_file_registers(0x50, 0x5f); delete_file_registers(0x70, 0x7f); } Processor * P16F505::construct(const char *name) { P16F505 *p = new P16F505(name); p->pc->set_reset_address(0x3ff); p->create(); p->create_symbols(); return p; } void P16F505::create() { create_iopin_map(); _12bit_processor::create(); add_file_registers(0x08, 0x1f, 0); create_sfr_map(); create_invalid_registers (); alias_file_registers(0x00,0x0f,0x20); add_file_registers(0x30, 0x3f, 0); alias_file_registers(0x00,0x0f,0x40); add_file_registers(0x50, 0x5f, 0); alias_file_registers(0x00,0x0f,0x60); add_file_registers(0x70, 0x7f, 0); pa_bits = PA0; indf->base_address_mask2 = 0x7F; tmr0.set_cpu(this,m_portc,5,option_reg); // T0CKI pin tmr0.start(0); pc->reset(); } void P16F505::create_symbols() { _12bit_processor::create_symbols(); addSymbol(m_trisb); addSymbol(m_trisc); } void P16F505::create_iopin_map() { package = new Package(14); if(!package) return; package->assign_pin(1, 0); package->assign_pin(2, m_portb->addPin(new IO_bi_directional("portb5"),5)); package->assign_pin(3, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(4, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(5, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(6, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(7, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(8, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(9, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(10, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional("portb2"),2)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(14, 0); // portb3 is input only, but we want pullup, so use IO_bi_directional_pu // but force as input pin disableing TRIS control m_IN_SignalControl = new IN_SignalControl; (&(*m_portb)[3])->setControl(m_IN_SignalControl); } void P16F505::create_sfr_map() { RegisterValue porVal(0,0); add_sfr_register(indf, 0, porVal); add_sfr_register(&tmr0, 1, porVal); add_sfr_register(pcl, 2, RegisterValue(0xff,0)); add_sfr_register(status, 3, porVal); add_sfr_register(fsr, 4, porVal); add_sfr_register(&osccal,5, RegisterValue(0x70,0)); add_sfr_register(m_portb,6, porVal); add_sfr_register(m_portc,7, porVal); add_sfr_register(m_trisb, 0xffffffff, RegisterValue(0x3f,0)); add_sfr_register(m_trisc, 0xffffffff, RegisterValue(0x3f,0)); add_sfr_register(Wreg, 0xffffffff, porVal); option_reg->set_cpu(this); osccal.set_cpu(this); } void P16F505::create_config_memory() { m_configMemory = new ConfigMemory(this,1); m_configMemory->addConfigWord(0,new P16F505ConfigWord(this)); } void P16F505::tris_instruction(unsigned int tris_register) { if (tris_register == 6) m_trisb->put(Wget()); else if (tris_register == 7) m_trisc->put(Wget()); } void P16F505::setConfigWord(unsigned int val, unsigned int diff) { PinModule *pmRB3 = &(*m_portb)[3]; configWord = val; if (verbose) printf("P16F505::setConfigWord val=%x diff=%x\n", val, diff); if (diff & WDTEN) wdt.initialize((val & WDTEN) == WDTEN); if ((val & MCLRE) == MCLRE) { pmRB3->getPin().update_pullup('1', true); pmRB3->getPin().newGUIname("MCLR"); } else pmRB3->getPin().newGUIname("portb3"); } void P16F505::updateGP2Source() { PinModule *pmPC5 = &(*m_portc)[5]; if(option_reg->value.get() & OPTION_REG::T0CS) { printf("OPTION_REG::T0CS forcing PORTC5 as input, TRIS disabled\n"); pmPC5->setControl(m_IN_SignalControl); pmPC5->getPin().newGUIname("T0CS"); } else { cout << "TRIS now controlling PORTC5\n"; pmPC5->getPin().newGUIname("portc5"); pmPC5->setControl(0); } } // option_new_bits_6_7 is called from class OPTION_REG when // bits 5, 6, or 7 of OPTION_REG change state // void P16F505::option_new_bits_6_7(unsigned int bits) { bool bit6 = (bits & OPTION_REG::BIT6) != OPTION_REG::BIT6; if(verbose) cout << "P16F505::option_new_bits_6_7 bits=" << hex << bits << "\n"; // Weak pullup if NOT_GPPU == 0 m_portb->setPullUp (bit6 , (configWord & MCLRE)); updateGP2Source(); } void P16F505::reset(RESET_TYPE r) { m_trisb->reset(r); m_trisc->reset(r); switch (r) { case IO_RESET: // Set GPWUF/RBWUF flag status->put(status->value.get() | 0x80); // fall through... default: _12bit_processor::reset(r); } } void P16F505::dump_registers () { _12bit_processor::dump_registers(); cout << "trisb = 0x" << hex << m_trisb->value.get() << '\n'; cout << "trisc = 0x" << hex << m_trisc->value.get() << '\n'; cout << "osccal = 0x" << osccal.value.get() << '\n'; } gpsim-0.30.0/src/xref.cc0000664000076400007640000000360613041763624011721 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "../config.h" #include "xref.h" #include "gpsim_interface.h" #include "value.h" //------------------------------------------------------------------- XrefObject::XrefObject() { data=0; } XrefObject::XrefObject(gpsimObject *value) { data=value; } XrefObject::~XrefObject() { list::iterator ioi; ioi=xrefs.begin(); while((ioi=xrefs.begin()) != xrefs.end()) { XrefObject *xref = (XrefObject *) *ioi; clear(xref); delete xref; } return; } void *XrefObject::first_xref() { list::iterator ioi; if (!xrefs.empty()) { ioi=xrefs.begin(); return(*ioi); } else return 0; } void XrefObject::_add(void *xref) { xrefs.push_back(xref); } void XrefObject::clear(void *xref) { xrefs.remove(xref); } void XrefObject::_update() { list::iterator ioi; ioi=xrefs.begin(); for(;ioi!=xrefs.end();++ioi) { gpointer *xref = (gpointer *) *ioi; gi.update_object(xref,get_val()); } } int XrefObject::get_val(void) { if(data) return data->get_value(); return 0; } void XrefObject::assign_data(gpsimObject *new_data) { data = new_data; } gpsim-0.30.0/src/p16x5x.h0000664000076400007640000000632013041763624011666 00000000000000/* Copyright (C) 2000,2001 T. Scott Dattalo, Daniel Schudel, Robert Pearce This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16x5x // // This file supports: // P16C54 // P16C55 // P16C56 #ifndef __P16X5X_H__ #define __P16X5X_H__ #include "packages.h" #include "stimuli.h" #include "12bit-processors.h" class PicPortRegister; class PicTrisRegister; class PicLatchRegister; class P16C54 : public _12bit_processor { public: PicPortRegister *m_porta; PicTrisRegister *m_trisa; PicPortRegister *m_portb; PicTrisRegister *m_trisb; #ifdef USE_PIN_MODULE_FOR_TOCKI PinModule *m_tocki; #else PicPortRegister *m_tocki; PicTrisRegister *m_trist0; #endif virtual PROCESSOR_TYPE isa(){return _P16C54_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x200; }; virtual unsigned int register_memory_size() const { return 0x20; }; virtual unsigned int config_word_address() const {return 0xFFF;}; virtual void create_sfr_map(); virtual void option_new_bits_6_7(unsigned int bits) {} P16C54(const char *_name=0, const char *desc=0); virtual ~P16C54(); void create(); virtual void create_iopin_map(); static Processor *construct(const char *name); virtual void tris_instruction(unsigned int tris_register); virtual unsigned int fsr_valid_bits() { return 0x1f; // Only 32 register addresses } virtual unsigned int fsr_register_page_bits() { return 0; // Only one register page. } }; class P16C55 : public P16C54 { public: PicPortRegister *m_portc; PicTrisRegister *m_trisc; virtual PROCESSOR_TYPE isa(){return _P16C55_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x200; }; virtual unsigned int register_memory_size() const { return 0x20; }; virtual unsigned int config_word_address() const {return 0xFFF;}; virtual void create_sfr_map(); P16C55(const char *_name=0, const char *desc=0); virtual ~P16C55(); virtual void create(); virtual void create_iopin_map(); static Processor *construct(const char *name); virtual void tris_instruction(unsigned int tris_register); }; class P16C56 : public P16C54 { public: virtual PROCESSOR_TYPE isa(){return _P16C56_;}; virtual unsigned int program_memory_size() const { return 0x400; }; virtual unsigned int register_memory_size() const { return 0x20; }; virtual unsigned int config_word_address() const {return 0xFFF;}; P16C56(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; #endif gpsim-0.30.0/src/program_files.h0000664000076400007640000000427613063451152013446 00000000000000 #include "stdio.h" #include "processor.h" #ifndef __PROGRAM_FILES_H__ #define __PROGRAM_FILES_H__ /** * ProgramFileType base type */ class ProgramFileType { public: enum { SUCCESS = 0, ERR_UNRECOGNIZED_PROCESSOR = -1, ERR_FILE_NOT_FOUND = -2, ERR_FILE_NAME_TOO_LONG = -3, ERR_LST_FILE_NOT_FOUND = -4, ERR_BAD_FILE = -5, ERR_NO_PROCESSOR_SPECIFIED = -6, ERR_PROCESSOR_INIT_FAILED = -7, ERR_NEED_PROCESSOR_SPECIFIED = -8, }; virtual ~ProgramFileType() { } /* * LoadProgramFile * 1) Loads a program into a processor object that is passed in. * 2) If no processor is passed in, it will use the program file * to determine processor type, allocate the processor object and * load the program into the processor object. * Returns: Processor object in pProcessor * */ virtual int LoadProgramFile(Processor **ppProcessor, const char *pFilename, FILE *pFile, const char *pProcessorName) = 0; virtual void DisplayError(int iError, const char *pProgFilename, const char *pLstFile); }; class ProgramFileTypeList : public vector { public: ProgramFileTypeList(); virtual ~ProgramFileTypeList(); static ProgramFileTypeList &GetList(); static ProgramFileTypeList *s_ProgramFileTypeList; virtual bool LoadProgramFile(Processor **pProcessor, const char *pFilename, FILE *pFile, const char *pProcessorName=0); bool IsErrorDisplayableInLoop(int iError); }; #if defined(_MSC_VER) #include #endif #include class ProgramFileBuf : public std::streambuf { protected: static const int m_iBufferSize = 1024; char m_Buffer[m_iBufferSize]; FILE * m_pFile; public: explicit ProgramFileBuf(FILE * pFile); protected: virtual int_type underflow( ); virtual streamsize xsgetn( char_type *_Ptr, streamsize _Count); }; class ProgramFileStream : public std::istream { protected: ProgramFileBuf m_buf; public: explicit ProgramFileStream(FILE * pFile) : std::istream(&m_buf), m_buf(pFile) { } }; #endif gpsim-0.30.0/src/cmd_manager.h0000664000076400007640000000254013041763624013050 00000000000000#ifndef __CMD_MANAGER_H__ #define __CMD_MANAGER_H__ #include #include "cmd_gpsim.h" #include "gpsim_interface.h" #include #include #include using namespace std; class CommandHandlerKey : public ICommandHandler { public: CommandHandlerKey(const char *name) { m_name = name; } virtual const char *GetName(void) {return m_name; } virtual int Execute(const char * commandline, ISimConsole *out) { return CMD_ERR_COMMANDNOTDEFINED;} virtual int ExecuteScript(list &script, ISimConsole *out) { return CMD_ERR_ERROR;} const char * m_name; }; class CCommandManager { public: CCommandManager(); int Register(ICommandHandler * ch); int Execute(string &sName, const char *cmdline); static CCommandManager m_CommandManger; static CCommandManager &GetManager(); ICommandHandler * find(const char *name); ISimConsole &GetConsole() { return GetUserInterface().GetConsole(); } void ListToConsole(); private: struct lessThan : binary_function { bool operator()(const ICommandHandler* left, const ICommandHandler* right) const { return strcmp(((ICommandHandler*)left)->GetName(), ((ICommandHandler*)right)->GetName()) < 0; } }; typedef vector List; List m_HandlerList; }; #endif gpsim-0.30.0/src/p16x7x.h0000664000076400007640000001573413041763624011701 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P16X7X_H__ #define __P16X7X_H__ #include "p16x6x.h" /* The '7x stuff is like '6x stuff with a/d converters */ //RRR#include "pir.h" //#include "a2dconverter.h" #include "pm_rd.h" //--------------------------------------------------------- class P16C71 : public P16X8X { public: ADCON0 adcon0; ADCON1 adcon1; sfr_register adres; virtual PROCESSOR_TYPE isa(){return _P16C71_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x400; }; virtual void create_sfr_map(); P16C71(const char *_name=0, const char *desc=0); ~P16C71(); void create(); static Processor *construct(const char *name); private: // This is not a real PIR register, but only one that allows the A2D Interrupt // flag be processed in manner similar to other processors. class PIR_16C71; PIR_16C71 *m_pir; }; class P16x71x : public _14bit_processor { public: INTCON_14_PIR intcon_reg; IOC *m_ioc; PicPortRegister *m_porta; PicTrisRegister *m_trisa; PicPortGRegister *m_portb; PicTrisRegister *m_trisb; T1CON t1con; PIR *pir1; PIE pie1; T2CON t2con; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; PCON pcon; PIR_SET_1 pir_set_def; ADCON0 adcon0; ADCON1 adcon1; sfr_register adres; virtual void create_iopin_map(); virtual void create_sfr_map(); virtual void option_new_bits_6_7(unsigned int bits); //RRRvoid create(); virtual void create_symbols(); virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_def); } P16x71x(const char *_name=0, const char *desc=0); ~P16x71x(); // static Processor *construct(const char *name){;} // virtual bool hasSSP() { return false; } }; class P16C712 : public P16x71x { public: TRISCCP trisccp; DATACCP dataccp; virtual PROCESSOR_TYPE isa(){return _P16C712_;}; virtual unsigned int program_memory_size() const { return 1024; }; virtual unsigned int register_memory_size () const { return 0x100; } virtual void create_sfr_map(); P16C712(const char *_name=0, const char *desc=0); ~P16C712(); void create(); static Processor *construct(const char *name); virtual bool hasSSP() { return false; } }; class P16C716 : public P16C712 { public: virtual PROCESSOR_TYPE isa(){return _P16C716_;}; virtual unsigned int program_memory_size() const { return 0x800; }; P16C716(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16F716 : public P16C712 { public: virtual PROCESSOR_TYPE isa(){return _P16F716_;}; virtual unsigned int program_memory_size() const { return 0x800; }; P16F716(const char *_name=0, const char *desc=0); ~P16F716(); static Processor *construct(const char *name); virtual void create_sfr_map(); virtual void create(); ECCPAS eccpas; PWM1CON pwm1con; }; class P16C72 : public P16C62 { public: // XXX // This pir1_2, pir2_2 stuff is not particularly pretty. It would be // better to just tell C++ to redefine pir1 and pir2 and PIR1v2 and // PIR2v2, but C++ only supports covariance in member function return // values. PIR1v2 *pir1_2_reg; PIR2v2 *pir2_2_reg; PIR_SET_2 pir_set_2_def; ADCON0 adcon0; ADCON1 adcon1; sfr_register adres; virtual PROCESSOR_TYPE isa(){return _P16C72_;}; virtual void create_symbols(); void create_sfr_map(); virtual PIR *get_pir1() { return (pir1_2_reg); } virtual PIR *get_pir2() { return (pir2_2_reg); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } P16C72(const char *_name=0, const char *desc=0); ~P16C72(); void create(); static Processor *construct(const char *name); }; class P16C73 : public P16C63 { public: // XXX // This pir1_2, pir2_2 stuff is not particularly pretty. It would be // better to just tell C++ to redefine pir1 and pir2 and PIR1v2 and // PIR2v2, but C++ only supports covariance in member function return // values. PIR1v2 *pir1_2_reg; PIR2v2 *pir2_2_reg; PIR_SET_2 pir_set_2_def; ADCON0 adcon0; ADCON1 adcon1; sfr_register adres; virtual PROCESSOR_TYPE isa(){return _P16C73_;}; virtual void create_symbols(); void create_sfr_map(); virtual PIR *get_pir1() { return (pir1_2_reg); } virtual PIR *get_pir2() { return (pir2_2_reg); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } P16C73(const char *_name=0, const char *desc=0); ~P16C73(); void create(); static Processor *construct(const char *name); }; class P16F73 : public P16C73 { public: virtual PROCESSOR_TYPE isa(){return _P16F73_;}; virtual unsigned int register_memory_size () const { return 0x200;}; virtual void create_symbols(); void create_sfr_map(); P16F73(const char *_name=0, const char *desc=0); ~P16F73(); void create(); static Processor *construct(const char *name); protected: PM_RD pm_rd; }; //--------------------------------------------------------- class P16C74 : public P16C65 // Not a typo, a 'c74 is more like a 'c65 then a 'c64! { public: // XXX // This pir1_2, pir2_2 stuff is not particularly pretty. It would be // better to just tell C++ to redefine pir1 and pir2 and PIR1v2 and // PIR2v2, but C++ only supports covariance in member function return // values. PIR1v2 *pir1_2_reg; PIR2v2 *pir2_2_reg; PIR_SET_2 pir_set_2_def; ADCON0 adcon0; ADCON1 adcon1; sfr_register adres; virtual PROCESSOR_TYPE isa(){return _P16C74_;}; virtual void create_symbols(); void create_sfr_map(); virtual PIR *get_pir1() { return (pir1_2_reg); } virtual PIR *get_pir2() { return (pir2_2_reg); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } virtual unsigned int program_memory_size() const { return 0x1000; }; P16C74(const char *_name=0, const char *desc=0); ~P16C74(); void create(); static Processor *construct(const char *name); }; class P16F74 : public P16C74 { public: virtual PROCESSOR_TYPE isa(){return _P16F74_;}; virtual unsigned int register_memory_size () const { return 0x200;}; virtual void create_symbols(); void create_sfr_map(); P16F74(const char *_name=0, const char *desc=0); ~P16F74(); void create(); static Processor *construct(const char *name); protected: PM_RD pm_rd; }; #endif gpsim-0.30.0/src/value.h0000664000076400007640000003425113063451152011725 00000000000000/* Copyright (C) 1998-2004 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __VALUE_H__ #define __VALUE_H__ #include "gpsim_object.h" #include #include #include class Processor; class Module; #include "xref.h" class Expression; class ComparisonOperator; class Packet; //------------------------------------------------------------------------ // /// Value - the base class that supports types /// /// Everything that can hold a value is derived from the Value class. /// The primary purpose of this is to provide external objects (like /// the gui) an abstract way of getting the value of diverse things /// like registers, program counters, cycle counters, etc. /// /// In addition, expressions of Values can be created and operated /// on. class Value : public gpsimObject { public: Value(); Value(const char *name, const char *desc, Module *pM=0); virtual ~Value(); virtual unsigned int get_leftVal() {return 0;} virtual unsigned int get_rightVal() {return 0;} /// Value 'set' methods provide a mechanism for casting values to the /// the type of this value. If the type cast is not supported in a /// derived class, an Error will be thrown. virtual void set(const char *cP,int len=0); virtual void set(double); virtual void set(gint64); virtual void set(int); virtual void set(bool); virtual void set(Value *); virtual void set(Expression *); virtual void set(Packet &); /// Value 'get' methods provide a mechanism of casting Value objects /// to other value types. If the type cast is not supported in a /// derived class, an Error will be thrown. virtual void get(bool &b); virtual void get(int &); virtual void get(guint64 &); virtual void get(gint64 &); virtual void get(double &); virtual void get(char *, int len); virtual void get(Packet &); inline operator gint64() { gint64 i; get(i); return i; } inline operator int() { gint64 i; get(i); return (int)i; } inline operator unsigned int() { gint64 i; get(i); return (unsigned int)i; } inline Value & operator =(int i) { set(i); return *this; } inline Value & operator =(unsigned int i) { set((int)i); return *this; } /// compare - this method will compare another object to this /// object. It takes a pointer to a ComparisonOperator as its /// input. Of the object's are mismatched for the particular /// operator, a 'Type Mismatch' Error will be thown. virtual bool compare(ComparisonOperator *compOp, Value *rvalue); /// copy - return an object that is identical to this one. virtual Value *copy(); /// xrefs - a cross reference allows a Value to notify another /// Value when it is changed. //** virtual void set_xref(Value *); //** virtual Value *get_xref(); // Some Value types that are used for symbol classes // contain a gpsimValue type that have update listeners. virtual void update(); // {} virtual Value* evaluate() { return copy(); } virtual void add_xref(void *xref); virtual void remove_xref(void *xref); XrefObject *xref() { return _xref; } void set_xref(XrefObject *__xref) {_xref = __xref;} virtual void set_module(Module *new_cpu); Module *get_module(); virtual void set_cpu(Processor *new_cpu); Processor *get_cpu() const; //virtual string toString(); void addName(string &r_sAliasedName); private: XrefObject *_xref; protected: // A pointer to the module that owns this value. Module *cpu; // Aliased names for this Value list *m_aka; }; /***************************************************************** ValueWrapper */ class ValueWrapper : public Value { public: explicit ValueWrapper(Value *pCopy); virtual ~ValueWrapper(); virtual unsigned int get_leftVal(); virtual unsigned int get_rightVal(); virtual void set(const char *cP,int len=0); virtual void set(double); virtual void set(gint64); virtual void set(int); virtual void set(bool); virtual void set(Value *); virtual void set(Expression *); virtual void set(Packet &); virtual void get(bool &b); virtual void get(int &); virtual void get(guint64 &); virtual void get(gint64 &); virtual void get(double &); virtual void get(char *, int len); virtual void get(Packet &); virtual Value *copy(); virtual void update(); virtual Value* evaluate(); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); private: Value *m_pVal; }; /***************************************************************** * Now we introduce classes for the basic built-in data types. * These classes are created by extending the Value class. For * convenience, they all must instantiate a getVal() method that * returns valueof the object in question as a simple value of * the base data type. For example, invoking getVal() on a * Boolean oject must return a simple 'bool' value. */ /*****************************************************************/ class Boolean : public Value { public: explicit Boolean(bool newValue); Boolean(const char *_name, bool newValue, const char *desc=0); static bool Parse(const char *pValue, bool &bValue); static Boolean * NewObject(const char *_name, const char *pValue, const char *desc); virtual ~Boolean(); string toString(); string toString(const char* format); static string toString(bool value); static string toString(const char* format, bool value); virtual void get(bool &b); virtual void get(int &i); virtual void get(char *, int len); virtual void get(Packet &); virtual void set(bool); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); bool getVal() { return value; } static Boolean* typeCheck(Value* val, string valDesc); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *return_str, int len); virtual char *toBitStr(char *return_str, int len); inline operator bool() { bool bValue; get(bValue); return bValue; } inline Boolean &operator = (bool bValue) { set(bValue); return *this; } private: bool value; }; inline bool operator!=(Boolean &LValue, Boolean &RValue) { return (bool)LValue != (bool)RValue; } //------------------------------------------------------------------------ /// Integer - built in gpsim type for a 64-bit integer. class Integer : public Value { public: Integer(const Integer &new_value); explicit Integer(gint64 new_value); Integer(const char *_name, gint64 new_value, const char *desc=0); static bool Parse(const char *pValue, gint64 &iValue); static Integer * NewObject(const char *_name, const char *pValue, const char *desc); virtual ~Integer(); virtual string toString(); string toString(const char* format); static string toString(gint64 value); static string toString(const char* format, gint64 value); virtual void get(gint64 &i); virtual void get(double &d); virtual void get(char *, int len); virtual void get(Packet &); virtual void set(gint64 v); virtual void set(int); virtual void set(double d); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); static void setDefaultBitmask(gint64 bitmask); inline void setBitmask(gint64 bitmask) { this->bitmask = bitmask; } inline gint64 getBitmask() { return bitmask; } gint64 getVal() { return value; } virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); virtual char *toBitStr(char *, int len); static Integer* typeCheck(Value* val, string valDesc); static Integer* assertValid(Value* val, string valDesc, gint64 valMin); static Integer* assertValid(Value* val, string valDesc, gint64 valMin, gint64 valMax); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); inline operator gint64() { gint64 i; get(i); return i; } inline operator guint64() { gint64 i; get(i); return (guint64)i; } inline operator bool() { gint64 i; get(i); return i != 0; } inline operator int() { gint64 i; get(i); return (int)i; } inline operator unsigned int() { gint64 i; get(i); return (unsigned int)i; } inline Integer & operator =(const Integer &i) { Integer & ii = (Integer &)i; gint64 iNew = (gint64)ii; set(iNew); bitmask = i.bitmask; return *this; } inline Integer & operator =(int i) { set(i); return *this; } inline Integer & operator =(unsigned int i) { set((int)i); return *this; } inline Integer & operator &=(int iValue) { gint64 i; get(i); set((int)i & iValue); return *this; } inline Integer & operator |=(int iValue) { gint64 i; get(i); set((int)i | iValue); return *this; } inline Integer & operator +=(int iValue) { gint64 i; get(i); set((int)i + iValue); return *this; } inline Integer & operator ++(int) { gint64 i; get(i); set((int)i + 1); return *this; } inline Integer & operator --(int) { gint64 i; get(i); set((int)i - 1); return *this; } inline Integer & operator <<(int iShift) { gint64 i; get(i); set(i << iShift); return *this; } inline bool operator !() { gint64 i; get(i); return i == 0; } private: gint64 value; // Used for display purposes gint64 bitmask; static gint64 def_bitmask; }; inline bool operator!=(Integer &iLValue, Integer &iRValue) { return (gint64)iLValue != (gint64)iRValue; } //------------------------------------------------------------------------ /// Float - built in gpsim type for a 'double' class Float : public Value { public: explicit Float(double newValue = 0.0); Float(const char *_name, double newValue, const char *desc=0); static bool Parse(const char *pValue, double &fValue); static Float * NewObject(const char *_name, const char *pValue, const char *desc); virtual ~Float(); virtual string toString(); string toString(const char* format); static string toString(double value); static string toString(const char* format, double value); virtual void get(gint64 &i); virtual void get(double &d); virtual void get(char *, int len); virtual void get(Packet &); virtual void set(gint64 v); virtual void set(double d); virtual void set(Value *); virtual void set(const char *cP,int len=0); virtual void set(Packet &); double getVal() { return value; } virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); static Float* typeCheck(Value* val, string valDesc); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); inline operator double() { double d; get(d); return d; } inline Float & operator = (double d) { set((double)d); return *this; } inline Float & operator = (int d) { set((double)d); return *this; } inline Float & operator += (Float &d) { set((double)*this + (double)d ); return *this; } inline Float & operator *= (Float &d) { set((double)*this * (double)d ); return *this; } inline Float & operator *= (double d) { set((double)*this * d ); return *this; } private: double value; }; inline bool operator!=(Float &iLValue, Float &iRValue) { return (double)iLValue != (double)iRValue; } /*****************************************************************/ class String : public Value { public: explicit String(const char *newValue); String(const char *newValue, size_t len); String(const char *_name, const char *newValue, const char *desc = 0); virtual ~String(); virtual std::string toString(); const char *getVal(); virtual void set(Value *); virtual void set(const char *cP, int len = 0); virtual void set(Packet &); virtual void get(char *, int len); virtual void get(Packet &); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *, int len); inline operator const char *() { return getVal(); } private: std::string value; }; inline bool operator!=(String &LValue, String &RValue) { return strcmp((const char *)LValue, (const char *)RValue) != 0; } /*****************************************************************/ class AbstractRange : public Value { public: AbstractRange(unsigned int leftVal, unsigned int rightVal); virtual ~AbstractRange(); virtual string toString(); string toString(const char* format); virtual unsigned int get_leftVal(); virtual unsigned int get_rightVal(); virtual void set(Value *); virtual Value *copy(); /// copy the object value to a user char array virtual char *toString(char *return_str, int len); static AbstractRange* typeCheck(Value* val, string valDesc); virtual bool compare(ComparisonOperator *compOp, Value *rvalue); private: unsigned int left; unsigned int right; }; //------------------------------------------------------------------------ // Function -- maybe should go into its own header file. // typedef list ExprList_t; namespace gpsim { class Function : public gpsimObject { public: Function(const char *_name, const char *desc=0); virtual ~Function(); virtual string description(); virtual string toString(); void call(ExprList_t *vargs); }; } char * TrimWhiteSpaceFromString(char * pBuffer); char * UnquoteString(char * pBuffer); string &toupper(string & sStr); #endif // __VALUE_H__ gpsim-0.30.0/src/gpsim_def.h0000664000076400007640000000203113041763613012541 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* * gpsim_def.h * * This include file contains global definitions. */ #ifndef __GPSIM_VERSION_H__ #define __GPSIM_VERSION_H__ //#define GPSIM_VERSION VERSION #define MAX_PROGRAM_MEMORY 0xffff #define DEFAULT_GUI_UPDATE_RATE 0x100000 #define MAX_HLL_FILES 20 #endif // __GPSIM_VERSION_H__ gpsim-0.30.0/src/hexutils.cc0000664000076400007640000002467713041763613012633 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2007 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // T. Scott Dattalo // Portions of this file were obtained from: /* intel16.c - read an intel hex file */ /* Copyright (c) 1994 Ian King */ #include #include #include "picdis.h" #include "exports.h" #include "pic-processor.h" #include "hexutils.h" #include "program_files.h" //------------------------------------------------------------------------ // IntelHexProgramFileType -- constructor // // When a IntelHexProgramFileType is instantiated, it will get placed // on to a 'ProgramFileType' list. This list is then used (ultimately) // by the 'load' command to load files of this type. IntelHexProgramFileType::IntelHexProgramFileType() { RegisterProgramFileType(this); // Determine endianess of current processor short word = 0x4321; isBigEndian = (*(char *)& word) != 0x21; } void IntelHexProgramFileType::putachar (FILE * file, unsigned char c) { checksum += c; fprintf(file, "%02X", c); } /* write big endian word */ void IntelHexProgramFileType::write_be_word(FILE * file, int w) { unsigned short nw =hton16(w); putachar(file, nw & 0xff ); putachar(file, (nw >> 8) & 0xff); } /* write little endian word */ void IntelHexProgramFileType::write_le_word(FILE * file, int w) { unsigned short nw =hton16(w); putachar(file, (nw >> 8) & 0xff); putachar(file, nw & 0xff ); } int IntelHexProgramFileType::getachar (FILE * file) { int c; do c = fgetc (file); while (c == '\r'); /* strip LF out of MSDOS files */ return c; } unsigned char IntelHexProgramFileType::getbyte (FILE * file) { unsigned char byte; unsigned int data; if (fscanf (file, "%02x", &data) != 1) return 0; byte = data & 0xff; checksum += byte; /* all the bytes are used in the checksum */ /* so here is the best place to update it */ return byte; } /* read big endian word */ int IntelHexProgramFileType::read_be_word(FILE * file) { int w; w = getbyte(file); w |= getbyte(file) << 8; return(ntoh16(w)); } /* read little endian word */ int IntelHexProgramFileType::read_le_word(FILE * file) { int w; w = getbyte(file) << 8; w |= getbyte(file); return(ntoh16(w)); } unsigned int IntelHexProgramFileType::getword(FILE *file) { unsigned char lo = getbyte(file); return ((getbyte(file) << 8) | lo); } #include "cmd_gpsim.h" int IntelHexProgramFileType::LoadProgramFile(Processor **pProcessor, const char *pFilename, FILE *inputfile, const char *pProcessorName) { if(verbose) cout << "load hex\n"; if(*pProcessor == NULL) { // Need to determine processor from file. // for now return error. return ERR_NEED_PROCESSOR_SPECIFIED; } // assume no configuration word is in the hex file. (*pProcessor)->set_config_word((*pProcessor)->config_word_address(),0xffff); int iReturn; if ((iReturn = readihex16 (*pProcessor, inputfile)) != SUCCESS) { // No errors were found in the hex file. (*pProcessor)->set_frequency(10e6); (*pProcessor)->reset(POR_RESET); (*pProcessor)->simulation_mode = eSM_STOPPED; if(verbose) get_cycles().dump_breakpoints(); return SUCCESS; } return iReturn; } /* * writeihexN outputs Register structures in Intel hex format * * bytes_per_word - number of bytes of register to output * fr - pointer to array of Register structures * size - number of Register structures to output * file - File descriptor for output * out_base - address offset in words for first register * * If bytes_per_word == 1 this writes ihex8 format * bytes_per_word == 2 this writes ihex16 format * address is big endian, data little endian * byte address (word_address*2) is written */ void IntelHexProgramFileType::writeihexN(int bytes_per_word, Register **fr, gint32 size, FILE *file, gint32 out_base) { gint32 extended_address; gint32 address; int rec_size = 32; // output record size in bytes int i; int j = 0; if (fr == NULL || file == NULL || size <= 0 || (bytes_per_word != 1 && bytes_per_word != 2) ) return; out_base <<= (bytes_per_word - 1); // convert word address to byte address extended_address = out_base >> 16; address = out_base & 0xffff; if (extended_address) fprintf(file, ":02000004%04X%02X\n", extended_address, ext_csum(extended_address) ); while( j < size) { if (rec_size > (size - j) * bytes_per_word) rec_size = (size -j) * bytes_per_word; if (address & 0x10000) { extended_address++; address &= 0xffff; fprintf(file, ":02000004%04X%02X\n", extended_address, ext_csum(extended_address) ); } fprintf(file, ":%02X", rec_size); checksum = rec_size; write_be_word(file, address); putachar(file, 0); for(i = 0; i < rec_size; j++, i += bytes_per_word) { if (bytes_per_word == 2) write_le_word(file, fr[j]->get_value()); else putachar(file, fr[j]->get_value()); } fprintf(file, "%02X\n", (-checksum) & 0xff); address += rec_size; } fprintf(file, ":00000001FF\n"); } int IntelHexProgramFileType::readihex16 (Processor *pProcessor, FILE * file) { int extended_address = 0; int address; int linetype = 0; int bytesthisline; int i; int lineCount = 1; int csby; Processor *& cpu = pProcessor; while (1) { if (getachar (file) != ':') { printf ("Need a colon as first character in each line\n"); printf ("Colon missing in line %d\n", lineCount); //exit (1); return ERR_BAD_FILE; } checksum = 0; bytesthisline = getbyte (file); address = read_be_word(file) / 2; /* wierdness of INHX16! address different */ /* endian-ness and 2x too big */ /* The address is big endian and is a byte address * which is why gpsim which uses word addresses considers * them 2x to big. This file assumes the data is little endian. * RRR */ linetype = getbyte (file); /* 0 for data, 1 for end */ switch (linetype ) { case 0: // Data record { unsigned char buff[256]; bytesthisline &= 0xff; for (i = 0; i < bytesthisline; i++) buff[i] = getbyte(file); cpu->init_program_memory_at_index(address|extended_address, buff, bytesthisline); } break; case 1: // End of hex file return SUCCESS; case 4: // Extended address { extended_address = read_be_word(file) << 15; printf ("Extended linear address %x %x\n", address, extended_address); } break; default: printf ("Error! Unknown record type! %d\n", linetype); return ERR_BAD_FILE; } csby = getbyte (file); /* get the checksum byte */ /* this should make the checksum zero */ /* due to side effect of getbyte */ if (checksum) { printf ("Checksum error in input file.\n"); printf ("Got 0x%02x want 0x%02x at line %d\n", csby, (0 - checksum) & 0xff, lineCount); return ERR_BAD_FILE; } (void) getachar (file); /* lose */ lineCount++; } return SUCCESS; } /* * readihexN loads Register structures from file in Intel hex format * * bytes_per_word - number of bytes of register to output (1 & 2 supported) * fr - pointer to array of Register structures * size - number of Register structures to output * file - File descriptor for output * offset - address offset in words for first register * * If bytes_per_word == 1 this reads ihex8 format * bytes_per_word == 2 this reads ihex16 format * address is big endian, data little endian * byte address (word address*2) is read */ int IntelHexProgramFileType::readihexN (int bytes_per_word, Register **fr, gint32 size, FILE * file, gint32 offset) { int extended_address = 0; int address; int linetype = 0; int wordsthisline, bytesthisline; int i; int lineCount = 1; int csby; while (1) { if (getachar (file) != ':') { printf ("Need a colon as first character in each line\n"); printf ("Colon missing in line %d\n", lineCount); return ERR_BAD_FILE; } checksum = 0; bytesthisline = getbyte (file); wordsthisline = bytesthisline / bytes_per_word; address = read_be_word(file); linetype = getbyte (file); /* 0 for data, 1 for end */ switch (linetype ) { case 0: // Data record { int data; gint32 index = (extended_address | address) / bytes_per_word - offset; if (index < 0) { printf("Address 0x%x less than offset 0x%x line %d\n", (extended_address | address) / bytes_per_word, offset, lineCount ); return ERR_BAD_FILE; } if (index + wordsthisline > size) { printf("Index %d exceeds size %d at line %d\n", index + wordsthisline, size, lineCount ); return ERR_BAD_FILE; } for (i = 0; i < wordsthisline; i++) { if (bytes_per_word == 1) data = getbyte(file); else data = read_le_word(file); fr[index+i]->put_value(data); } } break; case 1: // End of hex file return SUCCESS; case 4: // Extended address { extended_address = read_be_word(file) << 16; printf ("Extended linear address %x %x\n", address, extended_address); } break; default: printf ("Error! Unknown record type! %d\n", linetype); return ERR_BAD_FILE; } csby = getbyte (file); /* get the checksum byte */ /* this should make the checksum zero */ /* due to side effect of getbyte */ if (checksum) { printf ("Checksum error in input file.\n"); printf ("Got 0x%02x want 0x%02x at line %d\n", csby, (0 - checksum) & 0xff, lineCount); return ERR_BAD_FILE; } (void) getachar (file); /* lose */ lineCount++; } return SUCCESS; } /* ... The End ... */ gpsim-0.30.0/src/p16f91x.cc0000664000076400007640000007452713111705422012073 00000000000000/* Copyright (C) 2017 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16f91x // // This file supports: // P16F917 P16F914 // P16F916 P16F913 // #include #include #include #include "../config.h" #include "symbol.h" #include "p16f91x.h" #include "pic-ioports.h" #include "stimuli.h" #include "packages.h" P16F91X::P16F91X (const char *_name, const char *_desc) : _14bit_processor(_name,_desc), intcon_reg(this,"intcon","Interrupt Control"), t1con(this, "t1con", "TMR1 Control"), pie1(this,"PIE1", "Peripheral Interrupt Enable"), pie2(this,"PIE2", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), ccp2con(this, "ccp2con", "Capture Compare Control"), ccpr2l(this, "ccpr2l", "Capture Compare 2 Low"), ccpr2h(this, "ccpr2h", "Capture Compare 2 High"), pcon(this, "pcon", "pcon"), lvdcon(this, "lvdcon", "Low-Voltage Detect Control Register"), ssp(this), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adresh", "A2D Result"), adresl(this,"adresl", "A2D Result Low"), ansel(this, "ansel", "Analog Select Register"), usart(this), lcd_module(this, true), wdtcon(this, "wdtcon", "WDT Control", 0x1f), osctune(this, "osctune", "OSC Tune"), comparator(this) { pir1 = new PIR1v4(this,"pir1","Peripheral Interrupt Register",&intcon_reg, &pie1); pir2 = new PIR2v5(this,"pir2","Peripheral Interrupt Register",&intcon_reg, &pie2); m_porta = new PicPortRegister(this,"porta","", 8, 0xff); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); m_iocb = new IOC(this, "iocb", "Interrupt-On-Change B Register"); m_portb = new PicPortGRegister(this,"portb","",&intcon_reg,m_iocb,8,0xff); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false); m_wpub = new WPU(this, "wpub", "Weak Pull-up Register", m_portb, 0xff); m_portc = new PicPortRegister(this,"portc","", 8, 0xff); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false); m_porte = new PicPortRegister(this,"porte","", 4, 0x0f); m_trise = new PicTrisRegister(this,"trise","", m_porte, false, 0x7); osccon = new OSCCON(this, "osccon", "OSC Control"); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir1); e->initialize(256); e->set_intcon(&intcon_reg); set_eeprom_wide(e); } P16F91X::~P16F91X () { unassignMCLRPin(); remove_sfr_register(&tmr0); remove_sfr_register(&intcon_reg); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); delete_sfr_register(m_portb); delete_sfr_register(m_trisb); delete_sfr_register(m_wpub); delete_sfr_register(m_iocb); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(m_porte); delete_sfr_register(m_trise); remove_sfr_register(&pie1); remove_sfr_register(&pie2); delete_sfr_register(pir1); delete_sfr_register(pir2); remove_sfr_register(&t1con); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&pr2); delete_file_registers(0x20, 0x7f); delete_file_registers(0xa0, 0xef); delete_file_registers(0x120, 0x16f); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); remove_sfr_register(&adresl); remove_sfr_register(&ansel); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.cmcon1); remove_sfr_register(&comparator.vrcon); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); delete_sfr_register(osccon); remove_sfr_register(&osctune); remove_sfr_register(&wdtcon); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); delete get_eeprom(); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&t1con); remove_sfr_register(&pcon); remove_sfr_register(&lvdcon); delete_sfr_register(lcd_module.lcdcon); delete_sfr_register(lcd_module.lcdps); delete_sfr_register(lcd_module.lcdSEn[0]); delete_sfr_register(lcd_module.lcdSEn[1]); delete_sfr_register(lcd_module.lcddatax[0]); delete_sfr_register(lcd_module.lcddatax[1]); delete_sfr_register(lcd_module.lcddatax[3]); delete_sfr_register(lcd_module.lcddatax[4]); delete_sfr_register(lcd_module.lcddatax[6]); delete_sfr_register(lcd_module.lcddatax[7]); delete_sfr_register(lcd_module.lcddatax[9]); delete_sfr_register(lcd_module.lcddatax[10]); } bool P16F91X::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<2, CFG_WDTE = 1<<3, CFG_MCLRE = 1<<5, CFG_IESO = 1<<10, }; if (address == 0x2007) { unsigned int fosc = cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2); unsigned int valid_pins = m_porta->getEnableMask(); if ((cfg_word & CFG_MCLRE) == CFG_MCLRE) { assignMCLRPin(1); } else { unassignMCLRPin(); } osccon->set_config_xosc(fosc < 3); osccon->set_config_irc(fosc == 4 || fosc == 5); osccon->set_config_ieso(cfg_word & CFG_IESO); switch(fosc) { case 0: // LP oscillator: low power crystal is on RA4 and RA5 case 1: // XT oscillator: crystal/resonator is on RA4 and RA5 case 2: // HS oscillator: crystal/resonator is on RA4 and RA5 (&(*m_porta)[6])->AnalogReq((Register *)this, true, "OSC2"); (m_porta->getPin(7))->newGUIname("OSC1"); valid_pins &= 0xcf; break; case 3: // EC I/O on RA4 pin, CLKIN on RA5 (m_porta->getPin(7))->newGUIname("CLKIN"); valid_pins &= 0xef; break; case 5: // INTOSC CLKOUT on RA4 pin (&(*m_porta)[6])->AnalogReq((Register *)this, true, "CLKOUT"); case 4: // INTOSC (m_porta->getPin(7))->newGUIname("porta7"); set_int_osc(true); osccon->set_rc_frequency(); break; case 6: //RC oscillator: I/O on RA4 pin, RC on RA5 (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; case 7: // RC oscillator: CLKOUT on RA4 pin, RC on RA5 (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT"); (m_porta->getPin(5))->newGUIname("RC"); valid_pins &= 0xdf; break; }; if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_trisa->setEnableMask(valid_pins & 0xf7); } } return true; } //------------------------------------------------------------------- void P16F91X::create_sfr_map() { add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); alias_file_registers(0x00,0x00,0x100); alias_file_registers(0x00,0x00,0x180); add_sfr_register(&tmr0, 0x01); alias_file_registers(0x01,0x01,0x100); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); alias_file_registers(0x02,0x04,0x100); alias_file_registers(0x02,0x04,0x180); add_sfr_register(m_porta, 0x05); add_sfr_register(m_portb, 0x06); add_sfr_register(m_wpub, 0x95, RegisterValue(0xff,0),"wpub"); add_sfr_register(m_iocb, 0x96, RegisterValue(0xff,0),"iocb"); alias_file_registers(0x06, 0x06, 0x100); add_sfr_register(m_portc, 0x07); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0), "tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0), "tmr1h"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); alias_file_registers(0x0a,0x0b,0x100); alias_file_registers(0x0a,0x0b,0x180); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&ansel, 0x91, RegisterValue(0xff,0)); add_sfr_register(&pcon, 0x8e, RegisterValue(0x10,0)); add_file_registers(0x20, 0x7f, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); add_file_registers(0xa0, 0xef, 0); add_file_registers(0x120, 0x16f, 0); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); alias_file_registers(0x81, 0x81, 0x100); add_sfr_register(m_trisa, 0x85, RegisterValue(0xff,0)); add_sfr_register(m_trisb, 0x86, RegisterValue(0xff,0)); alias_file_registers(0x86, 0x86, 0x100); add_sfr_register(m_trisc, 0x87, RegisterValue(0xff,0)); intcon = &intcon_reg; add_sfr_register(pir1, 0x0c, RegisterValue(0,0),"pir1"); add_sfr_register(pir2, 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0), "pie1"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0), "pie2"); add_sfr_register(osccon, 0x8f, RegisterValue(0x60,0)); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); add_sfr_register(&wdtcon, 0x105, RegisterValue(0x08,0),"wdtcon"); add_sfr_register(lcd_module.lcdps, 0x108, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcdSEn[0], 0x11c, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcdSEn[1], 0x11d, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[0], 0x110, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[1], 0x111, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[3], 0x113, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[4], 0x114, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[6], 0x116, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[7], 0x117, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[9], 0x119, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[10], 0x11a, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcdcon, 0x107, RegisterValue(0x13,0)); lcd_module.set_Vlcd(&(*m_portc)[0], &(*m_portc)[1], &(*m_portc)[2]); lcd_module.set_LCDsegn(0, &(*m_portb)[0], &(*m_portb)[1], &(*m_portb)[2], &(*m_portb)[3]); lcd_module.set_LCDsegn(4, &(*m_porta)[4], &(*m_porta)[5], &(*m_portc)[3], &(*m_porta)[1]); lcd_module.set_LCDsegn(8, &(*m_portc)[7], &(*m_portc)[6], &(*m_portc)[4], &(*m_portc)[5]); lcd_module.set_LCDsegn(12, &(*m_porta)[0], &(*m_portb)[7], &(*m_portb)[6], &(*m_porta)[3]); lcd_module.setIntSrc(new InterruptSource(pir2, (1<<4))); lcd_module.set_t1con(&t1con); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); add_sfr_register(&comparator.cmcon, 0x9c, RegisterValue(0,0), "cmcon0"); add_sfr_register(&comparator.cmcon1, 0x97, RegisterValue(0,0), "cmcon1"); add_sfr_register(&comparator.vrcon, 0x9d, RegisterValue(0,0), "vrcon"); // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), NULL, &(*m_porta)[0], &(*m_porta)[1], // AN0 AN1 &(*m_porta)[2], &(*m_porta)[3], // AN2 AN3 &(*m_porta)[4], &(*m_porta)[5]); //OUT0 OUT1 comparator.cmcon.set_tmrl(&tmr1l); comparator.cmcon1.set_tmrl(&tmr1l); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN1, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 1, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 2, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN2, AN0, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 5, AN1, AN2, AN1, V06, NO_OUT); comparator.cmcon.set_configuration(1, 6, AN0, AN2, AN0, AN2, OUT0); comparator.cmcon.set_configuration(2, 6, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.vrcon.setValidBits(0xaf); pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; // FIXME -- can't delete this new'd item tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF)); // tmr1l.ccpcon = &ccp1con; tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); tmr2.add_ccp ( &ccp2con ); pr2.tmr2 = &tmr2; ccp1con.setIOpin(&(*m_portc)[5]); ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v4::CCP1IF, &tmr2); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; usart.initialize(pir1,&(*m_portc)[6], &(*m_portc)[7], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); } pie1.setPir(pir1); if (pir2) { pir2->set_intcon(&intcon_reg); pir2->set_pie(&pie2); } //pie2.setPir(get_pir2()); pie2.setPir(pir2); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); // Enable program memory reads and writes. get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); adcon0.setAdres(&adres); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setPir(pir1); adcon0.setChannel_Mask(7); adcon0.setChannel_shift(2); adcon0.setGo(1); adcon0.Vrefhi_position = 3; adcon0.Vreflo_position = 2; adcon0.setAdresLow(&adresl); adcon0.setA2DBits(10); adcon1.setAdcon0(&adcon0); intcon_reg.set_pir_set(get_pir_set()); ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // I2C port SSP_TYPE_BSSP ); add_sfr_register(&ssp.sspbuf, 0x13, RegisterValue(0,0),"sspbuf"); add_sfr_register(&ssp.sspcon, 0x14, RegisterValue(0,0),"sspcon"); add_sfr_register(&ssp.sspadd, 0x93, RegisterValue(0,0),"sspadd"); add_sfr_register(&ssp.sspstat, 0x94, RegisterValue(0,0),"sspstat"); tmr2.ssp_module[0] = &ssp; add_sfr_register(&ccpr1l, 0x15, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x16, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x17, RegisterValue(0,0)); add_sfr_register(&lvdcon, 0x109, RegisterValue(4,0)); lvdcon.setIntSrc(new InterruptSource(pir2, (1<<2))); } void P16F91X::option_new_bits_6_7(unsigned int bits) { m_portb->setRBPU( (bits & OPTION_REG::BIT7) == OPTION_REG::BIT7); m_portb->setIntEdge((bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); } void P16F91X::create_symbols() { if(verbose) cout << "creating P16F91X symbols\n"; pic_processor::create_symbols(); addSymbol(Wreg); addSymbol(m_porte); addSymbol(m_trise); } //------------------------------------------------------------------- void P16F91X::update_vdd() { lvdcon.check_lvd(); Processor::update_vdd(); } //------------------------------------------------------------------- void P16F91X::enter_sleep() { tmr1l.sleep(); lcd_module.sleep(); osccon->sleep(); _14bit_processor::enter_sleep(); } //------------------------------------------------------------------- void P16F91X::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr1l.wake(); lcd_module.wake(); osccon->wake(); _14bit_processor::exit_sleep(); } } //------------------------------------------------------------------- void P16F91X_40::create_iopin_map(void) { package = new Package(40); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin( 1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_bi_directional("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin( 8, m_porte->addPin(new IO_bi_directional("porte0"),0)); package->assign_pin( 9, m_porte->addPin(new IO_bi_directional("porte1"),1)); package->assign_pin(10, m_porte->addPin(new IO_bi_directional("porte2"),2)); package->assign_pin(11, 0); package->assign_pin(12, 0); package->assign_pin(13, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin(14, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(23, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(24, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(25, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(26, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, m_portd->addPin(new IO_bi_directional("portd0"),0)); package->assign_pin(20, m_portd->addPin(new IO_bi_directional("portd1"),1)); package->assign_pin(21, m_portd->addPin(new IO_bi_directional("portd2"),2)); package->assign_pin(22, m_portd->addPin(new IO_bi_directional("portd3"),3)); package->assign_pin(27, m_portd->addPin(new IO_bi_directional("portd4"),4)); package->assign_pin(28, m_portd->addPin(new IO_bi_directional("portd5"),5)); package->assign_pin(29, m_portd->addPin(new IO_bi_directional("portd6"),6)); package->assign_pin(30, m_portd->addPin(new IO_bi_directional("portd7"),7)); package->assign_pin(31, 0); package->assign_pin(32, 0); package->assign_pin(33, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(34, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(35, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(36, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(38, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(39, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(40, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); } void P16F91X_40::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F91X_40::create_sfr_map() { if(verbose) cout << "creating f91X_40 registers \n"; P16F91X::create_sfr_map(); add_sfr_register(m_porte, 0x09); add_sfr_register(m_trise, 0x89, RegisterValue(0x0f,0)); add_sfr_register(m_portd, 0x08); add_sfr_register(m_trisd, 0x88, RegisterValue(0xff,0)); adcon1.setNumberOfChannels(8); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setIOPin(5, &(*m_porte)[0]); adcon1.setIOPin(6, &(*m_porte)[1]); adcon1.setIOPin(7, &(*m_porte)[2]); ansel.setAdcon1(&adcon1); ansel.setValidBits(0xff); ansel.config(0xff, 0); add_sfr_register(&ccpr2l, 0x1b, RegisterValue(0,0)); add_sfr_register(&ccpr2h, 0x1c, RegisterValue(0,0)); add_sfr_register(&ccp2con, 0x1d, RegisterValue(0,0)); ccp2con.setIOpin(&(*m_portd)[2]); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v5::CCP2IF, &tmr2); ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; add_sfr_register(lcd_module.lcdSEn[2], 0x11e, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[2], 0x112, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[5], 0x115, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[8], 0x118, RegisterValue(0x0,0)); add_sfr_register(lcd_module.lcddatax[11], 0x11b, RegisterValue(0x0,0)); lcd_module.set_LCDcom(&(*m_portb)[4], &(*m_portb)[5], &(*m_porta)[2], &(*m_portd)[0]); lcd_module.set_LCDsegn(16, &(*m_portd)[3], &(*m_portd)[4], &(*m_portd)[5], &(*m_portd)[6]); lcd_module.set_LCDsegn(20, &(*m_portd)[7], &(*m_porte)[0], &(*m_porte)[1], &(*m_porte)[2]); } void P16F91X_40::create() { if(verbose) cout << " f91X_40 create \n"; _14bit_processor::create(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 } void P16F91X_40::create_symbols() { P16F91X::create_symbols(); addSymbol(m_portd); addSymbol(m_trisd); } P16F91X_40::P16F91X_40(const char *_name, const char *desc) : P16F91X(_name,desc) { if(verbose) cout << "f91X_40 constructor, type = " << isa() << '\n'; m_portd = new PicPortRegister(this,"portd","", 8, 0xff); m_trisd = new PicTrisRegister(this,"trisd","", m_portd, false); } P16F91X_40::~P16F91X_40() { delete_sfr_register(m_portd); delete_sfr_register(m_trisd); delete_sfr_register(lcd_module.lcddatax[2]); delete_sfr_register(lcd_module.lcddatax[5]); delete_sfr_register(lcd_module.lcddatax[8]); delete_sfr_register(lcd_module.lcddatax[11]); delete_sfr_register(lcd_module.lcdSEn[2]); remove_sfr_register(&ccp2con); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccpr2l); } //======================================================================== void P16F91X_28::create_iopin_map(void) { package = new Package(28); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin( 1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_bi_directional("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(8, 0); package->assign_pin(9, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin(10, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, 0); package->assign_pin(20, 0); package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); } void P16F91X_28::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F91X_28::create_sfr_map() { if(verbose) cout << "creating f91X_28 registers \n"; P16F91X::create_sfr_map(); add_sfr_register(m_porte, 0x09); add_sfr_register(m_trise, 0x89, RegisterValue(0x04,0)); adcon1.setNumberOfChannels(5); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); ansel.setAdcon1(&adcon1); ansel.setValidBits(0x1f); ansel.config(0x1f, 0); lcd_module.set_LCDcom(&(*m_portb)[4], &(*m_portb)[5], &(*m_porta)[2], &(*m_porta)[3]); } void P16F91X_28::create() { if(verbose) cout << " f91X_28 create \n"; _14bit_processor::create(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 } void P16F91X_28::create_symbols() { P16F91X::create_symbols(); } //======================================================================== P16F91X_28::P16F91X_28(const char *_name, const char *desc) : P16F91X(_name,desc) { if(verbose) cout << "f91X_28 constructor, type = " << isa() << '\n'; } P16F91X_28::~P16F91X_28() { } Processor * P16F917::construct(const char *name) { P16F917 *p = new P16F917(name); if(verbose) cout << " f917 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F917::create() { if(verbose) cout << " f917 create \n"; P16F91X_40::create(); P16F91X_40::create_iopin_map(); create_sfr_map(); } void P16F917::create_sfr_map() { P16F91X_40::create_sfr_map(); add_file_registers(0x190, 0x1ef, 0); } P16F917::~P16F917() { delete_file_registers(0x190, 0x1ef); } P16F917::P16F917(const char *_name, const char *desc) : P16F91X_40(_name, desc) { } void P16F917::create_symbols() { if(verbose) cout << "f917 create symbols\n"; P16F91X::create_symbols(); } //******************************************************* Processor * P16F916::construct(const char *name) { P16F916 *p = new P16F916(name); if(verbose) cout << " f916 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F916::create() { if(verbose) cout << " f916 create \n"; P16F91X_28::create(); P16F91X_28::create_iopin_map(); create_sfr_map(); } void P16F916::create_sfr_map() { P16F91X_28::create_sfr_map(); add_file_registers(0x190, 0x1ef, 0); } P16F916::~P16F916() { delete_file_registers(0x190, 0x1ef); } P16F916::P16F916(const char *_name, const char *desc) : P16F91X_28(_name, desc) { } //******************************************************* Processor * P16F914::construct(const char *name) { P16F914 *p = new P16F914(name); if(verbose) cout << " f914 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F914::create() { if(verbose) cout << " f914 create \n"; P16F91X_40::create(); P16F91X_40::create_iopin_map(); create_sfr_map(); } //******************************************************* Processor * P16F913::construct(const char *name) { P16F913 *p = new P16F913(name); if(verbose) cout << " f913 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F913::create() { if(verbose) cout << " f913 create \n"; P16F91X_28::create(); P16F91X_28::create_iopin_map(); create_sfr_map(); } gpsim-0.30.0/src/psp.h0000664000076400007640000000456113041763624011422 00000000000000/* Copyright (C) 2006 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PSP_H__ #define __PSP_H__ #include "pic-processor.h" #include "14bit-registers.h" #include "pic-ioports.h" #include "pir.h" class RD_SignalSink; class CS_SignalSink; class WR_SignalSink; class PicPSP_PortRegister; class PicTrisRegister; class PSPCON : public sfr_register, public TriggerObject { public: PSPCON(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); }; class PSP { public: void initialize( PIR_SET *pir_set, PicPSP_PortRegister *port_set, PicTrisRegister *port_tris, sfr_register *PSPcon, PinModule *pin_RD, PinModule *pin_CS, PinModule *pin_WR); void setRD_State(char new3State); void setCS_State(char new3State); void setWR_State(char new3State); void ParallelSetbit(int m_iobit,char cNewSinkState); void state_control(void); bool pspmode(void) { return((cntl_tris->get() & PSPMODE) == PSPMODE);} void psp_put(unsigned int new_value); unsigned int psp_get(void); PSP() { m_rd_sink=0; m_cs_sink=0; m_wr_sink=0; state=0;} enum { TRIS_MASK = 7, PSPMODE = 1<<4, IBOV = 1<<5, OBF = 1<<6, IBF = 1<<7 }; protected: enum { ST_INACTIVE = 0, ST_READ, ST_WRITE }; unsigned int put_value; unsigned int get_value; int state; bool rd; bool cs; bool wr; PIR_SET *pir_set; PicPSP_PortRegister *parallel_port; PicTrisRegister *parallel_tris; sfr_register *cntl_tris; PinModule *Not_RD; PinModule *Not_CS; PinModule *Not_WR; RD_SignalSink *m_rd_sink; CS_SignalSink *m_cs_sink; WR_SignalSink *m_wr_sink; }; #endif // __PSP_H__ gpsim-0.30.0/src/cod.cc0000664000076400007640000006725013065703127011525 00000000000000/* -*- Mode: C++; c-file-style: "GNU"; comment-column: 40 -*- */ /* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // cod.cc // // The file contains the code for reading Byte Craft's .cod // formatted symbol files. // #include #include #include #include #include #include #ifdef _WIN32 #include #endif #include "../config.h" #include "exports.h" #include "gpsim_def.h" #include "sim_context.h" #include "pic-processor.h" #include "picdis.h" #include "symbol.h" #include "cod.h" #include "interface.h" #include "fopen-path.h" #include "breakpoints.h" /* experiment with assertions */ #include "cmd_manager.h" /* end of assertion experiment */ PicCodProgramFileType::PicCodProgramFileType() { codefile = 0; temp_block = 0; lstfilename = 0; memset(&main_dir, 0, sizeof(main_dir)); // Define a flag that tells whether or not we should care about the // case of text strings in the .cod file. ignore_case_in_cod = 1; gputils_recent = 0; RegisterProgramFileType(this); } int PicCodProgramFileType::get_string(char *dest, char *src, size_t len) { size_t n = *src++; if(n < len) { n = min(n, len - 1); strncpy(dest, src, n); dest[n] = '\0'; return SUCCESS; } return ERR_BAD_FILE; } // Capitalize a string (there must be a library function that does this! void strtoupper(char *s) { if(!s) return; while(*s) { *s = toupper(*s); s++; } } void strtolower(char *s) { if(!s) return; char *t = s; if(verbose) cout << "tolower " << s; while(*s) { *s = tolower(*s); s++; } if(verbose) cout << "after " << t <<'\n'; } unsigned short get_short_int( char * buff) { return ( (unsigned char)buff[0] + ((unsigned char)buff[1] << 8)); } int PicCodProgramFileType::read_block(char * block, int block_number) { if (fseek(codefile, block_number * COD_BLOCK_SIZE, SEEK_SET)) { fprintf(stderr, "PicCodProgramFileType::read_block fseek error byte %" PRINTF_GINT64_MODIFIER "d\n", (gint64) block_number * COD_BLOCK_SIZE); return ERR_BAD_FILE; } size_t n = fread(block, 1, COD_BLOCK_SIZE, codefile); if (n == 0 && feof(codefile)) return SUCCESS; if (n == 0 && ferror(codefile)) { perror("PicCodProgramFileType::read_block fread error "); return ERR_BAD_FILE; } if (COD_BLOCK_SIZE != n) return ERR_BAD_FILE; return SUCCESS; } unsigned int get_be_int( char * buff) { return ( (unsigned char)buff[3] + ((unsigned char)buff[2] << 8) + ((unsigned char)buff[1] << 16) + ((unsigned char)buff[0] << 24)); } //----------------------------------------------------------- // cod_address_in_range - check to see if an address falls into // one of the valid code areas. A code area is define by a start // address and an end address. If the address is in a valid area // then a '1' is returned. // int cod_address_in_range(char *range_block,int address) { int i =0; int start,end; do { // get the start and end addresses of this range start = get_short_int(&range_block[i])/2; i+=2; end = get_short_int(&range_block[i])/2; i+=2; if((address>=start) && (address<=end)) return 1; // in range // The end address can be zero on only the first // start/end pair. if((end == 0) && (i>4)) return 0; } while(idir.block[COD_DIR_MEMMAP]); j = get_short_int(&dbi->dir.block[COD_DIR_MEMMAP + 2]); if ((i != j) || (i == 0)) { cout << ".cod range error \n"; return; } _64k_base = get_short_int(&dbi->dir.block[COD_DIR_HIGHADDR]) << 15; read_block(range_block, i); // Loop through all of the .cod file blocks that (may) contain code for (i = 0; i < COD_CODE_IMAGE_BLOCKS; i++) { index = get_short_int(&dbi->dir.block[2 * (COD_DIR_CODE + i)]); if (index != 0) { read_block(temp_block, index); for(j = 0; j < COD_BLOCK_SIZE / 2; j++) { int PCindex = i * COD_BLOCK_SIZE / 2 + j; if (cod_address_in_range(range_block, PCindex)) { cpu->init_program_memory_at_index(PCindex + _64k_base, (int)get_short_int(&temp_block[j * 2])); } } } } dbi = dbi->next_dir_block_info; } while (dbi); } //----------------------------------------------------------- FILE *PicCodProgramFileType::open_a_file(char **filename) { FILE *t; if(verbose) cout << "Trying to open a file: " << *filename << '\n'; if(0 != (t = fopen_path(*filename,"r"))) return t; if(!ignore_case_in_cod) return 0; strtoupper(*filename); if(0 != (t = fopen_path(*filename,"r"))) return t; strtolower(*filename); if(0 != (t = fopen_path(*filename,"r"))) return t; // cout << "couldn't open " << *filename << " (or any upper/lower case variation)\n"; return 0; } //----------------------------------------------------------- // Determing the .lst file name from the cod file file name. // imo this is cheezy because the .cod file and .lst file have // to have the same base file name. By convention, mpasm always // made sure this happened. gpasm otoh, gives you an option to // make the two different. Furthermore, gpasm includes the .lst // file file name in the list of source files within the .cod // file - unfortunately mpasm doesn't ... so gpsim has to assume // the list file isn't present void PicCodProgramFileType::set_lstname(const char *filename) { int i; lstfilename = strdup(filename); char *pc = strrchr(lstfilename, '.'); if (pc == 0) { if( (i = strlen(lstfilename)) < (256-4)) pc = lstfilename + i; else return; } strcpy(pc, ".lst"); } //----------------------------------------------------------- int PicCodProgramFileType::read_src_files_from_cod(Processor *cpu) { #define FILE_SIZE 64 #define FILES_PER_BLOCK (COD_BLOCK_SIZE/FILE_SIZE) int iReturn = SUCCESS; int i,j,start_block,end_block,offset,num_files; char b[FILE_SIZE]; num_files = 0; end_block = 0; // eliminates a (spurious) warning //start_block = get_short_int(&directory_block_data[COD_DIR_NAMTAB]); start_block = get_short_int(&main_dir.dir.block[COD_DIR_NAMTAB]); // First, just count the number of source files // These may be duplicates, but this is an upper bound if(start_block) { // end_block = get_short_int(&directory_block_data[COD_DIR_NAMTAB+2]); end_block = get_short_int(&main_dir.dir.block[COD_DIR_NAMTAB+2]); for(j=start_block; j<=end_block; j++) { read_block(temp_block, j); for(i=0; ifiles.list_id(num_files); num_files = 0; // now use 'num_files' as a counter. for(j=start_block; j<=end_block; j++) { read_block(temp_block, j); for(i=0; i= 'A') && (filenm[0] <= 'Z') && (':' == filenm[1]) && ('\\' == filenm[2])) { char *cp; filenm += 3; // strip C:\ from MPLAB files // convert \ to / now??? for (cp = filenm; *cp; ++cp) { // convert DOS slash to Unix slash if ('\\' == *cp) *cp = '/'; } } #endif string s1 = string(filenm); if(temp_block[offset] && (cpu->files.Find(s1) < 0)) { // // Add this file to the list // cpu->files.Add(filenm); if((strncmp(lstfilename, filenm,256) == 0) && (cpu->files.list_id() >= cpu->files.nsrc_files()) ) { if(verbose) cout << "Found list file " << ((cpu->files)[num_files])->name() << endl; cpu->files.list_id(num_files); found_lst_in_cod = 1; } num_files++; } else if(verbose) cout << "Could not find '" << filenm << "'\n"; } } if(verbose) cout << "Found " << num_files << " source files in .cod file\n"; if(num_files != cpu->files.nsrc_files()) cout << "warning, number of sources changed from " << num_files << " to " << cpu->files.nsrc_files() << " while reading code (gpsim bug)\n"; if(!found_lst_in_cod) { cpu->files.Add(lstfilename); cpu->files.list_id(num_files); if(verbose) printf("List file %s wasn't in .cod\n",lstfilename); } } else printf("No source file info\n"); _Cleanup: #if 0 // Debug code cout << " new file stuff: " << cpu->files.nsrc_files() << " new files\n"; for(i=0; ifiles.nsrc_files(); i++) { cout << ((cpu->files)[i])->name() << endl; } #endif return iReturn; } //----------------------------------------------------------- void PicCodProgramFileType::read_line_numbers_from_cod(Processor *cpu) { int j,start_block,end_block,offset; int file_id, sline,smod; unsigned int address; DirBlockInfo *dbi = &main_dir; do { start_block = get_short_int(&main_dir.dir.block[COD_DIR_LSTTAB]); if (start_block) { end_block = get_short_int(&main_dir.dir.block[COD_DIR_LSTTAB + 2]); int _64k_base = get_short_int(&dbi->dir.block[COD_DIR_HIGHADDR]) << 15; // Loop through all of the .cod file blocks that contain line number info for (j = start_block; j <= end_block; j++) { read_block(temp_block,j); // Get the line number info from within one .cod block for (offset = 0; offset < (COD_BLOCK_SIZE - COD_LS_SIZE); offset += COD_LS_SIZE) { if ((temp_block[offset + COD_LS_SMOD] & 4) == 0) { file_id = temp_block[offset + COD_LS_SFILE]; address = _64k_base + get_short_int(&temp_block[offset + COD_LS_SLOC]); //address = cpu->map_pm_address2index(address); sline = get_short_int(&temp_block[offset + COD_LS_SLINE]); smod = temp_block[offset + COD_LS_SMOD] & 0xff; if ((file_id <= cpu->files.nsrc_files()) && // (address <= cpu->program_memory_size()) && cpu->IsAddressInRange(address) && (smod == 0x80)) cpu->attach_src_line(address, file_id, sline, 0); } } } cpu->read_src_files(); } dbi = dbi->next_dir_block_info; } while (dbi); } //----------------------------------------------------------- // read_message_area(Processor *cpu) // // The .cod file message area contains information like assertions // and simulation scripts. void PicCodProgramFileType::read_message_area(Processor *cpu) { #define MAX_STRING_LEN 255 /* Maximum length of a debug message */ char DebugType,DebugMessage[MAX_STRING_LEN]; unsigned short i, j, start_block, end_block; unsigned short laddress; // If the .cod file contains a simulation script, then we'll // pass it to the command line interface. Note, we go through // this indirect way of accessing the CLI since we don't wish // for code in the src/ directory to depend directly on code // in the cli/ (or any other) directory. start_block = get_short_int(&main_dir.dir.block[COD_DIR_MESSTAB]); if(start_block) { end_block = get_short_int(&main_dir.dir.block[COD_DIR_MESSTAB+2]); for(i=start_block; i<=end_block; i++) { read_block(temp_block, i); #if 0 { // Debug code to display the contents of the message area. int q,p; printf ("Codefile block 0x%x\n",i); for (q=0,p=0; q < COD_BLOCK_SIZE; q+=16) { for (p=0; p<16; p++) printf("%02X ",(unsigned char)temp_block[q+p]); for (p=0; p<16; p++) printf("%c", isascii(temp_block[q+p]) ? temp_block[q+p] : '.'); printf("\n"); } #endif j = 0; // Each message has the form of // AAAAAAAACCstring // AAAAAAAA - 32bit address in PIC program memory // CC - 8-bit command // string - a 0-terminated string of characters. while (j < COD_BLOCK_SIZE-8) { /* read big endian */ laddress = get_be_int(&temp_block[j]); j += 4; // 4 = size of big endian DebugType = temp_block[j++]; if (DebugType == 0) { break; } get_string(DebugMessage, &temp_block[j], sizeof DebugMessage); j += strlen(DebugMessage)+1; if(verbose) printf("debug message: addr=%#x command=\"%c\" string=\"%s\"\n", laddress, DebugType, DebugMessage); // The lower case commands are user commands. The upper case are // compiler or assembler generated. This code makes no distinction // between them. switch(DebugType) { // The 'A' and 'E' options in gpasm specifies a list of gpsim commands // that are to be executed after the .cod file has been loaded. case 'a': case 'A': // assertion { string script("directive"); char buff[256]; snprintf(buff,sizeof(buff),"break e %d, %s\n",laddress,DebugMessage); string cmd(buff); cpu->add_command(script,cmd); } break; case 'e': case 'E': // gpsim command { string script("directive"); string cmd(DebugMessage); cmd = cmd + '\n'; cpu->add_command(script,cmd); } break; case 'c': case 'C': // gpsim command // The 'c'/'C' option in gpasm specifies a single gpsim command that is // to be invoked whenever the address associated with this directive // is being simulated. { bool bPost = DebugType == 'c'; CommandAssertion *pCA = new CommandAssertion(cpu,laddress,0, DebugMessage,bPost); get_bp().set_breakpoint(pCA,cpu); } case 'f': case 'F': // printf break; case 'l': case 'L': // log break; default: cout << "Warning: unknown debug message \"" << DebugType << "\"\n"; } } } } } //----------------------------------------------------------- // open_cod_file // void PicCodProgramFileType::read_symbols( Processor *cpu ) { char *s,length; short type; int i,j,start_block,end_block, value; char b[256]; start_block = get_short_int(&main_dir.dir.block[COD_DIR_LSYMTAB]); if(start_block) { end_block = get_short_int(&main_dir.dir.block[COD_DIR_LSYMTAB+2]); for(j=start_block; j<=end_block; j++) { read_block(temp_block, j); for(i=0; i128) type = COD_ST_CONSTANT; value = get_be_int(&s[length+3]); switch(type) { case COD_ST_C_SHORT: { // Change the register name to its symbolic name get_string(b, s, sizeof b); cpu->registers[value]->new_name(b); } break; case COD_ST_ADDRESS: { get_string(b, s, sizeof b); instruction *pI = cpu->pma->getFromAddress(value); if (pI) { string s(b); pI->addLabel(s); } } break; case COD_ST_CONSTANT: // Ignore as no useful purpose and may // conflict with other symbols - RRR break; default: get_string(b, s, sizeof b); cpu->addSymbol(new Integer(b,value)); break; } i += (length + 7); } } }else printf("No long symbol table info\n"); } /*---------------------------------------------*/ void clear_block(Block *b) { if(b && b->block) memset(b->block, 0, COD_BLOCK_SIZE); else assert(0); } /*---------------------------------------------*/ void create_block(Block *b) { assert(b != 0); b->block = (char *)malloc(COD_BLOCK_SIZE); clear_block(b); } void delete_block(Block *b) { if(b && b->block) { free(b->block); b->block = 0; } else assert(0); } /*------------------------------------------------------------------ * read_directory - read the directory block(s) in the .cod file */ int PicCodProgramFileType::read_directory(void) { DirBlockInfo *dbi; int ret; create_block(&main_dir.dir); if ((ret = read_block(main_dir.dir.block, 0)) != SUCCESS) return ret; dbi = &main_dir; do { int next_dir_block = get_short_int(&dbi->dir.block[COD_DIR_NEXTDIR]); if(next_dir_block) { dbi->next_dir_block_info = (DirBlockInfo *)malloc(sizeof(DirBlockInfo)); dbi = dbi->next_dir_block_info; create_block(&dbi->dir); ret = read_block(dbi->dir.block, next_dir_block); } else { dbi->next_dir_block_info = 0; return ret; } } while(1); return ERR_BAD_FILE; // should not get here } void PicCodProgramFileType::delete_directory(void) { DirBlockInfo *dbi; DirBlockInfo *next; next = main_dir.next_dir_block_info; while(next != 0) { dbi = next; next = dbi->next_dir_block_info; delete_block(&dbi->dir); free(dbi); } main_dir.next_dir_block_info = 0; delete_block(&main_dir.dir); } int PicCodProgramFileType::check_for_gputils(char *block) { int iReturn = SUCCESS; char buffer[256]; if((iReturn = get_string(buffer,&block[COD_DIR_COMPILER - 1],12)) != SUCCESS) { goto _Cleanup; } if ((strcmp("gpasm",buffer) == 0) || (strcmp("gplink",buffer) == 0)) { if(verbose) cout << "Have gputils\n"; if((iReturn = get_string(buffer,&block[COD_DIR_VERSION - 1],19)) != SUCCESS) { goto _Cleanup; } int major=0, minor=0, micro=0; if (sscanf(&buffer[0],"%d.%d.%d",&major,&minor,µ) >= 2) { if(verbose) cout << "gputils version major "<< major << " minor " << minor << " micro " << micro << endl; // if gputils version is greater than or equal to 0.13.0, then gputils // is considered "recent" if ((major >= 1) || ( minor >= 13)) { gputils_recent = 1; if(verbose) cout << "good, you have a recent version of gputils\n"; } else { cout << "Warning, you need to upgrade to gputils-0.13.0 or higher\n"; cout << "(Your assembler version is " << buffer << ")\n"; gputils_recent = 0; } } else { cout << "Warning, you need to upgrade to gputils-0.13.0 or higher\n"; cout << "Invalid version format\n"; // version number in old gputils format, so it can't be recent } } else { cout << "File not from gputils\n"; } _Cleanup: return iReturn; } //----------------------------------------------------------- // Read .c line numbers from special .asm files. void PicCodProgramFileType::read_hll_line_numbers_from_asm(Processor *cpu) { int line_number; int address; int prog_memory_size = cpu->program_memory_size(); int file_index; // Reset hll_file_id and hll_src_line throughout cpu memory for(address=0; addressprogram_memory[address]->set_hll_file_id(-1); cpu->program_memory[address]->set_hll_src_line(0); // Meaning 'not set' in this function. } // For each file int nfiles=cpu->files.nsrc_files(); for(file_index=0;file_indexfiles[file_index]->name().compare(cpu->files[file_index]->name().length()-4,4,".asm")) { int current_hll_file_id; int asmsrc_line; // Loop through the whole .asm file and look for any line markers cpu->files[file_index]->rewind(); asmsrc_line=0; while(cpu->files[file_index]->gets(text_buffer,sizeof(text_buffer))!=0) { asmsrc_line++; string fn; if(0==strncmp(text_buffer,";\t.line\t",8)) // \t.line\t12345\t"filename" { char *lineendpos=strchr(text_buffer, ';'); if(lineendpos==0) continue; *lineendpos=0; line_number=atoi(text_buffer+8); char *fnstart = strchr(lineendpos+1, '\"'); if(fnstart==0) continue; fnstart++; char *fnend = strchr(fnstart+1, '\"'); if(fnend==0) continue; *fnend=0; fn=fnstart; } else if(0==strncmp(text_buffer,";#CSRC ",7)) // ;#CSRC filename 12345 { char *fnend = strrchr(text_buffer, ' '); if(fnend==0) continue; *fnend=0; fn=text_buffer+7; char *linestart=fnend+1; line_number=atoi(linestart); } else { continue; } // Add hll file if not already added current_hll_file_id = cpu->files.Find(fn); if(current_hll_file_id<0) { current_hll_file_id=cpu->files.Add(fn, true); if(current_hll_file_id<0) continue; cpu->files[current_hll_file_id]->ReadSource(); } // Find closest address of asm line and set hll line number, hll file id and file context pm address. address=cpu->pma->find_closest_address_to_line(file_index, asmsrc_line); if(address >= 0) { int index = cpu->map_pm_address2index(address); cpu->program_memory[index]->set_hll_src_line(line_number); cpu->program_memory[index]->set_hll_file_id(current_hll_file_id); cpu->files[current_hll_file_id]->put_address(line_number, address); } } // Find address of last asm line and set hll_line -1, so we know the end when filling the gaps. address=cpu->pma->find_closest_address_to_line(file_index, asmsrc_line-1); if(address>=0) { int index = cpu->map_pm_address2index(address); cpu->program_memory[index]->set_hll_src_line(-1); } } } // Fill the addresses in the gaps. file_index=0; line_number=-1; for(address=0;addressprogram_memory[address]->get_hll_src_line(); if(line==0) { if(cpu->program_memory[address]->isa()!=instruction::INVALID_INSTRUCTION) { cpu->program_memory[address]->set_hll_file_id(file_index); cpu->program_memory[address]->set_hll_src_line(line_number); } } else { line_number=line; file_index=cpu->program_memory[address]->get_hll_file_id(); } } } //----------------------------------------------------------- // open_cod_file // // The purpose of this function is to process a .cod symbol file. // If a cpu hasn't been declared prior to calling this function, then this // function will attempt to determine the cpu from the .cod file. // /* int open_cod_file(Processor **pcpu, const char *filename) { char directory[256]; const char *dir_path_end; dir_path_end = get_dir_delim(filename); if(dir_path_end!=0) { strncpy(directory,filename,dir_path_end-filename); directory[dir_path_end-filename]=0; printf("directory is \"%s\"\n",directory); chdir(directory); filename=dir_path_end+1; printf("filename is \"%s\"\n",filename); } return load_cod_file(pcpu, filename, fopen(filename,"rb")); } */ int PicCodProgramFileType::LoadProgramFile(Processor **pcpu, const char *filename, FILE *pFile, const char *pProcessorName) { int error_code= SUCCESS; Processor *ccpu = 0; codefile = pFile; if(codefile == 0) { printf("Unable to open %s\n",filename); return ERR_FILE_NOT_FOUND; } temp_block = new char[COD_BLOCK_SIZE]; /* Start off by reading the directory block */ if ((error_code = read_directory()) != SUCCESS) goto _Cleanup; // Perform a series of integrity checks if((error_code = check_for_gputils(main_dir.dir.block)) != SUCCESS) { goto _Cleanup; } // If we get here, then the .cod file is good. if(*pcpu == 0) { char processor_type[16]; processor_type[0] = 'p'; // Hack to get around processors whose name begin with a digit. if(verbose) cout << "ascertaining cpu from the .cod file\n"; if(SUCCESS == get_string(&processor_type[1], &main_dir.dir.block[COD_DIR_PROCESSOR - 1], sizeof (processor_type)-1)) { char *pProcessorTypeOffset = isdigit(processor_type[1]) ? &processor_type[0] : &processor_type[1]; if (!pProcessorName) pProcessorName = pProcessorTypeOffset; if(verbose) cout << "found a " << processor_type << " in the .cod file\n"; *pcpu = (Processor *)CSimulationContext::GetContext()->add_processor(processor_type, pProcessorName); if(*pcpu == 0) { if(!ignore_case_in_cod) return(ERR_UNRECOGNIZED_PROCESSOR); // Could be that there's a case sensitivity issue: strtolower(processor_type); *pcpu = (Processor *)CSimulationContext::GetContext()-> add_processor(processor_type,pProcessorName); if(*pcpu == 0) return(ERR_UNRECOGNIZED_PROCESSOR); } } else { return(ERR_UNRECOGNIZED_PROCESSOR); } } else cout << "cpu is non NULL\n"; ccpu = *pcpu; read_hex_from_cod(ccpu); set_lstname(filename); ccpu->files.SetSourcePath(filename); read_src_files_from_cod(ccpu); // Associate the .lst and .asm files' line numbers with // the assembly instructions' addresses. read_line_numbers_from_cod(ccpu); read_symbols(ccpu); // If the .asm file contains special HLL source line comment, then // read these and put the HLL line numbers into each instruction. read_hll_line_numbers_from_asm(ccpu); // Read all the debug messages read_message_area(ccpu); _Cleanup: //delete directory_block_data; delete_directory(); delete [] temp_block; if(*pcpu != NULL) { (*pcpu)->reset(POR_RESET); bp.clear_global(); string script("directive"); (*pcpu)->run_script(script); } return error_code; } void PicCodProgramFileType::display_symbol_file_error(int err) { switch(err) { case ERR_FILE_NOT_FOUND: cout << "unable to find the symbol file\n"; break; case ERR_UNRECOGNIZED_PROCESSOR: cout << "unrecognized processor in the symbol file\n"; break; case ERR_BAD_FILE: cout << "bad file format\n"; break; } } gpsim-0.30.0/src/p17c75x.h0000664000076400007640000000657113041763624011741 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P17C75X_H__ #define __P17C75X_H__ #include "16bit-processors.h" #include "p16x6x.h" class P17C7xx : public _16bit_processor { public: CPUSTA cpusta; P17C7xx(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE isa(){return _P17C7xx_;}; virtual void create_symbols(); virtual void create(int ram_top); virtual void create_sfr_map(); virtual unsigned int program_memory_size() const { return 0x400; }; }; class P17C75x : public P17C7xx { public: P17C75x(); static Processor *construct(const char *name); virtual void create(int ram_top); virtual void create_sfr_map(); virtual PROCESSOR_TYPE isa(){return _P17C75x_;}; virtual void create_symbols(); virtual unsigned int program_memory_size() const { return 0x4000; }; }; class P17C752 : public P17C75x { public: virtual PROCESSOR_TYPE isa(){return _P17C752_;}; P17C752(); static Processor *construct(const char *name); void create(); // void create_sfr_map(); void create_sfr_map(); void create_symbols(); virtual unsigned int program_memory_size() const { return 0x2000; }; virtual unsigned int register_memory_size() const { return 0x800; }; }; class P17C756 : public P17C75x { public: virtual PROCESSOR_TYPE isa(){return _P17C756_;}; void create_sfr_map(); void create_symbols(); P17C756(); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int register_memory_size() const { return 0x800; }; }; class P17C756A : public P17C75x { public: virtual PROCESSOR_TYPE isa(){return _P17C756A_;}; void create_sfr_map(); void create_symbols(); P17C756A(); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int register_memory_size() const { return 0x800; }; }; class P17C762 : public P17C75x { public: virtual PROCESSOR_TYPE isa(){return _P17C762_;}; void create_sfr_map(); void create_symbols(); P17C762(); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int register_memory_size() const { return 0x800; }; }; class P17C766 : public P17C75x { public: virtual PROCESSOR_TYPE isa(){return _P17C766_;}; void create_sfr_map(); void create_symbols(); P17C766(); static Processor *construct(const char *name); void create(); virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int register_memory_size() const { return 0x800; }; }; #endif gpsim-0.30.0/src/expr.h0000664000076400007640000000737613063451152011577 00000000000000/* Parser for gpsim Copyright (C) 2004 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "value.h" #if !defined(__EXPR_H__) #define __EXPR_H__ using namespace std; class Expression; class symbol; typedef list ExprList_t; typedef list::iterator ExprList_itor; class Expression : public gpsimObject { public: Expression(); virtual ~Expression(); virtual Value* evaluate()=0; }; //************************************************************************// // // Literal Expressions // // A Literal Expression is a wrapper around a Value object. //---------------------------------------------------------------- class IndexedSymbol : public Expression { public: IndexedSymbol(gpsimObject *, ExprList_t*); virtual ~IndexedSymbol(); virtual Value* evaluate(); string toString(); private: Value * m_pSymbol; ExprList_t * m_pExprList; }; //----------------------------------------------------------------- class LiteralSymbol : public Expression { public: explicit LiteralSymbol(gpsimObject *); //LiteralSymbol(gpsimObject *, ExprList_t*); virtual ~LiteralSymbol(); virtual Value* evaluate(); virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); virtual int clear_break(); string toString(); Value *GetSymbol(); private: Value *sym; }; //----------------------------------------------------------------- class LiteralArray : public Expression { public: explicit LiteralArray(ExprList_t*); virtual ~LiteralArray(); virtual Value* evaluate(); string toString(); private: ExprList_t * m_pExprList; }; //----------------------------------------------------------------- class LiteralBoolean : public Expression { public: explicit LiteralBoolean(Boolean* value); virtual ~LiteralBoolean(); virtual Value* evaluate(); string toString(); private: Boolean* value; }; //----------------------------------------------------------------- class LiteralInteger : public Expression { public: explicit LiteralInteger(Integer* value); virtual ~LiteralInteger(); virtual Value* evaluate(); virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); string toString(); private: Integer* value; }; //----------------------------------------------------------------- class LiteralFloat : public Expression { public: explicit LiteralFloat(Float* value); virtual ~LiteralFloat(); virtual Value* evaluate(); string toString(); private: Float* value; }; //----------------------------------------------------------------- class LiteralString : public Expression { public: explicit LiteralString(String* newValue); virtual ~LiteralString(); virtual Value* evaluate(); string toString(); private: String* value; }; class RegisterExpression : public Expression { public: explicit RegisterExpression(unsigned int uAddress); virtual ~RegisterExpression(); virtual Value* evaluate(); string toString(); private: unsigned int m_uAddress; }; #endif // __EXPR_H__ gpsim-0.30.0/src/ttoken.cc0000664000076400007640000000344113041763624012256 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "ttoken.h" #include "pthread-wrap.h" namespace gpsim { Token::Token() { thread = new ThreadWrapper(); } void Token::Initialize(void *(*child) (void *), void *data) { pthread_mutex_init(&thread->mutex, NULL); pthread_cond_init (&thread->cvWaitOnParent, NULL); pthread_cond_init (&thread->cvWaitOnChild, NULL); grab(); pthread_attr_init(&thread->thAttribute); pthread_attr_setdetachstate(&thread->thAttribute, PTHREAD_CREATE_JOINABLE); pthread_create(&thread->thHostInterface, &thread->thAttribute, child, data); } void Token::waitForChild() { pthread_cond_wait(&thread->cvWaitOnChild, &thread->mutex); } void Token::grab() { pthread_mutex_lock(&thread->mutex); } void Token::passToChild() { pthread_cond_signal(&thread->cvWaitOnParent); pthread_cond_wait(&thread->cvWaitOnChild, &thread->mutex); } void Token::passToParent() { pthread_cond_signal(&thread->cvWaitOnChild); pthread_cond_wait(&thread->cvWaitOnParent, &thread->mutex); } } // end of namespace gpsim gpsim-0.30.0/src/comparator.cc0000664000076400007640000011665113103740330013115 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2006,2010,2013,2015 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "pic-ioports.h" #include "trace.h" #include "processor.h" #include "p16f88x.h" #include "pir.h" #include "stimuli.h" #include "14bit-tmrs.h" #include "comparator.h" #include "a2d_v2.h" #include "ctmu.h" //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif ComparatorModule::ComparatorModule(Processor *pCpu) : cmcon(pCpu,"cmcon", "Comparator Module Control"), cmcon1(pCpu,"cmcon1", "Comparator Configure Register"), vrcon(pCpu,"vrcon", "Voltage Reference Control") { } void ComparatorModule::initialize( PIR_SET *pir_set, PinModule *pin_vr0, PinModule *pin_cm0, PinModule *pin_cm1, PinModule *pin_cm2, PinModule *pin_cm3, PinModule *pin_cm4, PinModule *pin_cm5) { // cmcon = new CMCON; cmcon.assign_pir_set(pir_set); cmcon.setINpin(0, pin_cm0, "an0"); cmcon.setINpin(1, pin_cm1, "an1"); cmcon.setINpin(2, pin_cm2, "an2"); cmcon.setINpin(3, pin_cm3, "an3"); cmcon.setOUTpin(0, pin_cm4); cmcon.setOUTpin(1, pin_cm5); vrcon.setIOpin(pin_vr0); cmcon._vrcon = &vrcon; vrcon._cmcon = &cmcon; } //-------------------------------------------------- // //-------------------------------------------------- class CMSignalSource : public SignalControl { public: CMSignalSource(CMCON *_cmcon, int _index) : m_state('0'), m_cmcon(_cmcon), index(_index) { } ~CMSignalSource() { // cout << "deleting CMsignal source " << this << endl; } virtual void release() { m_cmcon->releasePin(index); } virtual char getState() { return m_state; } void putState(bool new_val) { m_state = new_val?'1':'0'; } private: char m_state; CMCON * m_cmcon; int index; }; //-------------------------------------------------- // //-------------------------------------------------- class CMxSignalSource : public PeripheralSignalSource { public: CMxSignalSource(PinModule *_pin, CMxCON0_base *_cmcon) : PeripheralSignalSource(_pin), m_cmcon(_cmcon) { } ~CMxSignalSource() { // cout << "deleting CMsignal source " << this << endl; } virtual void release() { m_cmcon->releasePin(); } private: CMxCON0_base * m_cmcon; }; //-------------------------------------------------- // //-------------------------------------------------- CM_stimulus::CM_stimulus(CMCON * arg, const char *cPname,double _Vth, double _Zth) : stimulus(cPname, _Vth, _Zth) { _cmcon = arg; } CM_stimulus::~CM_stimulus() { } void CM_stimulus::set_nodeVoltage(double v) { if (nodeVoltage != v) { nodeVoltage = v; Dprintf(("set_nodeVoltage %s _cmcon %p %s v=%.2f\n", name().c_str(), _cmcon, _cmcon->name().c_str(), v)); _cmcon->get(); // recalculate comparator values } } /* Setup the configuration for the comparators. Must be called for each comparator and each mode(CN2:CM0) that can be used. il1 = input Vin- when CIS == 0 ih1 = input Vin+ when CIS == 0 il2 = input Vin- when CIS == 1 ih2 = input Vin+ when CIS == 1 if input == VREF, reference voltage is used. */ void CMCON::set_configuration(int comp, int mode, int il1, int ih1, int il2, int ih2, int out) { if (comp > cMaxComparators || comp < 1 ) { cout << "CMCON::set_configuration comp=" << comp << " out of range\n"; return; } if (mode > cMaxConfigurations) { cout << "CMCON::set_configuration mode too large\n"; return; } m_configuration_bits[comp-1][mode] = (il1 << CFG_SHIFT*4) | (ih1 << CFG_SHIFT*3) | (il2 << CFG_SHIFT*2) | (ih2 << CFG_SHIFT) | out; } //------------------------------------------------------------------------ CMCON::CMCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), _vrcon(0), pir_set(0), m_tmrl(0), m_eccpas(0) { value.put(0); cm_input[0]=cm_input[1]=cm_input[2]=cm_input[3]=0; cm_output[0] = cm_output[1] = 0; cm_input_pin[0]=cm_input_pin[1]=cm_input_pin[2]=cm_input_pin[3]=0; cm_an[0] = cm_an[1] = cm_an[2] = cm_an[3] = 0; cm_output_pin[0]=cm_output_pin[1]=0; cm_source[0]=cm_source[1]=0; cm_stimulus[0]=cm_stimulus[1]=cm_stimulus[2]=cm_stimulus[3]=0; cm_source_active[0]=cm_source_active[1] = false; } CMCON::~CMCON() { unsigned int mode = value.get() & 0x07; for(int i = 0; i <2; i++) { if (cm_source[i]) { int cfg = m_configuration_bits[i][mode] & CFG_MASK; // Our Source active so port still defined if cm_output defined, // set default source. if (cfg == i && cm_output[i] && cm_source_active[i]) cm_output[i]->setSource(0); delete cm_source[i]; } } for (int i = 0; i < 4; i++) { if (cm_stimulus[i]) delete cm_stimulus[i]; if (cm_input_pin[i]) free(cm_input_pin[i]); if (cm_an[i]) free(cm_an[i]); } if (cm_output_pin[0]) free(cm_output_pin[0]); if (cm_output_pin[1]) free(cm_output_pin[1]); } void CMCON::releasePin(int i) { cm_source_active[i] = false; } void CMCON::setINpin(int i, PinModule *newPinModule, const char *an) { if (newPinModule == NULL) return; cm_input[i] = newPinModule; cm_input_pin[i] = strdup(newPinModule->getPin().name().c_str()); cm_an[i] = strdup(an); } void CMCON::setOUTpin(int i, PinModule *newPinModule) { if (newPinModule == NULL) return; cm_output[i] = newPinModule; cm_output_pin[i] = strdup(newPinModule->getPin().name().c_str()); } void CMCON::assign_pir_set(PIR_SET *new_pir_set) { pir_set = new_pir_set; } double CMCON::comp_voltage(int ind, int invert) { double Voltage; const char *name; switch(ind) { case V06: Voltage = 0.6; name = "V0.6"; break; case VREF: Voltage = _vrcon->get_Vref(); name = "Vref"; break; case NO_IN: Voltage = invert ? cpu->get_Vdd() : 0.; name = "No_IN"; break; default: Voltage = cm_input[ind]->getPin().get_nodeVoltage(); name = cm_input[ind]->getPin().name().c_str(); break; } if (name) // this is just to avoid a compiler warning { Dprintf(("CMCON::comp_voltage ind=%d IN%c %.2f %s\n", ind, invert?'-':'+', Voltage, name)); } return Voltage; } /* ** get() ** read the comparator inputs and set C2OUT and C1OUT ** as required. Also drive output pins if required. */ unsigned int CMCON::get() { unsigned int cmcon_val = value.get(); int mode = cmcon_val & 0x07; int i; for (i = 0; i < 2; i++) { double Vhigh; double Vlow; bool out_true; int out; int invert_bit = (i == 0) ? C1INV : C2INV; int output_bit = (i == 0) ? C1OUT : C2OUT; int shift = (cmcon_val & CIS) ? CFG_SHIFT : CFG_SHIFT*3; if ((m_configuration_bits[i][mode] & CFG_MASK) != ZERO) { Vhigh = comp_voltage( (m_configuration_bits[i][mode] >> shift) & CFG_MASK, cmcon_val & invert_bit); Vlow = comp_voltage( (m_configuration_bits[i][mode] >> (shift + CFG_SHIFT)) & CFG_MASK, (cmcon_val & invert_bit) == 0); if (Vhigh > Vlow) out_true = (cmcon_val & invert_bit)?false:true; else out_true = (cmcon_val & invert_bit)?true:false; if (out_true) cmcon_val |= output_bit; else cmcon_val &= ~output_bit; if ( (out = m_configuration_bits[i][mode] & CFG_MASK) < 2) { cm_source[out]->putState(out_true); cm_output[out]->updatePinModule(); update(); } } else // Don't care about inputs, register value 0 cmcon_val &= ~output_bit; } if (value.get() ^ cmcon_val) // change of state { int diff = value.get() ^ cmcon_val; // Signal ECCPAS ? if (m_eccpas) { if (diff & C1OUT) m_eccpas->c1_output(cmcon_val & C1OUT); if (diff & C2OUT) m_eccpas->c2_output(cmcon_val & C2OUT); } // Generate interupt ? if (pir_set) { if (diff & C1OUT) pir_set->set_c1if(); if (diff & C2OUT) pir_set->set_c2if(); } } if (m_tmrl) m_tmrl->compare_gate((cmcon_val & C1OUT) == C1OUT); value.put(cmcon_val); return(cmcon_val); } void CMCON::put(unsigned int new_value) { unsigned int mode = new_value & 0x7; unsigned int in_mask = 0; unsigned int out_mask = 0; unsigned int configuration; int i; if (verbose) cout << "CMCON::put(new_value) =" << hex << new_value << endl; trace.raw(write_trace.get() | value.get()); // Determine used input and output pins for(i = 0; i < 2; i++) { configuration = m_configuration_bits[i][mode]; if ((configuration & CFG_MASK) < 2) out_mask |= (1 << (configuration & CFG_MASK)); for(int j = 0; j < 4; j++) { configuration >>= CFG_SHIFT; if ((configuration & CFG_MASK) < 6) in_mask |= (1 << (configuration & CFG_MASK)); } } if (verbose) cout << "CMCON::put in_mask=" << in_mask << " out_mask=" << out_mask << endl; if ((mode != 0) && (mode != 7) && ! cm_stimulus[0]) // initialize stimulus { cm_stimulus[0] = new CM_stimulus(this, "cm_stimulus_1", 0, 1e12); cm_stimulus[1] = new CM_stimulus(this, "cm_stimulus_2", 0, 1e12); cm_stimulus[2] = new CM_stimulus(this, "cm_stimulus_3", 0, 1e12); cm_stimulus[3] = new CM_stimulus(this, "cm_stimulus_4", 0, 1e12); } // // setup outputs // for( i = 0; i < 2 && cm_output[i]; i++) { if (out_mask & (1<getPin().newGUIname(name); cm_output[i]->setSource(cm_source[i]); cm_source_active[i] = true; } else if (cm_source_active[i]) { cm_output[i]->getPin().newGUIname(cm_output[i]->getPin().name().c_str()); cm_output[i]->setSource(0); } } // // setup inputs for(i = 0; i < 4 ; i++) { if (cm_input[i]) { const char *name = cm_input[i]->getPin().GUIname().c_str(); if (cm_input[i]->getPin().snode) { if (in_mask & (1 << i)) (cm_input[i]->getPin().snode)->attach_stimulus(cm_stimulus[i]); else (cm_input[i]->getPin().snode)->detach_stimulus(cm_stimulus[i]); } // rewrite GUI name as required if (in_mask & (1 << i) ) { cm_input[i]->AnalogReq(this, true, cm_an[i]); } else { if (!strncmp(name, "an", 2)) cm_input[i]->AnalogReq(this, false, cm_input[i]->getPin().name().c_str()); } } } // if only one comparator, mask C2INV if (!cm_output[1]) new_value &= 0x1f; value.put(new_value); if (verbose) cout << "CMCON::put() val=0x" << hex << new_value <getPin().name().c_str()); } double VRCON::get_Vref() { unsigned int new_value = value.get(); Vref_high = ((Processor *)cpu)->get_Vdd(); Vref_low = 0.0; vr_Rhigh = (8 + (16 - (new_value & 0x0f))) * 2000.; vr_Rlow = (new_value & 0x0f) * 2000.; if (! (new_value & VRR)) // High range ? vr_Rlow += 16000.; vr_Vref = (Vref_high - Vref_low) * vr_Rlow / (vr_Rhigh + vr_Rlow) + Vref_low; if (verbose) { cout << "VRCON::put Rhigh=" <getPin().name().c_str())) vr_PinModule->getPin().newGUIname("Vref"); if (vr_PinModule->getPin().snode) { vr_pu->set_Zth(vr_Rhigh); vr_pd->set_Zth(vr_Rlow); vr_PinModule->getPin().snode->attach_stimulus(vr_pu); vr_PinModule->getPin().snode->attach_stimulus(vr_pd); vr_PinModule->getPin().snode->update(); } } else if (vr_PinModule) // not outputing voltage to pin { if (!strcmp("Vref", vr_PinModule->getPin().name().c_str())) vr_PinModule->getPin().newGUIname(pin_name); if (diff & 0x2f) // did value of vreference change ? _cmcon->get(); if(vr_PinModule && vr_PinModule->getPin().snode) { vr_PinModule->getPin().snode->detach_stimulus(vr_pu); vr_PinModule->getPin().snode->detach_stimulus(vr_pd); vr_PinModule->getPin().snode->update(); } } else // output pin not defined { if (diff & 0x2f) // did value of vreference change ? _cmcon->get(); } } else // vref disable { if (vr_PinModule && !strcmp("Vref", vr_PinModule->getPin().name().c_str())) vr_PinModule->getPin().newGUIname(pin_name); if(vr_PinModule && vr_PinModule->getPin().snode) { vr_PinModule->getPin().snode->detach_stimulus(vr_pu); vr_PinModule->getPin().snode->detach_stimulus(vr_pd); vr_PinModule->getPin().snode->update(); } } } //-------------------------------------------------- // Voltage reference //-------------------------------------------------- class P16F631; VRCON_2::VRCON_2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { value.put(0); vr_06v = new stimulus("vref_06v", 0.0, 100.); vr_pu = new stimulus("Cvref_pu", 0.0 , 48000.); vr_pd = new stimulus("Cvref_pd", 0.0, 0.0); ((Processor *)cpu)->CVREF = new Stimulus_Node("CVREF"); ((Processor *)cpu)->V06REF = new Stimulus_Node("V0.6REF"); ((Processor *)cpu)->CVREF->attach_stimulus(vr_pu); ((Processor *)cpu)->CVREF->attach_stimulus(vr_pd); ((Processor *)cpu)->V06REF->attach_stimulus(vr_06v); } VRCON_2::~VRCON_2() { delete vr_06v; delete vr_pu; delete vr_pd; delete ((Processor *)cpu)->CVREF; delete ((Processor *)cpu)->V06REF; } void VRCON_2::put(unsigned int new_value) { unsigned int old_value = value.get(); unsigned int diff = new_value ^ old_value; trace.raw(write_trace.get() | value.get()); if (verbose & 2) cout << "VRCON_2::put old=" << hex << old_value << " new=" << new_value << endl; if (!diff) return; value.put(new_value); // Turn 0.6 V reference on or off ? if (diff & VP6EN) { if (new_value & VP6EN) vr_06v->set_Vth(0.6); else vr_06v->set_Vth(0.0); ((Processor *)cpu)->V06REF->update(); } if(diff & (C1VREN | C2VREN | VRR | VR3 | VR2 | VR1 | VR0)) { double vr_Rhigh, vr_Rlow; if(new_value & (C1VREN | C2VREN)) vr_pu->set_Vth(((Processor *)cpu)->get_Vdd()); else vr_pu->set_Vth(0.0); vr_Rhigh = (8 + (16 - (new_value & 0x0f))) * 2000.; vr_pu->set_Zth(vr_Rhigh); vr_Rlow = (new_value & 0x0f) * 2000.; if (! (new_value & VRR)) // High range ? vr_Rlow += 16000.; vr_pd->set_Zth(vr_Rlow); ((Processor *)cpu)->CVREF->update(); ((Processor *)cpu)->CVREF->update(); } } CMxCON0::CMxCON0(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *cmModule) : CMxCON0_base(pCpu, pName, pDesc, _cm, cmModule) { } CMxCON0::~CMxCON0() { } void CMxCON0::put(unsigned int new_value) { unsigned int old_value = value.get(); unsigned int diff = (new_value ^ old_value) & mValidBits; // assume masked bits are read-only new_value = (new_value & mValidBits) | (old_value & ~mValidBits); trace.raw(write_trace.get() | value.get()); value.put(new_value); if (diff == 0) { get(); return; } if (diff & CxOE) { cm_output = m_cmModule->cmxcon1[cm]->output_pin(); if(new_value & CxOE) { char name[20]; if ( ! cm_source) cm_source = new CMxSignalSource(cm_output, this); snprintf(name, sizeof(name), "c%uout", cm + 1); assert(cm_output); cm_output->getPin().newGUIname(name); cm_output->setSource(cm_source); cm_source_active = true; } else if (cm_source_active) // Enable output enable turned off { cm_output->getPin().newGUIname(cm_output->getPin().name().c_str()); cm_output->setSource(0); } } get(); } double CMxCON0::get_hysteresis() { double ret = 0.; if (value.get() & CxHYS) ret = 0.05; return ret; } double CMxCON0::get_Vpos() { return m_cmModule->cmxcon1[cm]->get_Vpos(); } double CMxCON0::get_Vneg() { return m_cmModule->cmxcon1[cm]->get_Vneg(); } void CMxCON0::set_output(bool output) { unsigned int cmxcon0 = value.get(); bool old_out = cmxcon0 & CxOUT; if(output) cmxcon0 |= CxOUT; else cmxcon0 &= ~CxOUT; Dprintf(("cm%u POL %d output %d cmxcon0=%x old_out %d\n", cm+1, (bool)(cmxcon0 & CxPOL), output, cmxcon0, old_out)); value.put(cmxcon0); m_cmModule->set_cmout(cm, output); if (cmxcon0 & CxOE) { cm_source->putState(output?'1':'0'); m_cmModule->cmxcon1[cm]->output_pin()->updatePinModule(); } if (old_out != output) // state change { // Positive going edge, set interrupt ? if (output && (m_cmModule->cmxcon1[cm]->value.get() & CMxCON1::CxINTP)) IntSrc->Trigger(); // Negative going edge, set interrupt ? if (!output && (m_cmModule->cmxcon1[cm]->value.get() & CMxCON1::CxINTN)) IntSrc->Trigger(); } } void CMxCON0_V2::put(unsigned int new_value) { unsigned int old_value = value.get(); unsigned int diff = (new_value ^ old_value) & mValidBits; if (verbose) cout << name() << " put(new_value) =" << hex << new_value << endl; trace.raw(write_trace.get() | value.get()); value.put(new_value); // assume masked bits are read-only if (diff == 0) { get(); return; } if ((diff & CxON) && !(new_value & CxON)) // turning off { cm_output = m_cmModule->cmxcon1[cm]->output_pin(cm); cm_output->getPin().newGUIname(cm_output->getPin().name().c_str()); cm_output->setSource(0); // remove stimulus from input pins m_cmModule->cmxcon1[0]->setPinStimulus(0, POS+cm*2); m_cmModule->cmxcon1[0]->setPinStimulus(0, NEG+cm*2); return; } if (diff & CxOE) { cm_output = m_cmModule->cmxcon1[cm]->output_pin(cm); if(new_value & CxOE) { char name[20]; if ( ! cm_source) cm_source = new CMxSignalSource(cm_output, this); snprintf(name, sizeof(name), "c%uout", cm + 1); assert(cm_output); cm_output->getPin().newGUIname(name); cm_output->setSource(cm_source); cm_source_active = true; } else if (cm_source_active) // Enable output enable turned off { cm_output->getPin().newGUIname(cm_output->getPin().name().c_str()); cm_output->setSource(0); } } get(); } void CMxCON0_V2::set_output(bool output) { unsigned int cmxcon0 = value.get(); unsigned int cmxcon1 = m_cmModule->cmxcon1[cm]->value.get(); bool old_out = cmxcon0 & CxOUT; if(output) { cmxcon0 |= CxOUT; cmxcon1 |= ((cm==0)? CM2CON1_V2::MC1OUT : CM2CON1_V2::MC2OUT); } else { cmxcon0 &= ~CxOUT; cmxcon1 &= ~((cm==0)? CM2CON1_V2::MC1OUT : CM2CON1_V2::MC2OUT); } Dprintf(("cm%u POL %d output %d cmxcon0=%x old_out %d\n", cm+1, (bool)(cmxcon0 & CxPOL), output, cmxcon0, old_out)); value.put(cmxcon0); m_cmModule->cmxcon1[cm]->value.put(cmxcon1); m_cmModule->set_cmout(cm, output); if (cmxcon0 & CxOE) { cm_source->putState(output?'1':'0'); m_cmModule->cmxcon1[cm]->output_pin(cm)->updatePinModule(); } if (old_out != output) // state change { m_cmModule->cmxcon1[cm]->tmr_gate(cm, output); // Positive going edge, set interrupt ? if (output) IntSrc->Trigger(); } } double CMxCON0_V2::get_hysteresis() { double hyst_volt = 0.; if ( m_cmModule->cmxcon1[cm]->hyst_active(cm)) { hyst_volt = 0.05; // assume 50 mv hysteresis } return hyst_volt; } CMxCON0_V2::CMxCON0_V2(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *cmModule) : CMxCON0_base(pCpu, pName, pDesc, _cm, cmModule) { } CMxCON0_V2::~CMxCON0_V2() { } double CMxCON0_V2::get_Vpos() { return m_cmModule->cmxcon1[cm]->get_Vpos(cm, value.get()); } double CMxCON0_V2::get_Vneg() { return m_cmModule->cmxcon1[cm]->get_Vneg(cm, value.get()); } void CM2CON1_V4::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value & mValidBits); if (m_cmModule->tmr1l[0]) m_cmModule->tmr1l[0]->set_T1GSS((new_value & T1GSS) == T1GSS); } double CM2CON1_V4::get_Vpos(unsigned int cm, unsigned int cmxcon0) { double Voltage = 0.0; assert(m_vrcon); if (cmxcon0 & CMxCON0_V2::CxR) // use Vref defined in cm2con1 { if ((cm == 0 && (m_vrcon->value.get() & VRCON_2::C1VREN)) || (cm == 1 && (m_vrcon->value.get() & VRCON_2::C2VREN))) { Voltage = ((Processor *)cpu)->CVREF->get_nodeVoltage(); Dprintf(("%s CVref %.2f\n", __FUNCTION__, Voltage)); } else { Voltage = ((Processor *)cpu)->V06REF->get_nodeVoltage(); Dprintf(("%s cm%u V06ref %.2f\n", __FUNCTION__, cm+1, Voltage)); } } else // use CM1IN+ or CM2IN+ { if (!stimulus_pin[POS]) setPinStimulus(cm_inputPos[cm], POS); Voltage = cm_inputPos[cm]->getPin().get_nodeVoltage(); Dprintf(("%s cm%u %s %.2f\n", __FUNCTION__, cm+1, cm_inputPos[cm]->getPin().name().c_str(), Voltage)); } return Voltage; } CM2CON1_V4::CM2CON1_V4(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 * cmModule) : CM2CON1_V3(pCpu, pName, pDesc, _cm, cmModule), m_vrcon(0) { cm1_cvref = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[0], "cm1_cvref", 0, 1e12); cm1_v06ref = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[0], "cm1_v06ref", 0, 1e12); cm2_cvref = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[1], "cm2_cvref", 0, 1e12); cm2_v06ref = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[1], "cm2_v06ref", 0, 1e12); ((Processor *)cpu)->CVREF->attach_stimulus(cm1_cvref); ((Processor *)cpu)->V06REF->attach_stimulus(cm1_v06ref); ((Processor *)cpu)->CVREF->attach_stimulus(cm2_cvref); ((Processor *)cpu)->V06REF->attach_stimulus(cm2_v06ref); } CM2CON1_V4::~CM2CON1_V4() { ((Processor *)cpu)->CVREF->detach_stimulus(cm1_cvref); ((Processor *)cpu)->V06REF->detach_stimulus(cm1_v06ref); ((Processor *)cpu)->CVREF->detach_stimulus(cm2_cvref); ((Processor *)cpu)->V06REF->detach_stimulus(cm2_v06ref); delete cm1_cvref; delete cm1_v06ref; delete cm2_cvref; delete cm2_v06ref; } void CM2CON1_V3::put(unsigned int new_value) { unsigned int old_value = value.get(); trace.raw(write_trace.get() | value.get()); value.put(new_value & mValidBits); if ((new_value ^ old_value) & C1RSEL) m_cmModule->cmxcon0[0]->get(); if ((new_value ^ old_value) & C2RSEL) m_cmModule->cmxcon0[1]->get(); if (m_cmModule->tmr1l[0]) m_cmModule->tmr1l[0]->set_T1GSS((new_value & T1GSS) == T1GSS); } double CM2CON1_V3::get_Vpos(unsigned int cm, unsigned int cmxcon0) { double Voltage = 0.0; unsigned int cmxcon1 = value.get(); assert(m_vrcon); if (cmxcon0 & CMxCON0_V2::CxR) // use Vref defined in cm2con1 { if ((cm == 0 && (cmxcon1 & C1RSEL)) | (cm == 1 && (cmxcon1 & C2RSEL))) { Voltage = m_vrcon->get_Vref(); Dprintf(("%s cm%u Vref %.2f\n", __FUNCTION__, cm+1, Voltage)); } else { Voltage = 0.6; Dprintf(("%s cm%u Absref %.2f\n", __FUNCTION__, cm+1, Voltage)); } } else // use CM1IN+ or CM2IN+ { if (stimulus_pin[POS] != cm_inputPos[cm]) setPinStimulus(cm_inputPos[cm], POS); Voltage = cm_inputPos[cm]->getPin().get_nodeVoltage(); Dprintf(("%s cm%u %s %.2f\n", __FUNCTION__, cm+1, cm_inputPos[cm]->getPin().name().c_str(), Voltage)); } return Voltage; } double CM2CON1_V3::get_Vneg(unsigned int cm, unsigned int cmxcon0) { unsigned int cxNchan = cmxcon0 & (CMxCON0_V2::CxCH0 | CMxCON0_V2::CxCH1); if (stimulus_pin[NEG] != cm_inputNeg[cxNchan]) setPinStimulus(cm_inputNeg[cxNchan], NEG); Dprintf(("%s cm%u pin %u %s %.2f\n", __FUNCTION__, cm+1, cxNchan, cm_inputNeg[cxNchan]->getPin().name().c_str(), cm_inputNeg[cxNchan]->getPin().get_nodeVoltage())); return cm_inputNeg[cxNchan]->getPin().get_nodeVoltage(); } //************************************************************* // CM2CON1_V2 void CM2CON1_V2::put(unsigned int new_value) { unsigned int old_value = value.get(); new_value &= mValidBits; unsigned int diff = old_value ^ new_value; trace.raw(write_trace.get() | value.get()); value.put(new_value); if (diff & (C1RSEL | C1HYS)) m_cmModule->cmxcon0[0]->get(); if (diff & (C2RSEL | C2HYS)) m_cmModule->cmxcon0[1]->get(); } void CM2CON1_V3::tmr_gate(unsigned int cm, bool output) { if (cm == 1 && m_cmModule->tmr1l[0]) //CM2 { Dprintf(("CM2CON1_V3::tmr_gate cm%u output=%d\n", cm+1, output)); m_cmModule->tmr1l[0]->compare_gate(output); } } CM2CON1_V2::CM2CON1_V2(Processor *pCpu, const char *pName, const char *pDesc, ComparatorModule2 * cmModule): CMxCON1_base(pCpu, pName, pDesc, 0, cmModule), ctmu_stim(0), ctmu_attached(false) { assert(m_cmModule->cmxcon0[1]); cm_stimulus[2] = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[1], "cm_stimulus_2-", 0, 1e12); cm_stimulus[3] = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[1], "cm_stimulus_2+", 0, 1e12); ctmu_stimulus_pin = 0; } CM2CON1_V2::~CM2CON1_V2() { delete cm_stimulus[2]; delete cm_stimulus[3]; } double CM2CON1_V2::get_Vpos(unsigned int cm, unsigned int cmxcon0) { double Voltage = 0.0; unsigned int cmxcon1 = value.get(); if (cmxcon0 & CMxCON0_V2::CxR) // use Vref defined in cm2con1 { if ((cm == 0 && (cmxcon1 & C1RSEL)) | (cm == 1 && (cmxcon1 & C2RSEL))) { Voltage = m_cmModule->FVR_voltage; Dprintf(("%s cm%u FVR %.2f\n", __FUNCTION__, cm+1, Voltage)); } else { Voltage = m_cmModule->DAC_voltage; Dprintf(("%s cm%u DAC %.2f\n", __FUNCTION__, cm+1, Voltage)); } } else // use CM1IN+ or CM2IN+ { if (stimulus_pin[POS+cm*2] != cm_inputPos[cm]) setPinStimulus(cm_inputPos[cm], POS+cm*2); Voltage = cm_inputPos[cm]->getPin().get_nodeVoltage(); Dprintf(("%s cm%u %s %.2f\n", __FUNCTION__, cm+1, cm_inputPos[cm]->getPin().name().c_str(), Voltage)); } return Voltage; } double CM2CON1_V2::get_Vneg(unsigned int cm, unsigned int cmxcon0) { unsigned int cxNchan = cmxcon0 & (CMxCON0_V2::CxCH0 | CMxCON0_V2::CxCH1); if (stimulus_pin[NEG+cm*2] != cm_inputNeg[cxNchan]) setPinStimulus(cm_inputNeg[cxNchan], NEG+cm*2); if (cm_inputNeg[cxNchan]->getPin().snode) cm_inputNeg[cxNchan]->getPin().snode->update(); Dprintf(("%s cm%u pin %u %s %.2f\n", __FUNCTION__, cm+1, cxNchan, cm_inputNeg[cxNchan]->getPin().name().c_str(), cm_inputNeg[cxNchan]->getPin().get_nodeVoltage())); return cm_inputNeg[cxNchan]->getPin().get_nodeVoltage(); } bool CM2CON1_V2::hyst_active(unsigned int cm) { bool hyst = false; if (cm == 0) hyst = value.get() & C1HYS; else if (cm == 1) hyst = value.get() & C2HYS; return hyst; } void CM2CON1_V2::tmr_gate(unsigned int cm, bool output) { Dprintf(("CM2CON1_V2::tmr_gate cm%u output %d\n", cm+1, output)); for (int i=0; i < 3; i++) { if (m_cmModule->t1gcon[i]) { if (cm == 0) // CM1 m_cmModule->t1gcon[i]->CM1_gate(output); else if (cm == 1) //CM2 m_cmModule->t1gcon[i]->CM2_gate(output); } } } void CM2CON1_V2::set_ctmu_stim(stimulus *_ctmu_stim, CTMU *_ctmu_module) { if (_ctmu_stim) { if (!m_cmModule->ctmu_module) m_cmModule->ctmu_module = _ctmu_module; ctmu_stim = _ctmu_stim; attach_ctmu_stim(); } else { detach_ctmu_stim(); ctmu_stim = 0; } } void CM2CON1_V2::attach_ctmu_stim() { if (!cm_inputNeg[1]) { fprintf(stderr, "ERROR CM2CON1_V2::attach_ctmu_stim C12IN1- not defined\n"); return; } if (!(cm_inputNeg[1]->getPin().snode)) { printf("Warning CM2CON1_V2::attach_ctmu_stim %s has no node attached CTMU will not work properly\n", cm_inputNeg[1]->getPin().name().c_str()); return; } if (ctmu_stim) { cm_inputNeg[1]->getPin().snode->attach_stimulus(ctmu_stim); cm_inputNeg[1]->getPin().snode->update(); ctmu_attached = true; } } void CM2CON1_V2::detach_ctmu_stim() { if (ctmu_attached) { cm_inputNeg[1]->getPin().snode->detach_stimulus(ctmu_stim); cm_inputNeg[1]->getPin().snode->update(); ctmu_attached = false; } } CMxCON1::CMxCON1(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *cmModule) : CMxCON1_base(pCpu, pName, pDesc, _cm, cmModule) { } CMxCON1::~CMxCON1() { } CMxCON1_base::CMxCON1_base(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _cm, ComparatorModule2 *cmModule) : sfr_register(pCpu, pName, pDesc), cm(_cm), m_cmModule(cmModule) { assert(m_cmModule->cmxcon0[cm]); cm_stimulus[NEG] = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[cm], "cm_stimulus_-", 0, 1e12); cm_stimulus[POS] = new CM_stimulus((CMCON *)m_cmModule->cmxcon0[cm], "cm_stimulus_+", 0, 1e12); for(int i = 0; i<5; i++) cm_inputNeg[i] = 0; for(int i = 0; i<2; i++) { stimulus_pin[i] = 0; stimulus_pin[i+2] = 0; cm_inputPos[i] = 0; cm_output[i] = 0; } ctmu_stimulus_pin = 0; } CMxCON1_base::~CMxCON1_base() { delete cm_stimulus[NEG]; delete cm_stimulus[POS]; } double CMxCON1::get_Vneg(unsigned int arg, unsigned int arg2) { unsigned int cxNchan = value.get() & CxNMASK; if (!stimulus_pin[NEG]) setPinStimulus(cm_inputNeg[cxNchan], NEG); if (cm_inputNeg[cxNchan]->getPin().snode) cm_inputNeg[cxNchan]->getPin().snode->update(); Dprintf(("%s pin %u %s %.2f\n", __FUNCTION__, cxNchan, cm_inputNeg[cxNchan]->getPin().name().c_str(), cm_inputNeg[cxNchan]->getPin().get_nodeVoltage())); return cm_inputNeg[cxNchan]->getPin().get_nodeVoltage(); } double CMxCON1::get_Vpos(unsigned int arg, unsigned int arg2) { unsigned int cxPchan = (value.get() & CxPMASK) >> 3; double Voltage; switch(cxPchan) { case 0: if (stimulus_pin[POS] != cm_inputPos[cxPchan]) setPinStimulus(cm_inputPos[cxPchan], POS); Voltage = cm_inputPos[cxPchan]->getPin().get_nodeVoltage(); Dprintf(("%s %s %s v=%.2f\n", name().c_str(), __FUNCTION__, cm_inputPos[cxPchan]->getPin().name().c_str(), Voltage)); break; case 2: Voltage = m_cmModule->DAC_voltage; Dprintf(("%s %s %s v=%.2f\n", name().c_str(), __FUNCTION__, "DAC", Voltage)); break; case 4: Voltage = m_cmModule->FVR_voltage; Dprintf(("%s %s %s v=%.2f\n", name().c_str(), __FUNCTION__, "FVR", Voltage)); break; default: printf("CMxCON1::get_Vpos unexpected Pchan %x\n", cxPchan); case 6: Voltage = 0.; Dprintf(("%s %s %s v=%.2f\n", name().c_str(), __FUNCTION__, "AGND", Voltage)); break; } return Voltage; } // Attach a stimulus to an input pin so that changes // in the pin voltage can be reflected in the comparator output. // // pin may be 0 in which case a current stimulus, if any, will be detached // pol is either the enum POS or NEG // void CMxCON1_base::setPinStimulus(PinModule *pin, int pol) { if (pin == stimulus_pin[pol]) return; if (stimulus_pin[pol]) { (stimulus_pin[pol]->getPin().snode)->detach_stimulus(cm_stimulus[pol]); stimulus_pin[pol] = 0; } if (pin && pin->getPin().snode) { stimulus_pin[pol] = pin; (stimulus_pin[pol]->getPin().snode)->attach_stimulus(cm_stimulus[pol]); } } void CMxCON1::put(unsigned int new_value) { unsigned int old_value = value.get(); new_value &= mValidBits; unsigned int diff = old_value ^ new_value; trace.raw(write_trace.get() | value.get()); value.put(new_value); if ((diff & CxNMASK) || !stimulus_pin[NEG]) { unsigned int cxNchan = new_value & CxNMASK; setPinStimulus(cm_inputNeg[cxNchan], NEG); } if ((diff & CxPMASK) || !stimulus_pin[POS]) { unsigned int cxPchan = (new_value & CxPMASK) >> 3; if (cxPchan == 0) setPinStimulus(cm_inputPos[cxPchan], POS); else if (stimulus_pin[POS]) setPinStimulus(0, POS); } m_cmModule->run_get(cm); } void CMxCON1_base::set_OUTpin(PinModule *pin_cm0, PinModule *pin_cm1) { cm_output[0] = pin_cm0; cm_output[1] = pin_cm1; } void CMxCON1_base::set_INpinNeg(PinModule *pin_cm0, PinModule *pin_cm1, PinModule *pin_cm2, PinModule *pin_cm3, PinModule *pin_cm4) { cm_inputNeg[0] = pin_cm0; cm_inputNeg[1] = pin_cm1; cm_inputNeg[2] = pin_cm2; cm_inputNeg[3] = pin_cm3; cm_inputNeg[4] = pin_cm4; } void CMxCON1_base::set_INpinPos(PinModule *pin_cm0, PinModule *pin_cm1) { cm_inputPos[0] = pin_cm0; cm_inputPos[1] = pin_cm1; } ComparatorModule2::ComparatorModule2(Processor *pCpu) { for(int i = 0; i < 4; i++) { cmxcon0[i] = 0; cmxcon1[i] = 0; } cmout = 0; t1gcon[0] = t1gcon[1] = t1gcon[2] = 0; tmr1l[0] = tmr1l[1] = tmr1l[2] = 0; eccpas[0] = eccpas[1] = eccpas[2] = 0; sr_module = 0; ctmu_module = 0; } ComparatorModule2::~ComparatorModule2() { for(int i = 0; i < 4; i++) { if (cmxcon0[i]) delete cmxcon0[i]; if (cmxcon1[i]) delete cmxcon1[i]; if (i < 3 && cmxcon1[i] == cmxcon1[i+1]) cmxcon1[i+1] = 0; } if (cmout) delete cmout; } // this function sets the bits in the CMOUT register and also // sends the state to the T1GCON class if t1gcon is defined // void ComparatorModule2::set_cmout(unsigned int bit, bool value) { int i; if (cmout) { if (value) cmout->value.put(cmout->value.get() | (1<value.put(cmout->value.get() & ~(1<CM1_gate(value); if (eccpas[i]) eccpas[i]->c1_output(value); } if (sr_module) sr_module->syncC1out(value); break; case 1: //CM2 for(i=0; i < 3; i++) { if (t1gcon[i]) t1gcon[i]->CM2_gate(value); if (eccpas[i]) eccpas[i]->c2_output(value); } if (sr_module) sr_module->syncC2out(value); if (ctmu_module) ctmu_module->syncC2out(value); break; default: //Do nothing other CMs break; } } void ComparatorModule2::set_DAC_volt(double _volt) { DAC_voltage = _volt; for (int i=0; i < 4; i++) { if (cmxcon0[i]) cmxcon0[i]->get(); } } void ComparatorModule2::set_FVR_volt(double _volt) { FVR_voltage = _volt; Dprintf(("ComparatorModule2::set_FVR_volt %.2f\n", FVR_voltage)); for (int i=0; i < 4; i++) { if (cmxcon0[i]) cmxcon0[i]->get(); } } // set interrupt for comparator cm void ComparatorModule2::set_if(unsigned int cm) { switch(cm) { case 0: pir_set->set_c1if(); break; case 1: pir_set->set_c2if(); break; case 2: pir_set->set_c3if(); break; case 3: pir_set->set_c4if(); break; } } gpsim-0.30.0/src/16bit-instructions.h0000664000076400007640000010246113041763624014305 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __16BIT_INSTRUCTIONS_H__ #define __16BIT_INSTRUCTIONS_H__ #include "14bit-instructions.h" #include "16bit-registers.h" /*--------------------------------------------------------- * 16bit-instructions.h * * This .h file contains the definitions for the 16-bit core * instructions (the 16bit core of the 18cxxx processors that * is). Most of the instructions are derived from the corresponding * 12 and 14 bit core instructions. However, the virtual function * 'execute' is replaced. This is because the memory addressing and * the status register are different for the 16bit core. The alternative is * is to patch the existing instructions with the 16bit stuff. * I feel that this is an unwarranted performance hit. So gpsim * is slightly bigger, but it's also slightly faster... */ //--------------------------------------------------------- class Branching : public instruction { public: int destination_index; unsigned int absolute_destination_index; Branching(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(){ }; virtual void debug(){ }; virtual char *name(char *,int); virtual bool isBase() { return true;} void decode(Processor *new_cpu, unsigned int new_opcode); }; //--------------------------------------------------------- class multi_word_instruction : public instruction { public: unsigned int word2_opcode; unsigned int PMaddress; unsigned int PMindex; bool initialized; multi_word_instruction(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual int instruction_size() { return 2;} virtual enum INSTRUCTION_TYPES isa() {return MULTIWORD_INSTRUCTION;}; virtual bool isBase() { return true;} virtual void initialize(bool init_state) { initialized = init_state; } }; //--------------------------------------------------------- class multi_word_branch : public multi_word_instruction { public: unsigned int destination_index; multi_word_branch(Processor *new_cpu, unsigned int new_opcode, unsigned int address); void runtime_initialize(); virtual void execute(){}; virtual char *name(char *,int); }; //--------------------------------------------------------- class ADDULNK : public instruction { public: ADDULNK(Processor *new_cpu, unsigned int new_opcode,const char *, unsigned int address); virtual bool isBase() { return true;} virtual void execute(); virtual char *name(char *,int); protected: unsigned int m_lit; }; //--------------------------------------------------------- class ADDFSR16 : public instruction { public: ADDFSR16(Processor *new_cpu, unsigned int new_opcode,const char *, unsigned int address); virtual bool isBase() { return true;} virtual void execute(); virtual char *name(char *,int); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) { if (((new_opcode>>6)&3) == 3) { if (new_opcode & 0x100) return new ADDULNK(new_cpu,new_opcode,"subulnk", address); else return new ADDULNK(new_cpu,new_opcode,"addulnk", address); } if (new_opcode & 0x100) return new ADDFSR16(new_cpu,new_opcode,"subfsr", address); return new ADDFSR16(new_cpu,new_opcode,"addfsr", address); } protected: unsigned int m_fsr; unsigned int m_lit; Indirect_Addressing *ia; }; //--------------------------------------------------------- class CALLW16 : public CALLW { public: CALLW16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : CALLW(new_cpu, new_opcode, address){}; virtual bool isBase() { return true;} virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) { return new CALLW16(new_cpu,new_opcode,address); } }; //--------------------------------------------------------- class MOVSF : public multi_word_instruction { public: MOVSF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); void runtime_initialize(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVSF(new_cpu,new_opcode,address);} protected: unsigned int source,destination; }; //--------------------------------------------------------- class PUSHL : public instruction { public: PUSHL(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual bool isBase() { return true;} virtual void execute(); virtual char *name(char *,int); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) { return new PUSHL(new_cpu,new_opcode,address); } protected: unsigned int m_lit; }; //--------------------------------------------------------- class ADDLW16 : public ADDLW { public: ADDLW16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : ADDLW(new_cpu, new_opcode,address) {}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ADDLW16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ADDWF16 : public ADDWF { public: int i; ADDWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : ADDWF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ADDWF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ADDWFC16 : public ADDWFC { public: ADDWFC16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : ADDWFC(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ADDWFC16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ANDLW16 : public ANDLW { public: ANDLW16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : ANDLW(new_cpu, new_opcode,address) {}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ANDLW16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class ANDWF16 : public ANDWF { public: ANDWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : ANDWF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new ANDWF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BC : public Branching { public: BC(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BC(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BN : public Branching { public: BN(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BN(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BNC : public Branching { public: BNC(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BNC(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BNN : public Branching { public: BNN(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BNN(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BNOV : public Branching { public: BNOV(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BNOV(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BNZ : public Branching { public: BNZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BNZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BOV : public Branching { public: BOV(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BOV(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BRA16 : public instruction { public: int destination_index; unsigned int absolute_destination_index; BRA16(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BRA16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BSF16 : public BSF { public: int i; BSF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : BSF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BSF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BCF16 : public BCF { public: int i; BCF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : BCF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BCF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BTFSC16 : public BTFSC { public: int i; BTFSC16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : BTFSC(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BTFSC16(new_cpu,new_opcode,address);} }; //----------------------------------------------------------- class BTFSS16 : public BTFSS { public: int i; BTFSS16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : BTFSS(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BTFSS16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BTG : public Bit_op { public: BTG(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BTG(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class BZ : public Branching { public: BZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new BZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CALL16 : public multi_word_branch { public: bool fast; CALL16(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CALL16(new_cpu,new_opcode,address);} virtual char *name(char *,int); }; //----------------------------------------------------------- class CLRF16 : public CLRF { public: CLRF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : CLRF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CLRF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class COMF16 : public COMF { public: COMF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : COMF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new COMF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CPFSEQ : public Register_op { public: CPFSEQ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CPFSEQ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CPFSGT : public Register_op { public: CPFSGT(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CPFSGT(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class CPFSLT : public Register_op { public: CPFSLT(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new CPFSLT(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class DAW : public instruction { public: DAW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new DAW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class DECF16 : public DECF { public: DECF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : DECF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new DECF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class DECFSZ16 : public DECFSZ { public: DECFSZ16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : DECFSZ(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new DECFSZ16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class DCFSNZ : public Register_op { public: DCFSNZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new DCFSNZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class GOTO16 : public multi_word_branch { public: GOTO16(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new GOTO16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class INCF16 : public INCF { public: INCF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : INCF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new INCF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class INCFSZ16 : public INCFSZ { public: INCFSZ16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : INCFSZ(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new INCFSZ16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class INFSNZ : public Register_op { public: INFSNZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new INFSNZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class IORLW16 : public IORLW { public: IORLW16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : IORLW(new_cpu, new_opcode,address) {}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new IORLW16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class IORWF16 : public IORWF { public: IORWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : IORWF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new IORWF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class LCALL16 : public multi_word_branch { public: bool fast; LCALL16(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new LCALL16(new_cpu,new_opcode,address);} virtual char *name(char *,int); }; //--------------------------------------------------------- class LFSR : public multi_word_instruction { public: unsigned int fsr,k; Indirect_Addressing *ia; LFSR(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); void runtime_initialize(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new LFSR(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVF16 : public MOVF { public: MOVF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : MOVF(new_cpu,new_opcode,address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVFF : public multi_word_instruction { public: unsigned int source,destination; MOVFF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); void runtime_initialize(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVFF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVFP : public multi_word_instruction { public: unsigned int source,destination; MOVFP(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); void runtime_initialize(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVFP(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVLB16 : public Literal_op { public: MOVLB16(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVLB16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVLR : public Literal_op { public: MOVLR(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVLR(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVPF : public multi_word_instruction { public: unsigned int source,destination; MOVPF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); void runtime_initialize(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVPF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MOVWF16 : public MOVWF { public: MOVWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVWF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- #ifdef RRR class MOVWF16a : public MOVWF { public: MOVWF16a(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MOVWF16a(new_cpu,new_opcode,address);} }; #endif //RRR //--------------------------------------------------------- class MULLW : public Literal_op { public: MULLW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MULLW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class MULWF : public Register_op { public: MULWF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new MULWF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class NEGF : public Register_op { public: NEGF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new NEGF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class NEGW : public Register_op { public: NEGW(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new NEGW(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class POP : public instruction { public: POP(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new POP(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class PUSH : public instruction { public: PUSH(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new PUSH(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RCALL : public instruction { public: int destination_index; unsigned int absolute_destination_index; RCALL(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RCALL(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RETFIE16 : public RETFIE { public: bool fast; RETFIE16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : RETFIE(new_cpu,new_opcode,address) { fast = (new_opcode & 1); }; virtual void execute(); virtual char *name(char *,int); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RETFIE16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RETURN16 : public RETURN { public: bool fast; RETURN16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : RETURN(new_cpu,new_opcode,address) { fast = (new_opcode & 1); }; virtual void execute(); virtual char *name(char *,int); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RETURN16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RLCF : public Register_op { public: RLCF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RLCF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RLNCF : public Register_op { public: RLNCF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RLNCF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RRCF : public Register_op { public: RRCF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RRCF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class RRNCF : public Register_op { public: RRNCF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new RRNCF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SETF : public Register_op { public: SETF(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SETF(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SLEEP16 : public SLEEP { public: SLEEP16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : SLEEP(new_cpu,new_opcode,address) { }; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SLEEP16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBFWB : public Register_op { public: SUBFWB(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBFWB(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBLW16 : public SUBLW { public: SUBLW16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : SUBLW(new_cpu,new_opcode,address) { }; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBLW16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBWF16 : public SUBWF { public: SUBWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : SUBWF(new_cpu,new_opcode,address) { }; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBWF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SUBWFB16 : public SUBWFB { public: SUBWFB16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : SUBWFB(new_cpu,new_opcode,address) { }; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SUBWFB16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class SWAPF16 : public SWAPF { public: SWAPF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : SWAPF(new_cpu,new_opcode,address) { }; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new SWAPF16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class TBLRD : public instruction { public: TBLRD(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new TBLRD(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class TBLWT : public instruction { public: TBLWT(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new TBLWT(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class TLRD : public instruction { public: TLRD(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new TLRD(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class TLWT : public instruction { public: TLWT(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); virtual char *name(char *,int); virtual bool isBase() { return true;} static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new TLWT(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class TSTFSZ : public Register_op { public: TSTFSZ(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new TSTFSZ(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class XORLW16 : public XORLW { public: XORLW16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : XORLW(new_cpu, new_opcode, address) {}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new XORLW16(new_cpu,new_opcode,address);} }; //--------------------------------------------------------- class XORWF16 : public XORWF { public: XORWF16(Processor *new_cpu, unsigned int new_opcode, unsigned int address) : XORWF(new_cpu,new_opcode, address){}; virtual void execute(); static instruction *construct(Processor *new_cpu, unsigned int new_opcode, unsigned int address) {return new XORWF16(new_cpu,new_opcode,address);} }; #endif /* __12BIT_INSTRUCTIONS_H__ */ gpsim-0.30.0/src/icd.cc0000664000076400007640000006274113060754614011521 00000000000000/* Copyright (C) 2002 Ralf Forsberg This is based on the program icdprog 0.3 made by Geir Thomassen gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpasm; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* FIXME - the design of this code needs to be revisited. Instead of making the icd a separate entity that "controls" a a processor, it makes MUCH more sense to derive the Icd class from the Processor class and let it effectively intercept and re-direct calls to the processor being debugged. This way, the gui and cli (and even external regression testing scripts) can treat the Icd just like it's another processor - no special circumstances are required. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../config.h" #include "pic-processor.h" #include "icd.h" #define BAUDRATE B57600 // Not all OSs support the O_SYNC open flag #ifndef O_SYNC #define O_SYNC 0 #endif static bool use_icd = false; static int bulk_flag = 0; extern Processor *active_cpu; static int icd_fd; /* file descriptor for serial port */ static int icd_sync(void); bool get_use_icd() { return use_icd; } /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// class icd_Register : public Register { public: Register *replaced; int is_stale; icd_Register(Processor *); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual string &name(void) { if(replaced) return replaced->name(); else return gpsimObject::name(); }; virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_StatusReg : public Status_register { public: Status_register *replaced; int is_stale; icd_StatusReg(Processor *); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual string &name(void) { if(replaced) return replaced->name(); else return gpsimObject::name(); } virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_WREG : public WREG { public: WREG *replaced; int is_stale; icd_WREG(Processor *); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual string &name(void) { if(replaced) return replaced->name(); else return gpsimObject::name(); } virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_PCLATH : public PCLATH { public: PCLATH *replaced; int is_stale; icd_PCLATH(Processor *); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual string &name(void) { if(replaced) return replaced->name(); else return gpsimObject::name(); } virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_FSR : public FSR { public: FSR *replaced; int is_stale; icd_FSR(Processor *); virtual REGISTER_TYPES isa(void) {return replaced->isa();}; virtual string &name(void) { if(replaced) return replaced->name(); else return gpsimObject::name(); } virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual unsigned int get_value(void); virtual unsigned int get(void); }; class icd_PC : public Program_Counter { public: Program_Counter *replaced; int is_stale; icd_PC(Processor *); virtual void put_value(unsigned int new_value); virtual unsigned int get_value(void); }; /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// static void udelay(unsigned usec) { /* wait for msec milliseconds or more ... */ struct timespec time; time.tv_sec = usec / 1000000; time.tv_nsec = ( usec % 1000000) * 1000; nanosleep(&time,0); } static void dtr_set() { int flag = TIOCM_DTR; if(icd_fd<0) return; if(ioctl(icd_fd, TIOCMBIS, &flag)) { perror("ioctl"); throw new FatalError("ioctl"); } } static void dtr_clear() { int flag = TIOCM_DTR; if(icd_fd<0) return; if(ioctl(icd_fd, TIOCMBIC, &flag)) { perror("ioctl"); throw new FatalError("ioctl"); } } static void rts_set() { int flag = TIOCM_RTS; if(icd_fd<0) return; if(ioctl(icd_fd, TIOCMBIS, &flag)) { perror("ioctl"); throw new FatalError("ioctl"); } } static void rts_clear() { int flag = TIOCM_RTS; if(icd_fd<0) return; if(ioctl(icd_fd, TIOCMBIC, &flag)) { perror("ioctl"); throw new FatalError("ioctl"); } } void icd_hw_reset() { if(icd_fd<0) return; rts_clear(); dtr_clear(); /* reset */ udelay(10000); dtr_set(); /* remove reset */ } static int icd_write(const char *s) { if(icd_fd<0) return -1; if (write(icd_fd,s, strlen(s)) < 0) { perror("icd_write: "); return -1; } return 1; } static int icd_read(unsigned char *p, int len) { int n_read; n_read=read(icd_fd,p,1); rts_clear(); udelay(1); rts_set(); if(n_read != 1) { cout << "Error in number of bytes read \n"; cout << "len="<1) return n_read+icd_read(p+1,len-1); return n_read; } #define MAX_CMD_LEN 100 static int icd_cmd(const char *cmd, ...) { char command[MAX_CMD_LEN]; unsigned char resp[3]; va_list ap; if(icd_fd<0) return -1; va_start(ap, cmd); (void) vsnprintf(command,MAX_CMD_LEN, cmd, ap); va_end(ap); icd_write(command); if(!icd_read(resp,2)) { icd_sync(); icd_write(command); if(!icd_read(resp,2)) { cout << "Command "<0) { tries--; if(icd_cmd("$$6307\r")==1) return 1; icd_write("$"); icd_read(buf,0x42); } puts("***************** DID NOT SYNC!"); return 0; } static int icd_baudrate_init() { int tries=3; char ch; if(icd_fd<0) return 0; while(tries) { if (write(icd_fd,"U",1) != 1) { perror("icd_baudrate_init() write: "); return 0; } if(read(icd_fd,&ch,1) > 0) { rts_clear(); udelay(10); rts_set(); if(ch=='u') { return 1; } } tries--; } return 0; } const char *icd_target(void) { static char return_string[256]; unsigned int dev_id, type,rev; if(icd_fd<0) return 0; dev_id=icd_cmd("$$7020\r"); type = (dev_id>>5) & 0x1FF; rev = type & 0x1F; if(dev_id == 0x3FFF) { sprintf(return_string,"no target"); } else { switch(type) { case 0x68: sprintf(return_string,"16F870 rev %u",rev); break; case 0x69: sprintf(return_string,"16F871 rev %u",rev); break; case 0x47: sprintf(return_string,"16F872 rev %u",rev); break; case 0x4B: sprintf(return_string,"16F873 rev %u",rev); break; case 0x49: sprintf(return_string,"16F874 rev %u",rev); break; case 0x4F: sprintf(return_string,"16F876 rev %u",rev); break; case 0x4D: sprintf(return_string,"16F877 rev %u",rev); break; default: sprintf(return_string,"Unknown, device id = %02X",dev_id); break; } } return return_string; } struct termios oldtio, newtio; void put_dumb_register(Register **frp, int address) { Register *fr = *frp; icd_Register *ir = new icd_Register(fr->get_cpu()); //ir->set_cpu(fr->get_cpu()); *frp = ir; ir->replaced = fr; ir->address = address; } void put_dumb_status_register(Status_register **frp) { Status_register *fr = *frp; icd_StatusReg *ir = new icd_StatusReg(fr->get_cpu()); //ir->set_cpu(fr->get_cpu()); *frp = ir; ir->replaced = fr; ir->address = fr->address; } void put_dumb_pc_register(Program_Counter **frp) { Program_Counter *fr = *frp; icd_PC *ir = new icd_PC(fr->get_cpu()); *frp = ir; ir->replaced = fr; } void put_dumb_pclath_register(PCLATH **frp) { PCLATH *fr = *frp; icd_PCLATH *ir = new icd_PCLATH(fr->get_cpu()); //ir->set_cpu(fr->get_cpu()); *frp = ir; ir->replaced = fr; } void put_dumb_w_register(WREG **frp) { WREG *fr = *frp; icd_WREG *ir = new icd_WREG(fr->get_cpu()); //ir->set_cpu(fr->get_cpu()); *frp = ir; ir->replaced = fr; } void put_dumb_fsr_register(FSR **frp) { FSR *fr = *frp; icd_FSR *ir = new icd_FSR(fr->get_cpu()); //ir->set_cpu(fr->get_cpu()); *frp = ir; ir->replaced = fr; } static void create_dumb_register_file(void) { pic_processor *cpu=dynamic_cast(active_cpu); if(!cpu) return; for(unsigned int i=0;iregister_memory_size();i++) { put_dumb_register(&cpu->registers[i], i); } put_dumb_status_register(&cpu->status); put_dumb_pc_register(&cpu->pc); put_dumb_pclath_register(&cpu->pclath); put_dumb_w_register(&cpu->Wreg); put_dumb_fsr_register(&cpu->fsr); } int icd_connect(const char *port) { pic_processor *pic=dynamic_cast(active_cpu); if(!pic) { cout << "You have to load the .cod file (or .hex and processor)" << endl; return 0; } if((icd_fd=open(port, O_NOCTTY | O_RDWR | O_SYNC)) == -1) { perror("Error opening device:"); return 0; } tcgetattr(icd_fd, &oldtio); memset(&newtio,0, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VTIME] = 100; newtio.c_cc[VMIN] = 0; tcflush(icd_fd, TCIFLUSH); tcsetattr(icd_fd, TCSANOW, &newtio); icd_hw_reset(); rts_set(); if(!icd_baudrate_init()) { fprintf(stderr,"Can't initialize the ICD\n"); return 0; } create_dumb_register_file(); use_icd=true; icd_cmd("$$6300\r"); /* I really don't know what this is, but MPLAB does this. The program works ok without this though ..*/ // printf("ICD ver %s, target %s\n",icd_version(),icd_target()); // printf("Vdd %.2f, Vpp %.2f\n", icd_vdd(), icd_vpp()); if(icd_has_debug_module()) { if(verbose) cout << "Debug module present"<(active_cpu); if(!cpu) return; for(unsigned int i=0;iregister_memory_size();i++) { icd_Register *ir = dynamic_cast(cpu->registers[i]); assert(ir!=0); ir->is_stale=1; } icd_WREG *iw = dynamic_cast(cpu->Wreg); assert(iw!=0); iw->is_stale=1; icd_PC *ipc = dynamic_cast(cpu->pc); assert(ipc!=0); ipc->is_stale=1; icd_PCLATH *ipclath = dynamic_cast(cpu->pclath); assert(ipclath!=0); ipclath->is_stale=1; icd_FSR *ifsr = dynamic_cast(cpu->fsr); assert(ifsr!=0); ifsr->is_stale=1; icd_StatusReg *isreg = dynamic_cast(cpu->status); assert(isreg!=0); isreg->is_stale=1; } int icd_reset(void) { if(icd_fd<0) return 0; cout << "Reset" << endl; icd_cmd("$$700A\r"); icd_cmd("$$701B\r"); make_stale(); pic_processor *pic=dynamic_cast(active_cpu); if(!pic) return 0; pic->pc->get_value(); gi.simulation_has_stopped(); return 1; } int icd_detected(void) { if(icd_fd<0) return 0; if(use_icd) return 1; return 0; } const char *icd_version(void) { static char ret[256]; unsigned int ver1,ver2; if(icd_fd<0) return 0; ver1 = icd_cmd("$$7F00\r"); ver2 = icd_cmd("$$7021\r"); sprintf(ret, "%X.%02X.%02X", ver1>>8, ver1&0xFF, ver2); return ret; } float icd_vdd(void) { unsigned int vdd=0; if(icd_fd<0) return 0.0; vdd=icd_cmd("$$701C\r"); return ((double)vdd) / 40.0; } float icd_vpp(void) { unsigned int vpp=0; if(icd_fd<0) return 0.0; icd_cmd("$$7000\r"); // enable Vpp vpp=icd_cmd("$$701D\r") & 0xFF; // What the heck does the high byte contain ? icd_cmd("$$7001\r"); // disable Vpp return ((double)vpp) / 11.25; } int icd_step(void) { if(icd_fd<0) return 0; make_stale(); icd_cmd("$$700E\r"); return 1; } int icd_run(void) { if(icd_fd<0) return 0; make_stale(); if(icd_cmd("$$700F\r")!=1) { icd_sync(); if(icd_cmd("$$700F\r")!=1) cout << "fjsdk" << endl; } return 1; } int icd_stopped(void) { if(icd_fd<0) return 0; if(icd_cmd("$$701E\r")!=1) return 1; return 0; } int icd_halt(void) { if(icd_fd<0) return 0; make_stale(); icd_cmd("$$700D\r"); return 1; } int icd_set_break(int address) { if(icd_fd<0) return 0; cout << "Set breakpoint on address " << address << endl; icd_cmd("$$1F00\r"); if(icd_cmd("$$%04X\r",address)!=address) { puts("DEBUG: Set breakpoint failed?"); return 0; } return 1; } int icd_clear_break(void) { if(icd_fd<0) return 0; cout << "Clear breakpoints" << endl; icd_cmd("$$1F00\r"); return 1; } void icd_set_bulk(int flag) { bulk_flag=flag; } // Get the value of the specified file memory address /*int icd_read_file(int address) { unsigned char buf[8]; int offset = address - address%8; if(icd_fd<0) return 0; int value; cout << "this is deprecated" << endl; icd_cmd("$$%04X\r",0x7800+offset); icd_cmd("$$7C08\r"); icd_write("$$7D08\r"); icd_read(buf,8); value = buf[address%8]; pic_processor *pic=dynamic_cast(active_cpu); if(!pic) return; //if(gpsim_register_is_valid(1,REGISTER_RAM,address) && // !gpsim_register_is_alias(1,REGISTER_RAM,address)) { switch(address) { case 2: case 3: case 4: case 10: break; default: pic->registers[address]->put_value(value); cout << "Read file address " << address << "=" << value << endl; break; } } return 1; } int icd_write_file(int address, int data) { if(icd_fd<0) return 0; printf("Write file address 0x%04X with data 0x%02X\n",address,data); return 1; } int icd_read_eeprom(int address) { if(icd_fd<0) return 0; printf("Read eeprom address 0x%04X\n",address); return 1; } int write_eeprom(int address, int data) { if(icd_fd<0) return 0; printf("Write eeprom address 0x%04X with data 0x%02X\n",address,data); return 1; } int icd_get_state() { int pc=4, status, w, pclath, fsr; if(icd_fd<0) return 0; cout << "Get state" << endl; pc=icd_cmd("$$701F\r"); status=icd_cmd("$$7016\r")&0x00ff; w=icd_cmd("$$7017\r")&0x00ff; pclath=icd_cmd("$$7018\r")&0x00ff; fsr=icd_cmd("$$7019\r")&0x00ff; pic_processor *pic=dynamic_cast(active_cpu); if(!pic) return; pic->pc->put_value(pc); pic->status->put_value(status); pic->W->put_value(w); pic->pclath->put_value(pclath); pic->fsr->put_value(fsr); return 1; } */ // Get all of file memory /*int icd_get_file() { unsigned char buf[64]; if(icd_fd<0) return 0; cout << "Get file" << endl; pic_processor *pic=dynamic_cast(active_cpu); if(!pic) return; for(int i=0;iregister_memory_size()/0x40;i++) { if(icd_cmd("$$%04X\r",0x7A00+i)!=i) puts("EEEEEEEEEEEEEEEEEEEEE"); icd_write("$$7D40\r"); icd_read(buf,64); for(int j=0;j<64;j++) { if(gpsim_register_is_valid(1,REGISTER_RAM,i*0x40+j) && !gpsim_register_is_alias(1,REGISTER_RAM,i*0x40+j)) { switch(i*0x40+j) { case 2: case 3: case 4: case 10: break; default: pic->registers[i*0x40+j]->put_value(buf[j]); break; } } } // } return 1; } */ icd_Register::icd_Register(Processor *pCpu) : Register(pCpu,"","") { replaced=0; value.put(0x42); is_stale=1; }; void icd_Register::put_value(unsigned int new_value) { } void icd_Register::put(unsigned int new_value) { } unsigned int icd_Register::get_value(void) { return(get()); } unsigned int icd_Register::get(void) { if(is_stale) { switch(address) { case 2: value.put(icd_cmd("$$701F\r")); cpu_pic->pcl->value.put(value.get() & 0xff); cpu_pic->pclath->value.put(value.get() >> 8); is_stale=0; break; case 3: value.put(icd_cmd("$$7016\r")&0x00ff); is_stale=0; replaced->update(); break; case 4: value.put(icd_cmd("$$7019\r")&0x00ff); is_stale=0; replaced->update(); break; case 10: value.put(icd_cmd("$$701F\r")); cpu_pic->pcl->value.put(value.get() & 0xff); cpu_pic->pclath->value.put(value.get() >> 8); is_stale=0; break; default: { if(bulk_flag==0) { unsigned char buf[8]; int offset = address - address%8; icd_cmd("$$%04X\r",0x7800+offset); icd_cmd("$$7C08\r"); icd_write("$$7D08\r"); icd_read(buf,8); for(int i=0;i<8;i++) { switch(offset+i) { case 2: case 3: case 4: case 10: break; default: icd_Register *ifr = static_cast(get_cpu()->registers[offset+i]); assert(ifr!=0); ifr->value.put(buf[i]); ifr->is_stale=0; break; } } for(int i=0;i<0x8;i++) { switch(offset+i) { case 2: case 3: case 4: case 10: break; default: icd_Register *ifr = static_cast(get_cpu()->registers[offset+i]); assert(ifr!=0); ifr->replaced->update(); break; } } } else { unsigned char buf[64]; int offset=address-address%0x40; assert(offset>=0); if(icd_cmd("$$%04X\r",0x7A00+offset/0x40)!=offset/0x40) puts("DDDDDDDDDDDDDDDDDDD"); icd_write("$$7D40\r"); icd_read(buf,0x40); for(unsigned int i=0;i<0x40;i++) { switch(offset+i) { case 2: case 3: case 4: case 10: break; default: icd_Register *ifr = static_cast(get_cpu()->registers[offset+i]); assert(ifr!=0); ifr->value.put(buf[i]); ifr->is_stale=0; break; } } for(int i=0;i<0x40;i++) { switch(offset+i) { case 2: case 3: case 4: case 10: break; default: icd_Register *ifr = static_cast(get_cpu()->registers[offset+i]); assert(ifr!=0); ifr->replaced->update(); break; } } } } break; } } return(value.get()); } icd_WREG::icd_WREG(Processor *pCpu) : WREG(pCpu,"","") { replaced=0; value.put(0x42); is_stale=1; }; void icd_WREG::put_value(unsigned int new_value) { } void icd_WREG::put(unsigned int new_value) { } unsigned int icd_WREG::get_value(void) { return(get()); } unsigned int icd_WREG::get(void) { if(is_stale) { value.put(icd_cmd("$$7017\r")&0x00ff); is_stale=0; replaced->update(); } return(value.get()); } icd_StatusReg::icd_StatusReg(Processor *pCpu) : Status_register(pCpu,"","") { replaced=0; value.put(0x42); is_stale=1; }; void icd_StatusReg::put_value(unsigned int new_value) { } void icd_StatusReg::put(unsigned int new_value) { } unsigned int icd_StatusReg::get_value(void) { if(icd_fd<0) return 0; return(get()); } unsigned int icd_StatusReg::get(void) { if(is_stale) { value.put(icd_cmd("$$7016\r")&0x00ff); is_stale=0; replaced->update(); } return(value.get()); } icd_FSR::icd_FSR(Processor *pCpu) : FSR(pCpu,"","") { replaced=0; value.put(0x42); is_stale=1; }; void icd_FSR::put(unsigned int new_value) { } void icd_FSR::put_value(unsigned int new_value) { } unsigned int icd_FSR::get(void) { return get_value(); } unsigned int icd_FSR::get_value(void) { if(icd_fd<0) return 0; if(is_stale) { value.put(icd_cmd("$$7019\r")&0x00ff); is_stale=0; replaced->update(); } return(value.get()); } icd_PCLATH::icd_PCLATH(Processor *pCpu) : PCLATH(pCpu,"","") { replaced=0; value.put(0x42); is_stale=1; }; void icd_PCLATH::put(unsigned int new_value) { } void icd_PCLATH::put_value(unsigned int new_value) { } unsigned int icd_PCLATH::get(void) { return get_value(); } unsigned int icd_PCLATH::get_value(void) { if(icd_fd<0) return 0; if(is_stale) { value.put((icd_cmd("$$701F\r")&0xff00)>>8); is_stale=0; replaced->update(); } return(value.get()); } icd_PC::icd_PC(Processor *pCpu) : Program_Counter("pc", "ICD Program Counter", pCpu) { replaced=0; value=0x42; is_stale=1; }; void icd_PC::put_value(unsigned int new_value) { } unsigned int icd_PC::get_value(void) { if(icd_fd<0) return 0; if(is_stale) { value = icd_cmd("$$701F\r"); cpu_pic->pcl->value.put(value & 0xff); cpu_pic->pclath->value.put(value >> 8); is_stale=0; } return(value); } gpsim-0.30.0/src/trigger.h0000664000076400007640000001203613063451152012251 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__TRIGGER_H__) #define __TRIGGER_H__ #include using namespace std; class TriggerObject; class TraceType; class Expression; class Trace; //======================================================================== // // Triggers // (these comments are not completely implemented in code) // // gpsim divides a breakpoint into a TriggerAction and a TriggerObject. // The TriggerObject is something that gets evaluated. If it evaluates // to true then a TriggerAction is invoked. // Most breakpoints are simple and don't need this complexity. For example, // an execution breakpoint only needs to halt simulation whenever it's // encountered. But gpsim defines the TriggerObject to be something like // 'if address is executed' and the TriggerAction to be 'halt simulation'. // However this design accomodates much more complicated situations. For // example, the use may wish to break whenever register 42 is cleared during // a time when interrupts are disabled. In this case, the trigger action // is still a simple halt. However, the trigger object is more complicated: // // break w reg(42) (reg(42) == 0) && (STATUS & GIE == 0) // // In this case, the compound expression gets associated with write operations // to register 42. class TriggerAction { public: TriggerAction(); virtual ~TriggerAction(); virtual bool evaluate(); virtual bool getTriggerState(); virtual void action(); }; class SimpleTriggerAction : public TriggerAction { public: explicit SimpleTriggerAction(TriggerObject *_to); virtual void action(); protected: TriggerObject *to; }; // TriggerObject - a base class for handling all of gpsim's breakpoints. // // The TriggerObject class is designed to be part of a multiple inheritance // class heirarchy. Its main function is to provide an interface to the // breakpoint functionality. // // class TriggerObject { public: unsigned int bpn; // Enable the breakpoint and return true if successful virtual bool set_break() {return false;} // A unique number assigned when the break point is armed. int CallBackID; // When the breakpoint associated with this object is encountered, // then 'callback' is invoked. virtual void callback(); // Invoked to display info about the breakpoint. virtual void callback_print(); // clear_trigger is invoked when the breakpoint associated with // this object is cleared. virtual void clear_trigger(); // Will search for a place to store this break point. virtual int find_free(); // This object has no cpu associated with it. However, derived // types may and can choose to provide access to it through here: //virtual Processor *get_cpu() { return 0; } // Display the breakpoint - Probably should tie into a stream... virtual void print(); virtual int printExpression(char *pBuf, int szBuf); // Display traced information. Given an index into a Trace buffer, // printTraced() will extract the traced information and decode it // into a readable form. virtual int printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf); // Clear the breakpoint virtual void clear(); // set_Expr - associates an expression with the trigger virtual void set_Expression(Expression *); virtual bool bHasExpression() { return m_PExpr!=0; } virtual bool eval_Expression(); virtual char const * bpName() { return "Generic"; } virtual void set_action(TriggerAction *ta) { m_action = ta; } virtual TriggerAction *get_action() { return m_action;} virtual void invokeAction(); // Messages can be associatated with triggers string &message() {return m_sMessage;} virtual void new_message(const char *); virtual void new_message(string &); TriggerObject(); explicit TriggerObject(TriggerAction *); // Virtual destructor place holder virtual ~TriggerObject(); protected: // A block of trace types are reserved by the trigger class: static TraceType *m_brt; private: Expression *m_PExpr; string m_sMessage; // When the TriggerObject becomes true, then the TriggerAction is // evaluated. E.g. If the trigger object is an execution breakpoint, // then whenever the PC == break address, the Breakpoint_Instruction // class (which is derived from this class) will invoke action->evaluate() // which will in turn halt the execution. TriggerAction *m_action; }; #endif // !defined(__TRIGGER_H__) gpsim-0.30.0/src/errors.h0000664000076400007640000000221313063451152012116 00000000000000#if !defined(_ERRORS_H_) #define _ERRORS_H_ #include #include "gpsim_object.h" using namespace std; //***************************************************************** class AnError : public gpsimObject { public: AnError(const std::string &severity, const std::string &errMsg); virtual ~AnError(); string toString(); string get_errMsg(); private: string severity; string errMsg; }; //***************************************************************** class Error : public AnError { public: explicit Error(const std::string &errMsg); virtual ~Error(); static int count; }; //***************************************************************** class FatalError : public AnError { public: explicit FatalError(const std::string &errMsg); virtual ~FatalError(); }; //***************************************************************** class TypeMismatch : public Error { public: TypeMismatch(const std::string &theOperator, const std::string &expectedType, const std::string &observedType); TypeMismatch(const std::string &theOperator, const std::string &observedType); virtual ~TypeMismatch(); }; #endif // _ERRORS_ gpsim-0.30.0/src/processor.h0000664000076400007640000006051213063451152012627 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PROCESSOR_H__ #define __PROCESSOR_H__ #include #include #include #include #include #include "gpsim_classes.h" #include "modules.h" #include "trace.h" #include "registers.h" #include "gpsim_time.h" #include "gpsim_interface.h" class Processor; class ProcessorConstructor; class ProgramFileType; class FileContext; class FileContextList; class ProgramMemoryCollection; class CPU_Freq; class CPU_Vdd; //--------------------------------------------------------- /// MemoryAccess - A base class designed to support /// access to memory. For the PIC, this class is extended by /// the ProgramMemoryAccess and RegisterMemoryAccess classes. class MemoryAccess : public TriggerObject, public gpsimObject { public: explicit MemoryAccess(Processor *new_cpu); ~MemoryAccess(); virtual Processor *get_cpu(void); list SpecialRegisters; protected: Processor *cpu; /// The processor to which this object belongs }; //--------------------------------------------------------- /// The ProgramMemoryAccess class is the interface used /// by objects other than the simulator to manipulate the /// pic's program memory. For example, the breakpoint class /// modifies program memory when break points are set or /// cleared. The modification goes through here. class ProgramMemoryAccess : public MemoryAccess { public: /// Symbolic debugging enum HLL_MODES { ASM_MODE, // Source came from plain old .asm files HLL_MODE // Source came from a high level language like C or JAL. }; explicit ProgramMemoryAccess(Processor *new_cpu); ~ProgramMemoryAccess(); virtual void putToAddress(unsigned int addr, instruction *new_instruction); virtual void putToIndex(unsigned int uIndex, instruction *new_instruction); instruction *getFromAddress(unsigned int addr); instruction *getFromIndex(unsigned int uIndex); instruction *get_base_instruction(unsigned int addr); unsigned int get_opcode(unsigned int addr); unsigned int get_rom(unsigned int addr); void put_rom(unsigned int addr,unsigned int value); char *get_opcode_name(unsigned int addr, char *buffer, unsigned int size); virtual unsigned int get_PC(void); virtual void set_PC(unsigned int); virtual Program_Counter *GetProgramCounter(void); void remove(unsigned int address, instruction *bp_instruction); void put_opcode(unsigned int addr, unsigned int new_opcode); // When a pic is replacing one of it's own instructions, this routine // is called. void put_opcode_start(unsigned int addr, unsigned int new_opcode); // Assign a cross reference object to an instruction void assign_xref(unsigned int address, XrefObject * cross_reference); virtual void callback(void); void init(Processor *); // Helper functions for querying the program memory // hasValid_opcode -- returns true if the opcode at the address is valid bool hasValid_opcode_at_address(unsigned int address); bool hasValid_opcode_at_index(unsigned int uIndex); // step - step one of more instructions virtual void step(unsigned int steps, bool refresh=true); virtual void step_over(bool refresh=true); virtual void run(bool refresh=true); virtual void stop(void); virtual void finish(void); // isModified -- returns true if the program at the address has been modified // (this is only valid for those processor capable of writing to their own // program memory) bool isModified(unsigned int address); // Given a file and a line in that file, find the instrucion in the // processor's memory that's closest to it. virtual int find_closest_address_to_line(int file_id, int src_line); virtual int find_address_from_line(FileContext *fc, int src_line); //virtual int find_closest_address_to_hll_line(int file_id, int src_line); // Given an address to an instruction, find the source line that // created it: int get_src_line(unsigned int address); // Return the file ID of the source program responsible for the opcode at address. int get_file_id(unsigned int address); // A couple of functions for manipulating breakpoints virtual unsigned int set_break_at_address(unsigned int address); virtual unsigned int set_notify_at_address(unsigned int address, TriggerObject *cb); virtual unsigned int set_profile_start_at_address(unsigned int address, TriggerObject *cb); virtual unsigned int set_profile_stop_at_address(unsigned int address, TriggerObject *cb); virtual int clear_break_at_address(unsigned int address, enum instruction::INSTRUCTION_TYPES type); virtual int clear_break_at_address(unsigned int address, instruction * pInstruction); virtual int clear_notify_at_address(unsigned int address); virtual int clear_profile_start_at_address(unsigned int address); virtual int clear_profile_stop_at_address(unsigned int address); virtual int address_has_break(unsigned int address, enum instruction::INSTRUCTION_TYPES type=instruction::BREAKPOINT_INSTRUCTION); virtual int address_has_notify(unsigned int address); virtual int address_has_profile_start(unsigned int address); virtual int address_has_profile_stop(unsigned int address); virtual instruction *find_instruction(unsigned int address, enum instruction::INSTRUCTION_TYPES type); virtual void toggle_break_at_address(unsigned int address); virtual void set_break_at_line(unsigned int file_id, unsigned int src_line); virtual void clear_break_at_line(unsigned int file_id, unsigned int src_line); virtual void toggle_break_at_line(unsigned int file_id, unsigned int src_line); void set_hll_mode(unsigned int); enum HLL_MODES get_hll_mode(void) { return hll_mode;} bool isHLLmode(void) {return get_hll_mode() == HLL_MODE;} private: ProgramMemoryCollection *m_pRomCollection; unsigned int _address, _opcode, _state; enum HLL_MODES hll_mode; // breakpoint instruction pointer. This is used by get_base_instruction(). // If an instruction has a breakpoint set on it, then get_base_instruction // will return a pointer to the instruction and will initialize bpi to // the breakpoint instruction that has replaced the one in the processor's // program memory. Breakpoint_Instruction *bpi; }; //--------------------------------------------------------- /// The RegisterMemoryAccess class is the interface used /// by objects other than the simulator to manipulate the /// cpu's register memory. class RegisterMemoryAccess : public MemoryAccess { public: explicit RegisterMemoryAccess(Processor *pCpu); virtual ~RegisterMemoryAccess(); virtual Register *get_register(unsigned int address); unsigned int get_size(void) { return nRegisters; } void set_Registers(Register **_registers, int _nRegisters); // The insertRegister and removeRegister methods are used primarily // to set and clear breakpoints. bool insertRegister(unsigned int address, Register *); bool removeRegister(unsigned int address, Register *); bool hasBreak(unsigned int address); void reset(RESET_TYPE r); Register &operator [] (unsigned int address); private: unsigned int nRegisters; bool initialized; Register **registers; // Pointer to the array of registers. // }; //------------------------------------------------------------------------ // /// FileContext - Maintain state information about files. /// The state of each source file for a processor is recorded in the /// FileContext class. Clients can query information like the name /// of the source file or the line number responsible for generating /// a specific instruction. class FileContext { private: string name_str; // File name FILE *fptr; // File ptr when the file is opened vector line_seek; // A vector of file offsets to the start of lines vector pm_address; // A vector of program memory addresses for lines unsigned int m_uiMaxLine; // number of lines in the file friend class FileContextList; protected: bool m_bIsList; // True if this is a list file. bool m_bIsHLL; // True if this is a HLL file. void setListId(bool b) { m_bIsList = b; } void setHLLId(bool b) { m_bIsHLL = b; } public: // cache -- deprecated - this was used with the old gui source browser typedef vector Cache; Cache m_cache; explicit FileContext(std::string &new_name); explicit FileContext(const char *new_name); ~FileContext(); void ReadSource(); char *ReadLine(unsigned int line_number, char *buf, unsigned int nBytes); char *gets(char *buf, unsigned int nBytes); void rewind(void); void open(const char *mode); void close(); bool IsOpen() { return fptr != NULL; } bool IsList() { return m_bIsList; } bool IsHLL() { return m_bIsHLL; } /// get_address - given a line number, return the program memory address int get_address(unsigned int line); /// put_address - associate a line number with a program memory address. void put_address(unsigned int line, unsigned int address); string &name(void) { return name_str; } unsigned int max_line(); }; //------------------------------------------------------------------------ // // FileContextList - a vector of FileContext objects. // // class FileContextList : private vector { public: #ifndef _MSC_VER typedef vector _Myt; #endif FileContextList(); ~FileContextList(); int Add(string& new_name, bool hll=false); int Add(const char *new_name, bool hll=false); int Find(string &fname); FileContext *operator [] (int file_number); void list_id(int new_list_id); int list_id() { return list_file_id; } int nsrc_files(void) { return (int) size(); } char *ReadLine(int file_id, int line_number, char *buf, int nBytes); char *gets(int file_id, char *buf, int nBytes); void rewind(int file_id); void SetSourcePath(const char *pPath); private: string sSourcePath; int lastFile; int list_file_id; }; class CPU_Vdd : public Float { public: CPU_Vdd(Processor * _cpu, double freq); //const char *_name, double newValue, const char *desc); virtual void set(double d); private: Processor * cpu; }; //------------------------------------------------------------------------ // /// Processor - a generic base class for processors supported by gpsim class Processor : public Module { public: typedef bool (*LPFNISPROGRAMFILE)(const char *, FILE *); /// Load the source code for this processor. The pProcessorName /// is an optional name that a user can assign to the processor. virtual bool LoadProgramFile(const char *hex_file, FILE *pFile, const char *pProcessorName) = 0; /// The source files for this processor. FileContextList files; /// Oscillator cycles for 1 instruction unsigned int clocks_per_inst; /// Supply voltage // double Vdd; /// Stimulus nodes for CVREF and V06REF Stimulus_Node *CVREF; Stimulus_Node *V06REF; /// Processor capabilities unsigned long m_Capabilities; enum { eSTACK = 0x00000001, eWATCHDOGTIMER = 0x00000002, eBREAKONSTACKOVER = 0x00000004, eBREAKONSTACKUNDER = 0x00000009, eBREAKONWATCHDOGTIMER = 0x00000010, }; unsigned long GetCapabilities(); /// Processor RAM Register **registers; RegisterCollection *m_UiAccessOfRegisters; // should this be in rma class? /// Currently selected RAM bank Register **register_bank; /// Program memory - where instructions are stored. instruction **program_memory; /// Program memory interface ProgramMemoryAccess *pma; virtual ProgramMemoryAccess * createProgramMemoryAccess(Processor *processor); virtual void destroyProgramMemoryAccess(ProgramMemoryAccess *pma); virtual instruction * ConstructInvalidInstruction(Processor *processor, unsigned int address, unsigned int new_opcode) { return new invalid_instruction(processor,address,new_opcode); } /// register memory interface RegisterMemoryAccess rma; /// eeprom memory interface (if present). RegisterMemoryAccess ema; unsigned int m_uPageMask; unsigned int m_uAddrMask; /// Program Counter Program_Counter *pc; /// Context debugging is a way of debugging the processor while it is /// in different states. For example, when the interrupt flag is set /// (for those processors that support interrupts), the processor is /// in a different 'state' then when the interrupt flag is cleared. std::list pma_context; /// Tracing /// The readTT and writeTT are TraceType objects for tracing /// register reads and writes. /// The mTrace map is a collection of special trace types that /// share the same trace function code. For example, interrupts /// and resets are special trace events that don't warrant thier /// own trace function code. TraceType *readTT, *writeTT; map mTrace; // Processor's 'bad_instruction' object invalid_instruction bad_instruction; // --- TSD removed 01JAN07 These don't appear to be used anywhere //virtual void set(const char *cP,int len=0); //virtual void get(char *, int len); // // Creation and manipulation of registers // void create_invalid_registers (); void delete_invalid_registers (); void add_file_registers(unsigned int start_address, unsigned int end_address, unsigned int alias_offset); void delete_file_registers(unsigned int start_address, unsigned int end_address, bool bRemoveWithoutDelete=false); void alias_file_registers(unsigned int start_address, unsigned int end_address, unsigned int alias_offset); virtual int map_rm_address2index(int address) {return address;}; virtual int map_rm_index2address(int index) {return index;}; virtual void init_register_memory(unsigned int memory_size); virtual unsigned int register_memory_size () const = 0; virtual unsigned int CalcJumpAbsoluteAddress(unsigned int uInstAddr, unsigned int uDestAddr) { return uDestAddr; } virtual unsigned int CalcCallAbsoluteAddress(unsigned int uInstAddr, unsigned int uDestAddr) { return uDestAddr; } // // Creation and manipulation of Program Memory // virtual void init_program_memory(unsigned int memory_size); virtual void init_program_memory(unsigned int address, unsigned int value); virtual void erase_program_memory(unsigned int address); virtual void init_program_memory_at_index(unsigned int address, unsigned int value); virtual void init_program_memory_at_index(unsigned int address, const unsigned char *, int nBytes); virtual unsigned int program_memory_size(void) const {return 0;}; virtual unsigned int program_address_limit(void) const { return map_pm_index2address(program_memory_size()); }; virtual unsigned int get_program_memory_at_address(unsigned int address); void build_program_memory(unsigned int *memory, unsigned int minaddr, unsigned int maxaddr); virtual int map_pm_address2index(int address) const {return address;}; virtual int map_pm_index2address(int index) const {return index;}; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); guint64 cycles_used(unsigned int address); virtual bool IsAddressInRange(unsigned int address) { return address < program_address_limit(); } // opcode_size - number of bytes for an opcode. virtual int opcode_size() { return 2;} // // Symbolic debugging // // First the source files: void attach_src_line(unsigned int address, unsigned int file_id, unsigned int sline, unsigned int lst_line); void read_src_files(void); virtual void dump_registers(void); virtual instruction * disasm ( unsigned int address,unsigned int inst)=0; //virtual void initializeAttributes(); // // Processor State // // copy the entire processor state to a file virtual void save_state(FILE *); // take an internal snap shot of the current state. virtual void save_state(); // restore the processor state virtual void load_state(FILE *); // // Execution control // virtual void run(bool refresh=true) = 0; virtual void run_to_address(unsigned int destination); virtual void finish(void) = 0; virtual void sleep(void) {}; virtual void exit_sleep() {fputs("RRR exit_sleep\n", stderr);} virtual void step(unsigned int steps,bool refresh=true) = 0; virtual void step_over(bool refresh=true); virtual void step_one(bool refresh=true) = 0; virtual void step_cycle() = 0; virtual void interrupt(void) = 0 ; // Simulation modes /// setWarnMode - when true, gpsim will issue warnings whenever /// something suspicious is occuring. virtual void setWarnMode(bool); virtual bool getWarnMode() { return bWarnMode; } /// setSafeMode - when true, gpsim will model the 'official' /// behavior of the chip. When false, the simulator behaves the same /// as the hardware. virtual void setSafeMode(bool); virtual bool getSafeMode() { return bSafeMode; } /// setUnknownMode - when true, gpsim will implement three-state logic /// for data. When false, unkown data are treated as zeros. virtual void setUnknownMode(bool); virtual bool getUnknownMode() { return bUnknownMode; } /// setBreakOnReset - when true, gpsim will implement three-state logic /// for data. When false, unkown data are treated as zeros. virtual void setBreakOnReset(bool); virtual bool getBreakOnReset() { return bBreakOnReset; } bool getBreakOnInvalidRegisterRead() { return *m_pbBreakOnInvalidRegisterRead; } bool getBreakOnInvalidRegisterWrite() { return *m_pbBreakOnInvalidRegisterWrite; } /// /// Notification of breakpoint set virtual void NotifyBreakpointSet(Breakpoints::BreakStatus &bs, TriggerObject *bpo) { } virtual void NotifyBreakpointCleared(Breakpoints::BreakStatus &bs, TriggerObject *bpo) { } // Tracing control virtual void trace_dump(int type, int amount); virtual int trace_dump1(int type, char *buffer, int bufsize); virtual RegisterValue getWriteTT(unsigned int addr); virtual RegisterValue getReadTT(unsigned int addr); // // Processor Clock control // void set_frequency(double f); void set_frequency_rc(double f); void set_RCfreq_active(bool); virtual double get_frequency(); void set_ClockCycles_per_Instruction(unsigned int cpi) { clocks_per_inst = cpi; } unsigned int get_ClockCycles_per_Instruction(void) { return clocks_per_inst; } void update_cps(void); virtual double get_OSCperiod(); virtual double get_InstPeriod() { return get_OSCperiod() * get_ClockCycles_per_Instruction(); } virtual void disassemble (signed int start_address, signed int end_address); virtual void list(unsigned int file_id, unsigned int pcval, int start_line, int end_line); // Configuration control virtual bool set_config_word(unsigned int address, unsigned int cfg_word) {return false;} // fixme - make this a pure virtual function... virtual unsigned int get_config_word(unsigned int address) = 0; virtual unsigned int config_word_address(void) {return 0;} virtual int get_config_index(unsigned int address){return -1;}; // // Processor reset // virtual void reset(RESET_TYPE r) = 0; virtual double get_Vdd() { return m_vdd->getVal(); } virtual void set_Vdd(double v) {m_vdd->set(v); } virtual void update_vdd(); // // Debugging - used to view the state of the processor (or whatever). // virtual void Debug(); // // FIXME -- create -- a way of constructing a processor (why not use constructors?) // virtual void create(void); static Processor *construct(void); ProcessorConstructor *m_pConstructorObject; Processor(const char *_name=0, const char *desc=0); virtual ~Processor(); CPU_Vdd *m_vdd; phaseExecute1Cycle *mExecute1Cycle; ClockPhase *mCurrentPhase; phaseExecute2ndHalf *mExecute2ndHalf; // misnomer - should be 2-cycle phaseCaptureInterrupt *mCaptureInterrupt; phaseIdle *mIdle; private: CPU_Freq *mFrequency; unsigned int m_ProgramMemoryAllocationSize; // Simulation modes bool bSafeMode; bool bWarnMode; bool bUnknownMode; bool bBreakOnReset; Boolean *m_pbBreakOnInvalidRegisterRead; Boolean *m_pbBreakOnInvalidRegisterWrite; Boolean *m_pWarnMode; Boolean *m_pSafeMode; Boolean *m_pUnknownMode; Boolean *m_pBreakOnReset; }; //------------------------------------------------------------------- // // ProcessorConstructor -- a class to handle all of gpsim's supported // processors // // gpsim supports dozens of processors. All of these processors are // grouped together in the ProcessConstructor class. Within the class // is a static STL list<> object that holds an instance of a // ProcessorConstructor for each gpsim supported processor. Whenever // the user selects a processor to simulate, the find() member // function will search through the list and find the one that matches // the user supplied ASCII string. // // Why have this class? // The idea behind this class is that a ProcessorConstructor object // can be instantiated for each processor and that instantiation will // place the object into list of processors. Prior to gpsim-0.21, a // giant array held the list of all available processors. However, // there were two problems with this: it was painful to look at and // it precluded processors that were defined outside of the gpsim // core library. class ProcessorConstructorList; class ProcessorConstructor { public: typedef Processor * (*tCpuContructor) (const char *_name); protected: // A pointer to a function that when called will construct a processor tCpuContructor cpu_constructor; public: virtual Processor * ConstructProcessor(const char *opt_name=0); // The processor name (plus upto three aliases). #define nProcessorNames 4 const char *names[nProcessorNames]; //------------------------------------------------------------ // contructor -- // ProcessorConstructor( tCpuContructor _cpu_constructor, const char *name1, const char *name2, const char *name3=0, const char *name4=0); virtual ~ProcessorConstructor() { } static ProcessorConstructorList * processor_list; static ProcessorConstructorList * GetList(); }; // THE list of all of gpsim's processors: class ProcessorConstructorList : public list { public: ProcessorConstructorList() {} static ProcessorConstructor * findByType(const char *type); static string DisplayString(void); static ProcessorConstructorList *GetList(); private: static ProcessorConstructorList *processor_list; }; //---------------------------------------------------------- // Global definitions: #if defined(IN_MODULE) && defined(_WIN32) // we are in a module: don't access active_cpu object directly! LIBGPSIM_EXPORT Processor * get_active_cpu(void); #else // we are in gpsim: use of get_active_cpu() and set_active_cpu() is recommended, // even if active_cpu object can be accessed directly. extern Processor *active_cpu; inline Processor *get_active_cpu(void) { return active_cpu; } inline void set_active_cpu(Processor *act_cpu) { active_cpu = act_cpu; } #endif #endif gpsim-0.30.0/src/16bit-tmrs.cc0000664000076400007640000001033513041763624012662 00000000000000/* Copyright (C) 2000 T. Scott Dattalo Copyright (C) 2015 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "../config.h" #include "16bit-tmrs.h" #include "stimuli.h" // // 16bit-tmrs.cc // // Timer 1&2 modules for the 16bit core pic processors. // //-------------------------------------------------- // T5CON //-------------------------------------------------- T5CON::T5CON(Processor *pCpu, const char *pName, const char *pDesc) : T1CON(pCpu, pName, pDesc) { } T5CON::~T5CON() { } void T5CON::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); unsigned int diff = value.get() ^ new_value; value.put(new_value); if (!tmrl) return; // First, check the tmr1 clock source bit to see if we are changing from // internal to external (or vice versa) clocks. if( diff & (TMRxCS0 | TMRxCS1 | TxSOSCEN)) tmrl->new_clock_source(); if( diff & TMRxON) tmrl->on_or_off(value.get() & TMRxON); else if( diff & (TxCKPS0 | TxCKPS1 )) tmrl->update(); } CCPTMRS0::CCPTMRS0(CCPTMRS *_ccptmrs, Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), bit_mask(0xdb), ccptmrs(_ccptmrs) {} CCPTMRS0::~CCPTMRS0() { } void CCPTMRS0::put(unsigned int reg_value) { unsigned int new_value = reg_value & bit_mask; trace.raw(write_trace.get() | value.get()); unsigned int diff = value.get() ^ new_value; value.put(new_value); if (diff) ccptmrs->update0(new_value); } CCPTMRS1::CCPTMRS1(CCPTMRS *_ccptmrs, Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), bit_mask(0x0f), ccptmrs(_ccptmrs) {} CCPTMRS1::~CCPTMRS1() { } void CCPTMRS1::put(unsigned int reg_value) { unsigned int new_value = reg_value & bit_mask; trace.raw(write_trace.get() | value.get()); unsigned int diff = value.get() ^ new_value; value.put(new_value); if (diff) ccptmrs->update1(new_value); } CCPTMRS::CCPTMRS(Processor *pCpu) : ccptmrs0(this, pCpu, "ccptmrs0", "PWM Timer Selection Control Register 0"), ccptmrs1(this, pCpu, "ccptmrs1", "PWM Timer Selection Control Register 1"), t2(0), t4(0), t6(0), ccp1(0), ccp2(0), ccp3(0), ccp4(0), ccp5(0), last_value0(0), last_value1(0) { } CCPTMRS::~CCPTMRS() { } void CCPTMRS::change(CCPCON *ccp, unsigned int old, unsigned int val) { switch (old) { case 0: t2->rm_ccp(ccp); break; case 1: t4->rm_ccp(ccp); break; case 2: t6->rm_ccp(ccp); break; }; switch (val) { case 0: t2->add_ccp(ccp); ccp->set_tmr2(t2); break; case 1: ccp->set_tmr2(t4); t4->add_ccp(ccp); break; case 2: ccp->set_tmr2(t6); t6->add_ccp(ccp); break; }; } void CCPTMRS::update0(unsigned int reg_value) { unsigned int diff = last_value0 ^ reg_value; if (diff & (C1TSEL0 | C1TSEL1)) { change(ccp1, last_value0 & (C1TSEL0 | C1TSEL1), reg_value & (C1TSEL0 | C1TSEL1)); } if (diff & (C2TSEL0 | C2TSEL1)) { change(ccp2, (last_value0 & (C2TSEL0 | C2TSEL1))>>3, (reg_value & (C2TSEL0 | C2TSEL1))>>3); } if (diff & (C3TSEL0 | C3TSEL1)) { change(ccp3, (last_value0 & (C3TSEL0 | C3TSEL1))>>6, (reg_value & (C3TSEL0 | C3TSEL1))>>6); } last_value0 = reg_value; } void CCPTMRS::update1(unsigned int reg_value) { } void CCPTMRS::set_ccp(CCPCON *_c1, CCPCON *_c2, CCPCON *_c3, CCPCON *_c4, CCPCON *_c5) { ccp1 = _c1; ccp2 = _c2; ccp3 = _c3; ccp4 = _c4; ccp5 = _c5; } void CCPTMRS::set_tmr246(TMR2 *_t2, TMR2 *_t4, TMR2 *_t6) { t2 = _t2; t4 = _t4; t6 = _t6; } gpsim-0.30.0/src/spp.h0000664000076400007640000001001413041763613011406 00000000000000/* Copyright (C) 2014 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __SPP_H__ #define __SPP_H__ #include "pic-processor.h" #include "14bit-registers.h" #include "pic-ioports.h" #include "pir.h" class SPP; class SppSignalSource; class PicPSP_PortRegister; class PicTrisRegister; class SPPCON : public sfr_register, public TriggerObject { public: SPPCON(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void set_spp(SPP *_spp) { spp = _spp; } private: SPP *spp; }; class SPPCFG : public sfr_register, public TriggerObject { public: SPPCFG(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void set_spp(SPP *_spp) { spp = _spp; } private: SPP *spp; }; class SPPEPS : public sfr_register, public TriggerObject { public: SPPEPS(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void set_spp(SPP *_spp) { spp = _spp; } private: SPP *spp; }; class SPPDATA : public sfr_register, public TriggerObject { public: SPPDATA(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual unsigned int get(); virtual void put_value(unsigned int new_value); void set_spp(SPP *_spp) { spp = _spp; } private: SPP *spp; }; class SPP : public TriggerObject { public: void initialize( PIR_SET *pir_set, PicPSP_PortRegister *port_set, PicTrisRegister *port_tris, SPPCON *_sppcon, SPPCFG *_sppcfg, SPPEPS *_sppeps, SPPDATA *_sppdata, PinModule *pin_clk1spp, PinModule *pin_clk2spp, PinModule *pin_oespp, PinModule *pin_csspp ); void data_write(unsigned int data); unsigned int data_read(); void eps_write(unsigned int data); void cfg_write(unsigned int data); void enabled(bool state); virtual void callback(); SPP() : sppcon(0), sppcfg(0), sppeps(0), sppdata(0), state_enabled(0), cfg_value(0), eps_value(0), sig_oespp(0), sig_csspp(0), sig_clk1spp(0), sig_clk2spp(0), active_sig_oe(false), active_sig_cs(false), active_sig_clk1(false), active_sig_clk2(false) { } ~SPP(); enum { SPPEN = 1<<0, // SPPCON SPPOWN = 1<<1, WS0 = 1<<0, // SPPCFG WS1 = 1<<1, WS2 = 1<<2, WS3 = 1<<3, CLK1EN = 1<<4, CSEN = 1<<5, CLKCFG0 = 1<<6, CLKCFG1 = 1<<7, ADDR0 = 1<<0, //SPPEPS ADDR1 = 1<<1, ADDR2 = 1<<2, ADDR3 = 1<<3, SPPBUSY = 1<<4, WRSPP = 1<<6, RDSPP = 1<<7 }; protected: // cycle States enum { ST_IDLE = 0, ST_CYCLE1, ST_CYCLE2, }; // I/O operatiom enum { ADDR_WRITE = 1, DATA_WRITE, DATA_READ }; SPPCON *sppcon; SPPCFG *sppcfg; SPPEPS *sppeps; SPPDATA *sppdata; bool state_enabled; unsigned int cfg_value; unsigned int eps_value; unsigned int data_value; PinModule *pin_clk1spp; PinModule *pin_clk2spp; PinModule *pin_oespp; PinModule *pin_csspp; int cycle_state; unsigned int io_operation; SppSignalSource *sig_oespp; SppSignalSource *sig_csspp; SppSignalSource *sig_clk1spp; SppSignalSource *sig_clk2spp; bool active_sig_oe; bool active_sig_cs; bool active_sig_clk1; bool active_sig_clk2; PIR_SET *pir_set; PicPSP_PortRegister *parallel_port; PicTrisRegister *parallel_tris; }; #endif // __SPP_H__ gpsim-0.30.0/src/bitlog.cc0000664000076400007640000002340613041763624012235 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "bitlog.h" #include "../src/gpsim_time.h" #include BoolEventLogger::BoolEventLogger(unsigned int _max_events) : max_events(_max_events) { // Make sure that max_events is an even power of 2 if(max_events & (max_events - 1)) { max_events <<= 1; while(1) { if(max_events && (max_events & (max_events-1))) max_events &= max_events - 1; else break; } } else if(!max_events) max_events = 4096; buffer = new guint64[max_events]; gcycles = &get_cycles(); max_events--; // make the max_events a mask index = 0; } void BoolEventLogger::event(bool state) { // If the new event is different the most recently logged one // then we need to log this event. (Note that the event is implicitly // logged in the "index". I.e. 1 events are at odd indices. if(state ^ (index & 1)) { index = (index + 1) & max_events; buffer[index] = gcycles->get(); } } void BoolEventLogger::dump(int start_index, int end_index) { if((start_index > (int)max_events) || (start_index <= 0 )) start_index = 0; if(end_index == -1) end_index = index; if(start_index == end_index) return; // Loop through and dump events between the start and end points requested do { cout << hex << "0x" << start_index << " = 0x" << buffer[start_index]; if(start_index & 1) cout << ": hi\n"; else cout << ": lo\n"; start_index = (start_index + 1) & max_events; }while ( start_index != end_index); } void BoolEventLogger::dump_ASCII_art(guint64 time_step, guint64 start_time, int end_index) { int start_index = get_index(start_time); if((start_index > (int)max_events) || (start_index <= 0 )) { start_index = 0; start_time = buffer[0]; } if(buffer[start_index] == 0) { start_index = 0; start_time = buffer[0]; } if( (end_index > (int)max_events) || (end_index <= 0 )) end_index = index; if(start_index == end_index) return; if(time_step == 0) time_step = 1; // Loop through and dump events between the start and end points requested guint64 min_pulse = buffer[end_index] - buffer[start_index]; unsigned long i = start_index; int j = (start_index+1) & max_events; do { if( (buffer[j] - buffer[i]) < min_pulse ) min_pulse = (buffer[j] - buffer[i]); i = j; j = (j + 1) & max_events; }while (j != end_index); //cout << "minimum pulse width :" << min_pulse << '\n'; if(min_pulse == 0) { // bummer - there's an error in the log min_pulse = 1; cout << "log error - minimum pulse width shouldn't be zero\n"; } int num_chars = 0; guint64 t = start_time; //buffer[start_index]; guint64 stop_time = gcycles->get(); i = start_index; do { if(t<=buffer[end_index]) j = get_index(t); else j = end_index; switch(j-i) { case 0: case 1: if(i&1) cout <<'-'; else cout <<'_'; break; case 2: cout << '|'; break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: cout << (j-i); break; default: cout << '*'; } i = j; t += time_step; } while( t> 1; search_index = (start_index + bstep) & max_events; bstep >>= 1; // Binary search for the event time: do { if(event_time < buffer[search_index]) search_index = (search_index - bstep) & max_events; else search_index = (search_index + bstep) & max_events; //cout << hex << "search index "<< search_index << " buffer[search_index] " << buffer[search_index] << '\n'; bstep >>= 1; } while(bstep); if(event_time >= buffer[search_index]) return search_index; else return (--search_index & max_events); } //------------------------------------------------------------------------ ThreeStateEventLogger::ThreeStateEventLogger(unsigned int _max_events) : max_events(_max_events) { // Make sure that max_events is an even power of 2 if(max_events & (max_events - 1)) { max_events <<= 1; while(1) { if(max_events && (max_events & (max_events-1))) max_events &= max_events - 1; else break; } } else if(!max_events) max_events = 4096; pTimeBuffer = new guint64[max_events]; pEventBuffer = new char[max_events]; // Initialize the time buffer for (unsigned int i = 0; i < max_events; i++) { pEventBuffer[i] = 0; pTimeBuffer[i] = 0; } gcycles = &get_cycles(); max_events--; // make the max_events a mask index = max_events; bHaveEvents = false; } unsigned int ThreeStateEventLogger::get_index(guint64 event_time) { if (!bHaveEvents) return 0; unsigned long start_index, search_index, bstep; start_index = (index + 1) & max_events; bstep = (max_events+1) >> 1; search_index = (start_index + bstep) & max_events; bstep >>= 1; // Binary search for the event time: do { if(event_time < pTimeBuffer[search_index]) search_index = (search_index - bstep) & max_events; else search_index = (search_index + bstep) & max_events; bstep >>= 1; } while(bstep); if(event_time == pTimeBuffer[search_index]) return search_index; if(event_time < pTimeBuffer[search_index] && pTimeBuffer[search_index] != Cycle_Counter::END_OF_TIME) search_index = (search_index - 1) & max_events; return search_index; } unsigned int ThreeStateEventLogger::get_nEvents(unsigned int start_index, unsigned int stop_index) { return (stop_index >= start_index) ? (stop_index-start_index) : (max_events-stop_index+start_index); } unsigned int ThreeStateEventLogger::get_nEvents(guint64 start_time, guint64 stop_time) { unsigned int start_index = get_index(start_time); unsigned int stop_index = get_index(stop_time); return get_nEvents(start_index,stop_index); } void ThreeStateEventLogger::event(const char state) { // If the new event is different the most recently logged one // then we need to log this event. (Note that the event is implicitly // logged in the "index". I.e. 1 events are at odd indices. if(state != pEventBuffer[index]) { index = (index + 1) & max_events; pTimeBuffer[index] = gcycles->get(); pEventBuffer[index] = state; bHaveEvents = true; } } void ThreeStateEventLogger::dump(int start_index, int end_index) { if (!bHaveEvents) return; if((start_index > (int)max_events) || (start_index <= 0 )) start_index = 0; if(end_index == -1) end_index = index; if(start_index == end_index) return; // Loop through and dump events between the start and end points requested do { cout << hex << "0x" << start_index << " = 0x" << pTimeBuffer[start_index]; cout << " : " << pEventBuffer[start_index] << endl; start_index = (start_index + 1) & max_events; }while ( start_index != end_index); } void ThreeStateEventLogger::dump_ASCII_art(guint64 time_step, guint64 start_time, int end_index) { int start_index = get_index(start_time); if((start_index > (int)max_events) || (start_index <= 0 )) { start_index = 0; start_time = pTimeBuffer[0]; } if(pTimeBuffer[start_index] == 0) { start_index = 0; start_time = pTimeBuffer[0]; } if( (end_index > (int)max_events) || (end_index <= 0 )) end_index = index; if(start_index == end_index) return; // Loop through and dump events between the start and end points requested guint64 min_pulse = pTimeBuffer[end_index] - pTimeBuffer[start_index]; unsigned long i = start_index; int j = (start_index+1) & max_events; do { if( (pTimeBuffer[j] - pTimeBuffer[i]) < min_pulse ) min_pulse = (pTimeBuffer[j] - pTimeBuffer[i]); i = j; j = (j + 1) & max_events; }while (j != end_index); cout << "minimum pulse width :" << min_pulse << '\n'; if(min_pulse == 0) { // bummer - there's an error in the log min_pulse = 1; cout << "log error - minimum pulse width shouldn't be zero\n"; } time_step = 0; time_step = time_step ? time_step : ((min_pulse>2) ? min_pulse/2 : 1); int num_chars = 0; guint64 t = start_time; //buffer[start_index]; guint64 stop_time = gcycles->get(); i = start_index; do { if(t<=pTimeBuffer[end_index]) j = get_index(t); else j = end_index; cout << pEventBuffer[j]; /* switch(j-i) { case 0: case 1: if(i&1) cout <<'-'; else cout <<'_'; break; case 2: cout << '|'; break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: cout << (j-i); break; default: cout << '*'; } */ i = j; t += time_step; } while( t. */ #include #include class InvalidRegister; // Forward reference #ifndef __16_BIT_REGISTERS_H__ #define __16_BIT_REGISTERS_H__ #include "pic-processor.h" #include "14bit-registers.h" #include "14bit-tmrs.h" #include "pir.h" #include "uart.h" #include "a2dconverter.h" #include "ssp.h" #include "rcon.h" #include "eeprom.h" #define _16BIT_REGISTER_MASK 0xfff class _16bit_processor; class stimulus; // forward reference class IOPIN; class source_stimulus; class Stimulus_Node; class PORTB; //--------------------------------------------------------- // // Indirect_Addressing // // This class coordinates the indirect addressing on the 18cxxx // parts. Each of the registers comprising the indirect addressing // subsystem: FSRnL,FSRnH, INDFn, POSTINCn, POSTDECn, PREINCn, and // PLUSWn are each individually defined as sfr_registers AND included // in the Indirect_Addressing class. So accessing these registers // is the same as accessing any register: through the core cpu's // register memory. The only difference for these registers is that // the class Indirect_Addressing; // Forward reference //--------------------------------------------------------- // FSR registers class FSRL : public sfr_register { public: FSRL(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); protected: Indirect_Addressing *iam; }; class FSRH : public sfr_register { public: FSRH(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); protected: Indirect_Addressing *iam; }; class INDF16 : public sfr_register { public: INDF16(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); protected: Indirect_Addressing *iam; }; class PREINC : public sfr_register { public: PREINC(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); protected: Indirect_Addressing *iam; }; class POSTINC : public sfr_register { public: POSTINC(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); protected: Indirect_Addressing *iam; }; class POSTDEC : public sfr_register { public: POSTDEC(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); protected: Indirect_Addressing *iam; }; class PLUSW : public sfr_register { public: PLUSW(Processor *, const char *pName, const char *pDesc, Indirect_Addressing *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); protected: Indirect_Addressing *iam; }; class Indirect_Addressing { public: Indirect_Addressing(pic_processor *cpu, const string &n); pic_processor *cpu; //RRR _16bit_processor *cpu; unsigned int fsr_value; // 16bit concatenation of fsrl and fsrh unsigned int fsr_state; /* used in conjunction with the pre/post incr * and decrement. This is mainly needed for * those instructions that perform read-modify- * write operations on the indirect registers * eg. btg POSTINC1,4 . The post increment must * occur after the bit is toggled and not during * the read operation that's determining the * current state. */ int fsr_delta; /* If there's a pending update to the fsr register * pair, then the magnitude of that update is * stored here. */ guint64 current_cycle; /* Stores the cpu cycle when the fsr was last * changed. */ FSRL fsrl; FSRH fsrh; INDF16 indf; PREINC preinc; POSTINC postinc; POSTDEC postdec; PLUSW plusw; //void init(_16bit_processor *new_cpu); void put(unsigned int new_value); unsigned int get(); unsigned int get_value(); void put_fsr(unsigned int new_fsr); unsigned int get_fsr_value(){return (fsr_value & 0xfff);}; void update_fsr_value(); void preinc_fsr_value(); void postinc_fsr_value(); void postdec_fsr_value(); int plusw_fsr_value(); int plusk_fsr_value(int k); /* bool is_indirect_register(unsigned int reg_address) * * The purpose of this routine is to determine whether or not the * 'reg_address' is the address of an indirect register. This is * used by the 'put' and 'get' functions of the indirect registers. * Indirect registers are forbidden access to other indirect registers. * (Although double indirection in a single instruction cycle would * be powerful!). * * The indirect registers reside at the following addresses * 0xfeb - 0xfef, 0xfe3 - 0xfe7, 0xfdb- 0xfdf * If you look at the binary representation of these ranges: * 1111 1110 1011, 1111 1110 1100 - 1111 1110 1111 (0xfeb,0xfec - 0xfef) * 1111 1110 0011, 1111 1110 0100 - 1111 1110 0111 (0xfe3,0xfe4 - 0xfe7) * 1111 1101 1011, 1111 1101 1100 - 1111 1101 1111 (0xfdb,0xfdc - 0xfdf) * ------------------------------------------------------------------------ * 1111 11xx x011, 1111 11vv v1yy - 1111 11vv v1yy * * Then you'll notice that indirect register addresses share * the common bit pattern 1111 11xx x011 for the left column. * Furthermore, the middle 3-bits, xxx, can only be 3,4, 5. * The ranges in the last two columns share the bit pattern * 1111 11vv v1yy. The middle 3-bits, vvv, again can only be * 3,4, or 5. The least two lsbs, yy, are don't cares. */ inline bool is_indirect_register(unsigned int reg_address) { if( ((reg_address & 0xfc7) == 0xfc3) || ((reg_address & 0xfc4) == 0xfc4)) { unsigned midbits = (reg_address >> 3) & 0x7; if(midbits >= 3 && midbits <= 5) return 1; } return 0; } }; //--------------------------------------------------------- class Fast_Stack { public: unsigned int w,status,bsr; _16bit_processor *cpu; void init(_16bit_processor *new_cpu); void push(); void pop(); }; //--------------------------------------------------------- class PCL16 : public PCL { public: virtual unsigned int get(); virtual unsigned int get_value(); PCL16(Processor *, const char *pName, const char *pDesc=0); }; //--------------------------------------------------------- // Program Counter // class Program_Counter16 : public Program_Counter { public: //virtual void increment(); //virtual void skip(); //virtual void jump(unsigned int new_value); //virtual void interrupt(unsigned int new_value); virtual void computed_goto(unsigned int new_value); //virtual void new_address(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual void update_pcl(); virtual unsigned int get_value(); //virtual unsigned int get_next(); Program_Counter16(Processor *pCpu); }; //--------------------------------------------------------- // Stack // class Stack16; class STKPTR16 : public sfr_register { public: enum { STKUNF = 1<<6, STKOVF = 1<<7 }; STKPTR16(Processor *, const char *pName, const char *pDesc=0); Stack16 *stack; void put_value(unsigned int new_value); void put(unsigned int new_value); }; class TOSU : public sfr_register { public: TOSU(Processor *, const char *pName, const char *pDesc=0); Stack16 *stack; void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); }; class Stack16 : public Stack { public: STKPTR16 stkptr; TOSL tosl; TOSH tosh; TOSU tosu; Stack16(Processor *); ~Stack16(); virtual bool push(unsigned int); virtual unsigned int pop(); virtual void reset(RESET_TYPE); virtual bool stack_overflow(); virtual bool stack_underflow(); }; class TMR0_16; //--------------------------------------------------------- class CPUSTA : public sfr_register { public: enum { BOR = 1<<0, POR = 1<<1, PD = 1<<2, TO = 1<<3, GLINTD = 1<<4, STKAV = 1<<5, }; CPUSTA(Processor *, const char *pName, const char *pDesc=0); }; //--------------------------------------------------------- // T0CON - Timer 0 control register class T0CON : public OPTION_REG { public: enum { T08BIT = 1<<6, TMR0ON = 1<<7 }; T0CON(Processor *, const char *pName, const char *pDesc=0); void put(unsigned int new_value); void initialize(); }; //--------------------------------------------------------- // TMR0 - Timer for the 16bit core. // // The 18cxxx extends TMR0 to a 16-bit timer. However, it maintains // an 8-bit mode that is compatible with the 8-bit TMR0's in the // 14 and 12-bit cores. The 18cxxx TMR0 reuses this code by deriving // from the TMR0 class and providing definitions for many of the // virtual functions. class TMR0H : public sfr_register { public: TMR0H(Processor *, const char *pName, const char *pDesc=0); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); }; class TMR0_16 : public TMR0 { public: TMR0_16(Processor *, const char *pName, const char *pDesc=0); T0CON *t0con; INTCON *intcon; TMR0H *tmr0h; unsigned int value16; virtual void callback(); virtual void callback_print(); virtual void increment(); virtual unsigned int get(); virtual unsigned int get_value(); virtual void put_value(unsigned int new_value); virtual unsigned int get_prescale(); virtual unsigned int max_counts(); virtual void set_t0if(); virtual bool get_t0cs(); virtual void initialize(); virtual void start(int new_value,int sync=0); virtual void sleep(); virtual void wake(); }; //--------------------------------------------------------- /* class TMR3H : public TMRH { public: }; class TMR3L : public TMRL { public: }; */ class T3CON : public T1CON { public: enum { T3CCP1 = 1<<3, T3CCP2 = 1<<6, }; CCPRL *ccpr1l; CCPRL *ccpr2l; TMRL *tmr1l; T1CON *t1con; T3CON(Processor *pCpu, const char *pName, const char *pDesc=0); virtual void put(unsigned int new_value); virtual bool get_t1oscen() { if (t1con) return(t1con->get_t1oscen()); return(0); } }; //--------------------------------------------------------- // // TMR3_MODULE // // class TMR3_MODULE { public: _16bit_processor *cpu; char * name_str; T3CON *t3con; PIR_SET *pir_set; TMR3_MODULE(); void initialize(T3CON *t1con, PIR_SET *pir_set); }; //------------------------------------------------------------------- class TBL_MODULE : public EEPROM_EXTND { public: TBL_MODULE(_16bit_processor *pCpu); unsigned int state; unsigned int internal_latch; _16bit_processor *cpu; sfr_register tablat, tblptrl, tblptrh, tblptru; void increment(); void decrement(); void read(); void write(); virtual void start_write(); //void initialize(_16bit_processor *); }; ////////////////////////////////////////// ////////////////////////////////////////// // vapid Place holders ////////////////////////////////////////// ////////////////////////////////////////// class LVDCON : public sfr_register { public: unsigned int valid_bits; enum { LVDL0 = 1<<0, LVDL1 = 1<<1, LVDL2 = 1<<2, LVDL3 = 1<<3, LVDEN = 1<<4, IRVST = 1<<5, }; LVDCON(Processor *, const char *pName, const char *pDesc=0); }; /* High/Low-Voltage Detect Module */ class HLVDCON; class HLVD_stimulus : public stimulus { public: HLVD_stimulus(HLVDCON *_hlvd, const char *n=0); ~HLVD_stimulus(); virtual void set_nodeVoltage(double v); private: HLVDCON *hlvd; }; class HLVDCON : public sfr_register, public TriggerObject { public: enum { VDIRMAG = 1<<7, // Voltage Direction Magnitude Select bit BGVST = 1<<6, // Band Gap Reference Voltages Stable Status Flag bit IRVST = 1<<5, // Internal Reference Voltage Stable Flag bit HLVDEN = 1<<4, // High/Low-Voltage Detect Power Enable bit HLVDL3 = 1<<3, // Voltage Detection Level bits HLVDL2 = 1<<2, // Voltage Detection Level bits HLVDL1 = 1<<1, // Voltage Detection Level bits HLVDL0 = 1<<0, // Voltage Detection Level bits HLVDL_MASK = 0xf }; HLVDCON(Processor *pCpu, const char *pName, const char *pDesc); ~HLVDCON(); void put(unsigned int new_value); virtual void callback_print(){cout << name() << " has callback, ID = " << CallBackID << '\n';} void callback(); void set_hlvdin(PinModule *_hlvdin){ hlvdin = _hlvdin;} void check_hlvd(); virtual void setIntSrc(InterruptSource *_IntSrc) { IntSrc = _IntSrc;} private: PinModule *hlvdin; HLVD_stimulus *hlvdin_stimulus; bool stimulus_active; unsigned int write_mask; InterruptSource *IntSrc; }; #endif // __16_BIT_REGISTERS_H__ gpsim-0.30.0/src/p12x.h0000664000076400007640000002435513041763624011415 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P12X_H__ #define __P12X_H__ #include "12bit-processors.h" #include "pic-ioports.h" #include "a2dconverter.h" class P12_I2C_EE; class P12bitBase; class P12_OSCCON : public sfr_register { public: enum { FOSC4 = 1 << 0 }; P12_OSCCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), m_CPU(0) { } void put(unsigned int new_value); void set_cpu(P12bitBase *pCPU) { m_CPU = pCPU;} private: P12bitBase *m_CPU; }; class GPIO : public PicPortRegister { public: GPIO(P12bitBase *pCpu, const char *pName, const char *pDesc, unsigned int numIopins, unsigned int enableMask, unsigned int resetMask = (1 << 3), unsigned int wakeupMask = 0x0b, unsigned int configMaskMCLRE = (1<<4)); void setbit(unsigned int bit_number, char new_value); void setPullUp ( bool bNewPU , bool mclr); private: P12bitBase *m_CPU; bool m_bPU; unsigned int m_resetMask; unsigned int m_wakeupMask; unsigned int m_configMaskMCLRE; }; //-------------------------------------------------------- /* * IN_SignalControl is used to set a pin as input * regardless of the setting to the TRIS register */ class IN_SignalControl : public SignalControl { public: IN_SignalControl(){ } ~IN_SignalControl(){} char getState() { return '1'; } void release() { } }; //-------------------------------------------------------- /* * OUT_SignalControl is used to set a pin as input * regardless of the setting to the TRIS register */ class OUT_SignalControl : public SignalControl { public: OUT_SignalControl(){} ~OUT_SignalControl(){} char getState() { return '0'; } void release() { } }; //-------------------------------------------------------- /* * OUT_DriveControl is used to override output * regardless of the setting to the GPIO register */ class OUT_DriveControl : public SignalControl { public: OUT_DriveControl(){} ~OUT_DriveControl(){} char getState() { return '1'; } void release() { } }; class P12bitBase : public _12bit_processor { public: GPIO *m_gpio; PicTrisRegister *m_tris; P12_OSCCON osccal; virtual PROCESSOR_TYPE isa(){return _P12C508_;}; virtual void create_symbols(); virtual void enter_sleep(); virtual void create_sfr_map(); virtual void dump_registers(); virtual void tris_instruction(unsigned int tris_register); virtual void reset(RESET_TYPE r); P12bitBase(const char *_name=0, const char *desc=0); virtual ~P12bitBase(); static Processor *construct(const char *name); virtual void create_iopin_map(); virtual void create_config_memory(); virtual unsigned int fsr_valid_bits() { return 0x1f; // Assume only 32 register addresses } virtual unsigned int fsr_register_page_bits() { return 0; // Assume only one register page. } virtual void option_new_bits_6_7(unsigned int); IN_SignalControl *m_IN_SignalControl; OUT_SignalControl *m_OUT_SignalControl; OUT_DriveControl *m_OUT_DriveControl; virtual void updateGP2Source(); virtual void freqCalibration(); virtual void setConfigWord(unsigned int val, unsigned int diff); unsigned int configWord; // bits of Configuration word enum { FOSC0 = 1<<0, FOSC1 = 1<<1, WDTEN = 1<<2, CP = 1<<3, MCLRE = 1<<4 }; }; class P12C508 : public P12bitBase { public: P12C508(const char *_name=0, const char *desc=0); virtual ~P12C508(); static Processor *construct(const char *name); virtual void create(); virtual unsigned int program_memory_size() const { return 0x200; } }; class P12F508 : public P12C508 { public: P12F508(const char *_name=0, const char *desc=0); virtual ~P12F508(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE isa(){return _P12F508_;}; }; // A 12c509 is like a 12c508 class P12C509 : public P12C508 { public: virtual PROCESSOR_TYPE isa(){return _P12C509_;}; virtual unsigned int program_memory_size() const { return 0x400; }; virtual void create_sfr_map(); virtual unsigned int fsr_valid_bits() { return 0x3f; // 64 registers in all (some are actually aliased) } virtual unsigned int fsr_register_page_bits() { return 0x20; // 509 has 2 register banks } P12C509(const char *_name=0, const char *desc=0); ~P12C509(); static Processor *construct(const char *name); virtual void create(); }; class P12F509 : public P12C509 { public: P12F509(const char *_name=0, const char *desc=0); virtual ~P12F509(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE isa(){return _P12F509_;} }; // 12F510 - like a '509, but has an A2D and a comparator. class P12F510 : public P12F509 { public: P12F510(const char *_name=0, const char *desc=0); virtual ~P12F510(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE isa(){return _P12F510_;} }; // A 12CE518 is like a 12c508 class P12CE518 : public P12C508 { public: virtual PROCESSOR_TYPE isa(){return _P12CE518_;}; virtual void tris_instruction(unsigned int tris_register); P12CE518(const char *_name=0, const char *desc=0); ~P12CE518(); static Processor *construct(const char *name); virtual void create(); virtual void create_iopin_map(); virtual void freqCalibration(); private: P12_I2C_EE *m_eeprom; Stimulus_Node *scl; Stimulus_Node *sda; IO_bi_directional_pu *io_scl; IO_open_collector *io_sda; }; // A 12ce519 is like a 12ce518 class P12CE519 : public P12CE518 { public: virtual PROCESSOR_TYPE isa(){return _P12CE519_;}; virtual unsigned int program_memory_size() const { return 0x400; }; virtual void create_sfr_map(); virtual unsigned int fsr_valid_bits() { return 0x3f; // 64 registers in all (some are actually aliased) } virtual unsigned int fsr_register_page_bits() { return 0x20; // 519 has 2 register banks } P12CE519(const char *_name=0, const char *desc=0); ~P12CE519(); static Processor *construct(const char *name); virtual void create(); }; // 10F200 class P10F200 : public P12bitBase { public: virtual PROCESSOR_TYPE isa(){return _P10F200_;}; virtual unsigned int program_memory_size() const { return 0x100; }; P10F200(const char *_name=0, const char *desc=0); virtual ~P10F200(); static Processor *construct(const char *name); virtual void create(); virtual void create_iopin_map(); // GP2 can be driven by either FOSC/4, TMR 0, or the GP I/O driver virtual void updateGP2Source(); virtual void freqCalibration(); // WDT causes reset on sleep virtual bool exit_wdt_sleep() { return false; } }; // A 10F202 is like a 10f200 class P10F202 : public P10F200 { public: virtual PROCESSOR_TYPE isa(){return _P10F202_;}; virtual unsigned int program_memory_size() const { return 0x200; }; P10F202(const char *_name=0, const char *desc=0); ~P10F202(); static Processor *construct(const char *name); virtual void create(); }; class CMCON0; // A 10F204 is like a 10f200 class P10F204 : public P10F200 { public: virtual PROCESSOR_TYPE isa(){return _P10F204_;}; P10F204(const char *_name=0, const char *desc=0); ~P10F204(); static Processor *construct(const char *name); virtual void create(); // GP2 can be driven by either FOSC/4, COUT, TMR 0, or the GP I/O driver virtual void updateGP2Source(); protected: CMCON0 *m_cmcon0; }; // A 10F220 is based on 10f200 class P10F220 : public P10F200 { public: ADCON0_10 adcon0; ADCON1 adcon1; sfr_register adres; virtual PROCESSOR_TYPE isa(){return _P10F220_;}; P10F220(const char *_name=0, const char *desc=0); ~P10F220(); static Processor *construct(const char *name); virtual void create(); virtual void enter_sleep(); virtual void exit_sleep(); virtual void setConfigWord(unsigned int val, unsigned int diff); // Bits of configuration word enum { IOSCFS = 1<<0, NOT_MCPU = 1<<1, }; protected: }; // A 10F220 is like a 10f220 class P10F222 : public P10F220 { public: virtual PROCESSOR_TYPE isa(){return _P10F222_;}; P10F222(const char *_name=0, const char *desc=0); ~P10F222(); virtual unsigned int program_memory_size() const { return 0x200; }; static Processor *construct(const char *name); virtual void create(); // GP2 can be driven by either FOSC/4, TMR 0, or the GP I/O driver //virtual void updateGP2Source(); protected: }; class P16F505 : public P12bitBase { public: enum { FOSC0 = 1<<0, FOSC1 = 1<<1, FOSC2 = 1<<2, WDTEN = 1<<3, CP = 1<<4, MCLRE = 1<<5 }; P16F505(const char *_name=0, const char *desc=0); virtual ~P16F505(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE isa() { return _P16F505_; }; virtual void create(); virtual void create_symbols(); virtual void create_iopin_map(); virtual void create_sfr_map(); virtual void create_config_memory(); virtual void tris_instruction(unsigned int tris_register); virtual void setConfigWord(unsigned int val, unsigned int diff); virtual void updateGP2Source(); virtual void option_new_bits_6_7(unsigned int bits); virtual void reset(RESET_TYPE r); virtual void dump_registers(); virtual unsigned int program_memory_size() const { return 0x400; } virtual unsigned int fsr_valid_bits() { return 0x7f; } virtual unsigned int fsr_register_page_bits() { return 0x60; } GPIO *m_portb; GPIO *m_portc; PicTrisRegister *m_trisb; PicTrisRegister *m_trisc; }; #endif // __P12X_H__ gpsim-0.30.0/src/12bit-processors.h0000664000076400007640000000770713041763624013746 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "pic-processor.h" #ifndef __12_BIT_PROCESSORS_H__ #define __12_BIT_PROCESSORS_H__ // forward references class _12bit_processor; class IOPIN; class OptionTraceType; extern instruction *disasm12 (pic_processor *cpu,unsigned int address,unsigned int inst); class _12bit_processor : public pic_processor { public: #define WDTE 4 enum _12BIT_DEFINITIONS { PA0 = 1<<5, /* Program page preselect bits (in status) */ PA1 = 1<<6, PA2 = 1<<7, RP0 = 1<<5, /* Register page select bits (in fsr) */ RP1 = 1<<6 }; unsigned int pa_bits; /* a CPU dependent bit-mask defining which of the program * page bits in the status register are significant. */ OPTION_REG *option_reg; virtual void reset(RESET_TYPE r); virtual void save_state(); virtual void create_symbols(); #define FILE_REGISTERS 0x100 virtual unsigned int register_memory_size () const { return FILE_REGISTERS;}; virtual void dump_registers(); virtual void tris_instruction(unsigned int tris_register){return;}; virtual void create(); virtual void create_config_memory(); virtual PROCESSOR_TYPE isa(){return _12BIT_PROCESSOR_;}; virtual PROCESSOR_TYPE base_isa(){return _12BIT_PROCESSOR_;}; virtual instruction * disasm (unsigned int address, unsigned int inst) { return disasm12(this, address, inst); } void interrupt() { return; }; // Declare a set of functions that will allow the base class to // get information about the derived classes. NOTE, the values returned here // will cause errors if they are used -- the derived classes must define their // parameters appropriately. virtual unsigned int program_memory_size(){ return 3; }; // A bogus value that will cause errors if used // The size of a program memory bank is 2^11 bytes for the 12-bit core virtual void create_sfr_map() { return;}; // Return the portion of pclath that is used during branching instructions // Actually, the 12bit core has no pclath. However, the program counter class doesn't need // to know that. Thus this virtual function really just returns the code page for the // 12bit cores. virtual unsigned int get_pclath_branching_jump() { return ((status->value.get() & pa_bits) << 4); } // The modify pcl type instructions execute exactly like call instructions virtual unsigned int get_pclath_branching_modpcl() { return ((status->value.get() & pa_bits) << 4); } // The valid bits in the FSR register vary across the various 12-bit devices virtual unsigned int fsr_valid_bits() { return 0x1f; // Assume only 32 register addresses } virtual unsigned int fsr_register_page_bits() { return 0; // Assume only one register page. } virtual void put_option_reg(unsigned int); virtual void option_new_bits_6_7(unsigned int); virtual unsigned int config_word_address() const {return 0xfff;}; virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void enter_sleep(); virtual void exit_sleep(); _12bit_processor(const char *_name=0, const char *desc=0); virtual ~_12bit_processor(); protected: OptionTraceType *mOptionTT; }; #define cpu12 ( (_12bit_processor *)cpu) #endif gpsim-0.30.0/src/p18fk.cc0000664000076400007640000013161313115236763011707 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2010 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "p18x.h" #include "p18fk.h" #include "pic-ioports.h" #include "packages.h" #include "stimuli.h" #include "symbol.h" /* Config Word defines */ #define MCLRE (1<<7) #define P2BMX (1<<5) #define T3CMX (1<<4) #define HFOFST (1<<3) #define LPT1OSC (1<<2) #define CCP3MX (1<<2) #define PBADEN (1<<1) #define CCP2MX (1<<0) //------------------------------------------------------------------------ // // P18F14K22 // //------------------------------------------------------------------------ void P18F14K22::create_iopin_map() { package = new Package(20); if(!package) return; // Build the links between the I/O Ports and their tris registers. package->assign_pin( 1, 0); // Vdd package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IO_open_collector("porta3"),3)); // %%%FIXME - is this O/C ? package->assign_pin( 5, m_portc->addPin(new IO_bi_directional("portc5"),3)); package->assign_pin( 6, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin( 7, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin( 8, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin( 9, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin(19, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(20, 0); // Vss tmr1l.setIOpin(&(*m_porta)[5]); ssp.initialize(&pir_set_def, // PIR &(*m_portb)[6], // SCK &(*m_portc)[6], // SS &(*m_portc)[7], // SDO &(*m_portb)[4], // SDI m_trisb, // i2c tris port SSP_TYPE_MSSP ); } P18F14K22::P18F14K22(const char *_name, const char *desc) : _16bit_processor(_name,desc), adcon0(this, "adcon0", "A2D control register 0"), adcon1(this, "adcon1", "A2D control register 1"), adcon2(this, "adcon2", "A2D control register 2"), vrefcon0(this, "vrefcon0", "Fixed Voltage Reference Control Register"), vrefcon1(this, "vrefcon1", "Voltage Reference Control Register 0", 0xed), vrefcon2(this, "vrefcon2", "Voltage Reference Control Register 1",0x1f, &vrefcon1), eccp1as(this, "eccp1as", "ECCP 1 Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM 1 Control Register"), osctune(this, "osctune", "OSC Tune"), comparator(this), ansela(this, "ansel", "Analog Select Register"), anselb(this, "anselh", "Analog Select Register High"), slrcon(this, "slrcon", "Slew Rate Control Register", 0x07), ccptmrs(this), pstrcon(this, "pstrcon", "PWM Steering Control Register"), sr_module(this), ssp1(this) { if(verbose) cout << "18F14K22 constructor, type = " << isa() << '\n'; // delete pir2; // pir2 = (PIR2v2 *)(new PIR2v4(this, "pir2" , "Peripheral Interrupt Register",0,0 )); wpua = new WPU(this, "wpua", "Weak Pull-Up Porta Register", m_porta, 0x3f); wpub = new WPU(this, "wpub", "Weak Pull-Up Portb Register", m_portb, 0xf0); ioca = new IOC(this, "ioca", "Interrupt-On-Change Porta Control Register", 0xf0); iocb = new IOC(this, "iocb", "Interrupt-On-Change Portb Control Register", 0xf0); // By default TMR2 controls deals with all ccp units until // changed by ccptmrsx registers // ccptmrs.set_tmr246(&tmr2, &tmr4, &tmr6); // ccptmrs.set_ccp(&ccp1con, &ccp2con, &ccp3con, &ccp4con, &ccp5con); comparator.cmxcon0[0] = new CMxCON0_V2(this, "cm1con0", " Comparator C1 Control Register 0", 0, &comparator); comparator.cmxcon0[1] = new CMxCON0_V2(this, "cm2con0", " Comparator C2 Control Register 0", 1, &comparator); comparator.cmxcon1[0] = new CM2CON1_V2(this, "cm2con1", " Comparator Control Register 1", &comparator); comparator.cmxcon1[1] = comparator.cmxcon1[0]; } P18F14K22::~P18F14K22() { remove_sfr_register(comparator.cmxcon0[0]); remove_sfr_register(comparator.cmxcon0[1]); remove_sfr_register(comparator.cmxcon1[0]); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); remove_sfr_register(&osctune); remove_sfr_register(&tmr2); remove_sfr_register(&pr2); remove_sfr_register(&t2con); remove_sfr_register(&pwm1con); remove_sfr_register(&eccp1as); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccp2con); remove_sfr_register(osccon); remove_sfr_register(&ansela); remove_sfr_register(&anselb); delete_sfr_register(wpub); delete_sfr_register(iocb); delete_sfr_register(wpua); delete_sfr_register(ioca); remove_sfr_register(&slrcon); remove_sfr_register(&ccptmrs.ccptmrs1); remove_sfr_register(&ccptmrs.ccptmrs0); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adcon2); remove_sfr_register(&vrefcon0); remove_sfr_register(&vrefcon1); remove_sfr_register(&vrefcon2); remove_sfr_register(&sr_module.srcon0); remove_sfr_register(&sr_module.srcon1); remove_sfr_register(&pstrcon); remove_sfr_register(&ssp1.sspbuf); remove_sfr_register(&ssp1.sspadd); remove_sfr_register(ssp1.sspmsk); remove_sfr_register(&ssp1.sspstat); remove_sfr_register(&ssp1.sspcon); remove_sfr_register(&ssp1.sspcon2); remove_sfr_register(&ssp1.ssp1con3); } void P18F14K22::create() { RegisterValue porv(0,0); RegisterValue porvh(0xff,0); if(verbose) cout << "P18F14K22::create\n"; tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, false ); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); create_iopin_map(); _16bit_processor::create(); set_osc_pin_Number(0, 2, &(*m_porta)[5]); set_osc_pin_Number(1, 3, &(*m_porta)[4]); // @todo : some of these may not be right m_configMemory->addConfigWord(CONFIG1L-CONFIG1L,new ConfigWord("CONFIG1L", 0x00, "Configuration Register 1 low", this, CONFIG1L)); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0x25)); m_configMemory->addConfigWord(CONFIG3H-CONFIG1L,new Config3H(this, CONFIG3H, 0x88)); // add_sfr_register( osccon, 0xfd3, RegisterValue(0x30,0), "osccon"); osccon->por_value = RegisterValue(0x30,0); add_sfr_register(&adcon0, 0xfc2, porv, "adcon0"); add_sfr_register(&adcon1, 0xfc1, porv, "adcon1"); add_sfr_register(&adcon2, 0xfc0, porv, "adcon2"); add_sfr_register(&pstrcon, 0xfb9, RegisterValue(0x01,0)); add_sfr_register(&pwm1con, 0xfb7, porv); add_sfr_register(&eccp1as, 0xfb6, porv); add_sfr_register(comparator.cmxcon0[0], 0xf6d, RegisterValue(0x08,0), "cm1con0"); add_sfr_register(comparator.cmxcon0[1], 0xf6b, RegisterValue(0x08,0), "cm2con0"); add_sfr_register(comparator.cmxcon1[0], 0xf6c, porv, "cm2con1"); add_sfr_register(ioca, 0xf79, porvh); add_sfr_register(wpua, 0xf77, porvh); add_sfr_register(iocb, 0xf7a, porvh); add_sfr_register(wpub, 0xf78, porvh); add_sfr_register(&slrcon, 0xf76, porvh); add_sfr_register(&sr_module.srcon0, 0xf68, porv); add_sfr_register(&sr_module.srcon1, 0xf69, porv); add_sfr_register(&vrefcon0, 0xfba, RegisterValue(0x10,0)); add_sfr_register(&vrefcon1, 0xfbb, porv); add_sfr_register(&vrefcon2, 0xfbc, porv); add_sfr_register(&anselb, 0xf7f, RegisterValue(0x0f,0)); add_sfr_register(&ansela, 0xf7e, RegisterValue(0xff,0)); add_sfr_register(ssp1.sspmsk, 0xf6f, RegisterValue(0xff,0),"sspmask"); eccp1as.setBitMask(0xfc); // ECCP shutdown trigger eccp1as.setIOpin(0, 0, &(*m_portb)[0]); eccp1as.link_registers(&pwm1con, &ccp1con); //RRR comparator.cmcon.set_eccpas(&eccp1as); ccp1con.setBitMask(0xff); ccp1con.setCrosslinks(&ccpr1l, &pir1, PIR1v2::CCP1IF, &tmr2, &eccp1as); ccp1con.pwm1con = &pwm1con; ccp1con.pstrcon = &pstrcon; ccp1con.setIOpin(&((*m_portc)[5]), &((*m_portc)[4]), &((*m_portc)[3]), &((*m_portc)[2])); pwm1con.setBitMask(0x80); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setAdcon2(&adcon2); adcon0.setIntcon(&intcon); adcon0.setPir(&pir1); adcon0.setChannel_Mask(0x0f); // upto 16 channels adcon0.setA2DBits(10); adcon1.setNumberOfChannels(12); adcon1.setVrefHiChannel(3); adcon1.setVrefLoChannel(2); adcon1.setAdcon0(&adcon0); // VCFG0, VCFG1 in adcon0 vrefcon0.set_adcon1(&adcon1); vrefcon1.set_adcon1(&adcon1); vrefcon0.set_daccon0(&vrefcon1); ansela.setIOPin(0, &(*m_porta)[0], &adcon1); ansela.setIOPin(1, &(*m_porta)[1], &adcon1); ansela.setIOPin(2, &(*m_porta)[2], &adcon1); ansela.setIOPin(3, &(*m_porta)[4], &adcon1); ansela.setIOPin(4, &(*m_portc)[0], &adcon1); ansela.setIOPin(5, &(*m_portc)[1], &adcon1); ansela.setIOPin(6, &(*m_portc)[2], &adcon1); ansela.setIOPin(7, &(*m_portc)[3], &adcon1); anselb.setIOPin(8, &(*m_portc)[6], &adcon1); anselb.setIOPin(9, &(*m_portc)[7], &adcon1); anselb.setIOPin(10, &(*m_portb)[4], &adcon1); anselb.setIOPin(11, &(*m_portb)[5], &adcon1); } OSCCON * P18F14K22::getOSCCON(void) { OSCCON_HS * new_oc = new OSCCON_HS(this, "osccon", "OSC Control"); new_oc->minValPLL = 6; // This family doesn't allow PLL at 4MHz return new_oc; } void P18F14K22::set_config3h(gint64 value) { (value & MCLRE) ? assignMCLRPin(4) : unassignMCLRPin(); } // Set the oscillator mode from the CONFIG1H value void P18F14K22::osc_mode(unsigned int value) { unsigned int mode = value & (FOSC3 | FOSC2 | FOSC1 | FOSC0); unsigned int pin_Number0 = get_osc_pin_Number(0); unsigned int pin_Number1 = get_osc_pin_Number(1); bool pllen = value & PLLCFG; if (mode == 0x8 || mode == 0x9) set_int_osc(true); else set_int_osc(false); if (pin_Number1 < 253) { switch(mode) { case 0xf: // external RC CLKOUT RA6 case 0xe: case 0xc: case 0xa: case 0x9: case 0x6: case 0x4: // CLKO = OSC2 cout << "CLKO not simulated\n"; set_clk_pin(pin_Number1, get_osc_PinMonitor(1) , "CLKO", false, m_porta, m_trisa, m_lata); break; default: clr_clk_pin(pin_Number1, get_osc_PinMonitor(1), m_porta, m_trisa, m_lata); break; } } set_pplx4_osc(pllen); if (pin_Number0 < 253) { if ( mode != 0x9 && mode != 0x8 ) // not internal OSC, set OSC1 { set_clk_pin(pin_Number0, get_osc_PinMonitor(0) , "OSC1", true, m_porta, m_trisa, m_lata); } else { clr_clk_pin(pin_Number0, get_osc_PinMonitor(0), m_porta, m_trisa, m_lata); } } if (pin_Number1 < 253) { if ( mode < 4 ) { set_clk_pin(pin_Number1, get_osc_PinMonitor(1) , "OSC2", true, m_porta, m_trisa, m_lata); } else { clr_clk_pin(pin_Number1, get_osc_PinMonitor(1), m_porta, m_trisa, m_lata); } } } Processor * P18F14K22::construct(const char *name) { P18F14K22 *p = new P18F14K22(name); if(verbose) cout << " 18F14K22 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F14K22 construct completed\n"; return p; } void P18F14K22::create_sfr_map() { if(verbose) cout << "create_sfr_map P18F14K22\n"; _16bit_processor::create_sfr_map(); RegisterValue porv(0,0); // remove_sfr_register(t3con); // add_sfr_register(t3con2, 0xfb1,porv); add_sfr_register(&osctune, 0xf9b,porv); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[2], &(*m_porta)[4]); comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[1], &(*m_portc)[1], &(*m_portc)[2],&(*m_portc)[3]); comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[0], &(*m_portc)[0]); comparator.cmxcon1[0]->setBitMask(0x3f); comparator.cmxcon0[0]->setBitMask(0xbf); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, PIR2v2::C1IF)); comparator.cmxcon0[1]->setBitMask(0xbf); comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, PIR2v2::C2IF)); vrefcon0.set_cmModule(&comparator); // comparator.assign_t1gcon(&t1gcon, &t3gcon, &t5gcon); // comparator.assign_sr_module(&sr_module); // comparator.assign_eccpsas(&eccp1as, &eccp2as, &eccp3as); sr_module.srcon1.set_ValidBits(0xff); sr_module.setPins(&(*m_portb)[0], &(*m_porta)[2], &(*m_portc)[4]); vrefcon1.set_cmModule(&comparator); vrefcon1.setDACOUT(&(*m_porta)[2]); //1 usart16.initialize_16(this,&pir_set_def,&portc); add_sfr_register(&usart.spbrgh, 0xfb0,porv,"spbrgh"); add_sfr_register(&usart.baudcon, 0xfb8,porv,"baudcon"); usart.set_eusart(true); usart.set_TXpin(&(*m_portb)[7]); usart.set_RXpin(&(*m_portb)[5]); init_pir2(pir2, PIR2v4::TMR3IF); tmr3l.setIOpin(&(*m_portc)[0]); tmr2.ssp_module[0] = &ssp1; ssp1.initialize( 0, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP1 ); ssp1.mk_ssp_int(&pir1, PIR1v1::SSPIF); // SSP1IF ssp1.mk_bcl_int(pir2, PIR2v2::BCLIF); // BCL1IF } //------------------------------------------------------------------------ // // P18F26K22 // //------------------------------------------------------------------------ void P18F26K22::create_iopin_map() { package = new Package(28); if(!package) return; // Build the links between the I/O Ports and their tris registers. package->assign_pin( 1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); // %%%FIXME - is this O/C ? package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(8, 0); // Vss package->assign_pin(9, m_porta->addPin(new IO_bi_directional("porta7"),7)); // OSC1 package->assign_pin(10, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, 0); // Vss package->assign_pin(20, 0); // Vdd package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); tmr1l.setIOpin(&(*m_portc)[0]); ssp.initialize(&pir_set_def, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); //1portc.usart = &usart16; } P18F26K22::P18F26K22(const char *_name, const char *desc) : _16bit_processor(_name,desc), adcon0(this, "adcon0", "A2D control register 0"), adcon1(this, "adcon1", "A2D control register 1"), adcon2(this, "adcon2", "A2D control register 2"), vrefcon0(this, "vrefcon0", "Fixed Voltage Reference Control Register"), vrefcon1(this, "vrefcon1", "Voltage Reference Control Register 0", 0xed), vrefcon2(this, "vrefcon2", "Voltage Reference Control Register 1",0x1f, &vrefcon1), eccp1as(this, "eccp1as", "ECCP 1 Auto-Shutdown Control Register"), eccp2as(this, "eccp2as", "ECCP 2 Auto-Shutdown Control Register"), eccp3as(this, "eccp3as", "ECCP 3 Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM 1 Control Register"), pwm2con(this, "pwm2con", "Enhanced PWM 2 Control Register"), pwm3con(this, "pwm3con", "Enhanced PWM 3 Control Register"), osctune(this, "osctune", "OSC Tune"), t1gcon(this, "t1gcon", "Timer 1 Gate Control Register"), t3gcon(this, "t3gcon", "Timer 3 Gate Control Register"), tmr5l(this, "tmr5l", "TMR5 Low "), tmr5h(this, "tmr5h", "TMR5 High"), t5gcon(this, "t5gcon", "Timer 5 Gate Control Register"), t4con(this, "t4con", "TMR4 Control"), pr4(this, "pr4", "TMR4 Period Register"), tmr4(this, "tmr4", "TMR4 Register"), t6con(this, "t6con", "TMR6 Control"), pr6(this, "pr6", "TMR6 Period Register"), tmr6(this, "tmr6", "TMR6 Register"), pir3(this,"pir3","Peripheral Interrupt Register",0,0), pie3(this, "pie3", "Peripheral Interrupt Enable"), pir4(this,"pir4","Peripheral Interrupt Register 4",0,0), pie4(this, "pie4", "Peripheral Interrupt Enable 4"), pir5(this,"pir5","Peripheral Interrupt Register 5",0,0), pie5(this, "pie5", "Peripheral Interrupt Enable 5"), ipr3(this, "ipr3", "Interrupt Priorities 3"), ipr4(this, "ipr4", "Interrupt Priorities 4"), ipr5(this, "ipr5", "Interrupt Priorities 5"), ccp3con(this, "ccp3con", "Enhanced Capture Compare Control"), ccpr3l(this, "ccpr3l", "Capture Compare 3 Low"), ccpr3h(this, "ccpr3h", "Capture Compare 3 High"), ccp4con(this, "ccp4con", "Capture Compare Control"), ccpr4l(this, "ccpr4l", "Capture Compare 4 Low"), ccpr4h(this, "ccpr4h", "Capture Compare 4 High"), ccp5con(this, "ccp5con", "Capture Compare Control"), ccpr5l(this, "ccpr5l", "Capture Compare 5 Low"), ccpr5h(this, "ccpr5h", "Capture Compare 5 High"), usart2(this), comparator(this), pmd0(this, "pmd0", "Peripheral Module Disable 0"), pmd1(this, "pmd1", "Peripheral Module Disable 1"), pmd2(this, "pmd2", "Peripheral Module Disable 2"), ansela(this, "ansela", "PortA Analog Select Register"), anselb(this, "anselb", "PortB Analog Select Register"), anselc(this, "anselc", "PortC Analog Select Register"), slrcon(this, "slrcon", "Slew Rate Control Register", 0x1f), ccptmrs(this), pstr1con(this, "pstr1con", "PWM Steering Control Register 1"), pstr2con(this, "pstr2con", "PWM Steering Control Register 2"), pstr3con(this, "pstr3con", "PWM Steering Control Register 3"), sr_module(this), ssp1(this), ssp2(this), ctmu(this), hlvdcon(this, "hlvdcon", "High/Low-Voltage Detect Register"), osccon2(this, "osccon2", "Oscillator Control Register 2") { if(verbose) cout << "18F26K22 constructor, type = " << isa() << '\n'; delete pir2; pir2 = (PIR2v2 *)(new PIR2v4(this, "pir2" , "Peripheral Interrupt Register",0,0 )); wpub = new WPU(this, "wpub", "Weak Pull-Up Portb Register", m_portb, 0xff); iocb = new IOC(this, "iocb", "Interrupt-On-Change Portb Control Register", 0xf0); m_porte = new PicPortRegister(this,"porte","",8,0xFF); m_trise = new PicTrisRegister(this,"trise","", m_porte, false); m_late = new PicLatchRegister(this,"late","",m_porte); delete t1con; removeSymbol("tmr3_freq"); t1con = new T5CON(this, "t1con", "Timer 1 Control Register"); t3con2 = new T5CON(this, "t3con", "Timer 3 Control Register"); t5con = new T5CON(this, "t5con", "Timer 5 Control Register"); pir_set_def.set_pir3(&pir3); pir_set_def.set_pir4(&pir4); pir_set_def.set_pir5(&pir5); // By default TMR2 controls deals with all ccp units until // changed by ccptmrsx registers tmr2.add_ccp(&ccp3con); tmr2.add_ccp(&ccp4con); tmr2.add_ccp(&ccp5con); tmr2.m_txgcon = &t1gcon; t4con.tmr2 = &tmr4; tmr4.pr2 = &pr4; tmr4.t2con = &t4con; tmr4.setInterruptSource(new InterruptSource(&pir5, PIR5v1::TMR4IF)); tmr4.m_txgcon = &t3gcon; pr4.tmr2 = &tmr4; t6con.tmr2 = &tmr6; tmr6.pr2 = &pr6; tmr6.t2con = &t6con; tmr6.setInterruptSource(new InterruptSource(&pir5, PIR5v1::TMR6IF)); tmr6.m_txgcon = &t5gcon; pr6.tmr2 = &tmr6; ccptmrs.set_tmr246(&tmr2, &tmr4, &tmr6); ccptmrs.set_ccp(&ccp1con, &ccp2con, &ccp3con, &ccp4con, &ccp5con); comparator.cmxcon0[0] = new CMxCON0_V2(this, "cm1con0", " Comparator C1 Control Register 0", 0, &comparator); comparator.cmxcon0[1] = new CMxCON0_V2(this, "cm2con0", " Comparator C2 Control Register 0", 1, &comparator); comparator.cmxcon1[0] = new CM2CON1_V2(this, "cm2con1", " Comparator Control Register 1", &comparator); comparator.cmxcon1[1] = comparator.cmxcon1[0]; ctmu.ctmuconh = new CTMUCONH(this, "ctmuconh", "CTMU Control Register 0", &ctmu); ctmu.ctmuconl = new CTMUCONL(this, "ctmuconl", "CTMU Control Register 1", &ctmu); ctmu.ctmuicon = new CTMUICON(this, "ctmuicon", "CTMU Current Control Register", &ctmu); ctmu.ctmu_stim = new ctmu_stimulus(this,"ctmu_stim", 5.0, 1e12); adcon0.set_ctmu_stim(ctmu.ctmu_stim); ctmu.adcon1 = &adcon1; ctmu.cm2con1 = (CM2CON1_V2 *)comparator.cmxcon1[0]; ctmu.set_IOpins(&(*m_portb)[2],&(*m_portb)[3], &(*m_portc)[2]); hlvdcon.setIntSrc(new InterruptSource(pir2, PIR2v2::HLVDIF)); hlvdcon.set_hlvdin(&(*m_porta)[5]); } P18F26K22::~P18F26K22() { delete ctmu.ctmu_stim; delete_sfr_register(m_porte); delete_sfr_register(m_late); delete_sfr_register(m_trise); delete_sfr_register(t3con2); delete_sfr_register(t5con); delete_sfr_register(usart2.txreg); delete_sfr_register(usart2.rcreg); remove_sfr_register(comparator.cmxcon0[0]); remove_sfr_register(comparator.cmxcon0[1]); remove_sfr_register(comparator.cmxcon1[0]); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); remove_sfr_register(&osctune); remove_sfr_register(&tmr2); remove_sfr_register(&pr2); remove_sfr_register(&t2con); remove_sfr_register(&pwm1con); remove_sfr_register(&eccp1as); remove_sfr_register(&pwm2con); remove_sfr_register(&eccp2as); remove_sfr_register(&pwm3con); remove_sfr_register(&eccp3as); remove_sfr_register(&ccpr2h); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccp2con); remove_sfr_register(&ccpr3h); remove_sfr_register(&ccpr3l); remove_sfr_register(&ccp3con); remove_sfr_register(&ccpr4h); remove_sfr_register(&ccpr4l); remove_sfr_register(&ccp4con); remove_sfr_register(&ccpr5h); remove_sfr_register(&ccpr5l); remove_sfr_register(&ccp5con); remove_sfr_register(osccon); remove_sfr_register(&ipr3); remove_sfr_register(&pir3); remove_sfr_register(&pie3); remove_sfr_register(&pie4); remove_sfr_register(&pir4); remove_sfr_register(&ipr4); remove_sfr_register(&pie5); remove_sfr_register(&pir5); remove_sfr_register(&ipr5); remove_sfr_register(&tmr5h); remove_sfr_register(&tmr5l); remove_sfr_register(&t1gcon); remove_sfr_register(&t3gcon); remove_sfr_register(&t5gcon); remove_sfr_register(&pmd0); remove_sfr_register(&pmd1); remove_sfr_register(&pmd2); remove_sfr_register(&ansela); remove_sfr_register(&anselb); remove_sfr_register(&anselc); delete_sfr_register(wpub); delete_sfr_register(iocb); remove_sfr_register(&slrcon); remove_sfr_register(&ccptmrs.ccptmrs1); remove_sfr_register(&ccptmrs.ccptmrs0); remove_sfr_register(&tmr6); remove_sfr_register(&pr6); remove_sfr_register(&t6con); remove_sfr_register(&tmr4); remove_sfr_register(&pr4); remove_sfr_register(&t4con); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adcon2); remove_sfr_register(&vrefcon0); remove_sfr_register(&vrefcon1); remove_sfr_register(&vrefcon2); remove_sfr_register(&sr_module.srcon0); remove_sfr_register(&sr_module.srcon1); remove_sfr_register(&pstr1con); remove_sfr_register(&pstr2con); remove_sfr_register(&pstr3con); remove_sfr_register(&usart2.rcsta); remove_sfr_register(&usart2.txsta); remove_sfr_register(&usart2.spbrg); remove_sfr_register(&usart2.spbrgh); remove_sfr_register(&usart2.baudcon); remove_sfr_register(&ssp1.sspbuf); remove_sfr_register(&ssp1.sspadd); remove_sfr_register(ssp1.sspmsk); remove_sfr_register(&ssp1.sspstat); remove_sfr_register(&ssp1.sspcon); remove_sfr_register(&ssp1.sspcon2); remove_sfr_register(&ssp1.ssp1con3); remove_sfr_register(&ssp2.sspbuf); remove_sfr_register(&ssp2.sspadd); remove_sfr_register(ssp2.sspmsk); remove_sfr_register(&ssp2.sspstat); remove_sfr_register(&ssp2.sspcon); remove_sfr_register(&ssp2.sspcon2); remove_sfr_register(&ssp2.ssp1con3); delete_sfr_register(ctmu.ctmuconh); delete_sfr_register(ctmu.ctmuconl); delete_sfr_register(ctmu.ctmuicon); remove_sfr_register(&hlvdcon); remove_sfr_register(&osccon2); delete_file_registers(0xf3b, 0xf3c, false); delete_file_registers(0xf83, 0xf83, false); delete_file_registers(0xf85, 0xf88, false); delete_file_registers(0xf8c, 0xf91, false); delete_file_registers(0xf95, 0xf95, false); delete_file_registers(0xf97, 0xf9a, false); //delete_file_registers(0xf9d, 0xf9e, false); delete_file_registers(0xfb5, 0xfb5, false); delete_file_registers(0xfd4, 0xfd4, false); } void P18F26K22::create() { RegisterValue porv(0,0); RegisterValue porvh(0xff,0); if(verbose) cout << "P18F26K22::create\n"; tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); create_iopin_map(); _16bit_processor::create(); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&lvdcon); set_osc_pin_Number(0, 9, &(*m_porta)[7]); set_osc_pin_Number(1,10, &(*m_porta)[6]); m_configMemory->addConfigWord(CONFIG1L-CONFIG1L,new ConfigWord("CONFIG1L", 0x00, "Configuration Register 1 low", this, CONFIG1L)); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0x25)); m_configMemory->addConfigWord(CONFIG3H-CONFIG1L,new Config3H(this, CONFIG3H, 0xbf)); // add_sfr_register(osccon, 0xfd3, RegisterValue(0x30,0), "osccon"); add_sfr_register(&osccon2, 0xfd2, RegisterValue(0x04,0), "osccon2"); ((OSCCON_HS *)osccon)->osccon2 = &osccon2; osccon->write_mask = 0xf3; osccon->por_value = RegisterValue(0x30,0); add_sfr_register(&t1gcon, 0xfcc, porv, "t1gcon"); add_sfr_register(&ssp1.ssp1con3, 0xfcb, RegisterValue(0,0),"ssp1con3"); add_sfr_register(ssp1.sspmsk, 0xfca, RegisterValue(0xff,0),"ssp1msk"); add_sfr_register(&ssp1.sspbuf, 0xfc9, RegisterValue(0,0),"ssp1buf"); add_sfr_register(&ssp1.sspadd, 0xfc8, RegisterValue(0,0),"ssp1add"); add_sfr_register(&ssp1.sspstat, 0xfc7, RegisterValue(0,0),"ssp1stat"); add_sfr_register(&ssp1.sspcon, 0xfc6, RegisterValue(0,0),"ssp1con"); add_sfr_register(&ssp1.sspcon2, 0xfc5, RegisterValue(0,0),"ssp1con2"); add_sfr_register(&adcon0, 0xfc2, porv, "adcon0"); add_sfr_register(&adcon1, 0xfc1, porv, "adcon1"); add_sfr_register(&adcon2, 0xfc0, porv, "adcon2"); add_sfr_register(&tmr2, 0xfbc, porv, "tmr2"); add_sfr_register(&pr2, 0xfbb, RegisterValue(0xff,0), "pr2"); add_sfr_register(&t2con, 0xfba, porv, "t2con"); add_sfr_register(&pstr1con, 0xfb9, RegisterValue(0x01,0)); add_sfr_register(&pwm1con, 0xfb7, porv); add_sfr_register(&eccp1as, 0xfb6, porv); add_sfr_register(&t3gcon, 0xfb4, porv); add_sfr_register(&ipr3, 0xfa5, porv, "ipr3"); add_sfr_register(&pir3, 0xfa4, porv, "pir3"); add_sfr_register(&pie3, 0xfa3, porv, "pie3"); add_sfr_register(&hlvdcon, 0xf9c, porv, "hlvdcon"); add_sfr_register(&ipr5, 0xf7f, porv, "ipr5"); add_sfr_register(&pir5, 0xf7e, porv, "pir5"); add_sfr_register(&pie5, 0xf7d, porv, "pie5"); add_sfr_register(&ipr4, 0xf7c, porv, "ipr4"); add_sfr_register(&pir4, 0xf7b, porv, "pir4"); add_sfr_register(&pie4, 0xf7a, porv, "pie4"); add_sfr_register(comparator.cmxcon0[0], 0xf79, RegisterValue(0x08,0), "cm1con0"); add_sfr_register(comparator.cmxcon0[1], 0xf78, RegisterValue(0x08,0), "cm2con0"); add_sfr_register(comparator.cmxcon1[0], 0xf77, porv, "cm2con1"); add_sfr_register(&ssp2.sspbuf, 0xf6f, RegisterValue(0,0),"ssp2buf"); add_sfr_register(&ssp2.sspadd, 0xf6e, RegisterValue(0,0),"ssp2add"); add_sfr_register(&ssp2.sspstat, 0xf6d, RegisterValue(0,0),"ssp2stat"); add_sfr_register(&ssp2.sspcon, 0xf6c, RegisterValue(0,0),"ssp2con"); add_sfr_register(&ssp2.sspcon2, 0xf6b, RegisterValue(0,0),"ssp2con2"); add_sfr_register(ssp2.sspmsk, 0xf6a, RegisterValue(0xff,0),"ssp2msk"); add_sfr_register(&ssp2.ssp1con3, 0xf69, RegisterValue(0,0),"ssp2con3"); add_sfr_register(&ccpr2h, 0xf68, porv, "ccpr2h"); add_sfr_register(&ccpr2l, 0xf67, porv, "ccpr2l"); add_sfr_register(&ccp2con, 0xf66, porv, "ccp2con"); add_sfr_register(&pwm2con, 0xf65, porv); add_sfr_register(&eccp2as, 0xf64, porv); add_sfr_register(&pstr2con, 0xf63, RegisterValue(0x01,0)); add_sfr_register(iocb, 0xf62, porvh); add_sfr_register(wpub, 0xf61, porvh); add_sfr_register(&slrcon, 0xf60, porvh); add_sfr_register(&ccpr3h, 0xf5f, porv); add_sfr_register(&ccpr3l, 0xf5e, porv); add_sfr_register(&ccp3con, 0xf5d, porv); add_sfr_register(&pwm3con, 0xf5c, porv); add_sfr_register(&eccp3as, 0xf5b, porv); add_sfr_register(&pstr3con, 0xf5a, RegisterValue(0x01,0)); add_sfr_register(&ccpr4h, 0xf59, porv); add_sfr_register(&ccpr4l, 0xf58, porv); add_sfr_register(&ccp4con, 0xf57, porv); add_sfr_register(&ccpr5h, 0xf56, porv); add_sfr_register(&ccpr5l, 0xf55, porv); add_sfr_register(&ccp5con, 0xf54, porv); add_sfr_register(&tmr4, 0xf53, porv); add_sfr_register(&pr4, 0xf52, porvh); add_sfr_register(&t4con, 0xf51, porv); add_sfr_register(&tmr5h, 0xf50, porv, "tmr5h"); add_sfr_register(&tmr5l, 0xf4f, porv, "tmr5l"); add_sfr_register(t5con, 0xf4e, porv); add_sfr_register(&t5gcon, 0xf4d, porv); add_sfr_register(&tmr6, 0xf4c, porv); add_sfr_register(&pr6, 0xf4b, porvh); add_sfr_register(&t6con, 0xf4a, porv); add_sfr_register(&ccptmrs.ccptmrs0, 0xf49, porv); add_sfr_register(&ccptmrs.ccptmrs1, 0xf48, porv); add_sfr_register(&sr_module.srcon0, 0xf47, porv); add_sfr_register(&sr_module.srcon1, 0xf46, porv); add_sfr_register(ctmu.ctmuconh, 0xf45, porv, "ctmuconh"); add_sfr_register(ctmu.ctmuconl, 0xf44, porv, "ctmuconl"); add_sfr_register(ctmu.ctmuicon, 0xf43, porv, "ctmuicon"); add_sfr_register(&vrefcon0, 0xf42, RegisterValue(0x10,0)); add_sfr_register(&vrefcon1, 0xf41, porv); add_sfr_register(&vrefcon2, 0xf40, porv); add_sfr_register(&pmd0, 0xf3f, porv); add_sfr_register(&pmd1, 0xf3e, porv); add_sfr_register(&pmd2, 0xf3d, porv); add_sfr_register(&anselc, 0xf3a, RegisterValue(0xfc,0)); add_sfr_register(&anselb, 0xf39, RegisterValue(0x3f,0)); add_sfr_register(&ansela, 0xf38, RegisterValue(0x2f,0)); add_sfr_register(new RegZero(this, "ZeroFD4", "Always read as zero"), 0xFD4, porv); add_sfr_register(new RegZero(this, "ZeroFB5", "Always read as zero"), 0xFB5, porv); add_sfr_register(new RegZero(this, "ZeroF9A", "Always read as zero"), 0xF9A, porv); add_sfr_register(new RegZero(this, "ZeroF99", "Always read as zero"), 0xF99, porv); add_sfr_register(new RegZero(this, "ZeroF98", "Always read as zero"), 0xF98, porv); add_sfr_register(new RegZero(this, "ZeroF97", "Always read as zero"), 0xF97, porv); add_sfr_register(new RegZero(this, "trisd", "Always read as zero"), 0xF95, porv); add_sfr_register(new RegZero(this, "ZeroF91", "Always read as zero"), 0xF91, porv); add_sfr_register(new RegZero(this, "ZeroF90", "Always read as zero"), 0xF90, porv); add_sfr_register(new RegZero(this, "ZeroF8F", "Always read as zero"), 0xF8F, porv); add_sfr_register(new RegZero(this, "ZeroF8E", "Always read as zero"), 0xF8E, porv); add_sfr_register(new RegZero(this, "late", "Always read as zero"), 0xF8D, porv); add_sfr_register(new RegZero(this, "latd", "Always read as zero"), 0xF8C, porv); add_sfr_register(new RegZero(this, "ZeroF88", "Always read as zero"), 0xF88, porv); add_sfr_register(new RegZero(this, "ZeroF87", "Always read as zero"), 0xF87, porv); add_sfr_register(new RegZero(this, "ZeroF86", "Always read as zero"), 0xF86, porv); add_sfr_register(new RegZero(this, "ZeroF85", "Always read as zero"), 0xF85, porv); add_sfr_register(new RegZero(this, "portd", "Always read as zero"), 0xF83, porv); add_sfr_register(new RegZero(this, "ansele", "Always read as zero"), 0xF3C, porv); add_sfr_register(new RegZero(this, "anseld", "Always read as zero"), 0xF3B, porv); eccp1as.setBitMask(0xfc); eccp2as.setBitMask(0xfc); eccp3as.setBitMask(0xfc); // ECCP shutdown trigger eccp1as.setIOpin(0, 0, &(*m_portb)[0]); eccp2as.setIOpin(0, 0, &(*m_portb)[0]); eccp3as.setIOpin(0, 0, &(*m_portb)[0]); eccp1as.link_registers(&pwm1con, &ccp1con); eccp2as.link_registers(&pwm2con, &ccp2con); eccp3as.link_registers(&pwm3con, &ccp3con); //RRR comparator.cmcon.set_eccpas(&eccp1as); ccp1con.setBitMask(0xff); ccp2con.setBitMask(0xff); ccp3con.setBitMask(0xff); ccp4con.setBitMask(0x3f); ccp5con.setBitMask(0x3f); ccp1con.setCrosslinks(&ccpr1l, &pir1, PIR1v2::CCP1IF, &tmr2, &eccp1as); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v2::CCP2IF, &tmr2, &eccp2as); ccp3con.setCrosslinks(&ccpr3l, &pir4, PIR4v1::CCP3IF, &tmr2, &eccp3as); ccp1con.pwm1con = &pwm1con; ccp2con.pwm1con = &pwm2con; ccp3con.pwm1con = &pwm3con; ccp1con.pstrcon = &pstr1con; ccp2con.pstrcon = &pstr2con; ccp3con.pstrcon = &pstr3con; ccp1con.setIOpin(&((*m_portc)[2]), &((*m_portb)[2]), &((*m_portb)[1]), &((*m_portb)[4])); pwm1con.setBitMask(0x80); //ccp3con.setCrosslinks(&ccpr3l, &pir3, PIR3v2::CCP3IF, &tmr6, &eccp3as); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setAdcon2(&adcon2); adcon0.setIntcon(&intcon); adcon0.setPir(&pir1); adcon0.setChannel_Mask(0x1f); // upto 32 channels adcon0.setA2DBits(10); adcon1.setNumberOfChannels(20); adcon1.setVrefHiChannel(3); adcon1.setVrefLoChannel(2); adcon1.setAdcon0(&adcon0); // VCFG0, VCFG1 in adcon0 vrefcon0.set_adcon1(&adcon1); vrefcon1.set_adcon1(&adcon1); vrefcon0.set_daccon0(&vrefcon1); ansela.setIOPin(0, &(*m_porta)[0], &adcon1); ansela.setIOPin(1, &(*m_porta)[1], &adcon1); ansela.setIOPin(2, &(*m_porta)[2], &adcon1); ansela.setIOPin(3, &(*m_porta)[3], &adcon1); ansela.setIOPin(4, &(*m_porta)[5], &adcon1); anselb.setIOPin(8, &(*m_portb)[2], &adcon1); anselb.setIOPin(9, &(*m_portb)[3], &adcon1); anselb.setIOPin(10, &(*m_portb)[1], &adcon1); anselb.setIOPin(11, &(*m_portb)[4], &adcon1); anselb.setIOPin(12, &(*m_portb)[0], &adcon1); anselb.setIOPin(13, &(*m_portb)[5], &adcon1); anselc.setIOPin(14, &(*m_portc)[2], &adcon1); anselc.setIOPin(15, &(*m_portc)[3], &adcon1); anselc.setIOPin(16, &(*m_portc)[4], &adcon1); anselc.setIOPin(17, &(*m_portc)[5], &adcon1); anselc.setIOPin(18, &(*m_portc)[6], &adcon1); anselc.setIOPin(19, &(*m_portc)[7], &adcon1); osccon->write_mask = 0xf3; } void P18F26K22::set_config3h(gint64 value) { PinModule *p2b; (value & MCLRE) ? assignMCLRPin(1) : unassignMCLRPin(); if ( value & P2BMX) p2b = &((*m_portb)[5]); else p2b = &((*m_portc)[0]); if ( value & CCP3MX ) ccp3con.setIOpin(&((*m_portb)[5]), &((*m_portc)[5])); else ccp3con.setIOpin(&((*m_portc)[6]), &((*m_portc)[5])); if ( value & CCP2MX ) ccp2con.setIOpin(&((*m_portc)[1]), p2b); else ccp2con.setIOpin(&((*m_portb)[3]), p2b); if ( value & PBADEN ) anselb.por_value=RegisterValue( 0x3f,0); else anselb.por_value=RegisterValue(0,0); } void P18F26K22::osc_mode(unsigned int value) { unsigned int mode = value & (FOSC3 | FOSC2 | FOSC1 | FOSC0); unsigned int pin_Number0 = get_osc_pin_Number(0); unsigned int pin_Number1 = get_osc_pin_Number(1); set_pplx4_osc(value & PLLCFG); if (mode == 0x8 || mode == 0x9) { if (osccon) osccon->set_config_irc(true); set_int_osc(true); } else { set_int_osc(false); if (osccon) osccon->set_config_irc(false); } if (osccon) { osccon->set_config_ieso(value & IESO); osccon->set_config_xosc(mode < 4); } switch(mode) { case 0xf: // external RC CLKOUT RA6 case 0xe: case 0xc: case 0xa: case 0x9: case 0x6: case 0x4: if (pin_Number1 < 253) // CLKO = OSC2 { cout << "CLKO not simulated\n"; set_clk_pin(pin_Number1, get_osc_PinMonitor(1) , "CLKO", false, m_porta, m_trisa, m_lata); } break; } if (pin_Number0 < 253) { if (mode != 0x9 && mode != 0x8 ) // not internal OSC, set OSC1 { set_clk_pin(pin_Number0, get_osc_PinMonitor(0) , "OSC1", true, m_porta, m_trisa, m_lata); } else { clr_clk_pin(pin_Number0, get_osc_PinMonitor(0), m_porta, m_trisa, m_lata); } } if (pin_Number1 < 253) { if (mode < 4) { set_clk_pin(pin_Number1, get_osc_PinMonitor(1) , "OSC2", true, m_porta, m_trisa, m_lata); } else { clr_clk_pin(pin_Number1, get_osc_PinMonitor(1), m_porta, m_trisa, m_lata); } } } void P18F26K22::update_vdd() { hlvdcon.check_hlvd(); Processor::update_vdd(); } Processor * P18F26K22::construct(const char *name) { P18F26K22 *p = new P18F26K22(name); if(verbose) cout << " 18F26K22 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F26K22 construct completed\n"; return p; } void P18F26K22::create_sfr_map() { if(verbose) cout << "create_sfr_map P18F26K22\n"; _16bit_processor::create_sfr_map(); RegisterValue porv(0,0); add_sfr_register(m_porte, 0xf84,porv); add_sfr_register(m_trise, 0xf96,RegisterValue(0x07,0)); remove_sfr_register(t3con); add_sfr_register(t3con2, 0xfb1,porv); add_sfr_register(&osctune, 0xf9b,porv); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); osccon2.set_osccon(osccon); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[4], &(*m_porta)[5]); comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1], &(*m_portb)[3],&(*m_portb)[2]); comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[3], &(*m_porta)[2]); comparator.cmxcon1[0]->setBitMask(0x3f); comparator.cmxcon0[0]->setBitMask(0xbf); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, PIR2v2::C1IF)); comparator.cmxcon0[1]->setBitMask(0xbf); comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, PIR2v2::C2IF)); vrefcon0.set_cmModule(&comparator); comparator.assign_t1gcon(&t1gcon, &t3gcon, &t5gcon); comparator.assign_sr_module(&sr_module); comparator.assign_eccpsas(&eccp1as, &eccp2as, &eccp3as); sr_module.srcon1.set_ValidBits(0xff); sr_module.setPins(&(*m_portb)[0], &(*m_porta)[4], &(*m_porta)[5]); vrefcon1.set_cmModule(&comparator); vrefcon1.setDACOUT(&(*m_porta)[2]); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v2::CCP2IF, &tmr2); ccp2con.setIOpin(&((*m_portc)[1])); // May be altered by Config3H_2x21::set ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; ccp3con.setCrosslinks(&ccpr3l, &pir3, PIR3v1::CCP3IF, &tmr2); ccpr3l.ccprh = &ccpr3h; ccpr3l.tmrl = &tmr1l; ccpr3h.ccprl = &ccpr3l; ccp4con.setCrosslinks(&ccpr4l, &pir3, PIR3v1::CCP4IF, &tmr2); ccp4con.setIOpin(&((*m_portb)[0])); ccpr4l.ccprh = &ccpr4h; ccpr4l.tmrl = &tmr1l; ccpr4h.ccprl = &ccpr4l; ccp5con.setIOpin(&((*m_porta)[4])); ccp5con.setCrosslinks(&ccpr5l, &pir3, PIR3v1::CCP5IF, &tmr2); ccpr5l.ccprh = &ccpr5h; ccpr5l.tmrl = &tmr1l; ccpr5h.ccprl = &ccpr5l; //1 usart16.initialize_16(this,&pir_set_def,&portc); usart.txsta.new_name("txsta1"); usart.txreg->new_name("txreg1"); usart.rcsta.new_name("rcsta1"); usart.rcreg->new_name("rcreg1"); usart.mk_rcif_int(&pir1, PIR1v2::RCIF); usart.mk_txif_int(&pir1, PIR1v2::TXIF); add_sfr_register(&usart.spbrgh, 0xfb0,porv,"spbrgh1"); add_sfr_register(&usart.baudcon, 0xfb8,porv,"baudcon1"); usart.set_eusart(true); init_pir2(pir2, PIR2v4::TMR3IF); tmr3l.setIOpin(&(*m_portc)[0]); pir3.set_intcon(&intcon); pir3.set_pie(&pie3); pir3.set_ipr(&ipr3); pie3.setPir(&pir3); pir4.set_intcon(&intcon); pir4.set_pie(&pie4); pir4.set_ipr(&ipr4); pie4.setPir(&pir4); pir5.set_intcon(&intcon); pir5.set_pie(&pie5); pir5.set_ipr(&ipr5); pie5.setPir(&pir5); ((T5CON *)t1con)->t1gcon = &t1gcon; t1gcon.setInterruptSource(new InterruptSource(&pir3, PIR3v3::TMR1GIF)); t3gcon.setInterruptSource(new InterruptSource(&pir3, PIR3v3::TMR3GIF)); t5gcon.setInterruptSource(new InterruptSource(&pir3, PIR3v3::TMR5GIF)); t1gcon.set_tmrl(&tmr1l); t3gcon.set_tmrl(&tmr3l); t5gcon.set_tmrl(&tmr5l); t1gcon.setGatepin(&(*m_portb)[5]); t3gcon.setGatepin(&(*m_portc)[0]); t5gcon.setGatepin(&(*m_portb)[4]); t3con2->tmrl = &tmr3l; t5con->tmrl = &tmr5l; ((T5CON *)t3con2)->t1gcon = &t3gcon; ((T5CON *)t5con)->t1gcon = &t5gcon; tmr5l.setInterruptSource(new InterruptSource(&pir5, PIR5v1::TMR5IF)); tmr5l.tmrh = &tmr5h; tmr5h.tmrl = &tmr5l; tmr3l.t1con = t3con2; tmr5l.t1con = t5con; //cout << "Create second USART\n"; usart2.initialize(&pir3,&(*m_portb)[6], &(*m_portb)[7], new _TXREG(this,"txreg2", "USART Transmit Register", &usart2), new _RCREG(this,"rcreg2", "USART Receiver Register", &usart2)); add_sfr_register(&usart2.baudcon, 0xf70, porv, "baudcon2"); add_sfr_register(&usart2.rcsta, 0xf71, porv, "rcsta2"); add_sfr_register(&usart2.txsta, 0xf72, RegisterValue(0x02,0), "txsta2"); add_sfr_register(usart2.txreg, 0xf73, porv, "txreg2"); add_sfr_register(usart2.rcreg, 0xf74, porv, "rcreg2"); add_sfr_register(&usart2.spbrg, 0xf75, porv, "spbrg2"); add_sfr_register(&usart2.spbrgh, 0xf76, porv, "spbrgh2"); usart2.mk_rcif_int(&pir3, PIR3v1::RCIF); usart2.mk_txif_int(&pir3, PIR3v1::TXIF); tmr2.ssp_module[0] = &ssp1; tmr2.ssp_module[1] = &ssp2; ssp1.initialize( 0, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP1 ); ssp1.mk_ssp_int(&pir1, PIR1v1::SSPIF); // SSP1IF ssp1.mk_bcl_int(pir2, PIR2v2::BCLIF); // BCL1IF ssp2.initialize( 0, // PIR &(*m_portb)[1], // SCK &(*m_portb)[0], // SS &(*m_portb)[3], // SDO &(*m_portb)[2], // SDI m_trisb, // i2c tris port SSP_TYPE_MSSP1 ); ssp2.mk_ssp_int(&pir3, PIR3v3::SSP2IF); // SSP2IF ssp2.mk_bcl_int(&pir3, PIR3v3::BCL2IF); // BCL2IF } gpsim-0.30.0/src/modules.h0000664000076400007640000001576613063451152012273 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* modules.h The base class for modules is defined here. Include this file into yours for creating custom modules. */ #ifndef __MODULES_H__ #define __MODULES_H__ #include #include #include #include #include #include #include #include "gpsim_object.h" #include "gpsim_classes.h" #include "symbol.h" class Module; class Module_Types; class ModuleInterface; class Processor; class IOPIN; class XrefObject; class Value; class Package; class ICommandHandler; typedef Module * (*Module_FPTR)(); typedef Module_Types * (*Module_Types_FPTR)(); enum SIMULATION_MODES { eSM_INITIAL, eSM_STOPPED, eSM_RUNNING, eSM_SLEEPING, eSM_SINGLE_STEPPING, eSM_STEPPING_OVER, eSM_RUNNING_OVER }; //------------------------------------------------------------------------ // // ModuleLibrary // // A module library is an OS dependent dynamically loadable library of // gpsim Modules. A Module (see below) can range from anything as simple // as a resistor to as complicated as microcontroller. However, the interface // to loading libraries and instantiating modules is kept simple: class ModuleLibrary { public: static int LoadFile(string &sLibraryName); static int InstantiateObject(string &sObjectName, string &sInstantiatedName); static void ListLoadableModules(); }; /* * interface is a Module class member variable in gpsim, * in WIN32 Platform SDK it is a macro, defined in BaseTypes.h * the WIN32 Platform SDK definition should be undefined */ #ifdef interface #undef interface #endif //------------------------------------------------------------------------ // /// Module - Base class for all gpsim behavior models. class Module : public gpsimObject { public: Package *package; // A package for the module ModuleInterface *interface; // An interface to the module. SIMULATION_MODES simulation_mode; // describes the simulation state for this module XrefObject *xref; // Updated when the module changes /// I/O pin specific virtual int get_pin_count(); virtual string &get_pin_name(unsigned int pin_number); virtual int get_pin_state(unsigned int pin_number); virtual IOPIN *get_pin(unsigned int pin_number); virtual void assign_pin(unsigned int pin_number, IOPIN *pin); virtual void create_pkg(unsigned int number_of_pins); virtual double get_Vdd() { return Vdd; } virtual void set_Vdd(double v) { Vdd = v; } /// Symbols /// Each module has its own symbol table. The global symbol /// table can access this table too. SymbolTable_t & getSymbolTable() { return mSymbolTable;} int addSymbol(gpsimObject *, string *AliasedName=0); gpsimObject *findSymbol(const string &); int removeSymbol(gpsimObject *); int removeSymbol(const string &); int deleteSymbol(const string &); int deleteSymbol(gpsimObject *); /// Registers - mostly processors, but can apply to complex modules virtual unsigned int register_mask () const { return 0xff;} virtual unsigned int register_size () const { return 1;} /// Reset virtual void reset(RESET_TYPE r); /// Version virtual char *get_version() { return version;} /// gui /// The simulation engine doesn't know anything about the gui. /// However, the set_widget and get_widget provide a mechanism /// for the gui to associate a pointer with a module. virtual void set_widget(void * a_widget) {widget = a_widget;} virtual void *get_widget() {return widget;} /// cli /// Modules can have gpsim CLI scripts associated with them. /// add_command will add a single CLI command to a script void add_command(string &script_name, string &command); /// run_script will pass a script to the gpsim CLI. This script /// executes immediately (i.e. it'll execute before any commands /// that may already be queued). void run_script(string &script_name); const char *type(void) { return module_type.c_str(); } void set_module_type(string type) { module_type = type; } Module(const char *_name=0, const char *desc=0); virtual ~Module(); /// Functions to support actual hardware virtual bool isHardwareOnline() { return true; } private: void *widget; // GtkWidget * that is put in the breadboard. string module_type; // Storage for scripts specifically associated with this module. class ModuleScript { public: explicit ModuleScript(std::string &name_); ~ModuleScript(); void add_command(string &command); void run(ICommandHandler *); void concatenate(ModuleScript *); private: string name; list m_commands; }; map m_scripts; protected: double Vdd; // Derived modules should assign more reasonable values for this. char *version; SymbolTable_t mSymbolTable; }; class Module_Types { public: const char *names[2]; Module * (*module_constructor) (const char *module_name); }; #ifndef SWIG const int Module_Types_Name_Count = sizeof(((Module_Types*)NULL)->names) / sizeof(char*); /** * CFileSearchPath * Implemented in os_dependent.cc */ class CFileSearchPath : public list { public: CFileSearchPath() {} void AddPathFromFilePath(string &sFolder, string &sFile); const char * Find(string &path); }; /***************************************************************************** * * Helper functions * *****************************************************************************/ void GetFileName(string &sPath, string &sName); void GetFileNameBase(string &sPath, string &sName); void FixupLibraryName(string &sPath); void * load_library(const char *library_name, const char **pszError); void * get_library_export(const char *name, void *library_handle, const char **pszError); void free_library(void *handle); void free_error_message(const char * pszError); #endif class DynamicModuleLibraryInfo { public: DynamicModuleLibraryInfo(string &sCanonicalName, string &sUserSuppliedName, void *pHandle); inline string user_name(void) { return m_sCanonicalName; } inline Module_Types_FPTR mod_list(void) { return get_mod_list; } protected: string m_sCanonicalName; string m_sUserSuppliedName; void *m_pHandle; Module_Types * (*get_mod_list)(void); }; typedef map ModuleLibraries_t; #endif // __MODULES_H__ gpsim-0.30.0/src/p1xf1xxx.cc0000664000076400007640000020445113111717006012454 00000000000000/* Copyright (C) 2013,2014 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p1xf1xxx // // This file supports: // PIC12F1822 // PIC16F1823 // PIC16F1788 // //Note: All these processors have extended 14bit instructions #include #include #include #include "../config.h" #include "symbol.h" #include "stimuli.h" #include "eeprom.h" #include "p1xf1xxx.h" #include "pic-ioports.h" #include "packages.h" //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif APFCON::APFCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), m_usart(0), m_ssp(0), m_t1gcon(0) { int j; mValidBits=0xef; for(j =0; j <8; j++) { m_bitPin[0][j] = NULL; m_bitPin[1][j] = NULL; } } void APFCON::put(unsigned int new_value) { unsigned int old_value = value.get(); unsigned int diff = (new_value ^ old_value) & mValidBits; trace.raw(write_trace.get() | value.get()); new_value &= mValidBits; value.put(new_value); for(int i = 0; i < 8; i++) { unsigned int bit = 1<setIOPin1(m_bitPin[(new_value & bit)== bit][i]); break; case 1: assert(m_ccpcon); m_ccpcon->setIOPin2(m_bitPin[(new_value & bit)== bit][i]); break; case 2: assert(m_usart); m_usart->set_TXpin(m_bitPin[(new_value & bit)== bit][i]); break; case 3: assert(m_t1gcon); m_t1gcon->setGatepin(m_bitPin[(new_value & bit)== bit][i]); break; case 4: // not used break; case 5: assert(m_ssp); m_ssp->set_ssPin(m_bitPin[(new_value & bit)== bit][i]); break; case 6: assert(m_ssp); m_ssp->set_sdoPin(m_bitPin[(new_value & bit)== bit][i]); break; case 7: assert(m_usart); m_usart->set_RXpin(m_bitPin[(new_value & bit)== bit][i]); break; } } } } // Does not match any of 3 versions in pir.h, pir.cc // If required by any other porcessors should be moved there // class PIR1v1822 : public PIR1v2 { public: // rest of bits defined in PIR1v2 enum { TMR1GIF = 1<<7 }; //------------------------------------------------------------------------ PIR1v1822(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR1v2(pCpu,pName,pDesc,_intcon, _pie) { valid_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | TXIF | RCIF | ADIF | TMR1GIF; writable_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | ADIF | TMR1GIF; } virtual void set_tmr1gif() { trace.raw(write_trace.get() | value.get()); value.put(value.get() | TMR1GIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } }; class PIR2v1822 : public PIR { public: enum { CCP2IF = 1<<0, // for 16f178[89] C3IF = 1<<1, // for 16f178[89] C4IF = 1<<2, // for 16f178[89] BCLIF = 1<<3, EEIF = 1<<4, C1IF = 1<<5, C2IF = 1<<6, // not 12f1822 OSFIF = 1<<7 }; //------------------------------------------------------------------------ PIR2v1822(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { valid_bits = BCLIF | EEIF | C1IF | OSFIF; writable_bits = BCLIF | EEIF | C1IF | OSFIF; } void set_ccp2if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CCP2IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void set_c3if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C3IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void set_c4if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C4IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void set_bclif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | BCLIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } virtual void set_eeif() { trace.raw(write_trace.get() | value.get()); value.put(value.get() | EEIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void set_c1if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C1IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void set_c2if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | C2IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } void set_osfif(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | OSFIF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } }; class PIR3v178x : public PIR { public: enum { CCP3IF = 1<<4 }; PIR3v178x(Processor *pCpu, const char *pName, const char *pDesc,INTCON *_intcon, PIE *_pie) : PIR(pCpu,pName,pDesc,_intcon, _pie,0) { writable_bits = valid_bits = CCP3IF; } void set_ccp3if(void) { trace.raw(write_trace.get() | value.get()); value.put(value.get() | CCP3IF); if( value.get() & pie->value.get() ) setPeripheralInterrupt(); } }; //======================================================================== P12F1822::P12F1822(const char *_name, const char *desc) : _14bit_e_processor(_name,desc), comparator(this), pie1(this,"PIE1", "Peripheral Interrupt Enable"), pie2(this,"PIE2", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), t1con_g(this, "t1con", "TMR1 Control Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), fvrcon(this, "fvrcon", "Voltage reference control register", 0xbf, 0x40), borcon(this, "borcon", "Brown-out reset control register"), ansela(this, "ansela", "Analog Select"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low"), osccon(0), osctune(this, "osctune", "Oscillator Tunning Register"), oscstat(this, "oscstat", "Oscillator Status Register"), wdtcon(this, "wdtcon", "Watch dog timer control", 0x3f), usart(this), ssp(this), apfcon(this, "apfcon", "Alternate Pin Function Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register"), ccp1as(this, "ccp1as", "CCP1 Auto-Shutdown Control Register"), pstr1con(this, "pstr1con", "Pulse Sterring Control Register"), cpscon0(this, "cpscon0", " Capacitive Sensing Control Register 0"), cpscon1(this, "cpscon1", " Capacitive Sensing Control Register 1"), sr_module(this), dsm_module(this) { m_iocaf = new IOCxF(this, "iocaf", "Interrupt-On-Change flag Register", 0x3f); m_iocap = new IOC(this, "iocap", "Interrupt-On-Change positive edge", 0x3f); m_iocan = new IOC(this, "iocan", "Interrupt-On-Change negative edge", 0x3f); m_porta = new PicPortIOCRegister(this,"porta","", intcon, m_iocap, m_iocan, m_iocaf, 8,0x3f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false, 0x37); m_lata = new PicLatchRegister(this,"lata","",m_porta, 0x37); m_daccon0 = new DACCON0(this, "daccon0", "DAC Voltage reference register 0", 0xec, 32); m_daccon1 = new DACCON1(this, "daccon1", "DAC Voltage reference register 1", 0x1f, m_daccon0); m_cpu_temp = new CPU_Temp("cpu_temperature", 30., "CPU die temperature"); tmr0.set_cpu(this, m_porta, 4, &option_reg); tmr0.start(0); tmr0.set_t1gcon(&t1con_g.t1gcon); cpscon1.m_cpscon0 = &cpscon0; cpscon0.m_tmr0 = &tmr0; cpscon0.m_t1con_g = &t1con_g; ((INTCON_14_PIR *)intcon)->write_mask = 0xfe; m_wpua = new WPU(this, "wpua", "Weak Pull-up Register", m_porta, 0x3f); pir1 = new PIR1v1822(this,"pir1","Peripheral Interrupt Register",intcon, &pie1); pir2 = new PIR2v1822(this,"pir2","Peripheral Interrupt Register",intcon, &pie2); comparator.cmxcon0[0] = new CMxCON0(this, "cm1con0", " Comparator C1 Control Register 0", 0, &comparator); comparator.cmxcon1[0] = new CMxCON1(this, "cm1con1", " Comparator C1 Control Register 1", 0, &comparator); comparator.cmout = new CMOUT(this, "cmout", "Comparator Output Register"); } P12F1822::~P12F1822() { unassignMCLRPin(); delete_file_registers(0x20, 0x7f); delete_file_registers(0xa0, 0xbf); delete_sfr_register(m_iocap); delete_sfr_register(m_iocan); delete_sfr_register(m_iocaf); delete_sfr_register(m_daccon0); delete_sfr_register(m_daccon1); delete_sfr_register(m_trisa); delete_sfr_register(m_porta); delete_sfr_register(m_lata); delete_sfr_register(m_wpua); remove_sfr_register(&tmr0); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&t1con_g); remove_sfr_register(&t1con_g.t1gcon); remove_sfr_register(&tmr2); remove_sfr_register(&pr2); remove_sfr_register(&t2con); remove_sfr_register(&cpscon0); remove_sfr_register(&cpscon1); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspadd); remove_sfr_register(ssp.sspmsk); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.ssp1con3); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pwm1con); remove_sfr_register(&ccp1as); remove_sfr_register(&pstr1con); remove_sfr_register(&pie1); remove_sfr_register(&pie2); remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&borcon); remove_sfr_register(&fvrcon); remove_sfr_register(&sr_module.srcon0); remove_sfr_register(&sr_module.srcon1); remove_sfr_register(&apfcon ); remove_sfr_register(&ansela); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&usart.spbrg); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.baudcon); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspadd); remove_sfr_register(ssp.sspmsk); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.ssp1con3); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pwm1con); remove_sfr_register(&ccp1as); remove_sfr_register(&pstr1con); remove_sfr_register(&osctune); remove_sfr_register(&option_reg); remove_sfr_register(osccon); remove_sfr_register(&oscstat); remove_sfr_register(comparator.cmxcon0[0]); remove_sfr_register(comparator.cmxcon1[0]); remove_sfr_register(comparator.cmout); delete_sfr_register(usart.rcreg); delete_sfr_register(usart.txreg); delete_sfr_register(pir1); delete_sfr_register(pir2); remove_sfr_register(&dsm_module.mdcon); remove_sfr_register(&dsm_module.mdsrc); remove_sfr_register(&dsm_module.mdcarl); remove_sfr_register(&dsm_module.mdcarh); delete e; delete m_cpu_temp; delete osccon; } Processor * P12F1822::construct(const char *name) { P12F1822 *p = new P12F1822(name); p->create(0x7f, 256); p->create_invalid_registers (); p->create_symbols(); return p; } void P12F1822::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); addSymbol(m_cpu_temp); } void P12F1822::create_sfr_map() { pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); //add_sfr_register(indf, 0x00); add_file_registers(0xa0, 0xbf, 0x00); add_sfr_register(m_porta, 0x0c); add_sfr_register(pir1, 0x11, RegisterValue(0,0),"pir1"); add_sfr_register(pir2, 0x12, RegisterValue(0,0),"pir2"); add_sfr_register(&tmr0, 0x15); add_sfr_register(&tmr1l, 0x16, RegisterValue(0,0),"tmr1l"); add_sfr_register(&tmr1h, 0x17, RegisterValue(0,0),"tmr1h"); add_sfr_register(&t1con_g, 0x18, RegisterValue(0,0)); add_sfr_register(&t1con_g.t1gcon, 0x19, RegisterValue(0,0)); add_sfr_register(&tmr2, 0x1a, RegisterValue(0,0)); add_sfr_register(&pr2, 0x1b, RegisterValue(0,0)); add_sfr_register(&t2con, 0x1c, RegisterValue(0,0)); add_sfr_register(&cpscon0, 0x1e, RegisterValue(0,0), "cpscon0"); add_sfr_register(&cpscon1, 0x1f, RegisterValue(0,0)); add_sfr_register(m_trisa, 0x8c, RegisterValue(0x3f,0)); pcon.valid_bits = 0xcf; add_sfr_register(&option_reg, 0x95, RegisterValue(0xff,0)); add_sfr_register(&osctune, 0x98, RegisterValue(0,0)); add_sfr_register(osccon, 0x99, RegisterValue(0x38,0)); add_sfr_register(&oscstat, 0x9a, RegisterValue(0,0)); intcon_reg.set_pir_set(get_pir_set()); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con_g; tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con_g.tmrl = &tmr1l; t1con_g.t1gcon.set_tmrl(&tmr1l); t1con_g.t1gcon.setInterruptSource(new InterruptSource(pir1, PIR1v1822::TMR1IF)); tmr1l.setIOpin(&(*m_porta)[5]); t1con_g.t1gcon.setGatepin(&(*m_porta)[3]); add_sfr_register(&pie1, 0x91, RegisterValue(0,0)); add_sfr_register(&pie2, 0x92, RegisterValue(0,0)); add_sfr_register(&adresl, 0x9b); add_sfr_register(&adresh, 0x9c); add_sfr_register(&adcon0, 0x9d, RegisterValue(0x00,0)); add_sfr_register(&adcon1, 0x9e, RegisterValue(0x00,0)); usart.initialize(pir1, &(*m_porta)[0], // TX pin &(*m_porta)[1], // RX pin new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); usart.set_eusart(true); add_sfr_register(m_lata, 0x10c); add_sfr_register(comparator.cmxcon0[0], 0x111, RegisterValue(0x04,0)); add_sfr_register(comparator.cmxcon1[0], 0x112, RegisterValue(0x00,0)); add_sfr_register(comparator.cmout, 0x115, RegisterValue(0x00,0)); add_sfr_register(&borcon, 0x116, RegisterValue(0x80,0)); add_sfr_register(&fvrcon, 0x117, RegisterValue(0x00,0)); add_sfr_register(m_daccon0, 0x118, RegisterValue(0x00,0)); add_sfr_register(m_daccon1, 0x119, RegisterValue(0x00,0)); add_sfr_register(&sr_module.srcon0, 0x11a, RegisterValue(0x00,0)); add_sfr_register(&sr_module.srcon1, 0x11b, RegisterValue(0x00,0)); add_sfr_register(&apfcon , 0x11d, RegisterValue(0x00,0)); add_sfr_register(&ansela, 0x18c, RegisterValue(0x17,0)); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x191); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x192); get_eeprom()->get_reg_eedata()->new_name("eedatl"); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x193); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x194); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x195, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x196); add_sfr_register(usart.rcreg, 0x199, RegisterValue(0,0),"rcreg"); add_sfr_register(usart.txreg, 0x19a, RegisterValue(0,0),"txreg"); add_sfr_register(&usart.spbrg, 0x19b, RegisterValue(0,0),"spbrgl"); add_sfr_register(&usart.spbrgh, 0x19c, RegisterValue(0,0),"spbrgh"); add_sfr_register(&usart.rcsta, 0x19d, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x19e, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.baudcon, 0x19f,RegisterValue(0x40,0),"baudcon"); add_sfr_register(m_wpua, 0x20c, RegisterValue(0x3f,0),"wpua"); add_sfr_register(&ssp.sspbuf, 0x211, RegisterValue(0,0),"ssp1buf"); add_sfr_register(&ssp.sspadd, 0x212, RegisterValue(0,0),"ssp1add"); add_sfr_register(ssp.sspmsk, 0x213, RegisterValue(0xff,0),"ssp1msk"); add_sfr_register(&ssp.sspstat, 0x214, RegisterValue(0,0),"ssp1stat"); add_sfr_register(&ssp.sspcon, 0x215, RegisterValue(0,0),"ssp1con"); add_sfr_register(&ssp.sspcon2, 0x216, RegisterValue(0,0),"ssp1con2"); add_sfr_register(&ssp.ssp1con3, 0x217, RegisterValue(0,0),"ssp1con3"); add_sfr_register(&ccpr1l, 0x291, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x292, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x293, RegisterValue(0,0)); add_sfr_register(&pwm1con, 0x294, RegisterValue(0,0)); add_sfr_register(&ccp1as, 0x295, RegisterValue(0,0)); add_sfr_register(&pstr1con, 0x296, RegisterValue(1,0)); add_sfr_register(m_iocap, 0x391, RegisterValue(0,0),"iocap"); add_sfr_register(m_iocan, 0x392, RegisterValue(0,0),"iocan"); add_sfr_register(m_iocaf, 0x393, RegisterValue(0,0),"iocaf"); m_iocaf->set_intcon(intcon); add_sfr_register(&dsm_module.mdcon, 0x39c, RegisterValue(0x20,0)); add_sfr_register(&dsm_module.mdsrc, 0x39d, RegisterValue(0x00,0)); add_sfr_register(&dsm_module.mdcarl, 0x39e, RegisterValue(0x00,0)); add_sfr_register(&dsm_module.mdcarh, 0x39f, RegisterValue(0x00,0)); tmr2.ssp_module[0] = &ssp; ssp.initialize( get_pir_set(), // PIR &(*m_porta)[1], // SCK &(*m_porta)[3], // SS &(*m_porta)[0], // SDO &(*m_porta)[2], // SDI m_trisa, // i2c tris port SSP_TYPE_MSSP1 ); apfcon.set_usart(&usart); apfcon.set_ssp(&ssp); apfcon.set_t1gcon(&t1con_g.t1gcon); apfcon.set_pins(0, &(*m_porta)[2], &(*m_porta)[5]); //CCP1/P1A apfcon.set_pins(1, &(*m_porta)[0], &(*m_porta)[4]); //P1B apfcon.set_pins(2, &(*m_porta)[0], &(*m_porta)[4]); //USART TX Pin apfcon.set_pins(3, &(*m_porta)[4], &(*m_porta)[3]); //tmr1 gate apfcon.set_pins(5, &(*m_porta)[3], &(*m_porta)[0]); //SSP SS apfcon.set_pins(6, &(*m_porta)[0], &(*m_porta)[4]); //SSP SDO apfcon.set_pins(7, &(*m_porta)[1], &(*m_porta)[5]); //USART RX Pin if (pir1) { pir1->set_intcon(intcon); pir1->set_pie(&pie1); } pie1.setPir(pir1); pie2.setPir(pir2); t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); // tmr2.add_ccp ( &ccp2con ); pr2.tmr2 = &tmr2; ccp1as.setIOpin(0, 0, &(*m_porta)[2]); ccp1as.link_registers(&pwm1con, &ccp1con); ccp1con.setIOpin(&(*m_porta)[2], &(*m_porta)[0]); ccp1con.pstrcon = &pstr1con; ccp1con.pwm1con = &pwm1con; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v1822::CCP1IF, &tmr2, &ccp1as); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; ansela.config(0x17, 0); ansela.setValidBits(0x17); ansela.setAdcon1(&adcon1); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(intcon); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(0x1f); adcon0.setChannel_shift(2); adcon0.setGo(1); adcon1.setAdcon0(&adcon0); adcon1.setNumberOfChannels(32); // not all channels are used adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[4]); adcon1.setValidBits(0xf3); adcon1.setVrefHiConfiguration(0, 1); adcon1.set_FVR_chan(0x1f); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[2]); comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[1], &(*m_porta)[4]); comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[0]); comparator.cmxcon0[0]->setBitMask(0xf7); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, (1<<5))); comparator.cmxcon1[0]->setBitMask(0xf1); comparator.assign_pir_set(get_pir_set()); comparator.assign_t1gcon(&t1con_g.t1gcon); comparator.assign_sr_module(&sr_module); fvrcon.set_adcon1(&adcon1); fvrcon.set_cpscon0(&cpscon0); fvrcon.set_daccon0(m_daccon0); fvrcon.set_cmModule(&comparator); fvrcon.set_VTemp_AD_chan(0x1d); fvrcon.set_FVRAD_AD_chan(0x1f); m_daccon0->set_adcon1(&adcon1); m_daccon0->set_cpscon0(&cpscon0); m_daccon0->set_cmModule(&comparator); m_daccon0->set_FVRCDA_AD_chan(0x1e); m_daccon0->setDACOUT(&(*m_porta)[0]); cpscon0.set_pin(0, &(*m_porta)[0]); cpscon0.set_pin(1, &(*m_porta)[1]); cpscon0.set_pin(2, &(*m_porta)[2]); cpscon0.set_pin(3, &(*m_porta)[4]); sr_module.setPins(&(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[5]); osccon->set_osctune(&osctune); osccon->set_oscstat(&oscstat); osctune.set_osccon((OSCCON *)osccon); osccon->write_mask = 0xfb; dsm_module.usart_mod = &usart; } //------------------------------------------------------------------- void P12F1822::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) get_eeprom()->change_rom(address - 0x2100, value); } void P12F1822::create_iopin_map() { package = new Package(8); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(7, m_porta->addPin(new IO_bi_directional_pu("porta0"),0)); package->assign_pin(6, m_porta->addPin(new IO_bi_directional_pu("porta1"),1)); package->assign_pin(5, m_porta->addPin(new IO_bi_directional_pu("porta2"),2)); package->assign_pin(4, m_porta->addPin(new IO_bi_directional_pu("porta3"),3)); package->assign_pin(3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4)); package->assign_pin(2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5)); package->assign_pin( 1, 0); // Vdd package->assign_pin( 8, 0); // Vss } void P12F1822::create(int ram_top, int eeprom_size) { create_iopin_map(); e = new EEPROM_EXTND(this, pir2); set_eeprom(e); osccon = new OSCCON_2(this, "osccon", "Oscillator Control Register"); pic_processor::create(); e->initialize(eeprom_size, 16, 16, 0x8000); e->set_intcon(intcon); e->get_reg_eecon1()->set_valid_bits(0xff); add_file_registers(0x20, ram_top, 0x00); _14bit_e_processor::create_sfr_map(); create_sfr_map(); dsm_module.setOUTpin(&(*m_porta)[0]); dsm_module.setMINpin(&(*m_porta)[1]); dsm_module.setCIN1pin(&(*m_porta)[2]); dsm_module.setCIN2pin(&(*m_porta)[4]); // Set DeviceID if (m_configMemory && m_configMemory->getConfigWord(6)) m_configMemory->getConfigWord(6)->set(0x2700); } //------------------------------------------------------------------- void P12F1822::enter_sleep() { tmr1l.sleep(); osccon->sleep(); _14bit_e_processor::enter_sleep(); } //------------------------------------------------------------------- void P12F1822::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr1l.wake(); osccon->wake(); _14bit_e_processor::exit_sleep(); } } //------------------------------------------------------------------- void P12F1822::option_new_bits_6_7(unsigned int bits) { Dprintf(("P12F1822::option_new_bits_6_7 bits=%x\n", bits)); m_porta->setIntEdge ( (bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); m_wpua->set_wpu_pu ( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); } void P12F1822::oscillator_select(unsigned int cfg_word1, bool clkout) { unsigned int mask = 0x1f; unsigned int fosc = cfg_word1 & (FOSC0|FOSC1|FOSC2); osccon->set_config_irc(fosc == 4); osccon->set_config_xosc(fosc < 3); osccon->set_config_ieso(cfg_word1 & IESO); set_int_osc(false); switch(fosc) { case 0: //LP oscillator: low power crystal case 1: //XT oscillator: Crystal/resonator case 2: //HS oscillator: High-speed crystal/resonator (m_porta->getPin(4))->newGUIname("OSC2"); (m_porta->getPin(5))->newGUIname("OSC1"); mask = 0x0f; break; case 3: //EXTRC oscillator External RC circuit connected to CLKIN pin (m_porta->getPin(5))->newGUIname("CLKIN"); mask = 0x1f; if(clkout) { (m_porta->getPin(4))->newGUIname("CLKOUT"); mask = 0x0f; } break; case 4: //INTOSC oscillator: I/O function on CLKIN pin set_int_osc(true); mask = 0x3f; if(clkout) { (m_porta->getPin(4))->newGUIname("CLKOUT"); mask = 0x2f; } (m_porta->getPin(5))->newGUIname((m_porta->getPin(5))->name().c_str()); break; case 5: //ECL: External Clock, Low-Power mode (0-0.5 MHz): on CLKIN pin mask = 0x1f; if(clkout) { (m_porta->getPin(4))->newGUIname("CLKOUT"); mask = 0x0f; } (m_porta->getPin(5))->newGUIname("CLKIN"); break; case 6: //ECM: External Clock, Medium-Power mode (0.5-4 MHz): on CLKIN pin mask = 0x1f; if(clkout) { (m_porta->getPin(4))->newGUIname("CLKOUT"); mask = 0x0f; } (m_porta->getPin(5))->newGUIname("CLKIN"); break; case 7: //ECH: External Clock, High-Power mode (4-32 MHz): on CLKIN pin mask = 0x1f; if(clkout) { (m_porta->getPin(4))->newGUIname("CLKOUT"); mask = 0x0f; } (m_porta->getPin(5))->newGUIname("CLKIN"); break; }; ansela.setValidBits(0x17 & mask); m_porta->setEnableMask(mask); } void P12F1822::program_memory_wp(unsigned int mode) { switch(mode) { case 3: // no write protect get_eeprom()->set_prog_wp(0x0); break; case 2: // write protect 0000-01ff get_eeprom()->set_prog_wp(0x0200); break; case 1: // write protect 0000-03ff get_eeprom()->set_prog_wp(0x0400); break; case 0: // write protect 0000-07ff get_eeprom()->set_prog_wp(0x0800); break; default: printf("%s unexpected mode %u\n", __FUNCTION__, mode); break; } } //======================================================================== Processor * P12F1840::construct(const char *name) { P12F1840 *p = new P12F1840(name); p->create(0x7f, 256); p->create_invalid_registers (); p->create_symbols(); return p; } P12F1840::P12F1840(const char *_name, const char *desc) : P12F1822(_name, desc) { } P12F1840::~P12F1840() { delete_file_registers(0xc0, 0xef, 0x00); delete_file_registers(0x120, 0x16f, 0x00); delete_sfr_register(vrefcon); } void P12F1840::create(int ram_top, int eeprom_size) { P12F1822::create(ram_top, eeprom_size); add_file_registers(0xc0, 0xef, 0x00); add_file_registers(0x120, 0x16f, 0x00); // Set DeviceID if (m_configMemory && m_configMemory->getConfigWord(6)) m_configMemory->getConfigWord(6)->set(0x1b80); vrefcon = new sfr_register(this, "vrefcon", "Voltage Regulator Control Register"); add_sfr_register(vrefcon, 0x197, RegisterValue(0x01,0)); } //======================================================================== P16F178x::P16F178x(const char *_name, const char *desc) : _14bit_e_processor(_name,desc), comparator(this), pie1(this,"pie1", "Peripheral Interrupt Enable"), pie2(this,"pie2", "Peripheral Interrupt Enable"), pie3(this,"pie3", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), t1con_g(this, "t1con", "TMR1 Control Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), fvrcon(this, "fvrcon", "Voltage reference control register", 0xbf, 0x40), borcon(this, "borcon", "Brown-out reset control register"), ansela(this, "ansela", "Analog Select port a"), anselb(this, "anselb", "Analog Select port b"), anselc(this, "anselc", "Analog Select port c"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adcon2(this,"adcon2", "A2D Control 2"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low"), osccon(0), osctune(this, "osctune", "Oscillator Tunning Register"), oscstat(this, "oscstat", "Oscillator Status Register"), wdtcon(this, "wdtcon", "Watch dog timer control", 0x3f), usart(this), ssp(this), apfcon1(this, "apfcon1", "Alternate Pin Function Control Register 1"), apfcon2(this, "apfcon2", "Alternate Pin Function Control Register 2"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register"), ccp1as(this, "ccp1as", "CCP1 Auto-Shutdown Control Register"), pstr1con(this, "pstr1con", "Pulse Sterring Control Register") { m_iocbf = new IOCxF(this, "iocbf", "Interrupt-On-Change flag Register"); m_iocbp = new IOC(this, "iocbp", "Interrupt-On-Change positive edge"); m_iocbn = new IOC(this, "iocbn", "Interrupt-On-Change negative edge"); m_portb= new PicPortIOCRegister(this,"portb","", intcon, m_iocbp, m_iocbn, m_iocbf, 8,0xff); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false, 0xff); m_latb = new PicLatchRegister(this,"latb","",m_portb, 0xff); m_wpub = new WPU(this, "wpub", "Weak Pull-up Register", m_portb, 0xff); m_ioccf = new IOCxF(this, "ioccf", "Interrupt-On-Change flag Register"); m_ioccp = new IOC(this, "ioccp", "Interrupt-On-Change positive edge"); m_ioccn = new IOC(this, "ioccn", "Interrupt-On-Change negative edge"); m_portc= new PicPortIOCRegister(this,"portc","", intcon, m_ioccp, m_ioccn, m_ioccf, 8,0xff); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false, 0xff); m_latc = new PicLatchRegister(this,"latc","",m_portc, 0xff); m_wpuc = new WPU(this, "wpuc", "Weak Pull-up Register", m_portc, 0xff); m_iocaf = new IOCxF(this, "iocaf", "Interrupt-On-Change flag Register"); m_iocap = new IOC(this, "iocap", "Interrupt-On-Change positive edge"); m_iocan = new IOC(this, "iocan", "Interrupt-On-Change negative edge"); m_porta= new PicPortIOCRegister(this,"porta","", intcon, m_iocap, m_iocan, m_iocaf, 8,0xff); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false, 0xff); m_lata = new PicLatchRegister(this,"lata","",m_porta, 0xff); m_iocef = new IOCxF(this, "iocef", "Interrupt-On-Change flag Register", 0x08); m_iocep = new IOC(this, "iocep", "Interrupt-On-Change positive edge", 0x08); m_iocen = new IOC(this, "iocen", "Interrupt-On-Change negative edge", 0x08); m_porte= new PicPortIOCRegister(this,"porte","", intcon, m_iocep, m_iocen, m_iocef, 8,0x08); m_trise = new PicTrisRegister(this,"trise","", m_porte, false, 0x00); m_daccon0 = new DACCON0(this, "dac1con0", "DAC1 8bit Voltage reference register 0", 0xbd, 256); m_daccon1 = new DACCON1(this, "dac1con1", "DAC1 8bit Voltage reference register 1", 0xff, m_daccon0); m_dac2con0 = new DACCON0(this, "dac2con0", "DAC2 5bit Voltage reference register 0", 0xb4, 32); m_dac2con1 = new DACCON1(this, "dac2con1", "DAC2 5bit Voltage reference register 1", 0x1f, m_dac2con0); m_dac3con0 = new DACCON0(this, "dac3con0", "DAC3 5bit Voltage reference register 0", 0xb4, 32); m_dac3con1 = new DACCON1(this, "dac3con1", "DAC3 5bit Voltage reference register 1", 0x1f, m_dac3con0); m_dac4con0 = new DACCON0(this, "dac4con0", "DAC4 5bit Voltage reference register 0", 0xb4, 32); m_dac4con1 = new DACCON1(this, "dac4con1", "DAC4 5bit Voltage reference register 1", 0x1f, m_dac4con0); m_cpu_temp = new CPU_Temp("cpu_temperature", 30., "CPU die temperature"); tmr0.set_cpu(this, m_porta, 4, &option_reg); tmr0.start(0); tmr0.set_t1gcon(&t1con_g.t1gcon); set_mclr_pin(1); ((INTCON_14_PIR *)intcon)->write_mask = 0xfe; m_wpua = new WPU(this, "wpua", "Weak Pull-up Register", m_porta, 0xff); m_wpue = new WPU(this, "wpue", "Weak Pull-up Register", m_porte, 0x08); pir1 = new PIR1v1822(this,"pir1","Peripheral Interrupt Register",intcon, &pie1); pir2 = new PIR2v1822(this,"pir2","Peripheral Interrupt Register",intcon, &pie2); pir3 = new PIR3v178x(this,"pir3","Peripheral Interrupt Register",intcon, &pie3); pir2->valid_bits |= PIR2v1822::C2IF | PIR2v1822::CCP2IF | PIR2v1822::C3IF | PIR2v1822::C4IF; pir2->writable_bits |= PIR2v1822::C2IF | PIR2v1822::CCP2IF | PIR2v1822::C3IF | PIR2v1822::C4IF; comparator.cmxcon0[0] = new CMxCON0(this, "cm1con0", " Comparator C1 Control Register 0", 0, &comparator); comparator.cmxcon1[0] = new CMxCON1(this, "cm1con1", " Comparator C1 Control Register 1", 0, &comparator); comparator.cmout = new CMOUT(this, "cmout", "Comparator Output Register"); comparator.cmxcon0[1] = new CMxCON0(this, "cm2con0", " Comparator C2 Control Register 0", 1, &comparator); comparator.cmxcon1[1] = new CMxCON1(this, "cm2con1", " Comparator C2 Control Register 1", 1, &comparator); comparator.cmxcon0[2] = new CMxCON0(this, "cm3con0", " Comparator C3 Control Register 0", 2, &comparator); comparator.cmxcon1[2] = new CMxCON1(this, "cm3con1", " Comparator C3 Control Register 1", 2, &comparator); } P16F178x::~P16F178x() { unassignMCLRPin(); delete_file_registers(0x20, 0x7f); unsigned int ram = ram_size - 96; // first 96 bytes already added unsigned int add; for(add = 0x80; ram >= 80; add += 0x80) { ram -= 80; delete_file_registers(add + 0x20, add + 0x6f); } if (ram > 0) delete_file_registers(add + 0x20 , add + 0x20 + ram -1); delete_sfr_register(m_iocap); delete_sfr_register(m_iocan); delete_sfr_register(m_iocaf); delete_sfr_register(m_iocbp); delete_sfr_register(m_iocbn); delete_sfr_register(m_iocbf); delete_sfr_register(m_ioccp); delete_sfr_register(m_ioccn); delete_sfr_register(m_ioccf); delete_sfr_register(m_iocep); delete_sfr_register(m_iocen); delete_sfr_register(m_iocef); delete_sfr_register(m_daccon0); delete_sfr_register(m_daccon1); delete_sfr_register(m_dac2con0); delete_sfr_register(m_dac2con1); delete_sfr_register(m_dac3con0); delete_sfr_register(m_dac3con1); delete_sfr_register(m_dac4con0); delete_sfr_register(m_dac4con1); delete_sfr_register(m_trisa); delete_sfr_register(m_porta); delete_sfr_register(m_lata); delete_sfr_register(m_wpua); delete_sfr_register(m_portb); delete_sfr_register(m_trisb); delete_sfr_register(m_latb); delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(m_latc); delete_sfr_register(m_wpub); delete_sfr_register(m_wpuc); delete_sfr_register(m_trise); delete_sfr_register(m_porte); delete_sfr_register(m_wpue); remove_sfr_register(&tmr0); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&t1con_g); remove_sfr_register(&t1con_g.t1gcon); remove_sfr_register(&tmr2); remove_sfr_register(&pr2); remove_sfr_register(&t2con); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspadd); remove_sfr_register(ssp.sspmsk); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.ssp1con3); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pwm1con); remove_sfr_register(&ccp1as); remove_sfr_register(&pstr1con); remove_sfr_register(&pie1); remove_sfr_register(&pie2); remove_sfr_register(&pie3); remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adcon2); remove_sfr_register(&borcon); remove_sfr_register(&fvrcon); remove_sfr_register(&apfcon1); remove_sfr_register(&apfcon2); remove_sfr_register(&ansela); remove_sfr_register(&anselb); remove_sfr_register(&anselc); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&usart.spbrg); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.baudcon); remove_sfr_register(&ssp.sspbuf); remove_sfr_register(&ssp.sspadd); remove_sfr_register(ssp.sspmsk); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.ssp1con3); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&pwm1con); remove_sfr_register(&ccp1as); remove_sfr_register(&pstr1con); remove_sfr_register(&osctune); remove_sfr_register(&option_reg); remove_sfr_register(osccon); remove_sfr_register(&oscstat); remove_sfr_register(comparator.cmxcon0[0]); remove_sfr_register(comparator.cmxcon1[0]); remove_sfr_register(comparator.cmout); remove_sfr_register(comparator.cmxcon0[1]); remove_sfr_register(comparator.cmxcon1[1]); remove_sfr_register(comparator.cmxcon0[2]); remove_sfr_register(comparator.cmxcon1[2]); delete_sfr_register(usart.rcreg); delete_sfr_register(usart.txreg); delete_sfr_register(pir1); delete_sfr_register(pir2); delete_sfr_register(pir3); delete e; delete m_cpu_temp; } void P16F178x::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); addSymbol(m_cpu_temp); } void P16F178x::create_sfr_map() { pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); pir_set_2_def.set_pir3(pir3); add_file_registers(0x20, 0x7f, 0x00); unsigned int ram = ram_size - 96; // first 96 bytes already added unsigned int add; for(add = 0x80; ram >= 80; add += 0x80) { ram -= 80; add_file_registers(add + 0x20, add + 0x6f, 0x00); } if (ram > 0) add_file_registers(add + 0x20 , add + 0x20 + ram -1, 0x00); add_sfr_register(m_porta, 0x0c); add_sfr_register(m_portb, 0x0d); add_sfr_register(m_portc, 0x0e); add_sfr_register(m_porte, 0x10); add_sfr_register(pir1, 0x11, RegisterValue(0,0),"pir1"); add_sfr_register(pir2, 0x12, RegisterValue(0,0),"pir2"); add_sfr_register(pir3, 0x13, RegisterValue(0,0),"pir3"); add_sfr_register(&tmr0, 0x15); add_sfr_register(&tmr1l, 0x16, RegisterValue(0,0),"tmr1l"); add_sfr_register(&tmr1h, 0x17, RegisterValue(0,0),"tmr1h"); add_sfr_register(&t1con_g, 0x18, RegisterValue(0,0)); add_sfr_register(&t1con_g.t1gcon, 0x19, RegisterValue(0,0)); add_sfr_register(&tmr2, 0x1a, RegisterValue(0,0)); add_sfr_register(&pr2, 0x1b, RegisterValue(0,0)); add_sfr_register(&t2con, 0x1c, RegisterValue(0,0)); add_sfr_register(m_trisa, 0x8c, RegisterValue(0xff,0)); add_sfr_register(m_trisb, 0x8d, RegisterValue(0xff,0)); add_sfr_register(m_trisc, 0x8e, RegisterValue(0xff,0)); add_sfr_register(m_trise, 0x90, RegisterValue(0x08,0)); pcon.valid_bits = 0xcf; add_sfr_register(&option_reg, 0x95, RegisterValue(0xff,0)); add_sfr_register(&osctune, 0x98, RegisterValue(0,0)); add_sfr_register(osccon, 0x99, RegisterValue(0x38,0)); add_sfr_register(&oscstat, 0x9a, RegisterValue(0,0)); intcon_reg.set_pir_set(get_pir_set()); tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con_g; tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con_g.tmrl = &tmr1l; t1con_g.t1gcon.set_tmrl(&tmr1l); t1con_g.t1gcon.setInterruptSource(new InterruptSource(pir1, PIR1v1822::TMR1IF)); tmr1l.setIOpin(&(*m_porta)[5]); t1con_g.t1gcon.setGatepin(&(*m_porta)[3]); add_sfr_register(&pie1, 0x91, RegisterValue(0,0)); add_sfr_register(&pie2, 0x92, RegisterValue(0,0)); add_sfr_register(&pie3, 0x93, RegisterValue(0,0)); add_sfr_register(&adresl, 0x9b); add_sfr_register(&adresh, 0x9c); add_sfr_register(&adcon0, 0x9d, RegisterValue(0x00,0)); add_sfr_register(&adcon1, 0x9e, RegisterValue(0x00,0)); add_sfr_register(&adcon2, 0x9f, RegisterValue(0x00,0)); usart.initialize(pir1, &(*m_porta)[0], // TX pin &(*m_porta)[1], // RX pin new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); usart.set_eusart(true); add_sfr_register(m_lata, 0x10c); add_sfr_register(m_latb, 0x10d); add_sfr_register(m_latc, 0x10e); add_sfr_register(comparator.cmxcon0[0], 0x111, RegisterValue(0x04,0)); add_sfr_register(comparator.cmxcon1[0], 0x112, RegisterValue(0x00,0)); add_sfr_register(comparator.cmxcon0[1], 0x113, RegisterValue(0x04,0)); add_sfr_register(comparator.cmxcon1[1], 0x114, RegisterValue(0x00,0)); add_sfr_register(comparator.cmout, 0x115, RegisterValue(0x00,0)); add_sfr_register(&borcon, 0x116, RegisterValue(0x80,0)); add_sfr_register(&fvrcon, 0x117, RegisterValue(0x00,0)); add_sfr_register(m_daccon0, 0x118, RegisterValue(0x00,0)); add_sfr_register(m_daccon1, 0x119, RegisterValue(0x00,0)); add_sfr_register(&apfcon2 , 0x11c, RegisterValue(0x00,0)); add_sfr_register(&apfcon1 , 0x11d, RegisterValue(0x00,0)); add_sfr_register(comparator.cmxcon0[2], 0x11e, RegisterValue(0x04,0)); add_sfr_register(comparator.cmxcon1[2], 0x11f, RegisterValue(0x00,0)); add_sfr_register(&ansela, 0x18c, RegisterValue(0x17,0)); add_sfr_register(&anselb, 0x18d, RegisterValue(0x7f,0)); add_sfr_register(&anselc, 0x18e, RegisterValue(0xff,0)); get_eeprom()->get_reg_eedata()->new_name("eedatl"); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x191); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x192); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x193); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x194); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x195, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x196); add_sfr_register(usart.rcreg, 0x199, RegisterValue(0,0),"rcreg"); add_sfr_register(usart.txreg, 0x19a, RegisterValue(0,0),"txreg"); add_sfr_register(&usart.spbrg, 0x19b, RegisterValue(0,0),"spbrgl"); add_sfr_register(&usart.spbrgh, 0x19c, RegisterValue(0,0),"spbrgh"); add_sfr_register(&usart.rcsta, 0x19d, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x19e, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.baudcon, 0x19f,RegisterValue(0x40,0),"baudcon"); add_sfr_register(m_wpua, 0x20c, RegisterValue(0xff,0),"wpua"); add_sfr_register(m_wpub, 0x20d, RegisterValue(0xff,0),"wpub"); add_sfr_register(m_wpuc, 0x20e, RegisterValue(0xff,0),"wpuc"); add_sfr_register(m_wpue, 0x210, RegisterValue(0x04,0),"wpue"); add_sfr_register(&ssp.sspbuf, 0x211, RegisterValue(0,0),"ssp1buf"); add_sfr_register(&ssp.sspadd, 0x212, RegisterValue(0,0),"ssp1add"); add_sfr_register(ssp.sspmsk, 0x213, RegisterValue(0xff,0),"ssp1msk"); add_sfr_register(&ssp.sspstat, 0x214, RegisterValue(0,0),"ssp1stat"); add_sfr_register(&ssp.sspcon, 0x215, RegisterValue(0,0),"ssp1con"); add_sfr_register(&ssp.sspcon2, 0x216, RegisterValue(0,0),"ssp1con2"); add_sfr_register(&ssp.ssp1con3, 0x217, RegisterValue(0,0),"ssp1con3"); add_sfr_register(&ccpr1l, 0x291, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x292, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x293, RegisterValue(0,0)); add_sfr_register(&pwm1con, 0x294, RegisterValue(0,0)); add_sfr_register(&ccp1as, 0x295, RegisterValue(0,0)); add_sfr_register(&pstr1con, 0x296, RegisterValue(1,0)); add_sfr_register(m_iocap, 0x391, RegisterValue(0,0),"iocap"); add_sfr_register(m_iocan, 0x392, RegisterValue(0,0),"iocan"); add_sfr_register(m_iocaf, 0x393, RegisterValue(0,0),"iocaf"); m_iocaf->set_intcon(intcon); add_sfr_register(m_iocbp, 0x394, RegisterValue(0,0),"iocbp"); add_sfr_register(m_iocbn, 0x395, RegisterValue(0,0),"iocbn"); add_sfr_register(m_iocbf, 0x396, RegisterValue(0,0),"iocbf"); m_iocbf->set_intcon(intcon); add_sfr_register(m_ioccp, 0x397, RegisterValue(0,0),"ioccp"); add_sfr_register(m_ioccn, 0x398, RegisterValue(0,0),"ioccn"); add_sfr_register(m_ioccf, 0x399, RegisterValue(0,0),"ioccf"); m_ioccf->set_intcon(intcon); add_sfr_register(m_iocep, 0x39d, RegisterValue(0,0),"iocep"); add_sfr_register(m_iocen, 0x39e, RegisterValue(0,0),"iocen"); add_sfr_register(m_iocef, 0x39f, RegisterValue(0,0),"iocef"); m_iocef->set_intcon(intcon); add_sfr_register(m_dac2con0, 0x591, RegisterValue(0x00,0)); add_sfr_register(m_dac2con1, 0x592, RegisterValue(0x00,0)); add_sfr_register(m_dac3con0, 0x593, RegisterValue(0x00,0)); add_sfr_register(m_dac3con1, 0x594, RegisterValue(0x00,0)); add_sfr_register(m_dac4con0, 0x595, RegisterValue(0x00,0)); add_sfr_register(m_dac4con1, 0x596, RegisterValue(0x00,0)); tmr2.ssp_module[0] = &ssp; ssp.initialize( get_pir_set(), // PIR &(*m_porta)[1], // SCK &(*m_porta)[3], // SS &(*m_porta)[0], // SDO &(*m_porta)[2], // SDI m_trisa, // i2c tris port SSP_TYPE_MSSP1 ); apfcon1.set_usart(&usart); apfcon1.set_ssp(&ssp); apfcon1.set_t1gcon(&t1con_g.t1gcon); apfcon1.set_pins(0, &(*m_porta)[2], &(*m_porta)[5]); //CCP1/P1A apfcon1.set_pins(1, &(*m_porta)[0], &(*m_porta)[4]); //P1B apfcon1.set_pins(2, &(*m_porta)[0], &(*m_porta)[4]); //USART TX Pin apfcon1.set_pins(3, &(*m_porta)[4], &(*m_porta)[3]); //tmr1 gate apfcon1.set_pins(5, &(*m_porta)[3], &(*m_porta)[0]); //SSP SS apfcon1.set_pins(6, &(*m_porta)[0], &(*m_porta)[4]); //SSP SDO apfcon1.set_pins(7, &(*m_porta)[1], &(*m_porta)[5]); //USART RX Pin if (pir1) { pir1->set_intcon(intcon); pir1->set_pie(&pie1); } pie1.setPir(pir1); pie2.setPir(pir2); pie3.setPir(pir3); t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); // tmr2.add_ccp ( &ccp2con ); pr2.tmr2 = &tmr2; ccp1as.setIOpin(0, 0, &(*m_porta)[2]); ccp1as.link_registers(&pwm1con, &ccp1con); ccp1con.setIOpin(&(*m_porta)[2], &(*m_porta)[0]); ccp1con.pstrcon = &pstr1con; ccp1con.pwm1con = &pwm1con; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v1822::CCP1IF, &tmr2, &ccp1as); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; ansela.config(0x17, 0); ansela.setValidBits(0x17); ansela.setAdcon1(&adcon1); anselb.config(0x3f, 8); anselb.setValidBits(0x7f); anselb.setAdcon1(&adcon1); anselb.setAnsel(&ansela); ansela.setAnsel(&anselb); anselc.setValidBits(0xff); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setAdcon2(&adcon2); adcon0.setIntcon(intcon); adcon0.setA2DBits(12); adcon0.setPir(pir1); adcon0.setChannel_Mask(0x1f); adcon0.setChannel_shift(2); adcon0.setGo(1); adcon1.setAdcon0(&adcon0); adcon1.setNumberOfChannels(32); // not all channels are used adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[4]); adcon1.setValidBits(0xf7); adcon1.setVrefHiConfiguration(0, 3); adcon1.setVrefLoConfiguration(0, 2); adcon1.set_FVR_chan(0x1f); comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1], &(*m_portb)[3], &(*m_portb)[1]); comparator.cmxcon1[1]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1], &(*m_portb)[3], &(*m_portb)[1]); comparator.cmxcon1[2]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1], &(*m_portb)[3], &(*m_portb)[1]); comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[2], &(*m_porta)[3]); comparator.cmxcon1[1]->set_INpinPos(&(*m_porta)[2], &(*m_portb)[0]); comparator.cmxcon1[2]->set_INpinPos(&(*m_porta)[2], &(*m_portb)[4]); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[4]); comparator.cmxcon1[1]->set_OUTpin(&(*m_porta)[5]); comparator.cmxcon1[2]->set_OUTpin(&(*m_portb)[5]); comparator.cmxcon0[0]->setBitMask(0xbf); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, (1<<5))); comparator.cmxcon0[1]->setBitMask(0xbf); comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, (1<<6))); comparator.cmxcon0[2]->setBitMask(0xbf); comparator.cmxcon0[2]->setIntSrc(new InterruptSource(pir2, (1<<1))); comparator.cmxcon1[0]->setBitMask(0xff); comparator.cmxcon1[1]->setBitMask(0xff); comparator.cmxcon1[2]->setBitMask(0xff); comparator.assign_pir_set(get_pir_set()); comparator.assign_t1gcon(&t1con_g.t1gcon); fvrcon.set_adcon1(&adcon1); fvrcon.set_daccon0(m_daccon0); fvrcon.set_cmModule(&comparator); fvrcon.set_VTemp_AD_chan(0x1d); fvrcon.set_FVRAD_AD_chan(0x1f); m_daccon0->set_adcon1(&adcon1); m_daccon0->set_cmModule(&comparator); m_daccon0->set_FVRCDA_AD_chan(0x1e); m_daccon0->setDACOUT(&(*m_porta)[2], &(*m_portb)[7]); m_dac2con0->set_adcon1(&adcon1); m_dac2con0->set_cmModule(&comparator); m_dac2con0->set_FVRCDA_AD_chan(0x1c); m_dac2con0->setDACOUT(&(*m_porta)[5], &(*m_portb)[7]); m_dac3con0->set_adcon1(&adcon1); m_dac3con0->set_cmModule(&comparator); m_dac3con0->set_FVRCDA_AD_chan(0x19); m_dac3con0->setDACOUT(&(*m_portb)[2], &(*m_portb)[7]); m_dac4con0->set_adcon1(&adcon1); m_dac4con0->set_cmModule(&comparator); m_dac4con0->set_FVRCDA_AD_chan(0x18); m_dac4con0->setDACOUT(&(*m_porta)[4], &(*m_portb)[7]); osccon->set_osctune(&osctune); osccon->set_oscstat(&oscstat); osctune.set_osccon((OSCCON *)osccon); osccon->write_mask = 0xfb; } //------------------------------------------------------------------- void P16F178x::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) get_eeprom()->change_rom(address - 0x2100, value); } void P16F178x::create(int ram_top, int eeprom_size) { e = new EEPROM_EXTND(this, pir2); set_eeprom(e); osccon = new OSCCON_2(this, "osccon", "Oscillator Control Register"); pic_processor::create(); e->initialize(eeprom_size, 16, 16, 0x8000); e->set_intcon(intcon); e->get_reg_eecon1()->set_valid_bits(0xff); P16F178x::create_sfr_map(); _14bit_e_processor::create_sfr_map(); } //------------------------------------------------------------------- void P16F178x::enter_sleep() { tmr1l.sleep(); osccon->sleep(); _14bit_e_processor::enter_sleep(); } //------------------------------------------------------------------- void P16F178x::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr1l.wake(); osccon->wake(); _14bit_e_processor::exit_sleep(); } } //------------------------------------------------------------------- void P16F178x::option_new_bits_6_7(unsigned int bits) { Dprintf(("P16F178x::option_new_bits_6_7 bits=%x\n", bits)); m_porta->setIntEdge ( (bits & OPTION_REG::BIT6) == OPTION_REG::BIT6); m_wpua->set_wpu_pu ( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7); } void P16F178x::oscillator_select(unsigned int cfg_word1, bool clkout) { unsigned int mask = m_porta->getEnableMask(); unsigned int fosc = cfg_word1 & (FOSC0|FOSC1|FOSC2); osccon->set_config_irc(fosc == 4); osccon->set_config_xosc(fosc < 3); osccon->set_config_ieso(cfg_word1 & IESO); set_int_osc(false); switch(fosc) { case 0: //LP oscillator: low power crystal case 1: //XT oscillator: Crystal/resonator case 2: //HS oscillator: High-speed crystal/resonator (m_porta->getPin(6))->newGUIname("OSC2"); (m_porta->getPin(7))->newGUIname("OSC1"); mask &= 0x3f; break; case 3: //EXTRC oscillator External RC circuit connected to CLKIN pin (m_porta->getPin(7))->newGUIname("CLKIN"); mask &= 0x7f; if(clkout) { (m_porta->getPin(6))->newGUIname("CLKOUT"); mask &= 0xbf; } else { (m_porta->getPin(6))->newGUIname((m_porta->getPin(6))->name().c_str()); mask |= 0x40; } break; case 4: //INTOSC oscillator: I/O function on CLKIN pin set_int_osc(true); if(clkout) { (m_porta->getPin(6))->newGUIname("CLKOUT"); mask &= 0xbf; } else { (m_porta->getPin(6))->newGUIname((m_porta->getPin(6))->name().c_str()); mask |= 0x40; } mask |= 0x80; (m_porta->getPin(7))->newGUIname((m_porta->getPin(7))->name().c_str()); break; case 5: //ECL: External Clock, Low-Power mode (0-0.5 MHz): on CLKIN pin if(clkout) { (m_porta->getPin(6))->newGUIname("CLKOUT"); mask &= 0xbf; } else { (m_porta->getPin(6))->newGUIname((m_porta->getPin(6))->name().c_str()); mask |= 0x40; } mask &= 0x7f; (m_porta->getPin(7))->newGUIname("CLKIN"); break; case 6: //ECM: External Clock, Medium-Power mode (0.5-4 MHz): on CLKIN pin if(clkout) { (m_porta->getPin(6))->newGUIname("CLKOUT"); mask &= 0xbf; } else { mask |= 0x40; (m_porta->getPin(6))->newGUIname((m_porta->getPin(6))->name().c_str()); } (m_porta->getPin(7))->newGUIname("CLKIN"); mask &= 0x7f; break; case 7: //ECH: External Clock, High-Power mode (4-32 MHz): on CLKIN pin if(clkout) { (m_porta->getPin(6))->newGUIname("CLKOUT"); mask &= 0xbf; } else { mask |= 0x40; (m_porta->getPin(6))->newGUIname((m_porta->getPin(6))->name().c_str()); } (m_porta->getPin(7))->newGUIname("CLKIN"); mask &= 0x7f; break; }; ansela.setValidBits(0x17 & mask); m_porta->setEnableMask(mask); } void P16F178x::program_memory_wp(unsigned int mode) { switch(mode) { case 3: // no write protect get_eeprom()->set_prog_wp(0x0); break; case 2: // write protect 0000-01ff get_eeprom()->set_prog_wp(0x0200); break; case 1: // write protect 0000-03ff get_eeprom()->set_prog_wp(0x0400); break; case 0: // write protect 0000-07ff get_eeprom()->set_prog_wp(0x0800); break; default: printf("%s unexpected mode %u\n", __FUNCTION__, mode); break; } } //======================================================================== P16F1788::P16F1788(const char *_name, const char *desc) : P16F178x(_name,desc) { comparator.cmxcon0[3] = new CMxCON0(this, "cm4con0", " Comparator C4 Control Register 0", 3, &comparator); comparator.cmxcon1[3] = new CMxCON1(this, "cm4con1", " Comparator C4 Control Register 1", 3, &comparator); } P16F1788::~P16F1788() { remove_sfr_register(comparator.cmxcon0[3]); remove_sfr_register(comparator.cmxcon1[3]); } void P16F1788::create_iopin_map() { package = new Package(28); if(!package) return; //createMCLRPin(1); // Now Create the package and place the I/O pins package->assign_pin(1, m_porte->addPin(new IO_bi_directional_pu("porte3"),3)); package->assign_pin(2, m_porta->addPin(new IO_bi_directional_pu("porta0"),0)); package->assign_pin(3, m_porta->addPin(new IO_bi_directional_pu("porta1"),1)); package->assign_pin(4, m_porta->addPin(new IO_bi_directional_pu("porta2"),2)); package->assign_pin(5, m_porta->addPin(new IO_bi_directional_pu("porta3"),3)); package->assign_pin(6, m_porta->addPin(new IO_bi_directional_pu("porta4"),4)); package->assign_pin(7, m_porta->addPin(new IO_bi_directional_pu("porta5"),5)); package->assign_pin(10, m_porta->addPin(new IO_bi_directional_pu("porta6"),6)); package->assign_pin(9, m_porta->addPin(new IO_bi_directional_pu("porta7"),7)); package->assign_pin(11, m_portc->addPin(new IO_bi_directional_pu("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional_pu("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional_pu("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional_pu("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional_pu("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional_pu("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional_pu("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional_pu("portc7"),7)); package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin( 20, 0); // Vdd package->assign_pin( 19, 0); // Vss package->assign_pin( 8, 0); // Vss } Processor * P16F1788::construct(const char *name) { P16F1788 *p = new P16F1788(name); p->create(2048, 256); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F1788::create(int ram_top, int eeprom_size) { ram_size = ram_top; create_iopin_map(); P16F178x::create(ram_top, eeprom_size); create_sfr_map(); // Set DeviceID if (m_configMemory && m_configMemory->getConfigWord(6)) m_configMemory->getConfigWord(6)->set(0x302b); } void P16F1788::create_sfr_map() { add_sfr_register(comparator.cmxcon0[3], 0x11a, RegisterValue(0x04,0)); add_sfr_register(comparator.cmxcon1[3], 0x11b, RegisterValue(0x00,0)); adcon1.setIOPin(12, &(*m_portb)[0]); adcon1.setIOPin(10, &(*m_portb)[1]); adcon1.setIOPin(8, &(*m_portb)[2]); adcon1.setIOPin(9, &(*m_portb)[3]); adcon1.setIOPin(11, &(*m_portb)[4]); adcon1.setIOPin(13, &(*m_portb)[5]); ssp.set_sckPin(&(*m_portc)[0]); ssp.set_sdiPin(&(*m_portc)[1]); ssp.set_sdoPin(&(*m_portc)[2]); ssp.set_ssPin(&(*m_portc)[3]); ssp.set_tris(m_trisc); // Pin values for default APFCON usart.set_TXpin(&(*m_portc)[4]); // TX pin usart.set_RXpin(&(*m_portc)[5]); // RX pin ccp1con.setIOpin(&(*m_portc)[5], &(*m_portc)[4], &(*m_portc)[3], &(*m_portc)[2]); apfcon1.set_ValidBits(0xff); apfcon2.set_ValidBits(0x07); // pins 0,1 not used for p16f1788 apfcon1.set_pins(2, &(*m_portc)[4], &(*m_porta)[0]); //USART TX Pin // pin 3 defined in p12f1822 apfcon1.set_pins(5, &(*m_portc)[3], &(*m_porta)[3]); //SSP SS apfcon1.set_pins(6, &(*m_portc)[2], &(*m_porta)[4]); //SSP SDO apfcon1.set_pins(7, &(*m_portc)[5], &(*m_porta)[1]); //USART RX Pin comparator.cmxcon1[3]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1], &(*m_portb)[5], &(*m_portb)[1]); comparator.cmxcon1[3]->set_INpinPos(&(*m_porta)[2], &(*m_portb)[6]); comparator.cmxcon1[3]->set_OUTpin(&(*m_portc)[7]); comparator.cmxcon0[3]->setBitMask(0xbf); comparator.cmxcon0[3]->setIntSrc(new InterruptSource(pir2, (1<<2))); comparator.cmxcon1[3]->setBitMask(0xff); } //======================================================================== P16F1823::P16F1823(const char *_name, const char *desc) : P12F1822(_name,desc), anselc(this, "anselc", "Analog Select port c") { m_portc = new PicPortBRegister(this,"portc","", intcon, 8,0x3f); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false, 0x3f); m_latc = new PicLatchRegister(this,"latc","",m_portc, 0x3f); m_wpuc = new WPU(this, "wpuc", "Weak Pull-up Register", m_portc, 0x3f); comparator.cmxcon0[1] = new CMxCON0(this, "cm2con0", " Comparator C2 Control Register 0", 1, &comparator); comparator.cmxcon1[1] = new CMxCON1(this, "cm2con1", " Comparator C2 Control Register 1", 1, &comparator); cpscon1.mValidBits = 0x0f; pir2->valid_bits |= PIR2v1822::C2IF; pir2->writable_bits |= PIR2v1822::C2IF; } P16F1823::~P16F1823() { delete_sfr_register(m_portc); delete_sfr_register(m_trisc); delete_sfr_register(m_latc); remove_sfr_register(comparator.cmxcon0[1]); remove_sfr_register(comparator.cmxcon1[1]); delete_sfr_register(m_wpuc); remove_sfr_register(&anselc); } void P16F1823::create_iopin_map() { package = new Package(14); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(13, m_porta->addPin(new IO_bi_directional_pu("porta0"),0)); package->assign_pin(12, m_porta->addPin(new IO_bi_directional_pu("porta1"),1)); package->assign_pin(11, m_porta->addPin(new IO_bi_directional_pu("porta2"),2)); package->assign_pin(4, m_porta->addPin(new IO_bi_directional_pu("porta3"),3)); package->assign_pin(3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4)); package->assign_pin(2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5)); package->assign_pin(10, m_portc->addPin(new IO_bi_directional_pu("portc0"),0)); package->assign_pin(9, m_portc->addPin(new IO_bi_directional_pu("portc1"),1)); package->assign_pin(8, m_portc->addPin(new IO_bi_directional_pu("portc2"),2)); package->assign_pin(7, m_portc->addPin(new IO_bi_directional_pu("portc3"),3)); package->assign_pin(6, m_portc->addPin(new IO_bi_directional_pu("portc4"),4)); package->assign_pin(5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5)); package->assign_pin( 1, 0); // Vdd package->assign_pin( 14, 0); // Vss } Processor * P16F1823::construct(const char *name) { P16F1823 *p = new P16F1823(name); p->create(0x7f, 256); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F1823::create(int ram_top, int eeprom_size) { create_iopin_map(); e = new EEPROM_EXTND(this, pir2); set_eeprom(e); osccon = new OSCCON_2(this, "osccon", "Oscillator Control Register"); pic_processor::create(); e->initialize(eeprom_size, 16, 16, 0x8000); e->set_intcon(intcon); e->get_reg_eecon1()->set_valid_bits(0xff); add_file_registers(0x20, ram_top, 0x00); _14bit_e_processor::create_sfr_map(); P12F1822::create_sfr_map(); create_sfr_map(); dsm_module.setOUTpin(&(*m_portc)[4]); dsm_module.setMINpin(&(*m_portc)[3]); dsm_module.setCIN1pin(&(*m_portc)[2]); dsm_module.setCIN2pin(&(*m_portc)[5]); // Set DeviceID if (m_configMemory && m_configMemory->getConfigWord(6)) m_configMemory->getConfigWord(6)->set(0x2720); } void P16F1823::create_sfr_map() { add_sfr_register(m_portc, 0x0e); add_sfr_register(m_trisc, 0x8e, RegisterValue(0x3f,0)); add_sfr_register(m_latc, 0x10e); add_sfr_register(comparator.cmxcon0[1], 0x113, RegisterValue(0x04,0)); add_sfr_register(comparator.cmxcon1[1], 0x114, RegisterValue(0x00,0)); add_sfr_register(&anselc, 0x18e, RegisterValue(0x0f,0)); add_sfr_register(m_wpuc, 0x20e, RegisterValue(0x3f,0),"wpuc"); anselc.config(0x0f, 4); anselc.setValidBits(0x0f); anselc.setAdcon1(&adcon1); ansela.setAnsel(&anselc); anselc.setAnsel(&ansela); adcon1.setIOPin(4, &(*m_portc)[0]); adcon1.setIOPin(5, &(*m_portc)[1]); adcon1.setIOPin(6, &(*m_portc)[2]); adcon1.setIOPin(7, &(*m_portc)[3]); ssp.set_sckPin(&(*m_portc)[0]); ssp.set_sdiPin(&(*m_portc)[1]); ssp.set_sdoPin(&(*m_portc)[2]); ssp.set_ssPin(&(*m_portc)[3]); ssp.set_tris(m_trisc); // Pin values for default APFCON usart.set_TXpin(&(*m_portc)[4]); // TX pin usart.set_RXpin(&(*m_portc)[5]); // RX pin ccp1con.setIOpin(&(*m_portc)[5], &(*m_portc)[4], &(*m_portc)[3], &(*m_portc)[2]); apfcon.set_ValidBits(0xec); // pins 0,1 not used for p16f1823 apfcon.set_pins(2, &(*m_portc)[4], &(*m_porta)[0]); //USART TX Pin // pin 3 defined in p12f1822 apfcon.set_pins(5, &(*m_portc)[3], &(*m_porta)[3]); //SSP SS apfcon.set_pins(6, &(*m_portc)[2], &(*m_porta)[4]); //SSP SDO apfcon.set_pins(7, &(*m_portc)[5], &(*m_porta)[1]); //USART RX Pin comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[1], &(*m_portc)[1], &(*m_portc)[2], &(*m_portc)[3]); comparator.cmxcon1[1]->set_INpinNeg(&(*m_porta)[1], &(*m_portc)[1], &(*m_portc)[2], &(*m_portc)[3]); comparator.cmxcon1[1]->set_INpinPos(&(*m_portc)[0]); comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[2]); comparator.cmxcon1[1]->set_OUTpin(&(*m_portc)[4]); comparator.cmxcon0[0]->setBitMask(0xf7); comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, (1<<5))); comparator.cmxcon0[1]->setBitMask(0xf7); comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, (1<<6))); comparator.cmxcon1[0]->setBitMask(0xf3); comparator.cmxcon1[1]->setBitMask(0xf3); cpscon0.set_pin(4, &(*m_portc)[0]); cpscon0.set_pin(5, &(*m_portc)[1]); cpscon0.set_pin(6, &(*m_portc)[2]); cpscon0.set_pin(7, &(*m_portc)[3]); sr_module.srcon1.set_ValidBits(0xff); sr_module.setPins(&(*m_porta)[1], &(*m_porta)[2], &(*m_portc)[4]); } //======================================================================== Processor * P16F1825::construct(const char *name) { P16F1825 *p = new P16F1825(name); p->create(0x7f, 256); p->create_invalid_registers (); p->create_symbols(); return p; } P16F1825::P16F1825(const char *_name, const char *desc) : P16F1823(_name, desc) { } P16F1825::~P16F1825() { delete_file_registers(0xc0, 0xef); delete_file_registers(0x120, 0x16f); delete_file_registers(0x1a0, 0x1ef); delete_file_registers(0x220, 0x26f); delete_file_registers(0x2a0, 0x2ef); delete_file_registers(0x320, 0x32f); delete_file_registers(0x420, 0x46f); delete_file_registers(0x4a0, 0x4ef); delete_file_registers(0x520, 0x56f); delete_file_registers(0x5a0, 0x5ef); } void P16F1825::create(int ram_top, int eeprom_size) { P16F1823::create(ram_top, eeprom_size); add_file_registers(0xc0, 0xef, 0x00); add_file_registers(0x120, 0x16f, 0x00); add_file_registers(0x1a0, 0x1ef, 0x00); add_file_registers(0x220, 0x26f, 0x00); add_file_registers(0x2a0, 0x2ef, 0x00); add_file_registers(0x320, 0x32f, 0x00); add_file_registers(0x420, 0x46f, 0x00); add_file_registers(0x4a0, 0x4ef, 0x00); add_file_registers(0x520, 0x56f, 0x00); add_file_registers(0x5a0, 0x5ef, 0x00); // Set DeviceID if (m_configMemory && m_configMemory->getConfigWord(6)) m_configMemory->getConfigWord(6)->set(0x2760); } gpsim-0.30.0/src/pm_rd.cc0000664000076400007640000000566013041763624012060 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 2006 Roy Rankin 2006 David Barnett This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include using namespace std; #include #include "trace.h" #include "pic-processor.h" #include "pm_rd.h" //------------------------------------------------------------------------ // // PM-related registers void PMCON1::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); new_value &= valid_bits; bool rd_rise = (bool)(new_value & ~value.get() & RD); value.put((value.get() & RD) | new_value); if (rd_rise) pm_rd->start_read(); } unsigned int PMCON1::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } PMCON1::PMCON1(Processor *pCpu, PM_RD *pRd) : sfr_register(pCpu, "pmcon1", "Program Memory Read Write Control"), pm_rd(pRd) { valid_bits = PMCON1_VALID_BITS; } unsigned int PMDATA::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } void PMDATA::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } PMDATA::PMDATA(Processor *pCpu, const char *pName) : sfr_register(pCpu, pName, "Program Memory Data") {} unsigned int PMADR::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } void PMADR::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } PMADR::PMADR(Processor *pCpu, const char *pName) : sfr_register(pCpu, pName, "Program Memory Address") {} // ---------------------------------------------------------- PM_RD::PM_RD(pic_processor *pCpu) : cpu(pCpu), pmcon1(pCpu,this), pmdata(pCpu,"pmdata"), pmdath(pCpu,"pmdath"), pmadr(pCpu,"pmadr"), pmadrh(pCpu,"pmadrh") { } void PM_RD::start_read() { rd_adr = pmadr.value.get() | (pmadrh.value.get() << 8); get_cycles().set_break(get_cycles().get() + READ_CYCLES, this); } void PM_RD::callback() { // read program memory if(pmcon1.value.get() & PMCON1::RD) { int opcode = cpu->pma->get_opcode(rd_adr); pmdata.value.put(opcode & 0xff); pmdath.value.put((opcode>>8) & 0xff); pmcon1.value.put(pmcon1.value.get() & (~PMCON1::RD)); } } gpsim-0.30.0/src/hexutils.h0000664000076400007640000000535613041763624012470 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__HEXUTILS_H__) #define __HEXUTILS_H__ #include "program_files.h" /* * IntelHexProgramFileType * Note that the code is in hexutils.cc * */ class IntelHexProgramFileType : public ProgramFileType { public: IntelHexProgramFileType(); int readihex16 (Processor *pProcessor, FILE * file); inline void writeihex16(Register **fr, gint32 size, FILE *file, gint32 offset) { writeihexN(2, fr, size, file, offset); } inline void writeihex8(Register **fr, gint32 size, FILE *file, gint32 offset) { writeihexN(1, fr, size, file, offset); } inline int readihex16(Register **fr, gint32 size, FILE *file, gint32 offset) { return readihexN(2, fr, size, file, offset); } inline int readihex8(Register **fr, gint32 size, FILE *file, gint32 offset) { return readihexN(1, fr, size, file, offset); } // ProgramFileType overrides virtual int LoadProgramFile(Processor **pProcessor, const char *pFilename, FILE *pFile, const char *pProcessorName); private: unsigned char checksum; bool isBigEndian; int getachar (FILE * file); unsigned char getbyte (FILE * file); unsigned int getword (FILE *file); void putachar (FILE * file, unsigned char c); void write_be_word(FILE * file, int w); void write_le_word(FILE * file, int w); int read_be_word(FILE * file); int read_le_word(FILE * file); // Compute checksum for extended address record inline int ext_csum(gint32 add) { return ((-(6 + (add & 0xff) + ((add >> 8) & 0xff)) & 0xff)); } void writeihexN(int bytes_per_word, Register **fr, gint32 size, FILE *file, gint32 out_base); int readihexN (int bytes_per_word, Register **fr, gint32 size, FILE * file, gint32 offset); // The following do the same function of ntohs and htons // these save having to include networking includes inline int ntoh16(int w) { return isBigEndian ? w : ((w >> 8) & 0xff) | ((w & 0xff) << 8);} inline int hton16(int w) { return isBigEndian ? w : ((w >> 8) & 0xff) | ((w & 0xff) << 8);} }; #endif // __HEXUTILS_H__ gpsim-0.30.0/src/eeprom.cc0000664000076400007640000005506413103566377012256 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 2006,2013 Roy Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include using namespace std; #include #include "../config.h" #include "trace.h" #include "pic-processor.h" #include "eeprom.h" #include "pir.h" #include "intcon.h" // EEPROM - Peripheral // // This object emulates the 14-bit core's EEPROM/FLASH peripheral // (such as the 16c84). // // It's main purpose is to provide a means by which the control // registers may communicate. // //------------------------------------------------------------------------ // // EEPROM related registers //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif void EECON1::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); new_value &= valid_bits; //cout << "EECON1::put new_value " << hex << new_value << " valid_bits " << valid_bits << '\n'; Dprintf(("new_value %x valid_bits %x\n", new_value, valid_bits)); if(new_value & WREN) { if(eeprom->get_reg_eecon2()->is_unarmed()) { eeprom->get_reg_eecon2()->unready(); value.put(value.get() | WREN); } // WREN is true and EECON2 is armed (which means that we've passed through here // once before with WREN true). Initiate an eeprom write only if WR is true and // RD is false AND EECON2 is ready else if( (new_value & WR) && !(new_value & RD) && (eeprom->get_reg_eecon2()->is_ready_for_write())) { value.put(value.get() | WR); eeprom->start_write(); } else if( (new_value & WR) && (new_value & RD)) { cout << "\n*** EECON1: write ignored " <get_reg_eecon2()->is_writing() ) { eeprom->get_reg_eecon2()->unarm(); } //cout << "EECON1: write is disabled\n"; } value.put((value.get() & (RD | WR)) | new_value); if ( (value.get() & RD) && !( value.get() & WR) ) { Dprintf(("RD true WR false EEPGD|CFFS %x\n", value.get() & (EEPGD|CFGS))); if(value.get() & (EEPGD|CFGS)) { eeprom->get_reg_eecon2()->read(); eeprom->start_program_memory_read(); //cout << "eestate " << eeprom->eecon2->eestate << '\n'; // read program memory } else { //eeprom->eedata->value = eeprom->rom[eeprom->eeadr->value]->get(); eeprom->get_reg_eecon2()->read(); eeprom->callback(); value.put(value.get() & ~RD); } } } unsigned int EECON1::get() { trace.raw(read_trace.get() | value.get()); //trace.register_read(address,value.get()); return(value.get()); } EECON1::EECON1(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { valid_bits = EECON1_VALID_BITS; } void EECON2::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); if( (eestate == EENOT_READY) && (0x55 == new_value)) { eestate = EEHAVE_0x55; } else if ( (eestate == EEHAVE_0x55) && (0xaa == new_value)) { eestate = EEREADY_FOR_WRITE; } else if ((eestate == EEHAVE_0x55) || (eestate == EEREADY_FOR_WRITE)) { eestate = EENOT_READY; } } unsigned int EECON2::get() { trace.raw(read_trace.get() | value.get()); return(0); } EECON2::EECON2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { ee_reset(); } unsigned int EEDATA::get() { trace.raw(read_trace.get() | value.get()); return(value.get()); } void EEDATA::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } EEDATA::EEDATA(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { } unsigned int EEADR::get() { trace.raw(read_trace.get() | value.get()); //trace.register_read(address,value.get()); return(value.get()); } void EEADR::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); value.put(new_value); } EEADR::EEADR(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) { } //------------------------------------------------------------------------ EEPROM_PIR::EEPROM_PIR(Processor *pCpu, PIR *pPir) : EEPROM(pCpu),m_pir(pPir), eeadrh(pCpu, "eeadrh", "EE Address High byte") { } EEPROM_PIR::~EEPROM_PIR() { pic_processor *pCpu = dynamic_cast(cpu); if (pCpu) pCpu->remove_sfr_register(&eeadrh); } void EEPROM_PIR::start_write() { get_cycles().set_break(get_cycles().get() + EPROM_WRITE_TIME, this); if ( rom_size > 256 ) wr_adr = eeadr.value.get() + (eeadrh.value.get() << 8); else wr_adr = eeadr.value.get(); wr_data = eedata.value.get(); eecon2.start_write(); } //------------------------------------------------------------------------ // Set the EEIF and clear the WR bits. void EEPROM_PIR::write_is_complete() { assert(m_pir != 0); eecon1.value.put( eecon1.value.get() & (~eecon1.WR)); Dprintf(("eecon1 0x%x\n", eecon1.value.get())); m_pir->set_eeif(); } void EEPROM_PIR::initialize(unsigned int new_rom_size) { eeadrh.set_eeprom(this); EEPROM::initialize(new_rom_size); } //---------------------------------------------------------- // // EE PROM // // There are many conditions that need to be verified against a real part: // 1) what happens if RD and WR are set at the same time? // > the simulator ignores both the read and the write. // 2) what happens if a RD is initiated while data is being written? // > the simulator ignores the read // 3) what happens if EEADR or EEDATA are changed while data is being written? // > the simulator will update these registers with the new values that // are written to them, however the write operation will be unaffected. // 4) if WRERR is set, will this prevent a valid write sequence from being initiated? // > the simulator views WRERR as a status bit // 5) if a RD is attempted after the eeprom has been prepared for a write // will this affect the RD or write? // > The simulator will proceed with the read and leave the write-enable state alone. // 6) what happens if WREN goes low while a write is happening? // > The simulator will complete the write and WREN will be cleared. EEPROM::EEPROM(Processor *pCpu) : name_str(0), cpu(pCpu), intcon(0), eecon1(pCpu,"eecon1","EE Control 1"), eecon2(pCpu,"eecon2","EE Control 2"), eedata(pCpu,"eedata","EE Data"), eeadr(pCpu,"eeadr", "EE Address"), rom(0), m_UiAccessOfRom(0), rom_data_size(1), rom_size(0) { } EEPROM::~EEPROM() { pic_processor *pCpu = dynamic_cast(cpu); if (pCpu) { pCpu->remove_sfr_register(&eedata); pCpu->remove_sfr_register(&eeadr); pCpu->remove_sfr_register(&eecon1); pCpu->remove_sfr_register(&eecon2); } for (unsigned int i = 0; i < rom_size; i++) delete rom[i]; delete [] rom; delete m_UiAccessOfRom; } Register *EEPROM::get_register(unsigned int address) { if(addressperipheral_interrupt(); } void EEPROM::start_program_memory_read() { cout << "ERROR: program memory flash should not be accessible\n"; bp.halt(); } void EEPROM::callback() { switch(eecon2.get_eestate()) { case EECON2::EEREAD: //cout << "eeread\n"; eecon2.unarm(); if ( get_address() < rom_size ) eedata.value.put(rom[get_address()]->get()); else { cout << "EEPROM read address is out of range " << hex << eeadr.value.get() << endl; bp.halt(); } eecon1.value.put(eecon1.value.get() & (~EECON1::RD)); break; case EECON2::EEWRITE_IN_PROGRESS: //cout << "eewrite\n"; if(wr_adr < rom_size) rom[wr_adr]->value.put(wr_data); else { cout << "EEPROM write address is out of range " << hex << wr_adr << '\n'; bp.halt(); } write_is_complete(); if (eecon1.value.get() & eecon1.WREN) eecon2.unready(); else eecon2.unarm(); break; eecon1.value.put(eecon1.value.get() & (~EECON1::WR)); default: cout << "EEPROM::callback() bad eeprom state " << eecon2.get_eestate() << '\n'; bp.halt(); } } void EEPROM::reset(RESET_TYPE by) { switch(by) { case POR_RESET: eecon1.value.put(0); // eedata & eeadr are undefined at power up eecon2.unarm(); break; default: break; } } void EEPROM::initialize(unsigned int new_rom_size) { rom_size = new_rom_size; // Let the control registers have a pointer to the peripheral in // which they belong. eecon1.set_eeprom(this); eecon2.set_eeprom(this); eedata.set_eeprom(this); eeadr.set_eeprom(this); // Create the rom rom = (Register **) new char[sizeof (Register *) * rom_size]; assert(rom != 0); // Initialize the rom char str[100]; for (unsigned int i = 0; i < rom_size; i++) { snprintf (str, sizeof(str), "eereg 0x%02x", i); rom[i] = new Register(cpu,str); rom[i]->address = i; rom[i]->value.put(0); rom[i]->alias_mask = 0; } if(cpu) { //cpu->ema.set_cpu(cpu); cpu->ema.set_Registers(rom, rom_size); m_UiAccessOfRom = new RegisterCollection(cpu, "eeData", rom, rom_size); } } //---------------------------------------- // Save the current state of the eeprom. This is used to reconstitute // the trace buffer. void EEPROM::save_state() { if(!rom || !rom_size) return; for (unsigned int i = 0; i < rom_size; i++) if(rom[i]) rom[i]->put_trace_state(rom[i]->value); } void EEPROM::set_intcon(INTCON *ic) { intcon = ic; } void EEPROM::dump() { unsigned int i, j, reg_num,v; cout << " " << hex; // Column labels for (i = 0; i < 16; i++) cout << setw(2) << setfill('0') << i << ' '; cout << '\n'; for (i = 0; i < rom_size/16; i++) { cout << setw(2) << setfill('0') << i << ": "; for (j = 0; j < 16; j++) { reg_num = i * 16 + j; if(reg_num < rom_size) { v = rom[reg_num]->get_value(); cout << setw(2) << setfill('0') << v << ' '; } else cout << "-- "; } cout << " "; for (j = 0; j < 16; j++) { reg_num = i * 16 + j; if(reg_num < rom_size) { v = rom[reg_num]->get_value(); if( (v >= ' ') && (v <= 'z')) cout.put(v); else cout.put('.'); } } cout << '\n'; } } //------------------------------------------------------------------------ EEPROM_WIDE::EEPROM_WIDE(Processor *pCpu, PIR *pPir) : EEPROM_PIR(pCpu,pPir), eedatah(pCpu,"eedatah", "EE Data High byte") { } EEPROM_WIDE::~EEPROM_WIDE() { pic_processor *pCpu = dynamic_cast(cpu); pCpu->remove_sfr_register(&eedatah); } void EEPROM_WIDE::start_write() { get_cycles().set_break(get_cycles().get() + EPROM_WRITE_TIME, this); wr_adr = eeadr.value.get() + (eeadrh.value.get() << 8); wr_data = eedata.value.get() + (eedatah.value.get() << 8); eecon2.start_write(); } void EEPROM_WIDE::start_program_memory_read() { rd_adr = eeadr.value.get() | (eeadrh.value.get() << 8); get_cycles().set_break(get_cycles().get() + 2, this); } void EEPROM_WIDE::callback() { //cout << "eeprom call back\n"; Dprintf(("state 0x%x\n", eecon2.get_eestate())); switch(eecon2.get_eestate()) { case EECON2::EEREAD: //cout << "eeread\n"; eecon2.unarm(); if(eecon1.value.get() & EECON1::EEPGD) { // read program memory int opcode = cpu->pma->get_opcode(rd_adr); eedata.value.put(opcode & 0xff); eedatah.value.put((opcode>>8) & 0xff); } else { if (eeadr.value.get() < rom_size) eedata.value.put(rom[eeadr.value.get()]->get()); else { cout << "WIDE_EEPROM read address is out of range " << hex << eeadr.value.get() << '\n'; bp.halt(); } } eecon1.value.put(eecon1.value.get() & (~EECON1::RD)); break; case EECON2::EEWRITE_IN_PROGRESS: //cout << "eewrite\n"; Dprintf(("EEWRITE_IN_PROGRESS eecon1 %x\n", eecon1.value.get())); if(eecon1.value.get() & EECON1::EEPGD) // write program memory { cpu->init_program_memory_at_index(wr_adr, wr_data); } else // write eeprom memory { Dprintf(("wr_adr 0x%x rom_size 0x%x data 0x%x\n", wr_adr, rom_size, wr_data)); if(wr_adr < rom_size) { rom[wr_adr]->value.put(wr_data); } else { cout << "WIDE_EEPROM write address is out of range " << hex << wr_adr << '\n'; bp.halt(); } } write_is_complete(); if (eecon1.value.get() & eecon1.WREN) eecon2.unready(); else eecon2.unarm(); break; default: cout << "EEPROM_WIDE::callback() bad eeprom state " << eecon2.get_eestate() << '\n'; bp.halt(); } } void EEPROM_WIDE::initialize(unsigned int new_rom_size) { eedatah.set_eeprom(this); eeadrh.set_eeprom(this); EEPROM::initialize(new_rom_size); } void EEPROM_PIR::callback() { switch(eecon2.get_eestate()) { case EECON2::EEREAD: //cout << "eeread\n"; eecon2.unarm(); if(eecon1.value.get() & EECON1::EEPGD) { cout << "Should not be possible to get here\n"; } else { if ( get_address() < rom_size ) eedata.value.put(rom[get_address()]->get()); else { cout << "LONG_EEPROM read address is out of range " << hex << eeadr.value.get() + (eeadrh.value.get() << 8) << '\n'; bp.halt(); } } eecon1.value.put(eecon1.value.get() & (~EECON1::RD)); break; case EECON2::EEWRITE_IN_PROGRESS: //cout << "eewrite\n"; if(eecon1.value.get() & EECON1::EEPGD) // write program memory { cout << "EEPROM_PIR can't do program writes\n"; } else // read eeprom memory { if(wr_adr < rom_size) { rom[wr_adr]->value.put(wr_data); } else { cout << "LONG_EEPROM write address is out of range " << hex << wr_adr << '\n'; bp.halt(); } } write_is_complete(); if (eecon1.value.get() & eecon1.WREN) eecon2.unready(); else eecon2.unarm(); break; default: cout << "EEPROM_LONG::callback() bad eeprom state " << eecon2.get_eestate() << '\n'; bp.halt(); } } //------------------------------------------------------------------------ // EEPROM_EXTND is based on data sheets for 16F193X and // 12(L)F1822/PIC16(L)F1823. It has the following features // // read/write with 16 bit data path // performs I/O to eeprom, program and configuration memory // supports data latches for writing to program and Configuration memory // Performs block erase of program and Configuration memory // Supports write protect of program memory // EEPROM_EXTND::EEPROM_EXTND(Processor *pCpu, PIR *pPir) : EEPROM_WIDE(pCpu,pPir), write_latches(NULL), prog_wp(0) { } EEPROM_EXTND::~EEPROM_EXTND() { if (write_latches != NULL) delete[] write_latches; } void EEPROM_EXTND::initialize( unsigned int new_rom_size, int block_size, int num_latches, unsigned int cfg_word_base, bool _has_eeadrh) { EEPROM_WIDE::initialize(new_rom_size); erase_block_size = block_size; num_write_latches = num_latches; if (write_latches != NULL) delete[] write_latches; write_latches = new unsigned int [num_latches]; for(int i = 0; i < num_latches; i++) write_latches[i] = LATCH_MT; config_word_base = cfg_word_base; has_eeadrh = _has_eeadrh; } void EEPROM_EXTND::start_program_memory_read() { rd_adr = eeadr.value.get() | (eeadrh.value.get() << 8); get_cycles().set_break(get_cycles().get() + 2, this); cpu_pic->pc->increment(); } void EEPROM_EXTND::start_write() { eecon1.value.put( eecon1.value.get() | eecon1.WRERR); wr_adr = eeadr.value.get() + (eeadrh.value.get() << 8); wr_data = eedata.value.get() + (eedatah.value.get() << 8); eecon2.start_write(); if (eecon1.value.get() & (EECON1::EEPGD|EECON1::CFGS)) { // stop execution fo 2 ms get_cycles().set_break(get_cycles().get() + (guint64)(.002*get_cycles().instruction_cps()), this); cpu_pic->pc->increment(); bp.set_pm_write(); cpu_pic->pm_write(); } else get_cycles().set_break(get_cycles().get() + EPROM_WRITE_TIME, this); } void EEPROM_EXTND::callback() { int index; bool write_error = false; //cout << "eeprom call back\n"; bp.clear_pm_write(); switch(eecon2.get_eestate()) { case EECON2::EEREAD: //cout << "eeread\n"; eecon2.unarm(); if(eecon1.value.get() & EECON1::EEPGD) { // read program memory int opcode = cpu->pma->get_opcode(rd_adr); eedata.value.put(opcode & 0xff); eedatah.value.put((opcode>>8) & 0xff); } else if (eecon1.value.get() & EECON1::CFGS) // Read Config data { unsigned int read_data; read_data = cpu->get_config_word(config_word_base | rd_adr); if (read_data == 0xffffffff) read_data = 0; eedata.value.put(read_data & 0xff); eedatah.value.put((read_data>>8) & 0xff); } else // read eeprom data { if (eeadr.value.get() < rom_size) eedata.value.put(rom[eeadr.value.get()]->get()); else { cout << "EXTND_EEPROM read address is out of range " << hex << eeadr.value.get() << '\n'; bp.halt(); } } eecon1.value.put(eecon1.value.get() & (~EECON1::RD)); break; case EECON2::EEWRITE_IN_PROGRESS: //cout << "eewrite\n"; switch(eecon1.value.get() & (EECON1::EEPGD|EECON1::CFGS|EECON1::LWLO|EECON1::FREE)) { case EECON1::EEPGD: // write program memory bp.clear_pm_write(); index = wr_adr & (num_write_latches - 1); wr_adr &= ~(num_write_latches - 1); write_latches[index] = wr_data; if (wr_adr >= prog_wp) { for(int i = 0; i < num_write_latches; i++) { if (write_latches[i] != LATCH_MT) { cpu->init_program_memory(cpu->map_pm_index2address(wr_adr+i), write_latches[i]); write_latches[i] = LATCH_MT; } } } else { printf("Warning: attempt to Write protected Program memory 0x%x\n", wr_adr); write_error = true; bp.halt(); gi.simulation_has_stopped(); } break; case EECON1::EEPGD|EECON1::LWLO: // write to latches case EECON1::CFGS|EECON1::LWLO: // write to latches index = wr_adr & (num_write_latches - 1); write_latches[index] = wr_data; break; case EECON1::CFGS: // write config word memory index = wr_adr & (num_write_latches - 1); wr_adr &= ~(num_write_latches - 1); write_latches[index] = wr_data; for(int i = 0; i < num_write_latches; i++) { if (write_latches[i] != LATCH_MT) // was latch modified? { unsigned int cfg_add = config_word_base | (wr_adr+i); index = cpu->get_config_index(cfg_add); if (index < 0) { printf("EEWRITE No config word at 0x%x\n", cfg_add); write_error = true; } else if (!cpu_pic->getConfigMemory()->getConfigWord(index)->isEEWritable()) { printf("EEWRITE config word at 0x%x write protected\n", cfg_add); write_error = true; } else { Dprintf(("write config data cfg_add %x wr_data %x\n", cfg_add, wr_data)); if(!cpu->set_config_word(cfg_add, wr_data)) { printf("EEWRITE unknown failure to write %x to 0x%x\n", wr_data, cfg_add); write_error = true; } } write_latches[i] = LATCH_MT; } } break; case EECON1::CFGS|EECON1::FREE: // free Configuration memory row // This row erase simply skips non-existant or write protected // configuration words wr_adr &= ~(erase_block_size-1); for(int i = 0; i < erase_block_size; i++) { unsigned int cfg_add = config_word_base | (wr_adr+i); index = cpu->get_config_index(cfg_add); if (index >= 0 && cpu_pic->getConfigMemory()->getConfigWord(index)->isEEWritable()) { cpu->set_config_word(cfg_add, 0); } } break; case EECON1::EEPGD|EECON1::FREE: // free program memory row wr_adr &= ~(erase_block_size-1); if (wr_adr >= prog_wp) { for(int i = 0; i < erase_block_size; i++) //cpu->erase_program_memory(cpu->map_pm_index2address(wr_adr+i)); cpu->init_program_memory(cpu->map_pm_index2address(wr_adr+i), 0); } else { printf("Warning: attempt to row erase protected Program memory\n"); write_error = true; bp.halt(); gi.simulation_has_stopped(); } break; case EECON1::LWLO: // LWLO ignored to eeprom default: // write to eeprom if(wr_adr < rom_size) { rom[wr_adr]->value.put(wr_data); } else { cout << "EXTND_EEPROM write address is out of range " << hex << wr_adr << '\n'; write_error = true; bp.halt(); } break; } if (!write_error) eecon1.value.put( eecon1.value.get() & ~ eecon1.WRERR); write_is_complete(); if (eecon1.value.get() & eecon1.WREN) eecon2.unready(); else eecon2.unarm(); break; default: cout << "EEPROM_EXTND::callback() bad eeprom state " << eecon2.get_eestate() << '\n'; bp.halt(); } } gpsim-0.30.0/src/pir.h0000664000076400007640000005313413103351720011377 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef PIR_H #define PIR_H #include "assert.h" #include "pie.h" class INTCON; //--------------------------------------------------------- // PIR Peripheral Interrupt register base class for PIR1 & PIR2 class PIR : public sfr_register { protected: INTCON *intcon; PIE *pie; sfr_register *ipr; public: int valid_bits; int writable_bits; PIR(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *, int _valid_bits); // The PIR base class supports no PIR bits directly virtual void clear_sspif(){} virtual void clear_sppif(){} virtual void clear_rcif(){} virtual void clear_txif(){} virtual void set_adif(){} virtual void set_bclif(){} virtual void set_ccpif(){} virtual void set_cmif(){} virtual void set_c1if(){fprintf(stderr, "RRR set_c1if FIX\n");} virtual void set_c2if(){fprintf(stderr, "RRR set_c2if FIX\n");} virtual void set_c3if(){fprintf(stderr, "RRR set_c3if FIX\n");} virtual void set_c4if(){fprintf(stderr, "RRR set_c4if FIX\n");} virtual void set_c5if(){fprintf(stderr, "RRR set_c5if FIX\n");} virtual void set_eccp1if(){} virtual void set_eeif(){} virtual void set_errif(){} virtual void set_irxif(){} virtual void set_lvdif(){} virtual void set_pspif(){} virtual void set_rcif(){} virtual void set_rxb0if(){} virtual void set_rxb1if(){} virtual void set_sspif(){} virtual void set_sppif(){fprintf(stderr, "set_sppif FIX\n");} virtual void set_tmr1if(){} virtual void set_tmr1gif(){} virtual void set_tmr2if(){} virtual void set_tmr3if(){ fprintf(stderr, "set_tmr3if FIX\n");} virtual void set_txb0if(){} virtual void set_txb1if(){} virtual void set_txb2if(){} virtual void set_txif(){} virtual void set_wakif(){} virtual void set_usbif(){} virtual unsigned int get_txif() { return 0;} virtual unsigned int get_rcif() { return 0;} virtual unsigned int get_sspif() { return 0;} virtual unsigned int get_sppif() { return 0;} /// A generic method to set an interrupt bit by mask virtual void set(int mask) { put(get() | mask); } /// Obtain interrupt request state, as a mask of priorities if relevant virtual int interrupt_status(); virtual void put(unsigned int new_value); virtual void setInterrupt(unsigned int bitMask); virtual void setPeripheralInterrupt(); void set_intcon(INTCON *); void set_pie(PIE *); void set_ipr(sfr_register *); }; /*--------------------------------------------------------- // InterruptSource this is an alternative to the set_xxif method which a> is becoming unwieldly b> removes hard coding to allow multiple instantiation of classes with different interrupts */ class InterruptSource { public: InterruptSource(PIR *_pir, unsigned int bitMask); void Trigger(); void Clear(); unsigned int Get() { return m_pir->value.get() & m_bitMask;} void release(); // called when source is no longer needed. private: PIR *m_pir; unsigned int m_bitMask; }; //--------------------------------------------------------- // PIR1 Peripheral Interrupt register # 1 // // This is version 1 of the PIR1 register - as seen on the 16f62x class PIR1v1 : public PIR { public: enum { TMR1IF = 1<<0, TMR2IF = 1<<1, CCP1IF = 1<<2, SSPIF = 1<<3, TXIF = 1<<4, RCIF = 1<<5, CMIF = 1<<6, // 16f62x EEIF = 1<<7 // 16f62x }; virtual void set_tmr1if() { put(get() | TMR1IF); } virtual void set_tmr2if() { put(get() | TMR2IF); } virtual void set_ccpif() { put(get() | CCP1IF); } virtual void set_sspif() { put(get() | SSPIF); } virtual void set_txif(); virtual void set_rcif(); virtual void set_cmif(); virtual void set_c1if(){set_cmif();} virtual void set_c2if(){set_cmif();} virtual void set_eeif(); virtual unsigned int get_sspif() { return value.get() & SSPIF; } void clear_sspif(); unsigned int get_txif() { return value.get() & TXIF; } void clear_txif(); unsigned int get_rcif() { return value.get() & RCIF; } virtual void clear_rcif(); PIR1v1(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR1 Peripheral Interrupt register # 1 // // This is version 2 of the PIR1 register - as seen on the 18xxxx devices // and devices like the 16c63a. class PIR1v2 : public PIR { public: enum { TMR1IF = 1<<0, TMR2IF = 1<<1, CCP1IF = 1<<2, SSPIF = 1<<3, TXIF = 1<<4, RCIF = 1<<5, ADIF = 1<<6, // 18cxxx PSPIF = 1<<7, SPPIF = 1<<7 }; virtual void set_tmr1if() { put(get() | TMR1IF); } virtual void set_tmr2if() { put(get() | TMR2IF); } virtual void set_ccpif() { put(get() | CCP1IF); } virtual void set_sspif(); unsigned int get_sspif() { return value.get() & SSPIF; } virtual void clear_sspif(); virtual void set_txif(); virtual void set_rcif(); virtual void set_adif() { put(get() | ADIF); } unsigned int get_sppif() { return value.get() & SPPIF; } virtual void set_sppif(); virtual void set_pspif(); virtual unsigned int get_txif() { return value.get() & TXIF; } virtual void clear_txif(); unsigned int get_rcif() { return value.get() & RCIF; } virtual void clear_rcif(); PIR1v2(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR1 Peripheral Interrupt register # 1 // // This is version 3 of the PIR1 register - as seen on the p16f630 devices class PIR1v3 : public PIR { public: enum { TMR1IF = 1<<0, TMR2IF = 1<<1, //16f684 OSFIF = 1<<2, //16f684 CMIF = 1<<3, C1IF = 1<<3, //16f684 C2IF = 1<<4, //16f684 CCP1IF = 1<<5, //16f684 ADIF = 1<<6, EEIF = 1<<7 }; virtual void set_tmr1if(); virtual void set_tmr2if(); virtual void set_cmif(); virtual void set_adif(); virtual void set_eeif(); virtual void set_c1if(); virtual void set_c2if(); virtual void set_ccpif() { put(get() | CCP1IF); } PIR1v3(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR1 Peripheral Interrupt register # 1 // // This is version 4 of the PIR1 register - as seen on the p16f91x devices class PIR1v4 : public PIR { public: enum { TMR1IF = 1<<0, TMR2IF = 1<<1, CCP1IF = 1<<2, SSPIF = 1<<3, TXIF = 1<<4, RCIF = 1<<5, ADIF = 1<<6, EEIF = 1<<7 }; virtual void set_tmr1if(){ put(get() | TMR1IF); } virtual void set_tmr2if(){ put(get() | TMR2IF); } virtual void set_ccpif() { put(get() | CCP1IF); } virtual void set_sspif() { put(get() | SSPIF); } virtual void set_txif(); virtual void set_rcif(); virtual void clear_txif(); virtual void clear_rcif(); virtual unsigned int get_txif() { return value.get() & TXIF; } virtual unsigned int get_rcif() { return value.get() & RCIF; } virtual void set_adif() { put(get() | ADIF); } virtual void set_eeif() { put(get() | EEIF); } PIR1v4(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR2 Peripheral Interrupt register # 2 // // This is version 1 of the PIR1 register - as seen on the 16f62x class PIR2v1 : public PIR { public: enum { CCP2IF = 1<<0 }; virtual void set_ccpif() { put(get() | CCP2IF); } PIR2v1(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR2 Peripheral Interrupt register # 2 // // This is version 2 of the PIR2 register - as seen on the 18xxxx devices // and devices like the 16c63a. class PIR2v2 : public PIR { public: enum { CCP2IF = 1<<0, ECCP1IF = 1<<0, /* only on the PIC18F4xx devices */ TMR3IF = 1<<1, LVDIF = 1<<2, HLVDIF = 1<<2, /* 18f26k22 */ BCLIF = 1<<3, EEIF = 1<<4, C2IF = 1<<5, /* 18f14k22 */ C1IF = 1<<6, /* 18f14k22 */ CMIF = 1<<6, /* PIC16F87xA, PIC18F4xx devices */ OSCFIF = 1<<7 /* 18f14k22 */ }; virtual void set_eccp1if() { put(get() | ECCP1IF); } virtual void set_ccpif() /* RP - needs to define set_ccpif too! */ { put(get() | CCP2IF); } virtual void set_tmr3if() { put(get() | TMR3IF); } virtual void set_lvdif() { put(get() | LVDIF); } virtual void set_bclif(); virtual void set_eeif(); virtual void set_cmif(); virtual void set_c1if(){ set_cmif();} virtual void set_c2if(){ set_cmif();} PIR2v2(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR2 Peripheral Interrupt register # 3 // // This is version 2 of the PIR2 register - as seen on the 16f88x devices class PIR2v3 : public PIR { public: enum { CCP2IF = 1<<0, ULPWUIF = 1<<2, BCLIF = 1<<3, EEIF = 1<<4, C1IF = 1<<5, C2IF = 1<<6, OSFIF = 1<<7 }; virtual void set_ccpif() { put(get() | CCP2IF); } virtual void set_bclif(); virtual void set_eeif(); virtual void set_c1if(); virtual void set_c2if(); PIR2v3(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR2 Peripheral Interrupt register # 3 // // This is version 4 of the PIR2 register - as seen on the 18F4455 devices class PIR2v4 : public PIR { public: enum { CCP2IF = 1<<0, TMR3IF = 1<<1, HLVDIF = 1<<2, BCLIF = 1<<3, EEIF = 1<<4, USBIF = 1<<5, CMIF = 1<<6, OSCFIF = 1<<7 }; virtual void set_ccpif(){ put(get() | CCP2IF); } virtual void set_tmr3if() { put(get() | TMR3IF); } virtual void set_hlvdif() { put(get() | HLVDIF); } virtual void set_oscfif() { put(get() | OSCFIF); } virtual void set_bclif(); virtual void set_eeif(); virtual void set_usbif(); virtual void set_cmif(); virtual void set_c1if(){ set_cmif(); } virtual void set_c2if(){ set_cmif(); } PIR2v4(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR2 Peripheral Interrupt register // // This is version 5 of the PIR2 register - as seen on the p16f91x devices class PIR2v5 : public PIR { public: enum { CCP2IF = 1<<0, LVDIF = 1<<2, LCDIF = 1<<4, C1IF = 1<<5, C2IF = 1<<6, OSFIF = 1<<7 }; virtual void set_ccp2if() { put(get() | CCP2IF); } virtual void set_lvdif() { put(get() | LVDIF); } virtual void set_lcdif() { put(get() | LCDIF); } virtual void set_c1if() { put(get() | C1IF); } virtual void set_c2if() { put(get() | C2IF); } virtual void set_osfif() { put(get() | OSFIF); } PIR2v5(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR3 Peripheral Interrupt register # 3 // // This is version 1 of the PIR3 register - as seen on the 18F6520 devices class PIR3v1 : public PIR { public: enum { CCP3IF = 1<<0, CCP4IF = 1<<1, CCP5IF = 1<<2, TMR4IF = 1<<3, TXIF = 1<<4, RCIF = 1<<5 }; virtual void set_ccpif() /* RP - needs to define set_ccpif too! */ { put(get() | CCP3IF); } virtual void set_tmr2if() { put(get() | TMR4IF); } virtual void set_txif(); virtual void set_rcif(); virtual unsigned int get_txif() { return value.get() & TXIF; } virtual void clear_txif(); unsigned int get_rcif() { return value.get() & RCIF; } virtual void clear_rcif(); PIR3v1(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; //--------------------------------------------------------- // PIR3 Peripheral Interrupt register # 3 // // This is version 2 of the PIR3 register - as seen on the 18F248 devices // Perhaps other devices too - it contains bits for the CAN device class PIR3v2 : public PIR { public: enum { RXB0IF = 1<<0, RXB1IF = 1<<1, TXB0IF = 1<<2, TXB1IF = 1<<3, TXB2IF = 1<<4, ERRIF = 1<<5, WAKIF = 1<<6, IRXIF = 1<<7 }; virtual void set_rxb0if() { put(get() | RXB0IF); } virtual void set_rxb1if() { put(get() | RXB1IF); } virtual void set_txb0if() { put(get() | TXB0IF); } virtual void set_txb1if() { put(get() | TXB1IF); } virtual void set_txb2if() { put(get() | TXB2IF); } virtual void set_errif() { put(get() | ERRIF); } virtual void set_wakif() { put(get() | WAKIF); } virtual void set_irxif() { put(get() | IRXIF); } PIR3v2(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; class PIR3v3 : public PIR { public: enum { TMR1GIF = 1<<0, TMR3GIF = 1<<1, TMR5GIF = 1<<2, CTMUIF = 1<<3, TX2IF = 1<<4, RC2IF = 1<<5, BCL2IF = 1<<6, SSP2IF = 1<<7 }; PIR3v3(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; /*--------------------------------------------------------- PIR2 Peripheral Interrupt register # 2 This is version 1 of the PIR4 register - as seen on the 18f26k22 */ class PIR4v1: public PIR { public: enum { CCP3IF = 1<<0, CCP4IF = 1<<1, CCP5IF = 1<<2, }; virtual void set_ccp3if() { put(get() | CCP3IF); } virtual void set_ccp4if() { put(get() | CCP4IF); } virtual void set_ccp5if() { put(get() | CCP5IF); } PIR4v1(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; class PIR5v1: public PIR { public: enum { TMR4IF = 1<<0, TMR5IF = 1<<1, TMR6IF = 1<<2, }; virtual void set_tmr4if() { put(get() | TMR4IF); } virtual void set_tmr5if() { put(get() | TMR5IF); } virtual void set_tmr6if() { put(get() | TMR6IF); } PIR5v1(Processor *pCpu, const char *pName, const char *pDesc, INTCON *, PIE *); }; /* * PIR_SET defines an interface to some common interrupt capabilities. * PIR_SET is a pure virtual class - you must instantiate a more specific * version of PIR_SET. * * The idea behind PIR_SET is to hide the location of the interrupt bits. * in some cases, a bit might be in PIR1, in others it might be in PIR2. * Instead of accessing the register directly, you go through PIR_SET * and it will find the proper PIR register. */ class PIR_SET { public: virtual ~PIR_SET() { } virtual int interrupt_status() { return 0; } // uart stuff virtual bool get_txif() { return false; } virtual void set_txif() {} virtual void clear_txif() {} virtual bool get_rcif() { return false; } virtual void set_rcif() {} virtual void clear_rcif() {} // ssp stuff virtual bool get_sspif() { return false; } virtual void clear_sspif() {} virtual void set_sspif() {} virtual void set_bclif() {} virtual void set_sppif() {} virtual void set_pspif() {} virtual void set_cmif() {} virtual void set_c1if() {} virtual void set_c2if() {} virtual void set_c3if() {} virtual void set_c4if() {} // eeprom stuff virtual void set_eeif() {} // CCP stuff virtual void set_ccpif() {} // Timer stuff virtual void set_tmr1if() {} virtual void set_tmr1gif() {} virtual void set_tmr2if() {} virtual void set_adif() {} }; //---------------------------------------- // Supports 1 or 2 Pir version 1 registers class PIR_SET_1 : public PIR_SET { public: PIR_SET_1() { pir1 = 0; pir2 = 0;} virtual ~PIR_SET_1() { } void set_pir1(PIR *p1) { pir1 = p1; } void set_pir2(PIR *p2) { pir2 = p2; } virtual int interrupt_status() { assert(pir1 != 0); if (pir2 != 0) return (pir1->interrupt_status() | pir2->interrupt_status()); else return (pir1->interrupt_status()); } // uart stuff virtual bool get_txif() { assert(pir1 != 0); return (pir1->get_txif() != 0); } virtual void set_txif() { assert(pir1 != 0); pir1->set_txif(); } virtual void clear_txif() { assert(pir1 != 0); pir1->clear_txif(); } virtual bool get_rcif() { assert(pir1 != 0); return (pir1->get_rcif() != 0); } virtual void set_rcif() { assert(pir1 != 0); pir1->set_rcif(); } virtual void clear_rcif() { assert(pir1 != 0); pir1->clear_rcif(); } // ssp stuff virtual bool get_sspif() { assert(pir1 != 0); return (pir1->get_sspif() != 0); } virtual void set_sspif() { assert(pir1 != 0); pir1->set_sspif(); } virtual void clear_sspif() { assert(pir1 != 0); pir1->clear_sspif(); } // eeprom stuff virtual void set_eeif() { assert(pir1 != 0); pir1->set_eeif(); } // CCP stuff virtual void set_ccpif() { assert(pir1 != 0); pir1->set_ccpif(); } // Timer stuff virtual void set_tmr1if() { assert(pir1 != 0); pir1->set_tmr1if(); } virtual void set_tmr2if() { assert(pir1 != 0); pir1->set_tmr2if(); } // A/D stuff - not part of base PIR_SET class virtual void set_adif() { assert(pir1 != 0); pir1->set_adif(); } // Comparator virtual void set_cmif() { assert(pir1 != 0); pir1->set_cmif(); } virtual void set_c1if() { assert(pir1 != 0); pir1->set_c1if(); } virtual void set_c2if() { assert(pir1 != 0); pir1->set_c2if(); } virtual void set_c3if() { assert(pir1 != 0); pir1->set_c3if(); } virtual void set_c4if() { assert(pir1 != 0); pir1->set_c4if(); } private: PIR *pir1; PIR *pir2; }; // Supports 1, 2 ,3, 4 or 5 Pir registers class PIR_SET_2 : public PIR_SET { public: PIR_SET_2() { pir1 = 0; pir2 = 0; pir3 = 0; pir4 = 0; pir5 = 0;} virtual ~PIR_SET_2() { } void set_pir1(PIR *p1) { pir1 = p1; } void set_pir2(PIR *p2) { pir2 = p2; } void set_pir3(PIR *p3) { pir3 = p3; } void set_pir4(PIR *p4) { pir4 = p4; } void set_pir5(PIR *p5) { pir5 = p5; } virtual int interrupt_status() { assert(pir1 != 0); int result = pir1->interrupt_status(); if ( pir2 != 0 ) result |= pir2->interrupt_status(); if ( pir3 != 0 ) result |= pir3->interrupt_status(); if ( pir4 != 0 ) result |= pir4->interrupt_status(); if ( pir5 != 0 ) result |= pir5->interrupt_status(); return result; } // uart stuff virtual bool get_txif() { assert(pir1 != 0); return (pir1->get_txif() != 0); } virtual void set_txif() { assert(pir1 != 0); pir1->set_txif(); } virtual void clear_txif() { assert(pir1 != 0); pir1->clear_txif(); } virtual bool get_rcif() { assert(pir1 != 0); return (pir1->get_rcif() != 0); } virtual void set_rcif() { assert(pir1 != 0); pir1->set_rcif(); } virtual void clear_rcif() { assert(pir1 != 0); pir1->clear_rcif(); } // ssp stuff virtual bool get_sspif() { assert(pir1 != 0); return (pir1->get_sspif() != 0); } virtual void set_sspif() { assert(pir1 != 0); pir1->set_sspif(); } virtual void clear_sspif() { assert(pir1 != 0); pir1->clear_sspif(); } // spp stuff virtual bool get_sppif() { assert(pir1 != 0); return (pir1->get_sppif() != 0); } virtual void set_sppif() { assert(pir1 != 0); pir1->set_sppif(); } virtual void clear_sppif() { assert(pir1 != 0); pir1->clear_sppif(); } // eeprom stuff virtual void set_eeif() { assert(pir2 != 0); pir2->set_eeif(); } // CCP stuff virtual void set_ccpif() { assert(pir1 != 0); pir1->set_ccpif(); } // Timer stuff virtual void set_tmr1if() { assert(pir1 != 0); pir1->set_tmr1if(); } virtual void set_tmr1gif() { assert(pir1 != 0); pir1->set_tmr1gif(); } virtual void set_tmr2if() { assert(pir1 != 0); pir1->set_tmr2if(); } // A/D stuff - not part of base PIR_SET class virtual void set_adif() { assert(pir1 != 0); pir1->set_adif(); } // Comparator virtual void set_cmif() { assert(pir2 != 0); pir2->set_cmif(); } virtual void set_c1if() { assert(pir2 != 0); pir2->set_c1if(); } virtual void set_c2if() { assert(pir2 != 0); pir2->set_c2if(); } virtual void set_c3if() { assert(pir2 != 0); pir2->set_c3if(); } virtual void set_c4if() { assert(pir2 != 0); pir2->set_c4if(); } // I2C master virtual void set_bclif() { assert(pir2 != 0); pir2->set_bclif(); } // Parallel Slave Port virtual void set_pspif() { assert(pir1 != 0); pir1->set_pspif(); } private: PIR *pir1; PIR *pir2; PIR *pir3; PIR *pir4; PIR *pir5; }; #endif /* PIR_H */ gpsim-0.30.0/src/makefile.mingw0000664000076400007640000000532113112426166013256 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw TOP = ../.. include ../plat/win32/make.mingw ################################################################ # Nothing much configurable below INCLUDES = -I ../plat/win32 -I \ $(GLIB_PATH)/include/glib-2.0/ -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GTK_PATH)/include -I $(GTK_PATH)/lib/gtk+/include \ -I $(PTHREAD_PATH)/include DEFINES += -DHAVE_GUI DLL_LDLIBS = -L $(GLIB_PATH)/lib -l gobject-2.0 -l gthread-2.0 -l glib-2.0 \ -L $(PTHREAD_PATH)/lib -l pthreadGC2 # -lstdc++ all : \ ../config.h \ libgpsim.dll libgpsim_LIBS = \ libsrc.a \ ./dspic/libgpsim_dspic.a src_OBJECTS = \ 12bit-hexdecode.o \ 12bit-processors.o \ 14bit-hexdecode.o \ 14bit-instructions.o \ 14bit-processors.o \ 14bit-registers.o \ 14bit-tmrs.o \ 16bit-hexdecode.o \ 16bit-instructions.o \ 16bit-processors.o \ 16bit-registers.o \ 16bit-tmrs.o \ a2dconverter.o \ a2d_v2.o \ attributes.o \ bitlog.o \ breakpoints.o \ bytelog.o \ clock_phase.o \ cmd_manager.o \ cod.o \ comparator.o \ ctmu.o \ dsm_module.o \ eeprom.o \ errors.o \ expr.o \ fopen-path.o \ gpsim_object.o \ gpsim_time.o \ hexutils.o \ i2c-ee.o \ icd.o \ init.o \ intcon.o \ interface.o \ ioports.o \ lcd_module.o \ lxt_write.o \ modules.o \ operator.o \ os_dependent.o \ p1xf1xxx.o \ p12f6xx.o \ p12x.o \ p16f62x.o \ p16f87x.o \ p16x5x.o \ p16x6x.o \ p16x7x.o \ p16f88x.o \ p16x8x.o \ p16f8x.o \ p16f91x.o \ p17c75x.o \ p18fk.o \ p18x.o \ packages.o \ pic-instructions.o \ pic-processor.o \ pic-registers.o \ pic-ioports.o \ pie.o \ protocol.o \ pir.o \ pm_rd.o \ program_files.o \ processor.o \ psp.o \ registers.o \ sim_context.o \ ssp.o \ spp.o \ stimuli.o \ symbol.o \ tmr0.o \ trace.o \ trigger.o \ ttoken.o \ uart.o \ ui.o \ uxsleep.o \ ValueCollections.o \ value.o \ xref.o ../config.h : ../config_win32.h.in (cd .. ; $(AWK) -f plat/win32/configure_win32.awk config_win32.h.in > config.h) icd.o : ../plat/win32/icd.cc $(CXX) -I . $(CFLAGS) -c $< -o $@ uxsleep.o : ../plat/win32/uxsleep.cc $(CXX) $(CFLAGS) -c $< -o $@ ################ The libgpsim_dspic LIB ./dspic/libgpsim_dspic.a : cd ./dspic && $(MAKE) -f makefile.mingw all ################# The libsrc LIB libsrc.a : $(src_OBJECTS) $(RM) -f $@ $(AR) $(ARFLAGS) $@ $(src_OBJECTS) ################ The libgpsim DLL libgpsim.dll: $(libgpsim_LIBS) $(CXX) --shared -Wl,--whole-archive $(libgpsim_LIBS) -Wl,--no-whole-archive $(DLL_LDLIBS) \ -o $@ -Wl,--out-implib,libgpsim.a -Wl,--output-def,libgpsim.def -Wl,-s gpsim-0.30.0/src/breakpoints.cc0000664000076400007640000015605713045306452013303 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include "cmd_gpsim.h" #include "cmd_manager.h" #include "../config.h" #include "pic-processor.h" #include "breakpoints.h" #include "14bit-processors.h" #include "xref.h" #include "icd.h" extern "C"{ #include "lxt_write.h" } #define PCPU ((Processor *)cpu) extern guint64 simulation_start_cycle; // Global declaration of THE breakpoint object // create an instance of inline get_trace() method by taking its address Breakpoints &(*dummy_bp)() = get_bp; Breakpoints bp; //------------------------------------------------------------------------ // find_free - search the array that holds the break points for a free slot // int Breakpoints::find_free() { for(int i=0; i m_iMaxAllocated) m_iMaxAllocated = i + 1; return i; } } cout << "*** out of breakpoints\n"; return(MAX_BREAKPOINTS); } //------------------------------------------------------------------------ // set_breakpoint - Set a breakpoint of a specific type. // int Breakpoints::set_breakpoint(BREAKPOINT_TYPES break_type, Processor *cpu, unsigned int arg1, unsigned arg2, TriggerObject *f1) { breakpoint_number = find_free(); if(breakpoint_number >= MAX_BREAKPOINTS) return breakpoint_number; BreakStatus &bs = break_status[breakpoint_number]; bs.type = break_type; bs.cpu = cpu; bs.arg1 = arg1; bs.arg2 = arg2; bs.bpo = f1; switch (break_type) { case BREAK_ON_INVALID_FR: return(breakpoint_number); break; case BREAK_ON_CYCLE: { guint64 cyc = arg2; cyc = (cyc<<32) | arg1; // The cycle counter does its own break points. if(get_cycles().set_break(cyc, f1, breakpoint_number)) { if(cpu != NULL) { cpu->NotifyBreakpointSet(bs, f1); } return(breakpoint_number); } else bs.type = BREAK_CLEAR; } break; case BREAK_ON_STK_OVERFLOW: if ((cpu->GetCapabilities() & Processor::eBREAKONSTACKOVER) == Processor::eBREAKONSTACKOVER) { // pic_processor should not be referenced here // Should have a GetStack() virtual function in Processor class. // Of course then the Stack class needs to be a virtual class. if(((pic_processor *)(cpu))->stack->set_break_on_overflow(1)) return (breakpoint_number); } else { // Need to add console object printf("Stack breaks not available on a %s processor\n", cpu->name().c_str()); } bs.type = BREAK_CLEAR; break; case BREAK_ON_STK_UNDERFLOW: if ((cpu->GetCapabilities() & Processor::eBREAKONSTACKUNDER) == Processor::eBREAKONSTACKUNDER) { // pic_processor should not be referenced here // Should have a GetStack() virtual function in Processor class. // Of course then the Stack class needs to be a virtual class. if(((pic_processor *)(cpu))->stack->set_break_on_underflow(1)) return (breakpoint_number); } else { // Need to add console object printf("Stack breaks not available on a %s processor\n", cpu->name().c_str()); } bs.type = BREAK_CLEAR; break; case BREAK_ON_WDT_TIMEOUT: if ((cpu->GetCapabilities() & Processor::eBREAKONWATCHDOGTIMER) == Processor::eBREAKONWATCHDOGTIMER) { // pic_processor should not be referenced here // Should have a GetStack() virtual function in Processor class. // Of course then the Stack class needs to be a virtual class. ((_14bit_processor *)cpu)->wdt.set_breakpoint(BREAK_ON_WDT_TIMEOUT | breakpoint_number); return(breakpoint_number); } else { // Need to add console object printf("Watch dog timer breaks not available on a %s processor\n", cpu->name().c_str()); } default: // Not a valid type bs.type = BREAK_CLEAR; break; } return(MAX_BREAKPOINTS); } //------------------------------------------------------------------------ //BreakTraceType *m_brt=0; int Breakpoints::set_breakpoint(TriggerObject *bpo, Processor *pCpu, Expression *pExpr) { int bpn = find_free(); if(bpn >= MAX_BREAKPOINTS || !bpo->set_break()) { delete bpo; return MAX_BREAKPOINTS; } BreakStatus &bs = break_status[bpn]; bs.bpo = bpo; bs.type = BREAK_MASK; // place holder for now... bs.cpu = pCpu; bpo->bpn = bpn; bpo->set_Expression(pExpr); if(get_active_cpu() != NULL) get_active_cpu()->NotifyBreakpointSet(bs, bpo); return bpn; } //------------------------------------------------------------------------ static BreakpointRegister_Value::BRV_Ops MapComparisonOperatorToBreakOperator(ComparisonOperator *pCompareOp) { if (pCompareOp) switch(pCompareOp->isa()) { case ComparisonOperator::eOpEq: return BreakpointRegister_Value::eBREquals; case ComparisonOperator::eOpGe: return BreakpointRegister_Value::eBRGreaterThenEquals; case ComparisonOperator::eOpGt: return BreakpointRegister_Value::eBRGreaterThen; case ComparisonOperator::eOpLe: return BreakpointRegister_Value::eBRLessThenEquals; case ComparisonOperator::eOpLt: return BreakpointRegister_Value::eBRLessThen; case ComparisonOperator::eOpNe: return BreakpointRegister_Value::eBRNotEquals; } return BreakpointRegister_Value::eBRInvalid; } //------------------------------------------------------------------------ // int Breakpoints::set_break(gpsimObject::ObjectBreakTypes bt, gpsimObject::ObjectActionTypes at, Register *pReg, Expression *pExpr) { int iValue = -1; int iMask = -1; bool bCompiledExpression = false; BreakpointRegister_Value::BRV_Ops op = BreakpointRegister_Value::eBRInvalid; Processor *pCpu = (pReg && pReg->get_cpu()) ? pReg->get_cpu() : get_active_cpu(); Register *pRegInExpr = 0; if (pExpr) { /* attempt to compile expressions of these types: * * * ComparisonOperator * / \ * OpAnd LiteralInteger * / \ * register_symbol LiteralInteger * * --- OR --- * * ComparisonOperator * / \ * register_symbol LiteralInteger * * --- OR --- * * OpAnd (not implemented) * / \ * register_symbol LiteralInteger * */ ComparisonOperator *pCompareExpr = dynamic_cast(pExpr); op = MapComparisonOperatorToBreakOperator(pCompareExpr); if (op != BreakpointRegister_Value::eBRInvalid) { OpAnd* pLeftOp = dynamic_cast(pCompareExpr->getLeft()); LiteralSymbol *pLeftSymbol = pLeftOp ? dynamic_cast(pLeftOp->getLeft()) : dynamic_cast(pCompareExpr->getLeft()); Register *pRegSym = pLeftSymbol ? dynamic_cast(pLeftSymbol->GetSymbol()) : 0; pRegInExpr = pRegSym ? pRegSym->getReg() : 0; //pRegInExpr = pLeftSymbol ? dynamic_cast(pLeftSymbol) : 0; if (!pRegInExpr) { // Legacy code... try to cast the left most integer into a register. LiteralInteger *pLeftRegAsInteger = pLeftOp ? dynamic_cast(pLeftOp->getLeft()) : dynamic_cast(pCompareExpr->getLeft()); Integer *pRegAddress = pLeftRegAsInteger ? dynamic_cast(pLeftRegAsInteger->evaluate()) : 0; pRegInExpr = (pRegAddress && pCpu) ? &pCpu->rma[(int)pRegAddress->getVal()] : 0; delete pRegAddress; } LiteralInteger* pRightSymbol = pLeftOp ? dynamic_cast(pLeftOp->getRight()) : 0; Integer *pMask = pRightSymbol ? dynamic_cast(pRightSymbol->evaluate()) : 0; iMask = pCpu ? pCpu->register_mask() : iMask; gint64 i64=0; if (pMask) { pMask->get(i64); iMask = (int)i64; } LiteralInteger* pRightValue = dynamic_cast(pCompareExpr->getRight()); Integer *pValue = pRightValue ? dynamic_cast(pRightValue->evaluate()) : 0; // Now check if this parsing was successful if (pReg == pRegInExpr && pValue) { bCompiledExpression = true; pValue->get(i64); iValue = (int)i64; } delete pMask; delete pValue; } } // If there was no register passed in as an input and we failed to compile // the expression (and hence unable to extract a register from the expression) // then don't set a break. if (!pReg && !pRegInExpr) { fprintf(stderr, "set_break failed - no register given and expression compile failed\n"); return -1; } pReg = pReg ? pReg : pRegInExpr; if (pReg->address == AN_INVALID_ADDRESS) { fprintf(stderr, "set_break failed - invalid address\n"); return -1; } if (bt == gpsimObject::eBreakWrite) { if (bCompiledExpression) { delete pExpr; return (at == gpsimObject::eActionLog) ? set_breakpoint(new Log_Register_Write_value(pCpu, pReg->address, 0,iValue,op,iMask),pCpu) : set_breakpoint(new Break_register_write_value(pCpu, pReg->address, 0,iValue,op,iMask),pCpu); } else return (at == gpsimObject::eActionLog) ? set_breakpoint(new Log_Register_Write(pCpu, pReg->address,0), pCpu, pExpr) : set_breakpoint(new Break_register_write(pCpu, pReg->address,0), pCpu, pExpr); } else if (bt == gpsimObject::eBreakRead) { if (bCompiledExpression) { delete pExpr; return (at == gpsimObject::eActionLog) ? set_breakpoint(new Log_Register_Read_value(pCpu, pReg->address, 0,iValue,op,iMask),pCpu) : set_breakpoint(new Break_register_read_value(pCpu, pReg->address, 0,iValue,op,iMask),pCpu); } else return (at == gpsimObject::eActionLog) ? set_breakpoint(new Log_Register_Read(pCpu, pReg->address,0), pCpu, pExpr) : set_breakpoint(new Break_register_read(pCpu, pReg->address,0), pCpu, pExpr); } else if (bt == gpsimObject::eBreakChange) { if (bCompiledExpression) { delete pExpr; return (at == gpsimObject::eActionLog) ? set_breakpoint(new Log_Register_Write_value(pCpu, pReg->address, 0,iValue,op,iMask),pCpu) : set_breakpoint(new Break_register_write_value(pCpu, pReg->address, 0,iValue,op,iMask),pCpu); } else return (at == gpsimObject::eActionLog) ? set_breakpoint(new Log_Register_Write(pCpu, pReg->address,0), pCpu, pExpr) : set_breakpoint(new Break_register_change(pCpu, pReg->address,0), pCpu, pExpr); } return -1; } bool Breakpoints::set_expression(unsigned int bpn, Expression *pExpr) { if(bpn < MAX_BREAKPOINTS) { BreakStatus &bs = break_status[bpn]; if(bs.bpo) { bs.bpo->set_Expression(pExpr); return true; } } return false; } int Breakpoints::set_execution_break(Processor *cpu, unsigned int address, Expression *pExpr) { if (!cpu || !cpu->pma || !cpu->pma->hasValid_opcode_at_address(address)) return -1; Breakpoint_Instruction *bpi = new Breakpoint_Instruction(cpu,address,0); return bp.set_breakpoint(bpi,cpu,pExpr); } int Breakpoints::set_notify_break(Processor *cpu, unsigned int address, TriggerObject *f1 = 0) { GetTraceLog().enable_logging(); Notify_Instruction *ni = new Notify_Instruction(cpu,address,0,f1); return bp.set_breakpoint(ni,cpu); } int Breakpoints::set_profile_start_break(Processor *cpu, unsigned int address, TriggerObject *f1) { Profile_Start_Instruction *psi = new Profile_Start_Instruction(cpu,address,0,f1); return bp.set_breakpoint(psi,cpu); } int Breakpoints::set_profile_stop_break(Processor *cpu, unsigned int address, TriggerObject *f1) { Profile_Stop_Instruction *psi = new Profile_Stop_Instruction(cpu,address,0,f1); return bp.set_breakpoint(psi,cpu); } int Breakpoints::set_read_break(Processor *cpu, unsigned int register_number) { Break_register_read *brr = new Break_register_read(cpu,register_number,0); return bp.set_breakpoint(brr,cpu); } int Breakpoints::set_write_break(Processor *cpu, unsigned int register_number) { Break_register_write *brw = new Break_register_write(cpu,register_number,0); return bp.set_breakpoint(brw,cpu); } int Breakpoints::set_read_value_break(Processor *cpu, unsigned int register_number, unsigned int value, unsigned int mask) { return set_read_value_break(cpu, register_number, BreakpointRegister_Value::eBREquals, value, mask); } int Breakpoints::set_read_value_break(Processor *cpu, unsigned int register_number, unsigned int op, unsigned int value, unsigned int mask) { Break_register_read_value *brrv = new Break_register_read_value(cpu, register_number, value, op, BreakpointRegister_Value::eBREquals, mask); return bp.set_breakpoint(brrv,cpu); } int Breakpoints::set_write_value_break(Processor *cpu, unsigned int register_number, unsigned int value, unsigned int mask) { return set_write_value_break(cpu, register_number, BreakpointRegister_Value::eBREquals, value, mask); } int Breakpoints::set_write_value_break(Processor *cpu, unsigned int register_number, unsigned int op, unsigned int value, unsigned int mask) { Break_register_write_value *brwv = new Break_register_write_value(cpu, register_number, 0, value, op, mask); return bp.set_breakpoint(brwv,cpu); } int Breakpoints::set_change_break(Processor *cpu, unsigned int register_number) { Break_register_change *brc = new Break_register_change(cpu,register_number,0); return bp.set_breakpoint(brc,cpu); } int Breakpoints::set_cycle_break(Processor *cpu, guint64 future_cycle, TriggerObject *f1) { return(set_breakpoint (Breakpoints::BREAK_ON_CYCLE, cpu, (unsigned int)(future_cycle & 0xffffffff), (unsigned int)(future_cycle>>32), f1)); } int Breakpoints::set_stk_overflow_break(Processor *cpu) { return(set_breakpoint (Breakpoints::BREAK_ON_STK_OVERFLOW, cpu, 0, 0)); } int Breakpoints::set_stk_underflow_break(Processor *cpu) { return(set_breakpoint (Breakpoints::BREAK_ON_STK_UNDERFLOW, cpu, 0, 0)); } int Breakpoints::set_wdt_break(Processor *cpu) { if ((cpu->GetCapabilities() & Processor::eBREAKONWATCHDOGTIMER) == Processor::eBREAKONWATCHDOGTIMER) { // Set a wdt break only if one is not already set. if(!cpu14->wdt.hasBreak()) return(set_breakpoint (Breakpoints::BREAK_ON_WDT_TIMEOUT, cpu, 0, 0)); } else { // Need to add console object printf("Watch dog timer breaks not available on a %s processor\n", cpu->name().c_str()); } return MAX_BREAKPOINTS; } int Breakpoints::set_notify_read(Processor *cpu, unsigned int register_number) { GetTraceLog().enable_logging(); Log_Register_Read *lrr = new Log_Register_Read(cpu,register_number,0); return bp.set_breakpoint(lrr,cpu); } int Breakpoints::set_notify_write(Processor *cpu, unsigned int register_number) { GetTraceLog().enable_logging(); Log_Register_Write *lrw = new Log_Register_Write(cpu,register_number,0); return bp.set_breakpoint(lrw,cpu); } int Breakpoints::set_notify_read_value(Processor *cpu, unsigned int register_number, unsigned int value, unsigned int mask) { GetTraceLog().enable_logging(); Log_Register_Read_value *lrrv = new Log_Register_Read_value(cpu, register_number, 0, value, BreakpointRegister_Value::eBREquals, mask); return bp.set_breakpoint(lrrv,cpu); } int Breakpoints::set_notify_write_value(Processor *cpu, unsigned int register_number, unsigned int value, unsigned int mask) { GetTraceLog().enable_logging(); Log_Register_Write_value *lrwv = new Log_Register_Write_value(cpu, register_number, 0, value, BreakpointRegister_Value::eBREquals, mask); return bp.set_breakpoint(lrwv,cpu); } int Breakpoints::check_cycle_break(unsigned int bpn) { cout << "cycle break: 0x" << hex << get_cycles().get() << dec << " = " << get_cycles().get() << endl; halt(); if( bpn < MAX_BREAKPOINTS) { if (break_status[bpn].bpo) break_status[bpn].bpo->callback(); //trace.breakpoint( (Breakpoints::BREAK_ON_CYCLE>>8) ); //trace.raw(m_brt->type() | bpn); clear(bpn); } return(1); } bool Breakpoints::dump(TriggerObject *pTO) { if (!pTO) return false; pTO->print(); return true; } bool Breakpoints::dump1(unsigned int bp_num, int dump_type) { if(!bIsValid(bp_num)) { printf("Break point number: %u is out of range\n", bp_num); return false; } BreakStatus &bs = break_status[bp_num]; if(bs.bpo) { switch(dump_type) { case BREAK_ON_EXECUTION: if(dynamic_cast(bs.bpo) != 0) { // for 'break e' we skip RegisterAssertions // and dump user execution breaks. return false; } break; case BREAK_ON_REG_WRITE: if(dynamic_cast(bs.bpo) != 0 || dynamic_cast(bs.bpo) != 0) { // for 'break w' we dump register write classes break; } return false; case BREAK_ON_REG_READ: if(dynamic_cast(bs.bpo) != 0 || dynamic_cast(bs.bpo) != 0) { // for 'break r' we dump register read classes break; } default: break; } return dump(bs.bpo); } else { BREAKPOINT_TYPES break_type = break_status[bp_num].type; switch (break_type) { case BREAK_ON_CYCLE: { const char * pFormat = "%d: cycle 0x%" PRINTF_INT64_MODIFIER "x = %" PRINTF_INT64_MODIFIER "d\n"; guint64 cyc = bs.arg2; cyc = (cyc <<32) | bs.arg1; GetUserInterface().DisplayMessage(pFormat, bp_num, cyc, cyc); } break; case BREAK_ON_STK_UNDERFLOW: case BREAK_ON_STK_OVERFLOW: cout << hex << setw(0) << bp_num << ": " << bs.cpu->name() << " "; cout << "stack " << ((break_type == BREAK_ON_STK_OVERFLOW)?"ov":"und") << "er flow\n"; break; case BREAK_ON_WDT_TIMEOUT: cout << hex << setw(0) << bp_num << ": " << bs.cpu->name() << " "; cout << "wdt time out\n"; break; default: return false; break; } } return true; } void Breakpoints::dump(int dump_type) { bool have_breakpoints = 0; if(dump_type != BREAK_ON_CYCLE) { for(int i = 0; ipma->getFromAddress(address); if(!_this || p==_this) return 0; while(p->getReplaced()!=_this) { p=(Breakpoint_Instruction*)p->getReplaced(); } return p; } void Breakpoints::clear(unsigned int b) { if (!bIsValid(b)) return; BreakStatus &bs = break_status[b]; // //cout << "clearing bp:"<clear(); bs.type = BREAK_CLEAR; get_active_cpu()->NotifyBreakpointCleared(bs, bs.bpo); delete bs.bpo; bs.bpo = 0; return; } switch (bs.type) { case BREAK_ON_CYCLE: bs.type = BREAK_CLEAR; //cout << "Cleared cycle breakpoint number " << b << '\n'; break; case BREAK_ON_STK_OVERFLOW: bs.type = BREAK_CLEAR; if ((bs.cpu->GetCapabilities() & Processor::eSTACK) == Processor::eSTACK) { if(((pic_processor *)(bs.cpu))->stack->set_break_on_overflow(0)) cout << "Cleared stack overflow break point.\n"; else cout << "Stack overflow break point is already cleared.\n"; } break; case BREAK_ON_STK_UNDERFLOW: bs.type = BREAK_CLEAR; if ((bs.cpu->GetCapabilities() & Processor::eSTACK) == Processor::eSTACK) { if(((pic_processor *)(bs.cpu))->stack->set_break_on_underflow(0)) cout << "Cleared stack underflow break point.\n"; else cout << "Stack underflow break point is already cleared.\n"; } break; case BREAK_ON_WDT_TIMEOUT: bs.type = BREAK_CLEAR; if ((bs.cpu->GetCapabilities() & Processor::eBREAKONWATCHDOGTIMER) == Processor::eBREAKONWATCHDOGTIMER) { cout << "Cleared wdt timeout breakpoint number " << b << '\n'; ((_14bit_processor *)bs.cpu)->wdt.set_breakpoint(0); } break; default: bs.type = BREAK_CLEAR; break; } get_active_cpu()->NotifyBreakpointCleared(bs, NULL); } bool Breakpoints::bIsValid(unsigned int b) { return b < MAX_BREAKPOINTS; } bool Breakpoints::bIsClear(unsigned int b) { return bIsValid(b) && break_status[b].type == BREAK_CLEAR; } void Breakpoints::set_message(unsigned int b,string &m) { if (bIsValid(b) && break_status[b].type != BREAK_CLEAR && break_status[b].bpo) break_status[b].bpo->new_message(m); } // // dump_traced // Called by the trace class to display a breakpoint that is in the // trace buffer. void Breakpoints::dump_traced(unsigned int b) { BREAKPOINT_TYPES break_type = (BREAKPOINT_TYPES) ((b & 0xff0000) << 8); switch (break_type) { case BREAK_ON_EXECUTION: cout << "execution at "<< hex << setw(4) << setfill('0') << (b & 0xffff) << '\n'; break; case BREAK_ON_REG_WRITE: cout << "reg write: " << hex << setw(2) << setfill('0') << (b & 0xff) << '\n'; break; case BREAK_ON_REG_WRITE_VALUE: cout << "wrote " << hex << setw(2) << setfill('0') << ((b & 0xff00)>>8) << " to register " << hex << setw(2) << setfill('0') << (b & 0xff) << '\n'; break; case BREAK_ON_REG_READ: cout << "reg write: " << hex << setw(2) << setfill('0') << (b & 0xff) << '\n'; break; case BREAK_ON_REG_READ_VALUE: cout << "read " << hex << setw(2) << setfill('0') << ((b & 0xff00)>>8) << " from register " << hex << setw(2) << setfill('0') << (b & 0xff) << '\n'; break; case BREAK_ON_CYCLE: cout << "cycle " << '\n'; break; case BREAK_ON_WDT_TIMEOUT: cout << "wdt time out\n"; break; default: cout << "unknown\n"; } } // Clear all break points that are set for a specific processor // This only be called when a processor is being removed and not when a user // wants to clear the break points. Otherwise, internal break points like // invalid register accesses will get cleared. void Breakpoints::clear_all(Processor *c) { GetTraceLog().close_logfile(); for(int i=0; i c->register_memory_size()) return; while(c->registers[address]->isa()==Register::BP_REGISTER) { BreakpointRegister *nr = dynamic_cast(c->registers[address]); if(!nr) return; bp.clear(nr->bpn & ~Breakpoints::BREAK_MASK); } } void Breakpoints::halt() { if(get_use_icd()) { icd_halt(); return; } global_break |= GLOBAL_STOP_RUNNING; if(m_bExitOnBreak) { // Let the UI or client code choose how and // when to exit. GetUserInterface().NotifyExitOnBreak(0); } } Breakpoints::Breakpoints() { m_iMaxAllocated = 0; breakpoint_number = 0; m_bExitOnBreak = false; for(int i=0; isimulation_mode == eSM_RUNNING) && (simulation_start_cycle != get_cycles().get()) && eval_Expression()) { invokeAction(); } else m_replaced->execute(); } Breakpoint_Instruction::Breakpoint_Instruction(Processor *new_cpu, unsigned int new_address, unsigned int bp) : TriggerObject(0) { cpu = new_cpu; address = new_address; opcode = 0xffffffff; bpn = bp; m_replaced = new_cpu->pma->getFromAddress(address); set_action(new SimpleTriggerAction(this)); } Breakpoint_Instruction::~Breakpoint_Instruction() { } Processor* Breakpoint_Instruction::get_cpu() { return dynamic_cast(cpu); } //------------------------------------------------------------------- bool Breakpoint_Instruction::set_break() { if(get_use_icd()) bp.clear_all(get_cpu()); unsigned int uIndex = get_cpu()->map_pm_address2index(address); if(uIndex < get_cpu()->program_memory_size()) { m_replaced = get_cpu()->pma->getFromIndex(uIndex); get_cpu()->pma->putToIndex(uIndex, this); if(get_use_icd()) icd_set_break(address); return true; } return false; } void Breakpoint_Instruction::print() { // Output example // 42: p17c756 Execution at 0x0123 instruction *pReplaced = getReplaced(); gpsimObject *pLineSym = pReplaced ? pReplaced->getLineSymbol() : 0; const char *pLabel = pLineSym ? pLineSym->name().c_str() : "no label"; const char * pFormat = *pLabel == 0 ? "%d: %s %s at %s0x%x\n" : "%d: %s %s at %s(0x%x)\n"; GetUserInterface().DisplayMessage(pFormat, bpn, cpu->name().c_str(), bpName(), pLabel, address); TriggerObject::print(); } int Breakpoint_Instruction::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (!pBuf || !pTrace) return 0; int m; if (bHasExpression()) { char buf[256]; printExpression(buf, sizeof(buf)); m = snprintf(pBuf, szBuf, " assertion at 0x%04x, expr:%s",address,buf); } else m = snprintf(pBuf, szBuf, " execution at 0x%04x",address); return m>0 ? m : 0; } void Breakpoint_Instruction::clear() { if(get_use_icd()) icd_clear_break(); get_cpu()->pma->clear_break_at_address(address, this); instruction *pInst = get_cpu()->pma->getFromAddress(address); /* cout << "about to update cleared instruction breakpoint:" << pInst << " this:" << this << " address: 0x" << hex << address << endl; */ pInst->update(); } //------------------------------------------------------------------------ void Notify_Instruction::execute() { if(callback) callback->callback(); m_replaced->execute(); } Notify_Instruction::Notify_Instruction(Processor *cpu, unsigned int address, unsigned int bp, TriggerObject *cb) : Breakpoint_Instruction(cpu, address,bp) { callback=cb; } Notify_Instruction::~Notify_Instruction() { } //------------------------------------------------------------------------ Profile_Start_Instruction::Profile_Start_Instruction(Processor *cpu, unsigned int address, unsigned int bp, TriggerObject *cb) : Notify_Instruction(cpu, address, bp, cb) { } Profile_Stop_Instruction::Profile_Stop_Instruction(Processor *cpu, unsigned int address, unsigned int bp, TriggerObject *cb) : Notify_Instruction(cpu, address, bp, cb) { } //------------------------------------------------------------------------------ RegisterAssertion::RegisterAssertion(Processor *cpu, unsigned int address, unsigned int bp, unsigned int _regAddress, unsigned int _regMask, unsigned int _regValue, bool _bPostAssertion) : Breakpoint_Instruction(cpu, address,bp), regAddress(_regAddress), regMask(_regMask), regValue(_regValue), bPostAssertion(_bPostAssertion), m_pfnIsAssertionBreak(IsAssertionEqualsBreakCondition) { } RegisterAssertion::RegisterAssertion(Processor *cpu, unsigned int address, unsigned int bp, unsigned int _regAddress, unsigned int _regMask, unsigned int _operator, unsigned int _regValue, bool _bPostAssertion) : Breakpoint_Instruction(cpu, address,bp), regAddress(_regAddress), regMask(_regMask), regValue(_regValue), bPostAssertion(_bPostAssertion) { switch(_operator) { case eRAEquals: m_pfnIsAssertionBreak = IsAssertionEqualsBreakCondition; break; case eRANotEquals: m_pfnIsAssertionBreak = IsAssertionNotEqualsBreakCondition; break; case eRAGreaterThen: m_pfnIsAssertionBreak = IsAssertionGreaterThenBreakCondition; break; case eRALessThen: m_pfnIsAssertionBreak = IsAssertionLessThenBreakCondition; break; case eRAGreaterThenEquals: m_pfnIsAssertionBreak = IsAssertionGreaterThenEqualsBreakCondition; break; case eRALessThenEquals: m_pfnIsAssertionBreak = IsAssertionLessThenEqualsBreakCondition; break; default: assert(false); break; } } RegisterAssertion::~RegisterAssertion() { } bool RegisterAssertion::IsAssertionEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) != uRegTestValue; } bool RegisterAssertion::IsAssertionNotEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) == uRegTestValue; } bool RegisterAssertion::IsAssertionGreaterThenBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) <= uRegTestValue; } bool RegisterAssertion::IsAssertionLessThenBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) >= uRegTestValue; } bool RegisterAssertion::IsAssertionGreaterThenEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) < uRegTestValue; } bool RegisterAssertion::IsAssertionLessThenEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) > uRegTestValue; } //------------------------------------------------------------------------------ void RegisterAssertion::execute() { // For "post" assertions, the instruction is simulated first // and then the register assertion is checked. if(bPostAssertion && m_replaced) m_replaced->execute(); // If the assertion is true, and the "phase" of the instruction is // '0' then halt the simulation. Note, the reason for checking "phase" // is to ensure the assertion applies to the the proper cycle of a // multi-cycle instruction. For example, an assertion applied to a // a "GOTO" instruction should only get checked before the instruction // executes if it's a pre-assertion or after it completes if it's a // post assertion. unsigned int curRegValue = PCPU->rma[regAddress].get_value(); if( m_pfnIsAssertionBreak(curRegValue, regMask, regValue) && (PCPU->pc->get_phase() == 0) ) { cout << "Caught Register " << (bPostAssertion ? "post " : "") << "assertion " << "while excuting at address 0x" << hex << address << endl; cout << "register 0x" << hex << regAddress << " = 0x" << curRegValue << endl; cout << "0x" << PCPU->rma[regAddress].get_value() << " & 0x" << regMask << " != 0x" << regValue << endl; cout << " regAddress =0x" << regAddress << " regMask = 0x" << regMask << " regValue = 0x" << regValue << endl; PCPU->Debug(); if( (PCPU->simulation_mode == eSM_RUNNING) && (simulation_start_cycle != get_cycles().get())) { eval_Expression(); invokeAction(); trace.raw(m_brt->type(1) | curRegValue ); return; } } // If this is not a post assertion, then the instruction executes after // the instruction simulates. if(!bPostAssertion && m_replaced) m_replaced->execute(); } //------------------------------------------------------------------------------ void RegisterAssertion::print() { Breakpoint_Instruction::print(); Register & pReg = PCPU->rma[regAddress]; string & sName = pReg.name(); const char * pFormat = sName.empty() ? " break when register %s0x%x ANDed with 0x%x equals 0x%x\n" : " break when register %s(0x%x) ANDed with 0x%x equals 0x%x\n" ; GetUserInterface().DisplayMessage(pFormat, sName.c_str(), regAddress, regMask, regValue); TriggerObject::print(); } int RegisterAssertion::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (!pBuf || pTrace) return 0; unsigned int valueWritten = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf, szBuf, " Register Assertion PC=0x%04x, reg[0x%x]==0x%x != 0x%x", address,regAddress,valueWritten,regValue); return m>0 ? m : 0; } //------------------------------------------------------------------------------ #if 0 class BreakpointRegisterAction : public TriggerAction { public: BreakpointRegisterAction(BreakpointRegister *pbpr); virtual ~BreakpointRegisterAction(); virtual void action(); private: BreakpointRegister *m_pbpr; }; BreakpointRegisterAction::BreakpointRegisterAction(BreakpointRegister *pbpr) : m_pbpr(pbpr) { } BreakpointRegisterAction:: ~BreakpointRegisterAction() { } void BreakpointRegisterAction::action() { if(m_pbpr) m_pbpr->takeAction(); } #endif //------------------------------------------------------------------------------ /* BreakpointRegister::BreakpointRegister() : TriggerObject(new BreakpointRegisterAction(this)) { } */ BreakpointRegister::~BreakpointRegister() { } BreakpointRegister::BreakpointRegister(Processor *_cpu, TriggerAction *pTA, Register *pRepl) : Register(_cpu, "",0), TriggerObject(pTA) { setReplaced(pRepl); } BreakpointRegister::BreakpointRegister(Processor *_cpu, TriggerAction *ta, int _repl, int bp) : Register(_cpu, "",0), TriggerObject(ta) { bpn = bp; replace(_cpu,_repl); address = _repl; } void BreakpointRegister::invokeAction() { if(eval_Expression()) TriggerObject::invokeAction(); } void BreakpointRegister::takeAction() { } void BreakpointRegister::replace(Processor *_cpu, unsigned int reg) { if (_cpu) { cpu = _cpu; _cpu->rma.insertRegister(reg,this); } update(); } unsigned int BreakpointRegister::clear(unsigned int bp_num) { clear(); return 1; } /// BreakpointRegister::clear() will delete itself from the /// chain of BreakpointRegister objects. /// All derived classes that override this function need to /// call this function of this base class. // Note: There should be a RegisterChain class and this code // should exist in the RegisterChain class. get_cpu()->registers // would then be an array of RegisterChains. void BreakpointRegister::clear() { // FIXME, we don't know if this breakpoint register is actually associated // with the active cpu or not. It looks like we need a way for either the // registers to know in which array they're stored OR the Module class needs // to provide a 'removeRegister()' method. if (get_cpu()) { get_cpu()->rma.removeRegister(address,this); get_cpu()->registers[address]->update(); } } bool BreakpointRegister::set_break() { return true; } void BreakpointRegister::print() { // FIXME - broke with new symbol table. Register * pReg = 0; // get_symbol_table().findRegister(address); if (pReg) GetUserInterface().DisplayMessage("%d: %s %s: %s(0x%x)\n", bpn, cpu->name().c_str(), bpName(), pReg->name().c_str(), address); else GetUserInterface().DisplayMessage("%d: %s: reg(0x%x)\n", bpn, bpName(), address); TriggerObject::print(); } int BreakpointRegister::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (!pBuf || pTrace) return 0; int m = snprintf(pBuf, szBuf, " Breakpoint register "); return m>0 ? m : 0; } string &BreakpointRegister::name() const { return m_replaced ? m_replaced->name() : gpsimObject::name(); }; void BreakpointRegister::put_value(unsigned int new_value) { getReplaced()->put_value(new_value); } void BreakpointRegister::put(unsigned int new_value) { getReplaced()->put(new_value); } void BreakpointRegister::putRV(RegisterValue rv) { getReplaced()->putRV(rv); } unsigned int BreakpointRegister::get_value() { return(getReplaced()->get_value()); } RegisterValue BreakpointRegister::getRV() { return getReplaced()->getRV(); } RegisterValue BreakpointRegister::getRVN() { return getReplaced()->getRVN(); } unsigned int BreakpointRegister::get() { return(getReplaced()->get()); } Register *BreakpointRegister::getReg() { return getReplaced() ? getReplaced()->getReg() : this; } void BreakpointRegister::setbit(unsigned int bit_number, bool new_value) { getReplaced()->setbit(bit_number, new_value); } bool BreakpointRegister::get_bit(unsigned int bit_number) { return(getReplaced()->get_bit(bit_number)); } double BreakpointRegister::get_bit_voltage(unsigned int bit_number) { return(getReplaced()->get_bit_voltage(bit_number)); } bool BreakpointRegister::hasBreak() { return true; } void BreakpointRegister::update() { if(getReplaced()) getReplaced()->update(); } void BreakpointRegister::add_xref(void *an_xref) { if(getReplaced()) getReplaced()->add_xref(an_xref); } void BreakpointRegister::remove_xref(void *an_xref) { if(getReplaced()) getReplaced()->remove_xref(an_xref); } //------------------------------------------------------------------------ BreakpointRegister_Value:: BreakpointRegister_Value(Processor *_cpu, int _repl, int bp, unsigned int bv, unsigned int _operator, unsigned int bm ) : BreakpointRegister(_cpu,0,_repl,bp ) { m_uDefRegMask = _cpu->register_mask(); break_value = bv; break_mask = bm; switch(_operator) { case eBREquals: m_pfnIsBreak = IsEqualsBreakCondition; m_sOperator = "=="; break; case eBRNotEquals: m_pfnIsBreak = IsNotEqualsBreakCondition; m_sOperator = "!="; break; case eBRGreaterThen: m_pfnIsBreak = IsGreaterThenBreakCondition; m_sOperator = ">"; break; case eBRLessThen: m_pfnIsBreak = IsLessThenBreakCondition; m_sOperator = "<"; break; case eBRGreaterThenEquals: m_pfnIsBreak = IsGreaterThenEqualsBreakCondition; m_sOperator = ">="; break; case eBRLessThenEquals: m_pfnIsBreak = IsLessThenEqualsBreakCondition; m_sOperator = "<="; break; default: assert(false); break; } int regMask = (0x100 << (_cpu->register_size()-1)) - 1; if(break_mask == 0) break_mask = regMask; } BreakpointRegister_Value::~BreakpointRegister_Value() { // cout << __FUNCTION__ << " destructor\n"; } bool BreakpointRegister_Value::IsEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) == uRegTestValue; } bool BreakpointRegister_Value::IsNotEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) != uRegTestValue; } bool BreakpointRegister_Value::IsGreaterThenBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) > uRegTestValue; } bool BreakpointRegister_Value::IsLessThenBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) < uRegTestValue; } bool BreakpointRegister_Value::IsGreaterThenEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) >= uRegTestValue; } bool BreakpointRegister_Value::IsLessThenEqualsBreakCondition(unsigned int uRegValue, unsigned int uRegMask, unsigned int uRegTestValue) { return (uRegValue & uRegMask) <= uRegTestValue; } /* void BreakpointRegister_Value::invokeAction() { if(eval_Expression()) TriggerObject::invokeAction(); } */ /// BreakpointRegister_Value::print() - base class function /// would be unusual to not be over ridden. void BreakpointRegister_Value::print() { Register *pReg = getReg(); string & sName = pReg->name(); const char * pFormat = sName.empty() ? "%d: %s %s: break when register %s0x%x ANDed with 0x%x %s 0x%x\n" : "%d: %s %s: break when register %s(0x%x) ANDed with 0x%x %s 0x%x\n" ; GetUserInterface().DisplayMessage(pFormat, bpn,cpu->name().c_str(), bpName(), sName.c_str(), pReg->address, break_mask, m_sOperator.c_str(),break_value); TriggerObject::print(); } int BreakpointRegister_Value::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (pBuf && pTrace) { unsigned int valueRead = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf,szBuf," read 0x%x from reg 0x%x", valueRead, address); return m>0 ? m : 0; } return 0; } //------------------------------------------------------------------- // Break_register_write_value::Break_register_write_value(Processor *_cpu, int _repl, int bp, unsigned int bv, unsigned int _operator, unsigned int bm ) : BreakpointRegister_Value(_cpu, _repl, bp, bv, _operator, bm ) { } Break_register_write_value::~Break_register_write_value() { } void Break_register_write_value::takeAction() { trace.raw(m_brt->type(1) | (getReplaced()->get_value() & 0xffffff)); if(verbosity && verbosity->getVal()) { GetUserInterface().DisplayMessage(IDS_HIT_BREAK,bpn); string sFormattedRegAddress; sFormattedRegAddress = GetUserInterface().FormatRegisterAddress(getReg()); if(break_mask != m_uDefRegMask) { sFormattedRegAddress += " & "; sFormattedRegAddress += GetUserInterface().FormatLabeledValue("", break_mask); } GetUserInterface().DisplayMessage(IDS_BREAK_WRITING_REG_OP_VALUE, sFormattedRegAddress.c_str(), m_sOperator.c_str(), break_value); } bp.halt(); } //======================================================================== // Break_register_read::Break_register_read(Processor *_cpu, int _repl, int bp ): BreakpointRegister(_cpu,0,_repl,bp ) { } Break_register_read::~Break_register_read() { } void Break_register_read::takeAction() { trace.raw(m_brt->type(1) | (getReplaced()->get_value() & 0xffffff)); if(verbosity && verbosity->getVal()) { GetUserInterface().DisplayMessage(IDS_HIT_BREAK,bpn); string sFormattedRegAddress; sFormattedRegAddress = GetUserInterface().FormatRegisterAddress(getReg()); GetUserInterface().DisplayMessage(IDS_BREAK_READING_REG, sFormattedRegAddress.c_str()); } bp.halt(); } unsigned int Break_register_read::get() { unsigned int v = getReplaced()->get(); invokeAction(); return v; } RegisterValue Break_register_read::getRV() { RegisterValue rv = getReplaced()->getRV(); invokeAction(); return rv; } RegisterValue Break_register_read::getRVN() { RegisterValue rv = getReplaced()->getRVN(); invokeAction(); return rv; } bool Break_register_read::get_bit(unsigned int bit_number) { invokeAction(); return(getReplaced()->get_bit(bit_number)); } double Break_register_read::get_bit_voltage(unsigned int bit_number) { return getReplaced()->get_bit_voltage(bit_number); } int Break_register_read::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (pBuf && pTrace) { unsigned int valueRead = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf,szBuf," read 0x%x from reg 0x%x", valueRead, address); return m>0 ? m : 0; } return 0; } //======================================================================== // Break_register_write::Break_register_write(Processor *_cpu, int _repl, int bp ): BreakpointRegister(_cpu,0,_repl,bp ) { } Break_register_write::~Break_register_write() { } void Break_register_write::takeAction() { trace.raw(m_brt->type(1) | (getReplaced()->get_value() & 0xffffff)); if(verbosity && verbosity->getVal()) { GetUserInterface().DisplayMessage(IDS_HIT_BREAK,bpn); string sFormattedRegAddress; sFormattedRegAddress = GetUserInterface().FormatRegisterAddress( address, 0); GetUserInterface().DisplayMessage(IDS_BREAK_WRITING_REG, sFormattedRegAddress.c_str()); } bp.halt(); } void Break_register_write::put(unsigned int new_value) { getReplaced()->put(new_value); invokeAction(); } void Break_register_write::putRV(RegisterValue rv) { getReplaced()->putRV(rv); invokeAction(); } void Break_register_write::setbit(unsigned int bit_number, bool new_value) { getReplaced()->setbit(bit_number,new_value); invokeAction(); } int Break_register_write::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (pBuf && pTrace) { unsigned int valueRead = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf,szBuf," wrote 0x%x to reg 0x%x", valueRead, address); return m>0 ? m : 0; } return 0; } //======================================================================== Break_register_read_value::Break_register_read_value(Processor *_cpu, int _repl, int bp, unsigned int bv, unsigned int _operator, unsigned int bm ) : BreakpointRegister_Value(_cpu, _repl, bp, bv, _operator, bm ) { } Break_register_read_value::~Break_register_read_value() { } void Break_register_read_value::takeAction() { trace.raw(m_brt->type(1) | (getReplaced()->get_value() & 0xffffff)); if(verbosity && verbosity->getVal()) { GetUserInterface().DisplayMessage(IDS_HIT_BREAK,bpn); string sFormattedRegAddress; sFormattedRegAddress = GetUserInterface().FormatRegisterAddress(getReg()); if(break_mask != m_uDefRegMask) { sFormattedRegAddress += " & "; sFormattedRegAddress += GetUserInterface().FormatLabeledValue("", break_mask); } GetUserInterface().DisplayMessage(IDS_BREAK_READING_REG_OP_VALUE, sFormattedRegAddress.c_str(), m_sOperator.c_str(), break_value); } bp.halt(); } unsigned int Break_register_read_value::get() { unsigned int v = getReplaced()->get(); if(m_pfnIsBreak(v, break_mask, break_value)) invokeAction(); return v; } RegisterValue Break_register_read_value::getRV() { RegisterValue v = getReplaced()->getRV(); if(m_pfnIsBreak(v.data, break_mask, break_value)) invokeAction(); return(v); } RegisterValue Break_register_read_value::getRVN() { RegisterValue v = getReplaced()->getRVN(); if(m_pfnIsBreak(v.data, break_mask, break_value)) invokeAction(); return(v); } bool Break_register_read_value::get_bit(unsigned int bit_number) { unsigned int v = getReplaced()->get(); unsigned int mask = 1<<(bit_number & 7); if( (break_mask & mask) && (v & mask) == (break_value&mask)) invokeAction(); return getReplaced()->get_bit(bit_number); } double Break_register_read_value::get_bit_voltage(unsigned int bit_number) { return getReplaced()->get_bit_voltage(bit_number); } int Break_register_read_value::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (pBuf && pTrace) { unsigned int valueRead = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf,szBuf," read 0x%x from reg 0x%x", valueRead, address); return m>0 ? m : 0; } return 0; } //======================================================================== void Break_register_write_value::put(unsigned int new_value) { getReplaced()->put(new_value); if(m_pfnIsBreak(new_value, break_mask, break_value)) invokeAction(); } void Break_register_write_value::putRV(RegisterValue rv) { getReplaced()->putRV(rv); if(m_pfnIsBreak(rv.data, break_mask, break_value)) invokeAction(); } void Break_register_write_value::setbit(unsigned int bit_number, bool new_bit) { int val_mask = 1 << bit_number; int new_value = ((int)new_bit) << bit_number; getReplaced()->setbit(bit_number,new_value ? true : false); if( (val_mask & break_mask) && ( ( (getReplaced()->value.get() & ~val_mask) // clear the old bit | new_value) // set the new bit & break_mask) == break_value) invokeAction(); } int Break_register_write_value::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (pBuf && pTrace) { unsigned int valueRead = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf,szBuf," wrote 0x%x to reg 0x%x", valueRead, address); return m>0 ? m : 0; } return 0; } //======================================================================== // Break_register_change::Break_register_change(Processor *_cpu, int _repl, int bp ): BreakpointRegister(_cpu,0,_repl,bp ) { } Break_register_change::~Break_register_change() { } void Break_register_change::takeAction() { trace.raw(m_brt->type(1) | (getReplaced()->get_value() & 0xffffff)); if(verbosity && verbosity->getVal()) { GetUserInterface().DisplayMessage(IDS_HIT_BREAK,bpn); string sFormattedRegAddress; sFormattedRegAddress = GetUserInterface().FormatRegisterAddress( address, 0); GetUserInterface().DisplayMessage(IDS_BREAK_WRITING_REG, sFormattedRegAddress.c_str()); } bp.halt(); } void Break_register_change::put(unsigned int new_value) { unsigned int before = getReplaced()->get_value(); getReplaced()->put(new_value); if (before != getReplaced()->get_value()) invokeAction(); } void Break_register_change::putRV(RegisterValue rv) { RegisterValue before = getReplaced()->getRV_notrace(); getReplaced()->putRV(rv); if (before != getReplaced()->getRV_notrace()) invokeAction(); } void Break_register_change::setbit(unsigned int bit_number, bool new_value) { bool before = getReplaced()->get_bit(bit_number); getReplaced()->setbit(bit_number,new_value); if (before != getReplaced()->get_bit(bit_number)) invokeAction(); } int Break_register_change::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { if (pBuf && pTrace) { unsigned int valueRead = pTrace->get(tbi+1) & 0xffff; int m = snprintf(pBuf,szBuf," wrote 0x%x to reg 0x%x", valueRead, address); return m>0 ? m : 0; } return 0; } //======================================================================== //------------------------------------------------------------------------ // CommandAssertion // // Associates a gpsim command with an instruction. I.e. when the simulated // instruction is executed, the gpsim command will execute first and then // the instruction is simulated. CommandAssertion::CommandAssertion(Processor *new_cpu, unsigned int instAddress, unsigned int bp, const char *_command, bool _bPostAssertion) : Breakpoint_Instruction(new_cpu, instAddress, bp), bPostAssertion(_bPostAssertion) { int len = (int)strlen(_command); command = (char *)malloc(len+3); strcpy(command,_command); command[len] = '\n'; command[len+1] = 0; command[len+2] = 0; } CommandAssertion::~CommandAssertion() { free(command); } void CommandAssertion::execute() { if(bPostAssertion && getReplaced()) getReplaced()->execute(); //printf("execute command: %s -- post = %s\n",command,(bPostAssertion?"true":"false")); ICommandHandler *pCli = CCommandManager::GetManager().find("gpsimCLI"); if(pCli) { pCli->Execute(command, 0); } if(!bPostAssertion && getReplaced()) getReplaced()->execute(); } //------------------------------------------------------------------------------ void CommandAssertion::print() { Breakpoint_Instruction::print(); cout << " execute command " << command << endl; } int CommandAssertion::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { return 0; } //============================================================================ void Log_Register_Write::put(unsigned int new_value) { getReplaced()->put(new_value); takeAction(); } void Log_Register_Write::setbit(unsigned int bit_number, bool new_value) { getReplaced()->setbit(bit_number,new_value); takeAction(); } void Log_Register_Write::takeAction() { GetTraceLog().register_write(getReg(), get_cycles().get()); } void Log_Register_Write_value::takeAction() { GetTraceLog().register_write_value(getReg(), get_cycles().get()); } unsigned int Log_Register_Read::get() { unsigned int v = getReplaced()->get(); takeAction(); return v; } RegisterValue Log_Register_Read::getRV() { RegisterValue rv = getReplaced()->getRV(); takeAction(); return rv; } RegisterValue Log_Register_Read::getRVN() { RegisterValue rv = getReplaced()->getRVN(); takeAction(); return rv; } bool Log_Register_Read::get_bit(unsigned int bit_number) { takeAction(); return(getReplaced()->get_bit(bit_number)); } void Log_Register_Read::takeAction() { GetTraceLog().register_read(getReg(), get_cycles().get()); } void Log_Register_Read_value::takeAction() { GetTraceLog().register_read(getReg(), get_cycles().get()); } gpsim-0.30.0/src/attributes.cc0000664000076400007640000001606413041763624013145 00000000000000/* Copyright (C) 1998-2005 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "attributes.h" #include "processor.h" #include "symbol.h" #include "gpsim_time.h" #include "protocol.h" #include "../config.h" #include //======================================================================== // Attribute wrappers // // Attribute wrappers are simple classes that handle specific processor // attributes. Their primary purpose is to allow for a way to call back // into the processor classs whenever the attribute changes. //======================================================================== // WarnMode //======================================================================== WarnModeAttribute::WarnModeAttribute(Processor *_cpu) : Boolean(false) ,cpu(_cpu) { new_name("WarnMode"); set_description(" enable warning messages when true"); } void WarnModeAttribute::set(Value *v) { Boolean::set(v); bool currentVal; get(currentVal); cpu->setWarnMode(currentVal); } void WarnModeAttribute::get(bool &b) { b = cpu->getWarnMode(); Boolean::set(b); } //======================================================================== // SafeModeAttribute //======================================================================== SafeModeAttribute::SafeModeAttribute(Processor *_cpu) : Boolean("SafeMode", false, " Model the processor's specification when true. Model the actual\n" " processor when false (e.g. TRIS instruction for mid range PICs\n" " will emit a warning if SafeMode is true)." ), cpu(_cpu) { } SafeModeAttribute::~SafeModeAttribute() { } void SafeModeAttribute::set(Value *v) { Boolean::set(v); bool currentVal; Boolean::get(currentVal); cpu->setSafeMode(currentVal); } void SafeModeAttribute::get(bool &b) { b = cpu->getSafeMode(); Boolean::set(b); } //======================================================================== // UnknownModeAttribute //======================================================================== UnknownModeAttribute::UnknownModeAttribute(Processor *_cpu) : Boolean(false) ,cpu(_cpu) { new_name("UnknownMode"); set_description(" Enable three-state register logic. Unknown values are treated \n" " as 0 when this is false."); } void UnknownModeAttribute::set(Value *v) { Boolean::set(v); bool currentVal; Boolean::get(currentVal); cpu->setUnknownMode(currentVal); } void UnknownModeAttribute::get(bool &b) { b = cpu->getUnknownMode(); Boolean::set(b); } //======================================================================== // BreakOnResetAttribute //======================================================================== BreakOnResetAttribute::BreakOnResetAttribute(Processor *_cpu) : Boolean(false) ,cpu(_cpu) { new_name("BreakOnReset"); set_description(" If true, halt simulation when reset occurs \n"); } void BreakOnResetAttribute::set(Value *v) { Boolean::set(v); bool currentVal; Boolean::get(currentVal); cpu->setBreakOnReset(currentVal); } void BreakOnResetAttribute::get(bool &b) { b = cpu->getBreakOnReset(); Boolean::set(b); } //======================================================================== // // Cycle_Counter attribute // // The Cycle_counter attribute exposes the cycle counter through the // gpsim attribute interface. This allows for it to be queried from // the command line or sockets. class CycleCounterAttribute : public Integer { public: CycleCounterAttribute() : Integer(0) { //m_bClearableSymbol = false; new_name("cycles"); set_description(" Simulation time in terms of cycles."); } void set(gint64 i) { static bool warned = false; if(!warned) cout << "cycle counter is read only\n"; warned = true; } void get(gint64 &i) { i = cycles.get(); } void get(Packet &p) { p.EncodeUInt64(cycles.get()); } virtual string toString() { char buf[256]; gint64 i; get(i); long long int j = i; snprintf(buf,sizeof(buf),"%" PRINTF_INT64_MODIFIER "d = 0x%08" PRINTF_INT64_MODIFIER "X",j,j); return string(buf); } }; //======================================================================== // // GUI update rate attribute #ifdef HAVE_GUI class GUIUpdateRateAttribute : public Integer { public: GUIUpdateRateAttribute() : Integer(0) { //m_bClearableSymbol = false; new_name("sim.gui_update_rate"); set_description(" Specifies the number of cycles between gui updates"); } void set(gint64 i) { gi.set_update_rate(i); } void get(gint64 &i) { i = gi.get_update_rate(); } }; #endif //======================================================================== // Integer *verbosity; //######################################################################## void init_attributes() { // Define internal simulator attributes . verbosity = new Integer("sim.verbosity",1,"gpsim's verboseness 0=nothing printed 0xff=very verbose"); globalSymbolTable().addSymbol(verbosity); globalSymbolTable().addSymbol(new CycleCounterAttribute()); stop_watch = new StopWatch; #ifdef HAVE_GUI globalSymbolTable().addSymbol(new GUIUpdateRateAttribute()); #endif globalSymbolTable().addSymbol(new Integer("POR_RESET", POR_RESET)); // Power-on reset globalSymbolTable().addSymbol(new Integer("WDT_RESET", WDT_RESET)); // Watch Dog timer timeout reset globalSymbolTable().addSymbol(new Integer("IO_RESET", IO_RESET)); // I/O pin reset globalSymbolTable().addSymbol(new Integer("SOFT_RESET", SOFT_RESET)); // Software initiated reset globalSymbolTable().addSymbol(new Integer("BOD_RESET", BOD_RESET)); // Brown out detection reset globalSymbolTable().addSymbol(new Integer("SIM_RESET", SIM_RESET)); // Simulation Reset globalSymbolTable().addSymbol(new Integer("MCLR_RESET", MCLR_RESET)); // MCLR (Master Clear) Reset } void destroy_attributes() { globalSymbolTable().deleteSymbol("SourcePath"); globalSymbolTable().deleteSymbol("sim.verbosity"); globalSymbolTable().deleteSymbol("cycles"); #ifdef HAVE_GUI globalSymbolTable().deleteSymbol("sim.gui_update_rate"); #endif globalSymbolTable().deleteSymbol("POR_RESET"); globalSymbolTable().deleteSymbol("WDT_RESET"); globalSymbolTable().deleteSymbol("IO_RESET"); globalSymbolTable().deleteSymbol("SOFT_RESET"); globalSymbolTable().deleteSymbol("BOD_RESET"); globalSymbolTable().deleteSymbol("SIM_RESET"); globalSymbolTable().deleteSymbol("MCLR_RESET"); delete stop_watch; } gpsim-0.30.0/src/clock_phase.h0000664000076400007640000000603513063451152013063 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__CLOCK_PHASE_H__) #define __CLOCK_PHASE_H__ /* Clock Phase The Clock Phase base class takes an external clock source as its input and uses this to control a module's simulation state. For example, the clock input on a microcontroller drives all of the digital state machines. On every edge of the clock, there is digital logic that can potentially change states. The Clock Phase base class can be thought of the "logic" that responds to the clock input and redirects control to the state machines inside of a processor. */ class Processor; //RRRclass pic_processor; class ClockPhase { public: ClockPhase(); virtual ~ClockPhase(); virtual ClockPhase *advance()=0; void setNextPhase(ClockPhase *pNextPhase) { m_pNextPhase = pNextPhase; } ClockPhase *getNextPhase() { return m_pNextPhase; } protected: ClockPhase *m_pNextPhase; }; /* The Processor Phase base class is a Clock Phase class that contains a pointer to a Processor object. It's the base class from which all of the processor's various Phase objects are derived. */ class ProcessorPhase : public ClockPhase { public: explicit ProcessorPhase(Processor *pcpu); virtual ~ProcessorPhase(); protected: Processor *m_pcpu; }; /* The Execute 1 Cycle class is a Processor Phase class designed to execute a single instruction. */ class phaseExecute1Cycle : public ProcessorPhase { public: explicit phaseExecute1Cycle(Processor *pcpu); virtual ~phaseExecute1Cycle(); virtual ClockPhase *advance(); }; class phaseExecute2ndHalf : public ProcessorPhase { public: explicit phaseExecute2ndHalf(Processor *pcpu); virtual ~phaseExecute2ndHalf(); virtual ClockPhase *advance(); ClockPhase *firstHalf(unsigned int uiPC); protected: unsigned int m_uiPC; }; class phaseCaptureInterrupt : public ProcessorPhase { public: explicit phaseCaptureInterrupt(Processor *pcpu); ~phaseCaptureInterrupt(); virtual ClockPhase *advance(); void firstHalf(); protected: ClockPhase *m_pCurrentPhase; ClockPhase *m_pNextNextPhase; }; // phaseIdle - when a processor is idle, the current // clock source can be handled by this class. class phaseIdle : public ProcessorPhase { public: explicit phaseIdle(Processor *pcpu); virtual ~phaseIdle(); virtual ClockPhase *advance(); protected: }; #endif //if !defined(__CLOCK_PHASE_H__) gpsim-0.30.0/src/rcon.h0000664000076400007640000000344713041763624011563 00000000000000/* * Copyright (C) 1998-2007 T. Scott Dattalo * Copyright (C) 2007 Roy R Rankin * This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef RCON_H #define RCON_H // The methods of this class are typically called from Status_register //--------------------------------------------------------- class RCON : public sfr_register { public: enum { BOR = 1<<0, POR = 1<<1, PD = 1<<2, TO = 1<<3, RI = 1<<4, LWRT = 1<<6, IPEN = 1<<7 }; RCON(Processor *, const char *pName, const char *pDesc=0); inline void put_PD(unsigned int new_pd) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~PD) | ((new_pd) ? PD : 0)); } inline unsigned int get_PD() { get_trace().raw(read_trace.get() | value.get()); return( ( (value.get() & PD) == 0) ? 0 : 1); } inline void put_TO(unsigned int new_to) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~TO) | ((new_to) ? TO : 0)); } inline unsigned int get_TO() { get_trace().raw(read_trace.get() | value.get()); return( ( (value.get() & TO) == 0) ? 0 : 1); } }; #endif // RCON_H gpsim-0.30.0/src/p18fk.h0000664000076400007640000001337313045777152011557 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2010,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P18FK_H__ #define __P18FK_H__ #include "16bit-processors.h" #include "eeprom.h" #include "psp.h" #include "pir.h" #include "comparator.h" #include "spp.h" #include "ctmu.h" #ifdef IESO #undef IESO #endif #define IESO (1<<7) class PicPortRegister; class PicTrisRegister; class PicLatchRegister; class ADCON0_V2; class ADCON1_V2; class ADCON2_V2; class P18F14K22 : public _16bit_processor { public: ADCON0_V2 adcon0; ADCON1_2B adcon1; ADCON2_V2 adcon2; FVRCON_V2 vrefcon0; DACCON0_V2 vrefcon1; DACCON1 vrefcon2; ECCPAS eccp1as; PWM1CON pwm1con; OSCTUNE osctune; ComparatorModule2 comparator; ANSEL_2A ansela; ANSEL_2A anselb; IOC slrcon; // using IOC for it's mask this register is a NOP in gpsim // sfr_register slrcon; // this register is a NOP in gpsim CCPTMRS ccptmrs; PSTRCON pstrcon; SR_MODULE sr_module; SSP1_MODULE ssp1; WPU *wpua; WPU *wpub; IOC *ioca; IOC *iocb; virtual bool HasCCP2(void) { return false; } virtual bool MovedReg() { return false;} virtual OSCCON * getOSCCON(void); virtual PROCESSOR_TYPE isa(){return _P18F14K22_;} P18F14K22(const char *_name=0, const char *desc=0); ~P18F14K22(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual unsigned int access_gprs() { return 0x60; }; virtual unsigned int program_memory_size() const { return 0x4000; }; virtual unsigned int last_actual_register () const { return 0x01FF;}; virtual unsigned int eeprom_memory_size() const { return 256; }; virtual void create_iopin_map(); virtual void create_sfr_map(); virtual void osc_mode(unsigned int value); virtual void set_config3h(gint64 x); virtual string string_config3h(gint64 x) {return string("fix string_config3h");} virtual unsigned int get_device_id() { return (0x20 << 8)|(0x3 <<5); } void create(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } }; class P18F26K22 : public _16bit_processor { public: PicPortRegister *m_porte; PicTrisRegister *m_trise; PicLatchRegister *m_late; ADCON0_V2 adcon0; ADCON1_2B adcon1; ADCON2_V2 adcon2; FVRCON_V2 vrefcon0; DACCON0_V2 vrefcon1; DACCON1 vrefcon2; ECCPAS eccp1as; ECCPAS eccp2as; ECCPAS eccp3as; PWM1CON pwm1con; PWM1CON pwm2con; PWM1CON pwm3con; OSCTUNE osctune; T1GCON t1gcon; T5CON *t3con2; T1GCON t3gcon; TMRL tmr5l; TMRH tmr5h; T5CON *t5con; T1GCON t5gcon; T2CON t4con; PR2 pr4; TMR2 tmr4; T2CON t6con; PR2 pr6; TMR2 tmr6; PIR3v3 pir3; PIE pie3; PIR4v1 pir4; PIE pie4; PIR5v1 pir5; PIE pie5; sfr_register ipr3; sfr_register ipr4; sfr_register ipr5; CCPCON ccp3con; CCPRL ccpr3l; CCPRH ccpr3h; CCPCON ccp4con; CCPRL ccpr4l; CCPRH ccpr4h; CCPCON ccp5con; CCPRL ccpr5l; CCPRH ccpr5h; USART_MODULE usart2; ComparatorModule2 comparator; sfr_register pmd0; sfr_register pmd1; sfr_register pmd2; ANSEL_2B ansela; ANSEL_2B anselb; ANSEL_2B anselc; IOC slrcon; // using IOC for it's mask this register is a NOP in gpsim CCPTMRS ccptmrs; PSTRCON pstr1con; PSTRCON pstr2con; PSTRCON pstr3con; SR_MODULE sr_module; SSP1_MODULE ssp1; SSP1_MODULE ssp2; CTMU ctmu; HLVDCON hlvdcon; OSCCON2 osccon2; WPU *wpub; IOC *iocb; virtual bool HasCCP2(void) { return false; }; // at wrong address virtual bool MovedReg() { return true;} virtual OSCCON * getOSCCON(void) { return new OSCCON_HS(this, "osccon", "OSC Control"); } virtual PROCESSOR_TYPE isa(){return _P18F26K22_;}; P18F26K22(const char *_name=0, const char *desc=0); ~P18F26K22(); static Processor *construct(const char *name); virtual PROCESSOR_TYPE base_isa(){return _PIC18_PROCESSOR_;}; virtual unsigned int access_gprs() { return 0x60; }; virtual unsigned int program_memory_size() const { return 0x8000; }; virtual unsigned int last_actual_register () const { return 0x0F37;}; virtual unsigned int eeprom_memory_size() const { return 1024; }; virtual void create_iopin_map(); virtual void create_sfr_map(); virtual void osc_mode(unsigned int value); virtual void set_config3h(gint64 x); virtual string string_config3h(gint64 x) {return string("fix string_config3h");} virtual unsigned int get_device_id() { return (0x54 << 8)|(0x3 <<5); } void create(); virtual void update_vdd(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as the 18Fxxx devices use an EEPROM with PIR assert(0); } virtual void set_eeprom_pir(EEPROM_PIR *ep) { eeprom = ep; } virtual EEPROM_PIR *get_eeprom() { return ((EEPROM_PIR *)eeprom); } }; #endif gpsim-0.30.0/src/fopen-path.cc0000664000076400007640000001641113065573230013012 00000000000000/* -*- Mode: C++; c-file-style: "bsd"; comment-column: 40 -*- */ /* Copyright (C) 2000 Daniel Christian, T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // fopen-path.cc // // Modified version of fopen, that searches a path. // Technically this is a c++ file, but it should work in C too. // The functions use a C calling convention for compatibility. #include #include #include #include #include #include #include "../config.h" #include "gpsim_def.h" #include "pic-processor.h" #include "fopen-path.h" // should be command line static char **searchPath = 0; static int searchPathCount = 0; class CSourceSearchPath : public String { public: CSourceSearchPath() : String("SourcePath", NULL, "Search path for source files") { } virtual void set(const char *cP,int len=0) { set_search_path(cP); } virtual void set(Value *pValue) { String *pString = dynamic_cast(pValue); if(pString != NULL) { set_search_path(pString->getVal()); } } string toString() { string sPath; for (int iIndex = 0; iIndex < searchPathCount; ++iIndex) { sPath.append(searchPath[iIndex]); if(iIndex < searchPathCount - 1) { sPath.append(":"); } } return sPath; } char *toString(char *return_str, int len) { for (int iIndex = 0; iIndex < searchPathCount && len < 0; ++iIndex) { char *pFolder = searchPath[iIndex]; strncpy(return_str, pFolder, len); len -= strlen(pFolder); if(iIndex < searchPathCount) { len--; } } return return_str; } }; /// /// InitSourceSearchSymbol /// Used to initialize the CSourceSearchPath during startup. /// The symbol table will delete the CSourceSearchPath /// object so CSourceSearchPath cannot be static. void InitSourceSearchAsSymbol() { // The symbol table will delete the CSourceSearchPath object globalSymbolTable().addSymbol(new CSourceSearchPath()); } // Given a colon separated path, setup searchPath and searchPathCount // Fix:: Any old values are lost (and the memory leaked). void set_search_path (const char *path) { const char *cp, *tp; int pathLen; int ii; char **pathStr; if (!path || !*path) { // clear the path searchPathCount = 0; if(searchPath != 0) { free(searchPath); searchPath = 0; } if (verbose) cout << "Clearing Search directory.\n"; return; } // count colons to figure length for (cp = path, pathLen = 0; *cp; ++cp) { if (':' == *cp) ++pathLen; } ++pathLen; // always one more segments than colons // searchPath = (char *[])calloc (pathLen, sizeof (char *)); if(searchPath != 0) { free(searchPath); } // allocate an array of string pointers with one extra set to NULL // to mark the end of the array. searchPath = static_cast(calloc (pathLen, sizeof (char *))); assert (0 != searchPath); // Parse the colon delimited string path and put each folder into // the string array. for (cp = path, pathStr = searchPath, ii = 0, tp = strchr (path, ':'); (0 != tp) && (ii < pathLen); ++ii) { assert ((0 != cp) && (0 != tp)); if (tp == cp) { // treat empty path as "." *pathStr = strdup ("."); // allocate, in case we free later } else { // copy out the string section const char *sp; char *dp; *pathStr = (char *)malloc (tp - cp + 1); assert (0 != *pathStr); for (dp = *pathStr, sp = cp; sp < tp; *dp++ = *sp++); *dp = 0; // NULL terminate } if (verbose) cout << "Search directory: " << *pathStr << '\n'; ++pathStr; cp = tp+1; tp = strchr (cp, ':'); } if (*cp) { *pathStr = strdup (cp); // get last one } else { *pathStr = strdup ("."); // allocate, in case we free later } if (verbose) cout << "Search directory: " << *pathStr << '\n'; searchPathCount = pathLen; } //----------------------------------------------------------- // Try to open a file on a series of paths. First try as an absolute path. // This tries to keep as much of the original file path as possible. // for example: fopen_path ("src/pic/foo.inc", "r"), will try // src/pic/foo.inc, // PATH1/src/pic/foo.inc, PATH1/pic/foo.inc, PATH1/foo.inc // PATH2/src/pic/foo.inc, PATH2/pic/foo.inc, PATH2/foo.inc // ... // It also converts back slashes to forward slashes (for MPLAB compatibility) FILE *fopen_path(const char *filename, const char *perms) { FILE *fp; const char *fileStr; // filename walker char **pathStr; // path pointer int ii; // loop counter char *cp; // for string walking char *nameBuff=0; // where to build new filename long maxpath; #if defined(_WIN32) maxpath = MAX_PATH; #else if ((maxpath = pathconf(filename, _PC_PATH_MAX)) < 0) return 0; #endif if (strlen(filename) >= (unsigned int)maxpath) { errno = ENAMETOOLONG; return 0; } nameBuff = (char *)malloc(maxpath); strncpy(nameBuff, filename, maxpath); nameBuff[maxpath-1] = 0; for (cp = nameBuff; *cp; ++cp) { // convert DOS slash to Unix slash if ('\\' == *cp) *cp = '/'; } fp = fopen (nameBuff, perms); // first try absolute path if (fp) { if (verbose) printf ("Found %s as %s\n", filename, nameBuff); free(nameBuff); return fp; } // check along each directory for (pathStr = searchPath, ii=0; ii < searchPathCount; ++ii, ++pathStr) { // check each subdir in path for (fileStr = filename; fileStr && *fileStr; fileStr = strpbrk (fileStr+1, "/\\")) { strcpy (nameBuff, *pathStr); if (strlen(nameBuff) + strlen(fileStr) < (unsigned int)maxpath) { strcat (nameBuff, fileStr); for (cp = nameBuff; *cp; ++cp) { // convert DOS slash to Unix slash if ('\\' == *cp) *cp = '/'; } if (verbose) { printf ("Trying to open %s\n", nameBuff); } fp = fopen (nameBuff, perms); // try it if (0 != fp) { if (verbose) printf ("Found %s as %s\n", filename, nameBuff); free(nameBuff); return fp; } } } } if (verbose) { printf ("Failed to open %s in path: ", filename); for (pathStr = searchPath, ii=0; ii < searchPathCount; ++ii, ++pathStr) { printf ("%s ", *pathStr); } printf ("\n"); } free(nameBuff); return 0; } gpsim-0.30.0/src/pie.cc0000664000076400007640000000077013101223076011516 00000000000000#include // for guint64 #include "trace.h" #include "intcon.h" #include "pie.h" #include "pir.h" #include "processor.h" PIE::PIE(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), pir(0) { } void PIE::setPir(PIR *pPir) { pir = pPir; } void PIE::put(unsigned int new_value) { assert(pir); trace.raw(write_trace.get() | value.get()); value.put(new_value & pir->valid_bits); if(pir->interrupt_status()) pir->setPeripheralInterrupt(); } gpsim-0.30.0/src/trace_orb.h0000664000076400007640000000225313041763624012554 00000000000000/* Copyright (C) 1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __TRACE_ORB_H__ #define __TRACE_ORB_H__ //------------------------------------ // *** KNOWN CHANGE *** // // THIS FILE IS (OR SHOULD BE) TEMPORARY // // Here are a set of support functions called by the CLI. Eventually // these will be replaced with an indirect interface such as CORBA. #define TRACE_FILE_FORMAT_ASCII 0 #define TRACE_FILE_FORMAT_LXT 1 void trace_enable_logging(char *file=0, int mode=TRACE_FILE_FORMAT_ASCII); #endif gpsim-0.30.0/src/p1xf1xxx.h0000664000076400007640000001621713043352000012310 00000000000000#ifndef __P1xF1xxx_H__ #define __P1xF1xxx_H__ #include "14bit-processors.h" #include "14bit-tmrs.h" #include "intcon.h" #include "pir.h" #include "pie.h" #include "eeprom.h" #include "comparator.h" #include "a2dconverter.h" #include "pic-ioports.h" #include "dsm_module.h" #define FOSC0 (1<<0) #define FOSC1 (1<<1) #define FOSC2 (1<<2) #define IESO (1<<12) class APFCON : public sfr_register { public: void put(unsigned int new_value); void set_pins(unsigned int bit, PinModule *pin0, PinModule *pin1) { m_bitPin[0][bit] = pin0; m_bitPin[1][bit] = pin1; } void set_usart(USART_MODULE *_usart) { m_usart = _usart;}; void set_ssp(SSP1_MODULE *_ssp) { m_ssp = _ssp;}; void set_t1gcon(T1GCON *_t1gcon) { m_t1gcon = _t1gcon;}; void set_ccpcon(CCPCON *_ccpcon) { m_ccpcon = _ccpcon;}; void set_ValidBits(unsigned int _mask){mValidBits = _mask;} APFCON(Processor *pCpu, const char *pName, const char *pDesc); private: PinModule *m_bitPin[2][8]; USART_MODULE *m_usart; SSP1_MODULE *m_ssp; T1GCON *m_t1gcon; CCPCON *m_ccpcon; }; class P12F1822 : public _14bit_e_processor { public: ComparatorModule2 comparator; PIR_SET_2 pir_set_2_def; PIE pie1; PIR *pir1; PIE pie2; PIR *pir2; T2CON t2con; PR2 pr2; TMR2 tmr2; T1CON_G t1con_g; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; FVRCON fvrcon; BORCON borcon; ANSEL_P ansela; ADCON0 adcon0; ADCON1_16F adcon1; sfr_register adresh; sfr_register adresl; OSCCON_2 *osccon; OSCTUNE osctune; OSCSTAT oscstat; //OSCCAL osccal; WDTCON wdtcon; USART_MODULE usart; SSP1_MODULE ssp; APFCON apfcon; PWM1CON pwm1con; ECCPAS ccp1as; PSTRCON pstr1con; CPSCON0 cpscon0; CPSCON1 cpscon1; SR_MODULE sr_module; EEPROM_EXTND *e; WPU *m_wpua; IOC *m_iocap; IOC *m_iocan; IOCxF *m_iocaf; PicPortIOCRegister *m_porta; PicTrisRegister *m_trisa; PicLatchRegister *m_lata; DACCON0 *m_daccon0; DACCON1 *m_daccon1; DSM_MODULE dsm_module; virtual PIR *get_pir2() { return (NULL); } virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } virtual EEPROM_EXTND *get_eeprom() { return ((EEPROM_EXTND *)eeprom); } virtual PROCESSOR_TYPE isa(){return _P12F1822_;}; static Processor *construct(const char *name); P12F1822(const char *_name=0, const char *desc=0); ~P12F1822(); virtual void create_sfr_map(); virtual void create_symbols(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create_iopin_map(); virtual void create(int ram_top, int eeprom_size); virtual unsigned int register_memory_size () const { return 0x1000; } virtual void option_new_bits_6_7(unsigned int bits); virtual unsigned int program_memory_size() const { return 2048; } virtual void enter_sleep(); virtual void exit_sleep(); virtual void oscillator_select(unsigned int mode, bool clkout); virtual void program_memory_wp(unsigned int mode); }; class P12F1840 : public P12F1822 { public: static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 4096; } virtual void create(int ram_top, int eeprom_size); P12F1840(const char *_name=0, const char *desc=0); ~P12F1840(); sfr_register *vrefcon; }; class P16F178x : public _14bit_e_processor { public: ComparatorModule2 comparator; PIR_SET_2 pir_set_2_def; PIE pie1; PIR *pir1; PIE pie2; PIR *pir2; PIE pie3; PIR *pir3; T2CON t2con; PR2 pr2; TMR2 tmr2; T1CON_G t1con_g; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; FVRCON fvrcon; BORCON borcon; ANSEL_P ansela; ANSEL_P anselb; ANSEL_P anselc; ADCON0_DIF adcon0; ADCON1_16F adcon1; ADCON2_DIF adcon2; sfr_register adresh; sfr_register adresl; OSCCON_2 *osccon; OSCTUNE osctune; OSCSTAT oscstat; //OSCCAL osccal; WDTCON wdtcon; USART_MODULE usart; SSP1_MODULE ssp; APFCON apfcon1; APFCON apfcon2; PWM1CON pwm1con; ECCPAS ccp1as; PSTRCON pstr1con; EEPROM_EXTND *e; WPU *m_wpua; IOC *m_iocap; IOC *m_iocan; IOCxF *m_iocaf; PicPortIOCRegister *m_porta; PicTrisRegister *m_trisa; PicLatchRegister *m_lata; IOC *m_iocep; IOC *m_iocen; IOCxF *m_iocef; PicPortIOCRegister *m_porte; PicTrisRegister *m_trise; WPU *m_wpue; DACCON0 *m_daccon0; DACCON1 *m_daccon1; DACCON0 *m_dac2con0; DACCON1 *m_dac2con1; DACCON0 *m_dac3con0; DACCON1 *m_dac3con1; DACCON0 *m_dac4con0; DACCON1 *m_dac4con1; IOC *m_iocbp; IOC *m_iocbn; IOCxF *m_iocbf; PicPortBRegister *m_portb; PicTrisRegister *m_trisb; PicLatchRegister *m_latb; WPU *m_wpub; IOC *m_ioccp; IOC *m_ioccn; IOCxF *m_ioccf; PicPortBRegister *m_portc; PicTrisRegister *m_trisc; PicLatchRegister *m_latc; WPU *m_wpuc; virtual PIR *get_pir2() { return (NULL); } virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } virtual EEPROM_EXTND *get_eeprom() { return ((EEPROM_EXTND *)eeprom); } P16F178x(const char *_name=0, const char *desc=0); ~P16F178x(); virtual void create_sfr_map(); virtual void create_symbols(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create(int ram_top, int eeprom_size); virtual void option_new_bits_6_7(unsigned int bits); virtual void enter_sleep(); virtual void exit_sleep(); virtual void oscillator_select(unsigned int mode, bool clkout); virtual void program_memory_wp(unsigned int mode); unsigned int ram_size; }; class P16F1788 : public P16F178x { public: virtual PROCESSOR_TYPE isa(){return _P16F1788_;}; P16F1788(const char *_name=0, const char *desc=0); ~P16F1788(); static Processor *construct(const char *name); virtual void create_sfr_map(); virtual void create_iopin_map(); virtual void create(int ram_top, int eeprom_size); virtual unsigned int program_memory_size() const { return 16384; } virtual unsigned int register_memory_size () const { return 0x1000; } }; class P16F1823 : public P12F1822 { public: ANSEL_P anselc; virtual PROCESSOR_TYPE isa(){return _P16F1823_;}; P16F1823(const char *_name=0, const char *desc=0); ~P16F1823(); static Processor *construct(const char *name); virtual void create_sfr_map(); virtual void create_iopin_map(); virtual void create(int ram_top, int eeprom_size); PicPortBRegister *m_portc; PicTrisRegister *m_trisc; PicLatchRegister *m_latc; WPU *m_wpuc; }; class P16F1825 : public P16F1823 { public: static Processor *construct(const char *name); virtual unsigned int program_memory_size() const { return 8*1024; } virtual void create(int ram_top, int eeprom_size); P16F1825(const char *_name=0, const char *desc=0); ~P16F1825(); }; #endif //__P1xF1xxx_H__ gpsim-0.30.0/src/i2c-ee.cc0000664000076400007640000004070213045306452012013 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2004 Rob Pearce 2006,2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include using namespace std; #include #include "../config.h" #include "trace.h" #include "pic-processor.h" #include "stimuli.h" #include "i2c-ee.h" #include "registers.h" //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif #define Vprintf(arg) { if (verbose) {printf("%s:%d ",__FILE__,__LINE__); printf arg;} } // I2C EEPROM Peripheral // // This object emulates the I2C EEPROM peripheral on the 12CE51x // // It's main purpose is to provide a means by which the port pins // may communicate. // //-------------------------------------------------------------- // // PromAddress::PromAddress(I2C_EE *eeprom, const char *_name, const char * desc) : Value(_name,desc) { m_eeprom = eeprom; } void PromAddress::get(char *buffer, int buf_size) { snprintf(buffer, buf_size, "%p", m_eeprom); } class I2C_SLAVE_SDA : public IO_open_collector { public: i2c_slave *pEE; I2C_SLAVE_SDA(i2c_slave *_pEE, const char *_name) : IO_open_collector(_name), pEE(_pEE) { bDrivingState = true; bDrivenState = true; // Make the pin an output. update_direction(IO_bi_directional::DIR_OUTPUT,true); }; void setDrivenState(bool new_dstate) { bool diff = new_dstate ^ bDrivenState; Dprintf(("i2c_slave sda setDrivenState %d\n", new_dstate)); if( pEE && diff ) { bDrivenState = new_dstate; pEE->new_sda_edge(new_dstate); } } void setDrivingState(bool new_state) { bDrivingState = new_state; bDrivenState = new_state; if(snode) snode->update(); } }; class I2C_SLAVE_SCL : public IO_open_collector { public: i2c_slave *pEE; I2C_SLAVE_SCL(i2c_slave *_pEE, const char *_name) : IO_open_collector(_name), pEE(_pEE) { bDrivingState = true; bDrivenState = true; // Make the pin an output. update_direction(IO_bi_directional::DIR_OUTPUT,true); }; void setDrivenState(bool new_state) { bool diff = new_state ^ bDrivenState; Dprintf(("i2c_slave scl setDrivenState %d\n", new_state)); if( pEE && diff ) { bDrivenState = new_state; pEE->new_scl_edge(bDrivenState); } } void setDrivingState(bool new_state) { bDrivingState = new_state; bDrivenState = new_state; if(snode) snode->update(); } }; i2c_slave::i2c_slave() { scl = new I2C_SLAVE_SCL(this, "SCL"); sda = new I2C_SLAVE_SDA(this, "SDA"); bus_state = IDLE; bit_count = 0; xfr_data = 0; } i2c_slave::~i2c_slave() { if (sda) delete sda; if (scl) delete scl; } void i2c_slave::new_scl_edge(bool direction) { //Vprintf(("%s direction:%d\n", __FUNCTION__, direction)); if (direction) { // Rising edge nxtbit = sda->getDrivenState(); //Vprintf(("%s Rising edge, data=%d\n", __FUNCTION__, nxtbit)); } else { // Falling edge //cout << "I2C_EE SCL : Falling edge\n"; switch ( bus_state ) { case IDLE : sda->setDrivingState ( true ); break; case START : sda->setDrivingState ( true ); bus_state = RX_I2C_ADD; break; case RX_I2C_ADD : if ( shift_read_bit ( sda->getDrivenState() ) ) { Vprintf(("%s : got i2c address :0x%x r/w %u ", __FUNCTION__, xfr_data >> 1, xfr_data & 1)); if (match_address()) { bus_state = ACK_I2C_ADD; Vprintf((" - OK\n")); // Acknowledge the command by pulling SDA low. sda->setDrivingState ( false ); } else { // not for us bus_state = IDLE; Vprintf((" - not for us\n")); } } break; case ACK_I2C_ADD : sda->setDrivingState ( true ); // Check the R/W bit of the address byte if ( xfr_data & 0x01 ) { // master is reading, we transmit bus_state = TX_DATA; bit_count = 8; xfr_data = get_data(); sda->setDrivingState ( shift_write_bit() ); slave_transmit(true); } else { // master is writing, we read bus_state = RX_DATA; bit_count = 0; xfr_data = 0; slave_transmit(false); } break; case RX_DATA : if ( shift_read_bit ( sda->getDrivenState() ) ) { //start_write(); Vprintf(("%s : data set to 0x%x\n", __FUNCTION__, xfr_data)); put_data(xfr_data); sda->setDrivingState ( false ); bus_state = ACK_RX; } break; case ACK_RX : sda->setDrivingState ( true ); bus_state = RX_DATA; bit_count = 0; xfr_data = 0; break; case ACK_WR : sda->setDrivingState ( true ); bus_state = WRPEND; break; case WRPEND : // We were about to do the write but got more data instead // of the expected stop bit xfr_data = sda->getDrivenState(); bit_count = 1; bus_state = RX_DATA; Vprintf(("i2c_slave : write postponed by extra data\n")); break; case TX_DATA : if ( bit_count == 0 ) { sda->setDrivingState ( true ); // Release the bus bus_state = ACK_RD; } else { sda->setDrivingState ( shift_write_bit() ); } break; case ACK_RD : if ( sda->getDrivenState() == false ) { // The master has asserted ACK, so we send another byte bus_state = TX_DATA; bit_count = 8; xfr_data = get_data(); sda->setDrivingState ( shift_write_bit() ); } else { bus_state = IDLE; // Actually a limbo state } break; default : fprintf(stderr, "%s:%s ERROR unexpected state %d\n", __FILE__, __FUNCTION__, bus_state); sda->setDrivingState ( true ); // Release the bus break; } } } void i2c_slave::new_sda_edge(bool direction) { // Vprintf(("i2c_slave::new_sda_edge direction:%d\n", direction)); if (scl->getDrivenState()) { int curBusState = bus_state; if ( direction ) { /* stop bit */ Vprintf(("i2c_slave : Rising edge in SCL high => stop bit\n")); if ( bus_state == WRPEND ) { Vprintf(("i2c_slave : write is pending - commence...\n")); bus_state = IDLE; // Should be busy } else bus_state = IDLE; } else { /* start bit */ Vprintf(("i2c_slave : Falling edge in SCL high => start bit\n")); bus_state = START; bit_count = 0; xfr_data = 0; } if (bus_state != curBusState) Vprintf(("i2c_slave::new_sda_edge() new bus state = %d\n",bus_state)); } } bool i2c_slave::shift_read_bit ( bool x ) { xfr_data = ( xfr_data << 1 ) | ( x != 0 ); bit_count++; if ( bit_count == 8 ) return true; else return false; } bool i2c_slave::shift_write_bit () { bool bit; bit_count--; bit = ( xfr_data >> bit_count ) & 1; Dprintf(("I2c_slave : send bit %u = %c\n", bit_count, bit ? '1' : '0')); return bit; } bool i2c_slave::match_address() { return((xfr_data & 0xfe) == i2c_slave_address); } //---------------------------------------------------------- // // I2C EE PROM // // There are many conditions that need to be verified against a real part: // 1) what happens if // > the simulator // 2) what happens if a RD is initiated while data is being written? // > the simulator ignores the read // 3) what happens if // > the simulator I2C_EE::I2C_EE(Processor *pCpu, unsigned int _rom_size, unsigned int _write_page_size, unsigned int _addr_bytes, unsigned int _CSmask, unsigned int _BSmask, unsigned int _BSshift) : i2c_slave(), rom(0), rom_size(_rom_size), // size of eeprom in bytes rom_data_size(1), xfr_addr(0), write_page_off(0), write_page_size(_write_page_size), // Page size for writes bit_count(0), m_command(0), m_chipselect(0), m_CSmask(_CSmask), // mask for chip select in command m_BSmask(_BSmask), // mask for bank select in command m_BSshift(_BSshift), // right shift bank select to bit 0 m_addr_bytes(_addr_bytes), // number of address bytes m_write_protect(false), ee_busy(false) { // Create the rom rom = (Register **) new char[sizeof (Register *) * rom_size]; assert(rom != 0); // Initialize the rom char str[100]; for (unsigned int i = 0; i < rom_size; i++) { snprintf (str,sizeof(str),"ee0x%02x", i); rom[i] = new Register(pCpu,str,""); rom[i]->address = i; rom[i]->value.put(0); rom[i]->alias_mask = 0; } if (pCpu) { m_UiAccessOfRom = new RegisterCollection(pCpu, "eeData", rom, rom_size); } else m_UiAccessOfRom = NULL; } I2C_EE::~I2C_EE() { for (unsigned int i = 0; i < rom_size; i++) delete rom[i]; delete [] rom; if (m_UiAccessOfRom) delete m_UiAccessOfRom; } void I2C_EE::slave_transmit(bool yes) { if (yes) // prepare to output eeprom data { io_state = TX_EE_DATA; xfr_addr += write_page_off; write_page_off = 0; } else // getting eeprom address { io_state = RX_EE_ADDR; xfr_addr = (m_command & m_BSmask) >> m_BSshift; m_addr_cnt = m_addr_bytes; } } // data written by master device void I2C_EE::put_data(unsigned int data) { switch(io_state) { case RX_EE_ADDR: // convert xfr_data to base and page offset to allow // sequencel writes to wrap around page xfr_addr = ((xfr_addr << 8) | data ) % rom_size; if (--m_addr_cnt == 0) { write_page_off = xfr_addr % write_page_size; xfr_addr -= write_page_off; Vprintf(("I2C_EE : address set to 0x%x page offset 0x%x data:0x%x\n", xfr_addr, write_page_off ,data)); io_state = RX_EE_DATA; } break; case RX_EE_DATA: if (! m_write_protect) { rom[xfr_addr + write_page_off]->value.put( data ); write_page_off = (write_page_off+1) % write_page_size; } else cout << "I2c_EE start_write- write protect\n"; break; case TX_EE_DATA: cout << "I2C_EE put_data in output state\n"; break; default: cout << "I2c_EE unexpected state\n"; break; } } unsigned int I2C_EE::get_data() { unsigned int data = rom[xfr_addr]->get(); xfr_addr = (xfr_addr + 1) % rom_size; return (data); } // Bit 0 is write protect, 1-3 is A0 - A2 void I2C_EE::set_chipselect(unsigned int _cs) { m_write_protect = (_cs & 1) == 1; m_chipselect = (_cs & m_CSmask); } void I2C_EE::debug() { if (!scl || !sda || !rom) return; const char *cPBusState=0; switch (bus_state) { case IDLE: cPBusState = "IDLE"; break; case START: cPBusState = "START"; break; case RX_I2C_ADD: cPBusState = "RX_I2C_ADD"; break; case ACK_I2C_ADD: cPBusState = "ACK_I2C_ADD"; break; case RX_DATA: cPBusState = "RX_DATA"; break; case ACK_WR: cPBusState = "ACK_WR"; break; case ACK_RX: cPBusState = "ACK_RX"; break; case WRPEND: cPBusState = "WRPEND"; break; case ACK_RD: cPBusState = "ACK_RD"; break; case TX_DATA: cPBusState = "TX_DATA"; break; } cout << "I2C EEPROM: current state="<value.put(val); } // write data to eeprom unles write protect is active void I2C_EE::start_write() { unsigned int addr = xfr_addr + write_page_off; if (! m_write_protect) { rom[addr]->put ( xfr_data ); } else cout << "I2c_EE start_write- write protect\n"; } // allow 5 msec after last write void I2C_EE::write_busy() { guint64 fc; if (! ee_busy && ! m_write_protect) { fc = (guint64)(get_cycles().instruction_cps() * 0.005); get_cycles().set_break(get_cycles().get() + fc, this); ee_busy = true; } } void I2C_EE::write_is_complete() { } void I2C_EE::callback() { ee_busy = false; Vprintf(("I2C_EE::callback() - write cycle is complete\n")); } void I2C_EE::callback_print() { cout << "Internal I2C-EEPROM\n"; } bool I2C_EE::match_address() { if ((xfr_data & 0xf0) == 0xa0 && ((xfr_data & m_CSmask) == m_chipselect)) { m_command = xfr_data; return true; } return false; } void I2C_EE::reset(RESET_TYPE by) { switch(by) { case POR_RESET: bus_state = IDLE; ee_busy = false; break; default: break; } } void I2C_EE::attach ( Stimulus_Node *_scl, Stimulus_Node *_sda ) { _scl->attach_stimulus ( scl ); _sda->attach_stimulus ( sda ); } void I2C_EE::dump() { unsigned int i, j, reg_num,v; cout << " " << hex; // Column labels for (i = 0; i < 16; i++) cout << setw(2) << setfill('0') << i << ' '; cout << '\n'; for (i = 0; i < rom_size/16; i++) { cout << setw(2) << setfill('0') << i << ": "; for (j = 0; j < 16; j++) { reg_num = i * 16 + j; if(reg_num < rom_size) { v = rom[reg_num]->get_value(); cout << setw(2) << setfill('0') << v << ' '; } else cout << "-- "; } cout << " "; for (j = 0; j < 16; j++) { reg_num = i * 16 + j; if(reg_num < rom_size) { v = rom[reg_num]->get_value(); if( (v >= ' ') && (v <= 'z')) cout.put(v); else cout.put('.'); } } cout << '\n'; } } gpsim-0.30.0/src/p16x5x.cc0000664000076400007640000002307313041763624012030 00000000000000/* Copyright (C) 2000 T. Scott Dattalo, Daniel Schudel This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16x5x // // This file supports: // P16C54 // P16C55 // P16C56 #include #include #include #include "packages.h" #include "p16x5x.h" #include "pic-ioports.h" #include "symbol.h" void P16C54::create_iopin_map() { #ifdef USE_PIN_MODULE_FOR_TOCKI IOPIN * tockipin; #endif package = new Package(18); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta3"),3)); #ifdef USE_PIN_MODULE_FOR_TOCKI // RCP - attempt to add TOCKI without port register tockipin = new IOPIN("tocki"); m_tocki->setPin ( tockipin ); package->assign_pin( 3, tockipin ); // RCP - End new code #else package->assign_pin( 3, m_tocki->addPin(new IOPIN("tocki"),0)); #endif package->assign_pin( 4, 0); package->assign_pin( 5, 0); package->assign_pin( 6, m_portb->addPin(new IO_bi_directional("portb0"),0)); package->assign_pin( 7, m_portb->addPin(new IO_bi_directional("portb1"),1)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional("portb2"),2)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional("portb7"),7)); package->assign_pin(14, 0); package->assign_pin(15, 0); package->assign_pin(16, 0); } void P16C55::create_iopin_map() { package = new Package(28); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin( 6, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 8, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 9, m_porta->addPin(new IO_bi_directional("porta3"),3)); #ifdef USE_PIN_MODULE_FOR_TOCKI // RCP - attempt to add TOCKI without port register tockipin = new IOPIN("tocki"); m_tocki->setPin ( tockipin ); package->assign_pin( 1, tockipin ); // RCP - End new code #else package->assign_pin( 1, m_tocki->addPin(new IOPIN("tocki"),0)); #endif package->assign_pin( 2, 0); package->assign_pin( 3, 0); package->assign_pin( 4, 0); package->assign_pin( 5, 0); package->assign_pin(10, m_portb->addPin(new IO_bi_directional("portb0"),0)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional("portb1"),1)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional("portb2"),2)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional("portb3"),3)); package->assign_pin(14, m_portb->addPin(new IO_bi_directional("portb4"),4)); package->assign_pin(15, m_portb->addPin(new IO_bi_directional("portb5"),5)); package->assign_pin(16, m_portb->addPin(new IO_bi_directional("portb6"),6)); package->assign_pin(17, m_portb->addPin(new IO_bi_directional("portb7"),7)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(19, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(20, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(21, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(22, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(23, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(24, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(25, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(26, 0); package->assign_pin(27, 0); package->assign_pin(28, 0); } void P16C54::create_sfr_map() { if(verbose) cout << "creating c54 registers\n"; add_file_registers(0x07, 0x1f, 0x00); add_sfr_register(indf, 0x00); add_sfr_register(&tmr0, 0x01); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); add_sfr_register(m_porta, 0x05); add_sfr_register(m_portb, 0x06); add_sfr_register(option_reg, 0xffffffff, RegisterValue(0xff,0)); add_sfr_register(m_trisa, 0xffffffff, RegisterValue(0x1f,0)); add_sfr_register(m_trisb, 0xffffffff, RegisterValue(0xff,0)); #ifndef USE_PIN_MODULE_FOR_TOCKI add_sfr_register(m_tocki, 0xffffffff, RegisterValue(0x01,0)); add_sfr_register(m_trist0, 0xffffffff, RegisterValue(0x01,0)); #endif } void P16C54::create_symbols() { _12bit_processor::create_symbols(); } void P16C54::create() { create_iopin_map(); _12bit_processor::create(); } Processor * P16C54::construct(const char *name) { P16C54 *p = new P16C54(name); if(verbose) cout << " c54 construct\n"; p->pc->set_reset_address(0x1ff); p->create(); p->create_invalid_registers(); p->create_sfr_map(); p->create_symbols(); return p; } P16C54::P16C54(const char *_name, const char *desc) : _12bit_processor(_name,desc) { if(verbose) cout << "c54 constructor, type = " << isa() << '\n'; m_porta = new PicPortRegister(this,"porta","",8,0x1f); m_trisa = new PicTrisRegister(this,"trisa","",m_porta, false); m_portb = new PicPortRegister(this,"portb","",8,0xff); m_trisb = new PicTrisRegister(this,"trisb","",m_portb, false); #ifdef USE_PIN_MODULE_FOR_TOCKI // RCP - Attempt to assign TOCKI without a port register m_tocki = new PinModule(); cout << "c54 contructor assigning tmr0\n"; tmr0.set_cpu(this, m_tocki); #else m_tocki = new PicPortRegister(this,"tockiport","",8,0x01); m_trist0 = new PicTrisRegister(this,"trist0","",m_tocki, false); // cout << "c54 contructor assigning tmr0 to tocki register\n"; tmr0.set_cpu(this, m_tocki, 0,option_reg); #endif tmr0.start(0); } P16C54::~P16C54() { delete_file_registers(0x07, 0x1f); // add_sfr_register(indf); remove_sfr_register(&tmr0); // add_sfr_register(pcl); // add_sfr_register(status); // add_sfr_register(fsr); delete_sfr_register(m_porta); delete_sfr_register(m_portb); // delete_sfr_register(option_reg); delete_sfr_register(m_trisa); delete_sfr_register(m_trisb); #ifndef USE_PIN_MODULE_FOR_TOCKI delete_sfr_register(m_tocki); delete_sfr_register(m_trist0); #endif } void P16C54::tris_instruction(unsigned int tris_register) { switch (tris_register) { case 5: m_trisa->put(Wget()); //trace.write_TRIS(m_trisa->value.get()); break; case 6: m_trisb->put(Wget()); //trace.write_TRIS(m_trisb->value.get()); break; default: cout << __FUNCTION__ << ": Unknown TRIS register " << tris_register << endl; break; } } void P16C55::create_sfr_map() { if(verbose) cout << "creating c55 registers\n"; P16C54::create_sfr_map(); delete_file_registers(0x07, 0x07); add_sfr_register(m_portc, 0x07); add_sfr_register(m_trisc, 0xffffffff, RegisterValue(0xff,0)); } void P16C55::create_symbols() { P16C54::create_symbols(); } void P16C55::create() { P16C54::create(); } Processor * P16C55::construct(const char *name) { P16C55 *p = new P16C55(name); if(verbose) cout << " c55 construct\n"; p->pc->set_reset_address(0x1ff); p->create(); p->create_invalid_registers(); p->create_sfr_map(); p->create_symbols(); return p; } P16C55::P16C55(const char *_name, const char *desc) : P16C54(_name,desc) { if(verbose) cout << "c55 constructor, type = " << isa() << '\n'; m_portc = new PicPortRegister(this,"portc","",8,0xff); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false); } P16C55::~P16C55() { delete_sfr_register(m_trisc); } void P16C55::tris_instruction(unsigned int tris_register) { switch (tris_register) { case 5: m_trisa->put(Wget()); //trace.write_TRIS(m_trisa->value.get()); break; case 6: m_trisb->put(Wget()); //trace.write_TRIS(m_trisb->value.get()); break; case 7: m_trisc->put(Wget()); //trace.write_TRIS(m_trisc->value.get()); break; default: cout << __FUNCTION__ << ": Unknown TRIS register " << tris_register << endl; break; } } Processor * P16C56::construct(const char *name) { P16C56 *p = new P16C56(name); if(verbose) cout << " c56 construct\n"; p->pc->set_reset_address(0x3ff); p->create(); p->create_invalid_registers(); p->create_sfr_map(); p->create_symbols(); return p; } P16C56::P16C56(const char *_name, const char *desc) : P16C54(_name,desc) { if(verbose) cout << "c56 constructor, type = " << isa() << '\n'; } gpsim-0.30.0/src/operator.cc0000664000076400007640000003627113045306452012610 00000000000000#include #include #include "operator.h" #include "errors.h" #include "symbol.h" #include "processor.h" #include static bool isFloat(Value *v) { if(v && (typeid(*v) == typeid(Float))) return true; return false; } static bool isInteger(Value *v) { if(v && (typeid(*v) == typeid(Integer))) return true; return false; } static bool isBoolean(Value *v) { if(v && (typeid(*v) == typeid(Boolean))) return true; return false; } BinaryOperator::BinaryOperator(const std::string & opString, Expression* _leftExpr, Expression* _rightExpr) : Operator(opString) { leftExpr = _leftExpr; rightExpr = _rightExpr; value = 0; } BinaryOperator::~BinaryOperator() { delete leftExpr; delete rightExpr; delete value; } Value* BinaryOperator::shortCircuit(Value* leftValue) { return 0; } string BinaryOperator::show() { return toString(); } string BinaryOperator::showType() { return showOp(); } string BinaryOperator::toString() { return string("(" + leftExpr->toString() + showOp() + rightExpr->toString() + ")"); } Value *BinaryOperator::evaluate() { Value *left = leftExpr->evaluate(); Value *right = rightExpr->evaluate(); Value *out = applyOp(left, right); if (left) delete left; if (right) delete right; return out; } Expression *BinaryOperator::getLeft() { return leftExpr; } Expression *BinaryOperator::getRight() { return rightExpr; } /***************************************************************** * The basic unary operator class. */ UnaryOperator::UnaryOperator(const std::string & theOpString, Expression* expr_) : Operator(theOpString) { expr = expr_; value = 0; } UnaryOperator::~UnaryOperator() { delete expr; } string UnaryOperator::showType() { return showOp(); } string UnaryOperator::show() { return toString(); } string UnaryOperator::toString() { return string(showOp() + "(" + expr->toString() + ")"); } Value* UnaryOperator::evaluate() { Value* tmp, *vReturn; // start evaluating our operand expression: tmp = expr->evaluate(); // Apply the specific operator to the evaluated operand: vReturn = applyOp(tmp); // If the result is constant, save the result for future use: //if (tmp->isConstant()) { // value = tmp; //} delete tmp; return vReturn; } /***************************************************************** * Comparison operators */ ComparisonOperator::ComparisonOperator(const std::string &opString, Expression* leftExpr, Expression* rightExpr) : BinaryOperator(opString,leftExpr,rightExpr), bLess(false), bEqual(false), bGreater(false) { } ComparisonOperator:: ~ComparisonOperator() { } Value* ComparisonOperator::applyOp(Value* leftValue, Value* rightValue) { return new Boolean(leftValue->compare(this,rightValue)); } int ComparisonOperator::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *pExpr) { return get_bp().set_break(bt, at, (Register *)0, this); } /****************************************************************************** Operator: AbstractRange *****************************************************************************/ OpAbstractRange::OpAbstractRange(Expression *lVal, Expression *rVal) : BinaryOperator(":", lVal, rVal) { } OpAbstractRange::~OpAbstractRange() { } Value* OpAbstractRange::applyOp(Value* lVal, Value* rVal) { Value* result=0; Integer* lInteger = Integer::typeCheck(lVal, showOp()); Integer* rInteger = Integer::typeCheck(rVal, showOp()); int left = (int)lInteger->getVal(); int right = (int)rInteger->getVal(); result = new AbstractRange(left, right); return(result); } //------------------------------------------------------------------------ OpAdd::OpAdd(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("+",leftExpr,rightExpr) { } OpAdd::~OpAdd() { } Value *OpAdd::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) { double d1,d2; lval->get(d1); rval->get(d2); return new Float(d1+d2); } // Try to add as integers. (An exception is thrown if the values // cannot be type casted. gint64 i1,i2; lval->get(i1); rval->get(i2); return new Integer(i1+i2); //throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); } //------------------------------------------------------------------------ OpAnd::OpAnd(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("&",leftExpr,rightExpr) { } OpAnd::~OpAnd() { } Value *OpAnd::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); gint64 i1,i2; lval->get(i1); rval->get(i2); return new Integer(i1 & i2); } //------------------------------------------------------------------------ OpEq::OpEq(Expression* leftExpr, Expression* rightExpr) : ComparisonOperator("==",leftExpr,rightExpr) { bEqual = true; } OpEq::~OpEq() { } //------------------------------------------------------------------------ OpGe::OpGe(Expression* leftExpr, Expression* rightExpr) : ComparisonOperator(">=",leftExpr,rightExpr) { bEqual = true; bGreater = true; } OpGe::~OpGe() { } //------------------------------------------------------------------------ OpGt::OpGt(Expression* leftExpr, Expression* rightExpr) : ComparisonOperator(">",leftExpr,rightExpr) { bGreater = true; } OpGt::~OpGt() { } //------------------------------------------------------------------------ OpLe::OpLe(Expression* leftExpr, Expression* rightExpr) : ComparisonOperator("<=",leftExpr,rightExpr) { bLess = true; bEqual = true; } OpLe::~OpLe() { } //------------------------------------------------------------------------ OpLt::OpLt(Expression* leftExpr, Expression* rightExpr) : ComparisonOperator("<",leftExpr,rightExpr) { bLess = true; } OpLt::~OpLt() { } //------------------------------------------------------------------------ OpLogicalAnd::OpLogicalAnd(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("&&",leftExpr,rightExpr) { } OpLogicalAnd::~OpLogicalAnd() { } Value *OpLogicalAnd::applyOp(Value* lval, Value* rval) { if(isBoolean(lval) && isBoolean(rval)) { bool b1 = (static_cast(lval))->getVal(); bool b2 = (static_cast(rval))->getVal(); return new Boolean(b1 & b2); } throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); } //------------------------------------------------------------------------ OpLogicalOr::OpLogicalOr(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("||",leftExpr,rightExpr) { } OpLogicalOr::~OpLogicalOr() { } Value *OpLogicalOr::applyOp(Value* lval, Value* rval) { if(isBoolean(lval) && isBoolean(rval)) { bool b1 = (static_cast(lval))->getVal(); bool b2 = (static_cast(rval))->getVal(); return new Boolean(b1 | b2); } throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); } //------------------------------------------------------------------------ OpNe::OpNe(Expression* leftExpr, Expression* rightExpr) : ComparisonOperator("!=",leftExpr,rightExpr) { bLess = true; bGreater = true; } OpNe::~OpNe() { } //------------------------------------------------------------------------ OpSub::OpSub(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("-",leftExpr,rightExpr) { } OpSub::~OpSub() { } Value *OpSub::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) { double d1,d2; lval->get(d1); rval->get(d2); return new Float(d1-d2); } gint64 i1,i2; lval->get(i1); rval->get(i2); return new Integer(i1-i2); // throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); } //------------------------------------------------------------------------ OpMpy::OpMpy(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("*",leftExpr,rightExpr) { } OpMpy::~OpMpy() { } Value *OpMpy::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) { double d1,d2; lval->get(d1); rval->get(d2); return new Float(d1*d2); } gint64 i1,i2; lval->get(i1); rval->get(i2); return new Integer(i1*i2); throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); } //------------------------------------------------------------------------ OpOr::OpOr(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("|",leftExpr,rightExpr) { } OpOr::~OpOr() { } Value *OpOr::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); gint64 i1,i2; lval->get(i1); rval->get(i2); return new Integer(i1 | i2); } //------------------------------------------------------------------------ OpXor::OpXor(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("^",leftExpr,rightExpr) { } OpXor::~OpXor() { } Value *OpXor::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); gint64 i1,i2; lval->get(i1); rval->get(i2); return new Integer(i1 ^ i2); } //------------------------------------------------------------------------ OpDiv::OpDiv(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("/",leftExpr,rightExpr) { } OpDiv::~OpDiv() { } Value *OpDiv::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) { double d1,d2; lval->get(d1); rval->get(d2); if(d2 == 0.0) throw new Error("Divide by zero"); return new Float(d1/d2); } gint64 i1,i2; lval->get(i1); rval->get(i2); if(i2 == 0) throw new Error("Divide by zero"); return new Integer(i1/i2); } //------------------------------------------------------------------------ OpShl::OpShl(Expression* leftExpr, Expression* rightExpr) : BinaryOperator("<<",leftExpr,rightExpr) { } OpShl::~OpShl() { } Value *OpShl::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); gint64 i1; gint64 i2; rval->get(i2); if(i2 < 0 || i2 > 63) throw new Error("Operator " + showOp() + " bad shift count"); lval->get(i1); return new Integer(i1<>",leftExpr,rightExpr) { } OpShr::~OpShr() { } Value *OpShr::applyOp(Value *lval, Value *rval) { if(isFloat(lval) || isFloat(rval)) throw new TypeMismatch(showOp(), lval->showType(), rval->showType()); gint64 i1; gint64 i2; rval->get(i2); if(i2 < 0 || i2 > 63) throw new Error("Operator " + showOp() + " bad shift count"); lval->get(i1); return new Integer(i1>>i2); } /****************************************************************************** The logical NOT operator '!'. ******************************************************************************/ OpLogicalNot::OpLogicalNot(Expression* expr) : UnaryOperator("!", expr) { } OpLogicalNot::~OpLogicalNot() { } Value* OpLogicalNot::applyOp(Value* operand) { Boolean* op; bool bVal; op = Boolean::typeCheck(operand, showOp()); bVal = op->getVal(); return new Boolean(!bVal); } /****************************************************************************** The unary 'negate' operator. ******************************************************************************/ OpNegate::OpNegate(Expression* expr) : UnaryOperator("-", expr) { } OpNegate::~OpNegate() { } Value* OpNegate::applyOp(Value* operand) { Value* rVal=0; if (isInteger(operand)) { Integer* iOp = (Integer*)(operand); rVal = new Integer(-(iOp->getVal())); } else if (isFloat(operand)) { Float* fOp = (Float*)(operand); rVal = new Float(-(fOp->getVal())); } else { throw new TypeMismatch(showOp(), operand->showType()); } return rVal; } /****************************************************************************** The unary ones complement operator '~'. ******************************************************************************/ OpOnescomp::OpOnescomp(Expression* expr) : UnaryOperator("~", expr) { } OpOnescomp::~OpOnescomp() { } Value* OpOnescomp::applyOp(Value* operand) { Integer* op; op = Integer::typeCheck(operand, showOp()); return new Integer(~ op->getVal() ); } /****************************************************************************** The unary 'plus' operator. ******************************************************************************/ OpPlus::OpPlus(Expression* expr) : UnaryOperator("+", expr) { } OpPlus::~OpPlus() { } Value* OpPlus::applyOp(Value* operand) { Value* rVal=0; if (isInteger(operand)) { Integer* iOp = (Integer*)(operand); rVal = new Integer(iOp->getVal()); } else if (isFloat(operand) ) { Float* fOp = (Float*)(operand); rVal = new Float(fOp->getVal()); } else { throw new TypeMismatch(showOp(), operand->showType()); } return rVal; } /****************************************************************************** The unary '*' operator - indirect access ******************************************************************************/ OpIndirect::OpIndirect(Expression* expr) : UnaryOperator("*", expr) { } OpIndirect::~OpIndirect() { } Value* OpIndirect::applyOp(Value* operand) { Value* rVal=0; Register *pReg = 0; if (isInteger(operand)) { Integer* iOp = (Integer*)(operand); // hmm ... what about ema? Need a different indirection operator? if (get_active_cpu()) pReg = get_active_cpu()->rma.get_register(*iOp); if(pReg) { rVal = new Integer(pReg->get()); } else { static char sFormat[] = "Value $%x is an invalid memory address"; char sMsg[sizeof(sFormat) + 10]; sprintf(sMsg, sFormat, (int)iOp->getVal()); throw new Error(string(sMsg)); } } else if (isFloat(operand) ) { Float* fOp = (Float*)(operand); rVal = new Float(fOp->getVal()); } else { throw new TypeMismatch(showOp(), operand->showType()); } return rVal; } /****************************************************************************** The unary '*' operator - indirect access ******************************************************************************/ OpAddressOf::OpAddressOf(Expression* expr) : UnaryOperator("&", expr) { } OpAddressOf::~OpAddressOf() { } Value* OpAddressOf::evaluate() { Value* tmp; // start evaluating our operand expression: LiteralSymbol *pSym = dynamic_cast(expr); if (pSym) { tmp = applyOp(pSym->GetSymbol()); } else { throw new TypeMismatch(showOp(), expr->showType()); } return tmp; } Value* OpAddressOf::applyOp(Value* operand) { Value* rVal=0; /* register_symbol *pReg =dynamic_cast(operand); if (pReg) { rVal = new Integer(pReg->getAddress()); } else { AliasedSymbol *pSym = dynamic_cast(operand); if (pSym) { pReg = dynamic_cast(pSym); if (pReg) { rVal = new Integer(pReg->getAddress()); } } } */ Register *pReg = dynamic_cast(operand); rVal = pReg ? new Integer(pReg->getAddress()) : 0; if(rVal==0) { throw new TypeMismatch(showOp(), operand->showType()); } return rVal; } gpsim-0.30.0/src/packages.cc0000664000076400007640000001474513041763624012541 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include "../config.h" #include "pic-processor.h" #include "stimuli.h" #include "packages.h" #include Package::Package(void) { pins = 0; number_of_pins = 0; m_pinGeometry = 0; } Package::Package(unsigned int _number_of_pins) { number_of_pins = 0; create_pkg(_number_of_pins); } Package::~Package() { if (pins) destroy_pin(0); // delete all of the pins delete [] pins; delete [] m_pinGeometry; } void Package::create_pkg(unsigned int _number_of_pins) { if(number_of_pins) { cout << "error: Package::create_pkg. Package appears to already exist.\n"; return; } number_of_pins = _number_of_pins; pins = new IOPIN *[number_of_pins]; m_pinGeometry = new PinGeometry[number_of_pins]; for(unsigned int i=0; i number_of_pins) || (pin_number == 0)) { cout << "error: Package::assign_pin. Pin number is out of range.\n"; cout << "Max pins " << number_of_pins << ". Trying to add " << pin_number <<".\n"; return E_PIN_OUT_OF_RANGE; } if(pins[pin_number-1]) return E_PIN_EXISTS; return E_NO_PIN; } //------------------------------------------------------------------- //------------------------------------------------------------------- IOPIN *Package::get_pin(unsigned int pin_number) { if(E_PIN_EXISTS == pin_existance(pin_number)) return pins[pin_number-1]; else return 0; } //------------------------------------------------------------------- //------------------------------------------------------------------- float Package::get_pin_position(unsigned int pin_number) { return (bIsValidPinNumber(pin_number) ? m_pinGeometry[pin_number-1].pin_position : 0.0); } void Package::set_pin_position(unsigned int pin_number, float position) { if (bIsValidPinNumber(pin_number)) { m_pinGeometry[pin_number-1].bNew = false; m_pinGeometry[pin_number-1].pin_position=position; } } void Package::setPinGeometry(unsigned int pin_number, float x, float y, int orientation, bool bShowName) { if (bIsValidPinNumber(pin_number)) { m_pinGeometry[pin_number-1].bNew = true; m_pinGeometry[pin_number-1].m_x = x; m_pinGeometry[pin_number-1].m_y = y; m_pinGeometry[pin_number-1].m_orientation = orientation; m_pinGeometry[pin_number-1].m_bShowPinname = bShowName; } } PinGeometry *Package::getPinGeometry(unsigned int pin_number) { static PinGeometry BAD_PIN; if (bIsValidPinNumber(pin_number)) { m_pinGeometry[pin_number-1].convertToNew(); return &m_pinGeometry[pin_number-1]; } return &BAD_PIN; } //------------------------------------------------------------------- //------------------------------------------------------------------- void Package::assign_pin(unsigned int pin_number, IOPIN *pin, bool warn) { switch(pin_existance(pin_number)) { case E_PIN_EXISTS: if(pins[pin_number-1] && warn) cout << "warning: Package::assign_pin. Pin number " << pin_number << " already exists.\n"; case E_NO_PIN: pins[pin_number-1] = pin; if ((bool)verbose && pin) cout << "assigned pin " << pin->name() << " to package pin number " << dec << pin_number<name(); else return invalid; //FIXME } //------------------------------------------------------------------- //------------------------------------------------------------------- int Package::get_pin_state(unsigned int pin_number) { if(pin_existance(pin_number) == E_PIN_EXISTS) return pins[pin_number-1]->getDrivingState(); else return 0; } //------------------------------------------------------------------------ void PinGeometry::convertToNew() { if (!bNew) { m_orientation = (int) floor (pin_position); if (m_orientation) { m_x = 0.0; m_y = pin_position; } else { m_x = pin_position - m_orientation; m_y = 0.0; } m_bShowPinname = true; } } //------------------------------------------------------------------------ void Package::showPins() { unsigned int pin_number; for (pin_number=0; pin_number < number_of_pins; pin_number++) { IOPIN *pPin = pins[pin_number]; cout << " pin #"<name() << endl; } } gpsim-0.30.0/src/trigger.cc0000664000076400007640000001450613045306452012415 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "trigger.h" #include "../config.h" #include "value.h" #include "expr.h" #include "errors.h" #include "breakpoints.h" #include "ui.h" #include "trace.h" #include #include extern Integer *verbosity; // in ../src/init.cc using namespace std; static TriggerAction DefaultTrigger; //------------------------------------------------------------------------ // class BreakTraceType : public TraceType { public: BreakTraceType() : TraceType(2, "Break") { } virtual TraceObject *decode(unsigned int tbi); virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); }; TraceType *TriggerObject::m_brt=0; //------------------------------------------------------------------------ class BreakTraceObject : public TraceObject { public: BreakTraceObject(unsigned int bpn); virtual void print(FILE *); private: unsigned int m_bpn; }; //------------------------------------------------------------------------ BreakTraceObject::BreakTraceObject(unsigned int bpn) : TraceObject(), m_bpn(bpn) { } void BreakTraceObject::print(FILE *fp) { fprintf(fp, " BREAK: #"); Breakpoints::BreakStatus *bs = bp.get(m_bpn); TriggerObject *bpo = bs ? bs->bpo : 0; if (bpo) bpo->print(); else fprintf(fp,"%u\n", m_bpn); } //------------------------------------------------------------------------ TraceObject *BreakTraceType::decode(unsigned int tbi) { TraceObject *to; if (get_trace().type(tbi) == type()) { to = new BreakTraceObject(get_trace().get(tbi) ); to->print(stdout); return to; } else return 0; } int BreakTraceType::dump_raw(Trace *pTrace,unsigned tbi, char *buf, int bufsize) { int n = TraceType::dump_raw(pTrace, tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int bpn = trace.get(tbi) & 0xffffff; Breakpoints::BreakStatus *bs = bp.get(bpn); TriggerObject *bpo = bs ? bs->bpo : 0; int m = snprintf(buf, bufsize, " BREAK: #%u %s", bpn, (bpo ? bpo->bpName() : "")); m = m>0 ? m : 0; buf += m; bufsize -= m; return (m+n+ ((bs && bs->bpo)?bs->bpo->printTraced(pTrace,tbi, buf, bufsize):0)); } //------------------------------------------------------------------------ // TriggerAction // TriggerAction::TriggerAction() { } TriggerAction::~TriggerAction() { } bool TriggerAction::evaluate() { action(); return true; } bool TriggerAction::getTriggerState() { return false; } void TriggerAction::action() { if(verbosity && verbosity->getVal()) cout << "Hit a Breakpoint!\n"; bp.halt(); } //------------------------------------------------------------------------ // SimpleTriggerAction // // For most cases... A single trigger action coupled with a single trigger // object SimpleTriggerAction::SimpleTriggerAction(TriggerObject *_to) : TriggerAction(), to(_to) { } void SimpleTriggerAction::action() { TriggerAction::action(); if(to && verbosity && verbosity->getVal()) to->print(); } //------------------------------------------------------------------------ TriggerObject::TriggerObject() { m_PExpr = 0; set_action(&DefaultTrigger); } TriggerObject::TriggerObject(TriggerAction *ta) { // If a trace type has not been allocated yet, then allocate: if (!m_brt) { m_brt = new BreakTraceType(); get_trace().allocateTraceType(m_brt); } m_PExpr = 0; if(ta) set_action(ta); else set_action(&DefaultTrigger); } TriggerObject::~TriggerObject() { /* cout << "Trigger Object destructor\n"; if (m_PExpr) cout << "deleting expression "<< m_PExpr->toString() << endl; */ delete m_PExpr; if (m_action != &DefaultTrigger) delete m_action; } void TriggerObject::callback() { cout << "generic callback\n"; } void TriggerObject::callback_print() { cout << " has callback, ID = 0x" << CallBackID << '\n'; } void TriggerObject::clear_trigger() { } int TriggerObject::find_free() { bpn = bp.find_free(); if(bpn < MAX_BREAKPOINTS) { bp.break_status[bpn].type = Breakpoints::BREAK_CLEAR; bp.break_status[bpn].cpu = 0; //get_cpu(); bp.break_status[bpn].arg1 = 0; bp.break_status[bpn].arg2 = 0; bp.break_status[bpn].bpo = this; } return bpn; } void TriggerObject::print() { char buf[256]; buf[0]=0; printExpression(buf, sizeof(buf)); if (buf[0]) { GetUserInterface().DisplayMessage(" Expr:%s\n", buf); } if (message().size()) GetUserInterface().DisplayMessage(" Message:%s\n", message().c_str()); } int TriggerObject::printExpression(char *pBuf, int szBuf) { if (!m_PExpr || !pBuf) return 0; *pBuf = 0; m_PExpr->toString(pBuf,szBuf); return strlen(pBuf); } int TriggerObject::printTraced(Trace *pTrace, unsigned int tbi, char *pBuf, int szBuf) { return 0; } void TriggerObject::clear() { cout << "clear Generic breakpoint " << bpn << endl; } void TriggerObject::set_Expression(Expression *newExpression) { delete m_PExpr; m_PExpr = newExpression; } bool TriggerObject::eval_Expression() { if(m_PExpr) { bool bRet = true; try { Value *v = m_PExpr->evaluate(); if(v) { v->get(bRet); delete v; } } catch (Error *Perr) { if(Perr) cout << "ERROR:" << Perr->toString() << endl; delete Perr; } return bRet; } return true; } //------------------------------------------------------------------------ void TriggerObject::invokeAction() { trace.raw(m_brt->type() | bpn); m_action->action(); } //------------------------------------------------------------------- void TriggerObject::new_message(const char *s) { m_sMessage = string(s); } void TriggerObject::new_message(string &new_message) { m_sMessage = new_message; } gpsim-0.30.0/src/16bit-processors.cc0000664000076400007640000007747513045306452014115 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include //#include "14bit-registers.h" //#include "14bit-instructions.h" #include "../config.h" #include "packages.h" #include "16bit-processors.h" #include #include "stimuli.h" #include "symbol.h" #include "eeprom.h" //------------------------------------------------------------------------ // Configuration bits // // The 16bit-core PIC devices contain configuration memory starting at // address 0x300000. // string Config1H::toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; const char *OSCdesc[8] = { "LP oscillator", "XT oscillator", "HS oscillator", "RC oscillator", "EC oscillator w/ OSC2 configured as divide-by-4 clock output", "EC oscillator w/ OSC2 configured as RA6", "HS oscillator with PLL enabled/Clock frequency = (4 x FOSC)", "RC oscillator w/ OSC2 configured as RA6" }; snprintf(buff,sizeof(buff), "$%04x\n" " FOSC=%d - Clk source = %s\n" " OSCEN=%d - Oscillator switching is %s\n", i, i & (FOSC0 | FOSC1 | FOSC2), OSCdesc[i & (FOSC0 | FOSC1 | FOSC2)], ((i & OSCEN) ? 1 : 0), ((i & OSCEN) ? "disabled" : "enabled")); return string(buff); } string Config1H_4bits::toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; const char *OSCdesc[] = { "LP oscillator", "XT oscillator", "HS oscillator", "RC oscillator", "EC oscillator w/ OSC2 configured as divide-by-4 clock output", "EC oscillator w/ OSC2 configured as RA6", "HS oscillator with PLL enabled/Clock frequency = (4 x FOSC)", "RC oscillator w/ OSC2 configured as RA6", "Internal oscillator block, port function on RA6 and RA7", "Internal oscillator block, CLKO function on RA6, port function on RA7", "External RC oscillator, CLKO function on RA6", "External RC oscillator, CLKO function on RA6", "External RC oscillator, CLKO function on RA6", "External RC oscillator, CLKO function on RA6", "External RC oscillator, CLKO function on RA6", "External RC oscillator, CLKO function on RA6" }; snprintf(buff,sizeof(buff), "$%04x\n" " FOSC=%d - Clk source = %s\n" " OSCEN=%d - Oscillator switching is %s\n", i, i & (FOSC0 | FOSC1 | FOSC2 | FOSC3), OSCdesc[i & (FOSC0 | FOSC1 | FOSC2 | FOSC3)], ((i & OSCEN) ? 1 : 0), ((i & OSCEN) ? "disabled" : "enabled")); return string(buff); } //------------------------------------------------------------------------ // Config2H - default // The default Config2H register controls the 18F series WDT. class Config2H : public ConfigWord { #define WDTEN (1<<0) #define WDTPS0 (1<<1) #define WDTPS1 (1<<2) #define WDTPS2 (1<<3) #define CONFIG2H_default (WDTEN | WDTPS0 | WDTPS1 | WDTPS2) public: Config2H(_16bit_processor *pCpu, unsigned int addr) : ConfigWord("CONFIG2H", CONFIG2H_default, "WatchDog configuration", pCpu, addr) { set(CONFIG2H_default); } virtual void set(gint64 v) { Integer::set(v); if (m_pCpu) { m_pCpu->wdt.set_postscale((v & (WDTPS0|WDTPS1|WDTPS2)) >> 1); m_pCpu->wdt.initialize((v & WDTEN) == WDTEN); } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; snprintf(buff,sizeof(buff), "$%04x\n" " WDTEN=%d - WDT is %s, prescale=1:%d\n", i, ((i & WDTEN) ? 1 : 0), ((i & WDTEN) ? "enabled" : "disabled"), 1 << (i & (WDTPS0 | WDTPS1 | WDTPS2)>>1)); return string(buff); } }; //------------------------------------------------------------------------ // Config4L - default // The default Config4L register controls the 18F series WDT. class Config4L : public ConfigWord { #define STKVREN (1<<0) #define LVP (1<<2) #define BBSIZ0 (1<<4) #define BBSIZ1 (1<<5) #define XINST (1<<6) #define _DEBUG (1<<7) #define CONFIG4L_default (STKVREN | LVP | _DEBUG) public: Config4L(_16bit_processor *pCpu, unsigned int addr) : ConfigWord("CONFIG4L", CONFIG4L_default, "Config word 4L", pCpu, addr) { set(CONFIG4L_default); } #define Cpu16 ((_16bit_processor *)m_pCpu) virtual void set(gint64 v) { Integer::set(v); if (m_pCpu) { Cpu16->set_extended_instruction((v & XINST) == XINST); if(m_pCpu->stack) m_pCpu->stack->STVREN = ((v & STKVREN) == STKVREN); } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; snprintf(buff,sizeof(buff), "$%04x\n" " STVREN=%d - BBSIZE=%x XINST=%d\n", i, ((i & STKVREN) ? 1 : 0), (i & (BBSIZ1 | BBSIZ0)) >> 4, ((i & XINST) ? 1 : 0)); return string(buff); } }; #define PWRTEN 1<<0 #define BOREN 1<<1 #define BORV0 1<<2 #define BORV1 1<<2 #define CCP2MX 1<<0 //------------------------------------------------------------------- _16bit_processor::_16bit_processor(const char *_name, const char *desc) : pic_processor(_name,desc), /* adcon0(this, "adcon0", "A2D control register"), adcon1(this, "adcon1", "A2D control register"), */ adresl(this, "adresl", "A2D result low"), adresh(this, "adresh", "A2D result high"), intcon(this, "intcon", "Interrupt control"), intcon2(this, "intcon2", "Interrupt control"), intcon3(this, "intcon3", "Interrupt control"), bsr(this, "bsr", "Bank Select Register"), tmr0l(this, "tmr0l", "TMR0 Low"), tmr0h(this, "tmr0h", "TMR0 High"), t0con(this, "t0con", "TMR0 Control"), rcon(this, "rcon", "Reset Control"), pir1(this,"pir1","Peripheral Interrupt Register",0,0), ipr1(this, "ipr1", "Interrupt Priorities"), ipr2(this, "ipr2", "Interrupt Priorities"), pie1(this, "pie1", "Peripheral Interrupt Enable"), pie2(this, "pie2", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), ccp2con(this, "ccp2con", "Capture Compare Control"), ccpr2l(this, "ccpr2l", "Capture Compare 2 Low"), ccpr2h(this, "ccpr2h", "Capture Compare 2 High"), tmr3l(this, "tmr3l", "TMR3 Low"), tmr3h(this, "tmr3h", "TMR3 High"), osccon(0), lvdcon(this, "lvdcon", "LVD Control"), wdtcon(this, "wdtcon", "WDT Control", 1), prodh(this, "prodh", "Product High"), prodl(this, "prodl", "Product Low"), pclatu(this, "pclatu", "Program Counter Latch upper byte"), ind0(this,string("0")), ind1(this,string("1")), ind2(this,string("2")), usart(this), tbl(this), ssp(this) { set_osc_pin_Number(0, 253, NULL); set_osc_pin_Number(1, 253, NULL); package = 0; pll_factor = 0; pc = new Program_Counter16(this); pc->set_trace_command(); //trace.allocateTraceType(new PCTraceType(this,1))); m_porta = new PicPortRegister(this,"porta","",8,0xff); m_porta->setEnableMask(0x7f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); m_trisa->setEnableMask(0x7f); m_lata = new PicLatchRegister(this,"lata","", m_porta); m_lata->setEnableMask(0x7f); m_portb = new PicPortBRegister(this,"portb","", &intcon, 8,0xff, &intcon2, &intcon3); m_portb->assignRBPUSink(7,&intcon2); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false); m_latb = new PicLatchRegister(this,"latb","", m_portb); m_portc = new PicPortRegister(this,"portc","",8,0xff); m_trisc = new PicTrisRegister(this,"trisc","", m_portc, false); m_latc = new PicLatchRegister(this,"latc","", m_portc); pir2 = new PIR2v2(this,"pir2","Peripheral Interrupt Register",0,0); t1con = new T1CON(this, "t1con", "TMR1 Control"); t3con = new T3CON(this, "t3con", "TMR3 Control"); //tmr0l.set_cpu(this, m_porta, 4, option_reg); //tmr0l.start(0); m_porta->addSink(&tmr0l,4); stack = new Stack16(this); internal_osc = false; } //------------------------------------------------------------------- _16bit_processor::~_16bit_processor() { delete_sfr_map(); } //------------------------------------------------------------------- pic_processor *_16bit_processor::construct() { cout << "creating 16bit processor construct\n"; _16bit_processor *p = new _16bit_processor; if(verbose) cout << " 18c242 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); p->name_str = "generic 16bit processor"; globalSymbolTable().addModule(p); return p; } void _16bit_processor :: delete_sfr_map() { if(verbose) cout << "deleting 18cxxx common registers " << hex << last_actual_register() <<"\n"; unassignMCLRPin(); delete_file_registers(0x0, last_register); remove_sfr_register(&pie1); remove_sfr_register(&pir1); remove_sfr_register(&ipr1); remove_sfr_register(&pie2); delete_sfr_register(pir2); remove_sfr_register(&ipr2); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); delete_sfr_register(t3con); remove_sfr_register(&tmr3l); remove_sfr_register(&tmr3h); if ( HasCCP2() ) { remove_sfr_register(&ccp2con); remove_sfr_register(&ccpr2l); remove_sfr_register(&ccpr2h); } remove_sfr_register(&ccp1con); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspbuf); if (!MovedReg()) { remove_sfr_register(&t2con); remove_sfr_register(&pr2); remove_sfr_register(&tmr2); } delete_sfr_register(t1con); delete_sfr_register(osccon); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&rcon); remove_sfr_register(&wdtcon); remove_sfr_register(&lvdcon); remove_sfr_register(&t0con); remove_sfr_register(&tmr0l); remove_sfr_register(&tmr0h); remove_sfr_register(&ind2.fsrl); remove_sfr_register(&ind2.fsrh); remove_sfr_register(&ind2.plusw); remove_sfr_register(&ind2.preinc); remove_sfr_register(&ind2.postdec); remove_sfr_register(&ind2.postinc); remove_sfr_register(&ind2.postinc); remove_sfr_register(&ind2.indf); remove_sfr_register(&bsr); remove_sfr_register(&ind1.fsrl); remove_sfr_register(&ind1.fsrh); remove_sfr_register(&ind1.plusw); remove_sfr_register(&ind1.preinc); remove_sfr_register(&ind1.postdec); remove_sfr_register(&ind1.postinc); remove_sfr_register(&ind1.indf); remove_sfr_register(&ind0.fsrl); remove_sfr_register(&ind0.fsrh); remove_sfr_register(&ind0.plusw); remove_sfr_register(&ind0.preinc); remove_sfr_register(&ind0.postdec); remove_sfr_register(&ind0.postinc); remove_sfr_register(&ind0.indf); remove_sfr_register(&intcon3); remove_sfr_register(&intcon2); remove_sfr_register(&intcon); remove_sfr_register(&prodl); remove_sfr_register(&prodh); remove_sfr_register(&tbl.tablat); remove_sfr_register(&tbl.tblptrl); remove_sfr_register(&tbl.tblptrh); remove_sfr_register(&tbl.tblptru); remove_sfr_register(&pclatu); Stack16 *stack16 = static_cast(stack); remove_sfr_register(&stack16->stkptr); remove_sfr_register(&stack16->tosl); remove_sfr_register(&stack16->tosh); remove_sfr_register(&stack16->tosu); EEPROM *e = get_eeprom(); if (e) { remove_sfr_register(e->get_reg_eedata()); remove_sfr_register(e->get_reg_eeadr()); if ( e->get_reg_eeadrh() ) remove_sfr_register(e->get_reg_eeadrh()); remove_sfr_register(e->get_reg_eecon1()); remove_sfr_register(e->get_reg_eecon2()); } delete_sfr_register(m_porta); delete_sfr_register(m_lata); delete_sfr_register(m_trisa); delete_sfr_register(m_portb); delete_sfr_register(m_latb); delete_sfr_register(m_trisb); if ( HasPortC() ) { delete_sfr_register(m_portc); delete_sfr_register(m_latc); delete_sfr_register(m_trisc); } delete pc; } //------------------------------------------------------------------- void _16bit_processor :: create_sfr_map() { if(verbose) cout << "creating 18cxxx common registers\n"; last_register = last_actual_register(); add_file_registers(0x0, last_register, 0); RegisterValue porv(0,0); RegisterValue porv2(0,0); add_sfr_register(m_porta, 0xf80,porv); add_sfr_register(m_portb, 0xf81,porv); if ( HasPortC() ) add_sfr_register(m_portc, 0xf82,porv); add_sfr_register(m_lata, 0xf89,porv); add_sfr_register(m_latb, 0xf8a,porv); if ( HasPortC() ) add_sfr_register(m_latc, 0xf8b,porv); add_sfr_register(m_trisa, 0xf92,RegisterValue(0x7f,0)); add_sfr_register(m_trisb, 0xf93,RegisterValue(0xff,0)); if ( HasPortC() ) add_sfr_register(m_trisc, 0xf94,RegisterValue(0xff,0)); add_sfr_register(&pie1, 0xf9d,porv,"pie1"); add_sfr_register(&pir1, 0xf9e,porv,"pir1"); add_sfr_register(&ipr1, 0xf9f,porv,"ipr1"); add_sfr_register(&pie2, 0xfa0,porv,"pie2"); add_sfr_register(&ipr2, 0xfa2,porv,"ipr2"); if ( HasPortC() ) usart.initialize(&pir1,&(*m_portc)[6], &(*m_portc)[7], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); else usart.initialize(&pir1,0, 0, new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0xfab,porv,"rcsta"); add_sfr_register(&usart.txsta, 0xfac,RegisterValue(0x02,0),"txsta"); add_sfr_register(usart.txreg, 0xfad,porv,"txreg"); add_sfr_register(usart.rcreg, 0xfae,porv,"rcreg"); add_sfr_register(&usart.spbrg, 0xfaf,porv,"spbrg"); add_sfr_register(t3con, 0xfb1,porv); add_sfr_register(&tmr3l, 0xfb2,porv,"tmr3l"); add_sfr_register(&tmr3h, 0xfb3,porv,"tmr3h"); if ( HasCCP2() ) { add_sfr_register(&ccp2con, 0xfba,porv,"ccp2con"); add_sfr_register(&ccpr2l, 0xfbb,porv,"ccpr2l"); add_sfr_register(&ccpr2h, 0xfbc,porv,"ccpr2h"); } add_sfr_register(&ccp1con, 0xfbd,porv,"ccp1con"); add_sfr_register(&ccpr1l, 0xfbe,porv,"ccpr1l"); add_sfr_register(&ccpr1h, 0xfbf,porv,"ccpr1h"); add_sfr_register(&adresl, 0xfc3,porv,"adresl"); add_sfr_register(&adresh, 0xfc4,porv,"adresh"); add_sfr_register(&ssp.sspcon2, 0xfc5,porv,"sspcon2"); add_sfr_register(&ssp.sspcon, 0xfc6,porv,"sspcon1"); add_sfr_register(&ssp.sspstat, 0xfc7,porv,"sspstat"); add_sfr_register(&ssp.sspadd, 0xfc8,porv,"sspadd"); add_sfr_register(&ssp.sspbuf, 0xfc9,porv,"sspbuf"); if (!MovedReg()) { add_sfr_register(&t2con, 0xfca,porv,"t2con"); add_sfr_register(&pr2, 0xfcb,RegisterValue(0xff,0),"pr2"); add_sfr_register(&tmr2, 0xfcc,porv,"tmr2"); } add_sfr_register(t1con, 0xfcd,porv,"t1con"); add_sfr_register(&tmr1l, 0xfce,porv,"tmr1l"); add_sfr_register(&tmr1h, 0xfcf,porv,"tmr1h"); add_sfr_register(&rcon, 0xfd0,RegisterValue(0x1c,0),"rcon"); add_sfr_register(&wdtcon, 0xfd1,porv,"wdtcon"); add_sfr_register(&lvdcon, 0xfd2,porv,"lvdcon"); add_sfr_register( osccon, 0xfd3,RegisterValue(0x40,0),"osccon"); add_sfr_register(&t0con, 0xfd5,RegisterValue(0xff,0),"t0con"); add_sfr_register(&tmr0l, 0xfd6,porv,"tmr0l"); add_sfr_register(&tmr0h, 0xfd7,porv,"tmr0h"); t0con.put(0xff); /**FIXME - need a way to set this to 0xff at reset*/ add_sfr_register(status, 0xfd8); status->set_rcon(&rcon); add_sfr_register(&ind2.fsrl, 0xfd9,porv,"fsr2l"); add_sfr_register(&ind2.fsrh, 0xfda,porv,"fsr2h"); add_sfr_register(&ind2.plusw, 0xfdb,porv,"plusw2"); add_sfr_register(&ind2.preinc, 0xfdc,porv,"preinc2"); add_sfr_register(&ind2.postdec, 0xfdd,porv,"postdec2"); add_sfr_register(&ind2.postinc, 0xfde,porv,"postinc2"); add_sfr_register(&ind2.indf, 0xfdf,porv,"indf2"); add_sfr_register(&bsr, 0xfe0,porv, "bsr"); add_sfr_register(&ind1.fsrl, 0xfe1,porv,"fsr1l"); add_sfr_register(&ind1.fsrh, 0xfe2,porv,"fsr1h"); add_sfr_register(&ind1.plusw, 0xfe3,porv,"plusw1"); add_sfr_register(&ind1.preinc, 0xfe4,porv,"preinc1"); add_sfr_register(&ind1.postdec, 0xfe5,porv,"postdec1"); add_sfr_register(&ind1.postinc, 0xfe6,porv,"postinc1"); add_sfr_register(&ind1.indf, 0xfe7,porv,"indf1"); add_sfr_register(Wreg, 0xfe8); add_sfr_register(&ind0.fsrl, 0xfe9,porv,"fsr0l"); add_sfr_register(&ind0.fsrh, 0xfea,porv,"fsr0h"); add_sfr_register(&ind0.plusw, 0xfeb,porv,"plusw0"); add_sfr_register(&ind0.preinc, 0xfec,porv,"preinc0"); add_sfr_register(&ind0.postdec, 0xfed,porv,"postdec0"); add_sfr_register(&ind0.postinc, 0xfee,porv,"postinc0"); add_sfr_register(&ind0.indf, 0xfef,porv,"indf0"); add_sfr_register(&intcon3, 0xff0, porv,"intcon3"); porv2.data = 0xF5; add_sfr_register(&intcon2, 0xff1, porv2,"intcon2"); add_sfr_register(&intcon, 0xff2, porv,"intcon"); add_sfr_register(&prodl, 0xff3, porv,"prodl"); add_sfr_register(&prodh, 0xff4, porv,"prodh"); add_sfr_register(&tbl.tablat, 0xff5, porv,"tablat"); add_sfr_register(&tbl.tblptrl, 0xff6, porv,"tblptrl"); add_sfr_register(&tbl.tblptrh, 0xff7, porv,"tblptrh"); add_sfr_register(&tbl.tblptru, 0xff8, porv,"tblptru"); if(pcl) delete pcl; pcl = new PCL16(this,"pcl", "Program Counter Low byte"); add_sfr_register(pcl, 0xff9); add_sfr_register(pclath, 0xffa); add_sfr_register(&pclatu, 0xffb, porv, "pclatu"); pclath->mValidBits = 0xFF; // Data sheet implies does not depend on memory size Stack16 *stack16 = static_cast(stack); add_sfr_register(&stack16->stkptr, 0xffc,porv,"stkptr"); add_sfr_register(&stack16->tosl, 0xffd,porv,"tosl"); add_sfr_register(&stack16->tosh, 0xffe,porv,"tosh"); add_sfr_register(&stack16->tosu, 0xfff,porv,"tosu"); stack16->stack_mask = 31; EEPROM *e = get_eeprom(); if (e) { add_sfr_register(e->get_reg_eedata(), 0xfa8); add_sfr_register(e->get_reg_eeadr(), 0xfa9); if ( e->get_reg_eeadrh() ) add_sfr_register(e->get_reg_eeadrh(), 0xfaa); add_sfr_register(e->get_reg_eecon1(), 0xfa6, RegisterValue(0,0)); add_sfr_register(e->get_reg_eecon2(), 0xfa7); } // Initialize all of the register cross linkages pir_set_def.set_pir1(&pir1); tmr2.ssp_module[0] = &ssp; tmr1l.tmrh = &tmr1h; tmr1l.t1con = t1con; tmr1l.setInterruptSource(new InterruptSource(&pir1, PIR1v1::TMR1IF)); // tmr1l.ccpcon = &ccp1con; tmr1h.tmrl = &tmr1l; t1con->tmrl = &tmr1l; t2con.tmr2 = &tmr2; tmr2.pir_set = &pir_set_def; //get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp ( &ccp1con ); tmr2.add_ccp ( &ccp2con ); pr2.tmr2 = &tmr2; tmr3l.tmrh = &tmr3h; tmr3l.t1con = t3con; // tmr3l.ccpcon = &ccp1con; tmr3h.tmrl = &tmr3l; t3con->tmrl = &tmr3l; if (T3HasCCP()) { t3con->tmr1l = &tmr1l; t3con->ccpr1l = &ccpr1l; t3con->ccpr2l = &ccpr2l; t3con->t1con = t1con; } ccp1con.setCrosslinks(&ccpr1l, &pir1, PIR1v2::CCP1IF, &tmr2); ccp1con.setIOpin(&((*m_portc)[2])); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; pir1.set_intcon(&intcon); pir1.set_pie(&pie1); pir1.set_ipr(&ipr1); pie1.setPir(&pir1); // All of the status bits on the 16bit core are writable status->write_mask = 0xff; // AN5,AN6 and AN7 exist only on devices with a PORTE. } void _16bit_processor::init_pir2(PIR *pir2, unsigned int bitMask) { RegisterValue porv(0,0); tmr3l.setInterruptSource(new InterruptSource(pir2, bitMask)); pir_set_def.set_pir2(pir2); pir2->set_intcon(&intcon); pir2->set_pie(&pie2); pir2->set_ipr(&ipr2); pie2.setPir(pir2); add_sfr_register(pir2, 0xfa1,porv,"pir2"); } //------------------------------------------------------------------- //------------------------------------------------------------------- // // // create // // The purpose of this member function is to 'create' those things // that are unique to the 16-bit core processors. void _16bit_processor :: create () { if(verbose) cout << " _16bit_processor :: create\n" ; fast_stack.init(this); /* ind0.init(this); ind1.init(this); ind2.init(this); */ pic_processor::create(); osccon = getOSCCON(); create_sfr_map(); tmr0l.initialize(); intcon.set_rcon(&rcon); intcon.set_intcon2(&intcon2); intcon.set_pir_set(&pir_set_def); //tbl.initialize(this); tmr0l.start(0); if(pma) { pma->SpecialRegisters.push_back(&bsr); rma.SpecialRegisters.push_back(&bsr); } } // // create_symbols // // Create symbols for a generic 16-bit core. This allows symbolic // access to the pic. (e.g. It makes it possible to access the // status register by name instead of by its address.) // void _16bit_processor::create_symbols () { pic_processor::create_symbols(); } //------------------------------------------------------------------- // void _16bit_processor::interrupt () // // When the virtual function cpu->interrupt() is called during // pic_processor::run() AND the cpu gpsim is simulating is an 18cxxx // device then we end up here. For an interrupt to have occured, // the interrupt processing logic must have just ran. One of the // responsibilities of that logic is to determine at what address // the interrupt should begin executing. That address is placed // in 'interrupt_vector'. // //------------------------------------------------------------------- void _16bit_processor::interrupt () { bp.clear_interrupt(); stack->push(pc->value); // Save W,status, and BSR if this is a high priority interrupt. fast_stack.push(); intcon.in_interrupt = true; // Mask interrupts pc->interrupt(intcon.get_interrupt_vector()); } //------------------------------------------------------------------- void _16bit_processor::option_new_bits_6_7(unsigned int bits) { //portb.rbpu_intedg_update(bits); //cout << "16bit, option bits 6 and/or 7 changed\n"; } //------------------------------------------------------------------- void _16bit_processor::enter_sleep() { if (verbose) cout << "_16bit_processor::enter_sleep() \n"; tmr0l.sleep(); pic_processor::enter_sleep(); } //------------------------------------------------------------------- void _16bit_processor::exit_sleep() { if (verbose) cout << "_16bit_processor::exit_sleep() \n"; if (m_ActivityState == ePASleeping) { tmr0l.wake(); pic_processor::exit_sleep(); } } //------------------------------------------------------------------ // It is assummed that this will only be set to true for processors // that support extended instructions // void _16bit_processor::set_extended_instruction(bool v) { if (verbose) cout << "_16bit_processor::set_extended_instruction " << v <<"\n"; extended_instruction_flag = v; } //------------------------------------------------------------------- // Fetch the rom contents at a particular address. unsigned int _16bit_processor::get_program_memory_at_address(unsigned int address) { unsigned int uIndex = map_pm_address2index(address); if (uIndex < program_memory_size()) return program_memory[uIndex] ? program_memory[uIndex]->get_opcode() : 0xffffffff; if (address >= CONFIG1L && address <= 0x30000D) return get_config_word(address); uIndex = (address - 0x200000) >> 1; // Look to see if it's an ID location if( uIndex < IdentMemorySize() ) return idloc[uIndex]; // static const unsigned int DEVID1 = 0x3ffffe; // static const unsigned int DEVID2 = 0x3fffff; #define DEVID1 0x3ffffe if ((address & DEVID1) == DEVID1) { return get_device_id(); } return 0xffffffff; } unsigned int _16bit_processor::get_config_word(unsigned int address) { if (!(address >= CONFIG1L && address <= 0x30000D)) return 0xffffffff; address -= CONFIG1L; if (m_configMemory) { address &= 0xfffe; // Clear LSB unsigned int ret = 0xffff; if (m_configMemory->getConfigWord(address)) ret = (ret & 0xff00) | (((unsigned int )(m_configMemory->getConfigWord(address)->getVal())) & 0x00ff); address++; if (m_configMemory->getConfigWord(address)) ret = (ret & 0x00ff) | ((((unsigned int )(m_configMemory->getConfigWord(address)->getVal()))<<8) & 0xff00); return ret; } return 0xffffffff; } bool _16bit_processor::set_config_word(unsigned int address, unsigned int cfg_word) { if (address >= CONFIG1L && address <= 0x30000D) { if (verbose) cout << "Setting config word 0x"<getConfigWord(address)) m_configMemory->getConfigWord(address)->set((int)(cfg_word&0xff)); address++; if (m_configMemory->getConfigWord(address)) m_configMemory->getConfigWord(address)->set((int)((cfg_word>>8)&0xff)); return true; } else cout << "Setting config word no m_configMemory\n"; } return false; } //------------------------------------------------------------------- void _16bit_processor::create_config_memory() { m_configMemory = new ConfigMemory(this,configMemorySize()); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H(this, CONFIG1H)); m_configMemory->addConfigWord(CONFIG2H-CONFIG1L,new Config2H(this, CONFIG2H)); m_configMemory->addConfigWord(CONFIG4L-CONFIG1L,new Config4L(this, CONFIG4L)); } void _16bit_processor::set_out_of_range_pm(unsigned int address, unsigned int value) { // This method is only called by Processor::init_program_memory which writes words if ( get_eeprom() && (address>= 0xf00000) && (address < 0xf00000 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(1 + address - 0xf00000, value >> 8); get_eeprom()->change_rom(address - 0xf00000, value & 0xff); } else if( (address>= 0x200000) && (address < 0x200008) ) { idloc[(address - 0x200000) >> 1] = value; } } void _16bit_processor::osc_mode(unsigned int value) { IOPIN *m_pin; unsigned int pin_Number = get_osc_pin_Number(0); if (pin_Number < 253) { m_pin = package->get_pin(pin_Number); } if ( (pin_Number = get_osc_pin_Number(1)) < 253 && (m_pin = package->get_pin(pin_Number))) { pll_factor = 0; if (value < 5) { set_clk_pin(pin_Number, m_osc_Monitor[1], "OSC2", true, m_porta, m_trisa, m_lata); } else if(value == 6 ) { pll_factor = 2; set_clk_pin(pin_Number, m_osc_Monitor[1], "CLKO", false, m_porta, m_trisa, m_lata); } else { clr_clk_pin(pin_Number, m_osc_Monitor[1], m_porta, m_trisa, m_lata); } } } //------------------------------------------------------------------- // // Package stuff // void _16bit_processor::create_iopin_map() { cout << "_16bit_processor::create_iopin_map WARNING --- not creating package \n"; } void _16bit_compat_adc::create() { adcon0 = new ADCON0(this, "adcon0", "A2D control register"), adcon1 = new ADCON1(this, "adcon1", "A2D control register"), _16bit_processor::create(); a2d_compat(); } void _16bit_compat_adc::create_sfr_map() { _16bit_processor::create_sfr_map(); } void _16bit_compat_adc::create_symbols() { _16bit_processor::create_symbols(); } void _16bit_compat_adc :: a2d_compat() { if(verbose) cout << "creating old (compatible) A2D\n"; RegisterValue porv(0,0); add_sfr_register(adcon1, 0xfc1,porv,"adcon1"); add_sfr_register(adcon0, 0xfc2,porv,"adcon0"); adcon0->setAdresLow(&adresl); adcon0->setAdres(&adresh); adcon0->setAdcon1(adcon1); adcon0->setIntcon(&intcon); adcon0->setPir(&pir1); adcon0->setChannel_Mask(7); // Greater than 4 channels adcon0->setA2DBits(10); adcon1->setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3,0); adcon1->setChannelConfiguration(0, 0xff); adcon1->setChannelConfiguration(1, 0xff); adcon1->setChannelConfiguration(2, 0x1f); adcon1->setChannelConfiguration(3, 0x1f); adcon1->setChannelConfiguration(4, 0x0b); adcon1->setChannelConfiguration(5, 0x0b); adcon1->setChannelConfiguration(6, 0x00); adcon1->setChannelConfiguration(7, 0x00); adcon1->setChannelConfiguration(8, 0xff); adcon1->setChannelConfiguration(9, 0x3f); adcon1->setChannelConfiguration(10, 0x3f); adcon1->setChannelConfiguration(11, 0x3f); adcon1->setChannelConfiguration(12, 0x1f); adcon1->setChannelConfiguration(13, 0x0f); adcon1->setChannelConfiguration(14, 0x01); adcon1->setChannelConfiguration(15, 0x0d); adcon1->setVrefHiConfiguration(1, 3); adcon1->setVrefHiConfiguration(3, 3); adcon1->setVrefHiConfiguration(5, 3); adcon1->setVrefHiConfiguration(8, 3); adcon1->setVrefHiConfiguration(10, 3); adcon1->setVrefHiConfiguration(11, 3); adcon1->setVrefHiConfiguration(12, 3); adcon1->setVrefHiConfiguration(13, 3); adcon1->setVrefHiConfiguration(15, 3); adcon1->setVrefLoConfiguration(8, 2); adcon1->setVrefLoConfiguration(11, 2); adcon1->setVrefLoConfiguration(12, 2); adcon1->setVrefLoConfiguration(13, 2); adcon1->setVrefLoConfiguration(15, 2); adcon1->setNumberOfChannels(5); adcon1->setIOPin(0, &(*m_porta)[0]); adcon1->setIOPin(1, &(*m_porta)[1]); adcon1->setIOPin(2, &(*m_porta)[2]); adcon1->setIOPin(3, &(*m_porta)[3]); adcon1->setIOPin(4, &(*m_porta)[5]); } _16bit_compat_adc::_16bit_compat_adc(const char *_name, const char *desc) : _16bit_processor(_name, desc), adcon0(0), adcon1(0) { } _16bit_compat_adc::~_16bit_compat_adc() { if(adcon0) delete_sfr_register(adcon0); if(adcon1) delete_sfr_register(adcon1); } void _16bit_v2_adc::create(int nChannels) { adcon0 = new ADCON0_V2(this, "adcon0", "A2D control register"); adcon1 = new ADCON1_V2(this, "adcon1", "A2D control register"); adcon2 = new ADCON2_V2(this, "adcon2", "A2D control register"); RegisterValue porv(0,0); add_sfr_register(adcon2, 0xfc0,porv,"adcon2"); add_sfr_register(adcon1, 0xfc1,porv,"adcon1"); add_sfr_register(adcon0, 0xfc2,porv,"adcon0"); adcon0->setAdresLow(&adresl); adcon0->setAdres(&adresh); adcon0->setAdcon1(adcon1); adcon0->setAdcon2(adcon2); adcon0->setIntcon(&intcon); adcon0->setPir(&pir1); adcon0->setChannel_Mask(0xf); // upto 16 channels adcon0->setA2DBits(10); adcon1->setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3,0); adcon1->setNumberOfChannels(nChannels); adcon1->setChanTable(0x1fff, 0x1fff, 0x1fff, 0x0fff, 0x07ff, 0x03ff, 0x01ff, 0x00ff, 0x007f, 0x003f, 0x001f, 0x000f, 0x0007, 0x0003, 0x0001, 0x0000); adcon1->setVrefHiChannel(3); adcon1->setVrefLoChannel(2); adcon1->setIOPin(0, &(*m_porta)[0]); adcon1->setIOPin(1, &(*m_porta)[1]); adcon1->setIOPin(2, &(*m_porta)[2]); adcon1->setIOPin(3, &(*m_porta)[3]); } _16bit_v2_adc::_16bit_v2_adc(const char *_name, const char *desc) : _16bit_processor(_name, desc), adcon0(0), adcon1(0), adcon2(0) { } _16bit_v2_adc::~_16bit_v2_adc() { if(adcon0) delete_sfr_register(adcon0); if(adcon1) delete_sfr_register(adcon1); if(adcon2) delete_sfr_register(adcon2); } gpsim-0.30.0/src/16bit-hexdecode.cc0000664000076400007640000001677313041763613013637 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // T. Scott Dattalo 16bit core routines #include #include #include #include #include "../config.h" #include "16bit-processors.h" #include "pic-instructions.h" #include "12bit-instructions.h" #include "16bit-instructions.h" #include "gpsim_def.h" #include "pic-processor.h" #include "picdis.h" #include "stimuli.h" /* PIC 16-bit instruction set */ struct instruction_constructor op_18cxx[] = { // Extended Instructions { 0xfe00, 0xe800, ADDFSR16::construct }, // ADDFSR & SUBFSR, ADDULNK, SUBULNK { 0xffff, 0x0014, CALLW16::construct }, { 0xff00, 0xeb00, MOVSF::construct }, // MOVSF & MOVSS { 0xff00, 0xea00, PUSHL::construct }, // Normal instructions { 0xff00, 0x0f00, ADDLW16::construct }, { 0xfc00, 0x2400, ADDWF16::construct }, { 0xfc00, 0x2000, ADDWFC16::construct }, { 0xff00, 0x0b00, ANDLW16::construct }, { 0xfc00, 0x1400, ANDWF16::construct }, { 0xff00, 0xe200, BC::construct }, { 0xf000, 0x9000, BCF16::construct }, { 0xff00, 0xe600, BN::construct }, { 0xff00, 0xe300, BNC::construct }, { 0xff00, 0xe700, BNN::construct }, { 0xff00, 0xe500, BNOV::construct }, { 0xff00, 0xe100, BNZ::construct }, { 0xff00, 0xe400, BOV::construct }, { 0xf800, 0xd000, BRA16::construct }, { 0xf000, 0x8000, BSF16::construct }, { 0xf000, 0xb000, BTFSC16::construct }, { 0xf000, 0xa000, BTFSS16::construct }, { 0xf000, 0x7000, BTG::construct }, { 0xff00, 0xe000, BZ::construct }, { 0xfe00, 0xec00, CALL16::construct }, { 0xfe00, 0x6a00, CLRF16::construct }, { 0xffff, 0x0004, CLRWDT::construct }, { 0xfc00, 0x1c00, COMF16::construct }, { 0xfe00, 0x6200, CPFSEQ::construct }, { 0xfe00, 0x6400, CPFSGT::construct }, { 0xfe00, 0x6000, CPFSLT::construct }, { 0xffff, 0x0007, DAW::construct }, { 0xfc00, 0x0400, DECF16::construct }, { 0xfc00, 0x2c00, DECFSZ16::construct }, { 0xfc00, 0x4c00, DCFSNZ::construct }, { 0xff00, 0xef00, GOTO16::construct }, { 0xfc00, 0x2800, INCF16::construct }, { 0xfc00, 0x3c00, INCFSZ16::construct }, { 0xfc00, 0x4800, INFSNZ::construct }, { 0xff00, 0x0900, IORLW16::construct }, { 0xfc00, 0x1000, IORWF16::construct }, { 0xffc0, 0xee00, LFSR::construct }, { 0xfc00, 0x5000, MOVF16::construct }, { 0xf000, 0xc000, MOVFF::construct }, { 0xff00, 0x0100, MOVLB16::construct }, { 0xff00, 0x0e00, MOVLW::construct }, { 0xfe00, 0x6e00, MOVWF16::construct }, //RRR { 0xff00, 0x6f00, MOVWF16::construct }, //RRR { 0xff00, 0x6e00, MOVWF16a::construct }, { 0xff00, 0x0d00, MULLW::construct }, { 0xfe00, 0x0200, MULWF::construct }, { 0xfe00, 0x6c00, NEGF::construct }, { 0xffff, 0x0000, NOP::construct }, { 0xf000, 0xf000, NOP::construct }, { 0xffff, 0x0006, POP::construct }, { 0xffff, 0x0005, PUSH::construct }, { 0xf800, 0xd800, RCALL::construct }, { 0xffff, 0x00ff, RESET::construct }, { 0xfffe, 0x0010, RETFIE16::construct }, { 0xff00, 0x0c00, RETLW::construct }, { 0xfffe, 0x0012, RETURN16::construct }, { 0xfc00, 0x3400, RLCF::construct }, { 0xfc00, 0x4400, RLNCF::construct }, { 0xfc00, 0x3000, RRCF::construct }, { 0xfc00, 0x4000, RRNCF::construct }, { 0xfe00, 0x6800, SETF::construct }, { 0xffff, 0x0003, SLEEP16::construct }, { 0xfc00, 0x5400, SUBFWB::construct }, { 0xff00, 0x0800, SUBLW16::construct }, { 0xfc00, 0x5c00, SUBWF16::construct }, { 0xfc00, 0x5800, SUBWFB16::construct }, { 0xfc00, 0x3800, SWAPF16::construct }, { 0xfffc, 0x0008, TBLRD::construct }, { 0xfffc, 0x000c, TBLWT::construct }, { 0xfe00, 0x6600, TSTFSZ::construct }, { 0xff00, 0x0a00, XORLW16::construct }, { 0xfc00, 0x1800, XORWF16::construct }, }; struct instruction_constructor op_17cxx[] = { { 0xff00, 0xb100, ADDLW16::construct }, { 0xfe00, 0x0e00, ADDWF16::construct }, { 0xfe00, 0x1000, ADDWFC::construct }, { 0xff00, 0xb500, ANDLW16::construct }, { 0xfe00, 0x0a00, ANDWF16::construct }, { 0xf800, 0x8800, BCF::construct }, { 0xf800, 0x8000, BSF::construct }, { 0xf800, 0x9800, BTFSC::construct }, { 0xf800, 0x9000, BTFSS::construct }, { 0xf800, 0x3800, BTG::construct }, { 0xe000, 0xe000, CALL16::construct }, { 0xfe00, 0x2800, CLRF::construct }, { 0xffff, 0x0004, CLRWDT::construct }, { 0xfe00, 0x1200, COMF16::construct }, { 0xff00, 0x3100, CPFSEQ::construct }, { 0xff00, 0x3200, CPFSGT::construct }, { 0xff00, 0x3000, CPFSLT::construct }, { 0xfe00, 0x2e00, DAW::construct }, { 0xfe00, 0x0600, DECF16::construct }, { 0xfe00, 0x1600, DECFSZ16::construct }, { 0xfe00, 0x2600, DCFSNZ::construct }, { 0xe000, 0xc000, GOTO16::construct }, { 0xfe00, 0x1400, INCF16::construct }, { 0xfe00, 0x1e00, INCFSZ16::construct }, { 0xfe00, 0x2400, INFSNZ::construct }, { 0xff00, 0xb300, IORLW16::construct }, { 0xfe00, 0x0800, IORWF16::construct }, { 0xff00, 0xb700, LCALL16::construct }, { 0xe000, 0x6000, MOVFP::construct }, { 0xe000, 0x4000, MOVPF::construct }, { 0xff00, 0xb800, MOVLB::construct }, { 0xfe00, 0xba00, MOVLR::construct }, { 0xff00, 0xb000, MOVLW::construct }, { 0xff00, 0x0100, MOVWF16::construct }, { 0xff00, 0xbc00, MULLW::construct }, { 0xff00, 0x3400, MULWF::construct }, { 0xfe00, 0x2c00, NEGW::construct }, { 0xffff, 0x0000, NOP::construct }, { 0xffff, 0x0005, RETFIE16::construct }, { 0xff00, 0xb600, RETLW::construct }, { 0xffff, 0x0002, RETURN16::construct }, { 0xfe00, 0x1a00, RLCF::construct }, { 0xfe00, 0x2200, RLNCF::construct }, { 0xfe00, 0x1800, RRCF::construct }, { 0xfe00, 0x2000, RRNCF::construct }, { 0xfe00, 0x2a00, SETF::construct }, { 0xffff, 0x0003, SLEEP16::construct }, { 0xff00, 0xb200, SUBLW16::construct }, { 0xfe00, 0x0400, SUBWF16::construct }, { 0xfe00, 0x0200, SUBWFB::construct }, { 0xfe00, 0x1c00, SWAPF::construct }, { 0xfc00, 0xa800, TBLRD::construct }, { 0xfc00, 0xac00, TBLWT::construct }, { 0xfc00, 0xa000, TLRD::construct }, { 0xfc00, 0xa400, TLWT::construct }, { 0xff00, 0x3300, TSTFSZ::construct }, { 0xff00, 0xb400, XORLW16::construct }, { 0xfe00, 0x0c00, XORWF16::construct } }; const int NUM_OP_18CXX = sizeof(op_18cxx) / sizeof(op_18cxx[0]); const int NUM_OP_17CXX = sizeof(op_17cxx) / sizeof(op_17cxx[0]); instruction * disasm16 (pic_processor *cpu, unsigned int address, unsigned int inst) { instruction *pi; cpu16->setCurrentDisasmAddress(address); pi = 0; for(int i =0; i. */ #ifndef INTCON_H #define INTCON_H #include "gpsim_classes.h" #include "registers.h" #include "breakpoints.h" #include "pic-ioports.h" class IOCxF; class PicPortGRegister; //--------------------------------------------------------- // INTCON - Interrupt control register class INTCON : public sfr_register { public: unsigned int interrupt_trace; bool in_interrupt; enum { RBIF = 1<<0, INTF = 1<<1, T0IF = 1<<2, RBIE = 1<<3, INTE = 1<<4, T0IE = 1<<5, XXIE = 1<<6, // Processor dependent GIE = 1<<7 }; INTCON(Processor *pCpu, const char *pName, const char *pDesc); virtual void set_gie() { put(value.get() | GIE); } virtual void clear_gie() { put(value.get() & ~GIE); } void set_T0IF(); /* // Bit 6 of intcon depends on the processor that's being simulated, // This generic function will get called whenever interrupt flag upon // which bit 6 enables becomes true. (e.g. for the c84, this // routine is called when EEIF goes high.) */ virtual void peripheral_interrupt ( bool hi_pri = false ); virtual void set_rbif(bool b); inline void set_intf(bool b) { bool current = (value.get() & INTF) == INTF; if (b && !current) put(value.get() | INTF); if (!b && current) put(value.get() & ~INTF); } inline void set_t0if() { put(value.get() | T0IF); } inline void set_rbie() { put(value.get() | RBIE); } inline void set_inte() { put(value.get() | INTE); } inline void set_t0ie() { put(value.get() | T0IE); } void set_portGReg( PicPortGRegister *_portGReg) { portGReg = _portGReg; } virtual int check_peripheral_interrupt()=0; virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual void aocxf_val(IOCxF *, unsigned int val){} PicPortGRegister *portGReg; }; //--------------------------------------------------------- class INTCON2 : public sfr_register { public: INTCON2(Processor *pCpu, const char *pName, const char *pDesc); virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); virtual bool assignBitSink(unsigned int bitPosition, BitSink *); virtual bool releaseBitSink(unsigned int bitPosition, BitSink *); enum { RBIP = 1<<0, INT3IP = 1<<1, TMR0IP = 1<<2, INTEDG3 = 1<<3, INTEDG2 = 1<<4, INTEDG1 = 1<<5, INTEDG0 = 1<<6, RBPU = 1<<7 }; private: BitSink *m_bsRBPU; }; class INTCON3 : public sfr_register { public: INTCON3(Processor *pCpu, const char *pName, const char *pDesc); virtual void put_value(unsigned int new_value); virtual void put(unsigned int new_value); inline void set_int1f(bool b) { bool current = (value.get() & INT1IF) == INT1IF; if (b && !current) put(value.get() | INT1IF); if (!b && current) put(value.get() & ~INT1IF); } inline void set_int2f(bool b) { bool current = (value.get() & INT2IF) == INT2IF; if (b && !current) put(value.get() | INT2IF); if (!b && current) put(value.get() & ~INT2IF); } inline void set_int3f(bool b) { bool current = (value.get() & INT3IF) == INT3IF; if (b && !current) put(value.get() | INT3IF); if (!b && current) put(value.get() & ~INT3IF); } inline void set_int1e() { put(value.get() | INT1IE); } inline void set_int2e() { put(value.get() | INT2IE); } inline void set_int3e() { put(value.get() | INT3IE); } enum { INT1IF = 1<<0, INT2IF = 1<<1, INT3IF = 1<<2, INT1IE = 1<<3, INT2IE = 1<<4, INT3IE = 1<<5, INT1IP = 1<<6, INT2IP = 1<<7 }; }; class PIR_SET; // A 14-bit intcon with pir registers class INTCON_14_PIR : public INTCON { public: INTCON_14_PIR(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); inline void set_pir_set(PIR_SET *p) { pir_set = p; } virtual int check_peripheral_interrupt(); virtual void set_rbif(bool b); virtual void set_gie() { put_value(value.get() | GIE); } virtual void clear_gie() { put_value(value.get() & ~GIE); } virtual void aocxf_val(IOCxF *, unsigned int val); enum { IOCIF = 1<<0, INTF = 1<<1, T0IF = 1<<2, IOCIE = 1<<3, INTE = 1<<4, T0IE = 1<<5, PEIE = 1<<6, GIE = 1<<7 }; //private: PIR_SET *pir_set; unsigned int write_mask; // Bits that instructions can modify struct aocxf { struct IOCxF *ptr_iocxf; unsigned int val; }; vectoraocxf_list; }; //--------------------------------------------------------- // INTCON_16 - Interrupt control register for the 16-bit core class RCON; class INTCON_16 : public INTCON { public: enum { GIEH = GIE, GIEL = XXIE, TMR0IE = T0IE, INT0IE = INTE, TMR0IF = T0IF, INT0IF = INTF }; #define INTERRUPT_VECTOR_LO (0x18 >> 1) #define INTERRUPT_VECTOR_HI (0x08 >> 1) INTCON_16(Processor *pCpu, const char *pName, const char *pDesc); inline void set_rcon(RCON *r) { rcon = r; } inline void set_intcon2(INTCON2 *ic) { intcon2 = ic; } inline void set_pir_set(PIR_SET *p) { pir_set = p; } virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual void peripheral_interrupt ( bool hi_pri = false ); void clear_gies(); void set_gies(); virtual int check_peripheral_interrupt(); unsigned int get_interrupt_vector() { return interrupt_vector; } bool isHighPriorityInterrupt() { return ( interrupt_vector == INTERRUPT_VECTOR_HI ); } void set_interrupt_vector(unsigned int new_int_vect) { interrupt_vector = new_int_vect; } private: unsigned int interrupt_vector; // Starting address of the interrupt RCON *rcon; INTCON2 *intcon2; PIR_SET *pir_set; }; #endif /* INTCON_H */ gpsim-0.30.0/src/pm_rd.h0000664000076400007640000000565213041763624011723 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 2006 David Barnett This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef PM_RD_H #define PM_RD_H #include #include "gpsim_classes.h" #include "registers.h" #include "breakpoints.h" class pic_processor; class PM_RD; //--------------------------------------------------------- // PMCON1 - PM control register 1 // class PMCON1 : public sfr_register { public: enum { RD = (1<<0), }; PMCON1(Processor *p, PM_RD *); void put(unsigned int new_value); unsigned int get(); inline void set_pm(PM_RD *pm) {pm_rd = pm;} inline void set_valid_bits(unsigned int vb) { valid_bits = vb; } inline unsigned int get_valid_bits() { return (valid_bits); } inline void set_bits(unsigned int b) { valid_bits |= b; } inline void clear_bits(unsigned int b) { valid_bits &= ~b; } unsigned int valid_bits; PM_RD *pm_rd; }; const unsigned int PMCON1_VALID_BITS = (PMCON1::RD); // // PMDATA - PM data register // class PMDATA : public sfr_register { public: PMDATA(Processor *p, const char *pName); void put(unsigned int new_value); unsigned int get(); }; // // PMADR - PM address register // class PMADR : public sfr_register { public: PMADR(Processor *p, const char *pName); void put(unsigned int new_value); unsigned int get(); }; //------------------------------------------------------------------------ //------------------------------------------------------------------------ // For storing callback and cpu ptr and grouping PM regs class PM_RD : public TriggerObject { public: static const unsigned int READ_CYCLES = 2; PM_RD(pic_processor *p); //virtual void set_cpu(pic_processor *p) { cpu = p; } virtual void callback(); virtual void start_read(); inline virtual PMCON1 *get_reg_pmcon1() { return (&pmcon1); } inline virtual PMDATA *get_reg_pmdata() { return (&pmdata); } inline virtual PMDATA *get_reg_pmdath() { return (&pmdath); } inline virtual PMADR *get_reg_pmadr() { return (&pmadr); } inline virtual PMADR *get_reg_pmadrh() { return (&pmadrh); } //protected: pic_processor *cpu; PMCON1 pmcon1; PMDATA pmdata; PMDATA pmdath; PMADR pmadr; PMADR pmadrh; unsigned int rd_adr; // latched adr }; #endif /* PM_RD_H */ gpsim-0.30.0/src/program_files.cc0000664000076400007640000001044413041763624013604 00000000000000#include "exports.h" #include "program_files.h" #include "pic-processor.h" #include "cod.h" #include "hexutils.h" #include "cmd_gpsim.h" /** * RegisterProgramFileType * Exported function for external modules to register their * file types. */ void LIBGPSIM_EXPORT RegisterProgramFileType(ProgramFileType * pPFT) { ProgramFileTypeList::GetList().push_back(pPFT); } void ProgramFileType::DisplayError(int err, const char *pProgFilename, const char *pLstFile) { int iMessage; const char * pArg = ""; switch(err) { case ERR_UNRECOGNIZED_PROCESSOR: iMessage = IDS_PROGRAM_FILE_PROCESSOR_NOT_KNOWN; break; case ERR_FILE_NOT_FOUND: iMessage = IDS_FILE_NOT_FOUND; pArg = pProgFilename; break; case ERR_FILE_NAME_TOO_LONG: iMessage = IDS_FILE_NAME_TOO_LONG; pArg = pProgFilename; break; case ERR_LST_FILE_NOT_FOUND: if(pLstFile == NULL) { iMessage = IDS_LIST_FILE_NOT_FOUND; pArg = pProgFilename; } else { iMessage = IDS_FILE_NOT_FOUND; pArg = pLstFile; } break; case ERR_BAD_FILE: iMessage = IDS_FILE_BAD_FORMAT; pArg = pProgFilename; break; case ERR_NO_PROCESSOR_SPECIFIED: iMessage = IDS_NO_PROCESSOR_SPECIFIED; break; case ERR_PROCESSOR_INIT_FAILED: iMessage = IDS_PROCESSOR_INIT_FAILED; break; case ERR_NEED_PROCESSOR_SPECIFIED: iMessage = IDS_FILE_NEED_PROCESSOR_SPECIFIED; break; default: iMessage = SUCCESS; break; } if(iMessage != SUCCESS) GetUserInterface().DisplayMessage(iMessage, pArg); } /** * ProgramFileTypeList * Singleton class to manage the many (as of now three) file types. */ ProgramFileTypeList * ProgramFileTypeList::s_ProgramFileTypeList = new ProgramFileTypeList(); // We will instantiate g_HexFileType and g_CodFileType here to be sure // they are instantiated after s_ProgramFileTypeList. The objects will // move should the PIC code moved to its own external module. static IntelHexProgramFileType g_HexFileType; static PicCodProgramFileType g_CodFileType; ProgramFileTypeList &ProgramFileTypeList::GetList() { return *s_ProgramFileTypeList; } ProgramFileTypeList::ProgramFileTypeList() { reserve(5); } ProgramFileTypeList::~ProgramFileTypeList() { } bool ProgramFileTypeList::LoadProgramFile(Processor **pProcessor, const char *pFilename, FILE *pFile, const char *pProcessorName) { iterator it; iterator itLast; iterator itEnd = end(); int iReturn = ProgramFileType::SUCCESS; for(it = begin(); it != itEnd; ++it) { itLast = it; fseek(pFile, 0, SEEK_SET); //get_symbol_table().clear(); if((iReturn = (*it)->LoadProgramFile(pProcessor, pFilename, pFile, pProcessorName)) == ProgramFileType::SUCCESS) { return true; } if(IsErrorDisplayableInLoop(iReturn)) { (*it)->DisplayError(iReturn, pFilename, NULL); } } if(!IsErrorDisplayableInLoop(iReturn)) { (*itLast)->DisplayError(iReturn, pFilename, NULL); } return false; } bool ProgramFileTypeList::IsErrorDisplayableInLoop(int iError) { return iError != ProgramFileType::SUCCESS && iError != ProgramFileType::ERR_BAD_FILE && iError != ProgramFileType::ERR_NEED_PROCESSOR_SPECIFIED && iError != ProgramFileType::ERR_LST_FILE_NOT_FOUND; } /// /// ProgramFileBuf /// Used to wrap the FILE pointer to the program file /// for libraries that use istreams. ///////////////////////////////////////////////////// ProgramFileBuf::ProgramFileBuf(FILE *pFile) { m_pFile = pFile; setg(m_Buffer + 4, m_Buffer + 4, m_Buffer + 4); } ProgramFileBuf::int_type ProgramFileBuf::underflow( ) { if(gptr() < egptr()) { return *gptr(); } int numPutback; numPutback = gptr() - eback(); if (numPutback > 4) { numPutback = 4; } std::memcpy (m_Buffer+(4-numPutback), gptr() - numPutback, numPutback); int num; if((num = ::fread((void*)( m_Buffer + 4), 1, m_iBufferSize - 4, m_pFile)) <= 0) { if(errno != 0) printf("%s\n", strerror(errno)); return (int_type )traits_type::eof(); } setg(m_Buffer + (4 - numPutback), m_Buffer + 4, m_Buffer + 4 + num); return *gptr(); } streamsize ProgramFileBuf::xsgetn( char_type *_Ptr, streamsize _Count) { return ::fread(_Ptr, _Count, 1, m_pFile); } gpsim-0.30.0/src/a2dconverter.h0000664000076400007640000003641013077607073013220 00000000000000/* Copyright (C) 2006 T. Scott Dattalo Copyright (C) 2009, 2013, 2015 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __A2DCONVERTER_H__ #define __A2DCONVERTER_H__ #include "registers.h" #include "trigger.h" #include "intcon.h" #include "pir.h" #include "comparator.h" class DACCON0; class PinModule; class pic_processor; //--------------------------------------------------------- // ADRES // /* class ADRES : public sfr_register { public: void put(int new_value); }; */ /* AD_IN_SignalControl is used to set an ADC pin as input regardless of the setting to the TRIS register */ class AD_IN_SignalControl : public SignalControl { public: AD_IN_SignalControl(){} ~AD_IN_SignalControl(){} char getState() { return '1'; } void release() { } }; //--------------------------------------------------------- // ADCON1 // class ADCON1 : public sfr_register { public: enum PCFG_bits { PCFG0 = 1<<0, PCFG1 = 1<<1, PCFG2 = 1<<2, PCFG3 = 1<<3, // 16f87x etc. VCFG0 = 1<<4, // 16f88 VCFG1 = 1<<5, // 16f88 ADCS2 = 1<<6, ADFM = 1<<7 // Format Result select bit }; ADCON1(Processor *pCpu, const char *pName, const char *pDesc); ~ADCON1(); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void setChannelConfiguration(unsigned int cfg, unsigned int bitMask); void setVrefLoConfiguration(unsigned int cfg, unsigned int channel); void setVrefHiConfiguration(unsigned int cfg, unsigned int channel); unsigned int getVrefHiChannel(unsigned int cfg); unsigned int getVrefLoChannel(unsigned int cfg); double getChannelVoltage(unsigned int channel); virtual double getVrefHi(); virtual double getVrefLo(); void setValidCfgBits(unsigned int m, unsigned int s); void setNumberOfChannels(unsigned int); unsigned int getNumberOfChannels() { return(m_nAnalogChannels);} void setIOPin(unsigned int, PinModule *); void setVoltRef(unsigned int, float); int get_cfg(unsigned int); virtual unsigned int get_adc_configmask(unsigned int); virtual void set_cfg_index(unsigned int index) { cfg_index = index;} void set_channel_in(unsigned int channel, bool on); void setADCnames(); void setValidBits(unsigned int mask) { valid_bits = mask;} bool getADFM() { return adfm;} unsigned int getMaxCfg() { return cMaxConfigurations;} protected: unsigned int valid_bits; bool adfm; PinModule **m_AnalogPins; float *m_voltageRef; unsigned int m_nAnalogChannels; unsigned int mValidCfgBits; unsigned int mCfgBitShift; unsigned int mIoMask; unsigned int cfg_index; static const unsigned int cMaxConfigurations=16; /* Vrefhi/lo_position - this is an array that tells which * channel the A/D converter's voltage reference(s) are located. * The index into the array is formed from the PCFG bits. * The encoding is as follows: * 0-7: analog channel containing Vref(s) * 8: The reference is internal (i.e. Vdd) * 0xff: The analog inputs are configured as digital inputs */ unsigned int Vrefhi_position[cMaxConfigurations]; unsigned int Vreflo_position[cMaxConfigurations]; /* configuration bits is an array of 8-bit masks definining whether or not * a given channel is analog or digital */ unsigned int m_configuration_bits[cMaxConfigurations]; // used bt setControl to set pin direction as input AD_IN_SignalControl *m_ad_in_ctl; }; class ADCON0; //--------------------------------------------------------- // ADCON1_16F // class ADCON1_16F : public ADCON1 { public: enum { ADPREF0 = (1<<0), ADPREF1 = (1<<1), ADNREF = (1<<2), ADCS0 = (1<<4), ADCS1 = (1<<5), ADCS2 = (1<<6), ADFM = (1<<7) }; ADCON1_16F(Processor *pCpu, const char *pName, const char *pDesc); virtual void put_value(unsigned int new_value); void setAdcon0 (ADCON0 *_adcon0) {adcon0 = _adcon0;} virtual double getVrefHi(); virtual double getVrefLo(); void set_FVR_chan(unsigned int chan) { FVR_chan = chan;} private: ADCON0 *adcon0; unsigned int FVR_chan; }; //--------------------------------------------------------- // ADCON0 // class ADCON0 : public sfr_register, public TriggerObject { public: enum { ADON = 1<<0, ADIF = 1<<1, GO = 1<<2, CHS0 = 1<<3, CHS1 = 1<<4, CHS2 = 1<<5, ADCS0 = 1<<6, ADCS1 = 1<<7, }; enum AD_states { AD_IDLE, AD_ACQUIRING, AD_CONVERTING }; ADCON0(Processor *pCpu, const char *pName, const char *pDesc); void start_conversion(); void stop_conversion(); virtual void set_interrupt(); virtual void callback(); void put(unsigned int new_value); virtual void put_conversion(); bool getADIF() { return (value.get() & ADIF) != 0; } void setAdres(sfr_register *); void setAdresLow(sfr_register *); void setAdcon1(ADCON1 *); void setIntcon(INTCON *); virtual void setPir(PIR *); void setA2DBits(unsigned int); void setChannel_Mask(unsigned int ch_mask) { channel_mask = ch_mask; } void setChannel_shift(unsigned int ch_shift) { channel_shift = ch_shift; } void setGo(unsigned int go) { GO_bit = (1 << go); } virtual bool get_ADFM() { return adcon1->getADFM(); } virtual void set_Tad(unsigned int); virtual double getChannelVoltage(unsigned int channel) { return( adcon1->getChannelVoltage(channel)); } virtual double getVrefHi() { return(m_dSampledVrefHi = adcon1->getVrefHi());} virtual double getVrefLo() { return (m_dSampledVrefLo = adcon1->getVrefLo());} void setValidBits(unsigned int mask) { valid_bits = mask;} private: friend class ADCON0_10; friend class ADCON0_12F; friend class ADCON0_DIF; sfr_register *adres; sfr_register *adresl; ADCON1 *adcon1; INTCON *intcon; PIR *m_pPir; double m_dSampledVoltage; double m_dSampledVrefHi; double m_dSampledVrefLo; unsigned int m_A2DScale; unsigned int m_nBits; guint64 future_cycle; unsigned int ad_state; unsigned int Tad_2; unsigned int Tad; unsigned int channel_mask; unsigned int channel_shift; unsigned int GO_bit; unsigned int valid_bits; }; class ADCON0_91X : public ADCON0 { public: enum { ADON = 1<<0, GO = 1<<1, CHS0 = 1<<2, CHS1 = 1<<3, CHS2 = 1<<4, VCFG0 = 1<<5, // P16f91x VCFG1 = 1<<6, // P16f91x ADFM = 1<<7, // P16f91x }; ADCON0_91X(Processor *pCpu, const char *pName, const char *pDesc) : ADCON0(pCpu, pName, pDesc){}; virtual bool get_ADFM() { return value.get() & ADFM; } virtual double getVrefHi(); virtual double getVrefLo(); unsigned int Vrefhi_position; unsigned int Vreflo_position; }; class ADCON2_DIF; /* A/D converter with 12 or 10 bit differential input with ADCON2 */ class ADCON0_DIF : public ADCON0 { enum { ADON = 1<<0, GO = 1<<1, CHS0 = 1<<2, CHS1 = 1<<3, CHS2 = 1<<4, CHS3 = 1<<5, CHS4 = 1<<6, ADRMD = 1<<7 }; public: ADCON0_DIF(Processor *pCpu, const char *pName, const char *pDesc); virtual void put(unsigned int new_value); virtual void put_conversion(void); void setAdcon2(ADCON2_DIF * _adcon2) { adcon2 = _adcon2;} private: ADCON2_DIF *adcon2; }; //--------------------------------------------------------- // ADCON0_10 register for 10f22x A2D // class ADCON0_10 : public ADCON0 { public: enum { ADON = 1<<0, GO = 1<<1, CHS0 = 1<<2, CHS1 = 1<<3, ANS0 = 1<<6, ANS1 = 1<<7 }; void put(unsigned int new_value); ADCON0_10(Processor *pCpu, const char *pName, const char *pDesc); private: AD_IN_SignalControl ad_pin_input; }; //--------------------------------------------------------- // ANSEL // class ANSEL_H; class ANSEL : public sfr_register { public: enum { ANS0 = 1 << 0, ANS1 = 1 << 1, ANS2 = 1 << 2, ANS3 = 1 << 3, ANS4 = 1 << 4, ANS5 = 1 << 5, ANS6 = 1 << 6, ANS7 = 1 << 7 }; ANSEL(Processor *pCpu, const char *pName, const char *pDesc); void setAdcon1(ADCON1 *new_adcon1); void setAnselh(ANSEL_H *new_anselh) { anselh = new_anselh;} void put(unsigned int new_val); void setValidBits(unsigned int mask) { valid_bits = mask;} private: ADCON1 *adcon1; ANSEL_H *anselh; unsigned int valid_bits; }; //--------------------------------------------------------- // ANSEL_H // class ANSEL_H : public sfr_register { public: enum { ANS8 = 1 << 0, ANS9 = 1 << 1, ANS10 = 1 << 2, ANS11 = 1 << 3, ANS12 = 1 << 4, ANS13 = 1 << 5, }; ANSEL_H(Processor *pCpu, const char *pName, const char *pDesc); void setAdcon1(ADCON1 *new_adcon1); void setAnsel(ANSEL *new_ansel) { ansel = new_ansel;} void put(unsigned int new_val); void setValidBits(unsigned int mask) { valid_bits = mask;} private: ADCON1 *adcon1; ANSEL *ansel; unsigned int valid_bits; }; // // ANSEL_P is an analog select register associated // with a port. class ANSEL_P : public sfr_register { public: ANSEL_P(Processor *pCpu, const char *pName, const char *pDesc); void setAdcon1(ADCON1 *new_adcon1); void setAnsel(ANSEL_P *new_ansel) { ansel = new_ansel;} void put(unsigned int new_val); void setValidBits(unsigned int mask) { valid_bits = mask;} void config(unsigned int pins, unsigned int first_chan) { analog_pins = pins; first_channel = first_chan;} unsigned int get_mask() { return cfg_mask;} private: ADCON1 *adcon1; ANSEL_P *ansel; unsigned int valid_bits; // register bit mask unsigned int analog_pins; // bit map of analog port pins unsigned int first_channel; // channel number for LSB of analog_pins unsigned int cfg_mask; // A2D mask this port only }; //--------------------------------------------------------- // ADCON0_12F register for 12f675 A2D // class ADCON0_12F : public ADCON0 { public: enum { ADON = 1<<0, GO = 1<<1, CHS0 = 1<<2, CHS1 = 1<<3, CHS2 = 1<<4, VCFG = 1<<6, ADFM = 1<<7 }; void put(unsigned int new_value); virtual bool get_ADFM() { return(value.get() & ADFM); } virtual void set_Tad(unsigned int _tad) { Tad = _tad; } ADCON0_12F(Processor *pCpu, const char *pName, const char *pDesc); private: AD_IN_SignalControl ad_pin_input; }; //--------------------------------------------------------- // ANSEL_12F // class ANSEL_12F : public sfr_register { public: enum { ANS0 = 1 << 0, ANS1 = 1 << 1, ANS2 = 1 << 2, ANS3 = 1 << 3, ADCS0 = 1 << 4, ADCS1 = 1 << 5, ADCS2 = 1 << 6 }; ANSEL_12F(Processor *pCpu, const char *pName, const char *pDesc); void setAdcon0(ADCON0_12F *new_adcon0) { adcon0 = new_adcon0; } void setAdcon1(ADCON1 *new_adcon1) { adcon1 = new_adcon1; } void put(unsigned int new_val); void set_tad(unsigned int); private: ADCON1 *adcon1; ADCON0_12F *adcon0; }; // set voltage from stimulus class a2d_stimulus : public stimulus { public: a2d_stimulus(ADCON1 *arg, int chan, const char *n=0, double _Vth=0.0, double _Zth=1e12 ); ADCON1 *_adcon1; int channel; virtual void set_nodeVoltage(double v); }; //--------------------------------------------------------- // FVRCON register for Fixed Voltage Reference // class FVRCON : public sfr_register { public: enum { ADFVR0 = 1<<0, ADFVR1 = 1<<1, CDAFVR0 = 1<<2, CDAFVR1 = 1<<3, TSRNG = 1<<4, TSEN = 1<<5, FVRRDY = 1<<6, FVREN = 1<<7, }; FVRCON(Processor *, const char *pName, const char *pDesc=0, unsigned int bitMask= 0xff, unsigned int alwaysOne = 0); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void set_adcon1(ADCON1 *_adcon1) { adcon1 = _adcon1;} void set_cmModule(ComparatorModule2 *_cmModule) { cmModule = _cmModule;} void set_daccon0(DACCON0 *_daccon0) { daccon0_list.push_back(_daccon0);} void set_cpscon0(CPSCON0 *_cpscon0) { cpscon0 = _cpscon0;} void set_VTemp_AD_chan(unsigned int _chan) {VTemp_AD_chan = _chan;} void set_FVRAD_AD_chan(unsigned int _chan) {FVRAD_AD_chan = _chan;} private: double compute_VTemp(unsigned int); //Voltage of core temperature setting double compute_FVR_AD(unsigned int); //Voltage reference for ADC double compute_FVR_CDA(unsigned int); //Voltage reference for Comparators, DAC, CPS ADCON1 *adcon1; DACCON0 *daccon0; vector daccon0_list; ComparatorModule2 *cmModule; CPSCON0 *cpscon0; unsigned int VTemp_AD_chan; unsigned int FVRAD_AD_chan; unsigned int mask_writable; unsigned int always_one; // bits in register that are always 1 }; // // DAC module // class DACCON1; class DACCON0 : public sfr_register { public: enum { DACNSS = (1<<0), // Negative source select bit (18f26k22) DACPSS0 = (1<<2), DACPSS1 = (1<<3), DACOE2 = (1<<4), DACOE = (1<<5), DACLPS = (1<<6), DACEN = (1<<7), }; DACCON0(Processor *, const char *pName, const char *pDesc=0, unsigned int bitMask= 0xe6, unsigned int bit_res = 32); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual void set_adcon1(ADCON1 *_adcon1) { adcon1 = _adcon1;} void set_cpscon0(CPSCON0 *_cpscon0) { cpscon0 = _cpscon0;} void set_cmModule(ComparatorModule2 *_cmModule) { cmModule = _cmModule;} void set_FVRCDA_AD_chan(unsigned int _chan) {FVRCDA_AD_chan = _chan;} void set_dcaccon1_reg(unsigned int reg); void set_FVR_CDA_volt(double volt) { FVR_CDA_volt = volt;} void setDACOUT(PinModule *pin1, PinModule *pin2 = NULL) { output_pin[0] = pin1; output_pin[1] = pin2;} virtual void compute_dac(unsigned int value); virtual double get_Vhigh(unsigned int value); protected: void set_dacoutpin(bool output_enabled, int chan, double Vout); ADCON1 *adcon1; ComparatorModule2 *cmModule; vector cmModule_list; CPSCON0 *cpscon0; unsigned int FVRCDA_AD_chan; unsigned int bit_mask; unsigned int bit_resolution; unsigned int daccon1_reg; double FVR_CDA_volt; bool Pin_Active[2]; double Vth[2]; double Zth[2]; bool driving[2]; PinModule *output_pin[2]; IOPIN *pin; }; class DACCON1 : public sfr_register { public: DACCON1(Processor *, const char *pName, const char *pDesc=0, unsigned int bitMask= 0x1f, DACCON0 *_daccon0 = 0); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); void set_daccon0(DACCON0 *_daccon0) { daccon0 = _daccon0;} private: unsigned int bit_mask; DACCON0 *daccon0; }; class ADCON2_DIF : public sfr_register, public TriggerObject { public: enum { CHSNS0 = 1<<0, CHSNS1 = 1<<1, CHSNS2 = 1<<2, CHSNS3 = 1<<3, TRIGSEL0 = 1<<4, TRIGSEL1 = 1<<5, TRIGSEL2 = 1<<6, TRIGSEL3 = 1<<7, }; ADCON2_DIF(Processor *pCpu, const char *pName, const char *pDesc); private: }; #endif // __A2DCONVERTER_H__ gpsim-0.30.0/src/registers.h0000664000076400007640000003451613116644445012634 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __REGISTERS_H__ #define __REGISTERS_H__ #include class symbol; class XrefObject; class Processor; class Module; #include "gpsim_classes.h" #include "value.h" #include "ValueCollections.h" #include "clock_phase.h" #define AN_INVALID_ADDRESS 0xffffffff //--------------------------------------------------------- // RegisterValue class // // This class is used to represent the value of registers. // It also defines which bits have been initialized and which // are valid. // class RegisterValue { public: unsigned int data; // The actual numeric value of the register. unsigned int init; // bit mask of initialized bits. RegisterValue() { data = 0; init = 0xff; // assume 8-bit wide, uninitialized registers } RegisterValue(unsigned int d, unsigned int i) : data(d), init(i) { } RegisterValue(const RegisterValue &value) : data(value.data), init(value.init) { } inline bool initialized() { return init == 0; } inline unsigned int get() { return data; } inline void put(unsigned int d) { data = d; } inline void put(unsigned int d, unsigned int i) { data = d; init = i; } inline unsigned int geti() { return init; } inline void puti(unsigned int i) { init = i; } inline void operator = (RegisterValue rv) { data = rv.data; init = rv.init; } inline operator unsigned int () { return data; } inline operator int () { return (int)data; } bool operator == (const RegisterValue &rv) const { return data == rv.data && init == rv.init; } bool operator != (const RegisterValue &rv) const { return data != rv.data || init != rv.init; } void operator >>= (unsigned int val) { data >>= val; init >>= val; } char * toString(char *str, int len, int regsize=2) const; char * toBitStr(char *s, int len, unsigned int BitPos, const char *ByteSeparator="_", const char *HiBitNames=0, const char *LoBitNames=0, const char *UndefBitNames=0) const; }; //--------------------------------------------------------- /// Register - base class for gpsim registers. /// The Register class is used by processors and modules to /// to create memory maps and special function registers. /// class Register : public Value { public: enum REGISTER_TYPES { INVALID_REGISTER, GENERIC_REGISTER, FILE_REGISTER, SFR_REGISTER, BP_REGISTER }; RegisterValue value; unsigned int address; // If non-zero, the alias_mask describes all address at which // this file register appears. The assumption (that is true so // far for all pic architectures) is that the aliased register // locations differ by one bit. For example, the status register // appears at addresses 0x03 and 0x83 in the 14-bit core. // Consequently, alias_mask = 0x80 and address (above) is equal // to 0x03. unsigned int alias_mask; RegisterValue por_value; // power on reset value unsigned int mValidBits; // = 255 for 8-bit registers, = 65535 for 16-bit registers. // The read_trace and write_trace variables are used while // tracing register reads and writes. Essentially, these are // the trace commands. RegisterValue write_trace; RegisterValue read_trace; // The trace_state is used to reconstruct the state of the // register while traversing a trace buffer. RegisterValue trace_state; guint64 read_access_count; guint64 write_access_count; public: Register(Module *, const char *pName, const char *pDesc=0); virtual ~Register(); virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); virtual int clear_break(); /// get - method for accessing the register's contents. virtual unsigned int get(); /// put - method for writing a new value to the register. virtual void put(unsigned int new_value); /// put_value - is the same as put(), but some extra stuff like /// interfacing to the gui is done. (It's more efficient than /// burdening the run time performance with (unnecessary) gui /// calls.) virtual void put_value(unsigned int new_value); /// get_value - same as get(), but no trace is performed virtual unsigned int get_value() { return(value.get()); } /// getRV - get the whole register value - including the info /// of the three-state bits. virtual RegisterValue getRV() { value.data = get(); return value; } /// putRV - write a new value to the register. /// \deprecated {use SimPutAsRegisterValue()} /// virtual void putRV(RegisterValue rv) { value.init = rv.init; put(rv.data); } /// getRV_notrace and putRV_notrace are analogous to getRV and putRV /// except that the action (in the derived classes) will not be /// traced. The primary reason for this is to allow the gui to /// refresh it's windows without having the side effect of filling /// up the trace buffer virtual RegisterValue getRV_notrace() { value.data = value.get(); return value; } virtual void putRV_notrace(RegisterValue rv) { value.init = rv.init; put_value(rv.data); } virtual RegisterValue getRVN() { return getRVN_notrace(); } virtual RegisterValue getRVN_notrace() { return getRV_notrace(); } /// set --- cast another Value object type into a register type /// this is used primarily by expression and stimuli processing /// (the put() methods are used by the processors). /// FIXME -- consolidate the get, set, and put methods virtual void set(Value *); /// copy --- This is used during expression parsing. virtual Value *copy(); /// get(gint64 &i) --- ugh. virtual void get(gint64 &i); virtual void initialize() { } /// get3StateBit - returns the 3-state value of a bit /// if a bit is known then a '1' or '0' is returned else, /// a '?' is returned. No check is performed to ensure /// that only a single bit is checked, thus it's possible /// to get the state of a group of bits using this method. virtual char get3StateBit(unsigned int bitMask) { RegisterValue rv = getRV_notrace(); return (rv.init & bitMask) ? '?' : ((rv.data & bitMask) ? '1' : '0'); } /// In the Register class, the 'Register *get()' returns a /// pointer to itself. Derived classes may return something /// else (e.g. a break point may be pointing to the register /// it replaced and will return that instead). virtual Register *getReg() { return this; } virtual REGISTER_TYPES isa() {return GENERIC_REGISTER;}; virtual void reset(RESET_TYPE r) { return; }; /// The setbit function is not really intended for general purpose /// registers. Instead, it is a place holder which is over-ridden /// by the IO ports. virtual void setbit(unsigned int bit_number, bool new_value); /// like setbit, getbit is used mainly for breakpoints. virtual bool get_bit(unsigned int bit_number); virtual double get_bit_voltage(unsigned int bit_number); /// Breakpoint objects will overload this function and return true. virtual bool hasBreak() { return false; } /// register_size returns the number of bytes required to store the register /// (this is used primarily by the gui to determine how wide to make text fields) virtual unsigned int register_size () const; /* When the register is accessed, this action is recorded in the trace buffer. Here we can specify the exact trace command to use. */ virtual void set_write_trace(RegisterValue &rv); virtual void set_read_trace(RegisterValue &rv); virtual void put_trace_state(RegisterValue rv) { trace_state = rv; } virtual RegisterValue get_trace_state() { return trace_state; } /* convert value to a string: */ virtual char * toString(char *str, int len); virtual char * toBitStr(char *s, int len); virtual string &baseName() { return name_str; } virtual unsigned int getAddress() { return address; } virtual void setAddress(unsigned int addr) { address = addr; } Register *getReplaced() { return m_replaced; } void setReplaced(Register *preg) { m_replaced = preg; } virtual void new_name(string &); virtual void new_name(const char *); protected: // A pointer to the register that this register replaces. // This is used primarily by the breakpoint code. Register *m_replaced; }; //--------------------------------------------------------- // define a special 'invalid' register class. Accessess to // to this class' value get 0 class InvalidRegister : public Register { public: InvalidRegister(Processor *, const char *pName, const char *pDesc=0); void put(unsigned int new_value); unsigned int get(); virtual REGISTER_TYPES isa() {return INVALID_REGISTER;}; virtual Register *getReg() {return 0; } }; //--------------------------------------------------------- // Base class for a special function register. class BitSink; class sfr_register : public Register { public: sfr_register(Module *, const char *pName, const char *pDesc=0); RegisterValue wdtr_value; // wdt or mclr reset value virtual REGISTER_TYPES isa() {return SFR_REGISTER;}; virtual void initialize() {}; virtual void reset(RESET_TYPE r); // The assign and release BitSink methods don't do anything // unless derived classes redefine them. Their intent is to // provide an interface to the BitSink design - a design that // allows clients to be notified when bits change states. virtual bool assignBitSink(unsigned int bitPosition, BitSink *) {return false;} virtual bool releaseBitSink(unsigned int bitPosition, BitSink *) {return false;} }; //--------------------------------------------------------- // Program Counter // class PCTraceType; class Program_Counter : public Value { public: unsigned int value; /* pc's current value */ unsigned int memory_size; unsigned int pclath_mask; /* pclath confines PC to banks */ unsigned int instruction_phase; unsigned int trace_state; /* used while reconstructing the trace history */ // Trace commands unsigned int trace_increment; unsigned int trace_branch; unsigned int trace_skip; unsigned int trace_other; Program_Counter(const char *name, const char *desc, Module *pM); ~Program_Counter(); virtual void increment(); virtual void start_skip(); virtual void skip(); virtual void jump(unsigned int new_value); virtual void interrupt(unsigned int new_value); virtual void computed_goto(unsigned int new_value); virtual void new_address(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual void update_pcl(); virtual void get(char *buffer, int buf_size); virtual unsigned int get_value() { return value; } virtual unsigned int get_PC() { return value; } virtual void set_PC(unsigned int new_value) { value = new_value; this->update(); } /// set --- cast another Value object type into a program counter register type /// this is used primarily by expression and stimuli processing /// (the put() methods are used by the processors). /// FIXME -- consolidate the get, set, and put methods virtual void set(Value *); // initialize the dynamically allocated trace type virtual void set_trace_command(); /// get_raw_value -- on the 16-bit cores, get_value is multiplied by 2 /// whereas get_raw_value isn't. The raw value of the program counter /// is used as an index into the program memory. virtual unsigned int get_raw_value() { return value; } virtual void set_phase(int phase) { instruction_phase = phase; } virtual int get_phase() { return instruction_phase; } void set_reset_address(unsigned int _reset_address) { reset_address = _reset_address; } unsigned int get_reset_address() { return reset_address; } void reset(); virtual unsigned int get_next(); virtual void put_trace_state(unsigned int ts) { trace_state = ts; } protected: unsigned int reset_address; /* Value pc gets at reset */ PCTraceType *m_pPCTraceType; }; // Used in the command prompt interface class RegisterCollection : public IIndexedCollection { public: RegisterCollection(Processor *pProcessor, const char *collection_name, Register **ppRegisters, unsigned int uiSize); ~RegisterCollection(); virtual void get(char *return_str, int len); virtual unsigned int GetSize(); virtual Value &GetAt(unsigned int uIndex, Value *pValue=0); virtual void SetAt(unsigned int uIndex, Value *pValue); virtual void ConsolidateValues(int &iColumnWidth, vector &aList, vector &aValue); // virtual void SetAt(ExprList_t* pIndexers, Expression *pExpr); virtual unsigned int GetLowerBound(); virtual unsigned int GetUpperBound(); private: Processor * m_pProcessor; Register ** m_ppRegisters; unsigned int m_uSize; Integer m_ReturnValue; }; //------------------------------------------------------------------------ // BitSink // // A BitSink is an object that can direct bit changes in an SFR to some // place where they're needed. The purpose is to abstract the interface // between special bits and the various peripherals. // // A client wishing to be notified whenever an SFR bit changes states // will create a BitSink object and pass its pointer to the SFR. The // client will also tell the SFR which bit this applies to. Now, when // the bit changes states in the SFR, the SFR will call the setSink() // method. class BitSink { public: virtual ~BitSink() { } virtual void setSink(bool) = 0; }; #endif // __REGISTERS__ gpsim-0.30.0/src/picdis.h0000664000076400007640000000044313041763624012066 00000000000000/* picdis.h - constants and includes */ /* version 0.1 */ /* (c) I.King 1994 */ #include #include /* #define PIC12 0 #define PIC14 1 #define LOWERCASE 0 #define UPPERCASE 1 */ #define MAXPICSIZE 0x10000 #define CONFIGURATION_WORD 0x2007 /* ... The End ... */ gpsim-0.30.0/src/p16f8x.cc0000664000076400007640000007063613115237016012011 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2006 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16f8x // // This file supports: // PIC16F87 // PIC16F88 // PIC16F818 // PIC16F819 // #include #include #include //#include "../config.h" #include "stimuli.h" #include "p16f8x.h" #include "pic-ioports.h" #include "packages.h" #include "symbol.h" //======================================================================== // // Configuration Memory for the 16F8X devices. class Config1 : public ConfigWord { public: Config1(pic_processor *pCpu) : ConfigWord("CONFIG1", 0x3fff, "Configuration Word", pCpu, 0x2007) { } enum { FOSC0 = 1<<0, FOSC1 = 1<<1, WDTEN = 1<<2, PWRTEN = 1<<3, FOSC2 = 1<<4, MCLRE = 1<<5, BOREN = 1<<6, LVP = 1<<7, CPD = 1<<8, WRT0 = 1<<9, WRT1 = 1<<10, DEBUG = 1<<11, CCPMX = 1<<12, CP = 1<<13 }; virtual void set(gint64 v) { Integer::set(v); if (m_pCpu) m_pCpu->wdt.initialize((v & WDTEN) == WDTEN); } }; //======================================================================== P16F8x::P16F8x(const char *_name, const char *desc) : P16X6X_processor(_name,desc), wdtcon(this, "wdtcon", "WDT Control", 0x1f), osccon(0), osctune(this, "osctune", "OSC Tune"), usart(this), comparator(this) { pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir2_2_reg = new PIR2v2(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); delete pir1; delete pir2; pir1 = pir1_2_reg; pir2 = pir2_2_reg; } P16F8x::~P16F8x() { delete_file_registers(0xc0, 0xef); delete_file_registers(0x110,0x16f); delete_file_registers(0x190,0x1ef); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); remove_sfr_register(&wdtcon); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); delete get_eeprom(); remove_sfr_register(osccon); remove_sfr_register(&osctune); remove_sfr_register(&pie2); } void P16F8x::create_iopin_map() { package = new Package(18); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 3, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(15, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(16, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin(5, 0); // Vss package->assign_pin( 6, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin( 7, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(14, 0); // Vdd if (hasSSP()) { ssp.initialize( get_pir_set(), // PIR &(*m_portb)[4], // SCK &(*m_portb)[5], // SS &(*m_portb)[2], // SDO &(*m_portb)[1], // SDI m_trisb, // i2c tris port SSP_TYPE_SSP ); } } void P16F8x::create_sfr_map() { pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); add_file_registers(0xc0, 0xef, 0); add_file_registers(0x110,0x16f,0); add_file_registers(0x190,0x1ef,0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); add_sfr_register(get_pir2(), 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); pir_set_def.set_pir2(pir2); pie2.setPir(get_pir2()); alias_file_registers(0x00,0x04,0x100); alias_file_registers(0x80,0x84,0x100); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x86,0x86,0x100); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); //alias_file_registers(0x0a,0x0b,0x080); // Already done alias_file_registers(0x0a,0x0b,0x100); alias_file_registers(0x0a,0x0b,0x180); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); add_sfr_register(osccon, 0x8f, RegisterValue(0,0),"osccon"); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); osccon->write_mask = 0x73; osccon->has_iofs_bit = true; usart.initialize(pir1,&(*m_portb)[5], &(*m_portb)[2], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), &(*m_porta)[2], &(*m_porta)[0], &(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[3], &(*m_porta)[3], &(*m_porta)[4]); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN2, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN2, AN3, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 1, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 2, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN2, AN0, AN2, NO_OUT); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN3, NO_OUT); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 5, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 6, AN0, AN2, AN0, AN2, OUT0); comparator.cmcon.set_configuration(2, 6, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0x9c, RegisterValue(7,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0x9d, RegisterValue(0,0),"cvrcon"); add_sfr_register(&wdtcon, 0x105, RegisterValue(0x08,0),"wdtcon"); } void P16F8x::create_symbols() { if(verbose) cout << "8x create symbols\n"; Pic14Bit::create_symbols(); } void P16F8x::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } //======================================================================== bool P16F8x::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<4, CFG_MCLRE = 1<<5, CFG_CCPMX = 1<<12, CFG2_IESO = 1<<1 }; unsigned int fosc; // Let the base class do most of the work: if (address == 0x2007) { pic_processor::set_config_word(address, cfg_word); if (verbose) cout << "p16f8x 0x" << hex << address << " setting config word 0x" << cfg_word << '\n'; unsigned int valid_pins = m_porta->getEnableMask(); set_int_osc(false); // Careful these bits not adjacent fosc = ((cfg_word & CFG_FOSC2) >> 2) | (cfg_word & (CFG_FOSC0 | CFG_FOSC1)); if (osccon) { osccon->set_config_xosc(fosc < 3); osccon->set_config_irc(fosc == 4 || fosc == 5); } switch(fosc) { case 0: // LP oscillator: low power crystal is on RA6 and RA7 case 1: // XT oscillator: crystal/resonator is on RA6 and RA7 case 2: // HS oscillator: crystal/resonator is on RA6 and RA7 (m_porta->getPin(6))->newGUIname("OSC2"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 3: // EC: RA6 is an I/O, RA7 is a CLKIN case 6: // ER oscillator: RA6 is an I/O, RA7 is a CLKIN (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("CLKIN"); valid_pins = (valid_pins & 0x7f)|0x40; break; case 4: // INTRC: Internal Oscillator, RA6 and RA7 are I/O's set_int_osc(true); (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins |= 0xc0; break; case 5: // INTRC: Internal Oscillator, RA7 is an I/O, RA6 is CLKOUT set_int_osc(true); (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins = (valid_pins & 0xbf)|0x80; break; case 7: // ER oscillator: RA6 is CLKOUT, resistor (?) on RA7 (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("OSC1"); break; } // If the /MCLRE bit is set then RA5 is the MCLR pin, otherwise it's // a general purpose I/O pin. if ((cfg_word & CFG_MCLRE)) { assignMCLRPin(4); } else { unassignMCLRPin(); } if (cfg_word & CFG_CCPMX) ccp1con.setIOpin(&((*m_portb)[0])); else ccp1con.setIOpin(&((*m_portb)[3])); if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_porta->setTris(m_trisa); } return true; } else if (address == 0x2008 ) { cout << "p16f8x 0x" << hex << address << " config word 0x" << cfg_word << '\n'; if (osccon) osccon->set_config_ieso(cfg_word & CFG2_IESO); return true; } return false; } //======================================================================== void P16F8x::create_config_memory() { m_configMemory = new ConfigMemory(this,2); m_configMemory->addConfigWord(0,new Config1(this)); m_configMemory->addConfigWord(1,new ConfigWord("CONFIG2", 0,"Configuration Word",this,0x2008)); wdt.initialize(true); // default WDT enabled wdt.set_timeout(0.000035); set_config_word(0x2007, 0x3fff); } //======================================================================== void P16F8x::create(int eesize) { set_hasSSP(); create_iopin_map(); _14bit_processor::create(); osccon = new OSCCON_1(this, "osccon", "OSC Control"); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eesize); e->set_intcon(&intcon_reg); set_eeprom_wide(e); P16X6X_processor::create_sfr_map(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F8x::create_sfr_map(); } void P16F8x::enter_sleep() { tmr1l.sleep(); osccon->sleep(); _14bit_processor::enter_sleep(); } void P16F8x::exit_sleep() { if (m_ActivityState == ePASleeping) { tmr1l.wake(); osccon->wake(); _14bit_processor::exit_sleep(); } } //======================================================================== P16F81x::P16F81x(const char *_name, const char *desc) : P16X6X_processor(_name,desc), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low"), osccon(0), osctune(this, "osctune", "OSC Tune") { pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir2_2_reg = new PIR2v2(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); delete pir1; delete pir2; pir1 = pir1_2_reg; pir2 = pir2_2_reg; } P16F81x::~P16F81x() { remove_sfr_register(osccon); remove_sfr_register(&osctune); remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(&pie2); delete get_eeprom(); } void P16F81x::create_iopin_map() { package = new Package(18); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 3, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(15, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(16, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin(5, 0); // Vss package->assign_pin( 6, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin( 7, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(14, 0); // Vdd if (hasSSP()) { ssp.initialize( get_pir_set(), // PIR &(*m_portb)[4], // SCK &(*m_portb)[5], // SS &(*m_portb)[2], // SDO &(*m_portb)[1], // SDI m_trisb, // i2c tris port SSP_TYPE_SSP ); } } void P16F81x::create_sfr_map() { pir_set_2_def.set_pir1(pir1); pir_set_2_def.set_pir2(pir2); //add_file_registers(0xa0, 0xef, 0); //add_file_registers(0xc0, 0xef, 0); //add_file_registers(0x110,0x16f,0); //add_file_registers(0x190,0x1ef,0); add_sfr_register(get_pir2(), 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); pir_set_def.set_pir2(pir2); pie2.setPir(get_pir2()); alias_file_registers(0x00,0x04,0x100); alias_file_registers(0x80,0x84,0x100); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x86,0x86,0x100); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); //alias_file_registers(0x0a,0x0b,0x080); //Already done alias_file_registers(0x0a,0x0b,0x100); alias_file_registers(0x0a,0x0b,0x180); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); add_sfr_register(osccon, 0x8f, RegisterValue(0,0),"osccon"); add_sfr_register(&osctune, 0x90, RegisterValue(0,0),"osctune"); osccon->set_osctune(&osctune); osccon->write_mask = 0x70; osctune.set_osccon(osccon); add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(7); adcon1.setNumberOfChannels(5); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[4]); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setChannelConfiguration(8, 0x1f); adcon1.setChannelConfiguration(9, 0x1f); adcon1.setChannelConfiguration(10, 0x1f); adcon1.setChannelConfiguration(11, 0x1f); adcon1.setChannelConfiguration(12, 0x1f); adcon1.setChannelConfiguration(13, 0x0f); adcon1.setChannelConfiguration(14, 0x01); adcon1.setChannelConfiguration(15, 0x0d); // set a2d modes where an3 is Vref+ adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon1.setVrefHiConfiguration(8, 3); adcon1.setVrefHiConfiguration(10, 3); adcon1.setVrefHiConfiguration(11, 3); adcon1.setVrefHiConfiguration(12, 3); adcon1.setVrefHiConfiguration(13, 3); adcon1.setVrefHiConfiguration(15, 3); // set a2d modes where an2 is Vref- adcon1.setVrefLoConfiguration(8, 2); adcon1.setVrefLoConfiguration(11, 2); adcon1.setVrefLoConfiguration(12, 2); adcon1.setVrefLoConfiguration(13, 2); adcon1.setVrefLoConfiguration(15, 2); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3 , 0); } void P16F81x::create_symbols() { if(verbose) cout << "81x create symbols\n"; Pic14Bit::create_symbols(); } void P16F81x::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } //======================================================================== bool P16F81x::set_config_word(unsigned int address, unsigned int cfg_word) { enum { CFG_FOSC0 = 1<<0, CFG_FOSC1 = 1<<1, CFG_FOSC2 = 1<<4, CFG_MCLRE = 1<<5, CFG_CCPMX = 1<<12 }; // Let the base class do most of the work: if (pic_processor::set_config_word(address, cfg_word)) { // if (verbose) cout << "p16f81x 0x" << hex << address << " setting config word 0x" << cfg_word << '\n'; unsigned int valid_pins = m_porta->getEnableMask(); set_int_osc(false); // Careful these bits not adjacent switch(cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2)) { case 0: // LP oscillator: low power crystal is on RA6 and RA7 case 1: // XT oscillator: crystal/resonator is on RA6 and RA7 case 2: // HS oscillator: crystal/resonator is on RA6 and RA7 (m_porta->getPin(6))->newGUIname("OSC2"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 0x13: // ER oscillator: RA6 is CLKOUT, resistor (?) on RA7 (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("OSC1"); break; case 3: // EC: RA6 is an I/O, RA7 is a CLKIN case 0x12: // ER oscillator: RA6 is an I/O, RA7 is a CLKIN (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("CLKIN"); valid_pins = (valid_pins & 0x7f)|0x40; break; case 0x10: // INTRC: Internal Oscillator, RA6 and RA7 are I/O's set_int_osc(true); (m_porta->getPin(6))->newGUIname("porta6"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins |= 0xc0; break; case 0x11: // INTRC: Internal Oscillator, RA7 is an I/O, RA6 is CLKOUT set_int_osc(true); (m_porta->getPin(6))->newGUIname("CLKOUT"); (m_porta->getPin(7))->newGUIname("porta7"); valid_pins = (valid_pins & 0xbf)|0x80; break; } // If the /MCLRE bit is set then RA5 is the MCLR pin, otherwise it's // a general purpose I/O pin. if ((cfg_word & CFG_MCLRE)) { assignMCLRPin(4); } else { unassignMCLRPin(); } if (cfg_word & CFG_CCPMX) { ccp1con.setIOpin(&((*m_portb)[2])); } else { ccp1con.setIOpin(&((*m_portb)[3])); } if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO { m_porta->setEnableMask(valid_pins); m_porta->setTris(m_trisa); } return true; } return false; } //======================================================================== void P16F81x::create_config_memory() { m_configMemory = new ConfigMemory(this,2); m_configMemory->addConfigWord(0,new Config1(this)); m_configMemory->addConfigWord(1,new ConfigWord("CONFIG2", 0,"Configuration Word",this,0x2008)); wdt.initialize(true); // default WDT enabled wdt.set_timeout(0.000035); set_config_word(0x2007, 0x3fff); } //======================================================================== void P16F81x::create(int eesize) { set_hasSSP(); create_iopin_map(); _14bit_processor::create(); osccon = new OSCCON_1(this, "osccon", "OSC Control"); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eesize); e->set_intcon(&intcon_reg); set_eeprom_wide(e); P16X6X_processor::create_sfr_map(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F81x::create_sfr_map(); } //======================================================================== // // Pic 16F87 // Processor * P16F87::construct(const char *name) { P16F87 *p = new P16F87(name); p->P16F8x::create(256); p->P16F87::create_sfr_map(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F87::P16F87(const char *_name, const char *desc) : P16F8x(_name,desc) { if(verbose) cout << "f87 constructor, type = " << isa() << '\n'; m_porta->setEnableMask(0xff); // trisa5 is an input only pin m_trisa->setEnableMask(0xdf); } void P16F87::create_sfr_map() { } //======================================================================== // // Pic 16F88 // Processor * P16F88::construct(const char *name) { P16F88 *p = new P16F88(name); p->P16F88::create(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F88::P16F88(const char *_name, const char *desc) : P16F87(_name,desc), ansel(this,"ansel", "Analog Select"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adresh(this,"adresh", "A2D Result High"), adresl(this,"adresl", "A2D Result Low") { if(verbose) cout << "f88 constructor, type = " << isa() << '\n'; } P16F88::~P16F88() { remove_sfr_register(&adresl); remove_sfr_register(&adresh); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&ansel); } void P16F88::create() { P16F8x::create(256); P16F88::create_sfr_map(); } void P16F88::create_sfr_map() { add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); add_sfr_register(&adresh, 0x1e, RegisterValue(0,0)); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&ansel, 0x9b, RegisterValue(0x7f,0)); ansel.setAdcon1(&adcon1); adcon0.setAdresLow(&adresl); adcon0.setAdres(&adresh); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(10); adcon0.setPir(pir1); adcon0.setChannel_Mask(7); adcon1.setNumberOfChannels(7); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[4]); adcon1.setIOPin(5, &(*m_portb)[6]); adcon1.setIOPin(6, &(*m_portb)[7]); adcon1.setVrefHiConfiguration(2, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefLoConfiguration(1, 2); adcon1.setVrefLoConfiguration(3, 2); /* Channel Configuration done dynamiclly based on ansel */ adcon1.setValidCfgBits(ADCON1::VCFG0 | ADCON1::VCFG1 , 4); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } //======================================================================== // // Pic 16F818 // Processor * P16F818::construct(const char *name) { P16F818 *p = new P16F818(name); p->P16F818::create(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F818::P16F818(const char *_name, const char *desc) : P16F81x(_name,desc) { if(verbose) cout << "f818 constructor, type = " << isa() << '\n'; } void P16F818::create() { P16F81x::create(128); P16F818::create_sfr_map(); } void P16F818::create_sfr_map() { alias_file_registers(0x40,0x7f,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0x20,0x7f,0x180); } //======================================================================== // // Pic 16F819 // Processor * P16F819::construct(const char *name) { P16F819 *p = new P16F819(name); p->P16F819::create(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F819::P16F819(const char *_name, const char *desc) : P16F81x(_name,desc) { if(verbose) cout << "f819 constructor, type = " << isa() << '\n'; } P16F819::~P16F819() { delete_file_registers(0xc0,0xef); delete_file_registers(0x120,0x16f); } void P16F819::create() { P16F81x::create(256); P16F819::create_sfr_map(); } void P16F819::create_sfr_map() { add_file_registers(0xc0,0xef, 0); add_file_registers(0x120,0x16f, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x20,0x7f,0x180); } gpsim-0.30.0/src/packages.h0000664000076400007640000000635613063451152012374 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* pic-packages.h Here's where all of the pic packages are defined */ #ifndef __PACKAGES_H__ #define __PACKAGES_H__ #include using namespace std; #include "gpsim_classes.h" class IOPIN; // forward reference enum PACKAGE_TYPE { _NO_PACKAGE_, DIP_8PIN, DIP_14PIN, DIP_18PIN, DIP_28PIN, DIP_40PIN }; enum PACKAGE_PIN_ERRORS { E_NO_PIN, E_NO_PACKAGE, E_PIN_OUT_OF_RANGE, E_PIN_EXISTS }; // The PinGeometry holds information the gui can query to build // a graphical representation of the pin. struct PinGeometry { PinGeometry() : pin_position(0.0), bNew(false), m_x(0.0), m_y(0.0), m_orientation(0), m_bShowPinname(false) {} void convertToNew(); // transition from old to new style float pin_position; // Newer style bool bNew; float m_x; float m_y; int m_orientation; bool m_bShowPinname; }; class Package { public: unsigned int number_of_pins; Package(); explicit Package(unsigned int number_of_pins); virtual ~Package(); void assign_pin(unsigned int pin_number, IOPIN *pin, bool warn=true); void destroy_pin(unsigned int pin_number, IOPIN *pin=0); void create_pkg(unsigned int _number_of_pins); unsigned int isa(void){return _NO_PACKAGE_;}; virtual void create_iopin_map(void); virtual int get_pin_count(void) {return number_of_pins;}; virtual string &get_pin_name(unsigned int pin_number); virtual int get_pin_state(unsigned int pin_number); virtual float get_pin_position(unsigned int pin_number); virtual void set_pin_position(unsigned int pin_number, float position); int pin_existance(unsigned int pin_number); IOPIN *get_pin(unsigned int pin_number); void setPinGeometry(unsigned int pin_number, float x, float y, int orientation, bool bShowName); PinGeometry *getPinGeometry(unsigned int pin_number); // Debug void showPins(); protected: inline bool bIsValidPinNumber(unsigned int pin_number) { return (pin_number > 0) && (pin_number<=number_of_pins); } IOPIN **pins; /* An array containing all of the package's pins. The index * into the array is the package's pin #. If pins[i] is NULL * then there's gpsim does not provide any resources for * simulating the pin. */ // pin_position is used by the breadboard to position the pin // Its value can be in the range from 0.0000 to 3.9999. // 0.0 is upmost left position. 0.9999 is lowest left. // 1.0 is leftmost bottom position. 1.99 is rightmost bottom.. A.S.O // float *pin_position; PinGeometry *m_pinGeometry; }; #endif // __PACKAGES_H__ gpsim-0.30.0/src/ioports.h0000664000076400007640000003321313063451152012305 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __IOPORTS_H__ #define __IOPORTS_H__ #include "registers.h" #include "stimuli.h" class stimulus; class Stimulus_Node; class PinModule; ///**********************************************************************/ /// /// I/O ports /// /// An I/O port is collection of I/O pins. For a PIC processor, these /// are the PORTA, PORTB, etc, registers. gpsim models I/O ports in /// a similar way it models other registers; there's a base class from /// which all specific I/O ports are derived. However, I/O ports are /// special in that they're an interface between a processor's core /// and the outside world. The requirements vary wildly from one processor /// to the next; in fact they even vary dynamically within one processor. /// gpsim attempts to abstract this interface with a set of base classes /// that are responsible for routing signal state information. These /// base classes make no attempt to decipher this information, instead /// this job is left to the peripherals and stimuli connected to the /// I/O pins and ports. /// /// /// PinModule /// /// Here's a general description of gpsim I/O pin design: /// /// Data /// Select ======+ /// +-|-+ Outgoing /// Source1 ===>| M | data /// Source2 ===>| U |=============+ /// SourceN ===>| X | | /// +---+ | +-------+ /// Control +===>| IOPIN | /// Select ======+ | | /// +-|-+ I/O Pin | | /// Control1 ===>| M | Direction | |<======> Physical /// Control2 ===>| U |=================>| | Interface /// ControlN ===>| X | | | /// +---+ | | /// Sink Decode +===<| | /// Select ======+ | +-------+ /// +-|-+ Incoming | /// Sink1 <====| D | data | /// Sink2 <====| E |<============| /// SinkN <====| C | /// +---+ /// /// The PinModule models a Processor's I/O Pin. The schematic illustrates /// the abstract description of the PinModule. Its job is to merge together /// all of the Processor's peripherals that can control a processor's pin. /// For example, a UART peripheral may be shared with a general purpose I/O /// pin. The UART may have a transmit and receive pin and select whether it's /// in control of the I/O pins. The uart transmit pin and the port's I/O pin /// can both act as a source for the physical interface. The PinModule /// arbitrates between the two. Similarly, the UART receive pin can be multiplexed /// with a register pin. In this case, the PinModule will route signal /// changes to both devices. Finally, a peripheral like the '622's comparators /// may overide the output control. The PinModule again arbitrates. /// /// /// PortModule /// /// The PortModule is the base class for processor I/O ports. It's essentially /// a register that contains an array of PinModule's. /// /// Register PortModule /// |-> sfr_register | /// | | /// \------+--------/ /// | /// +--> PortRegister /// |--> PicPortRegister ///------------------------------------------------------------ /// /// SignalControl - A pure virtual class that defines the interface for /// a signal control. The I/O Pin Modules will query the source's state /// via SignalControl. The control is usually used to control the I/O pin /// direction (i.e. whether it's an input or output...), drive value, /// pullup state, etc. /// When a Pin Module is through with the SignalControl, it will call /// the release() method. This is primarily used to delete the SignalControl /// objects. class SignalControl { public: virtual ~SignalControl(); //// fixme virtual char getState()=0; virtual void release()=0; }; ///------------------------------------------------------------ /// PeripheralSignalSource - A class to interface I/O pins with /// peripheral outputs. class PeripheralSignalSource : public SignalControl { public: explicit PeripheralSignalSource(PinModule *_pin); virtual ~PeripheralSignalSource(); virtual void release(); /// getState - called by the PinModule to determine the source state virtual char getState(); /// putState - called by the peripheral to set a new state virtual void putState(const char new3State); /// toggle - called by the peripheral to toggle the current state. virtual void toggle(); private: PinModule *m_pin; char m_cState; }; ///------------------------------------------------------------ /// PortModule - Manages all of the I/O pins associated with a single /// port. The PortModule supplies the interface to the I/O pin's. It /// is designed to handle a group of I/O pins. However, the low level /// I/O pin processing is handled by PinModule objects contained within /// the PortModule. class PortModule { public: explicit PortModule(unsigned int numIopins); virtual ~PortModule(); /// updatePort -- loop through update all I/O pins virtual void updatePort(); /// updatePin -- Update a single I/O pin virtual void updatePin(unsigned int iPinNumber); /// updatePins -- Update several I/O pins virtual void updatePins(unsigned int iPinBitMask); /// updateUI -- convey pin state info to a User Interface (e.g. the gui). virtual void updateUI(); /// addPinModule -- supply a pin module at a particular bit position. /// Most of the low level I/O pin related processing will be handled /// here. The PortModule per-pin helper methods below essentially /// call methods in the PinModule to do the dirty work. /// Each bit position can have only one PinModule. If multiple /// modules are added, only the first will be used and the others /// will be ignored. void addPinModule(PinModule *, unsigned int iPinNumber); /// addSource -- supply a pin with a source of data. There may SignalControl *addSource(SignalControl *, unsigned int iPinNumber); /// addControl -- supply a pin with a data direction control SignalControl *addControl(SignalControl *, unsigned int iPinNumber); /// addPullupControl -- supply a pin with a pullup control SignalControl *addPullupControl(SignalControl *, unsigned int iPinNumber); /// addSink -- supply a sink to receive info driven on to a pin SignalSink *addSink(SignalSink *, unsigned int iPinNumber); /// addPin -- supply an I/O pin. Note, this will create a default pin module /// if one is not already created. IOPIN *addPin(IOPIN *, unsigned int iPinNumber); /// getPin -- an I/O pin accessor. This returns the I/O pin at a particular /// bit position. IOPIN *getPin(unsigned int iPinNumber); /// operator[] -- PinModule accessor. This returns the pin module at /// a particular bit position. PinModule &operator [] (unsigned int pin_number); PinModule * getIOpins(unsigned int pin_number); // set/get OutputMask which controls bits returned on I/O // port register get() call. Used to return 0 for analog pins virtual void setOutputMask (unsigned int OutputMask) { mOutputMask = OutputMask;} virtual unsigned int getOutputMask () { return(mOutputMask);} protected: unsigned int mNumIopins; unsigned int mOutputMask; private: /// PinModule -- The array of PinModules that are handled by PortModule. PinModule **iopins; }; ///------------------------------------------------------------ /// PinModule - manages the interface to a physical I/O pin. Both /// simple and complex I/O pins are handled. An example of a simple /// I/O is one where there is a single data source, data sink and /// control, like say the GPIO pin on a small PIC. A complex pin /// is one that is multiplexed with peripherals. /// /// The parent class 'PinMonitor', allows the PinModule to be /// registered with the I/O pin. In other words, when the I/O pin /// changes state, the PinModule will be notified. #define ANALOG_TABLE_SIZE 3 class PinModule : public PinMonitor { public: PinModule(); PinModule(PortModule *, unsigned int _pinNumber, IOPIN *new_pin=0); virtual ~PinModule(); /// updatePinModule -- The low level I/O pin state is resolved here /// by examining the direction and state of the I/O pin. void updatePinModule(); /// refreshPinOnUpdate - modal behavior. If set to true, then /// a pin's state will always be refreshed whenever the PinModule /// is updated. If false, then the pin is updated only if there /// is a detected state change. void refreshPinOnUpdate(bool bForcedUpdate); void setPin(IOPIN *); void clrPin() { m_pin = NULL; } void setDefaultSource(SignalControl *); void setSource(SignalControl *); void setDefaultControl(SignalControl *); void setControl(SignalControl *); void setPullupControl(SignalControl *); void setDefaultPullupControl(SignalControl *); char getControlState(); char getSourceState(); char getPullupControlState(); unsigned int getPinNumber() { return m_pinNumber;} void AnalogReq(Register *reg, bool analog, const char *newName); // If active control not default, return it SignalControl *getActiveControl() {return (m_activeControl == m_defaultControl)?0:m_activeControl;} // If active source not default, return it SignalControl *getActiveSource() {return (m_activeSource == m_defaultSource)?0:m_activeSource;} IOPIN &getPin() { return *m_pin;} /// virtual void setDrivenState(char); virtual void setDrivingState(char); virtual void set_nodeVoltage(double); virtual void putState(char); virtual void setDirection(); virtual void updateUI(); private: char m_cLastControlState; char m_cLastSinkState; char m_cLastSourceState; char m_cLastPullupControlState; SignalControl *m_defaultSource, *m_activeSource; SignalControl *m_defaultControl, *m_activeControl; SignalControl *m_defaultPullupControl, *m_activePullupControl; IOPIN *m_pin; PortModule *m_port; unsigned int m_pinNumber; bool m_bForcedUpdate; Register *m_analog_reg[ANALOG_TABLE_SIZE + 1]; bool m_analog_active[ANALOG_TABLE_SIZE + 1]; }; ///------------------------------------------------------------ class PortRegister : public sfr_register, public PortModule { public: PortRegister(Module *pCpu, const char *pName, const char *pDesc, unsigned int numIopins, unsigned int enableMask); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); virtual void putDrive(unsigned int new_drivingValue); virtual unsigned int getDriving(); virtual void setbit(unsigned int bit_number, char new_value); virtual void setEnableMask(unsigned int nEnableMask); IOPIN *addPin(IOPIN *, unsigned int iPinNumber); IOPIN *addPin(Module *mod, IOPIN *pin, unsigned int iPinNumber); unsigned int getEnableMask() { return mEnableMask; } virtual void updateUI(); protected: unsigned int mEnableMask; unsigned int drivingValue; RegisterValue rvDrivenValue; }; class PortSink : public SignalSink { public: PortSink(PortRegister *portReg, unsigned int iobit); virtual ~PortSink() { } virtual void setSinkState(char); virtual void release(); private: PortRegister *m_PortRegister; unsigned int m_iobit; }; /// IOPORT - Base class for I/O ports - deprecated #if defined(OLD_IOPORT_DESIGN) class IOPORT : public sfr_register { public: explicit IOPORT(unsigned int _num_iopins = 8); ~IOPORT(); IOPIN *addPin(IOPIN *, unsigned int iPinNumber); IOPIN *getIO(unsigned int pin_number); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); // setbit() is called when a stimulus writes a value to one // of the I/O pins in this Port. virtual void setbit(unsigned int bit_number, bool new_value); virtual bool get_bit(unsigned int bit_number); virtual unsigned int get(void); virtual unsigned int get_value(void); virtual void trace_register_write(void); protected: /// The I/O pins associated with this I/O port. /// This could be anything (or nothing.) IOPIN **pins; unsigned int valid_iopins, // A mask that for those ports that don't have all 8 io bits. stimulus_mask, // A mask indicating which io bits have a stimulus. internal_latch, // num_iopins; // Number of I/O pins attached to this port // Deprecated functions of the IOPORT class /// Stimuli void attach_stimulus(stimulus *new_stim, unsigned int bit_position); virtual int update_stimuli(void); void attach_iopin(IOPIN * new_pin, unsigned int bit_position); void attach_node(Stimulus_Node *new_node, unsigned int bit_position); virtual double get_bit_voltage(unsigned int bit_number); virtual void change_pin_direction(unsigned int bit_number, bool new_direction); }; #endif // OLD_IOPORT_DESIGN #endif // __IOPORTS_H__ gpsim-0.30.0/src/a2dconverter.cc0000664000076400007640000010043013113664271013342 00000000000000/* Copyright (C) 2006 T. Scott Dattalo Copyright (C) 2009, 2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "ioports.h" #include "trace.h" #include "gpsim_time.h" #include "ui.h" #include "pic-processor.h" #include "a2dconverter.h" #include "14bit-processors.h" #define p_cpu ((Processor *)cpu) static PinModule AnInvalidAnalogInput; //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------ // ADRES // /* void ADRES::put(int new_value) { trace.raw(write_trace.get() | value.get()); if(new_value > 255) value.put(255); else if (new_value < 0) value.put(0); else value.put(new_value); } */ //------------------------------------------------------ // ADCON0 // ADCON0::ADCON0(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), adres(0), adresl(0), adcon1(0), intcon(0), m_pPir(0), ad_state(AD_IDLE), channel_mask(7), channel_shift(3), GO_bit(GO) { } /* * Link PIC register for High Byte A/D result */ void ADCON0::setAdres(sfr_register *new_adres) { adres = new_adres; } /* * Link PIC register for Low Byte A/D result */ void ADCON0::setAdresLow(sfr_register *new_adresl) { adresl = new_adresl; } /* * Link PIC register for ADCON1 */ void ADCON0::setAdcon1(ADCON1 *new_adcon1) { adcon1 = new_adcon1; } /* * Link PIC register for INTCON */ void ADCON0::setIntcon(INTCON *new_intcon) { intcon = new_intcon; } /* * Link PIC register for PIR * If set ADIF in PIR otherwise ADIF in ADCON0 */ void ADCON0::setPir(PIR *pPir) { m_pPir = pPir; } /* * Set resolution of A2D converter */ void ADCON0::setA2DBits(unsigned int nBits) { m_A2DScale = (1<get_ClockCycles_per_Instruction(); Dprintf(("ad_state %u fc %" PRINTF_GINT64_MODIFIER "x now %" PRINTF_GINT64_MODIFIER "x\n", ad_state, fc, get_cycles().get())) if(ad_state != AD_IDLE) { // The A/D converter is either 'converting' or 'acquiring' // in either case, there is callback break that needs to be moved. stop_conversion(); get_cycles().reassign_break(future_cycle, fc, this); } else get_cycles().set_break(fc, this); future_cycle = fc; ad_state = AD_ACQUIRING; } void ADCON0::stop_conversion(void) { Dprintf(("stopping A/D conversion\n")); ad_state = AD_IDLE; } void ADCON0::set_Tad(unsigned int new_value) { // Get the A/D Conversion Clock Select bits // // This switch case will get the ADCS bits and set the Tad, or The A/D // converter clock period. Tad is the number of the oscillator periods // rather instruction cycle periods. ADCS2 only exists on some processors, // but should be 0 where it is not used. switch(new_value & (ADCS0 | ADCS1)) { case 0: Tad = (adcon1->value.get() & ADCON1::ADCS2) ? 4 : 2; break; case ADCS0: Tad = (adcon1->value.get() & ADCON1::ADCS2) ? 16 : 8; break; case ADCS1: Tad = (adcon1->value.get() & ADCON1::ADCS2) ? 64 : 32; break; case (ADCS0|ADCS1): // typical 4 usec, convert to osc cycles if (cpu) { Tad = (unsigned int)(4.e-6 * p_cpu->get_frequency()); Tad = Tad < 2? 2 : Tad; } else Tad = 6; break; } } void ADCON0::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); set_Tad(new_value); unsigned int old_value=value.get(); // SET: Reflect it first! value.put(new_value); if(new_value & ADON) { // The A/D converter is being turned on (or maybe left on) if((new_value & ~old_value) & GO_bit) { if (verbose) printf("starting A2D conversion\n"); Dprintf(("starting A2D conversion\n")); // The 'GO' bit is being turned on, which is request to initiate // and A/D conversion start_conversion(); } } else stop_conversion(); } void ADCON0::put_conversion(void) { double dRefSep = m_dSampledVrefHi - m_dSampledVrefLo; double dNormalizedVoltage; dNormalizedVoltage = (dRefSep>0.0) ? (m_dSampledVoltage - m_dSampledVrefLo)/dRefSep : 0.0; dNormalizedVoltage = dNormalizedVoltage>1.0 ? 1.0 : dNormalizedVoltage; unsigned int converted = (unsigned int)(m_A2DScale*dNormalizedVoltage + 0.5); Dprintf(("put_conversion: Vrefhi:%.4f Vreflo:%.4f conversion:%u normV:%f\n", m_dSampledVrefHi,m_dSampledVrefLo,converted,dNormalizedVoltage)); if (verbose) printf ("result=0x%02x\n", converted); Dprintf(("%u-bit result 0x%x ADFM %d\n", m_nBits, converted, get_ADFM())); if(adresl) { // non-null for more than 8 bit conversion if(get_ADFM()) { adresl->put(converted & 0xff); adres->put( (converted >> 8) & 0x3); } else { adresl->put((converted << 6) & 0xc0); adres->put( (converted >> 2) & 0xff); } } else { adres->put((converted ) & 0xff); } } // ADCON0 callback is called when the cycle counter hits the break point that // was set in ADCON0::put. void ADCON0::callback(void) { int channel; Dprintf((" ADCON0 Callback: 0x%" PRINTF_GINT64_MODIFIER "x\n",get_cycles().get())); // // The a/d converter is simulated with a state machine. // switch(ad_state) { case AD_IDLE: Dprintf(("ignoring ad callback since ad_state is idle\n")); break; case AD_ACQUIRING: channel = (value.get() >> channel_shift) & channel_mask; m_dSampledVoltage = getChannelVoltage(channel); m_dSampledVrefHi = getVrefHi(); m_dSampledVrefLo = getVrefLo(); Dprintf(("Acquiring channel:%d V=%g reflo=%g refhi=%g\n", channel,m_dSampledVoltage,m_dSampledVrefLo,m_dSampledVrefHi)); future_cycle = get_cycles().get() + (m_nBits * Tad)/p_cpu->get_ClockCycles_per_Instruction(); get_cycles().set_break(future_cycle, this); if (verbose) printf("A/D %u bits channel:%d Vin=%.4f Refhi=%.4f Reflo=%.4f ", m_nBits, channel,m_dSampledVoltage,m_dSampledVrefHi,m_dSampledVrefLo); ad_state = AD_CONVERTING; break; case AD_CONVERTING: put_conversion(); // Clear the GO/!DONE flag. value.put(value.get() & (~GO_bit)); set_interrupt(); ad_state = AD_IDLE; } } //------------------------------------------------------ // If the ADIF bit is in the PIR1 register, call setPir() // in the ADC setup. Otherwise, ADIF is assumed to be in // the ADCON0 register // // Chips like 10f220 do not have interupt and intcon is not defined. // Thus no interrupt needs be generated // void ADCON0::set_interrupt(void) { if (m_pPir) m_pPir->set_adif(); else if (intcon) { value.put(value.get() | ADIF); intcon->peripheral_interrupt(); } } double ADCON0_91X::getVrefHi() { if (value.get() & VCFG0) return getChannelVoltage(Vrefhi_position); else return ((Processor *)cpu)->get_Vdd(); } double ADCON0_91X::getVrefLo() { if (value.get() & VCFG1) return getChannelVoltage(Vreflo_position); else return 0.; } //------------------------------------------------------ // ADCON0 // ADCON0_DIF::ADCON0_DIF(Processor *pCpu, const char *pName, const char *pDesc) : ADCON0(pCpu, pName, pDesc) { } void ADCON0_DIF::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); if (new_value & ADRMD) // 10 Bit setA2DBits(10); else setA2DBits(12); set_Tad(new_value); unsigned int old_value=value.get(); // SET: Reflect it first! value.put(new_value); if(new_value & ADON) { // The A/D converter is being turned on (or maybe left on) if((new_value & ~old_value) & GO_bit) { if (verbose) printf("starting A2D conversion\n"); Dprintf(("starting A2D conversion\n")); // The 'GO' bit is being turned on, which is request to initiate // and A/D conversion start_conversion(); } } else stop_conversion(); } void ADCON0_DIF::put_conversion(void) { int channel = adcon2->value.get() & 0x0f; double dRefSep = m_dSampledVrefHi - m_dSampledVrefLo; double dNormalizedVoltage; double m_dSampledVLo; if (channel == 0x0e) // shift AN21 to adcon0 channel channel = 0x15; if (channel == 0x0f) // use ADNREF for V- m_dSampledVLo = getVrefLo(); else m_dSampledVLo = getChannelVoltage(channel); dNormalizedVoltage = (m_dSampledVoltage - m_dSampledVLo)/dRefSep; dNormalizedVoltage = dNormalizedVoltage>1.0 ? 1.0 : dNormalizedVoltage; int converted = (int)(m_A2DScale*dNormalizedVoltage + 0.5); Dprintf(("put_conversion: V+:%g V-:%g Vrefhi:%g Vreflo:%g conversion:%d normV:%g\n", m_dSampledVoltage, m_dSampledVLo, m_dSampledVrefHi,m_dSampledVrefLo,converted,dNormalizedVoltage)); if (verbose) printf ("result=0x%02x\n", converted); Dprintf(("%u-bit result 0x%x ADFM %d\n", m_nBits, converted, get_ADFM())); if(!get_ADFM()) { // signed int sign = 0; if (converted < 0) { sign = 1; converted = -converted; } converted = ((converted << (16-m_nBits)) % 0xffff) | sign; } adresl->put(converted & 0xff); adres->put((converted >> 8) & 0xff); } ADCON1_16F::ADCON1_16F(Processor *pCpu, const char *pName, const char *pDesc) : ADCON1(pCpu, pName, pDesc), FVR_chan(99) { valid_bits = 0x70; } void ADCON1_16F::put_value(unsigned int new_value) { unsigned int masked_value = new_value & valid_bits; unsigned int Tad = 6; setADCnames(); switch(masked_value & (ADCS0 | ADCS1)) { case 0: Tad = (new_value & ADCS2) ? 4 : 2; break; case ADCS0: Tad = (new_value & ADCS2) ? 16 : 8; break; case ADCS1: Tad = (new_value & ADCS2) ? 64 : 32; break; case (ADCS0|ADCS1): // typical 4 usec, convert to osc cycles if (cpu) { Tad = (unsigned int)(4.e-6 * p_cpu->get_frequency()); Tad = Tad < 2? 2 : Tad; } else Tad = 6; break; } adcon0->set_Tad(Tad); if (ADFM & valid_bits) adfm = ADFM & masked_value; //RRR FIXME handle ADPREF value.put(new_value & valid_bits); } double ADCON1_16F::getVrefLo() { if (ADNREF & value.get()) { if (Vreflo_position[cfg_index] < m_nAnalogChannels) return getChannelVoltage(Vreflo_position[cfg_index]); cerr << "WARNING Vreflo pin not configured\n"; return -1.; } return 0.; //Vss } double ADCON1_16F::getVrefHi() { if (ADPREF0 & valid_bits) { unsigned int mode = value.get() & (ADPREF1 | ADPREF0); switch(mode) { case 0: return ((Processor *)cpu)->get_Vdd(); case 1: cerr << "WARNING reserved value for ADPREF\n"; return -1.; case 2: if (Vrefhi_position[cfg_index] < m_nAnalogChannels) return getChannelVoltage(Vrefhi_position[cfg_index]); cerr << "WARNING Vrefhi pin not configured\n"; return -1.; case 3: if (FVR_chan < m_nAnalogChannels) return getChannelVoltage(FVR_chan); cerr << "WARNING FVR_chan not set\n"; return -1.; }; } if (Vrefhi_position[cfg_index] < m_nAnalogChannels) return getChannelVoltage(Vrefhi_position[cfg_index]); return ((Processor *)cpu)->get_Vdd(); } //------------------------------------------------------ // ADCON1 // ADCON1::ADCON1(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), valid_bits(0xff), adfm(false), m_AnalogPins(0), m_voltageRef(0), m_nAnalogChannels(0), mValidCfgBits(0), mCfgBitShift(0), mIoMask(0), cfg_index(0), m_ad_in_ctl(0) { for (int i=0; i<(int)cMaxConfigurations; i++) { setChannelConfiguration(i, 0); setVrefLoConfiguration(i, 0xffff); setVrefHiConfiguration(i, 0xffff); } } ADCON1::~ADCON1() { if (m_voltageRef) delete [] m_voltageRef; if (m_AnalogPins) { if (m_ad_in_ctl) { for (unsigned int i = 0; i < m_nAnalogChannels; i++) m_AnalogPins[i]->setControl(0); delete m_ad_in_ctl; } delete [] m_AnalogPins; } } void ADCON1::put(unsigned int new_value) { unsigned int masked_value = new_value & valid_bits; trace.raw(write_trace.get() | value.get()); put_value(masked_value); } void ADCON1::put_value(unsigned int new_value) { unsigned int masked_value = new_value & valid_bits; cfg_index = get_cfg(masked_value); setADCnames(); adfm = masked_value & ADFM; value.put(masked_value); } // Obtain new mIoMask and set pin names as per function void ADCON1::setADCnames() { unsigned int new_mask = m_configuration_bits[cfg_index]; unsigned int diff = mIoMask ^ new_mask; Dprintf (( "ADCON1::setADCnames - cfg_index=%u new_mask %02X channels %u\n", cfg_index, new_mask, m_nAnalogChannels )); char newname[20]; for(unsigned int i = 0; i < m_nAnalogChannels; i++) { if ((diff & (1 << i)) && m_AnalogPins[i] != &AnInvalidAnalogInput) { if (new_mask & (1<AnalogReq(this, true, newname); } else m_AnalogPins[i]->AnalogReq(this, false, m_AnalogPins[i]->getPin().name().c_str()); } } mIoMask = new_mask; } /* * If A2D uses PCFG, call for each PCFG value (cfg 0 to 15) with * each set bit of bitMask indicating port is an analog port * (either A2D input port or Vref). Processors which use an A2D * method that uses ANSEL register will not call this. * * As an example, for the following Port Configuration Control bit: * PCFG AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 * ---- ---- ----- ----- ----- ----- ----- ----- ----- * 1100 D D D A Vref+ Vref- A A * * then call setChannelConfiguration with cfg = 12 , bitMask = 0x1f * */ void ADCON1::setChannelConfiguration(unsigned int cfg, unsigned int bitMask) { if (cfg < cMaxConfigurations) m_configuration_bits[cfg] = bitMask; } unsigned int ADCON1::getVrefLoChannel(unsigned int cfg) { if (cfg < cMaxConfigurations) return(Vreflo_position[cfg]); return(0xffff); } unsigned int ADCON1::getVrefHiChannel(unsigned int cfg) { Dprintf(("ADCON1::getVrefHiChannel cfg=%u %u\n", cfg, Vrefhi_position[cfg])); if (cfg < cMaxConfigurations) return(Vrefhi_position[cfg]); return(0xffff); } /* * Call for each configuration mode that uses an І/O pin as Vref- * to declare which port is being used for this. */ void ADCON1::setVrefLoConfiguration(unsigned int cfg, unsigned int channel) { if (cfg < cMaxConfigurations) Vreflo_position[cfg] = channel; } /* * Call for each configuration mode that uses an І/O pin as Vref+ * to declare which port is being used for this. */ void ADCON1::setVrefHiConfiguration(unsigned int cfg, unsigned int channel) { if (cfg < cMaxConfigurations) Vrefhi_position[cfg] = channel; } /* * Number of A2D channels processor supports */ void ADCON1::setNumberOfChannels(unsigned int nChannels) { PinModule **save = NULL; // save existing pins when nChannels increases if (!nChannels || nChannels <= m_nAnalogChannels) return; // do nothing if NChannels decreases if (m_nAnalogChannels && nChannels > m_nAnalogChannels ) save = m_AnalogPins; if (m_voltageRef) delete [] m_voltageRef; m_voltageRef = new float [nChannels]; m_AnalogPins = new PinModule *[nChannels]; for (unsigned int i=0; i> mCfgBitShift); } /* * Associate a processor I/O pin with an A2D channel */ void ADCON1::setIOPin(unsigned int channel, PinModule *newPin) { if (channel < m_nAnalogChannels && m_AnalogPins[channel] == &AnInvalidAnalogInput && newPin!=0) { m_AnalogPins[channel] = newPin; } else { printf("%s:%d WARNING invalid channel number config for ADCON1 %u num %u\n",__FILE__,__LINE__, channel, m_nAnalogChannels); } } void ADCON1::setVoltRef(unsigned int channel, float value) { if (channel < m_nAnalogChannels ) { m_voltageRef[channel] = value; } else { printf("ADCON1::%s invalid channel number %u\n", __FUNCTION__, channel); } } //------------------------------------------------------ double ADCON1::getChannelVoltage(unsigned int channel) { double voltage=0.0; if(channel < m_nAnalogChannels) { if ( (1<getPin().get_nodeVoltage(); } else { cerr << "ADCON1::getChannelVoltage channel " << channel << " not valid analog input\n"; cerr << "Please raise a Gpsim bug report\n"; } } else // use voltage reference { Dprintf(("ADCON1::getChannelVoltage channel=%u voltage %f\n", \ channel, m_voltageRef[channel])); voltage = m_voltageRef[channel]; if (voltage < 0.0) { cout << "ADCON1::getChannelVoltage channel " << channel << " not a configured input\n"; voltage = 0.0; } } } else { cerr << "ADCON1::getChannelVoltage channel " << channel << " >= " << m_nAnalogChannels << " (number of channels)\n"; cerr << "Please raise a Gpsim bug report\n"; } return voltage; } double ADCON1::getVrefHi() { if (Vrefhi_position[cfg_index] < m_nAnalogChannels) return getChannelVoltage(Vrefhi_position[cfg_index]); return ((Processor *)cpu)->get_Vdd(); } double ADCON1::getVrefLo() { if (Vreflo_position[cfg_index] < m_nAnalogChannels) return getChannelVoltage(Vreflo_position[cfg_index]); return 0.0; } // if on is true, set pin as input regardless of TRIS state // else restore TRIS control // void ADCON1::set_channel_in(unsigned int channel, bool on) { Dprintf(("channel=%u on=%d m_ad_in_ctl=%p\n", channel, on, m_ad_in_ctl)); if (on && (m_ad_in_ctl == NULL)) m_ad_in_ctl = new AD_IN_SignalControl(); if (on) m_AnalogPins[channel]->setControl(m_ad_in_ctl); else m_AnalogPins[channel]->setControl(0); m_AnalogPins[channel]->updatePinModule(); } ANSEL::ANSEL(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), adcon1(0), anselh(0), valid_bits(0x7f) { } void ANSEL::setAdcon1(ADCON1 *new_adcon1) { adcon1 = new_adcon1; } void ANSEL::put(unsigned int new_value) { unsigned int cfgmax = adcon1->getNumberOfChannels(); unsigned int i; unsigned int mask = (new_value & valid_bits); if (anselh) mask |= anselh->value.get() << 8; trace.raw(write_trace.get() | value.get()); /* Generate ChannelConfiguration from ansel register */ for(i=0; i < cfgmax; i++) { adcon1->setChannelConfiguration(i, mask); } value.put(new_value & valid_bits); adcon1->setADCnames(); } ANSEL_H::ANSEL_H(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), adcon1(0), ansel(0), valid_bits(0x3f) { } void ANSEL_H::setAdcon1(ADCON1 *new_adcon1) { adcon1 = new_adcon1; } void ANSEL_H::put(unsigned int new_value) { unsigned int cfgmax = adcon1->getNumberOfChannels(); unsigned int i; unsigned int mask = ((new_value & valid_bits) << 8) ; trace.raw(write_trace.get() | value.get()); if (ansel) mask |= ansel->value.get(); /* Generate ChannelConfiguration from ansel register */ for(i=0; i < cfgmax; i++) { adcon1->setChannelConfiguration(i, mask); } value.put(new_value & valid_bits); adcon1->setADCnames(); } ANSEL_P::ANSEL_P(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), adcon1(0), ansel(0), valid_bits(0x3f), cfg_mask(0) { } void ANSEL_P::setAdcon1(ADCON1 *new_adcon1) { adcon1 = new_adcon1; } void ANSEL_P::put(unsigned int new_value) { unsigned int cfgmax = adcon1->getMaxCfg(); unsigned int i; unsigned int mask; unsigned int chan = first_channel; trace.raw(write_trace.get() | value.get()); new_value &= valid_bits; value.put(new_value); cfg_mask = 0; for(i=0; i< 8; i++) { if ((1<get_mask(); } if (!adcon1) return; /* Generate ChannelConfiguration from ansel register */ for(i=0; i < cfgmax; i++) { adcon1->setChannelConfiguration(i, mask); } adcon1->setADCnames(); } //------------------------------------------------------ // ADCON0_10 // ADCON0_10::ADCON0_10(Processor *pCpu, const char *pName, const char *pDesc) : ADCON0(pCpu, pName, pDesc) { GO_bit = GO; //ADCON0 and ADCON0_10 have GO flag at different bit // It should take 13 CPU instructions to complete conversion // Tad of 6 completes in 15 Tad = 6; } void ADCON0_10::put(unsigned int new_value) { unsigned int old_value=value.get(); /* On first call of this function old_value has already been set to * it's default value, but we want to call set_channel_in. First * gives us a way to do this. */ static bool first = true; trace.raw(write_trace.get() | value.get()); Dprintf(("ADCON0_10::put new_value=0x%02x old_value=0x%02x\n", new_value, old_value)); if ((new_value ^ old_value) & ANS0 || first) adcon1->set_channel_in(0, (new_value & ANS0) == ANS0); if ((new_value ^ old_value) & ANS1 || first ) adcon1->set_channel_in(1, (new_value & ANS1) == ANS1); first = false; // If ADON is clear GO cannot be set if ((new_value & ADON) != ADON) new_value &= ~GO_bit; // SET: Reflect it first! value.put(new_value); if(new_value & ADON) { // The A/D converter is being turned on (or maybe left on) if((new_value & ~old_value) & GO_bit) { if (verbose) printf("starting A2D conversion\n"); // The 'GO' bit is being turned on, which is request to initiate // and A/D conversion start_conversion(); } } else stop_conversion(); } //------------------------------------------------------ // ADCON0_12F used in 12f675. Uses ADCON1 as virtual rather than physical // register // ADCON0_12F::ADCON0_12F(Processor *pCpu, const char *pName, const char *pDesc) : ADCON0(pCpu, pName, pDesc) { GO_bit = GO; //ADCON0 and ADCON0_10 have GO flag at different bit valid_bits = 0xdf; } void ADCON0_12F::put(unsigned int new_value) { unsigned int old_value=value.get(); new_value &= valid_bits; // clear unused bits /* On first call of this function old_value has already been set to * it's default value, but we want to call set_channel_in. First * gives us a way to do this. */ trace.raw(write_trace.get() | value.get()); Dprintf(("ADCON0_12F::put new_value=0x%02x old_value=0x%02x\n", new_value, old_value)); // tell adcon1 to use Vref adcon1->set_cfg_index((new_value & VCFG) ? 2: 0); // If ADON is clear GO cannot be set if ((new_value & ADON) != ADON) new_value &= ~GO_bit; // SET: Reflect it first! value.put(new_value); if(new_value & ADON) { // The A/D converter is being turned on (or maybe left on) if((new_value & ~old_value) & GO_bit) { if (verbose) printf("starting A2D conversion\n"); // The 'GO' bit is being turned on, which is request to initiate // and A/D conversion start_conversion(); } } else stop_conversion(); } ANSEL_12F::ANSEL_12F(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), adcon1(0) { } void ANSEL_12F::set_tad(unsigned int new_value) { unsigned int Tad = 6; switch(new_value & (ADCS0 | ADCS1)) { case 0: Tad = (new_value & ADCS2) ? 4 : 2; break; case ADCS0: Tad = (new_value & ADCS2) ? 16 : 8; break; case ADCS1: Tad = (new_value & ADCS2) ? 64 : 32; break; case (ADCS0|ADCS1): // typical 4 usec, convert to osc cycles if (cpu) { Tad = (unsigned int)(4.e-6 * p_cpu->get_frequency()); Tad = Tad < 2? 2 : Tad; } else Tad = 6; break; } Dprintf(("ANSEL_12F::set_tad %x Tad=%u\n", new_value, Tad)); adcon0->set_Tad(Tad); } void ANSEL_12F::put(unsigned int new_value) { unsigned int cfgmax = adcon1->getNumberOfChannels(); unsigned int i; unsigned int mask; Dprintf(("ANSEL_12F::put %x cfgmax %u\n", new_value, cfgmax)); trace.raw(write_trace.get() | value.get()); /* Generate ChannelConfiguration from ansel register */ for(i=0; i < cfgmax; i++) { mask = new_value & 0x0f; adcon1->setChannelConfiguration(i, mask); } /* * Convert A2D conversion times and set in adcon */ set_tad(new_value & ( ADCS2 | ADCS1 | ADCS0)); value.put(new_value & 0x7f); adcon1->setADCnames(); } // catch stimulus and set channel voltage // a2d_stimulus::a2d_stimulus(ADCON1 * arg, int chan, const char *cPname,double _Vth, double _Zth) : stimulus(cPname, _Vth, _Zth) { _adcon1 = arg; channel = chan; } void a2d_stimulus::set_nodeVoltage(double v) { Dprintf(("nodeVoltage =%.1f\n", v)); nodeVoltage = v; _adcon1->setVoltRef(channel, v); } // //-------------------------------------------------- // member functions for the FVRCON class //-------------------------------------------------- // FVRCON::FVRCON(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bitMask, unsigned int alwaysOne) : sfr_register(pCpu, pName, pDesc), adcon1(0), daccon0(0), cmModule(0), cpscon0(0) { mask_writable = bitMask; always_one = alwaysOne; } void FVRCON::put(unsigned int new_value) { unsigned int masked_value = (new_value & mask_writable) | always_one; trace.raw(write_trace.get() | value.get()); value.put(masked_value); compute_VTemp(masked_value); compute_FVR_AD(masked_value); compute_FVR_CDA(masked_value); } void FVRCON::put_value(unsigned int new_value) { unsigned int masked_value = (new_value & mask_writable) | always_one; put(masked_value); update(); } double FVRCON::compute_VTemp(unsigned int fvrcon) { double ret = -1.; double Vt; //Transister junction threshold voltage at core temperature if((fvrcon & TSEN) && cpu14e->m_cpu_temp) { Vt = 0.659 - ( cpu14e->m_cpu_temp->getVal() + 40.) * 0.00132; ret = ((Processor *)cpu)->get_Vdd() - ((fvrcon&TSRNG)?4.:2.) * Vt; if (ret < 0.) { ret = -1.; cerr << "Warning FVRCON Vdd too low for temperature range\n"; } } if(adcon1) adcon1->setVoltRef(VTemp_AD_chan, ret); return ret; } double FVRCON::compute_FVR_AD(unsigned int fvrcon) { double ret = -1.; unsigned int gain = (fvrcon & (ADFVR0|ADFVR1)); if ((fvrcon & FVREN) && gain) ret = 1.024 * (1 << (gain - 1)); if (ret > ((Processor *)cpu)->get_Vdd()) { cerr << "warning FVRCON FVRAD > Vdd\n"; ret = -1.; } if(adcon1)adcon1->setVoltRef(FVRAD_AD_chan, ret); return ret; } double FVRCON::compute_FVR_CDA(unsigned int fvrcon) { double ret = 0.; unsigned int gain = (fvrcon & (CDAFVR0|CDAFVR1))>>2; if ((fvrcon & FVREN) && gain) ret = 1.024 * (1 << (gain - 1)); for (unsigned int i= 0; i < daccon0_list.size(); i++) { daccon0_list[i]->set_FVR_CDA_volt(ret); } if(cmModule) cmModule->set_FVR_volt(ret); if(cpscon0) cpscon0->set_FVR_volt(ret); return ret; } // //-------------------------------------------------- // member functions for the DAC classes //-------------------------------------------------- // DACCON0::DACCON0(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bitMask, unsigned int bit_res) : sfr_register(pCpu, pName, pDesc), adcon1(0), cmModule(0), cpscon0(0), bit_mask(bitMask), bit_resolution(bit_res), FVR_CDA_volt(0.) { Pin_Active[0] = false; Pin_Active[1] = false; } void DACCON0::put(unsigned int new_value) { unsigned int masked_value = (new_value & bit_mask); trace.raw(write_trace.get() | value.get()); value.put(masked_value); compute_dac(masked_value); } void DACCON0::put_value(unsigned int new_value) { unsigned int masked_value = (new_value & bit_mask); value.put(masked_value); compute_dac(masked_value); update(); } void DACCON0::set_dcaccon1_reg(unsigned int reg) { daccon1_reg = reg; compute_dac(value.get()); } void DACCON0::compute_dac(unsigned int value) { double Vhigh = get_Vhigh(value); double Vlow = 0.; double Vout; if(value & DACEN) // DAC is enabled { Vout = (Vhigh - Vlow) * daccon1_reg/bit_resolution - Vlow; } else if (value & DACLPS) Vout = Vhigh; else Vout = Vlow; set_dacoutpin(value & DACOE, 0, Vout); set_dacoutpin(value & DACOE2, 1, Vout); if (verbose) printf("%s-%d adcon1 %p FVRCDA_AD_chan %u Vout %.2f\n", __FUNCTION__, __LINE__, adcon1, FVRCDA_AD_chan, Vout); if(adcon1) adcon1->setVoltRef(FVRCDA_AD_chan, Vout); if(cmModule) cmModule->set_DAC_volt(Vout); if(cpscon0) cpscon0->set_DAC_volt(Vout); } void DACCON0::set_dacoutpin(bool output_enabled, int chan, double Vout) { IO_bi_directional_pu *out_pin; if (output_pin[chan]) out_pin = (IO_bi_directional_pu *) &(output_pin[chan]->getPin()); else return; if (output_enabled) { if (!Pin_Active[chan]) // DACOUT going to active { std::string pin_name = name().substr(0, 4); if (pin_name == "dacc") pin_name = "dacout"; else if (chan == 0) pin_name += "-1"; else pin_name += "-2"; output_pin[chan]->AnalogReq(this, true, pin_name.c_str()); Pin_Active[chan] = true; Vth[chan] = out_pin->get_VthIn(); Zth[chan] = out_pin->get_ZthIn(); driving[chan] = out_pin->getDriving(); out_pin->set_ZthIn(150e3); out_pin->setDriving(false); } out_pin->set_VthIn(Vout); out_pin->updateNode(); } else if (Pin_Active[chan]) // DACOUT leaving active { output_pin[chan]->AnalogReq(this, false, output_pin[chan]->getPin().name().c_str()); Pin_Active[chan] = false; out_pin->set_VthIn(Vth[chan]); out_pin->set_ZthIn(Zth[chan]); out_pin->setDriving(driving[chan]); out_pin->updateNode(); } } double DACCON0::get_Vhigh(unsigned int value) { unsigned int mode = (value & (DACPSS0|DACPSS1)) >> 2; switch(mode) { case 0: // Vdd return ((Processor *)cpu)->get_Vdd(); case 1: // Vref+ pin, get is from A2D setup if(adcon1) return(adcon1->getChannelVoltage(adcon1->getVrefHiChannel(0))); cerr << "ERROR DACCON0 DACPSS=01b adcon1 not set\n"; return 0.; case 2: // Fixed Voltage Reference return FVR_CDA_volt; case 3: // Reserved value cerr << "ERROR DACCON0 DACPSS=11b is reserved value\n"; return 0.; } return 0.; // cant get here } DACCON1::DACCON1(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bitMask, DACCON0 *_daccon0) : sfr_register(pCpu, pName, pDesc), bit_mask(bitMask), daccon0(_daccon0) { } void DACCON1::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } void DACCON1::put_value(unsigned int new_value) { unsigned int masked_value = (new_value & bit_mask); value.put(masked_value); if (daccon0) daccon0->set_dcaccon1_reg(masked_value); update(); } //------------------------------------------------------ // ADCON2_diff for A2D with differential input ie 16f178* // ADCON2_DIF::ADCON2_DIF(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) { } gpsim-0.30.0/src/pic-packages.h0000664000076400007640000000176213041763624013147 00000000000000/* Copyright (C) 1998,1999 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* packages.h Here's where all of the pic packages are defined */ #ifndef __PIC_PACKAGES_H__ #define __PIC_PACKAGES_H__ #include "gpsim_classes.h" #include "pic-processor.h" #include "stimuli.h" #include "packages.h" #endif // __PIC_PACKAGES_H__ gpsim-0.30.0/src/pic-instructions.h0000664000076400007640000002263113063451152014125 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PIC_INSTRUCTIONS_H__ #define __PIC_INSTRUCTIONS_H__ #ifdef HAVE_GUI #include #endif #include "value.h" class Register; // FIXME get rid of AddressSymbol and LineNumberSymbol classes class AddressSymbol : public Integer { public: AddressSymbol(Processor *pCpu, const char *, unsigned int); virtual string toString(); virtual Value* evaluate(); virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); }; class LineNumberSymbol : public AddressSymbol { protected: int src_id,src_line,lst_id,lst_line,lst_page; public: LineNumberSymbol(Processor *pCpu, const char *, unsigned int); void put_address(int new_address) {set(new_address);} void put_src_line(int new_src_line) {src_line = new_src_line;} void put_lst_line(int new_lst_line) {lst_line = new_lst_line;} void put_lst_page(int new_lst_page) {lst_page = new_lst_page;} }; /* * base class for an instruction */ class instruction : public Value { public: enum INSTRUCTION_TYPES { NORMAL_INSTRUCTION, INVALID_INSTRUCTION, BREAKPOINT_INSTRUCTION, NOTIFY_INSTRUCTION, PROFILE_START_INSTRUCTION, PROFILE_STOP_INSTRUCTION, MULTIWORD_INSTRUCTION, ASSERTION_INSTRUCTION }; /* * Not all instructions derived from the instruction * class use these constants... */ enum { REG_MASK_12BIT = 0x1f, REG_MASK_14BIT = 0x7f, REG_MASK_16BIT = 0xff, DESTINATION_MASK_12BIT = 0x20, DESTINATION_MASK_14BIT = 0x80, DESTINATION_MASK_16BIT = 0x200, ACCESS_MASK_16BIT = 0x100, }; instruction(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr); virtual ~instruction(); virtual void execute() = 0; virtual void debug(){ } virtual int instruction_size() { return 1;} virtual unsigned int get_opcode() { return opcode; } virtual unsigned int get_value() { return opcode; } virtual void put_value(unsigned int new_value) { } virtual unsigned int getAddress() { return m_uAddrOfInstr;} virtual void setAddress(unsigned int addr) { m_uAddrOfInstr = addr;} virtual int get_src_line() { return(src_line); } virtual int get_hll_src_line() { return(hll_src_line); } virtual void set_hll_src_line(int line) { hll_src_line=line; } virtual int get_lst_line() { return(lst_line); } virtual int get_file_id() {return(file_id); } virtual int get_hll_file_id() {return(hll_file_id); } virtual void set_hll_file_id(int file_id) {hll_file_id=file_id; } virtual enum INSTRUCTION_TYPES isa() {return NORMAL_INSTRUCTION;} virtual guint64 getCyclesUsed() { return cycle_count;} virtual bool isBase() = 0; void decode(Processor *new_cpu, unsigned int new_opcode); virtual void update_line_number(int file, int sline, int lline, int hllfile, int hllsline); virtual char *ReadSrcLine(char *buf, int nBytes); virtual char *ReadLstLine(char *buf, int nBytes); virtual char *ReadHLLLine(char *buf, int nBytes); virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0); virtual void addLabel(string &rLabel); // Some instructions require special initialization after they've // been instantiated. For those that do, the instruction base class // provides a way to control the initialization state (see the 16-bit // PIC instructions). virtual void initialize(bool init_state) {}; bool bIsModified() { return m_bIsModified; } void setModified(bool b) { m_bIsModified=b; } gpsimObject *getLineSymbol() { return pLineSymbol; } protected: bool m_bIsModified; // flag indicating if this instruction has // changed since start. guint64 cycle_count; // Nr of cycles used up by this instruction unsigned int opcode; unsigned int m_uAddrOfInstr; gpsimObject *pLineSymbol; int file_id; /* The source file that declared this instruction * (The file_id is an index into an array of files) */ int hll_file_id; /* The hll source file that declared this instruction */ int src_line; /* The line number within the source file */ int lst_line; /* The line number within the list file */ int hll_src_line; /* The line number within the HLL source file */ }; //--------------------------------------------------------- // An AliasedInstruction is a class that is designed to replace an // instruction in program memory. (E.g. breakpoint instructions are an // example). class AliasedInstruction : public instruction { public: explicit AliasedInstruction(instruction *); AliasedInstruction(); AliasedInstruction(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr); ~AliasedInstruction(); void setReplaced(instruction *); virtual instruction *getReplaced(); virtual void execute(); virtual void debug(); virtual int instruction_size(); virtual unsigned int get_opcode(); virtual unsigned int get_value(); virtual void put_value(unsigned int new_value); virtual int get_src_line(); virtual int get_hll_src_line(); virtual int get_lst_line(); virtual int get_file_id(); virtual int get_hll_file_id(); virtual void update_line_number(int file, int sline, int lline, int hllfile, int hllsline); virtual enum INSTRUCTION_TYPES isa(); virtual void initialize(bool init_state); virtual char *name(char *,int len); virtual bool isBase(); virtual void update(void); virtual void add_xref(void *xref); virtual void remove_xref(void *xref); protected: instruction *m_replaced; }; //--------------------------------------------------------- class invalid_instruction : public instruction { public: virtual void execute(); virtual void debug() { //cout << "*** INVALID INSTRUCTION ***\n"; }; //invalid_instruction(Processor *new_cpu=0,unsigned int new_opcode=0); invalid_instruction(Processor *new_cpu, unsigned int new_opcode, unsigned int address); virtual enum INSTRUCTION_TYPES isa() {return INVALID_INSTRUCTION;}; //virtual char *name(char *str){return("INVALID");}; static instruction *construct(Processor *new_cpu, unsigned int new_opcode,unsigned int address) {return new invalid_instruction(new_cpu,new_opcode,address);} virtual void addLabel(string &rLabel); virtual bool isBase() { return true; } }; //--------------------------------------------------------- class Literal_op : public instruction { public: Literal_op(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr); unsigned int L; virtual void debug(){ }; virtual char *name(char *,int); virtual bool isBase() { return true; } void decode(Processor *new_cpu, unsigned int new_opcode); }; //--------------------------------------------------------- class Bit_op : public instruction { public: Bit_op(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr); unsigned int mask,register_address; bool access; Register *reg; virtual void debug(){ }; virtual char *name(char *,int); virtual bool isBase() { return true; } void decode(Processor *new_cpu, unsigned int new_opcode); }; //--------------------------------------------------------- class Register_op : public instruction { public: Register_op(Processor *pProcessor, unsigned int uOpCode, unsigned int uAddrOfInstr); static Register *source; unsigned int register_address; bool destination, access; /* Register *destination;*/ virtual void debug(){ }; virtual char *name(char *,int); virtual bool isBase() { return true; } void decode(Processor *new_cpu, unsigned int new_opcode); }; //----------------------------------------------------------------- // // instruction_constructor - a class used to create the PIC instructions // // The way it works is the 'instruction_constructor' structure // contains three pieces of info for each instruction: // inst_mask - a bit mask indicating which bits uniquely // identify an instruction // opcode - What those unique bits should be // inst_constructor - A pointer to the static member function // 'construct' in the instruction class. // // An instruction is decoded by finding a matching entry in // the instruction_constructor array. A match is defined to // be: // inst_mask & passed_opcode == opcode // which means that the opcode that is passed to the decoder // is ANDed with the instruction mask bits and compared to // the base bits of the opcode. If this test passes, then the // 'inst_constructor' will be called. struct instruction_constructor { unsigned int inst_mask; unsigned int opcode; instruction * (*inst_constructor) (Processor *cpu, unsigned int inst, unsigned int address); }; #endif /* __PIC_INSTRUCTIONS_H__ */ gpsim-0.30.0/src/i2c-ee.h0000664000076400007640000001116013041763613011653 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 2006 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef I2C_EE_H #define I2C_EE_H #include "trigger.h" #include "gpsim_classes.h" #include "value.h" class Register; class RegisterCollection; class pic_processor; class I2C_EE; class I2C_SLAVE_SCL; class I2C_SLAVE_SDA; class Stimulus_Node; //------------------------------------------------------------------------ //------------------------------------------------------------------------ class PromAddress : public Value { public: PromAddress(I2C_EE *eeprom, const char *_name, const char * desc); void get(I2C_EE *&eeprom) { eeprom = m_eeprom;} void get(char *buffer, int buf_size); private: I2C_EE *m_eeprom; }; class i2c_slave { public: i2c_slave(); ~i2c_slave(); void new_sda_edge(bool direction); void new_scl_edge(bool direction); bool shift_read_bit ( bool x ); bool shift_write_bit (); virtual bool match_address(); virtual void put_data(unsigned int data){} virtual unsigned int get_data(){return 0;} virtual void slave_transmit(bool yes){} I2C_SLAVE_SCL *scl; // I2C clock I2C_SLAVE_SDA *sda; // I2C data unsigned int i2c_slave_address; protected: bool nxtbit; unsigned int bit_count; // Current bit number for either Tx or Rx unsigned int xfr_data; // latched data from I2C. enum { IDLE=0, START, RX_I2C_ADD, ACK_I2C_ADD, RX_DATA, ACK_RX, ACK_WR, WRPEND, ACK_RD, TX_DATA } bus_state; }; class I2C_EE : public i2c_slave, public TriggerObject { public: I2C_EE(Processor *pCpu, unsigned int _rom_size, unsigned int _write_page_size = 1, unsigned int _addr_bytes = 1, unsigned int _CSmask = 0, unsigned int _BSmask = 0, unsigned int _BSshift = 0 ); virtual ~I2C_EE(); void reset(RESET_TYPE); void debug(); virtual void callback(); virtual void callback_print(); virtual void start_write(); virtual void write_busy(); virtual void write_is_complete(); virtual void put_data(unsigned int data); virtual unsigned int get_data(); virtual void slave_transmit(bool); virtual bool match_address(); virtual Register *get_register(unsigned int address); inline int register_size() {return rom_data_size; } inline void set_register_size(int bytes) { rom_data_size = bytes; } virtual void attach ( Stimulus_Node *_scl, Stimulus_Node *_sda ); virtual void set_chipselect(unsigned int _chipselect); inline virtual unsigned int get_rom_size() { return (rom_size); } // XXX might want to make get_rom a friend only to cli_dump inline virtual Register **get_rom() { return (rom); } void dump(); protected: Register **rom; // The data area. RegisterCollection *m_UiAccessOfRom; // User access to the rom. unsigned int rom_size; int rom_data_size; // width of data in bytes unsigned int xfr_addr; // latched adr from I2C. unsigned int write_page_off; // offset into current write page unsigned int write_page_size; // max number of writes in one block unsigned int bit_count; // Current bit number for either Tx or Rx unsigned int m_command; // Most recent command received from I2C host unsigned int m_chipselect; // Chip select bits, A0 = bit 1, A1 = bit 2, A2 = bit 3 unsigned int m_CSmask; // Which chip select bits in command are active unsigned int m_BSmask; // Which block select bits are active in command unsigned int m_BSshift; // right shift for block select bits unsigned int m_addr_bytes; // number of address bytes in write command unsigned int m_addr_cnt; // # 0f address bytes yet to get bool m_write_protect; // chip is write protected bool ee_busy; // true if a write is in progress. bool nxtbit; enum { RX_EE_ADDR = 1, RX_EE_DATA, TX_EE_DATA } io_state; private: // Is this even used? virtual void change_rom(unsigned int offset, unsigned int val); }; #endif /* I2C_EE_H */ gpsim-0.30.0/src/bytelog.h0000664000076400007640000000305013041763624012255 00000000000000/* Copyright (C) 1998-2003 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__BYTELOG_H__) #define __BYTELOG_H__ class Cycle_Counter; namespace gpsim { //======================================================================== struct TimedByte { unsigned long long start; unsigned long long stop; unsigned long long rts; unsigned int b; }; class ByteLogger { protected: int index; int bufsize; TimedByte *buffer; public: ByteLogger(int _bufsize=128); int modIndex(int i); void start(unsigned long long t); void stop(unsigned long long t); void byte(unsigned int b); void rts(unsigned long long r); // void statistics(int i=-1); unsigned long long getStart(int i=-1); void get(int i, TimedByte &b); }; } // end of namespace gpsim #endif //!defined(__BYTELOG_H__) gpsim-0.30.0/src/p16f8x.h0000664000076400007640000001236113111746610011643 00000000000000/* Copyright (C) 1998-2002 T. Scott Dattalo Copyright (C) 2006 Roy Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P16F8X_H__ #define __P16F8X_H__ #include "p16x6x.h" #include "pir.h" #include "eeprom.h" #include "comparator.h" #include "a2dconverter.h" /*************************************************************************** * * Include file for: P16F87, P16F88 * * * The F8x devices are similar to 16F62x * * ***************************************************************************/ class P16F8x : public P16X6X_processor { public: PIR1v2 *pir1_2_reg; PIR2v2 *pir2_2_reg; PIR_SET_2 pir_set_2_def; WDTCON wdtcon; OSCCON_1 *osccon; OSCTUNE osctune; P16F8x(const char *_name=0, const char *desc=0); ~P16F8x(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); USART_MODULE usart; ComparatorModule comparator; virtual PROCESSOR_TYPE isa(){return _P16F87_;}; virtual void create_symbols(); virtual unsigned int register_memory_size () const { return 0x200;}; virtual unsigned int program_memory_size() { return 0; }; virtual void create_sfr_map(); // The f628 (at least) I/O pins depend on the Fosc Configuration bits. virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void create(int eesize); virtual void create_iopin_map(); virtual void create_config_memory(); virtual void enter_sleep(); virtual void exit_sleep(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } virtual PIR *get_pir1() { return (pir1); } virtual PIR *get_pir2() { return (pir2); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } }; class P16F81x : public P16X6X_processor { public: PIR1v2 *pir1_2_reg; PIR2v2 *pir2_2_reg; PIR_SET_2 pir_set_2_def; ADCON0 adcon0; ADCON1 adcon1; sfr_register adresh; sfr_register adresl; OSCCON_1 *osccon; OSCTUNE osctune; P16F81x(const char *_name=0, const char *desc=0); ~P16F81x(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual PROCESSOR_TYPE isa(){return _P16F818_;}; virtual void create_symbols(); virtual unsigned int register_memory_size () const { return 0x200;}; virtual unsigned int program_memory_size() { return 0; }; virtual void create_sfr_map(); // The f628 (at least) I/O pins depend on the Fosc Configuration bits. virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void create_config_memory(); virtual void create(int eesize); virtual void create_iopin_map(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } virtual PIR *get_pir1() { return (pir1); } virtual PIR *get_pir2() { return (pir2); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } }; class P16F87 : public P16F8x { public: virtual PROCESSOR_TYPE isa(){return _P16F87_;}; virtual unsigned int program_memory_size() const { return 0x1000; }; P16F87(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual void create_sfr_map(); }; class P16F88 : public P16F87 { public: ANSEL ansel; ADCON0 adcon0; ADCON1 adcon1; sfr_register adresh; sfr_register adresl; virtual PROCESSOR_TYPE isa(){return _P16F88_;}; virtual unsigned int program_memory_size() const { return 0x1000; }; virtual void create(); virtual void create_sfr_map(); P16F88(const char *_name=0, const char *desc=0); ~P16F88(); static Processor *construct(const char *name); }; class P16F818 : public P16F81x { public: virtual PROCESSOR_TYPE isa(){return _P16F818_;}; virtual unsigned int program_memory_size() const { return 0x400; }; virtual void create(); virtual void create_sfr_map(); P16F818(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16F819 : public P16F81x { public: virtual PROCESSOR_TYPE isa(){return _P16F819_;}; virtual unsigned int program_memory_size() const { return 0x800; }; virtual void create(); virtual void create_sfr_map(); P16F819(const char *_name=0, const char *desc=0); ~P16F819(); static Processor *construct(const char *name); }; #endif gpsim-0.30.0/src/value.cc0000664000076400007640000005653513060754614012102 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include #include "processor.h" #include "value.h" #include "errors.h" #include "operator.h" #include "protocol.h" #include "../config.h" #include "cmd_gpsim.h" #include char * TrimWhiteSpaceFromString(char * pBuffer) { size_t iPos = 0; char * pChar = pBuffer; while(*pChar != 0 && ::isspace(*pChar)) { pChar++; } if(pBuffer != pChar) { memmove(pBuffer, pChar, strlen(pBuffer) - iPos); } iPos = strlen(pBuffer); if(iPos > 0) { pChar = pBuffer + iPos - 1; while(pBuffer != pChar && ::isspace(*pChar)) { *pChar = 0; pChar--; } } return pBuffer; } char * UnquoteString(char * pBuffer) { char cQuote; if(*pBuffer == '\'') { cQuote = '\''; } else if(*pBuffer == '"') { cQuote = '"'; } else { return pBuffer; } int iLen = strlen(pBuffer); if(iLen > 1) { if(pBuffer[iLen - 1] == cQuote) { memmove(&pBuffer[0], &pBuffer[1], iLen - 2); pBuffer[iLen - 2] = 0; } } return pBuffer; } string &toupper(string & sStr) { string::iterator it; string::iterator itEnd = sStr.end(); for(it = sStr.begin(); it != itEnd; ++it) { if(isalpha(*it)) { *it = toupper((int)*it); } } return sStr; } //------------------------------------------------------------------------ Value::Value() : _xref(0), cpu(0), m_aka(0) { } Value::Value(const char *_name, const char *desc, Module *pMod) : gpsimObject(_name,desc), _xref(0), cpu(pMod),m_aka(0) { } Value::~Value() { // Remove references of this Value from the symbol table: if (cpu) { //cout << "Deleting value named:" << name_str << " addr "<< this << endl; cpu->removeSymbol(name_str); if (m_aka) { //cout << "m_aka ==" << m_aka << endl; list ::iterator it; it = m_aka->begin(); while(it != m_aka->end()) { string s(*it); //cout << " Value label " << s << endl; cpu->removeSymbol(s); ++it; } m_aka->clear(); delete m_aka; } if(_xref) { delete _xref; _xref = 0; } } } void Value::update() { if (_xref) _xref->_update(); } void Value::add_xref(void *an_xref) { if (!_xref) _xref = new XrefObject(); _xref->_add(an_xref); } void Value::remove_xref(void *an_xref) { _xref->clear(an_xref); } void Value::set(const char *cP,int i) { throw new Error(" cannot assign string to a " + showType()); } void Value::set(double d) { throw new Error(" cannot assign a double to a " + showType()); } void Value::set(gint64 i) { throw new Error(" cannot assign an integer to a " + showType()); } void Value::set(bool v) { throw new Error(" cannot assign a boolean to a " + showType()); } void Value::set(int i) { gint64 i64 = i; set(i64); } void Value::set(Value *v) { throw new Error(" cannot assign a Value to a " + showType()); } void Value::set(Expression *expr) { try { Value *v=0; if(!expr) throw new Error(" null expression "); if (verbose) cout << toString() << " is being assigned expression " << expr->toString() << endl; v = expr->evaluate(); if(!v) throw new Error(" cannot evaluate expression "); set(v); delete v; } catch (Error *err) { if(err) cout << "ERROR:" << err->toString() << endl; delete err; } } void Value::set(Packet &pb) { cout << "Value,"<showOp() + " comparison is not defined for " + showType()); } Value *Value::copy() { throw new Error(" cannot copy " + showType()); } /* void Value::set_xref(Value *v) { delete xref; xref = v; } Value *Value::get_xref() { return xref; } */ Processor *Value::get_cpu() const { return static_cast(cpu); } void Value::set_cpu(Processor *new_cpu) { cpu = new_cpu; } void Value::set_module(Module *new_cpu) { cpu = new_cpu; } Module *Value::get_module() { return cpu; } void Value::addName(string &r_sAliasedName) { if (!m_aka) m_aka = new list(); //cout << "Adding name " << r_sAliasedName << " to "<< name() << endl; m_aka->push_back(r_sAliasedName); } //------------------------------------------------------------------------ ValueWrapper::ValueWrapper(Value *pCopy) : m_pVal(pCopy) { } ValueWrapper::~ValueWrapper() { } unsigned int ValueWrapper::get_leftVal() { return m_pVal->get_leftVal(); } unsigned int ValueWrapper::get_rightVal() { return m_pVal->get_rightVal(); } void ValueWrapper::set(const char *cP,int len) { m_pVal->set(cP,len); } void ValueWrapper::set(double d) { m_pVal->set(d); } void ValueWrapper::set(gint64 i) { m_pVal->set(i); } void ValueWrapper::set(int i) { m_pVal->set(i); } void ValueWrapper::set(bool b) { m_pVal->set(b); } void ValueWrapper::set(Value *v) { m_pVal->set(v); } void ValueWrapper::set(Expression *e) { m_pVal->set(e); } void ValueWrapper::set(Packet &p) { m_pVal->set(p); } void ValueWrapper::get(bool &b) { m_pVal->get(b); } void ValueWrapper::get(int &i) { m_pVal->get(i); } void ValueWrapper::get(guint64 &i) { m_pVal->get(i); } void ValueWrapper::get(gint64 &i) { m_pVal->get(i); } void ValueWrapper::get(double &d) { m_pVal->get(d); } void ValueWrapper::get(char *pC, int len) { m_pVal->get(pC,len); } void ValueWrapper::get(Packet &p) { m_pVal->get(p); } Value *ValueWrapper::copy() { return m_pVal->copy(); } void ValueWrapper::update() { m_pVal->update(); } Value *ValueWrapper::evaluate() { return m_pVal->evaluate(); } bool ValueWrapper::compare(ComparisonOperator *compOp, Value *rvalue) { if(!compOp || !rvalue) return false; gint64 i,r; m_pVal->get(i); rvalue->get(r); if(i < r) return compOp->less(); if(i > r) return compOp->greater(); return compOp->equal(); } /***************************************************************** * The AbstractRange class. */ AbstractRange::AbstractRange(unsigned int newLeft, unsigned int newRight) { left = newLeft; right = newRight; } AbstractRange::~AbstractRange() { } string AbstractRange::toString() { char buff[256]; snprintf(buff, sizeof(buff), "%u:%u", left, right); return (string(buff)); } string AbstractRange::toString(const char* format) { char cvtBuf[1024]; snprintf(cvtBuf, sizeof(cvtBuf), format, left, right); return (string(&cvtBuf[0])); } char *AbstractRange::toString(char *return_str, int len) { if(return_str) { snprintf(return_str, len, "%u:%u", left, right); } return return_str; } unsigned int AbstractRange::get_leftVal() { return(left); } unsigned int AbstractRange::get_rightVal() { return(right); } AbstractRange* AbstractRange::typeCheck(Value* val, string valDesc) { if (typeid(*val) != typeid(AbstractRange)) { throw new TypeMismatch(valDesc, "AbstractRange", val->showType()); } // This static cast is totally safe in light of our typecheck, above. return((AbstractRange*)(val)); } bool AbstractRange::compare(ComparisonOperator *compOp, Value *rvalue) { throw new Error(compOp->showOp() + " comparison is not defined for " + showType()); } Value *AbstractRange::copy() { return new AbstractRange(get_leftVal(),get_rightVal()); } void AbstractRange::set(Value *v) { AbstractRange *ar=typeCheck(v, string("")); left = ar->get_leftVal(); right = ar->get_rightVal(); } /* bool AbstractRange::operator<(Value *rv) { AbstractRange *_rv = typeCheck(rv,"OpLT"); return right < _rv->left; } */ /***************************************************************** * The Boolean class. */ Boolean::Boolean(bool newValue) { value = newValue; } Boolean::Boolean(const char *_name, bool newValue,const char *_desc) : Value(_name,_desc) { value = newValue; } bool Boolean::Parse(const char *pValue, bool &bValue) { if(strncmp("true", pValue, sizeof("true")-1) == 0) { bValue = true; return true; } else if(strncmp("false", pValue, sizeof("false")-1) == 0) { bValue = false; return true; } return false; } Boolean * Boolean::NewObject(const char *_name, const char *pValue, const char *desc) { bool bValue; if(Parse(pValue, bValue)) { return new Boolean(_name, bValue); } return NULL; } Boolean::~Boolean() { } string Boolean::toString() { bool b; get(b); return (string(b ? "true" : "false")); } string Boolean::toString(bool value) { return (string(value ? "true" : "false")); } char *Boolean::toString(char *return_str, int len) { if(return_str) { bool b; get(b); snprintf(return_str,len,"%s",(b ? "true" : "false")); } return return_str; } char *Boolean::toBitStr(char *return_str, int len) { if(return_str) { bool b; get(b); snprintf(return_str,len,"%d",(b ? 1 : 0)); } return return_str; } string Boolean::toString(const char* format) { char cvtBuf[1024]; bool b; get(b); sprintf(cvtBuf, format, b); return (string(&cvtBuf[0])); } Boolean* Boolean::typeCheck(Value* val, string valDesc) { if (typeid(*val) != typeid(Boolean)) { throw new TypeMismatch(valDesc, "Boolean", val->showType()); } // This static cast is totally safe in light of our typecheck, above. return((Boolean*)(val)); } bool Boolean::compare(ComparisonOperator *compOp, Value *rvalue) { Boolean *rv = typeCheck(rvalue,""); switch(compOp->isa()) { case ComparisonOperator::eOpEq: return value == rv->value; case ComparisonOperator::eOpNe: return value != rv->value; default: Value::compare(compOp, rvalue); // error } return false; // keep the compiler happy. } Value *Boolean::copy() { bool b; get(b); return new Boolean(b); } // get(bool&) - primary method for accessing the value. void Boolean::get(bool &b) { b = value; } // get(int&) - type cast an integer into a boolean. Note // that we call get(bool &) instead of directly accessing // the member value. The reason for this is so that derived // classes can capture the access. void Boolean::get(int &i) { bool b; get(b); i = b ? 1 : 0; } /* void Boolean::get(double &d) { bool b; get(b); d = b ? 1.0 : 0.0; } */ void Boolean::get(char *buffer, int buf_size) { if(buffer) { bool b; get(b); if(b) strncpy(buffer,"true",buf_size); else strncpy(buffer,"false",buf_size); } } void Boolean::get(Packet &pb) { bool b; get(b); pb.EncodeBool(b); } void Boolean::set(Value *v) { Boolean *bv = typeCheck(v,string("set ")); bool b = bv->getVal(); set(b); } void Boolean::set(bool v) { value = v; //if(get_xref()) // get_xref()->set(v); } void Boolean::set(const char *buffer, int buf_size) { if(buffer) { bool bValue; if(Parse(buffer, bValue)) { set(bValue); } } } void Boolean::set(Packet &p) { bool b; if(p.DecodeBool(b)) set(b); } /* bool Boolean::operator&&(Value *rv) { Boolean *_rv = typeCheck(rv,"Op&&"); return value && _rv->value; } bool Boolean::operator||(Value *rv) { Boolean *_rv = typeCheck(rv,"Op||"); return value || _rv->value; } bool Boolean::operator==(Value *rv) { Boolean *_rv = typeCheck(rv,"OpEq"); return value == _rv->value; } bool Boolean::operator!=(Value *rv) { Boolean *_rv = typeCheck(rv,"OpNe"); return value != _rv->value; } */ /***************************************************************** * The Integer class. */ Integer::Integer(const Integer &new_value) { Integer & nv = (Integer&)new_value; nv.get(value); bitmask = new_value.bitmask; } Integer::Integer(gint64 newValue) { value = newValue; bitmask = def_bitmask; } Integer::Integer(const char *_name, gint64 newValue,const char *_desc) : Value(_name,_desc) { value = newValue; bitmask = def_bitmask; } gint64 Integer::def_bitmask = 0xffffffff; Integer::~Integer() { } void Integer::setDefaultBitmask(gint64 bitmask) { def_bitmask = bitmask; } Value *Integer::copy() { gint64 i; get(i); return new Integer(i); } void Integer::set(double d) { gint64 i = (gint64)d; set(i); } void Integer::set(gint64 i) { value = i; //if(get_xref()) // get_xref()->set(i); } void Integer::set(int i) { gint64 ii = i; set(ii); } void Integer::set(Value *v) { gint64 iv = 0; if (v) v->get(iv); set(iv); } void Integer::set(Packet &p) { unsigned int i; if(p.DecodeUInt32(i)) { set((int)i); return; } guint64 i64; if(p.DecodeUInt64(i64)) { set((gint64)i64); return; } } void Integer::set(const char *buffer, int buf_size) { if(buffer) { gint64 i; if(Parse(buffer, i)) { set(i); } } } bool Integer::Parse(const char *pValue, gint64 &iValue) { if(::isdigit(*pValue)) { if(strchr(pValue, '.')) { return false; } else { // decimal or 0x integer return sscanf(pValue, "%" PRINTF_GINT64_MODIFIER "i", &iValue) == 1; } } else if(*pValue == '$' && ::isxdigit(*(pValue+1))) { // hexidecimal integer char szHex[10] = "0x"; strcat(&szHex[0], pValue + 1); return sscanf(szHex, "%" PRINTF_GINT64_MODIFIER "i" , &iValue) == 1; } return false; } Integer * Integer::NewObject(const char *_name, const char *pValue, const char *desc) { gint64 iValue; if(Parse(pValue, iValue)) { return new Integer(_name, iValue, desc); } return NULL; } void Integer::get(gint64 &i) { i = value; } void Integer::get(double &d) { gint64 i; get(i); d = (double)i; } void Integer::get(char *buffer, int buf_size) { if(buffer) { gint64 i; get(i); long long int j = i; snprintf(buffer,buf_size,"%" PRINTF_INT64_MODIFIER "d",j); } } void Integer::get(Packet &pb) { gint64 i; get(i); unsigned int j = (unsigned int) (i &0xffffffff); pb.EncodeUInt32(j); } int Integer::set_break(ObjectBreakTypes bt, ObjectActionTypes at, Expression *expr) { Processor *pCpu = get_active_cpu(); if (pCpu) { // Legacy code compatibility! if ( bt == eBreakWrite || bt == eBreakRead ) { // Cast the integer into a register and set a register break point unsigned int iRegAddress = (unsigned int) value; Register *pReg = &pCpu->rma[iRegAddress]; return get_bp().set_break(bt, at, pReg, expr); } else if ( bt == eBreakExecute) { unsigned int iProgAddress = (unsigned int) value; return get_bp().set_execution_break(pCpu, iProgAddress, expr); } } return -1; } string Integer::toString() { gint64 i; get(i); IUserInterface & TheUI = GetUserInterface(); return string(TheUI.FormatValue(i, (unsigned int)bitmask)); } string Integer::toString(const char* format) { char cvtBuf[1024]; gint64 i; get(i); snprintf(cvtBuf,sizeof(cvtBuf), format, i); return (string(&cvtBuf[0])); } string Integer::toString(const char* format, gint64 value) { char cvtBuf[1024]; snprintf(cvtBuf,sizeof(cvtBuf), format, value); return (string(&cvtBuf[0])); } string Integer::toString(gint64 value) { char cvtBuf[1024]; long long int v=value; snprintf(cvtBuf,sizeof(cvtBuf), "%" PRINTF_INT64_MODIFIER "d", v); return (string(&cvtBuf[0])); } char *Integer::toString(char *return_str, int len) { if(return_str) { gint64 i; get(i); IUserInterface & TheUI = GetUserInterface(); strncpy(return_str, TheUI.FormatValue(i), len); // snprintf(return_str,len,"%" PRINTF_INT64_MODIFIER "d",i); } return return_str; } char *Integer::toBitStr(char *return_str, int len) { if(return_str) { gint64 i; get(i); int j=0; int mask=1<<31; for( ; mask ; mask>>=1, j++) if(jshowType()); } // This static cast is totally safe in light of our typecheck, above. return((Integer*)(val)); } Integer* Integer::assertValid(Value* val, string valDesc, gint64 valMin) { Integer* iVal; gint64 i; iVal = Integer::typeCheck(val, valDesc); iVal->get(i); if (i < valMin) { throw new Error(valDesc + " must be greater than " + Integer::toString(valMin) + ", saw " + Integer::toString(i) ); } return(iVal); } Integer* Integer::assertValid(Value* val, string valDesc, gint64 valMin, gint64 valMax) { Integer* iVal; gint64 i; iVal = (Integer::typeCheck(val, valDesc)); iVal->get(i); if ((i < valMin) || (i>valMax)) { throw new Error(valDesc + " must be be in the range [" + Integer::toString(valMin) + ".." + Integer::toString(valMax) + "], saw " + Integer::toString(i) ); } return(iVal); } bool Integer::compare(ComparisonOperator *compOp, Value *rvalue) { Integer *rv = typeCheck(rvalue,""); gint64 i,r; get(i); rv->get(r); if(i < r) return compOp->less(); if(i > r) return compOp->greater(); return compOp->equal(); } /* bool Integer::operator<(Value *rv) { Integer *_rv = typeCheck(rv,"OpLT"); return value < _rv->value; } bool Integer::operator>(Value *rv) { Integer *_rv = typeCheck(rv,"OpGT"); return value > _rv->value; } bool Integer::operator<=(Value *rv) { Integer *_rv = typeCheck(rv,"OpLE"); return value <= _rv->value; } bool Integer::operator>(Value *rv) { Integer *_rv = typeCheck(rv,"OpGT"); return value > _rv->value; } */ /***************************************************************** * The Float class. */ Float::Float(double newValue) { value = newValue; } Float::Float(const char *_name, double newValue,const char *_desc) : Value(_name,_desc) { value = newValue; } bool Float::Parse(const char *pValue, double &fValue) { return pValue ? sscanf(pValue,"%lg",&fValue) == 1 : false; } Float * Float::NewObject(const char *_name, const char *pValue, const char *desc) { double fValue; if(Parse(pValue, fValue)) { return new Float(_name, fValue); } return NULL; } Float::~Float() { } void Float::set(double d) { value = d; //if(get_xref()) // get_xref()->set(d); } void Float::set(gint64 i) { double d = (double)i; set(d); } void Float::set(Value *v) { /* typeCheck means cannot set integers - RRR Float *fv = typeCheck(v,string("set ")); double d = fv->getVal(); set(d); */ double d; if (typeid(*v) != typeid(Float) && typeid(*v) != typeid(Integer)) { throw new TypeMismatch(string("set "), "Float", v->showType()); } v->get(d); set(d); } void Float::set(const char *buffer, int buf_size) { if(buffer) { double d; if(Parse(buffer, d)) { set(d); } } } void Float::set(Packet &p) { double d; if(p.DecodeFloat(d)) { set(d); } } void Float::get(gint64 &i) { double d; get(d); i = (gint64)d; } void Float::get(double &d) { d = value; } void Float::get(char *buffer, int buf_size) { if(buffer) { double d;; get(d); snprintf(buffer,buf_size,"%g",d); } } void Float::get(Packet &pb) { double d; get(d); pb.EncodeFloat(d); } Value *Float::copy() { double d; get(d); return new Float(d); } string Float::toString() { return toString("%#-16.16g"); } string Float::toString(const char* format) { char cvtBuf[1024]; double d; get(d); sprintf(cvtBuf, format, d); return (string(&cvtBuf[0])); } char *Float::toString(char *return_str, int len) { if(return_str) { double d; get(d); snprintf(return_str,len,"%g",d); } return return_str; } Float* Float::typeCheck(Value* val, string valDesc) { if (typeid(*val) != typeid(Float)) { throw new TypeMismatch(valDesc, "Float", val->showType()); } // This static cast is totally safe in light of our typecheck, above. return((Float*)(val)); } bool Float::compare(ComparisonOperator *compOp, Value *rvalue) { Float *rv = typeCheck(rvalue,""); double d,r; get(d); rv->get(r); if(d < r) return compOp->less(); if(d > r) return compOp->greater(); return compOp->equal(); } /* bool Float::operator<(Value *rv) { Float *_rv = typeCheck(rv,"OpLT"); return value < _rv->value; } */ /***************************************************************** * The String class. */ String::String(const char *newValue) { if (newValue) value = newValue; } String::String(const char *newValue, size_t len) { if (newValue) value.assign(newValue, len); } String::String(const char *_name, const char *newValue, const char *_desc) : Value(_name, _desc) { if (newValue) value = newValue; } String::~String() { } std::string String::toString() { return value; } char *String::toString(char *return_str, int len) { if (return_str) snprintf(return_str, len, "%s", value.c_str()); return return_str; } void String::set(Value *v) { if (v) { std::string buf = v->toString(); set(buf.c_str()); } } // TODO: is this meant to do something void String::set(Packet &p) { cout << " fixme String::set(Packet &) is not implemented\n"; } // TODO: was len meant to do anything void String::set(const char *s, int len) { if (s) value = s; } void String::get(char *buf, int len) { if (buf) snprintf(buf, len, "%s", value.c_str()); } void String::get(Packet &p) { p.EncodeString(value.c_str()); } const char *String::getVal() { return value.c_str(); } Value *String::copy() { return new String(value.c_str()); } //------------------------------------------------------------------------ namespace gpsim { Function::Function(const char *_name, const char *desc) : gpsimObject(_name,desc) { } Function::~Function() { cout << "Function destructor\n"; } string Function::description() { if(cpDescription) return string(cpDescription); else return string("no description"); } string Function::toString() { return name(); } void Function::call(ExprList_t *vargs) { cout << "calling " << name() << endl; } } gpsim-0.30.0/src/clock_phase.cc0000664000076400007640000000751513041763624013233 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "clock_phase.h" #include "processor.h" #include "gpsim_time.h" //======================================================================== ClockPhase::ClockPhase() : m_pNextPhase(this) { } ClockPhase::~ClockPhase() { } //======================================================================== ProcessorPhase::ProcessorPhase(Processor *pcpu) : ClockPhase(), m_pcpu(pcpu) { } ProcessorPhase::~ProcessorPhase() { } //======================================================================== phaseExecute1Cycle::phaseExecute1Cycle(Processor *pcpu) : ProcessorPhase(pcpu) { } phaseExecute1Cycle::~phaseExecute1Cycle() { } /* phaseExecute1Cycle::advance() - advances a processor's time one clock cycle. */ ClockPhase *phaseExecute1Cycle::advance() { setNextPhase(this); m_pcpu->step_one(false); if (bp.global_break & GLOBAL_LOG) { if (GetTraceLog().log_file) { trace.cycle_counter(get_cycles().get()); trace.dump(1, GetTraceLog().log_file); GetTraceLog().items_logged++; } bp.global_break &= ~GLOBAL_LOG; } if (!bp.global_break) get_cycles().increment(); return m_pNextPhase; } //======================================================================== phaseIdle::phaseIdle(Processor *pcpu) : ProcessorPhase(pcpu) { } phaseIdle::~phaseIdle() { } /* phaseIdle::advance() - advances a processor's time one clock cycle, but does not execute code. */ ClockPhase *phaseIdle::advance() { setNextPhase(this); get_cycles().increment(); return m_pNextPhase; } #if 0 const char* phaseDesc(ClockPhase *pPhase) { if (pPhase == mIdle) return ("mIdle"); if (pPhase == mExecute1Cycle) return ("mExecute1Cycle"); if (pPhase == mExecute2ndHalf) return ("mExecute2ndHalf"); if (pPhase == mCaptureInterrupt) return ("mCaptureInterrupt"); return "unknown phase"; } #endif phaseCaptureInterrupt::phaseCaptureInterrupt(Processor *pcpu) : ProcessorPhase(pcpu), m_pCurrentPhase(0),m_pNextNextPhase(0) { } phaseCaptureInterrupt::~phaseCaptureInterrupt() {} #define Rprintf(arg) {printf("0x%06X %s() ",cycles.get(),__FUNCTION__); printf arg; } ClockPhase *phaseCaptureInterrupt::advance() { //Rprintf (("phaseCaptureInterrupt\n")); if (m_pNextPhase == m_pcpu->mExecute2ndHalf) m_pNextPhase->advance(); if (m_pCurrentPhase == m_pcpu->mIdle) { // Interrupted sleep // complete sleeping phase m_pNextPhase = m_pNextNextPhase->advance(); if (m_pNextPhase == m_pcpu->mIdle) { m_pNextPhase = m_pcpu->mExecute1Cycle; do { m_pNextPhase = m_pcpu->mExecute1Cycle->advance(); }while (m_pNextPhase != m_pcpu->mExecute1Cycle); } m_pcpu->mCurrentPhase = this; if (bp.global_break) m_pNextNextPhase = m_pNextPhase; else m_pCurrentPhase = NULL; m_pcpu->exit_sleep(); return this; } m_pcpu->interrupt(); return m_pNextPhase; } void phaseCaptureInterrupt::firstHalf() { m_pCurrentPhase = m_pcpu->mCurrentPhase; m_pNextPhase = this; m_pNextNextPhase = m_pcpu->mCurrentPhase->getNextPhase(); m_pcpu->mCurrentPhase->setNextPhase(this); m_pcpu->mCurrentPhase = this; } gpsim-0.30.0/src/p16x8x.cc0000664000076400007640000001312113041763613012022 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16x8x // // This file supports: // PIC16C84 // PIC16CR84 // PIC16F84 // PIC16F83 // PIC16CR83 // #include #include #include #include "../config.h" #include "symbol.h" #include "stimuli.h" #include "eeprom.h" #include "p16x8x.h" #include "pic-ioports.h" #include "packages.h" P16X8X::P16X8X(const char *_name, const char *desc) : Pic14Bit(_name,desc) { if(config_modes) config_modes->valid_bits = ConfigMode::CM_FOSC0 | ConfigMode::CM_FOSC1 | ConfigMode::CM_FOSC1x | ConfigMode::CM_WDTE | ConfigMode::CM_PWRTE; } P16X8X::~P16X8X() { delete_file_registers(0x0c, ram_top); if (get_eeprom()) { remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); delete get_eeprom(); } } void P16X8X::create_sfr_map() { Pic14Bit::create_sfr_map(); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x08); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x88, RegisterValue(0,0)); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x09); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x89); } //------------------------------------------------------------------- void P16X8X::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) get_eeprom()->change_rom(address - 0x2100, value); } void P16X8X::create_iopin_map() { package = new Package(18); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 3, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 4, 0); package->assign_pin( 5, 0); package->assign_pin( 6, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin( 7, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(14, 0); package->assign_pin(15, 0); package->assign_pin(16, 0); } void P16X8X::create(int _ram_top) { EEPROM *e; ram_top = _ram_top; create_iopin_map(); _14bit_processor::create(); e = new EEPROM(this); e->initialize(EEPROM_SIZE); e->set_intcon(&intcon_reg); set_eeprom(e); add_file_registers(0x0c, ram_top, 0x80); P16X8X::create_sfr_map(); } //======================================================================== // // Pic 16C84 // Processor * P16C84::construct(const char *name) { P16C84 *p = new P16C84(name); p->create(0x2f); p->create_invalid_registers (); p->create_symbols(); return p; } P16C84::P16C84(const char *_name, const char *desc) : P16X8X(_name,desc) { } void P16C84::create(int ram_top) { P16X8X::create(0x2f); createMCLRPin(4); } //======================================================================== // // Pic 16F84 // Processor * P16F84::construct(const char *name) { P16F84 *p = new P16F84(name); p->create(0x4f); p->create_invalid_registers (); p->create_symbols(); return p; } P16F84::P16F84(const char *_name, const char *desc) : P16X8X(_name,desc) { } void P16F84::create(int ram_top) { P16X8X::create(0x4f); createMCLRPin(4); } //======================================================================== // // Pic 16F83 // P16F83::P16F83(const char *_name, const char *desc) : P16X8X(_name,desc) { } Processor * P16F83::construct(const char *name) { P16F83 *p = new P16F83(name);; p->create(0x2f); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F83::create(int ram_top) { P16X8X::create(0x2f); createMCLRPin(4); } //======================================================================== P16CR83::P16CR83(const char *_name, const char *desc) : P16F83(_name,desc) { } Processor * P16CR83::construct(const char *name) { return 0; } //======================================================================== P16CR84::P16CR84(const char *_name, const char *desc) : P16F84(_name,desc) { } Processor * P16CR84::construct(const char *name) { return 0; } gpsim-0.30.0/src/gpsim_time.h0000664000076400007640000001520013041763613012743 00000000000000/* Copyright (C) 1998-2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __GPSIM_TIME_H__ #define __GPSIM_TIME_H__ #include "breakpoints.h" #include "exports.h" //--------------------------------------------------------- // Cycle Counter // // The cycle counter class is used to coordinate the timing // between the different peripherals within a processor and // in some cases, the timing between several simulated processors // and modules. // // The smallest quantum of simulated time is called a 'cycle'. // The simuluation engine increments a 'Cycle Counter' at quantum // simulation step. Simulation objects that wished to be notified // at a specific instance in time can set a cycle counter break // point that will get invoked whenever the cycle counter reaches // that instance. //------------------------------------------------------------ // // Cycle counter breakpoint list // // This is a friend class to the Cycle Counter class. Its purpose // is to maintain a doubly linked list of cycle counter break // points. class Cycle_Counter_breakpoint_list { public: // This is the value compared to the cycle counter. guint64 break_value; // True when this break is active. bool bActive; // The breakpoint_number is a number uniquely identifying this // cycle counter break point. Note, this number is used only // when the break point was assigned by a user unsigned int breakpoint_number; // If non-null, the TriggerObject will point to an object that will get invoked // when the breakpoint is encountered. TriggerObject *f; // Doubly-linked list mechanics.. // (these will be made private eventually) Cycle_Counter_breakpoint_list *next; Cycle_Counter_breakpoint_list *prev; Cycle_Counter_breakpoint_list *getNext(); Cycle_Counter_breakpoint_list *getPrev(); void clear(); void invoke(); Cycle_Counter_breakpoint_list(); }; class Cycle_Counter { public: #define BREAK_ARRAY_SIZE 4 #define BREAK_ARRAY_MASK (BREAK_ARRAY_SIZE -1) // Largest cycle counter value static const guint64 END_OF_TIME=0xFFFFFFFFFFFFFFFFULL; bool reassigned; // Set true when a break point is reassigned (or deleted) Cycle_Counter_breakpoint_list active, // Head of the active breakpoint linked list inactive; // Head of the inactive one. bool bSynchronous; // a flag that's true when the time per counter tick is constant Cycle_Counter(); ~Cycle_Counter(); void preset(guint64 new_value); // not used currently. /* increment - This inline member function is called once or twice for every simulated instruction. Its purpose is to increment the cycle counter using roll over arithmetic. If there's a breakpoint set on the new value of the cycle counter then the simulation is either stopped or a callback function is invoked. In either case, the break point is cleared. */ inline void increment() { // This has been changed so the cycle counter (value) // is incremented after processing breakpoints // Increment the current cycle then check if // we have a break point set here if(value == break_on_this) breakpoint(); value++; // Note that it's really inefficient to trace every cycle increment. // Instead, we implicitly trace the increments with the instruction traces. } /* advance the Cycle Counter by more than one instruction quantum. This is almost identical to the increment() function except that we allow the counter to be advanced by an arbitrary amount. They're separated only for efficiency reasons. This one runs slower. */ inline void advance(guint64 step) { while (step--) { if (value == break_on_this) breakpoint(); } value++; } // Return the current cycle counter value guint64 get() { return value; } // Return the cycle counter for some time off in the future: guint64 get(double future_time_from_now); bool set_break(guint64 future_cycle, TriggerObject *f=0, unsigned int abp = MAX_BREAKPOINTS); bool set_break_delta(guint64 future_cycle, TriggerObject *f=0, unsigned int abp = MAX_BREAKPOINTS); bool reassign_break(guint64 old_cycle,guint64 future_cycle, TriggerObject *f=0); void clear_current_break(TriggerObject *f=0); void dump_breakpoints(); void clear_break(guint64 at_cycle); void clear_break(TriggerObject *f); void set_instruction_cps(guint64 cps); double instruction_cps() { return m_instruction_cps; } double seconds_per_cycle() { return m_seconds_per_cycle; } private: // The number of instruction cycles that correspond to one second double m_instruction_cps; double m_seconds_per_cycle; guint64 value; // Current value of the cycle counter. guint64 break_on_this; // If there's a pending cycle break point, then it'll be this /* breakpoint when the member function "increment()" encounters a break point, breakpoint() is called. */ void breakpoint(); }; #if defined(IN_MODULE) && defined(_WIN32) // we are in a module: don't access cycles object directly! LIBGPSIM_EXPORT Cycle_Counter &get_cycles(); #else // we are in gpsim: use of get_cycles() is recommended, // even if cycles object can be accessed directly. extern Cycle_Counter cycles; inline Cycle_Counter &get_cycles() { return cycles; } #endif /// The stopwatch object is used to keep track of the amount of /// time between events. It can be controlled either through the /// class API or through its attributes class StopWatch : public TriggerObject { public: StopWatch(); ~StopWatch(); guint64 get(); double get_time(); void set_enable(bool); void set_direction(bool); void set_rollover(guint64); void set_value(guint64); void set_break(bool); void update(); virtual void callback(); virtual void callback_print(); private: Integer *value; Integer *rollover; Boolean *enable; Boolean *direction; bool count_dir; guint64 offset; guint64 break_cycle; }; extern StopWatch *stop_watch; #endif gpsim-0.30.0/src/trace.h0000664000076400007640000004721113063451152011707 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __TRACE_H__ #define __TRACE_H__ #include #include #include "exports.h" #include "gpsim_classes.h" #include "trigger.h" #include "value.h" #include "registers.h" extern "C" { #include "lxt_write.h" } class Processor; class Trace; class TraceFrame; //======================================================================== // A 'TraceObject' is created when the contents of the Trace buffer are // displayed. The TraceObjects are placed into TraceFrames, and eventually // the entire frame is displayed. class TraceObject { public: TraceObject(); virtual ~TraceObject() { } virtual void print(FILE *)=0; virtual void print_frame(TraceFrame *,FILE *); virtual void getState(TraceFrame *); // FIXME Is this even used? }; class CycleTraceObject : public TraceObject { public: CycleTraceObject(); virtual ~CycleTraceObject() { } virtual void print(FILE *); virtual void print_frame(TraceFrame *,FILE *); virtual void getState(TraceFrame *); }; class InvalidTraceObject : public TraceObject { public: explicit InvalidTraceObject(int type); virtual ~InvalidTraceObject() { } virtual void print(FILE *); protected: int mType; }; class ProcessorTraceObject : public TraceObject { public: Processor *cpu; ProcessorTraceObject(Processor *_cpu) : TraceObject() , cpu(_cpu) { } virtual ~ProcessorTraceObject() { } virtual void print(FILE *)=0; }; class ModuleTraceType; class ModuleTraceObject : public TraceObject { public: Module *pModule; ModuleTraceType *pModuleTraceType; unsigned int mTracedData; ModuleTraceObject(Module *_module, ModuleTraceType *pmtt, unsigned int d) : TraceObject() , pModule(_module), pModuleTraceType(pmtt), mTracedData(d) { } virtual ~ModuleTraceObject() { } virtual void print(FILE *); }; class RegisterWriteTraceObject : public ProcessorTraceObject { public: Register *reg; RegisterValue from; RegisterValue to; RegisterWriteTraceObject(Processor *_cpu, Register *_reg, RegisterValue trv); virtual ~RegisterWriteTraceObject() { } virtual void print(FILE *); virtual void getState(TraceFrame *); }; class RegisterReadTraceObject : public RegisterWriteTraceObject { public: RegisterReadTraceObject(Processor *_cpu, Register *_reg, RegisterValue trv); virtual ~RegisterReadTraceObject() { } virtual void print(FILE *); virtual void getState(TraceFrame *); }; class PCTraceObject : public ProcessorTraceObject { public: unsigned int address; PCTraceObject(Processor *_cpu, unsigned int _address); virtual ~PCTraceObject() { } virtual void print(FILE *); virtual void print_frame(TraceFrame *,FILE *); }; //======================================================================== // The TraceType class is the base class for the various trace types that // are supported by gpsim. In general, when a trace type is created, // a 32 bit identifier is created. The upper byte of this identifier is // the "type" of the trace and is dynamically allocated. The lower 24 // bits of this identifer are 0. When a TraceType is traced, the lower // 24 bits are filled with the information that is to be recorded in // the trace buffer. The whole 32 bits are then written to the trace buffer // array. class TraceType { public: TraceType(unsigned int nTraceEntries, const char *desc); virtual ~TraceType() { } void setType(unsigned int t) { mType = t;} // The actual type of the TraceType is an 8-bit field in the // upper 32-bits of an unsigned integer. A TraceType can have // more than one type, although the types are consecutive. unsigned int type(unsigned int iType=0) { return (iType= (mType&tMask)) && ((aType&tMask) <= ((mType&tMask) + (mSize<<24))); } virtual int bitsTraced() { return 24; } virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); // Debugging - provide a way to see the TraceTypes that have been allocated. virtual void showInfo(); const char *cpDescription(); private: unsigned int mType; // The integer type is dynamically // assigned by the Trace class. unsigned int mSize; // The number of positions this // type occupies protected: const char *mpDescription; // }; class CycleTraceType : public TraceType { public: explicit CycleTraceType(unsigned int nTraceEntries); virtual ~CycleTraceType() { } virtual TraceObject *decode(unsigned int tbi); virtual bool isFrameBoundary(); virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); virtual int entriesUsed(Trace *,unsigned int tbi); }; class ModuleTraceType : public TraceType { public: Module *pModule; ModuleTraceType(Module *_pModule, unsigned int nTraceEntries, const char *desc); virtual ~ModuleTraceType() { } virtual TraceObject *decode(unsigned int tbi); virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); }; class ProcessorTraceType : public TraceType { public: Processor *cpu; ProcessorTraceType(Processor *_cpu, unsigned int nTraceEntries, const char *pDesc); virtual ~ProcessorTraceType() { } virtual TraceObject *decode(unsigned int tbi) = 0; }; class PCTraceType : public ProcessorTraceType { public: PCTraceType(Processor *_cpu, unsigned int nTraceEntries); virtual ~PCTraceType() { } virtual TraceObject *decode(unsigned int tbi); virtual bool isFrameBoundary() { return true; } virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); }; class RegisterWriteTraceType : public ProcessorTraceType { public: RegisterWriteTraceType(Processor *_cpu, unsigned int nTraceEntries); virtual ~RegisterWriteTraceType() { } virtual TraceObject *decode(unsigned int tbi); virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); }; class RegisterReadTraceType : public ProcessorTraceType { public: RegisterReadTraceType(Processor *_cpu, unsigned int nTraceEntries); virtual ~RegisterReadTraceType() { } virtual TraceObject *decode(unsigned int tbi); virtual int dump_raw(Trace *,unsigned tbi, char *buf, int bufsize); }; // Trace Type for Resets class ResetTraceObject : public ProcessorTraceObject { public: ResetTraceObject(Processor *_cpu, RESET_TYPE r); virtual ~ResetTraceObject() { } virtual void print(FILE *fp); protected: RESET_TYPE m_reset; }; class ResetTraceType : public ProcessorTraceType { public: explicit ResetTraceType(Processor *_cpu); virtual ~ResetTraceType() { } TraceObject *decode(unsigned int tbi); void record(RESET_TYPE r); int dump_raw(Trace *pTrace,unsigned int tbi, char *buf, int bufsize); unsigned int m_uiTT; }; //======================================================================== // TraceFrame // // A trace frame collects all trace items that occurred at the same instant // of time. When the trace buffer is decoded, markers will be examined // to determine the frame boundaries. class TraceFrame { public: list traceObjects; guint64 cycle_time; TraceFrame(); virtual ~TraceFrame(); virtual void add(TraceObject *to); virtual void print(FILE *); virtual void update_state(); }; //----------------------------------------------------------- class TraceRawLog { public: char *log_filename; FILE *log_file; void log(); void enable(const char*); void disable(); TraceRawLog(); ~TraceRawLog(); }; //------------------------------------------------------------ class traceValue : public gpsimObject { public: traceValue(); virtual void put_value(unsigned int new_value) {}; virtual unsigned int get_value(); }; //--------------------------------------------------------- // Class for trace buffer class Trace { public: enum eTraceTypes { NOTHING = 0x3fffffff, LAST_TRACE_TYPE = (1<<24), TYPE_MASK = (0xff<<24), CYCLE_COUNTER_LO = (0x80<<24), CYCLE_COUNTER_MI = (0x40<<24), CYCLE_COUNTER_HI = (0xC0<<24) }; #define TRACE_BUFFER_SIZE (1<<12) #define TRACE_BUFFER_MASK (TRACE_BUFFER_SIZE-1) #define TRACE_BUFFER_NEAR_FULL (TRACE_BUFFER_SIZE * 3 /4) #define TRACE_STRING_BUFFER 50 unsigned int trace_buffer[TRACE_BUFFER_SIZE]; unsigned int trace_index; unsigned int trace_flag; bool bLogging; TraceRawLog logger; traceValue trace_value; // When interfaced with a gui, the contents of the trace // buffer are decoded one line-at-a-time, copied to the string_buffer // and sent to the gui via xref interface (actually, the gui // is notified that new data is available in the string_buffer). XrefObject *xref; char string_buffer[TRACE_STRING_BUFFER]; guint64 string_cycle; // The cycle corresponding to the decoded string unsigned int string_index; // The trace buffer index corresponding " " Processor *cpu; TraceFrame *current_frame; guint64 current_cycle_time; // used when decoding the trace buffer. list traceFrames; unsigned int lastTraceType; unsigned int lastSubTraceType; Trace(); ~Trace(); // trace raw allows any value to be written to the trace buffer. // This is useful for modules that wish to trace things, but do // not wish to modify the Trace class. inline void raw (unsigned int ui) { trace_buffer[trace_index] = ui; trace_index = (trace_index + 1) & TRACE_BUFFER_MASK; } /* inline void opcode_write (unsigned int address, unsigned int opcode) { trace_buffer[trace_index] = OPCODE_WRITE | (address & 0xffffff); trace_index = (trace_index + 1) & TRACE_BUFFER_MASK; trace_buffer[trace_index] = OPCODE_WRITE | (opcode & 0xffff); trace_index = (trace_index + 1) & TRACE_BUFFER_MASK; } */ inline void cycle_counter (guint64 cc) { // The 64 bit cycle counter requires three 24 bit traces. trace_buffer[trace_index] = (unsigned int)(CYCLE_COUNTER_LO | (cc & 0xffffff)); trace_index = (trace_index + 1) & TRACE_BUFFER_MASK; trace_buffer[trace_index] = (unsigned int)(CYCLE_COUNTER_MI | (cc>>24)); trace_index = (trace_index + 1) & TRACE_BUFFER_MASK; trace_buffer[trace_index] = (unsigned int)(CYCLE_COUNTER_HI | (cc>>48)); trace_index = (trace_index + 1) & TRACE_BUFFER_MASK; } inline bool near_full() { return (trace_index > TRACE_BUFFER_NEAR_FULL); } void switch_cpus(Processor *new_cpu) {cpu = new_cpu;}; int dump (int n=0, FILE *out_stream=0); void dump_last_instruction(); int dump1(unsigned int,char *, int); void dump_raw(int n); // tbi - trace buffer index masking. inline unsigned int tbi(unsigned int index) { return index & TRACE_BUFFER_MASK; } // inRange - returns true if the trace index i is between the // indices of low and high. // It's assumed that the range does not exceed half of the trace buffer bool inRange(unsigned int i, unsigned int low, unsigned int high) { i = tbi(i); if( low < high) return (i >= low && i <= high); // Looks like the range straddles the roll over boundary. return (i >= low || i <= high); } // get() return the trace entry at 'index' inline unsigned int operator [] (unsigned int index) { return trace_buffer[tbi(index)]; } unsigned int get(unsigned int index) { return trace_buffer[tbi(index)]; } // type() - return the trace type at 'index' unsigned int type(unsigned int index); // A gpsim clock cycle takes two consecutive trace buffer entries. // The is_cycle_trace() member function will examine the trace // buffer to determine if the two traces starting at 'index' are // a cycle trace. int is_cycle_trace(unsigned int index, guint64 *cvt_cycle); // When logging is enabled, the entire trace buffer will be copied to a file. void enableLogging(const char *fname); void disableLogging(); unsigned int allocateTraceType(TraceType *); // Trace frame manipulation void addFrame(TraceFrame *newFrame); void addToCurrentFrame(TraceObject *to); void deleteTraceFrame(); void printTraceFrame(FILE *); // Display information about allocated traces. void showInfo(); }; #if defined(IN_MODULE) && defined(_WIN32) // we are in a module: don't access trace object directly! LIBGPSIM_EXPORT Trace & get_trace(); #else // we are in gpsim: use of get_trace() is recommended, // even if trace object can be accessed directly. extern Trace trace; inline Trace &get_trace() { return trace; } #endif //----------------------------------------------------------- #define TRACE_FILE_FORMAT_ASCII 0 #define TRACE_FILE_FORMAT_LXT 1 class TraceLog : public TriggerObject { public: bool logging; bool lograw; int items_logged; char *log_filename; FILE *log_file; Processor *cpu; unsigned int last_trace_index; Trace buffer; int file_format; struct lt_trace *lxtp; struct lt_symbol *symp; TraceLog(); ~TraceLog(); virtual void callback(); void enable_logging(const char *new_filename=0, int format=TRACE_FILE_FORMAT_ASCII); void disable_logging(); void switch_cpus(Processor *new_cpu); void open_logfile(const char *new_fname, int format); void close_logfile(); void write_logfile(); void status(); void lxt_trace(unsigned int address, unsigned int value, guint64 cc); void register_read(Register *, guint64 cc); void register_write(Register *, guint64 cc); void register_read_value(Register *, guint64 cc); void register_write_value(Register *, guint64 cc); }; #if defined(_WIN32) // we are in a module: don't access trace_log object directly! LIBGPSIM_EXPORT TraceLog & GetTraceLog(); #else // we are in gpsim: use of GetTraceLog() is recommended, // even if trace_log object can be accessed directly. extern TraceLog trace_log; inline TraceLog &GetTraceLog() { return trace_log; } #endif //----------------------------------------------------------- class ProfileKeeper : public TriggerObject { public: bool enabled; Processor *cpu; unsigned int last_trace_index; unsigned int instruction_address; unsigned int trace_pc_value; ProfileKeeper(); ~ProfileKeeper(); void catchup(); virtual void callback(); void enable_profiling(); void disable_profiling(); void switch_cpus(Processor *new_cpu); }; extern ProfileKeeper profile_keeper; /********************************************************************** * boolean event logging * * The boolean event logger is a class for logging the time * of boolean (i.e. 0/1) events. * * The class is designed to be efficient for both logging events and * for accessing events that have already been logged. The events * are stored in several small buffers that are linked together with * binary trees. Each small buffer is linear, i.e. an array. Each * element of the array stores the time when the event occurred. * The state of the event is encoded in the position of the array. * In other words, "high" events are at the odd indices of the array * and "low" ones at the even ones. * * Each small buffer is associated with a contiguous time span. The * start and end of this span is recorded so that one can quickly * ascertain if a certain time instant resideds in the buffer. * * The binary tree is fairly standard. A single top node records three * numbers: the start time for the left child, the end time for the * left child (which by default is the start time for the right child) * and the end time for the right child. The nodes of left and right * children are similar to the parents. To find which small buffer * contains an event for a certain time, one simply starts at the * top of the tree and traverses the nodes until a leaf is reached. * A leaf, of course, is where the data is stored. * * The time for the event comes from gpsim's global cycle counter. * This counter is 64-bits wide. The buffers that store the time however, * are only 32-bits wide. There are two simple tricks employed to get * around this problem. First, full 64-bit time for the first event * is recorded. All subsequent events are 32-bit offsets from this. * Second, to ensure that the 32-bit offset does not wrap around, the * boolean event logger will set a cycle counter break point that is * less than 2^32 cycles in the future. If this break point is encountered * before the buffer fills, then this buffer is closed and added to the * binary and a new buffer is started. * * Repeated events are not logged. E.g.. if two 1's are logged, the * second one is ignored. * */ class BoolEventBuffer : public TriggerObject { public: guint32 index; // Index into the buffer guint64 *buffer; // Where the time is stored guint32 max_events; // Size of the event buffer guint64 start_time; // time of the first event guint64 future_cycle; // time at which the buffer can store no more data. bool bInitialState; // State when started. bool bActive; // True if the buffer is enabled for storing. bool bFull; // True if the buffer has been filled. BoolEventBuffer(bool _initial_state, guint32 _max_events = 4096); ~BoolEventBuffer(); unsigned int get_index(guint64 event_time); void activate(bool _initial_state); void deactivate(); void callback(); void callback_print(); inline bool event(bool state); inline bool isActive() { return bActive; } inline bool isFull() { return (index < max_events); } /* get_index - return the current index This is used by the callers to record where in the event buffer a specific event is stored. (e.g. The start bit of a usart bit stream.) */ inline unsigned int get_index() { return index; } bool get_event(int index) { return bool(index & 1) ^ bInitialState; } bool get_state(guint64 event_time) { return get_event(get_index(event_time)); } int get_edges(guint64 start_time, guint64 end_time) { return ( get_index(end_time) - get_index(start_time) ); } }; #endif gpsim-0.30.0/src/p18x.cc0000664000076400007640000026006613116645075011564 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2010 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "../config.h" #include "p18x.h" #include "pic-ioports.h" #include "packages.h" #include "stimuli.h" #include "symbol.h" /* Config Word defines */ #define MCLRE (1<<7) #define P2BMX (1<<5) #define T3CMX (1<<4) #define HFOFST (1<<3) #define LPT1OSC (1<<2) #define CCP3MX (1<<2) #define PBADEN (1<<1) #define CCP2MX (1<<0) /** * A special variant of the Config3H class that includes all the bits that * config register does on PIC18F2x21 and derivatives (including 4620). Note * that the "set" method requires that the parent processor is an instance * of the P18F2x21 class (or a derived variant thereof). */ class Config3H_2x21 : public ConfigWord { public: Config3H_2x21(_16bit_processor *pCpu, unsigned int addr, unsigned int def_val) : ConfigWord("CONFIG3H", ~def_val & 0xfff, "Config Reg 3H", pCpu, addr) { set(def_val); if (verbose) cout << "Config3H_2x21\n"; } virtual void set(gint64 v) { gint64 i64; get(i64); int diff = (i64 ^ v) &0xfff; Integer::set(v); if (m_pCpu) { P18F2x21 *pCpu21 = (P18F2x21*)m_pCpu; if (diff & MCLRE) (v & MCLRE) ? m_pCpu->assignMCLRPin(1) : m_pCpu->unassignMCLRPin(); if ( pCpu21->adcon1 ) { unsigned int pcfg = (v & PBADEN) ? 0 : (ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2); pCpu21->adcon1->por_value=RegisterValue(pcfg,0); } if ( diff & CCP2MX ) { if ( v & CCP2MX ) pCpu21->ccp2con.setIOpin(&((*pCpu21->m_portc)[1])); else pCpu21->ccp2con.setIOpin(&((*pCpu21->m_portb)[3])); } } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; snprintf(buff, sizeof(buff), "$%04x\n" " MCLRE=%d - %s\n" " LPT1OSC=%d - Timer1 configured for %s operation\n" " PBADEN=%d - PORTB<4:0> pins %s\n" " CCP2MX=%d - CCP2 I/O is muxed with %s\n", i, (i & MCLRE) ? 1:0, (i & MCLRE) ? "Pin is MCLRE" : "Pin is RE3", (i & LPT1OSC) ? 1:0, (i & LPT1OSC) ? "low-power" : "higher power", (i & PBADEN) ?1:0, (i & PBADEN) ? "analog on Reset" : "digital I/O on reset", (i & CCP2MX) ? 1:0, (i & CCP2MX) ? "RC1" : "RB3" ); return string(buff); } }; //---------------------------------------------------------------------- // For only MCLRE in CONFIG3H and using pin 4 (RA5) // class Config3H_1x20 : public ConfigWord { public: Config3H_1x20(_16bit_processor *pCpu, unsigned int addr, unsigned int def_val) : ConfigWord("CONFIG3H", ~def_val & 0xfff, "Config Reg 3H", pCpu, addr) { set(def_val); } virtual void set(gint64 v) { gint64 i64; get(i64); int diff = (i64 ^ v) &0xfff; Integer::set(v); if (m_pCpu) { if (diff & MCLRE) (v & MCLRE) ? m_pCpu->assignMCLRPin(4) : m_pCpu->unassignMCLRPin(); } } virtual string toString() { gint64 i64; get(i64); int i = i64 &0xfff; char buff[256]; snprintf(buff, sizeof(buff), "$%04x\n" " MCLRE=%d - %s\n", i, (i & MCLRE) ? 1:0, (i & MCLRE) ? "Pin is MCLRE" : "Pin is RA5" ); return string(buff); } }; //======================================================================== // // Pic 18C2x2 // void P18C2x2::create() { if(verbose) cout << "P18C2x2::create\n"; create_iopin_map(); _16bit_compat_adc::create(); osccon->value = RegisterValue(0x00,0); osccon->por_value = RegisterValue(0x00,0); init_pir2(pir2, PIR2v2::TMR3IF); } //------------------------------------------------------------------------ void P18C2x2::create_iopin_map() { package = new Package(28); if(!package) return; // Build the links between the I/O Ports and their tris registers. //package->assign_pin(1, 0); // /MCLR createMCLRPin(1); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(8, 0); // Vss package->assign_pin(9, 0); // OSC1 package->assign_pin(10, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, 0); // Vss package->assign_pin(20, 0); // Vdd package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); tmr1l.setIOpin(&(*m_portc)[0]); ssp.initialize(&pir_set_def, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); set_osc_pin_Number(0,9, NULL); set_osc_pin_Number(1,10, &(*m_porta)[6]); //1portc.usart = &usart16; } void P18C2x2::create_symbols() { if(verbose) cout << "P18C2x2 create symbols\n"; _16bit_processor::create_symbols(); } P18C2x2::P18C2x2(const char *_name, const char *desc) : _16bit_compat_adc(_name,desc) { if(verbose) cout << "18c2x2 constructor, type = " << isa() << '\n'; } //------------------------------------------------------------------------ // // P18C242 // P18C242::P18C242(const char *_name, const char *desc) : P18C2x2(_name,desc) { if(verbose) cout << "18c242 constructor, type = " << isa() << '\n'; } void P18C242::create() { if(verbose) cout << " 18c242 create \n"; P18C2x2::create(); } Processor * P18C242::construct(const char *name) { P18C242 *p = new P18C242(name); if(verbose) cout << " 18c242 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18C252 // P18C252::P18C252(const char *_name, const char *desc) : P18C242(_name,desc) { if(verbose) cout << "18c252 constructor, type = " << isa() << '\n'; } void P18C252::create() { if(verbose) cout << " 18c252 create \n"; P18C242::create(); } Processor * P18C252::construct(const char *name) { P18C252 *p = new P18C252(name);; if(verbose) cout << " 18c252 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //======================================================================== // // Pic 18C4x2 // void P18C4x2::create() { if(verbose) cout << "P18C4x2::create\n"; create_iopin_map(); _16bit_compat_adc::create(); osccon->value = RegisterValue(0x00,0); osccon->por_value = RegisterValue(0x00,0); } //------------------------------------------------------------------------ void P18C4x2::create_iopin_map() { package = new Package(40); if(!package) return; createMCLRPin(1); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin( 8, m_porte->addPin(new IO_bi_directional("porte0"),0)); package->assign_pin( 9, m_porte->addPin(new IO_bi_directional("porte1"),1)); package->assign_pin(10, m_porte->addPin(new IO_bi_directional("porte2"),2)); package->assign_pin(11, 0); package->assign_pin(12, 0); package->assign_pin(13, new IOPIN("OSC1")); package->assign_pin(14, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(23, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(24, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(25, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(26, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, m_portd->addPin(new IO_bi_directional("portd0"),0)); package->assign_pin(20, m_portd->addPin(new IO_bi_directional("portd1"),1)); package->assign_pin(21, m_portd->addPin(new IO_bi_directional("portd2"),2)); package->assign_pin(22, m_portd->addPin(new IO_bi_directional("portd3"),3)); package->assign_pin(27, m_portd->addPin(new IO_bi_directional("portd4"),4)); package->assign_pin(28, m_portd->addPin(new IO_bi_directional("portd5"),5)); package->assign_pin(29, m_portd->addPin(new IO_bi_directional("portd6"),6)); package->assign_pin(30, m_portd->addPin(new IO_bi_directional("portd7"),7)); package->assign_pin(31, 0); package->assign_pin(32, 0); package->assign_pin(33, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(34, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(35, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(36, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(38, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(39, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(40, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); psp.initialize(&pir_set_def, // PIR m_portd, // Parallel port m_trisd, // Parallel tris m_trise, // Control tris &(*m_porte)[0], // NOT RD &(*m_porte)[1], // NOT WR &(*m_porte)[2]); // NOT CS tmr1l.setIOpin(&(*m_portc)[0]); ssp.initialize(&pir_set_def, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); //1portc.ccp1con = &ccp1con; //1portc.usart = &usart16; } void P18C4x2::create_symbols() { if(verbose) cout << "P18C4x2 create symbols\n"; _16bit_processor::create_symbols(); } P18C4x2::P18C4x2(const char *_name, const char *desc) : _16bit_compat_adc(_name,desc) { if(verbose) cout << "18c4x2 constructor, type = " << isa() << '\n'; m_portd = new PicPSP_PortRegister(this,"portd","",8,0xff); m_trisd = new PicTrisRegister(this,"trisd","", (PicPortRegister *)m_portd, false); m_latd = new PicLatchRegister(this,"latd","",m_portd); m_porte = new PicPortRegister(this,"porte","",8,0x07); m_trise = new PicPSP_TrisRegister(this,"trise","", m_porte, false); m_late = new PicLatchRegister(this,"late","",m_porte); } P18C4x2::~P18C4x2() { delete_sfr_register(m_portd); delete_sfr_register(m_porte); delete_sfr_register(m_latd); delete_sfr_register(m_late); delete_sfr_register(m_trisd); delete_sfr_register(m_trise); } void P18C4x2::create_sfr_map() { if(verbose) cout << "create_sfr_map P18C4x2\n"; _16bit_processor::create_sfr_map(); RegisterValue porv(0,0); // Assume this should follow the old behaviour as it's an old chip osccon->por_value = porv; add_sfr_register(m_portd, 0xf83,porv); add_sfr_register(m_porte, 0xf84,porv); add_sfr_register(m_latd, 0xf8c,porv); add_sfr_register(m_late, 0xf8d,porv); add_sfr_register(m_trisd, 0xf95,RegisterValue(0xff,0)); add_sfr_register(m_trise, 0xf96,RegisterValue(0x07,0)); // rest of configureation in parent class adcon1->setNumberOfChannels(8); adcon1->setIOPin(5, &(*m_porte)[0]); adcon1->setIOPin(6, &(*m_porte)[1]); adcon1->setIOPin(7, &(*m_porte)[2]); init_pir2(pir2, PIR2v2::TMR3IF); tmr3l.setIOpin(&(*m_portc)[0]); //1 usart16.initialize_16(this,&pir_set_def,&portc); } //------------------------------------------------------------------------ // // P18C442 // P18C442::P18C442(const char *_name, const char *desc) : P18C4x2(_name,desc) { if(verbose) cout << "18c442 constructor, type = " << isa() << '\n'; } void P18C442::create() { if(verbose) cout << " 18c442 create \n"; P18C4x2::create(); cout << " 18c442 create \n"; set_osc_pin_Number(0,13, NULL); set_osc_pin_Number(1,14, &(*m_porta)[6]); } Processor * P18C442::construct(const char *name) { P18C442 *p = new P18C442(name); if(verbose) cout << " 18c442 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18C452 // P18C452::P18C452(const char *_name, const char *desc) : P18C442(_name,desc) { if(verbose) cout << "18c452 constructor, type = " << isa() << '\n'; } void P18C452::create() { if(verbose) cout << " 18c452 create \n"; P18C442::create(); } Processor * P18C452::construct(const char *name) { P18C452 *p = new P18C452(name); if(verbose) cout << " 18c452 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F242 // P18F242::P18F242(const char *_name, const char *desc) : P18C242(_name,desc) { if(verbose) cout << "18f242 constructor, type = " << isa() << '\n'; } void P18F242::create() { if(verbose) cout << " 18f242 create \n"; tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, false); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); P18C242::create(); } Processor * P18F242::construct(const char *name) { P18F242 *p = new P18F242(name); if(verbose) cout << " 18F242 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F252 // P18F252::P18F252(const char *_name, const char *desc) : P18F242(_name,desc) { if(verbose) cout << "18f252 constructor, type = " << isa() << '\n'; } void P18F252::create() { if(verbose) cout << " 18f252 create \n"; P18F242::create(); } Processor * P18F252::construct(const char *name) { P18F252 *p = new P18F252(name); if(verbose) cout << " 18F252 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F442 // P18F442::P18F442(const char *_name, const char *desc) : P18C442(_name,desc) { if(verbose) cout << "18f442 constructor, type = " << isa() << '\n'; } void P18F442::create() { if(verbose) cout << " 18f442 create \n"; tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, false); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); P18C442::create(); } Processor * P18F442::construct(const char *name) { P18F442 *p = new P18F442(name); if(verbose) cout << " 18F442 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F248 // P18F248::P18F248(const char *_name, const char *desc) : P18F242(_name,desc) { if(verbose) cout << "18f248 constructor, type = " << isa() << '\n'; } void P18F248::create() { if(verbose) cout << " 18f248 create \n"; P18F242::create(); } Processor * P18F248::construct(const char *name) { P18F248 *p = new P18F248(name); if(verbose) cout << " 18F248 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F258 // P18F258::P18F258(const char *_name, const char *desc) : P18F252(_name,desc) { if(verbose) cout << "18f258 constructor, type = " << isa() << '\n'; } void P18F258::create() { if(verbose) cout << " 18f258 create \n"; P18F252::create(); } Processor * P18F258::construct(const char *name) { P18F258 *p = new P18F258(name); if(verbose) cout << " 18F258 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F448 // P18F448::P18F448(const char *_name, const char *desc) : P18F442(_name,desc) { if(verbose) cout << "18f448 constructor, type = " << isa() << '\n'; } void P18F448::create() { if(verbose) cout << " 18f448 create \n"; P18F442::create(); } Processor * P18F448::construct(const char *name) { P18F448 *p = new P18F448(name); if(verbose) cout << " 18F448 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F452 // P18F452::P18F452(const char *_name, const char *desc) : P18F442(_name,desc) { if(verbose) cout << "18f452 constructor, type = " << isa() << '\n'; } void P18F452::create() { if(verbose) cout << " 18f452 create \n"; P18F442::create(); } Processor * P18F452::construct(const char *name) { P18F452 *p = new P18F452(name); if(verbose) cout << " 18F452 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F458 // P18F458::P18F458(const char *_name, const char *desc) : P18F452(_name,desc) { if(verbose) cout << "18f458 constructor, type = " << isa() << '\n'; } void P18F458::create() { if(verbose) cout << " 18f458 create \n"; P18F452::create(); } Processor * P18F458::construct(const char *name) { P18F458 *p = new P18F458(name); if(verbose) cout << " 18F458 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F2455 - 28 pin // P18F2455::P18F2455(const char *_name, const char *desc) : P18F2x21(_name,desc), ufrml(this, "ufrml", "USB Frame Number register Low" ), ufrmh(this, "ufrmh", "USB Frame Number register High" ), uir (this, "uir" , "USB Interrupt Status register" ), uie (this, "uie" , "USB Interrupt Enable register" ), ueir (this, "ueir" , "USB Error Interrupt Status register"), ueie (this, "ueie" , "USB Error Interrupt Enable register"), ustat(this, "ustat", "USB Transfer Status register" ), ucon (this, "ucon" , "USB Control register" ), uaddr(this, "uaddr", "USB Device Address register" ), ucfg (this, "ucfg" , "USB Configuration register" ), uep0 (this, "uep0" , "USB Endpoint 0 Enable register" ), uep1 (this, "uep1" , "USB Endpoint 1 Enable register" ), uep2 (this, "uep2" , "USB Endpoint 2 Enable register" ), uep3 (this, "uep3" , "USB Endpoint 3 Enable register" ), uep4 (this, "uep4" , "USB Endpoint 4 Enable register" ), uep5 (this, "uep5" , "USB Endpoint 5 Enable register" ), uep6 (this, "uep6" , "USB Endpoint 6 Enable register" ), uep7 (this, "uep7" , "USB Endpoint 7 Enable register" ), uep8 (this, "uep8" , "USB Endpoint 8 Enable register" ), uep9 (this, "uep9" , "USB Endpoint 9 Enable register" ), uep10(this, "uep10", "USB Endpoint 10 Enable register" ), uep11(this, "uep11", "USB Endpoint 11 Enable register" ), uep12(this, "uep12", "USB Endpoint 12 Enable register" ), uep13(this, "uep13", "USB Endpoint 13 Enable register" ), uep14(this, "uep14", "USB Endpoint 14 Enable register" ), uep15(this, "uep15", "USB Endpoint 15 Enable register" ) { cout << "\nP18F2455 does not support USB registers and functionality\n\n"; if(verbose) cout << "18f2455 constructor, type = " << isa() << '\n'; } P18F2455::~P18F2455() { remove_sfr_register(&ufrml); remove_sfr_register(&ufrmh); remove_sfr_register(&uir ); remove_sfr_register(&uie ); remove_sfr_register(&ueir ); remove_sfr_register(&ueie ); remove_sfr_register(&ustat); remove_sfr_register(&ucon ); remove_sfr_register(&uaddr); remove_sfr_register(&ucfg ); remove_sfr_register(&uep0 ); remove_sfr_register(&uep1 ); remove_sfr_register(&uep2 ); remove_sfr_register(&uep3 ); remove_sfr_register(&uep4 ); remove_sfr_register(&uep5 ); remove_sfr_register(&uep6 ); remove_sfr_register(&uep7 ); remove_sfr_register(&uep8 ); remove_sfr_register(&uep9 ); remove_sfr_register(&uep10); remove_sfr_register(&uep11); remove_sfr_register(&uep12); remove_sfr_register(&uep13); remove_sfr_register(&uep14); remove_sfr_register(&uep15); } void P18F2455::create_sfr_map() { if(verbose) cout << " 18f2455 create_sfr_map \n"; P18F2x21::create_sfr_map(); package->destroy_pin(14); package->assign_pin(14, 0, false); // Vusb /* The MSSP/I2CC pins are different on this chip. */ ssp.initialize(&pir_set_def, // PIR &(*m_portb)[1], // SCK &(*m_porta)[5], // SS &(*m_portc)[7], // SDO &(*m_portb)[0], // SDI m_trisb, // i2c tris port SSP_TYPE_MSSP ); add_sfr_register(&ufrml,0x0F66, RegisterValue(0,0),"ufrm"); add_sfr_register(&ufrmh,0X0F67, RegisterValue(0,0)); add_sfr_register(&uir ,0x0F68, RegisterValue(0,0)); add_sfr_register(&uie ,0x0F69, RegisterValue(0,0)); add_sfr_register(&ueir ,0x0F6A, RegisterValue(0,0)); add_sfr_register(&ueie ,0x0F6B, RegisterValue(0,0)); add_sfr_register(&ustat,0X0F6C, RegisterValue(0,0)); add_sfr_register(&ucon ,0x0F6D, RegisterValue(0,0)); add_sfr_register(&uaddr,0X0F6E, RegisterValue(0,0)); add_sfr_register(&ucfg ,0x0F6F, RegisterValue(0,0)); add_sfr_register(&uep0 ,0x0F70, RegisterValue(0,0)); add_sfr_register(&uep1 ,0x0F71, RegisterValue(0,0)); add_sfr_register(&uep2 ,0x0F72, RegisterValue(0,0)); add_sfr_register(&uep3 ,0x0F73, RegisterValue(0,0)); add_sfr_register(&uep4 ,0x0F74, RegisterValue(0,0)); add_sfr_register(&uep5 ,0x0F75, RegisterValue(0,0)); add_sfr_register(&uep6 ,0x0F76, RegisterValue(0,0)); add_sfr_register(&uep7 ,0x0F77, RegisterValue(0,0)); add_sfr_register(&uep8 ,0x0F78, RegisterValue(0,0)); add_sfr_register(&uep9 ,0x0F79, RegisterValue(0,0)); add_sfr_register(&uep10,0x0F7A, RegisterValue(0,0)); add_sfr_register(&uep11,0x0F7B, RegisterValue(0,0)); add_sfr_register(&uep12,0x0F7C, RegisterValue(0,0)); add_sfr_register(&uep13,0x0F7D, RegisterValue(0,0)); add_sfr_register(&uep14,0x0F7E, RegisterValue(0,0)); add_sfr_register(&uep15,0x0F7F, RegisterValue(0,0)); } Processor * P18F2455::construct(const char *name) { P18F2455 *p = new P18F2455(name); if(verbose) cout << " 18F2455 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F2550 - 28 pin // P18F2550::P18F2550(const char *_name, const char *desc) : P18F2x21(_name,desc), ufrml(this, "ufrml", "USB Frame Number register Low" ), ufrmh(this, "ufrmh", "USB Frame Number register High" ), uir (this, "uir" , "USB Interrupt Status register" ), uie (this, "uie" , "USB Interrupt Enable register" ), ueir (this, "ueir" , "USB Error Interrupt Status register"), ueie (this, "ueie" , "USB Error Interrupt Enable register"), ustat(this, "ustat", "USB Transfer Status register" ), ucon (this, "ucon" , "USB Control register" ), uaddr(this, "uaddr", "USB Device Address register" ), ucfg (this, "ucfg" , "USB Configuration register" ), uep0 (this, "uep0" , "USB Endpoint 0 Enable register" ), uep1 (this, "uep1" , "USB Endpoint 1 Enable register" ), uep2 (this, "uep2" , "USB Endpoint 2 Enable register" ), uep3 (this, "uep3" , "USB Endpoint 3 Enable register" ), uep4 (this, "uep4" , "USB Endpoint 4 Enable register" ), uep5 (this, "uep5" , "USB Endpoint 5 Enable register" ), uep6 (this, "uep6" , "USB Endpoint 6 Enable register" ), uep7 (this, "uep7" , "USB Endpoint 7 Enable register" ), uep8 (this, "uep8" , "USB Endpoint 8 Enable register" ), uep9 (this, "uep9" , "USB Endpoint 9 Enable register" ), uep10(this, "uep10", "USB Endpoint 10 Enable register" ), uep11(this, "uep11", "USB Endpoint 11 Enable register" ), uep12(this, "uep12", "USB Endpoint 12 Enable register" ), uep13(this, "uep13", "USB Endpoint 13 Enable register" ), uep14(this, "uep14", "USB Endpoint 14 Enable register" ), uep15(this, "uep15", "USB Endpoint 15 Enable register" ) { cout << "\nP18F2550 does not support USB registers and functionality\n\n"; if(verbose) cout << "18f2550 constructor, type = " << isa() << '\n'; } P18F2550::~P18F2550() { remove_sfr_register(&ufrml); remove_sfr_register(&ufrmh); remove_sfr_register(&uir ); remove_sfr_register(&uie ); remove_sfr_register(&ueir ); remove_sfr_register(&ueie ); remove_sfr_register(&ustat); remove_sfr_register(&ucon ); remove_sfr_register(&uaddr); remove_sfr_register(&ucfg ); remove_sfr_register(&uep0 ); remove_sfr_register(&uep1 ); remove_sfr_register(&uep2 ); remove_sfr_register(&uep3 ); remove_sfr_register(&uep4 ); remove_sfr_register(&uep5 ); remove_sfr_register(&uep6 ); remove_sfr_register(&uep7 ); remove_sfr_register(&uep8 ); remove_sfr_register(&uep9 ); remove_sfr_register(&uep10); remove_sfr_register(&uep11); remove_sfr_register(&uep12); remove_sfr_register(&uep13); remove_sfr_register(&uep14); remove_sfr_register(&uep15); } void P18F2550::create_sfr_map() { if(verbose) cout << " 18f2550 create_sfr_map \n"; P18F2x21::create_sfr_map(); package->destroy_pin(14); package->assign_pin(14, 0, false); // Vusb /* The MSSP/I2CC pins are different on this chip. */ ssp.initialize(&pir_set_def, // PIR &(*m_portb)[1], // SCK &(*m_porta)[5], // SS &(*m_portc)[7], // SDO &(*m_portb)[0], // SDI m_trisb, // i2c tris port SSP_TYPE_MSSP ); add_sfr_register(&ufrml,0x0F66, RegisterValue(0,0),"ufrm"); add_sfr_register(&ufrmh,0X0F67, RegisterValue(0,0)); add_sfr_register(&uir ,0x0F68, RegisterValue(0,0)); add_sfr_register(&uie ,0x0F69, RegisterValue(0,0)); add_sfr_register(&ueir ,0x0F6A, RegisterValue(0,0)); add_sfr_register(&ueie ,0x0F6B, RegisterValue(0,0)); add_sfr_register(&ustat,0X0F6C, RegisterValue(0,0)); add_sfr_register(&ucon ,0x0F6D, RegisterValue(0,0)); add_sfr_register(&uaddr,0X0F6E, RegisterValue(0,0)); add_sfr_register(&ucfg ,0x0F6F, RegisterValue(0,0)); add_sfr_register(&uep0 ,0x0F70, RegisterValue(0,0)); add_sfr_register(&uep1 ,0x0F71, RegisterValue(0,0)); add_sfr_register(&uep2 ,0x0F72, RegisterValue(0,0)); add_sfr_register(&uep3 ,0x0F73, RegisterValue(0,0)); add_sfr_register(&uep4 ,0x0F74, RegisterValue(0,0)); add_sfr_register(&uep5 ,0x0F75, RegisterValue(0,0)); add_sfr_register(&uep6 ,0x0F76, RegisterValue(0,0)); add_sfr_register(&uep7 ,0x0F77, RegisterValue(0,0)); add_sfr_register(&uep8 ,0x0F78, RegisterValue(0,0)); add_sfr_register(&uep9 ,0x0F79, RegisterValue(0,0)); add_sfr_register(&uep10,0x0F7A, RegisterValue(0,0)); add_sfr_register(&uep11,0x0F7B, RegisterValue(0,0)); add_sfr_register(&uep12,0x0F7C, RegisterValue(0,0)); add_sfr_register(&uep13,0x0F7D, RegisterValue(0,0)); add_sfr_register(&uep14,0x0F7E, RegisterValue(0,0)); add_sfr_register(&uep15,0x0F7F, RegisterValue(0,0)); } Processor * P18F2550::construct(const char *name) { P18F2550 *p = new P18F2550(name); if(verbose) cout << " 18F2550 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F4455 // P18F4455::P18F4455(const char *_name, const char *desc) : P18F4x21(_name,desc), ufrml(this, "ufrml", "USB Frame Number register Low" ), ufrmh(this, "ufrmh", "USB Frame Number register High" ), uir (this, "uir" , "USB Interrupt Status register" ), uie (this, "uie" , "USB Interrupt Enable register" ), ueir (this, "ueir" , "USB Error Interrupt Status register"), ueie (this, "ueie" , "USB Error Interrupt Enable register"), ustat(this, "ustat", "USB Transfer Status register" ), ucon (this, "ucon" , "USB Control register" ), uaddr(this, "uaddr", "USB Device Address register" ), ucfg (this, "ucfg" , "USB Configuration register" ), uep0 (this, "uep0" , "USB Endpoint 0 Enable register" ), uep1 (this, "uep1" , "USB Endpoint 1 Enable register" ), uep2 (this, "uep2" , "USB Endpoint 2 Enable register" ), uep3 (this, "uep3" , "USB Endpoint 3 Enable register" ), uep4 (this, "uep4" , "USB Endpoint 4 Enable register" ), uep5 (this, "uep5" , "USB Endpoint 5 Enable register" ), uep6 (this, "uep6" , "USB Endpoint 6 Enable register" ), uep7 (this, "uep7" , "USB Endpoint 7 Enable register" ), uep8 (this, "uep8" , "USB Endpoint 8 Enable register" ), uep9 (this, "uep9" , "USB Endpoint 9 Enable register" ), uep10(this, "uep10", "USB Endpoint 10 Enable register" ), uep11(this, "uep11", "USB Endpoint 11 Enable register" ), uep12(this, "uep12", "USB Endpoint 12 Enable register" ), uep13(this, "uep13", "USB Endpoint 13 Enable register" ), uep14(this, "uep14", "USB Endpoint 14 Enable register" ), uep15(this, "uep15", "USB Endpoint 15 Enable register" ), sppcon(this, "sppcon", "Streaming Parallel port control register"), sppcfg(this, "sppcfg", "Streaming Parallel port configuration register"), sppeps(this, "sppeps", "SPP ENDPOINT ADDRESS AND STATUS REGISTER"), sppdata(this, "sppdata", "Streaming Parallel port data register") { cout << "\nP18F4455 does not support USB registers and functionality\n\n"; if(verbose) cout << "18f4455 constructor, type = " << isa() << '\n'; } P18F4455::~P18F4455() { remove_sfr_register(&ufrml); remove_sfr_register(&ufrmh); remove_sfr_register(&uir ); remove_sfr_register(&uie ); remove_sfr_register(&ueir ); remove_sfr_register(&ueie ); remove_sfr_register(&ustat); remove_sfr_register(&ucon ); remove_sfr_register(&uaddr); remove_sfr_register(&ucfg ); remove_sfr_register(&uep0 ); remove_sfr_register(&uep1 ); remove_sfr_register(&uep2 ); remove_sfr_register(&uep3 ); remove_sfr_register(&uep4 ); remove_sfr_register(&uep5 ); remove_sfr_register(&uep6 ); remove_sfr_register(&uep7 ); remove_sfr_register(&uep8 ); remove_sfr_register(&uep9 ); remove_sfr_register(&uep10); remove_sfr_register(&uep11); remove_sfr_register(&uep12); remove_sfr_register(&uep13); remove_sfr_register(&uep14); remove_sfr_register(&uep15); remove_sfr_register(&sppcon); remove_sfr_register(&sppcfg); remove_sfr_register(&sppeps); remove_sfr_register(&sppdata); } void P18F4455::create() { P18F4x21::create(); if(verbose) cout << " 18f4455 create \n"; package->destroy_pin(18); package->assign_pin(18, 0, false); // Vusb /* The MSSP/I2CC pins are different on this chip. */ ssp.initialize(&pir_set_def, // PIR &(*m_portb)[1], // SCK &(*m_porta)[5], // SS &(*m_portc)[7], // SDO &(*m_portb)[0], // SDI m_trisb, // i2c tris port SSP_TYPE_MSSP ); // RP: RRR commented out comparator.cmcon.set_eccpas(&eccpas); ?? // Streaming Parallel port (SPP) spp.initialize(&pir_set_def, // PIR m_portd, //Parallel port m_trisd, //Parallel port tristate register &sppcon, &sppcfg, &sppeps, &sppdata, &(*m_porte)[0], // CLK1SPP &(*m_porte)[1], // CLK2SPP &(*m_porte)[2], // OESPP &(*m_portb)[4] // CSSPP ); add_sfr_register(&sppdata,0x0F62, RegisterValue(0,0)); add_sfr_register(&sppcfg,0x0F63, RegisterValue(0,0)); add_sfr_register(&sppeps,0x0F64, RegisterValue(0,0)); add_sfr_register(&sppcon,0x0F65, RegisterValue(0,0)); add_sfr_register(&ufrml,0x0F66, RegisterValue(0,0),"ufrm"); add_sfr_register(&ufrmh,0X0F67, RegisterValue(0,0)); add_sfr_register(&uir ,0x0F68, RegisterValue(0,0)); add_sfr_register(&uie ,0x0F69, RegisterValue(0,0)); add_sfr_register(&ueir ,0x0F6A, RegisterValue(0,0)); add_sfr_register(&ueie ,0x0F6B, RegisterValue(0,0)); add_sfr_register(&ustat,0X0F6C, RegisterValue(0,0)); add_sfr_register(&ucon ,0x0F6D, RegisterValue(0,0)); add_sfr_register(&uaddr,0X0F6E, RegisterValue(0,0)); add_sfr_register(&ucfg ,0x0F6F, RegisterValue(0,0)); add_sfr_register(&uep0 ,0x0F70, RegisterValue(0,0)); add_sfr_register(&uep1 ,0x0F71, RegisterValue(0,0)); add_sfr_register(&uep2 ,0x0F72, RegisterValue(0,0)); add_sfr_register(&uep3 ,0x0F73, RegisterValue(0,0)); add_sfr_register(&uep4 ,0x0F74, RegisterValue(0,0)); add_sfr_register(&uep5 ,0x0F75, RegisterValue(0,0)); add_sfr_register(&uep6 ,0x0F76, RegisterValue(0,0)); add_sfr_register(&uep7 ,0x0F77, RegisterValue(0,0)); add_sfr_register(&uep8 ,0x0F78, RegisterValue(0,0)); add_sfr_register(&uep9 ,0x0F79, RegisterValue(0,0)); add_sfr_register(&uep10,0x0F7A, RegisterValue(0,0)); add_sfr_register(&uep11,0x0F7B, RegisterValue(0,0)); add_sfr_register(&uep12,0x0F7C, RegisterValue(0,0)); add_sfr_register(&uep13,0x0F7D, RegisterValue(0,0)); add_sfr_register(&uep14,0x0F7E, RegisterValue(0,0)); add_sfr_register(&uep15,0x0F7F, RegisterValue(0,0)); // Initialize the register cross linkages init_pir2(pir2, PIR2v4::TMR3IF); //new InterruptSource(pir2, PIR2v4::USBIF); } Processor * P18F4455::construct(const char *name) { P18F4455 *p = new P18F4455(name); if(verbose) cout << " 18F4455 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F4550 // P18F4550::P18F4550(const char *_name, const char *desc) : P18F4x21(_name,desc), ufrml(this, "ufrml", "USB Frame Number register Low" ), ufrmh(this, "ufrmh", "USB Frame Number register High" ), uir (this, "uir" , "USB Interrupt Status register" ), uie (this, "uie" , "USB Interrupt Enable register" ), ueir (this, "ueir" , "USB Error Interrupt Status register"), ueie (this, "ueie" , "USB Error Interrupt Enable register"), ustat(this, "ustat", "USB Transfer Status register" ), ucon (this, "ucon" , "USB Control register" ), uaddr(this, "uaddr", "USB Device Address register" ), ucfg (this, "ucfg" , "USB Configuration register" ), uep0 (this, "uep0" , "USB Endpoint 0 Enable register" ), uep1 (this, "uep1" , "USB Endpoint 1 Enable register" ), uep2 (this, "uep2" , "USB Endpoint 2 Enable register" ), uep3 (this, "uep3" , "USB Endpoint 3 Enable register" ), uep4 (this, "uep4" , "USB Endpoint 4 Enable register" ), uep5 (this, "uep5" , "USB Endpoint 5 Enable register" ), uep6 (this, "uep6" , "USB Endpoint 6 Enable register" ), uep7 (this, "uep7" , "USB Endpoint 7 Enable register" ), uep8 (this, "uep8" , "USB Endpoint 8 Enable register" ), uep9 (this, "uep9" , "USB Endpoint 9 Enable register" ), uep10(this, "uep10", "USB Endpoint 10 Enable register" ), uep11(this, "uep11", "USB Endpoint 11 Enable register" ), uep12(this, "uep12", "USB Endpoint 12 Enable register" ), uep13(this, "uep13", "USB Endpoint 13 Enable register" ), uep14(this, "uep14", "USB Endpoint 14 Enable register" ), uep15(this, "uep15", "USB Endpoint 15 Enable register" ), sppcon(this, "sppcon", "Streaming Parallel port control register"), sppcfg(this, "sppcfg", "Streaming Parallel port configuration register"), sppeps(this, "sppeps", "SPP ENDPOINT ADDRESS AND STATUS REGISTER"), sppdata(this, "sppdata", "Streaming Parallel port data register") { cout << "\nP18F4550 does not support USB registers and functionality\n\n"; if(verbose) cout << "18f4550 constructor, type = " << isa() << '\n'; } P18F4550::~P18F4550() { remove_sfr_register(&ufrml); remove_sfr_register(&ufrmh); remove_sfr_register(&uir ); remove_sfr_register(&uie ); remove_sfr_register(&ueir ); remove_sfr_register(&ueie ); remove_sfr_register(&ustat); remove_sfr_register(&ucon ); remove_sfr_register(&uaddr); remove_sfr_register(&ucfg ); remove_sfr_register(&uep0 ); remove_sfr_register(&uep1 ); remove_sfr_register(&uep2 ); remove_sfr_register(&uep3 ); remove_sfr_register(&uep4 ); remove_sfr_register(&uep5 ); remove_sfr_register(&uep6 ); remove_sfr_register(&uep7 ); remove_sfr_register(&uep8 ); remove_sfr_register(&uep9 ); remove_sfr_register(&uep10); remove_sfr_register(&uep11); remove_sfr_register(&uep12); remove_sfr_register(&uep13); remove_sfr_register(&uep14); remove_sfr_register(&uep15); remove_sfr_register(&sppcon); remove_sfr_register(&sppcfg); remove_sfr_register(&sppeps); remove_sfr_register(&sppdata); } void P18F4550::create() { P18F4x21::create(); if(verbose) cout << " 18f4550 create \n"; package->destroy_pin(18); package->assign_pin(18, 0, false); // Vusb /* The MSSP/I2CC pins are different on this chip. */ ssp.initialize(&pir_set_def, // PIR &(*m_portb)[1], // SCK &(*m_porta)[5], // SS &(*m_portc)[7], // SDO &(*m_portb)[0], // SDI m_trisb, // i2c tris port SSP_TYPE_MSSP ); // Streaming Parallel port (SPP) spp.initialize(&pir_set_def, // PIR m_portd, //Parallel port m_trisd, //Parallel port tristate register &sppcon, &sppcfg, &sppeps, &sppdata, &(*m_porte)[0], // CLK1SPP &(*m_porte)[1], // CLK2SPP &(*m_porte)[2], // OESPP &(*m_portb)[4] // CSSPP ); // RP: RRR commented out comparator.cmcon.set_eccpas(&eccpas); ?? add_sfr_register(&sppdata,0x0F62, RegisterValue(0,0)); add_sfr_register(&sppcfg,0x0F63, RegisterValue(0,0)); add_sfr_register(&sppeps,0x0F64, RegisterValue(0,0)); add_sfr_register(&sppcon,0x0F65, RegisterValue(0,0)); add_sfr_register(&ufrml,0x0F66, RegisterValue(0,0),"ufrm"); add_sfr_register(&ufrmh,0X0F67, RegisterValue(0,0)); add_sfr_register(&uir ,0x0F68, RegisterValue(0,0)); add_sfr_register(&uie ,0x0F69, RegisterValue(0,0)); add_sfr_register(&ueir ,0x0F6A, RegisterValue(0,0)); add_sfr_register(&ueie ,0x0F6B, RegisterValue(0,0)); add_sfr_register(&ustat,0X0F6C, RegisterValue(0,0)); add_sfr_register(&ucon ,0x0F6D, RegisterValue(0,0)); add_sfr_register(&uaddr,0X0F6E, RegisterValue(0,0)); add_sfr_register(&ucfg ,0x0F6F, RegisterValue(0,0)); add_sfr_register(&uep0 ,0x0F70, RegisterValue(0,0)); add_sfr_register(&uep1 ,0x0F71, RegisterValue(0,0)); add_sfr_register(&uep2 ,0x0F72, RegisterValue(0,0)); add_sfr_register(&uep3 ,0x0F73, RegisterValue(0,0)); add_sfr_register(&uep4 ,0x0F74, RegisterValue(0,0)); add_sfr_register(&uep5 ,0x0F75, RegisterValue(0,0)); add_sfr_register(&uep6 ,0x0F76, RegisterValue(0,0)); add_sfr_register(&uep7 ,0x0F77, RegisterValue(0,0)); add_sfr_register(&uep8 ,0x0F78, RegisterValue(0,0)); add_sfr_register(&uep9 ,0x0F79, RegisterValue(0,0)); add_sfr_register(&uep10,0x0F7A, RegisterValue(0,0)); add_sfr_register(&uep11,0x0F7B, RegisterValue(0,0)); add_sfr_register(&uep12,0x0F7C, RegisterValue(0,0)); add_sfr_register(&uep13,0x0F7D, RegisterValue(0,0)); add_sfr_register(&uep14,0x0F7E, RegisterValue(0,0)); add_sfr_register(&uep15,0x0F7F, RegisterValue(0,0)); // Initialize the register cross linkages //new InterruptSource(pir2, PIR2v4::USBIF); } Processor * P18F4550::construct(const char *name) { P18F4550 *p = new P18F4550(name); if(verbose) cout << " 18F4550 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //------------------------------------------------------------------------ // // P18F1220 // Processor * P18F1220::construct(const char *name) { P18F1220 *p = new P18F1220(name); if(verbose) cout << " 18F1220 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } void P18F1220::create() { if(verbose) cout << "P18F1220::create\n"; tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, false); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); create_iopin_map(); _16bit_processor::create(); _16bit_v2_adc::create(7); osccon->value = RegisterValue(0x00,0); osccon->por_value = RegisterValue(0x00,0); osccon->has_iofs_bit = true; usart.txsta.setIOpin(&(*m_portb)[1]); usart.rcsta.setIOpin(&(*m_portb)[4]); adcon1->setIOPin(4, &(*m_portb)[0]); adcon1->setIOPin(5, &(*m_portb)[1]); adcon1->setIOPin(6, &(*m_portb)[4]); adcon1->setValidCfgBits(0x7f, 0); adcon0->setChannel_Mask(0x7); adcon1->setAdcon0(adcon0); // VCFG0, VCFG1 in adcon0 remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&ssp.sspcon); remove_sfr_register(&ssp.sspstat); remove_sfr_register(&ssp.sspadd); remove_sfr_register(&ssp.sspbuf); add_sfr_register(&osctune, 0xf9b,RegisterValue(0,0)); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); set_osc_pin_Number(0,16, &(*m_porta)[7]); set_osc_pin_Number(1,15, &(*m_porta)[6]); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0xcf)); m_configMemory->addConfigWord(CONFIG3H-CONFIG1L,new Config3H_1x20(this, CONFIG3H, 0x80)); add_sfr_register(&usart.spbrgh, 0xfb0,RegisterValue(0,0),"spbrgh"); add_sfr_register(&usart.baudcon, 0xfaa,RegisterValue(0,0),"baudctl"); usart.set_eusart(true); add_sfr_register(&pwm1con, 0xfb7, RegisterValue(0,0)); add_sfr_register(&eccpas, 0xfb6, RegisterValue(0,0)); ccp1con.setBitMask(0xff); ccp1con.setCrosslinks(&ccpr1l, &pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); eccpas.setIOpin(&(*m_portb)[1], &(*m_portb)[2], &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); ccp1con.pwm1con = &pwm1con; ccp1con.setIOpin(&((*m_portb)[3]), &((*m_portb)[2]), &((*m_portb)[6]), &((*m_portb)[7])); init_pir2(pir2, PIR2v2::TMR3IF); tmr3l.setIOpin(&(*m_portb)[6]); } //------------------------------------------------------------------------ void P18F1220::create_iopin_map() { package = new Package(18); if(!package) return; package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 6, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta4"),4)); package->assign_pin( 4, m_porta->addPin(new IO_open_collector("porta5"),5)); package->assign_pin(15, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(16, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(17, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(18, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(5, 0); package->assign_pin(14, 0); } P18F1220::P18F1220(const char *_name, const char *desc) : _16bit_v2_adc(_name,desc), osctune(this, "osctune", "OSC Tune"), eccpas(this, "eccpas", "ECCP Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register") { if(verbose) cout << "18F1220 constructor, type = " << isa() << '\n'; } P18F1220::~P18F1220() { remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); remove_sfr_register(&osctune); remove_sfr_register(&pwm1con); remove_sfr_register(&eccpas); } void P18F1220::osc_mode(unsigned int value) { IOPIN *m_pin; unsigned int pin_Number = get_osc_pin_Number(0); unsigned int fosc = value & (FOSC3 | FOSC2 | FOSC1 | FOSC0); if (osccon) { osccon->set_config_irc(fosc >= 8 && fosc <= 9); osccon->set_config_xosc(fosc > 9 || fosc < 3 || fosc == 6); osccon->set_config_ieso(value & IESO); } value &= (FOSC3 | FOSC2 | FOSC1 | FOSC0); set_int_osc(false); if (pin_Number < 253) { m_pin = package->get_pin(pin_Number); if (value == 8 || value == 9) { clr_clk_pin(pin_Number, get_osc_PinMonitor(0), m_porta, m_trisa, m_lata); set_int_osc(true); } else { set_clk_pin(pin_Number, get_osc_PinMonitor(0), "OSC1", true, m_porta, m_trisa, m_lata); } } if ( (pin_Number = get_osc_pin_Number(1)) < 253 && (m_pin = package->get_pin(pin_Number))) { pll_factor = 0; switch(value) { case 6: pll_factor = 2; case 0: case 1: case 2: set_clk_pin(pin_Number, get_osc_PinMonitor(1), "OSC2", true, m_porta, m_trisa, m_lata); break; case 4: case 9: case 12: case 13: case 14: case 15: cout << "CLKO not simulated\n"; set_clk_pin(pin_Number, get_osc_PinMonitor(1) , "CLKO", false, m_porta, m_trisa, m_lata); break; default: clr_clk_pin(pin_Number, get_osc_PinMonitor(1), m_porta, m_trisa, m_lata); break; } } } //------------------------------------------------------------------------ // // P18Fx320 // P18F1320::P18F1320(const char *_name, const char *desc) : P18F1220(_name,desc) { if(verbose) cout << "18f1320 constructor, type = " << isa() << '\n'; } void P18F1320::create() { if(verbose) cout << " 18fx320 create \n"; P18F1220::create(); } Processor * P18F1320::construct(const char *name) { P18F1320 *p = new P18F1320(name); if(verbose) cout << " 18F1320 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); return p; } //======================================================================== // // Pic 18C2x21 // void P18F2x21::create() { if(verbose) cout << "P18F2x21::create\n"; delete pir2; pir2 = (PIR2v2 *)(new PIR2v4(this, "pir2" , "Peripheral Interrupt Register",0,0 )); tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, false); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); create_iopin_map(); _16bit_processor::create(); m_configMemory->addConfigWord(CONFIG3H-CONFIG1L,new Config3H_2x21(this, CONFIG3H, 0x83)); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0x07)); set_osc_pin_Number(0, 9, &(*m_porta)[7]); set_osc_pin_Number(1,10, &(*m_porta)[6]); /// @bug registers not present on 28 pin according to table 5-1 of the /// data sheet, but bit-restricted according to section 16.4.7 add_sfr_register(&pwm1con, 0xfb7, RegisterValue(0,0)); add_sfr_register(&eccpas, 0xfb6, RegisterValue(0,0)); eccpas.setBitMask(0xfc); eccpas.setIOpin(0, 0, &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); comparator.cmcon.set_eccpas(&eccpas); ccp1con.setBitMask(0x3f); ccp1con.setCrosslinks(&ccpr1l, &pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); ccp1con.pwm1con = &pwm1con; ccp1con.setIOpin(&((*m_portc)[2]), 0, 0, 0); pwm1con.setBitMask(0x80); } //------------------------------------------------------------------------ void P18F2x21::create_iopin_map() { package = new Package(28); if(!package) return; // Build the links between the I/O Ports and their tris registers. package->assign_pin( 1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); // %%%FIXME - is this O/C ? package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(8, 0); // Vss package->assign_pin(9, m_porta->addPin(new IO_bi_directional("porta7"),7)); // OSC1 package->assign_pin(10, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, 0); // Vss package->assign_pin(20, 0); // Vdd package->assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); tmr1l.setIOpin(&(*m_portc)[0]); ssp.initialize(&pir_set_def, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); //1portc.usart = &usart16; } void P18F2x21::create_symbols() { if(verbose) cout << "P18F2x21 create symbols\n"; _16bit_processor::create_symbols(); } P18F2x21::P18F2x21(const char *_name, const char *desc) : _16bit_v2_adc(_name,desc), eccpas(this, "eccp1as", "ECCP Auto-Shutdown Control Register"), pwm1con(this, "eccp1del", "Enhanced PWM Control Register"), osctune(this, "osctune", "OSC Tune"), comparator(this) { if(verbose) cout << "18F2x21 constructor, type = " << isa() << '\n'; m_porte = new PicPortRegister(this,"porte","",8,0x08); // No TRIS register for port E on 28-pin devices } P18F2x21::~P18F2x21() { delete_sfr_register(m_porte); remove_sfr_register(&usart.spbrgh); remove_sfr_register(&usart.baudcon); remove_sfr_register(&osctune); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); remove_sfr_register(&pwm1con); remove_sfr_register(&eccpas); } void P18F2x21::create_sfr_map() { if(verbose) cout << "create_sfr_map P18F2x21\n"; _16bit_processor::create_sfr_map(); _16bit_v2_adc::create(13); RegisterValue porv(0,0); add_sfr_register(m_porte, 0xf84,porv); adcon1->setIOPin(4, &(*m_porta)[5]); /* Not on 28 pin processors adcon1->setIOPin(5, &(*m_porte)[0]); adcon1->setIOPin(6, &(*m_porte)[1]); adcon1->setIOPin(7, &(*m_porte)[2]); */ adcon1->setIOPin(8, &(*m_portb)[2]); adcon1->setIOPin(9, &(*m_portb)[3]); adcon1->setIOPin(10, &(*m_portb)[1]); adcon1->setIOPin(11, &(*m_portb)[4]); adcon1->setIOPin(12, &(*m_portb)[0]); add_sfr_register(&osctune, 0xf9b,porv); osccon->set_osctune(&osctune); osccon->has_iofs_bit = true; osctune.set_osccon(osccon); // rest of configuration in parent class // Link the comparator and voltage ref to porta comparator.initialize(&pir_set_def, &(*m_porta)[2], &(*m_porta)[0], &(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[3], &(*m_porta)[4], &(*m_porta)[5]); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN2, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(1, 2, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN3, AN1, AN3, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 5, AN1, AN3, AN1, AN3, OUT1); comparator.cmcon.set_configuration(1, 6, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 6, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0xfb4, RegisterValue(7,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0xfb5, RegisterValue(0,0),"cvrcon"); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v2::CCP2IF, &tmr2); // ccp2con.setIOpin(&((*m_portc)[1])); // handled by Config3H_2x21 ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; //1 usart16.initialize_16(this,&pir_set_def,&portc); add_sfr_register(&usart.spbrgh, 0xfb0,porv,"spbrgh"); add_sfr_register(&usart.baudcon, 0xfb8,porv,"baudcon"); usart.set_eusart(true); init_pir2(pir2, PIR2v4::TMR3IF); tmr3l.setIOpin(&(*m_portc)[0]); } void P18F2x21::osc_mode(unsigned int value) { IOPIN *m_pin; unsigned int pin_Number = get_osc_pin_Number(0); unsigned int fosc = value & (FOSC3 | FOSC2 | FOSC1 | FOSC0); if (osccon) { osccon->set_config_irc(fosc >= 8 && fosc <= 11); osccon->set_config_xosc(fosc > 11 || fosc < 4); osccon->set_config_ieso(value & IESO); } value &= (FOSC3 | FOSC2 | FOSC1 | FOSC0); set_int_osc(false); if (pin_Number < 253) { m_pin = package->get_pin(pin_Number); if (value == 8 || value == 9) // internal RC clock { clr_clk_pin(pin_Number, get_osc_PinMonitor(0), m_porta, m_trisa, m_lata); set_int_osc(true); } else { set_clk_pin(pin_Number, get_osc_PinMonitor(0), "OSC1", true, m_porta, m_trisa, m_lata); set_int_osc(false); } } if ( (pin_Number = get_osc_pin_Number(1)) < 253 && (m_pin = package->get_pin(pin_Number))) { pll_factor = 0; switch(value) { case 6: pll_factor = 2; case 0: case 1: case 2: set_clk_pin(pin_Number, get_osc_PinMonitor(1), "OSC2", true, m_porta, m_trisa, m_lata); break; case 3: case 4: case 9: case 10: case 11: case 12: case 13: case 14: case 15: cout << "CLKO not simulated\n"; set_clk_pin(pin_Number, get_osc_PinMonitor(1) , "CLKO", false, m_porta, m_trisa, m_lata); break; default: clr_clk_pin(pin_Number, get_osc_PinMonitor(1), m_porta, m_trisa, m_lata); break; } } } //------------------------------------------------------------------------ // // P18F2221 // P18F2221::P18F2221(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18F2221 constructor, type = " << isa() << '\n'; } Processor * P18F2221::construct(const char *name) { P18F2221 *p = new P18F2221(name); if(verbose) cout << " 18F2221 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F2221 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F2321 // P18F2321::P18F2321(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18F2321 constructor, type = " << isa() << '\n'; } Processor * P18F2321::construct(const char *name) { P18F2321 *p = new P18F2321(name); if(verbose) cout << " 18F2321 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F2321 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F2420 // P18F2420::P18F2420(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18F2420 constructor, type = " << isa() << '\n'; } Processor * P18F2420::construct(const char *name) { P18F2420 *p = new P18F2420(name); if(verbose) cout << " 18F2420 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F2420 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F2520 // P18F2520::P18F2520(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18F2520 constructor, type = " << isa() << '\n'; } Processor * P18F2520::construct(const char *name) { P18F2520 *p = new P18F2520(name); if(verbose) cout << " 18F2520 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F2520 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F2525 // P18F2525::P18F2525(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18F2525 constructor, type = " << isa() << '\n'; } Processor * P18F2525::construct(const char *name) { P18F2525 *p = new P18F2525(name); if(verbose) cout << " 18F2525 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F2525 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F2620 // P18F2620::P18F2620(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18F2620 constructor, type = " << isa() << '\n'; } Processor * P18F2620::construct(const char *name) { P18F2620 *p = new P18F2620(name); if(verbose) cout << " 18F2620 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F2620 construct completed\n"; return p; } //======================================================================== // // Pic 18F4x21 // void P18F4x21::create() { if(verbose) cout << "P18F4x21::create\n"; delete pir2; pir2 = (PIR2v2 *)(new PIR2v4(this, "pir2" , "Peripheral Interrupt Register",0,0 )); tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, false); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); create_iopin_map(); _16bit_processor::create(); m_configMemory->addConfigWord(CONFIG3H-CONFIG1L,new Config3H_2x21(this, CONFIG3H, 0x83)); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0x07)); set_osc_pin_Number(0, 13, &(*m_porta)[7]); set_osc_pin_Number(1,14, &(*m_porta)[6]); add_sfr_register(&pwm1con, 0xfb7, RegisterValue(0,0)); add_sfr_register(&eccpas, 0xfb6, RegisterValue(0,0)); eccpas.setIOpin(0, 0, &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); comparator.cmcon.set_eccpas(&eccpas); ccp1con.setBitMask(0xff); ccp1con.setCrosslinks(&ccpr1l, &pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); ccp1con.pwm1con = &pwm1con; ccp1con.setIOpin(&((*m_portc)[2]), &((*m_portd)[5]), &((*m_portd)[6]), &((*m_portd)[7])); } //------------------------------------------------------------------------ void P18F4x21::create_iopin_map() { package = new Package(40); if(!package) return; // Build the links between the I/O Ports and their tris registers. package->assign_pin( 1, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 6, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin( 8, m_porte->addPin(new IO_bi_directional("porte0"),0)); package->assign_pin( 9, m_porte->addPin(new IO_bi_directional("porte1"),1)); package->assign_pin(10, m_porte->addPin(new IO_bi_directional("porte2"),2)); package->assign_pin(11, 0); // Vdd package->assign_pin(12, 0); // Vss package->assign_pin(13, m_porta->addPin(new IO_bi_directional("porta7"),7)); package->assign_pin(14, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(15, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(16, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(17, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(18, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(23, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(24, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(25, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(26, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(19, m_portd->addPin(new IO_bi_directional("portd0"),0)); package->assign_pin(20, m_portd->addPin(new IO_bi_directional("portd1"),1)); package->assign_pin(21, m_portd->addPin(new IO_bi_directional("portd2"),2)); package->assign_pin(22, m_portd->addPin(new IO_bi_directional("portd3"),3)); package->assign_pin(27, m_portd->addPin(new IO_bi_directional("portd4"),4)); package->assign_pin(28, m_portd->addPin(new IO_bi_directional("portd5"),5)); package->assign_pin(29, m_portd->addPin(new IO_bi_directional("portd6"),6)); package->assign_pin(30, m_portd->addPin(new IO_bi_directional("portd7"),7)); package->assign_pin(31, 0); // Vss package->assign_pin(32, 0); // Vdd package->assign_pin(33, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(34, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(35, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(36, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(38, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(39, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(40, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); tmr1l.setIOpin(&(*m_portc)[0]); ssp.initialize(&pir_set_def, // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); //1portc.ccp1con = &ccp1con; //1portc.usart = &usart16; } void P18F4x21::create_symbols() { if(verbose) cout << "P18F4x21 create symbols\n"; _16bit_processor::create_symbols(); } P18F4x21::P18F4x21(const char *_name, const char *desc) : P18F2x21(_name,desc) { if(verbose) cout << "18f4x21 constructor, type = " << isa() << '\n'; m_portd = new PicPSP_PortRegister(this,"portd","",8,0xFF); m_trisd = new PicTrisRegister(this,"trisd","", (PicPortRegister *)m_portd, false); m_latd = new PicLatchRegister(this,"latd","",m_portd); // m_porte = new PicPortRegister(this,"porte","",8,0x07); m_porte->setEnableMask(0x07); // It's been created by the P18F2x21 constructor, but with the wrong enables m_trise = new PicPSP_TrisRegister(this,"trise","", m_porte, false); m_late = new PicLatchRegister(this,"late","",m_porte); } P18F4x21::~P18F4x21() { delete_sfr_register(m_portd); delete_sfr_register(m_trisd); delete_sfr_register(m_latd); delete_sfr_register(m_trise); delete_sfr_register(m_late); remove_sfr_register(&pwm1con); remove_sfr_register(&eccpas); } void P18F4x21::create_sfr_map() { if(verbose) cout << "create_sfr_map P18F4x21\n"; _16bit_processor::create_sfr_map(); _16bit_v2_adc::create(13); RegisterValue porv(0,0); add_sfr_register(m_portd, 0xf83,porv); add_sfr_register(m_porte, 0xf84,porv); add_sfr_register(m_latd, 0xf8c,porv); add_sfr_register(m_late, 0xf8d,porv); add_sfr_register(m_trisd, 0xf95,RegisterValue(0xff,0)); add_sfr_register(m_trise, 0xf96,RegisterValue(0x07,0)); add_sfr_register(&osctune, 0xf9b,porv); osccon->set_osctune(&osctune); osctune.set_osccon(osccon); adcon1->setIOPin(4, &(*m_porta)[5]); adcon1->setIOPin(5, &(*m_porte)[0]); adcon1->setIOPin(6, &(*m_porte)[1]); adcon1->setIOPin(7, &(*m_porte)[2]); adcon1->setIOPin(8, &(*m_portb)[2]); adcon1->setIOPin(9, &(*m_portb)[3]); adcon1->setIOPin(10, &(*m_portb)[1]); adcon1->setIOPin(11, &(*m_portb)[4]); adcon1->setIOPin(12, &(*m_portb)[0]); /* adcon1->setChanTable(0x1ff, 0x1fff, 0x1fff, 0x0fff, 0x07ff, 0x03ff, 0x01ff, 0x00ff, 0x007f, 0x003f, 0x001f, 0x000f, 0x0007, 0x0003, 0x0001, 0x0000); adcon1->setVrefHiChannel(3); adcon1->setVrefLoChannel(2); */ // Link the comparator and voltage ref to porta comparator.initialize(&pir_set_def, &(*m_porta)[2], &(*m_porta)[0], &(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[3], &(*m_porta)[4], &(*m_porta)[5]); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN2, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(1, 2, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN3, AN1, AN3, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 5, AN1, AN3, AN1, AN3, OUT1); comparator.cmcon.set_configuration(1, 6, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 6, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0xfb4, RegisterValue(7,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0xfb5, RegisterValue(0,0),"cvrcon"); ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v2::CCP2IF, &tmr2); // ccp2con.setIOpin(&((*m_portc)[1])); // Handled by Config3H_2x21::set ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; //1 usart16.initialize_16(this,&pir_set_def,&portc); add_sfr_register(&usart.spbrgh, 0xfb0,porv,"spbrgh"); add_sfr_register(&usart.baudcon, 0xfb8,porv,"baudcon"); usart.set_eusart(true); init_pir2(pir2, PIR2v4::TMR3IF); tmr3l.setIOpin(&(*m_portc)[0]); } //------------------------------------------------------------------------ // // P18F4221 // P18F4221::P18F4221(const char *_name, const char *desc) : P18F4x21(_name,desc) { if(verbose) cout << "18F4221 constructor, type = " << isa() << '\n'; } Processor * P18F4221::construct(const char *name) { P18F4221 *p = new P18F4221(name); if(verbose) cout << " 18F4221 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F4221 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F4321 // P18F4321::P18F4321(const char *_name, const char *desc) : P18F4x21(_name,desc) { if(verbose) cout << "18F4321 constructor, type = " << isa() << '\n'; } Processor * P18F4321::construct(const char *name) { P18F4321 *p = new P18F4321(name); if(verbose) cout << " 18F4321 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F4321 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F4420 // P18F4420::P18F4420(const char *_name, const char *desc) : P18F4x21(_name,desc) { if(verbose) cout << "18F4420 constructor, type = " << isa() << '\n'; } Processor * P18F4420::construct(const char *name) { P18F4420 *p = new P18F4420(name); if(verbose) cout << " 18F4420 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F4420 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F4520 // P18F4520::P18F4520(const char *_name, const char *desc) : P18F4x21(_name,desc) { if(verbose) cout << "18F4520 constructor, type = " << isa() << '\n'; } Processor * P18F4520::construct(const char *name) { P18F4520 *p = new P18F4520(name); if(verbose) cout << " 18F4520 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F4520 construct completed\n"; return p; } //------------------------------------------------------------------------ // // P18F4620 // P18F4620::P18F4620(const char *_name, const char *desc) : P18F4x21(_name,desc) { if(verbose) cout << "18F4620 constructor, type = " << isa() << '\n'; } Processor * P18F4620::construct(const char *name) { P18F4620 *p = new P18F4620(name); if(verbose) cout << " 18F4620 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F4620 construct completed\n"; return p; } //======================================================================== // // Pic 18F6x20 // void P18F6x20::create() { if(verbose) cout << "P18F6x20::create\n"; tbl.initialize ( eeprom_memory_size(), 32, 4, CONFIG1L, true); tbl.set_intcon(&intcon); set_eeprom_pir(&tbl); tbl.set_pir(pir2); tbl.eecon1.set_valid_bits(0xbf); create_iopin_map(); _16bit_processor::create(); m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0x27)); init_pir2(pir2, PIR2v2::TMR3IF); tmr3l.setIOpin(&(*m_portc)[0]); } //------------------------------------------------------------------------ void P18F6x20::create_iopin_map() { package = new Package(64); if(!package) return; // Build the links between the I/O Ports and their tris registers. package->assign_pin( 1, m_porte->addPin(new IO_bi_directional("porte1"),1)); package->assign_pin( 2, m_porte->addPin(new IO_bi_directional("porte0"),0)); package->assign_pin( 3, m_portg->addPin(new IO_bi_directional("portg0"),0)); package->assign_pin( 4, m_portg->addPin(new IO_bi_directional("portg1"),1)); package->assign_pin( 5, m_portg->addPin(new IO_bi_directional("portg2"),2)); package->assign_pin( 6, m_portg->addPin(new IO_bi_directional("portg3"),3)); createMCLRPin(7); package->assign_pin( 8, m_portg->addPin(new IO_bi_directional("portg4"),4)); package->assign_pin( 9, 0); // Vss package->assign_pin(10, 0); // Vdd package->assign_pin(11, m_portf->addPin(new IO_bi_directional("portf7"),7)); package->assign_pin(12, m_portf->addPin(new IO_bi_directional("portf6"),6)); package->assign_pin(13, m_portf->addPin(new IO_bi_directional("portf5"),5)); package->assign_pin(14, m_portf->addPin(new IO_bi_directional("portf4"),4)); package->assign_pin(15, m_portf->addPin(new IO_bi_directional("portf3"),3)); package->assign_pin(16, m_portf->addPin(new IO_bi_directional("portf2"),2)); package->assign_pin(17, m_portf->addPin(new IO_bi_directional("portf1"),1)); package->assign_pin(18, m_portf->addPin(new IO_bi_directional("portf0"),0)); package->assign_pin(19, 0); // AVdd package->assign_pin(20, 0); // AVss package->assign_pin(21, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin(22, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin(23, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin(24, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(25, 0); // Vss package->assign_pin(26, 0); // Vdd package->assign_pin(27, m_porta->addPin(new IO_bi_directional("porta5"),5)); package->assign_pin(28, m_porta->addPin(new IO_open_collector("porta4"),4)); package->assign_pin(29, m_portc->addPin(new IO_bi_directional("portc1"),1)); package->assign_pin(30, m_portc->addPin(new IO_bi_directional("portc0"),0)); package->assign_pin(31, m_portc->addPin(new IO_bi_directional("portc6"),6)); package->assign_pin(32, m_portc->addPin(new IO_bi_directional("portc7"),7)); package->assign_pin(33, m_portc->addPin(new IO_bi_directional("portc2"),2)); package->assign_pin(34, m_portc->addPin(new IO_bi_directional("portc3"),3)); package->assign_pin(35, m_portc->addPin(new IO_bi_directional("portc4"),4)); package->assign_pin(36, m_portc->addPin(new IO_bi_directional("portc5"),5)); package->assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(38, 0); // Vdd package->assign_pin(39, 0); // OSC1/CLKI package->assign_pin(40, m_porta->addPin(new IO_bi_directional("porta6"),6)); package->assign_pin(41, 0); // Vss package->assign_pin(42, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(43, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(44, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(45, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(46, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin(47, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin(48, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin(49, m_portd->addPin(new IO_bi_directional("portd7"),7)); package->assign_pin(50, m_portd->addPin(new IO_bi_directional("portd6"),6)); package->assign_pin(51, m_portd->addPin(new IO_bi_directional("portd5"),5)); package->assign_pin(52, m_portd->addPin(new IO_bi_directional("portd4"),4)); package->assign_pin(53, m_portd->addPin(new IO_bi_directional("portd3"),3)); package->assign_pin(54, m_portd->addPin(new IO_bi_directional("portd2"),2)); package->assign_pin(55, m_portd->addPin(new IO_bi_directional("portd1"),1)); package->assign_pin(56, 0); // Vss package->assign_pin(57, 0); // Vdd package->assign_pin(58, m_portd->addPin(new IO_bi_directional("portd0"),0)); package->assign_pin(59, m_porte->addPin(new IO_bi_directional("porte7"),7)); package->assign_pin(60, m_porte->addPin(new IO_bi_directional("porte6"),6)); package->assign_pin(61, m_porte->addPin(new IO_bi_directional("porte5"),5)); package->assign_pin(62, m_porte->addPin(new IO_bi_directional("porte4"),4)); package->assign_pin(63, m_porte->addPin(new IO_bi_directional("porte3"),3)); package->assign_pin(64, m_porte->addPin(new IO_bi_directional("porte2"),2)); psp.initialize(&pir_set_def, // PIR m_portd, // Parallel port m_trisd, // Parallel tris pspcon, // Control register &(*m_porte)[0], // NOT RD &(*m_porte)[1], // NOT WR &(*m_porte)[2]); // NOT CS tmr1l.setIOpin(&(*m_portc)[0]); ssp.initialize(&pir_set_def, // PIR &(*m_portc)[3], // SCK &(*m_portf)[7], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); set_osc_pin_Number(0,39, NULL); set_osc_pin_Number(1,40, &(*m_porta)[6]); } void P18F6x20::create_symbols() { if(verbose) cout << "P18F6x20 create symbols\n"; _16bit_processor::create_symbols(); } P18F6x20::P18F6x20(const char *_name, const char *desc) : _16bit_v2_adc(_name,desc), t4con(this, "t4con", "TMR4 Control"), pr4(this, "pr4", "TMR4 Period Register"), tmr4(this, "tmr4", "TMR4 Register"), pir3(this,"pir3","Peripheral Interrupt Register",0,0), pie3(this, "pie3", "Peripheral Interrupt Enable"), ipr3(this, "ipr3", "Interrupt Priorities"), ccp3con(this, "ccp3con", "Capture Compare Control"), ccpr3l(this, "ccpr3l", "Capture Compare 3 Low"), ccpr3h(this, "ccpr3h", "Capture Compare 3 High"), ccp4con(this, "ccp4con", "Capture Compare Control"), ccpr4l(this, "ccpr4l", "Capture Compare 4 Low"), ccpr4h(this, "ccpr4h", "Capture Compare 4 High"), ccp5con(this, "ccp5con", "Capture Compare Control"), ccpr5l(this, "ccpr5l", "Capture Compare 5 Low"), ccpr5h(this, "ccpr5h", "Capture Compare 5 High"), usart2(this), comparator(this) { if(verbose) cout << "18F6x20 constructor, type = " << isa() << '\n'; m_portd = new PicPSP_PortRegister(this,"portd","",8,0xFF); m_trisd = new PicTrisRegister(this,"trisd","", (PicPortRegister *)m_portd, false); m_latd = new PicLatchRegister(this,"latd","",m_portd); m_porte = new PicPortRegister(this,"porte","",8,0xFF); m_trise = new PicTrisRegister(this,"trise","", m_porte, false); m_late = new PicLatchRegister(this,"late","",m_porte); m_portf = new PicPortRegister(this,"portf","",8,0xFF); m_trisf = new PicTrisRegister(this,"trisf","", m_portf, false); m_latf = new PicLatchRegister(this,"latf","",m_portf); m_portg = new PicPortRegister(this,"portg","",8,0x1F); m_trisg = new PicTrisRegister(this,"trisg","", m_portg, false); m_latg = new PicLatchRegister(this,"latg","",m_portg); pspcon = new PSPCON(this, "pspcon",""); } P18F6x20::~P18F6x20() { delete_sfr_register(m_portd); delete_sfr_register(m_porte); delete_sfr_register(m_portf); delete_sfr_register(m_portg); delete_sfr_register(m_latd); delete_sfr_register(m_late); delete_sfr_register(m_latf); delete_sfr_register(m_latg); delete_sfr_register(m_trisd); delete_sfr_register(m_trise); delete_sfr_register(m_trisf); delete_sfr_register(m_trisg); delete_sfr_register(pspcon); delete_sfr_register(usart2.txreg); delete_sfr_register(usart2.rcreg); remove_sfr_register(&pie3); remove_sfr_register(&pir3); remove_sfr_register(&ipr3); remove_sfr_register(&usart2.rcsta); remove_sfr_register(&usart2.txsta); remove_sfr_register(&usart2.spbrg); remove_sfr_register(&ccp4con); remove_sfr_register(&ccpr4l); remove_sfr_register(&ccpr4h); remove_sfr_register(&ccp5con); remove_sfr_register(&ccpr5l); remove_sfr_register(&ccpr5h); remove_sfr_register(&t4con); remove_sfr_register(&pr4); remove_sfr_register(&tmr4); remove_sfr_register(&ccp3con); remove_sfr_register(&ccpr3l); remove_sfr_register(&ccpr3h); remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); } void P18F6x20::create_sfr_map() { if(verbose) cout << "create_sfr_map P18F6x20\n"; _16bit_processor::create_sfr_map(); _16bit_v2_adc::create(12); RegisterValue porv(0,0); osccon->por_value.put(0x01,0x01); // cout << "Create extra ports\n"; add_sfr_register(m_portd, 0xf83,porv); add_sfr_register(m_porte, 0xf84,porv); add_sfr_register(m_portf, 0xf85,porv); add_sfr_register(m_portg, 0xf86,porv); add_sfr_register(m_latd, 0xf8c,porv); add_sfr_register(m_late, 0xf8d,porv); add_sfr_register(m_latf, 0xf8e,porv); add_sfr_register(m_latg, 0xf8f,porv); add_sfr_register(m_trisd, 0xf95,RegisterValue(0xff,0)); add_sfr_register(m_trise, 0xf96,RegisterValue(0xff,0)); add_sfr_register(m_trisf, 0xf97,RegisterValue(0xff,0)); add_sfr_register(m_trisg, 0xf98,RegisterValue(0x1f,0)); add_sfr_register(&pie3, 0xfa3,porv,"pie3"); add_sfr_register(&pir3, 0xfa4,porv,"pir3"); add_sfr_register(&ipr3, 0xfa5,porv,"ipr3"); add_sfr_register(pspcon, 0xfb0,RegisterValue(0x00,0)); // cout << "Assign ADC pins to " << adcon1 << "\n"; adcon1->setIOPin(4, &(*m_porta)[5]); adcon1->setIOPin(5, &(*m_portf)[0]); adcon1->setIOPin(6, &(*m_portf)[1]); adcon1->setIOPin(7, &(*m_portf)[2]); adcon1->setIOPin(8, &(*m_portf)[3]); adcon1->setIOPin(9, &(*m_portf)[4]); adcon1->setIOPin(10, &(*m_portf)[5]); adcon1->setIOPin(11, &(*m_portf)[6]); // adcon1->setIOPin(12, &(*m_portb)[0]); /* adcon1->setChanTable(0x1ff, 0x1fff, 0x1fff, 0x0fff, 0x07ff, 0x03ff, 0x01ff, 0x00ff, 0x007f, 0x003f, 0x001f, 0x000f, 0x0007, 0x0003, 0x0001, 0x0000); adcon1->setVrefHiChannel(3); adcon1->setVrefLoChannel(2); */ // Link the comparator and voltage ref to portf comparator.initialize(&pir_set_def, &(*m_portf)[5], 0, 0, 0, 0, &(*m_portf)[2], &(*m_portf)[1]); // set anx for input pins comparator.cmcon.setINpin(0, &(*m_portf)[6], "an11"); comparator.cmcon.setINpin(1, &(*m_portf)[5], "an10"); comparator.cmcon.setINpin(2, &(*m_portf)[4], "an9"); comparator.cmcon.setINpin(3, &(*m_portf)[3], "an8"); comparator.cmcon.set_configuration(1, 0, AN0, AN1, AN0, AN1, ZERO); comparator.cmcon.set_configuration(2, 0, AN2, AN3, AN2, AN3, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN1, AN0, AN1, OUT0); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(1, 2, AN0, AN1, AN0, AN1, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN2, AN3, AN2, AN3, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN1, AN0, AN1, OUT0); comparator.cmcon.set_configuration(2, 3, AN2, AN3, AN2, AN3, OUT1); comparator.cmcon.set_configuration(1, 4, AN0, AN1, AN0, AN1, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN2, AN1, AN2, AN1, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN0, AN1, AN0, AN1, OUT0); comparator.cmcon.set_configuration(2, 5, AN2, AN1, AN2, AN1, OUT1); comparator.cmcon.set_configuration(1, 6, AN0, VREF, AN1, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 6, AN2, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0xfb4, RegisterValue(7,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0xfb5, RegisterValue(0,0),"cvrcon"); // cout << "Setting CCP cross-links\n"; ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v2::CCP2IF, &tmr2); ccp2con.setIOpin(&((*m_portc)[1])); ccpr2l.ccprh = &ccpr2h; ccpr2l.tmrl = &tmr1l; ccpr2h.ccprl = &ccpr2l; add_sfr_register(&ccp3con, 0xfb7,porv,"ccp3con"); add_sfr_register(&ccpr3l, 0xfb8,porv,"ccpr3l"); add_sfr_register(&ccpr3h, 0xfb9,porv,"ccpr3h"); add_sfr_register(&ccp4con, 0xf73,porv,"ccp4con"); add_sfr_register(&ccpr4l, 0xf74,porv,"ccpr4l"); add_sfr_register(&ccpr4h, 0xf75,porv,"ccpr4h"); add_sfr_register(&ccp5con, 0xf70,porv,"ccp5con"); add_sfr_register(&ccpr5l, 0xf71,porv,"ccpr5l"); add_sfr_register(&ccpr5h, 0xf72,porv,"ccpr5h"); add_sfr_register(&t4con, 0xf76,porv,"t4con"); add_sfr_register(&pr4, 0xf77,RegisterValue(0xff,0),"pr4"); add_sfr_register(&tmr4, 0xf78,porv,"tmr4"); ccp3con.setCrosslinks(&ccpr3l, &pir3, PIR3v1::CCP3IF, &tmr2); ccp3con.setIOpin(&((*m_portg)[0])); ccpr3l.ccprh = &ccpr3h; ccpr3l.tmrl = &tmr1l; ccpr3h.ccprl = &ccpr3l; tmr2.add_ccp ( &ccp3con ); ccp4con.setCrosslinks(&ccpr4l, &pir3, PIR3v1::CCP4IF, &tmr2); ccp4con.setIOpin(&((*m_portg)[3])); ccpr4l.ccprh = &ccpr4h; ccpr4l.tmrl = &tmr1l; ccpr4h.ccprl = &ccpr4l; tmr2.add_ccp ( &ccp4con ); ccp5con.setCrosslinks(&ccpr5l, &pir3, PIR3v1::CCP5IF, &tmr2); ccp5con.setIOpin(&((*m_portg)[4])); ccpr5l.ccprh = &ccpr5h; ccpr5l.tmrl = &tmr1l; ccpr5h.ccprl = &ccpr5l; tmr2.add_ccp ( &ccp5con ); //cout << "Create second USART\n"; usart2.initialize(&pir3,&(*m_portg)[1], &(*m_portg)[2], new _TXREG(this,"txreg2", "USART Transmit Register", &usart2), new _RCREG(this,"rcreg2", "USART Receiver Register", &usart2)); add_sfr_register(&usart2.rcsta, 0xf6b,porv,"rcsta2"); add_sfr_register(&usart2.txsta, 0xf6c,RegisterValue(0x02,0),"txsta2"); add_sfr_register(usart2.txreg, 0xf6d,porv,"txreg2"); add_sfr_register(usart2.rcreg, 0xf6e,porv,"rcreg2"); add_sfr_register(&usart2.spbrg, 0xf6f,porv,"spbrg2"); t4con.tmr2 = &tmr4; tmr4.pir_set = &pir_set_def; //get_pir_set(); tmr4.pr2 = &pr4; tmr4.t2con = &t4con; tmr4.add_ccp ( &ccp1con ); tmr4.add_ccp ( &ccp2con ); pr4.tmr2 = &tmr4; pir3.set_intcon(&intcon); pir3.set_pie(&pie3); pir3.set_ipr(&ipr3); pie3.setPir(&pir3); //pie3.new_name("pie3"); } //------------------------------------------------------------------------ // // P18F6520 // P18F6520::P18F6520(const char *_name, const char *desc) : P18F6x20(_name,desc) { if(verbose) cout << "18F6520 constructor, type = " << isa() << '\n'; } Processor * P18F6520::construct(const char *name) { P18F6520 *p = new P18F6520(name); if(verbose) cout << " 18F6520 construct\n"; p->create(); p->create_invalid_registers(); p->create_symbols(); if(verbose&2) cout << " 18F6520 construct completed\n"; return p; } gpsim-0.30.0/src/ctmu.cc0000664000076400007640000001770113041763624011726 00000000000000/* Copyright (C) 2015 Roy R Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "../config.h" #include "14bit-processors.h" #include "14bit-registers.h" #include "a2d_v2.h" #include "ctmu.h" #define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif CTMUCONH::CTMUCONH(Processor *pCpu, const char *pName, const char *pDesc, CTMU *_ctmu) : sfr_register(pCpu,pName,pDesc), ctmu(_ctmu) { ctmu->ctmuconh = this; } void CTMUCONH::put(unsigned int new_value) { unsigned int diff = value.get() ^ new_value; trace.raw(write_trace.get() | value.get()); value.put(new_value); if (diff & CTMUEN) // on or off { if (new_value & CTMUEN) // enable CTMU ctmu->enable(new_value); else ctmu->disable(); // disable CTMU } if ((diff & TGEN) || (diff & CTMUEN)) // Pulse generation { if ((new_value & TGEN) && (new_value & CTMUEN)) ctmu->tgen_on(); else ctmu->tgen_off(); } if (diff & IDISSEN) ctmu->idissen(new_value & IDISSEN); } CTMUCONL::CTMUCONL(Processor *pCpu, const char *pName, const char *pDesc, CTMU *_ctmu) : sfr_register(pCpu,pName,pDesc), ctmu(_ctmu) { ctmu->ctmuconl = this; } void CTMUCONL::put(unsigned int new_value) { unsigned int diff = value.get() ^ new_value; trace.raw(write_trace.get() | value.get()); value.put(new_value); if (diff) ctmu->stat_change(); } CTMUICON::CTMUICON(Processor *pCpu, const char *pName, const char *pDesc, CTMU *_ctmu) : sfr_register(pCpu,pName,pDesc), ctmu(_ctmu) { ctmu->ctmuicon = this; } void CTMUICON::put(unsigned int new_value) { unsigned int diff = value.get() ^ new_value; int adj= ((new_value & 0xfc) >>2); double I; trace.raw(write_trace.get() | value.get()); value.put(new_value); if (!diff) return; if (new_value & ITRIM5) { adj -= 0x40; } switch(new_value & (IRNG0|IRNG1)) { case 0: // Current off I = 0.; break; case 1: // Base current I = 0.55e-6; // 0.55 uA break; case 2: // 10x Range I = 5.5e-6; //5.5 uA break; case 3: // 100x Range I = 55e-6; // 55 uA } // AN1250 page 4 says adjustment steps 2%, no value found in 18f26k22 // spec sheet I += I * adj * 0.02; ctmu->new_current(I); } class CTMU_SignalSink : public SignalSink { public: CTMU_SignalSink(CTMU *_ctmu) : m_state(false), m_ctmu(_ctmu) { assert(_ctmu); } virtual void setSinkState(char new3State) { m_state = ((new3State == '0') | (new3State == 'w'))?false:true; m_ctmu->new_edge(); } virtual void release() { delete this; } bool get_state() { return m_state;} private: bool m_state; CTMU *m_ctmu; }; CTMU::CTMU(Processor *pCpu): cted1_state(false), cted2_state(false), ctmu_stim(0), m_cted1(0), m_cted2(0), ctmu_cted1_sink(0),ctmu_cted2_sink(0), ctpls_source(0), cpu(pCpu) { } void CTMU::enable(unsigned int value) { if (!ctmu_cted1_sink) { ctmu_cted1_sink = new CTMU_SignalSink(this); ctmu_cted2_sink = new CTMU_SignalSink(this); } m_cted1->addSink(ctmu_cted1_sink); m_cted2->addSink(ctmu_cted2_sink); idissen(value & CTMUCONH::IDISSEN); stat_change(); } void CTMU::disable() { current_off(); if (ctmu_cted1_sink) { m_cted1->removeSink(ctmu_cted1_sink); m_cted2->removeSink(ctmu_cted2_sink); delete ctmu_cted1_sink; ctmu_cted1_sink = 0; delete ctmu_cted2_sink; ctmu_cted2_sink = 0; } } void CTMU::current_off() { ctmu_stim->set_Vth(cpu->get_Vdd()); ctmu_stim->set_Zth(1e12); ctmu_stim->updateNode(); } void CTMU::new_current(double I) { current = I; if (I) resistance = Vsrc / I; else resistance = 1e12; } void CTMU::stat_change() { unsigned int value = ctmuconl->value.get(); bool edg1 = value & CTMUCONL::EDG1STAT; bool edg2 = value & CTMUCONL::EDG2STAT; // Don't do anything is CTMU not enables if (! (ctmuconh->value.get() & CTMUCONH::CTMUEN)) return; /* either edg1 or edg2 set, but not both */ if(edg1 ^ edg2) { ctmu_stim->set_Vth(Vsrc); ctmu_stim->set_Zth(resistance); ctmu_stim->updateNode(); if (ctmuconh->value.get() & CTMUCONH::TGEN) ctpls_source->putState('1'); } else { current_off(); if (ctmuconh->value.get() & CTMUCONH::TGEN) ctpls_source->putState('0'); if (ctmuconh->value.get() & CTMUCONH::CTTRIG) { adcon1->ctmu_trigger(); } } } #define EDG1_SEL(x) ((x) & (CTMUCONL::EDG1SEL0 | CTMUCONL::EDG1SEL1)) #define EDG2_SEL(x) ((x) & (CTMUCONL::EDG2SEL0 | CTMUCONL::EDG2SEL1)) void CTMU::new_edge() { unsigned int value = ctmuconl->value.get(); bool state1 = ctmu_cted1_sink->get_state(); bool state2 = ctmu_cted2_sink->get_state(); // return if edges are blocked if (!(ctmuconh->value.get() & CTMUCONH::EDGEN)) { cted1_state = state1; cted2_state = state2; return; } if (state1 != cted1_state) // state change on cted1 { //using CTED1 if (EDG1_SEL(value) == (CTMUCONL::EDG1SEL0 | CTMUCONL::EDG1SEL1)) { // positive edge active if (value & CTMUCONL::EDG1POL) { if (state1) value |= CTMUCONL::EDG1STAT; } // negative edge else { if (!state1) value |= CTMUCONL::EDG1STAT; } ctmuconl->put(value); } //using CTED1 if (EDG2_SEL(value) == (CTMUCONL::EDG2SEL0 | CTMUCONL::EDG2SEL1)) { // positive edge active if (value & CTMUCONL::EDG2POL) { if (state1) value |= CTMUCONL::EDG2STAT; } // negative edge else { if (!state1) value |= CTMUCONL::EDG2STAT; } ctmuconl->put(value); } cted1_state = state1; } if (state2 != cted2_state) // state change on cted2 { //using CTED2 if (EDG1_SEL(value) == (CTMUCONL::EDG1SEL1)) { // positive edge active if (value & CTMUCONL::EDG1POL) { if (state2) value |= CTMUCONL::EDG1STAT; } // negative edge else { if (!state2) value |= CTMUCONL::EDG1STAT; } ctmuconl->put(value); } //using CTED2 if (EDG2_SEL(value) == (CTMUCONL::EDG2SEL1)) { // positive edge active if (value & CTMUCONL::EDG2POL) { if (state2) value |= CTMUCONL::EDG2STAT; } // negative edge else { if (!state2) value |= CTMUCONL::EDG2STAT; } ctmuconl->put(value); } cted2_state = state2; } } //Status from comparator module for C2 void CTMU::syncC2out(bool high) { if ((ctmuconh->value.get() & CTMUCONH::TGEN) && high) { unsigned int value = ctmuconl->value.get(); value |= CTMUCONL::EDG2STAT; ctmuconl->put(value); } } void CTMU::tgen_on() { cm2con1->set_ctmu_stim(ctmu_stim, this); m_ctpls->getPin().newGUIname("ctpls"); if (!ctpls_source) ctpls_source = new PeripheralSignalSource(m_ctpls); m_ctpls->setSource(ctpls_source); } void CTMU::tgen_off() { cm2con1->set_ctmu_stim(0, 0); m_ctpls->getPin().newGUIname(m_ctpls->getPin().name().c_str()); if (ctpls_source) m_ctpls->setSource(0); } void CTMU::idissen(bool ground) { // Don't do anything is CTMU not enables if (! (ctmuconh->value.get() & CTMUCONH::CTMUEN)) return; if (ground) { ctmu_stim->set_Vth(0.); ctmu_stim->set_Zth(300.0); ctmu_stim->updateNode(); } else { stat_change(); } } gpsim-0.30.0/src/p16f87x.cc0000664000076400007640000007463613041763613012111 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16f87x // // This file supports: // P16F874 P16F877 // P16F871 P16F873 // P16F876 P16F873A // P14F874A P16F876A // P16F877A // #include #include #include #include "../config.h" #include "symbol.h" #include "p16f87x.h" #include "pic-ioports.h" #include "stimuli.h" //------------------------------------------------------------------- void P16F871::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F871::create_sfr_map() { if(verbose) cout << "creating f871 registers \n"; add_sfr_register(pir2, 0x0d, RegisterValue(0,0),"pir2"); add_sfr_register(&pie2, 0x8d, RegisterValue(0,0)); // Parent classes just set PIR1 pir_set_2_def.set_pir2(pir2_2_reg); usart.initialize(pir1,&(*m_portc)[6], &(*m_portc)[7], new _TXREG(this,"txreg", "USART Transmit Register", &usart), new _RCREG(this,"rcreg", "USART Receiver Register", &usart)); add_sfr_register(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta"); add_sfr_register(&usart.txsta, 0x98, RegisterValue(2,0),"txsta"); add_sfr_register(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg"); add_sfr_register(usart.txreg, 0x19, RegisterValue(0,0),"txreg"); add_sfr_register(usart.rcreg, 0x1a, RegisterValue(0,0),"rcreg"); intcon = &intcon_reg; if (pir2) { pir2->set_intcon(&intcon_reg); pir2->set_pie(&pie2); } pie2.setPir(get_pir2()); add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); // Enable program memory reads and writes. get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); alias_file_registers(0x00,0x04,0x100); alias_file_registers(0x80,0x84,0x100); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x86,0x86,0x100); //alias_file_registers(0x0a,0x0b,0x080); //already called alias_file_registers(0x0a,0x0b,0x100); alias_file_registers(0x0a,0x0b,0x180); //alias_file_registers(0x20,0x7f,0x100); // already called alias_file_registers(0xa0,0xbf,0x100); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); //1adcon0.analog_port = porta; //1adcon0.analog_port2 = porte; adcon0.setAdres(&adres); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setPir(pir1); adcon0.setChannel_Mask(7); adcon0.setAdresLow(&adresl); adcon0.setA2DBits(10); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3, 0); adcon1.setNumberOfChannels(8); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setIOPin(5, &(*m_porte)[0]); adcon1.setIOPin(6, &(*m_porte)[1]); adcon1.setIOPin(7, &(*m_porte)[2]); adcon1.setChannelConfiguration(0, 0xff); adcon1.setChannelConfiguration(1, 0xff); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setChannelConfiguration(8, 0xff); adcon1.setChannelConfiguration(9, 0x3f); adcon1.setChannelConfiguration(10, 0x3f); adcon1.setChannelConfiguration(11, 0x3f); adcon1.setChannelConfiguration(12, 0x1f); adcon1.setChannelConfiguration(13, 0x0f); adcon1.setChannelConfiguration(14, 0x01); adcon1.setChannelConfiguration(15, 0x0d); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon1.setVrefHiConfiguration(8, 3); adcon1.setVrefHiConfiguration(10, 3); adcon1.setVrefHiConfiguration(11, 3); adcon1.setVrefHiConfiguration(12, 3); adcon1.setVrefHiConfiguration(13, 3); adcon1.setVrefHiConfiguration(15, 3); adcon1.setVrefLoConfiguration(8, 2); adcon1.setVrefLoConfiguration(11, 2); adcon1.setVrefLoConfiguration(12, 2); adcon1.setVrefLoConfiguration(13, 2); adcon1.setVrefLoConfiguration(15, 2); } void P16F871::create() { if(verbose) cout << " f871 create \n"; P16C64::create(); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eeprom_memory_size()); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F871::create_sfr_map(); } Processor * P16F871::construct(const char *name) { P16F871 *p = new P16F871(name); if(verbose) cout << " f871 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F871::create_symbols() { if(verbose) cout << "f871 create symbols\n"; Pic14Bit::create_symbols(); } //======================================================================== P16F871::P16F871(const char *_name, const char *desc) : P16C64(_name,desc) , adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result"), adresl(this,"adresl", "A2D Result Low"), usart(this) { if(verbose) cout << "f871 constructor, type = " << isa() << '\n'; //pir2 = &pir2_2_reg; pir2_2_reg = new PIR2v2(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); delete pir2; pir2 = pir2_2_reg; } P16F871::~P16F871() { remove_sfr_register(&pie2); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); remove_sfr_register(&adresl); remove_sfr_register(&usart.rcsta); remove_sfr_register(&usart.txsta); remove_sfr_register(&usart.spbrg); delete_sfr_register(usart.txreg); delete_sfr_register(usart.rcreg); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); delete get_eeprom(); } //------------------------------------------------------- void P16F873::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F873::create_sfr_map() { if(verbose) cout << "creating f873 registers \n"; add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); // Enable program memory reads and writes. get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0xa0,0xff,0x100); // The rest of the A/D definition in 16C73 add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); adcon0.setAdresLow(&adresl); adcon0.setA2DBits(10); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3 , 0); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setChannelConfiguration(8, 0x1f); adcon1.setChannelConfiguration(9, 0x1f); adcon1.setChannelConfiguration(10, 0x1f); adcon1.setChannelConfiguration(11, 0x1f); adcon1.setChannelConfiguration(12, 0x1f); adcon1.setChannelConfiguration(13, 0x1f); adcon1.setChannelConfiguration(14, 0x01); adcon1.setChannelConfiguration(15, 0x0d); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon1.setVrefHiConfiguration(8, 3); adcon1.setVrefHiConfiguration(10, 3); adcon1.setVrefHiConfiguration(11, 3); adcon1.setVrefHiConfiguration(12, 3); adcon1.setVrefHiConfiguration(13, 3); adcon1.setVrefHiConfiguration(15, 3); adcon1.setVrefLoConfiguration(8, 2); adcon1.setVrefLoConfiguration(11, 2); adcon1.setVrefLoConfiguration(12, 2); adcon1.setVrefLoConfiguration(13, 2); adcon1.setVrefLoConfiguration(15, 2); add_sfr_register(&ssp.sspcon2, 0x91, RegisterValue(0,0) ,"sspcon2"); ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); } void P16F873::create() { if(verbose) cout << " f873 create \n"; P16C73::create(); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eeprom_memory_size()); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F873::create_sfr_map(); } //======================================================================== Processor * P16F873::construct(const char *name) { P16F873 *p = new P16F873(name); if(verbose) cout << " f873 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F873::create_symbols() { if(verbose) cout << "f873 create symbols\n"; Pic14Bit::create_symbols(); } P16F873::P16F873(const char *_name, const char *desc) : P16C73(_name,desc), adresl(this,"adresl", "A2D Result Low") { if(verbose) cout << "f873 constructor, type = " << isa() << '\n'; set_hasSSP(); } P16F873::~P16F873() { remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&adresl); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); delete get_eeprom(); } void P16F873A::create() { if(verbose) cout << " f873A create \n"; P16F873::create(); P16F873A::create_sfr_map(); } void P16F873A::create_sfr_map() { if(verbose) cout << "creating f873A registers \n"; // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), &(*m_porta)[2], &(*m_porta)[0], &(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[3], &(*m_porta)[4], &(*m_porta)[5]); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN2, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(1, 2, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN3, AN1, AN3, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 5, AN1, AN3, AN1, AN3, OUT1); comparator.cmcon.set_configuration(1, 6, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 6, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0x9c, RegisterValue(7,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0x9d, RegisterValue(0,0),"vrcon"); } Processor * P16F873A::construct(const char *name) { P16F873A *p = new P16F873A(name); if(verbose) cout << " f873A construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } P16F873A::P16F873A(const char *_name, const char *desc) : P16F873(_name,desc), comparator(this) { if(verbose) cout << "f873A constructor, type = " << isa() << '\n'; } P16F873A::~P16F873A() { remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); } Processor * P16F876::construct(const char *name) { P16F876 *p = new P16F876(name); if(verbose) cout << " f876 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F876::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F876::create_sfr_map() { if(verbose) cout << "creating f876 registers \n"; add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); // Enable program memory reads and writes. get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); add_file_registers(0x110, 0x16f, 0); add_file_registers(0x190, 0x1ef, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); // The rest of the A/D definition in 16C73 add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); adcon0.setAdresLow(&adresl); adcon0.setA2DBits(10); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3 , 0); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setChannelConfiguration(8, 0x1f); adcon1.setChannelConfiguration(9, 0x1f); adcon1.setChannelConfiguration(10, 0x1f); adcon1.setChannelConfiguration(11, 0x1f); adcon1.setChannelConfiguration(12, 0x1f); adcon1.setChannelConfiguration(13, 0x1f); adcon1.setChannelConfiguration(14, 0x01); adcon1.setChannelConfiguration(15, 0x0d); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon1.setVrefHiConfiguration(8, 3); adcon1.setVrefHiConfiguration(10, 3); adcon1.setVrefHiConfiguration(11, 3); adcon1.setVrefHiConfiguration(12, 3); adcon1.setVrefHiConfiguration(13, 3); adcon1.setVrefHiConfiguration(15, 3); adcon1.setVrefLoConfiguration(8, 2); adcon1.setVrefLoConfiguration(11, 2); adcon1.setVrefLoConfiguration(12, 2); adcon1.setVrefLoConfiguration(13, 2); adcon1.setVrefLoConfiguration(15, 2); add_sfr_register(&ssp.sspcon2, 0x91, RegisterValue(0,0) ,"sspcon2"); ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); } void P16F876::create() { if(verbose) cout << " f876 create \n"; P16C73::create(); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eeprom_memory_size()); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F876::create_sfr_map(); } void P16F876::create_symbols() { if(verbose) cout << "f876 create symbols\n"; Pic14Bit::create_symbols(); } P16F876::P16F876(const char *_name, const char *desc) : P16C73(_name,desc), adresl(this,"adresl", "A2D Result Low") { if(verbose) cout << "f876 constructor, type = " << isa() << '\n'; } P16F876::~P16F876() { remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); delete get_eeprom(); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(&adresl); delete_file_registers(0x110, 0x16f); delete_file_registers(0x190, 0x1ef); } Processor * P16F876A::construct(const char *name) { P16F876A *p = new P16F876A(name); if(verbose) cout << " f876A construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F876A::create_sfr_map() { if(verbose) cout << "creating f876A registers \n"; } void P16F876A::create() { if(verbose) cout << " f876A create \n"; P16F873A::create(); // get rid of aliases delete_file_registers(0x20,0x7f); // get rid of aliases delete_file_registers(0xa0,0xff); // "" add_file_registers(0x20,0x7f, 0); add_file_registers(0xa0, 0xef,0); add_file_registers(0x110, 0x16f, 0); add_file_registers(0x190, 0x1ef, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); P16F876A::create_sfr_map(); } P16F876A::P16F876A(const char *_name, const char *desc) : P16F873A(_name,desc), comparator(this) { if(verbose) cout << "f876A constructor, type = " << isa() << '\n'; } P16F876A::~P16F876A() { delete_file_registers(0x110, 0x16f); delete_file_registers(0x190, 0x1ef); } //------------------------------------------------------- void P16F874::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F874::create_sfr_map() { if(verbose) cout << "creating f874 registers \n"; add_sfr_register(get_eeprom()->get_reg_eedata(), 0x10c); add_sfr_register(get_eeprom()->get_reg_eecon1(), 0x18c, RegisterValue(0,0)); // Enable program memory reads and writes. get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD); add_sfr_register(get_eeprom()->get_reg_eeadr(), 0x10d); add_sfr_register(get_eeprom()->get_reg_eecon2(), 0x18d); get_eeprom()->get_reg_eedatah()->new_name("eedath"); add_sfr_register(get_eeprom()->get_reg_eedatah(), 0x10e); add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0x10f); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0xa0,0xff,0x100); // The rest of the A/D definition in 16C74 add_sfr_register(&adresl, 0x9e, RegisterValue(0,0)); adcon0.setA2DBits(10); adcon0.setAdresLow(&adresl); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2 | ADCON1::PCFG3, 0); adcon1.setChannelConfiguration(0, 0xff); adcon1.setChannelConfiguration(1, 0xff); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setChannelConfiguration(8, 0xff); adcon1.setChannelConfiguration(9, 0x3f); adcon1.setChannelConfiguration(10, 0x3f); adcon1.setChannelConfiguration(11, 0x3f); adcon1.setChannelConfiguration(12, 0x3f); adcon1.setChannelConfiguration(13, 0x1f); adcon1.setChannelConfiguration(14, 0x01); adcon1.setChannelConfiguration(15, 0x0d); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon1.setVrefHiConfiguration(8, 3); adcon1.setVrefHiConfiguration(10, 3); adcon1.setVrefHiConfiguration(11, 3); adcon1.setVrefHiConfiguration(12, 3); adcon1.setVrefHiConfiguration(13, 3); adcon1.setVrefHiConfiguration(15, 3); adcon1.setVrefLoConfiguration(8, 2); adcon1.setVrefLoConfiguration(11, 2); adcon1.setVrefLoConfiguration(12, 2); adcon1.setVrefLoConfiguration(13, 2); adcon1.setVrefLoConfiguration(15, 2); add_sfr_register(&ssp.sspcon2, 0x91, RegisterValue(0,0) ,"sspcon2"); ssp.initialize( get_pir_set(), // PIR &(*m_portc)[3], // SCK &(*m_porta)[5], // SS &(*m_portc)[5], // SDO &(*m_portc)[4], // SDI m_trisc, // i2c tris port SSP_TYPE_MSSP ); } void P16F874::create() { if(verbose) cout << " f874 create \n"; P16C74::create(); EEPROM_WIDE *e; e = new EEPROM_WIDE(this,pir2); e->initialize(eeprom_memory_size()); e->set_intcon(&intcon_reg); set_eeprom_wide(e); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F874::create_sfr_map(); } Processor * P16F874::construct(const char *name) { P16F874 *p = new P16F874(name); if(verbose) cout << " f874 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F874::create_symbols() { if(verbose) cout << "f874 create symbols\n"; Pic14Bit::create_symbols(); } P16F874::P16F874(const char *_name, const char *desc) : P16C74(_name,desc), comparator(this), adresl(this,"adresl", "A2D Result Low") { if(verbose) cout << "f874 constructor, type = " << isa() << '\n'; set_hasSSP(); } P16F874::~P16F874() { remove_sfr_register(&adresl); remove_sfr_register(&ssp.sspcon2); remove_sfr_register(get_eeprom()->get_reg_eedata()); remove_sfr_register(get_eeprom()->get_reg_eecon1()); remove_sfr_register(get_eeprom()->get_reg_eeadr()); remove_sfr_register(get_eeprom()->get_reg_eecon2()); remove_sfr_register(get_eeprom()->get_reg_eedatah()); remove_sfr_register(get_eeprom()->get_reg_eeadrh()); delete get_eeprom(); } //------------------------------------------------------- void P16F874A::set_out_of_range_pm(unsigned int address, unsigned int value) { if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size())) { get_eeprom()->change_rom(address - 0x2100, value); } } void P16F874A::create_sfr_map() { if(verbose) cout << "creating f874A registers \n"; // Link the comparator and voltage ref to porta comparator.initialize(get_pir_set(), &(*m_porta)[2], &(*m_porta)[0], &(*m_porta)[1], &(*m_porta)[2], &(*m_porta)[3], &(*m_porta)[4], &(*m_porta)[5]); comparator.cmcon.set_configuration(1, 0, AN0, AN3, AN0, AN3, ZERO); comparator.cmcon.set_configuration(2, 0, AN1, AN2, AN1, AN2, ZERO); comparator.cmcon.set_configuration(1, 1, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 1, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(1, 2, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 2, AN1, AN2, AN1, AN2, NO_OUT); comparator.cmcon.set_configuration(1, 3, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 3, AN1, AN2, AN1, AN2, OUT1); comparator.cmcon.set_configuration(1, 4, AN0, AN3, AN0, AN3, NO_OUT); comparator.cmcon.set_configuration(2, 4, AN1, AN3, AN1, AN3, NO_OUT); comparator.cmcon.set_configuration(1, 5, AN0, AN3, AN0, AN3, OUT0); comparator.cmcon.set_configuration(2, 5, AN1, AN3, AN1, AN3, OUT1); comparator.cmcon.set_configuration(1, 6, AN0, VREF, AN3, VREF, NO_OUT); comparator.cmcon.set_configuration(2, 6, AN1, VREF, AN2, VREF, NO_OUT); comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO); add_sfr_register(&comparator.cmcon, 0x9c, RegisterValue(7,0),"cmcon"); add_sfr_register(&comparator.vrcon, 0x9d, RegisterValue(0,0),"vrcon"); } void P16F874A::create() { if(verbose) cout << " f874A create \n"; P16F874::create(); P16F874A::create_sfr_map(); } Processor * P16F874A::construct(const char *name) { P16F874A *p = new P16F874A(name); if(verbose) cout << " f874A construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F874A::create_symbols() { if(verbose) cout << "f874A create symbols\n"; Pic14Bit::create_symbols(); } P16F874A::P16F874A(const char *_name, const char *desc) : P16F874(_name,desc), comparator(this) { if(verbose) cout << "f874A constructor, type = " << isa() << '\n'; } P16F874A::~P16F874A() { remove_sfr_register(&comparator.cmcon); remove_sfr_register(&comparator.vrcon); } void P16F877::create_sfr_map() { if(verbose) cout << "creating f877 registers \n"; } void P16F877::create() { if(verbose) cout << " f877 create \n"; P16F874::create(); delete_file_registers(0x20, 0x7f); // get rid of alias registers delete_file_registers(0xa0, 0xff); // "" add_file_registers(0x20, 0x7f, 0); add_file_registers(0xa0, 0xef, 0); add_file_registers(0x110, 0x16f, 0); add_file_registers(0x190, 0x1ef, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); P16F877::create_sfr_map(); } Processor * P16F877::construct(const char *name) { P16F877 *p = new P16F877(name); if(verbose) cout << " f877 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F877::create_symbols() { if(verbose) cout << "f877 create symbols\n"; Pic14Bit::create_symbols(); } P16F877::P16F877(const char *_name, const char *desc) : P16F874(_name,desc) { if(verbose) cout << "f877 constructor, type = " << isa() << '\n'; } P16F877::~P16F877() { delete_file_registers(0x110, 0x16f); delete_file_registers(0x190, 0x1ef); } void P16F877A::create_sfr_map() { if(verbose) cout << "creating f877A registers \n"; } void P16F877A::create() { if(verbose) cout << " f877A create \n"; P16F874A::create(); delete_file_registers(0x20, 0x7f); // get rid of alias registers delete_file_registers(0xa0, 0xff); // "" add_file_registers(0x20, 0x7f, 0); add_file_registers(0xa0, 0xef, 0); add_file_registers(0x110, 0x16f, 0); add_file_registers(0x190, 0x1ef, 0); alias_file_registers(0x70,0x7f,0x80); alias_file_registers(0x70,0x7f,0x100); alias_file_registers(0x70,0x7f,0x180); P16F877A::create_sfr_map(); } Processor * P16F877A::construct(const char *name) { P16F877A *p = new P16F877A(name); if(verbose) cout << " f877A construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); return p; } void P16F877A::create_symbols() { if(verbose) cout << "f877A create symbols\n"; Pic14Bit::create_symbols(); } P16F877A::P16F877A(const char *_name, const char *desc) : P16F874A(_name,desc), comparator(this) { if(verbose) cout << "f877A constructor, type = " << isa() << '\n'; } P16F877A::~P16F877A() { delete_file_registers(0x110, 0x16f); delete_file_registers(0x190, 0x1ef); } gpsim-0.30.0/src/p16x7x.cc0000664000076400007640000006376013041763624012041 00000000000000/* Copyright (C) 1998 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ // // p16x7x // // This file supports: // P16C71 // P16C712 // P16C716 // P16F716 // P16C72 // P16C73 // P16C74 #include #include #include #include "../config.h" #include "symbol.h" #include "packages.h" #include "p16x7x.h" #include "pic-ioports.h" #include "stimuli.h" #include "pm_rd.h" //#define DEBUG_AD //------------------------------------------------------ class P16C71::PIR_16C71 : public PIR_SET { public: PIR_16C71(ADCON0 *adcon0) : m_adcon0(adcon0) { } virtual int interrupt_status() { return m_adcon0->getADIF(); } private: ADCON0 *m_adcon0; }; //------------------------------------------------------------------------ // P16C71::P16C71(const char *_name, const char *desc) : P16X8X(_name, desc), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result") { if(verbose) cout << "c71 constructor, type = " << isa() << '\n'; m_pir = new PIR_16C71(&adcon0); } P16C71::~P16C71() { remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); delete m_pir; } void P16C71::create_sfr_map() { if(verbose) cout << "creating c71 registers \n"; add_sfr_register(&adcon0, 0x08, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x88, RegisterValue(0,0)); add_sfr_register(&adres, 0x09, RegisterValue(0,0)); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1,0); adcon1.setNumberOfChannels(4); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setChannelConfiguration(0, 0x0f); adcon1.setChannelConfiguration(1, 0x0f); adcon1.setChannelConfiguration(2, 0x03); adcon1.setChannelConfiguration(3, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(8); intcon = &intcon_reg; intcon_reg.set_pir_set(m_pir); } void P16C71::create_symbols() { pic_processor::create_symbols(); } void P16C71::create() { ram_top = 0x2f; P16X8X::create_iopin_map(); _14bit_processor::create(); set_eeprom(0); add_file_registers(0x0c, ram_top, 0x80); Pic14Bit::create_sfr_map(); create_sfr_map(); } Processor * P16C71::construct(const char *name) { P16C71 *p = new P16C71(name); if(verbose) cout << " c71 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16x71x::P16x71x(const char *_name, const char *desc) : _14bit_processor(_name, desc), intcon_reg(this,"intcon","Interrupt Control"), t1con(this, "t1con", "TMR1 Control"), pie1(this,"PIE1", "Peripheral Interrupt Enable"), t2con(this, "t2con", "TMR2 Control"), pr2(this, "pr2", "TMR2 Period Register"), tmr2(this, "tmr2", "TMR2 Register"), tmr1l(this, "tmr1l", "TMR1 Low"), tmr1h(this, "tmr1h", "TMR1 High"), ccp1con(this, "ccp1con", "Capture Compare Control"), ccpr1l(this, "ccpr1l", "Capture Compare 1 Low"), ccpr1h(this, "ccpr1h", "Capture Compare 1 High"), pcon(this, "pcon", "pcon"), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result") { if(verbose) cout << "x71x constructor \n"; pir1 = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg, &pie1); m_porta = new PicPortRegister(this,"porta","", 8,0x1f); m_trisa = new PicTrisRegister(this,"trisa","", m_porta, false); tmr0.set_cpu(this, m_porta, 4, option_reg); tmr0.start(0); m_ioc = new IOC(this, "iocen", "Interrupt-On-Change negative edge", 0xf0); m_portb = new PicPortGRegister(this,"portb","",&intcon_reg,m_ioc,8,0xff); m_trisb = new PicTrisRegister(this,"trisb","", m_portb, false); m_portb->intf_bit = 0; m_ioc->put_value(0xf0); } P16x71x::~P16x71x() { unassignMCLRPin(); remove_sfr_register(&tmr0); remove_sfr_register(&intcon_reg); delete_sfr_register(m_portb); delete_sfr_register(m_trisb); delete_sfr_register(m_porta); delete_sfr_register(m_trisa); remove_sfr_register(&tmr1l); remove_sfr_register(&tmr1h); remove_sfr_register(&pcon); remove_sfr_register(&t1con); remove_sfr_register(&tmr2); remove_sfr_register(&t2con); remove_sfr_register(&pr2); remove_sfr_register(&pie1); delete_sfr_register(pir1); remove_sfr_register(&ccpr1l); remove_sfr_register(&ccpr1h); remove_sfr_register(&ccp1con); remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); delete_file_registers(0x20,0x7f); delete_file_registers(0xa0,0xbf); } //------------------------------------------------------------------- void P16x71x::option_new_bits_6_7(unsigned int bits) { //1 ((PORTB *)portb)->rbpu_intedg_update(bits); m_portb->setRBPU( (bits & (1<<7)) == (1<<7)); m_portb->setIntEdge((bits & (1<<6)) == (1<<6)); } void P16x71x::create_sfr_map() { if(verbose) cout << "P16x71x::create_sfr_map\n"; add_sfr_register(indf, 0x00); alias_file_registers(0x00,0x00,0x80); add_sfr_register(&tmr0, 0x01); add_sfr_register(option_reg, 0x81, RegisterValue(0xff,0)); add_sfr_register(pcl, 0x02, RegisterValue(0,0)); add_sfr_register(status, 0x03, RegisterValue(0x18,0)); add_sfr_register(fsr, 0x04); alias_file_registers(0x02,0x04,0x80); add_sfr_register(m_porta, 0x05); add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0)); add_sfr_register(m_portb, 0x06); add_sfr_register(m_trisb, 0x86, RegisterValue(0xff,0)); add_sfr_register(pclath, 0x0a, RegisterValue(0,0)); //add_sfr_register(pclath, 0x8a, RegisterValue(0,0)); add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0)); alias_file_registers(0x0a,0x0b,0x80); intcon = &intcon_reg; m_porta->setEnableMask(0x1f); m_porta->setTris(m_trisa); // The 16c62,c64 have general purpose registers // at addresses 20-7f and a0-bf add_file_registers(0x20, 0x7f, 0); add_file_registers(0xa0, 0xbf, 0); add_sfr_register(pir1, 0x0c, RegisterValue(0,0),"pir1"); add_sfr_register(&pie1, 0x8c, RegisterValue(0,0)); add_sfr_register(&tmr1l, 0x0e, RegisterValue(0,0),"tmr1l"); add_sfr_register(&tmr1h, 0x0f, RegisterValue(0,0),"tmr1h"); add_sfr_register(&pcon, 0x8e, RegisterValue(0,0),"pcon"); add_sfr_register(&t1con, 0x10, RegisterValue(0,0)); add_sfr_register(&tmr2, 0x11, RegisterValue(0,0)); add_sfr_register(&t2con, 0x12, RegisterValue(0,0)); add_sfr_register(&pr2, 0x92, RegisterValue(0xff,0)); // get_pir_set()->set_pir1(get_pir1()); pir_set_def.set_pir1(pir1); intcon = &intcon_reg; intcon_reg.set_pir_set(get_pir_set()); // Maybe there's a better place for this, but let's go ahead and link all // of the registers together (there's probably a better way too) : tmr1l.tmrh = &tmr1h; tmr1l.t1con = &t1con; tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF)); tmr1h.tmrl = &tmr1l; t1con.tmrl = &tmr1l; t2con.tmr2 = &tmr2; tmr2.pir_set = get_pir_set(); tmr2.pr2 = &pr2; tmr2.t2con = &t2con; tmr2.add_ccp(&ccp1con); pr2.tmr2 = &tmr2; if (pir1) { pir1->set_intcon(&intcon_reg); pir1->set_pie(&pie1); pir1->valid_bits = pir1->writable_bits = 0x47; } pie1.setPir(pir1); /* The A/D section is similar to 16x71, but not equal */ add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); //1adcon0.analog_port = porta; adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setChannel_Mask(3); adcon0.setA2DBits(8); intcon = &intcon_reg; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1| ADCON1::PCFG2,0); adcon1.setNumberOfChannels(4); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setChannelConfiguration(0, 0x0f); adcon1.setChannelConfiguration(1, 0x0f); adcon1.setChannelConfiguration(2, 0x0f); adcon1.setChannelConfiguration(3, 0x0f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); add_sfr_register(&ccpr1l, 0x15, RegisterValue(0,0)); add_sfr_register(&ccpr1h, 0x16, RegisterValue(0,0)); add_sfr_register(&ccp1con, 0x17, RegisterValue(0,0)); ccp1con.setIOpin(&(*m_portb)[3], 0, 0, 0); ccp1con.setBitMask(0x3f); ccpr1l.ccprh = &ccpr1h; ccpr1l.tmrl = &tmr1l; ccpr1h.ccprl = &ccpr1l; } void P16x71x::create_iopin_map() { package = new Package(18); if(!package) return; // Now Create the package and place the I/O pins package->assign_pin(17, m_porta->addPin(new IO_bi_directional("porta0"),0)); package->assign_pin(18, m_porta->addPin(new IO_bi_directional("porta1"),1)); package->assign_pin( 1, m_porta->addPin(new IO_bi_directional("porta2"),2)); package->assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta3"),3)); package->assign_pin( 3, m_porta->addPin(new IO_open_collector("porta4"),4)); createMCLRPin(4); package->assign_pin( 5, 0); package->assign_pin( 6, m_portb->addPin(new IO_bi_directional_pu("portb0"),0)); package->assign_pin( 7, m_portb->addPin(new IO_bi_directional_pu("portb1"),1)); package->assign_pin( 8, m_portb->addPin(new IO_bi_directional_pu("portb2"),2)); package->assign_pin( 9, m_portb->addPin(new IO_bi_directional_pu("portb3"),3)); package->assign_pin(10, m_portb->addPin(new IO_bi_directional_pu("portb4"),4)); package->assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb5"),5)); package->assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb6"),6)); package->assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb7"),7)); package->assign_pin(14, 0); package->assign_pin(15, 0); package->assign_pin(16, 0); } void P16x71x::create_symbols() { pic_processor::create_symbols(); addSymbol(Wreg); } //-------------------------------------- void P16C712::create_sfr_map() { if(verbose) cout << "creating c712/6 registers \n"; /* Extra timers and Capture/Compare are like in 16x63 => 16X6X code */ //P16X6X_processor::create_sfr_map(); P16x71x::create_sfr_map(); ccp1con.setIOpin(&(*m_portb)[3], 0, 0, 0); ccp1con.setBitMask(0x3f); ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, 0); add_sfr_register(&trisccp, 0x87, RegisterValue(0xff,0)); add_sfr_register(&dataccp, 0x07, RegisterValue(0x00,0)); } void P16C712::create() { if(verbose) cout << " c712/6 create \n"; P16x71x::create_iopin_map(); /* 14 bits 18 pins connections */ _14bit_processor::create(); create_sfr_map(); //1ccp1con.iopin = portb->pins[2]; } Processor * P16C712::construct(const char *name) { P16C712 *p = new P16C712(name); if(verbose) cout << " c712 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16C712::P16C712(const char *_name, const char *desc) : P16x71x(_name, desc), trisccp(this, "trisccp", "TRISCCP Register"), dataccp(this, "dataccp", "DATACCP Register") { if(verbose) cout << "c712 constructor, type = " << isa() << '\n'; } P16C712::~P16C712() { remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); remove_sfr_register(&trisccp); remove_sfr_register(&dataccp); } //-------------------------------------- Processor * P16C716::construct(const char *name) { P16C716 *p = new P16C716(name); if(verbose) cout << " c716 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16C716::P16C716(const char *_name, const char *desc) : P16C712(_name, desc) { if(verbose) cout << "c716 constructor, type = " << isa() << '\n'; } //-------------------------------------- Processor * P16F716::construct(const char *name) { P16F716 *p = new P16F716(name); if(verbose) cout << " f716 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } void P16F716::create_sfr_map() { P16x71x::create_sfr_map(); add_sfr_register(&pwm1con, 0x18, RegisterValue(0,0)); add_sfr_register(&eccpas, 0x19, RegisterValue(0,0)); eccpas.setIOpin(&(*m_portb)[4], 0, &(*m_portb)[0]); eccpas.link_registers(&pwm1con, &ccp1con); // portb3 already set ccp1con.setIOpin(0, &(*m_portb)[5], &(*m_portb)[6], &(*m_portb)[7]); ccp1con.setBitMask(0xff); ccp1con.pwm1con = &pwm1con; ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas); } void P16F716::create() { if(verbose) cout << " c712/6 create \n"; P16x71x::create_iopin_map(); /* 14 bits 18 pins connections */ _14bit_processor::create(); create_sfr_map(); } P16F716::P16F716(const char *_name, const char *desc) : P16C712(_name, desc), eccpas(this, "eccpas", "ECCP Auto-Shutdown Control Register"), pwm1con(this, "pwm1con", "Enhanced PWM Control Register") { if(verbose) cout << "f716 constructor, type = " << isa() << '\n'; } P16F716::~P16F716() { remove_sfr_register(&pwm1con); remove_sfr_register(&eccpas); } //-------------------------------------- void P16C72::create_sfr_map() { if(verbose) cout << "creating c72 registers \n"; // Parent classes just set PIR version 1 pir_set_2_def.set_pir1(pir1_2_reg); pir_set_2_def.set_pir2(pir2_2_reg); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setPir(pir1_2_reg); adcon0.setChannel_Mask(7); // even though there are only 5 inputs... adcon0.setA2DBits(8); intcon = &intcon_reg; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1| ADCON1::PCFG2, 0); adcon1.setNumberOfChannels(5); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } void P16C72::create_symbols() { if(verbose) cout << "c72 create symbols\n"; pic_processor::create_symbols(); } void P16C72::create() { P16C62::create(); P16C72::create_sfr_map(); } Processor * P16C72::construct(const char *name) { P16C72 *p = new P16C72(name); if(verbose) cout << " c72 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16C72::P16C72(const char *_name, const char *desc) : P16C62(_name, desc), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result") { if(verbose) cout << "c72 constructor, type = " << isa() << '\n'; pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir2_2_reg = new PIR2v2(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); delete pir1; delete pir2; pir1 = pir1_2_reg; pir2 = pir2_2_reg; } P16C72::~P16C72() { remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); } //-------------------------------------- void P16C73::create_sfr_map() { if(verbose) cout << "creating c73 registers \n"; // Parent classes just set PIR version 1 pir_set_2_def.set_pir1(pir1_2_reg); pir_set_2_def.set_pir2(pir2_2_reg); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setPir(pir1_2_reg); adcon0.setChannel_Mask(7); // even though there are only 5 inputs... adcon0.setA2DBits(8); intcon = &intcon_reg; //1adcon1.analog_port = porta; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1| ADCON1::PCFG2, 0); adcon1.setNumberOfChannels(5); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } void P16C73::create_symbols() { if(verbose) cout << "c73 create symbols\n"; pic_processor::create_symbols(); } void P16C73::create() { P16C63::create(); P16C73::create_sfr_map(); } Processor * P16C73::construct(const char *name) { P16C73 *p = new P16C73(name); if(verbose) cout << " c73 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16C73::P16C73(const char *_name, const char *desc) : P16C63(_name, desc), adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result") { if(verbose) cout << "c73 constructor, type = " << isa() << '\n'; pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir2_2_reg = new PIR2v2(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); delete pir1; pir1 = pir1_2_reg; delete pir2; pir2 = pir2_2_reg; } P16C73::~P16C73() { remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); } //------------------------------------------------------------ void P16F73::create_sfr_map() { if(verbose) cout << "creating f73 registers \n"; add_sfr_register(pm_rd.get_reg_pmadr(), 0x10d); add_sfr_register(pm_rd.get_reg_pmadrh(), 0x10f); add_sfr_register(pm_rd.get_reg_pmdata(), 0x10c); add_sfr_register(pm_rd.get_reg_pmdath(), 0x10e); add_sfr_register(pm_rd.get_reg_pmcon1(), 0x18c); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0xa0,0xff,0x100); } void P16F73::create_symbols() { if(verbose) cout << "f73 create symbols\n"; pic_processor::create_symbols(); } void P16F73::create() { P16C73::create(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F73::create_sfr_map(); } Processor * P16F73::construct(const char *name) { P16F73 *p = new P16F73(name); if(verbose) cout << " f73 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16F73::P16F73(const char *_name, const char *desc) : P16C73(_name, desc), pm_rd(this) { if(verbose) cout << "f73 constructor, type = " << isa() << '\n'; } P16F73::~P16F73() { remove_sfr_register(pm_rd.get_reg_pmadr()); remove_sfr_register(pm_rd.get_reg_pmadrh()); remove_sfr_register(pm_rd.get_reg_pmdata()); remove_sfr_register(pm_rd.get_reg_pmdath()); remove_sfr_register(pm_rd.get_reg_pmcon1()); } //------------------------------------------------------------ // // 16C74 // void P16C74::create_sfr_map() { if(verbose) cout << "creating c74 registers \n"; // Parent classes just set PIR version 1 pir_set_2_def.set_pir1(pir1_2_reg); pir_set_2_def.set_pir2(pir2_2_reg); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); //1adcon0.analog_port = porta; //1adcon0.analog_port2 = porte; adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setPir(pir1_2_reg); adcon0.setChannel_Mask(7); adcon0.setA2DBits(8); intcon = &intcon_reg; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2, 0); adcon1.setNumberOfChannels(8); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setIOPin(5, &(*m_porte)[0]); adcon1.setIOPin(6, &(*m_porte)[1]); adcon1.setIOPin(7, &(*m_porte)[2]); adcon1.setChannelConfiguration(0, 0xff); adcon1.setChannelConfiguration(1, 0xff); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } void P16C74::create_symbols() { if(verbose) cout << "c74 create symbols\n"; Pic14Bit::create_symbols(); } void P16C74::create() { P16C65::create(); P16C74::create_sfr_map(); } Processor * P16C74::construct(const char *name) { P16C74 *p = new P16C74(name);; if(verbose) cout << " c74 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16C74::P16C74(const char *_name, const char *desc) : P16C65(_name, desc) , adcon0(this,"adcon0", "A2D Control 0"), adcon1(this,"adcon1", "A2D Control 1"), adres(this,"adres", "A2D Result") { if(verbose) cout << "c74 constructor, type = " << isa() << '\n'; pir1_2_reg = new PIR1v2(this,"pir1","Peripheral Interrupt Register",&intcon_reg,&pie1); pir2_2_reg = new PIR2v2(this,"pir2","Peripheral Interrupt Register",&intcon_reg,&pie2); delete pir1; delete pir2; pir1 = pir1_2_reg; pir2 = pir2_2_reg; } P16C74::~P16C74() { remove_sfr_register(&adcon0); remove_sfr_register(&adcon1); remove_sfr_register(&adres); } //------------------------------------------------------------ void P16F74::create_sfr_map() { if(verbose) cout << "creating f74 registers \n"; add_sfr_register(pm_rd.get_reg_pmadr(), 0x10d); add_sfr_register(pm_rd.get_reg_pmadrh(), 0x10f); add_sfr_register(pm_rd.get_reg_pmdata(), 0x10c); add_sfr_register(pm_rd.get_reg_pmdath(), 0x10e); add_sfr_register(pm_rd.get_reg_pmcon1(), 0x18c); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0xa0,0xff,0x100); } void P16F74::create_symbols() { if(verbose) cout << "f74 create symbols\n"; pic_processor::create_symbols(); } void P16F74::create() { P16C74::create(); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F74::create_sfr_map(); } Processor * P16F74::construct(const char *name) { P16F74 *p = new P16F74(name); if(verbose) cout << " f74 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); globalSymbolTable().addModule(p); return p; } P16F74::P16F74(const char *_name, const char *desc) : P16C74(_name, desc), pm_rd(this) { if(verbose) cout << "f74 constructor, type = " << isa() << '\n'; } P16F74::~P16F74() { remove_sfr_register(pm_rd.get_reg_pmadr()); remove_sfr_register(pm_rd.get_reg_pmadrh()); remove_sfr_register(pm_rd.get_reg_pmdata()); remove_sfr_register(pm_rd.get_reg_pmdath()); remove_sfr_register(pm_rd.get_reg_pmcon1()); } gpsim-0.30.0/src/p16f88x.h0000664000076400007640000002746413041763624011753 00000000000000/* Copyright (C) 2010,2015 Roy Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __P16F88X_H__ #define __P16F88X_H__ #include "p16x6x.h" /*************************************************************************** * * Include file for: P16F887, P16F88 * * * ***************************************************************************/ class P16F88x : public _14bit_processor { public: INTCON_14_PIR intcon_reg; PicPortRegister *m_porta; PicTrisRegister *m_trisa; PicPortGRegister *m_portb; PicTrisRegister *m_trisb; WPU *m_wpu; IOC *m_ioc; PicPortRegister *m_portc; PicTrisRegister *m_trisc; T1CON t1con; PIR *pir1; PIE pie1; PIR *pir2; PIE pie2; T2CON t2con; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; CCPCON ccp2con; CCPRL ccpr2l; CCPRH ccpr2h; PCON pcon; SSP_MODULE ssp; PIR1v2 *pir1_2_reg; PIR2v3 *pir2_2_reg; PIR_SET_2 pir_set_2_def; OSCCON *osccon; OSCTUNE osctune; WDTCON wdtcon; USART_MODULE usart; ComparatorModule2 comparator; VRCON vrcon; SRCON srcon; ANSEL ansel; ANSEL_H anselh; ADCON0 adcon0; ADCON1 adcon1; ECCPAS eccpas; PWM1CON pwm1con; PSTRCON pstrcon; sfr_register adresh; sfr_register adresl; PicPortRegister *m_porte; PicPSP_TrisRegister *m_trise; P16F88x(const char *_name=0, const char *desc=0); ~P16F88x(); virtual void set_out_of_range_pm(unsigned int address, unsigned int value); // virtual PROCESSOR_TYPE isa(){return _P16F88x_;}; virtual void create_symbols(); virtual unsigned int register_memory_size () const { return 0x200;}; virtual unsigned int program_memory_size() { return 0; }; virtual void option_new_bits_6_7(unsigned int bits); virtual void create_sfr_map(); // The f628 (at least) I/O pins depend on the Fosc Configuration bits. virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void create(int eesize); virtual void create_iopin_map(); virtual void create_config_memory(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } virtual PIR *get_pir1() { return (pir1); } virtual PIR *get_pir2() { return (pir2); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } }; class P16F884 : public P16F88x { public: virtual PROCESSOR_TYPE isa(){return _P16F884_;}; virtual unsigned int program_memory_size() const { return 4096; }; PicPSP_PortRegister *m_portd; PicTrisRegister *m_trisd; P16F884(const char *_name=0, const char *desc=0); ~P16F884(); static Processor *construct(const char *name); virtual void create_symbols(); virtual void create_sfr_map(); virtual void create_iopin_map(); }; class P16F887 : public P16F884 { public: virtual PROCESSOR_TYPE isa(){return _P16F887_;}; virtual unsigned int program_memory_size() const { return 8192; }; P16F887(const char *_name=0, const char *desc=0); ~P16F887(); static Processor *construct(const char *name); virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F882 : public P16F88x { public: virtual PROCESSOR_TYPE isa(){return _P16F882_;}; virtual unsigned int program_memory_size() const { return 2048; }; P16F882(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); virtual void create_symbols(); virtual void create_sfr_map(); virtual void create_iopin_map(); }; class P16F883 : public P16F882 { public: virtual PROCESSOR_TYPE isa(){return _P16F883_;}; virtual unsigned int program_memory_size() const { return 4096; }; P16F883(const char *_name=0, const char *desc=0); ~P16F883(); static Processor *construct(const char *name); virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F886 : public P16F882 { public: virtual PROCESSOR_TYPE isa(){return _P16F886_;}; virtual unsigned int program_memory_size() const { return 8192; }; P16F886(const char *_name=0, const char *desc=0); ~P16F886(); static Processor *construct(const char *name); virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F631 : public _14bit_processor { public: P16F631(const char *_name=0, const char *desc=0); virtual ~P16F631(); T1CON t1con; PIR *pir1; PIR *pir2; PIE pie1; PIE pie2; TMRL tmr1l; TMRH tmr1h; OSCTUNE osctune; PCON pcon; WDTCON wdtcon; OSCCON *osccon; VRCON_2 vrcon; SRCON srcon; ANSEL ansel; ComparatorModule2 comparator; ADCON0_12F adcon0; ADCON1_16F adcon1; EEPROM_WIDE *e; PIR1v2 *pir1_2_reg; PIR2v3 *pir2_3_reg; INTCON_14_PIR intcon_reg; PIR_SET_2 pir_set_2_def; WPU *m_wpua; WPU *m_wpub; IOC *m_ioca; IOC *m_iocb; virtual PIR *get_pir2() { return (pir2); } virtual PIR *get_pir1() { return (pir1); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } PicPortGRegister *m_porta; PicTrisRegister *m_trisa; PicPortGRegister *m_portb; PicTrisRegister *m_trisb; PicPortRegister *m_portc; PicTrisRegister *m_trisc; a2d_stimulus *m_cvref; a2d_stimulus *m_v06ref; virtual PROCESSOR_TYPE isa(){return _P16F631_;} static Processor *construct(const char *name); void create(int); virtual void create_symbols(); virtual void create_sfr_map(); virtual void create_iopin_map(); virtual void option_new_bits_6_7(unsigned int bits); virtual unsigned int program_memory_size() const { return 0x400; }; virtual unsigned int register_memory_size () const { return 0x200; } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual void create_config_memory(); virtual bool set_config_word(unsigned int address, unsigned int cfg_word); }; class P16F677 : public P16F631 { public: virtual PROCESSOR_TYPE isa(){return _P16F677_;}; virtual unsigned int program_memory_size() const { return 4096; }; virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } P16F677(const char *_name=0, const char *desc=0); ~P16F677(); static Processor *construct(const char *name); SSP_MODULE ssp; ANSEL_H anselh; sfr_register adresh; sfr_register adresl; virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F687 : public P16F677 { public: virtual PROCESSOR_TYPE isa(){return _P16F687_;}; virtual unsigned int program_memory_size() const { return 2048; }; virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } P16F687(const char *_name=0, const char *desc=0); ~P16F687(); static Processor *construct(const char *name); TMRL tmr1l; TMRH tmr1h; PCON pcon; USART_MODULE usart; virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F684 : public _14bit_processor { public: ComparatorModule comparator; virtual PROCESSOR_TYPE isa(){return _P16F684_;}; virtual unsigned int program_memory_size() const { return 2048; }; virtual unsigned int register_memory_size () const { return 0x100;}; virtual void create(int eesize); virtual void create_iopin_map(); virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } virtual void option_new_bits_6_7(unsigned int bits); virtual void create_config_memory(); virtual bool set_config_word(unsigned int, unsigned int); P16F684(const char *_name=0, const char *desc=0); virtual ~P16F684(); static Processor *construct(const char *name); PicPortGRegister *m_porta; PicTrisRegister *m_trisa; PicPortRegister *m_portc; PicTrisRegister *m_trisc; WPU *m_wpua; IOC *m_ioca; T1CON t1con; T2CON t2con; PIR1v3 *pir1; PIE pie1; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; OSCTUNE osctune; PCON pcon; WDTCON wdtcon; OSCCON *osccon; ANSEL ansel; ADCON0_12F adcon0; ADCON1_16F adcon1; sfr_register adresh; sfr_register adresl; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; ECCPAS eccpas; PWM1CON pwm1con; PSTRCON pstrcon; PIR1v3 *pir1_3_reg; INTCON_14_PIR intcon_reg; PIR_SET_1 pir_set_def; IOC *m_iocc; EEPROM_WIDE *e; virtual PIR_SET *get_pir_set() { return (&pir_set_def); } virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F685 : public P16F677 { public: virtual PROCESSOR_TYPE isa(){return _P16F685_;}; virtual unsigned int program_memory_size() const { return 4096; }; virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } P16F685(const char *_name=0, const char *desc=0); ~P16F685(); static Processor *construct(const char *name); T2CON t2con; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; PCON pcon; ECCPAS eccpas; PWM1CON pwm1con; PSTRCON pstrcon; virtual void create_symbols(); virtual void create_sfr_map(); }; class P16F689 : public P16F687 { public: virtual PROCESSOR_TYPE isa(){return _P16F689_;}; virtual unsigned int program_memory_size() const { return 4096; }; virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } P16F689(const char *_name=0, const char *desc=0); static Processor *construct(const char *name); }; class P16F690 : public P16F685 { public: virtual PROCESSOR_TYPE isa(){return _P16F690_;}; virtual unsigned int program_memory_size() const { return 4096; }; virtual void set_eeprom(EEPROM *ep) { // Use set_eeprom_pir as P16F8x expects to have a PIR capable EEPROM assert(0); } virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } P16F690(const char *_name=0, const char *desc=0); ~P16F690(); static Processor *construct(const char *name); CCPCON ccp2con; CCPRL ccpr2l; CCPRH ccpr2h; USART_MODULE usart; virtual void create_symbols(); virtual void create_sfr_map(); }; #endif gpsim-0.30.0/src/cod.h0000664000076400007640000001464113041763624011365 00000000000000/* .cod file support Copyright (C) 1999 James Bowman, Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__COD_H) #define __COD_H #include "program_files.h" /* * .cod definitions * * A .cod file consists of an array of 512 byte blocks. There are two types * of blocks: a "directory" block and a "data" block. The directory block * describes the miscellaneous stuff like the compiler, the date, copy right * and it also describes the type of information that's available in the .cod * file. The "type of information" is specified by a range of blocks. For * example, if there are symbols in the .cod file then the directory block * tells the starting and ending blocks that contain the symbols. * * Types of data blocks: * short symbol table - a list of symbols in the "short format", which * means that the symbol name is restricted to 12 characters. This * is an old format and is not provided by gpasm. * long symbol table - a list of symbols in the "long format". Like the * short symbol table except the symbol names can be up to 255 chars. * list table - a cross reference between the source line numbers, list * line numbers, and the program memory. * Memory map table - describes the ranges of memory used in the processor. * Local variables table - [c files - not supported by gpasm] this describes * the memory locations used by functions. * Source file names - a list of the files used to assemble the source file. * Debug messages - [not supported by gpasm] this provides a list of messages * that can control the simulator or emulator. */ #define COD_BLOCK_BITS 9 /* COD_BLOCK_SIZE = 2^COD_BLOCK_BITS */ /* number of bytes in one cod block */ #define COD_BLOCK_SIZE (1<. */ #include #include #include #include #include #include #include "../config.h" #include "cmd_gpsim.h" #include "ioports.h" #include "modules.h" #include "trace.h" #include "stimuli.h" #include "xref.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d-%s ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //#define D2 #ifdef D2 #define D2printf(arg) {fprintf(stderr, "%s:%d-%s ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define D2printf(arg) {} #endif //-------------------------------------------------- // //-------------------------------------------------- SignalControl::~SignalControl() { } PeripheralSignalSource::PeripheralSignalSource(PinModule *_pin) : m_pin(_pin), m_cState('?') { assert(m_pin); } PeripheralSignalSource::~PeripheralSignalSource() { } void PeripheralSignalSource::release() { } // getState is called when the PinModule is attempting to // update the output state for the I/O Pin. char PeripheralSignalSource::getState() { return m_cState; } /// putState is called when the peripheral output source /// wants to change the output state. void PeripheralSignalSource::putState(const char new3State) { if (new3State != m_cState) { m_cState = new3State; m_pin->updatePinModule(); } } void PeripheralSignalSource::toggle() { switch (m_cState) { case '1': case 'W': putState('0'); break; case '0': case 'w': putState('1'); break; } } //------------------------------------------------------------------- // // ioports.cc // // The ioport infrastructure for gpsim is provided here. The class // taxonomy for the IOPORT class is: // // file_register // |-> sfr_register // |-> IOPORT // |-> PORTA // |-> PORTB // |-> PORTC // |-> PORTD // |-> PORTE // |-> PORTF // // Each I/O port has an associated array of I/O pins which provide an // interface to the virtual external world of the stimuli. // //------------------------------------------------------------------- class SignalSource : public SignalControl { public: SignalSource(PortRegister *_reg, unsigned int bitPosition) : m_register(_reg), m_bitMask(1<getDriving()&m_bitMask)!=0)?'1':'0') : 'Z'; char r = m_register ? (((m_register->getDriving()&m_bitMask)!=0)?'1':'0') : 'Z'; /**/ Dprintf(("SignalSource::getState() %s bitmask:0x%x state:%c\n", (m_register?m_register->name().c_str():"NULL"), m_bitMask,r)); /**/ return r; } private: PortRegister *m_register; unsigned int m_bitMask; }; //------------------------------------------------------------------------ PortSink::PortSink(PortRegister *portReg, unsigned int iobit) : m_PortRegister(portReg), m_iobit(iobit) { assert (m_PortRegister); } void PortSink::setSinkState(char cNewSinkState) { Dprintf((" PortSink::setSinkState:bit=%u,val=%c\n", m_iobit, cNewSinkState)); m_PortRegister->setbit(m_iobit,cNewSinkState); } void PortSink::release() { //cout << "PortSink::release() ;" << this << endl; delete this; } //------------------------------------------------------------------------ PortRegister::PortRegister(Module *pCpu, const char *pName, const char *pDesc, unsigned int numIopins, unsigned int _mask) : sfr_register(pCpu, pName, pDesc), PortModule(numIopins), mEnableMask(_mask), drivingValue(0), rvDrivenValue(0,0) { mValidBits = (1<addSymbol(iopin); return PortModule::addPin(iopin, iPinNumber); } IOPIN * PortRegister::addPin(IOPIN *iopin, unsigned int iPinNumber) { cpu->addSymbol(iopin); return PortModule::addPin(iopin, iPinNumber); } void PortRegister::setEnableMask(unsigned int newEnableMask) { Dprintf (( "PortRegister::setEnableMask for %s to %02X\n", name_str.c_str(), newEnableMask )); mOutputMask = newEnableMask; //unsigned int maskDiff = getEnableMask() ^ newEnableMask; unsigned int oldEnableMask = getEnableMask(); for (unsigned int i=0, m=1; isetDefaultSource(new SignalSource(this, i)); pmP->addSink(new PortSink(this, i)); } else { if (pmP->getSourceState() == '?') { pmP->setDefaultSource(new SignalSource(this, i)); pmP->addSink(new PortSink(this, i)); } } } mEnableMask = newEnableMask; } void PortRegister::put(unsigned int new_value) { trace.raw(write_trace.get() | value.data); put_value(new_value); } void PortRegister::put_value(unsigned int new_value) { Dprintf(("PortRegister::put_value old=0x%x:new=0x%x\n",value.data,new_value)); unsigned int diff = mEnableMask & (new_value ^ value.data); drivingValue = new_value & mEnableMask; value.data = drivingValue; if(diff) { // If no stimuli are connected to the Port pins, then the driving // value and the driven value are the same. If there are external // stimuli (or perhaps internal peripherals) overdriving or overriding // this port, then the call to updatePort() will update 'drivenValue' // to its proper value. In either case, calling updatePort ensures // the drivenValue is updated properly updatePort(); } } //------------------------------------------------------------------------ // PortRegister::updateUI() UI really means GUI. // We just pass control to the update method, which is defined in gpsimValue. void PortRegister::updateUI() { update(); } //------------------------------------------------------------------------ // PortRegister::setbit // // This method is called whenever a stimulus changes the state of // an I/O pin associated with the port register. 3-state logic is // used. // FIXME - rvDrivenValue and value are always the same, so why have // FIXME - both? void PortRegister::setbit(unsigned int bit_number, char new3State) { int set_mask = (1<updatePinModule(); } } void PortModule::updateUI() { // hmmm nothing } void PortModule::updatePin(unsigned int iPinNumber) { if (iPinNumber < mNumIopins) iopins[iPinNumber]->updatePinModule(); } void PortModule::updatePins(unsigned int iPinBitMask) { for (unsigned int i=0,j=1; iupdatePinModule(); } SignalSink *PortModule::addSink(SignalSink *new_sink, unsigned int iPinNumber) { if (iPinNumber < mNumIopins) iopins[iPinNumber]->addSink(new_sink); return new_sink; } IOPIN *PortModule::addPin(IOPIN *new_pin, unsigned int iPinNumber) { if (iPinNumber < mNumIopins) { // If there is not a PinModule for this pin, then add one. if (iopins[iPinNumber] == &AnInvalidPinModule) iopins[iPinNumber] = new PinModule(this,iPinNumber); iopins[iPinNumber]->setPin(new_pin); } else { printf("PortModule::addPin ERROR pin %u > %u\n", iPinNumber, mNumIopins); } return new_pin; } void PortModule::addPinModule(PinModule *newModule, unsigned int iPinNumber) { if (iPinNumber < mNumIopins && iopins[iPinNumber] == &AnInvalidPinModule) iopins[iPinNumber] = newModule; } IOPIN *PortModule::getPin(unsigned int iPinNumber) { if (iPinNumber < mNumIopins) { return &iopins[iPinNumber]->getPin(); } return 0; } //------------------------------------------------------------------------ // PinModule PinModule::PinModule() : PinMonitor(), m_cLastControlState('?'), m_cLastSinkState('?'), m_cLastSourceState('?'), m_cLastPullupControlState('?'), m_defaultSource(0), m_activeSource(0), m_defaultControl(0), m_activeControl(0), m_defaultPullupControl(0), m_activePullupControl(0), m_pin(0), m_port(0), m_pinNumber(0) { for(int i = 0; i < ANALOG_TABLE_SIZE; i++) m_analog_reg[i] = NULL; } PinModule::PinModule(PortModule *_port, unsigned int _pinNumber, IOPIN *_pin) : PinMonitor(), m_cLastControlState('?'), m_cLastSinkState('?'), m_cLastSourceState('?'), m_cLastPullupControlState('?'), m_defaultSource(0), m_activeSource(0), m_defaultControl(0), m_activeControl(0), m_defaultPullupControl(0), m_activePullupControl(0), m_pin(_pin), m_port(_port), m_pinNumber(_pinNumber), m_bForcedUpdate(false) { setPin(m_pin); for(int i = 0; i < 3; i++) m_analog_reg[i] = NULL; } PinModule::~PinModule() { if (m_pin && (m_activeSource != m_defaultSource)) D2printf(("Pin %s sources active %p default %p\n", m_pin->name().c_str(), m_activeSource, m_defaultSource)); if (m_activeSource && (m_activeSource != m_defaultSource)) { //cout << __FUNCTION__ << " deleting active source:"<getState() <release(); m_activeSource = m_defaultSource; } if (m_defaultSource) { m_defaultSource->release(); delete m_defaultSource; m_defaultSource = 0; } if (m_activeControl && (m_activeControl != m_defaultControl)) { m_activeControl->release(); m_activeControl = m_defaultControl; } if (m_defaultControl) { m_defaultControl->release(); m_defaultControl = 0; } if (m_activePullupControl && (m_activePullupControl != m_defaultPullupControl)) m_activePullupControl->release(); if (m_defaultPullupControl) m_defaultPullupControl->release(); if (m_pin) m_pin->setMonitor(0); } void PinModule::setPin(IOPIN *new_pin) { // Replace our pin only if this one is valid and we don't have one already. if (!m_pin && new_pin) { m_pin = new_pin; m_pin->setMonitor(this); m_cLastControlState = getControlState(); m_cLastSourceState = getSourceState(); } } void PinModule::refreshPinOnUpdate(bool bForcedUpdate) { m_bForcedUpdate = bForcedUpdate; } void PinModule::updatePinModule() { if (!m_pin) return; bool bStateChange=m_bForcedUpdate; Dprintf(("PinModule::updatePinModule():%s enter cont=%c,source=%c,pullup%c\n", (m_pin ? m_pin->name().c_str() : "NOPIN"), m_cLastControlState,m_cLastSourceState,m_cLastPullupControlState)); char cCurrentControlState = getControlState(); unsigned int old_dir = m_pin->get_direction(); unsigned int new_dir = (cCurrentControlState=='1') ? IOPIN::DIR_INPUT : IOPIN::DIR_OUTPUT; if (new_dir != old_dir) { m_cLastControlState = cCurrentControlState; m_pin->update_direction(new_dir, false); bStateChange = true; } char cCurrentSourceState = getSourceState(); if (cCurrentSourceState != m_cLastSourceState) { m_cLastSourceState = cCurrentSourceState; m_pin->setDrivingState(cCurrentSourceState); bStateChange = true; } char cCurrentPullupControlState = getPullupControlState(); if (cCurrentPullupControlState != m_cLastPullupControlState) { m_cLastPullupControlState = cCurrentPullupControlState; m_pin->update_pullup(m_cLastPullupControlState,false); bStateChange = true; } if (bStateChange) { Dprintf(("PinModule::updatePinModule() exit cont=%c,source=%c,pullup%c\n", m_cLastControlState,m_cLastSourceState, m_cLastPullupControlState)); if (m_pin->snode) m_pin->snode->update(); else setDrivenState(cCurrentSourceState); } } void PinModule::setDefaultControl(SignalControl *newDefaultControl) { if(!m_defaultControl && newDefaultControl) { m_defaultControl = newDefaultControl; setControl(m_defaultControl); } else delete newDefaultControl; //// YIKES!!! -- wouldn't it be better to return an error code? } void PinModule::setControl(SignalControl *newControl) { m_activeControl = newControl ? newControl : m_defaultControl; } void PinModule::setDefaultSource(SignalControl *newDefaultSource) { if(!m_defaultSource && newDefaultSource) { m_defaultSource = newDefaultSource; setSource(m_defaultSource); } } void PinModule::setSource(SignalControl *newSource) { D2printf(("setSource new %p old %p default %p\n", newSource, m_activeSource, m_defaultSource)); if (m_activeSource && newSource != m_activeSource) m_activeSource->release(); m_activeSource = newSource ? newSource : m_defaultSource; } void PinModule::setDefaultPullupControl(SignalControl *newDefaultPullupControl) { if(!m_defaultPullupControl && newDefaultPullupControl) { m_defaultPullupControl = newDefaultPullupControl; setPullupControl(m_defaultPullupControl); } } void PinModule::setPullupControl(SignalControl *newPullupControl) { m_activePullupControl = newPullupControl ? newPullupControl : m_defaultPullupControl; } char PinModule::getControlState() { return m_activeControl ? m_activeControl->getState() : '?'; } char PinModule::getSourceState() { return m_activeSource ? m_activeSource->getState() : '?'; } char PinModule::getPullupControlState() { return m_activePullupControl ? m_activePullupControl->getState() : '?'; } void PinModule::setDrivenState(char new3State) { m_cLastSinkState = new3State; list :: iterator ssi; for (ssi = sinks.begin(); ssi != sinks.end(); ++ssi) (*ssi)->setSinkState(new3State); } void PinModule::setDrivingState(char new3State) { //printf("PinModule::%s -- does nothing\n",__FUNCTION__); } void PinModule::set_nodeVoltage(double) { //printf("PinModule::%s -- does nothing\n",__FUNCTION__); } void PinModule::putState(char) { //printf("PinModule::%s -- does nothing\n",__FUNCTION__); } void PinModule::setDirection() { //printf("PinModule::%s -- does nothing\n",__FUNCTION__); } void PinModule::updateUI() { m_port->updateUI(); } // AnalogReq is called by modules such as ADC and Comparator // to set or release a pin to/from analog mode. When a pin is in // analog mode the TRIS register is still active and output pins // are still driven high or low, but reads of the port register // return 0 for the pin. When a pin mode is changes the breadboard // name of the pin is changed to newname. // // A table of each calling module is kept as a module may // request analog mode after another has. The pin is put in // analog mode when the first module requests it (up=true) // and is taken out of analog mode when all modules have // requested analog mode to be released (up=false); // void PinModule::AnalogReq(Register * reg, bool analog, const char *newname) { int i, index; unsigned int total_cnt = 0; if (!m_port) return; // is the calling register in the table and what is the current // count of modules requesting analog mode for(i=0, index=-1; i < ANALOG_TABLE_SIZE && m_analog_reg[i]; i++) { if (m_analog_reg[i] == reg) index = i; if (m_analog_active[i]) total_cnt++; } // Register is not in table so add it. // if (index < 0) { assert(i < ANALOG_TABLE_SIZE); // table not large enough index = i; m_analog_reg[index] = reg; m_analog_active[index] = false; } if (analog) // Set pin to analog mode request { m_analog_active[index] = true; if (total_cnt == 0) { unsigned int mask = m_port->getOutputMask(); mask &= ~(1 << getPinNumber()); m_port->setOutputMask(mask); Dprintf(("PinModule::UpAnalogCnt up %s newname=%s mask=%x\n", getPin().name().c_str(), newname, mask)); getPin().newGUIname(newname); getPin().set_is_analog(true); getPin().set_Cth(5e-12); // add analog pin input capacitance } } else if (!analog && m_analog_active[index]) // release register request // for analog pin { m_analog_active[index] = false; if (total_cnt == 1) { const char *pt; unsigned int mask = m_port->getOutputMask(); mask |= (1 << getPinNumber()); Dprintf(("PinModule::UpAnalogCnt down %s newname=%s mask=%x\n", getPin().name().c_str(), newname, mask)); m_port->setOutputMask(mask); pt = strchr(newname, '.'); getPin().newGUIname(pt?pt+1:newname); getPin().set_is_analog(false); getPin().set_Cth(0.); } } } // The IOPORT class is deprecated. #if defined(OLD_IOPORT_DESIGN) //------------------------------------------------------------------- // // IOPORT::update_stimuli // // input: none // return: the states of the stimuli that are driving this ioport // // This member function will update each node that is attached to the // iopins of this port. If there are no pins attached, 0 is returned. // // //------------------------------------------------------------------- int IOPORT::update_stimuli(void) { unsigned int v = value.get(); return v ^ get_value(); } //------------------------------------------------------------------- //------------------------------------------------------------------- double IOPORT::get_bit_voltage(unsigned int bit_number) { double v; if(pins[bit_number]) { if(pins[bit_number]->snode) { cout << "Warning IOPORT::get_bit_voltage has changed\n"; v = pins[bit_number]->snode->get_nodeVoltage(); } else v = pins[bit_number]->get_Vth(); } else v = (value.get() & (1<snode) { double v = pins[i]->snode->get_nodeVoltage(); if(current_value & m) { // this io bit is currently a high if(v <= pins[i]->get_h2l_threshold()) current_value ^= m; } else if (v > pins[i]->get_l2h_threshold()) current_value ^= m; } } value.put(current_value); return(value.get()); } //------------------------------------------------------------------- // IOPORT::get(void) // // inputs: none // returns: the current state of the ioport // // get is identical to get_value except that tracing is performed. // //------------------------------------------------------------------- unsigned int IOPORT::get(void) { trace.raw(read_trace.get() | value.get()); return get_value(); } //------------------------------------------------------------------- // IOPORT::put(unsigned int new_value) // // inputs: new_value - // // returns: none // // The I/O Port is updated with the new value. If there are any stimuli // attached to the I/O pins then they will be updated as well. // //------------------------------------------------------------------- void IOPORT::put(unsigned int new_value) { // The I/O Ports have an internal latch that holds the state of the last // write, even if the I/O pins are configured as inputs. If the tris port // changes an I/O pin from an input to an output, then the contents of this // internal latch will be placed onto the external I/O pin. internal_latch = new_value; trace.raw(write_trace.get() | value.get()); unsigned int current_value = value.get(); value.put(new_value); if(stimulus_mask && (current_value != new_value)) { unsigned int diff = current_value ^ new_value; // Update all I/O pins that have stimuli attached to // them and their state is being changed by this put() operation. for(unsigned int i = 0; i>=1) if((diff&1) && pins[i] && pins[i]->snode) pins[i]->snode->update(); } } //------------------------------------------------------------------- // void IOPORT::put_value(unsigned int new_value) // // When there's a gui initiated change to the IO port, we'll pass // though here. There are three things that we do. First, we update // the I/O port the way the gui asks us. Note however, that it's // possible that the gui's requested will go un-honored (if for example, // we try to force an output to change states or if there's a stimulus // driving the bus already). // Next, after updating the IO port (and all of it's connected stimuli), // we'll call the gui to update its windows. This is done through the // xref->update call. // Finally, we'll check all of the I/O pins that have changed as a // result of the IO port update and individually call each of their // cross references. // //------------------------------------------------------------------- void IOPORT::put_value(unsigned int new_value) { unsigned int i,j; unsigned int old_value = value.get(); unsigned int diff; value.put(new_value); // Update the stimuli - if there are any if(stimulus_mask) update_stimuli(); update(); // Find the pins that have changed states diff = (old_value ^ value.get()) & valid_iopins; // Update the cross references for each pin that has changed. for(i=0,j=1; iupdate(); } } //------------------------------------------------------------------- //------------------------------------------------------------------- void IOPORT::setbit(unsigned int bit_number, bool new_value) { int bit_mask = 1<snode == 0) { // If this I/O pin is not attached to a node yet, // then create a node and attach it. pins[bit_position]->snode = new Stimulus_Node(); pins[bit_position]->snode->attach_stimulus(pins[bit_position]); } // attach the new stimulus to the same node as this I/O pin's pins[bit_position]->snode->attach_stimulus(new_stimulus); } } //------------------------------------------------------------------- //------------------------------------------------------------------- void IOPORT::attach_node(Stimulus_Node *new_node, unsigned int bit_position) { if(pins[bit_position]) { stimulus_mask |= (1<snode == new_node; } else cout << "Error: attaching node to a non-existing I/O pin.\n"; } //------------------------------------------------------------------- // trace_register_write // - a wrapper for trace.register_write // This provides an option for IOPORTs derived from the IOPORT class // to override the behavior of IOPORT traces. //------------------------------------------------------------------- void IOPORT::trace_register_write(void) { trace.raw(write_trace.get() | value.get()); //trace.register_write(address,value.get()); } IOPORT::IOPORT(unsigned int _num_iopins) : sfr_register() { stimulus_mask = 0; num_iopins = _num_iopins; valid_iopins = (1<. */ #ifndef __P16F91X_H__ #define __P16F91X_H__ #include "p16x7x.h" #include "eeprom.h" #include "comparator.h" #include "lcd_module.h" class IOPORT; class P16F91X : public _14bit_processor { public: P16F91X(const char *_name=0, const char *desc=0); ~P16F91X(); INTCON_14_PIR intcon_reg; T1CON t1con; PIR *pir1; PIE pie1; PIR *pir2; PIE pie2; T2CON t2con; PR2 pr2; TMR2 tmr2; TMRL tmr1l; TMRH tmr1h; CCPCON ccp1con; CCPRL ccpr1l; CCPRH ccpr1h; CCPCON ccp2con; CCPRL ccpr2l; CCPRH ccpr2h; PCON pcon; LVDCON_14 lvdcon; SSP_MODULE ssp; PIR1v2 *pir1_2_reg; PIR_SET_2 pir_set_2_def; virtual PIR *get_pir1() { return (pir1_2_reg); } virtual PIR_SET *get_pir_set() { return (&pir_set_2_def); } PIR2v2 *pir2_2_reg; virtual PIR *get_pir2() { return (pir2_2_reg); } ADCON0_91X adcon0; ADCON1_16F adcon1; sfr_register adres; sfr_register adresl; ANSEL_P ansel; USART_MODULE usart; LCD_MODULE lcd_module; WDTCON wdtcon; OSCCON *osccon; OSCTUNE osctune; ComparatorModule comparator; PicPortRegister *m_porta; PicTrisRegister *m_trisa; PicPortBRegister *m_portb; PicTrisRegister *m_trisb; WPU *m_wpub; IOC *m_iocb; PicPortRegister *m_portc; PicTrisRegister *m_trisc; PicPortRegister *m_porte; PicTrisRegister *m_trise; virtual void create_symbols(); virtual void create_sfr_map(); virtual void option_new_bits_6_7(unsigned int bits); virtual void set_eeprom_wide(EEPROM_WIDE *ep) { eeprom = ep; } virtual EEPROM_WIDE *get_eeprom() { return ((EEPROM_WIDE *)eeprom); } virtual void update_vdd(); virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual void enter_sleep(); virtual void exit_sleep(); }; class P16F91X_40 : public P16F91X { public: PicPortRegister *m_portd; PicTrisRegister *m_trisd; virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create_symbols(); virtual void create_sfr_map(); virtual void create_iopin_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; virtual void set_eeprom(EEPROM *ep) { // use set_eeprom_wide as P16F917 expect a wide EEPROM assert(0); } P16F91X_40(const char *_name=0, const char *desc=0); ~P16F91X_40(); private: }; class P16F91X_28 : public P16F91X { public: virtual void set_out_of_range_pm(unsigned int address, unsigned int value); virtual void create_symbols(); virtual void create_sfr_map(); virtual void create_iopin_map(); void create(); virtual unsigned int register_memory_size () const { return 0x200;}; virtual void set_eeprom(EEPROM *ep) { // use set_eeprom_wide as P16F917 expect a wide EEPROM assert(0); } P16F91X_28(const char *_name=0, const char *desc=0); ~P16F91X_28(); private: }; class P16F917 : public P16F91X_40 { public: virtual PROCESSOR_TYPE isa(){return _P16F917_;}; virtual unsigned int program_memory_size() const { return 8192; }; virtual unsigned int register_memory_size () const { return 0x200;}; P16F917(const char *_name=0, const char *desc=0); ~P16F917(); static Processor *construct(const char *name); void create(); void create_sfr_map(); virtual void create_symbols(); private: }; class P16F916 : public P16F91X_28 { public: virtual PROCESSOR_TYPE isa(){return _P16F916_;}; virtual unsigned int program_memory_size() const { return 8192; }; virtual unsigned int register_memory_size () const { return 0x200;}; P16F916(const char *_name=0, const char *desc=0); ~P16F916(); static Processor *construct(const char *name); void create(); void create_sfr_map(); private: }; class P16F914 : public P16F91X_40 { public: virtual PROCESSOR_TYPE isa(){return _P16F914_;}; virtual unsigned int program_memory_size() const { return 4096; }; virtual unsigned int register_memory_size () const { return 0x200;}; P16F914(const char *_name=0, const char *desc=0) : P16F91X_40(_name, desc) {}; static Processor *construct(const char *name); void create(); //RRRvirtual void create_symbols(); private: }; class P16F913 : public P16F91X_28 { public: virtual PROCESSOR_TYPE isa(){return _P16F913_;}; virtual unsigned int program_memory_size() const { return 4096; }; virtual unsigned int register_memory_size () const { return 0x200;}; P16F913(const char *_name=0, const char *desc=0) : P16F91X_28(_name, desc) {}; static Processor *construct(const char *name); void create(); private: }; #endif gpsim-0.30.0/src/gpsim_time.cc0000664000076400007640000006504013041763624013112 00000000000000/* Copyright (C) 1998-2000 T. Scott Dattalo This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include #include #include #include "14bit-processors.h" #include "interface.h" #include #include "stimuli.h" #include "errors.h" #include "../config.h" #include "xref.h" #include "protocol.h" //#define __DEBUG_CYCLE_COUNTER__ //-------------------------------------------------- // Global instantiation of the cycle counter // and the stop watch; //-------------------------------------------------- Cycle_Counter cycles; // create an instance of inline get_cycles() method by taking its address Cycle_Counter &(*dummy_cycles)(void) = get_cycles; StopWatch *stop_watch; //-------------------------------------------------- // member functions for the Cycle_Counter class //-------------------------------------------------- /* Overview of Cycle Counter break points. The Cycle Counter break points coordinate simulation time. At the moment, the cycle counter advances one count for every instruction cycle. Thus "real time" is defined in terms of "instruction cycles". (NOTE - This will change!) Now, the way gpsim uses these break points is by allowing peripherals to grab control of the simulation at a particular instance of time. For example, if the UART peripheral needs to send the next data bit in 100 microseconds, then it needs to have control of the simulator in exactly 100 microseconds from right now. The way this is handled, is that the cycle counter is advanced at every instruction cycle (This will change...) and when the cycle counter matches the cycle that corresponds to that 100 microsecond gap, gpsim will divert control to the UART peripheral. There are 3 components to a cycle counter break point. First there's the obvious thing: the number that corresponds to the cycle at which we wish to break. This is a 64-bit integer and thus should cover a fairly significant simulation interval! A 32-bit integer only covers about 7 minutes of simulation time for a pic running at 20MHz. 64-bits provides over 100,000 years of simulation time! The next component is the call back function. This is a pointer to a function, or actually a class that contains a function, that is called when the current value of the cycle counter matches the break point value. In the UART example, this function will be something that the UART peripheral passed when it set the break point. This is how the UART peripheral gets control of the simulator. Finally, the third component is the linked list mechanism. Each time a break point is set, it gets inserted into a linked list that is sorted by the cycle break point value. Thus the first element in the list (if there are any elements at all) is always the next cycle counter break point. */ Cycle_Counter_breakpoint_list::Cycle_Counter_breakpoint_list() { next = 0; prev = 0 ; f = 0; bActive = false; } Cycle_Counter_breakpoint_list *Cycle_Counter_breakpoint_list::getNext() { return next; } Cycle_Counter_breakpoint_list *Cycle_Counter_breakpoint_list::getPrev() { return prev; } void Cycle_Counter_breakpoint_list::clear() { bActive = false; if(f) f->clear_trigger(); } void Cycle_Counter_breakpoint_list::invoke() { if(bActive) { clear(); if(f) f->callback(); } } //-------------------------------------------------- void Cycle_Counter::preset(guint64 new_value) { value = new_value; get_trace().cycle_counter(value); } void Cycle_Counter::set_instruction_cps(guint64 cps) { if(cps) { m_instruction_cps = (double)cps; m_seconds_per_cycle = 1.0/m_instruction_cps; } } //-------------------------------------------------- // get(double seconds_from_now) // // Return the cycle number that corresponds to a time // biased from the current time. // // INPUT: time in seconds (note that it's a double) // // OUTPUT: cycle count guint64 Cycle_Counter::get(double future_time_from_now) { return value + (guint64)(m_instruction_cps * future_time_from_now); } //-------------------------------------------------- // set_break // set a cycle counter break point. Return 1 if successful. // // The break points are stored in a singly-linked-list sorted by the // order in which they will occur. When this routine is called, the // value of 'future_cycle' is compared against the values in the // 'active' list. bool Cycle_Counter::set_break(guint64 future_cycle, TriggerObject *f, unsigned int bpn) { Cycle_Counter_breakpoint_list *l1 = &active, *l2; static unsigned int CallBackID_Sequence=1; #ifdef __DEBUG_CYCLE_COUNTER__ cout << "Cycle_Counter::set_break cycle = 0x" << hex<callback_print(); } else cout << " does not have callback\n"; #endif l2 = &inactive; if (l2->next == 0) { l2->next = new Cycle_Counter_breakpoint_list; l2->next->prev = l2; } if(inactive.next == 0) { cout << " too many breaks are set on the cycle counter \n"; return 0; } else if(future_cycle <= value) { cout << "Cycle break point was ignored because cycle " << future_cycle << " has already gone by\n"; cout << "current cycle is " << value << '\n'; return 0; } else { // place the break point into the sorted break list bool break_set = false; while( (l1->next) && !break_set) { // If the next break point is at a cycle greater than the // one we wish to set, then we found the insertion point. // Otherwise if(l1->next->break_value >= future_cycle) break_set = true; else l1 = l1->next; } // At this point, we have the position where we need to insert the // break point: it's at l1->next. l2 = l1->next; l1->next = inactive.next; // remove the break point from the 'inactive' list inactive.next = inactive.next->next; l1->next->next = l2; l1->next->prev = l1; if(l2) l2->prev = l1->next; l1->next->break_value = future_cycle; l1->next->f = f; l1->next->breakpoint_number = bpn; l1->next->bActive = true; if(f) f->CallBackID = ++CallBackID_Sequence; #ifdef __DEBUG_CYCLE_COUNTER__ cout << "set_break l1->next=" << hex << l1->next << " "; if (f) f->callback_print(); else cout << endl; cout << "cycle break " << future_cycle << " bpn " << bpn << '\n'; if(f) cout << "call back sequence number = "<< f->CallBackID <<'\n'; #endif } break_on_this = active.next->break_value; return 1; } //-------------------------------------------------- // remove_break // remove break for TriggerObject void Cycle_Counter::clear_break(TriggerObject *f) { Cycle_Counter_breakpoint_list *l1 = &active, *l2 = 0; if(!f) return; while( (l1->next) && !l2) { if(l1->next->f == f) l2 = l1; l1=l1->next; } if(!l2) { //#ifdef __DEBUG_CYCLE_COUNTER__ cout << "WARNING Cycle_Counter::clear_break could not find break point\n Culprit:\t"; f->callback_print(); //#endif return; } // at this point l2->next points to our break point // It needs to be removed from the 'active' list and put onto the 'inactive' list. l1 = l2; l2 = l1->next; // save a copy for a moment l1->next = l1->next->next; // remove the break if(l1->next) l1->next->prev = l1; // fix the backwards link. l2->clear(); #ifdef __DEBUG_CYCLE_COUNTER__ if (f) cout << "Clearing break call back sequence number = "<< f->CallBackID <<'\n'; #endif // Now move the break to the inactive list. l1 = inactive.next; inactive.next = l2; l2->next = l1; break_on_this = active.next ? active.next->break_value : 0; } //-------------------------------------------------- // set_break_delta // set a cycle counter break point relative to the current cpu cycle value. Return 1 if successful. // bool Cycle_Counter::set_break_delta(guint64 delta, TriggerObject *f, unsigned int bpn) { #ifdef __DEBUG_CYCLE_COUNTER__ cout << "Cycle_Counter::set_break_delta delta = 0x" << hex<next && !found) { // If the next break point is at the same cycle as the // one we wish to clear, then we found the deletion point. // Otherwise keep searching. if(l1->next->break_value == at_cycle) found = 1; else l1=l1->next; } if(!found) { cout << "Cycle_Counter::clear_break could not find break at cycle 0x" << hex << setw(16) << setfill('0') << at_cycle << endl; return; } l2 = l1->next; // save a copy for a moment l1->next = l1->next->next; // remove the break if(l1->next) l1->next->prev = l2; l2->clear(); // Now move the break to the inactive list. l1 = inactive.next; if(!l1) return; l2->next = l1; inactive.next = l2; break_on_this = active.next ? active.next->break_value : 0; } //------------------------------------------------------------------------ // breakpoint // // When the cycle counter has encountered a cycle that has a breakpoint, // this routine is called. // void Cycle_Counter::breakpoint() { // There's a break point set on this cycle. If there's a callback function, then call // it other wise halt execution by setting the global break flag. // Loop in case there are multiple breaks //while(value == break_on_this && active.next) { while(active.next && value == active.next->break_value) { if(active.next->f) { // This flag will get set true if the call back // function moves the break point to another cycle. Cycle_Counter_breakpoint_list *l1 = active.next; TriggerObject *lastBreak = active.next->f; // this stops recursive callbacks if (l1->bActive) { l1->bActive = false; l1->f->callback(); } clear_current_break(lastBreak); } else { get_bp().check_cycle_break(active.next->breakpoint_number); clear_current_break(); } } if(active.next) break_on_this = active.next->break_value; } //------------------------------------------------------------------------ // reassign_break // change the cycle of an existing break point. // // This is only called by the internal peripherals and not (directly) by // the user. It's purpose is to accommodate the dynamic and unpredictable // needs of the internal cpu timing. For example, if tmr0 is set to roll // over on a certain cycle and the program changes the pre-scale value, // then the break point has to be moved to the new cycle. bool Cycle_Counter::reassign_break(guint64 old_cycle, guint64 new_cycle, TriggerObject *f) { Cycle_Counter_breakpoint_list *l1 = &active, *l2; bool found_old = false; bool break_set = false; reassigned = true; // assume that the break point does actually get reassigned. #ifdef __DEBUG_CYCLE_COUNTER__ cout << "Cycle_Counter::reassign_break, old " << old_cycle << " new " << new_cycle; if(f) cout << " Call back ID = " << f->CallBackID; cout << '\n'; dump_breakpoints(); #endif // // First, we search for the break point by comparing the 'old_cycle' // with the break point cycle of all active break points. Two criteria // must be satisfied for a match: // // 1) The 'old_cycle' must exactly match the cycle of an active // break point. // 2) The Call back function pointer must exactly match the call back // function point of the same active break point. // // The reason for both of these, is so that we can differentiate multiple // break points set at the same cycle. // // NOTE to consider: // // It would be far more efficient to have the "set_break" function return // a handle or a pointer that we could use here to immediately identify // the break we wish to reassign. This would also disambiguate multiple // breaks set at the same cycle. We'd still have to perform a search through // the linked list to find the new point, but that search would be limited // (i.e. the reassignment is either before *or* after the current). A bi- // directional search can be optimized with a doubly-linked list... while( (l1->next) && !found_old) { // If the next break point is at a cycle greater than the // one we wish to set, then we found the insertion point. if(l1->next->f == f && l1->next->break_value == old_cycle) { #ifdef __DEBUG_CYCLE_COUNTER__ cout << " cycle match "; if(f && (f->CallBackID == l1->next->f->CallBackID)) cout << " Call Back IDs match = " << f->CallBackID << ' '; #endif found_old = true; /* if(l1->next->f == f) found_old = true; else l1 = l1->next; */ } else l1 = l1->next; } if(found_old) { // Now move the break point #ifdef __DEBUG_CYCLE_COUNTER__ cout << " found old "; if(l1->next->bActive == false) { cout << "CycleCounter - reassigning in active break "; if(l1->next->f) l1->next->f->callback_print(); cout << endl; } #endif if(new_cycle > old_cycle) { // First check to see if we can stay in the same relative position within the list // Is this the last one in the list? (or equivalently, is the one after this one // a NULL?) if(l1->next->next == 0) { l1->next->break_value = new_cycle; l1->next->bActive = true; break_on_this = active.next->break_value; #ifdef __DEBUG_CYCLE_COUNTER__ cout << " replaced at current position (next is NULL)\n"; dump_breakpoints(); // debug #endif return 1; } // Is the next one in the list still beyond this one? if(l1->next->next->break_value >= new_cycle) { l1->next->break_value = new_cycle; l1->next->bActive = true; break_on_this = active.next->break_value; #ifdef __DEBUG_CYCLE_COUNTER__ cout << " replaced at current position (next is greater)\n"; dump_breakpoints(); // debug #endif return 1; } // Darn. Looks like we have to move it. #ifdef __DEBUG_CYCLE_COUNTER__ cout << " moving \n"; #endif l2 = l1->next; // l2 now points to this break point l1->next = l1->next->next; // Unlink this break point l1->next->prev = l1; while( l1->next && !break_set) { // If the next break point is at a cycle greater than the // one we wish to set, then we found the insertion point. // Otherwise, continue searching. if(l1->next->break_value > new_cycle) break_set = 1; else l1 = l1->next; } // At this point, we know that our breakpoint needs to be // moved to the position just after l1 l2->next = l1->next; l1->next = l2; l2->prev = l1; if(l2->next) l2->next->prev = l2; break_on_this = active.next->break_value; l2->break_value = new_cycle; l2->bActive = true; #ifdef __DEBUG_CYCLE_COUNTER__ dump_breakpoints(); // debug #endif } else { // old_cycle < new_cycle // First check to see if we can stay in the same relative position within the list #ifdef __DEBUG_CYCLE_COUNTER__ cout << " old cycle is less than new one\n"; #endif // Is this the first one in the list? if(l1 == &active) { l1->next->break_value = new_cycle; l1->next->bActive = true; break_on_this = new_cycle; #ifdef __DEBUG_CYCLE_COUNTER__ cout << " replaced at current position\n"; dump_breakpoints(); // debug #endif return 1; } // Is the previous one in the list still before this one? if(l1->break_value < new_cycle) { l1->next->break_value = new_cycle; l1->next->bActive = true; break_on_this = active.next->break_value; #ifdef __DEBUG_CYCLE_COUNTER__ cout << " replaced at current position\n"; dump_breakpoints(); // debug #endif return 1; } // Darn. Looks like we have to move it. l2 = l1->next; // l2 now points to this break point l1->next = l1->next->next; // Unlink this break point if(l1->next) l1->next->prev = l1; l1 = &active; // Start searching from the beginning of the list while( (l1->next) && !break_set) { // If the next break point is at a cycle greater than the // one we wish to set, then we found the insertion point. // Otherwise if(l1->next->break_value > new_cycle) break_set = 1; else l1 = l1->next; } l2->next = l1->next; if (l2->next) { l2->next->prev = l2; } l1->next = l2; l2->prev = l1; l2->break_value = new_cycle; l2->bActive = true; break_on_this = active.next->break_value; #ifdef __DEBUG_CYCLE_COUNTER__ dump_breakpoints(); // debug #endif } } else { // oops our assumption was wrong, we were unable to reassign the break point // to another cycle because we couldn't find the old one! reassigned = false; // If the break point was not found, it can't be moved. So let's just create // a new break point. cout << "WARNING Cycle_Counter::reassign_break could not find old break point\n"; cout << " a new break will created at cycle: 0x"<callback_print(); } set_break(new_cycle, f); } return 1; } void Cycle_Counter::clear_current_break(TriggerObject *f) { if(active.next == 0) return; if(value == break_on_this && (!f || (f && f==active.next->f))) { #ifdef __DEBUG_CYCLE_COUNTER__ cout << "Cycle_Counter::clear_current_break "; cout << "current cycle " << hex << setw(16) << setfill('0') << value << endl; cout << "clearing current cycle break " << hex << setw(16) << setfill('0') << break_on_this; if(active.next->f) cout << " Call Back ID = " << active.next->f->CallBackID; cout <<'\n'; if(active.next->next && active.next->next->break_value == break_on_this) { cout << " but there's one pending at the same cycle"; if(active.next->next->f) cout << " With ID = " << active.next->next->f->CallBackID; cout << '\n'; } #endif Cycle_Counter_breakpoint_list *l1; active.next->bActive = false; l1 = inactive.next; // ptr to 1st inactive bp inactive.next = active.next; // let the 1st active bp become the 1st inactive one active.next = active.next->next; // The 2nd active bp is now the 1st inactive.next->next = l1; // The 2nd inactive bp used to be the 1st if(active.next) { break_on_this = active.next->break_value; active.next->prev = &active; } else break_on_this = END_OF_TIME; } else { // If 'value' doesn't equal 'break_on_this' then what's most probably // happened is that the breakpoint associated with 'break_on_this' // has invoked a callback function that then did a ::reassign_break(). // There's a slight chance that we have a bug - but very slight... if(verbose & 4) { cout << "debug::Didn't clear the current cycle break because != break_on_this\n"; cout << "value = " << value << "\nbreak_on_this = " << break_on_this <<'\n'; } } } void Cycle_Counter::dump_breakpoints(void) { Cycle_Counter_breakpoint_list *l1 = &active; cout << "Current Cycle " << hex << setw(16) << setfill('0') << value << '\n'; cout << "Next scheduled cycle break " << hex << setw(16) << setfill('0') << break_on_this << '\n'; while(l1->next) { //cout << cpu->name_str << " " << "internal cycle break " << cout << "internal cycle break " << hex << setw(16) << setfill('0') << l1->next->break_value << ' '; if(l1->next->f) l1->next->f->callback_print(); else cout << "does not have callback\n"; l1 = l1->next; } } Cycle_Counter::~Cycle_Counter(void) { Cycle_Counter_breakpoint_list *l1, *l2; int cactive, cinactive; cactive = cinactive = 0; l1 = (&active)->next; while(l1) { cactive++; l2 = l1->next; l1->next = 0; delete l1; l1 = l2; } l1 = (&inactive)->next; while(l1) { cinactive++; l2 = l1->next; l1->next = 0; delete l1; l1 = l2; } } Cycle_Counter::Cycle_Counter(void) { value = 0; break_on_this = END_OF_TIME; m_instruction_cps = 5.0e6; m_seconds_per_cycle = 1 / m_instruction_cps; active.next = 0; active.prev = 0; inactive.next = 0; inactive.prev = 0; } //------------------------------------------------------------------------ // StopWatch // //======================================================================== // Stop Watch Attributes //======================================================================== class StopWatchValue : public Integer { private: StopWatch *sw; public: StopWatchValue(StopWatch *_sw) : Integer("stopwatch",0, " A timer for monitoring and controlling the simulation.\n" " The units are in simulation cycles.\n" " stopwatch.rollover - specifies rollover value.\n" " stopwatch.direction - specifies count direction.\n" " stopwatch.enable - enables counting if true.\n"), sw(_sw) { } virtual void set(Value *v) { Integer::set(v); if(sw) sw->update(); } virtual void get(gint64 &i) { i = (sw) ? sw->get() : 0; Integer::set(i); } virtual int set_break(ObjectBreakTypes bt=eBreakAny, ObjectActionTypes at=eActionHalt, Expression *expr=0) { if(sw) sw->set_break(true); return -1; // FIXME } virtual int clear_break() { if(sw) sw->set_break(false); return -1; // FIXME } }; class StopWatchRollover : public Integer { private: StopWatch *sw; public: StopWatchRollover(StopWatch *_sw) : Integer("stopwatch.rollover", 1000000, " specifies the stop watch roll over time."), sw(_sw) { } virtual void set(Value *v) { Integer::set(v); if(sw) sw->update(); } }; class StopWatchEnable : public Boolean { private: StopWatch *sw; public: StopWatchEnable(StopWatch *_sw) : Boolean("stopwatch.enable", true," If true, the stop watch is enabled."), sw(_sw) { } virtual void set(Value *v) { if(sw) sw->update(); Boolean::set(v); } }; class StopWatchDirection : public Boolean { private: StopWatch *sw; public: StopWatchDirection(StopWatch *_sw) : Boolean("stopwatch.direction", true, " If true, the stop watch counts up otherwise down."), sw(_sw) { } virtual void set(Value *v) { if(!v) return; bool bOldVal = getVal(); bool bNewVal; v->get(bNewVal); if(sw && bOldVal != bNewVal) sw->set_direction(bNewVal); } }; //------------------------------------------------------------ StopWatch::StopWatch() { offset = 0; value = new StopWatchValue(this); rollover = new StopWatchRollover(this); enable = new StopWatchEnable(this); direction = new StopWatchDirection(this); break_cycle = 0; if(!value || !rollover || !enable || !direction) throw Error("StopWatch"); globalSymbolTable().addSymbol(value); globalSymbolTable().addSymbol(rollover); globalSymbolTable().addSymbol(enable); globalSymbolTable().addSymbol(direction); update(); } StopWatch::~StopWatch() { globalSymbolTable().deleteSymbol(value->name()); globalSymbolTable().deleteSymbol(rollover->name()); globalSymbolTable().deleteSymbol(enable->name()); globalSymbolTable().deleteSymbol(direction->name()); } //---------------------------------------- // get() // If the stopwatch is running, then compute // the current value based on the cycle_counter. guint64 StopWatch::get(void) { if(enable->getVal()) { gint64 v = (cycles.get() - offset) % rollover->getVal(); if(!direction->getVal()) v = rollover->getVal() - v; return v; } return value->getVal(); } //---------------------------------------- // get() // If the stopwatch is running, then compute // the current value based on the cycle_counter. double StopWatch::get_time(void) { guint64 current_value =get(); if(current_value) return current_value /4000000.0; return 1.0; } void StopWatch::set_enable(bool b) { if(enable->getVal() != b) enable->set(b); update(); } void StopWatch::set_direction(bool b) { if(direction->getVal() == b) return; direction->set(b); offset = cycles.get() - ((rollover->getVal() - value->getVal()) % rollover->getVal()); if(break_cycle) set_break(true); } void StopWatch::set_rollover(guint64 new_rollover) { // setting the rollover attribute will update the stopwatch too. if(rollover) rollover->set((gint64)new_rollover); } void StopWatch::set_value(guint64 new_value) { if(value) value->set((gint64)new_value); } // update() compute a new offset such that the current // value of the stopwatch is correlated with the cycle counter. void StopWatch::update() { if(enable->getVal()) { if(direction->getVal()) offset = cycles.get() - value->getVal(); else offset = cycles.get() - (rollover->getVal() - value->getVal()); if(break_cycle) set_break(true); } } void StopWatch::set_break(bool b) { if(!b) { cycles.clear_break(this); break_cycle = 0; return; } if(!enable->getVal()) return; guint64 old_break_cycle = break_cycle; if(direction->getVal()) break_cycle = cycles.get() + rollover->getVal() - get(); else break_cycle = cycles.get() + get(); if(old_break_cycle == break_cycle) return; if(old_break_cycle) cycles.reassign_break(old_break_cycle,break_cycle ,this); else cycles.set_break(break_cycle ,this); } void StopWatch::callback() { break_cycle = cycles.get() + rollover->getVal(); cycles.set_break(break_cycle,this); cout << " stopwatch break\n"; get_bp().halt(); } void StopWatch::callback_print() { cout << "stopwatch\n"; } gpsim-0.30.0/src/intcon.cc0000664000076400007640000003336413041763613012251 00000000000000/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include // for guint64 #include #include "intcon.h" #include "gpsim_classes.h" // for RESET_TYPE #include "trace.h" #include "pir.h" #include "16bit-registers.h" #include "16bit-processors.h" #include "breakpoints.h" #include //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //-------------------------------------------------- // member functions for the INTCON base class //-------------------------------------------------- INTCON::INTCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), interrupt_trace(0),in_interrupt(0), portGReg(0) { } void INTCON::set_T0IF() { Dprintf((" INTCON::%s\n",__FUNCTION__)); put(value.get() | T0IF); } void INTCON::set_rbif(bool b) { bool current = (value.get() & RBIF) == RBIF; if (b && !current) put(value.get() | RBIF); if (!b && current) { put(value.get() & ~RBIF); if (portGReg) // check if IOC match condition still exists portGReg->setIOCif(); } } void INTCON::put(unsigned int new_value) { Dprintf((" INTCON::%s\n",__FUNCTION__)); trace.raw(write_trace.get() | value.get()); put_value(new_value); } void INTCON::put_value(unsigned int new_value) { unsigned int diff = new_value ^ value.get(); Dprintf((" INTCON::%s value %02x\n",__FUNCTION__, new_value)); value.put(new_value); // If we are clearing RBIF and we are using simple IOC, reset RBIF if // port miss-match still exists if ((diff & RBIF) && !(new_value & RBIF) && portGReg) portGReg->setIOCif(); // Now let's see if there's a pending interrupt // The INTCON bits are: // GIE | ---- | TOIE | INTE | RBIE | TOIF | INTF | RBIF // There are 3 sources for interrupts, TMR0, RB0/INTF // and RBIF (RB7:RB4 change). If the corresponding interrupt // flag is set AND the corresponding interrupt enable bit // is set AND global interrupts (GIE) are enabled, THEN // there's an interrupt pending. // note: bit6 is not handled here because it is processor // dependent (e.g. EEIE for x84 and ADIE for x7x). if(value.get() & GIE && !in_interrupt && ( ((value.get()>>3)&value.get() & (T0IF | INTF | RBIF)) || ( value.get() & XXIE && check_peripheral_interrupt() ))) cpu_pic->BP_set_interrupt(); } void INTCON::peripheral_interrupt ( bool hi_pri ) { Dprintf((" INTCON::%s\n",__FUNCTION__)); if ( hi_pri ) cout << "Dodgy call to 14-bit INTCON::peripheral_interrupt with priority set\n"; if (cpu_pic->is_sleeping()) cpu_pic->exit_sleep(); if( (value.get() & (GIE | XXIE)) == (GIE | XXIE) && !in_interrupt) cpu_pic->BP_set_interrupt(); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- INTCON2::INTCON2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), m_bsRBPU(0) {} bool INTCON2::assignBitSink(unsigned int bitPosition, BitSink *pBS) { if (bitPosition == 7) m_bsRBPU = pBS; return true; } bool INTCON2::releaseBitSink(unsigned int bitPosition, BitSink *) { if (bitPosition == 7) m_bsRBPU = 0; return true; } //---------------------------------------------------------------------- //---------------------------------------------------------------------- void INTCON2::put_value(unsigned int new_value) { unsigned int old_value = value.get(); value.put(new_value); if ((old_value ^ new_value) & RBPU && m_bsRBPU) m_bsRBPU->setSink((new_value & RBPU) != 0); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- void INTCON2::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- INTCON3::INTCON3(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc) {} //---------------------------------------------------------------------- //---------------------------------------------------------------------- void INTCON3::put_value(unsigned int new_value) { value.put(new_value); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- void INTCON3::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- INTCON_14_PIR::INTCON_14_PIR(Processor *pCpu, const char *pName, const char *pDesc) : INTCON(pCpu, pName, pDesc), pir_set(0), write_mask(0xff) {} void INTCON_14_PIR::put_value(unsigned int new_value) { unsigned int diff = new_value ^ value.get(); value.put(new_value); // Now let's see if there's a pending interrupt // The INTCON bits are: // GIE | ---- | TOIE | INTE | RBIE | TOIF | INTF | RBIF // There are 3 sources for interrupts, TMR0, RB0/INTF // and RBIF (RB7:RB4 change). If the corresponding interrupt // flag is set AND the corresponding interrupt enable bit // is set AND global interrupts (GIE) are enabled, THEN // there's an interrupt pending. // note: bit6 is not handled here because it is processor // dependent (e.g. EEIE for x84 and ADIE for x7x). // If we are clearing IOCIF and we are using simple IOC, reset IOCIF if // port miss-match still exists if ((diff & IOCIF) && !(new_value & IOCIF) && portGReg) portGReg->setIOCif(); if(value.get() & GIE && !in_interrupt && ( ((value.get()>>3) & value.get() & (T0IF | INTF | IOCIF)) || ( value.get() & PEIE && check_peripheral_interrupt() ))) { cpu_pic->BP_set_interrupt(); } } int INTCON_14_PIR::check_peripheral_interrupt() { assert(pir_set != 0); Dprintf((" INTCON::%s\n",__FUNCTION__)); return (pir_set->interrupt_status()); } void INTCON_14_PIR::put(unsigned int new_value) { // preserve read only bits, but do not let them be written unsigned int read_only = value.get() & ~write_mask; Dprintf((" INTCON_14_PIR::%s new_value %02x read_only %02x\n",__FUNCTION__, new_value, read_only)); trace.raw(write_trace.get() | value.get()); put_value((new_value & write_mask) | read_only); } void INTCON_14_PIR::aocxf_val(IOCxF *ptr, unsigned int val) { int i; int sum = val; bool found = false; for(i = 0; i < (int)aocxf_list.size(); i++) { if (aocxf_list[i].ptr_iocxf == ptr) { found = true; aocxf_list[i].val = val; } sum |= aocxf_list[i].val; } if (!found) { aocxf_list.push_back(aocxf()); aocxf_list[i].ptr_iocxf = ptr; aocxf_list[i].val = val; } set_rbif(sum); } void INTCON_14_PIR::set_rbif(bool b) { bool current = (value.get() & IOCIF) == IOCIF; if (b && !current) put_value(value.get() | IOCIF); if (!b && current) put_value(value.get() & ~IOCIF); } //---------------------------------------------------------------------- // INTCON_16 // // intcon for the 16-bit processor cores. // //---------------------------------------------------------------------- INTCON_16::INTCON_16(Processor *pCpu, const char *pName, const char *pDesc) : INTCON(pCpu, pName, pDesc), interrupt_vector(0), rcon(0), intcon2(0), pir_set(0) { } void INTCON_16::peripheral_interrupt ( bool hi_pri ) { Dprintf((" INTCON_16::%s\n",__FUNCTION__)); assert(rcon != 0); if(rcon->value.get() & RCON::IPEN) { // cout << "peripheral interrupt, priority " << hi_pri << "\n"; if ( hi_pri ) { if ( value.get() & GIEH && !in_interrupt ) { set_interrupt_vector(INTERRUPT_VECTOR_HI); cpu_pic->BP_set_interrupt(); } } else { if ( ( value.get() & (GIEH|GIEL) ) == (GIEH|GIEL) && !in_interrupt) { set_interrupt_vector(INTERRUPT_VECTOR_LO); cpu_pic->BP_set_interrupt(); } } } else { if((value.get() & (GIE | XXIE)) == (GIE | XXIE) && !in_interrupt) cpu_pic->BP_set_interrupt(); } } int INTCON_16::check_peripheral_interrupt() { assert(pir_set != 0); Dprintf((" INTCON_16::%s\n",__FUNCTION__)); return (pir_set->interrupt_status()); // Not quite right, but... // was return 0; but that was blatantly broken } //---------------------------------------------------------------------- // void INTCON_16::clear_gies() // // This routine clears the global interrupt enable bit(s). If priority // interrupts are used (IPEN in RCON is set) then the appropriate gie // bit (either giel or gieh) is cleared. // // This routine is called from 16bit_processor::interrupt(). // //---------------------------------------------------------------------- void INTCON_16::clear_gies() { assert(cpu != 0); if ( !(rcon->value.get() & RCON::IPEN) ) put(value.get() & ~GIE); else if ( isHighPriorityInterrupt() ) put(value.get() & ~GIEH); else put(value.get() & ~GIEL); } //---------------------------------------------------------------------- // void INTCON_16::clear_gies() // //---------------------------------------------------------------------- void INTCON_16::set_gies() { assert(rcon != 0); assert(intcon2 != 0); assert(cpu != 0); get(); // Update the current value of intcon // (and emit 'register read' trace). if(rcon->value.get() & RCON::IPEN) { // Interrupt priorities are being used. if(0 == (value.get() & GIEH)) { // GIEH is cleared, so we need to set it put(value.get() | GIEH); return; } else { // GIEH is set. This means high priority interrupts are enabled. // So we most probably got here because of an RETFIE instruction // after handling a low priority interrupt. We could check to see // if GIEL is low before calling put(), but it's not necessary. // So we'll just blindly re-enable giel, and continue with the // simulation. put(value.get() | GIEL); return; } } else { // Interrupt priorities are not used, so re-enable GIEH (which is in // the same bit-position as GIE on the mid-range core). put(value.get() | GIEH); return; } } //---------------------------------------------------------------------- // void INTCON_16::put(unsigned int new_value) // // Here's were the 18cxxx interrupt logic is primarily handled. // // inputs: new_value - // outputs: none // //---------------------------------------------------------------------- void INTCON_16::put(unsigned int new_value) { trace.raw(write_trace.get() | value.get()); put_value(new_value); } void INTCON_16::put_value(unsigned int new_value) { //trace.register_write(address,value.get()); value.put(new_value); //cout << " INTCON_16::put\n"; // Now let's see if there's a pending interrupt // if IPEN is set in RCON, then interrupt priorities // are being used. (In other words, there are two // interrupt priorities on the 18cxxx core. If a // low priority interrupt is being serviced, it's // possible for a high priority interrupt to interject. if(rcon->value.get() & RCON::IPEN) { unsigned int i1; int i2; // Use interrupt priorities // %%%FIXME%%% ***BUG*** - does not attempt to look for peripheral interrupts if( 0 == (value.get() & GIEH) || in_interrupt) return; // Interrupts are disabled // First we check the high priorities and then we check the // low ones. When ever we detect an interrupt, then the // bp.interrupt flag is set (which will cause the interrupt // to be handled at the high level) and additional checks // are aborted. // If TO, INT, or RB flags are set AND their correspond // interrupts are enabled, then the lower three bits of // i1 will reflect this. Note that INTF does NOT have an // associated priority bit! i1 = ( (value.get()>>3)&value.get()) & (T0IF | INTF | RBIF); i2 = check_peripheral_interrupt(); if ( ( i1 & ( (intcon2->value.get() & (T0IF | RBIF)) | INTF) ) || ( i2 & 2 ) ) { set_interrupt_vector(INTERRUPT_VECTOR_HI); cpu_pic->BP_set_interrupt(); return; } // If we reach here, then there are no high priority // interrupts pending. So let's check for the low priority // ones. if ( ( (i1 & (~intcon2->value.get() & (T0IF | RBIF))) || (i2 & 1) ) && (value.get() & GIEL) ) { //cout << " selecting low priority vector\n"; set_interrupt_vector(INTERRUPT_VECTOR_LO); cpu_pic->BP_set_interrupt(); return; } } else { // ignore interrupt priorities set_interrupt_vector(INTERRUPT_VECTOR_HI); if(value.get() & GIE && !in_interrupt) { if( ( (value.get()>>3)&value.get()) & (T0IF | INTF | RBIF) ) cpu_pic->BP_set_interrupt(); else if(value.get() & XXIE) { if(check_peripheral_interrupt()) cpu_pic->BP_set_interrupt(); } } } } gpsim-0.30.0/src/14bit-registers.h0000664000076400007640000007126313111705326013544 00000000000000/* Copyright (C) 1998 T. Scott Dattalo Copyright (C) 2013 Roy R. Rankin This file is part of the libgpsim library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include class InvalidRegister; // Forward reference #include "trace.h" #ifndef __14_BIT_REGISTERS_H__ #define __14_BIT_REGISTERS_H__ class _14bit_processor; #include "breakpoints.h" #include "rcon.h" #include "intcon.h" #include "pir.h" class stimulus; // forward reference class IOPIN; class source_stimulus; class Stimulus_Node; class PORTB; class pic_processor; #include "ioports.h" //--------------------------------------------------------- // BORCON register // class BORCON : public sfr_register { public: BORCON(Processor *, const char *pName, const char *pDesc=0); void put(unsigned int new_value); void put_value(unsigned int new_value); }; //--------------------------------------------------------- // BSR register // class BSR : public sfr_register { public: BSR(Processor *, const char *pName, const char *pDesc=0); unsigned int register_page_bits; void put(unsigned int new_value); void put_value(unsigned int new_value); }; //--------------------------------------------------------- // FSR register // class FSR : public sfr_register { public: FSR(Processor *, const char *pName, const char *pDesc=0); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); }; //--------------------------------------------------------- // FSR_12 register - FSR for the 12-bit core processors. // // class FSR_12 : public FSR { public: unsigned int valid_bits; unsigned int register_page_bits; /* Only used by the 12-bit core to define the valid paging bits in the FSR. */ FSR_12(Processor *, const char *pName, unsigned int _register_page_bits, unsigned int _valid_bits); virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); }; //--------------------------------------------------------- // Status register // class RCON; class Status_register : public sfr_register { public: #define STATUS_Z_BIT 2 #define STATUS_C_BIT 0 #define STATUS_DC_BIT 1 #define STATUS_PD_BIT 3 #define STATUS_TO_BIT 4 #define STATUS_OV_BIT 3 //18cxxx #define STATUS_N_BIT 4 //18cxxx #define STATUS_FSR0_BIT 4 //17c7xx #define STATUS_FSR1_BIT 6 //17c7xx #define STATUS_Z (1<put_PD(new_pd); else { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~STATUS_PD) | ((new_pd) ? STATUS_PD : 0)); } } inline unsigned int get_PD() { if (rcon) return (rcon->get_PD()); else { get_trace().raw(read_trace.get() | value.get()); return( ( (value.get() & STATUS_PD) == 0) ? 0 : 1); } } inline void put_TO(unsigned int new_to) { if (rcon) rcon->put_TO(new_to); else { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~STATUS_TO) | ((new_to) ? STATUS_TO : 0)); } } inline unsigned int get_TO() { if (rcon) return(rcon->get_TO()); else { get_trace().raw(read_trace.get() | value.get()); return( ( (value.get() & STATUS_TO) == 0) ? 0 : 1); } } // Special member function to set Z, C, DC, OV, and N for the 18cxxx family // Special member function to control just the N bit void put_N_Z(unsigned int new_value) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~(STATUS_Z | STATUS_N)) | ((new_value & 0xff ) ? 0 : STATUS_Z) | ((new_value & 0x80) ? STATUS_N : 0)); } void put_Z_C_N(unsigned int new_value) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~(STATUS_Z | STATUS_C | STATUS_N)) | ((new_value & 0xff ) ? 0 : STATUS_Z) | ((new_value & 0x100) ? STATUS_C : 0) | ((new_value & 0x80) ? STATUS_N : 0)); } inline void put_Z_C_DC_OV_N(unsigned int new_value, unsigned int src1, unsigned int src2) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~ (STATUS_Z | STATUS_C | STATUS_DC | STATUS_OV | STATUS_N)) | ((new_value & 0xff ) ? 0 : STATUS_Z) | ((new_value & 0x100) ? STATUS_C : 0) | (((new_value ^ src1 ^ src2)&0x10) ? STATUS_DC : 0) | (((new_value ^ src1) & 0x80) ? STATUS_OV : 0) | ((new_value & 0x80) ? STATUS_N : 0)); } inline void put_Z_C_DC_OV_N_for_sub(unsigned int new_value, unsigned int src1, unsigned int src2) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~ (STATUS_Z | STATUS_C | STATUS_DC | STATUS_OV | STATUS_N)) | ((new_value & 0xff) ? 0 : STATUS_Z) | ((new_value & 0x100) ? 0 : STATUS_C) | (((new_value ^ src1 ^ src2)&0x10) ? 0 : STATUS_DC) | ((((src1 & ~src2 & ~new_value) | (new_value & ~src1 & src2)) & 0x80) ? STATUS_OV : 0) | ((new_value & 0x80) ? STATUS_N : 0)); } // Special member function to control just the FSR mode void put_FSR0_mode(unsigned int new_value) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~(STATUS_FSR0_MODE)) | (new_value & 0x03 )); } unsigned int get_FSR0_mode(unsigned int new_value) { get_trace().raw(write_trace.get() | value.get()); return( (value.get()>>STATUS_FSR0_BIT) & 0x03); } void put_FSR1_mode(unsigned int new_value) { get_trace().raw(write_trace.get() | value.get()); value.put((value.get() & ~(STATUS_FSR1_MODE)) | (new_value & 0x03 )); } unsigned int get_FSR1_mode(unsigned int new_value) { get_trace().raw(read_trace.get() | value.get()); return( (value.get()>>STATUS_FSR1_BIT) & 0x03); } }; #include "gpsim_time.h" //--------------------------------------------------------- // Stack // class Stack { public: unsigned int contents[32]; /* the stack array */ int pointer; /* the stack pointer */ unsigned int stack_mask; /* 1 for 12bit, 7 for 14bit, 31 for 16bit */ bool stack_warnings_flag; /* Should over/under flow warnings be printed? */ bool break_on_overflow; /* Should over flow cause a break? */ bool break_on_underflow; /* Should under flow cause a break? */ explicit Stack(Processor *); virtual ~Stack() {} virtual bool push(unsigned int); virtual bool stack_overflow(); virtual bool stack_underflow(); virtual unsigned int pop(); virtual void reset(RESET_TYPE r) {pointer = 0;}; // %%% FIX ME %%% reset may need to change // because I'm not sure how the stack is affected by a reset. virtual bool set_break_on_overflow(bool clear_or_set); virtual bool set_break_on_underflow(bool clear_or_set); virtual unsigned int get_tos(); virtual void put_tos(unsigned int); bool STVREN; Processor *cpu; }; class STKPTR : public sfr_register { public: enum { STKUNF = 1<<6, STKOVF = 1<<7 }; STKPTR(Processor *, const char *pName, const char *pDesc=0); Stack *stack; void put_value(unsigned int new_value); void put(unsigned int new_value); }; class TOSL : public sfr_register { public: TOSL(Processor *, const char *pName, const char *pDesc=0); Stack *stack; virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); }; class TOSH : public sfr_register { public: TOSH(Processor *, const char *pName, const char *pDesc=0); Stack *stack; virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); }; // // Stack for enhanced 14 bit porcessors // class Stack14E : public Stack { public: STKPTR stkptr; TOSL tosl; TOSH tosh; explicit Stack14E(Processor *); ~Stack14E(); virtual void reset(RESET_TYPE r); virtual unsigned int pop(); virtual bool push(unsigned int address); virtual bool stack_overflow(); virtual bool stack_underflow(); #define NO_ENTRY 0x20 }; //--------------------------------------------------------- // W register class WTraceType; class WREG : public sfr_register { public: WREG(Processor *, const char *pName, const char *pDesc=0); ~WREG(); protected: WTraceType *m_tt; }; #include "tmr0.h" //--------------------------------------------------------- // INDF class INDF : public sfr_register { public: unsigned int fsr_mask; unsigned int base_address_mask1; unsigned int base_address_mask2; INDF(Processor *, const char *pName, const char *pDesc=0); void put(unsigned int new_value); virtual void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); virtual void initialize(); }; //--------------------------------------------------------- // // Indirect_Addressing // // This class coordinates the indirect addressing on the 18cxxx // parts. Each of the registers comprising the indirect addressing // subsystem: FSRnL,FSRnH, INDFn, POSTINCn, POSTDECn, PREINCn, and // PLUSWn are each individually defined as sfr_registers AND included // in the Indirect_Addressing class. So accessing these registers // is the same as accessing any register: through the core cpu's // register memory. The only difference for these registers is that // the class Indirect_Addressing14; // Forward reference //--------------------------------------------------------- // FSR registers class FSRL14 : public sfr_register { public: FSRL14(Processor *, const char *pName, const char *pDesc, Indirect_Addressing14 *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); protected: Indirect_Addressing14 *iam; }; class FSRH14 : public sfr_register { public: FSRH14(Processor *, const char *pName, const char *pDesc, Indirect_Addressing14 *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); protected: Indirect_Addressing14 *iam; }; class INDF14 : public sfr_register { public: INDF14(Processor *, const char *pName, const char *pDesc, Indirect_Addressing14 *pIAM); void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); unsigned int get_value(); protected: Indirect_Addressing14 *iam; }; class Indirect_Addressing14 { public: Indirect_Addressing14(pic_processor *cpu, const string &n); pic_processor *cpu; unsigned int fsr_value; // 16bit concatenation of fsrl and fsrh unsigned int fsr_state; /* used in conjunction with the pre/post incr * and decrement. This is mainly needed for * those instructions that perform read-modify- * write operations on the indirect registers * eg. btg POSTINC1,4 . The post increment must * occur after the bit is toggled and not during * the read operation that's determining the * current state. */ int fsr_delta; /* If there's a pending update to the fsr register * pair, then the magnitude of that update is * stored here. */ guint64 current_cycle; /* Stores the cpu cycle when the fsr was last * changed. */ FSRL14 fsrl; FSRH14 fsrh; INDF14 indf; //void init(_16bit_processor *new_cpu); void put(unsigned int new_value); unsigned int get(); unsigned int get_value(); void put_fsr(unsigned int new_fsr); unsigned int get_fsr_value(){return (fsr_value & 0xfff);}; void update_fsr_value(); /* bool is_indirect_register(unsigned int reg_address) * * The purpose of this routine is to determine whether or not the * 'reg_address' is the address of an indirect register. This is * used by the 'put' and 'get' functions of the indirect registers. * Indirect registers are forbidden access to other indirect registers. * (Although double indirection in a single instruction cycle would * be powerful!). */ inline bool is_indirect_register(unsigned int reg_address) { unsigned int bank_address = reg_address % 0x80; if(bank_address == 0 || bank_address == 1 || bank_address == 4 || bank_address == 5 || bank_address == 6 || bank_address == 7) return 1; return 0; } }; //--------------------------------------------------------- // PCL - Program Counter Low // class PCL : public sfr_register { public: virtual void put(unsigned int new_value); virtual void put_value(unsigned int new_value); virtual unsigned int get(); virtual unsigned int get_value(); virtual void reset(RESET_TYPE r); PCL(Processor *, const char *pName, const char *pDesc=0); }; //--------------------------------------------------------- // PCLATH - Program Counter Latch High // class PCLATH : public sfr_register { public: void put(unsigned int new_value); void put_value(unsigned int new_value); unsigned int get(); PCLATH(Processor *, const char *pName, const char *pDesc=0); }; //--------------------------------------------------------- // PCON - Power Control/Status Register // class PCON : public sfr_register { public: enum { BOR = 1<<0, // clear on Brown Out Reset POR = 1<<1, // clear on Power On Reset RI = 1<<2, // clear on Reset instruction RMCLR = 1<<3, // clear if hardware MCLR occurs SBOREN = 1<<4, // Software BOR Enable bit ULPWUE = 1<<5, // Ultra Low-Power Wake-up Enable bit STKUNF = 1<<6, // Stack undeflow STKOVF = 1<<7 // Stack overflow }; unsigned int valid_bits; void put(unsigned int new_value); PCON(Processor *, const char *pName, const char *pDesc=0, unsigned int bitMask=0x03); }; class OSCCON; class OSCTUNE : public sfr_register { public: void put(unsigned int new_value); virtual void set_osccon(OSCCON *new_osccon) { osccon = new_osccon;} unsigned int valid_bits; enum { TUN0 = 1<<0, TUN1 = 1<<1, TUN2 = 1<<2, TUN3 = 1<<3, TUN4 = 1<<4, TUN5 = 1<<5, PLLEN= 1<<6, INTSRC=1<<7 }; OSCCON *osccon; OSCTUNE(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), valid_bits(6), osccon(0) { } }; // This class is used to trim the frequency of the internal RC clock // 111111 - Max freq // 100000 - no adjustment // 000000 - mix freq class OSCCAL : public sfr_register { public: void put(unsigned int new_value); void set_freq(float base_freq); float base_freq; OSCCAL(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bitMask) : sfr_register(pCpu,pName,pDesc), base_freq(0.) { mValidBits=bitMask; // Can't use initialiser for parent class members } }; class OSCCON : public sfr_register, public TriggerObject { public: virtual void put(unsigned int new_value); virtual void callback(); virtual bool set_rc_frequency(bool override=false); virtual void set_osctune(OSCTUNE *new_osctune) { osctune = new_osctune;} virtual void set_config_irc(unsigned int cfg_irc){config_irc = cfg_irc;} virtual void set_config_xosc(unsigned int cfg_xosc){config_xosc = cfg_xosc;} virtual void set_config_ieso(unsigned int cfg_ieso){config_ieso = cfg_ieso;} virtual void reset(RESET_TYPE r); virtual void sleep(); virtual void wake(); virtual void por_wake(); virtual bool internal_RC(); virtual void clear_irc_stable_bits() { value.put(value.get() & ~(HTS|LTS));} virtual guint64 irc_por_time(); // time to stable intrc after power on reset virtual guint64 irc_lh_time(); // time to stable intrc after tran low to high range unsigned int write_mask; unsigned int clock_state; guint64 future_cycle; bool config_irc; // FOSC bits select internal RC oscillator bool config_ieso; //internal/external switchover bit from config word bool config_xosc; // FOSC bits select crystal/resonator bool has_iofs_bit; bool is_sleeping; OSCTUNE *osctune; enum MODE { UNDEF = 0, EXCSTABLE, // external source LFINTOSC, // Low Freq RC osc MFINTOSC, // Med Freq rc osc HFINTOSC, // High Freq RC osc INTOSC, // IOFS set T1OSC, // T1 OSC EC, // external clock, always stable OST, // startup PLL = 0x10 }; enum { SCS0 = 1<<0, SCS1 = 1<<1, LTS = 1<<1, HTS = 1<<2, IOFS = 1<<2, OSTS = 1<<3, IRCF0 = 1<<4, IRCF1 = 1<<5, IRCF2 = 1<<6, IDLEN = 1<<7 }; OSCCON(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc), write_mask(0x71), clock_state(OST), future_cycle(0), config_irc(false), config_ieso(true), config_xosc(false), has_iofs_bit(false), is_sleeping(false), osctune(0) { } }; /* OSCCON_1 IOFS bit takes 4 ms to stablize */ class OSCCON_1 : public OSCCON { public: // virtual void callback(); // virtual void put(unsigned int new_value); virtual guint64 irc_por_time(); // time to stable intrc after power on reset virtual guint64 irc_lh_time(); OSCCON_1(Processor *pCpu, const char *pName, const char *pDesc) : OSCCON(pCpu,pName,pDesc) { } }; class OSCCON2 : public sfr_register { public: void put(unsigned int new_value); void set_osccon(OSCCON *new_osccon) { osccon = new_osccon;} OSCCON2(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) , write_mask(0x1c), osccon(0) {;} unsigned int write_mask; enum { LFIOFS = 1<<0, // LFINTOSC Frequency Stable bit MFIOFS = 1<<1, // MFINTOSC Frequency Stable bit PRISD = 1<<2, // Primary Oscillator Drive Circuit Shutdown bit SOSCGO = 1<<3, // Secondary Oscillator Start Control bit MFIOSEL = 1<<4, // MFINTOSC Select bit SOSCRUN = 1<<6, // SOSC Run Status bit PLLRDY = 1<<7 // PLL Run Status bit }; OSCCON *osccon; }; /* RC clock 16Mhz with pll to 64Mhz */ class OSCCON_HS : public OSCCON { public: virtual bool set_rc_frequency(bool override=false); virtual bool internal_RC(); virtual void callback(); virtual void por_wake(); OSCCON_HS(Processor *pCpu, const char *pName, const char *pDesc) : OSCCON(pCpu, pName, pDesc), osccon2(0), minValPLL(5) {} OSCCON2 *osccon2; enum { SCS0 = 1<<0, SCS1 = 1<<1, HFIOFS = 1<<2, OSTS = 1<<3, IRCF0 = 1<<4, IRCF1 = 1<<5, IRCF2 = 1<<6, IDLEN = 1<<7 }; unsigned char minValPLL; }; class OSCSTAT : public sfr_register { public: void put(unsigned int new_value){;} enum { HFIOFS = 1<<0, LFIOFR = 1<<1, MFIOFR = 1<<2, HFIOFL = 1<<3, HFIOFR = 1<<4, OSTS = 1<<5, PLLR = 1<<6, T1OSCR = 1<<7 }; OSCSTAT(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu,pName,pDesc) {} }; /* * OSC status in OSCSTAT register */ class OSCCON_2 : public OSCCON { public: virtual void put(unsigned int new_value); void put_value(unsigned int new_value); virtual void callback(); virtual bool set_rc_frequency(bool override = false); virtual void set_oscstat(OSCSTAT *_oscstat) { oscstat = _oscstat;} virtual void set_callback(); virtual void por_wake(); OSCSTAT *oscstat; enum { SCS0 = 1<<0, SCS1 = 1<<1, IRCF0 = 1<<3, IRCF1 = 1<<4, IRCF2 = 1<<5, IRCF3 = 1<<6, SPLLEN = 1<<7 }; OSCCON_2(Processor *pCpu, const char *pName, const char *pDesc) : OSCCON(pCpu,pName,pDesc), oscstat(0) { } }; class WDTCON : public sfr_register { public: unsigned int valid_bits; enum { WDTPS3 = 1<<4, WDTPS2 = 1<<3, WDTPS1 = 1<<2, WDTPS0 = 1<<1, SWDTEN = 1<<0 }; WDTCON(Processor *pCpu, const char *pName, const char *pDesc, unsigned int bits) : sfr_register(pCpu,pName,pDesc), valid_bits(bits) { } virtual void put(unsigned int new_value); virtual void reset(RESET_TYPE r); }; // Interrupt-On-Change GPIO Register class IOC : public sfr_register { public: IOC(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _valid_bits = 0xff) : sfr_register(pCpu,pName,pDesc) { mValidBits=_valid_bits; } virtual void put(unsigned int new_value) { unsigned int masked_value = new_value & mValidBits; get_trace().raw(write_trace.get() | value.get()); value.put(masked_value); } }; // Interrupt-On-Change Register class IOCxF : public IOC { public: IOCxF(Processor *pCpu, const char *pName, const char *pDesc, unsigned int _valid_bits = 0xff) : IOC(pCpu,pName,pDesc, _valid_bits), intcon(0) { } void set_intcon(INTCON *new_value) { intcon = new_value; } void put(unsigned int new_value); protected: INTCON *intcon; }; class PicPortRegister; // WPU set weak pullups on pin by pin basis // class WPU : public sfr_register { public: PicPortRegister *wpu_gpio; bool wpu_pu; void put(unsigned int new_value); void set_wpu_pu(bool pullup_enable); WPU(Processor *pCpu, const char *pName, const char *pDesc, PicPortRegister* gpio, unsigned int mask=0x37) : sfr_register(pCpu,pName,pDesc), wpu_gpio(gpio), wpu_pu(false) { mValidBits=mask; // Can't use initialiser for parent class members } }; class CPSCON1; class T1CON_G; class CPS_stimulus; // Capacitance Sensing Control Register 0 class CPSCON0 : public sfr_register, public TriggerObject { public: enum { T0XCS = 1<<0, // Timer0 External Clock Source Select bit CPSOUT = 1<<1, // Capacitive Sensing Oscillator Status bit CPSRNG0 = 1<<2, // Capacitive Sensing Current Range bits CPSRNG1 = 1<<3, CPSRM = 1<<6, // Capacitive Sensing Reference Mode bit CPSON = 1<<7 // CPS Module Enable bit }; void put(unsigned int new_value); void set_chan(unsigned int _chan); void calculate_freq(); void set_pin(unsigned int _chan, PinModule *_pin) { pin[_chan] = _pin;} void set_DAC_volt(double); void set_FVR_volt(double); void callback(); virtual void callback_print(); CPSCON0(Processor *pCpu, const char *pName, const char *pDesc=0); ~CPSCON0(); TMR0 *m_tmr0; T1CON_G *m_t1con_g; private: unsigned int chan; PinModule *pin[16]; double DAC_voltage; double FVR_voltage; guint64 future_cycle; int period; CPS_stimulus *cps_stimulus; }; // Capacitance Sensing Control Register 1 class CPSCON1 : public sfr_register { public: void put(unsigned int new_value); CPSCON1(Processor *pCpu, const char *pName, const char *pDesc) : sfr_register(pCpu, pName, pDesc), m_cpscon0(0) { mValidBits = 0x03; } CPSCON0 *m_cpscon0; }; class CPS_stimulus : public stimulus { public: CPS_stimulus(CPSCON0 *arg, const char *n=0, double _Vth=0.0, double _Zth=1e12 ); CPSCON0 *m_cpscon0; virtual void set_nodeVoltage(double v); }; class SR_MODULE; // SR LATCH CONTROL 0 REGISTER class SRCON0 : public sfr_register { public: enum { SRPR = 1<<0, // Pulse Reset Input of the SR Latch bit SRPS = 1<<1, // Pulse Set Input of the SR Latch bit SRNQEN = 1<<2, // Latch Not Q Output Enable bit SRQEN = 1<<3, // Latch Q Output Enable bit SRCLK0 = 1<<4, // Latch Clock Divider bits SRCLK1 = 1<<5, // Latch Clock Divider bits SRCLK2 = 1<<6, // Latch Clock Divider bits SRLEN = 1<<7, // Latch Enable bit CLKMASK = SRCLK0|SRCLK1|SRCLK2, CLKSHIFT = 4 }; SRCON0(Processor *pCpu, const char *pName, const char *pDesc, SR_MODULE *_sr_module); void put(unsigned int new_value); private: SR_MODULE *m_sr_module; }; // SR LATCH CONTROL 1 REGISTER // class SRCON1 : public sfr_register { public: enum { SRRC1E = 1<<0, // Latch C1 Reset Enable bit SRRC2E = 1<<1, // Latch C2 Reset Enable bit SRRCKE = 1<<2, // Latch Reset Clock Enable bit SRRPE = 1<<3, // Latch Peripheral Reset Enable bit SRSC1E = 1<<4, // Latch C1 Set Enable bit SRSC2E = 1<<5, // Latch C2 Set Enable bit SRSCKE = 1<<6, // Latch Set Clock Enable bit SRSPE = 1<<7 // Latch Peripheral Set Enable bit }; SRCON1(Processor *pCpu, const char *pName, const char *pDesc, SR_MODULE *m_sr_module); void put(unsigned int new_value); void set_ValidBits(unsigned int validbits) { mValidBits = validbits;} private: SR_MODULE *m_sr_module; unsigned int mValidBits; }; class SRinSink; class SR_MODULE: public TriggerObject { public: explicit SR_MODULE(Processor *); ~SR_MODULE(); void update(); SRCON0 srcon0; SRCON1 srcon1; void pulse_reset() { state_reset = true;} void pulse_set() { state_set = true;} void clock_diff(unsigned int); void clock_enable(); void clock_disable(); void syncC1out(bool val); void syncC2out(bool val); void setPins(PinModule *, PinModule *,PinModule *); void setState(char); void Qoutput(); void NQoutput(); void releasePin(int); protected: void callback(); Processor *cpu; guint64 future_cycle; bool state_set; bool state_reset; bool state_Q; unsigned int srclk; bool syncc1out; // Synced output from comparator 1 bool syncc2out; // Synced output from comparator 2 PinModule *SRI_pin; PinModule *SRQ_pin; PinModule *SRNQ_pin; bool SRI; // state of input pin SRinSink *m_SRinSink; PeripheralSignalSource *m_SRQsource; PeripheralSignalSource *m_SRNQsource; bool m_SRQsource_active; bool m_SRNQsource_active; }; class LVDCON_14 : public sfr_register, public TriggerObject { public: unsigned int valid_bits; enum { LVDL0 = 1<<0, LVDL1 = 1<<1, LVDL2 = 1<<2, LVDEN = 1<<4, IRVST = 1<<5, }; LVDCON_14(Processor *, const char *pName, const char *pDesc=0); void check_lvd(); unsigned int write_mask; InterruptSource *IntSrc; void callback(); void put(unsigned int new_value); virtual void setIntSrc(InterruptSource *_IntSrc) { IntSrc = _IntSrc;} }; #endif gpsim-0.30.0/src/exports.h0000664000076400007640000000204413041763613012314 00000000000000#ifndef __GPSIM_EXPORTS_H__ #define __GPSIM_EXPORTS_H__ #ifdef _WIN32 // Microsoft Visual C DLL export and import macros // for classes exported from gpsim.exe. // Supported by GCC on Windows. // Each DLL will need its own versions with xxx_DLL_EXPORT // defined for the modules that contain the code. # if defined(LIBGPSIM_DLL_EXPORT) # define LIBGPSIM_EXT_CLASS __declspec( dllexport ) # define LIBGPSIM_EXPORT __declspec( dllexport ) // #pragma message ("dllexport") # else # define LIBGPSIM_EXT_CLASS __declspec( dllimport ) # define LIBGPSIM_EXPORT // #pragma message ("dllimport") # endif #else # define LIBGPSIM_EXT_CLASS # define LIBGPSIM_EXPORT // #pragma message ("LIBGPSIM_EXT_CLASS defined a nothing") #endif class ProgramFileType; /// /// Exported functions bool LIBGPSIM_EXPORT IsFileExtension(const char *pszFile, const char *pFileExt); void LIBGPSIM_EXPORT RegisterProgramFileType(ProgramFileType * pPFT); void LIBGPSIM_EXPORT EnableRealTimeMode(bool bEnable); void LIBGPSIM_EXPORT EnableRealTimeModeWithGui(bool bEnable); #endif gpsim-0.30.0/ylwrap0000755000076400007640000001531212734477075011130 00000000000000#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2013-01-12.17; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard () { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input=$1 shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case $input in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input=`pwd`/$input ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test $# -ne 0; do if test x"$1" = x"--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog=$1 shift # Make any relative path in $prog absolute. case $prog in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog=`pwd`/$prog ;; esac dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target=../$to;; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget=$target target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gpsim-0.30.0/configure0000775000076400007640000243760313117441636011600 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for gpsim 0.30.0. # # Report bugs to <>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: about your $0: system, including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='gpsim' PACKAGE_TARNAME='gpsim' PACKAGE_VERSION='0.30.0' PACKAGE_STRING='gpsim 0.30.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="config.h.in" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBDL GLIB GDK GTK X_LDFLAGS X_CFLAGS Y_LDFLAGS Y_CFLAGS LIBOBJS POW_LIB ALLOCA LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED LIBTOOL LEXLIB LEX_OUTPUT_ROOT LEX YFLAGS YACC LN_S CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX LIBREADLINE P_GTK_LIBS P_GTK_CFLAGS P_GLIB_LIBS P_GLIB_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC host_os host_vendor host_cpu host build_os build_vendor build_cpu build MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_leak_sanitize enable_address_sanitize enable_undefined_sanitize enable_gui enable_sockets enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR P_GLIB_CFLAGS P_GLIB_LIBS P_GTK_CFLAGS P_GTK_LIBS CXX CXXFLAGS CCC CXXCPP YACC YFLAGS LT_SYS_LIBRARY_PATH' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures gpsim 0.30.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gpsim] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of gpsim 0.30.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-leak-sanitize Enable memory leak debugging --enable-address-sanitize Enable memory error debugging --enable-undefined-sanitize Enable undefined behavior detection --disable-gui Only use the cli and not the gui --enable-sockets Allows gpsim to be controlled via a socket interface --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path P_GLIB_CFLAGS C compiler flags for P_GLIB, overriding pkg-config P_GLIB_LIBS linker flags for P_GLIB, overriding pkg-config P_GTK_CFLAGS C compiler flags for P_GTK, overriding pkg-config P_GTK_LIBS linker flags for P_GTK, overriding pkg-config CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. LT_SYS_LIBRARY_PATH User-defined run-time library search path. Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to <>. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF gpsim configure 0.30.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------------------------------- ## ## Report this to ## ## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES # --------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_cxx_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func # ac_fn_cxx_compute_int LINENO EXPR VAR INCLUDES # ---------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_cxx_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by gpsim $as_me 0.30.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" am__api_version='1.15' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='gpsim' VERSION='0.30.0' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # Determine the host and build type. The target is always a PIC. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Check whether --enable-leak-sanitize was given. if test "${enable_leak_sanitize+set}" = set; then : enableval=$enable_leak_sanitize; case "${enableval}" in yes) use_leak_sanitize=yes ;; no) use_leak_sanitize=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-leak-sanitize" "$LINENO" 5 ;; esac else use_leak_sanitize=no fi if test "$use_leak_sanitize" = "yes"; then echo enabling memory leak debugging LD_SANITIZE="-fsanitize=leak" else LD_SANITIZE="" fi # Check whether --enable-address-sanitize was given. if test "${enable_address_sanitize+set}" = set; then : enableval=$enable_address_sanitize; case "${enableval}" in yes) use_address_sanitize=yes ;; no) use_address_sanitize=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-address-sanitize" "$LINENO" 5 ;; esac else use_address_sanitize=no fi if test "$use_address_sanitize" = "yes"; then echo enabling memory address debugging LD_ADDRESS="-fsanitize=address" else LD_ADDRESS="" fi # Check whether --enable-undefined-sanitize was given. if test "${enable_undefined_sanitize+set}" = set; then : enableval=$enable_undefined_sanitize; case "${enableval}" in yes) use_undefined_sanitize=yes ;; no) use_undefined_sanitize=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-undefined-sanitize" "$LINENO" 5 ;; esac else use_undefined_sanitize=no fi if test "$use_undefined_sanitize" = "yes"; then echo enabling undefined behavior detection LD_UNDEFINED="-fsanitize=undefined" else LD_UNDEFINED="" fi # Check whether --enable-gui was given. if test "${enable_gui+set}" = set; then : enableval=$enable_gui; case "${enableval}" in yes) use_gui=yes ;; no) use_gui=no ;; *) as_fn_error $? "bad value ${enableval} for --disable-gui" "$LINENO" 5 ;; esac else use_gui=yes fi if test "$use_gui" = "no"; then echo disabling gui support else echo enabling gui support use_gui=yes $as_echo "#define HAVE_GUI /**/" >>confdefs.h fi # Check whether --enable-sockets was given. if test "${enable_sockets+set}" = set; then : enableval=$enable_sockets; case "${enableval}" in yes) use_sockets=yes ;; no) use_sockets=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-sockets" "$LINENO" 5 ;; esac else use_sockets=no fi if test "$use_sockets" = "no"; then echo disabling gpsim socket interface else echo enabling gpsim socket interface use_sockets=yes $as_echo "#define HAVE_SOCKETS /**/" >>confdefs.h fi DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "popt.h" "ac_cv_header_popt_h" "$ac_includes_default" if test "x$ac_cv_header_popt_h" = xyes; then : else as_fn_error $? "popt not installed: cannot find popt.h" "$LINENO" 5 fi GTK= GDK= GLIB= if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test "$use_gui" = "no"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for P_GLIB" >&5 $as_echo_n "checking for P_GLIB... " >&6; } if test -n "$P_GLIB_CFLAGS"; then pkg_cv_P_GLIB_CFLAGS="$P_GLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_P_GLIB_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$P_GLIB_LIBS"; then pkg_cv_P_GLIB_LIBS="$P_GLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_P_GLIB_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then P_GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0" 2>&1` else P_GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$P_GLIB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0) were not met: $P_GLIB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables P_GLIB_CFLAGS and P_GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables P_GLIB_CFLAGS and P_GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else P_GLIB_CFLAGS=$pkg_cv_P_GLIB_CFLAGS P_GLIB_LIBS=$pkg_cv_P_GLIB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi X_LDFLAGS=$P_GLIB_LIBS X_CFLAGS=$P_GLIB_CFLAGS Y_LDFLAGS= Y_CFLAGS= else # PKG_CHECK_MODULES(GTKEXTRAMOD, gtkextra-2.0, , # [PKG_CHECK_MODULES(GTKEXTRAMOD, gtkextra-3.0, , # [AC_MSG_ERROR(Cannot find gtkextra-2.0 or gtkextra-3.0 package)])]) pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for P_GTK" >&5 $as_echo_n "checking for P_GTK... " >&6; } if test -n "$P_GTK_CFLAGS"; then pkg_cv_P_GTK_CFLAGS="$P_GTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_P_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$P_GTK_LIBS"; then pkg_cv_P_GTK_LIBS="$P_GTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_P_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then P_GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0" 2>&1` else P_GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$P_GTK_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0) were not met: $P_GTK_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables P_GTK_CFLAGS and P_GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables P_GTK_CFLAGS and P_GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else P_GTK_CFLAGS=$pkg_cv_P_GTK_CFLAGS P_GTK_LIBS=$pkg_cv_P_GTK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi X_LDFLAGS=$P_GTK_LIBS X_CFLAGS=$P_GTK_CFLAGS # Y_LDFLAGS=$GTKEXTRAMOD_LIBS # Y_CFLAGS=$GTKEXTRAMOD_CFLAGS GTK_VERSION_T=`$PKG_CONFIG --modversion gtk+-2.0` echo linking with gtk-$GTK_VERSION_T cat >>confdefs.h <<_ACEOF #define GTK_VERSION "$GTK_VERSION_T" _ACEOF fi ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" if test "x$ac_cv_header_readline_readline_h" = xyes; then : fi if test "$ac_cv_header_readline_readline_h" = yes; then cat > conftest.$ac_ext < #include wi_LIB_READLINE_VERSION RL_VERSION_MAJOR RL_VERSION_MINOR EOF wi_READLINE_VERSION=$($CPP $CPPFLAGS conftest.$ac_ext | sed -n -e "s/^wi_LIB_READLINE_VERSION *\([0-9\][0-9\]*\) *\([0-9\][0-9\]*\)$/\1.\2/p") rm -rf conftest* if test -n "$wi_READLINE_VERSION"; then wi_MAJOR=$(expr $wi_READLINE_VERSION : '\([0-9][0-9]*\)\.') wi_MINOR=$(expr $wi_READLINE_VERSION : '[0-9][0-9]*\.\([0-9][0-9]*$\)') if test $wi_MINOR -lt 10; then wi_MINOR=$(expr $wi_MINOR \* 10) fi wi_READLINE_VERSION=$(expr $wi_MAJOR \* 100 + $wi_MINOR) else wi_READLINE_VERSION=-1 fi ac_save_LIBS="$LIBS" # Note: $LIBCURSES is permitted to be empty. for LIBREADLINE in "-lreadline.dll" "-lreadline" "-lreadline $LIBCURSES" "-lreadline -ltermcap" "-lreadline -lncurses" "-lreadline -lcurses" do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU Readline library $LIBREADLINE" >&5 $as_echo_n "checking for GNU Readline library $LIBREADLINE... " >&6; } LIBS="$ac_save_LIBS $LIBREADLINE" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* includes */ #include #include int main () { /* function-body */ int dummy = rl_completion_append_character; /* rl_completion_append_character appeared in version 2.1 */ readline(NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : wi_cv_lib_readline=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else wi_cv_lib_readline=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$wi_cv_lib_readline" = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE $wi_READLINE_VERSION _ACEOF break fi done LIBS="$ac_save_LIBS" fi if test "$wi_cv_lib_readline" != yes; then as_fn_error $? "Cannot find readline library" "$LINENO" 5 fi # Checks for programs. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: # Checks for libraries. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu #AC_CHECK_LIB([gpsim], [main]) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpopt" >&5 $as_echo_n "checking for main in -lpopt... " >&6; } if ${ac_cv_lib_popt_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpopt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_popt_main=yes else ac_cv_lib_popt_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_popt_main" >&5 $as_echo "$ac_cv_lib_popt_main" >&6; } if test "x$ac_cv_lib_popt_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPOPT 1 _ACEOF LIBS="-lpopt $LIBS" fi #AC_CHECK_LIB([pthread], [main]) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : LIBDL="-ldl" fi # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in fcntl.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/file.h sys/ioctl.h sys/socket.h sys/time.h termios.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_cxx_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF # Checks for library functions. # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if ${ac_cv_prog_gcc_traditional+:} false; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi #AC_FUNC_MALLOC #AC_FUNC_REALLOC for ac_header in sys/select.h sys/socket.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5 $as_echo_n "checking types of arguments for select... " >&6; } if ${ac_cv_func_select_args+:} false; then : $as_echo_n "(cached) " >&6 else for ac_arg234 in 'fd_set *' 'int *' 'void *'; do for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif int main () { extern int select ($ac_arg1, $ac_arg234, $ac_arg234, $ac_arg234, $ac_arg5); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done done # Provide a safe default value. : "${ac_cv_func_select_args=int,int *,struct timeval *}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5 $as_echo "$ac_cv_func_select_args" >&6; } ac_save_IFS=$IFS; IFS=',' set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` IFS=$ac_save_IFS shift cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG1 $1 _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG234 ($2) _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG5 ($3) _ACEOF rm -f conftest* { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5 $as_echo_n "checking for working strtod... " >&6; } if ${ac_cv_func_strtod+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_strtod=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifndef strtod double strtod (); #endif int main() { { /* Some versions of Linux strtod mis-parse strings with leading '+'. */ char *string = " +69"; char *term; double value; value = strtod (string, &term); if (value != 69 || term != (string + 4)) return 1; } { /* Under Solaris 2.4, strtod returns the wrong value for the terminating character under some conditions. */ char *string = "NaN"; char *term; strtod (string, &term); if (term != string && *(term - 1) == 0) return 1; } return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_func_strtod=yes else ac_cv_func_strtod=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5 $as_echo "$ac_cv_func_strtod" >&6; } if test $ac_cv_func_strtod = no; then case " $LIBOBJS " in *" strtod.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;; esac ac_fn_cxx_check_func "$LINENO" "pow" "ac_cv_func_pow" if test "x$ac_cv_func_pow" = xyes; then : fi if test $ac_cv_func_pow = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 $as_echo_n "checking for pow in -lm... " >&6; } if ${ac_cv_lib_m_pow+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pow (); int main () { return pow (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_m_pow=yes else ac_cv_lib_m_pow=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 $as_echo "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes; then : POW_LIB=-lm else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5 $as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} fi fi fi for ac_func in floor gethostbyname gethostname gettimeofday memset pow select socket sqrt strcasecmp strchr strdup strerror strncasecmp strndup strpbrk strrchr strstr strtoul do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # printf modifier define for long long as "ll" # config_win32.h.in defines this for Visual Studio stdclib as "I64" $as_echo "#define PRINTF_INT64_MODIFIER \"ll\"" >>confdefs.h # define printf modifier for GINT64 (guint64 and gint64) as "ll" on 32 bit machines and as "l" on 64 bit machines # config_win32.h.in defines this for Visual Studio stdclib as "I64" # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF if test "$ac_cv_sizeof_long" -ge 8; then gpsim_cv_printf_gint64_modifier=l else gpsim_cv_printf_gint64_modifier=ll fi cat >>confdefs.h <<_ACEOF #define PRINTF_GINT64_MODIFIER "$gpsim_cv_printf_gint64_modifier" _ACEOF AM_CFLAGS= AM_CXXFLAGS= AM_LDFLAGS= # Options for the system on which the package will run case "${host}" in *linux* ) if test "x$GCC" = "xyes"; then AM_CFLAGS="-Wall" AM_CXXFLAGS="-Wall" AM_LDFLAGS="-Wl,-warn-common -Wl,-warn-once" fi ;; *mingw* ) ;; esac CFLAGS="${CFLAGS} ${AM_CFLAGS} ${LD_SANITIZE} ${LD_ADDRESS} ${LD_UNDEFINED}" CXXFLAGS="${CXXFLAGS} ${AM_CXXFLAGS} ${LD_SANITIZE} ${LD_ADDRESS} ${LD_UNDEFINED}" LDFLAGS="${LDFLAGS} ${AM_LDFLAGS} ${LD_SANITIZE} ${LD_ADDRESS} ${LD_UNDEFINED}" # Host filesystem options case "${host}" in *mingw* | *-pc-os2_emx | *-pc-os2-emx | *djgpp* ) $as_echo "#define HAVE_DOS_BASED_FILE_SYSTEM 1" >>confdefs.h ;; esac ac_config_files="$ac_config_files Makefile cli/Makefile doc/Makefile examples/Makefile examples/modules/Makefile examples/projects/Makefile examples/12bit/Makefile examples/14bit/Makefile examples/16bit/Makefile eXdbm/Makefile gpsim/Makefile gui/Makefile modules/Makefile extras/Makefile extras/lcd/Makefile extras/dht11/Makefile extras/ds1820/Makefile extras/ds1307/Makefile extras/solar/Makefile extras/graphic_lcd/Makefile regression/Makefile src/Makefile src/dspic/Makefile xpms/Makefile gpsim.spec" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by gpsim $as_me 0.30.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to <>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ gpsim config.status 0.30.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "cli/Makefile") CONFIG_FILES="$CONFIG_FILES cli/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "examples/modules/Makefile") CONFIG_FILES="$CONFIG_FILES examples/modules/Makefile" ;; "examples/projects/Makefile") CONFIG_FILES="$CONFIG_FILES examples/projects/Makefile" ;; "examples/12bit/Makefile") CONFIG_FILES="$CONFIG_FILES examples/12bit/Makefile" ;; "examples/14bit/Makefile") CONFIG_FILES="$CONFIG_FILES examples/14bit/Makefile" ;; "examples/16bit/Makefile") CONFIG_FILES="$CONFIG_FILES examples/16bit/Makefile" ;; "eXdbm/Makefile") CONFIG_FILES="$CONFIG_FILES eXdbm/Makefile" ;; "gpsim/Makefile") CONFIG_FILES="$CONFIG_FILES gpsim/Makefile" ;; "gui/Makefile") CONFIG_FILES="$CONFIG_FILES gui/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "extras/Makefile") CONFIG_FILES="$CONFIG_FILES extras/Makefile" ;; "extras/lcd/Makefile") CONFIG_FILES="$CONFIG_FILES extras/lcd/Makefile" ;; "extras/dht11/Makefile") CONFIG_FILES="$CONFIG_FILES extras/dht11/Makefile" ;; "extras/ds1820/Makefile") CONFIG_FILES="$CONFIG_FILES extras/ds1820/Makefile" ;; "extras/ds1307/Makefile") CONFIG_FILES="$CONFIG_FILES extras/ds1307/Makefile" ;; "extras/solar/Makefile") CONFIG_FILES="$CONFIG_FILES extras/solar/Makefile" ;; "extras/graphic_lcd/Makefile") CONFIG_FILES="$CONFIG_FILES extras/graphic_lcd/Makefile" ;; "regression/Makefile") CONFIG_FILES="$CONFIG_FILES regression/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/dspic/Makefile") CONFIG_FILES="$CONFIG_FILES src/dspic/Makefile" ;; "xpms/Makefile") CONFIG_FILES="$CONFIG_FILES xpms/Makefile" ;; "gpsim.spec") CONFIG_FILES="$CONFIG_FILES gpsim.spec" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: gpsim-$PACKAGE_VERSION is now configured for $canonical_host_type Build: $build Host: $host Source directory: $srcdir Installation prefix: $prefix C compiler: $CC $CPPFLAGS $CFLAGS C++ compiler: $CXX $CPPFLAGS $CXXFLAGS gui: $use_gui Socket interface: $use_sockets " >&5 $as_echo " gpsim-$PACKAGE_VERSION is now configured for $canonical_host_type Build: $build Host: $host Source directory: $srcdir Installation prefix: $prefix C compiler: $CC $CPPFLAGS $CFLAGS C++ compiler: $CXX $CPPFLAGS $CXXFLAGS gui: $use_gui Socket interface: $use_sockets " >&6; } gpsim-0.30.0/compile0000755000076400007640000001624512734477075011250 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gpsim-0.30.0/ChangeLog0000664000076400007640000155000713117465701011433 000000000000002017-06-12 Roy Rankin * configure.ac : Change to release 0.30.0 * extras/i2c2par extras/i2c2par/Makefile.am extras/i2c2par/examples extras/i2c2par/examples/Makefile.am extras/i2c2par/examples/i2c2par.asm extras/i2c2par/i2c2par.cc extras/i2c2par/i2c2par.h extras/i2c2par/makefile.mingw extras/i2c2par/module_manager.cc : Delete i2c2par source in extras as it is already included * extras/lcd/raw_lcd.cc extras/lcd/raw_lcd.h : Catch changes on cc pin * plat/win32/gpsim.nsi : Fix windows cleanup * extras/lcd/examples/lcd_916.asm extras/lcd/examples/lcd_917.asm extras/lcd/examples/lcd_mod.asm regression/a2d/p16c71.asm regression/a2d/p16f819.asm regression/a2d/p16f871.asm regression/a2d/p16f873a.asm regression/a2d/p16f874a.asm regression/a2d/p16f88.asm regression/ccp/pwm_877a.asm regression/comparator/compar_882.asm regression/epwm/p16f882.asm regression/epwm/p16f887.asm regression/epwm/p18f1220.asm regression/epwm/p18f2321.asm regression/epwm/p18f26k22.asm regression/epwm/p18f4321.asm regression/i2c/p16f819.asm regression/i2c/p16f88.asm regression/instructions_14bit/instructions_14bit.asm regression/logic_test/logic_test.asm regression/node_test/node_test.asm regression/p16f684/a2d_684.asm regression/p16f684/epwm.asm regression/p16f690/epwm.asm regression/p16f84/p16f84.asm regression/p16f88x/a2d.asm regression/p16f88x/comparator.asm regression/p16f88x/epwm.asm regression/p16f88x/i2c_slave.asm regression/p16f88x/p16f882.asm regression/p16f88x/p16f883.asm regression/p16f88x/p16f886.asm regression/p16f88x/p16f887.asm regression/p16f91x/i2c_slave.asm regression/p16f91x/p16f913.asm regression/p16f91x/p16f914.asm regression/p16f91x/p16f916.asm regression/p16f91x/p16f917.asm regression/p16f91x/pwm_914.asm regression/p1xf18xx/p16f1823_spi.asm regression/psp/p16f871.asm regression/psp/p18f452.asm regression/psp/p18f6520.asm regression/register_stim/register_stim.asm regression/resistor/resistor.asm regression/switch_test/switch_test.asm : Align interrupt code 2017-06-10 Roy Rankin * PROCESSORS doc/gpsim.html src/p18x.cc src/p18x.h src/pic-processor.cc src/pic-processor.h : patch #46 Support for 18F258/18F458 * src/16bit-registers.h src/pic-registers.cc src/registers.h : bug #229 PCL of 16-bit devices isn't shown properly in RAM view * src/comparator.h : bug #227 Compile error * doc/gpsim.lyx : Update extras module section * src/lcd_module.cc : Fix debug print formats for 32 bit systems 2017-06-05 Roy Rankin * gui/gui_breadboard.cc : fix default filename for "Save Configuration" * modules/ttl.cc modules/usart.cc src/14bit-processors.cc src/14bit-registers.cc src/dsm_module.cc src/p16f88x.cc src/p16f8x.cc src/p18fk.cc src/p18x.cc src/stimuli.cc : Remove debug printf statements 2017-06-04 Roy Rankin * cli/cmd_stimulus.cc gui/gui_breadboard.cc : give full name for stimulus * cli/scan.ll : allow \"text\" as well as "text" * extras/lcd/Makefile.am plat/win32/gpsim.nsi : fixes for win32 build 2017-06-01 Roy Rankin * src/makefile.mingw plat/win32/gpsim.nsi extras/makefile.mingw gpsim/makefile.mingw gui/makefile.mingw plat/win32/make.mingw extras/ds1307/examples/Makefile extras/Makefile.am src/uart.cc src/uart.h : Fix windows build * extras/lcd/Makefile.am extras/lcd/examples/lcd_916.asm extras/lcd/examples/lcd_917.asm extras/lcd/examples/p16c64.inc extras/lcd/examples/p16c84.inc extras/lcd/raw_lcd.cc extras/lcd/raw_lcd.h extras/module_manager.cc : Add 7 segment LCD display * src/a2d_v2.cc src/a2dconverter.cc : Improve debugging * src/interface.cc : remove blank line * src/lcd_module.cc src/lcd_module.h src/p16f91x.cc src/p16f91x.h src/14bit-tmrs.cc src/14bit-tmrs.h regression/p16f91x/Makefile regression/p16f91x/p16f913.asm : Implement LCD module * src/p16f88x.cc : fix 16f685 program memory r/w * src/p16f8x.cc src/p16f8x.h src/14bit-registers.cc src/14bit-registers.h src/p1xf1xxx.cc regression/p18f26k22/osccon_26k22.asm : Fix osccon wake issue 2017-05-08 Roy Rankin * regression/p16f91x/Makefile regression/p16f91x/ccp_917.asm regression/p16f91x/compar_917.asm regression/p16f91x/i2c_low.inc regression/p16f91x/i2c_slave.asm regression/p16f91x/p16f913.asm regression/p16f91x/p16f914.asm regression/p16f91x/p16f916.asm regression/p16f91x/p16f917.asm regression/p16f91x/pwm_914.asm regression/p16f91x/usart_917.asm regression/p18f26k22/osccon_26k22.asm regression/run_regression.sh src/14bit-processors.cc src/14bit-registers.cc src/14bit-registers.h src/Makefile.am src/a2dconverter.cc src/a2dconverter.h src/comparator.cc src/comparator.h src/eeprom.cc src/lcd_module.cc src/lcd_module.h src/p16f91x.cc src/p16f91x.h src/pic-processor.cc src/pic-processor.h src/pir.cc src/pir.h : Add P16f91x processors (LCD functionality pending) 2017-04-27 Roy Rankin * regression/p16f690/Makefile regression/p16f690/eusart.asm regression/run_regression.sh regression/p16f690/eusart_690.asm : Add 690 eusart test * regression/p16f690/p16f690.asm regression/p18f26k22/Makefile regression/p18f26k22/osccon_26k22.asm regression/p1xf18xx/p16f1823.asm regression/p1xf18xx/p16f1823_i2c.asm regression/p1xf18xx/p16f1825.asm regression/wdt/nwdt_16f1823.asm regression/wdt/nwdt_16f88.asm regression/wdt/wdt_16f88.asm regression/p1xf18xx/Makefile regression/p16f88x/eusart.asm : Add OSCCON test, fix assert messages * src/14bit-processors.cc src/14bit-processors.h src/14bit-registers.h src/16bit-processors.h src/16bit-registers.cc src/16bit-registers.h src/p16f88x.cc src/p16f8x.cc src/p16f8x.h src/p18fk.cc src/p18fk.h src/p18x.cc src/p18x.h src/processor.cc src/processor.h src/14bit-registers.cc : Bug #226 OSCCON not setting LTS bit for p16f685, 2 clock startup * src/p1xf1xxx.cc src/p1xf1xxx.h : Add DSM functionality * extras/solar/solar.cc extras/solar/solar.h src/a2dconverter.cc src/cod.cc src/trace.cc : fix debug format 2017-04-19 Roy Rankin * src/p18x.cc src/p18x.h src/pic-processor.cc src/pic-processor.h : Feature request #55 Add P18f2525 processor 2017-03-23 Errol van de l'Isle * cli/cmd_module.cc cli/input.cc extras/rs232-gen/rs232-gen.c extras/solar/solar.cc modules/paraface.cc modules/resistor.cc modules/ttl.cc src/fopen-path.cc src/pic-processor.cc src/registers.cc src/trace.cc : Remove unused variables 2017-03-23 Errol van de l'Isle * src/processor.cc : Removed unused variables 2017-03-23 Errol van de l'Isle * src/os_dependent.cc : Removed unused variable and redundent expression 2017-03-16 Errol van de l'Isle * cli/socket.cc examples/scripts/client3.cc src/cod.cc src/lxt_write.c : Correct some undefined behaviour * gui/gui_breadboard.cc : Fix memory reallocation error 2017-03-13 Errol van de l'Isle * src/trace.h : Fix integer to bool logic 2017-03-13 Errol van de l'Isle * src/14bit-registers.h src/bitlog.h src/breakpoints.h src/clock_phase.h src/errors.h src/expr.h src/gpsim_interface.h src/gpsim_object.h src/ioports.h src/modules.h src/operator.h src/packages.h src/pic-instructions.h src/processor.h src/program_files.h src/stimuli.h src/trace.h src/trigger.h src/value.h src/xref.h : code review, make signle argument constrctors explicit. 2017-03-11 Errol van de l'Isle * src/value.h src/value.cc : Change internals of class String to use std::string instead of char * 2017-02-23 Errol van de l'Isle * src/icd.cc : Fix build error. 2017-02-23 Errol van de l'Isle * cli/input.cc cli/socket.cc plat/win32/fd2raw.cpp plat/win32/fd2raw.h plat/win32/icd.cc plat/win32/unistd.h src/icd.h src/interface.cc autoconf.ac : Set the minimum GLib version to version 2.26 and remove checks for versions lower than this. 2017-02-18 Roy Rankin * gui/settings_exdbm.cc : fix error detected by gcc-7 2017-02-12 Roy Rankin * src/14bit-instructions.h src/pic-instructions.cc : Bug #224 14bits Enhanced Instruction BRW not working 2017-01-26 Errol van de l'Isle * configure.ac : Add extra gcc and clang run time sanitization build options 2017-01-26 Errol van de l'Isle * gui/gui_regwin.cc : Correct error in svn r2392 2017-01-22 Errol van de l'Isle * src/14bit-processors.cc src/14bit-registers.h src/16bit-processors.cc src/bit.cc src/dspic/dspic-instructions.cc src/p12x.cc src/pic-ioports.cc src/registers.h src/uart.cc gui/gui_processor.h : Clarify calculation precedence for '&' and '?'. 2017-01-22 Errol van de l'Isle * gui/gui_breadboard.cc gui/gui_breadboard.h gui/gui_main.cc gui/gui_menu.cc gui/gui_processor.h gui/gui_profile.h gui/gui_register.h gui/gui_regwin.cc gui/gui_regwin.h gui/gui_scope.cc gui/gui_scope.h gui/gui_src.h gui/gui_stack.h gui/gui_statusbar.h gui/gui_stopwatch.h gui/gui_symbols.h gui/gui_trace.h gui/gui_watch.h gui/settings_exdbm.h : Some code tidy 2016-12-25 Errol van de l'Isle * cli/cmd_macro.cc cli/cmd_module.cc cli/input.cc modules/i2c.cc src/a2dconverter.cc src/errors.cc src/errors.h src/modules.cc src/modules.h src/operator.cc src/operator.h src/registers.cc src/ssp.cc : Minor optimisations 2016-12-24 Errol van de l'Isle * cli/cmd_break.cc cli/socket.cc extras/lcd/hd44780.cc extras/rs232-gen/rs232-gen.c modules/i2c.cc src/14bit-instructions.cc src/14bit-registers.cc src/14bit-tmrs.cc src/16bit-instructions.cc src/ValueCollections.h src/a2d_v2.cc src/a2dconverter.cc src/breakpoints.cc src/comparator.cc src/dsm_module.cc src/dspic/dspic-processors.cc src/expr.cc src/i2c-ee.cc src/icd.cc src/ioports.cc src/p1xf1xxx.cc src/pic-instructions.cc src/pic-ioports.cc src/processor.cc src/ssp.cc src/tmr0.cc src/trace.cc src/trigger.cc src/uart.cc src/value.cc : Correct the usage of printf and scanf type functions, enforceing the correct signed and data widths. 2016-11-24 Errol van de l'Isle * gui/gtkextra/gtkitementry.c gui/gtkextra/gtksheet.c gui/gui_regwin.cc : Fix some minor issues with gtk extra 2016-11-19 Errol van de l'Isle * gui/gui_profile.h gui/gui_profile.cc : Removed unreachable code leaving stubs so that profiling information can be added at a later date. Current and previous code is unable to extract profiling information. 2016-11-10 Errol van de l'Isle * src/ioports.h gui/gtkextra/gtksheets.c : Remove possible buffer over flows * cli/cmd_dump.cc src/program_files.cc src/sim_context.cc : Minor loop optimization 2016-10-31 Roy Rankin * gui/gui_breadboard.cc gui/gui_breadboard.h : bug #223 sigsegv in gui_breadboard.cc:646 * src/dsm_module.cc src/dsm_module.h : Data Signal Modulator (in developement) 2016-07-15 Roy Rankin * extras/dht11/examples/Makefile extras/ds1820/examples/Makefile src/Makefile.am : Fix missing files for "make dist" * gui/gui_menu.cc : patch #45 Simulation time cycles in decimal by default 2016-07-10 Errol van de l'Isle * gui/Makefile.am gui/gtkextra gui/gtkextra/COPYING gui/gtkextra/README.gpsim gui/gtkextra/gtkextra-marshal.c gui/gtkextra/gtkextra-marshal.h gui/gtkextra/gtkextra.c gui/gtkextra/gtkextrafeatures.h gui/gtkextra/gtkitementry.c gui/gtkextra/gtkitementry.h gui/gtkextra/gtksheet.c gui/gtkextra/gtksheet.h gui/gui_regwin.h gui/gui_symbols.cc modules/logic.cc : Include GtkSheet from GtkExtra to remove external dependedncy on it. 2016-07-07 Roy Rankin * regression/instructions_16bit/instructions_16bit.asm : Fix assemble error with gputils < 1.4.0 2016-07-01 Roy Rankin * cli/input.cc cli/socket.cc extras/dht11/dht11.cc extras/ds1820/bit1w.cc extras/lcd/hd44780.cc extras/lcd/hd44780.h extras/lcd/lcd.cc extras/lcd/lcd.h extras/lcd/lcdgui.cc gui/gui_menu.cc modules/usart.cc src/14bit-registers.cc src/14bit-tmrs.cc src/a2d_v2.cc src/a2dconverter.cc src/icd.cc src/p16f88x.cc src/p17c75x.cc src/p18x.cc src/pic-ioports.cc src/pic-registers.cc src/stimuli.cc src/tmr0.cc src/uart.cc : Fix GCC 6.1.1 warning messages * regression/instructions_16bit/instructions_16bit.asm : Fix assemble error with gputils 1.4.2 2016-06-30 Roy Rankin * src/16bit-processors.h src/p18fk.cc : Bug #222 breadboard issue with 18f26k22 clock pin labels 2016-06-28 Roy Rankin * src/ssp.h src/ssp.cc : Bug #221 When selecting I2C, SSx pin may change name in breadboard 2016-03-22 Roy Rankin * regression/p18f26k22/Makefile regression/p18f26k22/sync_26k22.asm src/16bit-processors.cc src/p18fk.cc src/pir.cc src/pir.h src/uart.cc src/uart.h : Add synchronous functionallity to euart. Uart sets name pin name when active 2016-03-15 Roy Rankin * cli/cmd_load.cc doc/gpsim.lyx : Bug #220 Make documentation more clear for processor loading 2016-02-15 Roy Rankin * src/14bit-tmrs.cc src/14bit-tmrs.h : Bug #219 TMR2 can exceed 255 after changing prescale bits of T2CON * src/p18x.cc src/pic-processor.cc : regression causing add_sfr_register to be called twice for osccon 2016-02-06 Roy Rankin * regression/p1xf18xx/Makefile regression/p1xf18xx/p12f1840.asm regression/p1xf18xx/p16f1825.asm src/p1xf1xxx.cc src/p1xf1xxx.h src/pic-processor.cc src/pic-processor.h : Feature 52 Add p16f1825, fix devID for p12f1840 2016-02-04 Errol van de l'Isle * gui/gui_src_asm.cc : Fix bug 217 issue with right click, fix memory leak 2016-02-04 Roy Rankin * regression/p1xf18xx/12f1822_g.lkr regression/p1xf18xx/16f1788_g.lkr regression/p1xf18xx/16f1823_g.lkr regression/p1xf18xx/Makefile regression/p1xf18xx/p12f1840.asm : Add basic p12f1840 test, cleanup Makefile * src/p1xf1xxx.cc src/p1xf1xxx.h src/pic-processor.cc src/pic-processor.h : Feature 51 - Add p12f1840 processor 2016-02-02 Errol van de l'Isle * gui/gui_regwin.cc : Bug fixes + patch from Rob Pearce. Added some input sanitization (feature 49) 2016-02-01 Roy Rankin * src/ssp.cc src/ssp.h regression/spi/p16c62.asm regression/spi/p16f88.asm : Add SPI proto trace * src/16bit-processors.cc : delete osccon when processor closes * src/stimuli.cc src/stimuli.h src/processor.cc src/registers.cc src/registers.h : fix address/value column in symbol GUI * src/pic-processor.cc : mclr pin name in processor symbol space * regression/p16f873/p16f873.asm : Fine tune interrupt handling 2016-01-31 Roy Rankin * src/i2c-ee.cc src/ioports.cc src/ioports.h : support for separate symbol space 2016-01-31 Roy Rankin * modules/Makefile.am modules/makefile.mingw modules/m_stimuli.cc modules/m_stimuli.h modules/stimuli.cc modules/stimuli.h : rename stimuli file for gdb as same file name used in src * modules/encoder.cc modules/gpsim_modules.cc modules/i2c-eeprom.cc modules/i2c.cc modules/i2c2par.cc modules/i2c2par.h modules/led.cc modules/led.h modules/logic.cc modules/logic.h modules/push_button.cc modules/resistor.cc modules/switch.cc modules/ttl.cc modules/ttl.h modules/usart.cc modules/usart.h modules/video.cc : Fix memory issues on module removal (bug 214), separate module symbol space * extras/ds1307/ds1307.cc extras/ds1307/ds1307.h : Bug 213 ds1307 not at i2c address 0xd0 2016-01-30 Roy Rankin * src/14bit-tmrs.cc src/14bit-tmrs.h src/16bit-tmrs.cc src/16bit-tmrs.h src/p18fk.cc : bug 215 Issues with tmr1_freq * src/symbol.cc : Print message when adding same name symbol with different value 2016-01-29 Errol van de l'Isle * gui/gui_src_opcode.cc : Fix build with gtk extra 2 * gui/gui_regwin.cc : Bug 216 - Fix numerical inputs 2016-01-19 Rob Pearce * src/16bit-processors.cc src/16bit-processors.h src/16bit-registers.cc src/p12f6xx.cc src/p12f6xx.h src/p16f88x.cc src/p16f88x.h src/p16f8x.cc src/p16f8x.h src/p1xf1xxx.cc src/p1xf1xxx.h src/pic-ioports.cc src/pic-processor.cc src/pic-processor.h : Changed "osccon" member of processor classes to a pointer so that it can be properly virtual * src/Makefile.am src/p18fk.h src/p18fk.cc src/p18x.cc src/p18x.h src/a2d_v2.cc src/a2d_v2.h src/pir.h : Reduce excessive file size (18FxxKyy family separate from other 18x) : Implement PIC18F14K22 processor * src/14bit-registers.cc : Fixed bug in setting IOFS (HFIOFS) bit of OSCCON 2016-01-05 Roy Rankin * cli/input.cc src/hexutils.cc src/icd.cc src/sim_context.cc : Fix unused results warnings * src/comparator.cc : Fix free cm_an in CMCON destructor 2015-12-23 Roy Rankin * src/pic-ioports.cc src/pic-ioports.h : PicPortGRegister generalize intf bit * src/14bit-tmrs.cc src/14bit-tmrs.h : add dummy registers triscpp, dataccp * src/pic-processor.cc src/pic-processor.h src/p16x7x.cc src/p16x7x.h : Bug 212 - add 16f716, fix package 16c712, 16c716 2015-11-28 Errol van de l'Isle * gui/gui_main.cc gui/gui_menu.cc gui/gui_regwin.cc gui/gui_regwin.h gui/gui_stopwatch.cc gui/gui_stopwatch.h : Reduce the number of global variables 2015-11-28 Errol van de l'Isle * extras/lcd/hd44780.cc extras/lcd/lcd.cc gui/gui_symbols.cc modules/encoder.cc modules/logic.cc modules/stimuli.cc modules/ttl.cc src/ValueCollections.cc src/ValueCollections.h src/attributes.cc src/bitlog.cc src/breakpoints.h src/comparator.h src/ctmu.h src/eeprom.h src/intcon.cc src/intcon.h src/interface.cc src/pic-processor.h src/processor.cc src/processor.h src/registers.cc src/registers.h src/stimuli.cc src/stimuli.h src/ui.cc : Removed unnecessary use of #include from headers. This leads to some code bloat with GCC for units that do not need iostream. 2015-11-28 Errol van de l'Isle * doc/gpsim.lyx : Update documentation 2015-11-28 Errol van de l'Isle * gui/gui_src.h gui/gui_src_opcode.cc : Major re-write of the opcode window. Simplefied the font handling, removed broken options. Improved redraw speed and gave it a similar look to the RAM & EPROM windows. 2015-11-19 Roy Rankin * cli/cmd_break.cc cli/cmd_break.h : undo fix for for bug 206 * cli/parse.yy src/expr.cc : improve error processing and undo fix for bug 206 * cli/scan.ll : Allow [dD]'nn' decimal values * doc/gpsim.lyx : Correct documentation errors * src/breakpoints.cc : new fix for bug 206 2015-11-17 Errol van de l'Isle * src/ValueCollections.cc src/cmd_manager.cc src/errors.cc src/os_dependent.cc src/processor.cc src/value.cc : Minor optimisations, found during static analysis of code * gui/gui_breadboard.cc gui/gui_breadboard.h : Removed trace buttons, added status line to show if the trace failed 2015-11-15 Errol van de l'Isle * gui/gui_menu.cc gui/gui_src.h gui/gui_src_asm.cc : Fix memory leaks. Refactor source browser 2015-11-11 Errol van de l'Isle * gui/gui.h gui/gui_scope.cc gui/gui_scope.h gui/gui_src.cc gui/gui_src.h gui/gui_src_asm.cc gui/gui_src_opcode.cc : Simplified keyboard handling 2015-11-07 Roy Rankin * regression/p16f88x regression/p16f88x/Makefile regression/p16f88x/comparator.asm regression/p16f88x/epwm.asm regression/p16f88x/eusart.asm regression/p16f88x/i2c.asm regression/p16f88x/i2c_low.inc regression/p16f88x/i2c_slave.asm regression/p16f88x/p16f882.asm regression/p16f88x/p16f883.asm regression/p16f88x/p16f886.asm regression/p16f88x/p16f887.asm regression/run_regression.sh regression/p16f88x/a2d.asm : Add p16f88x regressions test * regression/p1xf18xx/p12f1822.asm regression/p1xf18xx/p16f1823.asm src/p16f87x.cc src/p16f88x.cc * regression/tmr0_16bit/tmr0_16bit.asm : add nops after assert's * src/eeprom.cc : turn off debug * src/p18x.cc src/p1xf1xxx.cc src/pic-processor.cc src/pic-processor.h src/ssp.cc src/ssp.h src/p16f88x.cc : Add SSP registers to 16f88x and consolidate sspmsk code 2015-11-02 Errol van de l'Isle * gui/gui.h gui/gui_src.h gui/gui_src_asm.cc : Remove limit on number of source files. Removed unused and deprecated code. 2015-10-27 Errol van de l'Isle * cli/socket.cc eXdbm/eXdbm.c : Fix resource & memory leaks found with static analysis. 2015-10-27 Errol van de l'Isle * gui/gui.h gui/gui_menu.cc gui/gui_regwin.cc gui/gui_regwin.h gui/gui_src_asm.cc gui/gui_statusbar.cc gui/gui_statusbar.h : Improve register status bar code & remove it from the RAM window preparing to change the source window to be the main one 2015-10-25 Errol van de l'Isle * gui/gui.h gui/gui_break.cc gui/gui_main.cc gui/gui_processor.cc gui/gui_profile.cc gui/gui_profile.h gui/gui_register.h gui/gui_regwin.cc gui/gui_regwin.h gui/gui_src_opcode.cc gui/gui_statusbar.cc gui/gui_symbols.cc gui/gui_symbols.h src/ValueCollections.h src/operator.h src/packages.h src/ui.h : Fix minor errors and remove dead code found with static analysis. 2015-10-24 Errol van de l'Isle * gui/gui_menu.cc : Modified file selector to enable the selction of the processor for .hex files 2015-10-22 Roy Rankin * src/16bit-registers.cc src/clock_phase.cc src/clock_phase.h src/pic-processor.cc src/pic-registers.cc src/processor.h : Move clock phase variables into Processor class 2015-10-21 Roy Rankin * cli/cmd_clear.cc : fix sigsegv on improper input * gpsim/main.cc gui/gui.h gui/gui_breadboard.cc gui/gui_break.cc gui/gui_main.cc gui/gui_menu.cc gui/gui_regwin.cc gui/gui_src.h gui/gui_src_asm.cc gui/gui_src_opcode.cc gui/gui_statusbar.cc gui/gui_watch.cc src/14bit-tmrs.cc src/14bit-tmrs.h src/16bit-processors.cc src/comparator.cc src/expr.cc src/p18x.cc src/pic-instructions.cc src/pic-registers.cc src/processor.cc src/processor.h src/value.cc src/xref.cc src/xref.h : Fix memory leaks 2015-10-11 Roy Rankin * cli/cmd_break.cc : improve error message * cli/input.cc : add verbose output * gui/gui_breadboard.cc : trace nodes : gui/gui_src_asm.cc * cntl-F in src window when no code loaded causes sigsegv * src/cod.cc src/cod.h : improve error handling when opening code files * src/processor.cc src/processor.h : move m_ProgramMemoryAllocationSize into Processor class * src/breakpoints.cc src/expr.cc src/operator.cc : better handle error conditions * src/fopen-path.cc : handle invalid file names 2015-08-07 Errol van de l'Isle * gui_menu.cc gui_profile.cc gui_src_asm.cc : Fixed error in gui_message(), resource not destroyed. Re: patch from andi 2015-09-07 Roy Rankin * cli/cmd_break.cc cli/cmd_break.h cli/parse.yy src/breakpoints.cc : bug 206 Break command problems 2015-09-07 Roy Rankin * doc/gpsim.html doc/gpsim.lyx : Update documentation 2015-09-04 Roy Rankin * configure.ac : Change release to 0.29.1 * src/eeprom.cc src/p16f87x.cc src/p16f87x.h : bug 207 Wrong EEPROM size (16f876/876a/877/877a) * src/tmr0.cc : bug 205 TMR0: bug TMR0 is larger than 255 2015-08-17 Roy Rankin * configure.ac : Change release to 0.29.0 * gui/gui_src.cc : Fix compiler warning * src/p18x.cc src/pic-ioports.cc src/ssp.cc : Remove debug output 2015-08-13 Roy Rankin * modules/ttl.cc src/14bit-registers.cc src/14bit-registers.h src/14bit-tmrs.cc src/16bit-registers.cc src/16bit-tmrs.h src/comparator.cc src/comparator.h src/ctmu.h src/i2c-ee.cc src/ioports.cc src/p12x.cc src/p18x.cc src/pic-processor.cc src/pic-processor.h src/ssp.cc src/uart.cc : Fix memory error reported by Valgrind 2015-08-07 Errol van de l'Isle * modules/led.cc modules/led.h : bug 203 - led module looping 2015-08-03 Roy Rankin * modules/ttl.cc modules/ttl.h : bug 204 - tt595 Qs output lags by one SCK clock 2015-08-03 Roy Rankin * src/gpsim_time.cc src/gpsim_time.h : bug 202 - too many breaks 2015-07-29 Roy Rankin * extras/i2c2par/Makefile extras/i2c2par/examples/Makefile : remove from svn control * src/14bit-registers.cc : bug 201 - Nested CALL causes loop in p10f202 2015-07-26 Errol van de l'Isle * gui/gui_src.cc gui/gui_src.h gui/gui_src_asm.cc : Feature 41 In the source browser the find dialog now has a keyboard shortcut with improvments to the dialog. Improved keyboard keypress detection as keyboard modifiers not correctly detected. 2015-07-27 Roy Rankin * configure.ac makefile.mingw extras/Makefile.am extras/i2c2par extras/i2c2par/Makefile extras/i2c2par/Makefile.am extras/i2c2par/examples extras/i2c2par/examples/Makefile extras/i2c2par/examples/Makefile.am extras/i2c2par/examples/i2c2par.asm extras/i2c2par/i2c2par.cc extras/i2c2par/i2c2par.h extras/i2c2par/makefile.mingw extras/i2c2par/module_manager.cc : Feature 40 - Add support for 20x4 lcd module with I2C interface * extras/lcd/makefile.mingw extras/dht11/makefile.mingw extras/ds1307/makefile.mingw extras/ds1820/makefile.mingw extras/graphic_lcd/src/makefile.mingw : More Fixes for windows build 2015-07-27 Roy Rankin * gpsim/makefile.mingw modules/led.h modules/makefile.mingw src/gpsim_interface.h src/makefile.mingw src/modules.h : Fixes for windows build 2015-07-26 Roy Rankin * doc/screenshots/breadboard_register.png doc/screenshots/control_source.png : new screendump files * regression/a2d/10f222.lkr regression/ccp/16f819.lkr regression/ccp/16f877a.lkr regression/ccp/18f6520.lkr regression/comparator/10f204.lkr regression/comparator/16f628.lkr regression/comparator/16f873a.lkr regression/comparator/16f877a.lkr regression/comparator/16f882.lkr regression/tmr1_16bit/18f452.lkr regression/ttl/18f452.lkr : Remove gputil link files * regression/run_regression.sh regression/tmr1_16bit/tmr1_18f2620.asm regression/ttl/Makefile regression/ttl/ttl595.asm : add new regression tests 2015-07-26 Errol van de l'Isle * configure.ac : Add option for leak testing (X86-64 gcc or clang only) * extras/graphic_lcd/src/glcd.cc extras/graphic_lcd/src/glcd.h extras/graphic_lcd/src/glcd_100X32_sed1520.cc extras/graphic_lcd/src/glcd_100X32_sed1520.h extras/graphic_lcd/src/gpsim_modules.cc extras/graphic_lcd/src/osram.cc extras/graphic_lcd/src/osram.h extras/graphic_lcd/src/sed1520.cc extras/graphic_lcd/src/ssd0323.cc extras/graphic_lcd/src/ssd0323.h : Do all drawing with Cairo instead of deprecated GDK. 2015-07-26 Roy Rankin * src/pic-processor.cc src/p18x.h src/p18x.cc regression/a2d/Makefile regression/a2d/p18f26k22.asm regression/ccp/Makefile regression/ccp/pwm_26k22.asm regression/comparator/Makefile regression/comparator/compar_26k22.asm regression/tmr1_16bit/Makefile regression/tmr1_16bit/tmr1_18f26k22.asm regression/epwm/p18f26k22.asm regression/p18f26k22/Makefile regression/p18f26k22/ctmu_26k22.asm regression/p18f26k22/tbl_26k22.asm regression/p18f26k22/hlvd_26k22.asm : feature 46 - Add p18f26k22 Processor * gpsim/main.cc gui/gui_scope.cc gui/gui.h : fix scope error messages * cli/Makefile.am : fix continual rebuild of parse.cc * src/14bit-registers.cc src/14bit-registers.h : add CPSCON0::callback_print() function * src/16bit-processors.cc src/16bit-processors.h src/16bit-registers.h src/16bit-registers.cc : Bug 200 - tblptrx registers miss named Feature 45 - P18 processors do not return devid Add HLVDCON class * src/bit.cc : fix compiler warning * src/comparator.cc src/comparator.h src/ctmu.cc src/ctmu.h src/Makefile.am src/a2d_v2.h src/a2d_v2.cc src/p16f88x.cc : Add ctmu class for p18f26k22 * src/eeprom.h src/eeprom.cc : changes to integrate eeprom with TBL 2015-07-09 Roy Rankin * regression/a2d/16c71.lkr regression/a2d/16f819.lkr regression/a2d/16f871.lkr regression/a2d/16f873a.lkr regression/a2d/16f874a.lkr regression/a2d/16f88.lkr regression/a2d/18f1220.lkr regression/a2d/18f4321.lkr regression/a2d/18f452.lkr regression/a2d/Makefile : Remove outdated gputil link files 2015-07-09 Roy Rankin * stimuli.h simuli.cc : Feature 44 Entering node name into cli should show attached stimului Refine node RC voltage vs time calculation * stimuli.h simuli.cc src/processor.h src/processor.cc src/modules.h src/modules.cc : Feature 43 Allow setting of Vdd on processors * src/ioports.cc : feature 42 Analog inputs should have about 5pF capacitance * src/p1xf1xxx.cc : Fix cpscon0 register name (was cpscon) * regression/a2d/p16c71.asm regression/p1xf18xx/p16f1823.asm regression/switch_test/switch_test.asm regression/spi/p18f242.asm : adjust regression tests for above changes 2015-07-08 Errol van de l'Isle * gui/gui.h gui/gui_scope.h gui/gui_scope.cc : Replace all deprecated GDK drawing with Cairo drawing and some code clean up. 2015-06-25 Roy Rankin * gui/gui_watch.cc: initialize variable watch_list * regression/comparator/Makefile regression/comparator/compar_2321.asm regression/comparator/compar_628.asm regression/comparator/compar_6520.asm regression/comparator/compar_873a.asm regression/comparator/compar_877a.asm regression/comparator/compar_882.asm regression/p16f684/Makefile regression/p16f684/compar_684.asm regression/p16f690/p16f690.asm regression/p1xf18xx/Makefile regression/p1xf18xx/p16f1823_comp.asm regression/run_regression.sh : Improve comparator regression tests * regression/p1xf18xx/p16f1823_i2c.asm regression/p1xf18xx/p16f1823_i2c_v2.asm regression/p1xf18xx/p16f1823_spi.asm : fix variable names in asserts * src/14bit-registers.h : define aditional OSCCON and OSCTUNE bits * src/14bit-tmrs.cc src/14bit-tmrs.h : Allow timer classes to be used more than once * src/16bit-processors.cc src/16bit-processors.h : change t1con and t3con to pointers so they can be redefine if required * src/16bit-registers.cc src/16bit-registers.h : add OSCCON2 and OSCCON_HS classes * src/16bit-tmrs.cc src/16bit-tmrs.h : Timers 1,3,5 * src/a2d_v2.cc src/a2d_v2.h src/a2dconverter.cc src/a2dconverter.h src/p1xf1xxx.cc : improve inheratance structure * src/comparator.cc src/comparator.h src/p16f88x.cc src/p16f88x.h : restructure for up to 4 comparators * src/p16f62x.cc : Fix Bug 199 p16f627,8 comparator error mode 3 * src/p16x6x.cc : Allow multiple SSP modules to connect to tmr2 * src/p18x.cc : Fix bug 198 - p18f6620 comparator pins wrong Fix bug 197 Bad comparator output pin on p18f2x21 based processors * src/p18x.h : fix 2620 register size * src/pic-ioports.cc src/pic-ioports.h : make IOCxF optional in PicPortIOCRegister * src/pic-processor.cc src/pic-processor.h : allow for secondary oscillator * src/pir.cc src/pir.h : add support for PIR4, PIR5 registers * src/registers.cc : Fix register naming * src/ssp.cc src/ssp.h : Allow multiple SSP modules using flexable pir registers * src/stimuli.h : Increase input impedance * src/tmr0.h : make m_t1gcon useable by derrived classes 2015-05-31 Errol van de l'Isle * gui/gui_scope.cc gui/gui_scope.h : Draw signal names using Cairo * gui/gui_menu.cc gui/gui_processor.cc gui/gui_profile.cc gui/gui_profile.h gui/gui_regwin.cc gui/gui_regwin.h gui/gui_src.cc gui/gui_src.h gui/gui_src_asm.cc gui/gui_src_opcode.cc gui/gui_stack.cc gui/gui_statusbar.cc gui/gui_statusbar.h gui/gui_stopwatch.cc gui/gui_stopwatch.h gui/gui_symbols.cc gui/gui_symbols.h gui/gui_trace.cc gui/gui_trace.h gui/preferences.cc gui/settings_exdbm.cc modules/encoder.cc modules/encoder.h modules/gpsim_modules.cc modules/i2c-eeprom.cc modules/i2c-eeprom.h modules/i2c.cc modules/i2c2par.cc modules/i2c2par.h modules/led.cc modules/led.h modules/logic.cc modules/logic.h modules/push_button.cc modules/push_button.h modules/resistor.cc modules/stimuli.cc modules/stimuli.h modules/switch.cc modules/switch.h modules/ttl.cc modules/ttl.h modules/usart.cc modules/video.cc modules/video.h : Used clang tool "iwyu" to help tidy up which headers are included 2015-05-27 Errol van de l'Isle * gui/gui_main.cc : Fix display update from error introduced in svn 2323 * gui/gui_scope.cc gui/gui_scope.cc : Cleaned up code to prepare for removing GDK deprecated calls * gui/gui.h gui_break.cc gui_regwin.cc : Change CrossReferenceToGUI class to a pure calls 2015-05-23 Errol van de l'Isle * gui/gui_init.cc : Removed header dependencies and marked as should be removed * gui/gui_main.cc : Removed threading code, this style of threading is deprecated in GTK+ v3.6 and does not work under MS Windows. * gui/gui.h gui/gui_breadboard.cc gui/gui_object.cc gui/gui_object.h gui/gui_profile.cc gui/gui_regwin.cc gui/gui_regwin.h gui/gui_scope.cc gui/gui_src.cc gui/gui_src_asm.cc gui/gui_src_opcode.cc gui/gui_stack.cc gui/gui_stopwatch.cc gui/gui_symbols.cc gui/gui_trace.cc gui/gui_watch.cc : Change GUI_Object to an abstract type, error checking now at compile time not just run time. Removed un-used variable "wt" and partially used variable "wc" from GUI_Object. 2015-05-13 Errol van de l'Isle * gui/gui_breadboard.cc : Fixed regression. Now correcly shows the alternative pin name 2015-05-07 Errol van de l'Isle * extras/lcd/Makefile.am extras/lcd/hd44780.cc extras/lcd/hd44780.h extras/lcd/lcd.cc extras/lcd/lcd.h extras/lcd/lcdgui.cc extras/lcd/module_manager.cc gui/gui_breadboard.cc : Do drawing in the LCD module with Cairo. Clean up resource mangement 2015-04-26 Errol van de l'Isle * gui/gui_beradboard.cc : Correct crash introduced in svn 2319 2015-04-25 Errol van de l'Isle * gui/gui_breadboard.h gui/gui_breadboard.cc : All drawing now done with Cairo. Fix memory leak, some code tidy up 2015-04-13 Roy Rankin * src/14bit-tmrs.cc : Fix bug # 196 - PWM glitch when writing to CCPCON 2015-04-11 Errol van de l'Isle * gui/gui_breadboard.cc gui/gui_breadboard.h : Traces are now drawn using Cairo instead of deprecated GDK calls 2015-04-10 Roy Rankin * doc/gpsim.lyx modules/Makefile.am modules/gpsim_modules.cc modules/i2c2par.cc modules/i2c2par.h : add I2C to 8 bit bus modules for feature request # 40 * src/i2c-ee.cc src/i2c-ee.h : rewrite to make I2C slave code sharable via class i2c_slave 2015-04-04 Errol van de l'Isle * gui/gui_breadboard.cc gui/gui_breadboard.h : Replace deprecated GDK calls for displaying module name 2015-03-29 Roy Rankin * gui/gui_breadboard.c : Fix core dump when "Trace all" button used in Breadboard, regression from svn 2309 2015-03-27 Errol van de l'Isle * modules/led.cc modules/led.h modules/logic.cc modules/logic.h modules/video.cc modules/video.h : Replace deprecated GDK calls and code clean up 2015-03-27 Roy Rankin * regression/p16f676/reset.asm regression/p16f684/reset.asm regression/p16f84/reset.asm src/14bit-registers.cc src/intcon.cc src/intcon.h src/pic-ioports.cc src/pic-ioports.h : Bug 195 - Writing to an IOC IO port should not clear interrupt flag 2015-03-23 Roy Rankin * gui/gui_watch.cc: fix gtk_tree_model_foreach assert * src/14bit-tmrs.cc: fix debug print format warning 2015-03-21 Errol van de l'Isle * gui/gui.h gui/gui_breadboard.cc gui/gui_breadboard.h gui/gui_main.cc gui/gui_profile.cc gui/gui_regwin.cc gui/gui_regwin.h gui/gui_src_asm.cc : Replace some deprecated GDK calls and code clean up 2015-03-14 Errol van de l'Isle * gui/gui_watch.cc gui/watch.h : Replace the GtkCList with GtkListStore/GtkTreeView * extras/graphic_lcd/src/glcd_100x32_sed1520.cc extras/graphic_lcd/src/osram.cc extras/lcd/lcdgui.cc gui/gui.h gui/gui_breadboard.cc gui/gui_regwin.cc gui/gui_scope.cc gui/gui_src_asm.cc gui/gui_src_opcode.cc gui/gui_statusbar.cc gui/gui_stopwatch.cc gui/gui_trace.cc modules/led.cc modules/logic.cc : Replaced various small deprecated GTK calls. 2015-03-08 Errol van de l'Isle * gui/gui_profile.cc gui/gui_profile.h : Remove unused global style, replaced all GtkCList with GtkListStore/GtkTreeView and removed the need for some GLists * gui/gui_src.h gui/gui_src_asm.cc : Removed classes BreakPointInfo, BreakPointList, SourceBrowserAsm_Window which are not used and replaced other deprecated code. * gui/gui.h gui/gui_break.cc gui/gui_regwin.cc gui/gui_src.cc gui/gui_stack.cc gui_symbols.cc : Replaced deprecated GTK+ calls 2015-02-28 Errol van de l'Isle * gui/gui_src.h gui_src_asm.cc : Correct usage of signal "switch-page" * gui/gui_watch.cc gui/gui_watch.h : Replaced GList with std::vector<> * modules/usart.cc modules/usart.h : Removed definition of GTK_ENABLE_BROKEN * gui/gui_statusbar.cc gui/gui_statusbar.h gui/gui.h : Removed commented out dead code and code tidy up * gui/gui_processor.cc gui_processor.h gui_menu.cc : Remove conditional on NEW_SOURCE_BROWSER and code tidy. * gui/breadboard.cc : Made two globals variables local and used C++ style allocations not C Convert two GList to a std::vector<> 2015-02-23 Roy Rankin * src/tmr0.cc src/16bit-registers.cc : Bug 194 - P18 processor TMR0 may ignore TMR0H * src/p18x.cc src/p18x.h src/pic-processor.cc src/pic-processor.h : Feature 39 - Add p18f2620 processor (work in progress) * extras/lcd/examples/icons.inc extras/lcd/examples/lcd.inc extras/lcd/examples/lcd_mod.asm extras/lcd/examples/lcd_mod.stc extras/lcd/examples/lcd_mod20x4.stc extras/lcd/examples/screen.asm extras/lcd/hd44780.cc extras/lcd/hd44780.h extras/lcd/lcd.cc extras/lcd/lcd.h extras/lcd/lcdfont.h extras/lcd/lcdgui.cc extras/lcd/module_manager.cc : Add 20x4 lCD display and CGRam support as 1st step for feature request 40 - 20x4 LCD with I2C interface 2015-02-21 Errol van de l'Isle * extras/graphic_lcd/src/glcd.cc extras/graphic_lcd/src/glcd_100x32_sed1520.cc extras/graphic_lcd_src/osram.cc extras/lcd/lcdgui.cc gui/gui_main.cc gui/gui_profile.cc gui/gui_regwin.cc gui/gui_scope.cc gui/gui_src.cc gui/gui_src_asm.cc gui/gui_watch.cc modules/led.cc modules/logic.cc modules/video.cc : Number of minor changes to use GTK accessor functions to avoid direct access to GTK internals. Gpsim now compiles with -DGSEAL_ENABLE 2015-02-13 Roy Rankin * src/14bit-registers.cc : Bug 192 - Linear Address Calculation Bug on Enhanced Midrange * src/gpsim_time.cc : Bug 193 - Crash when simulation mode set to "update gui every cycle" * src/14bit-tmrs.cc src/14bit-tmrs.h src/gpsim_interface.h src/interface.cc src/tmr0.cc src/tmr0.h : Feature 38 - Update timer register values in GUI 2015-02-10 Errol van de l'Isle * gui/gui_src.h gui/gui_src_opcode.cc : Replace usage of GtkCList. Due to styles being done differently on a GtkTreeView I have now used icons instead of colours to indicate break points and the current program counter. This should help those with colour blindness. Replaced various deprecated API calls and other code tidy ups. Now compiles with -DGSEAL. 2015-02-05 Roy Rankin * src/14bit-registers.cc src/14bit-processors.cc src/14bit-processors.h src/pic-processor.h : Bug 190 - Enhanced processors not setting HFIOFS bit of OSCSTAT Bug 191 - Enhanced midrange chips reset from software enabled watchdog while sleeping * regression/p1xf18xx/p16f1823.asm : test setting HFIOFS bit of OSCSTAT * src/14bit-registers.cc * regression/run_regression.sh regression/wdt/16f1823.lkr regression/wdt/Makefile regression/wdt/nwdt_16f1823.asm regression/wdt/pwdt_16f1823.asm : Add 16f1823 WDT regression tests * src/p1xf1xxx.cc: Delete option_reg in destructor 2015-01-17 Errol van de l'Isle * gui/gui_src_asm.cc gui/gui_src.h : Remove usage of GtkPixmap. Modified to compile with -DGSEAL_ENABLE. Various code tidy ups, removed some dead code. Modified the find and font dialogs. 2015-01-17 Errol van de l'Isle * gui/gui_symbols.cc, gui/gui_symbols.h : Replace GtkCList with tree view 2015-01-06 Errol van de l'Isle * gui/gui_breadboard.cc, gui/gui_breadboard.h : Removed unused GtkCList, removed some dead code, modified to compile with -DGSEAL_ENABLE. Some code tidy up using checks from cppcheck. 2014-12-28 Errol van de l'Isle * gui/gui_stopwatch.cc, gui/gui_stopwatch.h : Replaced GtkOptionMenu with GTK 2 equivalent. Various code clean up. Required GTK version now 2.24 2014-12-27 Errol van de l'Isle * gui/gui_breadboard.cc, gui/gui_breadboard.h, gui/gui_src_asm.cc : Clean up last usage of GtkSignalFunc * gui/gui_trace.cc, gui/gui_trace.h : Replace GtkClist with tree view 2014-12-25 Errol van de l'Isle * gui/gui_dialog.cc, gui/gui_scope.cc : Dead code removal 2014-12-25 Errol van de l'Isle * gui/gui.h, gui/gui_breadboard.cc, gui/gui_breadboard.h, gui/gui_menu.cc, gui/gui_object.cc, gui/gui_object.h, gui/gui_profile.cc, gui/gui_profile.h, gui/gui_regwin.cc, gui/gui_regwin.h, gui/gui_scope.cc, gui/gui_scope.h, gui/gui_src.h, gui/gui_src_asm.cc, gui/gui_src_opcode.cc, gui/gui_stack.cc, gui/gui_stack.h, gui/gui_stopwatch.cc, gui/gui_stopwatch.h, gui/gui_symbols.cc, gui/gui_symbols.h, gui/gui_trace.cc, gui/gui_trace.h, gui/gui_watch.cc, gui/gui_watch.h : Replaced menus with GtkUIManager, replaced about dialog and done code tidy up to gui/gui_menu.cc and gui/gui_object.cc. Required GTK version now 2.18 2014-12-15 Errol van de l'Isle * modules/logic.cc, gui/gui_dialog.cc, gui/gui_regwin.h, gui/gui_menu.cc, gui/gui_breadboard.h, gui/gui_src.h, gui/gui_breadboard.cc, gui/gui_trace.cc, gui/gui_main.cc, gui/gui_statusbar.cc, gui/gui_regwin.cc, gui/gui_src_asm.cc, gui/gui.h, gui/gui_profile.cc, gui/gui_src_opcode.cc: Remove conditional GTK 1 code * gui/gui_menu.cc, gui/breadboard.cc, gui/gui_regwin.cc, configure.ac: - Replace GtkFileSelector with GtkFileChooserDialog and add checks for GTK v2.8 or above 2014-12-10 Roy Rankin * gui/gui_stack.cc gui/gui_stack.h: Replace GtkCList with GtkTreeView patch #44 2014-12-02 Roy Rankin * extras/graphic_lcd/src/glcd_100X32_sed1520.cc extras/graphic_lcd/src/osram.cc extras/lcd/lcdgui.cc gui/gui_breadboard.cc gui/gui_dialog.cc gui/gui_menu.cc gui/gui_profile.cc gui/gui_regwin.cc gui/gui_scope.cc gui/gui_src.cc gui/gui_src_asm.cc gui/gui_src_opcode.cc gui/gui_stack.cc gui/gui_statusbar.cc gui/gui_stopwatch.cc gui/gui_symbols.cc gui/gui_trace.cc gui/gui_watch.cc modules/encoder.cc modules/led.cc modules/logic.cc modules/push_button.cc modules/resistor.cc modules/switch.cc modules/usart.cc modules/video.cc: - Replace gtk_signal() functions with g_signal() equivalents - patch #43 2014-11-22 Roy Rankin * INSTALL.gpsim doc/gpsim_svn.html: Revise install documentation * src/14bit-processors.cc src/14bit-processors.h src/p1xf1xxx.cc src/pic-registers.cc src/pic-registers.h: Watchdog fixes for the 14bit enhanced cores - patch 41 * src/trace.cc src/trace.h: Trace dump for a large cycle counter - patch 42 2014-11-19 Roy Rankin * autogen.sh doc/gpsim_svn.html: add script to build configure command * doc/metadata/gpsim.png: Use icon from website * regression/analog_stim/p12f1822.asm: terminate if .sig files missing * src/sim_context.cc: fix ^c sigsegv if no file loaded - patches #39 2014-11-16 Roy Rankin * doc/Makefile.am doc/metadata/gpsim.appdata.xml: - Add metadata - Feature Request # 36 * extras/graphic_lcd/examples/sed1520/glcd_test.asm extras/graphic_lcd/examples/ssd0323/glcd_test.asm: - Replace __CONFIG to assemble with current gputils * modules/stimuli.cc regression/Makefile.am: - fix infinite loop bug # 188 2014-11-13 Roy Rankin * configure.ac: Set version to 0.28.90 for development * doc/Makefile.am doc/metadata/gpsim.appdata.xml doc/metadata/gpsim.desktop doc/metadata/gpsim.png doc/screenshots/control.png: - Add metadata files for distributions such a fedora 2014-11-06 Roy Rankin * configure.ac: Set version to 0.28.0 2014-11-05 Roy Rankin * doc/gpsim.lyx: Add missing documentation for modules in extras * modules/usart.cc: Adjust bit timing to Tch on each bit - Patch #40 * src/14bit-registers.cc: Fix OSCCAL::put use of base_frequency - Patch #40 * src/clock_phase.h src/pic-processor.cc src/pic-registers.cc: - Remove unused phaseExecuteInterrupt class - Patch #40 2014-11-03 Roy Rankin * cli/cmd_quit.cc: q short command for quit - Feature Request 35 * gui/gui_breadboard.cc: fix coredump bug #187 * regression/interrupts_14bit/Makefile regression/interrupts_14bit/int_sleep.asm regression/p16f676/reset.asm regression/p16f684/reset.asm src/pic-processor.cc: fix sleep interrupt, revisit patch #19 * src/14bit-processors.cc: Remove dead code * src/pic-ioports.cc: Fix i/o pin wakeup for 16f84A bug #186 * src/stimuli.cc: fix start of asynchronous_stimulus bug #185 2014-10-30 Roy Rankin * Makefile.am configure.ac doc/Makefile.am examples/12bit/Makefile.am examples/16bit/Makefile.am examples/Makefile.am examples/modules/Makefile.am examples/modules/usart_test/Makefile extras/graphic_lcd/Makefile.am extras/lcd/Makefile.am extras/lcd/examples/Makefile.am: add files to dist tarball required for mingw compile * plat/win32/gpsim.nsi plat/win32/makefile.mingw: - mingw compile for windows and linux * cli/makefile.mingw: cmd_stopwatch.o not used in distributon 2014-10-26 Roy Rankin * extras/dht11/makefile.mingw: cleanup windows build * plat/win32/make.mingw: set compiler for fedora 21 mingw * gui/gui_regwin.cc: remove disabled code, do not delete invalid register instances on class destructor * gui/gui_src.h gui/gui_src_asm.cc: rename SourcePage array from pages to Srcpages to avoid confusuion with NSourcePage pointer called pages * src/modules.cc src/pic-processor.cc src/trace.cc: - better cleanup on class removal * src/value.cc src/value.h src/xref.cc src/registers.cc src/pic-registers.cc: - make _xref found in class value a pointer 2014-10-05 Roy Rankin * extras/dht11/Makefile.am extras/dht11/examples/Makefile.am: - include files in distribution tar ball * extras/dht11/makefile.mingw extras/ds1307/makefile.mingw extras/ds1820/makefile.mingw extras/graphic_lcd/src/makefile.mingw extras/lcd/makefile.mingw: - compiler determined from plat/win32/make.mingw * makefile.mingw plat/win32/gpsim.nsi: - Add new extra devices * modules/Makefile.am: add missing attribute file * plat/win32/uxtime.h: fix struct class in linux X compile * src/makefile.mingw: fix file name change 2014-10-03 Roy Rankin * examples/modules/usart_test/usart_test.asm regression/usart_test/Makefile regression/usart_test/eusart.asm regression/usart_test/eusart_2455.asm regression/usart_test/usart_pir1v1.asm regression/usart_test/usart_pir1v2.asm: Fix uart regression tests * src/uart.cc src/uart.h: Fix timing of UART TXIF bit - bug #178 2014-10-01 Roy Rankin * cli/input.cc: give error message if opening .asm file - bug #183 * regression/p18f/extended_instructions.asm src/16bit-instructions.cc: P18F: Fix interaction of POSTINC/POSTDEC and SUBFSR/ADDFSR - patch 37 2014-09-26 Roy Rankin * modules/module_attribute.h: fix regression from svn 2273 2014-09-26 Roy Rankin * src/p18x.h: fix last_actual_register - patch 36 2014-09-23 Roy Rankin * modules/gpsim_modules.cc modules/stimuli.cc modules/stimuli.h: - add the file recorder and file stimulus modules * modules/ttl.cc src/stimuli.cc src/stimuli.h: In analogue stimulus module drive pin as voltage * regression/analog_stim/12f1822.lkr regression/analog_stim/Makefile regression/analog_stim/p12f1822.asm regression/analog_stim/stim_an.sig regression/analog_stim/stim_clk.sig: - Regression tests for for the analogue stimulus. 2014-09-22 Roy Rankin * gui/gui_menu.cc gui/gui_regwin.cc: Remove debugging printf * gui/gui_src_asm.cc src/cod.cc src/cod.h src/processor.cc: - Handle missing source file BUG # 135 * src/os_dependent.cc: Terminate path string for current folder 2014-09-17 Roy Rankin * configure.ac extras/Makefile.am extras/dht11/AUTHORS extras/dht11/Makefile.am extras/dht11/README extras/dht11/dht11.cc extras/dht11/dht11.h extras/dht11/examples extras/dht11/examples/16f627_g.lkr extras/dht11/examples/Makefile.am extras/dht11/examples/README extras/dht11/examples/dht11_example.asm extras/dht11/module_manager.cc: Add dht11 module - feature # 34 2014-09-16 Roy Rankin * src/14bit-instructions.cc src/16bit-instructions.cc src/14bit-processors.cc src/16bit-processors.cc: - Allow clearing INTCON:GIE in interrupt - bug #179 * src/14bit-registers.cc src/14bit-registers.h src/intcon.cc src/intcon.h src/p1xf1xxx.cc src/p1xf1xxx.h src/pic-ioports.h: - Fix INTCON:IOCIF IOCxF interaction - bug #180 * regression/instructions_14bit/branching.asm regression/p1xf18xx/Makefile regression/p1xf18xx/p12f1822.asm regression/p1xf18xx/p16f1788.asm regression/p1xf18xx/p16f1823.asm: - Fix tests for bug #180 2014-08-23 Roy Rankin * regression/run_regression.sh regression/tmr3_16bit regression/tmr3_16bit/18f452.lkr regression/tmr3_16bit/18f4550_g.lkr regression/tmr3_16bit/Makefile regression/tmr3_16bit/tmr3_16bit.asm regression/tmr3_16bit/tmr3_18f4550.asm: TMR3 regression test * src/14bit-tmrs.cc src/16bit-processors.cc src/16bit-processors.h src/16bit-registers.cc src/16bit-registers.h src/p18x.cc src/p18x.h src/pir.h: fix TMR3 bug #176 2014-08-07 Roy Rankin * regression/p1xf18xx/Makefile: add rule for p12f1822_usart.cod * regression/p1xf18xx/p16f1788.asm: tests for p16f1788 DAC and A/D * src/a2d_v2.cc: Fix comment * src/a2dconverter.cc src/a2dconverter.h: DAC and differential A/D * src/p1xf1xxx.cc src/p1xf1xxx.h: add DAC and A/D registers * src/ssp.cc: Remove debug printf statement 2014-07-31 Roy Rankin * regression/p1xf18xx/p12f1822.asm src/14bit-instructions.cc: - p12f182x: MOVIW must update Z bit - bug #175 * src/pic-ioports.cc: IOC only works on gpio0 of p12f675 - bug #174 * src/a2dconverter.cc src/p1xf1xxx.cc src/p1xf1xxx.h: - further work on p16f1788 2014-07-28 Roy Rankin * regression/p1xf18xx/Makefile: generate p16f1788.cod file * regression/p1xf18xx/p16f1823.asm: test writable PIR and PIE bits * src/p12f6xx.cc src/pir.h: revisit bug 171 patch * src/p1xf1xxx.cc: Set PIR2 C2IF bit writable for 16f1823 bug #172 * src/pie.cc: use associated PIR register valid_bits mask for PIE - bug # 173 2014-07-27 Roy Rankin * regression/p12f675/p12f683.asm src/p12f6xx.cc src/pir.h: - Fix tmr2 interrupt on 12F683 - bug #171 2014-07-21 Roy Rankin * gui/gui_stopwatch.cc: replace obsolete gtk_object_get_data function * regression/p1xf18xx/Makefile regression/p1xf18xx/p12f1822_usart.asm regression/run_regressionj.sh: Add 12f1822 usart regression test * src/p1xf1xxx.cc src/p1xf1xxx.h src/Makefile.am: - rename of files src/p12f182x.cc and src/p12f182x.h - Fix PIR1 part of bug #170 - Fix weak pull-up on 12f1822 RA3 bug #169 * src/14bit-processors.cc src/14bit-processors.h: - fix mcrl pin on extended processors * src/a2dconverter.cc: allow for no adcon1 register * src/p16f87x.cc: Delete all 16f877 registers * src/p16x6x.cc: remove unneeded output of class close * src/pic-processor.cc: add 16f1788 processor (not complete) * src/uart.cc: Fix apfcon pin switching part of bug #170 2014-07-10 Roy Rankin * modules/stimuli.cc: Fix compile error on FreeBSD - bug #160 * regression/p1xf18xx/Makefile: Fix regression test issue - patch #35 * gui/gui_menu.cc gui/gui_regwin.cc gui/gui_regwin.h gui/gui_scope.cc gui/gui_scope.h gui/gui_src.h gui/gui_src_asm.cc src/breakpoints.cc src/breakpoints.h src/cod.cc src/pic-processor.h: - Fix useless tests on unsigned int variables (FreeBSD warnings) 2014-07-01 Roy Rankin * regression/p1xf18xx/16f1788_g.lkr: add to svn 2014-05-17 Roy Rankin * regression/p1xf18xx/p12f1822.asm src/14bit-hexdecode.cc src/14bit-instructions.cc src/14bit-instructions.h: - fix ADDFSR instruction bug 161 from Tim Burke 2014-05-17 Roy Rankin * gui/gui_breadboard.cc gui/gui_breadboard.h: - Replace CList with GtkTreeView (patch 30 with rework) * src/ValueCollections.h: fix throw - bug 159 * src/p18x.cc src/p18x.h src/pic-processor.cc src/pic-processor.h: - add p18f2550, p18f4550 without USB support, remove PSP from p18f2520 * src/Makefile.am src/makefile.mingw src/pir.cc src/pir.h src/spp.cc src/spp.h: add streaming parallel port to p18f4455 p18f4550 (without USB functionality) 2014-05-09 Roy Rankin * modules/usart.cc: Correct baud rate after CPU frequency change Bug 167 * src/14bit-registers.cc: change OSCCON base frequency from 31.25 to 31 KHz * src/p16f88x.cc src/16bit-processors.cc src/p18x.cc src/p18x.h: - Fix default value of OSCCON - Bug 166 * src/p12x.cc src/p12x.h src/pic-processor.cc src/pic-processor.h: - Add 16F505 - patch 31 * regression/usart_test/Makefile: Fix make all * regression/usart_test/eusart_2455.asm: Test intrc frequency * regression/a2d/p18f1220.asm: Fix initial CPU frequency test * regression/p16f690/p16f690.asm: change for 8MHz INTRC 2014-04-14 Roy Rankin * cli/cmd_processor.cc: print unfound processor name * gpsim/main.cc: Fix issues with command line arguments - bug 165 2014-01-10 Roy Rankin * extras/ds1820/examples/Makefile.am: remove gpasm dependency from build * extras/ds1820/examples/README: modify instructions for above change 2014-01-06 Roy Rankin * src/p16f87x.cc: Added missing GP registers for p16f877 (bug #164) * gpsim/main.cc: Fix regression causing core dump from 13-10-28 change 2013-10-28 Borut Razem * gpsim/main.cc: display --version and --usage text before other texts 2013-10-27 Borut Razem * gpsim/main.cc, gpsim/makefile.mingw: fixed mingw ompilation 2013-10-26 Borut Razem * gpsim/main.h.in: added to source control 2013-10-22 Borut Razem * gpsim/main.cc, gpsim/Makefile.am, set_cl_revision.sh: fixed mess with --help and --version commnd line options, show svn revision number in --version 2013-10-16 Borut Razem * ChangeLog: added svn Revision stamp at the end of file 2013-10-15 Borut Razem * modules/stimuli.cc, modules/stimuli.h, modules/switch.h, modules/switch.cc, gui/gui_stopwatch.cc: applied patch #32 Make gpsim compile with clang, thanks to Ralf Horstmann 2013-09-20 Borut Razem * regression/rt.sh: applied patch #34 Allow overwriting make in regression tests, thanks to Ralf Horstmann * extras/ds1820/examples/Makefile.am: applied patch #33 Make gpsim buildable with BSD make, thanks to Ralf Horstmann 2013-09-07 Roy Rankin * regression/spi/p16f88.asm: Test SS operation * src/ssp.cc: Fix SS bug #158, Display pin function labels 2013-09-03 Roy Rankin * configure.ac: Development version 0.27.90 2013-09-02 Roy Rankin * configure.ac: Version 0.27.0 * ANNOUNCE: 0.27.0 release highlights 2013-08-18 Roy Rankin * COPYING: Current GPL license file * configure.ac: Version 0.27.rc1 * gui/gui_regwin.cc: Fix sigsegv when using gtkextra-3 2013-08-16 Borut Razem * doc/doc/gpsimWin32.html: updated libraries, links, ... * Makefile.am: removed plat/win32/Install.vcproj from EXTRA_DIST * plat/win32/gpsim.nsi: added missing DLLs * gpsim/gpsim.vcxproj, src/src.vcxproj: fixed pthreads library path 2013-08-14 Borut Razem * cli/cli.vcxproj, eXdbm/eXdbm.vcxproj, gpsim/gpsim.vcxproj, gui/gui.vcxproj, modules/modules.vcxproj, plat/win32/Install.vcxproj, src/src.vcxproj, gpsim.sln: Visual Studio upgraded to Visual Studio 2010, libraries upgraded (MSVC build) 2013-08-13 Borut Razem * cli/makefile.mingw, extras/ds1307/makefile.mingw, extras/graphic_lcd/src/makefile.mingw, extras/lcd/makefile.mingw, gpsim/makefile.mingw, gui/makefile.mingw, makefile.mingw, modules/makefile.mingw, plat/win32/make.mingw, plat/win32/gpsim.nsi: libraries upgraded (mingw build) 2013-08-10 Roy Rankin * gui/gui_breadboard.cc gui/gui_profile.cc gui/gui_src_opcode.cc gui/gui_stack.cc gui/gui_symbols.cc gui/gui_trace.cc gui/gui_watch.cc: - Fix CList GTK assert in Fedora 19 when using Adwaita theme 2013-08-07 Roy Rankin * regression/p1xf18xx/p12f1822.asm: - Add test to detect bad pcon, and fix trisa test * src/14bit-processors.cc: - set pcon to correct inital value on 14bit_e_processors * src/16bit-processors.cc: remove debug printout * src/processor.cc src/registers.cc: delete replaced registers 2013-08-06 Borut Razem * gpsim/main.cc: don't free returned popt values on _WIN32 since they reside in dll heap which is different from the main heap. * plat/win32/libgpsim.def: MSVC sync * extras/ds1307/makefile.mingw, extras/ds1820/makefile.mingw, extras/graphic_lcd/src/makefile.mingw, extras/lcd/makefile.mingw, plat/win32/make.mingw: adapted for Mingw GCC 4.7.3 2013-08-03 Roy Rankin * gui/gui_main.cc src/interface.cc: - Ifdef out unused depreciated thread code * src/breakpoints.cc: remove debug printout 2013-08-02 Roy Rankin * cli/Makefile.am: Generate missing parse.h even if parse.cc exists, remove scan.cc, parse.cc, parse.h on maintainer-clean, replace INCLUDES * extras/ds1820/examples/Makefile.am: Add an 'all' rule, replace GNU make syntax * eXdbm/Makefile.am extras/Makefile.am extras/ds1307/Makefile.am extras/ds1820/Makefile.am extras/graphic_lcd/src/Makefile.am extras/lcd/Makefile.am gpsim/Makefile.am gui/Makefile.am modules/Makefile.am src/Makefile.am src/dspic/Makefile.am: - Replace depreciated INCLUDES with AM_CPPFLAGS 2013-08-02 Roy Rankin * cli/Makefile.am : fix SVN parse.h issue with automake >= 1.12 * gui/gui_src_asm.cc : fix possible array overflow * src/pic-processor.cc : Fix MCLR handeling with erroneous WDT message 2013-07-29 Roy Rankin * regression/p16f676/reset.asm regression/p16f684/reset.asm regression/p16f690/p16f690.asm regression/p1xf18xx/p12f1822.asm regression/p1xf18xx/p16f1823.asm regression/run_regression.sh : - Fixes for regression tests * cli/input.cc gpsim/main.cc gui/gui_menu.cc gui/gui_regwin.cc modules/ttl.cc src/14bit-processors.cc src/14bit-processors.h src/14bit-registers.cc src/14bit-registers.h src/14bit-tmrs.cc src/14bit-tmrs.h src/16bit-processors.cc src/16bit-processors.h src/16bit-registers.cc src/16bit-registers.h src/a2d_v2.cc src/a2d_v2.h src/a2dconverter.cc src/a2dconverter.h src/comparator.cc src/comparator.h src/eeprom.cc src/i2c-ee.cc src/ioports.cc src/ioports.h src/operator.cc src/os_dependent.cc src/p12f182x.cc src/p12f6xx.cc src/p12f6xx.h src/p12x.cc src/p12x.h src/p16f62x.cc src/p16f62x.h src/p16f87x.cc src/p16f87x.h src/p16f88x.cc src/p16f88x.h src/p16f8x.cc src/p16f8x.h src/p16x5x.cc src/p16x6x.cc src/p16x6x.h src/p16x7x.cc src/p16x7x.h src/p16x8x.cc src/p16x8x.h src/p18x.cc src/p18x.h src/pic-processor.cc src/pic-processor.h src/processor.cc src/psp.cc src/psp.h src/ssp.cc src/ssp.h src/stimuli.cc src/trace.cc src/trigger.cc src/uart.cc src/uart.h : - Fix uninitialized variables, access of freed variables, proper delete types, processor classes cleanup on exit * src/pic-ioports.cc src/pic-ioports.h : - Allow always 1 bits in TRIS, don't trace internal reads of TRIS 2013-07-29 Roy Rankin * src/pic-instructions.cc : - Give proper register name in trace for banked 14bit processor registers * configure.ac extras/ds1820/Makefile.am extras/ds1820/examples/Makefile.am : - Fixes for make dist * src/registers.cc src/registers.h : - Make AN_INVALID_ADDRESS globally available 2013-06-30 Borut Razem * plat/win32/gpsim.nsi, plat/win32/make.mingw: Mingw compilatin with i686-pc-mingw32-gcc GCC 4.5.2 2013-06-30 Roy Rankin * cli/socket.cc eXdbm/eXdbm.c eXdbm/misc.c eXdbm/parse.c extras/graphic_lcd/src/glcd.cc gui/gui_regwin.cc gui/gui_scope.cc gui/gui_src.cc gui/gui_src_asm.cc gui/gui_src_opcode.cc gui/gui_trace.cc gui/gui_watch.cc src/attributes.cc src/bitlog.cc src/hexutils.cc src/i2c-ee.cc: - Fix compiler warnnings * src/16bit-registers.cc: Too many reads of WREG traced * src/14bit-processors.h src/14bit-processors.cc src/p12f182x.cc: - Try to fix windows regression issues 2013-06-29 Borut Razem * gpsim/main.cc: fixed invalid escape * plat/win32/libgpsim.def: MSVC sync * src/clock_phase.cc: GetTraceLog() for WIN32 compilation 2013-06-29 Roy Rankin * src/14bit-instructions.cc src/16bit-instructions.cc src/14bit-processors.cc src/14bit-registers.cc src/14bit-registers.h src/16bit-processors.cc src/pic-instructions.cc: - remove redundant field added in last patch to WREG, BSR and PCLATH registers * src/processor.cc: - Speed-up start by skipping resets on alias register memory locations 2013-06-29 Roy Rankin * cli/cmd_dump.cc src/icd.cc src/p16f88x.cc src/p16x6x.cc src/12bit-processors.cc src/p12f182x.cc src/p12f6xx.cc src/p12x.cc: - rename W Wreg * src/14bit-processors.cc src/14bit-processors.h src/pic-processor.cc src/pic-processor.h src/14bit-registers.cc src/14bit-registers.h src/14bit-instructions.cc src/16bit-instructions.cc src/pic-instructions.cc src/16bit-processors.cc src/16bit-registers.cc src/p16x5x.cc: - Allow break, logging on Wreg(if register in memory), rename W Wreg * src/ioports.cc: remove port trace messages * src/breakpoints.cc: remove debugging message * src/breakpoints.h src/clock_phase.cc src/trace.cc src/trace.h - Change logging to be same as break or single step as per doco 2013-06-25 Roy Rankin * regression/ccp/pwm_6520.asm regression/ccp_628/ccp_628.asm regression/p16f84/reset.asm regression/p18f/reset.asm regression/wdt/wdt_18f452.asm regression/wdt/wdt_18f4620.asm: - Adjust tmr0 counts in sleep tests * regression/p1xf18xx regression/p1xf18xx/12f1822_g.lkr regression/p1xf18xx/16f1823_g.lkr regression/p1xf18xx/Makefile regression/p1xf18xx/i2c_low.inc regression/p1xf18xx/p12f1822.asm regression/p1xf18xx/p16f1823.asm regression/p1xf18xx/p16f1823_comp.asm regression/p1xf18xx/p16f1823_i2c.asm regression/p1xf18xx/p16f1823_spi.asm regression/p1xf18xx/p16f1823_i2c_v2.asm regression/run_regression.sh - Add regression tests for p12f1822 and p16f1823 * regression/rt.sh: Print fail message * src/14bit-registers.cc src/14bit-registers.h src/comparator.cc src/comparator.h src/p12f182x.cc src/p12f182x.h: - Add SR latch * src/eeprom.cc src/eeprom.h: Modify insturction skip and wait * src/gpsim_time.cc src/gpsim_time.h: - Modify cycle increment and advance functions * src/16bit-registers.cc src/tmr0.cc src/tmr0.h: - Fix tmr0 overflow bug and remove empty function 2013-06-21 Roy Rankin * modules/resistor.cc: Update stimulus node on all property changes * src/14bit-instructions.h: Update copyright * src/14bit-registers.cc src/14bit-registers.h: - Add CPSCON classes for capacitor sensor module * src/14bit-tmrs.cc src/14bit-tmrs.h: Add support for capacitor sensor * src/a2dconverter.cc src/a2dconverter.h: FVR connect to capacitor sensor * src/p12f182x.cc src/p12f182x.h: Add compacitor sensor * src/tmr0.cc src/tmr0.h: Support t0xcs flag, remove magic number 2013-06-17 Roy Rankin * regression/i2c/p16f819.asm: Don't overwrite registers * regression/instructions_16bit/instructions_16bit.asm: - test subwfb and movlb instructions * cli/cmd_load.cc: error message on missing file * gui/gui_stopwatch.cc: use units for frequency * src/14bit-instructions.cc: fix register restore on retfie * src/14bit-processors.cc src/14bit-processors.h: Add CPU Temp * src/a2d_v2.h: add comment * src/14bit-registers.cc src/14bit-registers.h src/tmr0.cc src/tmr0.h src/14bit-tmrs.cc src/14bit-tmrs.h src/a2dconverter.cc src/a2dconverter.h src/stimuli.h src/comparator.cc src/comparator.h src/ssp.cc src/ssp.h src/p12f182x.cc src/p12f182x.h: - add or fix DAC, A2D, Comparator, T0, Tmr1, APFCON, SSP, USART, OSCCON * src/p12x.cc src/i2c-ee.cc: compile clean-up * src/pic-processor.h: Phase lock * 4 oscilator * src/pir.h: add set_c3if, set_c4if, set_tmr1gif * src/uart.cc src/uart.h: allow port select 2013-05-21 Borut Razem * plat/win32/gpsim.nsi: added RequestExecutionLevel admin 2013-05-21 Roy Rankin * extras/ds1820/rom1w.cc extras/ds1820/bit1w.cc: - Fixes for windows compile * gui/gui_stack.cc: Fix issue for 14bit enhanced stack * src/14bit-hexdecode.cc src/14bit-instructions.cc src/14bit-instructions.h src/14bit-registers.cc src/pic-instructions.cc src/14bit-registers.h: - 14bit enhanced commands and register fixup * src/a2dconverter.cc src/a2dconverter.h src/eeprom.cc src/pic-processor.cc src/pic-processor.h src/p12f182x.cc src/p12f182x.h: Add incomplete p16f1823 processor 2013-05-17 Roy Rankin * configure.ac extras/Makefile.am extras/ds1820/Makefile.am extras/ds1820/bit1w.cc extras/ds1820/bit1w.h extras/ds1820/ds1820.cc extras/ds1820/ds1820.h extras/ds1820/makefile.mingw extras/ds1820/module_manager.cc extras/ds1820/rom1w.cc extras/ds1820/rom1w.h extras/ds1820/examples/16f1823_g.lkr extras/ds1820/examples/Makefile extras/ds1820/examples/README extras/ds1820/examples/ds1820.asm extras/ds1820/examples/ds18b20.asm: Add module for ds1820, ds18s20 and ds18b20 temperature sensors * extras/ds1307/examples/README: fix typo 2013-05-04 Borut Razem * src/makefile.mingw: added p12f182x.o 2013-05-04 Roy Rankin * gui/gui_profile.cc: compiler warning cleanup * regression/p18f/extended_instructions.asm src/16bit-hexdecode.cc src/16bit-instructions.cc src/16bit-instructions.h src/16bit-processors.cc src/16bit-processors.h src/p18x.cc: - fix "Data addressing wrong (PIC18 w/ extended instruction mode)" - #139 * src/16bit-registers.cc src/16bit-registers.h regression/p18f/reset.asm src/14bit-registers.cc src/14bit-registers.h src/pic-processor.cc: - 18F stack reset on over/under flow - bug #154 2013-04-23 Roy Rankin * 14bit-hexdecode.cc 14bit-instructions.cc 14bit-instructions.h 14bit-processors.cc 14bit-processors.h 14bit-registers.cc 14bit-registers.h 16bit-hexdecode.cc 16bit-instructions.cc 16bit-instructions.h 16bit-processors.cc 16bit-registers.cc 16bit-registers.h pic-instructions.cc pic-ioports.cc pic-ioports.h pic-processor.cc pic-processor.h: - Add 14bit enhanced base class _14bit_e_processor * intcon.cc breakpoints.cc interface.cc: Fix compiler warnings * p12f182x.cc p12f182x.h Makefile.am: - add p12f1822 processor(incomplete) * gpsim_classes.h 12bit-processors.cc trace.cc: New stack with reset * processor.cc processor.h eeprom.cc eeprom.h: New eeprom class 2013-04-05 Roy Rankin * src/comparator.cc: fix pir1 setting with 2 comparators 2013-04-05 Roy Rankin * regression/Makefile.am: use regexp for regression EXTRA_DIST files * regression/run_regression.sh regression/p16f684/16f684.lkr regression/p16f684/Makefile regression/p16f684/a2d_684.asm regression/p16f684/compar_684.asm regression/p16f684/compar_684.stc regression/p16f684/epwm.asm regression/p16f684/nwdt_16f684.asm regression/p16f684/reset.asm regression/p16f684/wdt_16f684.asm regression/wdt/18f4620.lkr regression/wdt/Makefile regression/wdt/nwdt_18f4620.asm regression/wdt/wdt_18f4620.asm: - New regression tests * src/p12f6xx.cc src/p16f88x.cc src/p16f88x.h src/pic-processor.cc src/pic-processor.h src/pir.cc src/pir.h: Add 16f684 processor 2013-04-02 Borut Razem * doc/gpsim.html, doc/gpsim_svn.html: update links after project update to Allura 2013-03-25 Roy Rankin * eXdbm/parse.c: fix variable type mismatch, bug 3570700 * src/16bit-registers.cc src/pic-registers.cc: commands with PCL modification should take 2 cycles, bug 3509904 2013-03-23 Roy Rankin * extras/Makefile.am extras/ds1307/Makefile.am extras/graphic_lcd/INSTALL extras/lcd/INSTALL extras/lcd/Makefile.am - extras/graphic_lcd/configure.ac extras/lcd/autogen.sh extras/lcd/configure.in : Integrate extras further into linux build bug - 3560435 2013-03-20 Roy Rankin * regression/run_regression.sh regression/usart_test/18f2455.lkr regression/usart_test/Makefile regression/usart_test/eusart_2455.asm src/p18x.cc: Fix portc tris control and thus eusart operation for 18f[24]455 processors, bug 3171842 2013-03-18 Roy Rankin * modules/usart.cc: Debug message improved * regression/usart_test/usart_pir1v2.asm: test improved * src/uart.cc: fix SPBRG callback stall, bug 3602243 2013-03-16 Roy Rankin * regression/ccp_628/ccp_628.asm: - fix for gpasm change * regression/p18f/18f4321.lkr regression/p18f/Makefile regression/p18f/extended_instructions.asm regression/p18f/instructions.asm regression/p18f/reset.asm: - Switch to 18f4321 from 18f453 for true extended instruction set as now required by gpasm * regression/psp/18f6520.lkr regression/psp/Makefile regression/psp/p18f6520.asm regression/run_regression.sh src/psp.cc src/psp.h src/p18x.cc src/p18x.h: - Add psp functionality to 18f6520 - bug 3607516 Fix TRISD TRISE values after WDT reset - bug 3607517 * src/comparator.cc: Fix for compiler warning 2013-03-03 Roy Rankin * src/cod.cc: fix regressions caused by 2012-06-19 changes * cli/parse.yy: fix compile error with gcc 4.7.2 2013-03-02 Roy Rankin * configure.ac, Makefile.am: On OpenBSD, dlopen() and friends are provided within libc and there is no libdl.- patch 3601674 2012-06-19 Borut Razem * src/cod.cc: fixed loading cod file for program memory > 64k * gui/gui_menu.cc: modified mail address 2012-06-17 Rob Pearce * configure.ac Applied patch 3531562 to allow build against gtkextra-3 2012-03-19 Roy Rankin * regression/ccp/ccp_877a.asm src/14bit-tmrs.cc Fix CCP compare zero of TMR1 - bug 3508318 2012-02-28 Rob Pearce * src/p16f88x.cc Fix port C for 16f631 family - support request 3495121 2012-01-05 Roy Rankin * src/breakpoints.h src/breakpoints.cc src/trace.cc cli/cmd_break.cc Get logging working - bug 3432821 2012-01-03 Roy Rankin * gpsim/Makefile.am extras/graphic_lcd/configure.ac Changes for clantg++ compatibility as per bug 3426932 2012-01-03 Roy Rankin * src/p18x.h src/pir.cc src/pir.h src/p18x.cc Add USB registers (but not functionality) to 18F2455, 18F4455 after patch 3308765. * src/bitlog.h : fix to compile with latest glib * gui/gui_regwin.cc : fix reg=0 defense 2011-10-22 Rob Pearce * src/processor.cc Applied patch from Rupert Swarbrick in bug 3426928 - don't rely on static ProcessorConstructor instances being constructed before ProcessorConstructorList::findByType is called (avoids a segfault with some compilers) * src/14bit-tmrs.h src/p18x.cc Trivial: renamed a method for consistency with similar classes. * gui/gui_watch.cc Show all printable ASCII characters in watch window, not just those between '0' and 'z' 2011-10-19 Rob Pearce * src/registers.h src/14bit-registers.cc src/14bit-tmrs.cc src/ioports.cc src/registers.cc src/14bit-tmrs.h src/14bit-registers.h src/16bit-processors.cc gui/gui_watch.cc Cleaned up Register class "bit_mask" member and fixed bug 3425453 * regression/instructions_16bit/instructions_16bit.asm regression/instructions_14bit/branching.asm Regression tests for PCLATH register width 2011-06-02 Rob Pearce * src/16bit-registers.cc Attempt to fix bug 3311944 - reported as a POSTDEC bug but actually was that lfsr didn't work as the very first instruction at the reset vector * src/registers.h src/pic-registers.cc Fix ability to set PC from the command line, but not using the nasty hack in patch #3318235 - instead it's done properly 2011-06-02 Rob Pearce * src/p18x.h Fixed SFR size for 18Fx455 CPUs (with USB) * src/16bit-registers.cc src/16bit-registers.h src/16bit-instructions.cc regression/p18f/extended_instructions.asm : Fix for bug #3309120 and related indirect addressing problems on 18F in extended mode. Also a regression test for such issues. 2011-05-15 Roy Rankin * configure.ac : increase release number for development cycle 2011-04-27 Rob Pearce * doc/gpsim.html : Minor corrections to CPU list. 2011-04-27 Roy Rankin * regression/p16f690/Makefile : use local lkr file * regression/Makefile.am : tarball fix * configure.ac : increase release number * doc/gpsim.html ANNOUNCE : update documentation for release 2011-04-20 Roy Rankin * configure.ac ANNOUNCE : New release * regression/wdt/nwdt_16f648a.asm regression/wdt/16f648a.lkr regression/wdt/Makefile regression/Makefile.am regression/run_regression.sh : new regression test 2011-04-17 Rob Pearce * doc/gpsim.lyx : Minor corrections and a note on PIC18 program memory addressing. 2011-04-17 Roy Rankin * regression/usart_test/18f2221.lkr : replaces 18f2321.lkr * regression/Makefile.am : update regression file list * doc/gpsim.lyx modules/led.cc modules/led.h : Led module active high or low. Original patch from Tom Crane. 2011-04-09 Borut Razem * plat/win32/gpsim.nsi: removed extras/lcd/examples/lcdmemtest.hex 2011-04-07 Rob Pearce * src/p12f6xx.cc src/p16f88x.cc src/pic-ioports.h src/pic-ioports.cc regression/p12f675/12f629.lkr regression/p12f675/p12f629.asm regression/p12f675/Makefile regression/interrupts_14bit/interrupts_14bit.asm regression/run_regression.sh : Implemented patch for bug 3277143 (INT pin mis-handled on 12F629) and fixed the similar error on 16F88x. Also fixed the interrupt regression test to check INTEDG works (as had previously been done for 18F devices) and added a 12F629 test that checks interrupts 2011-03-30 Roy Rankin * gui/gui_src_asm.cc : fix
    /Windows/Source not ticked on startup. 2011-03-23 Roy Rankin * src/pic-processor.cc src/pic-processor.h src/p12x.h regression/wdt/10f200.lkr regression/wdt/wdt_10f200.asm regression/wdt/Makefile regression/a2d/p10f222.asm regression/run_regression.sh : Fix 10f2xx WDT bug 3059498 * regression/Makefile.am : - Add missing regression files into dist tarball * extras/lcd/examples/lcdmemtest.hex : - delete file from svn make clean removes * gui/gui_symbols.cc gui/gui_trace.cc gui/gui_menu.cc gui/gui_stack.cc gui/gui_watch.cc : Fix compiler warnings 2011-03-12 Roy Rankin * regression/p16f690/nwdt_16f631.asm regression/p16f690/eusart.asm regression/p16f690/epwm.asm regression/p16f690/p16f690.asm regression/p16f690/wdt_16f685.asm regression/p16f690/wdt_16f677.asm regression/p16f690/16f631.lkr regression/p16f690/Makefile regression/Makefile.am regression/run_regression.sh src/comparator.h src/14bit-registers.h src/processor.h src/pic-processor.cc src/a2dconverter.h src/p16f88x.h src/comparator.cc src/p16f88x.cc src/pic-processor.h src/14bit-registers.cc src/a2dconverter.cc : + Feature request 3110405 add 16f690/631/677/685/687/689 * gui/gui_src_asm.cc gui/gui_src.h : + Fix Source browser crash on font change (3190800) * src/p16x6x.h regression/interrupts_16bit/Makefile regression/usart_test/eusart.asm : Cosmetic fixes 2011-03-05 Roy Rankin * gui/gui_src_opcode.cc : set style for all p18 in program memory window 2011-03-01 Roy Rankin * gui/gui_src_opcode.cc : Further font fixes in program memory window * gui/gui_src.cc : memory program window updated during running 2011-02-21 Roy Rankin * gui/gui_src.h gui/gui_src_opcode.cc gui/gui_main.cc : + Fix issues with program memory window with P18 processors (3174547) and font issues. * gui/gui_src_asm.cc : minor display change for readability 2011-02-17 Roy Rankin * regression/tmr0_16bit/tmr0_16bit.stc regression/tmr0_16bit/Makefile regression/Makefile.am : remove trivial STC file * src/16bit-processors.cc src/14bit-registers.h src/uart.cc src/gpsim_time.cc src/psp.h src/bitlog.cc src/16bit-registers.cc modules/usart.cc gui/gui_symbols.cc gui/gui_profile.cc gui/gui_src_asm.cc : Fix uninitialized variables detected by valgrind 2011-02-17 Borut Razem * plat/win32/gpsim.nsi: fixed bug #3151323: problem on start gpsim 2011-02-13 Rob Pearce * src/p18x.h src/p18x.cc Fixes to 18F6520 implementation: correct EEPROM size, remove spurious wrong clock pin allocation, adjust structure to match style of 4x21 types 2011-02-12 Rob Pearce * src/p18x.h src/p18x.cc src/pic-processor.cc src/pic-processor.h Implemented the remaining devices from DS39689E (18F2221 & 4221) and all devices from DS39631D (18F2420,2520,4420,4520) 2011-02-10 Rob Pearce * src/p18x.h src/p18x.cc Re-factored 18F2455 and 18F4455 to be derived from 2x21 and 4x21 so they get the right Config3H and the right ADC, plus RE3/MCLRE pin 2011-02-03 Rob Pearce * src/p18x.h src/16bit-processors.cc src/p18x.cc src/eeprom.h Small re-organisation of how the EEPROM gets added to 18f2x21 and 4x21 derivatives. Some of the decisions pushed into the core classes so that new CPU derivatives need fewer unique methods. 2011-02-03 Roy Rankin * src/intcon.cc regression/tmr0_16bit/tmr0_16bit.asm regression/ccp_628/ccp_628.asm : + tmr0 not waking after sleep (bug 3162315) * src/ssp.cc : SPI and I2C may not start (bug 3169541) * extras/rs232-gen/rs232-gen.c extras/rs232-gen/example/Makefile extras/rs232-gen/Makefile : Update syntax (patch 3125817), fix baud rate 2011-02-03 Rob Pearce * src/p18x.cc src/p18x.h src/pic-processor.cc src/pic-processor.h src/eeprom.cc src/eeprom.h Initial implementation of PIC18F4620 for feature request #3159000 EEPROM_PIR class modified to support >256 byte EEPROM Some re-factoring of 18F2x21 derivatives for less duplication Config3H_2x21 class now implements PBADEN bit. Attempts to implement CCP2MX bit too, but the CCPCON class doesn't allow the pin re-allocation Note: This would break the 18F2455 so its Config3H has been commented until it is re-factored to be derived from the right base class! 2011-02-02 Rob Pearce * src/cod.cc Fixed addressing of memory on 16-bit cores while allocating HLL code references. This was responsible for a crash with large programs / long addresses found in 18F4620 development and bug #3154828, although it's not necessarily the only cause of that. 2011-01-03 Roy Rankin * src/comparator.cc regression/comparator/compar_882.asm regression/comparator/16f882.lkr regression/comparator/Makefile regression/run_regression.sh : Fix for bug # 3150231 Polarity should not change when ON bit is off. Fix comparator output pins cannot be driven from port when comparator is off. Add regression tests. 2010-12-10 Rob Pearce * src/14bit-tmrs.cc regression/ccp/pwm_6520.asm regression/ccp/pwm_877a.asm Fix for bug #3132914 : The clocking of TMR2 should not be affected by whether any of the CCPs are in PWM mode, and now it isn't. Duty cycle value is now handled correctly instead. 2010-11-28 Rob Pearce * src/pic-ioports.cc src/intcon.h regression/interrupts_16bit/interrupts_16bit.asm : Fix for bug #3120903 : INT0 edge selection moved to the correct register on 16-bit devices. Also fixed the regression test so that it actually bothers to check which edge caused the interrupt. Code for INT3 implemented but not tested yet. 2010-10-31 Rob Pearce * src/16bit-instructions.cc src/pic-processor.h src/p18x.h Partial implementation of "bugs" list (errata per CPU type) so that the 18F6520 has a buggy DAW instruction while the 18F4321 has a correct one. This matches the real hardware for those two - others need checking. * src/16bit-processors.h src/16bit-instructions.cc src/p18x.h A different approach to fixing the compiler warning Roy spotted (I'd already corrected my earlier error locally). 2010-10-31 Roy Rankin * src/16bit-processors.cc src/intcon.h src/intcon.cc src/pic-ioports.h src/pic-ioports.cc regression/interrupts_16bit/priority.asm regression/interrupts_16bit/interrupts_16bit.asm : - implement intcon3 for int1, int2 operation bug #3071596 * src/16bit-instructions.cc : fix complier warning 2010-10-25 Rob Pearce * modules/ttl.cc modules/ttl.h modules/gpsim_modules.cc regression/ttl/ttl165.asm regression/ttl/Makefile regression/run_regression.sh Added a module to simulate a 74x165 parallel-to-serial shift register 2010-10-22 Rob Pearce * src/14bit-tmrs.cc src/14bit-tmrs.h src/16bit-processors.cc src/p12f6xx.cc src/p16f88x.cc src/p16x6x.cc src/p18x.cc Fixed TMR2 to support multiple PWMs, bug #2823242 Implemented all five PWMs on the 18F6520 Fixed TMR2 wrap bug, #3092906 * regression/ccp/pwm_6520.asm regression/ccp/18f6520.lkr regression/ccp/Makefile regression/run_regression.sh Added regression test for the above 2010-10-08 Rob Pearce * modules/resistor.cc modules/resistor.h Minor fix to pulldown so that its resistance attribute is correctly initialised to 0 (it was confused and showed as 5V) 2010-09-29 Rob Pearce * src/p18x.h src/p18x.cc src/16bit-processors.cc src/16bit-processors.h Fixed GPR memory size and SFR peripheral set of 18F1220 (the 16 bit base class assumptions of portC and CCP2 are now optional) * src/14bit-tmrs.h src/14bit-tmrs.cc src/uart.cc Partial rework for >2 PWMs as on 18F6520, and multiple UARTs naming 2010-08-25 Rob Pearce * src/p18x.h src/p18x.cc src/p16x6x.cc src/p12f6xx.cc src/p16f88x.cc src/16bit-processors.cc src/16bit-processors.h src/pir.cc src/pir.h src/pic-instructions.cc src/pic-processor.h src/16bit-instructions.cc src/14bit-tmrs.h src/14bit-tmrs.cc Implemented PIR3 for 18F6520, including the presence of multiple CCPxIF flags in one PIR (needed some re-design) Fixed implementation of 18F "access bank", as some devices have more than 128 bytes mapped to SFR space 2010-08-21 Rob Pearce * src/p18x.h src/p18x.cc src/p16x6x.cc src/p16f87x.cc src/p16f62x.cc src/p16f88x.cc src/p16f8x.cc src/16bit-processors.cc src/pic-processor.cc src/pic-processor.h src/uart.cc src/uart.h Partial implementation of 18F6520, including change to UART-PIR linkage for multiple UART support. 2010-07-12 Roy Rankin * configure.ac : release changed to 0.25.1 post release SVN 2010-06-28 Roy Rankin * configure.ac : release changed to 0.25.0 * ANNOUNCE : 0.25.0 highlights 2010-06-28 Roy Rankin * src/16bit-processors.h src/16bit-processors.cc src/pic-processor.cc src/pic-processor.h src/p18x.cc : - fix porta7 for P18 processors, bug 3021904 * src/pic-ioports.h src/pic-ioports.cc regression/p16f676/reset.asm : - mask bits on write to tris regeister 2010-06-26 Rob Pearce * src/ssp.cc regression/spi/p18f242.asm Fix for bug #3021514 : - MSbit is now correctly sent in CKE=1 mode - Clock not disturbed if second byte sent within half bit of SSPIF Extended one of the SPI regression tests to include CKE=1 mode 2010-06-25 Rob Pearce * modules/ttl.cc modules/ttl.h modules/gpsim_modules.cc Fix to TTL377 so that all eight latches update "simultaneously" Added TTL595 serial-in-parallel-out shift register 2010-06-23 Roy Rankin - missed CLOCK_EXPERIMENTS changes 2010-06-22 Roy Rankin - remove dead code from CLOCK_EXPERIMENTS 2010-06-20 Roy Rankin * src/pic-processor.cc src/clock_phase.cc - fix cycle counter bug 3018510 2010-06-12 Rob Pearce * src/14bit-tmrs.cc Fix uninitialised ssp_module pointer (potential segfault) 2010-06-09 Ralf Forsberg * src/pic-processor.cc : Fix integer overflow in realtime mode. 2010-06-07 Roy Rankin * gui/gui_src_asm.cc : fix bug 3012488 finish key SIGSEGV for hex file 2010-06-07 Roy Rankin * src/pic-processor.cc : patches for realtime with GUI mode * doc/gpsim.html doc/gpsim.lyx gpsim.spec.in : Documentation of new license 2010-06-06 Borut Razem * modules/modules.vcproj, plat/win32/libgpsim.def, modules/gpsim_modules.cc: MSVC sync 2010-06-06 Ralf Forsberg - Don't add files from cod if the actual file is missing. 2010-06-06 Ralf Forsberg - Switching to realtime mode could hang up. 2010-06-06 Ralf Forsberg - Fixed step_over in HLL_MODE. - Update gui after finish command. 2010-06-06 Roy Rankin * gpsim/Makefile.am src/dspic/Makefile.am src/Makefile.am doc/Makefile.am extras/graphic_lcd/src/Makefile.am extras/ds1307/Makefile.am modules/Makefile.am gui/Makefile.am cli/Makefile.am Makefile.am : include windows build files in distribution tarball 2010-06-06 Ralf Forsberg - Remove MCLR pin monitor in pic destructor to avoid segfault in IOPIN desctructor. 2010-06-06 Roy Rankin * regression/p18f/extended_instructions.asm: add nops after asserts * INSTALL.gpsim : rename as INSTALL gets overwritten * doc/gpsim.html doc/gpsim_svn.html README Makefile.am : document LGPLv2+ change 2010-06-05 Borut Razem * modules/makefile.mingw: included video.* module * plat/win32/gpsim.nsi: updated dependency packages 2010-06-05 Roy Rankin * gui/gui_menu.cc gui/gui_statusbar.cc : fix bug 3009843 Simulation Time HH:MM:SS.CC displays incorrectly 2010-06-05 Roy Rankin * src/ modules/ COPPYING.LESSER README : to LGPLv2+ 2010-06-04 Ralf Forsberg - Added back HLL source browser support for sdcc and jal. - Fixed bug in FileContext where the vector pointers could become dangling after stl magic because of missing copy constrctor. Made them objects instead of pointers. 2010-05-?? Ralf Forsberg - Optimized video module using pixmap shadow buffer. 2010-06-01 Roy Rankin * src/14bit-tmrs.h src/14bit-tmrs.cc src/comparator.h src/comparator.cc src/p16f88x.cc src/p18x.h src/p18x.cc : Enhanced PWM Auto-Shutdown 2010-05-27 Roy Rankin * modules/video.cc modules/gpsim_modules.cc modules/video.h modules/Makefile.am + resurrect video module patch 3007214 by Paul S 2010-05-22 Roy Rankin * src/comparator.h src/14bit-tmrs.cc src/comparator.cc src/p16f88x.cc - Add comparator 2 gate control of timer 1 for 16f88x * src/uart.cc : fix bug 2827439 USART pin direction * modules/logic.cc : fixed compilation warnings 2010-05-18 Borut Razem * src/makefile.mingw: added p16f88x.o * extras/graphic_lcd/src/makefile.mingw, extras/lcd/makefile.mingw: include project root directory for config.h * extras/graphic_lcd/src/ssd0323.cc: fixed compilation warnings * extras/ds1307/makefile.mingw: added * makefile.mingw: adedd extras/ds1307 build * plat/win32/gpsim.nsi: added extras/ds1307/* to the package 2010-05-17 Roy Rankin - Extras built, installed as part of Gpsim 2010-05-17 Roy Rankin - Add ds1307 Realtime Clock module 2010-05-11 Roy Rankin * src/dspic/dspic-processors.cc src/dspic/dspic-registers.cc src/pic-processor.cc src/icd.cc src/16bit-registers.cc src/registers.h src/pic-registers.cc: Remove use of memory_size_mask which assumed memory size 2^n (bug 2979021) * src/pic-ioports.cc: B0 edge wakes processor from sleep (bug 2999264) 2010-05-01 Rob Pearce * src/16bit-registers.cc src/pic-instructions.cc Fixed bug #2983660 - BSF and BCF now work right on PLUSW registers Also PLUSW registers now work if destination is address 0 * regression/psp/p16f871.asm regression/psp/p18f452.asm Fixed the PSP regression test code to de-select the ADC channels, because the above fix shows up that they should (probably) have failed before. 2010-04-10 Roy Rankin * src/p16f8x.cc: correct usart pins for p16f87/8 (patch 2116354) * src/14bit-processors.cc: Correctly wake up from sleep (patch 2348392) * cli/cmd_load.cc doc/gpsim.lyx : Documentation updates (patch 2108073) 2010-04-08 Roy Rankin * gui/gui_breadboard.cc: fix trace bug 2983580 * src/pic-processor.cc: fix realtime mode lockup (bug 2973978) * src/p18x.h src/p18x.cc: add extended PWM * src/14bit-tmrs.cc src/14bit-tmrs.h: initialize some variables, fix to have extended PWM work with processors without prtrcon register 2010-04-07 Roy Rankin * gui/gui_breadboard.cc: lighten low pin color for those with red-green color blindness 2010-04-06 Roy Rankin * src/p16f88x.h src/p16f88x.cc src/Makefile.am src/pic-processor.h src/pic-processor.cc : Add 16f882/883/884/886/887 processors * src/comparator.h src/comparator.cc: add class used in 16f88x * src/14bit-tmrs.h src/14bit-tmrs.cc: add PWM(enhanced mode) support * src/pir.h src/pir.cc: add interupts for 16f88x * src/uart.cc: fix send_break code * src/uart.h: define 16f88x SCKP bit in _BAUDCON * src/a2dconverter.h src/a2dconverter.cc: ADC for 16f88x * src/ssp.cc: warning message line numbers in decimal * src/pic-registers.cc : fix debug statement * regression/usart_test/eusart.asm: refine test 2010-03-29 Rob Pearce * src/16bit-processors.cc src/16bit-processors.h src/p18x.cc src/p18x.h regression/instructions_16bit/18f452.lkr regression/instructions_16bit/instructions_16bit.asm Moved loading/reading of EEPROM and ID locations for 18F out of the 18fxx20 class into the base class, as it's common to all the family * src/intcon.cc Commented out an annoying debug print that isn't needed any more 2010-03-29 Roy Rankin * gui/gui_scope.cc use previous size and position of window (bug 2973982) 2010-03-28 Rob Pearce * src/p16f62x.cc Fixed missing aliases of INDF, PCLATH and INTCON (bug 2977843) 2010-03-12 Rob Pearce * src/p18x.cc src/processor.cc Fixed loading of EEPROM data from COD/HEX on 18F (bug 2968268) 2010-03-10 Rob Pearce * src/16bit-instructions.cc regression/instructions_16bit/instructions_16bit.asm : Fix issue 2968248; carry flag is "sticky" to DAW instruction * src/pic-ioports.cc regression/p18f452_ports/p18f452_ports.asm : Fix issue 2902082; writing the PORT register now updates the LAT register too. 2010-02-07 Roy Rankin * src/pic-processor.cc: Fix real-time mode regression (bug 2930175) 2010-01-12 Roy Rankin * src/p18x.h src/p18x.cc src/16bit-registers.cc: Add eeprom, usart for 18f1220/1320 * src/uart.cc src/uart.h: Eusart fixes and debug print fixes * modules/usart.cc: scroll patch and debug print fixes * regression/usart_test/eusart.asm: Pin direction per docs - Most of above changes supplied by Geoffrey Hausheer 2010-01-07 Roy Rankin * gui/gui_menu.cc: Fix sigsegv when changing simulation time units when no processor is defined (bug 2926629) 2006-11-07 Scott Dattalo * src/p18x.hh: wrong register memory size (bug 2921532) 2009-11-22 Rob Pearce * src/p18x.cc Fixed the creation of ports D and E on 18F4x21 devices 2009-10-25 Roy Rankin * src/p16f62x.h : wrong program memory size (bug 2885817) 2009-10-11 Roy Rankin * configure.ac : Missing readline lib now a terminating error for configure. (bug 2868402) Set version to 0.24.1 2009-09-28 Rob Pearce * src/16bit-hexdecode.cc, src/pic-processor.cc, src/16bit-tmrs.cc src/14bit-tmrs.cc, src/14bit-registers.cc, src/pic-ioports.cc Trivial changes only: - re-ordered processor type creation so the list reported is nearer numeric order - removed all #includes of processor type headers from "core" code (i.e. not processor type definition files) except pic-processor.cc The idea is to head towards being able to define processors outside of the core GPSim library, by making GPSim follow that sort of structure. 2009-09-13 Rob Pearce * extras/graphic_lcd/src/gpsim_modules.cc, extras/lcd/module_manager.cc, modules/gpsim_modules.cc, modules/encoder.cc Trivial changes only - removed some very obsolete commented out code and erroneous statements about module libraries. 2009-08-24 Borut Razem * src/14bit-registers.h, src/makefile.mingw, plat/win32/libgpsim.def: src/src.vcproj: mingw and MSVC sync 2009-08-24 Roy Rankin * gpsim/main.cc doc/gpsim.lyx : document optional -c -s * configure.ac ANNOUNCE : update for release 0.24.0 * doc/gpsim.html PROCESSORS : update with new processors 2009-08-23 Roy Rankin * src/os_dependent.cc : For linux fix loading modlib bug #2837446 2009-08-23 Roy Rankin * regression/p12f675/12f683.lkr regression/p12f675/p12f683.asm regression/p12f675/Makefile regression/run_regression.sh * add p12f683 regression test * regression/p12f675/p12f675.asm : fix bug in test * src/14bit-tmrs.h src/14bit-tmrs.cc src/comparator.h src/comparator.cc : support cmp T1 gate * src/p12f6xx.h src/p12f6xx.cc src/pic-processor.cc src/pic-processor.h : add P12f683 * src/eeprom.cc : print message if both RD and WR set in EECON1::put * src/gpsim_time.cc : add more debug output * src/trace.h : delete commented out code * src/eeprom.h : add callback_print() for debugging * gui/gui_regwin.cc : remove unneeded include 2009-07-17 Rob Pearce * src/14bit_tmrs.cc src/14bit_tmrs.h Turned the ccpcon/compare_value member pair in TMRL into a linked list of CCP references, built on demand and deleted when compare mode cancelled, thus fixing bug 2819395 * src/16bit-processors.cc p16x6x.cc Removed setting of tmrl->ccpcon as it no longer exists. The operation was pointless anyway, as it would always be set again before it became meaningful * regression/ccp/ccp877a.asm Added regression test for dual compare mode. This is a very slightly enhanced version of Roy's attachment in bug 2819395 2009-07-15 Rob Pearce * src/14bit_tmrs.cc src/14bit_tmrs.h Changed around the structure of who does what when a CCP is in compare mode. At the moment this should not have changed any functionality, but is in preparation for fixing bug 2819395 2009-07-15 Roy Rankin * regression/i2c/p16f88.asm : position modules * modules/stimuli.cc : fix error causing warning message * src/ioports.h src/stimuli.cc src/stimuli.h src/pic-processor.cc src/pic-processor.h gui/gui_breadboard.h gui/gui_breadboard.cc regression/p16f676/reset.asm regression/p16f676/Makefile regression/run_regression.sh : - Fix MCLR when it can be an IO pin 2009-07-11 Roy Rankin * regression/comparator/compar_877a.stc : position modules * regression/interrupts_14bit/interrupts_14bit.asm : use WDT * regression/usart_test/usart_pir1v1.asm * regression/usart_test/usart_pir1v2.asm regression/usart_test/eusart.asm regression/i2c/p16f876a.asm : Stop run-away tests 2009-07-07 Roy Rankin + src/pic-processor.cc src/pic-processor.h src/p18x.cc src/p18x.h : - Fix 18f2455 sigsegv, package size (2814946), ram and program size add 18f4455 40 pin version but still no USB support * src/processor.cc : Remove 2^N restriction on program memory size * src/packages.h src/packages.cc : Make warning in assign_pin optional 2009-07-05 Roy Rankin * src/16bit-processors.cc : fix Config1H::toString * src/eeprom.cc : fix delete issue * src/pic-processor.cc src/pic-processor.h src/p16x6x.cc src/p16x6x.h regression/p16f676/16f676.lkr regression/p16f676/Makefile regression/p16f676/p16f676.asm regression/Makefile.am regression/run_regression.sh : - Add p16f630, p16f676 * src/pir.cc src/pir.h : New PIR1 register type * src/p16f62x.cc : fix MCLR calls * src/stimuli.cc src/stimuli.h : input pull-up off for analog pins bug 2814950 * src/comparator.cc : new analog mode call, fix sigsegv * src/ioports.cc src/ioports.h src/a2d_v2.cc : new analog mode call * src/a2dconverter.cc src/a2dconverter.h : new analog pin mode call, 16f676 mode 2009-07-04 Roy Rankin * regression/interrupts_14bit/interrupts_14bit.stc regression/interrupts_16bit/interrupts_16bit.stc : + terminate test when interrupts fail * regression/a2d/p16f819.asm : fix comment * regression/a2d/p16f88.asm : set vref as analog pin * regression/a2d/Makefile : fix "make sim" 2009-06-15 Roy Rankin * src/p18x.h src/p18x.cc src/16bit-processors.h src/16bit-processors.cc src/pic-processor.h src/pic-processor.cc src/p16f62x.cc src/ioports.cc src/p18x.cc src/14bit-registers.cc src/p16f8x.cc : Config word set - clock mode and pins, add OSCTUNE where appropriate for p18 processors * regression/Makefile.am regression/run_regression.sh regression/p18f/reset.asm regression/p18f/Makefile : Add regression - test for p18 resets * regression/a2d/p18f1220.asm : add intrc frequency tests * regression/a2d/p18f4321.asm : MCLR turned off with Configword * regression/a2d/p16f88.asm : position test resistors 2009-06-10 Rob Pearce * src/os_dependent.cc Fixed IsFileExtension so that the extension must match the end of the file name and be preceeded by a dot. This is for bug 2803756 but not using the patch supplied as it wasn't quite semantically correct. 2009-06-07 Roy Rankin * src/16bit-processors.cc src/pic-processor.h src/pic-processor.cc src/p18x.cc src/14bit-processors.h src/14bit-processors.cc : - Add MCLR pin support to P18 processors * src/p16f8x.cc : Fix MCLR support * src/a2d_v2.cc : Remove unused variable to stop compiler warning 2009-06-01 Roy Rankin * regression/p12f675/p12f675.asm regression/a2d/p18f1220.asm regression/a2d/p18f4321.asm : - Test that analog pins read as 0 * regression/resistor/resistor.asm * regression/p18f452_ports/p18f452_ports.asm : - Set Analog pins to digital before tests * regression/a2d/p18f452.asm : set position in breadboard * src/ioports.h src/ioports.cc src/16bit-processors.cc src/a2d_v2.h src/a2d_v2.cc src/a2dconverter.h src/a2dconverter.cc src/comparator.cc src/14bit-registers.cc src/pic-ioports.cc : - analog pins are labeled and read as 0 (bug 1832222) * src/p18x.cc : remove ssp registers on p18f1220 2009-05-30 Roy Rankin * regression/comparator/compar_10f204.asm : reset vector wrong address * regression/p12f675/p12f675.asm : fix typos, clear analog ports at - end of ADC test * regression/Makefile.am : fix make dist * src/intcon.h src/intcon.cc src/pic-instructions.cc src/p12x.cc : - remove extraneous trace messages 2009-05-24 Roy Rankin * regression/p12f675/12f675.lkr regression/p12f675/p12f675.asm regression/p12f675/Makefile regression/Makefile.am src/Makefile.am regression/run_regression.sh src/p12f6xx.cc src/p12f6xx.h src/pic-processor.h src/pic-processor.cc : - Add 12f675 and 12f629 processors and regression tests * src/14bit-tmrs.cc src/14bit-tmrs.h : hooks to handle stop/start of - TMR1 for sleep, support for TMR1 Gate Enable * src/comparator.cc : fixes to allow single comparator * src/14bit-registers.cc src/14bit-registers.h : Add OSCCAL class - (OSCillator CALibration) , IOC class (Interrupt On Change) and WPU - class (Weak Pull Up) used in P12f629/675 * src/a2dconverter.cc src/a2dconverter.h : Add ADCON0_12F and - ANSEL_12F classes to support ADC for p12f675 * src/pic-ioports.cc src/pic-ioports.h : Add PicPortGRegister port - class which support IOC (Interrupt On Change) register * src/14bit-processors.cc src/14bit-processors.h : handle MCLR pin - action, remove dead code * src/p16f8x.cc : fix POR value for register ANSEL 2009-05-05 Roy Rankin * cli/cmd_processor.cc: revert as fix not in this file * gpsim/main.cc: fix "gpsim -p processor file.hex" bug # 1629719 load .stc or .cod file from command line without -c or -s 2009-05-05 Roy Rankin * cli/cmd_processor.cc: fix "gpsim -p processor file.hex" bug # 1629719 * regression/Makefile.am: remove */*.o files on make clean 2009-05-04 Roy Rankin * src/16bit-registers.h src/16bit-registers.cc src/16bit-processors.cc src/tmr0.cc src/tmr0.h src/p12x.cc src/pic-registers.cc src/12bit-processors.cc src/12bit-processors.h src/14bit-processors.cc src/14bit-processors.h src/16bit-processors.h regression/tmr0_16bit/tmr0_16bit.asm regression/wdt/wdt_18f452.asm regression/p16f84/reset.asm regression/a2d/p10f222.asm: - TMR0 stops during sleep - bug #502665 * regression/a2d/p16f871.asm regression/a2d/p16f873a.asm regression/a2d/p16f874a.asm: - bad register name in assert 2009-04-28 Roy Rankin * src/pic-registers.cc : backout part of last change which causes sigsegv 2009-04-28 Roy Rankin * src/pic-registers.h src/pic-registers.cc src/pic-ioports.cc regression/digital_stim/digital_stim.asm: - OPTION_REG values not properly processed on initial reset causing wrong edge detect for interrupt 2009-04-27 Roy Rankin * src/p12x.cc src/p12x.h src/pic-registers.cc: - For p12x processors support osccal function for internal RC frequency tuning and FOSC4. Add Configuration word support for IOSCFS and NOT_MCPU. Pin driving and label for FOSC4/COUT/T0SC/gpio2 and MCLR/gpio3 2009-04-21 Roy Rankin * regression/instructions_12bit/instructions_12bit.asm regression/a2d/p10f222.asm src/p12x.cc src/p12x.h: - Fix pullup on gpio3 on all p12x processors 2009-04-20 Roy Rankin * src/a2dconverter.h: Fix sigsegv introduced in last patch 2009-04-20 Roy Rankin * src/pic-processor.cc src/pic-processor.h src/p12x.cc src/p12x.h src/a2dconverter.cc src/a2dconverter.h regression/a2d/10f222.lkr regression/a2d/p10f222.asm regression/a2d/Makefile regression/run_regression.sh: - Add P10F220 and P10F222 processors 2009-03-23 Roy Rankin * configure.ac: set release 0.23.9 * ANNOUNCE: fix typo 2009-03-18 Roy Rankin * extras/lcd/configure.in: bump release number 2009-03-02 Roy Rankin * gpsim/main.cc: expand extent of try * gpsim.spec.in: improve utf8 conversion of AUTHORS file * ANNOUNCE: update for 0.23.0 2009-03-01 Borut Razem * gpsim/main.cc, src/errors.h, src/errors.cc, src/uart.cc, src/icd.cc, src/a2d_v2.cc, src/pic-processor.h, src/processor.cc, gui/gui_menu.cc, cli/scan.ll, cli/socket.cc, cli/input.cc, cli/input.h, doc/gpsim.lyx: undone changes I made yesterday: libgpsim functions now throw FataError exception, which is catched by main() 2009-02-28 Borut Razem * gpsim/main.cc, src/icd.cc, src/processor.cc, gui/gui_menu.cc, cli/scan.ll, cli/socket.cc, cli/input.cc, cli/input.h: use atexit() to execute exit_gpsim() when exiting to solve Win32 libgpsim.dll problem. 2009-02-28 Roy Rankin * gpsim.spec.in: update * src/trace.cc: fix segfualt (bug 1490171) * src/registers.cc src/pic-processor.h: fix pcl setting and segfault (bug 1642109) * src/eeprom.cc: fix segfault (bug 1823171) 2009-02-19 Roy Rankin * gui/gui_main.cc: set LC_NUMERIC locale to standardize IO (bug 1832702) 2009-02-18 Roy Rankin * gui/gui_src_asm.cc: Handle non uft8 characters is Source Browser window (bugs 1869795, 2579637) 2009-02-17 Roy Rankin * src/os_dependent.cc: Fix loading module libraries * cli/parse.yy cli/cmd_attach.cc doc/gpsim.lyx: fix help for attach and segfault (bug 2556045) * src/p16x6x.cc src/p16f62x.cc src/ioports.cc: debuging output only if verbose set 2009-02-14 Roy Rankin * cli/parse.yy: fix segfault (bug 2556041) 2009-02-14 Roy Rankin * src/expr.cc src/protocol.cc src/operator.cc src/ValueCollections.h src/protocol.h src/icd.cc src/comparator.cc src/value.cc src/processor.cc src/16bit-instructions.cc modules/usart.cc gui/settings_exdbm.cc gui/gui.h: Changes to compile with GCC 4.4 2009-02-14 Roy Rankin * regression/Makefile.am: correction on file list for make dist 2009-02-14 Roy Rankin * gpsim/main.cc src/icd.cc src/processor.cc gui/gui_menu.cc cli/scan.ll cli/socket.cc cli/input.cc cli/input.h: Do not exit from library routines * regression/Makefile.am make clean, cleans files in regression sub-directories fix list of files so make dist works 2008-12-26 Borut Razem * extras/lcd/lcdgui.cc, modules/led.cc, gui/gui_profile.cc: applied patch 2458749: segfault in gdk_color_alloc(), thanks to Don Wooton * src/makefile.mingw, src/src.vcproj: added a2d_v2.cc and a2d_v2.h 2008-12-22 Roy Rankin * regression/a2d/18f1220.lkr regression/a2d/18f4321.lkr regression/a2d/p18f1220.asm regression/a2d/p18f4321.asm regression/a2d/Makefile regression/run_regression.sh src/p18x.h src/16bit-processors.cc src/a2d_v2.h src/Makefile.am src/a2d_v2.cc src/p18x.cc src/a2dconverter.cc src/16bit-processors.h : Add new style A2D converter with adcon2 register which supports up to 16 channels 2008-12-07 Roy Rankin * src/16bit-registers.h src/p16f87x.cc src/p16f87x.h src/p16x7x.h src/a2dconverter.h src/p16x7x.cc src/p16f8x.h src/16bit-registers.cc src/p16f8x.cc src/a2dconverter.cc src/16bit-processors.h : Consolidate ADCON0_withcpp, ADCON0_16 and ADCON0 classes to just ADCON0. Fix ADCON1::setNumberOfChannels() to allow number of channels to be increased. 2008-12-02 Roy Rankin * src/14bit-registers.h src/dspic/dspic-instructions.cc src/pic-processor.cc src/pir.cc src/16bit-instructions.h src/comparator.cc src/hexutils.h src/14bit-registers.cc src/16bit-registers.cc modules/stimuli.cc : Fix GCC 4.3.0 warnings 2008-09-21 Borut Razem * plat/win32/gpsim.nsi, doc/gpsimWin32.html: updated for libpng-1.2.29, win_iconv_dll-tml-20080320, atk_1.22.0-2_win32, gtk+_2.14.2-1_win32, cairo-1.6.4-2, pango_1.20.5-2_win32, glib_2.18.1-1_win32 2008-09-20 Rob Pearce * src/intcon.cc src/intcon.h src/pir.cc src/pir.h src/p16x7x.cc Fixed handling of peripheral interrupts during ISR execution on 16-bit with priority enables, so that the new interrupt will be handled after the RETFIE This involved changing the PIR::interrupt_status() and dependents to return a bit-map of priorities rather than a simple boolean. 2008-09-17 Rob Pearce * src/intcon.cc : Fixed response to low priority interrupts during high priority ISR (i.e. it no longer runs the low-pri ISR immediately) * src/16bit-processors.cc src/intcon.cc src/intcon.h regression/interrupts_16bit/priority.asm regression/analog_stim/p18f452.asm regression/a2d/p18f452.asm Fixed handling of interrupts during ISR execution on 16-bit, at least for the non-priority case, so that the new interrupt will be handled after the RETFIE (as already worked on 14-bit). Also added test of priority nesting, which currently doesn't test this fix (it uses RBIF, which already worked). Also fixed a couple of ADC regression tests that failed to acknowledge the interrupt (due to a typo) and thus only passed because this condition was buggy. 2008-09-17 Rob Pearce * src/ssp.cc : Corrected SPI transfer complete behaviour so that SSPIF is set on completion of a master mode transfer regardless of the SSPOV state. (Confirmed this behaviour on an 18F2321) * src/14bit-tmrs.cc : Made some commented out debug code available with higher verbosity, for testing 2008-09-14 Borut Razem * configure.ac: fixed bug #1698566: missing libpopt header is unnoticed by configure 2008-08-29 Rob Pearce * src/14bit-tmrs.cc src/14bit-tmrs.h src/pir.h src/16bit-processors.cc src/p16x6x.cc src/p18x.cc regression/ccp/ccp_877a.asm : Changed the CCPCON class to not use pir_set, since this broke its ability to be duplicated. It now refers to a specific PIR register, meaning that the second CCP on a 16F87x or similar can actually generate the right interrupt. Added tests for this in the CCP_877a regression test 2008-08-26 Rob Pearce * src/processor.cc src/processor.h src/sim_context.cc src/cod.cc src/16bit-processors.h gui/gui_profile.cc : Corrections to use of Processor::program_memory_size() so that all of them expect it to be instruction words, not byte addresses. 2008-08-23 Rob Pearce * regression/interrupts_16bit/(interrupts_16bit.asm, priority.asm) regression/run_regression.sh : Enhance and enable regression tests for the 16bit core prioritised interrupts * src/intcon.cc : Corrected peripheral interrupts to use the right vectors when IPEN is set 2008-08-06 Rob Pearce * src/intcon.cc : Corrected low priority non-peripheral interrupts to obey the GIEL bit * regression/interrupts_16bit/(18f2321.lkr, Makefile, interrupts_16bit.asm, interrupts_16bit.stc, priority.asm, priority.stc) : First stab at some regression tests for the 16bit core prioritised interrupts 2008-08-04 Borut Razem * src/protocol.cc, src/i2c-ee.cc, src/eeprom.cc, src/pic-processor.cc. src/gpsim_object.cc, src/comparator.cc, src/value.h, src/p12x.cc, src/value.cc, src/cod.cc, config_win32.h.in, cli/scan.ll, cli/command.cc, cli/input.cc, plat/win32/libgpsim.def: MSVC sync, enable compilation on VC 2008 2008-08-02 Borut Razem * gpsim/main.cc, src/gpsim_interface.h, src/icd.h, src/modules.h, src/i2c-ee.cc, src/ui.h, src/trace.h, src/ui.cc, src/icd.cc, src/modules.cc, src/trace.cc, src/cmd_manager.h, modules/usart.cc, modules/logic.cc, modules/logic.h, gui/gui_src.cc, gui/gui_symbols.cc gui/gui_src.h, gui/gui_regwin.cc, gui/gui_trace.cc, gui/gui_profile.cc gui/gui_src_asm.cc, gui/gui_dialog.cc, gui/gui_menu.cc, gui/gui_stack.cc gui/gui_watch.cc, gui/gui_object.h, gui/settings_exdbm.cc, gui/gui_src_opcode.cc, gui/gui.h, gui/gui_breadboard.cc, ChangeLog, xpms/startp.xpm, xpms/pc.xpm, xpms/break.xpm, xpms/stopp.xpm, xpms/canbreak.xpm, cli/misc.h, cli/socket.cc, cli/ui_gpsim.h, cli/input.cc, cli/ui_gpsim.cc, plat/win32/icd.cc: fixed gcc warnings "warning: deprecated conversion from string constant to 'char*'" 2008-08-02 Rob Pearce * src/14bit-registers.cc, src/16bit-registers.cc : Fixed behaviour of PCLATH and PCL : - Setting PC from GUI no longer changes PCLATH on 16-bit cores - Setting PCLATH from GUI no longer changes PC * src/p18x.cc : Annotation - I think porta4 is defined wrong * src/pir.cc, src/pir.h, src/intcon.cc, src/intcon.h, src/16bit-processors.cc : Support for interrupt priority on 16-bit core peripherals * src/16bit-processors.cc : Fix TMR0 external inputs on 16-bit cores (T0CKI was not being connected) 2008-07-30 Borut Razem * regression/run_regression.sh: set GPSIM_MODULE_PATH=$(pwd)/../modules/.libs so that the correct libgpsim_modules.so is loaded during regression test execution on *nix platforms 2008-07-28 Borut Razem * cli/cmd_symbol.cc, gui/gui_breadboard.cc, modules/led.cc: enabled compilation on Fedora 9, gcc 4.3.0, fixed gcc error: must #include before using typeid 2008-06-26 Rob Pearce * src/uart.cc, regression/usart_test/eusart.asm : Added regression test for (and fixed) EUSART sync break operation. 2008-06-05 Scott Dattalo * src/os_dependent.cc: Now the library extension is appended to library names if the raw library name fails to load 2008-06-05 Scott Dattalo for Steffen Joeris * src/modules.h, src/operator.cc, src/processor.h, src/gpsim_object.cc * src/value.h, src/modules.cc, src/value.cc, src/processor.cc, modules/switch.cc * gui/gui_src.cc, gui/gui_symbols.cc, gui/gui_regwin.cc, gui/gui_stack.cc * gui/settings_exdbm.cc, cli/cmd_x.cc, cli/cmd_clear.cc Fixups for gcc-4.3 2008-06-22 Rob Pearce * src/uart.cc, src/uart.h, regression/usart_test/Makefile, regression/run_regression.sh, regression/usart_test/eusart.asm, regression/usart_test/18f2321.lkr: Added regression test for (and fixed) EUSART operation in BRG16 mode. 2008-06-08 Rob Pearce * src/uart.cc, src/uart.h, p18x.cc: Initial support for EUSART, as part of the existing usart class. Has been regression tested in legacy mode only. 2008-06-05 Scott Dattalo * src/value.h, src/value.cc, src/16bit-instructions.cc C++ cleanup - char * is now const char * in many places 2008-06-01 Rob Pearce * src/pic-processor.cc, src/pic-processor.h, p18x.cc, p18x.h: Initial attempt at providing support for the PIC18F4321. The same issues are present as per the 18F2321. * src/16bit-registers.cc, gui/gui_src_asm.cc: Bug fixes - "run to here" now updates the source browser PC indicator, and "set PC here" now works properly on 16bit processors * gui/gui_stopwatch.cc: No actual code change, but some comments regarding a suspicious looking sequence of operations. * src/16bit-processors.cc, src/16bit-processors.h, p18x.h: Fixed RAM sizes of 18F series processors 2008-05-31 Rob Pearce * src/pic-processor.h, src/16bit-processors.h, p18x.h, src/16bit-instructions.cc, src/pic-instructions.cc, src/14bit-registers.cc: Split out the _16BIT_PROCESSOR_ base type into _PIC17_PROCESSOR_ and _PIC18_PROCESSOR_ because nearly every place that tested it should have treated them differently. This led to some awkward switch cases where all PIC18 devices were listed in one block and all PIC17s in another (and which could easily be overlooked and cause pain when adding new devices). These are now simple and generic. * src/pic-processor.cc, src/pic-processor.h, p18x.cc, p18x.h: Initial attempt at providing support for the PIC18F2321. The USART is wrong (missing BAUDCON and SPBRGH), as is the ADC (ADCON2 missing, not enough channels) and the OSCTUNE register is missing. Also the RAM is too big. * src/16bit-registers.cc regression/instructions_16bit/instructions_16bit.asm Fixed a bug in the TBLPTR decrement on 256 byte boundaries, and added regression test for it. 2008-05-20 Rob Pearce * src/14bit-tmrs.cc: Fix TMR1 behaviour around CCP compare events, remove incorrect adcon interaction, enable CCP output drive * src/p16f62x.cc: Enable CCP onto the correct port pin * regression/ccp_628/* regression/run_regression.sh regression/Makefile.am: Add regression tests for these fixes, and others Changes are for bug 1967803 and to repair 679540, plus tests for 1811305, 1652549 2008-04-05 Scott Dattalo * src/gpsim_interface.h, src/interface.cc, cli/cmd_stopwatch.cc, cli/cmd_frequency.cc, cli/cmd_dump.cc, cli/cmd_list.cc, cli/command.cc, cli/cmd_step.cc, cli/command.h: The step and step over commands are now directed through the gpsim interface instead through the currently active processor. 2008-01-13 Borut Razem * plat/win32/gpsim.nsi: added StartMenu page * configure.ac: corrected URL 2008-01-10 Borut Razem * plat/win32/gpsim.nsi, plat/win32/makefile.migw: changed NSIS installation * doc/gpsimWin32.html: fixed typo 2007-12-23 Borut Razem * doc/gpsimWin32.html: fixed typo; jpeg and tiff dependencies * plat/win32/gpsim.nsi: added jpeg62.dll and libtiff3.dll * doc/gpsim_svn.html: corrected the URL of svn repository, thanks to Graeme Jury * doc/*.html: make WEB pages XHTML 1.0 Transitional copliant 2007-12-17 Roy Rankin * src/14bit-tmrs.h src/14bit-tmrs.cc: Add TMR1 external crystal simulation * regression/tmr1_16bit/tmr1_16bit.asm regression/tmr1_16bit/Makefile: - Add tests for external crystal and Fosc/4, lower frequency to speed up test time * regression/Makefile.am regression/run_regression.sh: - Run tmr1_16bit as part of regression tests * doc/gpsim.lyx: Add TMR1 external drive documentation 2007-12-09 Borut Razem * doc/gpsimWin32.html: NSIS v2.33, fontconfig-2.4.2-tml-20071015, gettext-runtime-0.17, glib-2.14.4, gtk+-2.12.3, pango-1.18.3 * doc/makefile.mingw: ignore errors * plat/gpsim.nsi: updated for gtk+-2.12.3 * plat/win32/gpsim.def: MSVC sync 2007-12-02 Roy Rankin * regression/wdt/18f452.lkr regression/wdt/16f88.lkr regression/wdt/16f628.lkr regression/wdt/16c64.lkr regression/wdt/wdt_16c64.asm regression/wdt/nwdt_18f452.asm regression/wdt/wdt_18f452.asm regression/wdt/nwdt_16f628.asm regression/wdt/nwdt_16f88.asm regression/wdt/wdt_16f88.asm regression/wdt/wdt_16f628.asm regression/wdt/Makefile regression/wdt/nwdt_16c64.asm regression/Makefile.am regression/run_regression.sh: - Add regression tests for Watchdog Time * regression/p16f84/reset.asm: Sleep continues on WDT expire * src/Makefile.am src/rcon.h src/16bit-registers.h: RCON moved to rcon.h * src/pic-processor.cc src/pic-processor.h src/16bit-processors.cc src/pic-registers.cc src/14bit-registers.h src/p16f8x.h src/p16f8x.cc: WDT and configuration fixes * src/processor.cc: Frequency change updates WDT * src/14bit-registers.cc: WDTCON functions added, Status register rcon support * src/16bit-instructions.cc: Implement Sleep instruction 2007-11-25 Roy Rankin * src/14bit-tmrs.cc: Fix TMR2 BUG message on reset 2007-11-09 Borut Razem * modules/usart.cc> fixed bug #1828634: SVN does not build with --disable-gui 2007-10-21 Roy Rankin * modules/switch.cc: Fix compiler warning * modules/led.cc: Fix core dump when no GUI 2007-10-21 Roy Rankin * doc/gpsim.lyx: Add LED doc, new switch state values * modules/switch.cc: State attribute given values open and closed * modules/led.cc, modules/led.h: Add color for simple LED * regression/switch_test/switch_test.asm: test new state values * examples/modules/led_test/led_mod.stc: Add position, simple green LED 2007-10-20 Scott Dattalo * src/pic-processor.cc: Fixed the 'Step-Over' bug that was preventing the gui from updating properly. * regression/rt.sh: Added an echo print that will display which regression test is currently running. This is commented out for now... 2007-10-18 Scott Dattalo * src/16bit-processors.cc: Fixed a printf format specifier bug. 2007-10-18 Scott Dattalo * gui/gui_src.h, gui/gui_src_asm.cc: Removed #if 0'd code. Made the dependency on the "new" source browser permanent. 2007-10-17 Borut Razem * configure.ac: added -Wall gcc command line option to CFLAGS and CXXFLAGS 2007-10-16 Borut Razem * src/value.cc, src/trace.cc, modules/stimuli.cc, gui/gui_trace.cc, gui/gui_profile.cc, gui/gui_menu.cc, gui/gui_scope.cc, configure.ac, config_win32.h.in: introduced PRINTF_GINT64_MODIFIER which defines the printf modifier for gint64 and guint64 types 2007-10-14 Borut Razem * src/p16x6x.h, src/p16x6x.cc, src/eeprom.cc, src/pic-processor.cc, src/p16f62x.cc, src/12bit-processors.cc, src/pic-processor.h, src/p12x.cc, src/14bit-processors.cc: fixed duplicatd sfr deletion, code cleaning * plat/win32/libgpsim.def: MSVC sync * src/icd.cc, src/bitlog.cc, gui/gui_object.cc, eXdbm/eXdbm.c, cli/cmd_help.cc: fixed trivial gcc 4.1.2 warnings 2007-10-14 Roy Rankin * src/value.cc: Allow Float::set to take Value type Integer * src/modules.h src/modules.cc gui/gui_breadboard.cc: - reinstate operation of breadboard "Add library", "Add module" and "Save Configuration" buttons and module attributes. 2007-10-13 Borut Razem * src/gpsim_interface.h, src/ioports.h, src/gpsim_object.h, src/dspic/dspic-instructions.h, src/ui.h, src/processor.h, src/pir.h, src/trace.h, src/program_files.h, src/pic-processor.h, src/registers.h, src/stimuli.h, modules/i2c.h, modules/led.h, gui/gui_symbols.cc, gui/gui_src.h, gui/gui_regwin.cc, gui/gui_menu.cc, gui/gui_scope.cc, gui/gui.h, cli/socket.cc: fixed virtual functions but non-virtual destructor warnings * src/modules.h, src/p16x6x.cc, src/pic-processor.cc, src/p16f62x.cc, src/12bit-processors.cc, src/pic-processor.h, src/p12x.cc, src/modules.cc src/processor.cc, src/14bit-processors.cc, src/pic-instructions.cc, src/pic-processor.cc: fixed gcc warning: dereferencing type-punned pointer will break strict-aliasing rules 2007-10-13 Roy Rankin * src/i2c-ee.h src/i2c-ee.cc modules/i2c-eeprom.h modules/i2c-eeprom.cc cli/cmd_dump.cc cli/cmd_load.cc: Fix eeprom address symbols 2007-10-10 Scott Dattalo * modules/i2c-eeprom.cc, cli/cmd_dump.cc, src/pic-processor.cc, src/symbol.cc, src/i2c-ee.cc: Fixed errors that Borut uncovered during the clean up process. 2007-10-09 Borut Razem * src/symbol.cc: fixed the fixed warnig ;-) 2007-10-07 Borut Razem * cli/cmd_attach.cc, cli/cmd_dump.cc, cli/cmd_dump.h, gui/gui_breadboard.cc, gui/gui_scope.cc, gui/gui_scope.h, gui/gui_src_asm.cc, gui/gui_stack.cc, gui/gui_watch.cc, modules/i2c.h, modules/stimuli.cc, modules/stimuli.h, src/14bit-registers.cc, src/14bit-tmrs.cc, src/16bit-processors.cc, src/bitlog.cc, src/eeprom.cc, src/hexutils.cc, src/hexutils.h, src/modules.cc, src/p16f8x.cc, src/packages.cc, src/pic-ioports.cc, src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h, src/registers.cc, src/stimuli.cc, src/symbol.cc, src/trace.cc: fixed trivial gcc warnings * doc/gpsimWin32.html: generic readline 2007-10-6 Scott Dattalo * regression/switch_test/switch_test.asm, regression/instructions_14bit/branching.asm: - WDT was timing out. * src/pic-processor.cc, src/pic-processor.h: - Added 12f508, 12f509, and 12f510 - Fixed I/O reset bug - WDT is now placed in the processor's symbol table. * src/p12x.cc, src/p12x.h: - Added 12f508, 12f509, and 12f510 (although the '510's comparator and A2D are not supported.) * cli/cmd_symbol.cc: - Module symbol tables can now be displayed independently of the global symbol table * cli/parse.yy: - The parser was quiting gpsim if the dump eeprom command failed. 2007-09-30 Borut Razem * doc/gpsimWin32.html: glib-2.14.1, atk-1.20.0, pango-1.18.2, cairo-1.4.10, NSIS v2.31 * plat/win32/gpsim.nsi: updated * plat/win32/libgpsim.def: MSVC sync 2007-09-17 Roy Rankin * cli/cmd_symbol.cc: symbols dumped as module.symbol with better format, don't dump line number symbols. * gui/gui_symbols.cc: symbols dumped as module.symbol. * src/registers.cc: Add module name in response to query array value. * src/i2c-ee.h, src/i2c-ee.cc, modules/i2c-eeprom.cc: Add RegisterCollection to allow command line viewing & change of EEPROM cells. * doc/gpsim.lyx:Document new EEPROM functionality, improve scope window documentation. 2007-09-16 Roy Rankin * cli/cmd_break.cc: unless verbose set, do not output assert messages when loading them to avoid user concusion and masking of error messages. * regression/rt.sh: simplified due to above change. 2007-09-13 Roy Rankin * src/hexutils.cc src/hexutils.h: read/write Intel hex files from/to register arrays. File format not dependant on endian of processor. * src/i2c-ee.h src/i2c-ee.cc src/eeprom.cc src/eeprom.h: EEPROM given register size. * modules/i2c-eeprom.h modules/i2c-eeprom.cc: .eeprom symbol added so dump/load can converse with module * cli/cmd_load.h cli/cmd_load.cc cli/cmd_dump.h cli/cmd_dump.cc cli/parse.yy: add EEPROM dump/load commands. * doc/gpsim.lyx: spelling corrections, document new load and dump commands, improve EEPROM documentation. * regression/i2c/p16f876a.asm: Add tests for EEPROM dump/load. 2007-09-02 Borut Razem * plat/win32/libgpsim.def: MSVC sync * src/attributes.cc, src/gpsim_time.cc, src/gpsim_time.h: create stop_watch object dynamically to overcome the static object creation sequence dependency on the C++ compiler implementation * src/16bit-instructions.cc, src/pic-instructions.cc, src/pic-instructions.h, src/pic-instructions.h, src/processor.cc, src/processor.h, src/dspic/sdpic-instructions.cc: each processor owns its own 'bad_instruction' object * src/symbol.cc, src/symbol.h: code cleaning * doc/snap_header.html: corrected ChangeLog link 2007-08-28 Roy Rankin * gui/gui_breadboard.cc: module settings fix for new symbol table * gli/cmd_dump.cc: fix detection of invalid registers in register dump 2007-08-26 Roy Rankin * gui/gui_symbols.cc: fix memory leak, re-enable filtering * gui/gui_breadboard.h gui/gui_breadboard.cc: breadboard need not be + running on start of gpsim to work * regression/resistor/resistor.asm: position resistors 2007-08-21 Roy Rankin * modules/usart.cc modules/switch.cc modules/paraface.cc * modules/led.cc modules/i2c-eeprom.h modules/video.cc * modules/resistor.cc modules/push_button.h modules/stimuli.cc * modules/logic.cc modules/logic.h modules/i2c-eeprom.cc * modules/paraface.h modules/led.h modules/video.h * modules/push_button.cc modules/resistor.h modules/encoder.cc * modules/encoder.h modules/stimuli.h gui/gui_breadboard.h * gui/gui_breadboard.cc: fix extra xpos, ypos in symbol table, + fix issues in deleting modules including core dumps 2007-08-09 Roy Rankin * src/p12x.cc: Fix eeprom regression introduced by last change 2007-07-29 Scott Dattalo * cli/cmd_break.cc: Fixed bug in expression parsing of assertions. * cli/parse.yy, src/value.h, src/value.cc: playing with a 'call' command. * src/symbol.cc: Symbol type is now shown in a symbol dump. * src/stimuli.cc, src/stimuli.h: Added 'analog sinks'. These are like digital sinks except they have the added capability of directing a signal to more than one object. * src/pic-processor.cc, src/pic-processor.h: Added the 10F202 and 10F204 * src/tmr0.cc: Fixed bug in computing current TMR0 value. * src/12bit-processors.cc: - option register wasn't accessible from command line - Config word wasn't handled properly. * src/p12x.cc, src/p12x.h - Added P12bitBase, this made it somewhat easier to add the 10F series. - Added the 10F200, 10F202, 10F204 and 10F206 (only '204 was tested) - Added comparator support for the 10F204 and 10F206 * regression/comparator/compar_10f204.asm, regression/comparator/10f204.lkr, regression/comparator/Makefile, regression/run_regression.sh: - Added a regression test for the 10F204. 2007-07-22 Rob Pearce * modules/usart.cc modules/usart.h doc/gpsim.lyx: Added a "hex" attribute to the usart module to force the display to show all bytes as hex, for use with pure binary data simulations. 2007-07-15 Roy Rankin * src/pic-processor.cc src/pic-processor.h src/p16f8x.h src/p16f8x.cc regression/ccp/16f819.lkr regression/ccp/ccp_819.asm regression/ccp/Makefile regression/a2d/16f819.lkr regression/a2d/p16f819.asm regression/a2d/Makefile regression/run_regression.sh regression/Makefile.am regression/i2c/16f819.lkr regression/i2c/Makefile regression/i2c/p16f819.asm: - Add P16f818 and P16f819 processors 2007-07-10 Roy Rankin * src/a2dconverter.cc: add comments for setup functions 2007-04-14 Borut Razem * plat/win32/libgpsim.def, plat/win32/Install.vcproj: MSVC sync * cli/cmd_module.cc, gui/gui_stack.c, src/modules.cc, src/modules.h, src/packages.cc, src/registers.cc, src/sim_context.cc, src/symbol.cc, src/symbol.h: fixes to make gpsim compile on MSVC, but it still doesn't run due to object construction / destruction sequence problems... 2007-03-27 Scott Dattalo * cli/cmd_break.cc, src/gpsim_object.h, src/breakpoints.h, src/registers.cc, src/registers.h, src/breakpoints.cc, gui/gui_regwin.cc - Added break on register change feature. From the command line: gpsim> break ch myvar This sets a breakpoint on the register 'myvar' and will halt execution whenever a write to this register changes the contents of myvar. - Added another menu item to the register window menu to support the break on change breakpoint. 2007-03-25 Martin Habets * src/p18x.cc: - Added I2C support to pic18f2455. - Fixed pin 18 on the pic18f2455. 2007-03-20 Martin Habets * src/16bit-instructions.cc, src/p18x.cc, src/p18x.h, src/pic-instructions.cc, src/pic-processor.cc, pic-processor.h: Added support for the p18f2455. 2007-03-20 Scott Dattalo * src/16bit-processors.cc, src/intcon.cc, src/pic-ioports.h, src/intcon.h, src/pic-ioports.cc, src/14bit-processors.cc: - PortB now writes intcon bits via a ptr to an intcon register. Previously, PortB obtained the intcon pointer from the Processor class 2007-03-15 Borut Razem * src/symbol.h: added #include "exports.h" to make it compile on WIN32 * plat/win32/gpsim.nsi: added extras\graphic_lcd\examples\sed1520\* and extras\graphic_lcd\examples\ssd0323\* to the package 2007-03-14 Scott Dattalo * src/dspic/dspic-registers.cc: There was no implementation defined for the Status register constructor. 2007-03-14 Scott Dattalo * src/16bit-processors.cc, src/intcon.cc, src/pic-ioports.h, src/intcon.h, src/pic-ioports.cc, src/registers.h, src/16bit-processors.h: - Added the concept of a 'bit sink' to the SFR registers. This allows arbitrary clients to associate themselves with arbitrary bits in an SFR. More work needs to be done, but this is used at the moment to control port B pull up resistors on the 16-bit core. 2007-03-07 Scott Dattalo * src/pic-processor.cc, src/trace.cc: Moved the ResetTraceObject from pic-processor.cc to trace.cc (yesterday's comment on this was not completely true!) * src/stimuli.cc: Resolved an ambiguity with pullup resistors on I/O pins. 2007-03-06 Scott Dattalo * src/pic-processor.cc, src/trace.cc, src/trace.h: Moved the ResetTraceObject from pic-processor.cc to trace.cc * src/value.cc: Value objects now remove themselves from the symbol table when they're destructed. * src/symbol.cc, src/stimuli.cc, src/packages.cc, src/modules.cc, src/cod.cc, src/breakpoints.cc, src/attributes.cc, modules/stimuli.cc, modules/stimuli.h, gui/gui_breadboard.cc, cli/cmd_attach.cc: - printf debug clean up. 2007-03-05 Scott Dattalo * src/ssp.cc: Removed some printf debug code. 2007-02-25 Scott Dattalo * src/modules.h, src/symbol.cc, src/modules.cc, cli/cmd_module.cc: The 'module' and 'module list' commands work again. 2007-02-25 Scott Dattalo * src/16bit-processor.cc: Bug in config memory construction was causing segv. Also, added more descriptions to the 16bit processor config words. 2007-02-22 Scott Dattalo * gpsim/main.cc, regression/instructions_14bit/branching.asm, src/p16x6x.h, src/pic-instructions.h, src/ioports.h, src/comparator.h, src/p16x6x.cc, src/p16f87x.cc, src/p16f87x.h, src/16bit-processors.cc, src/14bit-tmrs.h, src/pic-instructions.cc, src/dspic/dspic-registers.cc, src/processor.h, src/stimuli.cc, src/eeprom.cc, src/pic-processor.cc, src/pir.cc, src/registers.cc, src/uart.cc, src/p16f62x.cc, src/uart.h, src/p16x7x.h, src/tmr0.cc, src/pir.h, src/ssp.cc, src/tmr0.h, src/ioports.cc, src/psp.cc, src/14bit-tmrs.cc, src/comparator.cc, src/p16x7x.cc, src/12bit-processors.cc, src/p12x.cc, src/pic-processor.h, src/sim_context.cc, src/p16f8x.h, src/value.cc, src/processor.cc, src/eeprom.h, src/p16f8x.cc, src/pic-ioports.cc, src/registers.h, src/pic-registers.cc, src/breakpoints.cc, src/14bit-processors.cc, src/stimuli.h, gui/gui_scope.cc: - Memory leak fixes. - The 12C50x and the 16f62x devices leak no memory. 2007-02-18 Scott Dattalo * gui/gui_breadboard.cc, src/modules.cc, src/modules.h: The Module libraries are now implemented as STL maps. * src/symbol.h, src/symbol.cc: The symbol table now supports a 'deleteSymbol' method. This method removes a symbol from the symbol table and frees up the memory belonging to it. * gpsim/main.cc, regression/logic_test/logic_test.asm, src/16bit-registers.h, src/init.cc, src/trigger.cc, src/expr.cc, src/p16x6x.cc, src/p16x8x.cc, src/packages.h, src/breakpoints.h, src/16bit-processors.cc, src/14bit-registers.h, src/gpsim_time.h, src/pic-instructions.cc, src/dspic/dspic-registers.cc, src/p16f62x.h, src/processor.h, src/stimuli.cc, src/eeprom.cc, src/pic-processor.cc, src/registers.cc, src/p16f62x.cc, src/gpsim_time.cc, src/packages.cc, src/attributes.h, src/sim_context.h, src/icd.cc, src/12bit-processors.cc, src/p12x.cc, src/pic-processor.h, src/sim_context.cc, src/value.cc, src/processor.cc, src/14bit-registers.cc, src/16bit-registers.cc, src/p16f8x.cc, src/registers.h, src/pic-registers.cc, src/breakpoints.cc, src/14bit-processors.cc, src/attributes.cc, src/16bit-processors.h, cli/parse.yy, cli/cmd_break.cc, cli/cmd_module.cc, cli/input.cc: - Memory leak fixes. 2007-02-12 Scott Dattalo * src/symbol.cc: Deleted #if 0'd code.(the old symbol table implementation) 2007-02-11 Scott Dattalo * gpsim/main.cc, gpsim/Makefile.am, regression/register_stim/register_stim.stc, regression/logic_test/logic_test.asm, regression/p18f452_ports/18f452.lkr, src/16bit-registers.h, src/fopen-path.cc, src/trigger.cc, src/trigger.h, src/12bit-hexdecode.cc, src/symbol.h, src/14bit-hexdecode.cc, src/16bit-hexdecode.cc, src/p16x6x.h, src/expr.cc, src/pic-instructions.h, src/ioports.h, src/i2c-ee.h, src/gpsim_object.h, src/comparator.h, src/modules.h, src/p16x6x.cc, src/p17c75x.cc, src/p16x8x.cc, src/pie.h, src/packages.h, src/p16f87x.cc, src/breakpoints.h, src/p16f87x.h, src/16bit-processors.cc, src/14bit-instructions.cc, src/intcon.cc, src/14bit-registers.h, src/operator.cc, src/i2c-ee.cc, src/symbol.cc, src/ssp.h, src/14bit-tmrs.h, src/pic-ioports.h, src/ValueCollections.cc, src/pic-instructions.cc, src/dspic/dspic-processors.cc, src/dspic/dspic-instructions.cc, src/dspic/dspic-processors.h, src/dspic/dspic-registers.cc, src/dspic/dspic-registers.h, src/p16f62x.h, src/processor.h, src/pic-registers.h, src/stimuli.cc, src/eeprom.cc, src/pic-processor.cc, src/pir.cc, src/intcon.h, src/gpsim_object.cc, src/xref.h, src/registers.cc, src/uart.cc, src/p16f62x.cc, src/uart.h, src/pie.cc, src/p16x7x.h, src/tmr0.cc, src/12bit-instructions.h, src/Makefile.am, src/16bit-instructions.h, src/pir.h, src/gpsim_time.cc, src/a2dconverter.h, src/trace.h, src/pm_rd.cc, src/xref.cc, src/ssp.cc, src/ui.cc, src/packages.cc, src/tmr0.h, src/sim_context.h, src/icd.cc, src/ioports.cc, src/14bit-tmrs.cc, src/comparator.cc, src/p16x5x.cc, src/p16x7x.cc, src/value.h, src/expr.h, src/12bit-processors.cc, src/p12x.cc, src/pic-processor.h, src/sim_context.cc, src/p16f8x.h, src/p18x.cc, src/pm_rd.h, src/modules.cc, src/value.cc, src/processor.cc, src/14bit-registers.cc, src/eeprom.h, src/16bit-registers.cc, src/p12x.h, src/p16f8x.cc, src/trace.cc, src/a2dconverter.cc, src/cod.cc, src/pic-ioports.cc, src/registers.h, src/pic-registers.cc, src/breakpoints.cc, src/12bit-processors.h, src/14bit-processors.cc, src/14bit-processors.h, src/attributes.cc, src/16bit-processors.h, src/14bit-instructions.h, src/16bit-instructions.cc, src/stimuli.h, configure.ac, extras/graphic_lcd/src/glcd_100X32_sed1520.cc, extras/lcd/hd44780.cc, extras/lcd/lcd.cc, modules/usart.cc, modules/switch.cc, modules/led.cc, modules/resistor.cc, modules/i2c.cc, modules/stimuli.cc, modules/logic.cc, modules/i2c-eeprom.cc, modules/ttl.cc, modules/encoder.cc, gui/gui_src.cc, gui/gui_breadboard.h, gui/gui_symbols.cc, gui/gui_regwin.cc, gui/gui_watch.h, gui/gui_src_asm.cc, gui/gui_stack.cc, gui/gui_watch.cc, gui/gui_scope.cc, gui/gui_breadboard.cc, cli/cmd_load.h, cli/scan.ll, cli/cmd_symbol.cc, cli/socket.cc, cli/cmd_help.cc, cli/cmd_bus.cc, cli/cmd_help.h, cli/parse.yy, cli/cmd_attach.cc, cli/cmd_attach.h, cli/cmd_x.cc, cli/cmd_break.cc, cli/cmd_node.cc, cli/cmd_break.h, cli/cmd_stimulus.h, cli/cmd_run.cc, cli/input.cc, cli/cmd_load.cc, cli/cmd_log.cc, cli/cmd_stimulus.cc, cli/cmd_symbol.h: - Rewrote the symbol table. * src/stimulus_orb.h, src/symbol_orb.h: Removed 2007-01-27 Borut Razem * doc/gpsimWin32, plat/win32/libgpsim.def: MSVC sync * extras/lcd/lcd.h: synced with Scott's changes 2007-01-20 Scott Dattalo * src/pic-processor.cc, src/trace.h, src/p16x5x.cc, src/12bit-processors.cc, src/p12x.cc, src/pic-processor.h, src/processor.cc, src/14bit-registers.cc, src/trace.cc, src/trigger.cc, src/intcon.cc: - Added a Trace Type for Resets and Interrupts. - Removed some deprecated trace types (e.g. TRIS and Option). - Single stepping uses the clock phase code. * regression/rt.sh: Removed outdated comment. * cli/cmd_trace.cc: added an 'info' option to the trace command. This is for displaying information about allocated trace types. It is used primarily for debugging. 2007-01-20 Scott Dattalo * gui/gui_menu.cc: Bug [1631921]. Preferences dialog box was grabbing the gtk focus and preventing child dialog boxes from having focus. 2007-01-17 Scott Dattalo * src/expr.cc: Bug [1638250]. ramData[] references in expressions were evaluating to the index of the ramData and not to the ramData contents. 2007-01-14 Scott Dattalo * cli/cmd_stopwatch.cc, cli/cmd_quit.cc, cli/scan.ll, cli/cmd_symbol.cc, cli/cmd_shell.cc, cli/cmd_version.cc, cli/cmd_help.cc, cli/cmd_bus.cc, cli/cmd_set.cc, cli/cmd_frequency.cc, cli/cmd_attach.cc, cli/cmd_dump.cc, cli/cmd_x.cc, cli/cmd_list.cc, cli/cmd_echo.cc, cli/cmd_processor.cc, cli/cmd_disasm.cc, cli/cmd_reset.cc, cli/cmd_break.cc, cli/cmd_node.cc, cli/cmd_module.cc, cli/cmd_clear.cc, cli/command.cc, cli/cmd_trace.cc, cli/cmd_icd.cc, cli/cmd_run.cc, cli/cmd_step.cc, cli/input.cc, cli/cmd_load.cc, cli/cmd_log.cc, cli/cmd_stimulus.cc, cli/command.h, cli/cmd_macro.cc: - gcc-4.2 doesn't like const char * types being assigned to char * 2007-01-14 Scott Dattalo * regression/register_stim/Makefile: Regression test wasn't running. 2007-01-14 Borut Razem * plat/win32/libgpsim.def: MSVC sync * doc/gpsimWin32, plat/win32/gpsim.nsi: added svn Author stamp glib-2.12.7, gtk+-2.10.7, pango-1.14.9, NSIS v2.23 2007-01-13 Scott Dattalo * regression/p16f84/p16f84.stc: removed. The configuration file is now part of p16f84.asm * regression/p16f84/reset.asm: added. Tests resets and sleep. * regression/p16f509/reset.asm: cosmetic changes. * regression/ccp/ccp_877a.asm: made some local variables global so that I could more easily debug the clock phase changes. * regression/txisr_test/txisr_test.asm: Now captures unexpected resets. * regression/instructions_14bit/Makefile: Added branching.asm regression test * regression/instructions_14bit/branching.asm: Added. tests branching instructions. This was mainly created to debug the clock phase code for interrupts interrupting 2-cycle instructions. * regression/run_regression.sh: Added branching and reset regression tests. * src/14bit-instructions.cc: Cosmetic... * src/intcon.cc: Now interrupts are signified by calling cpu_pic->BP_set_interrupt() is called instead of bp.set_interrupt(). The purpose is to (eventually) separate interrupts from breakpoints. * src/clock_phase.h, src/clock_phase.cc: Added class 'phaseCaptureInterrupt'. As its name implies, this is part of the clock phase stuff and it's designed to handle interrupts. * src/pic-processor.cc: - Sleep is now handled by the clock phase code. - Interrupts are now handled by the clock phase code. - The run() method now only looks at the global break point flag. (Before, the sleep and interrupt states were handled with breakpoint flags.) - Added an 'ActivityState' to reflect what the processor is currently doing. This is primarily used by the 12-bit core to determine if the processor is sleeping. * src/14bit-registers.cc: cosmetic. Added debug code. * src/pic-ioports.cc: Port B wakeup on change feature was not working. * src/pic-registers.cc: Numerous clock phase related changes. Now interrupts are properly handled. Also, there was a nasty design error that prevent proper handling of interrupts during the middle of call or return statements. 2007-01-11 Borut Razem * plat/win32/make.mingw: added -Wno-format to prevent mingw build warnings: warning: unknown conversion type character `I' in format warning: int format, different type arg (arg X) warning: `I' flag used with `%x' printf format * acinclude.m4: check for the presence of the readline library. This version works also in cross-compilation environment. * plat/win32/libgpsim.def: MSVC sync 2007-01-10 Scott Dattalo * src/symbol.cc, src/symbol.h, src/stimuli.cc, src/stimuli.h: - stimulus and node symbols can now be added to the symbol table with the 'Clearable' flag turned off. * src/p16x6x.cc, src/p17c75x.cc, src/p16x8x.cc, src/p16f87x.cc, src/p16f62x.cc, src/p16x5x.cc, src/p12x.cc, src/p18x.cc, src/modules.cc, src/p16f8x.cc: - All processors were individually adding a module symbol to the symbol table. Now this is done in one place down in the Module class constructor. - The symbol table is now no longer automatically cleared whenever a processor is loaded. Previously, if you loaded a module (e.g. the usart) and then load the processor, the module's clearable symbols would be removed! There's still some work that needs to be done here. However, to do things correctly will take some time... 2007-01-08 Scott Dattalo * regression/make.regression: - Added a rule to run a regression test interactively. Suppose you have a file named 'mytest.asm'. Then the rule 'mytest.-' can be invoke like this: $ make mytest.- * regression/p16f84/p16f84.asm, regression/p16f84/Makefile: Placed the configuration script into the .asm file. * src/p16x8x.cc, src/p16x8x.h: - Added the MCLR pin to the '83 and the '84 * src/pic-instructions.cc - clock phase change - the SLEEP instruction no longer sets a breakpoint * src/pic-processor.cc, src/pic-processor.h: - Added an exit_sleep method. - Removed the external reset controls added in previous commit - Removed the WDT 'start_sleep' method. It was not being called. * src/p12x.cc: - Use the already existing config_modes structure to record whether the MCLR pin is enabled or not. * src/pic-ioports.cc: - RBIF changes now cause the processor to exit sleep. * src/14bit-processors.cc, src/14bit-processors.h: - Added MCLR support for the mid range processors. - Cleaned up config word management. 2007-01-05 Borut Razem * plat/win32/libgpsim.def: MSVC sync 2007-01-04 Scott Dattalo * port_stim/Makefile, tmr0_16bit/Makefile, spi/Makefile, logic_test/Makefile, make.regression, wavegen/Makefile, rt.sh, p12c509/Makefile, ttl/Makefile, ccp/Makefile, comparator/Makefile, txisr_test/Makefile, digital_stim/Makefile, resistor/Makefile, breakpoints/Makefile, interrupts_14bit/Makefile, node_test/Makefile, p16f84/Makefile, usart_test/Makefile, analog_stim/Makefile, eeprom_wide/Makefile, switch_test/Makefile, p18f452_ports/Makefile, macro_test/Makefile, psp/Makefile, instructions_12bit/Makefile, a2d/Makefile, instructions_14bit/Makefile, p12ce518/Makefile, instructions_16bit/Makefile, run_regression.sh, i2c/Makefile, p18f/Makefile: - Added make clean option to 'run_regression.sh' - Cleaned up the make rules * p18f/startup.stc: removed * regression/startup.stc: added 2007-01-02 Scott Dattalo * src/16bit-processors.cc, src/16bit-processors.h, src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h, src/12bit-processors.cc, src/12bit-processors.h, src/14bit-processors.cc, src/14bit-processors.h: - removed 'por()' method from Processor class * src/processor.h, src/processor.cc - removed 'por()' method from Processor class. - removed unused set() and get() methods - RegisterMemoryAccess now has a reset() method. * src/14bit-registers.h, src/14bit-registers.cc - The Status_register now has a 'reset()' method. * src/pic-processor.h, src/pic-processor.cc: - Added a 'phaseIdle' to handle idle processor states. (like when reset is being held low). - added support for MCLRE - ::reset() now handles MCLR resets - WDT handles MCLR resets * src/p12x.h, src/p12x.cc: - Added support for MCLRE. Now, when GPIO3 is held low on the 12c50x processors, the CPU is held in reset. * src/clock_phase.cc, src/clock_phase.h: - Added phaseIdle class. * src/pic-registers.cc: - The program counter class now handles resets. * src/16bit-instructions.cc: removed a comment. * src/gpsim_classes.h: - Added an 'EXIT_RESET' type to the RESET_TYPE enumeration. - Removed 'PROCESSOR_STATES' enumeration. * regression/p12c509/tmr0.asm: MCLR resets are now working. 2006-12-31 Scott Dattalo * src/os_dependent.cc: Applied patch [1625380] from Jean-Etienne Lamiaud that fixes dynamic module loading on OS X. 2006-12-27 Scott Dattalo * src/Makefile.am, modules/Makefile.am, eXdbm/Makefile.am, cli/Makefile.am, Makefile.am: Applied patch from Vitaly Lipatov that fixes the linking order. patch [1621792] 2006-12-27 Scott Dattalo * src/uart.cc: applied patch from Jean-Etienne Lamiaud that supports uart framing and overflow errors. patch [1621771] 2006-12-27 Scott Dattalo * regression/analog_stim/p18f452.asm, regression/analog_stim/18f452.lkr, regression/analog_stim/Makefile, regression/run_regression.sh: - Added a regression test for analog stimuli. * cli/cmd_stimulus.cc: the 'analog' modifier for asynchronous stimuli was being ignored. Bug [1621698] 2006-12-23 Borut Razem * plat/win32/libgpsim.def: MSVC sync * modules/i2c.cc, modules/i2c.h, modules/makefile.mingw, modules/vcproj: added i2c.cc, i2c.h to the project, removed warnings * doc/gpsimWin32, plat/win32/gpsim.nsi : atk-1.12.3, glib-2.12.6, gtk+-2.10.6, pango-1.14.8, NSIS v2.22 2006-12-22 Scott Dattalo * src/p16x6x.cc, src/16bit-processors.cc, src/14bit-registers.h, src/pic-ioports.h, src/pic-instructions.cc, src/pic-registers.h, src/pic-processor.cc, src/tmr0.cc, src/tmr0.h, src/p16x5x.cc, src/12bit-processors.cc, src/p12x.cc, src/pic-processor.h, src/p18x.cc, src/14bit-registers.cc, src/16bit-registers.cc, src/pic-ioports.cc, src/pic-registers.cc, src/12bit-processors.h, src/14bit-processors.cc, src/14bit-processors.h: - Option register is no longer a member of the pic_processor base class. The 12-bit and 14-bit separately declare an option register member and dynamically construct it. - Moved OPTION_REG from 14bit-registers to pic-registers - TMR0 now has a pointer to the option register (as opposed to directly referencing the option register in the cpu class). - TMR0 for 16-bit cores was using the option register instead of the T0CON during initialization - The TRIS register resets to all 1's for the 12-bit and 14-bit cores during WDT resets. However, it remains unchanged for the 16-bit cores. A flag was added to the PicTrisRegister base class to describe what action should be taken during WDT resets 2006-12-22 Scott Dattalo * regression/12c509/tmr0.asm: (This file is going to change names!). Testing various reset modes. 2006-12-22 Scott Dattalo * modules/stimuli.h, modules/stimuli.cc: Added an 'initial' attribute to the pulsegen module that allows the initial pin voltage to be specified. 2006-12-20 Scott Dattalo * cli/cmd_load.cc: Fixed missing end-of-line string continuation 2006-12-20 Scott Dattalo * gpsim/main.cc: added a -I option to the gpsim invocation. This is identical to the '-c' option except that it will not change the current working directory. The '-c' option automatically changes directories to where ever the included script resides. * src/input.cc, src/cmd_load.cc: now scripts residing in other directories can be loaded in such a way as to not cause a directory change. From gpsim's command line, the 'load' command now supports a 'i' option. 2006-12-20 Scott Dattalo * src/12bit-processors.cc, src/p12x.cc, src/p12x.h: Config word stuff was broken. * regression/p12c509/tmr0.asm: Converted into relative mode code. * regression/p12c509/Makefile, regression/p12c509/12c509.lkr: Added. This is in preparation for testing SLEEP and WDT for the 12bit cores. 2006-12-19 Scott Dattalo * modules/i2c.h, modules/i2c.cc, modules/Makefile.am: Added an i2c master module. Currently can only be driven with attributes. 2006-12-18 Scott Dattalo * src/pic-ioports.cc, src/p16f8x.cc, src/ioports.cc, src/pic-ioports.h: 2006-12-14 Scott Dattalo * src/trace.cc: command line tracing now 1) only display the last instruction traced after a step (instead of the last 2 instructions) and 2) the source line for the instruction. 2006-12-14 Scott Dattalo * src/ioports.h, src/ioports.cc: Added an 'updatePins()' method to the PortModule class. This provides a way of updating just a subset of the port pins. 2006-12-01 Borut Razem * modules/stimuli.cc: access trace object indirectly by using get_trace() * plat/win32/libgpsim.def: MSVC sync 2006-11-27 Scott Dattalo * src/pic-ioports.h, src/ioports.cc, src/pic-ioports.cc: - Improved class member initialization. Specifically, the pin enable mask was not getting set properly. * modules/gpsim_modules.cc, modules/stimuli.cc, modules/stimuli.h: - Added 16-bit and 32-bit versions of the parallel port stimulus - Added a 'pullup' register to the port stimulus. - Changed the parallel port stimulus I/O pins to IO_bi_directional_pu * regression/port_stim/port_stim.asm - The parallel port stimulus regression test now tests the module's pullup resistors. 2006-11-22 Scott Dattalo * src/interface.cc: start_simulation() is now incorporating functionality previously implemented in Processor::run(). * gui/gui_src.cc, gui/gui_src_asm.cc, gui/gui_menu.cc: The gui now starts a simulation by calling gpsim_interface::start_simulation() instead of active_cpu->run() * src/pic-processor.cc, src/clock_phase.cc, src/clock_phase.h, src/pic-registers.cc: The ClockPhase::setNextPhase() method is no longer virtual. 2006-11-21 Scott Dattalo * regression/TODO: Added. 2006-11-21 Scott Dattalo * src/ValueCollections.h, src/ValueCollections.cc: Added a new constructor for IIndexedCollection objects that allow for named Value object collections. 2006-11-20 Scott Dattalo * src/ValueCollections.h: SetAt method in the IndexedCollection template was using a '<=' where a '>=' should have been used instead. 2006-11-19 Scott Dattalo * src/clock_phase.cc, src/clock_phase.h, src/16bit-processors.cc, src/pic-processor.cc, src/processor.cc, src/pic-registers.cc: - Added support for interrupt phases in the new external clock feature. More work is still needed and still, //#define CLOCK_EXPERIMENTS Is commented out. - So this new code is inhibited by default. 2006-11-17 Borut Razem * src/makefile.mingw, src/src.vcproj: MSVC sync 2006-11-17 Scott Dattalo * src/clock_phase.h, src/clock_phase.cc: Added. Defines the ClockPhase class, which is a base class for supporting external processor clocks. Note, this could is currently experimental and is inhibited. To enable it, uncomment the line //#define CLOCK_EXPERIMENTS in clock_phase.h * src/pic-instructions.cc, src/pic-processor.cc, src/Makefile.am, src/processor.cc, src/16bit-registers.cc, src/pic-registers.cc, src/16bit-instructions.cc: - Support for external processor clocks. This is partially implemented and currently inhibited. 2006-11-16 Scott Dattalo * src/pic-instructions.cc, src/pic-instructions.h: .lst line numbers were not getting set properly for instructions containing assertions. 2006-11-15 Scott Dattalo * src/breakpoints.cc: post assertions are now displayed as such when they're triggered. Still need to have the breakpoint messages to display the postAssertion modifer. * src/value.cc: Added a diagnostic message. 2006-11-14 Scott Dattalo * cli/parse.yy, cli/cmd_break.cc, cli/cmd_break.h, src/gpsim_time.cc: 2006-01-02 I disabled the ability to set attribute breakpoints. That feature.has now been re-enabled. * regression/breakpoints/breakpoints.asm: Added a regression test for the stopwatch attribute breakpoint 2006-11-13 Scott Dattalo * gui/gui_trace.cc, gui/gui_profile.cc, gui/gui_menu.cc, gui/gui_scope.cc, gui/gui_stopwatch.cc, cli/socket.cc, modules/usart.cc, src/stimuli.cc, src/eeprom.cc, src/pic-processor.cc, src/uart.cc, src/tmr0.cc, src/gpsim_time.cc, src/pm_rd.cc, src/ssp.cc, src/14bit-tmrs.cc, src/processor.cc, src/14bit-registers.cc, src/16bit-registers.cc, src/trace.cc, src/a2dconverter.cc, src/breakpoints.cc, src/interface.cc, src/gpsim_time.h, src/i2c-ee.cc: - The 'value' member of the Cycle_Counter class is now private. 2006-11-12 Borut Razem * doc/gpsimWin32.html: use readline 5.1. Packages are available at http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.2-20061112-src.zip, http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.2-20061112-lib.zip, http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.2-20061112-bin.zip, cairo-1.2.6, glib-2.12.4, pango-1.14.5, NSIS v2.21 2006-11-11 Rob Pearce * regression/interrupts_14bit: modified PORTB change on state test to check for interrupts on both edges * src/processor.cc, src/processor.h, regression/usart_test: change of cpu frequency now propagates to other timings. Second USART test modified to set lower CPU clock to validate this 2006-11-11 Borut Razem * doc/gpsim.css, doc/spsimWin32.html: renamed from gpsimWin32.css * doc/index.html, doc/snap_header.html, doc/snap_footer.html, doc/snap.php: added * doc/gpsim.css, doc/gpsimWin32.html, doc/gpsim.html, doc/gpsim_svn.html: XHTML1 compatible * makefile.mingw: claen performs also clean-extras 2006-11-10 Scott Dattalo * ANNOUNCE: Updated for 0.22.0 release. Note that Borut created an 0.22.0 SVN tag that corresponds to revision 1827. 2006-11-10 Borut Razem * configure.ac, doc/gpsimWin32.html, extra/graphic_lcd/configure.ac, gpsim.spec.in, gui/gui_menu.c, modules/README: corrected all url-s from http://www.dattalo.com/gnupic/gpsim.html to http://gpsim.sourceforge.net/gpsim.html * regression/*.lkr, regression/*.asm, regression/Makefile, src/p16f8x.*, src/pm_rd.*, src/psp.*: added svn properties svn:eol-style native, svn:keywords "Author Date Id Revision" * plat/win32/gpsim.nsi, plat/win32/makefile.mingw: extract PRODUCT_WEB_SITE from ../../configure.ac * doc/gpsim.html, doc/gpsim_svn.html, doc/gpsim.ico: added favicon * doc/gpsim.html: applied patch from David Barnett: "I added the F73 and F74, removed the PIC17's, fixed a typo and changed the modified date" 2006-11-09 Scott Dattalo * configure.ac, extras/graphic_lcd/configure.ac: 0.22.0 Release 2006-11-09 Scott Dattalo * doc/gpsim.lyx: Added module documentation, macro documentation, scripting documentation, and examples documentation 2006-11-08 Scott Dattalo * doc/gpsim.lyx: Added module documentation and in particular the USART module. 2006-11-08 Borut Razem * extras/graphic_lcd/src/glcd_100X32_sed1520.cc, extras/lcd/hd44780.cc, extras/lcd/hd44780.h, extras/lcd/lcd.cc, extras/lcd/lcdgui.cc, extras/lcd/module_manager.cc: removed compiler warnings * doc/gpsim.html, doc/gpsim_svn.html: changed encoding to UTF-8 * plat/win32/gpsim.nsi: changed PRODUCT_WEB_SITE URL and PRODUCT_VERSION 2006-11-08 Scott Dattalo * src/breakpoints.cc: Fixed compiler warning. 2006-11-08 Borut Razem * plat/win32/libgpsim.def: MSVC sync * doc/gpsim_svn.html, doc/gpsim.html: doc/gpsim_cvs.html renamed to doc/gpsim_svn.html 2006-11-08 Scott Dattalo * src/processor.cc: Fixed -p command line option. (actually, there is still an issue with gpsim using the -p option to find the processor, but then naming the processor something else.) 2006-11-08 Scott Dattalo * configure.ac: 0.22.0-RC4 - release candidate 4 * doc/gpsim.html: fix broken links. * README, INSTALL: Minor documentation changes pertaining to 0.22.0 2006-11-08 J.R. Heisey * cli/cmd_macro.cc: - Made some of the macro command console output conditional on the verbose variable to clean up the console output. - Enhanced the console output of the cmd_macro::end_define(). * src/breakpoints.cc: Added call in Breakpoints::set_breakpoint() to Processor::NotifyBreakpointSet() to help with the integration of processors defined in their own dynamic library. 2006-11-07 Scott Dattalo * gui/gui_regwin.cc: EEPROM window abort bug fixed on 2006-11-04 had a flaw. Hopefully that's been fixed now. (The problem was that the fix assumed if the maxrow member of the register_sheet was 0 that there were no cells in the sheet. However, in the gtksheet widget, maxrow can be 0 if there's only 1 row!) 2006-11-07 Scott Dattalo * gui/gui_symbols.cc, gui/gui_src_asm.cc: Changed the way glib lists were deallocated. This removes a glib compile warning. 2006-11-07 Scott Dattalo * src/16bit-registers.h, src/16bit-registers.cc, src/p16x6x.h, src/p16x6x.cc, src/p16f87x.h, src/p16f8x.h, src/16bit-processors.h, src/16bit-processors.cc, src/p16f62x.h, src/p16f62x.cc, src/uart.h, src/uart.cc: - Removed USART_MODULE14 and USART_MODULE16 classes. All they were doing was declaring a 'cpu' pointer, but they weren't even using it. - All member functions of the USART_MODULE class are now non-virtual. 2006-11-06 Rob Pearce * src/stimuli.cc: Fixed the p12ce51x I2C-EE bug - it was due to a stimulus initialisation error caused by bit rot in the node summing function for the single stimulus connected case! 2006-11-06 David Barnett * modules/gpsim_modules.cc: The push_button is named as "push_button" in push_button.h, but "pushbutton" in gpsim_modules.cc. This had the effect that "module load push_button was saved into the netlist file, but "module type push_button not created" would display when loading the netlist. 2006-11-06 Scott Dattalo * doc/gpsim.html, doc/gpsim_cvs.html: Fixed links. Changed CVS references to SVN. 2006-11-05 Scott Dattalo * src/uart.cc, src/uart.h: TXIF is now only gets set if both TXEN and SPEN are set. The USART_MODULE class interface was redesigned slightly to simplify accesses to the various registers associated with the USART. * src/p16f62x.cc, src/16bit-registers.cc, src/p16f8x.cc, src/16bit-registers.h, src/p16x6x.cc, src/p16f87x.cc, src/16bit-processors.cc: - Adapted new USART_MODULE interface. * regression/usart_test/usart_pir1v1.asm, regression/usart_test/usart_pir1v2.asm: - The usart regression test noew makes sure that TXIF is not set before TXEN and SPEN are set. 2006-11-05 Scott Dattalo * src/trigger.cc, src/trace.cc, src/breakpoints.cc: Cleaned up trace printing of traced breakpoints. 2006-11-04 Borut Razem * plat/win32/libgpsim.def: MSVC sync 2006-11-04 Scott Dattalo * src/cod.cc, src/pic-processor.cc: Applied variation of patch submitted by David Barnett that prepends processor name with a 'p' if the name begins with a digit in the .cod file 2006-11-04 Scott Dattalo * gui/gui_breadboard.cc: Patch from Ralf that fixes coordinates of components selected in the breadboard. 2006-11-04 Scott Dattalo * gui/gui_regwin.cc: gpsim was aborting if eeprom window was opened while a processor without an eeprom was loaded. David Barnett reported this bug. 2006-11-04 Scott Dattalo * cli/input.cc: Typo in preprocessor ifdef. This was discovered while applying a patch from the Gentoo distro. (The patch had already independently been applied, yet the typo hadn't been noticed until this new patch had been submitted.) 2006-11-03 Scott Dattalo * src/trace.cc, src/trace.h, src/dspic/dspic-registers.cc, src/12bit-processors.cc, src/processor.cc, src/14bit-processors.cc, src/14bit-registers.cc, src/16bit-processors.cc, modules/stimuli.cc - TraceType constructors are only initialized with size (and not with type). - Trace entry allocation now gets size request from TraceType class. * src/trigger.cc, src/breakpoints.h, src/breakpoints.cc: Trigger action implementation for special breakpoints has been enhanced to take advantage of multiple trace entries. 2006-11-01 Scott Dattalo * src/trigger.cc, src/trigger.h, src/breakpoints.h, src/breakpoints.cc, src/trace.h, src/trace.cc: - Cleaned up breakpoint tracing. - Added TriggerObject::invokeAction() method to handle the default behavior of invoking a trigger object action and handling the tracing. - Moved the BreakTraceType and BreakTraceObject classes from breakpoints.cc to trigger.cc (probably should rename these?) * src/pic-processor.cc: Change the default Integer type output width to 2 characters. (At 8 characters, there were a lot of 0's.) * src/gpsim_object.cc: toString(char*,int) now returns something. 2006-11-01 Scott Dattalo * src/breakpoints.cc: Fixed core dump for breakpoint expressions that are entered improperly. 2006-11-01 Ralph Neider * modules/gpsim_modules.cc: push_buttons are now ignored when gpsim is built without the gui. 2006-11-01 Scott Dattalo * acinclude.m4: Patch from sf user iggie that fixes check for readline 5.2 2006-11-01 Borut Razem * plat/win32/libgpsim.def: MSVC sync 2006-11-01 Roy Rankin * src/pic-processor.cc: Removed p17c7xx processor family from processor list as code does not work 2006-10-31 Scott Dattalo * src/trace.h, src/trace.cc: TraceType type() now takes an argument that allows a user to select a particular subtype. * src/trigger.h, src/trigger.cc, src/breakpoints.cc, src/breakpoints.h: More breakpoint tracing changes. Execution break points are now displayed in the raw trace buffer. 2006-10-28 Scott Dattalo * src/trace.h, src/trace.cc: Raw trace dumps were cleaned up more. The cycle trace is now decoded in a fashion similar to other trace types. * src/breakpoints.cc: Began design for BreakTraceType and BreakTraceObject. 2006-10-30 Roy Rankin * src/ssp.cc : fixed improper use of type bool * regression/p12ce518/p12ce518.asm : correct error in test 2006-10-22 Borut Razem * plat/win32/gpsim.nsi: removed doc/*.html, added doc/screenshots/*, added extras\graphic_lcd\doc\* * plat/win32/libgpsim.def: MSVC sync * gui/gui.vcproj: generate config.h from config_win32.h.in * cli/cmd_log.cc, cli.socket.cc, gui/gui_menu.cc, gui/gui_scope.cc, gui/gui_src_asm.cc, modules/led.cc, modules/stimuli.cc, modules/switch.cc, src/12bit-processors.cc, src/14bit-processors.cc, src/16bit-processors.cc, src/comparator.cc, src/p16f8x.cc, src/spp.cc: fixed warning 2006-10-28 Scott Dattalo * cli/cmd_load.cc: used a different version of the toString() method in the load command 2006-10-28 Scott Dattalo * src/trace.h, src/trace.cc, src/12bit-processors.cc, src/14bit-registers.cc: - Added a CycleTraceType - Now trace type classes do not add themselves to the current trace frame whenever their decode() methods are called. 2006-10-25 Scott Dattalo * gui/gui_src_asm.cc: Source browser page ptr is not ignored when symbolic debugging is unavailable. * cli/parse.yy: Assigning a non-quoted value to one of the scope channel attributes was causing an abort. * src/pic-instructions.h, src/14bit-instructions.cc, src/pic-instructions.cc, src/16bit-instructions.h, src/16bit-instructions.cc: - Instruction class constructors now initialize all of their data memmbers. * doc/gpsim.html: Fixed some missing links. 2006-10-25 Steffen Joeris * modules/paraface.cc: Patch from Debian Etch release that enables certain Free BSD builds. 2006-10-24 Scott Dattalo * src/trace.cc: Added detailed comments on TraceFrames, TraceTypes, and TraceObjects. 2006-10-23 David Barnett * src/12bit-processors.cc: Fixed extra qualifier bug in the OptionTraceType class. 2006-10-23 Scott Dattalo * AUTHORS: Added Roy to the list :) * regression/Makefile.am: added the i2c regression tests to the distribution * configure.ac: RC2 - release candidate 2 * README.EXAMPLES: this was totally out of date and still needs to be cleaned up. * README: changed revision info, made minor changes. 2006-10-23 Scott Dattalo * src/14bit-processors.cc, src/12bit-processors.cc, src/12bit-processors.h, src/trace.h, src/trace.cc: The OPTION register now has its own trace object * doc/gpsim.lyx: Minor documentation updates * doc/gpsim.html: Placing gpsim web page under CVS control. * doc/screenshots/breadboard.png: added * doc/screenshots/registerview.png: added * doc/screenshots/scope1.png: added * doc/screenshots/scope2.png: added * doc/screenshots/source_browser.png: added 2006-10-23 Roy Rankin * src/p16x6x.h src/ioports.h src/p16x6x.cc src/p16f87x.cc src/i2c-ee.cc src/ssp.h src/pir.cc src/pir.h src/ssp.cc src/p18x.cc src/p16f8x.cc regression/run_regression.sh regression/i2c/p16f876a.asm regression/i2c/16f88.lkr regression/i2c/i2c_low.inc regression/i2c/16f876a.lkr regression/i2c/p16f88.asm regression/i2c/Makefile - Add I2C functionality 2006-10-22 Borut Razem * */.cvsignore: removed CVS leftovers * modules/stimuli.cc: trace.* replaced with get_trace().* the getter function instead of direct object access should be used in modules * plat/win32/sdcc.nsi: added examples/modules/*/README to the setup package 2006-10-19 Scott Dattalo * regression/Makefile.am: Added * configure.ac, extras/graphic_lcd/configure.ac, Makefile.am, examples/Makefile.am: Changed revision from 0.21.12-pre to 0.22.0-RC1. 2006-10-18 Scott Dattalo * src/processor.cc, src/processor.h: - insertRegister() and removeRegister() methods of the RegisterMemoryAccess class now return bool. * src/breakpoints.cc: deleted commented out code. * modules/stimuli.cc, modules/stimuli.h: Implemented the register mapping functionality. * cli/parse.yy: improved the reg() operator syntax. It used to be that only integer operands were accepted. Now, expressions are accepted. * regression/port_stim/18f452.lkr: added * regression/port_stim/Makefile: added * regression/port_stim/port_stim.stc: added * regression/port_stim/port_stim.asm: added * regression/run_regression.sh: Added a regression test for the port_stimulus module. 2006-10-17 Scott Dattalo * examples/projects/stack_test/stack_test.asm, examples/projects/stack_test/stack_test.stc, examples/projects/stack_test/Makefile, examples/projects/digital_stim/digital_stim.stc, examples/projects/digital_stim/digital_stim.asm, examples/projects/digital_stim/Makefile, examples/projects/p16f628_test/f628.asm, examples/projects/p16f628_test/Makefile, examples/projects/p16f628_test/f628.stc: - Clean up examples. * configure.ac: Removed the 12bit, 14bit, and 16bit subdirectories from the list of packaged directories. The example code there is old and needs a whole lot of work to get working. 2006-10-17 Scott Dattalo * examples/modules/Makefile.am, examples/modules/usart_test/usart_test.asm, examples/modules/mod_test/mod_test.stc, examples/modules/usart_test/Makefile: - updated examples * examples/modules/led_test/README: added * examples/modules/led_test/Makefile: added * examples/modules/logic_test/README: added * examples/modules/usart_test/README: added * examples/modules/mod_test/README: added * examples/modules/usart_test/usart.asm: removed 2006-10-17 Scott Dattalo * src/ssp.cc: Fixed uninitialized class data. 2006-10-17 Scott Dattalo * src/breakpoints.h, src/breakpoints.cc, src/processor.h, src/processor.cc, src/registers.cc, src/registers.h: Moved the register breakpoint clearing and setting functionality from the register breakpoint classes to the RegisterMemoryAccess. The purpose of this is to allow other types of register objects (besides break points) to replace registers. * modules/gpsim_modules.cc, modules/stimuli.cc, modules/stimuli.h: Added the parallel port stimulus. This stimulus is identical to a PIC port register in that it has a PORT, TRIS, and LATCH register. Users can control the state of the parallel port stimulus in one of two ways. First, there are user accessible attributes (eg port.latch can be assigned a value). Second, (and this is not completed yet) the user can embed the parallel stimulus into the register memory map. This allows the parallel stimulus to be accessed programmatically (that is from within the PIC assembly code). This allows an assembly program to directly control the simulation environment. 2006-10-17 Scott Dattalo * src/trace.cc, src/trace.h: Changed an empty trace entry from 0 to 0x3fffffff. This provides away to differentiate between an empty trace entry and an uninitialized trace type. 2006-10-17 Scott Dattalo * src/pic-ioports.h, src/pic-ioports.cc, src/16bit-processors.cc, src/16bit-processors.h: Moved the PicLatchRegister class from the 16bit-processor definitions to the pic-ioport definitions. 2006-10-16 Scott Dattalo * gui/gui_src_asm.cc: Renamed the popup menu item function 'Run here' to 'Run to here'. 2006-10-15 Scott Dattalo * gui/gui_src_asm.cc: The popup menu item function 'Move PC here' was not updating the program counter. 2006-10-15 Scott Dattalo * src/trace.h, src/trace.cc: - Added classes for tracing module events. - Fixed a couple of bugs with invalid trace objects being created. Also, invalid trace entries were causing the trace dump to be aborted. * src/16bit-instructions.cc: Removed commented out code * src/dspic/dspic-processors.cc, src/processor.h, src/pic-processor.cc, src/registers.cc, src/ioports.cc, src/processor.cc, src/14bit-registers.cc, src/registers.h: The interface to the trace buffer changed slightly. Also, registers were improperly allocating trace objects. * doc/gpsim.lyx: Added some more documentation. 2006-10-08 Scott Dattalo * modules/switch.cc, modules/switch.h: separated out the gui specific portions of the switch into another class. 2006-10-04 Scott Dattalo * modules/switch.cc: Switch resistance has successfully been reintroduced * regression/switch_test/switch_test.asm: Added a test to test the switch resistance. Note, there are no assertions set on the test because currently there is no way to query the node voltage directly. 2006-10-02 Borut Razem * gpsim.sln, cli/input.cc, cli/cli.vcproj, cli/makefile.mingw, gpsim/gpsim.vcproj, gpsim/makefile.mingw, plat/win32/gpsim.nsi: use readline 5.1. Packages are available at http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.1-20061001-src.zip, http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.1-20061001-lib.zip, http://gpsim.sourceforge.net/gpsimWin32/packages/readline-5.1-20061001-bin.zip * doc/gpsimwin32.html: readline 5.1 2006-09-29 Scott Dattalo * modules/switch.cc, modules/switch.h: Trying to reintroduce switch on resistance. * modules/gpsim_modules.cc, modules/resistor.cc, modules/resistor.h: minor clean ups * regression/switch_test/switch_test.asm: Additional comments. Tried to add a test to test switch on resistance... 2006-09-25 Borut Razem * src/sdc.vcproj, src/makefile.mingw: added pm_rd.* to the project 2006-09-21 Dave Barnett * src/pm_rd.cc, src/pm_rd.h: Support for midrange device's program memory read feature. * p16x7x.cc, src/p16x7x.h, src/pic-processor.cc, src/pic-processor.h, src/Makefile.am: Added support for the P16F73 and P16F74 * src/ssp.cc: Fixed typo in printf statement 2006-09-19 Scott Dattalo * src/pic-processor.cc, src/p16f62x.cc, src/p16f62x.h: Added the p16f624 and the p16f624a 2006-09-19 Scott Dattalo * src/pic-processor.cc, regression/p16f628/p16f628.asm: Added the p16f627a and p16f628a processors. Note that these are identical to the non-A versions. 2006-09-10 J.R. Heisey * src/ValueCollections.h: Added indexing operator to class IIndexedCollection. * src/sim_context.cc,h: Added function CSimulationContext:: GetCycleCounter(). * src/modules.cc,h : Added functions to class ModuleLibrary: GetLibraryFileHandle() and GetLibraryFunction(). * gui/gui_src_asm.cc, gui/gui_src.h: - Rescoped several functions into classes to help me keep track of their context. Especially the callbacks. - Implemented the popup menu items: Settings, Find PC, Move PC here, Run here, Breakpoint here, Profile start here, Profile stop here, and most importantly Add to Watch. - Note that the Font selection dialog doesn't seems to actually change the font. It appears to be the same with the old GUI. I haven't checked into it. - Changed the font selection dialog and the settings dialog to use the gtk_dialog_run() function. This fixed an issue when the close (upper right X) button was used the underlying window would be deallocated. This caused the window to never appear again requiring restarting gpsim. 2006-09-03 Scott Dattalo * gui/gui_scope.cc, gui/gui_scope.h: Signal name editing now works. Screen updates for signal names have been fixed. 2006-09-03 Borut Razem * doc/gpsimWin32: glib-2.12.1, gtk+-2.8.20, cairo-1.2.2 2006-08-27 Scott Dattalo * gui/gui_scope.cc, gui/gui_scope.h: - Time axis is now shown. Major and Minor tick marks and the corresponding grid lines are drawn. 2006-08-21 Scott Dattalo * gui/gui.h: KeyEvent now differentiates presses and releases. * gui/gui_src.cc: Update KeyEvent objects. * gui/gui_scope.cc, gui/gui_scope.h: Numerous enhancements: - Added support for markers - Wave pixmaps are now 1024 pixels wide. This primarily fixes a round off error in the binary search routine - Scroll thumb now adjust size based on amount of waveform plotted - Hot key functionality: z -- Zoom in Z -- Zoom out r -- pan right l -- (lowercase ell) pan left - Glitches are now plotted - High frequency events (i.e. events for which there is inadequate monitor resolution to completely show) are plotted in a different color. - Reomved the Pane widget - it was holding the waveforms and just eating up space. - Added WaveBase in anticipation of different types of waveforms. * src/bitlog.h, src/bitlog.cc: The ThreeStateLogger can now return the number of events occurring between two time intervals or between two event indices. (Used for high frequency measuring). 2006-08-08 Scott Dattalo * gui/gui_main.cc: Now scope window is updated when simulation stops. * gui/gui_src_asm.cc: Refresh gui menu when src window changes hidden state. * gui/gui_scope.cc: Redesigned scope window layout. Adding scrolling. 2006-08-06 Roy Rankin * regression/spi regression/spi/p16c62.asm regression/spi/16f88.lkr regression/spi/p18f242.asm regression/spi/16c62.lkr regression/spi/p16f88.asm regression/spi/Makefile regression/spi/18f242.lkr regression/run_regression.sh src/16bit-registers.h src/p16x6x.h src/p16x6x.cc src/p16f87x.cc src/16bit-processors.cc src/ssp.h src/14bit-tmrs.h src/ssp.cc src/ioports.cc src/14bit-tmrs.cc src/p18x.cc src/16bit-registers.cc src/p16f8x.cc src/16bit-processors.h: - Serial Peripheral Interface (SPI) 2006-07-31 Scott Dattalo * src/pic-ioports.cc: RBIF was not handled correctly when the change on interrupt was due to a write to PORTB. * regression/interrupts_14bit.asm: Add a check for the RBIF flag getting set correctly. * arc/p16x8x.cc: W was not getting added to the symbol table. 2006-07-30 Scott Dattalo * cli/cmd_log.cc: Cleaned up help description. 2006-07-30 Scott Dattalo * cli/parse.yy, cli/cmd_log.h, cli/cmd_break.cc, cli/cmd_break.h, cli/cmd_log.cc, src/gpsim_object.cc, src/value.h, src/value.cc, src/expr.h, src/expr.cc, src/trace.h, src/trace.cc, src/registers.h, src/breakpoints.h, src/breakpoints.cc, src/symbol.h, src/gpsim_object.h, src/operator.cc, src/operator.h, src/symbol.cc: - Fixed logging. The logging feature has been broken for a long time. The old code that performed logging has been mostly removed. The new logging code is similar to the breakpoint code. It utilizes TriggerActions.to perform the logging operations. - (The profiling feature is currently broken too. However, it should be possible to utilize TriggerActions for profiling). 2006-07-30 Scott Dattalo * gui/gui_scope.cc, gui/gui_scope.h: development snap - still not complete 2006-07-29 Borut Razem * cli/cli.vcproj, gpsim/gpsim.vcproj, gui/gui.vcproj, modules/modules.vcproj: added cairo dependency, clening * plat/win32/libgpsim.def: MSVC sync * src/i2c-ee.c, modules/i2c-eeprom.c: removed compiler warnings 2006-07-26 Roy Rankin * src/i2c-ee.h src/i2c-ee.cc modules/i2c-eeprom.cc modules/i2c-eeprom.h modules/gpsim_modules.cc: - Added I2C EEprom modules for 24xx024, 24xx16b, 24xx256 2006-07-24 Borut Razem * cli/makefile.mingw, cli/cli.vcproj: define HAVE_SOCKETS - sockets are enabled on WIN32 * plat/win32/libgpsim.def, src/src.vcproj: MSVC sync * doc/gpsimWin32: glib-2.10.3, gtk+-2.8.18, pango-1.12.3 2006-07-23 Scott Dattalo * cli/socket.cc: Re-enabled the socket interface. * examples/scripts/makefile: Hmm, for some reason pango is now required to build the examples. 2006-07-22 Rob Pearce * src/Makefile.am Added a2dconverter.h to the headers list, so that it's included in the tarball built by make dist 2006-07-14 Roy Rankin * src/p18x.h src/p18x.cc src/pic-instructions.cc src/pic-processor.cc src/pic-processor.h: - P18F248 now based on P18F242, P18F448 added based on P18F424 * src/p16x6x.cc: remove debug output 2006-07-12 Scott Dattalo * cli/parse.yy, cli/input.cc: Previously, the parser would abort parsing upon detection of syntax errors. Now the parser will only ignore the erroneous lines. The difference mainly applies to scripts. 2006-07-11 Scott Dattalo * gui/gui_scope.h, gui/gui_scope.cc: Added scope.zoom and scope.pan attributes that allow the image in the scope window to be panned and zoomed. * src/makefile.mingw: added the new psp.cc file. 2006-07-11 Roy Rankin * src/p16x6x.h src/p18x.h src/p16x6x.cc src/pic-ioports.h src/Makefile.am src/psp.cc src/p18x.cc src/psp.h src/pic-ioports.cc regression/psp/18f452.lkr regression/psp/16f871.lkr regression/psp/p18f452.asm regression/psp/p16f871.asm regression/psp/Makefile regression/run_regression.sh: - Add PSP functionality to 40 pin processors based on P16C64 & P18C4x2 2006-07-08 Scott Dattalo * makefile.mingw, plat/win32/make.mingw: Created a 'make depend' rule for the win32 makefiles. Here's how it works; first create the dependency file: $ make -f makefile.mingw depend This will create a file named 'mf' in each directory. Now gpsim can be built by: $ make -f mf (Note: There is a bug with make depend in the modules directory). 2006-07-08 Scott Dattalo * gui/gui_scope.cc, gui/gui_scope.h, gui/gui.h, gui/gui_src.cc: - Moved the KeyEvent class definition to gui.h. - Moved gui_scope local declarations to Scope_Window class. 2006-07-07 Scott Dattalo * gui/gui_scope.cc: Added a GtkEntry widget to hold scope signal names. Now signals can be specified either through the GtkEntry or by the command line attributes. 2006-07-06 Scott Dattalo * gui/gui_scope.cc: IOPINs can now be attached to scope channels. The attachment can only be made at the command line: gpsim> scope.ch0="porta0" Everytime the state of porta0 is changed, the event will also be sent to the scope window where it will get logged and displayed. (Note, the quotes are necessary to prevent gpsim from evaluating the pin name.) * regression/logic_test/logic_test.asm: The logic OR gates connected to porta0,porta1,porta2,portc0 are now displayed in the scope window. 2006-07-05 Scott Dattalo * src/stimuli.h, src/stimuli.cc: Added a virtual destructor to the PinMonitor class. * src/16bit-processors.h, src/16bit-processors.cc, src/pic-ioports.cc, src/processor.cc, src/gpsim_object.cc: minor changes to remove compiler warnings. * gpsim/CopyDlls.bat: This bat file copies the DLLs for the win32 builds to the gpsim/gpsim. A few more DLLs were added to the list. 2006-07-05 Scott Dattalo * plat/win32/make.mingw: Added an option to use ccache for mingw builds. Unfortunately, for this to work well the makefile dependencies also need to be implemented correctly. 2006-07-04 Roy Rankin * src/p16x6x.h src/p16x6x.cc src/p16f87x.cc src/p16f87x.h src/pir.cc src/pir.h src/comparator.h src/a2dconverter.h src/comparator.cc regression/comparator/compar_877a.asm: - Fixes involving PIR_SET 2006-07-03 Borut Razem * cli/cli.vcproj, src/src.vcproj, src/makefile.mingw, plat/uxtime.cc, plat/uxsleep.cc, plat/uxtime.h: uxtime.cc splitted to uxtime.cc and uxsleep.cc, since gettimeofday() is now declared in mingw 2006-07-01 Scott Dattalo * gui/gui_menu.cc, gui/gui_scope.cc, gui/gui_processor.cc, gui/gui_main.cc: - resurrected the scope window. - ThreeStateEventLogger logs traced states. - Implemented an efficient bisecting algorithm for mapping events states onto the plotting window. - Created attributes: scope.ch0 - scope.ch7 specify nodes that are to be monitored scope.start and scope.stop specify the range of time to be viewed. Currently, the scope window cannot display real data. Instead, it will synthesize test data. The scope.start and scope.stop attributes do work. * src/ioports.h, src/stimuli.h, src/stimuli.cc, src/ioports.cc: - Moved the SignalSink class to stimuli.h - Introduced addSink and removeSink methods to the PinMonitor class. - Removed references to 'OLD_IOPORT_DESIGN' * src/bitlog.cc, src/bitlog.h: The ThreeStateEventLogger class now has a flag to indicate when the event buffer is empty. Previously, a "bogus" time was placed at position 0, however this broke the logic that searches for events at particular times. * src/symbol.cc: Added a debug message. 2006-07-01 Scott Dattalo * cli/Makefile.am: Applied patch 1470810 which adds the readline library to list of libraries linked with the cli library. 2006-06-22 Borut Razem * extras/usart_con/*: removed from svn * makefile.mingw, plat/win32/gpsim.nsi: removed usart_con * modules/usart.cc, modules/usart.cc: added possibility to write to the console using the boolean attribute "console = true | false" * examples/modules/usart_gui/usart_gui.asm: send only '\n' for the newline, introduced putchar procedure, ... 2006-06-21 Roy Rankin * regression/usart_test/usart_pir1v1.asm, regression/usart_test/usart_pir1v2.asm: - Check PIC TX pin is high when first set to output. * src/pic-ioports.cc: Portb, allow driving state to be set even when bit is set. * src/tmr0.cc: Fix call of clear_break. 2006-06-16 Scott Dattalo * src/14bit-tmrs.h, src/14bit-tmrs.cc: TMR2 wasn't getting properly initialized when the TMR2ON bit in T2CON was getting set. * TODO: Removed the "Source Browser Search" todo item 2006-06-13 Borut Razem * CVSROOT: removed the CVS left-over * extras/usart_con/usart_con.cc: print control characters in <%02X> format * gui/gui_src_asm.cc: added strcasestr() function 2006-06-16 Scott Dattalo * TODO: Cleaned up the TODO list. * gui/gui_src_asm.cc, gui/gui_src.h: Implemented the Source Browser "Find" dialog box. When the new source browser had been re-written, this feature was ommitted. The dialog supports forward and backward searches and case sensitivity. The search history feature is not currently working (was it ever?). Also, it'd be useful to have a "search all files" feature. * gui/gui_menu.cc: Minor change to TextStyle API. 2006-06-13 Scott Dattalo * src/sim_context.cc, cli/input.cc, cli/cmd_load.cc: Rewrote code to get around a gcc 3.2.2 x86 bug regarding the mis-handling of const char * types (the ECX register was getting clobbered!). 2006-06-13 Borut Razem * src/os_dependent.c, src/modules.h, src/modules.cc: reverted cahanges for fix: [ 1488107 ] const violation in get_error_message() since dlerror() returns const char * on FreeBSD * pic_processor.h: fixed warning multiple default constructors specified * plat/win32/libgpsim.def: MSVC sync * doc/gpsimWin32.html: patched gtk+extra-2.1.1-src-20060611.zip 2006-06-12 Roy Rankin * regression/usart_test/usart_pir1v1.asm regression/usart_test/16f628.lkr regression/usart_test/usart_pir1v2.asm regression/usart_test/Makefile regression/run_regression.sh: - Improve USART regression tests * regression/usart_test/usart_test.stc regression/usart_test/usart_test.asm: removed as redundant * src/uart.cc src/uart.h: receive baud rate fix * modules/usart.cc modules/usart.h: Transmit baudrate fix, loop attribute added, receiver rewritten to remove event logger. 2006-06-10 Robert Pearce * doc/gpsim.lyx: Some hacked notes on creating new modules, and a few other tweaks 2006-06-10 Roy Rankin * src/gpsim_time.h src/stimuli.cc src/gpsim_time.cc src/processor.cc src/14bit-registers.cc: cycles_per_second changed to instruction_cps * src/cod.cc: prevent duplicate symbol messages from static .cod file by not loading constants * gui/gui_stopwatch.cc: remove magic number, Frequency format change * src/pir.cc src/pir.h: RCIF not being set by uart * src/uart.cc modules/usart.cc: fix baud rate error 2006-06-03 Scott Dattalo * src/16bit-processors.cc: The newly added config words were placed at word addresses instead of byte addresses. * src/pic-instructions.cc: Removed warning in CLRWDT instruction that said 16bit wdt timer is not implemented. * src/hexutils.cc: removed ifdef'd out code 2006-06-03 Scott Dattalo * cli/parse.yy, cli/input.cc, cli/input.h, cli/cmd_load.cc: Added an option to the load command to allow processors to be named. Eg: gpsim> load test.cod U1 # Assign U1 ref. des. to processor * src/processor.h, processor.cc, src/p16x6x.h, src/p16x6x.cc, src/p16f87x.h, src/p16f87x.cc, src/16bit-processors.h, src/16bit-processors.cc, src/pic-processor.h, src/pic-processor.cc, src/p16f62x.h, src/p16f62x.cc, src/p16x5x.h, src/p16x5x.cc, src/p16x7x.h, src/p16x7x.cc, src/12bit-processors.h, src/12bit-processors.cc, src/p12x.h, src/p12x.cc, src/p18x.h, src/p18x.cc, src/processor.h, src/processor.cc, src/p16x8x.h, src/p16x8x.cc, src/p16f8x.h, src/p16f8x.cc, src/14bit-processors.h,src/14bit-processors.cc, src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h: Pic processors now can be named when instantiated. * gui/gui_menu.cc: Adhere to the new calling convention for gpsim_open. * src/hextutils.h, src/hexutils.cc, src/program_files.cc, src/program_files.h, src/sim_context.h, src/sim_context.cc, src/cod.cc: New calling convention for LoadProgramFile * src/os_dependent.cc: There appeared to be a compiler bug IsFileExtension() (a const pointer in the callee's stack space was getting modified). But, there is a built in STL function that does the same thing IsFileExtension() was doing, so that's now used. * regression/ttl/ttl377.stc: added * regression/ttl/Makefile, regression/comparator/compar_877a.stc, regression/comparator/compar_628.stc, regression/comparator/compar_873a.stc, regression/p16f84/p16f84.stc, regression/switch_test/switch_test.stc, regression/switch_test/switch_test.asm, 2006-06-03 Roy Rankin * src/stimuli.cc, src/stimuli.h: New resistor-capacitor transient voltage calculation implemented and activated, getBitChar function re-written. * modules/switch.cc, modules/switch.h, regression/switch_test/switch_test.asm: - Switch module model changed eliminating Rclosed parameter 2006-03-02 Borut Razem * extras/graphic_lcd/makefile.mingw, plat/win32/gpsim.nsi: graphic_lcd.dll renamed to libgpsim_graphicLCD.dll * extras/lcd/examples/lcd_mod.stc: libgpsim_lcd.so changed to libgpsim_lcd 2006-05-31 Scott Dattalo * src/p16x6x.h, src/16bit-processors.cc, src/14bit-registers.h, src/processor.h, src/pic-registers.h, src/pic-processor.cc, src/pic-processor.h, src/p16x8x.h, src/pic-registers.cc, src/breakpoints.cc, src/12bit-processors.h, src/14bit-processors.cc, src/14bit-processors.h: Accesses to CONFIG2H now can control the WDT. A couple of new members were added to the WDT class to support the new reading and writing. Also, some minor class clean up was also performed. 2006-05-31 Borut Razem * Implemented enhancement request [ 1496325 ] To bundle the extra modules with gpsim-win32 snapshot makefile.mingw: added targets extras, clean_extras extras/graphic_lcd/makefile.mingw, extras/lcd/makefile.mingw, extras/usart_com/makefile.mingw: introduced GPSIM_LIB_PATH, GPSIM_INCLUDE_PATH, GPSIM_DEF_PATH variables plat/win32/gpsim.nsi: added potion to install extras modules 2006-05-28 Borut Razem * src/os_dependent.c, src/modules.h, src/modules.cc, src/sim_context.cc: fixed [ 1488107 ] const violation in get_error_message() 2006-05-29 Robert Pearce * regression/resistor/resistor.asm: improved failure reporting and added tests for the output pin not being swamped * src/stimuli.cc, src/stimuli.h: Adjusted default Zth values to be more sensible (ZthWeak now > ZthPullUp). Also some debug messages on wht looks like a dodgy condition. Need to follow up. * doc/gpsim.lyx: corrected some formatting. 2006-05-28 Borut Razem * plat/win32/gpsim.nsi: removed unneeded asprintf.dll from the package, added possibility to define the SETUP_DIR from the NSIS command line * doc/gpsimWin32.html: glib-2.8.6, gtk+-2.8.17, pango-1.12.1, cairo-1.0.4 * extras/graphic_lcd/src/gpsim_modules.cc, extras/graphic_lcd/src/sed1520.cc, extras/lcd/hd44780.cc: removed unneeded inclusion of config.h * extras/graphic_lcd/makefile.mingw: added, thanks to Xiaofan Chen * extras/lcd/makefile.mingw: corrected, thanks to Xiaofan Chen * makefile.mingw: added rules doc and setup * plat/win32/fd2raw.cpp: report error messages 2006-05-28 Roy Rankin * src/gpsim_object.cc: Improve GNU demangling * modules/switch.cc, modules/switch.h, regression/switch_test/switch_test.asm: - Fix infinite regression bug. 2006-05-27 Scott Dattalo * src/ValueCollections.cc, src/ValueCollections.h, src/14bit-registers.cc: An indexed collection can now accommodate a disjoint set. * src/16bit-processors.h, src/16bit-processors.cc, src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h, src/processor.h, src/processor.cc, src/pic-processor.h, src/14bit-processors.h,src/14bit-processors.cc, src/pic-processor.cc: The ProgramMemoryClass now uses the newly added "disjoint set" feature of an IndexedCollection to provide access to configuration memory. E.g. romData[0x300000] = 0x1234 will write 0x1234 to the configuration word at address 0x300000. In addition, infrastructure has been added to symbolically deal with configuration memory. E.g. gpsim> .CONFIG1H $00000027 gpsim> help .CONFIG2H $0000000f WatchDog configuration Currently the configuration memory does not control any thing. I.e., if you write to config memory, the data changes, but the processor configuration is not actually changed. * src/hexutils.cc: removed printf debugging. 2006-05-25 Scott Dattalo * modules/stimuli.h, modules/stimuli.cc: More support for file stimulus. 2006-05-25 Scott Dattalo * modules/logic.h, modules/logic.cc, modules/gpsim_modules.cc: Only use if the gui is enabled 2006-05-25 Scott Dattalo * modules/switch.h, modules/switch.cc, modules/gpsim_modules.cc: Only use gui if enabled. * modules/stimuli.h, modules/stimuli.cc: Began adding support for file stimulus. 2006-05-24 Borut Razem * modules/makefile.mingw, modules/modules.vcproj: added stimuli.* * plat/win32/libgpsim: MSVC sync 2006-05-23 Borut Razem * doc/gpsimWin32.html: CVS replaced with Subversion * src/14bit-tmrs.h, src/14bit-tmrs.cc: - PWM fixes CCP high if duty cycle 0, CCPRnH loaded on TMR2 compare, PWM starts after first TMR2 compare, PMR2::put and PR2::put rewrite * regression/ccp/pwm_877a.asm, regression/ccp/Makefile, regression/run_regression.sh: PWM regression 2006-05-21 Scott Dattalo * modules/stimuli.h, modules/stimuli.cc: New files for 'extended' stimuli. Currently only an asynchronous stimulus replacement called 'pulsegen' has been created. * modules/Makefile.am, modules/gpsim_modules.cc: Added pulsegen to the default list of modules. * regression/run_regression.sh, regression/wavegen/16f877a.lkr, regression/wavegen/Makefile, regression/wavegen/pulsegen.asm, regression/wavegen/pulsegen.stc: New regression test to test the pulsegen module. (This test is really just a copy of the ccp regression test except that the asynchronous stimulus has been replaced with a pulsegen module). * src/symbol.cc: Module symbol descriptions were not getting printed * cli/cmd_break.cc: removed bogus warning about cycle break points not getting set. 2006-05-21 Robert Pearce * src/p16f87x.h, src/p16f87x.cc: Re-worked 16F871 to be derived from 16C64 rather than 74, because that's the easiest way I could find to fix the RAM size (it had way too much) and the stray CCP2 2006-05-19 Scott Dattalo * src/expr.h, src/expr.cc: Added LiteralArray class for (better) handling array types. * cli/parse.yy, cli/scan.ll: experimenting with user-created typed symbols. * src/processor.cc: Removed bogus check that prevented users from over-writing the Rom contents. If the user wants to over write ROM then they should be allow to! 2006-05-19 Roy Rankin * src/14bit-tmrs.cc: TMR2 counts down not up, period wrong, fix 2 PWM with same duty cycle * src/p16f8x.cc: CCP1 pin determined by confguration word * src/p16x6x.cc: fix core dump for CCP2 2006-05-17 Scott Dattalo * regression/run_regression.sh: added regression test for ccp peripheral. This test only tests capture modes for the CMCON settings of 4,5,6, and 7. * regression/16f877a.lkr, regression/ccp_877a.asm, regression/ccp_877a.stc, regression/Makefile: new files for the ccp regression test. 2006-05-14 Borut Razem * src/makefile.mingw, src/vcproj: added 16f87 and 16f88 processors * modules/makefile.mingw: added i2c-eeprom * src/p12x.cc: removed unused variable * src/i2c-ee.cc: fixed warning: In member function `virtual bool I2C_EE::processCommand(unsigned int)': warning: control reaches end of non-void function; fixed MSVCcompilation * plat/win32/libgpsim.def: MSVC sync 2006-05-14 Scott Dattalo * src/value.h, src/value.cc, src/expr.cc: Expressions derived from the base gpsim types (like Integer, Float) were not getting evaluated properly. 2006-05-14 Roy Rankin * regression/a2d/p16f874a.asm, regression/a2d/p16c71.asm, regression/a2d/16f871.lkr, regression/a2d/16f874a.lkr, regression/a2d/p18f452.asm, regression/a2d/p16f88.asm, regression/a2d/p16f871.asm, regression/a2d/Makefile, regression/a2d/p16f873a.asm, regression/run_regression.sh, src/p16f87x.cc, src/p16f87x.h, src/16bit-processors.cc, src/p16f62x.cc, src/p16x7x.cc, src/p18x.cc, src/a2dconverter.cc: - tests and correction to a2d for various processors 2006-05-14 Roy Rankin * src/16bit-registers.h, src/14bit-registers.h, src/pic-processor.cc, src/Makefile.am, src/pic-processor.h, src/14bit-registers.cc, src/p16f8x.h, src/p16f8x.cc, regression/a2d/Makefile, regression/run_regression.sh, regression/a2d/16f88.lkr, regression/a2d/p16f88.asm: - Add 16f87 and 16f88 processors 2006-05-13 Scott Dattalo * src/a2dconvert.h: removed redundant class qualifiers in member function declarations. 2006-05-13 Scott Dattalo * src/processor.h, src/processor.cc, gui/gui_src_opcode.cc: Added romData[] accessor (analogous to ramData) to provide a way of querying and modifying the program memory. So now you can change program memory from the command line: gpsim> romData[address] = value Address and value can be symbols. 2006-05-12 Robert Pearce * regression/run_regression.sh, regression/txisr_test/...: Added a test for the correct behaviour of usart transmit interrupts 2006-05-11 Robert Pearce * src/p16f87x.cc: A2D converter fixes for the 16f871. 2006-05-10 Scott Dattalo * src/pir.h, src/pir.cc: Applied patch (with modifications) from Robert Pearce that adds the concept of 'writable' PIR register bits versus 'valid' ones. 2006-05-10 Scott Dattalo * src/16bit-hexdecode.cc, src/p16x6x.h, src/i2c-ee.h, src/p16x6x.cc, src/p16f87x.cc, src/16bit-processors.cc, src/i2c-ee.cc, src/eeprom.cc, src/pir.cc, src/p16f62x.cc, src/pie.cc, src/pir.h, src/p16x7x.cc, src/p18x.cc, src/value.cc, src/eeprom.h, src/16bit-registers.cc: - Redesigning PIR logic. The existing design requires numerous manuel configurations that are subject to error. The new design attempts to encapsulate the PIR configuration within the PIR classes. 2006-05-10 Scott Dattalo * modules/i2c-eeprom.h, modules/i2c-eeprom.h, Makefile.am, src/p12x.h, src/p12x.cc: Began designing a gpsim I2C module. 2006-05-08 Borut Razem * extras/usart_con.cc: sync with modules/usart.cc 2006-05-08 Roy Rankin * src/comparator.h, src/comparator.cc, src/p16f62x.cc: - rewritten so comparator processor differences in processor class * src/p16x6x.cc: portc register removed from p16f62x * src/p16f87x.cc, src/p16f87x.h: a2d added, comparator change * src/16bit-processors.cc, src/p16x7x.cc src/a2dconverter.h, src/a2dconverter.cc: code change for pending p16f88 * regression/a2d/Makefile, regression/run_regression.sh, regression/a2d/16f873a.lkr, regression/a2d/p16f873a.asm: - add a2d regression for p16f873a 2006-05-06 Scott Dattalo * src/stimuli.cc, src/stimuli.h, cli/cmd_stimulus.cc: Stimuli parameters are now initialized with Values instead of doubles. 2006-05-06 Scott Dattalo * modules/usart.h, modules/usart.cc: - Added the boolean attribute 'crlf'. If this is set true, then carriage returns and line feeds will generate new lines in the gui terminal window. 2006-05-06 Robert Pearce * modules/usart.h, modules/usart.cc: - Usart GUI now displays non-printable characters as <%02X>. - The usart module now supports a transmit FIFO. This allows transmit data to be queued while the simulation is stopped. 2006-04-30 Roy Rankin * gui/gui_src.h gui/gui_src_asm.cc: fix ungisgned - signed compile warnings * gui/gui_breadboard.cc: get trace working again * gui/Makefile.am: remove unused and incorrect defines 2006-04-29 Scott Dattalo * modules/switch.cc, modules/switch.h, regression/switch_test/switch_test.asm: Moved pin functionality from the Switch class into the Switch_Pin class. 2006-04-29 Robert Pearce * src/value.cc: Fixed Float type check error. 2006-04-29 Roy Rankin * src/gpsim_object.h src/gpsim_object.cc src/stimuli.cc src/stimuli.h gui/gui_breadboard.h gui/gui_breadboard.cc: - GUI pin rename code - rewritten and moved into IOPIN class * src/comparator.h src/comparator.cc p16f62x.cc: - Do dynamic GUI pin renaming * gui/Makefile.am: remove unused and incorrect defines * src/processor.cc: Set 4 clock cycles per instruction cycle * regression/comparator/compar_628.asm: Start by turning off comparators 2006-04-28 Borut Razem * modules/makefile.mingw, modules/modules.vcproj, plat/win32/libgpsim.def, extras/lcd/makefile.mingw, plat/win32/gpsim.nsi: WIN32 sync 2006-04-26 Scott Dattalo * modules/switch.cc, modules/switch.h, modules/gpsim_modules.cc: - Added On-resistance and Off-resistance attributes to the switch module. (They're called Ropen and Rclosed). - The switch module code now resides in the 'Switches' namespace. * modules/resistor.cc: - The resistor module now initializes itself with the gpsim default attributes (which for now are only xpos and ypos). * regression/switch_test/switch_test.asm, regression/switch_test/switch_test.stc: Moved the switch regression test configuration script into the switch_test.asm source 2006-04-24 Scott Dattalo * src/ioports.cc, src/ioports.h: Fully deprecated the IOPORT class. The old IOPORT class is still present, but conditionally disabled. * modules/logic.cc, modules/usart.cc, modules/logic.h, modules/switch.cc, src/stimuli.cc, src/stimuli.h, src/cod.cc, src/comparator.h, src/i2c-ee.cc: Removed all references to the IOPORT class. 2006-04-23 Scott Dattalo * src/gpsim_object.h, src/gpsim_object.cc: Removed TRUE and FALSE definitions. 2006-04-23 Roy Rankin * src/gpsim_object.h src/gpsim_object.cc gui/gui_breadboard.h gui/gui_breadboard.cc: Allow pin names to be changed after breadboard is started. * src/stimuli.cc: minor output format change and new debuging output 2006-04-22 Roy Rankin * modules/switch.cc modules/switch.h: fix windows regression problem 2006-04-17 J.R. Heisey * modules/gpsim_modules.cc, modules/push_button.cc, modules/resistor.cc, modules/push_button.h, modules/resistor.h, modules/encoder.cc, modules/encoder.h, modules/Makefile.am: - Removed references to the deprecated IOPORT class. - Temporarily removed the video and the parallel_port modules (I don't have a way to test them). - The push button module can now be used again. 2006-04-17 Borut Razem * config_win32.h.in: added the explanation why the warning is good: warning: `I' flag used with `%x' printf format * cli/cli.vcproj, modules.vcproj, modules/makefile.mingw, plat/win32/libgpsim.def: WIN32 sync 2006-04-16 Scott Dattalo * modules/binary_indicator.cc,h: removed from gpsim. This module did absolutely nothing. * modules/gpsim_modules.cc, modules/Makefile.am: removed references to the binary_indicator. 2006-04-16 Scott Dattalo * modules/ttl.cc: TTLbase now calls initializeAttributes(). This defines xpos and ypos attributes. * regression/ttl/ttl377.asm: xpos and ypos are initialized by the builtin script. * modules/led.cc, modules/led.h: Redesigned I/O pins to remove references to the deprecated IOPORT class. * modules/gpsim_modules.cc: Place Led classes in their own namespace. 2006-04-16 Borut Razem * config_win32.h.in: fixed bug [ 1470012 ] Breakpoints regression test crashes mingw gpsim * modules/makefile.mingw, modules/modules.vcproj: WIN32 sync 2006-04-16 Scott Dattalo * modules/gpsim_modules.cc, modules/Makefile.am, modules/ttl.cc, modules/ttl.h: Began a TTL module. Right now it contains only a '377. * regression/run_regression.sh, regression/ttl/18f452.lkr, regression/ttl/Makefile, regression/ttl/ttl377.asm: Regression test for the newly added '377 module in the ttl library. * src/modules.h, src/modules.cc, gpsim_object.cc: Modules can now be constructed with a name and a description. 2006-04-15 Scott Dattalo * regression/switch_test/switch_test.asm: corrected 'capacitance' 2006-04-15 Borut Razem * cli/cli.vcproj, cli/makefile.mingw: added define YYSTACK_USE_ALLOCA * src/a2dconverter.*: svn:keywords=Author Date Id Revision, svn:eol-style=native * src/a2dconverter.cc: corrected include path to "../config.h" * regression/switch_test/switch_test.stc: corected 'capacitance' 2006-04-15 Scott Dattalo * src/16bit-registers.h, src/16bit-processors.cc, src/16bit-registers.cc, src/16bit-processors.h, src/p18x.cc, src/a2dconverter.cc: A2D is now working (but not fully tested) for the 16bit core. * src/pir.h: Redesigned PIR base class in the first attempt in removing PIR_SET classes * src/symbol.cc, src/stimuli.cc: Fixed symbol table dump. * regression/a2d/Makefile, regression/a2d/p18f452.asm: Regression test for the 18f452 A2D converter. * modules/resistor.cc: Made 'Capacitance' attribute lower case. 2006-04-13 Scott Dattalo * gui/gui_src_asm.cc: removed debug printf * modules/resistor.cc: Added module description. * src/a2dconvert.cc: Added a verbose mode printf debug statement. * src/p16x7x.cc: P16C71 class now sets A2D converter bits. * src/symbol.cc, src/symbol.h: module_symbol can now display a module description. * regression/run_regression.sh: added A2D regression test for the p16c71. * a2d/Makefile, a2d/p16c71.asm, a2d/16c71.lkr: A2D regression test for the 16c71. 2006-04-13 Borut Razem * gui/gui_src_asm.cc: removed warnings * modules/switch.h, src/dspic/dspic-processors.h, src/operator.h: enable compilation on Fedora Core 5 (gcc 4.1.0) * regression/comparator/compar_628.stc, regression/comparator/compar_673a.stc, regression/comparator/compar_677.stc, regression/eeprom_wide/eeprom_wide.stc: changed libgpsim_modules.so with libgpsim_modules so that it runs on WIN32 * src/makefile.mingw, src/src.vcproj, plat/win32/libgpsim.def: WIN32 sync 2006-04-13 Scott Dattalo * src/Makefile.am, src/a2dconverter.h, src/a2dconverter.cc: New Files. * src/p16f87x.cc, src/p16x7x.h, src/p16x7x.cc: Removed a2d-specific stuff from p16x7x.[h,cc] and placed it into a2dconverter.[h,cc]. Also, the p16c71 doesn't have a PIR register. The INTCON class assumes that there is one. So a special (non-existant) PIR register has been created that is not instantiated in the register map, but is capable of communicating PIR-specific information with those peripherals that implement their own PIR functionality (this is currently only the P16C71 A2D module). * src/pir.h: The PIR_SET used to be a pure virtual base class. This class needs to be redesigned... * src/pir.h: Made class members private. * src/gpsim_object.h, src/gpsim_object.cc, src/value.h, src/value.cc: Moved Value descriptions into the parent gpsimObject class. The purpose of this change is to provide a uniform way in which gpsimObjects (like processors and modules) can describe themselves. * modules/resistor.cc: Added a voltage attribute to pull up resistors. Now pullup resistors can be used as general purpose voltage sources. 2006-04-11 Scott Dattalo * gui/gui_src_asm.cc: Double clicks in the source browser were causing segv's 2006-04-11 Scott Dattalo * gui/gui_src.h, gui/gui_src_asm.cc: Right-button mouse clicks now bring up a menu. Currently, not all of the menu items are supported. Furthermore, only GtkTextTag'd text responds. 2006-04-11 Roy Rankin * src/p16f87x.cc: if code read with breadboard closed, breadboard did not show processor. * src/pic-ioports.cc: fix portb does not show high inputs if register bits cleared from assembler code. * regression/rt.sh: allow multiple tests in one directory * regression/run_regression.sh: run comparator tests seperatly * src/comparator.cc: cleanup compiler warnings 2006-04-08 Scott Dattalo * cli/scan.cc: removed from SVN. This autogenerated by flex from scan.ll. 2006-04-09 Borut Razem * extras/graphic_lcd/utils/custom.png, extras/graphic_lcd/utils/fontimage.png, extras/graphic_lcd/utils/gpsim1.png, extras/graphic_lcd/utils/konqueror.png, extras/graphic_lcd/utils/konqueror16X16.png, extras/graphic_lcd/utils/konqueror3.png: mime-type image/png * src/src.vcproj, src/makefile.mingw: new files src/comparator.h src/comparator.cc * gui/gui_menu.cc, gui/gui_profile.cc, gui/gui_regwin.cc, gui/gui_src_asm.cc, gui/gui_watch.cc, modules/logic.cc, modules/resistor.cc, modules/switch.cc, modules/usart.cc, src/dspic/dspic-registers.cc, src/intcon.cc, src/ioports.cc, src/pic-instructions.cc: removed unused variables, #if 0-ed unused functions removed warnings: XXXX.h: In constructor `xxxx': XXXX.h:LLL: warning: `yyyy' will be initialized after XXXX.h:LLL: warning: `zzzz' XXXX.cc:LLL: warning: when initialized here 2006-04-08 Scott Dattalo * ChangeLog: experimental SVN checkin. 2006-04-08 Scott Dattalo * INSTALL: re-instated - somehow it got wiped out on 04-05 * ltconfig, missing, mkinstalldirs, stamp-h.in: removed from CVS. 2006-04-08 Roy Rankin * src/cod.cc src/sim_context.cc: backout Pin names changing in 2006-04-05 patch until better method can be found. * gui/gui_regwin.cc: fix core dump of ram window and ascii part of register windows not showing all characters. * src/p16f87x.cc: fix eeprom being initialized twice for most p16f87x processors. 2006-04-08 Roy Rankin * src/pic-processor.h src/pic-processor.cc src/p16f87x.h p16f87x.cc: Add support for p16f87xA which are p16f87x with 2 comparators and vref. * src/p16f62x.h src/p16f62x.cc src/Makefile.am src/pir.cc src/pir.h: new files src/comparator.h src/comparator.cc to add comparator and vref functions. * new directory regression/comparator with new files compar_628.asm compar_628.stc compar_877a.asm compar_877a.stc compar_873a.asm compar_873a.stc Makefile 16f628.lkr 16f877a.lkr 16f873.lkr for comparator regression tests. * regression/run_regression.sh: invoke comparator regression tests 2006-04-05 Roy Rankin * src/ioports.h src/ioports.cc : Fix setEnableMask() so it works when pin is already added. Stop memory leak in newDefaultControl(). * src/pic-ioports.cc: setTris() can be run multiple times. * src/p16f62x.cc src/cod.cc: Correct error in Oscillator configuration bit processing. Pins 5, 6 and 7 of port A may be I/O depending on configuration bits. Pin names changed depending on configuration bits. * src/p16x6x.cc: Bit 5 of port A is I/O for all of 16X6x family p16x63 and higher. * src/eeprom.h src/eeprom.cc src/p16f87x.cc: fix bugs in writing to EEPROM and added FLASH program writing using wide mode (p16f87x). * regression/run_regression.sh: add directory regression/eeprom_wide with files Makefile, 16f873.lkr, eedate_wide.asm and eeprom_wide.stc for regression testing of EEPROM and FLASH single byte wide read-write operations. 2006-03-30 Scott Dattalo * gui/gui_regwin.cc: In 03-27 changes, a variable initialization got commented out and caused a segv on some systems 2006-03-30 Scott Dattalo * src/14bit-registers.h, src/14bit-registers.cc: Resetting the program counter low register (PCL) was causing the cycle counter to advance by one. 2006-03-29 Scott Dattalo * gui/gui_src_asm.cc, gui/gui_src.h: Source files are now only parsed whenever they're brought into view. (The previous commit parsed the source, but only placed it into a gtk_text_view whenever the source was brought into view). * src/processor.cc: Config addresses in the .lst file were causing a segv when the list file was processed. 2006-03-28 Scott Dattalo * gui/gui_src_asm.cc, gui/gui_src.h: - If there are many source files, the notebook will now allow the tabs to be scrolled. - Source files are now only rendered whenever the page in which they reside is brought into view. (Otherwise, large projects will take a very long time to load). 2006-03-27 Scott Dattalo * gui/gui_watch.cc: - Watch window was causing segv for the case when a watched register did not have an entry in the symbol table. - Fixed a bug where the "hex" attribute was being repeatedly added to the eXdbm data base. Note this fix was only applied to non-WIN32 OSes * gui/gui_regwin.cc, gui/gui_regwin.h: The register window cells were not getting resized correctly whenever the font was changed. Also, the default font was changed to Monospace. 2006-03-24 Scott Dattalo * src/symbol.h, src/symbol.cc: Added a convenience function for searching the symbol table for strings. * src/processor.h, src/processor.cc: Change FileContext::Add method to accept only a const char *. 2006-03-24 Scott Dattalo * src/processor.h, src/processor.cc: The FileContext class now handles list files. * gui/gui_src_asm.cc, gui/gui_src.h, gui/gui_menu.cc: Breakpoints can be manipulated through the list file view of the source browser. Switching pages in the source browser now updates the margin. The preferences editor 'Margins' and 'Tabs' were combined into just 'Margins'. 2006-03-22 J.R. Heisey * cli/input.cc, gui/gui_symbols.cc: use glib's g_strndup() instead of strndup. 2006-03-22 J.R. Heisey * gui/gui_src_asm.cc: Last change cause segv in preferences editor. 2006-03-22 J.R. Heisey * src/cod.cc, src/pic-instructions.cc, src/processor.cc, src/processor.h: Fixed list file processing. Now the file context class knows if it owns a .lst file versus a .asm or .inc file. * gui/gui_src.h, gui/gui_src_asm.cc: List files are now displayed in the source browser. The program counter indicator tracks correctly. Breakpoints can not be controlled from within the list file view yet. Changed strndup calls to g_strndup. The form is a GNU extension while the latter is part of glib, but both do the same thing. This removes an OS dependency. 2006-03-21 Scott Dattalo * gui/gui_object.cc: removed debug printf * gui/gui_src_asm.cc: Added a delete_event handler for the source browser; killing the source browser window was causing gpsim to crash otherwise. The source browser name has been updated to match the old browser's name (this is mainly for registry and .gpsim settings). Added GTK_WAIT's for slower machines. Apparently gtk's event queue is getting overwhelmed while the source browser is being created. 2006-03-21 Borut Razem * src/cod.cc: fixed bug "[ 1448454 ] usart_test - ERROR: == comparison is not defined for String" by merging "assertions" and "assertions" lists to a single "directive" list 2006-03-20 Scott Dattalo * regression/breakpoints.asm: Embedded script error was causing regression test to fail. * regression/rt.sh: Minor fix to Borut's regression test enhancement; the 'tee' command was appending multiple regression tests to the same log file. Also, on Athlon 64's, the tee command was causing pipe errors for some reason. 2006-03-19 Scott Dattalo * gui/gui_menu.cc, gui/gui_src.h, gui/gui_src_asm.cc: The preferences window now configures the source browser tabs, margins, and font. 2006-03-19 Borut Razem * plat/win32/gpsim.nsi: added share and lib\gtk-2.0\2.4.0\engines to the package, use share\themes\MS-Windows\gtk-2.0\gtkrc as the default gtkrc * gpsim/regression/rt.sh: failure detection 2006-03-15 Scott Dattalo * gui/gui_src.h, gui/gui_src_asm.cc: Added .lst files to the source browser. Added the "ColorHolder" class to wrap a GdkColor that can be changed and reverted back to its original value. The colors for the source browser are now saved. Line numbers, addresses, and opcodes in the margin can be selectively enabled * gui/gui_menu.cc: Example code for src browser configuration is now rendered in a SourcePage. * gui/gui_statusbar.cc, gui/gui_main.cc, gui/gui.h, gui/gui_regwin.cc, gui/gui_break.cc, gui/gui_profile.cc: The global 'gp' has been renamed gpGuiProcessor. 2006-03-15 Alain Portal * src/p12.h: Remove redundant class scoping (causes errors with gcc-4.1) 2006-03-14 Borut Razem * src/dspic/makefile.mingw: added * plat/win32/gpsim.nsi: fixed typo 2006-03-13 Scott Dattalo * src/processor.cc: hex files were not getting loaded properly. 2006-03-12 Scott Dattalo * src/pic-ioports.cc: PIC TRIS writes were not getting traced. 2006-03-12 Borut Razem * config_win32.h.in: added #define _USE_MATH_DEFINES, so that M_PI is defined in MSVC math.h 2006-03-12 Scott Dattalo * gui/gui_src.h, gui/gui_src_asm.cc, gui/gui_menu.cc: - Gui Preferences for source browser is *almost* working now. It's possible to modify colors, but the state of the colors are not being saved in the gpsim config file. Also, the line number, address, opcode configuration is not completed. - The Source browser now utilized the text_view margin for displaying addresses and opcodes. Also, breakpoints changes the margin field text to red. (This duplicated the diamond indicator, but I plan to use that for modifying complex breakpoints). 2006-03-12 Borut Razem * plat/win32/gpsim.nsi, doc/gpsimWin32.html, plat/win32/make.mingw, cli/makefile.mingw, gpsim/makefile.mingw, gui/makefile.mingw, modules/makefile.mingw: glib-2.8.6, gtk+-2.8.13, pango-1.10.2, atk-1.10.3, cairo-1.0.2, ... 2006-03-09 Borut Razem * examples/modules/usart_gui/usart_gui.asm, examples/modules/usart_gui/usart_gui.stc: Renamed the usart RX and TX pins to RXPIN and TXPIN 2006-03-07 Scott Dattalo * src/gui_src_asm.cc: Turned off debugging. Added a gtk event queue wait. * src/gui_processor.h: The default is to now enable the new source browser. 2006-03-06 Scott Dattalo * src/stimuli.cc: The stimulus command without any options now shows more information. In particular, value stimuli (the ones that allow you to specify an array of data) are now shown. 2006-03-06 Scott Dattalo * doc/gpsim.lyx, doc/gpsim.pdf: Updated the documentation to reflect the deprecation of the X command 2006-03-06 Scott Dattalo * gui/gui_menu.cc, gui/gui_src.h, gui/gui_src_asm.cc: Moved the gtk text tag table to the source browser parent class. Added a SourceBuffer class to wrap the text buffers. With these changes, multiple source browsers will share the same text buffers. 2006-03-06 Scott Dattalo * cli/cmd_x.cc: The x command has been deprecated. 2006-03-05 Scott Dattalo * src/stimuli.h: The default Thevenin resistance for an IOPIN was too low. This caused an INPUT only pin to appear as though if it was driving! (Bug reported by Alex Holden). 2006-03-05 Borut Razem * configure.ac: removed GTK+ 1.x leftovers * plat/win32/gpsim.nsi: remove extras/graphic_lcd/* when uninstalling gpsim, added extras/usart_con * extras/usart_con/AUTHORS, extras/usart_con/autogen.sh, extras/usart_con/ChangeLog, extras/usart_con/configure.in, extras/usart_con/COPYING, extras/usart_con/INSTALL, extras/usart_con/Makefile.am, extras/usart_con/makefile.mingw, extras/usart_con/module_manager.cc, extras/usart_con/NEWS, extras/usart_con/README, extras/usart_con/usart_con.cc, extras/usart_con/usart_con.h: receive-only usart module, received characters are printed to the console 2006-03-04 Scott Dattalo * gui/gui_menu.cc, gui/gui_src.h, gui/gui_src.cc: See comment on 2006-02-27. Removed the line numbers from the source browser. Changed the current PC and breakpoint indicator. Also, now clicking on a break indicator toggles a break point. 2006-03-04 Scott Dattalo * src/modules.h, src/modules.cc, src/os_dependent.cc: Changed references from char * to const char * for error strings processing. (Alex Holden reports that on BSD dlerror returns const char * where as on linux it returns plain char *). 2006-03-04 Scott Dattalo * cli/ui_gpsim.cc: GlobalVerbosityAccessor verbose was declared twice! (Thanks to Alex Holden for pointing this out). 2006-02-27 Scott Dattalo * src/processor.cc: FileContext put_address and get_address methods were ignoring the last line of files. * gui/gui_src.h: Rewrote the source browser using the gtk+-2.X API. *** NOTE *** The older version of the source browser is still present and enabled by default. To enable the new browser, 'NEW_SOURCE_BROWSER' needs to be defined. (This can either be accomplished by ./configure or by editing gui/gui_processor.h * gui/gui.h, gui/gui_processor.h: Added new source window class to list of gui classes. * gui/gui_menu.cc: ifdef'd removed the source browser preference configuration (for now) * gui/gui_object.cc, gui/gui_object.h: set_name() now requires const char * instead of just char *. 2006-02-25 Borut Razem * src/p18x.cc: EEPROM sfr registers were not mapped on 16 bit pics 2006-02-20 Borut Razem * src/os_dependent.cc: reverted changes I made 2006-02-19, since the GPSIMPATH functionality was already implemented 2006-02-20 Scott Dattalo * src/symbol.cc: Symbol_Table::clear() crashes when the simulation engine is used as a stand alone library (Reported by David Saxtion). 2006-02-19 Borut Razem * regression/switch_test/switch_test.stc, examples/modules/usart_gui/usart_gui.stc: removed .so extension from "module library libgpsim_modules.so" so that it runs on WIN32 platform * src/modules.cc: made ModuleLibrary::MakeCanonicalName() a dummy method on WIN32 platform. Is it really needed on *nix? * src/os_dependent.cc: introduced GPSIM_MODULE_PATH environment variable on WIN32 platform to define additional directories where modules are searched. The search order for WIN32 is as follows: 1. The directory specified by library_name. 2. The current directory. 3. The system directory. 4. The 16-bit system directory. 5. The Windows directory. 6. The directory from which the application loaded followed by directories listed in GPSIM_MODULE_PATH environment variable followed by directories listed in PATH environment variable. 2006-02-17 Scott Dattalo * src/16bit-instructions.cc, src/16bit-instructions.h, src/16bit-hexdecode.cc: Fixed a few bugs with the newly added extended instructions. * src/16bit-processors.cc, src/16bit-processors.cc, src/16bit-registers.cc: added the pclatu register. * src/pic-instructions.cc: the instruction class constructor now initializes most of it's data members directly. * regression/make.regression: .cod files are now removed for the 'make clean rule' * regression/run_regression.sh, regression/p18f/18f452.lkr, p18f/Makefile, p18f/extended_instructions.asm, p18f/instructions.asm, p18f/startup.stc: Regression test for the 18f extended instructions. 2006-02-16 Borut Razem * plat/win32/libgpsim.def: MSVC sync 2006-02-14 Scott Dattalo * src/16bit-instructions.cc, src/16bit-instructions.h, src/16bit-hexdecode.cc: Added support for the extended instructions ADDFSR, ADDULNK, CALLW, MOVSF, MOVSS, SUBFSR, and SUBULNK, in the 18fxxxx family. 2006-02-13 Scott Dattalo * src/gui/gui_menu.cc: more source browser experiments. 2006-02-08 Scott Dattalo * modules/usart.cc: Renamed the usart RX and TX pins to RXPIN and TXPIN. The old names conflict with the names of constants. (This is a problem with absolute mode code.) Updated the gui to use gtk_text_view instead of the obsolete gtk_text. (note this change really needs to be made for all of gpsim's gui!) 2006-02-08 Scott Dattalo * src/dspic/dspic-instructions.cc, src/dspic/dspic-instructions.h: Support for some versions of the MOV instruction. 2006-02-05 Scott Dattalo * src/dspic/dspic-instructions.cc, src/dspic/dspic-instructions.h, src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h, src/dspic/dspic-registers.cc, src/dspic/dspic-registers.h: Unified the Literal and Register Direct addressing modes. Added support for the Status register. Program counter tracing is now supported. 2006-02-04 Scott Dattalo * src/dspic/dspic-instructions.cc, src/dspic/dspic-instructions.h, src/dspic/dspic-processors.cc: Added support for the Literal, Register Direct, and Register Indirect addressing modes. 2006-02-03 Roy Rankin * src/processor.cc, src/pic-processor: The pic-processor class was over-writing the cycles_per_instruction value in the processor class * modules/switch.cc, modules/switch.h, modules/resistor.cc, regression/switch_test/switch_test.stc, regression/switch_test/switch_test.asm: Switch modules now handle analog inputs and RC loads. 2006-01-30 J.R. Heisey * src/processor.cc, src/processor.h: added methods for mapping register addresses into register indexes (for the dspic) and use this to create invalid registers. * src/registers.cc: contructors now propagate calls to parents * gui/gui_regwin.cc: a non-existent register at address 0 was crashing the register window * src/dspic/dspic-instructions.cc, src/dspic/dspic-instructions.h, src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h, src/dspic/dspic-registers.cc, src/dspic/dspic-registers.h: dspic port: -- added register memory -- added W0-W15 -- invalid registers populate register space -- added Program Counter -- single stepping works. -- GOTO, RCALL and BRA instructions are now supported. 2006-01-25 Roy Rankin * gui/gui_profile.cc: fix core dump 2006-01-29 J.R. Heisey * makefile.mingw, src/makefile.mingw, gpsim/makefile.mingw, plat/win32/make.mingw: added dspic to MINGW 2006-01-27 Scott Dattalo * src/dspic/dspic-registers.cc, src/dspic/dspic-registers.cc: added to CVS - initial support of dspic family registers * src/dspic/Makefile.am: dspic-registers added * src/dspic/dspic-instructions.cc, src/dspic/dspic-instructions.h: stubbed out the entire dspic instruction set. * src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h: added initialization code to allow the dspic to be instantiated. * src/hexutils.cc: fixed two buglets introduced in earlier checkin * src/pic-instructions.cc: the invalid_instruction constructor now calls the Instruction constructor. * src/processor.cc: The disassemble method can now accommodate the dspic's 24-bit opcodes. 2006-01-27 Scott Dattalo * configure.ac: changed version from 0.21.11 to 0.21.12-pre * cli/scan.ll: conditionally use YY_* macros. 2006-01-27 Scott Dattalo * Makefile.am, configure.ac, src/Makefile.am: update makefiles for dspic support. * src/dspic/Makefile.am, src/dspic/dspic-instructions.cc, src/dspic/dspic-instructions.h, src/dspic/gpsim_modules.cc, src/dspic/dspic-processors.cc, src/dspic/dspic-processors.h: Initial infrastructure for dspic port. * src/hexutils.h: New file. * src/hexutils.cc, src/program_files.cc: Hex files generated by gpasm and mpasm are really Intel hex files. The hex files generated by the gcc-pic30 tool chain also generate Intel hex files. Now gpsim supports more of the features of the Intel hex file format. * src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h: minor changes to deal with Hexfiles. * src/p16x6x.cc: TMR1L and TMR1H were named as just tmrl and tmrh 2006-01-21 Borut Razem * src/stimuli.cc: fixed bug exposed by resistor regression test, see the comment "; the following test for a core dump bug" in regression/resistor/resistor.asm * cli/cmd_module.cc: added missing paramterer to DisplayMessage() call 2006-01-20 Borut Razem * plat/win32/libgpsim.def: MSVC sync * src/gpsim_object.h: removed empty destructor from class BreakType in order to avoid gcc warning: `class BreakType' has virtual functions but non-virtual destructor * src/breakpoints.cc: changed // comments to /**/ in order to avoid gcc warning: multi-line comment * src/cod.cc: removed gcc warning: unused variable 'pCli' * src/os_dependent.cc: removed gcc warning: 'bAltPaths' defined but not used * program_files.cc: removed gcc warning: 'iReturn' might be used uninitialized in this function * src/stimuli.cc: removed gcc warning: 'pPinSymbol' might be used uninitialized in this function and warning: 'pMod' might be used uninitialized in this function * value.cc: removed gcc warning: statement has no effect * src/ValueCollection.cc: removed gcc warning: unused variable 'uUpperBound' * src/lxt_write.c: removed gcc warning: 'lt_emit_u64' defined but not used * src/modules.cc: removed gcc warning: extra tokens at end of #endif directive * plat/win32/icd.c: removed gcc warning: 'use_icd' defined but not used * gui/gui_breadbord.cc: removed warning: 'orientation' might be used uninitialized in this function warning: 'pin_x' might be used uninitialized in this function warning: 'pin_y' might be used uninitialized in this function warning: 'label_x' might be used uninitialized in this function warning: 'label_y' might be used uninitialized in this function * gui/gui_menu.cc: removed gcc warning: unused variable 'start' warning: unused variable 'end' warning: unused variable 'color' warning: unused variable 'tag' warning: unused variable 'cParray' * gui/gui_src_asm.cc: removed gcc warning: unused variable 'dragbreak' warning: unused variable 'dragstartline' warning: unused variable 'dragwidget_oldy' warning: unused variable 'dragwidget' warning: unused variable 'dragwidget_x' warning: 'gint drag_scroll_cb(void*)' defined but not used warning: 'void text_insert(SourceBrowserAsm_Window*, int, GtkStyle*, char*, int)' defined but not used * gui/gui_watch.cc: warning: unused variable 'uBitmaskForMaskedValue' 2006-01-20 Scott Dattalo * src/trigger.cc, src/breakpoints.cc: Breakpoint messages were not getting printed when execution breakpoints were hit. 2006-01-19 Scott Dattalo * cli/parse.yy, cli/cmd_break.cc, cli/cmd_break.h, src/breakpoints.cc Rewrote breakpoint parsing. gpsim recently introduced an expression option for breakpoints. As this feature was refined, it turned out that the best way to handle expressions was with a two level approach. At the high level, there is a 'break condition', e.g. 'break w MyVariable'. The condition in this case is to break if the variable 'MyVariable' is written to. At the next level, there is a qualifying expression. For example: break w MyVariable, ((PC > IntVector) && (PC * src/errors.h, src/sim_context.cc: Slight clean up to Roy's patch. 2006-01-12 Roy Rankin * src/modules.cc: remove library load failure exception throw. In Linux, a failed module library load command from the command window repeats the error message already printed. Even worse, if the failure occurs fromthe breadboard GUI "Add libs" function, gpsim crashes. * src/os_dependent.cc: Fix up error handling on library loads for Linux. Also for readability changed #ifndef _WIN32 to #ifdef _WIN32 reversing the cases. 2006-01-10 J.R. Heisey * modules/led.cc, modules/led.h: Added dynamic gui update to the led modules. 2006-01-07 Scott Dattalo * regression/resistor/resistor.asm: Tiny comment change * regression/run_regression.ch: Added the resistor regression test to the test suite. 2006-01-07 Roy Rankin * modules/resistor.cc: Pulldown resistor voltage is now set to 0 Volts. * src/stimulus.h, src/stimuli.cc: Adjusted default resistance values for stimuli to more closely match PIC I/O pins. * regression/resistor/resistor.asm: Set pulldown resistance for the pulldown resistor. 2006-01-06 Roy Rankin * src/stimuli.cc: Fixed crash regarding module pin names. * regression/resistor/Makefile: New regression test for the resistor module. * regression/resistor/resistor.asm: * regression/resistor/resistor.stc: * regression/resistor/16f873.lkr: 2006-01-02 Scott Dattalo * src/ui.h, src/ui.cc: added another method for formatting registers (though this might be removed later). * src/value.h, src/value.cc: Moved Value specific breakpoint functionality to the Value class. Fixed typo in an error message. * src/symbol.cc, src/symbol.h: Fixed a bug with clearing the symbol table. - Added breakpoint expression compilation to the register_symbol class (this was previously being handled in cli/cmd_break.cc). - The w_symbol now is printed out as a W register. * src/module.h, src/processor.h: moved the register_size and register_mask methods from the processor class to the module class. (Modules can have regsiters too!). * src/p16x7x.cc, src/p16x6x.cc, src/p16x5x.cc, src/p16f87x.cc, src/p16f62x.cc, src/16bit-processors.cc, src/14bit-processors.cc: W was not getting added to the symbol table. * src/gpsim_time.cc: stopwatch changes to conform to value class api. * src/breakpoints.cc, src/breakpoints.h: cleaned up/fixed printout of register breakpoints. Added a more generic 'set_break()' method that replaces several other specific methods (the old ones haven't been removed yet). * cli/parse.yy: certain read and write break points were not getting parsed properly. * cli/scan.ll: echo command was failing to be recognized. * cli/cmd_break.cc: moved most of the expression parsing into the simulation engine. * src/expr.h, src/expr.cc: LiteralSymbols are cast into either registers or program memory address when breaks are set on them. * src/cod.cc: pruned some dead code. * src/tmr0.cc, src/tmr0.h: TMR0 class now conforms to new break API. 2006-01-02 Scott Dattalo * configure.ac, cli/input.cc, cli/socket.cc: add configuration option to inhibit the socket interface. 2005-12-31 Borut Razem * plat/win32/gpsim.nsi: added examples/modules/usart_gui/*.* and extras/graphic_lcd/*.* to the WIN32 setup 2005-12-30 Scott Dattalo * src/value.cc, src/value.h: Clarified error message when user attempts to set or clear breakpoints on register symboles. Also, fixed error message on Integer casts to Booleans. * src/bitlog.h, src/bitlog.cc: Added dump() and dump_ASCII_art() methods to the ThreeStateEventLogger class. These are debug functions used to examine event logs. * modules/usart.cc: Utilize new event logger utilities. 2005-12-28 Scott Dattalo * regression/breakpoints, regression/breakpoints/breakpoints.asm, regression/breakpoints/Makefile, regression/breakpoints/16f873.lkr, regression/breakpoints/breakpoints.stc: Added a regression test for testing breakpoints. (Not much there yet) 2005-12-28 Scott Dattalo * cli/cmd_break.cc, src/breakpoints.cc: gpsim would crash if a break point was set on a register that did not have a symbol table entry. 2005-12-28 Roy Rankin * modules/usart.cc, modules/usart.h: Fixed bugs in mSendByte. Fixed usart attributes. Cleaned up error messages. * modules/usart.cc, modules/usart.h: Added a gui interface to the usart module. * examples/modules/usart_gui/Makefile: New * examples/modules/usart_gui/README: New * examples/modules/usart_gui/usart_gui.asm: New * examples/modules/usart_gui/usart_gui.stc: New. The usart_gui example illustrates the new Usart GUI interface. 2005-12-23 J.R. Heisey * src/symbol.cc: findRegisterSymbol dumped core if a register was being loaded from a module (and not from a processor) * src/os_dependent.cc, src/processor.cc: Relative paths were getting concatenated to absolute paths * src/16bit-processors.cc: ccp1 is now associated with portc2 2005-12-19 Scott Dattalo * src/icd.cc, src/modules.cc, src/pic-processor.cc, src/sim_context.cc, modules/paraface.cc: Re-added needed unistd.h includes that were removed on 2005-12-10. New systems may not unistd, but older ones do. 2005-12-17 Scott Dattalo * cli/input.cc: removed glib dependencies for non-gui builds 2005-12-16 Scott Dattalo * src/ioports.h, src/ioports.cc, src/pic-ioports.h, src/pic-ioports.cc: moved some of the functionality in the PicPort classes upto the generic Port classes. Also added comments. 2005-12-12 J.R. Heisey * src/16bit-instructions.h, src/breakpoints.h, src/pic-instructions.h, src/pic-instructions.cc, src/processor.h, src/processor.cc: fixed gcc errors: processor.h:150: error: using typedef-name `instruction::INSTRUCTION_TYPES' after `enum' 2005-12-10 J.R. Heisey src/registers.h: * src/expr.cc, src/ValueCollections.cc, src/ValueCollections.h: Added toString(ExprList_t*) and move some code from IndexedSymbol::toString() into it. * src/modules.cc, src/modules.h: Added functions for deleting module libraries. * 14bit-processors.cc, src/14bit-processors.h, src/p12x.h, src/16bit-processors.h, src/p16f62x.cc, src/p16x5x.cc, src/p16x5x.h, src/p16x6x.cc,src/p16x7x.cc, src/p16x8x.cc, src/p18x.cc, src/p18x.h, src/Makefile.am, src/makefile.mingw, src/src.vcproj, src/ioports.cc, src/ioports.h, src/pic-ioports.cc, src/pic-ioports.h: Moved PicPortBRegister, PicTrisRegister and PicPortRegister definitions into these files from ioports.cc and ioports.h. Added pic-ioports.cc,h to build files. This was motivated by moving undesirable code for the SWIG script language builds. * src/value.cc, src/value.h: Renamed New() to NewObject() to avoid conflict with SWIG. * src/breakpoints.h, src/interface.h, src/os_dependent.cc, src/pic-instructions.h, src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h, src/stimuli.h, src/trace.h: removed unneeded reference to the header unistd.h. 2005-12-06 Scott Dattalo * src/ioports.h, src/ioports.cc: Cleaned up the IOPORT class and deprecated some old functions. * src/stimuli.cc: use new IOPORT class functions. * modules/encoder.cc, modules/logic.h, modules/paraface.cc, modules/push_button.cc: Updated to new I/O port class api. * gui/gui_src_asm.cc: Removed printf debug 2005-12-05 Scott Dattalo * gui/gui_src_asm.cc: Source browser crashed if there was no instruction at the current PC. * regression/instructions_16bit/18f452.lkr: mchip stock linker script has a bug with hard coded interrupt routine size. 2005-12-04 Robert Pearce * src/p12.cc, src/p12.h: Added pullups to 12bit-core I/O pins 2005-12-03 Robert Pearce * src/p12.cc, src/p12.h, src/pic-processors.cc, src/pic-processors.h: Added the 10F202. 2005-12-02 Scott Dattalo * eeprom.cc, eeprom.h, i2c-ee.cc, i2c-ee.h, registers.cc, registers.h, processors.cc: Extended the RegisterCollection class to support an arbitrary array of Registers. Added CLI access to the EEPROM. Usage: eeData shows all eeprom registers. eeData[expression] shows one or several eeprom registers. * packages.cc, packages.h: Added better support for module pin placement. * gui/gui.h, gui/gui_breadboard.cc, gui/gui_breadboard.h, gui/gui_main.cc: Cleaned up package creation in preparation for a graphic LCD module. 2005-11-27 Borut Razem * plat/win32/gpsim.nsi, plat/win32/make.mingw, cli/makefile.mingw, gpsim/makefile.mingw, gui/makefile.mingw, modules/makefile.mingw, src/makefile.mingw, regression/README: MINGW sync 2005-11-22 J.R. Heisey * cli\cmd_log.cc gui\gui_regwin.cc src\init.cc src\pic-processor.cc, src\trace.cc src\trace.h: Changed references of trace_log to GetTraceLog() to decouple the global trace_log in the libgpsim.so/dll from the executable. Please do the same with any other globals you find and that I missed. src\expr.cc: Implemented dumping a range of an indexed variable using the integer range operator. (i.e. ramData[3:20] 2005-11-21 J.R. Heisey * src\symbol.cc src\symbol.h src\ValueCollections.cc src\ValueCollections.h: Fixed couple bugs and added additional support for ndexable variables. * src\value.cc src\value.h: Fixed bitmask issue with the copy constructor of Integer. Added assignment operator to Integer from const Integer&. * src\ValueCollections.cc src\ValueCollections.h again: Implemented the omitted ability to do array=value and array[range]=value. 2005-11-21 J.R. Heisey * src\12bit-processors.cc, src\breakpoints.h, cli\cmd_break.cc, cli\cmd_clear.cc, src\cmd_gpsim.h, cli\cmd_log.cc, cli\cmd_run.cc, cli\cmd_set.cc, gpsim\CopyDlls.bat, src\exports.h, src\fopen-path.h, plat\win32\gpsim.def, plat\win32\libgpsim.def, src\gpsim_interface.h, src\gpsim_time.cc src\gpsim_time.h gui\gui_menu.cc gui\gui_regwin.cc, gui\gui_src_asm.cc gui\gui_trace.cc gui\gui_watch.cc src\hexutils.cc, src\i2c-ee.cc src\icd.cc plat\win32\icd.cc src\icd.h cli\input.cc, src\interface.cc, src\interface.h, gpsim\main.cc, cli\misc.h, src\os_dependent.cc, src\pic-processor.cc, src\pic-processor.h, src\processor.h, src\program_files.cc, cli\scan.ll, src\sim_context.cc, cli\socket.cc, src\stimuli.cc, src\symbol.h, src\trace.h, src\ttoken.cc, src\ttoken.h, cli\ui_gpsim.cc, cli\cli.vcproj, gui\gui.vcproj, src\src.vcproj, gpsim\gpsim.vcproj: These changes are for building the files in the src folder as the library libgpsim.dll under Windows. There were a couple of global variables that needed to be decoupled with accessor functions for access from gpsim.exe and other modules. I found that putting global variables in the gpsim.def file didn't work. The globals needing accessor functions were realtime_mode, reatime_mode_with_gui, verbose, and use_icd. I also needed to create the NullConsole and NullUserInterface class in src. These provide IConsole and IUserInterface objects with no implementation. Now cli in gpsim.exe creates it own implementation and passes it to the function SetUserInterface(). Any other application that links to libgpsim.dll and expects test messages will need to pass there own IConsole and IUserInterface implementations. At some point I hope I (or someone) will clean up all of the cout references and use the GetUserInterface() function. Renamed macros in exports.h from GPSIM_DLL_EXPORT, GPSIM_EXT_CLASS, and GPSIM_EXPORT to added the LIB prefix reflecting the new library file. Created a new file libgpsim.def and moved all the symbols from gpsim.def into it. Emptied gpsim.def of all symbols. References to bp now call get_bp(). References to ui now call 2005-11-13 Scott Dattalo * gui/gui_menu.cc: The experimental Preferences window caused a crash if it was opened, but the source browser was not opened. 2005-11-13 Borut Razem * plat/win32/gpsim.def: MSVC sync * modules/switch.cc: added #include 2005-11-12 Scott Dattalo * cli/input.cc, cli/scan.ll: Under certain conditions, command assertions were causing the lexer to get confused. * gui/gui_menu.cc: experiment code with preferences. * src/ioports.cc, modules/encoder.cc, modules/paraface.cc, modules/push_button.cc: Calls to Stimulus_Node->update() method unnecessarily passed the current simulation time. * modules/resistor.cc, modules/resistor.h: The pullup resistor module was completely broken. * modules/switch.cc, modules/switch.h: The switch module never did work, but now it does! This is now truly a two-port device. * src/gpsim_time.cc, src/gpsim_time.h: Added methods to control the real time to simulated time mapping. * src/breakpoints.cc: Command Assertions were unnecessarily adding an extra '\n' to the end of the command string. * src/stimuli.cc, src/stimuli.h: Originally node updates would update the node state and refresh connected stimuli all within the context of a single method. Now this has been split into two methods. This was added to support the switch module. In addition, the new method 'getThevenin()' retrieves the full electrical state of a stimulus. 2005-11-09 Robert Pearce * src/pic-processor.cc, src/processor.cc: Update simulation time base when ever the processor's oscillator frequency is changed. 2005-11-08 Borut Razem * makefile.mingw: MINGW sync 2005-11-06 J.R. Heisey * src/cmd_gpsim.h: Ability to format a value using a bit mask. * cli/cmd_symbol.h: Routines to dump and set an indexed value. * cli/cmd_x.cc cli/cmd_x.h: Lets use set reg(2)=expr. * src/processor.h: Implemented new function Processor:: ConstructInvalidInstruction() function to allow derived classes to define there own Invalid instruction types. * src/expr.cc src/expr.h, src/ValueCollections.cc,h, src/symbol.cc src/symbol.h: Implemented classes to expose to the command prompt interface an indexed variable symbol type commonly refered to as arrays. * cli/scan.ll, cli/parse.yy: Implemented the parsing of indexed (array) variables in the command language. RAM, EEPROM and ROM are the first ones. (i.e. RAM[$20]) * cli/scan.ll: Implemented strings as single quotes as well as double quotes. * Fixed issue where setting a RAM value from the command prompt would not update the GUI windows. * cli/parse.yy: Allow setting a RAM using the reg() operator. (i.e. reg(3)=54) * src/value.cc src/value.h: Added extra operators for Integer and Float. Also added a bitmask for Integer to be used for display purposes. * src/registers.cc,h: Implemented RegisterCollection class. * src/sim_context.cc: In CSimulationContext::Clear() now clear the symbol table after I delete the processors in the processor list. This provents the symbol table from deleting a symbol that is actually owned by the processor. 2005-11-02 Robert Pearce * src/tmr0.cc, src/stimuli.cc: Fix TMR0 external clocking ploarity. Fixed a typo in IOPIN::getBitChar(). 2005-10-24 Scott Dattalo * src/gpsim_time.cc, src/gpsim_time.h: Fixed a nasty cycle counter bug that would erroneously clear a break point whenever two breaks were set at the same cycle. * src/interface.cc: Interface callback breakpoint now can display a message in the breakpoint list. * src/p16x6x.cc, src/p18x.cc, src/pir.cc, src/pir.h, src/14bit-tmrs.cc, src/14bit-tmrs.h, src/16bit-processors.cc: The whole "pir_set" design needs to be re-implemented. At issue is that every pic potentially has a different bit mapping for the PIR registers. The pir_set desgin attempts to accommodate this with pure VF's. Unfortunately, peripherals like the TMRL class that need to set PIR bits only can call specific methods like "set_tmr1f()". However, the TMRL class is used as a base for TMR3 too! I created a new class called "InterruptSource" that can trigger interrupts instead. 2005-10-21 Borut Razem * makefile.mingw, plat/win32/makefile.mingw, plat/win32/make.mingw, plat/win32/gpsim.nsi: building gpsim setup executable on WIN32 2005-10-20 Scott Dattalo * regression/make.regression: modified the default make target to create a .cod file * regression/tmr0_16bit/Makefile, regression/tmr0_16bit/tmr0_16bit.asm: Added tests for 16bit mode of tmr0. * regression/tmr0_16bit/delay.inc, regression/tmr0_16bit/delay.asm: Added to CVS. Made the delay routine a separate source module. Also, a DELAY macro has been created so that exactly N cycles can be delayed, where 0 < N < 65536+15. * src/16bit-processors.cc: portd and porte registers were not getting added to the symbol table. 2005-10-14 Scott Dattalo * regression/tmr0_16bit/tmr0_16bit.asm: Interrupt test assertions. 2005-10-13 Borut Razem * makefile.mingw, doc/makefile.mingw: building gpsim documentation on WIN32 2005-10-13 Scott Dattalo * gpsim/main.cc, cli/cmd_load.cc, cli/cmd_macro.cc, cli/input.cc, cli/socket.cc: command assertions were not getting processed immediately. * regression/tmr0_16bit/tmr0_16bit.asm: Started interrupt test. 2005-10-12 Borut Razem * regression/make.regression, regression/run_regression.sh, regression/*/Makefile: added possibility to define gpism path 2005-10-12 Scott Dattalo * src/16bit-registers.cc, regression/tmr0_16bit/tmr0_16bit.asm: The high byte of TMR0 was not getting updated during TMR0L reads. 2005-10-11 Scott Dattalo * src/pic-instructions.cc, src/pic-instructions.h: Added methods to the instruction class that provide acces to the source defining an instruction (this is going to be used with tracing and disassembly soon). 2005-10-11 Borut Razem * regression/usart_test/usart_test.asm, regression/logic_test/logic_test.asm, modules/makefile.mingw, gui/gui_breadbord.cc, plat/win32/gpsim.nsi: gpsim_modules.dll renamed to libgpsim_modules.dll 2005-10-09 Scott Dattalo * regression/tmr0_16bit/tmr0_16bit.asm: More tmr0 regressions testing * src/cod.cc, src/breakpoints.h, src/breakpoints.cc: Added the CommandAssertion class. These are assertions that are associated with instructions in such a way that when an instruction executes, the command assertion will issue a gpsim command line command. * gpsim/main.cc: removed a debug printf. * cli/input.cc, cmd_macro.cc, cli/ui_gpsim.cc: command assertions were getting inserted into the end of the command line input stream as opposed to interjected immediately. 2005-10-10 Scott Dattalo * gpsim/main.cc, cli/cmd_load.cc, cli/cmd_symbol.cc, src/symbol.cc, src/symbol.h: Simplified the way user defined symbols are added to the symbol table. 2005-10-09 Borut Razem * plat/win32/fd2raw.cpp, cli/input.cc: win32_set_is_readable() not needed for glib >= 2.6 * src/sim_context.cc, src/i2c_ee.cc: fixed the p12ce518 regression test problem * cli/socket.cc: g_io_channel_set_flags() not implemented on WIN32; call it only on non-WIN32 platforms or if _DEBUG 2005-10-08 Scott Dattalo * src/tmr0.cc, regression/tmr0_16bit/tmr0_16bit.asm: tmr0 clear_break was getting called recursively. The tmr0 regression test now checks psa combinations. 2005-10-08 Robert Pearce * src/p12x.cc, src/p16x5x.cc, src/p16x5x.h, src/stimuli.cc, src/tmr0.cc, src/tmr0.h: Added support for clocking TMR0 from an external source. This applies to the 12-bit core where TMR0 is a dedicated pin. 2005-10-08 Borut Razem * src/processor.cc: fixed the "processor list" problem * gpsim/makefile.mingw, gpsim/gpsim.vcproj, plat/win32/gpsim.nsi, doc/gpsimWin32.html: linking with libgtkextra-win32-2.1_dll.lib, using gtkextra-win32-2.1.dll 2005-10-07 Borut Razem * plat/win32/gpsim.nsi: Changed version to 0.24.11 2005-09-23 J.R. Heisey * cli/parse.yy: Added to string_option the ability to use a string variable. This will apply to any command that uses the string_option. I specifically added it for module library. 2005-10-03 Scott Dattalo * configure.ac: Changed version to 0.24.11 2005-10-03 Scott Dattalo * src/12bit-processors.cc, src/14bit-processors.cc, src/14bit-tmrs.cc, src/16bit-registers.cc, src/p12x.cc, src/p16f62x.cc, src/p18x.cc, src/pic-processor.cc, src/tmr0.cc: Debug cleanups. 2005-10-03 Scott Dattalo * gui/gui_menu.cc: More source browser preference configuration. * gui/gui_regwin.cc: Turned register sheet rows and columns back on. (They were off because of a bug in gtkextra, but that bug is fixed now). * src/16bit-processors.cc, src/16bit-registers.cc, src/p18x.cc, src/tmr0.cc: The create+sfr_map() method was getting called twice fof the p18f devices. T0CON was not retaining its 0xff reset value. TMR0L was reporting the wrong value while it was turned off. * regression/run_regression.sh, regression/tmr0_16bit/18f452.lkr, regression/tmr0_16bit/Makefile, regression/tmr0_16bit/tmr0_16bit.asm, regression/tmr0_16bit/tmr0_16bit.stc: Added a regression test for TMR0. 2005-10-02 Borut Razem * gui/makefile.mingw: Updates to support user defined preferences. * doc/gpsimWin32.html: Use CSS 2005-10-01 Scott Dattalo * src/processor.cc: Changed Processor::init_program_memory_at_index() so a derived processor can define its own bad_instruction type. Fixed a crashing bug in trim() when a empty was passed in. 2005-09-30 Scott Dattalo * gui/gui_menu.cc, gui/gui_src.h, gui/gui_src_asm.cc: Source browser clean up. 2005-09-29 Scott Dattalo * gui/gui_menu.cc, gui/gui_src.h, gui/gui_src_asm.cc: More preferences work; now the colors for the source browser example text can be configured (this configuration doesn't map back into the source browser yet). 2005-09-28 Scott Dattalo * src/16bit-registers.cc, src/16bit-registers.h, src/tmr0.cc, src/tmr0.h: The high byte of TMR0 for the 18F family was not updating correctly in certain circumstances (like during single stepping). Thanks to Robert Merkel for reporting this issue. 2005-09-27 Scott Dattalo * gui/gui_menu.cc: Even More work on preferences dialog window. 2005-09-26 Scott Dattalo * gui/gui_menu.cc: Even More work on preferences dialog window. 2005-09-26 Scott Dattalo * gui/gui_menu.cc: More work on preferences dialog window. 2005-09-25 Robert Pearce * src/p12x.cc, src/p12x.h, src/p16x5x.cc, src/p16x5x.h, src/pic-processor.h, src/pic-processor.cc: Added support for the 16C56 and the 10F200. 2005-09-23 Scott Dattalo * src/breakpoints.cc: Breakpoint numbers are now printed in decimal. 2005-09-23 J.R. Heisey * cli/ui_gpsim.cc: Fixed a bug were a reused string was not being cleared before being appended to. *gui/gui_symbols.cc: Added code snippet to truncate multi-line symbol values. 2005-09-21 J.R. Heisey * src/cod.cc: Added an extra test to prevent a error message from displaying when a non cod file attempted. This really should validate that the file is a cod file earlier. 2005-09-20 Scott Dattalo * gui/gui_regwin.cc: GUIRegisterList.register_size was being set improperly. 2005-09-20 J.R. Heisey * gui_processor.cc, gui_processor.h, gui_register.h, gui_regwin.cc, gui_watch.cc: Made changes in Register_Window to and other code to support EEPROM memory window in the same way we now support RAM memory window. 2005-09-19 Scott Dattalo * gui/preferences.cc, gui/preferences.h: New files to support user defined gui preferences. * gui/Makefile.am, gui/gui.h, gui/gui_main.cc, gui/gui_menu.cc, gui/gui_regwin.cc, gui/gui_watch.cc: Updates to support user defined preferences. 2005-09-17 Scott Dattalo * src/14bit-tmrs.cc, src/16bit-registers.cc, src/16bit-registers.h, src/ssp.cc, src/uart.cc, src/uart.h: - Initialized data members of many classes. Thanks to Robert Merkel for uncovering this issue. 2005-09-16 Scott Dattalo * gui/gui_watch.cc: Had to change the way ASCII is checked under windows. 2005-09-16 Scott Dattalo * gui/gui_src_asm.cc: fixed compiler warnings * gui/gui_watch.cc: Removed mask, BP, type, and b15..b0 bit columns. Added a newbit string column. * src/12bit-instructions.h, src/14bit-instructions.h, src/16bit-instructions.h, src/breakpoints.h, src/hexutils.cc, src/pic-instructions.cc, src/pic-instructions.h, src/processor.cc: Fixed disassembly output for shadowed instructions. 2005-09-16 Scott Dattalo * gui/gui.h, gui/gui_main.cc, gui/gui_regwin.cc, gui/gui_regwin.h, gui/gui_watch.cc, gui/gui_watch.h: Added color info to the watch window. Watch window columns are now adjustable. Centralized color processing. 2005-09-15 Scott Dattalo * gui/gui_main.cc, gui/gui_watch.cc, gui/gui_watch.h: The state of the watch window is now preserved from one debug session to the next. 2005-09-14 Scott Dattalo * gui/gui_src.h, gui/gui_src_asm.cc, src/breakpoints.cc, src/breakpoints.h, src/pic-instructions.cc, src/pic-instructions.h, src/processor.cc, src/trace.cc: Fixed usability issues with setting breakpoints through the source browser. The 'Drag Break' feature has been disabled since it really doesn't work too well for assertions (or at least doesn't apply). Fixed a bug that prevented toggling breaks that occur at the current PC. A new class was added to better handle the breakpoint classes. This new class, AliasedInstruction, is a base for the breakpoint class and basically will provide an API to handle aliased or replace instructions. 2005-09-11 Scott Dattalo * plat/win32/gpsim.def: updated for API changes. 2005-09-11 Scott Dattalo * src/ioports.cc, src/ioports.h, src/stimuli.cc, src/stimuli.h, src/value.cc, gui/gui_breadboard.cc, gui/gui_breadboard.h: Attributes can now be updated through the breadboard. Pin states can now be updated through the breadboard. 2005-09-10 J.R. Heisey * src/cmd_gpsim.h, cli/ui_gpsim.cc: Modified one of the FormatProgramAddress() functions in IUserInterface and CGpsimUserInterface. 2005-09-09 Scott Dattalo * src/cod.cc: delete_directory() incorrectly deleted memory. 2005-09-08 J.R. Heisey * configure.ac, plat/win32/gpsim.nsi: bump build number * gui/gui_src_asm.cc, src/value.cc: Fixed crashes when 'Add to watch' menu item is selected with no test selected or with white space selected. 2005-09-07 Scott Dattalo * cli/cmd_load.cc: null pointer fix (was causing core dump in the regression test). * module/usart.cc: added the TxBuffer attribute. * regression/usart_test/usart_test.cc: tested usart module transmitter. 2005-09-07 J.R. Heisey * cli/cmd_load.cc, cli/parse.yy: Fixed a bug in load command where you could not specify both processor and file as literal strings. 2005-09-06 J.R. Heisey * gui_processor.cc, gui_processor.h, gui_register.h, gui_regwin.cc, gui_regwin.h, gui_watch.cc, gui_main.cc: Changed Register_Window:: registers from type GUIRegister* to GUIRegisterList*. Added GUIRegisterList * m_pGUIRegisters to GUI_Processor. Now GUIRegisters are instantiated in a GUI_Processor for that other windows besides the RAM_RegisterWindow. This fixes a bug where you cannot add a register symbol to the watch window unless the RAM_RegisterWindow was opened once. * gui/gui_src_asm.cc, gui/gui_watch.cc: Removed 'Select symbol' pop up menu item since it was broken anyway. Added 'Add to watch' pop up menu item. Select symbol text in the source window, selecting 'Add to watch' will add register symbols to the Watch window. * src/symbol.cc, src/symbol.h: Added findRegisterSymbol() that accepts a const char * as a parameter. gui/gui_main.cc: Call new function GUI_Processor::SetCPU() from GUI_Interface::NewProcessor(). SetCPU() does some additional initialization. * src/value.cc, src/value.h: Added toupper(string&) function. * gui/gui_src_asm.cc: Changed to use new toupper() function due to issues between Windows and Linux. * src/operator.cc: quite some type mismatch warning messages 2005-09-03 Scott Dattalo * src/bitlog.cc, src/bitlog.h: Fixed bugs with the new ThreeStateEventLogger class. * src/uart.cc, modules/usart.h, modules/usart.cc * regression/usart_test/*: added a regression test for the usart * src/symbol.h, src/symbol.cc: attribute symbol can now be used in expressons. 2005-09-02 Borut Razem * doc/gpsimWin32.html: linking with glib-2.6.6, gtk+-2.6.9, pango-1.8.2 2005-09-02 Manuel Bouyer * src/16bit-registers.cc: PCL accesses were using program memory indexes instead of program memory addresses. * src/14bit-tmrs.cc: TMR2:current_value() would return the contents of PR2 even when configured for normal operation. * src/p18x.cc: typo in porte names. 2005-09-01 Manuel Bouyer * src/p18x.cc: Fix crash when an 18F252 is instantiated. * src/gpsim_time.cc: Disabled unnecessary debug printing * src/uart.cc: Fixed spurious uart transmit. Add io sink for Receiver. 2005-08-31 J.R. Heisey * src/processor.cc: Fixed a crashing bug when the --source=disable option is used. 2005-08-30 J.R. Heisey * cli/input.cc: Created function parse_string_only() which will parse the passed in command string with out emptying existing commands from the buffer. Modified LLStack::GetNext() and LLStack::Pop() to not remove the last LLStack object. Fixed memory leak in LLStack::Pop(). * cli/ui_gpsim.cc: Added EOL to injected abort_gpsim_now command. 2005-08-30 Scott Dattalo * src/gpsim_time.h, src/gpsim_time.cc, bitlog.cc: Made the constant 'END_OF_TIME' part of the Cycle_Counter class. This is now used to initialize members of the ThreeStateLogger class. 2005-08-30 Scott Dattalo * src/processor.h, src/processor.cc, src/pic_processor.cc: Fixed step-over feature for the 18F family. 2005-08-30 Scott Dattalo * regression/rt.sh: The new version of the regression test script was not checked in yesterday. This new version creates a simple stc file and invokes a single regression test. It then checks to see if the test was successful. * regression/simulate, regression/create_stc: Removed from CVS. 2005-08-29 J.R. Heisey * src/ioports.cc, src/ioports.h: Added PortModule::getPin(). Fixed a few compiler warnings. src/src.vcproj: Added bit.cc and bit.h. src/stimuli.cc, src/symbol.cc, src/symbol.h: Changed references of IOPORT to PortRegister. 2005-08-29 Scott Dattalo * modules/encoder.cc, modules/logic.cc, modules/paraface.cc, modules/push_button.cc, modules/switch.cc, src/i2c-ee.cc, src/p12x.cc IOPIN::update_direction method now has a refresh option. * src/ioports.h, src/ioports.cc: - Added several options to control when I/O pins refresh their state information (with respect to stimuli that is). - PicPortBRegister::get () had the wrong parameter signature and thus was not getting invoked (the parent get() method was getting invoked instead). * modules/usart.cc: updating to new iopin api. Added new code and removed a bunch dead code and generally cleaned things up - it's still not working yet though. * src/12bit-processors.cc, src/12bit-processors.h, src/p16f62x.cc: pic-processor.cc, pic-processor.h, processor.h set_config_word now returns true if the config word address is successfully set. * src/pic-processor.cc: Fixed bug with init_program_memory_at_index() - it was not setting the configuration word if the address was in configuration memory. * src/bitlog.cc: Added a 'ThreeStateEventLogger' that's analogous to the bit and byte logger. * src/intcon.cc: Turned off some debugging code. * src/registers.h: fixed typo in comment * src/stimuli.cc, src/stimuli.h: Iopin's were checking Z state before W state - this caused a W-state condition to be returned as a Z-state. In addition, the getDrivingState() was being checked as opposed to the getDrivenState(). - Added getMonitor() method. * src/uart.h, src/uart.cc: Updating to new I/O pin design. And numerous changes to clean up and fix the code - this is still not working though. 2005-08-23 Scott Dattalo * run_regression.sh, rt.sh: Redesigned the regression tests to make use of new gpsim scripting features. Also, all tests have been converted from absolute-mode to object-code mode. * digital_stim/digital_stim.asm, digital_stim/digital_stim.stc * instructions_12bit/instructions_12bit.asm * instructions_12bit/instructions_12bit.stc * instructions_14bit/instructions_14bit.asm * instructions_14bit/instructions_14bit.stc * instructions_16bit/instructions_16bit.asm * instructions_16bit/instructions_16bit.stc * interrupts_14bit/interrupts_14bit.asm * interrupts_14bit/interrupts_14bit.stc * logic_test/Makefile, logic_test/logic_test.asm, logic_test/logic_test.stc * macro_test/macro_test.asm, macro_test/macro_test.stc * node_test/node_test.asm, node_test/node_test.stc * p12ce518/p12ce518.asm, p12ce518/p12ce518.stc * p16f84/p16f84.asm, p16f84/p16f84.stc * p18f452_ports/p18f452_ports.asm, p18f452_ports/p18f452_ports.stc * register_stim/register_stim.asm, register_stim/register_stim.stc * digital_stim/16f84.lkr, digital_stim/Makefile: added * instructions_12bit/12c508.lkr, instructions_12bit/Makefile: added * instructions_14bit/16f628.lkr, instructions_14bit/Makefile: added * instructions_16bit/18f452.lkr, instructions_16bit/Makefile: added * interrupts_14bit/16f84.lkr, interrupts_14bit/Makefile: added * macro_test/16f84.lkr, macro_test/Makefile: added * node_test/16f877.lkr, node_test/Makefile: added * p12ce518/p12ce519.lkr, p12ce518/Makefile: added * p16f84/16f84.lkr, p16f84/Makefile: added * p18f452_ports/18f452.lkr, p18f452_ports/Makefile: added * register_stim/16f84.lkr, register_stim/Makefile: added 2005-08-22 Scott Dattalo * src/ioports.cc: Fixed typo in pullup in setDefaultPullupControl method. 2005-08-21 J.R. Heisey * cli/input.cc, cli/input.h, gpsim/main.cc: Added two command options. Option -E will echo commands to the console. Useful for stc debugging. This will also display all the command line parameters. Useful when another tool launches gpsim but does not display the command line. gpsim/main.cc, src/init.cc: Option '-S disable' will prevent source code from being loaded. Usefule for automated regression testing. '-S enable' will enable source code loading. See online help. * src/p16x7x.cc: Fixed an sign/unsigned warning. * src/processor.h: Test function for whether source file is open. * src/sim_context.cc, src/sim_context.h: Added new global boolean property called EnableSourceLoad. Setting it to false will prevent source code from being loaded. Purpose is when gpsim is used for automated regression testing to speed things up. * src/stimuli.cc: Fixed a crashing bug when port() operator is used with out any module explicitly entered as a parameter. * src/symbol.h, src/value.h: Added findBoolean() to Symbol_Table. * src/value.h: Added a equals operator to Boolean. 2005-08-19 J.R. Heisey * cli/input.cc: Added code to allow stc files with for Windows EOL to be read under Linux. 2005-08-18 J.R. Heisey * src/processor.cc, src/processor.h, src/registers.cc, src/symbol.cc: Added two processor boolean attributes BreakOnValidRegisterRead and BreakOnInvalidRegisterWrite. * src/breakpoints.cc, src/breakpoints.h, src/cmd_gpsim.h, plat/win32/gpsim.def, cli/input.cc, cli/ui_gpsim.cc, gpsim/main.cc: Added -e or --exit command line option that accepts a parameter onbreak. This causes gpsim to exit when the simulation halts. 2005-08-11 Scott Dattalo * src/breakpoints.cc, src/breakpoints.h: Allowed breakpoint expressions for breakpoint instructions to act like assertions. * src/cmd_manager.h, src/cod.cc, src/gpsim_interface.h, src/modules.cc, src/modules.h, cli/input.cc: Added the capability to run multiple module scripts. * cli/ui_gpsim.cc: Fixed bug guint64 formatted output. * regression/logic_test/Makefile, regression/logic_test/logic_test.asm: The new I/O port design more correctly implements I/O pins and this exposed a bug in the regression test. Also, this regression test was used to develop the multiple Module Script feature. 2005-08-11 J.R. Heisey * src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/symbol.h: Quick fix of when trying to attach an input data stimuli that was broken a couple of checkins ago. 2005-08-11 Borut Razem * plat/win32/gpsim.nsi: bump build number 2005-08-11 Scott Dattalo * src/ioports.cc, src/ioports.h: Added the PeripheralSignalSource class to simplify the connection of I/O pins to peripherals. Also, added more documentation about the I/O port design. * src/p16x7x.h, src/p16x7x.cc, src/p16f87x.cc: The Analog to Digital convertor peripheral now connects to I/O pins again. Also, the A2D module was redesigned so that less of the internal implementation is exposed. * src/14bit-tmrs.h, src/14bit-tmrs.cc, src/ssp.h, src/ssp.cc, src/p16x6x.cc: Updated the peripheral connections with the new PeripheralSignalSource class. 2005-08-10 J.R. Heisey * src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/symbol.h, cli/cmd_attach.cc, cli/cmd_attach.h, cli/parse.yy, cli/scan.ll, plat/win32/gpsim.def: Modified the attach command with the pin() and port() operators. Now you can use one of 4 variations of these operators to specify the module, port name and/or pin number that represents the underlying stimulus object. An example of how to use: if a pin number is defined as a program file symbol, you may use the symbol name in the port() or pin() operators. This way your STC file can be more generic and support a variety of firmware code files as long as you use the same symbol name for the pin. See the online help for more details. The pin() operator refers to package based pins. The port() operator refers to port based pins. Other stimulus may still be refered to using just the name of the stimulus. * src/attributes.cc: Changed a few global symbols so that Symbol_Table::Clear() does not remove them. * src/fopen-path.cc, src/fopen-path.h, gpsim/main.cc: Fixed -L source path command line option. Added code to support a gpsim SourcePath global string symbol that give command prompt access to the source search path. * src/ioports.h: Fixed a warning message about the destructor of PinModule not being virtual. * src/symbol.cc,h, cli/cmd_symbol.cc: Added the ability to use the '.' character as a trailing wild card in the symbol command. Example PIC. will list all symbols that begin with the letters PIC. 2005-08-04 Scott Dattalo * gui/gui_breadboard.cc, src/symbol.h, src/symbol.cc, src/stimuli.cc: Verified that template issues with gcc 3.4.X have been resolved and removed a #define that had beed added to get around this. 2005-08-06 Scott Dattalo * src/ssp.h, src/ssp.cc: Updated the SSP peripheral with the new I/O port API. * src/14bit-processors.h, src/p16f87x.cc, src/p16f87x.h, src/p16x6x.cc, src/p16x6x.h, src/p16x7x.cc, src/p16x7x.h: Updated to the new SSP API. 2005-08-04 J.R. Heisey * symbol.cc, symbol.h: Fixed the template compile problems for gcc 3.4.4 due to new bugs in gcc. I didn't see this issue using gcc 3..3.3 on linux. I only have 3.4.4 version of the compiler under cygwin. I've left the #define commented out so someone can test it under linux before removing the #ifdef's. 2005-08-04 Scott Dattalo * gui/gui_breadboard.cc, src/symbol.h, src/symbol.cc, src/stimuli.cc: Backed out some of the symbol changes made by JR because the code doesn't compile on Linux (gcc 3.4.2). At the moment, this means that stimuli and node dumps do not work. 2005-08-04 J.R. Heisey * cli/cmd_node.cc, plat/win32/gpsim.def, gui/gui_breadboard.cc, modules/resistor.cc, src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/symbol.h, src/value.h: Eliminated the node_list and stimulus_list. There are now Symbol_Table functions and iterators available for node_symbol and stimulus_symbol objects which contain Stimulus_Node and stimulus objects respectively. Adjusted the way stimulus and stimulus_Node objects are named. Unnamed objects are not put into the symbol table. The respective new_name() functions will add the objects into the symbol table appropriately. Removes several references that added these objects to the symbol table. Also modified the PullupResister to name the res IO_bi_directional i/o pin to pullupname + ".pin". Now the PullupResister exists in the symbol table as a module with what ever you named it. The pin is attribute of the PullupResister module. Whew! 2005-08-04 Scott Dattalo * src/uart.cc, src/uart.h, src/p16x6x.cc, src/16bit-processors.cc, src/16bit-registers.cc, src/16bit-registers.h, src/p16f62x.cc: Add I/O source and sink connections to the usart peripheral. So now the usart is connected to I/O pins using the new I/O port design. 2005-08-02 J.R. Heisey * src/os_dependent.cc, src/processor.cc,h, src/cod.cc, plat/win32/gpsim.def: Fixed a problem where loading a program file (no STC) using the GUI resulted source code not being found even though that source was in the same folder as the program file. * gui/gui_menu.cc: Fixed the display of cycle count in cycles where %Lx was used in a sprintf instead of the platform independent project macro PRINTF_INT64_MODIFIER. 2005-08-02 Scott Dattalo * src/16bit-processors.cc, src/p18x.cc: The new I/O port register symbols were getting added to the symbol table twice. Also, the eeprom peripheral for some of the 18f devices was not getting created. 2005-08-02 J.R. Heisey src/cmd_gpsim.h * src/cod.cc: Removed an error message from PicCodProgramFileType:: open_a_file() that is handled externally. * src/registers.cc: Fixed a bug in RegisterValue::toString() not displaying enough digits. * src/value.h, src/symbol.h, src/registers.h, gui/gui_register.h: Added some conversion and equals operators. * cli/ui_gpsim.cc, src/cmd_gpsim.h: Added several string formatting routines. * plat/win32/gpsim.def: Updated for new pin I/o routines. * gui/gui_watch.cc, gui/gui_watch.h: Updated display of values to account for uninitialized bits and bit masked register symbols. 2005-08-01 Scott Dattalo * src/p16x5x.h, src/p16x5x.cc: Upgraded the P16C54 and P16C55 to the new I/O port design. * src/16bit-processors.cc, src/16bit-registers.cc, src/16bit-registers.h, src/p18x.cc, src/p18x.h: Completed converting the 16-bit core I/O ports to the new I/O redesign (note - the peripheral-to-I/O mapping still needs to be completed). * src/ioports.h, src/ioports.cc: deprecated the old PIC_IOPORT class and all of its children. 2005-08-01 Scott Dattalo * src/14bit-processors.cc, src/14bit-processors.h, src/14bit-tmrs.cc, src/14bit-tmrs.h, src/intcon.cc, src/intcon.h, src/pir.h, src/p16x6x.cc, src/p16x6x.h, src/ioports.cc, src/ioports.h, src/p16x7x.cc, src/p12x.cc: -- The intcon and pir registers were not getting set up correctly for the midrange devices. -- Added 'sinks' and 'sources' for the CCP module. * src/16bit-processors.cc, src/16bit-processors.h, src/p18x.cc, src/p18x.h: Began porting the new I/O port design to the 16bit core devices. * src/symbol.cc: Added a diagnostic message that is printed whenever a register symbol with a null cpu is added to the symbol table. * regression/run_regression.sh, regression/p18f452_ports.asm, regression/p18f452_ports.stc: -- Added new regression test to test the P18F family I/O ports. -- Redesigned the processor construction sequence. -- The P18F1220 did not have PortB pullup resistors. 2005-07-30 J.R. Heisey * src/symbol.cc, src/symbol.h: Added a list of symbols that are defined from the gpsim command line. The list and the symbol values are preserved when the symbol table is cleared due to a new processor being allocated. Removed the add() function that accepted a symbol type as a string. See comments for cmd_symbol.cc,h. * src/attributes.cc, src/sim_context.cc, src/sim_context.h: Changed or added calls to the symbol table. * cli/ui_gpsim.cc, src/cmd_gpsim.h: Added functions to render integer values to strings based on a system level defined radix. The radix will be exposed as a global attribute. There are distinct radix definitions for program addresses, RAM addresses and data values. Will expose a global attribute to define the prefix for displaying hexidecimal values. The default is '$'. * gpsim/main.cc: Added -D command line option for defining symbols and their values to be placed into the symbol table. * src/value.cc, src/value.h: Added string parsing and constructor functions for each data type. Used for the command line parsing of symbol definitions. * cli/cmd_symbol.cc,h, cli/cmd_load.cc,h, cli/parse.yy: The load command will now accept symbols as input for the filename. Combined with the symbol defines on the command line, one STC file can be used to open any program file by defining a symbol on the gpsim command line and referencing that symbol in the load commmand. * The symbol command can now be used to create a symbol from the gpsim command prompt or an STC file. The syntax is symbol =. Types include string, integer, float and boolean. * gpsim/gpsim.vcproj, gui/gui_menu.cc, gui/gui_regwin.cc: Removed the references for gtk_file_selection_get_filename_utf8(). This was added due to compile time issues with gtkextra-2.1 under Visual Studio .NET. The VS.NET build links a gtkextra static lib into the exe. Even if you can get it to compile, sometimes gpsim will crash before its main() function is entered. The use of gtkextra-2.1 under VS.NET is not recommended and I have reverted the gpsim.vcproj back to gtkextra-2.0. * src/program_files.cc: Changed error handling logic to prevent a "list file not found" error from displaying in an inappropriate situation. 2005-07-29 Scott Dattalo * src/ioports.cc, src/ioports.h, src/p12x.cc, src/p16x6x.cc, src/registers.h, src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/tmr0.cc, src/tmr0.h: Introduced the concept of Multi-State logic to stimuli. 2005-07-15 J.R. Heisey * src/symbol.cc: Added check to prevent a symbol name of a null string from being added as a symbol. * src/stimuli.cc: Added a check to prevent a IOPIN name null string pointer from being added to the symbol table. * modules/resistor.cc: PullupResistor() constructor was setting its attribute before it had set its own name resulting in the attribute name not being scoped correctly. * src/breakpoints.cc, src/breakpoints.h, cli/cmd_break.cc, cli/cmd_break.h: Added code to support break expressions of the form (Reg & mask BoolOp value) where BoolOp includes <, >, <=, >= and != operators. Just need to change the print() and action() console output functions of the break classes and uncomment code in parse.yy. 2005-07-26 Scott Dattalo * src/bit.h, src/bit.cc, src/Makefile.am: Added new files to handle a 'Bit' object. This code was formerly tucked away in registers.cc. * src/stimuli.h, src/ioports.h, src/ioports.cc: Added a control object for the PinModule to handle I/O pin pullups. Also, added an option to prohibit certain stimulus updates whenever I/O pin state information changes. 2005-07-26 Scott Dattalo * src/16bit-instructions.cc, regression/instructions_16bit/instructions_16bit.asm: Fixed bug with 16bit processors Table Read (more index vs address). Thanks to Peter Onion for pointing this (and other 16bit stuff out). 2005-07-26 Scott Dattalo * src/i2c-ee.cc, src/i2c-ee.h, src/ioports.cc, src/ioports.h, src/p12x.cc, src/stimuli.cc, src/stimuli.h: Fixed 12CE51x internal eeprom peripheral. * gui/gui_menu.cc, gui/gui_regwin.cc: Removed dependency on gtk win32 port. 2005-07-25 Scott Dattalo * regression/instructions_16bit/instructions_16bit.asm: added tests for multi-word instructions. * regression/p12ce518/p12ce518.asm: debugging eeprom i2c interface * gui/gui_src_opcode.cc, src/16bit-instructions.cc, src/16bit-instructions.h: Fixed more problems with address <--> index mapping. (and there are still some issues remaing with the program memory viewer). * src/i2c-ee.cc, src/ioports.cc, src/ioports.h, src/p12x.cc, src/p12x.h: The eeprom i2c interface is broken... 2005-07-23 Borut Razem * gpsim/gpsim.vcproj, doc/gpsimWin32.html, plat/win32/gpsim.nsi: use pthreads-w32-2-7-0-release * cli/scan.ll: corrected typo 2005-07-22 Scott Dattalo * cli/cmd_disasm.cc: rnages were disassembling wrong addresses * gui/gui_src_asm.cc: cleanup * src/12bit-processors.cc, src/14bit-processors.cc, src/14bit-registers.cc, src/14bit-tmrs.cc, src/attributes.cc, src/gpsim_classes.h: Implenting new ioport design for 12bit cores. Fixed bugs with resets. * src/16bit-hexdecode.cc, src/16bit-instructions.cc, src/16bit-processors.h, src/16bit-registers.cc, src/cod.cc: 16bit processors were not getting loaded properly due to some bugs with address <-> index mapping 2005-07-21 Scott Dattalo * src/ioports.h, src/ioports.cc: classes derived from PortRegister can now specify the type of PinModule class. 2005-07-15 Scott Dattalo * src/12bit-processors.cc, src/14bit-processors.cc, src/14bit-processors.h, src/16bit-registers.cc, src/16bit-registers.h, src/intcon.h, src/ioports.cc, src/ioports.h, src/p16f62x.cc, src/p16f87x.cc, src/p16x6x.cc, src/p16x6x.h, src/p16x7x.cc, src/p16x7x.h, src/p16x8x.cc, src/p16x8x.h, src/pic-processor.cc, src/pic-processor.h, src/registers.cc, src/registers.h, src/stimuli.cc, src/stimuli.h, src/tmr0.cc, src/tmr0.h, src/uart.cc, src/uart.h: I/O Port Redesign: These files have been updated to accommodate a new I/O Port design. Currently the design applies only to the mid-range PIC family, but will be propogated to the 12 and 16 bit cores too. In summary, the I/O pins are now managed with I/O pin modules. A port register maintains an array of these modules. In the old design, the I/O pins were managed directly by the Port registers. New classes have been designed to allow multiple signal sources, signal controls, and signal sinks for I/O pins. These new objects can be added at will and thus allow the exact behavior of an I/O pin be tailored to a specific processor (and even changed dynamically). Thus a base class in the processor heirarchy can instantiate a register object, and the derived processors populate it with custom functionality. * cli/cmd_break.cc: documentation clean up * modules/usart.cc, modules/usart.h: tinkering - * regression/logic_test/Makefile, regression/logic_test/logic_test.asm: Incorporates an un-released gpasm feature of the .direct macro. This feature allows multiple strings to be passed to gpasm. * regression/p16f84/p16f84.asm: Bug fix in PORTB pullup test 2005-07-15 J.R. Heisey * gui/gui_watch.cc, gui/gui_watch.h: Fixed problem with register symbol names not displaying in the Watch window. Introduced this bug when I made the bit mask feature in register symbols. * gui/gui_regwin.cc: Fixed problem with register symbol names not displaying in the RAM window. Introduced this bug when I made the bit mask feature in register symbols. 2005-07-11 J.R. Heisey * src/breakpoints.cc, h, src/cmd_gpsim.h, src/symbol.cc, plat/win32/gpsim.def, gpsim/main.cc, cli/ui_gpsim.cc, cli/ui_gpsim.h: Made changes so that when hitting a break will display program and register address symbols. * src/breakpoint.cc: Removed calls to eval_Expression() where it is not necessary. Enhanced the break on value action text to include symbols and bit mask value. * cli/ui_gpsim.cc,h, gpsim/main.cc: Added functions that help display program and register address symbols along with the address value. * src/trigger.cc: Fixed problem in TriggerObject:: eval_Expression() that was preventing non-expression based break points to not fire. * src/symbol.cc: Added check in Symbol_Table:: findRegisterSymbol() to get register bit mask defined for the CPU when the passed in value is zero. 2005-07-10 J.R. Heisey * plat/win32/gpsim.def, src/symbol.cc, src/symbol.h: Change function name from findRegister() to findRegisterSymbol() to reflect the return type. Added new findRegisterSymbol() version that takes a single address parameter. Did some minor code optimization of the findRegister() function. Due to the introductions of register symbol bit mask, I modified findRegister() to only return symbols that are defined for all bits of the register. * src/processor.cc: Changed some entry condition checks to allow processor::disassemble to disassemble one program address. Also made some minor code optimizations. 2005-07-06 Borut Razem * src/breakpoints.cc, src/gpsim_time.cc, src/interface.cc, src/processor.src, src/trace.cc: declare dummy_bp, dummy_cycles, dummy_gi, dummy_get_active_cpu, dummy_set_active_cpu and dummy_trace as non static to compile with gcc 3.4.4 * plat/win32/gpsim.nsi: corrected version number to 0.21.8 * gpsim/gpsim.vcproj, gpsim/makefile.mingw: linking with libgtkextra-win32-2.1.lib * doc/gpsimWin32.html: linking with gtk+extra-2.1.1, glib-2.6.5, gtk+-2.6.8, pango-1.8.0, 1.9.0, fontconfig-2.2.2-20040412 * plat/win32/make.mingw: change gcc command line options mcpu with mtune to compile with gcc 3.4.4 2005-07-08 J.R. Heisey * plat/win32/gpsim.def, src/symbol.cc, src/symbol.h: Added version of Symbol_Table::findRegister() that takes a bitmask parameter. Added Symbol_Table::findConstant() for future use. Need to implement a symbol to referenced from address cross reference. * gui/gui_src_opcode.cc, src/processor.cc: Fixed issues accessing program memory arrays using address instead of an appropriate index. * gui/gui_src_opcode.cc, src/processor.cc: Fixed issues with Processor::disassemble() function not traversing over break points to find the base instruction object. 2005-07-07 J.R. Heisey * cli/cmd_break.cc, cli/cmd_break.h: Code to display address labels in break related messages. * plat/win32/gpsim.def, src/pic-instructions.cc, src/pic-instructions.h, src/processor.cc, src/processor.h, src/symbol.cc: Code to display address labels in a disassembly output. Added members to Processor class to support a page mask and offset mask that can be used to calculate absolute addresses for disassembly output for JUMP and CALL instructions. See the functions CalcJumpAbsoluteAddress() and CalcCallAbsoluteAddress(); 2005-07-06 J.R. Heisey * src/stimuli.cc, src/symbol.cc, src/symbol.h: Fixed a problem where renamed stimulus_symbol objects were getting lost. This caused a error when running the regression test digital_stim. 2005-07-06 Borut Razem * plat/win32/gpsim.nsi: NSIS 2.07 compatible 2005-07-05 J.R. Heisey * src/symbol.cc, h: The access to a derived object's name() function was broken when I made the name() function in the base class const. I've propogated the const attribute to overriden versions of name(). - Somewhere along this process on of my program variables stopped being added to the symbol table. So, I've changed the if statement that determines when a duplicate variable exists in the symbol table. - I've added a function called findProgramAddressLabel() so that a label name can be displayed where appropriate. * src/breakpoints.cc: Changed ::print() functions to output program memory labels where they could. Changed implementation to use the Console object rather than cout. * src/registers.cc: InvalidRegiser() constructor was not setting its address member variable. Now the address is included in the console warning. * src/attributes.cc: WarnModeAttribute() was not setting its value member variable. - init_attributes() added some constant attributes for reset types. 2005-07-01 Scott Dattalo * cli/scan.ll, cli/parse.yy, cli/input.cc: The recently added command line error processing change did not compile under Linux and was free a constant pointer. * gui/gui_main.cc, gpsim/main.cc: The command line prompt was always selected. 2005-07-01 J.R. Heisey * cli/scan.ll, cli/parse.yy, cli/input.cc,h: - Full command line text is displayed when a command line error occures. - Command line buffers are cleared appropriately after a command line error. 2005-06-30 Scott Dattalo * regression/logic_test/logic_test.asm, regression/logic_test/Makefile, regression/logic_test/16f873.lkr: Added a regression test for gpsim Logic Modules. 2005-06-30 J.R. Heisey * src/breakpoints.cc, src/breakpoints.h, cli/cmd_break.cc: New break point dump filtering. break r dumps register read break points. break w dumps register write break points. break e dumps execution break points. * cli/cmd_disasm.cc: Updated disassemble command on line help to reflect reality. 2005-06-30 Scott Dattalo * cli/input.cc, gpsim/main.cc, gui/gui_main.cc, src/gpsim_interface.h, src/interface.cc, src/modules.cc, src/modules.h, src/processor.cc: Added methods to the gpsim_interface class that manage the state of gui. This is done so that gui-based modules can query the gui state and conditionally build their graphical portions. * modules/led.cc, modules/logic.cc: The Logic and LED modules now will not build any graphics if the gui is not initialized. Pin names were getting added to the symbol twice. 2005-06-27 Scott Dattalo * src/stimuli.cc, src/stimuli.h: Added putState()/getState() methods and removed putDrivingState method from the stimulus class. The purpose of this is to abstract away whether a node is driving or not. The main affect is in the gui breadboard where the state of I/O pins is queried. * gui/gui_breadboard.cc, gui/gui_breadboard.h, modules/usart.cc, modules/video.cc, modules/video.h, src/14bit-tmrs.cc, src/i2c-ee.cc, src/ssp.cc, src/uart.cc: Updated calls to new stimulus class API. * modules/logic.cc, modules/logic.h: The logic gate modules had bit rotted. 2005-06-26 J.R. Heisey * plat/win32/gpsim.def, src/processor.cc, src/processor.h: New function Processor::init_program_memory_at_index() to continue the separation of PM address from PM array index. 2005-06-26 Scott Dattalo * src/trace.cc: The wrong variable was being used to index the program counter array. This caused the trace to get an invalid instruction. 2005-06-26 Scott Dattalo * INSTALL: Added notes from Bas Wijnen regarding Debian. 2005-06-25 Scott Dattalo * src/symbol.cc, regression/simulate: The new 'BITS' indicator for register symbol queries broke the regression test. Now, the BITS indicator is only displayed if only a portion of the register applies to a register symbol. 2005-06-24 J.R. Heisey * src/modules.cc: Fixed a bug in Module::get() where a derive class does not override this function, now this function will return a null string. This fixes problems when a derived class is being displayed in the GUI symbol window causing a UTF-8 warning. * src/symbol.cc: Fixed an introduced null pointer exception. 2005-06-23 J.R. Heisey * plat/win32/gpsim.def, src/symbol.cc, src/symbol.h: register_symbol::m_uMask is used to mask out bits not associated with the symbol after retrieving the value from the register. Masked bit values are right shifted such that if the 16th bit is high in the register and m_uMask = 0x80, then the symbol value returned or displayed will be one. Likewise to set the 16th bit of our example register_symbol you would set the register_symbol value to 0x01 and not 0x80. No other bits in the register are changed. It works as if this symbol is its own register. The encoding into the target register is hidden by register_symbol. The default value of m_uMask is 0xff so that no bits are masked out. An new version of Symbol_Table::add_register() may be used to add masked register_symbol objects to the symbol table. register_symbol::copy() is changed to return the correct symbol string. 2005-06-21 J.R. Heisey * cli/cmd_run.cc: Added help text saying that CTRL->C will stop a running simulation. * src/breakpoints.cc, src/processor.cc, src/processor.h, src/trace.cc, plat/win32/gpsim.def, gui/gui_profile.cc, gui/gui_src_asm.cc: There was significant ambiguity for some functions that appear to accept an simulation address but acted upon it as a ProgramMemoryAccess index. The ProgramMemoryAccess indexing operator was a prime example. I have eliminated the indexing operator and added the functions getFromAddress() and getFromIndex() to make things more explicitly clear. I have also removed put() and get() and added putToAddress() and putToIndex(). Other new functions are hasValid_opcode_at_address() and hasValid_opcode_at_index(). This mostly effected gui code so the simulation itself should have no impact. The original intent of this change was to fix bugs in the gui where double clicking on a breakpoint icon in the source window would not toggle the breakpoint. 2005-06-17 J.R. Heisey * cli/cmd_dump.cc: dump register for special registers broken when pReg->isa() and Register::SFR_REGISTER were not being used. Now we dump the registers listed in MemoryAccess::SpecialRegisters. * cli/input.cc: Implemented the ability to break running firmware using Ctrl->C key when running under Windows. It would previously exit gpsim. * gpsim/main.cc: Changed logic so the -i on the gpsim command line will not attempt to start the gui interface. * cli/cmd_break.cc, cli/cmd_clear.cc, cli/cmd_disasm.cc, cli/cmd_dump.cc, cli/cmd_frequency.cc, cli/cmd_help.cc, cli/cmd_load.cc, cli/cmd_module.cc, cli/cmd_processor.cc, cli/cmd_step.cc, cli/cmd_stimulus.cc, cli/cmd_trace.cc, cli/cmd_version.cc, cli/command.cc, cli/command.h: Implemented command abbreviations. Made abbreviations for several often used commands. 2005-06-14 J.R. Heisey gui/gui_src.h, gui/gui_src_asm.cc, gui/gui_statusbar.cc, src/processor.cc, src/processor.h, src/registers.h: Fixed some problems with the source window optimization. Fixed problem with the text search dialog not searching alternate source windows. Fixed problem with Set PC Here from an alternate window. 2005-06-13 J.R. Heisey *src/cmd_manager.cc, src/cmd_manager.h, src/modules.cc, cli/cmd_shell.cc: Fixed introduced bug where the command line interface from a library module was not accessible. A ! bang character alone lists the command line interfaces. 2005-06-13 Scott Dattalo * configure.ac: Fixed recently introduced typo. * src/attributes.cc: Cycle counter attribute now prints correctly again. * src/processor.cc, src/processor.h: fixed bug in IsAddressInRange() method, also reversed return value to match meaning of name (now returns true if the address is in range). * src/symbol.cc: Symbol table dump was not showing symbol values. * src/registers.cc: fixed warning message for when invalid registers are accessed. 2005-06-10 Scott Dattalo * src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/symbol.h: Stimuli symbols were not getting added to the symbol table when their name was being changed. 2005-06-10 J.R. Heisey *src/gpsim_object.cc,h: Small change to allow name() call in a const variable context. *plat/win32/gpsim.def, src/processor.cc, src/stimuli.cc, src/symbol.cc, src/symbol.h, gui/gui_profile.cc: Changed the implementation of the Symbol_Table class to order by symbol name so that a binary search will improve lookup speed. 2005-06-10 Scott Dattalo * cli/cmd_stimulus.cc, doc/gpsim.lyx: Updated documentation. 2005-06-09 J.R. Heisey *cli/cmd_module.cc: Added extra help for module command. *gui/gui_src.h, gui/gui_src_asm.cc, plat/win32/gpsim.def, src/processor.cc,h: Changed the parsing of the source for formatted display to speed things up during file loading. Source is now cached in a form for rendering to the formatted text window. 2005-06-09 Scott Dattalo * gui/gui_main.cc, gui/gui_regwin.cc, gui/gui_src.cc, gui/gui_src_asm.cc, gui/gui_src_opcode.cc, configure.ac: Found the source of a bug that causes gpsim to hang when gtk-2.6.7 and gtkextra-2.0 are used. The problem is either with gtkextra or the interaction of it with gtk. gpsim currently has in place a stop-gap measure to prevent the problem from keeping the simulator from being unusable. 2005-06-06 J.R. Heisey *src/os_dependent.cc: The environment variable GPSIMPATH may be used to specify folders where shared libraries may be found. This is primarily for windows developers of gpsim. - Small change to prevent load_library() from displaying an error message that is not needed. *cli/cmd_node.cc: Use a reference instead of allocating a string on the local stack. *modules/modules.vcproj: Changed Visual Studio build of modules to libgpsim_modules.dll 2005-06-04 Scott Dattalo * gui/gui.h, gui/gui_menu.cc, gui/gui_object.cc, gui/gui_object.h, gui/gui_src_asm.cc, gui/gui_statusbar.cc, gui/gui_statusbar.h: -- removed the cycle counter and time view from the status bar of the register and source windows and moved them to the window that contains the buttons. -- fixed text-width bugs in the status window. -- rewrote the implementation of the gui update code. -- Created a 'TimeWidget' class and a 'TimeFormatter' class for displaying the cycle counter object. -- Added a MainWindow class (kind of empty now). -- Re-introduced a few of the GTKWAIT macros. 2005-06-04 Scott Dattalo * configure.ac, gpsim/Makefile.am: remove the explicit checks for the pthread library. 2005-06-04 Scott Dattalo * gpsim/main.cc: Allow filenames whose first character is a number. 2005-06-04 Scott Dattalo Patch from: Rob Pearce * src/cod.cc: Fixed gramatical error. * src/eeprom.cc, src/eeprom.h: Added a new state to the eeprom state machine to fix ?? * src/ioports.cc: fix to the 628 porta comparator. 2005-06-03 Scott Dattalo * gui/gui_main.cc: Added a call to g_main_iteration() to allow GTK events to get processed. (This replaces the GTKWAIT macro that was removed in the previous commit). 2005-06-02 Scott Dattalo * gui/gui_src_asm.cc, gui/gui_main.cc: Removed GTKWAIT macros. Apparently on newer versions of GTK these macros block indefinitely. On really old versions of GTK (pre 2.0) these macros were necessary. 2005-05-26 J.R. Heisey * src/breakpoints.cc,h, plat/win32/gpsim.def: added register assertions functionality. Can now assert the register value with !=, <=, >=, <, and > operators. 2005-06-01 Scott Dattalo * src/os_dependent.cc: Printed an error message if a shared library fails to open. 2005-05-26 J.R. Heisey * src/program_files.cc: Fixed crashing bug when no file types are able to open a program file. 2005-05-25 Borut Razem * plat/win32/gpsim.nsi, extras/lcd/makefile.mingw: added missing files to the WIN32 installation package in order to be able to compile the LCD modue; make LCD module mingw makefile a litle bit more flexible 2005-05-24 Scott Dattalo * src/cod.cc, src/breakpoints.cc, src/trigger.cc, regression/assertions/assertions.asm: Added support for scripts embedded in .cod files. 2005-05-24 Scott Dattalo * src/modules.h, src/modules.cc, src/processor.cc, src/breakpoints.cc, src/pic-processor.cc, src/hexutils.cc, gui/gui_src.cc, gui/gui_src_asm.cc, cli/scan.ll, src/cmd_manager.h, cli/cmd_dump.cc: -- renamed the enum's for the SIMULATION_MODE(s) (the enum 'INITIAL' collides with a macro in flex) -- added support for module scripts -- If a symbol begins with a period, then the scanner will automatically prepend the active processor name. (This is a short cut for accessing processor attributes). 2005-05-24 Borut Razem * doc/gpsimWin32.html, gpsim/gpsim.vcproj, gpsim/makefile.mingw: WIN32 with official release of gtk+extra-2.0.0 2005-05-22 Scott Dattalo * cli/cmd_break.cc, cli/cmd_break.h, cli/parse.yy, cli/scan.ll, src/breakpoints.cc, src/breakpoints.h, src/operator.cc, src/trigger.cc, src/trigger.h, src/value.cc: Added the capability of associating user defined messages with break points. Break point expressions (if present) are now displayed when the break points are displayed. * regression/assertions/Makefile, regression/assertions/assertions.asm: Use the coff.inc include file supplied with gputils and specifically the macros for assertions. 2005-05-21 Scott Dattalo * cli/cmd_break.h, cli/cmd_break.cc, cli/input.cc, cli/parse.yy, src/cod.cc, src/breakpoints.cc: Execution breakpoints were failing to propogate execute() if an attached expression evaluated false. Added support for gpasm style assertions. * cli/scan.ll: Shell command escape character ('!') was conflicting with the not operator. * regression/assertions/assertions.asm, regression/assertions/Makefile, regression/assertions/16f873.lkr: Added a regression test for gpasm assertions. 2005-05-20 Scott Dattalo * cli/scan.ll, regression/run_regression.sh, regression/macro_test/macro_test.stc: Macros can now be nested. 2005-05-20 Scott Dattalo * gui/gui_profile.cc: ifdef'd out code that a) is seldom (never?) used and b) incompatible with the latest official release of gtkextra. 2005-05-19 Scott Dattalo * src/ttoken.h, src/ttoken.cc, src/bytelog.cc, src/bytelog.h, src/pthread-wrap.h: Create a gpsim namespace and place the objects in these files in there. * cli/scan.ll: removed some printf debugging junk. 2005-05-19 Scott Dattalo * cli/scan.ll, cli/cmd_macro.cc, cli/parse.yy, cli/input.cc: A recent change in string processing broke macros. Also, began adding code to support nested macros. * regression/macro_test/macro_test.asm, regression/macro_test/macro_test.stc: Added new regression test for macros. 2005-05-18 Scott Dattalo * cli/scan.ll: Fixed end-of-line scan bug introduced on 5-16. 2005-05-16 J.R. Heisey * src/os_dependent.cc: Added debug code to allow alternate directory paths for module libraries so I can specify debug build locations for shared libraries. * src/program_files.cc: Fixed bug caused by symbol table not being cleared when Program files are loaded. * src/modules.cc: Fixed bug when a module library failed to load it was still being added to the installed library list. * configure.ac: bumped build number to 0.21.5 2005-05-16 Scott Dattalo * cli/input.cc, cli/scan.h, cli/scan.ll, cli/input.cc: command assertions where causing parse errors. 2005-05-14 Scott Dattalo * cli/cmd_processor.cc: The processor command wasn't working because of a typo in an if statement. * cli/parse.yy, cli/cmd_break.cc, cli/cmd_break.h: Added 'break #number' to allow inspection of an individual break point. Clean up some memory management. * src/breakpoints.cc: 'dump1()' wasn't checking to see if the break point number was valid. * src/os_dependent.cc: non-windows file extension comparisons were not working. * src/pic-processor.cc, src/symbol.h, src/symbol.cc, src/value.cc: val_symbols like the PIC program counter can now be parts of gpsim expressions. * src/cod.cc: hack - line number offset errof. * doc/gpsim.lyx: Updated the documentation. 2005-05-12 Scott Dattalo * gui/gui_regwin.cc, gui/gui_src_opcode.cc, gui/gui_src_asm.cc: Removed calls to GTKWAIT because they sometimes block in the newer version (2.6.7) of GTK. Thanks to Micah Carrick for pin-pointing this one. 2005-05-11 Scott Dattalo * src/sim_context.cc: The included file "direct.h" does not exist on FC3. 2005-05-10 J.R. Heisey * cli/cmd_load.cc: Updated on line help for load command. * gui/gui_src_asm.cc: Removed a call to gtk_widget_destory() in SourcePage::Close() where it was causing a crash in Windows. * cli/scan.ll: Defined literal string values to be quoted. This was done so that quoted Windows paths in the load command to accommodate colons for drive designation and backslashes for folder delimiters. * gpsim/main.cc: Added the gpsim.exe startup folder to the module/library search path. * src/sim_context.cc, src/errors.h: Added an error message to CSimulationContext:: LoadProgram(). * cli/cmd_module.cc, src/modules.cc, src/modules.h, src/os_dependent.cc, gpsim/main.cc: Added code to not load a module library that is already loaded. 2005-05-06 J.R. Heisey * gui/gui_regwin.cc: Fixed crash that occurs when RAM register count is not a multiple of 16. * plat/win32/gpsim.def: Added new function reference. * src/processor.cc: Fixed broken list command * src/sim_context.cc: Fixed broken register output on stepping that broken on previous check in. Test for open file failure. * src/program_files.h: Add new error code. 2005-05-05 J.R. Heisey * cli/cmd_break.cc, cli/cmd_disasm.cc, cli/cmd_dump.cc, cli/cmd_frequency.cc, cli/cmd_list.cc, cli/cmd_load.cc, cli/cmd_load.h, cli/cmd_log.cc, cli/cmd_processor.cc, cli/cmd_reset.cc, cli/cmd_step.cc, cli/cmd_x.cc, cli/command.cc, cli/command.h, cli/input.cc, cli/input.h, cli/parse.yy, src/cod.cc, src/cod.h, src/hexutils.cc, src/Makefile.am, src/modules.h, src/os_dependent.cc, src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h, src/program_files.cc, src/program_files.h, src/sim_context.cc, src/sim_context.h, src/src.vcproj, src/symbol.cc, src/symbol.h, config_win32.h.in, configure.ac, plat/win32/gpsim.def, gui/gui_menu.cc, gui/gui_src_asm.cc, gui/gui_statusbar.cc, gpsim/Makefile.am: - Replaced the cli and gui references to hexfiles verses cod file with program files. Gpsim will now figure out the file type and load the file. - Both the gui and cli will recoginze command files by the stc file extension. All other files are assumed to be program files. - The c, h and s load options of the load command will be accepted for backwards compatibility of existing command files but are no longer needed. - The processor command is not optional. If the program file contains the information about the processor type, gpsim will allocate the processor type based on the program file information. Using the processor command overrides this behavior. 2005-05-01 Borut Razem * plat/win32/gpsim.def: MSVC sync 2005-04-29 Scott Dattalo * HISTORY, README, INSTALL, configure.ac, gpsim.spec.in: Updates for the 0.21.4 * extras/lcd/ChangeLog, Makefile.am, configure.in: bumped the Rev of the LCD module to 0.2.4 2005-04-29 Scott Dattalo * src/breakpoints.cc: Register assertions were not halting simulation when assertion was true. 2005-04-26 Scott Dattalo * cli/Makefile.am, examples/14bit/Makefile.am: Updated so that 'make dist' would work again. * src/attributes.cc, src/init.cc: Moved attribute initialization from init.cc to attributes.cc * src/breakpoints.cc, src/symbol.cc, src/symbol.h, src/trigger.cc: Complex expressions are now fully supported. Updated the help info for the break command to reflect the new syntax (more work needed). 2005-04-26 Scott Dattalo * src/breakpoints.cc, src/breakpoints.h, cli/parse.yy, cli/cmd_break.cc, cli/cmd_break.h: continuing with complex break expressions. 2005-04-25 Scott Dattalo * src/trigger.h, src/trigger.cc, src/breakpoints.cc: Added complex expressions to the TriggerObject class. (not complete) 2005-04-23 Borut Razem * src/bitlog.cc, src/bytelog.cc, src/ttoken.cc: removed #define IN_MODULE * plat/win32/gpsim.def, modules/makefile.mingw, src/makefile.mingw, modules/modules.vcproj, src/src.vcproj: MINGW sync * gpsim/makefile.mingw: force linker to onclude BoolEventLogger class methods in gpsim.exe, so that they can be referenced by modules * src/modules.cc (get_attribute): fixed attribute name comparison * src/sim_context.h: added end of line at end of file * plat/win32/gpsim.nsi: remove pthreadVC1.dll 2005-04-22 Scott Dattalo * bitlog.cc, bitlog.h, bytelog.cc, bytelog.h, ttoken.cc, ttoken.h, pthread-wrap.h: moved these from the modules/ directory into the src/ directory. 2005-04-19 J.R. Heisey * src/breakpoints.cc, src/processor.cc, src/processor.h: Fixed corruption when clearing a Breakpoint_Instruction object. The object was not removed properly from the chain of instruction objects in the pma. 2005-04-19 Scott Dattalo * src/os_dependent.cc: Added 'errno.h' to the list of include files. (without this, os_dependent.cc wouldn't compile on FC3-64bit). 2005-04-19 Scott Dattalo * src/symbol.cc, src/symbol.h: Fixed reference to symbol table that was preventing compilation on Linux. 2005-04-19 J.R. Heisey * gui/gui_src_asm.cc, gui/gui_statusbar.cc, gui/gui_statusbar.h: Modified the statusbar so that it can handle a switch from one processor to another. * src/sim_context.cc, src/symbol.cc,h: Fixed a crash on gpsim exit. * src/os_dependent.c: added test in load_library() to the first call to sLoad() to determine whether the a failure was due to the library file not found or some other error. This needs to be completed for the linux builds. 2005-04-18 Scott Dattalo * src/stimuli.cc: Stimulus_Node destructor now removes itself from the symbol table. 2005-04-17 Scott Dattalo * src/stimuli.h, src/stimuli.cc: Added methods to control the resistance and voltage of the IO_bi_directional_pu pullup resistor. 2005-04-16 Scott Dattalo * src/symbol.cc: set methods for register symbol now initialize the "init" field in the register object. 2005-04-16 J.R. Heisey * src/value.cc,h, src/symbol.cc,h, src/processor.cc,h, src/pic-processor.cc,h, makefile.mingw, Makefile.am, cli/input.cc, cli/init.cc, gui/gui_symbols.cc, gui/gui_stack.cc, gui/gui_src_asm.cc, gui/gui_profile.cc, src/gpsim_time.cc, plat/win32/gpsim.def, src/cod.cc, cli/cmd_processor.cc, added src/sim_context.cc.h: Restructured classes in preparation for allowing a simulation context to be reset for a new processor with out having to close the program and with out memory leaks. The new class CSimulationContext, implemented as a singleton for now, owns a CProcessorList. The singelton class ProcessorContructorList is used to create processor objects. Eventually CSimulationContext may own Breakpoints, Symbol_Table and the active_cpu objects. For now. there are accessor functions to get to the global objects. CSimulationContext.set_processor() will check for a matching processor in the processor list before allocating a new processor. Processor related classes now delete the objects that they own on destruction. May not be conprehensive. set_processor() currently deletes a matching processor object rather than reinitializing it for a new simulation session. 2005-04-15 Scott Dattalo * cli/command.h, cli/input.cc, cli/parse.yy, cli/scan.ll, gpsim/main.cc: Finished support for reentrant parsing. * cli/cmd_disasm.cc: Cleaned up a buglet in printing. * src/attributes.cc, src/attributes.h, src/pic-processor.cc, src/processor.cc, src/processor.h: Added an attribute that controls the behavior of simulator when a reset is encountered. 2005-04-15 Scott Dattalo * src/cod.cc, cli/cmd_run.cc, cli/cmd_run.h, cli/input.cc, cli/input.h, cli/parse.yy, cli/scan.ll: Added initial support for .COD file assertions. -- Parser is now reentrant -- gpsim's CLI interface is now a registered interface that can be referenced and accessed by the simulation engine. * src/ioports.cc: experimental tinkering 2005-04-14 Scott Dattalo * build.xml: configure was not getting invoked. 2005-04-14 Scott Dattalo * build.xml: autoconf was not getting invoked... 2005-04-13 Scott Dattalo * build.xml: An XML script for an experimental regression tool (based on the open source projects "ant" and "CruiseControl"). 2005-04-09 Borut Razem * cli/makefile.mingw, src/makefile.mingw: MINGW sync 2005-04-08 J.R. Heisey * src/breakpoints.cc, src/cmd_manager.cc,h, gpsim/main.cc, src/processor.cc,h, cli/ui_gpsim.cc,h, src/registers.cc, cli.vcproj, gpsim.vcproj, src.vcproj: Created a IUserInterface and CGpsimUserInterface as the implementation with functions to write predefined parameterized strings to the console (or in the future a GUI popup). Modules call the C function GetUserInterface() to retrieve an instance of CGpsimUserInterface as a IUserInterface. Using IUserInterface functions is the prefered way of writing error and notification messages to the gpsim console from other modules. 2005-04-08 Scott Dattalo * cli/parse.yy, cli/cmd_break.h: Added support for a break command like: break r|w reg(N) Where N is an integer and 'reg' is the new reg operator. 2005-04-08 Scott Dattalo * cli/parse.yy, cli/scan.ll: Added a "reg()" operator that can cast integers into registers (although this is not fully implemented yet). A single quote before an identifier now acts as an 'escape' character. This allows user defined strings to collide with gpsim built in strings. (e.g. If a user has a variable named help, its contents can be examined by typing 'help at the command line). 2005-04-07 J.R. Heisey src/breakpoints.cc: Fixed a memory leak by properly removing chained BreakpointRegister objects from the Register chain when clearing a break object. When the chain is properly maintained the object may be deleted. 2005-04-07 J.R. Heisey * cli/scan.ll, cli/parse.yy, cli/cmd_break.cc,h, src/processor.cc,h, src/pic-processor.cc, operator.cc,h, src/breakpoints.cc: Changed the break command syntax. Added code to support the syntax. 2005-04-07 Scott Dattalo * cli/cmd_manager.h, cli/cmd_manager.cc, cli/cmd_gpsim.h: moved from cli/ to src/ * src/processor.cc, src/Makefile.am, src/interface.cc, src/processor.cc, gpsim/main.cc, cli/Makefile.am, cli/cmd_manager.cc, cli/cmd_module.cc, cli/cmd_shell.cc: Updated these files to use the newly relocated .h files. The reason for doing this is to fix a src/ dependency on cli/ files. When src/ depends on cli/ then any module that links against the gpsim library must also link against the cli library. * src/registers.cc: added a Bit class (currently not used though) * src/symbol.cc: attribute symbols that wrap other symbols now change the name of the wrapped symbol. This allows heirarchical names such as processor_name.attribute to appear in the symbol table. 2005-04-06 J.R. Heisey * src/processor.cc.h: Two new break message functions. 2005-04-05 J.R. Heisey * src/value.h, src/registers.cc,h, src/processor.cc.h, src/preakpoints.cc,h, plat/win32/gpsim.def: Implemented classes and functions for displaying the register address and possible value for break on read and break on write. 2005-04-05 J.R. Heisey * gpsim/main.cc, src/interface.cc, src/gpsim_interface.h, cli/cmd_manager.h: Added code to support for an external module to access the global ISimConsole object from the Interface class. 2005-04-04 J.R. Heisey * src/processor.cc,h: Added the function Processor::IsAddressInRange(). Use IsAddressInRange() in ProgramMemoryAccess::get_src_line() and ProgramMemoryAccess::operator [](unsigned int address) 2005-04-02 Scott Dattalo * src/processor.cpp: Reverted the change J.R. made on 2005-03-31 because it breaks the gui for the 18F family of PICs. We'll need to come up with another way of solving the initial PC value problem. 2005-03-31 J.R. Heisey * src/processor.cpp: Changed call ProgramCounter->get_PC() to ProgramCounter->get_value() to fix a problem where the initial position of the PC in the source was not getting set properly. Return value is used for indexing into source code line. Mostly used by the UI so should not affect behavior. 2005-03-30 J.R. Heisey * cli/cmd_dump.cc: Changed ram dump command to handle ram sizes greater than one byte. * cli/cmd_x.cc: Removed call to dump.dump(DUMP_SFRS) since previous call to dump.dump(DUMP_RAM) already dump thes sfrs too.ram halt. * Cleaned up a couple of GUI error messages. (invalid window handle, invalid value strings) 2005-03-24 J.R. Heisey * src/breakpoints.cc, src/processor.cc, h, cli/cmd_clear.cc: Fixed crash in Breakpoints::clear() that I reintroduced in my last checkin. Also Fixed the original memory leak by properly removing chained Breakpoint_Instruction objects from the instruction chain when clearing a break object. When the chain is properly maintained the object may be deleted. Perhaps this should be a temporary fix until a base class for Breakpoint_Instruction all have a replaced member. 2005-03-23 Scott Dattalo * gui/gui_src_asm.cc: changed the comment text color to 'dim gray' 2005-03-23 Scott Dattalo * src/value.cc: Fixed write to a null pointer in String::get(char *buf, int len). * src/symbol.cc: Fixed infinite loop in char *register_symbol::name (char *buf, int len). * regression/ccp/ccp.asm: added more features to the ccp regression test. 2005-03-22 J.R. Heisey * gui/gui_watch.cc: Fixed problem with register values > 127 causing pango runtime warnings 2005-03-21 J.R. Heisey * src/breakpoints.cc, src/processor.h: created a notification to Processor when breakpoints are set or cleared. Cleaned up code in breakpoints.cc. 2005-03-23 Scott Dattalo * src/16bit-instructions.cc: The NEGF instruction for the 18f family was erroneously writing the negated result to W. * regression/instructions_16bit/instructions_16bit.asm: added a regression test for the NEGF instruction. 2005-03-21 J.R. Heisey * src/processor.cc: Copy a null string to input parameter Processor::get(char *cP, int len) because not value is associate with a Processor object. Fixes trace errors from pango when the symbol window is scrolled to some symbol objects. * src/value.cc: Copy a null string to input parameter String::get(char *buf, int len) when not value string is allocated. Fixes trace errors from pango when symbol window is scrolled to some symbol objects. 2005-03-18 J.R. Heisey * cli/cmd_load.cc/h, src/cod.cc/h, cli/input.cc, cli/parse.yy: added error checking for opening cod, hex and stc files. Particularily when opened from the GUI. 2005-03-17 Scott Dattalo * src/stimuli.cc: tweaking of I/O thresholds. 2005-03-16 Scott Dattalo * cli/scan.ll, src/stimuli.h, src/stimuli.cc, src/symbol.cc, src/symbol.h: Added/enhanced methods for searching, adding, and removing symbols and stimuli. 2005-03-14 J.R. Heisey * src/modules.h, modules.cc, os_dependent.cc: Elimaticated undesired error message on failure to load a function of a module. Simplified Module_Library() constructor to use os independent api call get_library_export() 2005-03-14 Scott Dattalo * plat/win32/gpsim.def: MSVC sync. * modules/modules.vcproj: Use new pthread library. * gui/gui_register.h, gui/gui_regwin.cc: pass registerValue by value in getValueAsString() method. 2005-03-03 Borut Razem * plat/win32/gpsim.def: MSVC sync 2005-03-10 Scott Dattalo * src/stimuli.cc: Added an 'X' state to getBitChar method of the IO_open_collector class. 2005-03-09 Borut Razem * modules/makefile.mingw: pthreads upgrade 2005-03-08 Scott Dattalo * src/value.cc, gui/gui_profile.cc, gui/gui_statusbar.cc, gui/gui_trace.cc: Corrected temporary hack regarding PRINTF_INT64_MODIFIER 2005-03-08 Borut Razem * plat/win32/gpsim.nsi: removed examples\14bit\*.inc * cli/cmd_manager.h: added newline at the end of file * doc/gpsimWin32.html: atk upgraded to 1.8.0 2005-03-08 Scott Dattalo * regression/ccp/ccp.asm: improvements to ccp regression test * gui/gui_profile.cc, gui/gui_trace.cc, gui/gui_statusbar.cc, src/value.cc: Temporarily removed windows-specific macro. * src/stimulus.cc, src/stimuli.h: Cleaned up asynchronous stimuli * src/registers.h, src/ssp.cc, src/ioports.cc, src/14bit-tmrs.cc: Made the default register class access functions all go through one function to obtain a register's value. 2005-02-26 Scott Dattalo * src/processor.h, src/trace.h, src/breakpoints.h, src/symbol.h, src/gpsim_interface.h, src/gpsim_time.h: The external references demarcated by 'IN_MODULE' were not getting resolved in FC3. Since these were introduced to resolve a linking problem with WIN32 DLL's, I made the demarcation dependent on only Windows. 2005-02-25 Scott Dattalo * src/stimuli.h, src/stimuli.cc: Added methods to the IOPIN class to differentiate between a pin driving a node and one being driven by a node. * src/14bit-tmrs.cc, src/i2c-ee.cc, src/packages.cc, src/ssp.cc, src/stimuli.cc, src/stimuli.h, src/uart.cc, extras/lcd/lcd.cc, gui/gui_breadboard.cc, modules/logic.cc, modules/logic.h, modules/usart.cc, modules/video.cc, modules/video.h: Propogate IOPIN change to all consumers. 2005-02-24 Scott Dattalo * src/stimuli.h, src/stimuli.cc: Added impedance thresholds to differentiate strong, weak, and floating drivers. 2005-02-16 Scott Dattalo * src/ioports.cc: experiments in ioport redesign. 2005-02-16 Scott Dattalo * src/stimuli.h, src/stimuli.cc: Added 'getBitChar()' method to the open collector stimulus class. 2005-02-15 Scott Dattalo * src/ioports.cc, src/ioports.h: Added a 'getIO' method to the IOPIN class that will allow an individual I/O pin in a port to be accessed. * src/stimuli.h, src/stimuli.cc: Add more state information to the snode class. Also, added the 'getBitChar()' method that will return the state of the stimulus in the form of an ASCII character (e.g. 0,1,Z,W). 2005-02-11 Scott Dattalo * src/os_dependent.cc: Libraries stored in system directories were getting ignored. 2005-02-09 Scott Dattalo * src/Makefile.am: Newly added src file 'os_dependent.cc' was not part of the Makefile * cli/input.cc, src/os_dependent.cc: abstracted some os dependent changes that were recently added 2005-02-01 Scott Dattalo * src/processor.h, src/processor.cc, src/trace.cc: Added 'Debug()' method to processor class and call it whenever a register assertion occur.s 2005-01-30 Borut Razem * config_win32.h.in, configure_win32.awk: extract version, package and bugreport values from configure.ac 2005-01-26 Scott Dattalo * configure.ac: repositioned the call to the m4 macro wi_READLINE_LIB so that it would run properly. 2005-01-26 Scott Dattalo * plat/win32/gpsim.def: added more external cross references. * module/modules.vcproj: changed from pthreadVC1.lib to pthreadVC.lib. 2005-01-23 Scott Dattalo * configure.ac: Craig Franklin updated gpsim's configure files. It turns out there was a tiny bug preventing things to build a *second* time (the first time would work fine) * src/gpsim_time.h, src/gpsim_time.cc, src/init.cc: The newly added and globally instantiated StopWatch class' constructor was making calls to the globally instantiated (but not necessarily constructed) Symbol_Table class. Now, StopWatch::init() will make the calls to the symbol table. 2005-01-21 Borut Razem * plat/win32/gpsim.def, src/src.vcproj: MSVC sync * doc/gpsimWin32.html: gpsim works with flex 2.4.31 2005-01-20 Scott Dattalo * src/breakpoints.cc: Trigger actions were not printing execution breakpoint messages. * src/registers.h, src/registers.cc: Added a skip_start function to the program counter. 2005-01-19 Scott Dattalo * src/registers.cc, src/registers.h, src/gpsim_object.cc, src/gpsim_object.h, src/symbol.cc, src/symbol.h, src/value.cc, src/value.h: Added the 'toBitStr' method to gpsim_object and propopogated the change through the derived classes. Also, the register class now calls get() to obtain the value printed with toString and toBitStr instead of directly using its value object. 2005-01-17 Scott Dattalo * src/gpsim_time.h, src/gpsim_time.cc: Finished the StopWatch class. * src/value.cc, src/value.h, src/attributes.cc, src/attributes.h: Added attribute breakpoints. For attributes that can be associated with breakpoints, you can now write 'break attribute' to set a breakpoint on that attribute. * cli/Makefile.am, cli/cmd_break.cc, cli/cmd_break.h, cli/cmd_help.cc, cli/command.cc, cli/parse.yy: The 'stopwatch' command is now handled by attributes. Added the following attributes: stopwatch, stopwatch.enable, stopwatch.direction, stopwatch.rollover. The 'stopwatch' attribute supports breakpoints, so the 'break stopwatch' command will break whenever the stopwatch rolls over. 2005-01-15 Scott Dattalo * src/attributes.cc, src/attributes.h: New files to support gpsim attributes. * src/Makefile.am, src/makefile.mingw: added the new files to the make files. 2005-01-14 Scott Dattalo * gpsim/main.cc, gui/gui_main.cc: The gtk main loop is now started even if the command line option --cli is specified. This way, the GIOChannels will still operate. 2005-01-13 Scott Dattalo * cli/sockect.cc, src/value.cc: Added support for 'Socket Sinks' and 'Socket Sources'. These essentially are two ways in which a client can choose to communicate with gpsim. 2005-01-10 Scott Dattalo * cli/sockect.cc, src/protocol.cc, src/protocol.h, src/symbol.cc, src/symbol.h, src/value.cc,src/value.h: Fixed bugs associated with socket notify links. 2005-01-09 Scott Dattalo * src/ioports.cc: Began I/O port redesign. * cli/socket.cc, src/protocol.h: Added Socket callbacks. * examples/scripts/client3.cc, examples/scripts/makefile, examples/scripts/client_interface.cc, examples/scripts/client_interface.h: Added a new client script example illustrating socket callbacks. * gui/gui_main.cc: removed a printf debug statement. 2005-01-09 Borut Razem * plat/win32/gpsim.def: MSVC sync * doc/gpsimWin32.html: dependedncy on gawk, ... * cli/cli.vcproj, cli/scan.ll: make it work with flex 2.4.31 * plat/win32/gpsim.nsi, modules/makefile.mingw, modules/modules.vcproj: pthreads 2005-01-03 * gui/gui_menu.cc: use utf-8 encoded LATIN SMALL LETTER Z WITH CARON instead LATIN SMALL LETTER Z. 2005-01-07 Scott Dattalo * src/16bit-processors.cc: stop gap hack - added registers to hold the places of the analog SFR's * cli/socket.cc, src/protocol.h, src/value.cc, src/value.h: More socket improvements. 2005-01-05 Scott Dattalo * src/breakpoints.cc, src/gpsim_classes.h, src/gpsim_interface.h, src/interface.cc, src/modules.cc, src/modules.h, src/pic-processor.cc, src/protocol.cc, src/protocol.h, cli/command.cc, cli/socket.cc: Enhancements to support the socket interface. Added a run command and a reset command and made them invocable via the interface class. 2005-01-02 Scott Dattalo * gui/gui_main.cc, cli/input.cc, src/interface.cc: Added function 'gUseThreads()' and use it to run-time select the usage of threads. 2005-01-02 Borut Razem * gui/gui_break.cc, gui/dialog.cc, gui/gui_init.cc, gui/gui_menu.cc, gui/gui_processor.cc, gui/gui_src.cc, gui/gui_src_asm.cc gui/gui_src_opcode.cc: removed unneeded include gtkcombobox.h * gui/gui_breadboard.cc: fixed compiler warnings * cli/Makefile.am, gui/Makefile.am: added AM_ preffix to CFLAGS, CXXFLAGS, CPPFLAGS and YFLAGS * doc/gpsimWin32.html: gtk+ version 2.4.14, XHTML 1.0 Transitional compliant, gtk+extra-2-1.1.0-20050102 * doc/gpsim_cvs.html: changed first build instructions 2004-12-17 Scott Dattalo * gui/gui_main.cc, src/interface.cc, cli/socket.cc: removed dependencies on GTK 2.0. 2004-12-19 Borut Razem * plat/win32/gpsim.nsi: added examples/scripts/client_interface.h to installation * mingw/makefile.mingw, gpsim/gpsim.vcproj: added gthread-2.0.lib * src/src.vcproj: removed plat\win32\glist.cpp from project; CLI mode now requires linking with full glib library; added src/trigger.cc and src/trigger.h to the project * modules/modules.vcproj: pthreads to the project * gpsim.sln: removed building of modules in CLI configuration 2004-12-17 Scott Dattalo * gui/gui_main.cc, src/interface.cc: replaced pthread_* calls and declarations with the corresponding GTK ones. 2004-12-17 Scott Dattalo * gui/gui_main.cc, src/interface.cc: Added experimental code to test threading. 2004-12-16 Scott Dattalo * gui/gui_main.cc, gui/gui_menu.cc: Use the interface instead of the cpu pointer to initiate simulation. * src/Makefile.am, src/trigger.cc, src/trigger.h, src/breakpoints.cc, src/breakpoints.h: Split the trigger classes away from the breakpoint classes. * src/gpsim_interface.h, src/init.cc, src/interface.cc, src/pic-processor.cc, src/protocol.cc, src/protocol.h, src/trace.h, cli/cmd_run.cc, cli/cmd_set.cc, cli/cmd_trace.cc, cli/input.cc, cli/socket.cc: Attempted (but failed) to add a feature that would allow a socket interface to send data to the simulator while a simulation is running. It turns out that the giochannel stuff used to control the socket runs in the gui event loop. The only time the socket is handled is whenever the loop can run. However, since gpsim is a single threaded application (the gui does spawn its own private thread), the gui event loop only runs whenever the simulation gives it cpu time. Thus it's not possible for a socket to update the simulation except when the gui is being refreshed! * examples/scripts/client.cc, examples/scripts/gensquares.asm, examples/scripts/makefile, examples/scripts/client2.cc, examples/scripts/client_interface.cc, examples/scripts/client_interface.h: Added a class to encapsulate the gpsim client socket interface. Added another example to test socket updates while the simulation is running. 2004-12-16 Borut Razem * plat/win32/gpsim.def: MSVC sync * src/14bit-registers.h: declare void Status_register::put(unsigned int new_value) as virtual, not inline * gui/gui_src_opcode.cc: removed definition of unused variable pm_size in method SourceBrowserOpcode_Window::NewProcessor() * extras/lcd/makefile.mingw: added * plat/win32/gpsim.nsi: added additional files from examples\scripts to the package * cli/input.cc: function have_line() is needed also in non GUI mode * gui/profile.cc, gui/gui_statusbar.cc, gui/gui_stopwatch.cc, gui/gui_trace.cc, src/14bit-tmrs.cc, src/16bit-registers.cc, src/eeprom.cc, src/i2c-ee.cc, src/interface.cc, src/interface.h, src/ioports.cc, src/p16x7x.cc, src/pic-processor.cc, src/pic-registers.cc, src/ssp.cc, src/stimuli.cc, src/tmr0.cc, src/uart.cc: replace direct access to cycles with a getter function get_cycles() 2004-12-15 Scott Dattalo * src/init.cc, src/gpsim_time.cc: Delayed creation of the cycle counter attribute. It turns out that this attribute was created in the Cycle_Counter constructor which is called by the globally instantiated 'cycles' object. On Windows, this call happened before the symbol table was inititialized . 2004-12-14 Scott Dattalo * src/init.cc: added new function for initialization. Also added new attribute 'sim.verbosity' that will control the simulator's verbosity. Note, this duplicates the behavior of the global variable 'verbose'. However, the goal is to phase out the global variable. * cli/cmd_run.cc: the run command now examines the new verbosity attribute. * src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h: the run member function now takes a parameter that controls whether or text will be printed. * cli/socket.cc: * src/interface.h: added extern def for new init function. * gpsim/main.cc: call new initialization function * src/breakpoints.cc: removed superfluous carriage return print. * examples/scripts/README, examples/scripts/client.cc, examples/scripts/makefile: added new files to illustrate scripting. * examples/scripts/gensquares.asm: minor tweak to simplify example regression test. 2004-12-14 Scott Dattalo * cli/scan.ll, cli/socket.cc, src/protocol.cc, src/protocol.h, src/value.cc: Fixed compilation issues with FC3 on an Athlon 64. 2004-12-11 Borut Razem * src/makefile.mingw, src/src.vcproj: added protocol.cc and protocol.h * plat/win32/gpsim.def: MSVC sync 2004-12-10 Scott Dattalo * src/gpsim_time.cc: Added a "cycles" attribute for interfacing with the cycle counter class. * src/protocol.cc, src/protocol.h, src/symbol.cc, src/symbol.h, src/value.cc, src/value.h, cli/socket.cc: More improvements to the protocol stuff. 2004-12-09 Scott Dattalo * src/protocol.h, src/protocol.cc, src/Makefile.am: New files to support a communication protocol for gpsim. * cli/socket.cc: moved much of the protocol related stuff to the new files. * src/value.h, src/value.cc, src/symbol.h, src/symbol.cc: Symbols and Values can now be assigned by Packets. * src/12bit-instructions.h, src/12bit-processors.h, src/14bit-instructions.h, src/14bit-processors.h, src/14bit-tmrs.h, src/16bit-processors.h, src/16bit-tmrs.h, src/breakpoints.h, src/p12x.h, src/p16f62x.h, src/p16x5x.h, src/p16x6x.h, src/p16x8x.h, src/pic-instructions.h, src/pic-processor.h, src/processor.h, src/trace.h, src/xref.h: fixed typo in GPL disclaimer. 2004-12-07 Scott Dattalo * cli/socket.cc: More socket clean up * src/modules.cc, src/modules.h, src/processor.cc, src/processor.h, src/symbol.cc, src/symbol.h: Removed deprecated code for setting/getting attributes. Added a new member function to the module_symbol that allows a character string to assign values to a module (this doesn't do anything yet). * modules/resistor.cc, modules/resistor.h, modules/usart.cc, modules/usart.h: removed deprecated set_attribute member function. 2004-12-06 Scott Dattalo * cli/socket.cc: Experimenting with binary data. Cleaned up socket link creation. Added a generic symbol read/write socket command. 2004-12-06 Scott Dattalo * cli/socket.cc: Wrap gtk2.x calls with #defines 2004-12-02 Scott Dattalo * cli/socket.cc: More additions to SocketLinks. It's now possible to tie a socket to a gpsim attribute. This allows an external application to directly control gpsim's behavior. 2004-12-02 Scott Dattalo * src/pic-processor.h, src/pic-processor.cc, src/p16f87x.h, src/p16f87x.cc: Added the PIC 16f876 2004-12-01 Scott Dattalo * cli/socket.cc: Fixed the socket interface for issues related to gtk 2.x. Began adding the SockeLink class. This class will sit on top of the socket interface and will hide it from the clients. The clients will be able to open SocketLinks and connect directly to gpsim internal objects. 2004-12-01 Borut Razem * plat/win32/gpsim.def: MSVC sync 2004-11-30 Scott Dattalo * gpsim/gpsim.vcproj: Removed references to files resource.h and gpsim.rc. 2004-11-30 Scott Dattalo * cli/cmd_break.cc, cli/cmd_break.h, cli/cmd_help.cc, cli/cmd_help.h, cli/cmd_load.cc, cli/cmd_load.h, cli/cmd_log.cc, cli/cmd_log.h, cli/cmd_macro.cc,, cli/cmd_macro.h, cli/cmd_module.cc, cli/cmd_module.h, cli/cmd_processor.cc,, cli/cmd_processor.h, cli/cmd_symbol.cc, cli/cmd_symbol.h, cli/command.cc, cli/misc.h, cli/parse.yy, cli/scan.ll: Changed the parser token STRING to LITERAL_STRING_T. The reason for this is to allow string type attributes to be treated like numeric attributes. * src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h, src/symbol.cc, src/symbol.h, src/value.cc, src/value.h: - Enhanced the 'String' class so that 1) it uses char * instead of STL string (yes this IS an enhancement) 2) the set() and get() methods can read and write to the String class. - Changed many instances of 'char *' to 'const char *'. 2004-11-29 Scott Dattalo * src/pic-processor.cc, src/processor.cc, src/processor.h, src/trace.cc, src/value.cc, src/value.h: Change Integer, Boolean, and Float classes back to hold values of native types (as opposed to holding pointers to the native types). * modules/video.cc: changed reference to cpu->frequency to cpu->set_frequency 2004-11-29 Scott Dattalo * cli/cmd_stimulus.cc: register stim were not getting started. * regression/register_stim/register_stim.[asm|stc], regression/run_regression.sh: Added a regression test for register stimuli. 2004-11-29 Scott Dattalo * src/stimuli.h, src/stimuli.cc, src/value.cc, src/value.h: Redesigned the 'asynchronous_stimulus' to be a 'ValueStimulus'. Added a new stimulus type: AttributeStimulus. An attribute stimulus is a stimulus that can be tied directly to some attribute. For example, a register symbol is a type of attribute. So an attribute stimulus can be tied to a register symbol to create a 'register stimulus'. * cli/cmd_stimulus.cc, cli/command.cc, cli/parse.yy: Added support for attribute stimuli. 2004-11-28 Borut Razem * plat/win32/gpsim.def: MSVC sync 2004-11-24 Scott Dattalo * src/processor.cc: operator[] for FileContext was not checking negative indices. 2004-11-24 Scott Dattalo * cli/input.cc: yet another attempt to fix tab completion. * modules/binary_indicator.cc, modules/binary_indicator.h modules/bitlog.h, modules/led.h, modules/logic.cc, modules/logic.h, modules/paraface.h, modules/resistor.cc, modules/video.cc, modules/video.h: Changed IO_input to IOPIN for all pins. This is an attempt to remove a warning message regarding IO_input that is generated while building under CygWin. * modules/makefile.mingw, plat/win32/gpsim.nsi: Renamed modules.dll to a slightly more descriptive gpsim_modules.dll * src/i2c-ee.cc, src/p12.cc, src/p16f62x.cc, src/p17c75x.cc, src/stimuli.h: exchanged references to IO_input to IOPIN. 2004-11-23 Scott Dattalo * plat/win32/gpsim.def, modules/modules.vcproj: MSVC sync * modules/*.cc: removed (char *) casts in calls to new_name() * gpsim/main.cc: removed some unnecessary includes. * gpsim/gpsim.vcproj: MSVC sync * cli/input.cc: removed some debug stuff * cli/cmd_log.cc: removed unreferenced variable. 2004-11-23 Borut Razem * plat/win32/gpsim.def, modules/modules.vcproj: MSVC sync 2004-11-23 Scott Dattalo * cli/input.cc: The tab completion fix for window's now causes a crash on Linux. Sigh. Now both oses are supported (without crashes) 2004-11-23 Scott Dattalo * cli/input.cc: Fixed tab completion related window's crash * gui/gui_symbols.cc: Windows doesn't support strndup() 2004-11-22 Scott Dattalo * cli/input.cc: buffer overflow in command_generator(). * src/ioports.cc, src/pic-registers.cc, src/registers.cc, src/stimuli.cc: valgrind check - unitialized memory. * src/value.h, src/value.cc, src/interface.h, src/symbol.cc, src/symbol.h, gui/gui_profile.cc, gui/gui_regwin.cc, gui/gui_regwin.h, gui/gui_src.cc, gui/gui_src.h, gui/gui_src_asm.cc, gui/gui_stack.cc, gui/gui_symbols.cc, gui/gui_watch.cc, gui/gui_watch.h: The gui was accessing the symbol table improperly. A new Symbol_Table_Iterator class was created to abstract accesses to the symbol table. In addition, get() and set() methods were added to the symbol classes that will allow reading/writing symbol values using strings. 2004-11-19 Scott Dattalo * gui/gui_breadboard.cc, gui/gui_regwin.cc, cli/parse.yy: valgrind check - fixed some uninitialized memory. 2004-11-19 Scott Dattalo * gui/gui_breadboard.cc: Don't let modules open a closed breadboard window. 2004-11-18 Scott Dattalo * cli/input.cc: disallow TAB characters under windows since it causes a crash most of the time. * modules/bitlog.cc, modules/bytelog.cc, modules/ttoken.cc, modules/makefile.mingw: These were not getting built under windows. * plat/win32/gpsim.nsi: added pthreadVC.dll to gpsim's windows binary distribution. * doc/gpsimWin32.html: Updated documentation for pthreads. 2004-11-17 Scott Dattalo * src/processor.cc, src/value.cc, src/value.h: made Integer,Float and Boolean values get() and set() their values through just one member function. This allows derived attributes to trap reads and writes to the values. 2004-11-16 Scott Dattalo * src/value.h, src/value.cc, src/processor.h, src/processor.cc, src/pic-processor.cc, src/symbol.h, src/symbol.cc: Added 3 new attributes: SafeMode, WarnMode, and UnknownMode to control the simulator's behavior under certain simulation conditions. Attribute handling has also been enhanced. * cli/parse.yy, cli/cmd_help.cc, cli/cmd_help.h: Help command will display information about attributes. 2004-11-15 Scott Dattalo * src/ioports.h, src/ioports.cc, src/16bit-registers.cc: Beginning to redesign I/O ports. 2004-11-14 Scott Dattalo * src/i2c-ee.cc, src/ioports.cc, src/ioports.h, src/stimuli.cc, src/uart.cc: The usart has bitrotted. The relatively recent I/O pin changes broke this and probably other peripherals too. * modules/Makefile.am: added new files. * modules/pthread-wrap.h, modules/ttoken.cc, modules/ttoken.h: The token class provides co-routine support for modules. * modules/bitlog.cc, modules/bitlog.h, modules/bytelog.cc, modules/bytelog.h: Bit and Byte event loggers. bitlog was originally part of the uart module. * modules/usart.cc, modules/usart.h: removed the bit logger class and am now making an attempt to resurrect this code. 2004-11-10 Scott Dattalo * cmd/cmd_break.cc: updated the help description for 'break' * src/operator.cc, src/symbol.h, src/symbol.cc: Allow registers to be type-cast into integers. 2004-11-10 Scott Dattalo * gui/gui_breadboard.cc: * src/breakpoints.cc, src/gpsim_object.cc, src/gpsim_object.h, src/modules.cc, src/processor.cc, src/registers.cc, src/registers.h, src/symbol.cc, src/symbol.h: - More attribute enhancements - added a module load capability that uses attributes. 2004-11-08 Scott Dattalo * cli/cmd_attach.h, cli/cmd_load.cc, cli/cmd_symbol.cc, cli/cmd_symbol.h, cli/command.cc, cli/parse.yy, cli/scan.ll cli/socket.cc: More attibute updates * gui/gui_breadboard.cc, gui/gui_menu.cc, gui/gui_object.cc, gui/gui_profile.cc, gui/gui_regwin.cc, gui/gui_src_asm.cc, gui/gui_stack.cc, gui/gui_statusbar.cc, gui/gui_symbols.cc: - Removed debugging printfs. - Changed attribute handling. * src/cod.cc, src/expr.cc, src/expr.h, src/gpsim_object.cc, src/modules.cc, src/p16x8x.cc, src/pic-processor.cc, src/processor.cc src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/symbol.h, src/tmr0.cc, src/value.cc, src/value.h: - Removed debugging statements - Added the attribute_symbol class. - Added more methods to the derived symbol classes to handle type casting. 2004-11-07 Borut Razem * plat/win32/gpsim.def, plat/win32/gpsim.nsi, src/makefile.mingw, src/src.vcproj: MSVC sync * doc/gpsimWin32.html: updated glib version to 2.4.7, gtk+ version to 2.4.13 2004-11-06 Scott Dattalo * cli/socket.cc, gui/gui_profile.cc, gui/gui_stack.cc, gui/gui_symbol.cc, src/symbol.cc, src/symbol.h, src/value.cc src/value.h: gpsim symbols now support more of the methods of the Value class. 2004-11-05 Scott Dattalo * cli/cmd_clear.cc, cli/cmd_disasm.cc, cli/cmd_set.cc cli/command.cc, cli/scan.ll, gui/gui_breadboard.cc, src/errors.cc src/expr.cc, src/operator.cc, src/value.cc, src/value.h: Cleaned up the Value class. 2004-11-05 Scott Dattalo * src/attribute.h, src/attribute.cc, Makefile.am: Removed attribute.* from gpsim. The class 'Value' has replaced it. 2004-11-04 Scott Dattalo * cli/cmd_break.cc, cli/cmd_log.cc, cli/cmd_symbol.cc, cli/cmd_x.cc, src/attribute.cc, src/cod.cc, src/expr.cc, src/gpsim_classes.h, src/modules.cc, src/modules.h, src/p12x.cc, src/p16f62x.cc, src/p16x5x.cc, src/p16x6x.cc, src/p16x7x.cc, src/p16x8x.cc, src/p18x.cc, src/pic-instructions.cc, src/pic-processor.cc, src/processor.h, src/symbol.cc, src/symbol.h, src/value.cc, src/value.h: - Rearranged class heirarchy so that gpsimValue derives from gpsimObject instead of Value. - Substitued the Value class for those places where the Attribute class is used. * modules/encoder.cc, modules/led.cc, modules/logic.cc, modules/push_button.cc, modules/resistor.cc, modules/switch.cc, modules/usart.cc, modules/video.cc 2004-11-04 Scott Dattalo * regression/create_stc, regression/simulate, src/expr.cc, src/symbol.cc, src/symbol.h, src/value.cc: Regression tests were failing due to recent parser changes. 2004-11-03 Scott Dattalo * cli/parse.yy, cli/scan.ll, src/14bit-registers.cc, src/16bit-instructions.cc, src/16bit-registers.cc, src/breakpoints.cc, src/breakpoints.h, src/expr.cc, src/expr.h, src/icd.cc, src/modules.cc, src/operator.cc, src/operator.h, src/p16x7x.cc, src/pic-instructions.cc, src/pic-instructions.h, src/pic-registers.cc, src/registers.cc, src/symbol.cc, src/symbol.h, src/value.cc, src/value.h: Added command line assignments. Now you can write stuff like: temp1 = temp2 << 4 where temp1 and temp2 are two registers. 2004-11-02 Scott Dattalo * src/attribute.cc, src/attribute.h, src/modules.cc, src/modules.h: cleaned up include dependencies. 2004-11-02 Scott Dattalo * src/gpsim_time.cc, src/gpsim_time.h: Fixed a bug with clearing cycle counter break points. 2004-11-01 Scott Dattalo * src/gpsim_time.cc, src/gpsim_time.h, src/breakpoints.cc, src/ioports.h, src/ioports.cc, src/stimuli.cc, src/tmr0.cc: Interrupts, tmr0 and I/O pins were all broken in some way. * regression/interrupts_14bit.asm, regression/interrupts_14bit.stc: Added regression test for the midrange devices 2004-10-29 Scott Dattalo * src/gpsim_time.cc, src/gpsim_time.h: Cycle counter debugging. 2004-10-20 Scott Dattalo * src/16bit-instructions.cc: Fixed bug in DECF instruction. * regression/instructions_16bit/instructions_16bit.asm: Added decf instruction to the regression test. 2004-10-20 Scott Dattalo * src/ioports.cc, src/ioports.h, src/stimuli.cc, src/stimuli.h: PORTB pullups updated. Added an overloaded update() member to Stimulus_Node that doesn't require time as an input (we never used it anyway). 2004-10-19 Scott Dattalo * src/stimuli.h, src/stimuli.cc, src/ioports.cc, src/i2c-ee.cc: Optimized I/O port stimulus updates. 2004-10-19 Scott Dattalo * src/stimuli.h, src/stimuli.cc: Began adding capitance modelling to stimuli. 2004-10-18 Scott Dattalo * src/gpsim_classes.h, src/registers.h: Added EXTERNAL_RESET and BOD_RESET types. 2004-10-17 Borut Razem * plat/win32/gpsim.def: MSVC sync * src/symbol.cc: fixed gpsim crash on WIN32 in remove_module() 2004-10-13 Scott Dattalo * src/cod.cc: Applied patch from Craig Franklin that adds support for reading .cod file message area. 2004-10-12 Scott Dattalo * src/gpsim_time.cc: Added diagnostic printf's * src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h: add an option to not update the gui while single stepping. 2004-10-11 Scott Dattalo * src/cod.cc, src/processor.cc: Applied, but modified, patch from Craig Franklin that brings gpsim up to date with new gputils release. 2004-10-07 Scott Dattalo * gui/gui_breadboard.cc, gui/gui_breadboard.h, gui/gui_menu.cc: Cleaned up the gui breadboard code a little by making the gui_module structure a GuiModule class. In addition, new modules are queued into the breadboard and realized only after the breadboard has been built. 2004-10-07 Scott Dattalo * gui/gui_src_opcode.cc: window was being built before cpu had been initialized. * cli/cmd_disasm.cc, src/processor.cc, src/trace.cc: Disassembling and tracing had wrong addresses for the 18F family (again...) 2004-10-06 Scott Dattalo * gui/gui_src.h, gui/gui_src_asm.cc, gui/gui_src_opcode.cc, gui/gui_statusbar.cc, src/breakpoints.cc: Fixed breakpoint icon refreshing. Also fixed Source browser window creation if either ~/gpsim is missing or the registry hasn't been initialized 2004-10-05 Scott Dattalo * gui/gui_src_asm.cc: Moved the creation of the Search Dialog window out of Build() and into its own function. Changed the behavior of the signal callbacks to conform to GTK+ 2.X 2004-10-04 Scott Dattalo * README, INSTALL: Cleaned up stale documentation. 2004-10-04 Scott Dattalo * cli/input.cc: Send an extra CR to the parser when loading a command file. Turns out that when the gui loads a file, the parser doesn't process it until another CR is seen. 2004-10-04 Scott Dattalo * gui/gui_src_asm.cc, gui/gui_regwin.cc, gui/gui_breadboard.cc: Removed some debugging printfs. * gui/gui_object.cc: With GTK+ 2.2.1 under linux, the gtk_widget_show() was losing the (x,y) position of the window. 2004-10-04 Scott Dattalo * gui/gui_breadboard.cc, gui/gui_breadboard.h: The breadboard expose events invalidated drawing areas which in turn recursively generated expose events. I'm not sure why this code worked with GTK+ 1.x 2004-10-04 Scott Dattalo * gui/gui_breadboard.cc, gui/gui.h, gui/gui_stopwatch.cc, gui/gui_object.cc, gui/gui_main.cc, gui/gui_object.h, gui/gui_profile.cc, gui/gui_regwin.cc, gui/gui_scope.cc, gui/gui_src.h, gui/gui_src_asm.cc, gui/gui_src_opcode.cc, gui/gui_stack.cc, gui/gui_stopwatch.cc, gui/gui_symbols.cc, gui/gui_trace.cc, gui/gui_watch.cc: Work in progress - trying to resolve breadboard start up issues with GTK+ 2.X . 2004-10-03 Borut Razem * config_win32.h.in, plat/win32/configure_win32.awk, cli/cli.vcproj, src/src.vcproj, plat/win32/make.mingw, makefile.mingw, cli/makefile.mingw, gpsim/makefile.mingw, gui/makefile.mingw, modules/makefile.mingw, src/makefile.mingw: added configure_win32.awk script, which takes version number from configure.in and inserts them into config_win32.h.in and generates cofig.h * plat/win32/gpsim.def: MSVC sync 2004-10-01 Scott Dattalo * src/processor.cc, src/processor.h, gui/gui.h, gui/gui_regwin.c gui/gui_asm.cc, gui/gui_src_opcode.c, plat/win32/make.mingw: Stabilizing windows port. Apparently under windows there's a problem if you issue too many gui calls to the GTK library. I found that this can be mitigated by periodically clearing out the gtk event queue. 2004-09-29 Scott Dattalo * cli/input.cc, gui/gui_menu.cc, gui/gui_src_asm.cc, src/modules.h, src/modules.cc, src/processor.cc, src/pic-processor.cc, src/pic-processor.h, src/trace.h plat/win32/gpsim.def: Clean ups to get the Windows port to compile. 2004-09-29 Scott Dattalo * gui/gui_src_asm.cc, src/pic-instructions.cc: Uninitialized variables in the instruction class were causing the source browser to place objects beyond the range allocated to the source browser. This confused GTK+ 2.x. 2004-09-28 Scott Dattalo * cli/cmd_load.cc, cmd/input.cc: Allow loading of filenames with spaces. (note, gpsim's command line interface still does not support this). 2004-09-28 Scott Dattalo * gui/gui_main.cc, gui/gui_menu.cc, gui/gui_object.cc, gui/gui_object.h, gui/gui_regwin.cc, gui/gui_src.h, gui/gui_src_asm.cc, src/gpsim_interface.h, M src/interface.cc: - Fixed a few bugs caused by upgrading to GTK+ 2.x: -- Window state was not being saved -- Register window font was fouled up -- Source browser pixel position calculations are different There are still some other bugs that need to be fixed: -- The breadboard window somehow prevents the Source browser window from opening -- Q no longer quits -- scrolling in source browser only works if the scroll pane has focus -- The register window cheats in guessing character width. 2004-09-24 Scott Dattalo * src/processor.cc: save_state() was skipping address 0. * src/registers.cc: Bit string encoding has been enhanced 2004-09-15 Scott Dattalo * gui/gui_regwin.h, gui/gui_regwin.cc: max allowable registers is 64k (used to be 4k) * gui/gui_src_asm.cc: improperly initialized instructions were causing a core dump. 2004-09-19 Borut Razem * configure.in: gpsim is configured to link with GTK+ 2.x by default. Use --enable-gtk1 for linking with GTK+ 1.x (deprecated). 2004-09-15 Scott Dattalo * gui/gui_regwin.cc, gui/gui_src_asm.cc: Fixed ranging checks. 2004-09-15 Scott Dattalo * src/processor.cc, src/processor.h, src/pic-processor.cc: getWriteTT and getReadTT used to return TraceType objects, but now they return unsigned ints. 2004-09-15 Scott Dattalo * src/processor.cc, src/trace.cc, gui/gui_src_opcode.cc: - 18f processors' addresses were off by a factor of two in disassembly operations. 2004-09-14 Borut Razem * cli/cli.cvproj, src/src.vcproj, plat/win32/gpsim.def: MSVC sync * cli/makefile.mingw, src/makefile.mingw: MinGW sync * plat/win32/gpsim.nsi: corrected revision number to 0.22.3 2004-09-14 Scott Dattalo * regression/p12ce518/p12c518.asm, regression/p12ce518/p12c518.stc, regression/p12ce518/EEdriver.asm: Added a regression test for the 12ce518. * src/stimuli.cc, src/i2c-ee.cc, src/ioports.cc, src/stimuli.h, src/14bit-registers.cc: Fixed stimuli so that the 12CE518 internal EEPROM would work. 2004-09-13 Scott Dattalo * src/i2c-ee.cc, src/i2c-ee.h, src/ioports.cc, src/p12x.cc, src/stimuli.cc, src/stimuli.h: Partially check in for work on the 12ce518 bug (internal I/O pins). 2004-09-12 Scott Dattalo * cli/Makefile.am, cli/errors.cc, cli/errors.h: * src/Makefile.am, src/errors.cc, src/errors.h: Moved errors.* from cli/ to src/ * src/expr.cc, src/operator.cc, cli/cmd_disasm.cc, cli/cmd_set.cc, cli/cmd_x.cc, cli/command.cc, cli/command.h, cli/parse.yy, cli/scan.ll: Updated the directory path for including errors.h. 2004-09-12 Borut Razem * cli/cli.cvproj, src/src.vcproj, plat/win32/gpsim.def: MSVC sync * cli/makefile.mingw, src/makefile.mingw, gpsim/makefile.mignw: MinGW sync 2004-09-11 Scott Dattalo * configure.in: Bumped the Revision up to 0.22.3 since there have been *so* many changes. * cli/expr.h, cli/expr.cc, cli/operator.cc, cli/operator.h: - moved to the src/ directory * src/expr.h, src/expr.cc: copied from the cli/ directory * src/Makefile.am, cli/Makefile.am * src/symbol.h, src/value.h, src/symbol.cc, src/value.cc: - It turns out that gpsim's symbols are essentially identical to the value objects that were recently added to support expression parsing. Since expressions need to handle symbols too, I decided to make the Value class a base class for gpsimValue. Now, much of what has been written for expressions will naturally handle many of gpsim fundamental types. * src/pic-processor.cc, src/pic-processor.h, src/eeprom.cc, src/eeprom.h, src/14bit-registers.cc: The W register, eeprom, and option register states were not saved during a processor 'save_state()' call. * src/p12x.cc: internal 12ce518 i2c module was not connected correctly. * cli/cmd_clear.cc, cli/cmd_disasm.cc, cli/cmd_frequency.cc, cli/cmd_log.h, cli/cmd_macro.cc, cli/cmd_module.h, cli/cmd_set.cc, cli/cmd_step.cc, cli/cmd_stimulus.h, cli/cmd_symbol.cc, cli/cmd_trace.cc, cli/cmd_trace.h, cli/cmd_x.cc, cli/command.cc, cli/command.h: Updated the paths to the include files that have moved 2004-09-08 Scott Dattalo * cli/cmd_x.cc, cli/expr.cc, cli/expr.h, cli/operator.cc, cli/operator.h, cli/parse.yy, cli/scan.ll: - Added command line comparison expressions. * src/pic-processor.cc, src/pic-registers.cc, src/symbol.cc, src/symbol.h, src/value.cc, src/value.h: - Added support for a generic symbol type. - Added the pic PC object to the symbol table. * regression/digital_stim/digital_stim.stc: The new expression parsing introduced a grammer conflict that requires a stimulus data list to be expressed differently. 2004-09-08 Scott Dattalo * src/14bit-registers.h, src/14bit-tmrs.h, src/breakpoints.cc, src/breakpoints.h, src/eeprom.h, src/gpsim_interface.h, src/gpsim_time.cc, src/gpsim_time.h, src/i2c-ee.h, src/p16x7x.h, src/pic-processor.cc, src/processor.cc, src/processor.h, src/ssp.h, src/stimuli.cc, src/stimuli.h, src/tmr0.h, src/trace.h, src/uart.h gui/gui_profile.cc, modules/encoder.h, modules/paraface.h modules/usart.cc: Started adding Triggers and Actions. * regression/run_regression.sh: Added the digital_stim regression test to the list of tests to run. 2004-09-07 Scott Dattalo * src/stimuli.cc, src/stimuli.h, cmd_x.cc, cmd_stimulus.cc: Digital asynchronous stimuli were not getting the proper voltage data values. Enhanced the asynchronous stimulus by making the data array an array of C++ objects instead of a type casted structured. 2004-09-06 Scott Dattalo * examples/14bit/analog_stim2.stc, examples/14bit/ap.stc, examples/14bit/async_pulse.stc, examples/14bit/async_stim2.stc, examples/14bit/dtmf.stc, examples/12bit/gpio_stim.stc: - Updated the asynchronous stimulus syntax in all of the example startup scripts 2004-09-05 Scott Dattalo * src/ioport.cc, src/stimuli.cc: Applied patch from Robert Pearce regarding I/O Pins and stimuli Fixed a couple more issues with I/O pins and contention. 2004-09-02 Borut Razem * cli/socket.cc: read complete line before procesing, support for different line endings (LF, CR-FL) * cli/cmd_macro.cc: enable compilation on VS 7.1 2004-09-02 Scott Dattalo * cli/cmd_macro.cc: Clarified the help description for the macro command. 2004-09-02 Scott Dattalo * cli/cmd_macro.cc, cli/cmd_macro.h, cli/scan.h, cli/scan.ll: Completed support for parameterized macros 2004-09-02 Scott Dattalo * cli/cmd_macro.cc, cli/cmd_macro.h, cli/input.cc, cli/parse.yy, cli/scan.ll: Added support for parameterized macros. This is not completed 2004-09-02 Borut Razem * cli/input.cc, cli/socket.cc: socket port to WIN32 * gpsim/gpsim.vcproj, cli/cli.vcproj, cli/makefile.mingw, gpsim/makefile.mingw: added cmd_macro.* and socket.cc to the project, wsock32.lib dependency 2004-09-01 Scott Dattalo * cli/parse.yy: Fixed a bug that caused old versions of bison to choke. 2004-09-01 Scott Dattalo * cli/cmd_macro.cc, cli/input.cc: Converted the LLInput struct into a class. Now, the macro command can invoke a macro and redirect it's output to the parser stream. * src/trace.cc, src/trace.h: Added the ProcessorTraceObject to the TraceObject heirarchy. Now, TraceObjects no longer store info about a processor. (Thus modules can be processor agnostic.) 2004-09-01 Scott Dattalo * src/p16x5x.cc: The 16C55 processor was only declaring a package of 18 pins (instead of 28). 2004-08-31 Scott Dattalo * cli/cmd_macro.cc, cli/cmd_macro.h: Added the 'macro' command. * cli/Makefile.am, cli/parse.yy, cli/command.cc, cli/scan.ll: Parser now calls the gpsim command cmd_macro. 2004-08-31 Scott Dattalo * cli/scan.ll, cli/parse.yy: Added language support for macro definitions. (although, macros are not yet supported). 2004-08-29 Borut Razem * plat/win32/gsim.def, cli/makefile.migw, src/makefile.migw, cli/cli.vcproj, src/src.vcproj: updated * cli/errors.h, cli/scan.ll: corrected include paths * plat/win32/gpsim.nsi: gpsom.pdf included in WIN32 setup * doc/gpsimWin32.html: gtk+ 2.4.7 2004-08-27 Scott Dattalo * src/breakpoints.cc, src/gpsim_object.cc, src/gpsim_object.h, src/modules.cc, src/modules.h, src/pic-processor.cc, gui/gui_src_asm.cc, gui/gui_statusbar.cc: The Module class was overriding functionality provided in the gpsimObject class. This caused problems for external processors (That is, processors not a part of gpsim). 2004-08-26 Scott Dattalo * src/gpsim_object.cc, src/gpsim_object.h: New files that support the gpsimObject class. This is a base class for almost all gpsim objects. * cli/viewable.cc, cli/viewable.h: Removed. The functionality that was provide by these was moved to gpsimObject. * src/Makefile.am, src/modules.h, src/registers.cc, src/registers.h, src/symbol.cc, src/value.cc, src/value.h, cli/Makefile.am, cli/cmd_x.cc, cli/command.cc, cli/command.h, cli/expr.cc, cli/expr.h, cli/parse.yy: Added the gpsimObject Meta class. Added support for symbolically viewing registers with the 'x' command. Added support for viewing a range of registers. 2004-08-26 Scott Dattalo * src/stimuli.cc, src/symbol.cc, src/symbol.h, gui/gui_profile.cc, gui/gui_stack.cc, gui/gui_symbols.cc cli/scan.ll: The symbol class is now derived from the gpsimValue class. This change allows some of the recent enhancements created for other things to be applied to symbols as well. * examples/14bit/p16c64_pwm.stc, examples/14bit/portc_stim.stc: The PWM module was crashing. I'm not sure why, but I think what actually was happening that the example stc file was just broken. 2004-08-25 Scott Dattalo * cli/cmd_trace.cc, src/14bit-registers.cc, src/trace.cc, src/trace.h: Removed a stale option to the trace command and added a new option that will allow the decode trace buffer to be saved to a file. 2004-08-25 Manuel Bouyer * src/stimuli.cc: fixed bug in finding the node voltage when 3 or more stimuli are attached to a node. 2004-08-24 Scott Dattalo * src/stimuli.cc: Attaching three or more stimuli to one node caused gpsim to hang. 2004-08-24 Manuel Bouyer * src/stimuli.cc: Fixed iopin stimulus update. 2004-08-24 Scott Dattalo * cli/cmd_attach.cc, cli/cmd_attach.h, cli/cmd_symbol.cc, cli/cmd_symbol.h, cli/expr.cc, cli/expr.h, cli/parse.yy, cli/scan.ll, src/stimuli.cc, src/stimuli.h, src/symbol.h: The attach command can now accept a list of symbols. Also, Nodes and stimuli are now added to the symbol table whenever they're constructed. 2004-08-19 Scott Dattalo * src/processor.cc: writeTT and readTT were not initialized in Processor constructor. 2004-08-18 Scott Dattalo * src/registers.cc, src/registers.h, src/symbol.cc, src/symbol.h, src/trace.cc, src/trace.h, cli/cmd_symbol.cc, cli/cmd_symbol.h, cli/expr.cc, cli/expr.h, cli/parse.yy, cli/scan.ll: More improvements to tracing. Added some more symbolic command line processing. 2004-08-16 Scott Dattalo * src/trace.cc, src/trace.h: CVS was broken. 2004-08-16 Scott Dattalo * src/intcon.cc, src/intcon.h, src/processor.h, src/trace.cc src/trace.h, src/value.h: Trace stuff *** CVS is broken at the moment but will be fixed within 3 hours of the time stamp of this change 2004-08-14 Borut Razem * plat/win32/gpsim.nsi: small changes * doc/gpsimWin32.html: documented GCC compilation 2004-08-13 Scott Dattalo * src/14bit-processors.cc, src/14bit-registers.cc, src/14bit-registers.h src/14bit-tmrs.cc, src/16bit-registers.cc, src/eeprom.cc, src/intcon.cc, src/ioports.cc, src/p16x7x.cc, src/pic-processor.cc, src/pic-registers.cc, src/pie.cc, src/pir.cc, src/processor.cc, src/processor.h, src/registers.cc, src/registers.h, src/ssp.cc, src/tmr0.cc, src/trace.cc, src/trace.h, src/uart.cc: More Tracing. 2004-08-11 Scott Dattalo * src/trace.cc, src/trace.h, src/processor.cc, src/pic-processors.cc src/value.h, src/value.cc, src/registers.h, src/registers.cc, 14bit-registers.cc: More trace stuff. 2004-08-10 Borut Razem * plat/win32/gpsim.nsi: packaging of examples, extras, ... * plat/win32/gpsim.def: updated exports * extras/lcd/lcd.cc, extras/lcd/lcdengine.cc, extras/lcd/lcdgui.cc, extras/lcd/module_manager.cc: define IN_MODULE for modules, calling accessor methods for global objects * modules/makefile.mingw, modules/modules.vcproj: removed unneeded define MODULES_EXPORTS 2004-08-09 Scott Dattalo * src/14bit-registers.cc, src/14bit-registers.h, src/14bit-tmrs.cc, src/16bit-registers.cc, src/attribute.cc, src/eeprom.cc, src/intcon.cc src/ioports.cc, src/modules.cc, src/p16x7x.cc, src/pie.cc, src/pir.cc src/registers.cc, src/ssp.cc, src/tmr0.cc, src/trace.cc, src/trace.h src/uart.cc, gui/gui_breadboard.cc, modules/led.cc, modules/paraface.cc modules/resistor.cc,modules/usart.cc: Continuing this ongoing trace experiment. 2004-08-09 Scott Dattalo * src/trace.cc, gpsim/main.cc: more experimental code * src/attribute.cc, src/attribute.h, gui/gui_breadboard.cc: Some annoying bug with attributes that I can't figure out. Problem appears when shared libraries are disabled. 2004-08-06 Scott Dattalo * src/processor.cc, src/processor.h, src/registers.h, src/trace.cc: Partial implementation of trace reconstruction. 2004-08-04 Scott Dattalo * src/14bit-registers.cc, src/16bit-processors.cc, src/16bit-registers.cc src/p12x.cc, src/p16f62x.cc, src/p16f87x.cc, src/p16x5x.cc, src/p16x6x.cc src/p16x7x.cc, src/p16x8x.cc, src/p18x.cc, src/pic-processor.cc, src/pic-processor.h, src/processor.cc, src/processor.h, src/registers.cc src/registers.h, src/tmr0.cc, src/trace.cc, src/trace.h, gui/gui_regwin.cc cli/cmd_trace.cc: Two categories of changes have been made: First, the unitialized register concept has been propogated to all of the register constructions. Second, tracing has been improved yet again. 2004-08-04 Borut Razem * plat/win32/gpsim.nsi: packaging of MinGW executables * gpsim/gpsim.vcproj: cleanup * plat/win32/make.mingw, cli/makefile.mingw, gpsim/makefile.mingw, gui/makefile.mingw, modules/makefile.mingw, src/makefile.mingw: do not define NDEBUG to enable assertions in release version 2004-08-02 Borut Razem * gui/gui_breadboard.cc, gui/gui_menu.cc, src/hexutils.cc, src/interface.cc, src/packages.cc, src/xref.cc: reverted unneeded changes * config_win32.h.in, plat/win32/fd2raw.cpp: ifdefed MSVC specifics * cli/input.cc, src/pic_processor.cc: corrected the sequence of includes 2004-08-01 Borut Razem * makefile.mingw, cli/makefile.mingw, gpsim/makefile.mingw, gui/makefile.mingw, modules/makefile.mingw, src/makefile.mingw, plat/win32/make.mingw: added mingw (cygwin -mno-cygwin) gcc WIN32 native makefiles * config_win32.h.in, gui/gui_breadboard.cc, gui/gui_menu.cc, src/hexutils.cc, cli/input.cc, src/interface.cc, src/packages.cc, src/pic_processor.cc, plat/win32/uxtime.h, src/xref.cc: changes to enable mingw (cygwin -mno-cygwin) gcc WIN32 native compilation * src/modules.cc: added initialization of widget Module class member * plat/win32/glist.cpp: corrected line formatting 2004-07-31 Borut Razem * plat/win32/gpsim.def: updated exports * acinclude.m4, src/breakpoints.cc, cli/input.cc: small cleanups 2004-07-29 Scott Dattalo * src/14bit-instructions.cc, src/16bit-instructions.cc, src/pic-instructions.cc, src/pic-registers.cc, src/trace.cc, src/trace.h: The newly rewritten trace printing code was broken. The good news is that while fixing it, I found a way to save a little simulation time by not tracing the instruction opcodes. 2004-07-29 Scott Dattalo * src/ioports.cc, src/ioports.h, src/modules.cc, src/registers.cc, src/registers.h, src/stimuli.cc, src/stimuli.h: Minor stimuli bug fixes, commenting and general cleanup. * cli/cmd_trace.cc, src/trace.cc, src/trace.h, src/trace_orb.h, src/pic-registers.cc, src/processor.cc, src/processor.h: Rewrote the trace printing code. 2004-07-24 Borut Razem * plat/win32/gpsim.def: updated exports * plat/win32/gpsim.nsi: don't cd when running gpsim * doc/gpsimWin32.html: XHTML 1.0 compliant, snapshots at a separate page 2004-07-22 Scott Dattalo * src/stimuli.cc, modules/resistor.cc, modules/resistor.h: Bug fixes to the recent I/O pin redesign 2004-07-22 Scott Dattalo * src/14bit-tmrs.cc, src/breakpoints.cc, src/breakpoints.h, src/i2c-ee.cc, src/ioports.cc, src/ioports.h, src/p16x7x.cc, src/p16x7x.h, src/packages.cc, src/pic-processor.h, src/processor.cc, src/processor.h, src/registers.cc, src/registers.h, src/ssp.cc, src/stimuli.cc, src/stimuli.h, src/uart.cc, modules/binary_indicator.cc, modules/binary_indicator.h, modules/led.cc, modules/led.h, modules/logic.cc, modules/logic.h, modules/paraface.cc, modules/paraface.h, modules/resistor.cc, modules/resistor.h, modules/usart.cc, modules/video.cc, modules/video.h: Rewrote the way stimuli are handled. Before, gpsim only used a single parameter (more or less) to represent the state of an stimulus. Now, two parameters are used. Currently, these parameters are designated as the voltage and impedance. Before, the single parameter was somewhat similar to a current. 2004-07-20 Scott Dattalo * src/stimuli.h, src/stimuli.cc: added input leakage modelling to I/O pins. 2004-07-19 Scott Dattalo * src/pic-processor.cc, src/pic-processor.h, src/pic-registers.cc, src/processor.h, src/processor.cc, gui/gui_statusbar.cc, gui/gui_stopwatch.cc, modules/usart.cc, cli/cmd_frequency.cc: Added new member functions to the Processor class to simplify handling time. 2004-07-17 Borut Razem * plat/win32/gpsim.def, src/src.vcproj, src/i2c-ee.cc: small fixes for MSVC compilation 2004-07-16 Scott Dattalo * gui/gui_statusbar.h, gui/gui_statusbar.cc: Now the status bar can accept an arbitrary of registers to display. * src/16bit-processors.cc, src/processor.h: Added BSR to the list of registers viewable in the status bar. * cli/cmd_trace.cc, cli/cmd_trace.h, cli/parse.yy, src/trace.cc: The trace raw option was broken. 2004-07-15 Scott Dattalo * cli/input.cc, cli/socket.cc, gui/gui_main.cc: The newly created gpsim socket interface now uses GLib GIOChannels instead of Pthreads. 2004-07-14 Scott Dattalo * gui_break.cc, gui_main.cc, gui_processor.cc, gui_processor.h, gui_regwin.cc gui_regwin.h, gui_src.h, gui_src_asm.cc, gui_src_opcode.cc, gui_statusbar.cc, gui_statusbar.h: Finished abstracting the gui status bar. Added a status bar to the source viewer. * 14bit-registers.cc, 14bit-registers.h, 14bit-tmrs.h, 16bit-processors.cc, Makefile.am, eeprom.h, intcon.h, ioports.cc, ioports.h, p12x.cc, p12x.h, p16f62x.cc, p16x5x.cc, p16x6x.cc, p16x8x.cc, pic-processor.cc, pic-processor.h, pic-registers.cc, pic-registers.h, pie.h, pir.h, processor.cc, processor.h, registers.h: Cleaned up some stale code. Added a MemoryAccess class and made it the base class to the RegisterMemoryAccess and ProgramMemoryAccess classes. 2004-07-14 Robert Pearce * src/i2c-ee.cc, src/i2c-ee.h, src/Makefile.am: New files that support an i2c peripheral * src/p12x.cc, src/p12x.h, src/pic-processor.h, src/pic-processor.cc: Added the 12CE518 and 12CE519 processors. * src/ioport.cc: Fixed an ambiguity in the ioport trace logic. 2004-07-13 Scott Dattalo * gui/gui_statusbar.cc: abstracting the status bar boxes. * src/pic-registers.cc: cross reference to Program Counter was broken. * src/processor.h, src/processor.cc: Added a set_PC method to the pma class 2004-07-12 Scott Dattalo * gui/gui_statusbar.cc: abstracting the status bar boxes. * examples/scripts/gensquares.asm, examples/scripts/testgensquares.py, examples/scripts/testgensquares.py: Script testing 2004-07-12 Scott Dattalo * cli/socket.cc: dinking around... * examples/scripts/testsocket.py: 2004-07-09 Scott Dattalo * cli/socket.cc: Added a very thin object layer to the socket interface * examples/scripts/testsocket.py: added to the repository. This is a simple python script that will exercise all of the commands that gpsim will accept through a socket interface. 2004-07-08 Scott Dattalo * gui/gui_main.cc, cli/socket.cc, cli/input.cc, configure.in: Added support for multithreading. * TODO: cleaned up the TODO list a little by removing some outdated items. 2004-07-08 Manuel Bouyer * src/16bit-registers.cc, src/16bit-registers.h: Added put() and update_pin_directions() methods for the PORTC16 class 2004-07-07 Scott Dattalo * cli/socket.cc: New file * cli/input.cc: init_gpsim() will now create a socket. Added a Socket class that is capable of creating a socket and accepting commands. * src/registers.h: added an option to fetch the RegisterValue object without causing a trace to be emitted. 2004-07-06 Borut Razem * gui/settings.h, gui/settings_exdbm.h, gui/settings_exdbm.cc, gui/gui.h, plat/win32/settings_reg.h, plat/win32/settings_reg.cpp, gui/gui.vcproj, gui/Makefile.am: added additional layer to hide differences between eXdbm and WIN32 registry * store settings in registy on WIN32 2004-07-03 Borut Razem * plat/win32/gpsim.ico, plat/win32/gpsim.nsi: created NSIS setup script 2004-07-02 Scott Dattalo * gpsim/input.cc, gui/gui_menu.cc: Now files are correctly loaded through the menu interface (File/Open) * cli/parse.yy, cli/scan.ll, cli/operator.cc, cli/operator.h: Added new binary operators: -,*,/,&,^,<<,>> 2004-07-02 Scott Dattalo * gpsim/main.cc: Emit warning if a user specifies both a .hex file and a .cod file at the command line. 2004-06-30 Scott Dattalo * plat/win32/gpsim.def: Added additional export definitions. * cli/cmd_clear.cc: type casting fixes. * src/breakpoints.h: added get_bp accessor function for the global bp (breakpoint) object * src/gpsim_time.h: now uses the bp accessor function. * src/processor.cc: If the listing file is not present, gpsim will not crash now... 2004-06-30 Scott Dattalo * gpsim/main.cc, cli/input.cc: Starting gpsim in cli only mode would cause a crash. 2004-06-30 Borut Razem * plat/win32/gpsim.def: small fix for MSVC compilation 2004-06-28 Scott Dattalo * cli/parse.yy, cli/misc.h, cli/cmd_symbol.cc, src/symbol.cc: Removed 'NUMBER' and 'FLOATING_NUMBER' types from the CLI parser. Now all numbers are represented by expressions. All commands that used to numbers have been converted over to use expressions. 2004-06-28 Scott Dattalo * cli/cmd_module.cc, src/modules.h, src/modules.cc, gui/gui_breadboard.cc: Module positioning now works again. 2004-06-27 Scott Dattalo * gui/gui_breadboard.cc: From Ralph, the breadboard was not using module pixmaps. * cli/cmd_module.cc, cli/cmd_module.h, cli/command.cc, cli/parse.yy: cli module command now supports expressions. 2004-06-27 Borut Razem * gpsim.sln: set project dependency - modules depends on gpsim * gpsim/gpsim.vcproj: corrected Ignore Specific Library settings * doc/gpsimWin32.html: added to CVS 2004-06-24 Scott Dattalo * cli/cmd_break.cc, cli/cmd_break.h, cli/cmd_log.cc, cli/cmd_log.h, cli/cmd_stimulus.h, cli/command.cc, cli/command.h, cli/expr.cc, cli/expr.h, cli/parse.yy,cli/scan.ll: The 'break' and 'log' commands now accept expressions 2004-06-24 Borut Razem * plat/win32/fd2raw.cpp, plat/win32/fd2raw.h: functions to set the WIN32 console to raw mode. * cli/input.cc: call functions to set WIN32 console to raw mode * gui/gui.vcproj: added fd2raw.cpp and fd2raw.h to the project * cli/cli.vcproj: added errors.cc and errors.h to the project 2004-06-23 Scott Dattalo * cli/Makefile.am, cli/cmd_attach.cc, cli/cmd_attach.h, cli/cmd_bus.cc, cli/cmd_bus.h * cli/cmd_clear.cc, cli/cmd_clear.h, cli/cmd_disasm.cc, cli/cmd_disasm.h, * cli/cmd_frequency.cc, cli/cmd_frequency.h, cli/cmd_node.cc, cli/cmd_node.h, * cli/cmd_set.cc, cli/cmd_set.h, cli/cmd_step.cc, cli/cmd_step.h, * cli/cmd_stimulus.cc, cli/cmd_stimulus.h, cli/cmd_trace.cc, cli/cmd_trace.h, * cli/cmd_x.cc, cli/command.cc, cli/command.h, cli/expr.cc, cli/expr.h, * cli/input.cc, cli/misc.h, cli/operator.cc, cli/operator.h, cli/parse.h, * cli/parse.yy, cli/scan.ll * gpsim/main.cc, gui/gui_breadboard.cc, src/processor.cc, * src/processor.h, src/stimuli.cc Rewrote the command parser and added expression parsing. * cli/errors.cc, cli/expr.cc, cli/operator.cc, cli/viewable.cc, cli/errors.h, cli/expr.h, cli/operator.h, cli/viewable.h: New files for expression parsing. 2004-06-16 Borut Razem * plat/win32/gpsim.def, gui/gui_src_asm.cc, src/symbol.cc, src/symbol.h: small fixes to enable compilation on MSVC 2004-06-15 Scott Dattalo * more pedantic fixes 2004-06-14 Scott Dattalo * more pedantic fixes (mostly in cli) 2004-06-14 Scott Dattalo * tons of pedantic fixes (and there are many more needed). 2004-06-14 Scott Dattalo * aclocal.m4, configure.in The AC_DEFINE macro was incompletely defined. * acconfig.h: removed from CVS * INSTALL: updated installation instructions for CVS checkouts * doc/gpsim_cvs.html: Added to the CVS 2004-06-12 Borut Razem * cli/viewable.cc: #warning not recognised by MSVC * eXdbm/eXdbm.vcproj, gui/gui.vcproj, modules.vcproj: new project files for GUI support * gpsim.sln, gpsim/gpsim.vcproj, cli/cli.vcproj, src/src.vcproj: GUI support * plat/win32/gpsim.def, plat/win32/modules.def: WIN32 def files for DLL modules support * plat/win32/glist.cpp: added g_win32_error_message() for --disable-gui * cli/input.c: define gpsim_rl_getc() only if defined HAVE_READLINE && defined HAVE_GUI 2004-06-09 Scott Dattalo * cli/expr.cc, cli/expr.h, cli/viewable.h, cli/viewable.cc, cli/operator.h, cli/operator.cc: New files to support parsing * cli/parse.yy, cli/scan.ll: added new parsing and lexing rules for expression parsing. * src/stimuli.cc: Manuel Boyer found and fixed a bug where the a named stimulus was ignoring its newly assigned name. 2004-06-09 Scott Dattalo * cli/parse.yy, cli/scan.ll, cli/misc.h, cli/cmd_stimulus.cc, cli/command.h Cleaned up the parser by removing the explicit YYABORT and YYACCEPT macros. Also, redesigned the parser implementation of the stimulus command. 2004-06-03 Scott Dattalo * examples/12bit/it_12bit.asm: removed * regressions/instructions_12bit/instructions_12bit.asm: added * regressions/instructions_12bit/instructions_12bit.stc: added Now the 12bit core has a regression test. 2004-06-05 Scott Dattalo * src/eeprom.cc: The eeprom memory access object was not getting initialized. * src/stimuli.cc: applied patch from Manuel Boyer. The IO_open_collector was duplicating the base class' job of setting the pin name. 2004-06-02 Scott Dattalo * cli/cmd_break.cc, src/processor.cc: 18fxxx addressing was broken. (the divide by 2 issue for the 18f addressess was not being handled correctly.) 2004-06-01 Scott Dattalo * src/value.h: Made the string &name() member function in the gpsimValue class virtual. 2004-05-31 Scott Dattalo * almost all files: Since the Register class and the Instruction class are now derived from gpsimValue, all objects that use registers and instructions have to change. These changes have been propogated through gpsim. Next, the gui will start taking advantage of the abstractness that this change introduces. * src/16bit-instructions.cc, src/14bit-instructions.h: Manuel Boyer reported two bugs with the 16bit subwf instruction. He fixed one (N-bit was ignored) with a patch and I fixed the other (OV bit was ignored). 2004-05-27 Scott Dattalo * src/value.h, src/value.cc: New files that support abstract values. * src/register.h, src/pic-instructions.h: Now all base objects that have values are derived from the new gpsimValue object. 2004-05-27 Scott Dattalo * src/breakpoints.h, src/breakpoints.cc: Execution breakpoints now support a customizable message that will be displayed when the break is encountered. 2004-05-21 Scott Dattalo * src/processor.cc, src/register.h, register.cc, gui/gui_register.h, gui/gui_regwin.c: Gui Register Window now can show unitialized register data. 2004-05-21 Scott Dattalo * src/register.h: Added new accessor member functions to the Register class to manipulate the new way register values are represented. 2004-05-20 Scott Dattalo * Tons of files... Changed the Register class' 'unsigned int value' field to an object. The get() and put() accessor functions now provide read and write access. 2004-05-20 Scott Dattalo * gui/gui_src_asm.cc: Syntax highlighting now is only applied to lines that are associated with generated code. 2004-05-16 Scott Dattalo * src/processor.h, src/processor.cc: Added mapping between program memory and source file line numbers 2004-05-16 Scott Dattalo * gui/gui_src.h, src/gui_src_asm.cc: Fixed memory leak with 'canbreak' XPM. Added 'SourcePage' class to hold information about a source browser notebook page. Corresponding info in 'SourceBrowserAsm_Window'. Added a new member to the sa_entry structure to keep track of pixmaps. 2004-05-15 Scott Dattalo * src/pic-processor: If the simulation is started from an address that has an execution break, now gpsim will ignore that break. * xpm/canbreak.xpm: New xpm that's used to indicate source lines that will accept breakpoints. * gui/gui_src.h, gui/gui_src_asm.h: Added 'canbreak' XPM to the source browser lines that can accept break points. NOTE: this code currently leaks memory! 2004-05-12 Manuel Bouyer * src/16bit-instructions.cc, src/p18x.cc, src/p18x.h, src/pic-instructions.cc, src/pic-processor.cc, src/pic-processor.h: Fix usart problems in 18x devices. * src/pir.cc, src/pir.h, src/uart.cc, src/uart.h: Fix usart bugs. (Changes were submitted as a patch and applied by Scott). 2004-05-15 Scott Dattalo * src/xref.h, xref.cc: added get_value() member function to XrefObject class * gui/gui.h, gui/gui_break.cc, gui/gui_main.cc, gui/gui_processor.cc, gui/gui_regwin.cc, gui/gui_regwin.h, gui/gui_statusbar.cc: Converted the structure labeled_entry into a class and renamed it to LabeledEntry. * gui/gui_statusbar.h: Added. 2004-05-12 Scott Dattalo * cli/scan.ll: Identifiers can now contain dashes. 2004-05-12 Scott Dattalo * src/stimuli.cc: bi-directional I/O pins were not working properly with modules. * src/processor.cc: removed debug printf stuff * src/ioports.cc: IOPORT class was using a hardcoded number of pins 2004-04-27 Borut Razem * cli/input.cc, gui/gui_main.cc: fixes to make working of CLI & GUI in parallel 2004-04-22 Borut Razem * modules/binary_indicator.cc modules/binary_indicator.h modules/encoder.cc modules/encoder.h modules/gpsim_modules.cc modules/led.cc modules/led.h modules/logic.cc modules/logic.h modules/paraface.cc modules/paraface.h modules/push_button.cc modules/push_button.h modules/resistor.cc modules/resistor.h modules/switch.cc modules/switch.h modules/usart.cc modules/usart.h modules/video.cc modules/video.h: defined IN_MODULE symbol for modules, call get_interface(), get_cycles(), get_active_cpu(), get_symbol_table(), get_trace(void) accessor methods instead direct object access 2004-04-21 Borut Razem * src/gpsim_interface.h, src/gpsim_time.h, src/processor.cc, src/symbol.cc, src/trace.cc: create instances of inline methods by taking theirs address, so that they can be accessed from dynamic loadable modules 2004-04-19 Scott Dattalo * modules/binary_indicator.cc, modules/encoder.cc, modules/gpsim_modules.cc, modules/led.cc, modules/logic.cc, modules/paraface.cc, modules/push_button.cc, modules/resistor.cc, modules/switch.cc, modules/usart.cc, modules/video.cc: Fixed ambiguous (to read, but still syntactically correct) references to "new_name". * src/breakpoints.h, src/breakpoints.cc: added a post assertion option to the register assertions. 2004-04-18 Borut Razem * src/14bit-registers.h, src/gpsim_interface.h, src/gpsim_time.h, src/processor.h, src/symbol.h, src/trace.h: introduced get_interface(), get_cycles(), get_active_cpu(), get_symbol_table(), get_trace(void) accessor methods * config_win32.h.in: defined GPSIM_MAJOR_VERSION, GPSIM_MINOR_VERSION and GPSIM_MICRO_VERSION symbols 2004-04-15 Scott Dattalo * src/14bit-tmrs.cc, src/ioports.cc, src/ioports.h: PORTC's T1OSC input can clock TMR1 on some PIC's. I've added some preliminary support for this. 2004-04-14 Scott Dattalo * gui/gui_break.cc, gui/gui_menu.cc, gui/gui_profile.cc, gui/gui_src_asm.cc, gui/gui_src_opcode.cc, gui/gui_stack.cc, src/16bit-registers.cc, src/breakpoints.cc, src/cod.cc, src/eeprom.cc, src/ioports.cc, src/ioports.h, src/pic-processor.cc, src/processor.cc, src/processor.h, src/trace.cc: Made the processor's ProgramMemoryAccess class dynamically allocated. * src/Makefile.am: ssp.h was not part of the install. 2004-04-14 Scott Dattalo * src/14bit-tmrs.cc: The TMR2 peripheral failed to properly clear its breakpoint whenever it was being turned off. *src/modules.h: string.h was not getting included. 2004-04-13 Scott Dattalo * src/breakpoints.cc, src/breakpoints.h: Redesigned breakpoints so that a) they're more object oriented and b) more easily extensible. * src/interface.cc, src/gpsim_interface.h: Removed the CyclicBreakPoint class and moved the functionality it was providing into the gpsimInterface class * src/14bit-registers.h, src/14bit-tmrs.h, modules/usart.cc, cli/cmd_set.cc, src/eeprom.h, src/gpsim_time.cc, src/gpsim_time.h, src/p16x7x.h, src/pic-processor.cc, src/processor.cc, src/processor.h, src/ssp.h, src/stimuli.cc, src/stimuli.h, src/tmr0.h, src/trace.h, src/uart.h, gui/gui_profile.cc, modules/encoder.h, modules/paraface.h,: Removed the BreakCallBack class. The functionality it was providing is now implemented by the BreakpointObject class. 2004-04-11 Borut Razem * src/interface.cc: added initialization of interface_seq_number in gpsimInterface constructor. 2004-04-07 Scott Dattalo * src/breakpoints.h, src/breakpoints: Adding assertion type breakpoints and redesigning the whole Breakpoint class. 2004-04-07 Bert Driehuis * extras/lcd/lcd.cc: reference was made to a no-longer existing API * extras/lcd/module_manager.cc: contained comments which were out of date, that hampered readability. * src/modules.cc: will not load two shared extension modules, if the first does not have an "initialize" routine. As a side effect of debugging this one, the error reporting of the dynaloader has been expanded. The trick turned out to be to clear pre-existing error conditions with a dummy call to dlerror(). An alternative implementation would call dlerror in an else clause when loading "initialize" fails, but doing it like this patch does it has the advantage of also dealing with like errors in libraries gpsim might use. For a similar situation, look up "not a typewriter" and "perror" in Google. - did not immediately fail when incomplete linking conditions exist. By changing to RTLD_NOW, a bad dynamic module will be detected at load time rather than at run time. *** this will break broken modules out there that until now appeared to have worked *** 2004-04-04 Arthur Peters * src/Makefile.am, src/ssp.cc, src/ssp.h: Added SSP support to gpsim. * src/14bit-processors.h, src/ioports.cc, src/ioports.h, src/p16f87x.cc, src/p16x6x.cc, src/p16x6x.h, src/p16x7x.cc, src/p16x8x.cc, src/pir.cc, src/14bit-processors.h, src/pir.h: Added SSP support to gpsim. 2004-04-04 Borut Razem * modules/encoder.cc, modules/gpsim_modules.cc, modules/paraface.cc, modules/push_button.cc, modules/switch.cc, modules/video.cc: modules port on WIN32 2004-04-03 Borut Razem * src/stimuli.cc: fixed warning C4715: 'IOPIN::get_iop' : not all control paths return a value: IOPIN::get_iop() returns 0 in case that iopp and iop are NULL 2004-04-01 Scott Dattalo * modules/resistor.cc, modules/resitor.h: Several member functions in the resistor classes were declared, but not defined anywhere. * src/pic-instructions.h, src/breakpoints.h, src/breakpoints.cc: adding assertions to the simulator. * src/processor.cc, src/processor.h, gui/gui_src_asm.cc: Source browser windows can now get a unique name. 2004-03-30 Scott Dattalo * numeous files throughout gpsim: The Module class now uses a string type instead of a 'char *' for the module name. Also, the gui x and y coordinate were removed from the module class (I still want to remove the 'widget' member too). * modules/usart.cc: calls to the old gpsim api were still lingering around here. * gui/gui_src_asm.cc, gui/gui_src.h, src/processor.h: more browser splitting stuff. 2004-03-29 Borut Razem * src/modules.cc: support of external modules on WIN32 2004-03-25 Scott Dattalo * gui/gui_src_asm.cc: Now we can load hex files again. 2004-03-25 Bert Driehuis * extras/lcd/lcdengine.cc, extras/lcd/lcdengine.cc, extras/lcd/lcd.h, extras/lcd/lcdgui.cc, extras/lcd/examples/lcd.asm: Added support for CGRAM in the LCD module. 2004-03-25 Scott Dattalo * src/processor.h, src/processor.cc: Added pma_context list * gui/Makefile.am: Recently added .h files are now in the Makefile * gui/gui_src.h, gui/gui_src_asm.cc: Multiple source browsers are now created based on the number of pma_contexts * gui/gui_object.h, gui/gui_src_asm.cc, gui/gui_breadboard.cc, gui/gui_main.cc, gui/gui_profile.cc, gui/gui_regwin.cc, gui/gui_scope.cc, gui/gui_src.cc, gui/gui_src_opcode.cc, gui/gui_stack.cc, gui/gui_stopwatch.cc, gui/gui_symbols.cc, gui/gui_trace.cc, gui/gui_watch.cc: The GUI_Object 'name' member has been changed from a char * to a private string and is now no longer directly accessed by the derived classes. New methods set_name() and and name() control the access. 2004-03-24 Scott Dattalo * gui/gui_src_asm.cc, gui/gui_src.h: Added BreakPointList class to handle the 3 lists of breakpoints. Removed duplicate code too. 2004-03-23 Borut Razem * src/modules.cc: gpsim on WIN32 doesn't support modules yet * gui/gui_breadboard.cc: GTK+ 2.x port 2004-03-22 Scott Dattalo * gui/gui_src.cc: Changed the event key processing from a case statement to a C++ map object. 2004-03-22 Scott Dattalo * gui/gui.h, gui/gui_breadboard.h, gui/gui_object.h, gui/gui_processor.h, * gui/gui_profile.h, gui/gui_register.h, gui/gui_regwin.h, gui/gui_scope.h, * gui/gui_src.h, gui/gui_stack.h, gui/gui_stopwatch.h, gui/gui_symbols.h, * gui/gui_trace.h, gui/gui_watch.h: Finished the gui split started on 03-16. Added support for multiple source browsers (to be used with context debugging). 2004-03-22 Chris Emerson * modules/encoder.cc, modules/encoder.h: new files: added an encoder module * modules/Makefile.am: Added the encoder to the list of files. * gpsim/main.cc: gracefully revert to cli if gtk_init fails. * src/ioports.cc: remove PORTA debug message. 2004-03-17 Scott Dattalo * gui/gui.h, gui/gui_breadboard.h, gui/gui_object.h, gui/gui_processor.h, * gui/gui_profile.h, gui/gui_register.h, gui/gui_regwin.h, gui/gui_scope.h, * gui/gui_src.h, gui/gui_stack.h, gui/gui_stopwatch.h, gui/gui_symbols.h, * gui/gui_trace.h, gui/gui_watch.h Split gui.h into a bunch of separate include files. 2004-03-16 Scott Dattalo * gui/gui_regwin.cc, gui/gui.h: abstracted the width of registers 2004-03-15 Scott Dattalo * src/modules.h, src/modules.cc: Removed the "ExternalModule" class * modules/binary_indicator.cc, modules/gpsim_modules.cc, modules/led.cc, modules/logic.cc, modules/paraface.cc, modules/push_button.cc, modules/resistor.cc, modules/switch.cc, modules/usart.cc, modules/video.cc, extras/lcd/lcd.h, extras/lcd/lcd.cc Now the modules are no longer "external". 2004-03-14 Bert Driehuis * extras/lcd/lcdengine.cc, extras/lcd/lcd.h, extras/lcd/examples/lcd.asm: Fixed the LCD modules "E" logic. 2004-03-13 Robert Pearce * src/16f87x.cc, src/16f87x.h, src/pic-processor.cc, src/pic-processor.h: Added 16f871. 2004-03-09 Scott Dattalo * src/16bit-instructions.cc, src/trace.cc: Addresses displayed for the 18F devices are now displayed properly. 2004-03-09 Scott Dattalo * src/14bit-processor.cc: PCL (low byte of program counter) was one count too large. 2004-03-09 Scott Dattalo * src/processor.cc, src/processor.h, src/pic-processor.cc, src/pic-processor.h: Moved the implementations of the disasm() and list() methods from the pic_processor class to the processor class. 2004-03-09 Scott Dattalo * src/pic-instructions.h, src/12bit-instructions.h, src/stimuli.h, src/14bit-instructions.h, src/14bit-instructions.h, src/16bit-instructions.h, src/16bit-instructions.cc: changed references of pic-processor to Processor. 2004-03-08 Scott Dattalo * modules/push_button.cc, modules/push_button.h: new module from Carlos Ghirardelli. 2004-03-04 Scott Dattalo * src/register.h, src/pic-register.h, src/pic-processor.h, src/pic-processor.cc, src/14bit-registers.cc Removed the "file_register" class. Moved the sfr_register class to register.h. 2004-03-04 Scott Dattalo * src/processor.h, src/processor.cc, src/cod.cc: Added the new meber 'Find()' to the 'Files' class. 2004-03-03 Bert Driehuis * /extras/rs232-gen/rs232.c: Now compiles under BSD 2004-03-03 Scott Dattalo * gui/gui_profile.cc, gui/gui_src_asm.cc, src/cod.cc, src/icd.cc, src/pic-processor.cc, src/processor.cc, src/processor.h Removed references to "processor_id". Changed name of _Files to Files in the Processor class. 2004-03-01 Bert Driehuis * regression/run_regression.sh, regression/simulate: Fixes to allow regression tests to run on BSD 4.9. 2004-03-01 Bert Driehuis * extras/lcd/lcd.cc: Bring the LCD module up-to-date with recent gpsim changes 2004-03-01 Bert Driehuis * acinclude.m4, cli/input.cc: Fix readline support for BSD 4.9 2004-03-02 Scott Dattalo * src/pic-processor.cc: fixed a memory allocation bug in the FileContext class; an array was one element too small. * examples/modules/led_test, examples/modules/led_test/led_mod.asm, examples/modules/led_test/led_mod.asm: Added the LED test code to CVS. * modules/gpsim_modules.cc, modules/led.cc: LED module now works. 2004-03-01 Bert Driehuis * src/icd.cc: include time.h for BSD 2004-03-01 Scott Dattalo * modules/* - Updated the (internal) modules to comply with the new gpsim interface standard * dozens of files: -- removed all references to 'pic_id' -- changed pic_processor references to Processor references 2004-02-29 Borut Razem * src/eeprom.cc: initialization of variable eestate in EECON2::EECON2(void) by calling ee_reset() 2004-02-28 Borut Razem * config_win32.h.in : strtoll defined as _strtoi64, removed definition of atoll, version number updated to 0.21.2 * gui/gui.h, gui/gui_stopwatch.cc: prevent calling Update() from Update(). The problem manifested on GTK+ 2.x on Linux and WIN32. * gui/gui_breadboard.cc, gui/gui_regwin.cc, gui/gui_src_asm.cc, gui/gui_src_opcode.cc: GTK+ 2.x port - use pango font handling * examples/14bit/pulse_measure.asm: variable upper renamed to _upper; upper is an assembler instruction operand in gpasm and mpasm 2004-02-28 Scott Dattalo * gui/gui_main.cc, gui/gui_menu.cc, gui/gui_processor.cc: Inhibit the half-baked gui_scope. 2004-02-27 Scott Dattalo * src/pic-processor.cc, src/interface.cc, src/interface.h, src/init.cc, src/icd.cc, src/cod.cc, src/breakpoints.cc, gui/gui_main.cc, gpsim/main.cc, cli/input.h, cli/input.cc, cli/cmd_x.cc, cli/cmd_run.cc, cli/cmd_dump.h, cli/cmd_dump.cc: The gpsim library, which is the code comprised of everything in the src/ subdirectory, now has no dependencies on the gui or cli code base. This makes it possible to link against just libgpsim. 2004-02-25 Scott Dattalo * gui/gui_stopwatch.cc, extras/rs232-gen/rs232-gen.c: changed all references of atoll to strtoll. bug 820326 2004-02-25 Hans-Juergen Dorn * src/16bit-registers.cc: gpsim was pushing onto the stack before decrementing the stack pointer. Also, the gpsim internally formatted address was being pushed. 2004-02-17 Scott Dattalo * gui/gui_scope.cc: expose and resizing kind of work. 2004-02-17 Scott Dattalo * gui/gui_scope.cc: taking off the rough edges. 2004-02-16 Scott Dattalo * gui/gui_scope.cc: - new file that will support a simple waveform viewer. * gui/Makefile.am: add the gui_scope.cc to the list * gui/gui_regwin.cc: Check for null pointers * gui/gui_symbols.cc: Check for null pointers * src/pic-processor.cc, src/p16x5x.h, src/p12x.h, src/p12x.cc, src/14bit-registers.h, src/14bit-registers.cc, src/14bit-processors.cc, src/12bit-processors.h, src/12bit-processors.cc Added FSR_12 - a new class for the 12-bit core. I also redesigned the way FSR and INDF interact. * src/p18x.cc - the 18f252 package pins weren't defined. 2004-02-13 Scott Dattalo * src/processor.cc, src/processor.h, src/pic-processor.cc, src/cod.cc: Support for new file context * gui/gui_src_asm.cc, gui/gui_profile.cc: Use the new file context code. 2004-02-12 Scott Dattalo * src/interface.cc, src/interface.h: Finally, the C-style interface is gone (or nearly gone). * src/processor.cc, src/processor.h, src/cod.cc Redesigning the "file_context" object. * gui/gui_watch.cc, gui/gui_profile.cc: Removed final traces of the old C-style interface. 2004-02-11 Scott Dattalo * gui/gui_symbols.cc: - changed strndup to a strcpy (plus malloc...): 2004-02-11 Scott Dattalo * gui/* changed calls to gpsim_* to the C++ interface. * src/interface.cc - removed many of the gpsim_* functions * src/stimuli.cc, cli/cmd_set.cc - changed calls to gpsim_* to the C++ interface. 2004-02-10 Scott Dattalo * src/processor.cc, src/processor.h, src/pic-processor.cc, src/pic-processor.h: Added step, run, and finish members to the ProgramMemoryAccess class * src/interface.cc, gui/gui* removed more gpsim_* functions from interface.cc 2004-02-10 Scott Dattalo * gui/gui_symbol.cc, src/symbol.h, src/symbol.cc Cleaned up symbol api. 2004-02-09 Scott Dattalo * all files! 'NULL' has been replaced with '0' throughout all of gpsim. The reason is two-fold: 1) MAC users were having trouble compiling 2) Stroustrup says NULL shouldn't be used in C++ :). 2004-02-08 Scott Dattalo * src/processor.cc, src/processor.h, gui/gui_src.cc, gui/gui_src_asm.cc, gui/gui_break.cc: Fixed 'ProgramMemoryAccess' class for the 18f devices * src/16bit-processors, src/p18x.cc: Removed some debug stuff * extras/lcd/*: Changed the LCD module from version 0.2.0 to 0.2.1 2004-02-06 Scott Dattalo * tons of files changed... Removed 'break_point' member from the Register class Changed the mechanism for checking how a break point is set on a register. * gui/gui.h, gui/gui_watch.cc, gui/gui_regwin.cc: modified GUIRegister class to adopt to changes made in the break point stuff. Also add rma member for getting access to processor registers. 2004-02-05 Scott Dattalo * src/pic-processor.h Fixed a nasty, nasty bug. The "GP_Processor" pointer in the pic_processor class was conditionally compiled. However the condition (HAVE_GUI) occurs in the include file config.h. Now the bug is that config.h was not included in all cases. Some classes were derived from pic_processor with this definition while others weren't. Syntactically, everything was okay. But the compile had the conflicting information for the size of pic_processor class. * src/* - whole bunch of other files touched while looking for this bug. 2004-02-04 Scott Dattalo * src/processor.cc Experimenting with operator [] for the ProgramMemoryAccess class. 2004-02-02 Scott Dattalo * src/intcon.*, src/processor.*, src/16bit-processor.* Fixed the weird bug that was discussed in the 2004-01-30 entry. The problem was basically invalid type casting. In the processor class heirarchy, there are about 5 or 6 levels of inheritance. Most of the time gpsim accesses a processor's details through one of the base classes. Sometimes though, an object needs access to somthing specific to a processor. In these cases, gpsim would type cast a pointer to the specific processor. The bug is that you can't safely type cast a base class object into a derived class object in C++. 2004-01-30 Scott Dattalo * almost all source files - still trying to sort out include dependencies. There's a weird bug where gcc is adding an extra 4-byte offset to pointers in some instances. I have no clue why... 2004-01-29 Scott Dattalo * almost all source files - trying to sort out include dependencies 2004-01-28 Scott Dattalo * src/pir.h moved all of the PIR*::put()'s to the PIR base class * src/intcon.h, src/intcon.cc moved inline functions that called bp and trace objects from the header file to the .cc file. * src/pir.cc new file - added so that inline functions that called bp and trace objects could be removed from the header file. * src/Makefile.am added pir.cc to the list of src files. 2004-01-26 Scott Dattalo * src/* gui/* Replaced references to 'file_register' with 'Register'. Removed many gpsim_*() calls. Renamed the program_memory_access class to ProgramMemoryAccess. Moved processor member functions associated with code breakpoints into the ProgramMemoryAccess class. 2004-01-26 Scott Dattalo * src/register.h, src/register.cc, src/pic-register.h, src/pic-processor.h, src/14bit-registers.cc cleaned up some include file dependencies. moved the program counter class. 2004-01-23 Scott Dattalo * src/trace.cc, src/trace.h: added boolean event logger * src/intcon.cc, src/16bit-*: Debugging an interrupt problem with the 16-bit core 2004-01-22 Scott Dattalo * gui/gui*.cc: converted the cross_reference_to_gui structure into the CrossReferenceToGUI class. * src/pir.h: fixed default names of the PIR registers * regression/p16f873/p16f873.asm: added 2004-01-20 Scott Dattalo * gui/gui_regwin.cc, gui/gui_src_asm.cc, gui_watch.cc: Changed gpsim_* api calls to their direct counterparts * src/interface.cc, src/interface.h: Removed obsolete API's * src/breakpoints.cc (clear_all_register): added * cli/input.cc: fixed memory leak. * doc/gpsim.lyx: updated documentation with recent CLI changes 2004-01-18 Borut Razem * configure.in: added --enable-gtk2 configure command line option for linking with GTK+ 2.x 2004-01-17 Borut Razem Update to GTK+ 2.x: * config_win32.h.in: version 0.21.1, updated #defines * cli/cmd_load.cc, cli/input.cc, cli/input.h: char * replaced with const char *, removed unneeded #include * gui/gui.h, gui/gui_breadboard.cc, gui/gui_break.cc, gui/gui_dialog.cc, gui/gui_menu.cc,gui/gui_object.cc, gui/gui_profile.cc, gui/gui_regwin.cc, gui\gui_src.cc, gui/gui_src_asm.cc, gui/gui_src_opcode.cc, gui/gui_stack.cc, gui/gui_statusbar.cc, gui/gui_stopwatch.cc, gui/gui_symbols.cc, gui/gui_trace.cc, gui/gui_watch.cc: char * replaced with const char *, GdkFont replaced with PangoFontDescription, GtkStyle replaced with GtkStyle *, #define GTK_ENABLE_BROKEN, #include replaced with #include , update for GTK+ 2.x * src/cod.cc, src/interface.cc, src/interface.h, src/modules.cc, src/modules.h, src/p16x5x.cc, src/pic-processor.cc, src/pic-processor.h, src/processor.h, src/stimuli.cc, src/stimuli.h, src/symbol.cc, src/symbol.h, src/trace.cc, src/trace.h: char * replaced with const char *, __PRETTY_FUNCTION__ replaced with __FUNCTION__ * modules/binary_indicator.cc, modules/binary_indicator.h, modules/led.cc, modules/led.h, modules/logic.cc, modules/logic.h, modules/paraface.cc, modules/paraface.h, modules/resistor.cc, modules/resistor.h, modules/switch.cc, modules/switch.h, modules/usart.cc, modules/usart.h, modules/video.cc, modules/video.h: char * replaced with const char *, 2004-01-06 Scott Dattalo * gui/gui_regwin.cc -- valgrind memcheck bug fixes * src/cod.cc * src/registers.cc 2004-01-06 Scott Dattalo * src/p16x5x.cc - patch from Rob Pearce that fixes the 16C5X tris writes. 2004-01-05 Scott Dattalo * src/14bit-tmrs.cc - tmr2 bug. PWM period was getting ANDed with 0xff. 2004-01-03 Scott Dattalo * Applied patch from Borut Razem - adds new files to Visual Studio project files. 2004-01-03 Scott Dattalo * Applied patch from Bradley McLean mailto:bradlist@bradm.net that adds support for the 18f1320. * Applied patch from Mike Durian that fixes an 18f SUB instruction. 2003-12-31 Scott Dattalo * Applied patch from Mike Durian. He's added several files to more reasonably group together portions of the simulator. In addition, he's added eeprom support to the 18f devices * src/eeprom.cc - new file to consolidate eeprom related stuff * src/intcon.cc - new file to consolidate variations in intcon registers * src/pie.cc - new file for pie register * src/intcon.h * src/pir.h * src/pic-instructions - fixed bug in 18f banking * src/16x5x.h - 16c54 register memory size was wrong * gui/gui_stopwatch.cc - added a check to make sure there's a processor * gui/gui_src*.cc - removed reference to cpu->pc->get_value() 2003-12-28 Scott Dattalo * another patch from Borut Razem: * cli/input.cc: - added function get_dir_delim(), which searches for both / and \ delimiters on WIN32 systems. - fixed bug in gpsim_read(): logic for deallocating input_buf was moved out of 'if (chars_left > 0)' block. - some code cleaning, some compiler warnings fixed * cli/input.h: - added declarations of exit_gpsim() and get_dir_delim() * gpsim/main.cc: - removed declaration of exit_gpsim(), now included in cli/input.h * src/14bit-registers.cc: - deallocation of name_str1 is already done in ~Register(). * cod.cc: - included cli/input.h for declaration of get_dir_delim() - substr() replaced with get_string(), which gets the string from .cod file. strings in .cod file are represented as: - first byte defines the string length - the string starts at the second byte. - read_src_files_from_cod(): conversion to DOS file name - open_cod_file() opens .cod file in binary mode * src/pic-instructions.cc: - initialize xref to NULL if HAVE_GUI not defined * src/processor.cc, * src/processor.h: - static pointer to the processor_list 2003-12-27 Scott Dattalo * patch from Borut Razem for Visual Studio projects 2003-11-29 Scott Dattalo * src/pic-processor.cc - rewrote the way gpsim groups together all of the processors it supports. Now the ProcessorConstructor class will allow processors to be instantiated anywhere in the code (before, they were declared in one giant array.) 2003-11-29 Scott Dattalo * src/16bit-registers.cc - Access to PLUSWx are now signed. 2003-11-28 Scott Dattalo * gui/* - More C to C++ conversions * gui/gui_menu.cc - Patch from Alex Holden to enable compilation on a MAC * src/icd.cc * INSTALL - added instructions for MAC OS 2003-11-24 Scott Dattalo * gui/* First round of struct to class conversion is now completed 2003-11-20 Scott Dattalo * src/ioports.cc - PORT B pullups were not working * regression/* - Added some more regression tests 2003-11-16 Scott Dattalo * gui/* More conversions to C++ 2003-11-15 Scott Dattalo * gui/* started converting gui struct's into C++ classes. Started with Register Window. 2003-10-26 Scott Dattalo * src/gpsim-time.cc linked-list bug fixes. 2003-10-26 Scott Dattalo * eXdbm/* applied patch from Borut Razem mailto:borut.razem@siol.net to fix an uninitialized pointer bug. 2003-10-26 Scott Dattalo * modules/* removed all references to gui if not building with the gui 2003-09-24 Scott Dattalo (patches from Steve Tell) * modules/paraface.h - Solaris patch for bogus device * src/cod.cc - Endian bug * gui/gui_processor.cc - use memset instead of bzero. 2003-09-14 Scott Dattalo * src/gpsim_time.h - changed cycle counter break point from a Singly linked list to a doubly linked list. This is in preparation for separating module time from pic processor time so that when the PIC goes to sleep, time doesn't stop. 2003-09-07 Scott Dattalo * src/p16f62x.h - duplicate declaration of intcon register 2003-09-07 Scott Dattalo * src/breakpoints.cc - this time the 'Too many cycle counter breakpoints' was fixed. BTW the problem was that 'clear_break' was not putting the cleared breakpoint back into the 'inactive' list 2003-09-07 Scott Dattalo * src/pic_processor.cc -- Fixed the "Too many cycle counter breakpoints" bug * src/interface.cc It turns out that the "realtime" stuff was * src/breakpoints.cc 1) duplicating a class declaration. 2) not clearing * src/breakpoints.h cycle counter break points. * gpsim.sln - added for win32 port. 2003-08-30 Scott Dattalo * src/p12x.cc -- The 12c5xx will reset if an I/O is toggled and the processor is sleeping. 2003-08-27 Scott Dattalo * config_win32.h.in - added 2003-08-25 Scott Dattalo * src/ioports.cc - more 16f628 Port A fixes 2003-08-19 Scott Dattalo * eXdbm/parse.c - "char" is used to store result of fgetc, but EOF doesn't fit in the default unsigned chars. * src/cod.cc - an endian issue which made symbol values come out wrong. - note these fixes came from a patch attached to an anonymous bug report 2003-08-18 Scott Dattalo * src/ioports.cc - Port A on the F62x devices was named "ioport" * src/p16f62x.cc - intcon was not declared at 0x8b (bug 566165) * regression/p16f628.asm - Added a regression test for the f68 * regression/p16f628.stc 2003-08-17 Scott Dattalo * regression/* started the regression test directory. Only two tests are performed: instruction validation for the midrange family and a simple node test. 2003-08-17 Scott Dattalo * Huge patch from Borut Razem mailto:borut.razem@siol.net that enables gpsim to be compiled with MS Visual C under Windows. 2003-06-19 Scott Dattalo * src/gpsim_time.h Multiple breaks at one Cycle were getting clobbered. * src/gpsim_time.cc * src/16bit-registers.cc Added support for TMR3 * src/pic-processor.h add pll_scale for the 18f devices. 2003-05-25 Scott Dattalo * src/breakpoints.cc program memory break points were not working. * Started formatting the Changelog properly gpsim - Gnu Pic Simulator, a simulator for Microchip's PIC microcontrollers. T. Scott Dattalo gpsim-0.21.0 * Starting with 0.21.0, Changelog will be properly formatted * Added 18f454,18455 * Added breakpoint capability on nodes * Added spi Module * Added attributes to external usart module * Ralf rewrote the Breadboard * gui is now in C++ * Added 16f627,16f628 processors * log command has been added (Command Line) * Profiling has been added (gui) * Trace viewer has been added * Added parport - parallel port loadable module * Source level debugging of C files * Added 16c55,16c62,16c63,16c72,16c73 processors * Added 18c442,18c452 processor * Added module attibutes (attribute.cc) * breadboard updates when either a tris or port is changed in the register viewer * Enhanced module interface - now LCD module works with gpsim * Patch from Rudy Moore to fix TMR0 bug * Beautified the Single Step and Trace dump outputs * Added break on stack overflow and underflow * Added break mask to wv/rv type break points. Now you can specify which bits are significant. * Added "abort_gpsim_now" command. This will unconditionally abort gpsim. * Added "--cli" command line option. Invokes gpsim in command line mode even if it has been configured to use the gui. * Program viewer can now display ASCII encode text in "dt" tables * Symbolic setting of execution breaks was not working. * C++ bugs fixed * Fixed WDT during SLEEP bug reported by Tor Fredrik Aas mailto:tfa@abn.hibu.no * USART baud rates were generated incorrectly and have been fixed. * TXIF was handled improperly (reported by Wojciech Zabolotny ) * TMR1 was incrementing even when disabled (Reported by Wojciech) * Patch from JG for Suse 7.1. * Patch from Robert Pearce to add 16C55 * Sleep now works for 12c5xx. * Config word now works for 12c5xx * GPIO can wake a sleeping 12c5xx * Added pullup/pulldown resistors to the gpsim modules (idea from SET) * Numerous patches from from (SET) Salvador mailto:salvador@inti.gov.ar * SET - added "frequency" command * SET - Added time field to the gui status bar. * Carlos Nieves Ă“nega - Massive patch for the 17cxx core * Carlos Nieves Ă“nega - Registers for 17cxx core * From Salvador Eduardo Tropea mailto:salvador@inti.gov.ar * Modified: In gpsim/main.cc put a cast in poptGetContext call, but perhaps is a fault in the version I use of popt, double check it. * Added: gtk_window_set_wmclass calls to help Enlightenment to remmember the positions of the windows. * Added: In gui/gui_main.c a couple of #undef to avoid redefinitions in eXdbm.h. Also check if that's OK for the eXdbm you are using. * Modified: Moved the INTCON register from _14bit_18pins class to child classes. That's because I needed to inherit from it and P16X6X_processor and both defines INTCON. I also think things are more clear in this way. * Fixed: A bug in the A/D routines. If you started a conversion at the same time you were enabling the A/D this conversion was aborted. To fix it I transfered new_value to value before calling start_conversion(). * Added: Partial support for 16C712 and 16C716 CPUs, they inherit from 14bits 18pins processors because they have 18 pins and also from 16x6x because they have TMR1, TMR2 and Capture/Compare facilities like in 16C63. I could check it deeply, just the A/D part. I also didn't implement the DATACCP and TRISCCP registers, I don't know how they work, but I think they control the use of some I/O pins (normal or CCP function). 28JUL00 gpsim-0.20.0 o Modules - gpsim now supports dynamically loaded modules -- module command o gui - upgraded to latest versions of gtk & gtkextra o gui - Menu items now work o gui - button bar o gui - now refreshes while simulating o gui - Stack Window has been added o BSD is now supported o numerous bug fixes 05APR00 gpsim-0.19.0 o Daniel Schudel joins gpsim development. -- Added support for the 16x5x family o Added 16f87x family o gui - Added Program Memory sheet -- Added support for program memory writes o gui - Added Breadboard window (graphical pinout) o Asynchronous mode of the usart fixed. o A/D converter enhanced o Analog Stimuli revisited. o Scripting was fixed. o cli - Once again, gpsim can be built without the gui. 03FEB00 gpsim-0.18.0 o cli - added 'processor pins' command to display the state of a pic's I/O pins o cli - added 'set' command for modifying gpsim behavior flags. set options supported: -- verbose - if set, diagnostic info will be displayed -- radix - not supported yet -- gui_update - controls the rate at which the gui is refreshed o cli - added 's' option to the dump command to display only the special function registers (and not the rest of ram). o 18cxxx: -- TBLRD & TBLWT instructions are now supported -- MULLW & MULWF instructions are now supported -- configuration word support -- tmr0 interrupt o Cycle counter - 64 bits is now fully supported o config word bug fixed o gui - added Watch window o gui - added more color coding to register window o gui - removed stagnant menu selections o gui - window state is saved between gpsim sessions -- This requires a new package `eXdbm'. o getopt is now used to process invocation options (now you can have spaces between the options and file names). o support >64k object code in .cod files o gtksheet has been removed from the distribution -- This means that you'll have to install gtk+-extra, the package that supports gtk-sheet (see INSTALL) o .cod file format bug fixes (you'll need the latest gpasm) o __config word for 18cxxx family is now supported 16NOV99 gpsim-0.17.0 o gui - Major overhaul of Register Window o gui - Symbol window added o 18Cxxx -- Interrupts are now supported -- TMR0 is implemented -- USART asynchronous mode is supported o automake is now used to create the makefiles o version numbering has changed so that 'minor releases' (which by definition are the only ones I've made) are now expressed in the middle revision instead of the last revision number. o numerous bug fixes o Cycle counter is now 64 bits. gpsim-0.0.16 o 18Cxxx core has been added o Ralf Forsberg has joined me in development. His major contributions have been in the gui code. Some of what he's done: - Wrote a new source browser with these features: -- Syntax highlighting (e.g. opcodes and comments are colored differently) -- Iconic indicators (e.g. bitmaps indicating breaks, current pc...) -- Multiple sources - Significant restructuring of the gpsim to gui interface 28JUL99 gpsim-0.0.15 o gui - asm source browser o gui - program memory browser o gui - register viewer enhancements o gui - control menu o numerous bug fixes 30JUN99 gpsim-0.0.14 o gui o numerous bug fixes 25APR99 gpsim-0.0.13 o Split the command line interface from simulator - created a `src' directory for the simulator - created a `cli' directory for the command line interface o Re-wrote the cli to use bison and flex (whew - whatabitch) o Hi-Tech C-compiler .cod files can be loaded by gpsim now. o Fixed C++ errors that egcs abhored but gcc ignored. 08MAR99 gpsim-0.0.12 o Added support for .cod files (mostly in cod.cc) o Added more symbolic debugging features o Added 'list' command for listing source files o Updated the 'load' command for loading .cod files o Repeat last command with carriage return o Added more documentation 10JAN99 gpsim-0.0.11 o Added support for the PIC16C74 o Fixed core dumps associated with the 12C50x (again, dammit) o Fundamentally changed the way registers are created. o Added a 'config' script 20DEC98 gpsim-0.0.10 o Added support for the PIC16C71 o Enhanced the asynchronous stimulus to support analog values o Added a triangle_wave stimulus (mainly for testing) o Changed the behavior of 'run' to ignore a breakpoint if there is one set at the current instruction (see below) o Added a few examples illustrating the use of analog stimuli 07DEC98 gpsim-0.0.9 o Added support for the 12c508 and 12c509 o Bug Fixes: - DC bit wasn't updated correctly in add's and sub's (if W was the destination) - stack was rolling over after 7 pushes - goto's and call's were limited to 10 bits o Added the command line option '-v' and the command version. Both echo gpsim's version. o Enhanced 'it.asm' and added 'it_12bit.asm' - two routines that exercise gpsim's ability to simulate the pic instructions. o Added a trace for skipped instructions (before you'd see skipped instructions the same as non skipped ones in the trace buffer). 16NOV98 gpsim-0.0.8 o Fixed pcl related bugs (see the new pcl_test.asm for examples) o Implemented the TMR2 peripheral o Implemented the CCP1 and CCP2 peripherals o Implemented the TMR1 peripheral o added more support for the PIC16C64 o began support for the PIC16C65 o fixed the configuration word loading that got broke in the last release 21OCT98 gpsim-0.0.7 o added new command 'processor' o added new command 'load' - Startup command files can now be loaded any time and can be nested. o added new command 'symbol' o added new command 'reset' o redesigned the pic processor base class o added new file p16x8x o added support for the PIC16CR83, PIC16CR84, PIC16F83, PIC16F84 o added new file p16x6x o added support for the PIC16C61 o began support for the PIC16C64 o Changed the command line invocation: -p now selects a processor and not a core (e.g. -p14 used to be the way gp sim liked to select a device within the midrange, 14-bit family; now you must specify the specific device you wish to simulate: -pp16c61 .) o Generally overhauled everything in anticipation of supporting the 12-bit core 30SEP98 gpsim-0.0.6 o now can asynchronously halt the execution. o Multiplexed I/O pins are now supported (better). It's possible to clock TMR0 from an external clock now o The c84 is now fully supported - though not thoroughly debugged o I fixed two nasty cycle breakpoint bugs, single-stepping during a pending interrupt, and a couple of other minor annoyances. o I've begun formal documentation, but it is not included with this release. 18SEP98 gpsim-0.0.5 o added new command 'node' o added new command 'attach' o redesigned the stimulus infrastructure. o added 'name' option to stimuli o iopins are now considered stimuli 04SEP98 gpsim-0.0.4 o added new command 'stimulus' o added new command 'echo' o redesigned the breakpoint mechanism for register breaks o added support for startup configuration files o began support for stimulus files o began support for symbols o interrupts are working 28AUG98 gpsim-0.0.3 o added support for interrupts o TMR0 and WDT are now working o added new command 'x' for examining/modifying registers o added a 'break wdt' - break on wdt timeout o now you can step over a breakpoint 17AUG98 gpsim-0.0.2 o added readline library and made the command line interface more robust o eeprom is now working 30JUL98 gpsim-0.0.1 o initial release - basic stuff $Revision: 2419 $ gpsim-0.30.0/aclocal.m40000664000076400007640000015300713117441633011515 00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Copyright (C) 1998-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_LEX # ----------- # Autoconf leaves LEX=: if lex or flex can't be found. Change that to a # "missing" invocation, for better error output. AC_DEFUN([AM_PROG_LEX], [AC_PREREQ([2.50])dnl AC_REQUIRE([AM_MISSING_HAS_RUN])dnl AC_REQUIRE([AC_PROG_LEX])dnl if test "$LEX" = :; then LEX=${am_missing_run}flex fi]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([acinclude.m4]) gpsim-0.30.0/regression/0000775000076400007640000000000013117466025012111 500000000000000gpsim-0.30.0/regression/ttl/0000775000076400007640000000000013117466027012716 500000000000000gpsim-0.30.0/regression/ttl/ttl165.asm0000664000076400007640000000770513041763600014401 00000000000000 ;; ttl165.asm ;; list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location ExitInterrupt: RETFIE 1 MAIN CODE Start: .sim "module library libgpsim_modules" .sim "module load TTL165 U1" .sim "node nd0 nd1 nd2 nd3 nd4 nd5 nd6 nd7" .sim "attach nd0 portb0 U1.D0" .sim "attach nd1 portb1 U1.D1" .sim "attach nd2 portb2 U1.D2" .sim "attach nd3 portb3 U1.D3" .sim "attach nd4 portb4 U1.D4" .sim "attach nd5 portb5 U1.D5" .sim "attach nd6 portb6 U1.D6" .sim "attach nd7 portb7 U1.D7" .sim "node nClk nE nPL nDs nQ nQb" .sim "attach nClk porte0 U1.CP" .sim "attach nE porte1 U1.CE" .sim "attach nPL porte2 U1.PL" .sim "attach nQ portc0 U1.Q7" .sim "attach nQb portc1 U1.nQ7" .sim "attach nDs portc2 U1.Ds" .sim "p18f452.xpos = 100.00" .sim "p18f452.ypos = 100.00" .sim "U1.xpos = 300.00" .sim "U1.ypos = 200.00" nop clrf TRISB clrf TRISE movlw 3 movwf TRISC clrf LATB clrf LATC clrf LATE bsf LATE,0 bsf LATE,2 ; Latch data into the 165 comf LATB,f .assert "portc == 2" bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 2" bcf LATE,0 bsf LATE,0 .assert "portc == 2" nop movlw 0xAA movwf LATB .assert "portc == 2" nop bcf LATE,2 ; Reload the shift register .assert "portc == 1" nop movlw 0xA5 movwf LATB nop bsf LATE,2 .assert "portc == 1" ; SR=0xA5 nop bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 2" ; SR=0x4A nop bsf LATC,2 ; Set the Ds pin bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 5" ; SR=0x95 nop bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 6" ; SR=0x2B nop bcf LATE,0 bsf LATE,0 ; Shift the data one bit nop .assert "portc == 6" ; SR=0x57 bcf LATE,0 bsf LATE,0 ; Shift the data one bit nop .assert "portc == 5" ; SR=0xAF bcf LATC,2 ; Clear the Ds pin bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 2" ; SR=0x5E nop bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 1" ; SR=0xBC nop bcf LATE,0 bsf LATE,0 ; Shift the data one bit .assert "portc == 2" ; SR=0x78 nop bsf LATE,1 ; Disable the clock bcf LATE,0 bsf LATE,0 ; No shift .assert "portc == 2" ; SR=0x78 nop done: .assert "\"*** PASSED TTL-165 test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED TTL-165 test\"" bra done end gpsim-0.30.0/regression/ttl/ttl595.asm0000664000076400007640000000636613041763600014412 00000000000000 ;; ttl595.asm ;; list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location ExitInterrupt: RETFIE 1 MAIN CODE Start: .sim "module library libgpsim_modules" .sim "module load ttl595 U1" .sim "node nb0 nb1 nb2 nb3 nb4 nb5 nb6 nb7" .sim "node nc0 nc1 nc2 nc3 nc4 nc5 nc6 nc7" #define Ds LATC,0 #define RCK LATC,1 #define MR LATC,2 #define SCK LATE,0 #define OE LATE,1 .sim "attach nc0 portc0 U1.Ds" .sim "attach nc1 portc1 U1.RCK" .sim "attach nc2 portc2 U1.MR" .sim "attach nb0 portb0 U1.Q0" .sim "attach nb1 portb1 U1.Q1" .sim "attach nb2 portb2 U1.Q2" .sim "attach nb3 portb3 U1.Q3" .sim "attach nb4 portb4 U1.Q4" .sim "attach nb5 portb5 U1.Q5" .sim "attach nb6 portb6 U1.Q6" .sim "attach nb7 portb7 U1.Q7" .sim "node nClk nE" .sim "attach nClk porte0 U1.SCK" .sim "attach nE porte1 U1.OE" .sim "p18f452.xpos = 84" .sim "p18f452.ypos = 48" .sim "U1.xpos = 288" .sim "U1.ypos = 48" nop movlw 0x06 ; all pins digital movwf ADCON1 CLRF TRISC CLRF TRISE SETF TRISB bcf INTCON2,7 ; set weak pullups on portB CLRF LATB CLRF LATE bsf MR bsf Ds ; Ds = 1 bsf SCK ; clock shift register .assert "portb == 0, \"***FAILED 18f452 ttl595 output without clock\"" nop bsf RCK ; clock shift register to output latch bcf SCK .assert "portb == 1, \"***FAILED 18f452 ttl595 output with 1 shift\"" nop bsf SCK ; second SR clock; bcf RCK bsf RCK ; second load output latch .assert "portb == 3, \"***FAILED 18f452 ttl595 output with 2 shift\"" nop bsf OE ;OE high to disable output .assert "portb == 0xff, \"***FAILED 18f452 ttl595 output with OE high\"" nop bcf OE ;OE low to enable output .assert "portb == 3, \"***FAILED 18f452 ttl595 output after OE high\"" nop ; clear shift register bcf MR .assert "portb == 3, \"***FAILED 18f452 ttl595 output after MR low\"" nop bcf RCK ; load output from shift register bsf RCK nop .assert "portb == 0, \"***FAILED 18f452 ttl595 output after MR low and load\"" nop done: .assert "\"*** PASSED TTL-595 test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED TTL-595 test\"" bra done end gpsim-0.30.0/regression/ttl/ttl377.asm0000664000076400007640000000506213041763600014400 00000000000000 ;; ttl377.asm ;; list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location ExitInterrupt: RETFIE 1 MAIN CODE Start: .sim "module library libgpsim_modules" .sim "module load ttl377 U1" .sim "node nb0 nb1 nb2 nb3 nb4 nb5 nb6 nb7" .sim "node nc0 nc1 nc2 nc3 nc4 nc5 nc6 nc7" .sim "attach nb0 portb0 U1.D0" .sim "attach nb1 portb1 U1.D1" .sim "attach nb2 portb2 U1.D2" .sim "attach nb3 portb3 U1.D3" .sim "attach nb4 portb4 U1.D4" .sim "attach nb5 portb5 U1.D5" .sim "attach nb6 portb6 U1.D6" .sim "attach nb7 portb7 U1.D7" .sim "attach nc0 portc0 U1.Q0" .sim "attach nc1 portc1 U1.Q1" .sim "attach nc2 portc2 U1.Q2" .sim "attach nc3 portc3 U1.Q3" .sim "attach nc4 portc4 U1.Q4" .sim "attach nc5 portc5 U1.Q5" .sim "attach nc6 portc6 U1.Q6" .sim "attach nc7 portc7 U1.Q7" .sim "node nClk nE" .sim "attach nClk porte0 U1.CP" .sim "attach nE porte1 U1.E" .sim "p18f452.xpos = 24.00000000000000" .sim "p18f452.ypos = 24.00000000000000" .sim "U1.xpos = 156.0000000000000" .sim "U1.ypos = 24.00000000000000" nop CLRF TRISB CLRF TRISE SETF TRISC CLRF LATB CLRF LATE BSF LATE,0 ;Clock data into the 377 COMF LATB BCF LATE,0 BSF LATE,0 .assert "latb == portc" COMF LATB BCF LATE,0 BSF LATE,0 .assert "latb == portc" nop done: .assert "\"*** PASSED TTL-377 test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED TTL-377 test\"" bra done end gpsim-0.30.0/regression/ttl/Makefile0000664000076400007640000000023113041763600014263 00000000000000 include ../make.regression all : ttl377.cod ttl165.cod ttl595.cod ttl%.cod : ttl%.o gplink --map -o $@ $< sim : sim_ttl377 sim_ttl165 sim_ttl595 gpsim-0.30.0/regression/ttl/ttl377.stc0000664000076400007640000000003113041763600014400 00000000000000 load ttl377.cod p18f452 gpsim-0.30.0/regression/p18f452_ports/0000775000076400007640000000000013117466027014353 500000000000000gpsim-0.30.0/regression/p18f452_ports/18f452.lkr0000664000076400007640000000222013041763600015623 00000000000000// $Id: 18f452.lkr 1903 2007-02-12 05:03:40Z sdattalo $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . //CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED //CODEPAGE NAME=page START=0x2A END=0x7FFF CODEPAGE NAME=page START=0x00 END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/regression/p18f452_ports/Makefile0000664000076400007640000000051313041763600015723 00000000000000include ../make.regression SCRIPT = 18f452.lkr PROJECT = p18f452_ports OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/p18f452_ports/p18f452_ports.asm0000664000076400007640000000377413041763600017241 00000000000000 ;; 18F452 tests ;; ;; This regression test exercises the 18f452's I/O ports. ;; ;; Tests performed: ;; ;; list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA failures RES 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE CLRF failures ;Assume success ; Set ADC ports to digital I/O MOVLW (1< include __CONFIG _WDT_ON & _MCLRE_ON radix dec ; Printf Command .command macro x .direct "C", x endm GPR_DATA UDATA ResetSequence RES 1 optionShadow RES 1 GLOBAL optionShadow, ResetSequence ; Define the reset conditions to be checked. eRSTSequence_PowerOnReset equ 1 eRSTSequence_AwakeMCLR equ 2 eRSTSequence_AwakeWDT equ 3 eRSTSequence_AwakeIO equ 4 eRSTSequence_WDTTimeOut equ 5 ;---------------------------------------------------------------------- ; ********************* STARTUP LOCATION *************************** ;---------------------------------------------------------------------- START CODE 0x000 ; ;############################################################ ;# Create a stimulus to simulate a switch ; .sim "module lib libgpsim_modules" .sim "module load pulsegen PG1" .sim "module load pulsegen MCLR" .sim "MCLR.initial = 5.0" .sim "PG1.clear = 0" ; At cycle 0, .sim "PG1.set = 1" ; .sim "PG1.clear = 0x200" ; .sim "PG1.period = 0x400" ;############################################################ .sim "node nSwitch" .sim "attach nSwitch gpio0 PG1.pin" .sim "node nMCLR" .sim "attach nMCLR gpio3 MCLR.pin" ;############################################################ .sim "symbol resetCounter=1" ; NOT_GPWU = 0 - Enable wakeup if I/O pins 0,1, or 3 change states ; NOT_GPPU = 1 - Disable weak pullups on I/O pins 0,1, and 3 ; TOCS = 0 - Let the clock source for TMR0 be the internal fosc/4 ; TOSE = 0 - don't care - TMR0 source edge. ; PSA = 1 - assign Prescale to the WDT ; PS2:0 = 000 - prescale = 2^0=1 .sim "optionShadow=8" ; PSA=1 .sim "ResetSequence=0" .sim ".BreakOnReset = false" ; Set a cycle break point far in the future in case the resets fail. .sim "break c 0x1000000" ;break e START ;break e Activate ;break e AbortActivate ;break e SendIsComplete ;break e SwitchWasJustPressed bSWITCH equ 0 .assert "option==0xff" .assert "(tris&0x3f)==0x3f" MOVWF OSCCAL ; put calibration into oscillator cal reg ; OPTION register setup MOVF optionShadow,W ;optionShadow is initialized by the gpsim script OPTION ; GPIO setup ; If this is a PowerOn reset, then the state of the GPIO output register ; is unknown. If this is not a PowerOn reset then the GPIO pins have ; the same state they had prior to the reset. ; ; TRIS register setup - The I/O pins are always configured as Inputs after ; any reset. MOVLW 1< /MCLR while sleeping goto PowerOnReset ;/TO=1, /PD=1 ==> Power has just been applied TO_is_low BTFSS STATUS,NOT_PD goto AwakeWDT ;/TO=0, /PD=0 ==> WDT while sleeping goto WDTTimeOut ;/TO=0, /PD=1 ==> WDT while not sleeping ;======================================================================== ; ; PowerOnReset ; ;======================================================================== PowerOnReset: movf ResetSequence,W XORLW eRSTSequence_AwakeMCLR skpnz goto done .assert "resetCounter==1,\"*** FAILED Power On Reset\"" MOVLW eRSTSequence_PowerOnReset MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT SLEEP ;======================================================================== ; ; AwakeWDT - WDT timed out while we were sleeping. ; ;======================================================================== AwakeWDT: MOVLW eRSTSequence_AwakeWDT .assert "resetCounter==2,\"*** FAILED WDT Reset\"" MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT ; loop until WDT times out here: goto here ;======================================================================== ; ; WDTTimeOut - WatchDog timer timed out while we were awake. ; ;======================================================================== WDTTimeOut: .assert "resetCounter==3,\"*** FAILED WDT timeout\"" MOVLW eRSTSequence_WDTTimeOut MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT .command "PG1.clear = cycles+100" nop SLEEP ;======================================================================== ; ; AwakeIO - an I/O pin changed states to awaken us from sleep. ; ;======================================================================== AwakeIO: MOVLW eRSTSequence_AwakeIO .assert "resetCounter==4,\"*** FAILED Wakeup on I/O pin change\"" MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT ; reset the processor by driving /MCLR low for a few cycles .command "MCLR.clear = cycles+100" .command "MCLR.set = cycles+110" nop SLEEP ;======================================================================== ; ; AwakeMCLR - MCLR went low while we were sleeping. ; ;======================================================================== AwakeMCLR: MOVLW eRSTSequence_AwakeMCLR .assert "resetCounter==5,\"*** FAILED /MCLR Reset\"" MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT ; reset the processor by driving /MCLR low for a few cycles .command "MCLR.clear = cycles+100" .command "MCLR.set = cycles+110" nop waitForMCLR: goto waitForMCLR .assert "\"*** PASSED 12c509 Sleep and Reset test\"" done: goto done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x3ff ; processor reset vector OSC_CAL_VALUE EQU 0x80 MOVLW OSC_CAL_VALUE end gpsim-0.30.0/regression/p12c509/12c509.lkr0000664000076400007640000000117313041763600014366 00000000000000// Sample linker command file for 12C509 // $Id: 12c509.lkr,v 1.8 2005/03/24 04:17:15 craigfranklin Exp $ LIBPATH . CODEPAGE NAME=page START=0x0 END=0x3FF CODEPAGE NAME=.idlocs START=0x400 END=0x403 PROTECTED CODEPAGE NAME=.config START=0xFFF END=0xFFF PROTECTED DATABANK NAME=sfrs START=0x0 END=0x06 PROTECTED DATABANK NAME=gpr0 START=0x07 END=0x1F DATABANK NAME=gpr1 START=0x30 END=0x3F SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/p12c509/Makefile0000664000076400007640000000034413041763600014470 00000000000000include ../make.regression STARTUP_STC=../startup.stc all : reset.cod reset.cod: reset.o gplink --map -s 12c509.lkr -o $@ $< sim: sim_p12c509_reset sim_p12c509_reset: reset.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/p12c509/it_12bit.asm0000664000076400007640000001524113041763600015151 00000000000000 list p=12c508 ;; it.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; a pic. Nothing useful is performed - this program is only used to ;; debug gpsim. ;; The way it is structured, a test is performed and then various ;; status bits are examined. If things 'are as expected' then the ;; next test will be performed, otherwise the program will go into ;; an infinite loop (goto $). ;; If the 'success:' label is reached, then all of the tests were ;; successful. include "p12x.inc" __config _wdt_on cblock 0x0c temp,temp1,temp2 endc org 0 ;; Assume that 'goto' works and begin the thorough instruction ;; tests below (the pcl related tests must be in bank 0 because ;; the 5x hardware cannot make calls to bank 1 [bit 8 of the PC ;; always gets cleared]). goto start ;; ;; Test indirect branching ;; test_pcl: clrf temp clrf temp1 tt1: movf temp,w call table_test xorwf temp,w skpz bsf temp1,0 incf temp,f btfss temp,4 goto tt1 goto test_pcl2 table_test: addwf pcl,f table: retlw 0 retlw 1 retlw 2 retlw 3 retlw 4 retlw 5 retlw 6 retlw 7 retlw 8 retlw 9 retlw 10 retlw 11 retlw 12 retlw 13 retlw 14 retlw 15 test_pcl2: ;; If this is the first time through, then clear the registers btfsc temp2,0 goto test_pcl3 movlw 0x10 movwf fsr next clrf indf incf fsr,f btfss fsr,5 goto next ;; ;; Set this flag to indicate we've gotten here once already ;; (note: we're assuming that temp2 was cleared at the beginning ;; of the simulation. By default, gpsim clears ram at ;; initialization. If this is not true, then you might have ;; to manually clear temp2. bsf temp2,0 clrf pcl test_pcl3: movlw ly movwf pcl ; == goto ly lx goto test_pcl4 ly movlw lx movwf pcl test_pcl4: movlw 0 tris gpio NOP NOP NOP NOP ;; ;; If we get here, then all of the tests were passed ;; success: goto $ NOP NOP NOP NOP start: ;; ;; if bit 0 of temp2 is set, then we've already passed ;; through here once. The reason we got here a second ;; time is because of the 'clrf pcl' test (which is basically ;; a 'goto 0' instruction). btfsc temp2,0 goto test_pcl clrf temp1 ;Assume clrf works... ; ;; ;; map tmr0 to the internal clock ;; clrw option ;initialize tmr0 start1: ;; Perform some basic tests on some important instructions setc ;set the Carry flag skpc ;and verify that it happened goto $ clrc ;Now try clearing the carry skpnc goto $ setz ;set the Zero flag skpz ;and verify that it happened goto $ clrz ;Now try clearing it skpnz goto $ setdc ;set the Digit Carry flag skpdc ;and verify that it happened goto $ clrdc ;Now try clearing it skpndc goto $ movlw 1 movwf temp movf temp,f skpnz goto $ movlw 0 movwf temp movf temp,f skpz goto $ clrf temp ;Clear a register skpz ;and verify that the Z bit in the goto $ ;status register was set. movf temp,w ;Read the register that was just skpz ;cleared, and again verify that Z goto $ ;was set incf temp,w ;Now this should cause the Z bit to skpnz ;get cleared. goto $ movlw 0xff movwf temp incf temp skpz goto $ ;; ;; incfsz ;; movlw 0xff movwf temp movf temp,f ;Should clear Z incfsz temp,w goto $ skpnz ;incfsz shouldn't affect Z goto $ incfsz temp,f ;temp should now be zero goto $ incfsz temp,w ;the following inst. shouldn't be skipped skpnz ;Z should be clear from above. goto $ ;; addlw 0xaa ;; ;; addwf test: ;; ;; The purpose of this test is to a) verify that the addwf instruction ;; adds correctly and b) that the appropriate status register bits are ;; set correctly. clrw clrf temp addwf temp,w ; 0+0 skpnc goto $ skpz goto $ skpndc goto $ movlw 1 ; 0+1 addwf temp,w skpnc goto $ skpnz goto $ skpndc goto $ movlw 8 ; 8+8 movwf temp addwf temp,w skpnc goto $ skpnz goto $ skpdc goto $ movlw 0x88 ; 0x88+0x88 movwf temp addwf temp,w skpc goto $ skpnz goto $ skpdc goto $ movlw 0x80 ; 0x80+0x80 movwf temp addwf temp,w skpc goto $ skpz goto $ skpndc goto $ movlw 1 movwf temp movlw 0xff addwf temp,w skpc goto $ skpz goto $ skpdc goto $ clrc clrdc ;; ;; andwf test: ;; clrf temp movlw 1 andwf temp,f skpz goto $ skpc skpndc goto $ andwf temp,w skpz goto $ skpc skpndc goto $ movlw 1 movwf temp andwf temp,f skpnz goto $ skpc skpndc goto $ movlw 0xff andwf temp,f ;1 & 0xff should = 1 skpnz goto $ skpc skpndc goto $ movlw 0xff ;Now add 0xff to see if temp addwf temp,f ;really is 1. (should cause a carry) skpnz skpc goto $ ;; ;; iorwf ;; movlw 0 movwf temp iorwf temp,f skpz goto $ movlw 1 iorwf temp,f skpnz goto $ movlw 0xff addwf temp,f skpnz skpc goto $ ;; ;; rlf ;; clrdc clrf temp clrc rlf temp,w skpdc skpnc goto $ skpz goto $ setc rlf temp,f skpdc skpnc goto $ skpz goto $ movlw 0xff addwf temp,f skpnz skpc goto $ rlf temp,f skpnc goto $ movlw 0x80 movwf temp rlf temp,w skpc goto $ movwf temp addwf temp,w skpz goto $ ;; ;; rrf ;; clrdc clrf temp clrc rrf temp,w skpdc skpnc goto $ skpz goto $ setc rrf temp,f skpdc skpnc goto $ skpz goto $ movlw 0x80 addwf temp,f skpnz skpc goto $ rrf temp,f skpnc goto $ movlw 1 movwf temp rrf temp,w skpc goto $ movwf temp addwf temp,w skpz goto $ ;; ;; subwf test: ;; clrw clrf temp subwf temp,w ; 0-0 skpc goto $ skpz goto $ skpdc goto $ movlw 1 ; 0-1 subwf temp,w skpnc goto $ skpnz goto $ skpndc goto $ movlw 0x10 ; 0x10-0x10 movwf temp subwf temp,w skpc goto $ skpz goto $ skpdc goto $ movlw 0x88 ; 0x88-0x88 movwf temp subwf temp,w skpc goto $ skpz goto $ skpdc goto $ clrf temp movlw 0x80 ; 0 - 0x80 subwf temp,f skpnc goto $ skpnz goto $ skpdc goto $ movlw 0 ; 0x80 - 0 subwf temp,w skpc goto $ skpnz goto $ skpdc goto $ movlw 1 ; 0x80 - 1 subwf temp,w skpc goto $ skpnz goto $ skpndc goto $ clrc clrdc ;; ;; xorwf ;; clrf temp movlw 0xff xorwf temp,f skpc skpndc goto $ skpnz goto $ xorwf temp,f skpz goto $ xorwf temp,f incfsz temp,f goto $ ;; ;; swapf ;; movlw 0x0f movwf temp swapf temp,f xorwf temp,f incfsz temp,f goto $ decf temp1,f incfsz temp1,w goto done ;; repeat the test with in the next bank of registers bsf fsr,5 goto start1 done: bcf fsr,5 NOP NOP NOP NOP NOP NOP goto test_pcl endgpsim-0.30.0/regression/instructions_12bit/0000775000076400007640000000000013117466027015660 500000000000000gpsim-0.30.0/regression/instructions_12bit/instructions_12bit.asm0000664000076400007640000003030313041763600022037 00000000000000 ;; it.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; a pic. Nothing useful is performed - this program is only used to ;; debug gpsim. ;; The way it is structured, a test is performed and then various ;; status bits are examined. If things 'are as expected' then the ;; next test will be performed, otherwise the program will go into ;; an infinite loop (goto $). ;; If the 'success:' label is reached, then all of the tests were ;; successful. list p=12c508 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __config _WDT_ON & _MCLRE_OFF ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE ;; Assume that 'goto' works and begin the thorough instruction ;; tests below (the pcl related tests must be in bank 0 because ;; the 5x hardware cannot make calls to bank 1 [bit 8 of the PC ;; always gets cleared]). goto start ;; ;; Test indirect branching ;; test_pcl: clrf temp clrf temp1 tt1: movf temp,w call table_test xorwf temp,w skpz bsf temp1,0 incf temp,f btfss temp,4 goto tt1 goto test_pcl2 table_test: addwf PCL,F table: retlw 0 retlw 1 retlw 2 retlw 3 retlw 4 retlw 5 retlw 6 retlw 7 retlw 8 retlw 9 retlw 10 retlw 11 retlw 12 retlw 13 retlw 14 retlw 15 test_pcl2: ;; If this is the first time through, then clear the registers btfsc temp2,0 goto test_pcl3 movlw 0x10 movwf FSR next clrf INDF incf FSR,f btfss FSR,5 goto next ;; ;; Set this flag to indicate we've gotten here once already ;; (note: we're assuming that temp2 was cleared at the beginning ;; of the simulation. By default, gpsim clears ram at ;; initialization. If this is not true, then you might have ;; to manually clear temp2. bsf temp2,0 clrf PCL test_pcl3: movlw ly movwf PCL ; == goto ly lx goto test_pcl4 ly movlw lx movwf PCL test_pcl4: movlw 0 tris GPIO NOP NOP NOP NOP ;; ;; If we get here, then all of the tests were passed ;; success: done: .assert "\"*** PASSED 12bit core instruction test\"" goto $ NOP NOP NOP NOP failed: movlw 1 movwf failures .assert "\"*** FAILED: 12bit core instruction test\"" goto done start: ;; ;; if bit 0 of temp2 is set, then we've already passed ;; through here once. The reason we got here a second ;; time is because of the 'clrf pcl' test (which is basically ;; a 'goto 0' instruction). btfsc temp2,0 goto test_pcl clrf temp1 ;Assume clrf works... clrf failures ; ;; ;; map tmr0 to the internal clock ;; clrw option ;initialize tmr0 start1: ;; Perform some basic tests on some important instructions setc ;set the Carry flag skpc ;and verify that it happened goto failed clrc ;Now try clearing the carry skpnc goto failed setz ;set the Zero flag skpz ;and verify that it happened goto failed clrz ;Now try clearing it skpnz goto failed setdc ;set the Digit Carry flag skpdc ;and verify that it happened goto failed clrdc ;Now try clearing it skpndc goto failed movlw 1 movwf temp movf temp,f skpnz goto failed movlw 0 movwf temp movf temp,f skpz goto failed clrf temp ;Clear a register skpz ;and verify that the Z bit in the goto failed ;status register was set. movf temp,w ;Read the register that was just skpz ;cleared, and again verify that Z goto failed ;was set incf temp,w ;Now this should cause the Z bit to skpnz ;get cleared. goto failed movlw 0xff movwf temp incf temp,f skpz goto failed ;; ;; incfsz ;; movlw 0xff movwf temp movf temp,f ;Should clear Z incfsz temp,w goto failed skpnz ;incfsz shouldn't affect Z goto failed incfsz temp,f ;temp should now be zero goto failed incfsz temp,w ;the following inst. shouldn't be skipped skpnz ;Z should be clear from above. goto failed ;; addlw 0xaa ;; ;; addwf test: ;; ;; The purpose of this test is to a) verify that the addwf instruction ;; adds correctly and b) that the appropriate status register bits are ;; set correctly. clrw clrf temp addwf temp,w ; 0+0 skpnc goto failed skpz goto failed skpndc goto failed movlw 1 ; 0+1 addwf temp,w skpnc goto failed skpnz goto failed skpndc goto failed movlw 8 ; 8+8 movwf temp addwf temp,w skpnc goto failed skpnz goto failed skpdc goto failed movlw 0x88 ; 0x88+0x88 movwf temp addwf temp,w skpc goto failed skpnz goto failed skpdc goto failed movlw 0x80 ; 0x80+0x80 movwf temp addwf temp,w skpc goto failed skpz goto failed skpndc goto failed movlw 1 movwf temp movlw 0xff addwf temp,w skpc goto failed skpz goto failed skpdc goto failed clrc clrdc ;; ;; andwf test: ;; clrf temp movlw 1 andwf temp,f skpz goto failed skpc skpndc goto failed andwf temp,w skpz goto failed skpc skpndc goto failed movlw 1 movwf temp andwf temp,f skpnz goto failed skpc skpndc goto failed movlw 0xff andwf temp,f ;1 & 0xff should = 1 skpnz goto failed skpc skpndc goto failed movlw 0xff ;Now add 0xff to see if temp addwf temp,f ;really is 1. (should cause a carry) skpnz skpc goto failed ;; ;; iorwf ;; movlw 0 movwf temp iorwf temp,f skpz goto failed movlw 1 iorwf temp,f skpnz goto failed movlw 0xff addwf temp,f skpnz skpc goto failed ;; ;; rlf ;; clrdc clrf temp clrc rlf temp,w skpdc skpnc goto failed skpz goto failed setc rlf temp,f skpdc skpnc goto failed skpz goto failed movlw 0xff addwf temp,f skpnz skpc goto failed rlf temp,f skpnc goto failed movlw 0x80 movwf temp rlf temp,w skpc goto failed movwf temp addwf temp,w skpz goto failed ;; ;; rrf ;; clrdc clrf temp clrc rrf temp,w skpdc skpnc goto failed skpz goto failed setc rrf temp,f skpdc skpnc goto failed skpz goto failed movlw 0x80 addwf temp,f skpnz skpc goto failed rrf temp,f skpnc goto failed movlw 1 movwf temp rrf temp,w skpc goto failed movwf temp addwf temp,w skpz goto failed ;; ;; subwf test: ;; clrw clrf temp subwf temp,w ; 0-0 skpc goto failed skpz goto failed skpdc goto failed movlw 1 ; 0-1 subwf temp,w skpnc goto failed skpnz goto failed skpndc goto failed movlw 0x10 ; 0x10-0x10 movwf temp subwf temp,w skpc goto failed skpz goto failed skpdc goto failed movlw 0x88 ; 0x88-0x88 movwf temp subwf temp,w skpc goto failed skpz goto failed skpdc goto failed clrf temp movlw 0x80 ; 0 - 0x80 subwf temp,f skpnc goto failed skpnz goto failed skpdc goto failed movlw 0 ; 0x80 - 0 subwf temp,w skpc goto failed skpnz goto failed skpdc goto failed movlw 1 ; 0x80 - 1 subwf temp,w skpc goto failed skpnz goto failed skpndc goto failed clrc clrdc ;; ;; xorwf ;; clrf temp movlw 0xff xorwf temp,f skpc skpndc goto failed skpnz goto failed xorwf temp,f skpz goto failed xorwf temp,f incfsz temp,f goto failed ;; ;; swapf ;; movlw 0x0f movwf temp swapf temp,f xorwf temp,f incfsz temp,f goto failed decf temp1,f incfsz temp1,w goto d1 ;; repeat the test with in the next bank of registers bsf FSR,5 goto start1 d1: bcf FSR,5 NOP NOP NOP NOP NOP NOP goto test_pcl end gpsim-0.30.0/regression/instructions_12bit/instructions_12bit.stc0000664000076400007640000000011113041763600022042 00000000000000# simple script to load the simulation load s instructions_12bit.cod gpsim-0.30.0/regression/instructions_12bit/Makefile0000664000076400007640000000052013041763600017226 00000000000000include ../make.regression SCRIPT = 12c508.lkr PROJECT = instructions_12bit OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/instructions_12bit/12c508.lkr0000664000076400007640000000110413041763600017121 00000000000000// Sample linker command file for 12C508 // $Id: 12c508.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=page START=0x0 END=0x1FF CODEPAGE NAME=.idlocs START=0x200 END=0x203 PROTECTED CODEPAGE NAME=.config START=0xFFF END=0xFFF PROTECTED DATABANK NAME=sfrs START=0x0 END=0x06 PROTECTED DATABANK NAME=gprs START=0x07 END=0x1F SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/tmr3_16bit/0000775000076400007640000000000013117466027014005 500000000000000gpsim-0.30.0/regression/tmr3_16bit/18f4550_g.lkr0000664000076400007640000000403313041763577015667 00000000000000// File: 18f4550_g.lkr // Generic linker script for the PIC18F4550 processor #DEFINE _CODEEND _DEBUGCODESTART - 1 #DEFINE _CEND _CODEEND + _DEBUGCODELEN #DEFINE _DATAEND _DEBUGDATASTART - 1 #DEFINE _DEND _DATAEND + _DEBUGDATALEN LIBPATH . #IFDEF _CRUNTIME #IFDEF _EXTENDEDMODE FILES c018i_e.o FILES clib_e.lib FILES p18f4550_e.lib #ELSE FILES c018i.o FILES clib.lib FILES p18f4550.lib #FI #FI #IFDEF _DEBUGCODESTART CODEPAGE NAME=page START=0x0 END=_CODEEND CODEPAGE NAME=debug START=_DEBUGCODESTART END=_CEND PROTECTED #ELSE CODEPAGE NAME=page START=0x0 END=0x7FFF #FI CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED #IFDEF _EXTENDEDMODE DATABANK NAME=gpre START=0x0 END=0x5F #ELSE ACCESSBANK NAME=accessram START=0x0 END=0x5F #FI DATABANK NAME=gpr0 START=0x60 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF #IFDEF _DEBUGDATASTART DATABANK NAME=gpr3 START=0x300 END=_DATAEND DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED #ELSE //no debug DATABANK NAME=gpr3 START=0x300 END=0x3FF #FI DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF DATABANK NAME=gpr6 START=0x600 END=0x6FF DATABANK NAME=gpr7 START=0x700 END=0x7FF ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED #IFDEF _CRUNTIME SECTION NAME=CONFIG ROM=config #IFDEF _DEBUGDATASTART STACK SIZE=0x100 RAM=gpr2 #ELSE STACK SIZE=0x100 RAM=gpr3 #FI #FI gpsim-0.30.0/regression/tmr3_16bit/18f452.lkr0000664000076400007640000000212113041763577015272 00000000000000// $Id: 18f452.lkr 1436 2006-01-21 23:28:33Z sdattalo $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/regression/tmr3_16bit/tmr3_18f4550.asm0000664000076400007640000001552713041763577016330 00000000000000 ;; tmr3_18f4550.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; TMR1 for a 18f4550 pic (like the 18fxxx family) although ;; most of the functionality is generic to all processors where ;; t1mer1 supports an external clock source. ;; ;; Here are the tests performed: ;; ;; -- TMR3 count seconds when driven by simulated external crystal ;; -- TMR3 driven Fosc/4 with prescale of 8 ;; -- TMR3 count seconds when driven by external stimuli ;; -- TMR3L and TMR3H can be read and written list p=18f4550 ; list directive to define processor include include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA w_temp RES 1 status_temp RES 1 bsr_temp RES 1 failures RES 1 TMR0_RollOver RES 1 TMR3_RollOver RES 1 countLo RES 1 countHi RES 1 TMR3H_Sampled RES 1 TMR3H_Last RES 1 SecondsLo RES 1 SecondsHi RES 1 GLOBAL countLo, countHi GLOBAL SecondsLo, SecondsHi ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ HI_PRI CODE 0x008 ; interrupt vector location bra hi_pri_isr LO_PRI CODE 0x018 ; interrupt vector location nop hi_pri_isr: movwf w_temp movff STATUS,status_temp movff BSR,bsr_temp check_TMR0_interrupt: ;;================== ;; TMR3 Interrupt ;;================== BTFSC INTCON,T0IF ;If the roll over flag is not set BTFSS INTCON,T0IE ;or the interrupt is not enabled bra checkTMR0IntEnd ; ;; TMR0 has rolled over. Clear the pending interrupt and notify ;; the foreground code by incrementing the "roll over" counter ;; Notice that the increment operation is atomic - this means ;; we won't have to worry about the foreground code and interrupt ;; code clashing over accesses to this variable. BCF INTCON,T0IF,0 ; Clear the pending interrupt INCF TMR0_RollOver,F ; Set a flag to indicate rollover checkTMR0IntEnd: ;;================== ;; TMR3 Interrupt ;;================== BTFSC PIR2,TMR3IF BTFSS PIE2,TMR3IE BRA checkTMR3IntEnd BCF PIR2,TMR3IF ;Clear the interrupt INCF TMR3_RollOver,F ;Set a flag BSF TMR3H, 7 ; Preload for 1 sec overflow ; Note, since we have a 32768 Hz crystal tied to TMR3 and we have the timer ; configured as a 16-bit timer TMR3H loaded with 0x80, then this interrupt ; will happen once every second. INFSNZ SecondsLo,F ;Update the system time. INCF SecondsHi,F CLRF TMR3H_Sampled CLRF TMR3H_Last checkTMR3IntEnd: ExitInterrupt: MOVFF bsr_temp, BSR ; Restore BSR MOVF w_temp, W ; Restore WREG MOVFF status_temp, STATUS ; Restore STATUS RETFIE 1 MAIN CODE Start: ;------------------------------------------------------------------------ ; ; Embedded simulation scripts ; ; Set the clock frequency to 10MHz .sim "frequency 10e6" ; define a stimulus to generate a 32kHz clock. This will be tied ; to TMR3's input and is used to simulate an external drive. ; ; 40MHz ; Instruction Rate = (4 clks/instruction) / (10e6 clks/second) ; = 400nS per instruction ; 32.768kHz ==> 30.517uS period ; Instruction Cycles/32.768kHz cycle = 30.517uS / .4uS ; = 76.2925 instructions ; .sim "stimulus asynchronous_stimulus " .sim "initial_state 0" .sim "start_cycle 0x2008130" ; .sim "start_cycle 0x0008130" .sim "period 305" .sim "{ 38,1 , 76,0 , 114,1 , 152,0 , 190,1 , 228,0 , 266,1}" .sim "name Clk32kHz" .sim "end" ; Create a node .sim "node clk_node" ; attach the clock .sim "attach clk_node Clk32kHz portc0" ; At reset, all bits of t1Con should be clear. .assert "t1con == 0x00" nop .assert "t3con == 0x00" nop MOVLW (1< ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 TMR0_RollOver RES 1 TMR3_RollOver RES 1 countLo RES 1 countHi RES 1 TMR3H_Sampled RES 1 TMR3H_Last RES 1 SecondsLo RES 1 SecondsHi RES 1 GLOBAL countLo, countHi GLOBAL SecondsLo, SecondsHi ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: ;;================== ;; TMR3 Interrupt ;;================== BTFSC INTCON,T0IF ;If the roll over flag is not set BTFSS INTCON,T0IE ;or the interrupt is not enabled bra checkTMR0IntEnd ; ;; TMR0 has rolled over. Clear the pending interrupt and notify ;; the foreground code by incrementing the "roll over" counter ;; Notice that the increment operation is atomic - this means ;; we won't have to worry about the foreground code and interrupt ;; code clashing over accesses to this variable. BCF INTCON,T0IF,0 ; Clear the pending interrupt INCF TMR0_RollOver,F ; Set a flag to indicate rollover checkTMR0IntEnd: ;;================== ;; TMR3 Interrupt ;;================== BTFSC PIR2,TMR3IF BTFSS PIE2,TMR3IE BRA checkTMR3IntEnd BCF PIR2,TMR3IF ;Clear the interrupt INCF TMR3_RollOver,F ;Set a flag BSF TMR3H, 7 ; Preload for 1 sec overflow ; Note, since we have a 32768 Hz crystal tied to TMR3 and we have the timer ; configured as a 16-bit timer TMR3H loaded with 0x80, then this interrupt ; will happen once every second. INFSNZ SecondsLo,F ;Update the system time. INCF SecondsHi,F CLRF TMR3H_Sampled CLRF TMR3H_Last checkTMR3IntEnd: ExitInterrupt: RETFIE 1 MAIN CODE Start: ;------------------------------------------------------------------------ ; ; Embedded simulation scripts ; ; Set the clock frequency to 10MHz .sim "frequency 10e6" ; define a stimulus to generate a 32kHz clock. This will be tied ; to TMR3's input and is used to simulate an external drive. ; ; 40MHz ; Instruction Rate = (4 clks/instruction) / (10e6 clks/second) ; = 400nS per instruction ; 32.768kHz ==> 30.517uS period ; Instruction Cycles/32.768kHz cycle = 30.517uS / .4uS ; = 76.2925 instructions ; .sim "stimulus asynchronous_stimulus " .sim "initial_state 0" .sim "start_cycle 0x2008130" .sim "period 305" .sim "{ 38,1 , 76,0 , 114,1 , 152,0 , 190,1 , 228,0 , 266,1}" .sim "name Clk32kHz" .sim "end" ; Create a node .sim "node clk_node" ; attach the clock .sim "attach clk_node Clk32kHz portc0" ; At reset, all bits of t1Con should be clear. .assert "t1con == 0x00" MOVLW (1< ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CP_OFF & _IntRC_OSC & _MCLRE_OFF & _WDT_ON ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA 0x07 ee_state RES 1 eebyte RES 1 ee_bitcnt RES 1 eeaddr RES 1 eedata RES 1 failures RES 1 temp RES 1 GPR2_DATA UDATA 0x30 eeShadow RES 0x10 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE goto start include "EEdriver.asm" start: movlw 0xC0 ; Set up GPIO pins movwf GPIO movlw 0x0F tris GPIO movlw 1<<7 ; Assume that we're going to fail movwf failures ; by setting the MSB of failures FillEEPROM: movlw 0 movwf temp movlw eeShadow movwf FSR FillLoop: clrwdt ; Set the address movf FSR,W andlw 0x0f movwf eeaddr ; Set the data swapf temp,W iorwf temp,W movwf eedata movwf INDF call write_byte .assert "W == 0x01, \"*** FAILED Write_byte returned error\"" nop FillWaitForWrite: call read_current btfss ee_state,ee_ok goto FillWaitForWrite .assert "W == 0x01, \"*** FAILED read_current error\"" nop movf INDF,W xorwf eedata,W skpnz goto loop_ok .assert "\"*** FAILED data mis-match\"" incf failures,f ; failed loop_ok: incf FSR,F incf temp,F btfss temp,4 goto FillLoop ; If we reach this point then it means that we didn't ; get stuck in the loop. bcf failures,7 movf failures,W skpz goto failed done: .assert "\"*** PASSED 12CE518 internal EEPROM test\"" goto done failed: .assert "\"*** FAILED 12CE518 internal EEPROM test\"" goto $ end gpsim-0.30.0/regression/p12ce518/Makefile0000664000076400007640000000050713041763602014640 00000000000000include ../make.regression SCRIPT = 12ce519.lkr PROJECT = p12ce518 OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/p12ce518/EEdriver.asm0000664000076400007640000002562213041763602015414 00000000000000; ; Program: FL51XINC.ASM V1.10 ; Revision Date: ; 09-09-97 Adapted to 12C51x parts ; 01-Apr-1999 Added emulation hooks ; ; 01-July-2004 Modified to suit LinTrain ; ; nolist ; comment this line out for use on real part ;#define EMULATED ; ; PIC12C51X EEPROM communication code. This code should be included in ; with the application. These routines provide the following functionality: ; write a byte to a specified address. ; read a byte from a specified address. ; read a byte from the next address. ; ; Emulation Requires: ; MPLAB-ICE ; PCM16XA0 processor module ; DVA12XP80 Device Adapter. ; Define EMULATED at the top of this file (#define EMULATED) ; This will set the I2C_PORT, SDA and SCL lines to communicate over ; Port A, pins 0 and 1. It also assembles in the necessary TRIS ; instructions to allow reading from the SDA line. ; ; To convert the code for the actual part, simply comment out the #define EMULATED ; line and reassemble. ; ; ; INTRODUCTION: ; The Microchip 12CE51x family of microntrollers are multichip modules ; which contain a PIC12C508 microcontroller and a 24LC00 EEPROM. ; This application note is intended to provide users with highly compressed ; assembly code for communication between the EEPROM and the Microcontroller, ; which will leave the user a maximum amount of code space for the core ; application. ; ;*************************************************************************** ;*************************** EEPROM Subroutines ************************** ;*************************************************************************** ; Communication for EEPROM based on I2C protocol, with Acknowledge. ; ; Byte_Write: Byte write routine ; Inputs: EEPROM Address EEADDR ; EEPROM Data EEDATA ; Outputs: Return 01 in W if OK, else return 00 in W ; ; Read_Current: Read EEPROM at address currently held by EE device. ; Inputs: NONE ; Outputs: EEPROM Data EEDATA ; Return 01 in W if OK, else return 00 in W ; ; Read_Random: Read EEPROM byte at supplied address ; Inputs: EEPROM Address EEADDR ; Outputs: EEPROM Data EEDATA ; Return 01 in W if OK, else return 00 in W ; ; Note: EEPROM subroutines will set bit 7 in ee_state register if the ; EEPROM acknowledged OK, else that bit will be cleared. This bit ; can be checked instead of refering to the value returned in W ;*************************************************************************** ; ; OPERATION: ; For detailed operating information and other important information about ; this code, see AN571. This code was derived from AN571, with changes ; as appropriate for the specific hardware in the PIC12C51x parts. ;********************************************************************** ; ; ;*************************************************************************** ;*************************** Variable Listing **************************** ;*************************************************************************** ok equ 01h no equ 00h #ifdef EMULATED i2c_port equ 5 ; Port A control register, used for I2C scl equ 01h ; EEPROM Clock, SCL (I/O bit 7) sda equ 00h ; EEPROM Data, SDA (I/O bit 6) #else i2c_port equ GPIO ; Port B control register, used for I2C scl equ 07h ; EEPROM Clock, SCL (I/O bit 7) sda equ 06h ; EEPROM Data, SDA (I/O bit 6) #endif ee_ok equ 07h ; Bit 7 in ee_state used as OK flag for EE ; All variables declared in the RAMDEF.INC file ;*************************************************************************** ;*************************** EEPROM Subroutines ************************** ;*************************************************************************** ; Communication for EEPROM based on I2C protocol, with Acknowledge. ; ; WRITE_BYTE: Byte write routine ; Inputs: EEPROM Address EEADDR ; EEPROM Data EEDATA ; Outputs: Return 01 in W if OK, else return 00 in W ; ; READ_CURRENT: Read EEPROM at address currently held by EE device. ; Inputs: NONE ; Outputs: EEPROM Data EEDATA ; Return 01 in W if OK, else return 00 in W ; ; READ_RANDOM: Read EEPROM byte at supplied address ; Inputs: EEPROM Address EEADDR ; Outputs: EEPROM Data EEDATA ; Return 01 in W if OK, else return 00 in W ; ; Note: EEPROM subroutines will set bit 7 in ee_state register if the ; EEPROM acknowledged OK, else that bit will be cleared. This bit ; can be checked instead of refering to the value returned in W ;*************************************************************************** ;********************** Set up EEPROM control bytes ************************ ;*************************************************************************** read_current: movlw b'10000100' ; PC offset for read current addr. EE_OK bit7='1' movwf ee_state ; Load PC offset goto init_read_control write_byte: movlw b'10000000' ; PC offset for write byte. EE_OK: bit7 = '1' goto init_write_control read_random: movlw b'10000011' ; PC offset for read random. EE_OK: bit7 = '1' init_write_control: movwf ee_state ; Load PC offset register, value preset in W movlw b'10100000' ; Control byte with write bit, bit 0 = '0' start_bit: bcf i2c_port,sda ; Start bit, SDA and SCL preset to '1' ; ;******* Set up output data (control, address, or data) and ee_bitcnt ******** ;*************************************************************************** prep_transfer_byte: movwf eebyte ; Byte to transfer to EEPROM already in W movlw .8 ; ee_bitcnt to transfer 8 bits movwf ee_bitcnt #ifdef EMULATED movlw 0x00 ; make sure both are outputs tris i2c_port #endif ; ;************ Clock out data (control, address, or data) byte ************ ;*************************************************************************** output_byte: bcf i2c_port,scl ; Set clock low during data set-up rlf eebyte,f ; Rotate left, high order bit into carry bit bcf i2c_port,sda ; Set data low, if rotated carry bit is skpnc ; a '1', then: bsf i2c_port,sda ; reset data pin to a one, otherwise leave low nop bsf i2c_port,scl ; clock data into EEPROM decfsz ee_bitcnt,f ; Repeat until entire byte is sent goto output_byte nop ; ;************************** Acknowledge Check ***************************** ;*************************************************************************** bcf i2c_port,scl ; Set SCL low, 0.5us < ack valid < 3us nop bsf i2c_port,sda #ifdef EMULATED movlw (0x01 << sda) ; make SDA an input tris i2c_port #endif goto $+1 ; May be necessary for SCL Tlow at low voltage, bsf i2c_port,scl ; Raise SCL, EEPROM acknowledge still valid btfsc i2c_port,sda ; Check SDA for acknowledge (low) bcf ee_state,ee_ok ; If SDA not low (no ack), set error flag bcf i2c_port,scl ; Lower SCL, EEPROM release bus btfss ee_state,ee_ok ; If no error continue, else stop bit goto stop_bit #ifdef EMULATED movlw 0x00 ; SDA back to an output tris i2c_port #endif ; ;***** Set up program ee_bitcnt offset, based on EEPROM operating mode ***** ;*************************************************************************** movf ee_state,w andlw b'00001111' addwf PCL,f goto init_address ;PC offset=0, write control done, send address goto init_write_data ;PC offset=1, write address done, send data goto stop_bit ;PC offset=2, write done, send stop bit goto init_address ;PC offset=3, write control done, send address goto init_read_control ;PC offset=4, send read control goto read_byte_setup ;PC offset=5, set ee_bitcnt and read byte goto stop_bit ;PC offset=6, random read done, send stop ; ;********** Initalize EEPROM data (address, data, or control) bytes ****** ;*************************************************************************** init_address: incf ee_state,f ; Increment PC offset to 2 (write) or to 4 (read) movf eeaddr,w ; Put EEPROM address in W, ready to send to EEPROM goto prep_transfer_byte init_write_data: incf ee_state,f ; Increment PC offset to go to STOP_BIT next movf eedata,w ; Put EEPROM data in W, ready to send to EEPROM goto prep_transfer_byte init_read_control: bsf i2c_port,scl ; Raise SCL nop bsf i2c_port,sda ; raise SDA incf ee_state,f ; Increment PC offset to go to read_byte_setup next movlw b'10100001' ; Set up read control byte, ready to send to EEPROM goto start_bit ; bit 0 = '1' for read operation ; ;************************** Read EEPROM data ***************************** ;*************************************************************************** read_byte_setup: bsf i2c_port,sda nop bsf i2c_port,scl ; set data bit to 1 so we're not pulling bus down. movlw .8 ; Set ee_bitcnt so 8 bits will be read into EEDATA movwf ee_bitcnt #ifdef EMULATED movlw (0x01 << sda) tris i2c_port #endif read_byte: bsf i2c_port,scl ; Raise SCL, SDA valid. SDA still input from ack setc ; Assume bit to be read = 1 btfss i2c_port,sda ; Check if SDA = 1 clrc ; if SDA not = 1 then clear carry bit rlf eedata,f ; rotate carry bit (=SDA) into EEDATA bcf i2c_port,scl ; Lower SCL bsf i2c_port,sda ; reset SDA decfsz ee_bitcnt,f ; Loop until bit count expires goto read_byte ; Read next bit if not finished reading byte bsf i2c_port,scl nop bcf i2c_port,scl ;****************** Generate a STOP bit and RETURN *********************** ;*************************************************************************** stop_bit: #ifdef EMULATED movlw 0x00 ; set SDA as output tris i2c_port #endif bcf i2c_port,sda ; SDA=0, on TRIS, to prepare for transition to '1' bsf i2c_port,scl ; SCL = 1 to prepare for STOP bit goto $+1 ; 4 NOPs neccessary for I2C spec Tsu:sto = 4.7us goto $+1 bsf i2c_port,sda ; Stop bit, SDA transition to '1' while SCL high btfss ee_state,ee_ok ; Check for error retlw no ; if error, send back NO retlw ok ; if no error, send back OK ; ;Note: SDA and SCL still being driven by master, both set to outputs. ;**************************************************************************** list ;************************ End EEPROM Subroutines ************************** gpsim-0.30.0/regression/p12ce518/p12ce518.stc0000664000076400007640000000012213041763602015054 00000000000000# # Startup commands for testing the p12c518 # # Source code: load p12ce518.cod gpsim-0.30.0/regression/p16f84/0000775000076400007640000000000013117466027013043 500000000000000gpsim-0.30.0/regression/p16f84/reset.asm0000664000076400007640000002127213041763600014604 00000000000000 ; 12C509 gpsim regression test ; ; The purpose of this test is to verify that the 'C509 ; is implemented correctly. Here's a list of specific things ; tested: ; ; 1) Reset conditions ; 2) WDT ; 3) Sleep ; 4) Wakeup on PIN change. list p=16f84 include include __CONFIG _WDT_ON radix dec ; Printf Command .command macro x .direct "C", x endm GPR_DATA UDATA ResetSequence RES 1 optionShadow RES 1 w_temp RES 1 status_temp RES 1 temp1 RES 1 GLOBAL optionShadow, ResetSequence ; Define the reset conditions to be checked. eRSTSequence_PowerOnReset equ 1 eRSTSequence_AwakeMCLR equ 2 eRSTSequence_AwakeWDT equ 3 eRSTSequence_AwakeIO equ 4 eRSTSequence_WDTTimeOut equ 5 ;---------------------------------------------------------------------- ; ********************* STARTUP LOCATION *************************** ;---------------------------------------------------------------------- START CODE 0x000 ; ;############################################################ ;# Create a stimulus to simulate a switch ; .sim "module lib libgpsim_modules" .sim "module load pulsegen P_INTF" .sim "module load pulsegen P_RBIF" .sim "module load pulsegen RESET" .sim "RESET.initial = 5.0" .sim "P_INTF.clear = 0" ; At cycle 0, .sim "P_INTF.set = 1" .sim "P_RBIF.clear = 0" ; At cycle 0, .sim "P_RBIF.set = 1" ;############################################################ .sim "node nINTF" .sim "attach nINTF portb0 P_INTF.pin" .sim "node nRBIF" .sim "attach nRBIF portb4 P_RBIF.pin" .sim "node nRESET" ; .sim "attach nRESET p16f84.MCLR RESET.pin" .sim "attach nRESET MCLR RESET.pin" ;############################################################ .sim "symbol resetCounter=1" ; NOT_GPWU = 0 - Enable wakeup if I/O pins 0,1, or 3 change states ; NOT_GPPU = 1 - Disable weak pullups on I/O pins 0,1, and 3 ; TOCS = 0 - Let the clock source for TMR0 be the internal fosc/4 ; TOSE = 0 - don't care - TMR0 source edge. ; PSA = 1 - assign Prescale to the WDT ; PS2:0 = 000 - prescale = 2^0=1 .sim "optionShadow=8" ; PSA=1 .sim "ResetSequence=0" .sim ".BreakOnReset = false" .sim "p16f84.frequency=100000" ; Set a cycle break point far in the future in case the resets fail. .sim "break c 0x1000000" RESET_VECTOR CODE 0x000 ; processor reset vector .assert "option_reg==0xff,\"*** FAILED 16f84 reset bad OPTION_REG\"" .assert "(trisa&0x1f)==0x1f, \"*** FAILED 16f84 reset bad TRISA\"" .assert "(trisb&0xff)==0xff, \"*** FAILED 16f84 reset bad TRISB\"" movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp check_rbi: btfsc INTCON,RBIF btfss INTCON,RBIE goto check_int ; bsf temp5,1 ;Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w bcf INTCON,RBIF check_int: btfsc INTCON,INTF btfss INTCON,INTE goto check_t0 ; bsf temp5,0 ;Set a flag to indicate rb0 int occured bcf INTCON,INTF check_t0: btfsc INTCON,T0IF btfss INTCON,T0IE goto exit_int ;; tmr0 has rolled over bcf INTCON,T0IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie bSWITCH equ 0 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; OPTION register setup BANKSEL OPTION_REG MOVF optionShadow,W ;optionShadow is initialized by the gpsim script MOVWF OPTION_REG ; GPIO setup ; If this is a PowerOn reset, then the state of the GPIO output register ; is unknown. If this is not a PowerOn reset then the GPIO pins have ; the same state they had prior to the reset. ; ; TRIS register setup - The I/O pins are always configured as Inputs after ; any reset. RB0 equ 0 RB4 equ 4 MOVLW (1< /MCLR while sleeping ; -or- Interrupt wake-up from sleep goto PowerOnReset ;/TO=1, /PD=1 ==> Power has just been applied TO_is_low BTFSS STATUS,NOT_PD goto AwakeWDT ;/TO=0, /PD=0 ==> WDT while sleeping goto WDTTimeOut ;/TO=0, /PD=1 ==> WDT while not sleeping BTFSC INTCON, RBIF ;Did we just wake up from SLEEP due goto AwakeIO ;to a change in the I/O pins? ;======================================================================== ; ; PowerOnReset ; ;======================================================================== PowerOnReset: movf ResetSequence,W XORLW eRSTSequence_AwakeMCLR skpnz goto done movf PORTB,W ;Clear miss-match, if any bcf INTCON, RBIF .assert "(intcon&1)==0, \"*** FAILED p16f84 to clear INTCON\"" nop .assert "resetCounter==1,\"*** FAILED p16f84 Power On Reset\"" MOVLW eRSTSequence_PowerOnReset MOVWF ResetSequence CLRWDT .command "resetCounter = resetCounter+1" SLEEP ; The WDT should cause a reset. So we shouldn't fall through ; (note, the instruction after the SLEEP should not be executed). ; RRR WDT will not cause a reset but will fall through nop ;RRR .command "resetCounter = resetCounter+1" nop ;======================================================================== ; ; AwakeWDT - WDT timed out while we were sleeping. ; ;======================================================================== AwakeWDT: .assert "resetCounter==2,\"*** FAILED WDT Reset p16f84\"" MOVLW eRSTSequence_AwakeWDT MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT ; loop until WDT times out here: goto here ;======================================================================== ; ; WDTTimeOut - WatchDog timer timed out while we were awake. ; ;======================================================================== WDTTimeOut: .assert "resetCounter==3,\"*** FAILED WDT timeout p16f84\"" MOVLW eRSTSequence_WDTTimeOut MOVWF ResetSequence CLRWDT .command "P_RBIF.clear = cycles+100" nop ; Keep interrupts enabled, but turn on RBIE. Changes on ; RB4-RB7 should wake us from sleep MOVLW 1< ; processor specific variable definitions include ; Grab some useful macros CONFIG_WORD EQU _CP_OFF & _WDT_OFF __CONFIG CONFIG_WORD ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA failures RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ; Node Test ; This script will tie Port A and Port B together ;"# First, create 8 nodes: .sim "node loop_back0" .sim "node loop_back1" .sim "node loop_back2" .sim "node loop_back3" .sim "node loop_back4" .sim "node loop_back5" .sim "node loop_back6" .sim "node loop_back7" ;# Now tie the ports together: .sim "attach loop_back0 portb0 porta0" .sim "attach loop_back1 portb1 porta1" .sim "attach loop_back2 portb2 porta2" .sim "attach loop_back3 portb3 porta3" .sim "attach loop_back4 portb4 porta4" ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start CLRF failures ;Assume success MOVLW 0xff BSF STATUS,RP0 CLRF TRISA^0x80 ;Port A is an output MOVWF TRISB^0x80 ;Port B is an input BSF OPTION_REG ^ 0x80, NOT_RBPU ;Disable the pullups BCF STATUS,RP0 MOVLW 0x0F a_to_b_loop: MOVWF PORTA ;Port A and Port B are externally XORWF PORTB,W ;connected. So we should see the SKPZ ;same thing on each port. GOTO FAILED DECFSZ PORTB,W goto a_to_b_loop BSF PORTA,4 ;Port A bit 4 is an open collector. BTFSC PORTB,4 .assert "\"*** FAILED 16f84 test -RA4 stuck high\"" GOTO FAILED ; Now let's write from PORTB to PORTA. ; With the configuration bit setting we have, all of PORTA I/O lines ; should be able to serve as inputs BSF STATUS,RP0 COMF TRISA^0x80,F ;Port A is now an input port COMF TRISB^0x80,F ;Port B is now an output port BCF STATUS,RP0 CLRW b_to_a_loop: MOVWF PORTB ;Port A and Port B are externally XORWF PORTA,W ;connected. So we should see the ANDLW 0x1f SKPZ ;same thing on each port. GOTO FAILED DECFSZ PORTB,W goto b_to_a_loop ; ; Now test PORTB's internal pullups ; CLRF PORTB MOVLW 0xff BSF STATUS,RP0 MOVWF TRISA^0x80 ;Port A is an input MOVWF TRISB^0x80 ;Port B is an input BSF OPTION_REG ^ 0x80, NOT_RBPU ;Disable the pullups BCF STATUS,RP0 MOVF PORTB,W ANDLW 0x0F SKPZ GOTO FAILED BSF STATUS,RP0 BCF OPTION_REG ^ 0x80, NOT_RBPU ;Enable the pullups BCF STATUS,RP0 MOVF PORTB,W ;All lines should be high XORLW 0xFF SKPZ GOTO FAILED GOTO done FAILED: .assert "\"*** FAILED 16f84 test\"" INCF failures,F done: .assert "\"*** PASSED 16f84 test\"" GOTO $ end gpsim-0.30.0/regression/tmr0_16bit/0000775000076400007640000000000013117466027014002 500000000000000gpsim-0.30.0/regression/tmr0_16bit/delay.asm0000664000076400007640000000266713041763577015543 00000000000000 list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal GLOBAL DelayCycles GLOBAL Delay256N GLOBAL Delay4 GLOBAL Delay5 GLOBAL Delay6 GLOBAL Delay7 GLOBAL Delay8 GLOBAL Delay9 DELAY_CODE CODE ;------------------------------------------------------------ ; DelayCycles: ; ; Input: W -- the desired delay ; Output: Returns after W+7 cycles DelayCycles: dc1: ADDLW -3 ;3-cycle delay loop BC dc1 ; W now contains either -3 (0xFD), -2 (0xFE) or -1 (0xFF). ; The -2 case needs to be delayed an extra cycle more than ; the -3 case, and the -1 case needs yet another cycle of delay. ; ; Examine the bottom two bits and W to determine the exact delay ; BTFSS WREG,1 BRA dc2 ;W=0xFD - no extra delay needed RRCF WREG,F BC dc2 dc2: RETURN Delay256Loop RCALL Delay4 Delay256N: RCALL dc3 DECFSZ WREG,F bra Delay256Loop Delay5 NOP Delay4 RETURN dc3: RCALL Delay64 RCALL Delay32 RCALL Delay16 RCALL Delay8 NOP Delay128 RCALL Delay64 Delay64 RCALL Delay32 Delay32 RCALL Delay16 Delay16 RCALL Delay8 Delay8 nop Delay7 nop Delay6 bra Delay4 Delay9 bra Delay7 END gpsim-0.30.0/regression/tmr0_16bit/tmr0_16bit.asm0000664000076400007640000002402613041763577016325 00000000000000 ;; tmr0_16bit.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; TMR0 for a 16bit-core pic (like the 18fxxx family) ;; Here are the tests performed: ;; ;; -- TMR0L and TMR0H can be read and written ;; -- Writing to TMR0L list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal include "delay.inc" ; Defines the "DELAY" macro ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 TMR0_RollOver RES 1 tmr0Lo RES 1 tmr0Hi RES 1 psa RES 1 b16bitMode RES 1 countLo RES 1 countHi RES 1 GLOBAL tmr0Lo, tmr0Hi GLOBAL psa,b16bitMode GLOBAL done GLOBAL TMR0_RollOver GLOBAL countLo, countHi ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: BTFSC INTCON,T0IF ;If the roll over flag is not set BTFSS INTCON,T0IE ;or the interrupt is not enabled RETFIE 1 ; Then leave ;; TMR0 has rolled over. Clear the pending interrupt and notify ;; the foreground code by incrementing the "roll over" counter ;; Notice that the increment operation is atomic - this means ;; we won't have to worry about the foreground code and interrupt ;; code clashing over accesses to this variable. BCF INTCON,T0IF,0 ; Clear the pending interrupt INCF TMR0_RollOver,F ; Set a flag to indicate rollover ExitInterrupt: RETFIE 1 MAIN CODE Start: ; At reset, all bits of t0Con should be set. .assert "t0con == 0xff" nop ;------------------------------------------------------------ ; The high byte of TMR0 is exposed to the firmware as a shadow register. When ; firmware writes to this register, the value is latched. When the firmware ; writes the to the low byte, then the latched high byte will get copied ; along with the low byte to TMR0. This allows all 16-bits to be written in a ; single cycle. Similarly, when TMR0L is read, the high byte of the timer ; is copied to the shadowed register. TMR0H_ShadowRegisterTest: .command "echo *** Testing TMR0H" MOVLW 42 MOVWF TMR0H .assert "tmr0h == 42" nop MOVWF TMR0L .assert "tmr0l == 42" nop MOVF TMR0L,W .assert "tmr0l == 42" nop MOVF TMR0H,W .assert "tmr0h == 42" nop ; Clear the shadowed TMR0H register and verify that it cleared. CLRF TMR0H .assert "tmr0h == 0" nop ; Now, when we read the low byte of Timer 0, the high byte gets ; refreshed. So let's check that TMR0H changes due to a TMR0L read: MOVF TMR0L,W .assert "tmr0l == 42" nop MOVF TMR0H,W .assert "tmr0h == 42" NOP TMR0_8BitModeTest: .command "echo *** Testing 8-bit mode" ; Stop the timer and clear its value CLRF T0CON CLRF TMR0L CLRF TMR0H .assert "(tmr0l == 0) && (tmr0h == 0)" nop ; The timer is off, so any value written to it should be read back ; unchanged. MOVLW 42 MOVWF TMR0L .assert "tmr0l == 42" NOP MOVWF TMR0H .assert "tmr0h == 42" NOP MOVWF tmr0Hi ;------------------------------------------------------------ ; 8-bit mode tests ; ; First, TMR0 is tested in 8-bit mode and with interrupts disabled. ; All 8 combinations of PSA are tested. CLRF psa ; Shadow's the PSA bits of T0CON L1_tmr0_8BitModeTest: ; Beginning of the loop ; Start off with T0CON and TMR0L in a known state. .command "psa" CLRF T0CON CLRF TMR0L CLRF tmr0Lo ; Assume that the PSA is not assigned to TMR0: MOVLW (1<>psa)" NOP .assert "tmr0l == ((tmr0Lo+5)>>psa)" NOP .assert "tmr0l == ((tmr0Lo+6)>>psa)" NOP .assert "tmr0l == ((tmr0Lo+7)>>psa)" NOP .assert "tmr0l == ((tmr0Lo+8)>>psa)" NOP .assert "tmr0l == ((tmr0Lo+9)>>psa)" NOP .assert "tmr0l == ((tmr0Lo+10)>>psa)" ; 8 23-cycle delays. MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+33)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+56)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+79)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+102)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+125)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+148)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+171)>>psa )" MOVLW 23 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+194)>>psa )" ; 255 and 256 cycle boundary condition MOVLW 61 - 10 RCALL DelayCycles .assert "tmr0l == ((tmr0Lo+255)>>psa )" NOP .assert "tmr0l == (((tmr0Lo+256)>>psa)&0xff)" nop ; now for some bigger delays. DELAY 250 .assert "tmr0l == (((tmr0Lo+256+251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+2*251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+3*251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+4*251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+5*251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+6*251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+7*251)>>psa)&0xff)" nop DELAY 250 .assert "tmr0l == (((tmr0Lo+256+8*251)>>psa)&0xff)" nop DELAY 8190 .assert "tmr0l == (((tmr0Lo+256+8*251+8191)>>psa)&0xff)" nop INCF psa,F btfss psa,3 bra L1_tmr0_8BitModeTest ; Through looping through all combinations of PSA. ; Now make sure that the high byte of TMR0 hasn't changed. MOVF TMR0H,W .assert "W == tmr0Hi" NOP ;------------------------------------------------------------ ; Interrupt tests NOP NOP NOP CLRF T0CON ;Stop TMR0 CLRF INTCON ;Clear any pending interrupts BSF INTCON,T0IE ;Enable TMR0 overflow interrupts BSF INTCON,GIE ;Enable global interrupts CLRF psa ;Loop counter and prescaler assignment. L1_InterruptTest: ; Stop and clear TMR0: CLRF T0CON CLRF TMR0H CLRF TMR0L CLRF TMR0_RollOver ;Interrupt flag ;Software counter to count cycles SETF countLo ;Start off with counter==-1 SETF countHi ; Assume that the PSA is not assigned to TMR0: MOVLW (1<>(5+psa)) == 1" nop INCF psa,F btfss psa,3 bra L1_InterruptTest ; ; test that t0 continues to run after sleep woken up by t1 nop bsf T0CON,PSA ; bypass precounter bsf T1CON,T1SYNC ;sync off bsf T1CON,TMR1ON ; start timer 1 bsf PIE1,TMR1IE ; turn on interrupt sleep movf TMR0L,W bcf T1CON,TMR1ON ; stop timer 1 nop nop .assert "tmr0l != W, \"*** FAILED 16bit-core TMR0 test- TMR0 stopped after sleep\"" nop ; ; TMR0 should not interrupt during sleep as it is turned off ; The WDT cancels the sleep ; clrf TMR0_RollOver sleep nop .assert "TMR0_RollOver == 0, \"*** FAILED 16bit-core TMR0 test- TMR0 interrupt in sleep\"" nop ;------------------------------------------------------------ ; 16bit-mode tests CLRF psa L1_tmr0_16BitModeTest: CLRF T0CON CLRF TMR0H CLRF TMR0L ; Assume that the PSA is not assigned to TMR0: MOVLW (1<>psa))" MOVF TMR0L,W .assert "( ((tmr0h<<8)+W) == (2>>psa))" MOVF TMR0L,W .assert "( ((tmr0h<<8)+W) == (3>>psa))" MOVF TMR0L,W .assert "( ((tmr0h<<8)+W) == (4>>psa))" MOVF TMR0L,W .assert "( ((tmr0h<<8)+W) == (5>>psa))" MOVF TMR0L,W MOVWF tmr0Lo .command "tmr0Lo" .command "tmr0h" DELAY 1024-2 MOVF TMR0L,W MOVWF tmr0Lo .command "tmr0Lo" .command "tmr0h" DELAY 8192-2 MOVF TMR0L,W MOVWF tmr0Lo .command "tmr0Lo" .command "tmr0h" INCF psa,F btfss psa,3 bra L1_tmr0_16BitModeTest nop done: .assert "\"*** PASSED 16bit-core TMR0 test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED 16bit-core TMR0 test\"" bra done end gpsim-0.30.0/regression/tmr0_16bit/18f452.lkr0000664000076400007640000000212113041763577015267 00000000000000// $Id: 18f452.lkr 1310 2005-10-03 13:59:01Z sdattalo $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/regression/tmr0_16bit/Makefile0000664000076400007640000000046713041763577015377 00000000000000include ../make.regression SCRIPT = 18f452.lkr PROJECT = tmr0_16bit OBJECTS = $(PROJECT).o delay.o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/tmr0_16bit/delay.inc0000664000076400007640000000167513041763577015532 00000000000000 EXTERN DelayCycles EXTERN Delay256N EXTERN Delay4 EXTERN Delay5 EXTERN Delay6 EXTERN Delay7 EXTERN Delay8 EXTERN Delay9 ;------------------------------------------------------------------------ ; DELAY macro ; ; The purpose of this macro is to delay exactly "delay" number of instruction ; cycles, where: ; ; ; 0 < delay < 65547 ; DELAY macro delay if delay == 1 NOP else if delay == 2 BRA $+2 else if delay == 3 NOP BRA $+2 else if delay<10 RCALL Delay#v(delay) else if delay < 265 MOVLW delay-10 RCALL DelayCycles else if delay < 274 RCALL Delay9 MOVLW delay-10-9 RCALL DelayCycles else MOVLW (delay-11) & 0xff RCALL DelayCycles MOVLW (delay-11)>>8 RCALL Delay256N endif endif endif endif endif endif endm gpsim-0.30.0/regression/tmr3_16bit.save/0000775000076400007640000000000013117466027014742 500000000000000gpsim-0.30.0/regression/tmr3_16bit.save/Makefile0000644000076400007640000000050510735406737016325 00000000000000include ../make.regression SCRIPT = 18f452.lkr PROJECT = tmr3_16bit OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/txisr_test/0000775000076400007640000000000013117466027014323 500000000000000gpsim-0.30.0/regression/txisr_test/txisr_test.stc0000664000076400007640000000011113041763600017150 00000000000000 # simple script to load and start the simulation load s txisr_test.cod gpsim-0.30.0/regression/txisr_test/16f871.lkr0000664000076400007640000000251413041763600015604 00000000000000// Sample linker command file for 16F871 LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED SHAREBANK NAME=gprnobnk0 START=0x20 END=0x6F SHAREBANK NAME=gprnobnk0 START=0x120 END=0x16F SHAREBANK NAME=gprnobnk1 START=0xA0 END=0xBF SHAREBANK NAME=gprnobnk1 START=0x1A0 END=0x1BF SHAREBANK NAME=gprnobnk2 START=0x70 END=0x7F SHAREBANK NAME=gprnobnk2 START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk2 START=0x170 END=0x17F SHAREBANK NAME=gprnobnk2 START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/txisr_test/Makefile0000664000076400007640000000054613041763600015701 00000000000000# USART module transmit interrupt regression test # # include ../make.regression SCRIPT = 16f871.lkr PROJECT = txisr_test OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/txisr_test/txisr_test.asm0000664000076400007640000001035013041763600017145 00000000000000 ;; USART TXISR test ;; ;; The purpose of this program is to verify that gpsim's ;; USART module generates TX interrupts properly. ;; ;; ;; list p=16f871 include include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x20 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 ;fsr_temp RES 1 INT_VAR1 UDATA 0xA0 w_temp1 RES 1 ;Alias for w_temp at address 0x20 GPR_DAT UDATA 0x30 temp1 RES 1 temp2 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 GLOBAL tx_ptr ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH .assert "tx_ptr==0, \"*** FAILED unexpected reset\"" goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH bcf STATUS,RP0 btfss PIR1,TXIF goto int_done call tx_message movwf TXREG btfss tx_ptr,5 goto int_done bsf STATUS,RP0 bcf PIE1^0x80,TXIE ; Enable Tx interrupts bcf STATUS,RP0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=20e6" .sim "module library libgpsim_modules" .sim "module load usart U1" ; .sim "U1.xpos = 250.0" ; .sim "U1.ypos = 80.0" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 9600" .sim "U1.rxbaud = 9600" .sim "tx_ptr=0" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. bsf STATUS,RP0 bsf TRISC,7 ;RX is an input bcf TRISC,6 ;RC6 must be an input for TX to drive pin ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< include ; Grab some useful macros .command macro x .direct "C", x endm ;-------------------------------------------------------- ; config word(s) ;-------------------------------------------------------- __config _CONFIG1, 0xffa4 __config _CONFIG2, 0xdfff ;-------------------------------------------------------- ; items in internal ram ;-------------------------------------------------------- GPR_DATA UDATA_SHR result RES 2 delay_count RES 1 delay_temp RES 1 ;-------------------------------------------------------- ; reset vector ;-------------------------------------------------------- STARTUP code 0x0000 goto start ;; We use 2 ananlogue file inputs. Pin A1 gets an analogue value, ;; and pin A3 is use to signal when pin A1 is ready to be probed. .sim "module library libgpsim_modules" .sim "module load FileStimulus S1" ;.sim "set v" .sim "S1.file = \"stim_an.sig\"" .sim "node na1" .sim "attach na1 S1.pin porta1" .sim "module load FileStimulus S2" .sim "S2.file = \"stim_clk.sig\"" .sim "node na3" .sim "attach na3 S2.pin porta3" .sim "break c 0x10000" ;-------------------------------------------------------- ; code ;-------------------------------------------------------- MAIN code 0x0020 start: ;; Initialisation banksel ADCON1 bsf ADCON1, ADFM ; Output is right justified bsf ADCON0, 2 ; Input is on pin PORTA1 bsf ADCON0, ADON ; Enable ADC clrf result clrf result+1 banksel PORTA main_loop: btfss PORTA, 3 ; Wait until AN0 is set goto main_loop bcf PIR1, ADIF banksel ADCON0 bsf ADCON0, GO ; Take a measurement btfsc ADCON0, GO goto $-1 movf ADRESH, W ; A 0 value terminates the set iorwf ADRESL, W bz finish movf ADRESL, W ; Add the value sampled to the end result addwf result, F btfsc STATUS, C incf result+1, F movf ADRESH, W addwf result+1, F banksel PORTA btfsc PORTA, 3 ; Wait until the cycle is over goto $-1 goto main_loop finish: movf result, W iorwf result+1, W .assert "W==0xff, \"*** FAILED File Stimulus Test\"" nop .assert "W!=0xff, \"*** PASSED File Stimulus Test\"" nop bra $ end gpsim-0.30.0/regression/analog_stim/p18f452.asm0000664000076400007640000000734413041763600016044 00000000000000 list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA LoopCounter RES 1 lastADRES RES 1 a2dIntFlag RES 1 ;LSB is set when an A2D interrupt occurs GLOBAL done GLOBAL a2dIntFlag, LoopCounter ;------------------------------------------------------------------------ STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: btfsc PIR1,ADIF ;If A2D int flag is not set btfsc PIE1,ADIE ;Or the interrupt is not enabled goto a2dint .assert "\"FAIL 18F452 unexpected interrupt\"" nop RETFIE 1 ; Then leave ;; An A/D interrupt has occurred a2dint: bsf a2dIntFlag,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt ExitInterrupt: RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "node na0" ;.sim "attach na0 V1.pin porta0" .sim "stimulus asynchronous_stimulus" ;# Specify the initial state of the stimulus. Note that this ;# is the value the stimulus is BEFORE start_cycle. .sim "initial_state 0.0" ;# all times are with respect to the cpu's cycle counter .sim "start_cycle 1" ;# the asynchronous stimulus will roll over in 'period' ;# cycles. Delete this line if you don't want a roll over. .sim "period 7000" ;# gpsim assumes digital data by default .sim "analog" ;# Now specify the data points. Each point needs two values: ;# the time at which it changes and the value to which it ;# changes. ;# t v ;# ---- ---------- .sim "{ 1000, 0.0," .sim " 2000, 1.0," .sim " 3000, 2.0," .sim " 4000, 3.0," .sim " 5000, 4.0," .sim " 6000, 5.0 }" .sim "name asy_analog" .sim "end" .sim "attach na0 asy_analog porta0" Start: ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; MOVLW 1< ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 w_temp RES 1 status_temp RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector .sim "symbol callCounter=1" .sim "symbol callFrom=0" .sim "symbol cycleCounter=0" .sim "break c 0x100000" movlw high start ; load upper byte of 'start' label .assert "callCounter==1,\"*** FAILED Call level 1\"" movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp check_t0: btfsc INTCON,T0IF btfss INTCON,T0IE goto exit_int ;; tmr0 has rolled over bcf INTCON,T0IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: call L1 .assert "callCounter==2,\"*** FAILED Call level 1\"" nop call L2 .assert "callCounter==4,\"*** FAILED Call level 1\"" nop call L3 .assert "callCounter==7,\"*** FAILED Call level 1\"" nop .command "callCounter = 2" call L1 .assert "callCounter==3,\"*** FAILED Call level 1\"" call L1 .assert "callCounter==4,\"*** FAILED Call level 1\"" call L1 .assert "callCounter==5,\"*** FAILED Call level 1\"" nop .command "callCounter = 2" call Nest1 .assert "callCounter==0x124,\"*** FAILED Call level 3\"" ;; Verify instruction cycle counts .command "cycleCounter = cycles" nop .assert "(cycleCounter+1) == cycles" goto $+1 .assert "(cycleCounter+3) == cycles" call L1 .assert "(cycleCounter+7) == cycles" ;; ;; tmr0 test ;; ;; The following block of code tests tmr0 together with interrupts. ;; Each prescale value (0-7) is loaded into the timer. The software ;; waits until the interrupt due to tmr0 rollover occurs before ;; loading the new prescale value. clrwdt bsf INTCON,T0IE ;Enable TMR0 overflow interrupts bsf INTCON,GIE ;Global interrupts clrf temp1 ;Software flag used to monitor when the ;interrupt has been serviced. clrw test_tmr0: option ;Assign new prescale value test_flag: clrwdt call Test1 btfss temp1,0 ;Wait for the interrupt to occur and goto test_flag ;get serviced clrf temp1 ;Clear flag for the next time bsf STATUS,RP0 incf (OPTION_REG^0x80),W bcf STATUS,RP0 andlw 0x7 ;Check the prescaler skpz goto test_tmr0 ; ; Now test 14-bit core SFRs (which should be done in an SFR test but there isn't one) ; movlw 0xFF movwf PCLATH .assert "pclath == 0x1F, \"*** FAILED 14-bit PCLATH masking\"" nop clrf PCLATH goto done L1: .command "callCounter = callCounter+1" return L2: .command "callCounter = callCounter+2" return L3: .command "callCounter = callCounter+3" return Nest1: .command "callCounter = callCounter+1" call Nest2 .command "callCounter = callCounter+1" return Nest2: .command "callCounter = callCounter+0x10" call Nest3 .command "callCounter = callCounter+0x10" return Nest3: .command "callCounter = callCounter+0x100" return Test1: .command "callCounter = 2" call Test2 .assert "callCounter == 7,\"*** FAILED Call level 4\"" ; .command "callFrom=2" call Test3 ; .assert "callCounter == 9,\"*** FAILED Call level 4\"" ; .command "callFrom=3" call Test4 ; .assert "callCounter == 10,\"*** FAILED Call level 4\"" return Test2: ; .command "callFrom=2" call Test3 .command "callCounter = callCounter+1" ; .command "callFrom=3" call Test4 .command "callCounter = callCounter+1" return Test3: ; .assert "callFrom==2" ; nop ; .command "callFrom=3" call Test4 .command "callCounter = callCounter+1" return Test4: .command "callCounter = callCounter+1" ; .assert "callFrom==3" return done: .assert "\"*** PASSED Midrange core Branching test\"" nop end gpsim-0.30.0/regression/instructions_14bit/instructions_14bit.asm0000664000076400007640000001710513116713671022056 00000000000000 ;; it.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; instructions on a mid-range (14bit core) Pic. list p=16f628 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf temp1 ;Assume clrf works... ; ;; ;; map tmr0 to the internal clock ;; clrw option ;initialize tmr0 BankLoop: ;; Perform some basic tests on some important instructions setc ;set the Carry flag skpc ;and verify that it happened goto failed clrc ;Now try clearing the carry skpnc goto failed setz ;set the Zero flag skpz ;and verify that it happened goto failed clrz ;Now try clearing it skpnz goto failed setdc ;set the Digit Carry flag skpdc ;and verify that it happened goto failed clrdc ;Now try clearing it skpndc goto failed movlw 1 movwf temp movf temp,f skpnz goto failed movlw 0 movwf temp movf temp,f skpz goto failed clrf temp ;Clear a register skpz ;and verify that the Z bit in the goto failed ;status register was set. movf temp,w ;Read the register that was just skpz ;cleared, and again verify that Z goto failed ;was set incf temp,w ;Now this should cause the Z bit to skpnz ;get cleared. goto failed movlw 0xff movwf temp incf temp,f skpz goto failed ;; ;; incfsz ;; movlw 0xff movwf temp movf temp,f ;Should clear Z incfsz temp,w goto failed skpnz ;incfsz shouldn't affect Z goto failed incfsz temp,f ;temp should now be zero goto failed incfsz temp,w ;the following inst. shouldn't be skipped skpnz ;Z should be clear from above. goto failed ;; addlw 0xaa ;; ;; addwf test: ;; ;; The purpose of this test is to a) verify that the addwf instruction ;; adds correctly and b) that the appropriate status register bits are ;; set correctly. clrw clrf temp addwf temp,w ; 0+0 skpnc goto failed skpz goto failed skpndc goto failed movlw 1 ; 0+1 addwf temp,w skpnc goto failed skpnz goto failed skpndc goto failed movlw 8 ; 8+8 movwf temp addwf temp,w skpnc goto failed skpnz goto failed skpdc goto failed movlw 0x88 ; 0x88+0x88 movwf temp addwf temp,w skpc goto failed skpnz goto failed skpdc goto failed movlw 0x80 ; 0x80+0x80 movwf temp addwf temp,w skpc goto failed skpz goto failed skpndc goto failed movlw 1 movwf temp movlw 0xff addwf temp,w skpc goto failed skpz goto failed skpdc goto failed clrc clrdc ;; ;; andwf test: ;; clrf temp movlw 1 andwf temp,f skpz goto failed skpc skpndc goto failed andwf temp,w skpz goto failed skpc skpndc goto failed movlw 1 movwf temp andwf temp,f skpnz goto failed skpc skpndc goto failed movlw 0xff andwf temp,f ;1 & 0xff should = 1 skpnz goto failed skpc skpndc goto failed movlw 0xff ;Now add 0xff to see if temp addwf temp,f ;really is 1. (should cause a carry) skpnz skpc goto failed ;; ;; iorwf ;; movlw 0 movwf temp iorwf temp,f skpz goto failed movlw 1 iorwf temp,f skpnz goto failed movlw 0xff addwf temp,f skpnz skpc goto failed ;; ;; rlf ;; clrdc clrf temp clrc rlf temp,w skpdc skpnc goto failed skpz goto failed setc rlf temp,f skpdc skpnc goto failed skpz goto failed movlw 0xff addwf temp,f skpnz skpc goto failed rlf temp,f skpnc goto failed movlw 0x80 movwf temp rlf temp,w skpc goto failed movwf temp addwf temp,w skpz goto failed ;; ;; rrf ;; clrdc clrf temp clrc rrf temp,w skpdc skpnc goto failed skpz goto failed setc rrf temp,f skpdc skpnc goto failed skpz goto failed movlw 0x80 addwf temp,f skpnz skpc goto failed rrf temp,f skpnc goto failed movlw 1 movwf temp rrf temp,w skpc goto failed movwf temp addwf temp,w skpz goto failed ;; ;; subwf test: ;; clrw clrf temp subwf temp,w ; 0-0 skpc goto failed skpz goto failed skpdc goto failed movlw 1 ; 0-1 subwf temp,w skpnc goto failed skpnz goto failed skpndc goto failed movlw 0x10 ; 0x10-0x10 movwf temp subwf temp,w skpc goto failed skpz goto failed skpdc goto failed movlw 0x88 ; 0x88-0x88 movwf temp subwf temp,w skpc goto failed skpz goto failed skpdc goto failed clrf temp movlw 0x80 ; 0 - 0x80 subwf temp,f skpnc goto failed skpnz goto failed skpdc goto failed movlw 0 ; 0x80 - 0 subwf temp,w skpc goto failed skpnz goto failed skpdc goto failed movlw 1 ; 0x80 - 1 subwf temp,w skpc goto failed skpnz goto failed skpndc goto failed clrc clrdc ;; ;; xorwf ;; clrf temp movlw 0xff xorwf temp,f skpc skpndc goto failed skpnz goto failed xorwf temp,f skpz goto failed xorwf temp,f incfsz temp,f goto failed ;; ;; swapf ;; movlw 0x0f movwf temp swapf temp,f xorwf temp,f incfsz temp,f goto failed decf temp1,f incfsz temp1,w goto done ;; repeat the test with in the next bank bsf STATUS,RP0 goto BankLoop done: .assert "\"*** PASSED MidRange core instruction test\"" bcf STATUS,RP0 NOP NOP NOP NOP NOP NOP goto $ NOP NOP NOP NOP NOP NOP NOP andlw 0xaa andwf temp,w bcf temp,5 bsf temp,5 btfsc temp,5 btfss temp,5 call routine clrf temp clrw clrwdt comf temp,w decf temp,w decfsz temp,w goto l1 nop nop nop l1: incf temp,w incfsz temp,w iorlw 0xaa iorwf temp,w movlw 0xaa movf temp,w movwf temp nop option goto r1 retfie retlw 0xaa routine return r1: rlf temp,w rrf temp,w sleep sublw 0xaa subwf temp,w swapf temp,w tris 5 xorlw 0xaa xorwf temp,w ;; ;; Test indirect branching ;; test_pcl: clrf temp clrf temp1 tt1: movf temp,w call table_test xorwf temp,w skpz bsf temp1,0 incf temp,f btfss temp,4 goto tt1 goto test_pcl2 table_test: addwf PCL,f table: retlw 0 retlw 1 retlw 2 retlw 3 retlw 4 retlw 5 retlw 6 retlw 7 retlw 8 retlw 9 retlw 10 retlw 11 retlw 12 retlw 13 retlw 14 retlw 15 test_pcl2: btfsc temp2,0 goto test_pcl3 movlw 0x20 movwf FSR next clrf INDF incf FSR,1 btfss FSR,4 goto next bsf temp2,0 clrf PCL test_pcl3: movlw LOW(ly) movwf PCL ; == goto ly lx goto test_pcl4 ly movlw LOW(lx) movwf PCL test_pcl4: goto $ failed: .assert "\"*** FAILED MidRange core instruction test\"" goto done end gpsim-0.30.0/regression/instructions_14bit/16f628.lkr0000664000076400007640000000250213041763600017140 00000000000000// Sample linker command file for 16F628 // $Id: 16f628.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x217F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x120 END=0x14F SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/instructions_14bit/Makefile0000664000076400007640000000017213041763600017233 00000000000000include ../make.regression all : instructions_14bit.cod branching.cod %.cod: %.o gplink --map -s 16f628.lkr -o $@ $^ gpsim-0.30.0/regression/instructions_14bit/instructions_14bit.stc0000664000076400007640000000010613041763600022052 00000000000000# simple script to load the simulation load s instructions_14bit.cod gpsim-0.30.0/regression/tmr1_16bit/0000775000076400007640000000000013117466027014003 500000000000000gpsim-0.30.0/regression/tmr1_16bit/tmr1_18f2620.asm0000664000076400007640000001465413041763577016320 00000000000000 ;; tmr1_16bit.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; TMR1 for a p18f2620 pic (like the 18fxxx family) although ;; most of the functionality is generic to all processors where ;; t1mer1 supports an external clock source. ;; ;; Here are the tests performed: ;; ;; -- TMR1 count seconds when driven by simulated external crystal ;; -- TMR1 driven Fosc/4 with prescale of 8 ;; -- TMR1 count seconds when driven by external stimuli ;; -- TMR1L and TMR1H can be read and written list p=18f2620 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 TMR0_RollOver RES 1 TMR1_RollOver RES 1 countLo RES 1 countHi RES 1 TMR1H_Sampled RES 1 TMR1H_Last RES 1 SecondsLo RES 1 SecondsHi RES 1 GLOBAL countLo, countHi GLOBAL SecondsLo, SecondsHi ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: ;;================== ;; TMR1 Interrupt ;;================== BTFSC INTCON,T0IF ;If the roll over flag is not set BTFSS INTCON,T0IE ;or the interrupt is not enabled bra checkTMR0IntEnd ; ;; TMR0 has rolled over. Clear the pending interrupt and notify ;; the foreground code by incrementing the "roll over" counter ;; Notice that the increment operation is atomic - this means ;; we won't have to worry about the foreground code and interrupt ;; code clashing over accesses to this variable. BCF INTCON,T0IF,0 ; Clear the pending interrupt INCF TMR0_RollOver,F ; Set a flag to indicate rollover checkTMR0IntEnd: ;;================== ;; TMR1 Interrupt ;;================== BTFSC PIR1,TMR1IF BTFSS PIE1,TMR1IE BRA checkTMR1IntEnd BCF PIR1,TMR1IF ;Clear the interrupt INCF TMR1_RollOver,F ;Set a flag BSF TMR1H, 7 ; Preload for 1 sec overflow ; Note, since we have a 32768 Hz crystal tied to TMR1 and we have the timer ; configured as a 16-bit timer TMR1H loaded with 0x80, then this interrupt ; will happen once every second. INFSNZ SecondsLo,F ;Update the system time. INCF SecondsHi,F CLRF TMR1H_Sampled CLRF TMR1H_Last checkTMR1IntEnd: ExitInterrupt: RETFIE 1 MAIN CODE Start: ;------------------------------------------------------------------------ ; ; Embedded simulation scripts ; ; Set the clock frequency to 10MHz .sim "frequency 10e6" ; define a stimulus to generate a 32kHz clock. This will be tied ; to TMR1's input and is used to simulate an external drive. ; ; 40MHz ; Instruction Rate = (4 clks/instruction) / (10e6 clks/second) ; = 400nS per instruction ; 32.768kHz ==> 30.517uS period ; Instruction Cycles/32.768kHz cycle = 30.517uS / .4uS ; = 76.2925 instructions ; .sim "stimulus asynchronous_stimulus " .sim "initial_state 0" .sim "start_cycle 0x2008130" .sim "period 305" .sim "{ 38,1 , 76,0 , 114,1 , 152,0 , 190,1 , 228,0 , 266,1}" .sim "name Clk32kHz" .sim "end" ; Create a node .sim "node clk_node" ; attach the clock .sim "attach clk_node Clk32kHz portc0" ; At reset, all bits of t1Con should be clear. .assert "t1con == 0x00" MOVLW (1< ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA 0 temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 TMR0_RollOver RES 1 TMR1_RollOver RES 1 countLo RES 1 countHi RES 1 TMR1H_Sampled RES 1 TMR1H_Last RES 1 SecondsLo RES 1 SecondsHi RES 1 SecondsLo3 RES 1 SecondsHi3 RES 1 SecondsLo5 RES 1 SecondsHi5 RES 1 GLOBAL countLo, countHi GLOBAL SecondsLo, SecondsHi GLOBAL SecondsLo3, SecondsHi3 GLOBAL SecondsLo5, SecondsHi5 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: ;;================== ;; TMR1 Interrupt ;;================== ; banksel TMR0_RollOver BTFSC INTCON,T0IF ;If the roll over flag is not set BTFSS INTCON,T0IE ;or the interrupt is not enabled bra checkTMR0IntEnd ; ;; TMR0 has rolled over. Clear the pending interrupt and notify ;; the foreground code by incrementing the "roll over" counter ;; Notice that the increment operation is atomic - this means ;; we won't have to worry about the foreground code and interrupt ;; code clashing over accesses to this variable. BCF INTCON,T0IF,0 ; Clear the pending interrupt INCF TMR0_RollOver,F ; Set a flag to indicate rollover checkTMR0IntEnd: ;;================== ;; TMR1 Interrupt ;;================== BTFSC PIR1,TMR1IF BTFSS PIE1,TMR1IE BRA checkTMR1IntEnd BCF PIR1,TMR1IF ;Clear the interrupt INCF TMR1_RollOver,F ;Set a flag BSF TMR1H, 7 ; Preload for 1 sec overflow ; Note, since we have a 32768 Hz crystal tied to TMR1 and we have the timer ; configured as a 16-bit timer TMR1H loaded with 0x80, then this interrupt ; will happen once every second. INFSNZ SecondsLo,F ;Update the system time. INCF SecondsHi,F CLRF TMR1H_Sampled CLRF TMR1H_Last checkTMR1IntEnd: ;;================== ;; TMR3 Interrupt ;;================== BTFSC PIR2,TMR3IF BTFSS PIE2,TMR3IE BRA checkTMR3IntEnd BCF PIR2,TMR3IF ;Clear the interrupt INCF TMR1_RollOver,F ;Set a flag BANKSEL TMR3H BSF TMR3H, 7 ; Preload for 1 sec overflow INFSNZ SecondsLo3,F ;Update the system time. INCF SecondsHi3,F CLRF TMR1H_Sampled CLRF TMR1H_Last checkTMR3IntEnd: ;;================== ;; TMR5 Interrupt ;;================== BTFSC PIR5,TMR5IF BTFSS PIE5,TMR5IE BRA checkTMR5IntEnd BCF PIR5,TMR5IF ;Clear the interrupt INCF TMR1_RollOver,F ;Set a flag BANKSEL TMR5H BSF TMR5H, 7 ; Preload for 1 sec overflow INFSNZ SecondsLo5,F ;Update the system time. INCF SecondsHi5,F CLRF TMR1H_Sampled CLRF TMR1H_Last checkTMR5IntEnd: ExitInterrupt: RETFIE 1 MAIN CODE Start: ;------------------------------------------------------------------------ ; ; Embedded simulation scripts ; ; Set the clock frequency to 10MHz .sim "frequency 10e6" ; define a stimulus to generate a 32kHz clock. This will be tied ; to TMR1's input and is used to simulate an external drive. ; ; 40MHz ; Instruction Rate = (4 clks/instruction) / (10e6 clks/second) ; = 400nS per instruction ; 32.768kHz ==> 30.517uS period ; Instruction Cycles/32.768kHz cycle = 30.517uS / .4uS ; = 76.2925 instructions ; .sim "stimulus asynchronous_stimulus " .sim "initial_state 0" .sim "start_cycle 0x2008130" .sim "period 305" .sim "{ 38,1 , 76,0 , 114,1 , 152,0 , 190,1 , 228,0 , 266,1}" .sim "name Clk32kHz" .sim "end" ; Create a node .sim "node clk_node" ; attach the clock .sim "attach clk_node Clk32kHz portc0" banksel CCPTMRS0 BSF CCPTMRS0,C3TSEL1 clrf BAUDCON2 ; At reset, all bits of t1Con should be clear. .assert "t1con == 0x00" MOVLW (1< ; processor specific variable definitions include ; Grab some useful macros radix dec ; Numbers are assumed to be decimal ;---------------------------------------------------------------------- ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 TMR0_RollOver RES 1 TMR1_RollOver RES 1 countLo RES 1 countHi RES 1 TMR1H_Sampled RES 1 TMR1H_Last RES 1 SecondsLo RES 1 SecondsHi RES 1 GLOBAL countLo, countHi GLOBAL SecondsLo, SecondsHi ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: ;;================== ;; TMR1 Interrupt ;;================== BTFSC INTCON,T0IF ;If the roll over flag is not set BTFSS INTCON,T0IE ;or the interrupt is not enabled bra checkTMR0IntEnd ; ;; TMR0 has rolled over. Clear the pending interrupt and notify ;; the foreground code by incrementing the "roll over" counter ;; Notice that the increment operation is atomic - this means ;; we won't have to worry about the foreground code and interrupt ;; code clashing over accesses to this variable. BCF INTCON,T0IF,0 ; Clear the pending interrupt INCF TMR0_RollOver,F ; Set a flag to indicate rollover checkTMR0IntEnd: ;;================== ;; TMR1 Interrupt ;;================== BTFSC PIR1,TMR1IF BTFSS PIE1,TMR1IE BRA checkTMR1IntEnd BCF PIR1,TMR1IF ;Clear the interrupt INCF TMR1_RollOver,F ;Set a flag BSF TMR1H, 7 ; Preload for 1 sec overflow ; Note, since we have a 32768 Hz crystal tied to TMR1 and we have the timer ; configured as a 16-bit timer TMR1H loaded with 0x80, then this interrupt ; will happen once every second. INFSNZ SecondsLo,F ;Update the system time. INCF SecondsHi,F CLRF TMR1H_Sampled CLRF TMR1H_Last checkTMR1IntEnd: ExitInterrupt: RETFIE 1 MAIN CODE Start: ;------------------------------------------------------------------------ ; ; Embedded simulation scripts ; ; Set the clock frequency to 10MHz .sim "frequency 10e6" ; define a stimulus to generate a 32kHz clock. This will be tied ; to TMR1's input and is used to simulate an external drive. ; ; 40MHz ; Instruction Rate = (4 clks/instruction) / (10e6 clks/second) ; = 400nS per instruction ; 32.768kHz ==> 30.517uS period ; Instruction Cycles/32.768kHz cycle = 30.517uS / .4uS ; = 76.2925 instructions ; .sim "stimulus asynchronous_stimulus " .sim "initial_state 0" .sim "start_cycle 0x2008130" .sim "period 305" .sim "{ 38,1 , 76,0 , 114,1 , 152,0 , 190,1 , 228,0 , 266,1}" .sim "name Clk32kHz" .sim "end" ; Create a node .sim "node clk_node" ; attach the clock .sim "attach clk_node Clk32kHz portc0" ; At reset, all bits of t1Con should be clear. .assert "t1con == 0x00" MOVLW (1<&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = regression ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README TODO DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ README \ rt.sh run_regression.sh make.regression startup.stc \ */*.lkr */*.asm */*.stc */*.inc */Makefile analog_stim/*.sig MOSTLYCLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ CLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ DISTCLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ MAINTAINERCLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu regression/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu regression/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/regression/Makefile.am0000664000076400007640000000065013041763602014063 00000000000000 EXTRA_DIST = \ README \ rt.sh run_regression.sh make.regression startup.stc \ */*.lkr */*.asm */*.stc */*.inc */Makefile analog_stim/*.sig MOSTLYCLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ CLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ DISTCLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ MAINTAINERCLEANFILES = */*.o */*.hex */*.cod */*.lst */*.log */*.map */*~ gpsim-0.30.0/regression/macro_test/0000775000076400007640000000000013117466027014253 500000000000000gpsim-0.30.0/regression/macro_test/16f84.lkr0000664000076400007640000000160413041763600015447 00000000000000// Sample linker command file for 16F84 // $Id: 16f84.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x3FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0xB PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x8B PROTECTED DATABANK NAME=gprs START=0xC END=0x4F SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/macro_test/Makefile0000664000076400007640000000050713041763600015626 00000000000000include ../make.regression SCRIPT = 16f84.lkr PROJECT = macro_test OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/macro_test/macro_test.stc0000664000076400007640000000121713041763600017040 00000000000000load macro_test.cod # Macro test # echo gpsim macro test #set verbose 0xfe mac_exp macro add, mask mac_flags = (mac_flags+add) & mask endm mac1 macro p1, p2 run mac_exp p1, p2 endm break e mac_loop # this should have no effect on 'mac_flags', but # the loop of code in macro_test.asm should increment # the variable 'mac_count' mac1 1, 0b00000010 # mac_flags=0, mac_count=0 mac1 1, 0x1f # mac_flags=1, mac_count=1 mac1 2, 0x1f # mac_flags=3, mac_count=2 mac1 3, 0x1f # mac_flags=6, mac_count=3 mac1 4, 0x1f # mac_flags=10, mac_count=4 mac1 6, 0x1f # mac_flags=16, mac_count=5 failures = mac_flags + mac_count - 21 gpsim-0.30.0/regression/macro_test/macro_test.asm0000664000076400007640000000275313041763600017035 00000000000000 radix dec ;; The purpose of this program is to test gpsim macros ;; list p=16f84 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros GPR_DATA UDATA failures RES 1 mac_count RES 1 mac_flags RES 1 GLOBAL mac_count, mac_flags, failures GLOBAL mac_loop ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf failures clrf mac_count ; a counter clrf mac_flags mac_loop: incf mac_count,F btfss mac_flags,4 goto mac_loop movf failures,W skpz failed: .assert "\"*** FAILED Macro test\"" goto $ done: .assert "\"*** PASSED Macro test\"" goto done end gpsim-0.30.0/regression/missing/0000775000076400007640000000000013117466027013564 500000000000000gpsim-0.30.0/regression/missing/Makefile0000644000076400007640000000053212335763504015143 00000000000000 #EXTENDED_INSTRUCTIONS=1 include ../make.regression SCRIPT = 18f2455.lkr PROJECT = instructions OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : miss.cod miss.cod: miss.o 12f508_g.lkr gplink --map -s 12f508_g.lkr -o miss.cod miss.o miss.o: miss.asm miss.h miss.h: cp sub.h miss.h sim: gpsim-0.30.0/regression/TODO0000664000076400007640000000021613041763600012513 00000000000000TODO Items that need regression tests: 1) Sleep modes 2) Reset modes 3) Program memory writes 4) Socket interface (is anyone using this?) gpsim-0.30.0/regression/neil/0000775000076400007640000000000013117466027013042 500000000000000gpsim-0.30.0/regression/neil/Makefile0000664000076400007640000000026312327446765014434 00000000000000include ../make.regression all : q.cod debouncer.cod q.cod : q.o gplink --map -s 16f690_g.lkr -o $@ $^ debouncer.cod : debouncer.o gplink --map -s 16f690_g.lkr -o $@ $^ gpsim-0.30.0/regression/register_stim/0000775000076400007640000000000013117466027014773 500000000000000gpsim-0.30.0/regression/register_stim/16f84.lkr0000664000076400007640000000160413041763577016204 00000000000000// Sample linker command file for 16F84 // $Id: 16f84.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x3FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0xB PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x8B PROTECTED DATABANK NAME=gprs START=0xC END=0x4F SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/register_stim/Makefile0000664000076400007640000000055113041763577016362 00000000000000include ../make.regression SCRIPT = 16f84.lkr PROJECT = register_stim OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) $(PROJECT).o : $(PROJECT).asm sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/register_stim/register_stim.asm0000664000076400007640000000535313116716523020301 00000000000000 radix dec ;; The purpose of this program is to test gpsim's register stimuli. ;; list p=16f84 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA failures RES 1 shift_in RES 1 ; A shifting bit pattern stimulus is connected to this. flag_reg RES 1 ; Another register stimulus is tied to this. temp1 RES 1 GLOBAL shift_in GLOBAL flag_reg ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf shift_in clrf flag_reg clrf temp1 start_loop: ; First, wait for shift_in to become '1' decfsz shift_in,W goto start_loop movf flag_reg,W movwf temp1 ; The register stimulus will shift the register 'shift_in' 1 bit position left every ; 100 cycles. The final value will stick at 0x80. Meanwhile, the flag_reg will ; will become 0xff after about 1000 cycles. shift_loop movf shift_in,W ; Compare shift_in to it's last known value. xorwf temp1,W skpnz ; If it has changed, then update it and check it. goto L1 xorwf temp1,F ; temp1 = temp1^(shift_in^temp1) = shift_in decf temp1,W ; temp1 should be 2^n andwf temp1,W skpz goto failed ; failed L1: incfsz flag_reg,W ; does flag == 0xff? goto shift_loop ; loop is finished. temp1 should be 0x80. movlw 0x80 xorwf temp1,W skpz goto failed done: .assert "\"*** PASSED Register Stimulation test\"" goto done failed: .assert "\"*** FAILED Register Stimulation test\"" goto failed end gpsim-0.30.0/regression/register_stim/register_stim.stc0000664000076400007640000000217213041763577020316 00000000000000 load register_stim.cod # Attribute Stimulus Test # # Two stimuli are created. One generates a shifting # bit pattern. This is tied to pic register named # shift_in. The other stimulus is a flag that the # firmware will monitor. # echo Attribute Stimulus test ############################################################ # define a stimulus to generate shifting bit pattern. stimulus attribute_stimulus # The initial state AND the state the stimulus is when # it rolls over initial_state 0 # Start cycle (with respect to the CPU's cycle counter). start_cycle 0 # the stimulus will roll over in 'period' cycles. period 1000 # Data: # { 100, 0x01, 200, 0x02, 300, 0x04, 400, 0x08, 500, 0x10, 600, 0x20, 700, 0x40, 800, 0x80 } # Give the stimulus a name: name bit_shifter end ############################################################ # define a stimulus that generates a step function # stimulus attribute_stimulus initial_state 0 start_cycle 0 period 1000 { 900, 0xff } # Give the stimulus a name: name flag_stim end # attach the stimuli to registers attach bit_shifter .shift_in attach flag_stim .flag_reg gpsim-0.30.0/regression/p16f819/0000775000076400007640000000000013117466027013131 500000000000000gpsim-0.30.0/regression/p16f819/Makefile0000644000076400007640000000024210644626500014501 00000000000000include ../make.regression SCRIPT = 16f819.lkr all : a2d_819.cod ccp_819.cod %.cod : %.o gplink --map -s $(SCRIPT) -o $@ $< sim: sim_a2d_819 sim_ccp_819 gpsim-0.30.0/regression/p16f676/0000775000076400007640000000000013117466027013132 500000000000000gpsim-0.30.0/regression/p16f676/reset.asm0000664000076400007640000002024713041763600014674 00000000000000 ; 16f676 gpsim regression test ; ; The purpose of this test is to verify that the 16f676 ; is implemented correctly. Here's a list of specific things ; tested: ; ; 1) Power On Reset ; 2) WDT during sleep ; 3) WDT during execution ; 4) Interrupt on PIN change during sleep ; 5) MCLR during sleep ; 6) MCLR during execution list p=16f676 include include __CONFIG _WDT_ON & _MCLRE_ON radix dec ; Printf Command .command macro x .direct "C", x endm GPR_DATA UDATA_SHR ResetSequence RES 1 optionShadow RES 1 aint_cnt RES 1 w_temp RES 1 status_temp RES 1 GLOBAL optionShadow, ResetSequence, aint_cnt ; Define the reset conditions to be checked. eRSTSequence_PowerOnReset equ 1 eRSTSequence_AwakeMCLR equ 2 eRSTSequence_AwakeWDT equ 3 eRSTSequence_AwakeIO equ 4 eRSTSequence_WDTTimeOut equ 5 ;---------------------------------------------------------------------- ; ********************* Reset Vector LOCATION *************************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program NT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc INTCON,RAIF goto raif_int .assert "\"***FAILED p16f676 unexpected interrupt\"" nop exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ; Interrupt from porta state change raif_int incf aint_cnt,F bcf INTCON,RAIF .assert "(intcon & 1) == 1, \"***FAILED p16f676 RAIF not cleared with match condition\"" nop movf PORTA,W ; reading ports should clear match condition bcf INTCON,RAIF .assert "(intcon & 1) == 0, \"***FAILED p16f676 RAIF is clear\"" nop goto exit_int ;############################################################ ;# Create a stimulus to simulate a switch ; .sim "module lib libgpsim_modules" .sim "p16f676.xpos = 72" .sim "p16f676.ypos = 72" .sim "module load pulsegen PG1" .sim "PG1.clear = 0" .sim "PG1.period = 0" .sim "PG1.set = 1" .sim "PG1.xpos = 228" .sim "PG1.ypos = 84" .sim "module load pulsegen MCLRE" .sim "MCLRE.clear = 0" .sim "MCLRE.period = 0" .sim "MCLRE.set = 1" .sim "MCLRE.xpos = 84" .sim "MCLRE.ypos = 204" .sim "MCLRE.initial = 5.0" ;############################################################ .sim "node nSwitch" .sim "attach nSwitch porta0 PG1.pin" .sim "node nMCLR" .sim "attach nMCLR MCLR MCLRE.pin" ;############################################################ .sim "symbol resetCounter=1" ; NOT_GPWU = 0 - Enable wakeup if I/O pins 0,1, or 3 change states ; NOT_GPPU = 1 - Disable weak pullups on I/O pins 0,1, and 3 ; TOCS = 0 - Let the clock source for TMR0 be the internal fosc/4 ; TOSE = 0 - don't care - TMR0 source edge. ; PSA = 1 - assign Prescale to the WDT ; PS2:0 = 000 - prescale = 2^0=1 .sim "optionShadow=8" ; PSA=1 .sim "ResetSequence=0" .sim ".BreakOnReset = false" ; Set a cycle break point far in the future in case the resets fail. .sim "break c 0x1000000" bSWITCH equ 0 start .assert "option_reg==0xff, \"***FAILED p16f676 reset, option 0xff\"" .assert "(trisa&0x3f)==0x3f, \"***FAILED p16f676 reset, trisa 0x3f\"" ;RRR MOVWF OSCCAL ; put calibration into oscillator cal reg ; PORTA setup ; If this is a PowerOn reset, then the state of the PORTA output register ; is unknown. If this is not a PowerOn reset then the PORTA pins have ; the same state they had prior to the reset. ; ; TRIS register setup - The I/O pins are always configured as Inputs after ; any reset. MOVF optionShadow,W ;optionShadow is initialized by the gpsim script BANKSEL TRISA MOVWF OPTION_REG MOVLW 1< /MCLR while sleeping goto PowerOnReset ;/TO=1, /PD=1 ==> Power has just been applied TO_is_low BTFSS STATUS,NOT_PD goto AwakeWDT ;/TO=0, /PD=0 ==> WDT while sleeping goto WDTTimeOut ;/TO=0, /PD=1 ==> WDT while not sleeping ;======================================================================== ; ; PowerOnReset ; ;======================================================================== PowerOnReset: movf ResetSequence,W XORLW eRSTSequence_AwakeMCLR skpnz goto done .assert "resetCounter==1,\"*** FAILED Power On Reset\"" nop MOVLW eRSTSequence_PowerOnReset MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop SLEEP nop ;======================================================================== ; ; AwakeWDT - WDT timed out while we were sleeping. ; ;======================================================================== AwakeWDT: MOVLW eRSTSequence_AwakeWDT .assert "resetCounter==2,\"*** FAILED WDT Reset\"" nop MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT ; loop until WDT times out here: goto here ;======================================================================== ; ; WDTTimeOut - WatchDog timer timed out while we were awake. ; ;======================================================================== WDTTimeOut: .assert "resetCounter==3,\"*** FAILED WDT timeout\"" nop MOVLW eRSTSequence_WDTTimeOut MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT .command "PG1.clear = cycles+100" nop CLRF aint_cnt CLRF CMCON ; porta0, porta1 analog SLEEP nop ;======================================================================== ; ; AwakeIO - an I/O pin changed state when in analog mode ; This should not wakeup from sleep (continue with WDT wakeup) ; ;======================================================================== .assert "aint_cnt==0, \"*** FAILED Wakeup on analog pin change\"" nop MOVLW 7 MOVWF CMCON ; porta0, porta1 in digital mode CLRF aint_cnt ; we may get an interrupt on this change .command "PG1.set = cycles+100" nop SLEEP nop ;======================================================================== ; ; AwakeIO - an I/O pin changed states to awaken us from sleep. ; ;======================================================================== AwakeIO: .assert "aint_cnt==1, \"*** FAILED No Wakeup on I/O pin change\"" nop MOVLW eRSTSequence_AwakeIO .assert "resetCounter==4,\"*** FAILED Unexpected Wakeup on I/O pin change\"" nop MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT ; reset the processor by driving /MCLR low for a few cycles .command "MCLRE.clear = cycles+100" .command "MCLRE.set = cycles+110" nop SLEEP nop .assert "\"*** FAILED Unexpected Wakeup waiting for MCLR\"" nop ;======================================================================== ; ; AwakeMCLR - MCLR went low while we were sleeping. ; ;======================================================================== AwakeMCLR: MOVLW eRSTSequence_AwakeMCLR .assert "resetCounter==5,\"*** FAILED /MCLR Reset\"" nop MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT ; reset the processor by driving /MCLR low for a few cycles .command "MCLRE.clear = cycles+100" .command "MCLRE.set = cycles+110" nop waitForMCLR: goto waitForMCLR .assert "\"*** PASSED 16f676 Sleep and Reset test\"" done: goto done end gpsim-0.30.0/regression/p16f676/16f676.lkr0000664000076400007640000000227013041763600014415 00000000000000// Sample linker command file for 16F676 LIBPATH . CODEPAGE NAME=page START=0x0 END=0x3FE CODEPAGE NAME=oscval START=0x3FF END=0x3FF PROTECTED CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=icd_inst START=0x2004 END=0x2004 PROTECTED CODEPAGE NAME=mfg_code START=0x2005 END=0x2005 PROTECTED CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x217F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED SHAREBANK NAME=gpr0 START=0x20 END=0x5F SHAREBANK NAME=gpr0 START=0xA0 END=0xDF PROTECTED SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=OSCVAL ROM=oscval // Oscillator value SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=ICD_INST ROM=icd_inst // ICD instruction SECTION NAME=MFG_CODE ROM=mfg_code // Manufacturing code SECTION NAME=DEVICEID ROM=.device_id // Device ID SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/p16f676/p16f676.asm0000664000076400007640000003214013041763600014564 00000000000000 ;; Node test ;; ;; The purpose of this program is to verify that nodes ;; can interconnect I/O pins. list p=16f676 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CP_OFF & _WDT_ON & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _BODEN_OFF & _MCLRE_OFF ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 adc_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup R1" .sim "R1.resistance = 10000.0" .sim "R1.voltage = 2.0" .sim "R1.xpos = 252" .sim "R1.ypos = 84" ; Use a pullup resistor as a voltage reference .sim "module load pullup R2" .sim "R2.resistance = 10000.0" .sim "R2.voltage = 4.0" .sim "R2.xpos = 252" .sim "R2.ypos = 120" .sim "node n1" .sim "attach n1 porta2 porta3" ; .sim "attach n1 porta2 MCLR" .sim "node n2" .sim "attach n2 porta0 porta5 R1.pin" .sim "node n3" .sim "attach n3 porta1 porta4 R2.pin" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR1,CMIF goto cmif_int btfsc PIR1,TMR1IF goto tmr1_int btfsc PIR1,EEIF goto ee_int btfsc PIR1,ADIF goto adc_int btfsc INTCON,T0IF goto tmr0_int .assert "\"***FAILED p16f676 unexpected interrupt\"" nop ; Interrupt from Comparator cmif_int incf cmif_cnt,F bcf PIR1,CMIF goto exit_int ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from TMR1 tmr1_int incf tmr1_cnt,F bcf PIR1,TMR1IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ; Interrupt from adc adc_int incf adc_cnt,F bcf PIR1,ADIF goto exit_int exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; ; test pins in analog mode return 0 on register read BANKSEL TRISA clrf TRISA bcf OPTION_REG,NOT_RAPU ; enable pullups on portA BANKSEL PORTA movlw 0xff movwf PORTA .assert "(porta & 0x17) == 0, \"**FAILED 16f676 analog bits read 0\"" nop clrf PORTA movwf PORTA movf PORTA,W BANKSEL ANSEL clrf ANSEL ; turn off ADC port selects BANKSEL PORTA movlw 0xff movwf CMCON ; turn off Comparator .assert "cmcon == 0x1f, \"**FAILED 16f676 CMCON read 0 bits\"" nop ; ; test PORTA works as expected ; clrf PORTA bsf STATUS,RP0 movlw 0x38 movwf TRISA ;PORTA 0,1,2 output 3,4,5 input bcf STATUS,RP0 .assert "porta == 0x00, \"PORTA = 0x00\"" nop movlw 0x07 movwf PORTA ; drive 0,1,2 bits high .assert "porta == 0x3f, \"PORTA = 0x3f\"" nop bsf STATUS,RP0 movlw 0x07 movwf TRISA ; PORTA 4, 5 output 0,1,2,3 input (3 input only) bcf STATUS,RP0 .assert "porta == 0x0c, \"PORTA = 0x0c\"" nop movlw 0x38 movwf PORTA ; drive output bits high .assert "porta == 0x3f, \"PORTA = 0x3f\"" nop call test_compare call test_tmr1 call test_eerom call test_adc .assert "\"*** PASSED 16f676 Functionality\"" goto $ test_compare: ;; Comparator Tests ;; ;; Mode 1 (Comparator with Output) ;; CIN- > CIN+ COUT = 0 and porta2 low unless CINV=1 ;; CIS has no effect on output ;; CIN- < CIN+ gives output ;; Mode 3 (Comparator with output and Vref) ;; CIN- high COUT = 0 ;; CІN- low COUT = 1 ;; CIS has no effect on COUT ;; Mode 5 (Mux input with output and Vref) ;; CIN- low, CIS = 0 COUT = 1 ;; CIN+ high (CIN- low) with CIS = 0 has no effect on COUT ;; CIN+ high, CIN- low, CIS 1 COUT = 0 ;; CIN+ low (CIN- high) CIS 1 COUT = 1 ;; CIN+ high (CIN- high) CIS 1 COUT = 0 ;; enable and catch interrupt when CINV set ; ; Test mode 1 Comparator with output ; bsf STATUS,RP0 movlw 0x03 movwf TRISA ; PORTA 2, 4, 5 output 0,1,3 input (3 input only) bcf STATUS,RP0 movlw 0x20 movwf PORTA ; AN0 1 AN1 0 movlw 0x01 movwf CMCON .assert "cmcon == 1, \"*** FAILED 16f676 cmcon Comp mode 1 Cinv 0 v+ > v-\"" nop .assert "(porta & 0x04) == 0, \"*** FAILED 16f676 porta2 Comp mode 1 Cinv 0 v+ > v-\"" nop bsf CMCON,CINV ; Cinv = 1 .assert "cmcon == 0x51, \"*** FAILED 16f676 cmcon Comp mode 1 Cinv 1 v+ > v-\"" nop bsf CMCON,CIS ; CIS = 1 .assert "cmcon == 0x59, \"*** FAILED 16f676 cmcon Comp mode 1 Cinv 1 CIS 1 v+ > v-\"" nop .assert "(porta & 0x04) == 0x04, \"*** FAILED 16f676 porta2 Comp mode 1 Cinv 1 v+ > v-\"" nop movlw 0x01 movwf CMCON ; clear CINV and CIS movlw 0x10 movwf PORTA ; AN0 0 AN1 1 .assert "cmcon == 0x41, \"*** FAILED 16f676 Comp mode1 v+ < v-\"" nop .assert "(porta & 0x04) == 0x04, \"*** FAILED 16f676 porta2 Comp mode 1 Cinv 1 v+ < v-\"" nop bsf CMCON,CINV .assert "cmcon == 0x11, \"*** FAILED 16f676 cmcon Comp mode 1 Cinv 1 v+ < v-\"" nop .assert "(porta & 0x04) == 0, \"*** FAILED 16f676 porta2 Comp mode 1 Cinv 1 v+ < v-\"" nop nop ; ; Mode 3 internal reference with output ; BANKSEL VRCON bsf VRCON,VREN ; Voltage reference high range BANKSEL CMCON movlw 0x03 movwf CMCON .assert "cmcon == 0x03, \"*** FAILED 16f676 cmcon Comp mode 3 Cinv 0 AN1 5V\"" nop bcf PORTA,4 ; drive AN1 to low .assert "cmcon == 0x43, \"*** FAILED 16f676 cmcon Comp mode 3 Cinv 0 AN1 0V\"" nop bsf CMCON,CIS ; CIS should not change output .assert "cmcon == 0x4b, \"*** FAILED 16f676 cmcon Comp mode 3 Cinv 0 Cis 1 AN1 0V\"" nop ; ; test mode 5 - MUX input with Vref and Output ; movlw 0x05 movwf CMCON ; mode 5 and AN1 .assert "cmcon == 0x45, \"*** FAILED 16f676 cmcon Comp mode 5 CIS 0 AN0 0V AN1 0V\"" nop bsf PORTA,5 ; Drive AN0 high (AN1 low) .assert "cmcon == 0x45, \"*** FAILED 16f676 cmcon Comp mode 5 CIS 0 AN0 5V AN1 0V\"" nop bsf CMCON,CIS ; select AN0 (PORTA0) .assert "cmcon == 0x0d, \"*** FAILED 16f676 cmcon Comp mode 5 CIS 1 AN0 5V AN1 0V\"" nop movlw 0x10 ; Drive AN0 low AN1 High movwf PORTA .assert "cmcon == 0x4d, \"*** FAILED 16f676 cmcon Comp mode 5 CIS 1 AN0 0V AN1 5V\"" nop bsf PORTA,5 ; Drive AN0 high (AN1 high) .assert "cmcon == 0x0d, \"*** FAILED 16f676 cmcon Comp mode 5 CIS 1 AN0 5V AN1 5V\"" nop ; ; test comparator interupts ; bcf PIR1,CMIF BANKSEL PIE1 movlw (1 << GIE) | ( 1 << PEIE ) movwf INTCON bsf PIE1,CMIE BANKSEL CMCON bsf CMCON,CINV ; this should change output and cause interrupt cm_loop: movf cmif_cnt,W btfsc STATUS,Z goto cm_loop nop ;RRR clrf INTCON movlw 0x07 ; turn off comparator movwf CMCON return test_tmr1: ;; Here are the tests performed: ;; ;; -- TMR1L and TMR1H can be read and written ;; -- TMR1 driven Fosc/4 with prescale of 8 and generates an interrupt ; Load TMR1H, TMR1L with 0x8000 CLRF TMR1L MOVLW 0x80 MOVWF TMR1H BCF PIR1,TMR1IF ;Clear any TMR1 pending interrupt BANKSEL PIE1 BSF PIE1,TMR1IE ;Enable TMR1 interrupts BANKSEL TMR1L BSF INTCON,PEIE ;Enable Peripheral interrupts BSF INTCON,GIE ;Enable Global interrupts ; TMR1 not running yet, TMR1H and TMR1L should be unchanged MOVF TMR1L,W ; test read .assert "W==0, \"*** FAILED 16f676 TMR1 test TMR1L read\"" nop MOVF TMR1H,W .assert "W==0x80, \"*** FAILED 16f676 TMR1 test TMR1H read\"" nop ; at 4Mhz prescale of 8 Fosc/4 should interrupt in 0.1 seconds movlw 0xcf movwf TMR1H movlw 0x2c movwf TMR1L MOVLW (1< __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _PWRTE_ON & _BODEN_ON & _WDT_OFF & _HS_OSC errorlevel -302 variables UDATA 0x30 temp1 RES 1 temp2 RES 1 STARTUP CODE NOP goto start NOP NOP NOP PROG1 CODE ; start .sim "break c 0x100000" .sim "module lib libgpsim_modules" .sim "module load e24xx024 ee" .sim "module load pu pu1" .sim "module load pu pu2" .sim "node n1" .sim "attach n1 portc4 pu1.pin portb4 ee.SDA" ; SDA .sim "node n2" .sim "attach n2 portc3 pu2.pin portb1 ee.SCL" ; SCL .sim "node n3" .sim "attach n3 porta0 ee.WP" .sim "node n4" .sim "attach n4 porta1 ee.A0" .sim "node n5" .sim "attach n5 porta2 ee.A1" .sim "node n6" .sim "attach n6 porta3 ee.A2" .sim "scope.ch0 = \"portc3\"" .sim "scope.ch1 = \"portc4\"" .sim "pu1.xpos = 240." .sim "pu1.ypos = 336." .sim "pu2.xpos = 216." .sim "pu2.ypos = 24." .sim "ee.xpos = 48." .sim "ee.ypos = 180." .sim "p16f876a.xpos = 240." .sim "p16f876a.ypos = 84." call ProgInit ; Get everything running step-by-step call I2CSendResult call write_eeprom call is_ready call read_eeprom .command "dump e ee dump.hex" nop call is_ready call clr_eeprom .command "load e ee dump.hex" nop call is_ready call read_eeprom .assert "\"*** PASSED p16f876a I2C test\"" goto $ ;****************************** SUBROUTINES **************************** ;************************************************************************ START_I2C MACRO banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 banksel PORTA ENDM RSTART_I2C MACRO banksel SSPCON2 ; Generate I2C repeat start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 banksel PORTA ENDM STOP_I2C MACRO banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PORTA ENDM IDLE_WAIT_I2C MACRO banksel SSPCON2 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_W goto $-1 banksel PORTA ENDM ;****************** Initialize Registers and Variables ***************** ;************************************************************************ ProgInit banksel PORTA clrf PORTA ; Set all bits to zero on Port A banksel TRISA clrf TRISA banksel SSPADD movlw 0x0C ; Set I2C baud rate to 385 kHz movwf SSPADD banksel SSPCON movlw 0x08 ; Set for I2C master mode movwf SSPCON movlw 0x28 ; Enable I2C movwf SSPCON return ;************************************************************************ I2CSendResult banksel SSPCON2 ; Generate I2C start, bus collision bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 bsf SSPCON2,SEN bcf TRISB,1 IDLE_WAIT_I2C .assert "(pir2 & 0x08) == 0x08, \"FAILED BCLIF for start\"" nop banksel TRISB bsf TRISB,1 banksel PIR2 bcf PIR2,BCLIF banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN IDLE_WAIT_I2C .assert "(portc & 0x18) == 0, \"FAILED Start SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Start SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Start BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED Start S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x18) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,ACKDT bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 .assert "(portc & 0x18) == 0x10, \"FAILED ACKEN SCL low, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED ACKEN SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED ACKEN BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED ACKEN S bit set\"" nop bcf SSPCON2,ACKDT bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x18) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 .assert "(portc & 0x18) == 0x18, \"FAILED Stop SCL, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Stop SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Stop BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x10, \"FAILED Stop P bit set\"" nop return ; ; repeatedly send command to eeprom until an ACK ; is received back ; ; The call of delay is not required for operation of the code, ; but it speeds up the simulation with the GUI running. -- RRR ; is_ready banksel SSPCON movlw 0x04 movwf temp2 clrf temp1 call delay banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xa0 ; write command to eeprom call I2C_send_w call I2C_stop banksel SSPCON2 ; Generate I2C start btfsc SSPCON2,ACKSTAT goto is_ready banksel PIR2 bcf PIR2,BCLIF return write_eeprom_address banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xa0 ; write command to eeprom call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write command to eeprom ACK\"" nop .assert "(sspstat & 0x01) == 0x00, \"FAILED write to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write eeprom address call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write address to eeprom ACK\"" nop return write_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSPIF movlw 0x80 ; write data1 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x81 ; write data2 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return clr_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write data1 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write data2 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return read_eeprom call write_eeprom_address banksel SSPCON2 ; Generate I2C repeated start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 movlw 0xa1 ; Send address/read to eeprom banksel SSPBUF movwf SSPBUF banksel SSPCON2 ; wait for idle (ACKEN,RCEN,PEN,RSEN,SEN) == 0 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_W ; also R_W == 0 goto $-1 .assert "(sspstat & 0x01) == 0x00, \"FAILED address/read to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read data from eeprom btfsc SSPCON2,RCEN goto $-1 .assert "(pir1 & 0x08) == 0x08, \"FAILED RCEN SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RCEN BCLIF clear\"" nop .assert "(sspstat & 0x01) == 0x01, \"FAILED RCEN BF set\"" nop banksel SSPBUF movf SSPBUF,W .assert "W == 0x80, \"FAILED RCEN, read Data\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read next byte btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W .assert "W == 0x81, \"FAILED RCEN, read Data2\"" nop banksel SSPCON2 bsf SSPCON2,ACKDT ; send NACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 return I2C_stop banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 return delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return ;********************** Output byte in W via I2C bus ******************** ;************************************************************************ I2C_send_w banksel SSPBUF ; Second byte of data (middle) movwf SSPBUF banksel SSPSTAT btfsc SSPSTAT,R_W goto $-1 return end gpsim-0.30.0/regression/i2c/p16f88.asm0000664000076400007640000004207513116700214014142 00000000000000 list p=16f88 include include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_IO & _PWRTE_ON & _LVP_OFF & _BODEN_OFF & _MCLR_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16F88. ;; Specifically, I2C errorlevel -302 ; Printf Command .command macro x .direct "C", x endm _ClkIn equ 8000000 ; Input Clock Frequency _ClkOut equ (_ClkIn >> 2) ; ; Compute the delay constants for setup & hold times ; _40uS_Delay set (_ClkOut/250000) _47uS_Delay set (_ClkOut/212766) _50uS_Delay set (_ClkOut/200000) TRUE equ 1 FALSE equ 0 LSB equ 0 MSB equ 7 #define SCL_PIN 2 #define SDA_PIN 3 #define I2CPORT PORTB #define _SCL_D I2CPORT,SCL_PIN #define _SCL TRISB,SCL_PIN #define _SDA TRISB,SDA_PIN #define T0IE TMR0IE #define T0IF TMR0IF #define _ENABLE_BUS_FREE_TIME TRUE #define _CLOCK_STRETCH_CHECK TRUE #define _OPTION_INIT (0xC0 | 0x02) ; Prescaler to TMR0 for Appox 1 mSec timeout ;***************************************************************************** ; I2C Bus Status Reg Bit Definitions ;***************************************************************************** #define _Bus_Busy Bus_Status,0 #define _Abort Bus_Status,1 #define _Txmt_Progress Bus_Status,2 #define _Rcv_Progress Bus_Status,3 #define _Txmt_Success Bus_Status,4 #define _Rcv_Success Bus_Status,5 #define _Fatal_Error Bus_Status,6 #define _ACK_Error Bus_Status,7 ;***************************************************************************** ; I2C Bus Contro Register ;***************************************************************************** #define _10BitAddr Bus_Control,0 #define _Slave_RW Bus_Control,1 #define _Last_Byte_Rcv Bus_Control,2 #define _SlaveActive Bus_Control,6 #define _TIME_OUT_ Bus_Control,7 RELEASE_BUS MACRO bsf STATUS,RP0 ; select page 1 bsf _SDA ; tristate SDA bsf _SCL ; tristate SCL ; bcf _Bus_Busy ; Bus Not Busy, TEMP ????, set/clear on Start & Stop ENDM ;**************************************************************************** ; A MACRO To Load 8 OR 10 Bit Address To The Address Registers ; ; SLAVE_ADDRESS is a constant and is loaded into the SlaveAddress Register(s) ; depending on 8 or 10 bit addressing modes ;**************************************************************************** LOAD_ADDR_10 MACRO SLAVE_ADDRESS bsf _10BitAddr ; Slave has 10 bit address movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ; load low byte of address movlw (((SLAVE_ADDRESS >> 7) & 0x06) | 0xF0) ; 10 bit addr 11110AA0 movwf SlaveAddr+1 ; hi order address ENDM LOAD_ADDR_8 MACRO SLAVE_ADDRESS bcf _10BitAddr ; Set for 8 Bit Address Mode movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ENDM ;**************************************************************************** ; I2C_WRITE_SUB ; ; Writes a message just like I2C_WRITE, except that the data is preceeded ; by a sub-address to a slave device. ; Eg. : A serial EEPROM would need an address of memory location for ; Random Writes ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ (constant) ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; _Sub_Address_ Sub-address of Slave (constant) ; ; Sequence : ; S-SlvAW-A-SubA-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag ; ; Returns : WREG = 1 on success, else WREG = 0 ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ; COMMENTS : ; I2C_WR may prove to be more efficient than this macro in most situations ; Advantages will be found for Random Address Block Writes for Slaves with ; Auto Increment Sub-Addresses (like Microchip's 24CXX series Serial ; EEPROMS) ; ;**************************************************************************** I2C_WR_SUB MACRO _BYTES_, _SourcePointer_, _Sub_Address_ movlw (_BYTES_ + 1) movwf tempCount movlw (_SourcePointer_ - 1) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -1) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -1) call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W movwf (_SourcePointer_ - 1) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM I2C_WR_SUB2 MACRO _BYTES_, _SourcePointer_, _Sub_Address_, _Sub_Address2_ movlw (_BYTES_ + 2) movwf tempCount movlw (_SourcePointer_ - 2) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -2) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -2) movlw (_SourcePointer_ - 1) movwf FSR movlw _Sub_Address2_ movwf INDF movlw (_SourcePointer_ - 2) movwf FSR call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W ; movwf (_SourcePointer_ - 2) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM ;**************************************************************************** ; I2C_WRITE ; ; A basic macro for writing a block of data to a slave ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; ; Sequence : ; S-SlvAW-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ;**************************************************************************** I2C_WR MACRO _BYTES_, _SourcePointer_ movlw _BYTES_ movwf tempCount movlw _SourcePointer_ movwf FSR call _i2c_block_write call TxmtStopBit ; Issue a stop bit for slave to end transmission ENDM ;***************************************************************************** ; ; I2C_READ ; ; The basic MACRO/procedure to read a block message from a slave device ; ; Parameters : ; _BYTES_ : constant : #of bytes to receive ; _DestPointer_ : destination pointer of RAM (File Registers) ; ; Sequence : ; S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; If last byte, then Master will NOT Acknowledge (send NACK) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ;***************************************************************************** I2C_READ MACRO _BYTES_, _DestPointer_ movlw (_BYTES_ -1) movwf tempCount ; -1 because, the last byte is used out of loop movlw _DestPointer_ movwf FSR ; FIFO destination address pointer call _i2c_block_read ENDM ;*************************************************************************** ; ; I2C_READ_SUB ; This MACRO/Subroutine reads a message from a slave device preceeded by ; a write of the sub-address. ; Between the sub-addrers write & the following reads, a STOP condition ; is not issued and a "REPEATED START" condition is used so that an other ; master will not take over the bus, and also that no other master will ; overwrite the sub-address of the same salve. ; ; This function is very commonly used in accessing Random/Sequential reads ; from a memory device (e.g : 24Cxx serial of Serial EEPROMs from Microchip). ; ; Parameters : ; _BYTES_ # of bytes to read ; _DestPointer_ The destination pointer of data to be received. ; _BubAddress_ The sub-address of the slave ; ; Sequence : ; S-SlvAW-A-SubAddr-A-S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; ;*************************************************************************** I2C_READ_SUB MACRO _BYTES_, _DestPointer_, _SubAddress_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM I2C_READ_SUB2 MACRO _BYTES_, _DestPointer_, _SubAddress_, _SubAddress2_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address movlw _SubAddress2_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- INT_VAR UDATA IO_buf RES 10 IN_buf RES 10 GPR_DATA UDATA_SHR w_temp RES 1 status_temp RES 1 SlaveAddr RES 1 ; Slave Addr must be loader into this reg SlaveAddrHi RES 1 ; for 10 bit addressing mode DataByte RES 1 ; load this reg with the data to be transmitted BitCount RES 1 ; The bit number (0:7) transmitted or received Bus_Status RES 1 ; Status Reg of I2C Bus for both TXMT & RCVE Bus_Control RES 1 ; control Register of I2C Bus DelayCount RES 1 DataByteCopy RES 1 ; copy of DataByte for Left Shifts (destructive) SubAddr RES 1 ; sub-address of slave (used in I2C_HIGH.ASM) SrcPtr RES 1 ; source pointer for data to be transmitted tempCount RES 1 ; a temp variable for scratch RAM StoreTemp_1 RES 1 ; a temp variable for scratch RAM, do not disturb contents _End_I2C_Ram RES 1 ; unused, only for ref of end of RAM allocation ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 if _CLOCK_STRETCH_CHECK ; TMR0 Interrupts enabled only if Clock Stretching is Used btfss INTCON,T0IF goto check ; other Interrupts bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,T0IF goto int_ret endif check: btfss PIR1,SSPIF goto int_ret bcf PIR1,SSPIF call sspint int_ret: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "p16f88.xpos = 96" .sim "p16f88.ypos = 144" .sim "module load pu pu1" .sim "pu1.xpos = 276" .sim "pu1.ypos = 72" .sim "module load pu pu2" .sim "pu2.xpos = 96" .sim "pu2.ypos = 48" .sim "node n1" .sim "attach n1 portb2 pu1.pin portb4" ; ee.SCL" .sim "node n2" .sim "attach n2 portb3 pu2.pin portb1" ; ee.SDA" .sim "node n3" ;.sim "attach n3 porta0 ee.WP" .sim "node n4" ;.sim "attach n4 porta1 ee.A0" .sim "node n5" ;.sim "attach n5 porta2 ee.A1" .sim "node n6" ;.sim "attach n6 porta3 ee.A2" .sim "scope.ch0 = \"portb2\"" .sim "scope.ch1 = \"portb3\"" bsf STATUS,RP0 ; bank 1 movlw 0xf6 ; set internal RC to 8 Mhz movwf OSCCON clrf TRISA bsf PIE1,SSPIE ; allow SSP interrupts bsf INTCON,GIE ; allow interrupts bsf INTCON,PEIE ; allow interrupts bcf STATUS,RP0 ; bank 0 ; bsf PORTA,0 ; Write protect bsf PORTA,1 ; A0 movlw 0x10 movwf tempCount movlw IO_buf movwf FSR Fill_loop: movf FSR,W movwf INDF incf FSR,F decfsz tempCount,F goto Fill_loop movlw 0x36 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xa2 movwf SSPADD bcf STATUS,RP0 ; bank 0 call InitI2CBus_Master LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive .assert "\"Slave not active\"" nop LOAD_ADDR_8 0xa2 ; I2C_WR_SUB 8, IO_buf, 0x0c I2C_WR_SUB2 8, IO_buf, 0x0c, 0x0c call TxmtStopBit ; Issue a stop bit to end transmission movf Bus_Status,W .assert "W == 0x10, \"*** FAILED I2C write status\"" nop poll_ready: LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive goto poll_ready ; slave not active yet nop ; ; write 0xa2 0x0c 0x0c to set an address ; write RSTART 0xa3 to initiate read ; read 8 bytes of data into ram starting at IN_buf ; LOAD_ADDR_8 0xa2 I2C_READ_SUB2 8, IN_buf, 0x0c, 0x0c nop bcf STATUS,RP0 ; bank 0 movf IN_buf,W .assert "W == 0xf5, \"*** FAILED read data\"" nop movf Bus_Status,W .assert "W == 0x30, \"*** FAILED 8 bit read status\"" nop ; ; write 8 bytes of data in slave 10bit mode ; bcf STATUS,RP0 ; bank 0 movlw 0x37 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xf0 movwf SSPADD bcf STATUS,RP0 ; bank 0 LOAD_ADDR_10 0x0c I2C_WR 8, IO_buf .assert "\"*** PASSED p16f88 I2C test\"" nop goto $ IsSlaveActive bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; bcf _SlaveActive btfss _ACK_Error ; skip if NACK, device is not present or not responding bsf _SlaveActive ; ACK received, device present & listening call TxmtStopBit return include "i2c_low.inc" _i2c_block_write: call TxmtStartBit ; send START bit bcf _Slave_RW ; set for write operation call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; _block_wr1_loop: btfss _Txmt_Success return movf INDF,W movwf DataByte ; start from the first byte starting at _DataPointer_ incf FSR, F call SendData ; send next byte, bus is our's ! decfsz tempCount, F goto _block_wr1_loop ; loop until desired bytes of data ; transmitted to slave return ; ;**************************************************************************** _i2c_block_read: call TxmtStartBit ; send START bit bsf _Slave_RW ; set for read operation bcf _Last_Byte_Rcv ; not a last byte to rcv call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set btfsc _Txmt_Success goto _block_rd1_loop ; end call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw FALSE ; Error : may be device not responding ; _block_rd1_loop: call GetData movf DataByte,W movwf INDF ;start receiving data, starting at Destination Pointer incf FSR, F decfsz tempCount, F goto _block_rd1_loop ; loop until desired bytes of data transmitted to slave bsf _Last_Byte_Rcv ; last byte to rcv, so send NACK call GetData movf DataByte,W movwf INDF call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw TRUE sspint: bsf STATUS,RP0 ; bank 1 btfsc SSPSTAT,R_W ; write test ? goto sspint_wr btfsc SSPSTAT,UA ; UA bit set goto sspint_ua bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return sspint_wr: bcf STATUS,RP0 ; bank 0 movlw 0xf5 ; byte to send movwf SSPBUF bsf SSPCON,CKP ; turn off clock stretch return sspint_ua: movlw 0x0c ; second byte address movwf SSPADD bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return end gpsim-0.30.0/regression/i2c/i2c_low.inc0000664000076400007640000003227213041763602014542 00000000000000;**************************************************************************** ; ; Low Level I2C Routines ; ; Single Master Transmitter & Single Master Receiver Routines ; These routines can very easily be converted to Multi-Master System ; when PIC16C6X with on chip I2C Slave Hardware, Start & Stop Bit ; detection is available. ; ; The generic high level routines are given in I2C_HIGH.ASM ; ; ; Program: I2C_LOW.ASM ; Revision Date: ; 1-16-97 Compatibility with MPASMWIN 1.40 ; ;*************************************************************************** ;************************************************************************** ; I2C Bus Initialization ; ;************************************************************************** InitI2CBus_Master: bcf STATUS,RP0 movlw ~(1< include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_IO & _PWRTE_ON & _LVP_OFF & _BODEN_OFF & _MCLR_OFF ;; The purpose of this program is to test gpsim's ability ;; to simulate a pic 16F819. ;; Specifically, I2C errorlevel -302 ; Printf Command .command macro x .direct "C", x endm _ClkIn equ 8000000 ; Input Clock Frequency _ClkOut equ (_ClkIn >> 2) ; ; Compute the delay constants for setup & hold times ; _40uS_Delay set (_ClkOut/250000) _47uS_Delay set (_ClkOut/212766) _50uS_Delay set (_ClkOut/200000) TRUE equ 1 FALSE equ 0 LSB equ 0 MSB equ 7 #define SCL_PIN 2 #define SDA_PIN 3 #define I2CPORT PORTB #define _SCL_D I2CPORT,SCL_PIN #define _SCL TRISB,SCL_PIN #define _SDA TRISB,SDA_PIN #define T0IE TMR0IE #define T0IF TMR0IF #define _ENABLE_BUS_FREE_TIME TRUE #define _CLOCK_STRETCH_CHECK TRUE #define _OPTION_INIT (0xC0 | 0x02) ; Prescaler to TMR0 for Appox 1 mSec timeout ;***************************************************************************** ; I2C Bus Status Reg Bit Definitions ;***************************************************************************** #define _Bus_Busy Bus_Status,0 #define _Abort Bus_Status,1 #define _Txmt_Progress Bus_Status,2 #define _Rcv_Progress Bus_Status,3 #define _Txmt_Success Bus_Status,4 #define _Rcv_Success Bus_Status,5 #define _Fatal_Error Bus_Status,6 #define _ACK_Error Bus_Status,7 ;***************************************************************************** ; I2C Bus Contro Register ;***************************************************************************** #define _10BitAddr Bus_Control,0 #define _Slave_RW Bus_Control,1 #define _Last_Byte_Rcv Bus_Control,2 #define _SlaveActive Bus_Control,6 #define _TIME_OUT_ Bus_Control,7 RELEASE_BUS MACRO bsf STATUS,RP0 ; select page 1 bsf _SDA ; tristate SDA bsf _SCL ; tristate SCL ; bcf _Bus_Busy ; Bus Not Busy, TEMP ????, set/clear on Start & Stop ENDM ;**************************************************************************** ; A MACRO To Load 8 OR 10 Bit Address To The Address Registers ; ; SLAVE_ADDRESS is a constant and is loaded into the SlaveAddress Register(s) ; depending on 8 or 10 bit addressing modes ;**************************************************************************** LOAD_ADDR_10 MACRO SLAVE_ADDRESS bsf _10BitAddr ; Slave has 10 bit address movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ; load low byte of address movlw (((SLAVE_ADDRESS >> 7) & 0x06) | 0xF0) ; 10 bit addr 11110AA0 movwf SlaveAddr+1 ; hi order address ENDM LOAD_ADDR_8 MACRO SLAVE_ADDRESS bcf _10BitAddr ; Set for 8 Bit Address Mode movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ENDM ;**************************************************************************** ; I2C_WRITE_SUB ; ; Writes a message just like I2C_WRITE, except that the data is preceeded ; by a sub-address to a slave device. ; Eg. : A serial EEPROM would need an address of memory location for ; Random Writes ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ (constant) ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; _Sub_Address_ Sub-address of Slave (constant) ; ; Sequence : ; S-SlvAW-A-SubA-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag ; ; Returns : WREG = 1 on success, else WREG = 0 ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ; COMMENTS : ; I2C_WR may prove to be more efficient than this macro in most situations ; Advantages will be found for Random Address Block Writes for Slaves with ; Auto Increment Sub-Addresses (like Microchip's 24CXX series Serial ; EEPROMS) ; ;**************************************************************************** I2C_WR_SUB MACRO _BYTES_, _SourcePointer_, _Sub_Address_ movlw (_BYTES_ + 1) movwf tempCount movlw (_SourcePointer_ - 1) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -1) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -1) call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W movwf (_SourcePointer_ - 1) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM I2C_WR_SUB2 MACRO _BYTES_, _SourcePointer_, _Sub_Address_, _Sub_Address2_ movlw (_BYTES_ + 2) movwf tempCount movlw (_SourcePointer_ - 2) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -2) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -2) movlw (_SourcePointer_ - 1) movwf FSR movlw _Sub_Address2_ movwf INDF movlw (_SourcePointer_ - 2) movwf FSR call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W ; movwf (_SourcePointer_ - 2) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM ;**************************************************************************** ; I2C_WRITE ; ; A basic macro for writing a block of data to a slave ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; ; Sequence : ; S-SlvAW-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ;**************************************************************************** I2C_WR MACRO _BYTES_, _SourcePointer_ movlw _BYTES_ movwf tempCount movlw _SourcePointer_ movwf FSR call _i2c_block_write call TxmtStopBit ; Issue a stop bit for slave to end transmission ENDM ;***************************************************************************** ; ; I2C_READ ; ; The basic MACRO/procedure to read a block message from a slave device ; ; Parameters : ; _BYTES_ : constant : #of bytes to receive ; _DestPointer_ : destination pointer of RAM (File Registers) ; ; Sequence : ; S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; If last byte, then Master will NOT Acknowledge (send NACK) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ;***************************************************************************** I2C_READ MACRO _BYTES_, _DestPointer_ movlw (_BYTES_ -1) movwf tempCount ; -1 because, the last byte is used out of loop movlw _DestPointer_ movwf FSR ; FIFO destination address pointer call _i2c_block_read ENDM ;*************************************************************************** ; ; I2C_READ_SUB ; This MACRO/Subroutine reads a message from a slave device preceeded by ; a write of the sub-address. ; Between the sub-addrers write & the following reads, a STOP condition ; is not issued and a "REPEATED START" condition is used so that an other ; master will not take over the bus, and also that no other master will ; overwrite the sub-address of the same salve. ; ; This function is very commonly used in accessing Random/Sequential reads ; from a memory device (e.g : 24Cxx serial of Serial EEPROMs from Microchip). ; ; Parameters : ; _BYTES_ # of bytes to read ; _DestPointer_ The destination pointer of data to be received. ; _BubAddress_ The sub-address of the slave ; ; Sequence : ; S-SlvAW-A-SubAddr-A-S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; ;*************************************************************************** I2C_READ_SUB MACRO _BYTES_, _DestPointer_, _SubAddress_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM I2C_READ_SUB2 MACRO _BYTES_, _DestPointer_, _SubAddress_, _SubAddress2_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address movlw _SubAddress2_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- cblock 0x20 Add:2 IO_buf:10 IN_buf:10 endc cblock 0xf0 w_temp status_temp SlaveAddr ; Slave Addr must be loader into this reg SlaveAddrHi ; for 10 bit addressing mode DataByte ; load this reg with the data to be transmitted BitCount ; The bit number (0:7) transmitted or received Bus_Status ; Status Reg of I2C Bus for both TXMT & RCVE Bus_Control ; control Register of I2C Bus DelayCount DataByteCopy ; copy of DataByte for Left Shifts (destructive) SubAddr ; sub-address of slave (used in I2C_HIGH.ASM) SrcPtr ; source pointer for data to be transmitted tempCount ; a temp variable for scratch RAM StoreTemp_1 ; a temp variable for scratch RAM, do not disturb contents _End_I2C_Ram ; unused, only for ref of end of RAM allocation endc ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 if _CLOCK_STRETCH_CHECK ; TMR0 Interrupts enabled only if Clock Stretching is Used btfss INTCON,T0IF goto check ; other Interrupts bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,T0IF goto int_ret endif check: btfss PIR1,SSPIF goto int_ret bcf PIR1,SSPIF call sspint int_ret: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "module load pu pu1" .sim "module load pu pu2" .sim "node n1" .sim "attach n1 portb2 pu1.pin portb4" ; ee.SCL" .sim "node n2" .sim "attach n2 portb3 pu2.pin portb1" ; ee.SDA" .sim "node n3" ;.sim "attach n3 porta0 ee.WP" .sim "node n4" ;.sim "attach n4 porta1 ee.A0" .sim "node n5" ;.sim "attach n5 porta2 ee.A1" .sim "node n6" ;.sim "attach n6 porta3 ee.A2" .sim "scope.ch0 = \"portb4\"" .sim "scope.ch1 = \"portb1\"" bsf STATUS,RP0 ; bank 1 movlw 0xf6 ; set internal RC to 8 Mhz movwf OSCCON clrf TRISA bsf PIE1,SSPIE ; allow SSP interrupts bsf INTCON,GIE ; allow interrupts bsf INTCON,PEIE ; allow interrupts bcf STATUS,RP0 ; bank 0 ; bsf PORTA,0 ; Write protect bsf PORTA,1 ; A0 movlw 0x10 movwf tempCount movlw IO_buf movwf FSR Fill_loop: movf FSR,W movwf INDF incf FSR,F decfsz tempCount,F goto Fill_loop movlw 0x36 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xa2 movwf SSPADD bcf STATUS,RP0 ; bank 0 call InitI2CBus_Master LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive .assert "\"Slave not active\"" nop LOAD_ADDR_8 0xa2 ; I2C_WR_SUB 8, IO_buf, 0x0c I2C_WR_SUB2 8, IO_buf, 0x0c, 0x0c call TxmtStopBit ; Issue a stop bit to end transmission movf Bus_Status,W .assert "W == 0x10, \"*** FAILED I2C write status\"" nop poll_ready: LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive goto poll_ready ; slave not active yet nop ; ; write 0xa2 0x0c 0x0c to set an address ; write RSTART 0xa3 to initiate read ; read 8 bytes of data into ram starting at IN_buf ; LOAD_ADDR_8 0xa2 I2C_READ_SUB2 8, IN_buf, 0x0c, 0x0c nop bcf STATUS,RP0 ; bank 0 movf IN_buf,W .assert "W == 0xf5, \"*** FAILED read data\"" nop movf Bus_Status,W .assert "W == 0x30, \"*** FAILED 8 bit read status\"" nop ; ; write 8 bytes of data in slave 10bit mode ; bcf STATUS,RP0 ; bank 0 movlw 0x37 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xf0 movwf SSPADD bcf STATUS,RP0 ; bank 0 LOAD_ADDR_10 0x0c I2C_WR 8, IO_buf .assert "\"*** PASSED 16f819 I2C test\"" nop goto $ IsSlaveActive bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; bcf _SlaveActive btfss _ACK_Error ; skip if NACK, device is not present or not responding bsf _SlaveActive ; ACK received, device present & listening call TxmtStopBit return include "i2c_low.inc" _i2c_block_write: call TxmtStartBit ; send START bit bcf _Slave_RW ; set for write operation call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; _block_wr1_loop: btfss _Txmt_Success return movf INDF,W movwf DataByte ; start from the first byte starting at _DataPointer_ incf FSR, F call SendData ; send next byte, bus is our's ! decfsz tempCount, F goto _block_wr1_loop ; loop until desired bytes of data ; transmitted to slave return ; ;**************************************************************************** _i2c_block_read: call TxmtStartBit ; send START bit bsf _Slave_RW ; set for read operation bcf _Last_Byte_Rcv ; not a last byte to rcv call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set btfsc _Txmt_Success goto _block_rd1_loop ; end call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw FALSE ; Error : may be device not responding ; _block_rd1_loop: call GetData movf DataByte,W movwf INDF ;start receiving data, starting at Destination Pointer incf FSR, F decfsz tempCount, F goto _block_rd1_loop ; loop until desired bytes of data transmitted to slave bsf _Last_Byte_Rcv ; last byte to rcv, so send NACK call GetData movf DataByte,W movwf INDF call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw TRUE sspint: bsf STATUS,RP0 ; bank 1 btfsc SSPSTAT,R_W ; write test ? goto sspint_wr btfsc SSPSTAT,UA ; UA bit set goto sspint_ua bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return sspint_wr: bcf STATUS,RP0 ; bank 0 movlw 0xf5 ; byte to send movwf SSPBUF bsf SSPCON,CKP ; turn off clock stretch return sspint_ua: movlw 0x0c ; second byte address movwf SSPADD bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return end gpsim-0.30.0/regression/i2c/Makefile0000664000076400007640000000042213041763602014141 00000000000000# I2C module regression test # # include ../make.regression all : p16f876a.cod p16f88.cod p16f819.cod p%.cod : p%.o gplink --map -s $*.lkr -o $@ $< p16f88.cod: p16f88.asm i2c_low.inc p16f819.cod: p16f819.asm i2c_low.inc sim: sim_p16f88 sim_p16f876a sim_p16f819 gpsim-0.30.0/regression/i2c/16f88.lkr0000664000076400007640000000304113041763602013767 00000000000000// Sample linker command file for 16F88 LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2009 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED SHAREBANK NAME=sfrnobnk START=0x70 END=0x7F SHAREBANK NAME=sfrnobnk START=0xF0 END=0xFF SHAREBANK NAME=sfrnobnk START=0x170 END=0x17F SHAREBANK NAME=sfrnobnk START=0x1F0 END=0x1FF DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG0 ROM=page0 // ROM code space SECTION NAME=PROG1 ROM=page1 // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEVICEID ROM=.device_id // Device ID SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/i2c/16f876a.lkr0000664000076400007640000000330413041763602014217 00000000000000// Sample linker command file for 16F876 // $Id: 16f876a.lkr 1828 2006-11-10 18:59:10Z borutr $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=page2 START=0x1000 END=0x17FF CODEPAGE NAME=page3 START=0x1800 END=0x1FFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=PROG3 ROM=page2 // ROM code space - page2 SECTION NAME=PROG4 ROM=page3 // ROM code space - page3 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/i2c/16f819.lkr0000664000076400007640000000267413041763602014064 00000000000000// Sample linker command file for 16F819.lkr LIBPATH . CODEPAGE NAME=vectors START=0x0000 END=0x0004 PROTECTED CODEPAGE NAME=page START=0x0005 END=0x07FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2009 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=gpr0 START=0xA0 END=0xEF DATABANK NAME=gpr1 START=0x120 END=0x16F SHAREBANK NAME=gprnobnk0 START=0x20 END=0x6F SHAREBANK NAME=gprnobnk0 START=0x1A0 END=0x1EF SHAREBANK NAME=gprnobnk1 START=0x70 END=0x7F SHAREBANK NAME=gprnobnk1 START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk1 START=0x170 END=0x17F SHAREBANK NAME=gprnobnk1 START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEVICEID ROM=.device_id // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/psp/0000775000076400007640000000000013117466027012715 500000000000000gpsim-0.30.0/regression/psp/18f6520.lkr0000664000076400007640000000242713041763600014260 00000000000000// $Id: 18f6520.lkr 448 2006-08-19 02:52:41Z craigfranklin $ // File: 18f6520.lkr // Sample linker script for the PIC18F6520 processor // Not intended for use with MPLAB C18. For C18 projects, // use the linker scripts provided with that product. LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF003FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x5F DATABANK NAME=gpr0 START=0x60 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF DATABANK NAME=gpr6 START=0x600 END=0x6FF DATABANK NAME=gpr7 START=0x700 END=0x7FF ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED gpsim-0.30.0/regression/psp/18f452.lkr0000664000076400007640000000200313041763600014164 00000000000000// $Id: 18f452.lkr 1828 2006-11-10 18:59:10Z borutr $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=page START=0x00 END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/regression/psp/16f871.lkr0000664000076400007640000000251413041763600014176 00000000000000// Sample linker command file for 16F871 LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED SHAREBANK NAME=gprnobnk0 START=0x20 END=0x6F SHAREBANK NAME=gprnobnk0 START=0x120 END=0x16F SHAREBANK NAME=gprnobnk1 START=0xA0 END=0xBF SHAREBANK NAME=gprnobnk1 START=0x1A0 END=0x1BF SHAREBANK NAME=gprnobnk2 START=0x70 END=0x7F SHAREBANK NAME=gprnobnk2 START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk2 START=0x170 END=0x17F SHAREBANK NAME=gprnobnk2 START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/psp/Makefile0000664000076400007640000000033613041763600014270 00000000000000# PSP (Parallel Slave Port) module regression test # # include ../make.regression all : p16f871.cod p18f452.cod p18f6520.cod p%.cod : p%.o gplink --map -s $*.lkr -o $@ $< sim: sim_p16f871 sim_p18f452 sim_p18f6520 gpsim-0.30.0/regression/psp/p18f6520.asm0000664000076400007640000001236413116716400014430 00000000000000 list p=18f6520 include include ;; The purpose of this program is to test gpsim's ability to simulate ;; the Parallel Slave port (PSP) functionality. ;; ;; Portb and portd form the PSP bus and porta pins 0, 1, and 2 ;; drive the, active low, bus control signals RD, WR and CS respectively errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR1,PSPIF goto done .assert "\"FAILED 18F6520 unexpected interupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "node pspRD" .sim "attach pspRD porta0 porte0" .sim "node pspWR" .sim "attach pspWR porta1 porte1" .sim "node pspCS" .sim "attach pspCS porta2 porte2" .sim "node p0" .sim "attach p0 portb0 portd0" .sim "node p1" .sim "attach p1 portb1 portd1" .sim "node p2" .sim "attach p2 portb2 portd2" .sim "node p3" .sim "attach p3 portb3 portd3" .sim "node p4" .sim "attach p4 portb4 portd4" .sim "node p5" .sim "attach p5 portb5 portd5" .sim "node p6" .sim "attach p6 portb6 portd6" .sim "node p7" .sim "attach p7 portb7 portd7" ; ; The test relies on porta being digital I/O, and porte being PSP, so it's ; necessary to disable all ADC channels movlw 0xff movwf ADCON1 ; ; First test portd operates in normal mode clrf TRISD ; PortD output movlw 0x55 movwf PORTD .assert "portd == 0x55, \"FAILED, Portd put value OK\"" nop .assert "portb == 0x55, \"FAILED, Portd drives Portb\"" nop movf PORTD,W ; check read Portd .assert "W == 0x55, \"FAILED, Read portd OK\"" nop clrf TRISB ; PortB output movlw 0xff movwf TRISD ; PortD input movwf PORTB .assert "portd == 0xff, \"FAILED, Read portd as input\"" nop ; ; Now test PSP in bus RD mode ; movlw 0x07 ; set bits high movwf PORTA movlw 0xff movwf TRISB movlw 0xf8 movwf TRISA movlw 0x17 movwf PSPCON ; set PSPMODE .assert "pspcon == 0x10, \"FAILED, PSPMODE, IBOV only writable\"" nop movwf TRISE movlw 0xf0 movwf PORTD ; Output should not change in PSP mode .assert "(pspcon & 0xe0) == 0x40, \"FAILED, OBF set on portd write\"" nop .assert "portb != 0xf0, \"FAILED, Output not changed\"" nop bcf PORTA,0 ; Drive RD low to put data on bus bcf PORTA,2 ; Drive CS low to select .assert "(pspcon & 0xe0) == 0x00, \"FAILED, OBF cleared on PSP RD\"" nop .assert "portb == 0xf0, \"FAILED, Output on bus\"" nop .assert "(pir1 & 0x80) == 0, \"FAILED, PSPIF not set until RD off\"" nop bsf PORTA,0 ; Turn off RD .assert "(pir1 & 0x80) == 0x80, \"FAILED, PSPIF set for RD\"" nop ; ; test PSP WR function ; clrf TRISB ; set B as output movlw 0x0f movwf PORTB ; drive bus bcf PORTA,1 ; Turn on WR (CS already on) .assert "(pspcon & 0xe0) == 0x00, \"FAILED, IBF not set yet\"" nop bsf PORTA,2 ; Turn off CS .assert "(pspcon & 0xe0) == 0x80, \"FAILED, IBF now set\"" nop movf PORTD,W .assert "W == 0x0f, \"FAILED, Value read from bus\"" nop .assert "(pspcon & 0xe0) == 0x00, \"FAILED, IBF cleared on read of portd\"" nop bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS .assert "(pspcon & 0xe0) == 0xa0, \"FAILED, IBF, IBOV both set \"" nop movlw 0xff movwf PORTB ; change value on bus(value not read by PSP) movwf TRISB ; put bus in Z state movf PORTD,W .assert "W == 0x0f, \"FAILED, Value read from high-Z bus \"" nop bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS movlw 0x17 movwf PSPCON .assert "(pspcon & 0xe0) == 0x80, \"FAILED, IBOV cleared, but not IBF \"" nop movlw 0x07 ; turn off PSP movwf PSPCON .assert "(pspcon & 0xf0) == 0x00, \"FAILED, IBF & PSPMODE claered\"" nop ; ; test interupts ; movlw 0x17 movwf PSPCON bsf PIE1,PSPIE movlw 0xc0 movwf INTCON ; Enable interupts bcf PIR1,PSPIF bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS .assert "\"FAILED, interrupt\"" nop goto $-1 done: .assert "\"*** PASSED 18F6520 PSP test\"" goto $-1 end gpsim-0.30.0/regression/psp/p18f452.asm0000664000076400007640000001224513116716056014353 00000000000000 list p=18f452 include include ;; The purpose of this program is to test gpsim's ability to simulate ;; the Parallel Slave port (PSP) functionality. ;; ;; Portb and portd form the PSP bus and porta pins 0, 1, and 2 ;; drive the, active low, bus control signals RD, WR and CS respectively errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR1,PSPIF goto done .assert "\"FAILED 18F452 unexpected interupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "node pspRD" .sim "attach pspRD porta0 porte0" .sim "node pspWR" .sim "attach pspWR porta1 porte1" .sim "node pspCS" .sim "attach pspCS porta2 porte2" .sim "node p0" .sim "attach p0 portb0 portd0" .sim "node p1" .sim "attach p1 portb1 portd1" .sim "node p2" .sim "attach p2 portb2 portd2" .sim "node p3" .sim "attach p3 portb3 portd3" .sim "node p4" .sim "attach p4 portb4 portd4" .sim "node p5" .sim "attach p5 portb5 portd5" .sim "node p6" .sim "attach p6 portb6 portd6" .sim "node p7" .sim "attach p7 portb7 portd7" ; ; The test relies on porta being digital I/O, and porte being PSP, so it's ; necessary to disable all ADC channels movlw 0x07 movwf ADCON1 ; ; First test portd operates in normal mode clrf TRISD ; PortD output movlw 0x55 movwf PORTD .assert "portd == 0x55, \"FAILED, Portd put value OK\"" nop .assert "portb == 0x55, \"FAILED, Portd drives Portb\"" nop movf PORTD,W ; check read Portd .assert "W == 0x55, \"FAILED, Read portd OK\"" nop clrf TRISB ; PortB output movlw 0xff movwf TRISD ; PortD input movwf PORTB .assert "portd == 0xff, \"FAILED, Read portd as input\"" nop ; ; Now test PSP in bus RD mode ; movlw 0x07 ; set bits high movwf PORTA movlw 0xff movwf TRISB movlw 0xf8 movwf TRISA movlw 0x17 movwf TRISE movlw 0xf0 movwf PORTD ; Output should not change in PSP mode .assert "(trise & 0xe0) == 0x40, \"FAILED, OBF set on portd write\"" nop .assert "portb != 0xf0, \"FAILED, Output not changed\"" nop bcf PORTA,0 ; Drive RD low to put data on bus bcf PORTA,2 ; Drive CS low to select .assert "(trise & 0xe0) == 0x00, \"FAILED, OBF cleared on PSP RD\"" nop .assert "portb == 0xf0, \"FAILED, Output on bus\"" nop .assert "(pir1 & 0x80) == 0, \"FAILED, PSPIF not set until RD off\"" nop bsf PORTA,0 ; Turn off RD .assert "(pir1 & 0x80) == 0x80, \"FAILED, PSPIF set for RD\"" nop ; ; test PSP WR function ; clrf TRISB ; set B as output movlw 0x0f movwf PORTB ; drive bus bcf PORTA,1 ; Turn on WR (CS already on) .assert "(trise & 0xe0) == 0x00, \"FAILED, IBF not set yet\"" nop bsf PORTA,2 ; Turn off CS .assert "(trise & 0xe0) == 0x80, \"FAILED, IBF now set\"" nop movf PORTD,W .assert "W == 0x0f, \"FAILED, Value read from bus\"" nop .assert "(trise & 0xe0) == 0x00, \"FAILED, IBF cleared on read of portd\"" nop bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS .assert "(trise & 0xe0) == 0xa0, \"FAILED, IBF, IBOV both set \"" nop movlw 0xff movwf PORTB ; change value on bus(value not read by PSP) movwf TRISB ; put bus in Z state movf PORTD,W .assert "W == 0x0f, \"FAILED, Value read from high-Z bus \"" nop bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS movlw 0x17 movwf TRISE ; set B as output .assert "(trise & 0xe0) == 0x80, \"FAILED, IBOV cleared, but not IBF \"" nop movlw 0x07 ; turn off PSP movwf TRISE ; set B as output .assert "(trise & 0xf0) == 0x00, \"FAILED, IBF & PSPMODE claered\"" nop ; ; test interupts ; movlw 0x17 movwf TRISE bsf PIE1,PSPIE movlw 0xc0 movwf INTCON ; Enable interupts bcf PIR1,PSPIF bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS .assert "\"FAILED, interrupt\"" nop goto $-1 done: .assert "\"*** PASSED 18F452 PSP test\"" goto $-1 end gpsim-0.30.0/regression/psp/p16f871.asm0000664000076400007640000001251513116715607014357 00000000000000 list p=16f871 include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate ;; the Parallel Slave port (PSP) functionality. ;; ;; Portb and portd form the PSP bus and porta pins 0, 1, and 2 ;; drive the, active low, bus control signals RD, WR and CS respectively errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;bank 0 btfsc PIR1,PSPIF goto done .assert "\"FAILED 16F871 unexpected interupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "node pspRD" .sim "attach pspRD porta0 porte0" .sim "node pspWR" .sim "attach pspWR porta1 porte1" .sim "node pspCS" .sim "attach pspCS porta2 porte2" .sim "node p0" .sim "attach p0 portb0 portd0" .sim "node p1" .sim "attach p1 portb1 portd1" .sim "node p2" .sim "attach p2 portb2 portd2" .sim "node p3" .sim "attach p3 portb3 portd3" .sim "node p4" .sim "attach p4 portb4 portd4" .sim "node p5" .sim "attach p5 portb5 portd5" .sim "node p6" .sim "attach p6 portb6 portd6" .sim "node p7" .sim "attach p7 portb7 portd7" ; ; The test relies on porta being digital I/O, and porte being PSP, so it's ; necessary to disable all ADC channels bsf STATUS,RP0 ; bank 1 movlw 0x07 movwf ADCON1 bcf STATUS,RP0 ; bank 0 ; ; First test portd operates in normal mode bsf STATUS,RP0 ; bank 1 clrf TRISD ; PortD output bcf STATUS,RP0 ; bank 0 movlw 0x55 movwf PORTD .assert "portd == 0x55, \"FAILED, Portd put value OK\"" nop .assert "portb == 0x55, \"FAILED, Portd drives Portb\"" nop movf PORTD,W ; check read Portd .assert "W == 0x55, \"FAILED, Read portd OK\"" nop bsf STATUS,RP0 ; bank 1 clrf TRISB ; PortB output movlw 0xff movwf TRISD ; PortD input bcf STATUS,RP0 ; bank 0 movwf PORTB .assert "portd == 0xff, \"FAILED, Read portd as input\"" nop ; ; Now test PSP in bus RD mode ; movlw 0x07 ; set bits high movwf PORTA bsf STATUS,RP0 ; bank 1 movlw 0xff movwf TRISB movlw 0xf8 movwf TRISA movlw 0x17 movwf TRISE bcf STATUS,RP0 ; bank 0 movlw 0xf0 movwf PORTD ; Output should not change in PSP mode .assert "(trise & 0xe0) == 0x40, \"FAILED, OBF set on portd write\"" nop .assert "portb != 0xf0, \"FAILED, Output not changed\"" nop bcf PORTA,0 ; Drive RD low to put data on bus bcf PORTA,2 ; Drive CS low to select .assert "(trise & 0xe0) == 0x00, \"FAILED, OBF cleared on PSP RD\"" nop .assert "portb == 0xf0, \"FAILED, Output on bus\"" nop .assert "(pir1 & 0x80) == 0, \"FAILED, PSPIF not set until RD off\"" nop bsf PORTA,0 ; Turn off RD .assert "(pir1 & 0x80) == 0x80, \"FAILED, PSPIF set for RD\"" nop ; ; test PSP WR function ; bsf STATUS,RP0 ; bank 1 clrf TRISB ; set B as output bcf STATUS,RP0 ; bank 0 movlw 0x0f movwf PORTB ; drive bus bcf PORTA,1 ; Turn on WR (CS already on) .assert "(trise & 0xe0) == 0x00, \"FAILED, IBF not set yet\"" nop bsf PORTA,2 ; Turn off CS .assert "(trise & 0xe0) == 0x80, \"FAILED, IBF now set\"" nop movf PORTD,W .assert "W == 0x0f, \"FAILED, Value read from bus\"" nop .assert "(trise & 0xe0) == 0x00, \"FAILED, IBF cleared on read of portd\"" nop bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS .assert "(trise & 0xe0) == 0xa0, \"FAILED, IBF, IBOV both set \"" nop bsf STATUS,RP0 ; bank 1 movlw 0x17 movwf TRISE ; set B as output .assert "(trise & 0xe0) == 0x80, \"FAILED, IBOV cleared, but not IBF \"" nop movlw 0x07 ; turn off PSP movwf TRISE ; set B as output .assert "(trise & 0xf0) == 0x00, \"FAILED, IBF & PSPMODE claered\"" nop ; ; test interupts ; movlw 0x17 movwf TRISE bsf PIE1,PSPIE movlw 0xc0 movwf INTCON ; Enable interupts bcf STATUS,RP0 ; bank 0 bcf PIR1,PSPIF bcf PORTA,2 ; Turn on CS bsf PORTA,2 ; Turn off CS .assert "\"FAILED, interrupt\"" nop goto $-1 done: .assert "\"*** PASSED 16F871 PSP test\"" goto $-1 end gpsim-0.30.0/regression/comparator/0000775000076400007640000000000013117466027014262 500000000000000gpsim-0.30.0/regression/comparator/compar_2321.asm0000664000076400007640000003073713041763600016637 00000000000000 ;; Comparator test ;; ;; The purpose of this program is to verify the ;; comparator module of the processor list p=18f2321 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros CONFIG OSC=INTIO2 ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 temp RES 1 w_temp RES 1 status_temp RES 1 cmp_int RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR2,CMIF goto icm1 goto exit_int icm1: bcf PIR2,CMIF bsf cmp_int,0 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "p18f2321.xpos = 60" .sim "p18f2321.ypos = 84" .sim "module load pullup C1P" .sim "C1P.capacitance = 0" .sim "C1P.resistance = 10000" .sim "C1P.voltage = 1" .sim "C1P.xpos = 72" .sim "C1P.ypos = 24" .sim "module load pullup C1N" .sim "C1N.capacitance = 0" .sim "C1N.resistance = 10000" .sim "C1N.voltage = 2.5" .sim "C1N.xpos = 228" .sim "C1N.ypos = 36" .sim "module load pullup C2P" .sim "C2P.capacitance = 0" .sim "C2P.resistance = 10000" .sim "C2P.voltage = 2.8" .sim "C2P.xpos = 252" .sim "C2P.ypos = 96" .sim "module load pullup C2N" .sim "C2N.capacitance = 0" .sim "C2N.resistance = 10000" .sim "C2N.voltage = 2" .sim "C2N.xpos = 228" .sim "C2N.ypos = 144" .sim "node c1p" .sim "attach c1p C1P.pin porta3" .sim "node c1n" .sim "attach c1n C1N.pin porta0" .sim "node c2p" .sim "attach c2p C2P.pin porta2" .sim "node c2n" .sim "attach c2n C2N.pin porta1" .assert "cmcon == 0x07, \"FAILED 18f2321 CMCON POR\"" ; Rest value nop clrf PIR2 movlw CMODE7 ; turn off comparator movwf CMCON movlw 0xff movwf ADCON1 ; analog off all channels movlw 0x0f ; RA0-RA3 are inputs movwf TRISA ; mode 1 - one independant comparator with output movlw CMODE1 movwf CMCON call c1_out nop ; ; mode 2 - two independant comparators ; movlw CMODE2 movwf CMCON call ind_comp nop ; ; Two Independent Comparators with Outputs ; movlw CMODE3 movwf CMCON call ind_comp_out nop ; Two Common Reference(C1+) Comparators ; movlw CMODE4 movwf CMCON call ref_com nop ; Two Common Reference(C1+) Comparators with output ; movlw CMODE5 movwf CMCON call ref_com_out nop ; ; test mode - Four Inputs muxed to two comparators with Vref ; movlw CMODE6 ; Comparator mux reference movwf CMCON call mux_vref nop .assert "\"*** PASSED Comparator on 18f2321\"" goto $ ; One Independent Comparator with Output c1_out: ; C1IN- (2.5) ; C1IN+ (1.0) thus C1 out=0 ; C2in- (2.0) ; C2IN+ (2.8) but C2 off so out=0 .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 18f2321 c1_out, c1out=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 18f2321 c1_out, OUT1=0 OUT2=0\"" nop bsf CMCON,C1INV .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f2321 c1_out, c1out=1\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 18f2321 c1_out, OUT1=1 OUT2=0\"" nop ; C1IN- (2.5) ; C1IN+ (3.1) C1+ > C1- with invert thus C1 out=0 .command "C1P.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 18f2321 c1_out INVERT , c1out=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 18f2321 c1_out, INVERT OUT1=0 OUT2=0\"" nop return ; Two independent Comparators ind_comp: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f2321 2 ind comp CIS=0 C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f2321 2 ind comp CIS=1 C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f2321 2 ind comp C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f2321 2 ind comp C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"FAILED 18f2321 2 ind comp C1OUT=0 C2OUT=0\"" nop return ; Two independent Comparators with outputs ind_comp_out: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f2321 ind_comp_out CIS=0 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 18f2321 ind_comp_out CIS=0 port C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f2321 ind_comp_out CIS=1 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 18f2321 ind_comp_out CIS=1 port C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f2321 ind_comp_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 18f2321 ind_comp_out port C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f2321 ind_comp_out C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 18f2321 ind_comp_out port C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 18f2321 ind_comp_out C1OUT=0 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 18f2321 ind_comp_out port C1OUT=0 C2OUT=0\"" nop return ; ; Four Inputs muxed to two comparators with Vref ; mux_vref: .command "C1P.voltage = 1.0" nop .command "C1N.voltage = 2.5" nop .command "C2P.voltage = 2.8" nop .command "C2N.voltage = 2.0" nop ; C1IN- = 2.5 + = 2.29 out = 0 ; C2IN- = 2.0 + = 2.29 out = 1 movlw 0xAB ; enable Vref 11 low range 2.29v movwf CVRCON .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f2321 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 18f2321 mux with vref CMIF=1\"" nop clrf PIR2 movlw 0x8B ; enable Vref 11 high range 2.92v BANKSEL CVRCON movwf CVRCON ; C1IN- = 2.5 + = 2.92 out = 1 ; C2IN- = 2.0 + = 2.92 out = 1 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f2321 mux with vref C1OUT=1 C2OUT=1\"" nop movlw 0x03 movwf TRISC .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f2321 mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 18f2321 CMIF=1\"" nop bcf PIR2,CMIF .assert "(pir2 & 0x40) == 0x00, \"FAILED 18f2321 CMIF=0\"" nop .command "C1N.voltage = 3.0" ; drive comp1 low (C1IN- > Vref) nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f2321 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 18f2321 CMIF=1 C1 change\"" nop bcf PIR2,CMIF bsf CMCON,C1INV ; invert output bsf CMCON,C2INV .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f2321 mux with vref invert C1OUT=1 C2OUT=0\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 40f2321 CMIF=1\"" nop bcf PIR2,CMIF .command "C2N.voltage = 3.5" ; C2IN- > Vref nop .command "C1N.voltage = 2.5" ; C1IN- < Vref nop .command "C1P.voltage = 3.1" ; C1IN+ > Vref nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f2321 mux with vref new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 40f2321 mux with vref CMIF=1 C1, C2 change\"" nop bsf CMCON,CIS ; switch pins .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f2321 mux with vref new inputs C1OUT=1 C2OUT=0\"" nop movlw 0xc7 ; clear invert, CIS bits andwf CMCON,F .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f2321 mux with vref invert normal C1OUT=1 C2OUT=0\"" nop clrf PIR2 clrf cmp_int bsf PIE2,CMIE ; enable Comparator interrupts bsf INTCON,PEIE ; enable Peripheral interrupts bsf INTCON,GIE ; and global interrupts bsf CMCON,C1INV ; generate an interrupt btfsc cmp_int,0 goto done1 nop .assert "\"*** FAILED Comparator no interrupt 18f2321\"" nop goto $ done1: return ; ; Two common reference Comparators ; ; C1IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com: .command "C2P.voltage = 0.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f2321 ref_com CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f2321 ref_com CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f2321 ref_com C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f2321 ref_com C1OUT=1 C2OUT=1\"" nop return ; ; Two common reference Comparators with outputs ; ; C1IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com_out: .command "C2P.voltage = 0.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f2321 ref_com_out CIS=0 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 18f2321 ref_com_out CIS=0 port C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f2321 ref_com_out CIS=1 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 18f2321 ref_com_out CIS=1 port C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f2321 ref_com_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 18f2321 ref_com_out CIS=0 port C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f2321 ref_com_out C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 18f2321 ref_com_out port C1OUT=1 C2OUT=1\"" nop return end gpsim-0.30.0/regression/comparator/compar_877a.stc0000664000076400007640000000114213041763600016733 00000000000000 #set verbose 1 load compar_877a.cod U1 # Module libraries: module library libgpsim_modules # Modules: U1.xpos = 60 U1.ypos = 36 module load pullup PU1 PU1.resistance = 10000 PU1.xpos = 228 PU1.ypos = 36 module load pulldown PD2 PD2.resistance = 10000 PD2.xpos = 228 PD2.ypos = 96 # Connections: node nb0 attach nb0 porta0 portb0 PU1.pin PD2.pin #attach nb0 porta0 portb0 node nb1 attach nb1 porta1 portb1 node nb2 attach nb2 porta2 portb2 node nb3 attach nb3 porta3 portb3 node nb4 #attach nb4 porta4 portb4 PU2.pin attach nb4 porta4 portb4 portc4 node nb5 attach nb5 porta5 portb5 portc5 # End. gpsim-0.30.0/regression/comparator/compar_628.asm0000664000076400007640000002757013041763600016570 00000000000000 ;; Comparator test ;; ;; The purpose of this program is to verify the ;; comparator module of the processor list p=16f628 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmp_int RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR1,CMIF goto icm1 goto exit_int icm1: bcf PIR1,CMIF bsf cmp_int,0 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "p16f628.xpos = 60" .sim "p16f628.ypos = 84" .sim "module load pullup C1P" .sim "C1P.capacitance = 0" .sim "C1P.resistance = 10000" .sim "C1P.voltage = 1" .sim "C1P.xpos = 72" .sim "C1P.ypos = 24" .sim "module load pullup C1N" .sim "C1N.capacitance = 0" .sim "C1N.resistance = 10000" .sim "C1N.voltage = 2.5" .sim "C1N.xpos = 228" .sim "C1N.ypos = 36" .sim "module load pullup C2P" .sim "C2P.capacitance = 0" .sim "C2P.resistance = 10000" .sim "C2P.voltage = 2.8" .sim "C2P.xpos = 252" .sim "C2P.ypos = 96" .sim "module load pullup C2N" .sim "C2N.capacitance = 0" .sim "C2N.resistance = 10000" .sim "C2N.voltage = 2" .sim "C2N.xpos = 228" .sim "C2N.ypos = 144" .sim "node c1p" .sim "attach c1p C1P.pin porta3" .sim "node c1n" .sim "attach c1n C1N.pin porta0" .sim "node c2p" .sim "attach c2p C2P.pin porta2" .sim "node c2n" .sim "attach c2n C2N.pin porta1" .assert "cmcon == 0x00, \"FAILED 16f628 CMCON POR\"" ; Rest value nop BANKSEL PIR1 clrf PIR1 movlw CMODE7 ; turn off comparator BANKSEL CMCON movwf CMCON movlw 0x0f ; RA0-RA3 are inputs BANKSEL TRISA movwf TRISA ; mode 1 - one independant comparator with output movlw CMODE1 BANKSEL CMCON movwf CMCON call mux_3in nop ; ; test mode - Four Inputs muxed to two comparators with Vref ; movlw CMODE2 ; Comparator mux reference movwf CMCON call mux_vref nop ; Two Common Reference(C2+) Comparators ; movlw CMODE3 movwf CMCON call ref_com2 nop ; ; mode 4 - two independant comparators ; movlw CMODE4 movwf CMCON call ind_comp nop ; C2 only ; movlw CMODE5 movwf CMCON call c2_only nop ; ; Two Common Reference Comparators with Outputs ; movlw CMODE6 movwf CMCON call ref2_com_out nop .assert "\"*** PASSED Comparator on 16f628\"" goto $ ; ; 3 inputs mux to two comparators mux_3in: ; ; C2IN+(2.5V) to both comparator + ; C1IN-(3.1V), C1IN+(2.1V) muxed to C1 - by CIS ; C2in-(1.5V) connected to C2 - .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.1" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f684 mux_3in CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f684 mux_3in CIS=1 C1OUT=1 C2OUT=1\"" nop return ; Two independent Comparators ind_comp: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f628 2 ind comp CIS=0 C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f628 2 ind comp CIS=1 C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f628 2 ind comp C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 2 ind comp C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f628 2 ind comp C1OUT=0 C2OUT=0\"" nop return ; One (C2) independent Comparators c2_only: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + but C1 off thus C1 out=0 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 c2 only CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 c2 only CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f628 c2 only C1OUT=0 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 c2 only C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f628 2 c2 only C1OUT=0 C2OUT=0\"" nop return ; ; Four Inputs muxed to two comparators with Vref ; mux_vref: .command "C1P.voltage = 1.0" nop .command "C1N.voltage = 2.5" nop .command "C2P.voltage = 2.8" nop .command "C2N.voltage = 2.0" nop ; C1IN- = 2.5 + = 2.29 out = 0 ; C2IN- = 2.0 + = 2.29 out = 1 movlw 0xAB ; enable Vref 11 low range 2.29v BANKSEL VRCON movwf VRCON .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir1 & 0x40) == 0x40, \"FAILED 16f628 mux with vref CMIF=1\"" nop BANKSEL PIR1 clrf PIR1 movlw 0x8B ; enable Vref 11 high range 2.92v BANKSEL VRCON movwf VRCON ; C1IN- = 2.5 + = 2.92 out = 1 ; C2IN- = 2.0 + = 2.92 out = 1 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f628 mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f628 mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(pir1 & 0x40) == 0x40, \"FAILED 16f628 CMIF=1\"" nop BANKSEL PIR1 bcf PIR1,CMIF .assert "(pir1 & 0x40) == 0x00, \"FAILED 16f628 CMIF=0\"" nop .command "C1N.voltage = 3.0" ; drive comp1 low (C1IN- > Vref) nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir1 & 0x40) == 0x40, \"FAILED 16f628 CMIF=1 C1 change\"" nop bcf PIR1,CMIF BANKSEL CMCON bsf CMCON,C1INV ; invert output bsf CMCON,C2INV .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f628 mux with vref invert C1OUT=1 C2OUT=0\"" nop .assert "(pir1 & 0x40) == 0x40, \"FAILED 40f2321 CMIF=1\"" nop BANKSEL PIR1 bcf PIR1,CMIF .command "C2N.voltage = 3.5" ; C2IN- > Vref nop .command "C1N.voltage = 2.5" ; C1IN- < Vref nop .command "C1P.voltage = 3.1" ; C1IN+ > Vref nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f628 mux with vref new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir1 & 0x40) == 0x40, \"FAILED 40f2321 mux with vref CMIF=1 C1, C2 change\"" nop BANKSEL CMCON bsf CMCON,CIS ; switch pins .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f628 mux with vref new inputs C1OUT=1 C2OUT=0\"" nop movlw 0xc7 ; clear invert, CIS bits andwf CMCON,F .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f628 mux with vref invert normal C1OUT=1 C2OUT=0\"" nop BANKSEL PIR1 clrf PIR1 clrf cmp_int BANKSEL PIE1 bsf PIE1,CMIE ; enable Comparator interrupts bsf INTCON,PEIE ; enable Peripheral interrupts bsf INTCON,GIE ; and global interrupts BANKSEL CMCON bsf CMCON,C1INV ; generate an interrupt btfsc cmp_int,0 goto done1 nop .assert "\"*** FAILED Comparator no interrupt 16f628\"" nop goto $ done1: return ; ; Two common reference Comparators ; ; C2IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com2: .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 0.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f628 ref_com CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f628 ref_com CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 16f628 ref_com C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 16f628 ref_com C1OUT=1 C2OUT=1\"" nop return ; ; Two common reference Comparators with outputs ; ; C2IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref2_com_out: .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 4.5" nop .command "C1N.voltage = 3.1" nop BANKSEL TRISA ; RA3 is output bcf TRISA,3 .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f628 ref2_com_out CIS=0 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x18) == 0x10, \"*** FAILED 16f628 ref2_com_out CIS=0 port C1OUT=0 C2OUT=1\"" nop BANKSEL CMCON bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f628 ref2_com_out CIS=1 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x18) == 0x10, \"*** FAILED 16f628 ref2_com_out CIS=1 port C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 16f628 ref2_com_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x18) == 0x08, \"*** FAILED 16f628 ref2_com_out CIS=0 port C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 16f628 ref2_com_out C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x18) == 0x18, \"*** FAILED 16f628 ref2_com_out port C1OUT=1 C2OUT=1\"" nop return end gpsim-0.30.0/regression/comparator/compar_26k22.asm0000664000076400007640000003363213041763600017013 00000000000000; ; ; Copyright (c) 2015 Roy Rankin ; ; This file is part of the gpsim regression tests ; ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, see ; . list p=18f26k22 include include CONFIG WDTEN=OFF CONFIG MCLRE = INTMCLR CONFIG FOSC = INTIO67 ; __CONFIG _CONFIG1, _CP_OFF & _WDTE_OFF & _FOSC_INTOSC & _LVP_OFF & _MCLRE_OFF ; __CONFIG _CONFIG2, _PLLEN_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F1788. ;; Specifically, the comparator and gate function of Tmr1 is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 int_cm1 RES 1 int_cm2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 GLOBAL int_cm1, int_cm2 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X008 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p18f26k22.xpos = 72" .sim "p18f26k22.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "V1.voltage = 2.0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" .sim "V2.voltage = 2.5" .sim "module load pullup V3" .sim "V3.resistance = 100.0" .sim "V3.xpos = 84" .sim "V3.ypos = 288" .sim "V3.voltage = 4.5" .sim "module load pullup V4" .sim "V4.resistance = 100.0" .sim "V4.xpos = 240" .sim "V4.ypos = 120" .sim "V4.voltage = 3.5" .sim "module load pullup V5" .sim "V5.resistance = 100.0" .sim "V5.xpos = 240" .sim "V5.ypos = 160" .sim "V5.voltage = 3.5" .sim "node na0" .sim "attach na0 V3.pin porta3" ; C1IN+ .sim "node na1" .sim "attach na1 V1.pin porta1" ; C12IN1- .sim "node na3" .sim "attach na3 V2.pin porta0" ; C12IN0- .sim "node na4" .sim "attach na4 V4.pin portb3" ; C12IN2- .sim "node na5" .sim "attach na5 V5.pin portc0" ; T3G BANKSEL ANSELA movlw 0x0f movwf ANSELA ; select AN0, AN1, AN2, AN3 clrf ANSELC ; movwf TRISA movlw 0x03 movwf TRISC ; portc0 (AN4) portc1(AN5) input, portc4 output movlw 0xff movwf CTMUICON bsf INTCON,GIE ;Global interrupts bsf INTCON,PEIE ;Peripheral interrupts bsf PIE2,C1IE ;CM1 interrupts bsf PIE2,C2IE ;CM2 interrupts call t3_port call test_compar call test_tot1 ; can C2 increment TMR1 call test_sr call test_dac .assert "\"*** PASSED 18F26k22 comparator test\"" nop goto $-1 test_dac: bsf ADCON2,ADFM ;right justify ; movlw 0xf0 ;right justify, Frc, Vdd ref ; movwf ADCON1 bsf TRISC,0 ;Set RC0 to input bsf ANSELC,0 ;Set RC0 to analog movlw (0x1e<<2)|(1< ; processor specific variable definitions include ; Grab some useful macros ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR2,CMIF btfss PIE2,CMIE goto exit_int goto done1 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; ; test mode 6 - Four Inputs muxed to two comparators with Vref ; .assert "cmcon == 0x07, \"FAILED 16f873A CMCON POR\"" ; Rest value nop bcf PIR2,CMIF BSF STATUS,RP0 movlw 0x06 movwf ADCON1 movlw 0x0f ; RA3-RA0 are inputs movwf TRISA movlw 0xAB ; enable Vref 11 low range movwf CVRCON movlw CMODE6 ; comparater mux reference movwf CMCON .assert "(cmcon & 0x40) == 0x00, \"FAILED 16f873A m6 C1OUT=0 C2OUT=0\"" nop movlw 0x8B ; enable Vref 11 high range movwf CVRCON .assert "(cmcon & 0x40) == 0x40, \"FAILED 16f873A m6 C1OUT=1 C2OUT=0\"" nop bcf OPTION_REG,NOT_RBPU ; set pull ups on B port bcf OPTION_REG,T0CS ; Timer not from RA4 CLRF TRISB^0x80 ;Port B is an output BCF STATUS,RP0 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m6 C1OUT=1 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f873A CMIF=1\"" nop bcf PIR2,CMIF .assert "(pir2 & 0x40) == 0x00, \"FAILED 16f873A CMIF=0\"" nop bsf PORTB,0 ; drive comp 1 input high .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f873A m6 C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f873A CMIF=1\"" nop bcf PIR2,CMIF bsf STATUS,RP0 bsf CMCON,C1INV ; invert output bsf CMCON,C2INV bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f873A m6 invert C1OUT=1 C2OUT=0\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f873A CMIF=1\"" nop bcf PIR2,CMIF bsf PORTB,1 ; drive comp 2 input high bcf PORTB,0 ; drive comp 1 input low .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f873A m6 new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f873A CMIF=1\"" nop bcf PIR2,CMIF movlw 0x06 ; comparater mux reference normal output bsf STATUS,RP0 movwf CMCON movf CMCON,W ; This updates compare value bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f873A m6 invert normal C1OUT=1 C2OUT=0\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f873A CMIF=1\"" nop bcf PIR2,CMIF bsf STATUS,RP0 bsf PIE2,CMIE ; enable Comparator interupts bcf STATUS,RP0 bsf INTCON,PEIE ; enable Periperal inturrupts bsf INTCON,GIE ; and globale interupts bsf PORTB,0 ; drive comp1 input high nop nop goto FAILED ; no interrupt done1: ; ; mode 4 - Two Common reference Comparators ; movlw 0x08 movwf PORTB ; Both Comparator true movlw CMODE4 bsf STATUS,RP0 movwf CMCON bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m4 C1OUT=1 C2OUT=1\"" nop movlw 0x03 movwf PORTB .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f873A m4 C1OUT=0 C2OUT=0\"" nop movlw 0x07 movwf PORTB .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f873A m4 bit 2 C1OUT=0 C2OUT=0\"" nop movlw 0x0c movwf PORTB .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m4 bit 2 C1OUT=1 C2OUT=1\"" nop ; ; mode 2 - Two independant Comparators ; movlw 0x05 movwf PORTB movlw CMODE2 bsf STATUS,RP0 movwf CMCON bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f873A m2 C1OUT=0 C2OUT=1\"" nop movlw 0x0a movwf PORTB .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f873A m2 C1OUT=1 C2OUT=0\"" nop movlw 0x0c movwf PORTB .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m2 C1OUT=1 C2OUT=1\"" nop ; ; mode 1 - One independant Comparator with output ; bsf STATUS,RP0 movlw 0x0f ; RA3-RA0 are inputs movwf TRISA movlw 0xf0 ; RB4, RB5 are inputs movwf TRISB movlw CMODE1 movwf CMCON bcf STATUS,RP0 movlw 0x01 movwf PORTB .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f873A m1 C1OUT=0 C2OUT=0\"" nop .assert "(porta & 0x10) == 0x00, \"FAILED 16f873A m1 porta4=0\"" nop .assert "(portb & 0x10) == 0x00, \"FAILED 16f873A m1 portb4=0\"" nop movlw 0x08 movwf PORTB .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f873A m1 C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x10) == 0x10, \"FAILED 16f873A m1 porta4=1\"" nop .assert "(portb & 0x10) == 0x10, \"FAILED 16f873A m1 portb4=1\"" nop movlw 0x0c movwf PORTB .assert "(cmcon & 0xc0) == 0x40, \"FAILED m1 16f873A AN2=1 C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x10) == 0x10, \"FAILED m1 16f873A AN2=1 porta4=1\"" nop .assert "(portb & 0x10) == 0x10, \"FAILED m1 16f873A AN2=1 portb4=1\"" nop bsf STATUS,RP0 bsf CMCON,C2INV ; Invert Comp 2 should have no effect bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x40, \"FAILED m1 16f873A C2INV=1 C1OUT=1\"" nop .assert "(porta & 0x10) == 0x10, \"FAILED m1 16f873A C2INV=1 porta4=1\"" nop .assert "(portb & 0x10) == 0x10, \"FAILED M1 16f873A C2INV=1 portb4=1\"" nop bsf STATUS,RP0 bcf CMCON,C2INV ; Invert Comp 1 only bsf CMCON,C1INV bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x00, \"FAILED m1 16f873A C1INV=1 C1OUT=1\"" nop .assert "(porta & 0x10) == 0x00, \"FAILED m1 16f873A C1INV=1 porta4=0\"" nop .assert "(portb & 0x10) == 0x00, \"FAILED m1 16f873A C1INV=1 portb4=0\"" nop ; ; mode 5 - Two Common reference Comparators with outputs ; bsf STATUS,RP0 movlw 0x0f ; RA3-RA0 are inputs movwf TRISA movlw 0x30 ; RB4, RB5 are inputs movwf TRISB bcf STATUS,RP0 movlw 0x08 movwf PORTB movlw CMODE5 ; Two common ref Comparators with output bsf STATUS,RP0 movwf CMCON bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m5 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"FAILED 16f873A m5 porta4=1 porta5=1\"" nop .assert "(portb & 0x30) == 0x30, \"FAILED 16f873A m5 portb4=1 portb5=1\"" nop movlw 0x03 movwf PORTB .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f873A m5 C1OUT=0 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x00, \"FAILED 16f873A m5 porta4=0 porta5=0\"" nop .assert "(portb & 0x30) == 0x00, \"FAILED 16f873A m5 portb4=0 portb5=0\"" nop movlw CMODE5|0x10 ; invert COMP1 output bsf STATUS,RP0 movwf CMCON bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f873A m5 C1INV=1 C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"FAILED 16f873A m5 C1INV=1 porta4=1 porta5=0\"" nop .assert "(portb & 0x30) == 0x10, \"FAILED 16f873A m5 C1INV=1 portb4=1 portb5=0\"" nop movlw CMODE5|0x30 ; invert COMP1 & COMP2 output bsf STATUS,RP0 movwf CMCON bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m5 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"FAILED 16f873A m5 C1INV=1 C2INV=1 porta4=1 porta5=1\"" nop .assert "(portb & 0x30) == 0x30, \"FAILED 16f873A m5 C1INV=1 C2INV=1 portb4=1 portb5=1\"" nop ; ; mode 3 - Two independant Comparators with outputs ; movlw 0x05 movwf PORTB movlw CMODE3 bsf STATUS,RP0 movwf CMCON bcf STATUS,RP0 .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f873A m3 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"FAILED 16f873A m3 porta4=0 porta5=1\"" nop .assert "(portb & 0x30) == 0x20, \"FAILED 16f873A m3 portb4=0 portb5=1\"" nop movlw 0x0a movwf PORTB .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f873A m3 C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"FAILED 16f873A m3 porta4=1 porta5=0\"" nop .assert "(portb & 0x30) == 0x10, \"FAILED 16f873A m3 portb4=1 portb5=0\"" nop movlw 0x0c movwf PORTB .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f873A m3 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"FAILED 16f873A m3 porta4=1 porta5=1\"" nop .assert "(portb & 0x30) == 0x30, \"FAILED 16f873A m3 portb4=1 portb5=1\"" nop .assert "\"*** PASSED Comparator on 16f873A\"" goto $ FAILED: .assert "\"*** FAILED Comparator no interupt 16f873A\"" goto $ end gpsim-0.30.0/regression/comparator/compar_10f204.asm0000664000076400007640000002141613041763600017056 00000000000000 ; 10f204 gpsim regression test ; ; The purpose of this test is to verify that the 'F204 ; is implemented correctly. Here's a list of specific things ; tested: ; ; 1) Reset conditions ; 2) WDT ; 3) Sleep ; 4) Wakeup on PIN change. ; 5) Comparator. list p=10f204 include include __CONFIG _WDT_ON & _MCLRE_ON radix dec ; Printf Command .command macro x .direct "C", x endm GPR_DATA UDATA ResetSequence RES 1 optionShadow RES 1 GLOBAL optionShadow, ResetSequence ; Define the reset conditions to be checked. eRSTSequence_PowerOnReset equ 1 eRSTSequence_AwakeMCLR equ 2 eRSTSequence_AwakeWDT equ 3 eRSTSequence_AwakeIO equ 4 eRSTSequence_WDTTimeOut equ 5 ;---------------------------------------------------------------------- ; ********************* STARTUP LOCATION *************************** ;---------------------------------------------------------------------- START CODE 0x000 ; ; +-------------------+ ; 1 |o | 6 ; ------|GP0/CIN+ GP3/MCLR|------ ; 2 | | 5 ; ---|VSS 10F204 VDD|--- ; 3 | | 4 ; ------|GP1/CIN- GP2/COUT|------ ; | | ; +-------------------+ ; ;############################################################ ;# Create a stimulus to simulate a switch ; .sim "module lib libgpsim_modules" .sim "module load pulsegen MCLR" .sim "module load pullup VP" .sim "module load pullup VN" .sim "MCLR.initial = 5.0" .sim "VP.voltage = 5.0" .sim "VP.resistance = 1.0e3" .sim "VN.voltage = 5.0" .sim "VN.resistance = 1.0e3" .sim "MCLR.xpos=250.0" .sim "MCLR.ypos=85.0" .sim "VP.xpos=250.0" .sim "VP.ypos=130.0" .sim "VN.xpos=250.0" .sim "VN.ypos=180.0" ;############################################################ .sim "node nMCLR" .sim "attach nMCLR gpio3 MCLR.pin" .sim "node nVP" .sim "attach nVP gpio0 VP.pin" .sim "node nVN" .sim "attach nVN gpio1 VN.pin" ;############################################################ ; define symbols that can be used in the assertion expressions. .sim "symbol CHigh=4" .sim "symbol CLow=0" .sim "symbol Cexp=0" .sim "symbol CMask=4" ;############################################################ .sim "symbol resetCounter=1" ; NOT_GPWU = 0 - Enable wakeup if I/O pins 0,1, or 3 change states ; NOT_GPPU = 1 - Disable weak pullups on I/O pins 0,1, and 3 ; TOCS = 0 - Let the clock source for TMR0 be the internal fosc/4 ; TOSE = 0 - don't care - TMR0 source edge. ; PSA = 1 - assign Prescale to the WDT ; PS2:0 = 000 - prescale = 2^0=1 .sim "optionShadow=8" ; PSA=1 .sim "ResetSequence=0" .sim ".BreakOnReset = false" ; Set a cycle break point far in the future in case the resets fail. .sim "break c 0x1000000" bSWITCH equ 0 .assert "option==0xff" .assert "(tris&0x3f)==0x3f" MOVWF OSCCAL ; put calibration into oscillator cal reg ; OPTION register setup MOVF optionShadow,W ;optionShadow is initialized by the gpsim script OPTION ; GPIO setup ; If this is a PowerOn reset, then the state of the GPIO output register ; is unknown. If this is not a PowerOn reset then the GPIO pins have ; the same state they had prior to the reset. ; ; TRIS register setup - The I/O pins are always configured as Inputs after ; any reset. MOVLW (1< /MCLR while sleeping goto PowerOnReset ;/TO=1, /PD=1 ==> Power has just been applied TO_is_low BTFSS STATUS,NOT_PD goto AwakeWDT ;/TO=0, /PD=0 ==> WDT while sleeping goto WDTTimeOut ;/TO=0, /PD=1 ==> WDT while not sleeping ;======================================================================== ; toggleGP2 ; ; The purpose of this code is to write a 1 and then a 0 to GP2. The GP2 ; output pin is then checked. Note that the assertion expression are ; parametrically defined. toggleGP2: movf GPIO,W iorlw 1< VN and verify that the output doesn't change due to this .command "VN.voltage=0.0" .command "VP.voltage=5.0" nop .assert "(gpio & (1<<2))==0,\"*** FAILED Comparator test\"" ; Now toggle GPIO and verify that we can write to the port. nop .command "Cexp=CHigh" call toggleGP2 ; Make VP < VN and verify that the output doesn't change .command "VN.voltage=0.0" .command "VP.voltage=5.0" nop ; Toggle GPIO again and verify that we can still write to the port. call toggleGP2 ; Now turn on the comparator movlw (1< VN and verify the comparator output reflects this .command "VN.voltage=0.0" .command "VP.voltage=5.0" nop .assert "(gpio & (1<<2))==(1<<2),\"*** FAILED Comparator test\"" call delay ; verify that GPIO2 cannot be written to .command "CMask=0" call toggleGP2 ; make VP < VN .command "VN.voltage=5.0" .command "VP.voltage=0.0" nop .assert "(gpio & (1<<2))==0,\"*** FAILED Comparator test\"" call delay ; verify again that GPIO2 can't be written to. .command "Cexp=0" call toggleGP2 nop ; toggle the comparator output polarity and repeat the above tests. bcf CMCON0,POL .assert "(gpio & (1<<2))==(1<<2),\"*** FAILED Comparator test\"" nop .command "Cexp=1<<2" call toggleGP2 .command "VN.voltage=0.0" .command "VP.voltage=5.0" nop .assert "(gpio & (1<<2))==0,\"*** FAILED Comparator test\"" nop .command "Cexp=0" call toggleGP2 ;turn off the comparator output bsf CMCON0,NOT_COUTEN .command "Cexp=1<<2" .command "CMask=1<<2" call toggleGP2 .assert "\"*** PASSED 10F204 Comparator test\"" nop ;======================================================================== ; ; AwakeWDT - WDT timed out while we were sleeping. ; ;======================================================================== AwakeWDT: .assert "\"*** FAILED -- Unexpected WDT Reset\"" nop ;======================================================================== ; ; WDTTimeOut - WatchDog timer timed out while we were awake. ; ;======================================================================== WDTTimeOut: .assert "\"*** FAILED -- Unexpected WDT timeout\"" nop ;======================================================================== ; ; AwakeIO - an I/O pin changed states to awaken us from sleep. ; ;======================================================================== AwakeIO: .assert "\"*** FAILED -- Unexpected Wakeup on I/O pin change\"" nop ;======================================================================== ; ; AwakeMCLR - MCLR went low while we were sleeping. ; ;======================================================================== AwakeMCLR: .assert "\"*** FAILED -- Unexpected /MCLR Reset\"" nop .assert "\"*** PASSED 12c509 Sleep and Reset test\"" done: goto done ;======================================================================== delay: delay10: goto delay8 delay8: goto delay6 delay6: goto delay4 delay4: return ;======================================================================== ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0xff ; processor reset vector OSC_CAL_VALUE EQU 0x80 MOVLW OSC_CAL_VALUE end gpsim-0.30.0/regression/comparator/compar_873a.stc0000664000076400007640000000110013041763600016721 00000000000000 #set verbose 1 load compar_873a.cod U1 # Module libraries: module library libgpsim_modules # Modules: U1.xpos=84. U1.ypos=24. module load pullup PU1 PU1.resistance=10000. module load pulldown PD2 PD2.resistance=10000. module load pullup PU2 # Connections: node nb0 attach nb0 porta0 portb0 PU1.pin PD2.pin #attach nb0 porta0 portb0 node nb1 attach nb1 porta1 portb1 node nb2 attach nb2 porta2 portb2 node nb3 attach nb3 porta3 portb3 node nb4 #attach nb4 porta4 portb4 PU2.pin attach nb4 porta4 portb4 portc4 node nb5 attach nb5 porta5 portb5 portc5 # End. gpsim-0.30.0/regression/comparator/Makefile0000664000076400007640000000070613041763600015636 00000000000000include ../make.regression all : compar_873a.cod compar_628.cod compar_877a.cod compar_10f204.cod \ compar_882.cod compar_26k22.cod compar_2321.cod compar_6520.cod %.cod : %.o gplink --map -o $@ $< sim: sim_compar_628 sim_compar_873a sim_compar_877a sim_compar_10f204 \ sim_compar_882 sim_compar_26k22 sim_compar_2321 sim_compar_6520 \ sim_compar_26k22 sim_compr_873a: compar_873a.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=compar_873a.stc gpsim-0.30.0/regression/comparator/compar_6520.asm0000664000076400007640000003073313041763600016640 00000000000000 ;; Comparator test ;; ;; The purpose of this program is to verify the ;; comparator module of the processor list p=18f6520 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros CONFIG OSC=RC ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 temp RES 1 w_temp RES 1 status_temp RES 1 cmp_int RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR2,CMIF goto icm1 goto exit_int icm1: bcf PIR2,CMIF bsf cmp_int,0 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "p18f6520.xpos = 60" .sim "p18f6520.ypos = 84" .sim "module load pullup C1P" .sim "C1P.capacitance = 0" .sim "C1P.resistance = 10000" .sim "C1P.voltage = 1" .sim "C1P.xpos = 72" .sim "C1P.ypos = 24" .sim "module load pullup C1N" .sim "C1N.capacitance = 0" .sim "C1N.resistance = 10000" .sim "C1N.voltage = 2.5" .sim "C1N.xpos = 228" .sim "C1N.ypos = 36" .sim "module load pullup C2P" .sim "C2P.capacitance = 0" .sim "C2P.resistance = 10000" .sim "C2P.voltage = 2.8" .sim "C2P.xpos = 252" .sim "C2P.ypos = 96" .sim "module load pullup C2N" .sim "C2N.capacitance = 0" .sim "C2N.resistance = 10000" .sim "C2N.voltage = 2" .sim "C2N.xpos = 228" .sim "C2N.ypos = 144" .sim "node c1p" .sim "attach c1p C1P.pin portf5" .sim "node c1n" .sim "attach c1n C1N.pin portf6" .sim "node c2p" .sim "attach c2p C2P.pin portf3" .sim "node c2n" .sim "attach c2n C2N.pin portf4" .assert "cmcon == 0x07, \"FAILED 18f6520 CMCON POR\"" ; Rest value nop clrf PIR2 movlw CMODE7 ; turn off comparator movwf CMCON movlw 0xff movwf ADCON1 ; analog off all channels movlw 0x78 ; RF3-RF6 are inputs movwf TRISF ; mode 1 - one independant comparator with output movlw CMODE1 movwf CMCON call c1_out nop ; ; mode 2 - two independant comparators ; movlw CMODE2 movwf CMCON call ind_comp nop ; ; Two Independent Comparators with Outputs ; movlw CMODE3 movwf CMCON call ind_comp_out nop ; Two Common Reference(C1+) Comparators ; movlw CMODE4 movwf CMCON call ref_com nop ; Two Common Reference(C1+) Comparators with output ; movlw CMODE5 movwf CMCON call ref_com_out nop ; ; test mode - Four Inputs muxed to two comparators with Vref ; movlw CMODE6 ; Comparator mux reference movwf CMCON call mux_vref nop .assert "\"*** PASSED Comparator on 18f6520\"" goto $ ; One Independent Comparator with Output c1_out: ; C1IN- (2.5) ; C1IN+ (1.0) thus C1 out=0 ; C2in- (2.0) ; C2IN+ (2.8) but C2 off so out=0 .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 18f6520 c1_out, c1out=0\"" nop .assert "(portf & 0x06) == 0x00, \"*** FAILED 18f6520 c1_out, OUT1=0 OUT2=0\"" nop bsf CMCON,C1INV .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f6520 c1_out, c1out=1\"" nop .assert "(portf & 0x06) == 0x04, \"*** FAILED 18f6520 c1_out, OUT1=1 OUT2=0\"" nop ; C1IN- (2.5) ; C1IN+ (3.1) C1+ > C1- with invert thus C1 out=0 .command "C1P.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 18f6520 c1_out INVERT , c1out=0\"" nop .assert "(portf & 0x06) == 0x00, \"*** FAILED 18f6520 c1_out, INVERT OUT1=0 OUT2=0\"" nop return ; Two independent Comparators ind_comp: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f6520 2 ind comp CIS=0 C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f6520 2 ind comp CIS=1 C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f6520 2 ind comp C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f6520 2 ind comp C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"FAILED 18f6520 2 ind comp C1OUT=0 C2OUT=0\"" nop return ; Two independent Comparators with outputs ind_comp_out: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f6520 ind_comp_out CIS=0 C1OUT=1 C2OUT=1\"" nop .assert "(portf & 0x06) == 0x06, \"*** FAILED 18f6520 ind_comp_out CIS=0 port C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f6520 ind_comp_out CIS=1 C1OUT=1 C2OUT=1\"" nop .assert "(portf & 0x06) == 0x06, \"*** FAILED 18f6520 ind_comp_out CIS=1 port C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f6520 ind_comp_out C1OUT=1 C2OUT=0\"" nop .assert "(portf & 0x06) == 0x04, \"*** FAILED 18f6520 ind_comp_out port C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f6520 ind_comp_out C1OUT=0 C2OUT=1\"" nop .assert "(portf & 0x06) == 0x02, \"*** FAILED 18f6520 ind_comp_out port C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 18f6520 ind_comp_out C1OUT=0 C2OUT=0\"" nop .assert "(portf & 0x06) == 0x00, \"*** FAILED 18f6520 ind_comp_out port C1OUT=0 C2OUT=0\"" nop return ; ; Four Inputs muxed to two comparators with Vref ; mux_vref: .command "C1P.voltage = 1.0" nop .command "C1N.voltage = 2.5" nop .command "C2P.voltage = 2.8" nop .command "C2N.voltage = 2.0" nop ; C1IN- = 2.5 + = 2.29 out = 0 ; C2IN- = 2.0 + = 2.29 out = 1 movlw 0xAB ; enable Vref 11 low range 2.29v movwf CVRCON .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f6520 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 18f6520 mux with vref CMIF=1\"" nop clrf PIR2 movlw 0x8B ; enable Vref 11 high range 2.92v BANKSEL CVRCON movwf CVRCON ; C1IN- = 2.5 + = 2.92 out = 1 ; C2IN- = 2.0 + = 2.92 out = 1 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f6520 mux with vref C1OUT=1 C2OUT=1\"" nop movlw 0x03 movwf TRISC .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 18f6520 mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 18f6520 CMIF=1\"" nop bcf PIR2,CMIF .assert "(pir2 & 0x40) == 0x00, \"FAILED 18f6520 CMIF=0\"" nop .command "C1N.voltage = 3.0" ; drive comp1 low (C1IN- > Vref) nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f6520 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 18f6520 CMIF=1 C1 change\"" nop bcf PIR2,CMIF bsf CMCON,C1INV ; invert output bsf CMCON,C2INV .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f6520 mux with vref invert C1OUT=1 C2OUT=0\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 40f6520 CMIF=1\"" nop bcf PIR2,CMIF .command "C2N.voltage = 3.5" ; C2IN- > Vref nop .command "C1N.voltage = 2.5" ; C1IN- < Vref nop .command "C1P.voltage = 3.1" ; C1IN+ > Vref nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 18f6520 mux with vref new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 40f6520 mux with vref CMIF=1 C1, C2 change\"" nop bsf CMCON,CIS ; switch pins .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f6520 mux with vref new inputs C1OUT=1 C2OUT=0\"" nop movlw 0xc7 ; clear invert, CIS bits andwf CMCON,F .assert "(cmcon & 0xc0) == 0x40, \"FAILED 18f6520 mux with vref invert normal C1OUT=1 C2OUT=0\"" nop clrf PIR2 clrf cmp_int bsf PIE2,CMIE ; enable Comparator interrupts bsf INTCON,PEIE ; enable Peripheral interrupts bsf INTCON,GIE ; and global interrupts bsf CMCON,C1INV ; generate an interrupt btfsc cmp_int,0 goto done1 nop .assert "\"*** FAILED Comparator no interrupt 18f6520\"" nop goto $ done1: return ; ; Two common reference Comparators ; ; C1IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com: .command "C2P.voltage = 0.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f6520 ref_com CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f6520 ref_com CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f6520 ref_com C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f6520 ref_com C1OUT=1 C2OUT=1\"" nop return ; ; Two common reference Comparators with outputs ; ; C1IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com_out: .command "C2P.voltage = 0.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f6520 ref_com_out CIS=0 C1OUT=0 C2OUT=1\"" nop .assert "(portf & 0x06) == 0x02, \"*** FAILED 18f6520 ref_com_out CIS=0 port C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 18f6520 ref_com_out CIS=1 C1OUT=0 C2OUT=1\"" nop .assert "(portf & 0x06) == 0x02, \"*** FAILED 18f6520 ref_com_out CIS=1 port C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 18f6520 ref_com_out C1OUT=1 C2OUT=0\"" nop .assert "(portf & 0x06) == 0x04, \"*** FAILED 18f6520 ref_com_out CIS=0 port C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 18f6520 ref_com_out C1OUT=1 C2OUT=1\"" nop .assert "(portf & 0x06) == 0x06, \"*** FAILED 18f6520 ref_com_out port C1OUT=1 C2OUT=1\"" nop return end gpsim-0.30.0/regression/comparator/compar_877a.asm0000664000076400007640000003130413041763600016725 00000000000000 ;; Comparator test ;; ;; The purpose of this program is to verify the ;; comparator module of the processor list p=16f877a ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmp_int RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR2,CMIF goto icm1 goto exit_int icm1: bcf PIR2,CMIF bsf cmp_int,0 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "p16f877a.xpos = 60" .sim "p16f877a.ypos = 84" .sim "module load pullup C1P" .sim "C1P.capacitance = 0" .sim "C1P.resistance = 10000" .sim "C1P.voltage = 1" .sim "C1P.xpos = 72" .sim "C1P.ypos = 24" .sim "module load pullup C1N" .sim "C1N.capacitance = 0" .sim "C1N.resistance = 10000" .sim "C1N.voltage = 2.5" .sim "C1N.xpos = 228" .sim "C1N.ypos = 36" .sim "module load pullup C2P" .sim "C2P.capacitance = 0" .sim "C2P.resistance = 10000" .sim "C2P.voltage = 2.8" .sim "C2P.xpos = 252" .sim "C2P.ypos = 96" .sim "module load pullup C2N" .sim "C2N.capacitance = 0" .sim "C2N.resistance = 10000" .sim "C2N.voltage = 2" .sim "C2N.xpos = 228" .sim "C2N.ypos = 144" .sim "node c1p" .sim "attach c1p C1P.pin porta3" .sim "node c1n" .sim "attach c1n C1N.pin porta0" .sim "node c2p" .sim "attach c2p C2P.pin porta2" .sim "node c2n" .sim "attach c2n C2N.pin porta1" .assert "cmcon == 0x07, \"FAILED 16f877a CMCON POR\"" ; Rest value nop BANKSEL PIR2 clrf PIR2 movlw CMODE7 ; turn off comparator BANKSEL CMCON movwf CMCON movlw 0x07 movwf ADCON1 ; analog off all channels movlw 0x0f ; RA0-RA3 are inputs movwf TRISA ; mode 1 - one independant comparator with output movlw CMODE1 movwf CMCON call c1_out nop ; ; mode 2 - two independant comparators ; movlw CMODE2 movwf CMCON call ind_comp nop ; ; Two Independent Comparators with Outputs ; movlw CMODE3 movwf CMCON call ind_comp_out nop ; Two Common Reference(C1+) Comparators ; movlw CMODE4 movwf CMCON call ref_com nop ; Two Common Reference(C1+) Comparators with output ; movlw CMODE5 movwf CMCON call ref_com_out nop ; ; test mode - Four Inputs muxed to two comparators with Vref ; movlw CMODE6 ; Comparator mux reference movwf CMCON call mux_vref nop .assert "\"*** PASSED Comparator on 16f877a\"" goto $ ; One Independent Comparator with Output c1_out: ; C1IN- (2.5) ; C1IN+ (1.0) thus C1 out=0 ; C2in- (2.0) ; C2IN+ (2.8) but C2 off so out=0 .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 16f877a c1_out, c1out=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f877a c1_out, OUT1=0 OUT2=0\"" nop bsf CMCON,C1INV .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 16f877a c1_out, c1out=1\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 16f877a c1_out, OUT1=1 OUT2=0\"" nop ; C1IN- (2.5) ; C1IN+ (3.1) C1+ > C1- with invert thus C1 out=0 .command "C1P.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 16f877a c1_out INVERT , c1out=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f877a c1_out, INVERT OUT1=0 OUT2=0\"" nop return ; Two independent Comparators ind_comp: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f877a 2 ind comp CIS=0 C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f877a 2 ind comp CIS=1 C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f877a 2 ind comp C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f877a 2 ind comp C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"FAILED 16f877a 2 ind comp C1OUT=0 C2OUT=0\"" nop return ; Two independent Comparators with outputs ind_comp_out: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 16f877a ind_comp_out CIS=0 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 16f877a ind_comp_out CIS=0 port C1OUT=1 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 16f877a ind_comp_out CIS=1 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 16f877a ind_comp_out CIS=1 port C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 16f877a ind_comp_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 16f877a ind_comp_out port C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f877a ind_comp_out C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 16f877a ind_comp_out port C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon & 0xc0) == 0x00, \"*** FAILED 16f877a ind_comp_out C1OUT=0 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f877a ind_comp_out port C1OUT=0 C2OUT=0\"" nop return ; ; Four Inputs muxed to two comparators with Vref ; mux_vref: .command "C1P.voltage = 1.0" nop .command "C1N.voltage = 2.5" nop .command "C2P.voltage = 2.8" nop .command "C2N.voltage = 2.0" nop ; C1IN- = 2.5 + = 2.29 out = 0 ; C2IN- = 2.0 + = 2.29 out = 1 movlw 0xAB ; enable Vref 11 low range 2.29v movwf CVRCON .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f877a mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f877a mux with vref CMIF=1\"" nop BANKSEL PIR2 clrf PIR2 movlw 0x8B ; enable Vref 11 high range 2.92v BANKSEL CVRCON movwf CVRCON ; C1IN- = 2.5 + = 2.92 out = 1 ; C2IN- = 2.0 + = 2.92 out = 1 .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f877a mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(cmcon & 0xc0) == 0xc0, \"FAILED 16f877a mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f877a CMIF=1\"" nop BANKSEL PIR2 bcf PIR2,CMIF .assert "(pir2 & 0x40) == 0x00, \"FAILED 16f877a CMIF=0\"" nop .command "C1N.voltage = 3.0" ; drive comp1 low (C1IN- > Vref) nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f877a mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 16f877a CMIF=1 C1 change\"" nop bcf PIR2,CMIF BANKSEL CMCON bsf CMCON,C1INV ; invert output bsf CMCON,C2INV .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f877a mux with vref invert C1OUT=1 C2OUT=0\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 40f2321 CMIF=1\"" nop BANKSEL PIR2 bcf PIR2,CMIF .command "C2N.voltage = 3.5" ; C2IN- > Vref nop .command "C1N.voltage = 2.5" ; C1IN- < Vref nop .command "C1P.voltage = 3.1" ; C1IN+ > Vref nop .assert "(cmcon & 0xc0) == 0x80, \"FAILED 16f877a mux with vref new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x40) == 0x40, \"FAILED 40f2321 mux with vref CMIF=1 C1, C2 change\"" nop BANKSEL CMCON bsf CMCON,CIS ; switch pins .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f877a mux with vref new inputs C1OUT=1 C2OUT=0\"" nop movlw 0xc7 ; clear invert, CIS bits andwf CMCON,F .assert "(cmcon & 0xc0) == 0x40, \"FAILED 16f877a mux with vref invert normal C1OUT=1 C2OUT=0\"" nop BANKSEL PIR2 clrf PIR2 clrf cmp_int BANKSEL PIE2 bsf PIE2,CMIE ; enable Comparator interrupts bsf INTCON,PEIE ; enable Peripheral interrupts bsf INTCON,GIE ; and global interrupts BANKSEL CMCON bsf CMCON,C1INV ; generate an interrupt btfsc cmp_int,0 goto done1 nop .assert "\"*** FAILED Comparator no interrupt 16f877a\"" nop goto $ done1: return ; ; Two common reference Comparators ; ; C1IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com: .command "C2P.voltage = 0.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f877a ref_com CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f877a ref_com CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 16f877a ref_com C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 16f877a ref_com C1OUT=1 C2OUT=1\"" nop return ; ; Two common reference Comparators with outputs ; ; C1IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 ref_com_out: .command "C2P.voltage = 0.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.5" nop .command "C1N.voltage = 3.1" nop .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f877a ref_com_out CIS=0 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 16f877a ref_com_out CIS=0 port C1OUT=0 C2OUT=1\"" nop bsf CMCON,CIS .assert "(cmcon & 0xc0) == 0x80, \"*** FAILED 16f877a ref_com_out CIS=1 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 16f877a ref_com_out CIS=1 port C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon & 0xc0) == 0x40, \"*** FAILED 16f877a ref_com_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 16f877a ref_com_out CIS=0 port C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon & 0xc0) == 0xc0, \"*** FAILED 16f877a ref_com_out C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 16f877a ref_com_out port C1OUT=1 C2OUT=1\"" nop return end gpsim-0.30.0/regression/comparator/compar_882.asm0000775000076400007640000001354713116677005016602 00000000000000 list p=16f882 include include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F882. ;; Specifically, the comparator is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR int_cm1 RES 1 int_cm2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f882.xpos = 72" .sim "p16f882.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" .sim "V2.voltage = 2.5" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 100.0" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "V3.voltage = 4.5" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" movlw 9 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN3 BANKSEL TRISA movwf TRISA movwf TRISC bsf INTCON,GIE ;Global interrupts bsf INTCON,PEIE ;Peripheral interrupts BANKSEL PIE2 bsf PIE2,C1IE ;CM1 interrupts call test_compar call test_tot1 ; can C2 increment T1 .assert "\"*** PASSED 16F882 comparator test\"" goto $-1 ; ; Test Comparator2 gate control of Timer 1 ; test_tot1: BANKSEL T1CON movlw (1< include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F882. ;; Specifically, the comparator is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR int_cm1 RES 1 int_cm2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f882.xpos = 72" .sim "p16f882.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" .sim "V2.voltage = 2.5" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 100.0" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "V3.voltage = 4.5" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" movlw 9 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN3 BANKSEL TRISA movwf TRISA movwf TRISC bsf INTCON,GIE ;Global interrupts bsf INTCON,PEIE ;Peripheral interrupts BANKSEL PIE2 bsf PIE2,C1IE ;CM1 interrupts call test_compar call test_tot1 ; can C2 increment T1 .assert "\"*** PASSED 16F882 comparator test\"" goto $-1 ; ; Test Comparator2 gate control of Timer 1 ; test_tot1: BANKSEL T1CON movlw (1< include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _LVP_OFF & _MCLRE_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16F883. ;; Specifically, I2C errorlevel -302 ; Printf Command .command macro x .direct "C", x endm _ClkIn equ 8000000 ; Input Clock Frequency _ClkOut equ (_ClkIn >> 2) ; ; Compute the delay constants for setup & hold times ; _40uS_Delay set (_ClkOut/250000) _47uS_Delay set (_ClkOut/212766) _50uS_Delay set (_ClkOut/200000) TRUE equ 1 FALSE equ 0 LSB equ 0 MSB equ 7 #define SCL_PIN 2 #define SDA_PIN 3 #define I2CPORT PORTB #define _SCL_D I2CPORT,SCL_PIN #define _SCL TRISB,SCL_PIN #define _SDA TRISB,SDA_PIN #define T0IE TMR0IE #define T0IF TMR0IF #define _ENABLE_BUS_FREE_TIME TRUE #define _CLOCK_STRETCH_CHECK TRUE #define _OPTION_INIT (0xC0 | 0x02) ; Prescaler to TMR0 for Appox 1 mSec timeout ;***************************************************************************** ; I2C Bus Status Reg Bit Definitions ;***************************************************************************** #define _Bus_Busy Bus_Status,0 #define _Abort Bus_Status,1 #define _Txmt_Progress Bus_Status,2 #define _Rcv_Progress Bus_Status,3 #define _Txmt_Success Bus_Status,4 #define _Rcv_Success Bus_Status,5 #define _Fatal_Error Bus_Status,6 #define _ACK_Error Bus_Status,7 ;***************************************************************************** ; I2C Bus Contro Register ;***************************************************************************** #define _10BitAddr Bus_Control,0 #define _Slave_RW Bus_Control,1 #define _Last_Byte_Rcv Bus_Control,2 #define _SlaveActive Bus_Control,6 #define _TIME_OUT_ Bus_Control,7 RELEASE_BUS MACRO bsf STATUS,RP0 ; select page 1 bsf _SDA ; tristate SDA bsf _SCL ; tristate SCL ; bcf _Bus_Busy ; Bus Not Busy, TEMP ????, set/clear on Start & Stop ENDM ;**************************************************************************** ; A MACRO To Load 8 OR 10 Bit Address To The Address Registers ; ; SLAVE_ADDRESS is a constant and is loaded into the SlaveAddress Register(s) ; depending on 8 or 10 bit addressing modes ;**************************************************************************** LOAD_ADDR_10 MACRO SLAVE_ADDRESS bsf _10BitAddr ; Slave has 10 bit address movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ; load low byte of address movlw (((SLAVE_ADDRESS >> 7) & 0x06) | 0xF0) ; 10 bit addr 11110AA0 movwf SlaveAddr+1 ; hi order address ENDM LOAD_ADDR_8 MACRO SLAVE_ADDRESS bcf _10BitAddr ; Set for 8 Bit Address Mode movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ENDM ;**************************************************************************** ; I2C_WRITE_SUB ; ; Writes a message just like I2C_WRITE, except that the data is preceeded ; by a sub-address to a slave device. ; Eg. : A serial EEPROM would need an address of memory location for ; Random Writes ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ (constant) ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; _Sub_Address_ Sub-address of Slave (constant) ; ; Sequence : ; S-SlvAW-A-SubA-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag ; ; Returns : WREG = 1 on success, else WREG = 0 ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ; COMMENTS : ; I2C_WR may prove to be more efficient than this macro in most situations ; Advantages will be found for Random Address Block Writes for Slaves with ; Auto Increment Sub-Addresses (like Microchip's 24CXX series Serial ; EEPROMS) ; ;**************************************************************************** I2C_WR_SUB MACRO _BYTES_, _SourcePointer_, _Sub_Address_ movlw (_BYTES_ + 1) movwf tempCount movlw (_SourcePointer_ - 1) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -1) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -1) call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W movwf (_SourcePointer_ - 1) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM I2C_WR_SUB2 MACRO _BYTES_, _SourcePointer_, _Sub_Address_, _Sub_Address2_ movlw (_BYTES_ + 2) movwf tempCount movlw (_SourcePointer_ - 2) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -2) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -2) movlw (_SourcePointer_ - 1) movwf FSR movlw _Sub_Address2_ movwf INDF movlw (_SourcePointer_ - 2) movwf FSR call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W ; movwf (_SourcePointer_ - 2) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM ;**************************************************************************** ; I2C_WRITE ; ; A basic macro for writing a block of data to a slave ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; ; Sequence : ; S-SlvAW-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ;**************************************************************************** I2C_WR MACRO _BYTES_, _SourcePointer_ movlw _BYTES_ movwf tempCount movlw _SourcePointer_ movwf FSR call _i2c_block_write call TxmtStopBit ; Issue a stop bit for slave to end transmission ENDM ;***************************************************************************** ; ; I2C_READ ; ; The basic MACRO/procedure to read a block message from a slave device ; ; Parameters : ; _BYTES_ : constant : #of bytes to receive ; _DestPointer_ : destination pointer of RAM (File Registers) ; ; Sequence : ; S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; If last byte, then Master will NOT Acknowledge (send NACK) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ;***************************************************************************** I2C_READ MACRO _BYTES_, _DestPointer_ movlw (_BYTES_ -1) movwf tempCount ; -1 because, the last byte is used out of loop movlw _DestPointer_ movwf FSR ; FIFO destination address pointer call _i2c_block_read ENDM ;*************************************************************************** ; ; I2C_READ_SUB ; This MACRO/Subroutine reads a message from a slave device preceeded by ; a write of the sub-address. ; Between the sub-addrers write & the following reads, a STOP condition ; is not issued and a "REPEATED START" condition is used so that an other ; master will not take over the bus, and also that no other master will ; overwrite the sub-address of the same salve. ; ; This function is very commonly used in accessing Random/Sequential reads ; from a memory device (e.g : 24Cxx serial of Serial EEPROMs from Microchip). ; ; Parameters : ; _BYTES_ # of bytes to read ; _DestPointer_ The destination pointer of data to be received. ; _BubAddress_ The sub-address of the slave ; ; Sequence : ; S-SlvAW-A-SubAddr-A-S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; ;*************************************************************************** I2C_READ_SUB MACRO _BYTES_, _DestPointer_, _SubAddress_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM I2C_READ_SUB2 MACRO _BYTES_, _DestPointer_, _SubAddress_, _SubAddress2_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address movlw _SubAddress2_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- INT_VAR UDATA IO_buf RES 10 IN_buf RES 10 GPR_DATA UDATA_SHR w_temp RES 1 status_temp RES 1 SlaveAddr RES 1 ; Slave Addr must be loader into this reg SlaveAddrHi RES 1 ; for 10 bit addressing mode DataByte RES 1 ; load this reg with the data to be transmitted BitCount RES 1 ; The bit number (0:7) transmitted or received Bus_Status RES 1 ; Status Reg of I2C Bus for both TXMT & RCVE Bus_Control RES 1 ; control Register of I2C Bus DelayCount RES 1 DataByteCopy RES 1 ; copy of DataByte for Left Shifts (destructive) SubAddr RES 1 ; sub-address of slave (used in I2C_HIGH.ASM) SrcPtr RES 1 ; source pointer for data to be transmitted tempCount RES 1 ; a temp variable for scratch RAM StoreTemp_1 RES 1 ; a temp variable for scratch RAM, do not disturb contents _End_I2C_Ram RES 1 ; unused, only for ref of end of RAM allocation ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 if _CLOCK_STRETCH_CHECK ; TMR0 Interrupts enabled only if Clock Stretching is Used btfss INTCON,T0IF goto check ; other Interrupts bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,T0IF goto int_ret endif check: btfss PIR1,SSPIF goto int_ret bcf PIR1,SSPIF call sspint int_ret: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "p16f883.xpos = 96" .sim "p16f883.ypos = 144" .sim "module load pu pu1" .sim "pu1.xpos = 276" .sim "pu1.ypos = 72" .sim "module load pu pu2" .sim "pu2.xpos = 276" .sim "pu2.ypos = 180" .sim "node n1" .sim "attach n1 portb3 pu1.pin portc4" ; ee.SCL" .sim "node n2" .sim "attach n2 portb2 pu2.pin portc3" ; ee.SDA" .sim "node n3" .sim "node n4" .sim "node n5" .sim "node n6" .sim "scope.ch0 = \"portc4\"" .sim "scope.ch1 = \"portc3\"" bsf STATUS,RP0 ; bank 1 movlw 0xf6 ; set internal RC to 8 Mhz movwf OSCCON clrf TRISA bsf PIE1,SSPIE ; allow SSP interrupts bsf INTCON,GIE ; allow interrupts bsf INTCON,PEIE ; allow interrupts banksel ANSEL clrf ANSEL clrf ANSELH banksel PORTA ; bsf PORTA,0 ; Write protect bsf PORTA,1 ; A0 movlw 0x10 movwf tempCount movlw IO_buf movwf FSR Fill_loop: movf FSR,W movwf INDF incf FSR,F decfsz tempCount,F goto Fill_loop movlw 0x09 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xaf movwf SSPMSK bcf STATUS,RP0 ; bank 0 movlw 0x36 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xa2 movwf SSPADD bcf STATUS,RP0 ; bank 0 call InitI2CBus_Master LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive .assert "\"*** FAILED I2C Slave not active\"" nop LOAD_ADDR_8 0xa2 ; I2C_WR_SUB 8, IO_buf, 0x0c I2C_WR_SUB2 8, IO_buf, 0x0c, 0x0c call TxmtStopBit ; Issue a stop bit to end transmission movf Bus_Status,W .assert "W == 0x10, \"*** FAILED I2C slave write status\"" nop poll_ready: LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive goto poll_ready ; slave not active yet nop ; ; write 0xa2 0x0c 0x0c to set an address ; write RSTART 0xa3 to initiate read ; read 8 bytes of data into ram starting at IN_buf ; LOAD_ADDR_8 0xa2 I2C_READ_SUB2 8, IN_buf, 0x0c, 0x0c nop bcf STATUS,RP0 ; bank 0 movf IN_buf,W .assert "W == 0xf5, \"*** FAILED I2C slave read data\"" nop movf Bus_Status,W .assert "W == 0x30, \"*** FAILED I2C slave 8 bit read status\"" nop ; ; write 8 bytes of data in slave 10bit mode ; bcf STATUS,RP0 ; bank 0 movlw 0x37 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0x06 movwf SSPADD bcf STATUS,RP0 ; bank 0 LOAD_ADDR_10 0x30c bcf PIR1,SSPIF I2C_WR 8, IO_buf btfss PIR1,SSPIF goto $-1 .assert "\"*** PASSED p16f883 I2C slave test \"" nop goto $ IsSlaveActive bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; bcf _SlaveActive btfss _ACK_Error ; skip if NACK, device is not present or not responding bsf _SlaveActive ; ACK received, device present & listening call TxmtStopBit return include "i2c_low.inc" _i2c_block_write: call TxmtStartBit ; send START bit bcf _Slave_RW ; set for write operation call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; _block_wr1_loop: btfss _Txmt_Success return movf INDF,W movwf DataByte ; start from the first byte starting at _DataPointer_ incf FSR, F call SendData ; send next byte, bus is our's ! decfsz tempCount, F goto _block_wr1_loop ; loop until desired bytes of data ; transmitted to slave return ; ;**************************************************************************** _i2c_block_read: call TxmtStartBit ; send START bit bsf _Slave_RW ; set for read operation bcf _Last_Byte_Rcv ; not a last byte to rcv call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set btfsc _Txmt_Success goto _block_rd1_loop ; end call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw FALSE ; Error : may be device not responding ; _block_rd1_loop: call GetData movf DataByte,W movwf INDF ;start receiving data, starting at Destination Pointer incf FSR, F decfsz tempCount, F goto _block_rd1_loop ; loop until desired bytes of data transmitted to slave bsf _Last_Byte_Rcv ; last byte to rcv, so send NACK call GetData movf DataByte,W movwf INDF call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw TRUE sspint: bsf STATUS,RP0 ; bank 1 btfsc SSPSTAT,R_W ; write test ? goto sspint_wr btfsc SSPSTAT,UA ; UA bit set goto sspint_ua bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return sspint_wr: bcf STATUS,RP0 ; bank 0 movlw 0xf5 ; byte to send movwf SSPBUF bsf SSPCON,CKP ; turn off clock stretch return sspint_ua: movlw 0x0c ; second byte address movwf SSPADD bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return end gpsim-0.30.0/regression/p16f88x/a2d.asm0000664000076400007640000001346013116673172014333 00000000000000 list p=16f882 include include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F882. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 global t1, t2, check ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F882 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f882.xpos = 72" .sim "p16f882.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; BANKSEL OPTION_REG bcf OPTION_REG,7 movlw 3 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F886. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F886 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f886.xpos = 72" .sim "p16f886.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN1 call rdprog BANKSEL TRISA movwf TRISA bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC errorlevel -302 variables UDATA 0x30 temp1 RES 1 temp2 RES 1 STARTUP CODE NOP goto start NOP NOP NOP PROG1 CODE ; start .sim "break c 0x100000" .sim "module lib libgpsim_modules" .sim "module load e24xx024 ee" .sim "module load pu pu1" .sim "module load pu pu2" .sim "node n1" .sim "attach n1 portc4 pu1.pin portb4 ee.SDA" ; SDA .sim "node n2" .sim "attach n2 portc3 pu2.pin portb1 ee.SCL" ; SCL .sim "node n3" .sim "attach n3 porta0 ee.WP" .sim "node n4" .sim "attach n4 porta1 ee.A0" .sim "node n5" .sim "attach n5 porta2 ee.A1" .sim "node n6" .sim "attach n6 porta3 ee.A2" .sim "scope.ch0 = \"portc3\"" .sim "scope.ch1 = \"portc4\"" .sim "pu1.xpos = 240." .sim "pu1.ypos = 336." .sim "pu2.xpos = 216." .sim "pu2.ypos = 24." .sim "ee.xpos = 48." .sim "ee.ypos = 180." .sim "p16f883.xpos = 240." .sim "p16f883.ypos = 84." call ProgInit ; Get everything running step-by-step call I2CSendResult call write_eeprom call is_ready call read_eeprom .command "dump e ee dump.hex" nop call is_ready call clr_eeprom .command "load e ee dump.hex" nop call is_ready call read_eeprom .assert "\"*** PASSED p16f883 I2C test\"" goto $ ;****************************** SUBROUTINES **************************** ;************************************************************************ START_I2C MACRO banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 banksel PORTA ENDM RSTART_I2C MACRO banksel SSPCON2 ; Generate I2C repeat start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 banksel PORTA ENDM STOP_I2C MACRO banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PORTA ENDM IDLE_WAIT_I2C MACRO banksel SSPCON2 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_W goto $-1 banksel PORTA ENDM ;****************** Initialize Registers and Variables ***************** ;************************************************************************ ProgInit banksel ANSEL clrf ANSEL clrf ANSELH banksel PORTA clrf PORTA ; Set all bits to zero on Port A banksel TRISA clrf TRISA bsf TRISB,4 banksel SSPCON movlw 0x09 ; set mask mode movwf SSPCON banksel SSPMSK movlw 0x1C movwf SSPMSK banksel SSPCON movlw 0x08 ; Set for I2C master mode movwf SSPCON banksel SSPADD movlw 0xff movwf SSPADD ; sspadd should be masked by SSPMSK banksel SSPCON movlw 0x08 ; Set for I2C master mode movwf SSPCON movlw 0x28 ; Enable I2C movwf SSPCON return ;************************************************************************ I2CSendResult banksel SSPCON2 ; Generate I2C start, bus collision bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 bsf SSPCON2,SEN bcf TRISB,1 IDLE_WAIT_I2C .assert "(pir2 & 0x08) == 0x08, \"FAILED BCLIF for start\"" nop banksel TRISB bsf TRISB,1 banksel PIR2 bcf PIR2,BCLIF banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN IDLE_WAIT_I2C .assert "(portc & 0x18) == 0, \"FAILED Start SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Start SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Start BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED Start S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x18) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,ACKDT bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 .assert "(portc & 0x18) == 0x10, \"FAILED ACKEN SCL low, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED ACKEN SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED ACKEN BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED ACKEN S bit set\"" nop bcf SSPCON2,ACKDT bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x18) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 .assert "(portc & 0x18) == 0x18, \"FAILED Stop SCL, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Stop SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Stop BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x10, \"FAILED Stop P bit set\"" nop return ; ; repeatedly send command to eeprom until an ACK ; is received back ; ; The call of delay is not required for operation of the code, ; but it speeds up the simulation with the GUI running. -- RRR ; is_ready banksel SSPCON movlw 0x04 movwf temp2 clrf temp1 call delay banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xa0 ; write command to eeprom call I2C_send_w call I2C_stop banksel SSPCON2 ; Generate I2C start btfsc SSPCON2,ACKSTAT goto is_ready banksel PIR2 bcf PIR2,BCLIF return write_eeprom_address banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xa0 ; write command to eeprom call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write command to eeprom ACK\"" nop .assert "(sspstat & 0x01) == 0x00, \"FAILED write to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write eeprom address call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write address to eeprom ACK\"" nop return write_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSPIF movlw 0x80 ; write data1 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x81 ; write data2 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return clr_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write data1 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write data2 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return read_eeprom call write_eeprom_address banksel SSPCON2 ; Generate I2C repeated start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 movlw 0xa1 ; Send address/read to eeprom banksel SSPBUF movwf SSPBUF banksel SSPCON2 ; wait for idle (ACKEN,RCEN,PEN,RSEN,SEN) == 0 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_W ; also R_W == 0 goto $-1 .assert "(sspstat & 0x01) == 0x00, \"FAILED address/read to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read data from eeprom btfsc SSPCON2,RCEN goto $-1 .assert "(pir1 & 0x08) == 0x08, \"FAILED RCEN SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RCEN BCLIF clear\"" nop .assert "(sspstat & 0x01) == 0x01, \"FAILED RCEN BF set\"" nop banksel SSPBUF movf SSPBUF,W .assert "W == 0x80, \"FAILED RCEN, read Data\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read next byte btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W .assert "W == 0x81, \"FAILED RCEN, read Data2\"" nop banksel SSPCON2 bsf SSPCON2,ACKDT ; send NACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 return I2C_stop banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 return delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return ;********************** Output byte in W via I2C bus ******************** ;************************************************************************ I2C_send_w banksel SSPBUF ; Second byte of data (middle) movwf SSPBUF banksel SSPSTAT btfsc SSPSTAT,R_W goto $-1 return end gpsim-0.30.0/regression/p16f88x/eusart.asm0000664000076400007640000001567013057432720015171 00000000000000 ;; EUSART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly when configured as an EUSART. ;; The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=16f884 include include __CONFIG _CONFIG1, _WDT_OFF & _MCLRE_ON & _INTRC_OSC_NOCLKOUT ; CONFIG WDT=OFF ; CONFIG MCLRE=ON, LPT1OSC=OFF, PBADEN=DIG, CCP2MX=RC1 errorlevel -302 radix dec BAUDHI equ ((100000/4)/48) BAUDLO equ 129 ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x70 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"*** FAILED sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=10e6" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" ; .sim "U1.xpos = 250.0" ; .sim "U1.ypos = 80.0" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. banksel TRISC bsf TRISC,7 ;RX is an input bsf TRISC,6 ;TX EUSART sets pin direction ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used banksel TXSTA movlw (1< 77 && tmr0 < 85, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop ; Disable interrupts because the following tests don't give good receive bytes bcf PIE1,RCIE banksel TXSTA bsf TXSTA,SENDB ; request a break sequence banksel PORTC btfss PORTC,6 ; Shouldn't happen just yet .assert "\"*** FAILED break sent too soon\"" nop clrf TMR0 movlw 0x55 movwf TXREG ; break is sent rather than this character call delay btfsc PORTC,6 ; Should happen by now .assert "\"*** FAILED to send break\"" nop btfss PORTC,6 ; Wait 'til through transmitting goto $-1 ; bra $-2 ; ; At 4800 baud each bit takes 0.208 msec. Output will be low for ; start + 12 bit times or 2.70 msec. With 10Mhz TMR0 / 64 is 106 TMR0 counts. movf TMR0,W .assert "tmr0 > 101 && tmr0 < 111, \"*** FAILED sync pulse\"" nop done: .assert "\"*** PASSED p16f884 E-Usart\"" goto $ tx_message: incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw 0x30 return delay: decfsz temp2,f goto delay return TransmitNextByte: banksel TXREG clrf rxFlag call tx_message movwf TXREG clrwdt rx_loop: btfss rxFlag,0 goto rx_loop ; clrf temp2 ; call delay ;; Delay between bytes. btfss PIR1,TXIF goto $-1 return end gpsim-0.30.0/regression/p16f88x/p16f887.asm0000664000076400007640000001336413116673474014720 00000000000000 list p=16f887 include include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F887. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F887 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f887.xpos = 72" .sim "p16f887.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16F887 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc2\"" ; P1A .sim "scope.ch1 = \"portd5\"" ; P1B .sim "scope.ch2 = \"portd6\"" ; P1C .sim "scope.ch3 = \"portd7\"" ; P1D .sim "scope.ch4 = \"portb4\"" .sim "node na0" .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 16f887 PWM test\"" goto $-1 pwm_shutdown BANKSEL CM1CON0 movlw (1< PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: banksel CCP1CON clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 banksel ANSEL clrf ANSEL ; turn ports to digital clrf ANSELH banksel CCPR1L movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF banksel TRISC ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; P1A bcf TRISD,5 ; P1B bcf TRISD,6 ; P1C bcf TRISD,7 ; P1D clrf PIE1 ; Disable peripheral interrupts movlw 0x03 ; Port B pull-up Tmr0 internal clock prescaler 16 movwf OPTION_REG banksel PIR1 ; Bank0 clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/p16f88x/p16f883.asm0000664000076400007640000001341713116673430014703 00000000000000 list p=16f883 include include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F883. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F883 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f883.xpos = 72" .sim "p16f883.ypos = 72" .sim "break c 0x100000" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BOR_OFF & _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F882. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F882 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f882.xpos = 72" .sim "p16f882.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL clrf ANSELH movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA bsf OSCCON,4 bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< ] " exit 0 fi case "$1" in *clean) DIRS='breakpoints instructions_12bit instructions_14bit instructions_16bit node_test p16f84 p18f452_ports p16f628 digital_stim analog_stim p12ce518 eeprom_wide epwm interrupts_14bit macro_test logic_test resistor usart_test txisr_test tmr0_16bit tmr1_16bit tmr3_16bit switch_test p18f comparator a2d psp ttl ccp ccp_628 wavegen spi i2c port_stim p12c509 wdt p12f675 p16f676 p16f690 p16f684 p1xf18xx p18f26k22 p16f91x' echo ${DIRS} for i in ${DIRS} ; do echo $i cd $i make clean cd .. done exit 0 ;; *) if [ $# -gt 0 ] then GPSIM_PATH=$1 export GPSIM_PATH fi ;; esac GPSIM_MODULE_PATH=$(pwd)/../modules/.libs export GPSIM_MODULE_PATH RT=./rt.sh # Basic breakpoint test ${RT} breakpoints sim # Instruction set simulation of the mid-range devices ${RT} instructions_14bit sim_instructions_14bit ${RT} instructions_14bit sim_branching #instruction set simulation for the 16bit cores: ${RT} instructions_16bit sim #instruction set simulation for the 12bit cores: ${RT} instructions_12bit sim ${RT} node_test sim #${RT} p12c509 it_12bit #${RT} p12c509 tmr0 ${RT} p16f84 sim ${RT} p18f452_ports sim #${RT} p16f628 p16f628 #${RT} p16f873 sim ${RT} digital_stim sim ${RT} analog_stim sim ${RT} register_stim sim ${RT} p12ce518 sim ${RT} eeprom_wide sim ${RT} interrupts_14bit sim ${RT} interrupts_16bit test_basic ${RT} interrupts_16bit test_priority ${RT} macro_test sim ${RT} logic_test sim ${RT} resistor sim ${RT} usart_test sim_pir1v1 ${RT} usart_test sim_pir1v2 ${RT} usart_test sim_eusart ${RT} usart_test sim_eusart_2455 ${RT} txisr_test sim ${RT} tmr0_16bit sim ${RT} tmr1_16bit sim ${RT} tmr3_16bit sim ${RT} switch_test sim ${RT} p18f sim_instructions ${RT} p18f sim_extended_instructions ${RT} p18f sim_reset ${RT} comparator sim ${RT} a2d sim_p16c71 ${RT} a2d sim_p16f871 ${RT} a2d sim_p16f873a ${RT} a2d sim_p16f874a ${RT} a2d sim_p16f88 ${RT} a2d sim_p16f819 ${RT} a2d sim_p18f452 ${RT} a2d sim_p18f4321 ${RT} a2d sim_p18f1220 ${RT} a2d sim_p10f222 ${RT} a2d sim_p18f26k22 ${RT} psp sim_p18f452 ${RT} psp sim_p18f6520 ${RT} psp sim_p16f871 ${RT} ttl sim_ttl377 ${RT} ttl sim_ttl165 ${RT} ttl sim_ttl595 ${RT} ccp sim_ccp_877a ${RT} ccp sim_ccp_819 ${RT} ccp sim_pwm_877a ${RT} ccp sim_pwm_6520 ${RT} ccp sim_pwm_26k22 ${RT} epwm sim ${RT} ccp_628 sim ${RT} wavegen sim ${RT} spi sim_p16f88 ${RT} spi sim_p18f242 ${RT} spi sim_p16c62 ${RT} i2c sim_p16f88 ${RT} i2c sim_p16f819 ${RT} i2c sim_p16f876a ${RT} port_stim sim_port_stim ${RT} p12f675 sim_p12f629 ${RT} p12f675 sim_p12f675 ${RT} p12f675 sim_p12f683 ${RT} p12c509 sim_p12c509_reset ${RT} p16f84 sim_reset ${RT} wdt sim_wdt_10f200 ${RT} wdt sim_wdt_16f88 ${RT} wdt sim_nwdt_16f88 ${RT} wdt sim_nwdt_16f1823 ${RT} wdt sim_pwdt_16f1823 ${RT} wdt sim_wdt_16f628 ${RT} wdt sim_nwdt_16f628 ${RT} wdt sim_nwdt_16f648a ${RT} wdt sim_wdt_16c64 ${RT} wdt sim_nwdt_16c64 ${RT} wdt sim_wdt_18f452 ${RT} wdt sim_nwdt_18f452 ${RT} wdt sim_wdt_18f4620 ${RT} wdt sim_nwdt_18f4620 ${RT} p16f676 sim_p16f676 ${RT} p16f676 sim_reset ${RT} p16f690 sim_epwm ${RT} p16f690 sim_eusart ${RT} p16f690 sim_eusart_690 ${RT} p16f690 sim_nwdt_16f631 ${RT} p16f690 sim_p16f690 ${RT} p16f690 sim_wdt_16f677 ${RT} p16f690 sim_wdt_16f685 ${RT} p16f684 sim_a2d_684 ${RT} p16f684 sim_compar_684 ${RT} p16f684 sim_epwm ${RT} p16f684 sim_nwdt_16f684 ${RT} p16f684 sim_reset ${RT} p16f684 sim_wdt_16f684 ${RT} p1xf18xx sim_p12f1822 ${RT} p1xf18xx sim_p12f1822_usart ${RT} p1xf18xx sim_p16f1823 ${RT} p1xf18xx sim_p16f1823_comp ${RT} p1xf18xx sim_p16f1823_i2c ${RT} p1xf18xx sim_p16f1823_i2c_v2 ${RT} p1xf18xx sim_p16f1823_spi ${RT} p18f26k22 sim ${RT} p16f88x sim ${RT} p16f91x sim grep ERR */*log gpsim-0.30.0/regression/epwm/0000775000076400007640000000000013117466027013063 500000000000000gpsim-0.30.0/regression/epwm/p18f26k22.asm0000775000076400007640000001662613116677627015001 00000000000000 list p=18f26k22 include include ; __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA 0 t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp .assert "\"FAILED 18F26k22 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc2\"" ; P1A .sim "scope.ch1 = \"portb2\"" ; P1B .sim "scope.ch2 = \"portb1\"" ; P1C .sim "scope.ch3 = \"portb4\"" ; P1D ; .sim "scope.ch4 = \"portb4\"" .sim "node na0" .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 18f26k22 PWM test\"" goto $-1 pwm_shutdown ; movlw (1< PR2, expect TMR2 to wrap around ; ;Tmr1 on 8 bit internal clock prescale 32 movlw (1< PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop movlw 0x20 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop movlw 0x10 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: BANKSEL CCP1CON clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0L ; Clear Timer0 clrf ANSELA ;all ports to digital clrf ANSELB ;all ports to digital clrf ANSELC ;all ports to digital movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; P1A bcf TRISB,2 ; P1B bcf TRISB,1 ; P1C bcf TRISB,4 ; P1D clrf PIE1 ; Disable peripheral interrupts clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/epwm/p18f4321.asm0000775000076400007640000001636613116677654014625 00000000000000 list p=18f4321 include include ; __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp .assert "\"FAILED 18F4321 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc2\"" ; P1A .sim "scope.ch1 = \"portd5\"" ; P1B .sim "scope.ch2 = \"portd6\"" ; P1C .sim "scope.ch3 = \"portd7\"" ; P1D .sim "scope.ch4 = \"portb4\"" .sim "node na0" .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 18f4321 PWM test\"" goto $-1 pwm_shutdown movlw (1< PR2, expect TMR2 to wrap around ; ;Tmr1 on 8 bit internal clock prescale 32 movlw (1< PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop movlw 0x20 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop movlw 0x10 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0L ; Clear Timer0 clrf ADCON1 ; turn ports to digital movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; P1A bcf TRISD,5 ; P1B bcf TRISD,6 ; P1C bcf TRISD,7 ; P1D clrf PIE1 ; Disable peripheral interrupts clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/epwm/p18f2321.asm0000775000076400007640000001633613116677571014616 00000000000000 list p=18f2321 include include ; __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp .assert "\"FAILED 18f2321 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc2\"" ; P1A ; .sim "scope.ch1 = \"portd5\"" ; P1B ; .sim "scope.ch2 = \"portd6\"" ; P1C ; .sim "scope.ch3 = \"portd7\"" ; P1D ; .sim "scope.ch4 = \"portb4\"" .sim "node na0" .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 18f2321 PWM test\"" goto $-1 pwm_shutdown movlw (1< PR2, expect TMR2 to wrap around ; ;Tmr1 on 8 bit internal clock prescale 32 movlw (1< PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop movlw 0x20 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop movlw 0x10 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0L ; Clear Timer0 clrf ADCON1 ; turn ports to digital movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; P1A ; bcf TRISD,5 ; P1B ; bcf TRISD,6 ; P1C ; bcf TRISD,7 ; P1D clrf PIE1 ; Disable peripheral interrupts clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/epwm/Makefile0000664000076400007640000000035513041763602014441 00000000000000include ../make.regression all : p16f887.cod p18f4321.cod p16f882.cod p18f1220.cod p18f2321.cod p18f26k22.cod p%.cod : p%.o gplink --map -o $@ $< sim: sim_p16f887 sim_p18f4321 sim_p16f882 sim_p18f1220 sim_p18f2321 sim_p18f26k22 gpsim-0.30.0/regression/epwm/p18f1220.asm0000775000076400007640000001561213116677730014604 00000000000000 list p=18f1220 include include ; __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x008 ; interrupt vector location` movwf w_temp swapf STATUS,W movwf status_temp .assert "\"FAILED 18f1220 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portb3\"" ; P1A .sim "scope.ch1 = \"portb2\"" ; P1B .sim "scope.ch2 = \"portb6\"" ; P1C .sim "scope.ch3 = \"portb7\"" ; P1D .sim "scope.ch4 = \"portb1\"" .sim "node na0" .sim "attach na0 porta0 portb1" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM .assert "\"*** PASSED 18f1220 PWM test\"" goto $-1 pwm_shutdown ; INT1 low bcf PORTA,0 ; C1 control and 0 output movlw (1< PR2, expect TMR2 to wrap around ; ;Tmr1 on 8 bit internal clock prescale 32 movlw (1< PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0L ; loop until CCP2 goes low ; btfsc PORTC,1 ; goto $-1 ; .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTB,3 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop movlw 0x20 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0L ; loop until CCP2 goes low ; btfsc PORTC,1 ; goto $-1 ; .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTB,3 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop movlw 0x10 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: movlw 0x7f ; ports are digital movwf ADCON1 clrf CCP1CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0L ; Clear Timer0 movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF bsf PORTA,0 ; Make output pins bcf TRISA,0 ; drive shutdown int1 bcf TRISB,3 ; P1A bcf TRISB,2 ; P1B bcf TRISB,6 ; P1C bcf TRISB,7 ; P1D clrf PIE1 ; Disable peripheral interrupts clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/epwm/p16f887.asm0000775000076400007640000001742113116677465014551 00000000000000 list p=16f887 include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16F887 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc2\"" ; P1A .sim "scope.ch1 = \"portd5\"" ; P1B .sim "scope.ch2 = \"portd6\"" ; P1C .sim "scope.ch3 = \"portd7\"" ; P1D .sim "scope.ch4 = \"portb4\"" .sim "node na0" .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 16f887 PWM test\"" goto $-1 pwm_shutdown BANKSEL CM1CON0 movlw (1< PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: banksel CCP1CON clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 banksel ANSEL clrf ANSEL ; turn ports to digital clrf ANSELH banksel CCPR1L movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF banksel TRISC ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; P1A bcf TRISD,5 ; P1B bcf TRISD,6 ; P1C bcf TRISD,7 ; P1D clrf PIE1 ; Disable peripheral interrupts movlw 0x03 ; Port B pull-up Tmr0 internal clock prescaler 16 movwf OPTION_REG banksel PIR1 ; Bank0 clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/epwm/p16f882.asm0000775000076400007640000001745513116677431014544 00000000000000 list p=16f882 include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16f882 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc2\"" ; P1A .sim "scope.ch1 = \"portb2\"" ; P1B .sim "scope.ch2 = \"portb1\"" ; P1C .sim "scope.ch3 = \"portb4\"" ; P1D .sim "scope.ch4 = \"portb4\"" .sim "node na0" .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 16f882 PWM test\"" goto $-1 pwm_shutdown BANKSEL CM1CON0 movlw (1< PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: banksel CCP1CON clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 banksel ANSEL clrf ANSEL ; turn ports to digital clrf ANSELH banksel CCPR1L movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF banksel TRISC ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; P1A bcf TRISB,2 ; P1B bcf TRISB,1 ; P1C bcf TRISB,4 ; P1D clrf PIE1 ; Disable peripheral interrupts movlw 0x03 ; Port B pull-up Tmr0 internal clock prescaler 16 movwf OPTION_REG banksel PIR1 ; Bank0 clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/microchip_usart/0000775000076400007640000000000013117466027015306 500000000000000gpsim-0.30.0/regression/microchip_usart/Makefile0000664000076400007640000000014712121052575016661 00000000000000 p16_tprp.cod: p16_tprp.o gplink --map -s 16f877.lkr -o $@ $< p16_tprp.o: p16_tprp.asm gpasm -c $< gpsim-0.30.0/regression/startup.stc0000664000076400007640000000005713041763600014243 00000000000000# gpsim configuration file. load STC run quit gpsim-0.30.0/regression/p1xf18xx/0000775000076400007640000000000013117466027013522 500000000000000gpsim-0.30.0/regression/p1xf18xx/p16f1823_i2c_v2.asm0000664000076400007640000004324013041763602016400 00000000000000; ; ; Copyright (c) 2013 Roy Rankin ; MACROS and some code included the following ;************************************************************************ ;* Microchip Technology Inc. 2006 ;* 02/15/06 ;* Designed to run at 20MHz ;************************************************************************ list p=16f1823 include include __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2, _PLLEN_OFF ;; The purpose of this program is to test gpsim's ability ;; to simulate a pic 16F1823. ;; Specifically, slave modes of I2C errorlevel -302 ; Printf Command .command macro x .direct "C", x endm _ClkIn equ 8000000 ; Input Clock Frequency _ClkOut equ (_ClkIn >> 2) ; ; Compute the delay constants for setup & hold times ; _40uS_Delay set (_ClkOut/250000) _47uS_Delay set (_ClkOut/212766) _50uS_Delay set (_ClkOut/200000) TRUE equ 1 FALSE equ 0 LSB equ 0 MSB equ 7 ; These parameters are for the Software master #define SCL_PIN 0 #define SDA_PIN 1 #define I2CPORT PORTA #define I2CTRI TRISA #define _SCL_D I2CPORT,SCL_PIN #define _SCL I2CTRI,SCL_PIN #define _SDA I2CTRI,SDA_PIN #define _SDA_D I2CPORT,SDA_PIN #define T0IE TMR0IE #define T0IF TMR0IF #define _ENABLE_BUS_FREE_TIME TRUE #define _CLOCK_STRETCH_CHECK TRUE #define _OPTION_INIT (0xC0 | 0x02) ; Prescaler to TMR0 for Appox 1 mSec timeout ;***************************************************************************** ; I2C Bus Status Reg Bit Definitions ;***************************************************************************** #define _Bus_Busy Bus_Status,0 #define _Abort Bus_Status,1 #define _Txmt_Progress Bus_Status,2 #define _Rcv_Progress Bus_Status,3 #define _Txmt_Success Bus_Status,4 #define _Rcv_Success Bus_Status,5 #define _Fatal_Error Bus_Status,6 #define _ACK_Error Bus_Status,7 ;***************************************************************************** ; I2C Bus Contro Register ;***************************************************************************** #define _10BitAddr Bus_Control,0 #define _Slave_RW Bus_Control,1 #define _Last_Byte_Rcv Bus_Control,2 #define _SlaveActive Bus_Control,6 #define _TIME_OUT_ Bus_Control,7 RELEASE_BUS MACRO banksel TRISA bsf _SDA ; tristate SDA bsf _SCL ; tristate SCL ; bcf _Bus_Busy ; Bus Not Busy, TEMP ????, set/clear on Start & Stop ENDM ;**************************************************************************** ; A MACRO To Load 8 OR 10 Bit Address To The Address Registers ; ; SLAVE_ADDRESS is a constant and is loaded into the SlaveAddress Register(s) ; depending on 8 or 10 bit addressing modes ;**************************************************************************** LOAD_ADDR_10 MACRO SLAVE_ADDRESS bsf _10BitAddr ; Slave has 10 bit address movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ; load low byte of address movlw (((SLAVE_ADDRESS >> 7) & 0x06) | 0xF0) ; 10 bit addr 11110AA0 movwf SlaveAddr+1 ; hi order address ENDM LOAD_ADDR_8 MACRO SLAVE_ADDRESS bcf _10BitAddr ; Set for 8 Bit Address Mode movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ENDM ;**************************************************************************** ; I2C_WRITE_SUB ; ; Writes a message just like I2C_WRITE, except that the data is preceeded ; by a sub-address to a slave device. ; Eg. : A serial EEPROM would need an address of memory location for ; Random Writes ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ (constant) ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; _Sub_Address_ Sub-address of Slave (constant) ; ; Sequence : ; S-SlvAW-A-SubA-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag ; ; Returns : WREG = 1 on success, else WREG = 0 ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ; COMMENTS : ; I2C_WR may prove to be more efficient than this macro in most situations ; Advantages will be found for Random Address Block Writes for Slaves with ; Auto Increment Sub-Addresses (like Microchip's 24CXX series Serial ; EEPROMS) ; ;**************************************************************************** I2C_WR_SUB MACRO _BYTES_, _SourcePointer_, _Sub_Address_ movlw (_BYTES_ + 1) movwf tempCount movlw (_SourcePointer_ - 1) movwf FSR0L moviw FSR0 movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -1) movlw _Sub_Address_ movwi FSR0 call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W movwf (_SourcePointer_ - 1) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM I2C_WR_SUB2 MACRO _BYTES_, _SourcePointer_, _Sub_Address_, _Sub_Address2_ movlw (_BYTES_ + 2) movwf tempCount movlw (_SourcePointer_ - 2) movwf FSR0L moviw FSR0 movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -2) movlw _Sub_Address_ movwi FSR0 movlw (_SourcePointer_ - 1) movwf FSR0L movlw _Sub_Address2_ movwi FSR0 movlw (_SourcePointer_ - 2) movwf FSR0L call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W ; movwf (_SourcePointer_ - 2) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM ;**************************************************************************** ; I2C_WRITE ; ; A basic macro for writing a block of data to a slave ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; ; Sequence : ; S-SlvAW-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ;**************************************************************************** I2C_WR MACRO _BYTES_, _SourcePointer_ movlw _BYTES_ movwf tempCount movlw _SourcePointer_ movwf FSR0L call _i2c_block_write call TxmtStopBit ; Issue a stop bit for slave to end transmission ENDM ;***************************************************************************** ; ; I2C_READ ; ; The basic MACRO/procedure to read a block message from a slave device ; ; Parameters : ; _BYTES_ : constant : #of bytes to receive ; _DestPointer_ : destination pointer of RAM (File Registers) ; ; Sequence : ; S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; If last byte, then Master will NOT Acknowledge (send NACK) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ;***************************************************************************** I2C_READ MACRO _BYTES_, _DestPointer_ movlw (_BYTES_ -1) movwf tempCount ; -1 because, the last byte is used out of loop movlw _DestPointer_ movwf FSR0L ; FIFO destination address pointer call _i2c_block_read ENDM ;*************************************************************************** ; ; I2C_READ_SUB ; This MACRO/Subroutine reads a message from a slave device preceeded by ; a write of the sub-address. ; Between the sub-addrers write & the following reads, a STOP condition ; is not issued and a "REPEATED START" condition is used so that an other ; master will not take over the bus, and also that no other master will ; overwrite the sub-address of the same salve. ; ; This function is very commonly used in accessing Random/Sequential reads ; from a memory device (e.g : 24Cxx serial of Serial EEPROMs from Microchip). ; ; Parameters : ; _BYTES_ # of bytes to read ; _DestPointer_ The destination pointer of data to be received. ; _BubAddress_ The sub-address of the slave ; ; Sequence : ; S-SlvAW-A-SubAddr-A-S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; ;*************************************************************************** I2C_READ_SUB MACRO _BYTES_, _DestPointer_, _SubAddress_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM I2C_READ_SUB2 MACRO _BYTES_, _DestPointer_, _SubAddress_, _SubAddress2_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address movlw _SubAddress2_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- ; cblock 0x20 UDATA ADD RES 2 IO_buf RES 10 IN_buf RES 10 ; cblock 0xf0 UDATA_SHR w_temp RES 1 status_temp RES 1 SlaveAddr RES 1 ; Slave Addr must be loader into this reg SlaveAddrHi RES 1 ; for 10 bit addressing mode DataByte RES 1 ; load this reg with the data to be transmitted BitCount RES 1 ; The bit number (0:7) transmitted or received Bus_Status RES 1 ; Status Reg of I2C Bus for both TXMT & RCVE Bus_Control RES 1 ; control Register of I2C Bus DelayCount RES 1 DataByteCopy RES 1 ; copy of DataByte for Left Shifts (destructive) SubAddr RES 1 ; sub-address of slave (used in I2C_HIGH.ASM) SrcPtr RES 1 ; source pointer for data to be transmitted tempCount RES 1 ; a temp variable for scratch RAM StoreTemp_1 RES 1 ; a temp variable for scratch RAM, do not disturb contents SEN_test RES 1 ; ACKTIM not tested _End_I2C_Ram RES 1 ; unused, only for ref of end of RAM allocation ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program INT_VECTOR CODE 0X004 ;; ;; Interrupt ;; BANKSEL PIR1 if _CLOCK_STRETCH_CHECK ; TMR0 Interrupts enabled only if Clock Stretching is Used btfss INTCON,T0IF goto check ; other Interrupts bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,T0IF goto int_ret endif check: btfss PIR1,SSP1IF goto int_ret bcf PIR1,SSP1IF call sspint int_ret: retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "p16f1823.xpos = 48" .sim "p16f1823.ypos = 36" .sim "module load pu pu1" .sim "pu1.xpos = 216" .sim "pu1.ypos = 48" .sim "module load pu pu2" .sim "pu2.xpos = 216" .sim "pu2.ypos = 96" .sim "node n1" .sim "attach n1 portc0 pu1.pin porta0" ; ee.SCL" .sim "node n2" .sim "attach n2 portc1 pu2.pin porta1" ; ee.SDA" .sim "scope.ch0 = \"porta0\"" .sim "scope.ch1 = \"porta1\"" BANKSEL APFCON bsf APFCON,0 ;; should not change anything bsf APFCON,6 ;; select alternate SDO bsf APFCON,3 ;; select alternate T1G BANKSEL ANSELA clrf ANSELA clrf ANSELC BANKSEL OSCCON movlw (0xe<<3)|2 ; set internal RC to 8 Mhz movwf OSCCON ;RRR clrf TRISA bsf PIE1,SSP1IE ; allow SSP interrupts bsf INTCON,GIE ; allow interrupts bsf INTCON,PEIE ; allow interrupts BANKSEL PORTA ; bsf PORTA,0 ; Write protect ; bsf PORTA,1 ; A0 movlw 0x10 movwf tempCount movlw IO_buf movwf FSR0L Fill_loop: movf FSR0L,W movwi FSR0++ decfsz tempCount,F goto Fill_loop bsf SEN_test,0 banksel SSPCON ; test slave receive of data with SEN set ; I2C Slave mode, 7-bit address movlw (1<. ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F1823. ;; Specifically, basic port operation, eerom, interrupts, ;; a2d, dac, SR latch, capacitor sense, and enhanced instructions list p=16f1823 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2, _STVREN_ON ; & _WRT_BOOT ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 inte_cnt RES 1 iocaf_val RES 1 GLOBAL inte_cnt, iocaf_val ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 10000.0" .sim "V1.capacitance = 20e-12" .sim "V1.voltage=1.0" .sim "node n1" .sim "attach n1 porta0 porta3" .sim "node n2" .sim "attach n2 porta1 porta4" .sim "node n3" .sim "attach n3 porta2 porta5" .sim "node n4" .sim "attach n4 portc0 V1.pin" .sim "p16f1823.xpos = 72" .sim "p16f1823.ypos = 72" .sim "V1.xpos = 216" .sim "V1.ypos = 120" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location ; many of the core registers now saved and restored automatically clrf BSR ; set bank 0 btfsc PIR2,EEIF goto ee_int btfsc INTCON,T0IF goto tmr0_int btfsc INTCON,IOCIF goto inte_int .assert "\"***FAILED p16f1823 unexpected interrupt\"" nop ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR2,EEIF goto exit_int ; Interrupt from INT pin inte_int incf inte_cnt,F bcf INTCON,GIE ; stop interrupts goto exit_int exit_int: retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .assert "p16f1823.frequency == 500000., \"FALIED 16F1823 POR clock 500kHz\"" nop BANKSEL OSCCON bsf OSCCON,6 ;set clock to 16 MHz btfss OSCSTAT,HFIOFL goto $-1 .assert "(oscstat & 0x1f) == 0x19, \"*** FAILED 16f1823 HFIO bit error\"" nop .assert "p16f1823.frequency == 16000000., \"FALIED 16F1823 RC clock 16MHz\"" nop call cap_sense BANKSEL FVRCON ; Enable Core Temp, high range, FVR AD 2.048v movlw (1<= 21 && tmr0 < 25), \"*** FAILED 16f1823 CPSCON TMR1 Counting\"" nop ; set tmr0 for RA4/T0CKI, but CPS not feeding clock BANKSEL OPTION_REG bsf OPTION_REG,TMR0CS BANKSEL TMR0 movlw 0x00 movwf TMR0 ; DAC non-idle output (0.16V) BANKSEL DACCON0 movlw (1<. ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 12F1840. list p=12f1840 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2, _STVREN_ON ; & _WRT_BOOT ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm GLOBAL temp, temp2, temp3, A0 ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 temp2 RES 1 temp3 RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 inte_cnt RES 1 iocaf_val RES 1 GPR_DATA2 UDATA 0xa0 A0 RES 1 GLOBAL iocaf_val ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program .sim "node n1" .sim "attach n1 porta0 porta3" .sim "node n2" .sim "attach n2 porta1 porta4" .sim "node n3" .sim "attach n3 porta2 porta5" .sim "p12f1840.BreakOnReset = false" .sim "log w W" .sim "log r W" ;.sim "log lxt" .sim "log on" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location ; many of the core registers now saved and restored automatically clrf BSR ; set bank 0 btfsc PIR2,EEIF goto ee_int btfsc INTCON,T0IF goto tmr0_int btfsc INTCON,IOCIF goto inte_int .assert "\"***FAILED p12f1840 unexpected interrupt\"" nop ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR2,EEIF goto exit_int ; Interrupt from INT pin inte_int incf inte_cnt,F BANKSEL IOCAF movf IOCAF,W movwf iocaf_val xorlw 0xff andwf IOCAF, F goto exit_int exit_int: ;; STATUS and W now restored by RETFIE retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start BANKSEL PCON btfss PCON,NOT_RI goto soft_reset BANKSEL STKPTR movf STKPTR,W ; ; ; test pins in analog mode return 0 on register read BANKSEL TRISA clrf STATUS clrf TRISA .assert "trisa == 0x08, \"**FAILED 12f1840 TRISA clears to 0x08\"" nop BANKSEL PORTA movlw 0xff movwf PORTA .assert "porta == 0x28, \"**FAILED 12f1840 analog bits read 0\"" nop movf PORTA,W ; ; test PORTA works as expected ; clrf PORTA BANKSEL ANSELA clrf ANSELA ; set port to digital BANKSEL TRISA movlw 0x38 movwf TRISA ;PORTA 0,1,2 output 3,4,5 input clrf BSR ; bank 0 .assert "porta == 0x00, \"PORTA = 0x00\"" nop movlw 0x07 movwf PORTA ; drive 0,1,2 bits high .assert "porta == 0x3f, \"PORTA = 0x3f\"" nop BANKSEL LATA movf LATA,W BANKSEL TRISA movlw 0x07 movwf TRISA ; PORTA 4, 5 output 0,1,2,3 input (3 input only) BANKSEL PORTA .assert "porta == 0x09, \"PORTA = 0x09\"" nop movlw 0x38 movwf PORTA ; drive output bits high .assert "porta == 0x3f, \"PORTA = 0x3f\"" nop call test_eerom call test_int call read_config_data call test_indr reset soft_reset: .assert "cycles > 100, \"*** FAILED 12f1840 Unexpected soft reset\"" nop .assert "\"*** PASSED 12f1840 Functionality\"" nop goto $ test_eerom: ; ; test can write and read to all 128 eeprom locations ; using intterupts clrf adr_cnt clrf data_cnt ; setup interrupts bsf INTCON,PEIE bsf INTCON,GIE BANKSEL PIE1 bsf PIE2,EEIE BANKSEL PIR1 ; ; write to EEPROM starting at EEPROM address 0 ; value of address as data using interrupts to ; determine write complete. ; read and verify data l1: movf adr_cnt,W clrf eerom_cnt BANKSEL EEADRL movwf EEADRL movf data_cnt,W movwf EEDATL bcf EECON1, CFGS ;Deselect Configuration space bcf EECON1, EEPGD ;Point to DATA memory bsf EECON1, WREN ;Enable writes bcf INTCON,GIE ;Disable interrupts while enabling write movlw 0x55 ;Magic sequence to enable eeprom write movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR ;Begin eeprom write bsf INTCON,GIE ;Re-enable interrupts bcf EECON1, WREN ;Disable writes ;; clrf BSR ; Bank 0 movf eerom_cnt,W skpnz goto $-2 ; ; read what we just wrote ; movf adr_cnt,W BANKSEL EEADRL movwf EEADRL bcf EECON1, CFGS ;Deselect Config space bcf EECON1, EEPGD ;Point to DATA memory bsf EECON1,RD ; start read operation movf EEDATL,W ; Read data BANKSEL PIR1 xorwf data_cnt,W ; did we read what we wrote ? skpz goto eefail incf adr_cnt,W andlw 0x7f movwf adr_cnt movwf data_cnt skpz goto l1 return eefail: .assert "\"***FAILED 12f1840 eerom write/read error\"" nop test_tmr0: return test_int: BANKSEL TRISA bsf TRISA,2 bcf TRISA,5 BANKSEL PORTA clrf PORTA BANKSEL IOCAP bsf IOCAP,2 ; set interrupt on + edge of porta2 movlw 0xff movwf IOCAF .assert "iocaf == 0x3f, \"*** FAILED 12f1840 INT test - IOCAF writable bits\"" nop clrf IOCAF BANKSEL OPTION_REG bsf OPTION_REG,INTEDG BANKSEL INTCON bsf INTCON,GIE ;Global interrupts bcf INTCON,PEIE ;No Peripheral interrupts bsf INTCON,IOCIE clrf inte_cnt bsf PORTA,5 ; make a rising edge nop movf inte_cnt,w .assert "W == 0x01, \"*** FAILED 12f1840 INT test - No int on rising edge\"" nop .assert "iocaf_val == 0x04, \"*** FAILED 12f1840 IOCAF bit 2 not set\"" nop clrf inte_cnt bcf PORTA,5 ; make a falling edge nop movf inte_cnt,w .assert "W == 0x00, \"*** FAILED 12f1840 INT test - Unexpected int on falling edge\"" nop ; Setup - edge interrupt BANKSEL IOCAP clrf IOCAP bsf IOCAN,2 clrf IOCAF BANKSEL PORTA clrf inte_cnt bsf PORTA,5 ; make a rising edge nop movf inte_cnt,w .assert "W == 0x00, \"*** FAILED 12f1840 INT test - Unexpected int on rising edge\"" nop clrf inte_cnt bcf PORTA,5 ; make a falling edge nop movf inte_cnt,w .assert "W == 0x01, \"*** FAILED 12f1840 INT test - No int on falling edge\"" nop .assert "iocaf_val == 0x04, \"*** FAILED 12f1840 IOCAF bit 2 not set\"" nop return ; ; Test reading and writing Configuration data via eeprom interface ; read_config_data: BANKSEL EEADRL ; Select correct Bank movlw 0x06 ; movwf EEADRL ; Store LSB of address clrf EEADRH ; Clear MSB of address bsf EECON1,CFGS ; Select Configuration Space bcf INTCON,GIE ; Disable interrupts bsf EECON1,RD ; Initiate read nop nop bsf INTCON,GIE ; Restore interrupts .assert "eedath == 0x1b && eedatl == 0x80, \"*** FAILED 12f1840 Device ID\"" nop ; test write BANKSEL PIR2 clrf PIR2 BANKSEL EECON1 movlw 0x01 ; movwf EEADRL ; Store LSB of address bsf EECON1, WREN ;Enable writes bcf INTCON,GIE movlw 0x55 ;Magic sequence to enable eeprom write movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR nop nop bsf INTCON,GIE bcf EECON1, WREN ;Enable writes BANKSEL PIR2 btfss PIR2,EEIF goto $-1 .assert "UserID2 == 0x1b80, \"*** FAILED 12f1840 write to UserID2\"" nop return clear_prog: ; This row erase routine assumes the following: ; 1. A valid address within the erase block is loaded in ADDRH:ADDRL ; 2. ADDRH and ADDRL are located in shared data memory 0x70 - 0x7F bcf INTCON,GIE ; Disable ints so required sequences will execute properly BANKSEL EEADRL movlw 0 movwf EEADRL movlw 1 movwf EEADRH bsf EECON1,EEPGD ; Point to program memory bcf EECON1,CFGS ; Not configuration space bsf EECON1,FREE ; Specify an erase operation bsf EECON1,WREN ; Enable writes movlw 0x55 ; Start of required sequence to initiate erase movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR ; Set WR bit to begin erase nop nop bcf EECON1,WREN ; Disable writes bsf INTCON,GIE ; Enable interrupts btfsc EECON1,WR goto $-1 return write_prog: bcf INTCON,GIE ; Disable ints so required sequences will execute properly BANKSEL EEADRH ; Bank 3 ; movf ADDRH,W ; Load initial address movlw 0x03 movwf EEADRH ; ; movf ADDRL,W ; movlw 0x00 movwf EEADRL ; movlw 0x00 ; movlw LOW DATA_ADDR ; Load initial data address movwf FSR0L ; movlw 0x20 ; Program memory ; movlw HIGH DATA_ADDR ; Load initial data address movwf FSR0H ; bsf EECON1,EEPGD ; Point to program memory bcf EECON1,CFGS ; Not configuration space bsf EECON1,WREN ; Enable writes bsf EECON1,LWLO ; Only Load Write Latches LOOP moviw FSR0++ ; Load first data byte into lower movwf EEDATL ; moviw FSR0++ ; Load second data byte into upper movwf EEDATH ; movf EEADRL,W ; Check if lower bits of address are '000' xorlw 0x07 ; Check if we're on the last of 8 addresses andlw 0x07 ; btfsc STATUS,Z ; Exit if last of eight words, goto START_WRITE ; movlw 0x55 ; Start of required write sequence: movwf EECON2 movlw 0xAA ; movwf EECON2 bsf EECON1,WR ; Set WR bit to begin write nop nop incf EEADRL,F ; Still loading latches Increment address goto LOOP ; Write next latches START_WRITE bcf EECON1,LWLO ; No more loading latches - Actually start Flash program ; memory write movlw 0x55 ; Start of required write sequence: movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR ; Set WR bit to begin write nop nop bcf EECON1,WREN ; Disable writes bsf INTCON,GIE ; Enable interrupts return test_indr: movlb 0 ; select bank 0 ; read low byte of program memory starting at 0x300 movlw 0x83 movwf FSR1H clrf FSR1L addfsr FSR1,1 .assert "fsr1h == 0x83 && fsr1l == 0x01, \"*** FAILED 12f1840 addfsr fsr1,1\"" nop addfsr FSR1,-1 ; undo above instruction .assert "fsr1h == 0x83 && fsr1l == 0x00, \"*** FAILED 12f1840 addfsr fsr1,-1\"" nop clrf temp moviw FSR1++ addwf temp,F moviw FSR1++ addwf temp,F moviw FSR1++ addwf temp,F moviw FSR1++ addwf temp,F moviw FSR1++ .assert "(status & 0x4) == 0x0, \"*** FAILED 12f1840 Z bit is 1 after MOVIW\"" nop addwf temp,F .assert "temp == 0xff, \"*** FAILED 12f1840 read program memory\"" nop moviw FSR1++ ; Read a 0 .assert "(status & 0x4) == 0x4, \"*** FAILED 12f1840 Z bit is 0 after MOVIW\"" nop ; put address of temp into temp, FSR0 and 0x20 movlw temp movwf temp movwf FSR0L movwf 0x20 clrf FSR0H ; put address of w_temp into w_temp movlw temp+1 movwf w_temp moviw ++FSR0 .assert "W == 0x71, \"*** FAILED 12f1840 ++FSR0 read of w_temp\"" nop moviw -1[FSR0] .assert "W == 0x70, \"*** FAILED 12f1840 -1[FSR0] read of temp\"" nop moviw -20[FSR1] moviw 0[FSR0] movlw 0xf1 movwi ++FSR0 .assert "temp2 == 0xf1, \"*** FAILED 12f1840 ++FSR0 write\"" nop addlw 1 movwi 1[FSR0] .assert "temp3 == 0xf2, \"*** FAILED 12f1840 1[FSR0] write\"" nop movwi 10[FSR1] ; not valid to write indirect to program memory moviw 10[FSR1] ; read unchanged program memory .assert "W == 0xff, \"*** FAILED 12f1840 10[FSR1] W/R program memory(no write)\"" nop movlw 0x20 movwf FSR1L clrf FSR1H movf INDF0,W addwf INDF1,W .assert "W == 0x61, \"*** FAILED 12f1840 INDF operations\"" nop clrf FSR1L movlw 0x80 movwf FSR1H incf FSR1L,F movf INDF1,W .assert "W == 0x1a, \"*** FAILED 12f1840 INDF operations program mem\"" nop movlw 0x20 ; linear memory address 0x20000 == 0x20 movwf FSR0H movlw 0x6f movwf 0x6f movlw 0x4f movwf FSR0L ; 0x204f points to 0x6f movwf INDF0 ; write 0x4f to 0x6f (bank 0) incf FSR0L,F ; 0x2050 points to 0xa0 movwf INDF0 ; write 0x4f to 0xa0 (bank 1) .assert "A0 == 0x4f, \"*** FAILED 12f1840 INDF operations linear memory\"" nop return org 0x300 rrDATA dw 0x01, 0x02, 0x03, 0x04, 0xf5, 0 end gpsim-0.30.0/regression/p1xf18xx/i2c_low.inc0000664000076400007640000003201413041763602015466 00000000000000;**************************************************************************** ; ; Low Level I2C Routines ; ; Single Master Transmitter & Single Master Receiver Routines ; These routines can very easily be converted to Multi-Master System ; when PIC16C6X with on chip I2C Slave Hardware, Start & Stop Bit ; detection is available. ; ; The generic high level routines are given in I2C_HIGH.ASM ; ; ; Program: I2C_LOW.ASM ; Revision Date: ; 1-16-97 Compatibility with MPASMWIN 1.40 ; ;*************************************************************************** ;************************************************************************** ; I2C Bus Initialization ; ;************************************************************************** InitI2CBus_Master: BANKSEL I2CPORT movlw ~(1< __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_HS & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF & _IESO_ON #define SCL_PIN 0 #define SDA_PIN 1 #define I2CPORT PORTC #define I2CTRI TRISC #define _SCL_D I2CPORT,SCL_PIN #define _SCL I2CTRI,SCL_PIN #define _SDA I2CTRI,SDA_PIN #define _SCL_DRIVE I2CTRI,2 #define _SDA_DRIVE I2CTRI,3 errorlevel -302 variables UDATA_SHR temp1 RES 1 temp2 RES 1 STARTUP CODE NOP goto start NOP NOP NOP PROG1 CODE ; start .sim "p16f1823.frequency = 20000000." .sim "break c 0x100000" .sim "module lib libgpsim_modules" .sim "module load e24xx024 ee" .sim "module load pu pu1" .sim "module load pu pu2" .sim "node n1" .sim "attach n1 portc1 pu1.pin portc3 ee.SDA" ; SDA .sim "node n2" .sim "attach n2 portc0 pu2.pin portc2 ee.SCL" ; SCL .sim "node n3" .sim "attach n3 porta0 ee.WP" .sim "node n4" .sim "attach n4 porta1 ee.A0" .sim "node n5" .sim "attach n5 porta2 ee.A1" .sim "node n6" .sim "attach n6 porta4 ee.A2" .sim "scope.ch0 = \"portc3\"" .sim "scope.ch1 = \"portc2\"" .sim "pu1.xpos = 372." .sim "pu1.ypos = 156." .sim "pu2.xpos = 252." .sim "pu2.ypos = 156" .sim "ee.xpos = 252." .sim "ee.ypos = 60." .sim "p16f1823.xpos = 72." .sim "p16f1823.ypos = 24." call ProgInit ; Get everything running step-by-step call I2CSendResult call write_eeprom call is_ready call read_eeprom .command "dump e ee dump.hex" nop call is_ready call clr_eeprom .command "load e ee dump.hex" nop call is_ready call read_eeprom .assert "\"*** PASSED p16f1823 I2C test\"" goto $ ;****************************** SUBROUTINES **************************** ;************************************************************************ START_I2C MACRO banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 banksel PORTA ENDM RSTART_I2C MACRO banksel SSPCON2 ; Generate I2C repeat start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 banksel PORTA ENDM STOP_I2C MACRO banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PORTA ENDM IDLE_WAIT_I2C MACRO banksel SSPCON2 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_NOT_W goto $-1 banksel PORTA ENDM ;****************** Initialize Registers and Variables ***************** ;************************************************************************ ProgInit banksel ANSELA clrf ANSELA clrf ANSELC banksel PORTA clrf PORTA ; Set all bits to zero on Port A banksel TRISA clrf TRISA ; clrf TRISC bsf _SDA_DRIVE banksel OSCSTAT .assert "p16f1823.frequency == 500000., \"FALIED 16F1823 POR 2 speed clock 500kHz\"" nop btfss OSCSTAT,OSTS goto $-1 .assert "p16f1823.frequency == 20000000., \"FALIED 16F1823 after 2 speed clock 20MHz\"" nop .assert "(oscstat & 0x1f) == 0x00, \"*** FAILED 16f1823 OSCSTAT bit error\"" nop banksel SSPADD movlw 0x0C ; Set I2C baud rate to 385 kHz movwf SSPADD movlw 0x08 ; Set for I2C master mode movwf SSPCON movlw 0x28 ; Enable I2C movwf SSPCON return ;************************************************************************ I2CSendResult banksel SSPCON2 ; Generate I2C start, bus collision bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 bsf SSPCON2,SEN banksel I2CTRI bcf _SCL_DRIVE IDLE_WAIT_I2C .assert "(pir2 & 0x08) == 0x08, \"FAILED BCL1IF for start\"" nop banksel I2CTRI bsf _SCL_DRIVE banksel PIR2 bcf PIR2,BCL1IF banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN IDLE_WAIT_I2C .assert "(portc & 0x03) == 0, \"FAILED Start SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Start SSP1IF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Start BCL1IF clear\"" nop .assert "(ssp1stat & 0x3f) == 0x08, \"FAILED Start S bit set\"" nop banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x03) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSP1IF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCL1IF clear\"" nop .assert "(ssp1stat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 bsf SSPCON2,ACKDT bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 .assert "(portc & 0x03) == 0x02, \"FAILED ACKEN SCL low, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED ACKEN SSP1IF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED ACKEN BCL1IF clear\"" nop .assert "(ssp1stat & 0x3f) == 0x08, \"FAILED ACKEN S bit set\"" nop bcf SSPCON2,ACKDT bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x03) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSP1IF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCL1IF clear\"" nop .assert "(ssp1stat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 .assert "(portc & 0x03) == 0x03, \"FAILED Stop SCL, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Stop SSP1IF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Stop BCL1IF clear\"" nop .assert "(ssp1stat & 0x3f) == 0x10, \"FAILED Stop P bit set\"" nop return ; ; repeatedly send command to eeprom until an ACK ; is received back ; ; The call of delay is not required for operation of the code, ; but it speeds up the simulation with the GUI running. -- RRR ; is_ready banksel SSPCON movlw 0x04 movwf temp2 clrf temp1 call delay banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xa0 ; write command to eeprom call I2C_send_w call I2C_stop banksel SSPCON2 ; Generate I2C start btfsc SSPCON2,ACKSTAT goto is_ready banksel PIR2 bcf PIR2,BCL1IF return write_eeprom_address banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xa0 ; write command to eeprom call I2C_send_w .assert "(ssp1con2 & 0x40) == 0x00, \"FAILED write command to eeprom ACK\"" nop .assert "(ssp1stat & 0x01) == 0x00, \"FAILED write to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSP1IF movlw 0x00 ; write eeprom address call I2C_send_w .assert "(ssp1con2 & 0x40) == 0x00, \"FAILED write address to eeprom ACK\"" nop return write_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSP1IF movlw 0x80 ; write data1 call I2C_send_w .assert "(ssp1con2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSP1IF movlw 0x81 ; write data2 call I2C_send_w .assert "(ssp1con2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return clr_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSP1IF movlw 0x00 ; write data1 call I2C_send_w .assert "(ssp1con2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSP1IF movlw 0x00 ; write data2 call I2C_send_w .assert "(ssp1con2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return read_eeprom call write_eeprom_address banksel SSPCON2 ; Generate I2C repeated start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 movlw 0xa1 ; Send address/read to eeprom banksel SSPBUF movwf SSPBUF banksel SSPCON2 ; wait for idle (ACKEN,RCEN,PEN,RSEN,SEN) == 0 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_NOT_W ; also R_W == 0 goto $-1 .assert "(ssp1stat & 0x01) == 0x00, \"FAILED address/read to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 bsf SSPCON2,RCEN ; read data from eeprom btfsc SSPCON2,RCEN goto $-1 .assert "(pir1 & 0x08) == 0x08, \"FAILED RCEN SSP1IF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RCEN BCL1IF clear\"" nop .assert "(ssp1stat & 0x01) == 0x01, \"FAILED RCEN BF set\"" nop banksel SSPBUF movf SSPBUF,W .assert "W == 0x80, \"FAILED RCEN, read Data\"" nop banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSP1IF banksel SSPCON2 bsf SSPCON2,RCEN ; read next byte btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W .assert "W == 0x81, \"FAILED RCEN, read Data2\"" nop banksel SSPCON2 bsf SSPCON2,ACKDT ; send NACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 return I2C_stop banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 return delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return ;********************** Output byte in W via I2C bus ******************** ;************************************************************************ I2C_send_w banksel SSPBUF ; Second byte of data (middle) movwf SSPBUF banksel SSPSTAT btfsc SSPSTAT,R_NOT_W goto $-1 return end gpsim-0.30.0/regression/p1xf18xx/p16f1823_comp.asm0000664000076400007640000002747213041763602016263 00000000000000; ; ; Copyright (c) 2015 Roy Rankin ; ; This file is part of the gpsim regression tests ; ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, see ; . list p=16f1823 include include __CONFIG _CONFIG1, _CP_OFF & _WDTE_OFF & _FOSC_INTOSC & _LVP_OFF & _MCLRE_OFF __CONFIG _CONFIG2, _PLLEN_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F1823. ;; Specifically, the comparator and gate function of Tmr1 is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR int_cm1 RES 1 int_cm2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 GLOBAL int_cm1, int_cm2 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X004 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f1823.xpos = 72" .sim "p16f1823.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "V1.voltage = 2.0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" .sim "V2.voltage = 2.5" .sim "module load pullup V3" .sim "V3.resistance = 100.0" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "V3.voltage = 4.5" .sim "node na0" .sim "attach na0 V3.pin porta0 portc0" ; C1IN+, C2IN+ .sim "node na1" .sim "attach na1 V1.pin portc1" ; C12IN1- .sim "node na3" .sim "attach na3 V2.pin porta1" ; C12IN0- movlw 0x03 BANKSEL ANSELA clrf ANSELA clrf ANSELC movwf ANSELA ; select AN0, AN1 movwf ANSELC ; select AN4, AN5 BANKSEL TRISA movwf TRISA ; movlw 0x02 movwf TRISC ; portc0 (AN4) portc1(AN5) input, portc4 output bsf INTCON,GIE ;Global interrupts bsf INTCON,PEIE ;Peripheral interrupts BANKSEL PIE2 bsf PIE2,C1IE ;CM1 interrupts bsf PIE2,C2IE ;CM2 interrupts call test_compar call test_tot1 ; can C2 increment TMR1 call test_sr ; can CM control SR latch .assert "\"*** PASSED 16F1823 comparator test\"" nop goto $-1 ; ; Test Comparator driving SR latch ; Assumes called with C1OUT = C2OUT = 0 and ; C1POL = 0, C2POL = 1 ; test_sr: BANKSEL SRCON0 ; turn on Q output pin movlw (1<. ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 12F1822. list p=12f1822 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2, _STVREN_ON ; & _WRT_BOOT ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm GLOBAL temp, temp2, temp3, A0 ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 temp2 RES 1 temp3 RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 inte_cnt RES 1 iocaf_val RES 1 GPR_DATA2 UDATA 0xa0 A0 RES 1 GLOBAL iocaf_val ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program .sim "node n1" .sim "attach n1 porta0 porta3" .sim "node n2" .sim "attach n2 porta1 porta4" .sim "node n3" .sim "attach n3 porta2 porta5" .sim "p12f1822.BreakOnReset = false" .sim "log w W" .sim "log r W" ;.sim "log lxt" .sim "log on" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location ; many of the core registers now saved and restored automatically clrf BSR ; set bank 0 btfsc PIR2,EEIF goto ee_int btfsc INTCON,T0IF goto tmr0_int btfsc INTCON,IOCIF goto inte_int .assert "\"***FAILED p12f1822 unexpected interrupt\"" nop ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR2,EEIF goto exit_int ; Interrupt from INT pin inte_int incf inte_cnt,F BANKSEL IOCAF movf IOCAF,W movwf iocaf_val xorlw 0xff andwf IOCAF, F goto exit_int exit_int: ;; STATUS and W now restored by RETFIE retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start BANKSEL PCON btfss PCON,NOT_RI goto soft_reset BANKSEL STKPTR movf STKPTR,W ; ; ; test pins in analog mode return 0 on register read BANKSEL TRISA clrf STATUS clrf TRISA .assert "trisa == 0x08, \"**FAILED 12f1822 TRISA clears to 0x08\"" nop BANKSEL PORTA movlw 0xff movwf PORTA .assert "porta == 0x28, \"**FAILED 12f1822 analog bits read 0\"" nop movf PORTA,W ; ; test PORTA works as expected ; clrf PORTA BANKSEL ANSELA clrf ANSELA ; set port to digital BANKSEL TRISA movlw 0x38 movwf TRISA ;PORTA 0,1,2 output 3,4,5 input clrf BSR ; bank 0 .assert "porta == 0x00, \"PORTA = 0x00\"" nop movlw 0x07 movwf PORTA ; drive 0,1,2 bits high .assert "porta == 0x3f, \"PORTA = 0x3f\"" nop BANKSEL LATA movf LATA,W BANKSEL TRISA movlw 0x07 movwf TRISA ; PORTA 4, 5 output 0,1,2,3 input (3 input only) BANKSEL PORTA .assert "porta == 0x09, \"PORTA = 0x09\"" nop movlw 0x38 movwf PORTA ; drive output bits high .assert "porta == 0x3f, \"PORTA = 0x3f\"" nop call test_eerom call test_int call read_config_data call test_indr reset soft_reset: .assert "cycles > 100, \"*** FAILED 12f1822 Unexpected soft reset\"" nop .assert "\"*** PASSED 12f1822 Functionality\"" nop goto $ test_eerom: ; ; test can write and read to all 128 eeprom locations ; using intterupts clrf adr_cnt clrf data_cnt ; setup interrupts bsf INTCON,PEIE bsf INTCON,GIE BANKSEL PIE1 bsf PIE2,EEIE BANKSEL PIR1 ; ; write to EEPROM starting at EEPROM address 0 ; value of address as data using interrupts to ; determine write complete. ; read and verify data l1: movf adr_cnt,W clrf eerom_cnt BANKSEL EEADRL movwf EEADRL movf data_cnt,W movwf EEDATL bcf EECON1, CFGS ;Deselect Configuration space bcf EECON1, EEPGD ;Point to DATA memory bsf EECON1, WREN ;Enable writes bcf INTCON,GIE ;Disable interrupts while enabling write movlw 0x55 ;Magic sequence to enable eeprom write movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR ;Begin eeprom write bsf INTCON,GIE ;Re-enable interrupts bcf EECON1, WREN ;Disable writes ;; clrf BSR ; Bank 0 movf eerom_cnt,W skpnz goto $-2 ; ; read what we just wrote ; movf adr_cnt,W BANKSEL EEADRL movwf EEADRL bcf EECON1, CFGS ;Deselect Config space bcf EECON1, EEPGD ;Point to DATA memory bsf EECON1,RD ; start read operation movf EEDATL,W ; Read data BANKSEL PIR1 xorwf data_cnt,W ; did we read what we wrote ? skpz goto eefail incf adr_cnt,W andlw 0x7f movwf adr_cnt movwf data_cnt skpz goto l1 return eefail: .assert "\"***FAILED 12f1822 eerom write/read error\"" nop test_tmr0: return test_int: BANKSEL TRISA bsf TRISA,2 bcf TRISA,5 BANKSEL PORTA clrf PORTA BANKSEL IOCAP bsf IOCAP,2 ; set interrupt on + edge of porta2 movlw 0xff movwf IOCAF .assert "iocaf == 0x3f, \"*** FAILED 12f1822 INT test - IOCAF writable bits\"" nop clrf IOCAF BANKSEL OPTION_REG bsf OPTION_REG,INTEDG BANKSEL INTCON bsf INTCON,GIE ;Global interrupts bcf INTCON,PEIE ;No Peripheral interrupts bsf INTCON,IOCIE clrf inte_cnt bsf PORTA,5 ; make a rising edge nop movf inte_cnt,w .assert "W == 0x01, \"*** FAILED 12f1822 INT test - No int on rising edge\"" nop .assert "iocaf_val == 0x04, \"*** FAILED 12f1822 IOCAF bit 2 not set\"" nop clrf inte_cnt bcf PORTA,5 ; make a falling edge nop movf inte_cnt,w .assert "W == 0x00, \"*** FAILED 12f1822 INT test - Unexpected int on falling edge\"" nop ; Setup - edge interrupt BANKSEL IOCAP clrf IOCAP bsf IOCAN,2 clrf IOCAF BANKSEL PORTA clrf inte_cnt bsf PORTA,5 ; make a rising edge nop movf inte_cnt,w .assert "W == 0x00, \"*** FAILED 12f1822 INT test - Unexpected int on rising edge\"" nop clrf inte_cnt bcf PORTA,5 ; make a falling edge nop movf inte_cnt,w .assert "W == 0x01, \"*** FAILED 12f1822 INT test - No int on falling edge\"" nop .assert "iocaf_val == 0x04, \"*** FAILED 12f1822 IOCAF bit 2 not set\"" nop return ; ; Test reading and writing Configuration data via eeprom interface ; read_config_data: BANKSEL EEADRL ; Select correct Bank movlw 0x06 ; movwf EEADRL ; Store LSB of address clrf EEADRH ; Clear MSB of address bsf EECON1,CFGS ; Select Configuration Space bcf INTCON,GIE ; Disable interrupts bsf EECON1,RD ; Initiate read nop nop bsf INTCON,GIE ; Restore interrupts .assert "eedath == 0x27 && eedatl == 0x00, \"*** FAILED 12f1822 Device ID\"" nop ; test write BANKSEL PIR2 clrf PIR2 BANKSEL EECON1 movlw 0x01 ; movwf EEADRL ; Store LSB of address bsf EECON1, WREN ;Enable writes bcf INTCON,GIE movlw 0x55 ;Magic sequence to enable eeprom write movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR nop nop bsf INTCON,GIE bcf EECON1, WREN ;Enable writes BANKSEL PIR2 btfss PIR2,EEIF goto $-1 .assert "UserID2 == 0x2700, \"*** FAILED 12f1822 write to UserID2\"" nop return clear_prog: ; This row erase routine assumes the following: ; 1. A valid address within the erase block is loaded in ADDRH:ADDRL ; 2. ADDRH and ADDRL are located in shared data memory 0x70 - 0x7F bcf INTCON,GIE ; Disable ints so required sequences will execute properly BANKSEL EEADRL movlw 0 movwf EEADRL movlw 1 movwf EEADRH bsf EECON1,EEPGD ; Point to program memory bcf EECON1,CFGS ; Not configuration space bsf EECON1,FREE ; Specify an erase operation bsf EECON1,WREN ; Enable writes movlw 0x55 ; Start of required sequence to initiate erase movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR ; Set WR bit to begin erase nop nop bcf EECON1,WREN ; Disable writes bsf INTCON,GIE ; Enable interrupts btfsc EECON1,WR goto $-1 return write_prog: bcf INTCON,GIE ; Disable ints so required sequences will execute properly BANKSEL EEADRH ; Bank 3 ; movf ADDRH,W ; Load initial address movlw 0x03 movwf EEADRH ; ; movf ADDRL,W ; movlw 0x00 movwf EEADRL ; movlw 0x00 ; movlw LOW DATA_ADDR ; Load initial data address movwf FSR0L ; movlw 0x20 ; Program memory ; movlw HIGH DATA_ADDR ; Load initial data address movwf FSR0H ; bsf EECON1,EEPGD ; Point to program memory bcf EECON1,CFGS ; Not configuration space bsf EECON1,WREN ; Enable writes bsf EECON1,LWLO ; Only Load Write Latches LOOP moviw FSR0++ ; Load first data byte into lower movwf EEDATL ; moviw FSR0++ ; Load second data byte into upper movwf EEDATH ; movf EEADRL,W ; Check if lower bits of address are '000' xorlw 0x07 ; Check if we're on the last of 8 addresses andlw 0x07 ; btfsc STATUS,Z ; Exit if last of eight words, goto START_WRITE ; movlw 0x55 ; Start of required write sequence: movwf EECON2 movlw 0xAA ; movwf EECON2 bsf EECON1,WR ; Set WR bit to begin write nop nop incf EEADRL,F ; Still loading latches Increment address goto LOOP ; Write next latches START_WRITE bcf EECON1,LWLO ; No more loading latches - Actually start Flash program ; memory write movlw 0x55 ; Start of required write sequence: movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR ; Set WR bit to begin write nop nop bcf EECON1,WREN ; Disable writes bsf INTCON,GIE ; Enable interrupts return test_indr: movlb 0 ; select bank 0 ; read low byte of program memory starting at 0x300 movlw 0x83 movwf FSR1H clrf FSR1L addfsr FSR1,1 .assert "fsr1h == 0x83 && fsr1l == 0x01, \"*** FAILED 12f1822 addfsr fsr1,1\"" nop addfsr FSR1,-1 ; undo above instruction .assert "fsr1h == 0x83 && fsr1l == 0x00, \"*** FAILED 12f1822 addfsr fsr1,-1\"" nop clrf temp moviw FSR1++ addwf temp,F moviw FSR1++ addwf temp,F moviw FSR1++ addwf temp,F moviw FSR1++ addwf temp,F moviw FSR1++ .assert "(status & 0x4) == 0x0, \"*** FAILED 12f1822 Z bit is 1 after MOVIW\"" nop addwf temp,F .assert "temp == 0xff, \"*** FAILED 12f1822 read program memory\"" nop moviw FSR1++ ; Read a 0 .assert "(status & 0x4) == 0x4, \"*** FAILED 12f1822 Z bit is 0 after MOVIW\"" nop ; put address of temp into temp, FSR0 and 0x20 movlw temp movwf temp movwf FSR0L movwf 0x20 clrf FSR0H ; put address of w_temp into w_temp movlw temp+1 movwf w_temp moviw ++FSR0 .assert "W == 0x71, \"*** FAILED 12f1822 ++FSR0 read of w_temp\"" nop moviw -1[FSR0] .assert "W == 0x70, \"*** FAILED 12f1822 -1[FSR0] read of temp\"" nop moviw -20[FSR1] moviw 0[FSR0] movlw 0xf1 movwi ++FSR0 .assert "temp2 == 0xf1, \"*** FAILED 12f1822 ++FSR0 write\"" nop addlw 1 movwi 1[FSR0] .assert "temp3 == 0xf2, \"*** FAILED 12f1822 1[FSR0] write\"" nop movwi 10[FSR1] ; not valid to write indirect to program memory moviw 10[FSR1] ; read unchanged program memory .assert "W == 0xff, \"*** FAILED 12f1822 10[FSR1] W/R program memory(no write)\"" nop movlw 0x20 movwf FSR1L clrf FSR1H movf INDF0,W addwf INDF1,W .assert "W == 0x61, \"*** FAILED 12f1822 INDF operations\"" nop clrf FSR1L movlw 0x80 movwf FSR1H incf FSR1L,F movf INDF1,W .assert "W == 0x1a, \"*** FAILED 12f1822 INDF operations program mem\"" nop movlw 0x20 ; linear memory address 0x20000 == 0x20 movwf FSR0H movlw 0x6f movwf 0x6f movlw 0x4f movwf FSR0L ; 0x204f points to 0x6f movwf INDF0 ; write 0x4f to 0x6f (bank 0) incf FSR0L,F ; 0x2050 points to 0xa0 movwf INDF0 ; write 0x4f to 0xa0 (bank 1) .assert "A0 == 0x4f, \"*** FAILED 12f1822 INDF operations linear memory\"" nop return org 0x300 rrDATA dw 0x01, 0x02, 0x03, 0x04, 0xf5, 0 end gpsim-0.30.0/regression/p1xf18xx/p16f1825.asm0000664000076400007640000004672213041754701015246 00000000000000; ; ; Copyright (c) 2013 Roy Rankin ; ; This file is part of the gpsim regression tests ; ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, see ; . ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F1825. ;; Specifically, basic port operation, eerom, interrupts, ;; a2d, dac, SR latch, capacitor sense, and enhanced instructions list p=16f1825 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2, _STVREN_ON ; & _WRT_BOOT ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 inte_cnt RES 1 iocaf_val RES 1 GLOBAL inte_cnt, iocaf_val ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 10000.0" .sim "V1.capacitance = 20e-12" .sim "V1.voltage=1.0" .sim "node n1" .sim "attach n1 porta0 porta3" .sim "node n2" .sim "attach n2 porta1 porta4" .sim "node n3" .sim "attach n3 porta2 porta5" .sim "node n4" .sim "attach n4 portc0 V1.pin" .sim "p16f1825.xpos = 72" .sim "p16f1825.ypos = 72" .sim "V1.xpos = 216" .sim "V1.ypos = 120" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location ; many of the core registers now saved and restored automatically clrf BSR ; set bank 0 btfsc PIR2,EEIF goto ee_int btfsc INTCON,T0IF goto tmr0_int btfsc INTCON,IOCIF goto inte_int .assert "\"***FAILED p16f1825 unexpected interrupt\"" nop ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR2,EEIF goto exit_int ; Interrupt from INT pin inte_int incf inte_cnt,F bcf INTCON,GIE ; stop interrupts goto exit_int exit_int: retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;set clock to 16 MHz BANKSEL OSCCON bsf OSCCON,6 btfss OSCSTAT,HFIOFL goto $-1 .assert "(oscstat & 0x1f) == 0x19, \"*** FAILED 16f1825 HFIO bit error\"" nop call cap_sense BANKSEL FVRCON ; Enable Core Temp, high range, FVR AD 2.048v movlw (1<= 21 && tmr0 < 25), \"*** FAILED 16f1825 CPSCON TMR1 Counting\"" nop ; set tmr0 for RA4/T0CKI, but CPS not feeding clock BANKSEL OPTION_REG bsf OPTION_REG,TMR0CS BANKSEL TMR0 movlw 0x00 movwf TMR0 ; DAC non-idle output (0.16V) BANKSEL DACCON0 movlw (1< include __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_OFF & _CLKOUTEN_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x70 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 global rxLastByte ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location clrf BSR ; set bank 0 btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"sent character looped back\"" nop BANKSEL RCREG movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=16e6" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "U1.xpos = 250.0" .sim "U1.ypos = 80.0" .sim "module load usart U2" .sim "U2.xpos = 80.0" .sim "U2.ypos = 200.0" .sim "node PIC_tx" .sim "node PIC_rx" .sim "node PIC_tx2" .sim "node PIC_rx2" ;; Tie the USART module to the PIC .sim "attach PIC_tx porta0 U1.RXPIN" .sim "attach PIC_rx porta1 U1.TXPIN" ;; Tie the USART module to the PIC .sim "attach PIC_tx2 porta4 U2.RXPIN" .sim "attach PIC_rx2 porta5 U2.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 9600" .sim "U1.rxbaud = 9600" .sim "U1.loop = true" .sim "U2.txbaud = 9600" .sim "U2.rxbaud = 9600" .sim "U2.loop = true" ;set clock to 16 Mhz BANKSEL OSCCON bsf OSCCON,6 BANKSEL APFCON movlw 0x84 ;movwf APFCON ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS BANKSEL ANSELA clrf ANSELA ; set port to digital BANKSEL PORTA bsf PORTA,0 ;Make sure the TX line drives high when ;it is programmed as an output. BANKSEL TRISA bsf TRISA,1 ;RX is an input bcf TRISA,0 ;TX is an output bsf TRISA,5 ;Alternate RX is an input bcf TRISA,4 ;Alternate TX is an output BANKSEL SPBRGL movlw 25 ;9600 baud. movwf SPBRGL clrf BSR .assert "(porta & 0x01) == 0x01, \"FAILED: 12F1822 USART TX bit initilized as high\"" clrf tx_ptr ;; Turn on the serial port BANKSEL RCSTA movlw (1< 9 bits ; and < 10 bits or between 0.9375 and 1.041 msec. ; with oscillator at 16MHz and TMR0 / 64 expect between 58 and 65 ; TMR0 cycles. movf TMR0,W .assert "tmr0 > 58 && tmr0 < 65, \"*** FAILED 12F1822 USART baud rate\"" nop clrf rxFlag call rx_loop done: .assert "\"*** PASSED 12F1822 USART\"" goto $ TransmitNextByte: clrf rxFlag call tx_message BANKSEL TXREG movwf TXREG BANKSEL PIR1 rx_loop: btfss rxFlag,0 goto rx_loop ; clrf temp2 ; call delay ;; Delay between bytes. btfss PIR1,TXIF goto $-1 return tx_message incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw TX_TABLE skpnc incf PCLATH,f movwf PCL TX_TABLE dt "0123456789ABCDEF",0 delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return end gpsim-0.30.0/regression/p1xf18xx/p16f1823_spi.asm0000664000076400007640000001606313116715415016114 00000000000000; ; ; Copyright (c) 2013 Roy Rankin ; ; This file is part of the gpsim regression tests ; ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, see ; . list p=16f1823 include include ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16f1823. ;; Specifically, SPI errorlevel -302 ; Printf Command .command macro x .direct "C", x endm __CONFIG _CONFIG2, _PLLEN_OFF #define SDO_PORT PORTC,2 #define SDI_PORT PORTC,1 #define SCK_PORT PORTC,0 #define SS_PORT PORTC,3 #define SDO_TRIS TRISC,2 #define SDI_TRIS TRISC,1 #define SCK_TRIS TRISC,0 #define SS_TRIS TRISC,3 #define DRV_CLOCK PORTA,1 #define DRV_CLOCK_TRIS TRISA,1 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR w_temp RES 1 status_temp RES 1 loopcnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program ;; ;; Interrupt ;; INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfss PIE1,SSP1IF goto check ; other Interrupts ; bsf _TIME_OUT_ ; MUST set this Flag bcf PIE1,SSP1IF check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "module load pu pu1" .sim "module load pu pu2" .sim "module load not not" ; .sim "p16f88.xpos = 132." ; .sim "p16f88.ypos = 96." .sim "not.xpos=264." .sim "not.ypos=180." .sim "pu1.xpos=252." .sim "pu1.ypos=96." .sim "pu2.xpos=264." .sim "pu2.ypos=252." .sim "node ss" .sim "attach ss portc3 porta2" ; Not SS .sim "node sck" .sim "attach sck portc0 porta1 pu1.pin" ; SCK .sim "node sdo" .sim "attach sdo not.in0 portc2 pu2.pin" .sim "node sdi" .sim "attach sdi portc1 not.out" BANKSEL ANSELA clrf ANSELA clrf ANSELC BANKSEL OSCCON movlw (0xe<<3)|3 ; set internal RC to 8 Mhz movwf OSCCON BANKSEL TRISC bcf SDO_TRIS ; SDO bcf SCK_TRIS ; SCK movlw 0xff BANKSEL SSPSTAT movwf SSPSTAT .assert "ssp1stat == 0xC0, \"SPI sspstat only SMP, CKE writable\"" nop clrf SSPSTAT ; ; Test SPI Master mode ; movlw 0x21 ; SSPEN | SPI master Fosc/16 movwf SSPCON1 movlw 0xab movwf SSPBUF BANKSEL PIR1 bcf PIR1,SSP1IF loop: btfss PIR1,SSP1IF goto loop .assert "(ssp1stat & 1) == 1, \"FAILED MSSP SPI Master BF not set\"" nop BANKSEL SSPBUF movf SSPBUF,W .assert "(ssp1stat & 1) == 0, \"FAILED MSSP SPI Master BF not cleared\"" nop .assert "W == 0x54, \"FAILED MSSP SPI Master wrong data\"" nop ; ; TEST SPI Slave mode with SS ; clrf SSPCON1 BANKSEL TRISC bcf DRV_CLOCK_TRIS ; external SCK drive bsf SCK_TRIS ; SCK bsf SS_TRIS ; SS BANKSEL PORTA bcf DRV_CLOCK bcf PIR1,SSP1IF banksel SSPCON1 movlw 0x24 ; SSPEN | SPI slave mode SS enable movwf SSPCON1 movlw 0xab movwf SSPBUF BANKSEL PORTA bsf DRV_CLOCK bcf DRV_CLOCK BANKSEL SSPBUF movwf SSPBUF ; test WCOL set .assert "(ssp1con & 0x80) == 0x80, \"FAILED MSSP SPI WCOL set\"" nop bcf SSPCON1,WCOL ; clear WCOL bit .assert "(ssp1con & 0x80) == 0x00, \"FAILED MSSP SPI WCOL was cleared\"" nop clrf loopcnt BANKSEL PORTA loop2: incf loopcnt,F bsf DRV_CLOCK bcf DRV_CLOCK btfss PIR1,SSP1IF goto loop2 BANKSEL SSPBUF movf SSPBUF,W .assert "W == 0x54, \"FAILED MSSP SPI Slave data\"" nop ; ; Test Slave receive overrun ; movlw 0x10 movwf loopcnt BANKSEL PORTA loop4: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt,F goto loop4 .assert "(ssp1con & 0x40) == 0x40, \"FAILED MSSP SPI SSPOV\"" nop ; ; Test SPI Master mode TMR2 ; BANKSEL SSPCON1 clrf SSPCON1 BANKSEL TRISA bsf DRV_CLOCK_TRIS ; external SCK drive off bcf SCK_TRIS ; SCK output BANKSEL PR2 movlw 0x1 movwf PR2 clrf TMR2 movlw 0x3C ; prescale = 1 postscale 16 movwf T2CON bcf PIR1,SSP1IF BANKSEL SSPCON1 movlw 0x23 ; SSPEN | SPI master TMR2 movwf SSPCON1 movlw 0xab movwf SSPBUF BANKSEL PIR1 loop3: btfss PIR1,SSP1IF goto loop3 .assert "(ssp1stat & 1) == 1, \"FAILED MSSP SPI Master TMR2, BF not set\"" nop BANKSEL SSPBUF movf SSPBUF,W .assert "(ssp1stat & 1) == 0, \"FAILED MSSP SPI Master TMR2, BF not cleared\"" nop .assert "W == 0x54, \"FAILED MSSP SPI Master TMR2 wrong data\"" nop ; ; Test SPI Master mode with different clock phasing ; movlw 0x31 ; SSPEN | SPI master Fosc/16 / CKP=1 movwf SSPCON1 bsf SSPSTAT,CKE ; Delayed clock phasing movlw 0xc9 movwf SSPBUF BANKSEL PIR1 bcf PIR1,SSP1IF loop5: btfss PIR1,SSP1IF goto loop5 .assert "(ssp1stat & 1) == 1, \"FAILED MSSP SPI Master BF not set\"" nop BANKSEL SSPBUF movf SSPBUF,W .assert "(ssp1stat & 1) == 0, \"FAILED MSSP SPI Master BF not cleared\"" nop .assert "W == 0x36, \"FAILED MSSP SPI Master (CKP) wrong data\"" nop ; ; Test SPI Master mode with BOEN set (MSSP1) ; bsf SSPCON3,BOEN movlw 0x3 movwf SSPADD ; Fosc/16 (sspadd+1)*4 movlw (1<. ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F1788. ;; Specifically, basic port operation, eerom, interrupts, ;; a2d, dac, SR latch, capacitor sense, and enhanced instructions list p=16f1788 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC & _PWRTE_ON & _BOREN_OFF & _MCLRE_ON & _CLKOUTEN_OFF __CONFIG _CONFIG2, _STVREN_ON ; & _WRT_BOOT ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm TSEN EQU H'0005' TSRNG EQU H'0004' ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 inte_cnt RES 1 iocaf_val RES 1 GLOBAL iocaf_val ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlp high start ; load upper byte of 'start' label goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 10000.0" .sim "V1.capacitance = 20e-12" .sim "V1.voltage=1.0" .sim "node n1" .sim "attach n1 porta0 porta3" .sim "node n2" .sim "attach n2 porta1 porta4" .sim "node n3" .sim "attach n3 porta2 porta5" .sim "node n4" .sim "attach n4 portb0 V1.pin" .sim "node n5" .sim "attach n5 porta6 porta7" .sim "node n6" .sim "attach n6 portb1 portb7" .sim "p16f1788.xpos = 72" .sim "p16f1788.ypos = 72" .sim "V1.xpos = 260" .sim "V1.ypos = 120" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location ; many of the core registers now saved and restored automatically ; movwf w_temp ; swapf STATUS,W clrf BSR ; set bank 0 ; movwf status_temp btfsc PIR2,EEIF goto ee_int btfsc INTCON,T0IF goto tmr0_int btfsc INTCON,IOCIF goto inte_int .assert "\"***FAILED p16f1788 unexpected interrupt\"" nop ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR2,EEIF goto exit_int ; Interrupt from INT pin inte_int incf inte_cnt,F BANKSEL IOCAF movf IOCAF,W movwf iocaf_val xorlw 0xff andwf IOCAF, F goto exit_int exit_int: retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;set clock to 16 Mhz BANKSEL OSCCON bsf OSCCON,6 call test_pir_pie_bits BANKSEL FVRCON ; Enable Core Temp, high range, FVR AD 2.048v movlw (1< ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA failures RES 1 ;; The Port Stimulus port, tris, and latch registers get mapped to these addresses: P1_DATA UDATA 0x10 P1_Port RES 1 P1_Tris RES 1 P1_Lat RES 1 P1_Pullup RES 1 ;; Alternate addresses to map the port stimulus. P1_AltPort RES 1 P1_AltTris RES 1 P1_AltLat RES 1 P1_AltPullup RES 1 GLOBAL P1_Port, P1_Tris, P1_Lat, P1_Pullup GLOBAL P1_AltPort, P1_AltTris, P1_AltLat, P1_AltPullup ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE 0x000 nop .sim "module library libgpsim_modules" .sim "module load PortStimulus P1" .sim "P1.xpos = 250.0" .sim "P1.ypos = 100.0" ;# First, create 8 nodes: .sim "node n0" .sim "node n1" .sim "node n2" .sim "node n3" .sim "node n4" .sim "node n5" .sim "node n6" .sim "node n7" ;# Now tie the ports together: .sim "attach n0 portb0 P1.p1" .sim "attach n1 portb1 P1.p2" .sim "attach n2 portb2 P1.p3" .sim "attach n3 portb3 P1.p4" .sim "attach n4 portb4 P1.p5" .sim "attach n5 portb5 P1.p6" .sim "attach n6 portb6 P1.p7" .sim "attach n7 portb7 P1.p8" ;# specify the PortStimulus addresses. ;These are the PIC addresses to where the PortStimulus registers are mapped. .sim "P1.portAdr = &P1_Port" .sim "P1.trisAdr = &P1_Tris" .sim "P1.latAdr = &P1_Lat" .sim "P1.pullupAdr = &P1_Pullup" CLRF failures ;Assume success CLRF BSR MOVLW 0xff MOVWF TRISB ;Port B is an input CLRF P1_Pullup ;Turn off the pullups (should already be off). CLRF P1_Tris ;Stimulus port is an output CLRF P1_Lat a_to_b_loop: MOVWF P1_Lat ;PortStimulus and Port B are externally XORWF PORTB,W ;connected. So we should see the bnz FAILED ;same thing on each port. DECFSZ PORTB,W goto a_to_b_loop ; Now let the P1's Pullups drive the bus. We'll simulate an ; open collector with a pullup resistor. The TRIS register ; will switch the driver direction. When configured as an output, ; the port module will drive low. When configured as an input, ; the pull up resistors will drive high. COMF P1_Pullup,F ;Turn on all of the pullups COMF P1_Tris,F ;Port Stimulus is now an input port CLRF P1_Lat ;make all of the drivers low MOVLW 0xff a_to_b_loop_pullups: MOVWF P1_Tris ;PortStimulus and Port B are externally XORWF PORTB,W ;connected. So we should see the bnz FAILED ;same thing on each port. DECFSZ PORTB,W goto a_to_b_loop_pullups ; Now let's write from PORTB to the PortStimulus. MOVLW 0xff ;Make the PortStimulus an input MOVWF P1_Tris COMF TRISB,F ;Port B is now an output port CLRW b_to_a_loop: MOVWF LATB ;Drive to Pic's Port B XORWF P1_Port,W ;Read the result on the PortStimulus. bnz FAILED ;Should be the same thing on each port. DECFSZ PORTB,W bra b_to_a_loop ; Now lets remap the port stimulus. CLRF P1_AltLat MOVLW 0x55 MOVWF LATB .assert "P1.port == 0x55 ,\"Failed - Unable to write to memory mapped port\"" nop ; Next check that reading the register as a register returns the expected value. ; Note, we have to use the reg() operator because had we written 'P1_Port == 0x55' ; we'd be comparing 0x55 to the symbolic representation of the register we replaced ; during the remap .assert "reg(&P1_Port) == 0x55 ,\"Failed - Unable to write to memory mapped port\"" nop .command "P1.portAdr = &P1_AltPort" .command "P1.trisAdr = &P1_AltTris" .command "P1.latAdr = &P1_AltLat" nop .assert "P1.port == 0x55 ,\"Failed - Unable to read port stimulus after remapping\"" nop ; note .assert "P1_Port == 0 ,\"Failed - Unable to restore register after port remapping\"" nop .assert "reg(&P1_Port) == 0 ,\"Failed - Unable to restore register after port remapping\"" nop .assert "reg(&P1_AltPort) == 0x55 ,\"Failed - Unable to remap port register a second time\"" nop .assert "\"*** PASSED 18F452 port test\"" bra $ FAILED: .assert "\"*** FAILED 18F452 port test\"" bra $ end gpsim-0.30.0/regression/rrr/0000775000076400007640000000000013117466027012720 500000000000000gpsim-0.30.0/regression/rrr/Makefile0000644000076400007640000000252312660230471014272 00000000000000 #EXTENDED_INSTRUCTIONS=1 include ../make.regression SCRIPT = 18f2455.lkr PROJECT = instructions OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : reset.cod eusart_2455.cod eusart_4455.cod q.cod q2455.cod dc628.cod stack.cod stack_reset.cod p16f505.cod spp_4455.cod p16f886.cod test_pwm2.cod p16f886.cod: p16f886.o gplink -o p16f886.cod p16f886.o test_pwm2.cod: test_pwm2.o gplink -o test_pwm2.cod test_pwm2.o reset.cod: reset.o $(SCRIPT) gplink --map -s $(SCRIPT) -o reset.cod reset.o stack.cod: stack.o $(SCRIPT) gplink --map -s $(SCRIPT) -o stack.cod stack.o stack_reset.cod: stack_reset.o $(SCRIPT) gplink --map -s $(SCRIPT) -o stack_reset.cod stack_reset.o q2455.cod: q2455.o $(SCRIPT) gplink --map -s $(SCRIPT) -o q2455.cod q2455.o q.cod: q.o 12f508_g.lkr p16f505.cod gplink --map -s 12f508_g.lkr -o q.cod q.o p16f505.cod: p16f505.o gplink --map -s 16f505_g.lkr -o p16f505.cod p16f505.o dc628.cod: dc628.o 16f628.lkr gplink --map -s 16f628.lkr -o dc628.cod dc628.o eusart_2455.cod: eusart_2455.o 18f2455.lkr gplink --map -s 18f2455.lkr -o eusart_2455.cod eusart_2455.o eusart_4455.cod: eusart_4455.o 18f2455.lkr gplink --map -s 18f2455.lkr -o eusart_4455.cod eusart_4455.o spp_4455.cod: spp_4455.o 18f2455.lkr gplink --map -s 18f2455.lkr -o spp_4455.cod spp_4455.o sim: gpsim-0.30.0/regression/wavegen/0000775000076400007640000000000013117466027013547 500000000000000gpsim-0.30.0/regression/wavegen/pulsegen.stc0000664000076400007640000000002413041763577016026 00000000000000 load pulsegen.cod gpsim-0.30.0/regression/wavegen/pulsegen.asm0000664000076400007640000002275513041763577016034 00000000000000 ;; Pulse Generator ;; ;; Test gpsim's built in pulse generator module list p=16f877a include include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA var1 RES 1 var2 RES 1 var3 RES 1 failures RES 1 status_temp RES 1 w_temp RES 1 interrupt_temp RES 1 GLOBAL var1,var2,var3,failures GLOBAL done ;; The capTime 16-bit register is a working register that keeps track ;; of the capture edge. capTimeH RES 1 capTimeL RES 1 capTimeHb RES 1 capTimeLb RES 1 GLOBAL capTimeH, capTimeL, capTimeHb, capTimeLb temp1 RES 1 temp2 RES 1 t1 RES 1 t2 RES 1 t3 RES 1 kz RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; Simulation Script .sim "module lib libgpsim_modules" .sim "module load pulsegen PG1" .sim "node nRC2" .sim "PG1.set = 0" .sim "PG1.clear = 0x200" .sim "PG1.period = 0x400" .sim "attach nRC2 PG1.pin portc2" ;---------------------------------------------------------------------- ; ******************* INTERRUPT VECTOR LOCATION ******************** ;---------------------------------------------------------------------- INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp ;; Are peripheral interrupts enabled? btfss INTCON,PEIE goto exit_int bsf STATUS,RP0 movf PIE1 ^ 0x80,W bcf STATUS,RP0 movwf interrupt_temp check_tmr1: btfsc PIR1,TMR1IF btfss interrupt_temp,TMR1IE goto check_ccp1 ;; tmr1 has rolled over bcf PIR1,TMR1IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover check_ccp1: btfsc PIR1,CCP1IF btfss interrupt_temp,CCP1IE goto exit_int bcf PIR1,CCP1IF ; Clear the pending interrupt bsf temp1,1 ; Set a flag to indicate match exit_int: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf failures ;Assume success. clrf kz ;kz == Known Zero. ;; disable (primarily) global and peripheral interrupts clrf INTCON ;; ;; CCP test ;; ;; The CCP module is intricately intertwined with the TMR1 ;; module. So first, let's initialize TMR1: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale ;; In this mode, TMR1 will count instruction cycles. clrf T1CON ; clrf PIR1 ; Clear the interrupt/roll over flag ;; Zero TMR1 clrf TMR1L clrf TMR1H ;; Start the timer bsf T1CON,TMR1ON ccp_test1: movlw (1< 5 call ccpWaitForPORTC2_low call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==4)" clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 6 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x10)" clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 7 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x40)" goto done ;------------------------------------------------------------------------ ;ccpCaptureTwoEvents ; ; Capture two events for the current CCP setting and return the time ; difference between them ccpCaptureTwoEvents: call ccpWaitForCapture movf CCPR1L,W movwf capTimeLb movf CCPR1H,W movwf capTimeHb call ccpWaitForCapture movf CCPR1L,W movwf capTimeL movf CCPR1H,W movwf capTimeH ; Subtract the time of the most recently captured edge from the previous one movf capTimeLb,W subwf capTimeL,F movf capTimeHb,W skpc incfsz capTimeHb,W subwf capTimeH,F return ;------------------------------------------------------------------------ ;ccpWaitForCapture ; ; Spin loop that polls an interrupt flag that is set whenever a capture ; interrupt triggers. ccpWaitForCapture: clrf t1 ;A 16-bit software timeout counter clrf t2 ccpWaitLoop: ;; The watchdog counter ensures we don't loop forever! call ccpWDCounter ;; ;; when an edge is captured, the interrupt routine will ;; set a flag: ;; btfss temp1,1 goto ccpWaitLoop bcf temp1,1 return ;------------------------------------------------------------------------ ccpWaitForPORTC2_high: btfsc PORTC,2 return call ccpWDCounter goto ccpWaitForPORTC2_high ccpWaitForPORTC2_low: btfss PORTC,2 return call ccpWDCounter goto ccpWaitForPORTC2_high ;------------------------------------------------------------------------ ; ccpWDCounter ; a 16bit watch dog counter is incremented by 1. If it rolls over then we failed. ccpWDCounter: incfsz t1,f return incfsz t2,f return goto failed ;If we get here then we haven't caught anything! ;Either a) there's a gpsim bug or b) the stimulus ;file is incorrect. ; movlw 1 ;This 16-bit software counter ; addwf t1,f ;will time out if there's something wrong, ; rlf kz,w ; addwf t2,f ; skpc ; return ;; ;; Compare ;; ;; Now for the compare mode. ccp_test2: goto done ;;########################################## clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf PORTC,2 ;CCP bit is an output bcf STATUS,RP0 ;; Start off the compare mode by setting the output on a compare match ;; ;; ccp = 8 <- Set output on match ;; ccp = 9 <- Clear output on match ;; ccp = 10 <- Just set the ccp1if flag, but don't change the output ;; ccp = 11 <- Reset tmr1 on a match movlw 0x8 movwf CCP1CON ;; clrf PIR1 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR1L movlw 0x12 movwf CCPR1H ;; Clear the interrupt flag clrf temp1 tt3: ;; Stop and clear tmr1 clrf T1CON clrf TMR1L clrf TMR1H ;; Now start it bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: btfss temp1,1 goto $-1 bcf temp1,1 ;; Try the next capture mode incf CCP1CON,F ;; If bit 2 of ccp1con is set then we're through with capture modes ;; (and are starting pwm modes) btfsc CCP1CON,2 goto done goto tt3 failed: .assert "\"*** FAILED Pulse Generator test\"" incf failures,F goto $ done: .assert "\"*** PASSED Pulse Generator test\"" goto $ end gpsim-0.30.0/regression/wavegen/Makefile0000664000076400007640000000030313041763577015131 00000000000000include ../make.regression all : pulsegen.cod pulsegen.cod : pulsegen.o gplink --map -s 16f877a.lkr -o $@ $^ sim: pulsegen pulsegen: pulsegen.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/wavegen/16f877a.lkr0000664000076400007640000000332013041763577015210 00000000000000// Sample linker command file for 16F877a and 876a // $Id: 16f877a.lkr 1828 2006-11-10 18:59:10Z borutr $ LIBPATH . CODEPAGE NAME=vectors START=0x0000 END=0x0004 PROTECTED CODEPAGE NAME=page0 START=0x0005 END=0x07FF CODEPAGE NAME=page1 START=0x0800 END=0x0FFF CODEPAGE NAME=page2 START=0x1000 END=0x17FF CODEPAGE NAME=page3 START=0x1800 END=0x1FFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=PROG3 ROM=page2 // ROM code space - page2 SECTION NAME=PROG4 ROM=page3 // ROM code space - page3 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/spi/0000775000076400007640000000000013117466027012706 500000000000000gpsim-0.30.0/regression/spi/16c62.lkr0000664000076400007640000000147413041763577014115 00000000000000// Sample linker command file for 16C62 // $Id: 16c62.lkr 1828 2006-11-10 18:59:10Z borutr $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x7F DATABANK NAME=gpr1 START=0xA0 END=0xBF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/spi/p16f88.asm0000664000076400007640000001302013041763577014266 00000000000000 list p=16f88 include include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_IO & _PWRTE_ON & _LVP_OFF & _BODEN_OFF & _MCLR_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16F88. ;; Specifically, I2C errorlevel -302 ; Printf Command .command macro x .direct "C", x endm #define SDO_PORT PORTB,2 #define SDI_PORT PORTB,1 #define SCK_PORT PORTB,4 #define SS_PORT PORTB,5 #define SDO_TRIS TRISB,2 #define SDI_TRIS TRISB,1 #define SCK_TRIS TRISB,4 #define SS_TRIS TRISB,5 #define DRV_CLOCK PORTA,1 #define DRV_CLOCK_TRIS TRISA,1 #define DRV_SS PORTA,2 #define DRV_SS_TRIS TRISA,2 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR w_temp RES 1 status_temp RES 1 loopcnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfss INTCON,SSPIF goto check ; other Interrupts ; bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,SSPIF check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "module load pu pu1" .sim "module load pu pu2" .sim "module load not not" .sim "p16f88.xpos = 72" .sim "p16f88.ypos = 24" .sim "pu1.xpos = 228" .sim "pu1.ypos = 24" .sim "pu2.xpos = 96" .sim "pu2.ypos = 240" .sim "not.xpos = 96" .sim "not.ypos = 168" .sim "node ss" .sim "attach ss portb5 porta2" ; Not SS .sim "node sck" .sim "attach sck portb4 porta1 pu1.pin" ; SCK .sim "node sdo" .sim "attach sdo not.in0 portb2 pu2.pin" .sim "node sdi" .sim "attach sdi portb1 not.out" bsf STATUS,RP0 ; bank 1 movlw 0xf6 ; set internal RC to 8 Mhz movwf OSCCON clrf ANSEL bcf SDO_TRIS ; SDO bcf SCK_TRIS ; SCK bcf DRV_SS_TRIS movlw 0xff movwf SSPSTAT .assert "sspstat == 0xC0, \"*** FAILED p16f88 SPI sspstat only SMP, CKE writable\"" clrf SSPSTAT BANKSEL SSPCON bsf DRV_SS ; set SS high ; ; Test SPI Master mode ; movlw 0x21 ; SSPEN | SPI master Fosc/16 movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop: btfss PIR1,SSPIF goto loop .assert "(sspstat & 1) == 1, \"*** FAILED p16f88 SSP SPI Master BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"*** FAILED p16f88 SSP SPI Master BF not cleared\"" nop .assert "W == 0x54, \"*** FAILED p16f88 SSP SPI Master wrong data\"" nop ; ; TEST SPI Slave mode with SS ; clrf SSPCON bsf STATUS,RP0 ; bank 1 bcf DRV_CLOCK_TRIS ; external SCK drive bsf SCK_TRIS ; SCK bsf SS_TRIS ; SS bcf STATUS,RP0 ; bank 0 bcf DRV_SS bcf DRV_CLOCK movlw 0x24 ; SSPEN | SPI slave mode SS enable movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF bsf DRV_CLOCK bcf DRV_CLOCK movwf SSPBUF ; test WCOL set .assert "(sspcon & 0x80) == 0x80, \"***FAILED p16f88 SSP SPI WCOL set\"" nop bcf SSPCON,WCOL ; clear WCOL bit .assert "(sspcon & 0x80) == 0x00, \"***FAILED p16f88 SSP SPI WCOL was cleared\"" nop ; SS is high, so transfer should not happen bsf DRV_SS movlw 0x0a movwf loopcnt ss_loop: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt goto ss_loop .assert "(pir1 & 0x08) == 0, \"*** FAILED p16f88 SSP SPI slave with SS\"" nop bcf DRV_SS ; clear SS clrf loopcnt loop2: incf loopcnt,F bsf DRV_CLOCK bcf DRV_CLOCK btfss PIR1,SSPIF goto loop2 movf SSPBUF,W .assert "W == 0x54, \"*** FAILED p16f88 SSP SPI Slave data\"" nop ; ; Test Slave receive overrun ; movlw 0x10 movwf loopcnt loop4: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt,F goto loop4 .assert "(sspcon & 0x40) == 0x40, \"*** FAILED p16f88 SSP SPI SSPOV\"" nop ; ; Test SPI Master mode TMR2 ; clrf SSPCON bsf STATUS,RP0 ; bank 1 bsf DRV_CLOCK_TRIS ; external SCK drive off bcf SCK_TRIS ; SCK output movlw 0x1 movwf PR2 bcf STATUS,RP0 ; bank 0 clrf TMR2 movlw 0x3C ; prescale = 1 postscale 16 movwf T2CON movlw 0x23 ; SSPEN | SPI master TMR2 movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop3: btfss PIR1,SSPIF goto loop3 .assert "(sspstat & 1) == 1, \"*** FAILED p16f88 SSP SPI Master TMR2, BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"*** FAILED p16f88 SSP SPI Master TMR2, BF not cleared\"" nop .assert "W == 0x54, \"*** FAILED p16f88 SSP SPI Master TMR2 wrong data\"" nop .assert "\"*** PASSED 16f88 SSP SPI test\"" goto $ end gpsim-0.30.0/regression/spi/Makefile0000664000076400007640000000063613041763577014301 00000000000000# PSP (Parallel Slave Port) module regression test # # include ../make.regression all : p16f88.cod p18f242.cod p16c62.cod p%.cod : p%.o gplink --map -s $*.lkr -o $@ $< sim: sim_p16f88 sim_p18f242 sim_p16c62 #sim_88: p16f88.cod # $(GPSIM) -i -c $(STARTUP_STC) -D STC=$< # #sim_242: p18f242.cod # $(GPSIM) -i -c $(STARTUP_STC) -D STC=$< # #sim_c62: p16c62.cod # $(GPSIM) -i -c $(STARTUP_STC) -D STC=$< # gpsim-0.30.0/regression/spi/16f88.lkr0000664000076400007640000000304113041763577014120 00000000000000// Sample linker command file for 16F88 LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2009 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED SHAREBANK NAME=sfrnobnk START=0x70 END=0x7F SHAREBANK NAME=sfrnobnk START=0xF0 END=0xFF SHAREBANK NAME=sfrnobnk START=0x170 END=0x17F SHAREBANK NAME=sfrnobnk START=0x1F0 END=0x1FF DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG0 ROM=page0 // ROM code space SECTION NAME=PROG1 ROM=page1 // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEVICEID ROM=.device_id // Device ID SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/spi/p16c62.asm0000664000076400007640000001261513041763577014264 00000000000000 list p=16c62 include include __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON ;; The purpose of this program is to test gpsim's ability to simulate a pic 16F88. ;; Specifically, SPI errorlevel -302 ; Printf Command .command macro x .direct "C", x endm #define SDO_PORT PORTC,5 #define SDI_PORT PORTC,4 #define SCK_PORT PORTC,3 #define SS_PORT PORTA,5 #define SDO_TRIS TRISC,5 #define SDI_TRIS TRISC,4 #define SCK_TRIS TRISC,3 #define SS_TRIS TRISA,5 #define DRV_CLOCK PORTA,1 #define DRV_CLOCK_TRIS TRISA,1 #define DRV_SS PORTA,2 #define DRV_SS_TRIS TRISA,2 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA w_temp RES 1 status_temp RES 1 loopcnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfss INTCON,SSPIF goto check ; other Interrupts ; bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,SSPIF check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "module load pu pu1" .sim "module load pu pu2" .sim "module load not not" .sim "not.xpos=240." .sim "not.ypos=200." .sim "pu1.xpos=228." .sim "pu1.ypos=72." .sim "pu2.xpos=228." .sim "pu2.ypos=120." .sim "node ss" .sim "attach ss porta5 porta2" ; Not SS .sim "node sck" .sim "attach sck portc3 porta1 pu1.pin" ; SCK .sim "node sdo" .sim "attach sdo not.in0 portc5 pu2.pin" .sim "node sdi" .sim "attach sdi portc4 not.out" bsf STATUS,RP0 ; bank 1 bcf SDO_TRIS ; SDO bcf SCK_TRIS ; SCK bcf DRV_SS_TRIS movlw 0xff movwf SSPSTAT .assert "sspstat == 0x00, \"*** FAILED p16c62 SPI BSSP sspstat not writable\"" clrf SSPSTAT bcf STATUS,RP0 ; bank 0 bsf DRV_SS ; set SS high ; ; Test SPI Master mode ; movlw 0x21 ; SSPEN | SPI master Fosc/16 movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop: btfss PIR1,SSPIF goto loop .assert "(sspstat & 1) == 1, \"*** FAILED p16c62 BSSP SPI Master BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"*** FAILED p16c62 BSSP SPI Master BF not cleared\"" nop .assert "W == 0x54, \"*** FAILED p16c62 BSSP SPI Master wrong data\"" nop ; ; TEST SPI Slave mode with SS ; clrf SSPCON bsf STATUS,RP0 ; bank 1 bcf DRV_CLOCK_TRIS ; external SCK drive bsf SCK_TRIS ; SCK bsf SS_TRIS ; SS bcf STATUS,RP0 ; bank 0 bcf DRV_SS ; enable bcf DRV_CLOCK movlw 0x24 ; SSPEN | SPI slave mode SS enable movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF bsf DRV_CLOCK bcf DRV_CLOCK movwf SSPBUF ; test WCOL set .assert "(sspcon & 0x80) == 0x80, \"*** FAILED p16c62 BSSP SPI WCOL set\"" nop bcf SSPCON,WCOL ; clear WCOL bit .assert "(sspcon & 0x80) == 0x00, \"*** FAILED p16c62 BSSP SPI WCOL was cleared\"" nop nop ; SS is high, so transfer should not happen bsf DRV_SS movlw 0x0a movwf loopcnt ss_loop: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt goto ss_loop .assert "(pir1 & 0x08) == 0, \"*** FAILED p16c62 SSP SPI slave SS block\"" nop bcf DRV_SS ; clear SS clrf loopcnt loop2: incf loopcnt,F bsf DRV_CLOCK bcf DRV_CLOCK btfss PIR1,SSPIF goto loop2 movf SSPBUF,W .assert "W == 0x54, \"*** FAILED p16c62 BSSP SPI Slave data\"" nop ; ; Test Slave receive overrun ; movlw 0x10 movwf loopcnt loop4: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt,F goto loop4 .assert "(sspcon & 0x40) == 0x40, \"*** FAILED p16c62 BSSP SPI SSPOV\"" nop ; ; Test SPI Master mode TMR2 ; clrf SSPCON bsf STATUS,RP0 ; bank 1 bsf DRV_CLOCK_TRIS ; external SCK drive off bcf SCK_TRIS ; SCK output movlw 0x1 movwf PR2 bcf STATUS,RP0 ; bank 0 clrf TMR2 movlw 0x3C ; prescale = 1 postscale 16 movwf T2CON movlw 0x23 ; SSPEN | SPI master TMR2 movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop3: btfss PIR1,SSPIF goto loop3 .assert "(sspstat & 1) == 1, \"*** FAILED p16c62 BSSP SPI Master TMR2, BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"*** FAILED p16c62 BSSP SPI Master TMR2, BF not cleared\"" nop .assert "W == 0x54, \"*** FAILED p16c62 BSSP SPI Master TMR2 wrong data\"" nop .assert "\"*** PASSED 16c62 BSSP SPI test\"" goto $ end gpsim-0.30.0/regression/spi/p18f242.asm0000664000076400007640000001224113041763577014344 00000000000000 list p=18f242 include include ;; The purpose of this program is to test gpsim's ability to simulate a pic 16F88. ;; Specifically, SPI errorlevel -302 ; Printf Command .command macro x .direct "C", x endm #define SDO_PORT PORTC,5 #define SDI_PORT PORTC,4 #define SCK_PORT PORTC,3 #define SS_PORT PORTA,5 #define SDO_TRIS TRISC,5 #define SDI_TRIS TRISC,4 #define SCK_TRIS TRISC,3 #define SS_TRIS TRISA,5 #define DRV_CLOCK PORTA,1 #define DRV_CLOCK_TRIS TRISA,1 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA w_temp RES 1 status_temp RES 1 loopcnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp btfss INTCON,SSPIF goto check ; other Interrupts ; bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,SSPIF check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "module load pu pu1" .sim "module load pu pu2" .sim "module load not not" ; .sim "p16f88.xpos = 132." ; .sim "p16f88.ypos = 96." .sim "not.xpos=252." .sim "not.ypos=216." .sim "pu1.xpos=84." .sim "pu1.ypos=316." .sim "pu2.xpos=228." .sim "pu2.ypos=108." .sim "node ss" .sim "attach ss porta5 porta2" ; Not SS .sim "node sck" .sim "attach sck portc3 porta1 pu1.pin" ; SCK .sim "node sdo" .sim "attach sdo not.in0 portc5 pu2.pin" .sim "node sdi" .sim "attach sdi portc4 not.out" movlw 0xf6 ; set internal RC to 8 Mhz movwf OSCCON bcf SDO_TRIS ; SDO bcf SCK_TRIS ; SCK movlw 0xff movwf SSPSTAT .assert "sspstat == 0xC0, \"SPI sspstat only SMP, CKE writable\"" clrf SSPSTAT ; ; Test SPI Master mode ; movlw 0x21 ; SSPEN | SPI master Fosc/16 movwf SSPCON1 bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop: btfss PIR1,SSPIF goto loop .assert "(sspstat & 1) == 1, \"FAILED MSSP SPI Master BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"FAILED MSSP SPI Master BF not cleared\"" nop .assert "W == 0x54, \"FAILED MSSP SPI Master wrong data\"" nop ; ; TEST SPI Slave mode with SS ; clrf SSPCON1 bcf DRV_CLOCK_TRIS ; external SCK drive bsf SCK_TRIS ; SCK bsf SS_TRIS ; SS bcf DRV_CLOCK movlw 0x24 ; SSPEN | SPI slave mode SS enable movwf SSPCON1 bcf PIR1,SSPIF movlw 0xab movwf SSPBUF bsf DRV_CLOCK bcf DRV_CLOCK movwf SSPBUF ; test WCOL set .assert "(sspcon1 & 0x80) == 0x80, \"FAILED MSSP SPI WCOL set\"" nop bcf SSPCON1,WCOL ; clear WCOL bit .assert "(sspcon1 & 0x80) == 0x00, \"FAILED MSSP SPI WCOL was cleared\"" nop clrf loopcnt loop2: incf loopcnt,F bsf DRV_CLOCK bcf DRV_CLOCK btfss PIR1,SSPIF goto loop2 movf SSPBUF,W .assert "W == 0x54, \"FAILED MSSP SPI Slave data\"" nop ; ; Test Slave receive overrun ; movlw 0x10 movwf loopcnt loop4: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt,F goto loop4 .assert "(sspcon1 & 0x40) == 0x40, \"FAILED MSSP SPI SSPOV\"" nop ; ; Test SPI Master mode TMR2 ; clrf SSPCON1 bsf DRV_CLOCK_TRIS ; external SCK drive off bcf SCK_TRIS ; SCK output movlw 0x1 movwf PR2 clrf TMR2 movlw 0x3C ; prescale = 1 postscale 16 movwf T2CON movlw 0x23 ; SSPEN | SPI master TMR2 movwf SSPCON1 bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop3: btfss PIR1,SSPIF goto loop3 .assert "(sspstat & 1) == 1, \"FAILED MSSP SPI Master TMR2, BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"FAILED MSSP SPI Master TMR2, BF not cleared\"" nop .assert "W == 0x54, \"FAILED MSSP SPI Master TMR2 wrong data\"" nop ; ; Test SPI Master mode with different clock phasing ; movlw 0x31 ; SSPEN | SPI master Fosc/16 / CKP=1 movwf SSPCON1 bsf SSPSTAT,CKE ; Delayed clock phasing bcf PIR1,SSPIF movlw 0xc9 movwf SSPBUF loop5: btfss PIR1,SSPIF goto loop5 .assert "(sspstat & 1) == 1, \"FAILED MSSP SPI Master BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"FAILED MSSP SPI Master BF not cleared\"" nop .assert "W == 0x36, \"FAILED MSSP SPI Master (CKP) wrong data\"" nop .assert "\"*** PASSED 18f242 MSSP SPI test\"" goto $ end gpsim-0.30.0/regression/spi/18f242.lkr0000664000076400007640000000164113041763577014176 00000000000000// $Id: 18f242.lkr 1828 2006-11-10 18:59:10Z borutr $ // File: 18f242.lkr // Sample linker script for the PIC18F242 processor LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x3FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/regression/wdt/0000775000076400007640000000000013117466027012711 500000000000000gpsim-0.30.0/regression/wdt/nwdt_16f88.asm0000664000076400007640000000266213041754701015144 00000000000000 ;; 16F88 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word ;; WDT turned on by SWDTEN bit of WDTCON register list p=16f88 include "p16f88.inc" include .command macro x .direct "C", x endm __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _FOSC_EXTRCIO & _MCLR_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16f88.BreakOnReset = false" .sim "break c 0x10000" .sim "p16f88.frequency=10000" btfss STATUS,NOT_TO goto wdt_reset ; Delay past time WDT expected to go off call delay1 call delay1 movlw 0x07 ; turn on WDT with prescale 256 banksel WDTCON movwf WDTCON banksel temp incf phase, F ; WDT should now go off in less than one delay call delay1 nop done: .assert "\"*** FAILED p16f88 SWDTEN did not turn on WDT\"" nop GOTO $ wdt_reset: btfss phase,0 goto FAILED .assert "(status & 0x18) == 0x08,\"*** FAILED 16f88 status after WDT Reset\"" nop .assert "\"*** PASSED p16f88 no WDT, SWDTEN\"" goto $ FAILED: .assert "\"*** FAILED p16f88 unexpected WDT triggered\"" nop goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return end gpsim-0.30.0/regression/wdt/nwdt_16f628.asm0000664000076400007640000000171213041763600015215 00000000000000 ;; 16F628 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word list p=16f628 include "p16f628.inc" include .command macro x .direct "C", x endm __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF cblock 0x20 temp tmp2 endc ORG 0 .sim "p16f628.BreakOnReset = false" .sim "p16f628.frequency = 10000" .sim "break c 0x10000" btfss STATUS,NOT_TO goto wdt_reset ; Delay past time WDT expected to go off call delay1 call delay1 done: .assert "\"*** PASSED p16f628 no WDT test\"" nop GOTO $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: .assert "\"*** FAILED p16f628 unexpected WDT triggered\"" nop goto $ end gpsim-0.30.0/regression/wdt/nwdt_18f452.asm0000664000076400007640000000254513041763600015217 00000000000000 ;; 18F452 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word ;; WDT turned on by SWDTEN bit of WDTCON register list p=18f452 include "p18f452.inc" include .command macro x .direct "C", x endm __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_64_2H cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p18f452.BreakOnReset = false" .sim "break c 0x10000" .sim "p18f452.frequency=10000" btfss RCON,NOT_TO goto wdt_reset ; Delay past time WDT expected to go off call delay1 call delay1 movlw 0x01 ; turn on WDT banksel WDTCON movwf WDTCON banksel temp incf phase, F ; WDT should now go off in less than one delay call delay1 nop done: .assert "\"*** FAILED p18f452 SWDTEN did not turn on WDT\"" nop GOTO $ wdt_reset: btfss phase,0 goto FAILED .assert "(rcon & 0x0c) == 0x04,\"*** FAILED 18f452 status after WDT Reset\"" nop .assert "\"*** PASSED p18f452 no WDT, SWDTEN\"" goto $ FAILED: .assert "\"*** FAILED p18f452 unexpected WDT triggered\"" nop goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return end gpsim-0.30.0/regression/wdt/16f648a.lkr0000664000076400007640000000310613041763600014333 00000000000000// Sample linker command file for 16F648A LIBPATH . CODEPAGE NAME=page0 START=0x0 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.devid START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=.oscval START=0x2008 END=0x2008 PROTECTED CODEPAGE NAME=.test START=0x2009 END=0x200F PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x120 END=0x16F SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF PROTECTED SHAREBANK NAME=gprnobnk START=0x170 END=0x17F PROTECTED SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF PROTECTED SECTION NAME=PROG1 ROM=page0 // ROM code space SECTION NAME=PROG2 ROM=page1 // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEVID ROM=.devid // device id SECTION NAME=OSCVAL ROM=.oscval // Oscillator value SECTION NAME=TEST ROM=.test // Test program memory SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/wdt/pwdt_16f1823.asm0000664000076400007640000000337513041763600015304 00000000000000 ;; 16F88 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word ;; WDT turned on by SWDTEN bit of WDTCON register list p=16f1823 include "p16f1823.inc" include .command macro x .direct "C", x endm __CONFIG _CONFIG1, _CP_OFF & _WDTE_SWDTEN & _MCLRE_OFF & _IESO_OFF & _FCMEN_OFF __CONFIG _CONFIG2, _WRT_OFF cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16f1823.BreakOnReset = false" .sim "break c 0x20000" .sim "p16f1823.frequency=10000" btfss STATUS,NOT_TO goto wdt_reset ; WDT should not go off, delay past time WDT would be expected to go off call delay1 call delay1 movlw 0x06|(1>>SWDTEN) ; turn on WDT with prescale 256 banksel WDTCON movwf WDTCON banksel temp incf phase, F ; WDT should now go off in less than one delay call delay1 nop done: .assert "\"*** FAILED p16f1823 SWDTEN did not turn on WDT\"" nop GOTO $ wdt_reset: btfsc phase,0 goto sleep_test goto FAILED sleep_test: movlw 0x06|(1>>SWDTEN) ; turn on WDT with prescale 256 banksel WDTCON movwf WDTCON banksel phase incf phase, F sleep nop movlw 0x25 ; test max bits banksel WDTCON movwf WDTCON .assert "wdtcon == 0x25, \"*** FAILED 16f1823 writable bits of WDTCON\"" nop .assert "\"*** PASSED p16f1823 config WDTE_SWDTEN\"" nop goto $ FAILED: .assert "\"*** FAILED p16f1823 unexpected WDT triggered\"" nop goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return end gpsim-0.30.0/regression/wdt/wdt_18f4620.asm0000664000076400007640000000360213041763600015115 00000000000000 ;; 18F452 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 kHz ;; list p=18f4620 include "p18f4620.inc" include .command macro x .direct "C", x endm cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p18f4620.BreakOnReset = false" .sim "break c 0x10000" .sim "p18f4620.frequency=10000" ; are we seeing a WDT reset? btfss RCON,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; During sleep, Ń–f the WDT goes off, PC = PC + 2 bcf T0CON,5 ; set tmr0 as timer movf TMR0L,W sleep .assert "(rcon & 0x0c) == 0x00,\"*** FAILED p18f4620 status after sleep\"" nop .assert "(tmr0l - W) <= 0x4,\"*** FAILED p18f4620 TMR0 stops during sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(rcon & 0x0c) == 0x0c,\"*** FAILED p18f4620 status after clrwdt\"" call delay1 call delay1 FAILED: .assert "\"*** FAILED p18f4620 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p18f4620 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(rcon & 0x0c) == 0x04,\"*** FAILED p18f4620 status after WDT Reset\"" nop .assert "\"*** PASSED p18f4620 WDT\"" goto $ end gpsim-0.30.0/regression/wdt/nwdt_16f1823.asm0000664000076400007640000000274613042542245015304 00000000000000 ;; 16F88 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word ;; WDT turned on by SWDTEN bit of WDTCON register list p=16f1823 include "p16f1823.inc" include .command macro x .direct "C", x endm __CONFIG _CONFIG1, _CP_OFF & _WDTE_OFF & _MCLRE_OFF & _IESO_OFF & _FCMEN_OFF __CONFIG _CONFIG2, _WRT_OFF cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16f1823.BreakOnReset = false" .sim "break c 0x20000" .sim "p16f1823.frequency=10000" btfss STATUS,NOT_TO goto wdt_reset BANKSEL OSCCON .assert "osccon == 0x38, \"*** FAILED p16f1823 osccon pow value\"" nop movlw 0xff movwf OSCCON .assert "osccon == 0xfb, \"*** FAILED p16f1823 osccon write mask\"" nop ; WDT should not go off, delay past time WDT would be expected to go off call delay1 call delay1 movlw 0x07 ; Set SWDTEN and prescale 256 banksel WDTCON movwf WDTCON banksel temp incf phase, F ; WDT should not go off, wait one delay call delay1 nop done: .assert "\"*** PASSED p16f1823 config WDTE_OFF\"" nop GOTO $ wdt_reset: goto FAILED FAILED: .assert "\"*** FAILED p16f1823 unexpected WDT triggered\"" nop goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return end gpsim-0.30.0/regression/wdt/18f4620.lkr0000664000076400007640000000315413041763600014251 00000000000000// File: 18f4620.lkr // Sample linker script for the PIC18F4620 processor // Not intended for use with MPLAB C18. For C18 projects, // use the linker scripts provided with that product. LIBPATH . CODEPAGE NAME=page START=0x0 END=0xFFFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF003FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF DATABANK NAME=gpr6 START=0x600 END=0x6FF DATABANK NAME=gpr7 START=0x700 END=0x7FF DATABANK NAME=gpr8 START=0x800 END=0x8FF DATABANK NAME=gpr9 START=0x900 END=0x9FF DATABANK NAME=gpr10 START=0xA00 END=0xAFF DATABANK NAME=gpr11 START=0xB00 END=0xBFF DATABANK NAME=gpr12 START=0xC00 END=0xCFF DATABANK NAME=gpr13 START=0xD00 END=0xDFF DATABANK NAME=gpr14 START=0xE00 END=0xEFF DATABANK NAME=gpr15 START=0xF00 END=0xF7F ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED gpsim-0.30.0/regression/wdt/18f452.lkr0000664000076400007640000000200513041763600014162 00000000000000// $Id: 18f452.lkr 1458 2006-02-18 05:12:33Z sdattalo $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=page START=0x00 END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/regression/wdt/16f628.lkr0000664000076400007640000000240313041763600014167 00000000000000// Sample linker command file for 16F628 // $Id: 16f628.lkr,v 1.9 2006/08/19 02:50:39 craigfranklin Exp $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x217F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x120 END=0x14F SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/wdt/nwdt_16c64.asm0000664000076400007640000000164213041763600015126 00000000000000 ;; 16C64 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word list p=16c64 include "p16c64.inc" include .command macro x .direct "C", x endm __CONFIG _WDT_OFF & _RC_OSC cblock 0x20 temp tmp2 endc ORG 0 .sim "p16c64.BreakOnReset = false" .sim "p16c64.frequency = 10000" .sim "break c 0x10000" btfss STATUS,NOT_TO goto wdt_reset ; Delay past time WDT expected to go off call delay1 call delay1 done: .assert "\"*** PASSED p16c64 no WDT test\"" nop GOTO $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: .assert "\"*** FAILED p16c64 unexpected WDT triggered\"" nop goto $ end gpsim-0.30.0/regression/wdt/16f1823.lkr0000664000076400007640000001367113041763600014256 00000000000000// File: 16f1823_g.lkr // Generic linker script for the PIC16F1823 processor LIBPATH . CODEPAGE NAME=page0 START=0x0 END=0x7FF CODEPAGE NAME=.idlocs START=0x8000 END=0x8003 PROTECTED CODEPAGE NAME=.devid START=0x8006 END=0x8006 PROTECTED CODEPAGE NAME=.config START=0x8007 END=0x8008 PROTECTED CODEPAGE NAME=eedata START=0xF000 END=0xF0FF PROTECTED LINEARMEM NAME=linear0 START=0x2000 END=0x206F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=sfr4 START=0x200 END=0x21F PROTECTED DATABANK NAME=sfr5 START=0x280 END=0x29F PROTECTED DATABANK NAME=sfr6 START=0x300 END=0x31F PROTECTED DATABANK NAME=sfr7 START=0x380 END=0x39F PROTECTED DATABANK NAME=sfr8 START=0x400 END=0x41F PROTECTED DATABANK NAME=sfr9 START=0x480 END=0x49F PROTECTED DATABANK NAME=sfr10 START=0x500 END=0x51F PROTECTED DATABANK NAME=sfr11 START=0x580 END=0x59F PROTECTED DATABANK NAME=sfr12 START=0x600 END=0x61F PROTECTED DATABANK NAME=sfr13 START=0x680 END=0x69F PROTECTED DATABANK NAME=sfr14 START=0x700 END=0x71F PROTECTED DATABANK NAME=sfr15 START=0x780 END=0x79F PROTECTED DATABANK NAME=sfr16 START=0x800 END=0x81F PROTECTED DATABANK NAME=sfr17 START=0x880 END=0x89F PROTECTED DATABANK NAME=sfr18 START=0x900 END=0x91F PROTECTED DATABANK NAME=sfr19 START=0x980 END=0x99F PROTECTED DATABANK NAME=sfr20 START=0xA00 END=0xA1F PROTECTED DATABANK NAME=sfr21 START=0xA80 END=0xA9F PROTECTED DATABANK NAME=sfr22 START=0xB00 END=0xB1F PROTECTED DATABANK NAME=sfr23 START=0xB80 END=0xB9F PROTECTED DATABANK NAME=sfr24 START=0xC00 END=0xC1F PROTECTED DATABANK NAME=sfr25 START=0xC80 END=0xC9F PROTECTED DATABANK NAME=sfr26 START=0xD00 END=0xD1F PROTECTED DATABANK NAME=sfr27 START=0xD80 END=0xD9F PROTECTED DATABANK NAME=sfr28 START=0xE00 END=0xE1F PROTECTED DATABANK NAME=sfr29 START=0xE80 END=0xE9F PROTECTED DATABANK NAME=sfr30 START=0xF00 END=0xF1F PROTECTED DATABANK NAME=sfr31 START=0xF80 END=0xFEF PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F SHADOW=linear0:0x2000 DATABANK NAME=gpr1 START=0xA0 END=0xBF SHADOW=linear0:0x2050 SHAREBANK NAME=gprnobank START=0x70 END=0x7F SHAREBANK NAME=gprnobank START=0xF0 END=0xFF PROTECTED SHAREBANK NAME=gprnobank START=0x170 END=0x17F PROTECTED SHAREBANK NAME=gprnobank START=0x1F0 END=0x1FF PROTECTED SHAREBANK NAME=gprnobank START=0x270 END=0x27F PROTECTED SHAREBANK NAME=gprnobank START=0x2F0 END=0x2FF PROTECTED SHAREBANK NAME=gprnobank START=0x370 END=0x37F PROTECTED SHAREBANK NAME=gprnobank START=0x3F0 END=0x3FF PROTECTED SHAREBANK NAME=gprnobank START=0x470 END=0x47F PROTECTED SHAREBANK NAME=gprnobank START=0x4F0 END=0x4FF PROTECTED SHAREBANK NAME=gprnobank START=0x570 END=0x57F PROTECTED SHAREBANK NAME=gprnobank START=0x5F0 END=0x5FF PROTECTED SHAREBANK NAME=gprnobank START=0x670 END=0x67F PROTECTED SHAREBANK NAME=gprnobank START=0x6F0 END=0x6FF PROTECTED SHAREBANK NAME=gprnobank START=0x770 END=0x77F PROTECTED SHAREBANK NAME=gprnobank START=0x7F0 END=0x7FF PROTECTED SHAREBANK NAME=gprnobank START=0x870 END=0x87F PROTECTED SHAREBANK NAME=gprnobank START=0x8F0 END=0x8FF PROTECTED SHAREBANK NAME=gprnobank START=0x970 END=0x97F PROTECTED SHAREBANK NAME=gprnobank START=0x9F0 END=0x9FF PROTECTED SHAREBANK NAME=gprnobank START=0xA70 END=0xA7F PROTECTED SHAREBANK NAME=gprnobank START=0xAF0 END=0xAFF PROTECTED SHAREBANK NAME=gprnobank START=0xB70 END=0xB7F PROTECTED SHAREBANK NAME=gprnobank START=0xBF0 END=0xBFF PROTECTED SHAREBANK NAME=gprnobank START=0xC70 END=0xC7F PROTECTED SHAREBANK NAME=gprnobank START=0xCF0 END=0xCFF PROTECTED SHAREBANK NAME=gprnobank START=0xD70 END=0xD7F PROTECTED SHAREBANK NAME=gprnobank START=0xDF0 END=0xDFF PROTECTED SHAREBANK NAME=gprnobank START=0xE70 END=0xE7F PROTECTED SHAREBANK NAME=gprnobank START=0xEF0 END=0xEFF PROTECTED SHAREBANK NAME=gprnobank START=0xF70 END=0xF7F PROTECTED SHAREBANK NAME=gprnobank START=0xFF0 END=0xFFF PROTECTED SECTION NAME=PROG0 ROM=page0 // ROM code space - page0 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEEPROM ROM=eedata // Data EEPROM SECTION NAME=LINEAR0 RAM=linear0 // Linear Memory gpsim-0.30.0/regression/wdt/Makefile0000664000076400007640000000127413041763600014266 00000000000000# WDT module regression test # # include ../make.regression all : wdt_16f88.cod nwdt_16f88.cod wdt_16f628.cod nwdt_16f628.cod \ wdt_16c64.cod nwdt_16c64.cod wdt_18f452.cod nwdt_18f452.cod \ wdt_10f200.cod nwdt_16f648a.cod wdt_18f4620.cod \ nwdt_18f4620.cod pwdt_16f1823.cod nwdt_16f1823.cod p%.cod : p%.o gplink --map -s $*.lkr -o $@ $< wdt_%.cod : wdt_%.o gplink --map -s $*.lkr -o $@ $< nwdt_%.cod : nwdt_%.o gplink --map -s $*.lkr -o $@ $< pwdt_%.cod : pwdt_%.o gplink --map -s $*.lkr -o $@ $< sim: sim_wdt_16f88 sim_nwdt_16f88 sim_wdt_16f628 sim_nwdt_16f628 \ sim_wdt_16c64 sim_nwdt_16c64 sim_wdt_18f452 sim_nwdt_18f452 \ sim_wdt_10f200 sim_wdt_18f4620 sim_nwdt_18f4620 gpsim-0.30.0/regression/wdt/wdt_16f88.asm0000664000076400007640000000577213057520410014766 00000000000000 ;; 16F88 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=16f88 include "p16f88.inc" include .command macro x .direct "C", x endm cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16f88.BreakOnReset = false" .sim "break c 0x100000" .sim "p16f88.frequency=10000" .sim "symbol cycleCounter=0" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. BANKSEL OSCCON movlw 0xff movwf OSCCON .assert "osccon == 0x73, \"*** FAILED 18f88 osccon writable bits\"" nop bcf OSCCON,SCS0 movlw 0x72 ; set RC clock 8MHz movwf OSCCON .assert "osccon == 0x76, \"*** FAILED 18f88 osccon IOFS OK\"" nop movlw 0x12 ; set RC clock 125 kHz movwf OSCCON sleep nop nop .command "cycleCounter = cycles" nop btfss OSCCON,IOFS ; wait for stable goto $-1 ; at 125 kHz 4ms delay = 125 cycles .assert "((cycles - cycleCounter) >= 125) && ((cycles - cycleCounter) <= 129), \"*** FAILED 16f88 RC stable delay from sleep\"" nop movlw 0x02 ; set RC clock 31 kHz movwf OSCCON .assert "osccon == 0x0e, \"*** FAILED 18f88 osccon IOFS OK high to low\"" nop bsf OSCCON,IRCF2 ; set RC clock 1MHz .command "cycleCounter = cycles" nop btfss OSCCON,IOFS ; wait for stable goto $-1 ; at 1MHz 4ms delay = 1000 cycles .assert "((cycles - cycleCounter) >= 1000) && ((cycles - cycleCounter) <= 1004), \"*** FAILED 16f88 RC stable delay low to high\"" nop bcf OSCCON,SCS1 ; turn off RC clock .assert "p16f88.frequency == 10000.,\"*** FAILED 18f88 frequency \"" nop call delay1 clrwdt call delay1 ; ; My reading of the specs indicate sleep should continue (no reset) ; when the WDT goes off sleeps continue sleep nop .assert "(status & 0x18) == 0x00,\"*** FAILED 16f88 status after sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 16f88 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p16f88 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p16f88 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(status & 0x18) == 0x08,\"*** FAILED 16f88 status after WDT Reset\"" nop .assert "\"*** PASSED p16f88 WDT\"" goto $ end gpsim-0.30.0/regression/wdt/wdt_18f452.asm0000664000076400007640000000357413041763600015044 00000000000000 ;; 18F452 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 kHz ;; list p=18f452 include "p18f452.inc" include .command macro x .direct "C", x endm cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p18f452.BreakOnReset = false" .sim "break c 0x10000" .sim "p18f452.frequency=10000" ; are we seeing a WDT reset? btfss RCON,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; During sleep, Ń–f the WDT goes off, PC = PC + 2 bcf T0CON,5 ; set tmr0 as timer movf TMR0L,W sleep nop .assert "(rcon & 0x0c) == 0x00,\"*** FAILED p18f452 status after sleep\"" nop .assert "(tmr0l - W) <= 0x4,\"*** FAILED p18f452 TMR0 stops during sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(rcon & 0x0c) == 0x0c,\"*** FAILED p18f452 status after clrwdt\"" call delay1 call delay1 FAILED: .assert "\"*** FAILED p18f452 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p18f452 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(rcon & 0x0c) == 0x04,\"*** FAILED p18f452 status after WDT Reset\"" nop .assert "\"*** PASSED p18f452 WDT\"" goto $ end gpsim-0.30.0/regression/wdt/16c64.lkr0000664000076400007640000000140113041763600014073 00000000000000// Sample linker command file for 16C64 // $Id: 16c64.lkr,v 1.9 2006/08/19 02:50:37 craigfranklin Exp $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x7F DATABANK NAME=gpr1 START=0xA0 END=0xBF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations gpsim-0.30.0/regression/wdt/nwdt_16f648a.asm0000664000076400007640000000171613041763600015364 00000000000000 ;; 16F648 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word list p=16f648a include "p16f648a.inc" include .command macro x .direct "C", x endm __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF cblock 0x20 temp tmp2 endc ORG 0 .sim "p16f648a.BreakOnReset = false" .sim "p16f648a.frequency = 10000" .sim "break c 0x10000" btfss STATUS,NOT_TO goto wdt_reset ; Delay past time WDT expected to go off call delay1 call delay1 done: .assert "\"*** PASSED p16f648 no WDT test\"" nop GOTO $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: .assert "\"*** FAILED p16f648 unexpected WDT triggered\"" nop goto $ end gpsim-0.30.0/regression/wdt/10f200.lkr0000664000076400007640000000070513041763600014146 00000000000000// Sample linker command file for 10F200 LIBPATH . CODEPAGE NAME=page START=0x0 END=0xFF CODEPAGE NAME=.idlocs START=0x100 END=0x103 PROTECTED CODEPAGE NAME=.config START=0xFFF END=0xFFF PROTECTED DATABANK NAME=sfrs START=0x0 END=0x07 PROTECTED DATABANK NAME=gprs START=0x10 END=0x1F SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations gpsim-0.30.0/regression/wdt/16f88.lkr0000664000076400007640000000304113041763600014106 00000000000000// Sample linker command file for 16F88 LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2009 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED SHAREBANK NAME=sfrnobnk START=0x70 END=0x7F SHAREBANK NAME=sfrnobnk START=0xF0 END=0xFF SHAREBANK NAME=sfrnobnk START=0x170 END=0x17F SHAREBANK NAME=sfrnobnk START=0x1F0 END=0x1FF DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG0 ROM=page0 // ROM code space SECTION NAME=PROG1 ROM=page1 // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEVICEID ROM=.device_id // Device ID SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/wdt/wdt_16c64.asm0000664000076400007640000000353413041763600014752 00000000000000 ;; 16C64 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=16c64 include "p16c64.inc" include .command macro x .direct "C", x endm cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16c64.BreakOnReset = false" .sim "break c 0x10000" .sim "p16c64.frequency=10000" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; My reading of the specs indicate sleep should continue (no reset) ; when the WDT goes off sleeps continue sleep nop .assert "(status & 0x18) == 0x00,\"*** FAILED 16c64 status after sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 16c64 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p16c64 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p16c64 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(status & 0x18) == 0x08,\"*** FAILED 16c64 status after WDT Reset\"" nop .assert "\"*** PASSED p16c64 WDT\"" goto $ end gpsim-0.30.0/regression/wdt/wdt_10f200.asm0000664000076400007640000000354413041763600015020 00000000000000 ;; 10F200 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=10f200 include "p10f200.inc" include .command macro x .direct "C", x endm cblock 0x10 temp tmp2 phase endc ORG 0 .sim "p10f200.BreakOnReset = false" .sim "break c 0x10000" .sim "p10f200.frequency=10000" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; My reading of the specs indicate ; when the WDT goes off during sleep then reset sleep nop .assert "(status & 0x18) != 0x00,\"*** FAILED 10f200 WDT continue after sleep\"" nop next_phase: incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 10f200 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p10f200 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p10f200 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto next_phase .assert "(status & 0x18) == 0x08,\"*** FAILED 10f200 status after WDT Reset\"" nop .assert "\"*** PASSED p10f200 WDT\"" goto $ end gpsim-0.30.0/regression/wdt/nwdt_18f4620.asm0000664000076400007640000000255613041763600015302 00000000000000 ;; 18F4620 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT disabled by configuration word ;; WDT turned on by SWDTEN bit of WDTCON register list p=18f4620 include "p18f4620.inc" include .command macro x .direct "C", x endm __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_64_2H cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p18f4620.BreakOnReset = false" .sim "break c 0x10000" .sim "p18f4620.frequency=10000" btfss RCON,NOT_TO goto wdt_reset ; Delay past time WDT expected to go off call delay1 call delay1 movlw 0x01 ; turn on WDT banksel WDTCON movwf WDTCON banksel temp incf phase, F ; WDT should now go off in less than one delay call delay1 nop done: .assert "\"*** FAILED p18f4620 SWDTEN did not turn on WDT\"" nop GOTO $ wdt_reset: btfss phase,0 goto FAILED .assert "(rcon & 0x0c) == 0x04,\"*** FAILED 18f4620 status after WDT Reset\"" nop .assert "\"*** PASSED p18f4620 no WDT, SWDTEN\"" goto $ FAILED: .assert "\"*** FAILED p18f4620 unexpected WDT triggered\"" nop goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return end gpsim-0.30.0/regression/wdt/wdt_16f628.asm0000664000076400007640000000354713041763600015047 00000000000000 ;; 16F628 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=16f628 include "p16f628.inc" include .command macro x .direct "C", x endm cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16f628.BreakOnReset = false" .sim "break c 0x10000" .sim "p16f628.frequency=10000" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; My reading of the specs indicate sleep should continue (no reset) ; when the WDT goes off sleeps continue sleep nop .assert "(status & 0x18) == 0x00,\"*** FAILED 16f628 status after sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 16f628 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p16f628 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p16f628 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(status & 0x18) == 0x08,\"*** FAILED 16f628 status after WDT Reset\"" nop .assert "\"*** PASSED p16f628 WDT\"" goto $ end gpsim-0.30.0/regression/p16f91x/0000775000076400007640000000000013117466027013231 500000000000000gpsim-0.30.0/regression/p16f91x/qqq.stc0000664000076400007640000000253713115200272014457 00000000000000 # This file was written by gpsim. # You can use this file for example like this: # gpsim -s mycode.cod -c netlist.stc # If you want to add commands, you can create another .stc file # and load this file from it. Something like this: # ----------- myproject.stc --------------- # load s mycode.cod # frequency 12000000 # load c netlist.stc # ----------------------------------------- # You can then just load this new file: # gpsim -c myproject.stc # and use netlist.stc whenever you save from the breadboard. # # Processor position: module library libgpsim_modules # Modules: p16f917.BreakOnReset = true p16f917.SafeMode = true p16f917.UnknownMode = true p16f917.WarnMode = true p16f917.tmr1_freq = 32768 p16f917.xpos = 72 p16f917.ypos = 72 module load pullup V1 V1.capacitance = 0 V1.resistance = 100 V1.voltage = 5 V1.xpos = 240 V1.ypos = 72 module load pullup V2 V2.capacitance = 0 V2.resistance = 100 V2.voltage = 2 V2.xpos = 84 V2.ypos = 24 module load pullup V3 V3.capacitance = 0 V3.resistance = 1e+07 V3.voltage = 5 V3.xpos = 240 V3.ypos = 120 module load pullup V4 V4.capacitance = 0 V4.resistance = 100 V4.voltage = 0.5 V4.xpos = 84 V4.ypos = 348 # Connections: node na0 attach na0 V3.pin p16f917.porta0 node na1 attach na1 V1.pin p16f917.porta1 node na3 attach na3 V2.pin p16f917.porta3 node na4 attach na4 V4.pin p16f917.porta2 # End. gpsim-0.30.0/regression/p16f91x/netlist.stc0000664000076400007640000000253713115162226015345 00000000000000 # This file was written by gpsim. # You can use this file for example like this: # gpsim -s mycode.cod -c netlist.stc # If you want to add commands, you can create another .stc file # and load this file from it. Something like this: # ----------- myproject.stc --------------- # load s mycode.cod # frequency 12000000 # load c netlist.stc # ----------------------------------------- # You can then just load this new file: # gpsim -c myproject.stc # and use netlist.stc whenever you save from the breadboard. # # Processor position: module library libgpsim_modules # Modules: p16f917.BreakOnReset = true p16f917.SafeMode = true p16f917.UnknownMode = true p16f917.WarnMode = true p16f917.tmr1_freq = 32768 p16f917.xpos = 72 p16f917.ypos = 72 module load pullup V1 V1.capacitance = 0 V1.resistance = 100 V1.voltage = 5 V1.xpos = 240 V1.ypos = 72 module load pullup V2 V2.capacitance = 0 V2.resistance = 100 V2.voltage = 2 V2.xpos = 84 V2.ypos = 24 module load pullup V3 V3.capacitance = 0 V3.resistance = 1e+07 V3.voltage = 5 V3.xpos = 240 V3.ypos = 120 module load pullup V4 V4.capacitance = 0 V4.resistance = 100 V4.voltage = 0.5 V4.xpos = 84 V4.ypos = 348 # Connections: node na0 attach na0 V3.pin p16f917.porta0 node na1 attach na1 V1.pin p16f917.porta1 node na3 attach na3 V2.pin p16f917.porta3 node na4 attach na4 V4.pin p16f917.porta2 # End. gpsim-0.30.0/regression/p16f91x/i2c_low.inc0000664000076400007640000003227213076262724015212 00000000000000;**************************************************************************** ; ; Low Level I2C Routines ; ; Single Master Transmitter & Single Master Receiver Routines ; These routines can very easily be converted to Multi-Master System ; when PIC16C6X with on chip I2C Slave Hardware, Start & Stop Bit ; detection is available. ; ; The generic high level routines are given in I2C_HIGH.ASM ; ; ; Program: I2C_LOW.ASM ; Revision Date: ; 1-16-97 Compatibility with MPASMWIN 1.40 ; ;*************************************************************************** ;************************************************************************** ; I2C Bus Initialization ; ;************************************************************************** InitI2CBus_Master: bcf STATUS,RP0 movlw ~(1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16F914 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF bsf STATUS, RP0 ; Bank1 movlw 0x2F ; movwf PR2 ; bcf TRISC, 5 ; Make CCP1 pin an output bcf TRISD, 2 ; Make CCP2 pin an output clrf PIE1 ; Disable peripheral interrupts movlw 0x83 ; Tmr0 internal clock prescaler 16 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf PIR1 ; Clear peripheral interrupts Flags movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP1CON ; movlw 0x06 ; Start Timer2 prescaler is 16, just like TMR0 movwf T2CON movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 00 movwf CCP2CON ; .assert "ccpr1l != ccpr1h, \"CCPR1H before TRM2 reset\"" nop ; ; The CCP1 interrupt is disabled, ; do polling on the TMR2 Interrupt flag bit ; PWM_Period_Match btfss PIR1, TMR2IF goto PWM_Period_Match clrf TMR0 .assert "ccpr1l == ccpr1h, \"CCPR1H loaded from CCPR1H\"" nop .assert "(portc & 0x20) == 0x20, \"CCP1 is high start PWM_Period_Match\"" nop .assert "(portd & 0x04) == 0x04, \"CCP2 is high start PWM_Period_Match\"" nop ; loop until CCP2 goes low btfsc PORTD,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP2 duty cycle PWM_Period_Match\"" nop ; loop until CCP1 goes low btfsc PORTC,5 goto $-1 .assert "tmr0 == 0x1f, \"CCP1 duty cycle PWM_Period_Match\"" nop ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x2f, \"TMR2 period\"" nop ; ; Increase TMR2 but less than first duty cycle ; clrf TMR0 movlw 0x0D movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,5 goto $-1 .assert "(portc & 0x20)==0, \"CCP1 is low TMR2 put, only change period\"" nop .assert "(portd & 0x04)==0, \"CCP2 is low TMR2 put, only change period\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x23, \"TMR2 put, only change period\"" nop ; ; Increase TMR2 between first and second duty cycle ; clrf TMR0 movlw 0x1D movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,5 goto $-1 .assert "(portc & 0x20) == 0x00, \"CCP1 is low - TMR2 put between duty cycles\"" nop .assert "(portd & 0x04) == 0x04, \"CCP2 is high - TMR2 put between duty cycles\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x13, \"TMR2 put, between duty cycles\"" nop ; ; in this test TMR2 > PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,5 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTD,2 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,5 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTD,2 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,5 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM nop .assert "\"*** PASSED p16f914 PWM test\"" goto $-1 end gpsim-0.30.0/regression/p16f91x/i2c_slave.asm0000664000076400007640000004220713116672351015525 00000000000000 list p=16f917 include include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _MCLRE_OFF & _IESO_OFF & _FCMEN_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16F917. ;; Specifically, I2C errorlevel -302 ; Printf Command .command macro x .direct "C", x endm _ClkIn equ 8000000 ; Input Clock Frequency _ClkOut equ (_ClkIn >> 2) ; ; Compute the delay constants for setup & hold times ; _40uS_Delay set (_ClkOut/250000) _47uS_Delay set (_ClkOut/212766) _50uS_Delay set (_ClkOut/200000) TRUE equ 1 FALSE equ 0 LSB equ 0 MSB equ 7 #define SCL_PIN 2 #define SDA_PIN 3 #define I2CPORT PORTB #define _SCL_D I2CPORT,SCL_PIN #define _SCL TRISB,SCL_PIN #define _SDA TRISB,SDA_PIN #define T0IE TMR0IE #define T0IF TMR0IF #define _ENABLE_BUS_FREE_TIME TRUE #define _CLOCK_STRETCH_CHECK TRUE #define _OPTION_INIT (0xC0 | 0x02) ; Prescaler to TMR0 for Appox 1 mSec timeout ;***************************************************************************** ; I2C Bus Status Reg Bit Definitions ;***************************************************************************** #define _Bus_Busy Bus_Status,0 #define _Abort Bus_Status,1 #define _Txmt_Progress Bus_Status,2 #define _Rcv_Progress Bus_Status,3 #define _Txmt_Success Bus_Status,4 #define _Rcv_Success Bus_Status,5 #define _Fatal_Error Bus_Status,6 #define _ACK_Error Bus_Status,7 ;***************************************************************************** ; I2C Bus Contro Register ;***************************************************************************** #define _10BitAddr Bus_Control,0 #define _Slave_RW Bus_Control,1 #define _Last_Byte_Rcv Bus_Control,2 #define _SlaveActive Bus_Control,6 #define _TIME_OUT_ Bus_Control,7 RELEASE_BUS MACRO bsf STATUS,RP0 ; select page 1 bsf _SDA ; tristate SDA bsf _SCL ; tristate SCL ; bcf _Bus_Busy ; Bus Not Busy, TEMP ????, set/clear on Start & Stop ENDM ;**************************************************************************** ; A MACRO To Load 8 OR 10 Bit Address To The Address Registers ; ; SLAVE_ADDRESS is a constant and is loaded into the SlaveAddress Register(s) ; depending on 8 or 10 bit addressing modes ;**************************************************************************** LOAD_ADDR_10 MACRO SLAVE_ADDRESS bsf _10BitAddr ; Slave has 10 bit address movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ; load low byte of address movlw (((SLAVE_ADDRESS >> 7) & 0x06) | 0xF0) ; 10 bit addr 11110AA0 movwf SlaveAddr+1 ; hi order address ENDM LOAD_ADDR_8 MACRO SLAVE_ADDRESS bcf _10BitAddr ; Set for 8 Bit Address Mode movlw (SLAVE_ADDRESS & 0xff) movwf SlaveAddr ENDM ;**************************************************************************** ; I2C_WRITE_SUB ; ; Writes a message just like I2C_WRITE, except that the data is preceeded ; by a sub-address to a slave device. ; Eg. : A serial EEPROM would need an address of memory location for ; Random Writes ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ (constant) ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; _Sub_Address_ Sub-address of Slave (constant) ; ; Sequence : ; S-SlvAW-A-SubA-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag ; ; Returns : WREG = 1 on success, else WREG = 0 ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ; COMMENTS : ; I2C_WR may prove to be more efficient than this macro in most situations ; Advantages will be found for Random Address Block Writes for Slaves with ; Auto Increment Sub-Addresses (like Microchip's 24CXX series Serial ; EEPROMS) ; ;**************************************************************************** I2C_WR_SUB MACRO _BYTES_, _SourcePointer_, _Sub_Address_ movlw (_BYTES_ + 1) movwf tempCount movlw (_SourcePointer_ - 1) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -1) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -1) call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W movwf (_SourcePointer_ - 1) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM I2C_WR_SUB2 MACRO _BYTES_, _SourcePointer_, _Sub_Address_, _Sub_Address2_ movlw (_BYTES_ + 2) movwf tempCount movlw (_SourcePointer_ - 2) movwf FSR movf INDF,W movwf StoreTemp_1 ; temporarily store contents of (_SourcePointer_ -2) movlw _Sub_Address_ movwf INDF ; store temporarily the sub-address at (_SourcePointer_ -2) movlw (_SourcePointer_ - 1) movwf FSR movlw _Sub_Address2_ movwf INDF movlw (_SourcePointer_ - 2) movwf FSR call _i2c_block_write ; write _BYTES_+1 block of data movf StoreTemp_1,W ; movwf (_SourcePointer_ - 2) ; restore contents of (_SourcePointer_ - 1) ; call TxmtStopBit ; Issue a stop bit to end transmission ENDM ;**************************************************************************** ; I2C_WRITE ; ; A basic macro for writing a block of data to a slave ; ; Parameters : ; _BYTES_ #of bytes starting from RAM pointer _SourcePointer_ ; _SourcePointer_ Data Start Buffer pointer in RAM (file Registers) ; ; Sequence : ; S-SlvAW-A-D[0]-A.....A-D[N-1]-A-P ; ; If an error occurs then the routine simply returns and user should check for ; flags in Bus_Status Reg (for eg. _Txmt_Success flag) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ;**************************************************************************** I2C_WR MACRO _BYTES_, _SourcePointer_ movlw _BYTES_ movwf tempCount movlw _SourcePointer_ movwf FSR call _i2c_block_write call TxmtStopBit ; Issue a stop bit for slave to end transmission ENDM ;***************************************************************************** ; ; I2C_READ ; ; The basic MACRO/procedure to read a block message from a slave device ; ; Parameters : ; _BYTES_ : constant : #of bytes to receive ; _DestPointer_ : destination pointer of RAM (File Registers) ; ; Sequence : ; S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; If last byte, then Master will NOT Acknowledge (send NACK) ; ; NOTE : The address of the slave must be loaded into SlaveAddress Registers, ; and 10 or 8 bit mode addressing must be set ; ;***************************************************************************** I2C_READ MACRO _BYTES_, _DestPointer_ movlw (_BYTES_ -1) movwf tempCount ; -1 because, the last byte is used out of loop movlw _DestPointer_ movwf FSR ; FIFO destination address pointer call _i2c_block_read ENDM ;*************************************************************************** ; ; I2C_READ_SUB ; This MACRO/Subroutine reads a message from a slave device preceeded by ; a write of the sub-address. ; Between the sub-addrers write & the following reads, a STOP condition ; is not issued and a "REPEATED START" condition is used so that an other ; master will not take over the bus, and also that no other master will ; overwrite the sub-address of the same salve. ; ; This function is very commonly used in accessing Random/Sequential reads ; from a memory device (e.g : 24Cxx serial of Serial EEPROMs from Microchip). ; ; Parameters : ; _BYTES_ # of bytes to read ; _DestPointer_ The destination pointer of data to be received. ; _BubAddress_ The sub-address of the slave ; ; Sequence : ; S-SlvAW-A-SubAddr-A-S-SlvAR-A-D[0]-A-.....-A-D[N-1]-N-P ; ; ;*************************************************************************** I2C_READ_SUB MACRO _BYTES_, _DestPointer_, _SubAddress_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM I2C_READ_SUB2 MACRO _BYTES_, _DestPointer_, _SubAddress_, _SubAddress2_ bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set movlw _SubAddress_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address movlw _SubAddress2_ movwf DataByte ; START address of EEPROM(slave 1) call SendData ; write sub address ; ; do not send STOP after this, use REPEATED START condition ; I2C_READ _BYTES_, _DestPointer_ ENDM ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- INT_VAR UDATA IO_buf RES 10 IN_buf RES 10 GPR_DATA UDATA_SHR w_temp RES 1 status_temp RES 1 SlaveAddr RES 1 ; Slave Addr must be loader into this reg SlaveAddrHi RES 1 ; for 10 bit addressing mode DataByte RES 1 ; load this reg with the data to be transmitted BitCount RES 1 ; The bit number (0:7) transmitted or received Bus_Status RES 1 ; Status Reg of I2C Bus for both TXMT & RCVE Bus_Control RES 1 ; control Register of I2C Bus DelayCount RES 1 DataByteCopy RES 1 ; copy of DataByte for Left Shifts (destructive) SubAddr RES 1 ; sub-address of slave (used in I2C_HIGH.ASM) SrcPtr RES 1 ; source pointer for data to be transmitted tempCount RES 1 ; a temp variable for scratch RAM StoreTemp_1 RES 1 ; a temp variable for scratch RAM, do not disturb contents _End_I2C_Ram RES 1 ; unused, only for ref of end of RAM allocation ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 if _CLOCK_STRETCH_CHECK ; TMR0 Interrupts enabled only if Clock Stretching is Used btfss INTCON,T0IF goto check ; other Interrupts bsf _TIME_OUT_ ; MUST set this Flag bcf INTCON,T0IF goto int_ret endif check: btfss PIR1,SSPIF goto int_ret bcf PIR1,SSPIF call sspint int_ret: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module lib libgpsim_modules" .sim "p16f917.xpos = 96" .sim "p16f917.ypos = 144" .sim "module load pu pu1" .sim "pu1.xpos = 276" .sim "pu1.ypos = 72" .sim "module load pu pu2" .sim "pu2.xpos = 276" .sim "pu2.ypos = 180" .sim "node n1" .sim "attach n1 portb3 pu1.pin portc4" ; ee.SCL" .sim "node n2" .sim "attach n2 portb2 pu2.pin portc3" ; ee.SDA" .sim "node n3" .sim "node n4" .sim "node n5" .sim "node n6" .sim "scope.ch0 = \"portc4\"" .sim "scope.ch1 = \"portc3\"" bsf STATUS,RP0 ; bank 1 movlw 0xf6 ; set internal RC to 8 Mhz movwf OSCCON clrf TRISA bsf PIE1,SSPIE ; allow SSP interrupts bsf INTCON,GIE ; allow interrupts bsf INTCON,PEIE ; allow interrupts banksel ANSEL clrf ANSEL banksel PORTA ; bsf PORTA,0 ; Write protect bsf PORTA,1 ; A0 movlw 0x10 movwf tempCount movlw IO_buf movwf FSR Fill_loop: movf FSR,W movwf INDF incf FSR,F decfsz tempCount,F goto Fill_loop movlw 0x09 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xaf ; movwf SSPMSK bcf STATUS,RP0 ; bank 0 movlw 0x36 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0xa2 movwf SSPADD bcf STATUS,RP0 ; bank 0 call InitI2CBus_Master LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive .assert "\"*** FAILED I2C Slave not active\"" nop LOAD_ADDR_8 0xa2 ; I2C_WR_SUB 8, IO_buf, 0x0c I2C_WR_SUB2 8, IO_buf, 0x0c, 0x0c call TxmtStopBit ; Issue a stop bit to end transmission movf Bus_Status,W .assert "W == 0x10, \"*** FAILED I2C slave write status\"" nop poll_ready: LOAD_ADDR_8 0xa2 call IsSlaveActive btfss _SlaveActive goto poll_ready ; slave not active yet nop ; ; write 0xa2 0x0c 0x0c to set an address ; write RSTART 0xa3 to initiate read ; read 8 bytes of data into ram starting at IN_buf ; LOAD_ADDR_8 0xa2 I2C_READ_SUB2 8, IN_buf, 0x0c, 0x0c nop bcf STATUS,RP0 ; bank 0 movf IN_buf,W .assert "W == 0xf5, \"*** FAILED I2C slave read data\"" nop movf Bus_Status,W .assert "W == 0x30, \"*** FAILED I2C slave 8 bit read status\"" nop ; ; write 8 bytes of data in slave 10bit mode ; bcf STATUS,RP0 ; bank 0 movlw 0x37 movwf SSPCON bsf STATUS,RP0 ; bank 1 movlw 0x06 movwf SSPADD bcf STATUS,RP0 ; bank 0 LOAD_ADDR_10 0x30c bcf PIR1,SSPIF I2C_WR 8, IO_buf btfss PIR1,SSPIF goto $-1 .assert "\"*** PASSED p16f917 I2C slave test \"" nop goto $ IsSlaveActive bcf _Slave_RW ; set for write operation call TxmtStartBit ; send START bit call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; bcf _SlaveActive btfss _ACK_Error ; skip if NACK, device is not present or not responding bsf _SlaveActive ; ACK received, device present & listening call TxmtStopBit return include "i2c_low.inc" _i2c_block_write: call TxmtStartBit ; send START bit bcf _Slave_RW ; set for write operation call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set ; _block_wr1_loop: btfss _Txmt_Success return movf INDF,W movwf DataByte ; start from the first byte starting at _DataPointer_ incf FSR, F call SendData ; send next byte, bus is our's ! decfsz tempCount, F goto _block_wr1_loop ; loop until desired bytes of data ; transmitted to slave return ; ;**************************************************************************** _i2c_block_read: call TxmtStartBit ; send START bit bsf _Slave_RW ; set for read operation bcf _Last_Byte_Rcv ; not a last byte to rcv call Txmt_Slave_Addr ; if successful, then _Txmt_Success bit is set btfsc _Txmt_Success goto _block_rd1_loop ; end call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw FALSE ; Error : may be device not responding ; _block_rd1_loop: call GetData movf DataByte,W movwf INDF ;start receiving data, starting at Destination Pointer incf FSR, F decfsz tempCount, F goto _block_rd1_loop ; loop until desired bytes of data transmitted to slave bsf _Last_Byte_Rcv ; last byte to rcv, so send NACK call GetData movf DataByte,W movwf INDF call TxmtStopBit ; Issue a stop bit for slave to end transmission retlw TRUE sspint: bsf STATUS,RP0 ; bank 1 btfsc SSPSTAT,R_W ; write test ? goto sspint_wr btfsc SSPSTAT,UA ; UA bit set goto sspint_ua bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return sspint_wr: bcf STATUS,RP0 ; bank 0 movlw 0xf5 ; byte to send movwf SSPBUF bsf SSPCON,CKP ; turn off clock stretch return sspint_ua: movlw 0x0c ; second byte address movwf SSPADD bcf STATUS,RP0 ; bank 0 movf SSPBUF,W return end gpsim-0.30.0/regression/p16f91x/p16f913.asm0000664000076400007640000002003013116671576014665 00000000000000 list p=16f913 include include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;& _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F913. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc PIR1,EEIF goto ee_int btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F913 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt exit_int swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f913.xpos = 72" .sim "p16f913.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.voltage = 2.0" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "module load pullup V4" .sim "V4.voltage = 0.5" .sim "V4.resistance = 100.0" .sim "V4.xpos = 84" .sim "V4.ypos = 348" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" .sim "node na4" .sim "attach na4 V4.pin porta2" BANKSEL LCDCON bcf LCDCON,VLCDEN call test_eerom ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA movlw 7 movwf CMCON0 BANKSEL PORTC bsf PORTC,5 BANKSEL PIE1 bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;& _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F916. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc PIR1,EEIF goto ee_int btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F916 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt exit_int swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f916.xpos = 72" .sim "p16f916.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.voltage = 2.0" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "module load pullup V4" .sim "V4.voltage = 0.5" .sim "V4.resistance = 100.0" .sim "V4.xpos = 84" .sim "V4.ypos = 348" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" .sim "node na4" .sim "attach na4 V4.pin porta2" call test_eerom ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA movlw 7 movwf CMCON0 BANKSEL PORTC bsf PORTC,5 BANKSEL PIE1 bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA var1 RES 1 var2 RES 1 var3 RES 1 failures RES 1 status_temp RES 1 w_temp RES 1 interrupt_temp RES 1 GLOBAL var1,var2,var3,failures GLOBAL done ;; The capTime 16-bit register is a working register that keeps track ;; of the capture edge. capTimeH RES 1 capTimeL RES 1 capTimeHb RES 1 capTimeLb RES 1 GLOBAL capTimeH, capTimeL, capTimeHb, capTimeLb temp1 RES 1 temp2 RES 1 t1 RES 1 t2 RES 1 t3 RES 1 kz RES 1 GLOBAL temp1, temp2, t1, t2, t3, kz ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; Simulation Script .sim "node test_node_C" ;# Create an asynchronous stimulus that's 1000 cycles long ;# and attach it to portc bit 2. .sim "stimulus asynchronous_stimulus" .sim "initial_state 0" .sim "start_cycle 0x100" .sim "period 0x400" .sim "{ 0x200, 1}" ; .sim "0x300, 0," ; .sim "0x400, 1," ; .sim "0x600, 0," ; .sim "0x700, 1," ; .sim "0x800, 0}" .sim "name asy1" .sim "end" .sim "attach test_node_C asy1 portc5" ;---------------------------------------------------------------------- ; ******************* INTERRUPT VECTOR LOCATION ******************** ;---------------------------------------------------------------------- INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp ;; Are peripheral interrupts enabled? btfss INTCON,PEIE goto exit_int bsf STATUS,RP0 movf PIE1,W bcf STATUS,RP0 movwf interrupt_temp check_tmr1: btfsc PIR1,TMR1IF btfss interrupt_temp,TMR1IE goto check_ccp1 ;; tmr1 has rolled over bcf PIR1,TMR1IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover check_ccp1: btfsc PIR1,CCP1IF btfss interrupt_temp,CCP1IE goto check_ccp2 bcf PIR1,CCP1IF ; Clear the pending interrupt bsf temp1,1 ; Set a flag to indicate match check_ccp2: bsf STATUS,RP0 movf PIE2,W bcf STATUS,RP0 movwf interrupt_temp btfsc PIR2,CCP2IF btfss interrupt_temp,CCP2IE goto exit_int bcf PIR2,CCP2IF ; Clear the pending interrupt bsf temp1,2 ; Set a flag to indicate match exit_int: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf failures ;Assume success. clrf kz ;kz == Known Zero. ;; disable (primarily) global and peripheral interrupts clrf INTCON ; BANKSEL TRISC ; clrf TRISC ;; ;; CCP test ;; ;; The CCP module is intricately intertwined with the TMR1 ;; module. So first, let's initialize TMR1: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale ;; In this mode, TMR1 will count instruction cycles. BANKSEL T1CON clrf T1CON ; clrf PIR1 ; Clear the interrupt/roll over flag clrf PIR2 ;; Zero TMR1 clrf TMR1L clrf TMR1H ;; Start the timer bsf T1CON,TMR1ON ccp_test1: movlw (1< 5 call ccpWaitForPORTC2_low call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==4), \"*** FAILED CCP 16f917 mode 5\"" nop clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 6 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x10), \"*** FAILED CCP 16f917 mode 6\"" nop clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 7 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x40), \"*** FAILED CCP 16f917 mode 7\"" nop goto test_ccp1_compare ;------------------------------------------------------------------------ ;ccpCaptureTwoEvents ; ; Capture two events for the current CCP setting and return the time ; difference between them ccpCaptureTwoEvents: call ccpWaitForCapture movf CCPR1L,W movwf capTimeLb movf CCPR1H,W movwf capTimeHb call ccpWaitForCapture movf CCPR1L,W movwf capTimeL movf CCPR1H,W movwf capTimeH ; Subtract the time of the most recently captured edge from the previous one movf capTimeLb,W subwf capTimeL,F movf capTimeHb,W skpc incfsz capTimeHb,W subwf capTimeH,F return ;------------------------------------------------------------------------ ;ccpWaitForCapture ; ; Spin loop that polls an interrupt flag that is set whenever a capture ; interrupt triggers. ccpWaitForCapture: clrf t1 ;A 16-bit software timeout counter clrf t2 ccpWaitLoop: ;; The watchdog counter ensures we don't loop forever! call ccpWDCounter ;; ;; when an edge is captured, the interrupt routine will ;; set a flag: ;; btfss temp1,1 goto ccpWaitLoop bcf temp1,1 return ;------------------------------------------------------------------------ ccpWaitForPORTC2_high: btfsc PORTC,5 return call ccpWDCounter goto ccpWaitForPORTC2_high ccpWaitForPORTC2_low: btfss PORTC,5 return call ccpWDCounter goto ccpWaitForPORTC2_high ;------------------------------------------------------------------------ ; ccpWDCounter ; a 16bit watch dog counter is incremented by 1. If it rolls over then we failed. ccpWDCounter: incfsz t1,f return incfsz t2,f return goto failed ;If we get here then we haven't caught anything! ;Either a) there's a gpsim bug or b) the stimulus ;file is incorrect. ; movlw 1 ;This 16-bit software counter ; addwf t1,f ;will time out if there's something wrong, ; rlf kz,w ; addwf t2,f ; skpc ; return ;; ;; Compare ;; ;; Now for the compare mode. test_ccp1_compare: clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf PORTC,5 ;CCP bit is an output bcf STATUS,RP0 ;; Start off the compare mode by setting the output on a compare match ;; ;; ccp = 8 <- Set output on match ;; ccp = 9 <- Clear output on match ;; ccp = 10 <- Just set the ccp1if flag, but don't change the output ;; ccp = 11 <- Reset tmr1 on a match movlw 0x8 movwf CCP1CON ;; clrf PIR1 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR1L movlw 0x12 movwf CCPR1H ;; Clear the interrupt flag clrf temp1 tt3: ;; Stop and clear tmr1 clrf T1CON clrf TMR1L clrf TMR1H ;; Now start it bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: btfss temp1,1 goto $-1 bcf temp1,1 ;; Try the next capture mode incf CCP1CON,F ;; If bit 2 of ccp1con is set then we're through with capture modes ;; (and are starting pwm modes) btfsc CCP1CON,2 goto done_ccp1 goto tt3 done_ccp1: ; goto done .assert "(tmr1h==0) && (tmr1l<0x40), \"*** FAILED CCP 16f917 ccp1con=b no tmr1 reset\"" nop clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf TRISD, 2 ;CCP bit is an output bsf PIE2, CCP2IE bcf STATUS,RP0 ;; Start off the compare mode by setting the output on a compare match ;; ;; ccp = 8 <- Set output on match ;; ccp = 9 <- Clear output on match ;; ccp = 10 <- Just set the ccp1if flag, but don't change the output ;; ccp = 11 <- Reset tmr1 on a match movlw 0x8 movwf CCP2CON ;; clrf PIR2 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR2L movlw 0x0 movwf CCPR2H ;; Clear the interrupt flag clrf temp1 tt4: ;; Stop and clear tmr1 clrf T1CON clrf TMR1L clrf TMR1H ;; Now start it bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: btfss temp1,2 goto $-1 bcf temp1,2 ;; Try the next capture mode incf CCP2CON,F ;; If bit 2 of ccp2con is set then we're through with capture modes ;; (and are starting pwm modes) btfsc CCP2CON,2 goto done_ccp2 goto tt4 done_ccp2: ; ; test running both CCPs in compare mode at the same time ; clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf TRISC, 5 ;CCP1 bit is an output bcf TRISD, 2 ;CCP2 bit is an output bsf PIE2, CCP2IE bcf STATUS,RP0 movlw 0x8 movwf CCP2CON movwf CCP1CON ;; clrf PIR2 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR2L movlw 0x0 movwf CCPR2H movlw 0x34 movwf CCPR1L movlw 0x2 movwf CCPR1H ;; Clear the interrupt flag clrf temp1 ;; Now start T1 bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: ccp12_loop1: movf temp1,W btfsc STATUS,Z goto ccp12_loop1 ;; Now confirm that it wasn't CCP1 that happened first .assert "(temp1 & 0x3) != 2, \"*** FAILED CCP 917 test both CCP running\"" nop ;; Wait until the timer reaches 0x300 ccp12_loop2: movf TMR1H,W xorlw 3 btfss STATUS,Z goto ccp12_loop2 ;; and confirm that both CCPs have fired by now .assert "(temp1 == 6), \"*** FAILED CCP 917 test both CCP running\"" nop goto done failed: .assert "\"*** FAILED CCP 917 test\"" incf failures,F goto $ done: .assert "\"*** PASSED p16f917 CCP test\"" goto $ ; .sim "set verbose 4" end gpsim-0.30.0/regression/p16f91x/usart_917.asm0000664000076400007640000001564613103767677015437 00000000000000 ;; USART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly. The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=16f917 include include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x20 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 ;fsr_temp RES 1 INT_VAR1 UDATA 0xA0 w_temp1 RES 1 ;Alias for w_temp at address 0x20 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program BAUDHI equ ((100000/16)/48)-1 BAUDLO equ 100000/(48*64)-1 ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH bcf STATUS,RP0 btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=10e6" .sim ".xpos = 48" .sim ".ypos = 36" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "U1.xpos = 240" .sim "U1.ypos = 204" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. bsf STATUS,RP0 bsf TRISC,7 ;RX is an input bcf TRISC,6 ;TX is an output ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 9 bits ; and < 10 bits or between 1.872 and 2.08 msec. ; with oscillator at 10MHz and TMR0 / 64 expect between 73 and 81 ; TMR0 cycles. Or 146 - 162 for 2 characters movf TMR0,W .assert "tmr0 > 146 && tmr0 < 162, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop .assert "(pir1 & 0x10) == 0x10, \"*** FAILED TXIF low double send\"" nop done: .assert "\"*** PASSED p16f917 Usart\"" goto $ TransmitNextByte: clrf rxFlag call tx_message btfss PIR1,TXIF goto $-1 movwf TXREG rx_loop: btfss rxFlag,0 goto rx_loop return tx_message incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw TX_TABLE skpnc incf PCLATH,f movwf PCL TX_TABLE dt "0123456789ABCDEF",0 delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return end gpsim-0.30.0/regression/p16f91x/p16f914.asm0000664000076400007640000001775613116671631014703 00000000000000 list p=16f914 include include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;& _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F914. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc PIR1,EEIF goto ee_int btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F914 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt exit_int swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f914.xpos = 72" .sim "p16f914.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.voltage = 2.0" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "module load pullup V4" .sim "V4.voltage = 0.5" .sim "V4.resistance = 100.0" .sim "V4.xpos = 84" .sim "V4.ypos = 348" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" .sim "node na4" .sim "attach na4 V4.pin porta2" call test_eerom ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA movlw 7 movwf CMCON0 BANKSEL PORTC bsf PORTC,5 BANKSEL PIE1 bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< ; processor specific variable definitions include ; Grab some useful macros ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmp_int RES 1 cm2_int RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR2,C1IF goto icm1 btfsc PIR2,C2IF goto icm2 goto exit_int icm1: bcf PIR2,C1IF bsf cmp_int,0 goto exit_int icm2: bcf PIR2,C2IF bsf cm2_int,0 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "p16f917.xpos = 60" .sim "p16f917.ypos = 84" .sim "module load pullup AN3" .sim "AN3.capacitance = 0" .sim "AN3.resistance = 10000" .sim "AN3.voltage = 3." .sim "AN3.xpos = 72" .sim "AN3.ypos = 24" .sim "module load pullup AN0" .sim "AN0.capacitance = 0" .sim "AN0.resistance = 10000" .sim "AN0.voltage = 2.5" .sim "AN0.xpos = 228" .sim "AN0.ypos = 36" .sim "module load pullup AN2" .sim "AN2.capacitance = 0" .sim "AN2.resistance = 10000" .sim "AN2.voltage = 2.8" .sim "AN2.xpos = 252" .sim "AN2.ypos = 96" .sim "module load pullup AN1" .sim "AN1.capacitance = 0" .sim "AN1.resistance = 10000" .sim "AN1.voltage = 2" .sim "AN1.xpos = 228" .sim "AN1.ypos = 144" .sim "node c1p" .sim "attach c1p AN3.pin porta3" .sim "node c1n" .sim "attach c1n AN0.pin porta0" .sim "node c2p" .sim "attach c2p AN2.pin porta2" .sim "node c2n" .sim "attach c2n AN1.pin porta1" .assert "cmcon0 == 0x00, \"FAILED 16f917 CMCON0 POR\"" ; Rest value nop BANKSEL PIR2 clrf PIR2 movlw CMODE7 ; turn off comparator BANKSEL CMCON0 movwf CMCON0 clrf ANSEL movlw 0x0f ; RA0-RA3 are inputs movwf TRISA ; mode 1 - Three Inputs Multiplexed to Two Comparators movlw CMODE1 movwf CMCON0 call c1_out nop ; ; mode 2 - Four Inputs Multiplexed to Two Comparators with Vref ; movlw CMODE2 movwf CMCON0 call mux_vref nop ; ; mode 3 Two Common Reference Comparator ; movlw CMODE3 movwf CMCON0 call ref_com nop ; mode 4 Two Independent Comparators ; movlw CMODE4 movwf CMCON0 call ind_comp nop ; mode 5 One Independent Comparator with Reference Option ; movlw CMODE5 movwf CMCON0 call one_comp nop ; ; mode 6 Two Common Reference Comparators with Outputs ; movlw CMODE6 movwf CMCON0 call ref_com_out nop .assert "\"*** PASSED p16f917 Comparator\"" goto $ ; One Independent Comparator with Reference Option ; ; C2- AN1 (0.65) ; C2+ AN2 (0.7) or V0.6 one_comp: .command "AN2.voltage = 0.7" nop .command "AN1.voltage = 0.65" nop .assert "(cmcon0 & 0xc0) == 0x80, \"*** FAILED 16f917 one_comp, c2out=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0x00, \"*** FAILED 16f917 one_comp, c2out=0\"" nop return ; Three Inputs Multiplexed to Two Comparators c1_out: ; C1IN- AN0 (2.5) ; C1IN+ AN2 (2.8) thus C1 out=1 ; C2in- AN1 (2.0) ; C2IN+ AN2 (2.8) thus C2 out=1 .assert "(cmcon0 & 0xc0) == 0xc0, \"*** FAILED 16f917 c1_out, cxout=1\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f917 c1_out, OUT1=0 OUT2=0\"" nop bsf CMCON0,C1INV bsf CMCON0,C2INV ; Invert c1,c1 out=0 .assert "(cmcon0 & 0xc0) == 0x00, \"*** FAILED 16f917 c1_out, invert cxout=01\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f917 c1_out, OUT1=0 OUT2=0\"" nop ; C1IN- AN3 (3.) ; C1IN+ (2.8) with invert thus C1 out=1 bsf CMCON0,CIS ; switch c1 Vin- .assert "(cmcon0 & 0xc0) == 0x40, \"*** FAILED 16f917 c1_out INVERT , c1out=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f917 c1_out, INVERT OUT1=0 OUT2=0\"" nop return ; Two independent Comparators ind_comp: ; ; Both Comparator true ; C1IN-AN0(2.1V), C1 - ; C1IN+AN3(3.1V) C1 + thus C1 out=1 ; C2in-AN1(1.5V) connected to C2 - ; C2IN+AN2(2.5V) C2 + thus C2 out=1 .command "AN2.voltage = 2.5" nop .command "AN1.voltage = 1.5" nop .command "AN3.voltage = 3.1" nop .command "AN0.voltage = 2.1" nop .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f917 2 ind comp CIS=0 C1OUT=1 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f917 2 ind comp CIS=1 C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "AN2.voltage = 1.4" nop nop .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f917 2 ind comp C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "AN3.voltage = 2.0" nop .command "AN2.voltage = 2.5" nop .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f917 2 ind comp C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "AN2.voltage = 1.4" nop .assert "(cmcon0 & 0xc0) == 0x00, \"FAILED 16f917 2 ind comp C1OUT=0 C2OUT=0\"" nop return ; Two independent Comparators with outputs ind_comp_out: ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "AN2.voltage = 2.5" nop .command "AN1.voltage = 1.5" nop .command "AN3.voltage = 3.1" nop .command "AN0.voltage = 2.1" nop .assert "(cmcon0 & 0xc0) == 0xc0, \"*** FAILED 16f917 ind_comp_out CIS=0 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 16f917 ind_comp_out CIS=0 port C1OUT=1 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0xc0, \"*** FAILED 16f917 ind_comp_out CIS=1 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 16f917 ind_comp_out CIS=1 port C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "AN2.voltage = 1.4" nop nop .assert "(cmcon0 & 0xc0) == 0x40, \"*** FAILED 16f917 ind_comp_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 16f917 ind_comp_out port C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "AN3.voltage = 2.0" nop .command "AN2.voltage = 2.5" nop .assert "(cmcon0 & 0xc0) == 0x80, \"*** FAILED 16f917 ind_comp_out C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 16f917 ind_comp_out port C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "AN2.voltage = 1.4" nop .assert "(cmcon0 & 0xc0) == 0x00, \"*** FAILED 16f917 ind_comp_out C1OUT=0 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x00, \"*** FAILED 16f917 ind_comp_out port C1OUT=0 C2OUT=0\"" nop return ; ; Four Inputs muxed to two comparators with Vref ; mux_vref: .command "AN3.voltage = 1.0" nop .command "AN0.voltage = 2.5" nop .command "AN2.voltage = 2.8" nop .command "AN1.voltage = 2.0" nop ; C1IN- = AN0 2.5 + = 2.29 out = 0 ; C2IN- = AN1 2.0 + = 2.29 out = 1 BANKSEL PIR2 clrf PIR2 BANKSEL VRCON movlw 0xAB ; enable Vref 11 low range 2.29v movwf VRCON .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f917 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x60) == 0x40, \"FAILED 16f917 mux with vref C2IF=1\"" nop BANKSEL PIR2 clrf PIR2 movlw 0x8B ; enable Vref 11 high range 2.97v BANKSEL VRCON movwf VRCON ; C1IN- = 2.5 + = 2.97 out = 1 was 0 ; C2IN- = 2.0 + = 2.97 out = 1 was 1 .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f917 mux with vref C1OUT=1 C2OUT=1\"" nop .assert "(pir2 & 0x60) == 0x20, \"FAILED 16f917 mux with vref C1IF=1 C2IF =0\"" nop BANKSEL PIR2 bcf PIR2,C1IF .assert "(pir2 & 0x60) == 0x00, \"FAILED 16f917 mux with vref C1IF=0, C2IF=0\"" nop .command "AN0.voltage = 3.0" ; drive comp1 low (C1IN- > Vref) nop nop .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f917 mux with vref C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x60) == 0x20, \"FAILED 16f917 mux with vref C1IF=1 C1 change\"" nop bcf PIR2,C1IF BANKSEL CMCON0 bsf CMCON0,C1INV ; invert output bsf CMCON0,C2INV .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f917 mux with vref invert C1OUT=1 C2OUT=0\"" nop .assert "(pir2 & 0x60) == 0x60, \"FAILED 16f917 mux with vref invert CxIF=1\"" nop BANKSEL PIR2 clrf PIR2 .command "AN1.voltage = 3.5" ; C2IN- > Vref nop .command "AN0.voltage = 2.5" ; C1IN- < Vref nop .command "AN3.voltage = 3.1" ; C1IN+ > Vref nop .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f917 mux with vref new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir2 & 0x60) == 0x60, \"FAILED 16f917 mux with vref CxIF=1 C1, C2 change\"" nop BANKSEL CMCON0 bsf CMCON0,CIS ; switch pins ; ; C1 - AN3 (3.1) + Vref (2.97) invert out = 1 ; C2 - AN2 (2.8) + Vref (2.97) invert out = 0 ; bcf PIR2,C1IF .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f917 mux with vref new inputs C1OUT=1 C2OUT=0\"" nop movlw 0xc7 ; clear invert, CIS bits andwf CMCON0,F .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f917 mux with vref invert normal C1OUT=1 C2OUT=0\"" nop BANKSEL PIR2 clrf PIR2 clrf cmp_int BANKSEL PIE2 bsf PIE2,C1IE ; enable Comparator interrupts bsf PIE2,C2IE ; enable Comparator interrupts bsf INTCON,PEIE ; enable Peripheral interrupts bsf INTCON,GIE ; and global interrupts BANKSEL CMCON0 bsf CMCON0,C1INV ; generate an interrupt btfsc cmp_int,0 goto done1 nop .assert "\"*** FAILED Comparator no interrupt 16f917 mux with vref \"" nop goto $ done1: return ; ; Two common reference Comparators ; ; C1IN+ AN2(2.5V) to both comparator + ; C1IN-AN0(3.1V),connected to C1 - out=0 ; C2in-AN1(1.5V) connected to C2 - out=1 ref_com: .command "AN2.voltage = 2.5" nop .command "AN1.voltage = 1.5" nop .command "AN3.voltage = 0.5" nop .command "AN0.voltage = 3.1" nop .assert "(cmcon0 & 0xc0) == 0x80, \"*** FAILED 16f917 ref_com CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0x80, \"*** FAILED 16f917 ref_com CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "AN0.voltage = 1.7" nop .command "AN1.voltage = 2.7" nop .assert "(cmcon0 & 0xc0) == 0x40, \"*** FAILED 16f917 ref_com C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "AN1.voltage = 2.3" nop .assert "(cmcon0 & 0xc0) == 0xc0, \"*** FAILED 16f917 ref_com C1OUT=1 C2OUT=1\"" nop return ; ; Two common reference Comparators with outputs ; ; C1IN+AN2(2.5V) to both comparator + ; C1IN-AN0(3.1V),connected to C1 - out=0 ; C2in-AN1(1.5V) connected to C2 - out=1 ref_com_out: .command "AN3.voltage = 0.5" nop .command "AN1.voltage = 1.5" nop .command "AN2.voltage = 2.5" nop .command "AN0.voltage = 3.1" nop .assert "(cmcon0 & 0xc0) == 0x80, \"*** FAILED 16f917 ref_com_out CIS=0 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 16f917 ref_com_out CIS=0 port C1OUT=0 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0x80, \"*** FAILED 16f917 ref_com_out CIS=1 C1OUT=0 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x20, \"*** FAILED 16f917 ref_com_out CIS=1 port C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "AN0.voltage = 1.7" nop .command "AN1.voltage = 2.7" nop .assert "(cmcon0 & 0xc0) == 0x40, \"*** FAILED 16f917 ref_com_out C1OUT=1 C2OUT=0\"" nop .assert "(porta & 0x30) == 0x10, \"*** FAILED 16f917 ref_com_out CIS=0 port C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "AN1.voltage = 2.3" nop .assert "(cmcon0 & 0xc0) == 0xc0, \"*** FAILED 16f917 ref_com_out C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x30) == 0x30, \"*** FAILED 16f917 ref_com_out port C1OUT=1 C2OUT=1\"" nop return end gpsim-0.30.0/regression/p16f91x/q.stc0000664000076400007640000000324613110024017014107 00000000000000 # This file was written by gpsim. # You can use this file for example like this: # gpsim -s mycode.cod -c netlist.stc # If you want to add commands, you can create another .stc file # and load this file from it. Something like this: # ----------- myproject.stc --------------- # load s mycode.cod # frequency 12000000 # load c netlist.stc # ----------------------------------------- # You can then just load this new file: # gpsim -c myproject.stc # and use netlist.stc whenever you save from the breadboard. # # Processor position: module library libgpsim_extras module library libgpsim_modules # Modules: p16f917.BreakOnReset = true p16f917.SafeMode = true p16f917.UnknownMode = true p16f917.WarnMode = true p16f917.tmr1_freq = 32768 p16f917.xpos = 120 p16f917.ypos = 36 module load lcd_7seg lcd1 lcd1.xpos = 300 lcd1.ypos = 108 module load lcd_7seg lcd2 lcd2.xpos = 300 lcd2.ypos = 276 module load pullup V1 V1.capacitance = 0 V1.resistance = 1000 V1.voltage = 1 V1.xpos = 84 V1.ypos = 420 module load pullup V2 V2.capacitance = 0 V2.resistance = 1000 V2.voltage = 2 V2.xpos = 84 V2.ypos = 372 module load pullup V3 V3.capacitance = 0 V3.resistance = 1000 V3.voltage = 3 V3.xpos = 84 V3.ypos = 324 # Connections: node vlcd3 attach vlcd3 pin portc2 node vlcd2 attach vlcd2 pin portc1 node vlcd1 attach vlcd1 pin portc0 node Com0 attach Com0 cc portb4 node Com1 attach Com1 cc portb5 node Seg0 attach Seg0 seg0 seg0 portb0 node Seg1 attach Seg1 seg1 seg1 portb1 node Seg2 attach Seg2 seg2 seg2 portb2 node Seg3 attach Seg3 seg3 seg3 portb3 node Seg4 attach Seg4 seg4 seg4 porta4 node Seg5 attach Seg5 seg5 seg5 porta5 node Seg6 attach Seg6 seg6 seg6 portc3 # End. gpsim-0.30.0/regression/p16f91x/p16f917.asm0000664000076400007640000001775613116671703014706 00000000000000 list p=16f917 include include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;& _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F917. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc PIR1,EEIF goto ee_int btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F917 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt exit_int swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f917.xpos = 72" .sim "p16f917.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.voltage = 2.0" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "module load pullup V4" .sim "V4.voltage = 0.5" .sim "V4.resistance = 100.0" .sim "V4.xpos = 84" .sim "V4.ypos = 348" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" .sim "node na4" .sim "attach na4 V4.pin porta2" call test_eerom ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; movlw 3 BANKSEL ANSEL movwf ANSEL ; select AN0, AN1 BANKSEL TRISA movwf TRISA movlw 7 movwf CMCON0 BANKSEL PORTC bsf PORTC,5 BANKSEL PIE1 bsf PIE1,ADIE ;A2D interrupts bcf STATUS,RP0 ;adcon0 is in bank 0 movlw (1< ; processor specific variable definitions include ; Grab some useful macros __CONFIG (_CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF) errorlevel -302 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA var1 RES 1 var2 RES 1 var3 RES 1 failures RES 1 GLOBAL var1,var2,var3,failures GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf var1 clrf var2 clrf var3 call delay .assert "var1==0" incf var1,F ;This write will cause a break .assert "var1==4" movf var1,W movlw 50 movwf var3 L_StopWatchDelayTest: call delay decfsz var3,F goto L_StopWatchDelayTest passed: clrf failures done: ; If no expression is specified, then break unconditionally .assert "\"*** PASSED breakpoint test\"" nop goto done delay: goto $+1 goto $+1 return ; Don't let the simulation run forever. .sim "break c 0x10000" .sim "step 6" .sim "echo Breakpoints:" .sim "break" .sim "break w var1" .sim "run" .sim "var1=4" .sim "echo stepping over breakpoint" .sim "step" .sim "trace 5" .sim "stopwatch.enable = true" .sim "stopwatch.rollover = 300" .sim "break stopwatch" ;, \"Hit stopwatch breakpoint\"" .sim "run" ; This run will take us to the stopwatch break .sim "run" ; This run will take us to the done label end gpsim-0.30.0/regression/breakpoints/16f873.lkr0000664000076400007640000000530413041763600015717 00000000000000//********************************************************************* // * // Software License Agreement * // * // The software supplied herewith by Microchip Technology * // Incorporated (the "Company") for its PICmicro® Microcontroller * // is intended and supplied to you, the Company’s customer, for use * // solely and exclusively on Microchip PICmicro Microcontroller * // products. The software is owned by the Company and/or its * // supplier, and is protected under applicable copyright laws. All * // rights are reserved. Any use in violation of the foregoing * // restrictions may subject the user to criminal sanctions under * // applicable laws, as well as to civil liability for the breach of * // the terms and conditions of this license. * // * // THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO * // WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, * // BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND * // FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE * // COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, * // INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * // * //********************************************************************* // File: 16f873.lkr // Linker Script file, modified // Date: 06/07/2000 // Modified 7/18/2000 -.RLF LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x70 PROTECTED CODEPAGE NAME=page0 START=0x71 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF PROTECTED CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x7F DATABANK NAME=gpr1 START=0xA0 END=0xFF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/p18f26k22/0000775000076400007640000000000013117466027013360 500000000000000gpsim-0.30.0/regression/p18f26k22/sync_26k22.asm0000664000076400007640000001620013041763600015574 00000000000000; ; ; Copyright (c) 2016 Roy Rankin ; ; This file is part of the gpsim regression tests ; ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, see ; . list p=18f26k22 include include CONFIG WDTEN=ON CONFIG WDTPS=128 CONFIG MCLRE = INTMCLR CONFIG FOSC = INTIO67 errorlevel -302 radix dec ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 temp RES 1 txif_int RES 1 tx2if_int RES 1 rcif_int RES 1 rc2if_int RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X008 goto interrupt ;SPBRG : 3 : 1 Mbits/se ;TXSTA : 10110000 (B0h) : 8-bit tran ;RCSTA : 10010000 (90h) : 8-bit rece ;******************************************* ; Sample Code For Synchronous Mode ;******************************************* #define ClkFreq 16000000 #define baud(X) ((10*ClkFreq/(4*X))+5)/10 - 1 #define TXSTA_INIT 0xB0 #define RCTSA_INIT 0x90 MAIN CODE .sim "scope.ch0 = \"portc6\"" .sim "scope.ch1 = \"portc7\"" .sim "node clock data" .sim "attach clock portc6 portb6" .sim "attach data portc7 portb7" start ;set clock to 16 Mhz BANKSEL OSCCON bsf OSCCON,6 clrf STATUS BANKSEL ANSELA clrf ANSELA ; set port to digital clrf ANSELC bsf TRISC,7 bsf TRISC,6 bsf TRISB,7 bsf TRISB,6 call RC_CREN_Master call TXEN_Master call RC_Master call TX_Master clrf RCSTA clrf RCSTA2 .assert "\"*** PASSED 18f26k22 synchronous euart\"" nop TXEN_Master: call Setup_Sync_TXEN_Master_Mode call Setup_Sync_RC_Slave_Mode bsf RCSTA2,RX9 movlw 0x55 movwf TXREG .assert("(txsta1 & 2) == 0, \"*** FAILED p18f26k22 TXMT=0 after TXREG loaded and TXEN==0\"" ) nop ; delay to check data not sent yet decfsz WREG,W goto $-1 .assert("(txsta1 & 2) == 0, \"*** FAILED p18f26k22 TXMT=0 before TXEN==1\"" ) nop .assert("(pir3 & 0x20) == 0, \"*** FAILED p18f26k22 rc2if=0 before TXEN==1\"" ) nop bsf TXSTA,TXEN btfss TXSTA,TRMT goto $-1 .assert("(pir3 & 0x20) == 0x20, \"*** FAILED p18f26k22 rc2if=1 after TXEN==1\"" ) nop .assert("(rcsta2 & 0x01) == 0x01, \"*** FAILED p18f26k22 RX9D=1 after transfer\"") nop movf RCREG2,W .assert ("W == 0x55, \"*** FAILED p18f26k22 rcreg 9 bit transfer\"") nop return TX_Master: call Setup_Sync_TX_Master_Mode call Setup_Sync_RC_Slave_Mode movlw (1<. list p=18f26k22 include include ; CONFIG WDTEN=ON ; CONFIG WDTPS=128 ; CONFIG MCLRE = INTMCLR ; CONFIG FOSC = INTIO67 errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 delay1 RES 1 delay2 RES 1 counter RES 1 counter_hi RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 inte_cnt RES 1 padd RES 3 GPR_DATA2 UDATA 0x100 buffer RES 64 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X008 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: call test_eerom call prog_2_ram call erase_block call ram_2_prog call verify_ram_2_prog call read_config_data call read_devid .assert "\"*** PASSED 18F26k22 TBL EEPROM test\"" nop goto $-1 copy_exec: ; test that copied code can work movf TBLPTRL,W return ; ; Test reading and writing Configuration data via eeprom interface ; read_config_data: movlw 0x30 movwf TBLPTRU movlw 0x00 movwf TBLPTRH movlw 0x00 ; movwf TBLPTRL movlw (1<. list p=18f26k22 include include CONFIG WDTEN=ON CONFIG WDTPS=128 CONFIG MCLRE = INTMCLR CONFIG FOSC = XT CONFIG IESO = ON errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 delay1 RES 1 delay2 RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X008 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p18f26k22.xpos = 84" .sim "p18f26k22.ypos = 24" .sim ".frequency = 8000000." call test_osccon .assert "\"*** PASSED 18F26k22 OSCCON test\"" nop goto $-1 test_osccon: BANKSEL OSCCON ;select bank 15 btfss OSCCON,OSTS goto $-1 .assert "cycles == 1028, \"***FAILED p18f26k22 2 speed clock to XT\"" nop .assert "osccon == 0x38, \"***FAILED p18f26k22 osccon after 2 speed clock\"" nop .assert "osccon2 == 0x04, \"***FAILED p18f26k22 osccons after 2 speed clock\"" nop .assert "p18f26k22.frequency==8000000., \"***FAILED p18f26k22 XT freq\"" nop bsf OSCCON,SCS1 ; switch to intrc .assert "p18f26k22.frequency==1000000., \"***FAILED p18f26k22 def RC f=1e6\"" nop .assert "osccon == 0x3e, \"***FAILED p18f26k22 def RC osccon=0x3e\"" nop .assert "osccon2 == 0x04, \"***FAILED p18f26k22 def RC osccon=0x04\"" nop bsf OSCCON,IRCF2 ; set 16MHz RC .assert "p18f26k22.frequency==16000000., \"***FAILED p18f26k22 osccon=0x70 f=16e6\"" nop .assert "osccon == 0x7e, \"***FAILED p18f26k22 osccon=0x7e\"" nop .assert "osccon2 == 0x04, \"***FAILED p18f26k22 osccon=0x04\"" nop movlw 0x03 ; LFINTOSC movwf OSCCON bsf OSCTUNE,INTSRC ; HFINTOSC .assert "osccon == 0x0b, \"***FAILED p18f26k22 osccon=0x0b\"" nop bsf OSCCON2,MFIOSEL nop return ; When edge1 is set, CTPLS goes high and the - input of C2 is changed ; by current source of CTMU. When C2 output changes to 1 CTPLS goes low ; and the current source is turned off. pulse_delay: ; In pulse mode we have C = 5pF, V = 2.048, I = 0.55 uA ; so pulse should last t = CV/I = 18.6 uSec ; Note Gpsim only resolves time to Instruction rate ; for 16MHz clock tmr5l = 0x4A ; C2 on + = Vref - = C12IN- (connected to CTMU) movlw (1<. list p=18f26k22 include include CONFIG WDTEN=ON CONFIG WDTPS=128 CONFIG MCLRE = INTMCLR CONFIG FOSC = INTIO67 errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 delay1 RES 1 delay2 RES 1 hlvd_int RES 1 GLOBAL hlvd_int ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X008 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p18f26k22.xpos = 84" .sim "p18f26k22.ypos = 24" .sim "module library libgpsim_modules" .sim "module load pulldown R" .sim "R.resistance = 10." .sim "R.voltage = 5." .sim "R.xpos = 84" .sim "R.ypos = 228" .sim "node na0" .sim "attach na0 R.pin porta5" movlw 0x70 ;set 16MHz movwf OSCCON movlw (1<= 1.024 on HLVDIN movlw (1<= 4.74V movlw (1< 4.74\"" nop bcf PIR2,HLVDIF bcf HLVDCON,VDIRMAG ; under-voltage test .assert "(pir2 & 0x04) == 0x00, \"***FAILED 18f26k22 no HLDVIF VDIRMAG=0, Vdd > 4.74\"" nop ; enable HLVD interrupts bsf PIE2,HLVDIF bsf INTCON,GIE bsf INTCON,PEIE clrf hlvd_int .command "p18f26k22.Vdd=3.30" nop nop .assert "hlvd_int != 0, \"***FAILED 18f26k22 interrupt VDIRMAG=0, Vdd < 4.74\"" nop nop .assert "\"*** PASSED 18F26k22 HLVD test\"" nop goto $-1 interrupt: movlb 0 ; BSR=0 btfsc PIR2,HLVDIF goto int_hlvd .assert "\"FAILED 18F26k22 unexpected interrupt\"" nop back_interrupt: retfie 1 int_hlvd: bsf hlvd_int,0 bcf PIR2,HLVDIF goto back_interrupt end gpsim-0.30.0/regression/p18f26k22/Makefile0000664000076400007640000000037113100355730014727 00000000000000include ../make.regression all: hlvd_26k22.cod ctmu_26k22.cod tbl_26k22.cod sync_26k22.cod osccon_26k22.cod %.cod : %.o gplink --map -o $@ $< sim: sim_hlvd_26k22 sim_ctmu_26k22 sim_tbl_26k22 sim_sync_26k22 sim_osccon_26k22 .PHONY: all clean gpsim-0.30.0/regression/p18f26k22/ctmu_26k22.asm0000664000076400007640000001777513041763600015612 00000000000000; ; ; Copyright (c) 2015 Roy Rankin ; ; This file is part of the gpsim regression tests ; ; This library is free software; you can redistribute it and/or ; modify it under the terms of the GNU Lesser General Public ; License as published by the Free Software Foundation; either ; version 2.1 of the License, or (at your option) any later version. ; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; Lesser General Public License for more details. ; ; You should have received a copy of the GNU Lesser General Public ; License along with this library; if not, see ; . list p=18f26k22 include include CONFIG WDTEN=ON CONFIG WDTPS=128 CONFIG MCLRE = INTMCLR CONFIG FOSC = INTIO67 errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR 0 delay1 RES 1 delay2 RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;; ;; Interrupt ;; INTERRUPT_VECTOR CODE 0X008 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p18f26k22.xpos = 84" .sim "p18f26k22.ypos = 24" .sim "module library libgpsim_modules" .sim "module load pulldown R" .sim "R.resistance = 420000." .sim "R.xpos = 84" .sim "R.ypos = 228" .sim "node na0" .sim "attach na0 R.pin porta2" .sim "module load pulldown Cx" .sim "Cx.resistance = 1.2e10" .sim "Cx.capacitance = 11.e-12" ; 11 pF .sim "Cx.xpos = 84" .sim "Cx.ypos = 288" .sim "node na5" .sim "attach na5 Cx.pin porta3" ; drive CTED1 with Portb1 .sim "node na1" .sim "attach na1 portb2 portb1" ; drive CTED2 with Portb5 .sim "node na2" .sim "attach na2 portb3 portb5" ; Float Porta1 (AN1) for comparator/A2D input connected to CTMU .sim "node na3" .sim "attach na3 porta1" ; attach CTPLS to T3G to time CTPLS .sim "node na4" .sim "attach na4 portc2 portb4" call setup bsf CTMUCONH,EDGEN ; enable edges bsf CTMUCONH,CTMUEN ; enable CTMU call cap_stray call pulse_delay call time_measure call current_measure clrf CTMUCONH ; disable CTMU .assert "\"*** PASSED 18F26k22 CTMU test\"" nop goto $-1 ; When edge1 is set, CTPLS goes high and the - input of C2 is changed ; by current source of CTMU. When C2 output changes to 1 CTPLS goes low ; and the current source is turned off. pulse_delay: ; In pulse mode we have C = 5pF, V = 2.048, I = 0.55 uA ; so pulse should last t = CV/I = 18.6 uSec ; Note Gpsim only resolves time to Instruction rate ; for 16MHz clock tmr5l = 0x4A ; C2 on + = Vref - = C12IN- (connected to CTMU) movlw (1< ; processor specific variable definitions include ; Grab some useful macros __CONFIG (_CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF) errorlevel -302 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "module load pu pu1" .sim "pu1.xpos = 220." .sim "pu1.ypos = 40." .sim "module load pd pd1" .sim "pd1.xpos = 72." .sim "pd1.ypos = 300." ; .sim "pu1.resistance=1000." .sim "pd1.resistance=3900." .sim "node A" .sim "attach A porta0 porta1 pu1.pin" .sim "node B" .sim "attach B porta2 portb0 pd1.pin" ; ; the following test for a core dump bug ; .sim "node C" .sim "attach C pd1" nop ; Turn off the A2D converter and make PORTA's I/O's digital: bsf STATUS,RP0 movlw (1< ; processor specific variable definitions include ; Grab some useful macros ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE ;---------------------------------------------------------------------- ; gpsim configuration script ; ; The configuration environment consists of a switch SW1 connecting ; portb0 and portc0 to portc1. Resistors on either side of the switch ; ensure that the nodes are never floating and allow the switch voltage ; to be checked. ; ; SW2.A is connected to the same node as SW1.A and SW2.B is connected to ; portc2. This allows checking of 2 switch infinite regression bug. ; ; Portb0 is used to drive the switch while portc 0-2 monitor the results ; ; PU1 SW1 ; | A \ B ; portb0 >--+--+----O \O-----+--> portc1 ; | | ; portc0 <--+ | ; | A \ B PD1 ; |-----O \O----------> portc2 ; SW2 ; ; The pull up and pull down resistors are modelled as parallel RC networks: ; ; ; 5V ; ^ x ; | | ; +--+--+ +--+--+ ; | | | | ; R \ === C R \ === C ; / | / | ; | | | | ; +--+--+ +--+--+ ; | | ; x /// ; ; Pull up Pull Down ; ; The 'x' is connection point. ; ;# Module libraries: .sim "module library libgpsim_modules" ;# The processor's reference designator is U1 .sim "U1.xpos = 48.0" .sim "U1.ypos = 36.0" .sim "module load switch SW1" .sim "SW1.state=false" .sim "SW1.xpos = 216.0" .sim "SW1.ypos = 156.0" .sim "SW1.Ropen = 1.0e8" .sim "module load pullup PU1" .sim "PU1.resistance=1.0e8" .sim "PU1.capacitance=2.00e-07" .sim "PU1.xpos = 204.0" .sim "PU1.ypos = 36.0" .sim "module load pulldown PD1" .sim "PD1.resistance=5000." .sim "PD1.capacitance=4.00e-06" .sim "PD1.xpos = 204.0" .sim "PD1.ypos = 96.0" .sim "module load switch SW2" .sim "SW2.state=open" .sim "SW2.xpos = 216.0" .sim "SW2.ypos = 228.0" .sim "SW2.Ropen = 1.0e6" ;# Connections: .sim "node nb0" .sim "attach nb0 SW1.A portb0 portc0 PU1.pin SW2.A" .sim "node nc0" .sim "attach nc0 SW1.B PD1.pin portc1" .sim "node nc1" .sim "attach nc1 SW2.B portc2" .sim "frequency 10.0e6" ;# Scope monitoring .sim "scope.ch0=\"portb0\"" .sim "scope.ch1=\"portc0\"" .sim "scope.ch2=\"portc1\"" .sim "scope.ch3=\"portc2\"" ;# End of configuration ; ;------------------------------------------------------------------------ start BSF STATUS,RP0 movlw 0x07 ; RC2,RC1 and RC0 are inputs movwf TRISC CLRF TRISB^0x80 ;Port B is an output BCF STATUS,RP0 ; The switch is open and portb0 is driving one side of it and portc0. ; The other side goes to portc1 and is pulled up by the pullup resistor ; Toggling portb0 should have no effect on portc1 BCF PORTB,0 ; both sides of switch should be 0 .assert "(portc & 3) == 0, \"SW open, both sides 0\"" nop bsf PORTB,0 call sdelay nop .assert "(portc & 3) == 1, \"SW open, drive high\"" ; drive side only high nop ; Close the switch because of capacitance portc1 will go high after a delay: ; R=145, C=4.2e-6 TC=6.11e-4 or 1527 cycles 0-2 volts requires 0.51 Tc .command "SW1.state=true" nop nop ; portc0 should be same as portc1 .assert "(portc & 3) == 0, \"SW1 closed, cap holds low\"" nop nop movlw 1 ; wait 1280 cycles call delay nop .assert "(portc & 3) == 3, \"Sw1 closed, after < 1TC\"" nop movlw 8 ; let voltage go all the way high call delay ; drive portb low, voltages should from ~5 to 1 volts in 1.6 TC ; or 2443 cycles, but because of RC step need 3 delay loops BCF PORTB,0 ; change drive voltage movlw 3 call delay .assert "(portc & 3) == 0, \"drive low 1.6TC\"" ; both sides now low nop movlw 6 ; let voltages go to 0 call delay ; ; test capacitance delay on drive transition ; BSF PORTB,0 ; drive high again movlw 9 call delay .assert "(portc & 3) == 3, \"prepare switch open\"" ; make sure both sides are high nop ; Open the switch, the time constant for the floating side is 0.02 sec. ; At 10 MHz oscillator frequency the time constant is 50,000 instruction ; cycles. To go from 5 to 0.5 volts requires 2.3 time constants or ; 1.15e5 cycles. As delay loop is 1277 want to delay 90 loops (5A hex). ; Note, although 1 Volt is the h2l transition voltage at 1.6 time constants, ; we miss this. ; ; The drive side time constant is 150 * 2e-7 = 3e-5 sec or 75 cycles ; so drive side goes low as soon as drive does. ; .command "SW1.state=false" nop ; driven side still driven, floating side ; held by capacitance. .assert "(portc & 3) == 3, \"SW1 open driving high\"" nop BCF PORTB,0 ; C = 0.2 uF R = 150 so time constant = 30 uS ; allow 77 uS (10Mhz clock) for portc0 to settle movlw 0x40 movwf temp1 decfsz temp1,f goto $-1 nop ; C = 4 uF R = 5000 so time constant = 20 mS ; for Fosc = 10MHz clock = 50,000 instuction cycles ; require ~ 2 time constants to reach low state .assert "(portc & 3) == 2, \" SW1 open driving low\"" nop movlw 0x29 ; delay 52,480 cycles call delay .assert "(portc & 3) == 2, \"SW1 open float still high\"" nop movlw 0x31 ; delay another 62,720 cycles call delay nop .assert "(portc & 3) == 0, \"SW1 open float low after 115215 cycles\"" nop ; Turn off Capacitance to test DC behaviour ; .command "PD1.capacitance=0.0" nop .command "PU1.capacitance=0." nop .assert "(portc & 3) == 0" nop BSF PORTB,0 ; Drive one side of switch high .assert "(portc & 3) == 1, \"Drive side high C=0\"" nop ; Close the switch: .command "SW1.state=true" nop .assert "(portc & 3) == 3, \"Both sides high C=0\"" nop BCF PORTB,0 .assert "(portc & 3) == 0, \"Both sides low C=0\"" nop ; Close the SW2 switch, portc2 should be same as portc0 and portc1 BSF PORTB,0 ; Drive one side of switch high .command "SW2.state=closed" nop .assert "(portc & 7) == 7, \"2 Switch drive high\"" nop BCF PORTB,0 .assert "(portc & 7) == 0, \"2 switch drive low\"" nop ; Now test very large switch resistance .command "SW1.state=false" nop .command "SW2.state=open" nop BCF PORTB,0 .assert "(portc & 3) == 0, \"Both sides low C=0 Starting Large Ron\"" nop .command "SW1.Rclosed=1e4" nop .command "PD1.capacitance=0.50e-06" nop .assert "(portc & 3) == 0, \"SW1.Rclosed = 10k\"" nop .command "SW1.state=true" ; Now with the switch closed, the switch resistance and ; the pull down resistance form a voltage divider: ; ; 10k ; portb0 -----/\/\/\---+----+------ portc0 ; \ | ; / | ; 5k \ === 4uF ; / | ; | | ; /// /// ; ; When portb0 is driven to 5.0V, portc0 will rise to 5/3=1.66V BSF PORTB,0 ; Drive one side of switch high movlw 30 call delay BCF PORTB,0 ; Drive the switch low again movlw 30 call delay ; Remove the pull down resistor by making its value very large ; Now when we drive portb0 high, the other side can rise to 5.0V .command "PD1.resistance=1.0e8" nop BSF PORTB,0 ; Drive one side of switch high movlw 9 call delay BCF PORTB,0 ; Drive the switch low again movlw 9 call delay nop done: .assert "\"*** PASSED Switch Test on 16f877\"" goto $ FAILED: .assert "\"*** FAILED Switch Test on 16f877\"" goto $ delay ; W=9 = delay about 11,500 cycles or 1.2 ms at 10 Mhz clrwdt movwf temp2 clrf temp1 delay_loop decfsz temp1,f goto $+2 decfsz temp2,f goto delay_loop return sdelay ; delay about 100 cycles or 40 us at 10 Mhz clrwdt movlw 0x20 movwf temp1 decfsz temp1,f goto $-1 return end gpsim-0.30.0/regression/switch_test/16f877.lkr0000664000076400007640000000330513041763600015741 00000000000000// Sample linker command file for 16F877 // $Id: 16f877.lkr 1351 2005-11-12 16:18:52Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=page2 START=0x1000 END=0x17FF CODEPAGE NAME=page3 START=0x1800 END=0x1FFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=PROG3 ROM=page2 // ROM code space - page2 SECTION NAME=PROG4 ROM=page3 // ROM code space - page3 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/README0000664000076400007640000000644313041763600012713 00000000000000Regression tests for gpsim Introduction ------------ The purpose of the regression tests is to ensure that gpsim works. Basic elements like instruction simulation and breakpoints are verified. In addition when new bugs are found and fixed, specific tests are created to ensure that future versions of gpsim are not infected. Each regression test or a collection of similar regression tests occupies a subdirectory that is child of this README's directory. The item(s) to be tested are placed into their own .asm file. This file is assembled by gpasm and simulated by gpsim and then the results are "analyzed" by a script. Once the .asm file is created, the whole process becomes automatic. However, the regression files need to adhere to a format that is understood by the scripts. Running ------- If you want to perform a regression test with the default set up then run: On *nix: ./run_regression.sh On WIN32 + Cygwin from the shell: ./run_regression.sh '/cygdrive/c/Program Files/gpsim/bin' (You may need to change the file to an executable [chmod +x]). This should step through each test and print PASS or FAIL results. The 'run_regression.sh' script consists of a list of regression tests that are to be tested. Each of these is a single line that invokes the secondary script 'rt.sh'. This script takes two parameters: the directory containing the regression test and the name of the Makefile target the test should invoke. Typically there is a 'sim' target. So an example of rt.sh action would be: cd node_test make sim Files needed for a regression test ---------------------------------- Each test requires a .asm file and a .stc file. The .asm file contains the assembly code (of course) and the .stc file contains startup commands that allow you to configure your simulation environment for your test. For example, if your test involves measuring the width of a pulse then you'll want to create an asynchronous stimulus to generate the pulse. If there are no special startup conditions, then the .stc file can be really simple. For example, 14-bit core instruction test .stc file contains only: # simple script to load the simulation load s instructions_14bit.cod It's also possible to embed gpsim scripts directly in the assembly source files. See the logic_test/ regression test for an example. Assembly file format -------------------- The assembly file must be in the relocatable code format. The reason is because gpsim makes use of gpasm directives that are only available in this format. The assembly file can contain anything you want. However, to simplify the parsing of the results there must be an assertion that contains the string "*** PASSED". For example, something like this: .assert ",\"*** PASSED MidRange core interrupt test\"" This assertion should be placed in the assembly file at an instruction that executes only after all of the tests have completed. (Note, this type of assertion has no break condition expression - so therefore it will always assert and gpsim will halt the simulation when this is encountered. The message will be printed to stdout.) Makefiles --------- In addition to the Assembly File format, there must also be a Makefile in each regression directory. This Makefile can be anything you want, but at some point there must be a make target that can invoke gpsim. gpsim-0.30.0/regression/logic_test/0000775000076400007640000000000013117466027014247 500000000000000gpsim-0.30.0/regression/logic_test/logic_test.stc0000664000076400007640000000011313041763577017037 00000000000000 # simple script to load and start the simulation load s logic_test.cod gpsim-0.30.0/regression/logic_test/Makefile0000664000076400007640000000046113041763577015636 00000000000000include ../make.regression SCRIPT = 16f873.lkr PROJECT = logic_test OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC="$<" gpsim-0.30.0/regression/logic_test/logic_test.asm0000664000076400007640000001523213116714324017023 00000000000000 ;; Logic test ;; ;; The purpose of this program is to verify that gpsim's ;; Logic modules function. ;; ;; ;; list p=16f873 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG (_CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF) errorlevel -302 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA var1 RES 1 var2 RES 1 var3 RES 1 failures RES 1 GLOBAL var1,var2,var3,failures GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf var1 clrf var2 clrf var3 bsf STATUS,RP0 clrf TRISA^0x80 ;Port A is an output clrf TRISB^0x80 ;Port B is an output movlw 0xff movwf TRISC^0x80 ;Port C is an input ; Turn off the A2D converter and make PORTA's I/O's digital: movlw (1<>2) | (porta>>1) | porta) & 1)" btfss PORTA,3 goto L_OrCheck ; AND Gate check. ; U3_or ; portb3 ---|-+ U4_or ; |& )----|-+ ; portb4 ---|-+ |& )---+ ; +--|-+ | ; portb5 --------+ | ; | ; portc1 ------------------+ ; .sim "node nb3" .sim "attach nb3 U3_and.in0 portb3" .sim "node nb4" .sim "attach nb4 U3_and.in1 portb4" .sim "node n3_4" .sim "attach n3_4 U3_and.out U4_and.in0" .sim "node nb5" .sim "attach nb5 U4_and.in1 portb5" .sim "node nc1" .sim "attach nc1 U4_and.out portc1" ; Loop through the 8 states: L_AndCheck movlw 1<<3 addwf PORTB,F .assert "((portc>>1) & 1) == ( ((portb>>5) & (portb>>4) & (portb>>3)) & 1)" movf PORTB,W andlw b'111000' skpz goto L_AndCheck ; xor Gate check. ; U1_xor ; portb0 ---))-\ U2_xor ; ))^ )---))-\ ; portb1 ---))-/ ))^ )--+ ; +--))-/ | ; portb2 --------+ | ; | ; portc2 ------------------+ ; .sim "node nb0" .sim "attach nb0 U1_xor.in0 portb0" .sim "node nb1" .sim "attach nb1 U1_xor.in1 portb1" .sim "node n1_2" .sim "attach n1_2 U1_xor.out U2_xor.in0" .sim "node nb2" .sim "attach nb2 U2_xor.in1 portb2" .sim "node nc2" .sim "attach nc2 U2_xor.out portc2" ; Loop through the 8 states: L_XorCheck: incf PORTB,F .assert "((portc>>2) & 1) == ( ((portb>>2) ^ (portb>>1) ^ portb) & 1)" btfss PORTB,3 goto L_XorCheck ; Not Gate test ; U7_not ; |\ ; portb6 ---| O-----+ ; |/ | ; portc3 -----------+ ; ; U8_not U9_not ; |\ |\ ; portb7 ---| O-----| O---+ ; |/ |/ | ; portc4 -----------------+ ; .sim "node nb6" .sim "attach nb6 U7_not.in0 portb6" .sim "node nc3" .sim "attach nc3 U7_not.out portc3" bsf PORTB, 6 ;(don't need to do this...) .assert "((portc>>3) & 1) == ( ((portb>>6) & 1)^1)" bcf PORTB, 6 .assert "((portc>>3) & 1) == ( ((portb>>6) & 1)^1)" nop .sim "node nb7" .sim "attach nb7 U8_not.in0 portb7" .sim "node n7_8" .sim "attach n7_8 U8_not.out U9_not.in0" .sim "node nc4" .sim "attach nc4 U9_not.out portc4" bsf PORTB, 7 ;(don't need to do this...) .assert "((portc>>4) & 1) == ( ((portb>>7) & 1))" bcf PORTB, 7 .assert "((portc>>4) & 1) == ( ((portb>>7) & 1))" nop passed: clrf failures done: ; If no expression is specified, then break unconditionally #define UNRELEASED_GPASM ifdef UNRELEASED_GPASM .assert "\"*** PASSED Logic Module test\"" else .assert "" endif goto done nop end end gpsim-0.30.0/regression/logic_test/16f873.lkr0000664000076400007640000000530413041763577015547 00000000000000//********************************************************************* // * // Software License Agreement * // * // The software supplied herewith by Microchip Technology * // Incorporated (the "Company") for its PICmicro® Microcontroller * // is intended and supplied to you, the Company’s customer, for use * // solely and exclusively on Microchip PICmicro Microcontroller * // products. The software is owned by the Company and/or its * // supplier, and is protected under applicable copyright laws. All * // rights are reserved. Any use in violation of the foregoing * // restrictions may subject the user to criminal sanctions under * // applicable laws, as well as to civil liability for the breach of * // the terms and conditions of this license. * // * // THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO * // WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, * // BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND * // FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE * // COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, * // INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * // * //********************************************************************* // File: 16f873.lkr // Linker Script file, modified // Date: 06/07/2000 // Modified 7/18/2000 -.RLF LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x70 PROTECTED CODEPAGE NAME=page0 START=0x71 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF PROTECTED CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x7F DATABANK NAME=gpr1 START=0xA0 END=0xFF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/eeprom_wide/0000775000076400007640000000000013117466027014412 500000000000000gpsim-0.30.0/regression/eeprom_wide/Makefile0000664000076400007640000000051113041763600015760 00000000000000include ../make.regression SCRIPT = 16f873.lkr PROJECT = eeprom_wide OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/eeprom_wide/eeprom_wide.asm0000664000076400007640000001337113041763600017331 00000000000000 list p=p16f873 radix dec ; ; Test EEPROM and FLASH program single byte reads and writes. ; on 16f873 which uses wide mode __config _WDT_OFF include "p16f873.inc" include ; Grab some useful macros cblock 0x20 ; bank 0 and 2 adr_cnt data_cnt status_temp datah datal ee_int endc ; W shadowing for interrupts ; When an interrupt occurs, we don't know what the current bank settings ; are. The solution here is to declare two temporaries that have the ; same base address. That way we don't need to worry about the bank setting. cblock 0x70 w_temp ; W is stored here during interrupts if the ; bank bits point to bank 0 or 2 endc cblock 0xf0 w_temp_shadow ; W is stored here during interrupts if the ; bank bits point to bank 0 or 2 endc ;;======================================================================== ;;======================================================================== ; ; Start ; org 0 goto start org 4 ;;************** ;; Interrupt ;;************* movwf w_temp swapf STATUS,W clrf STATUS ;Bank 0 movwf status_temp btfss PIR2,EEIF goto check ;;; eeprom has interrupted bcf PIR2,EEIE incf ee_int,F goto i_ret check: .assert "\"*** FAILED wide EEPROM unexpected interrupt\"" nop i_ret: clrf STATUS ;bank 0 swapf status_temp,W movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;;************* ;; end of interrupt ;;************* start: clrf STATUS ;Point to Bank 0 clrf adr_cnt clrf data_cnt ; bsf INTCON,EEIE bsf INTCON,PEIE bsf INTCON,GIE bsf STATUS,RP0 ;Bank 1 bsf PIR2,EEIE bcf STATUS,RP0 ;Bank 0 ; ; write to EEPROM starting at EEPROM address 0 ; value of address as data using interrupts to ; determine write complete. ; read and verify data l1: bcf PIR2,EEIF movf adr_cnt,W clrf ee_int bcf STATUS,RP0 bsf STATUS,RP1 ;Bank 2 movwf EEADR ^ 0x100 movf data_cnt,W movwf EEDATA ^ 0x100 bcf INTCON,GIE ;Disable interrupts while enabling write bsf STATUS,RP0 ; Bank 3 bcf (EECON1 ^ 0x180),EEPGD ;Point to data Memory bsf (EECON1 ^ 0x180),WREN ;Enable eeprom writes movlw 0x55 ;Magic sequence to enable eeprom write movwf (EECON2 ^ 0x180) movlw 0xaa movwf (EECON2 ^ 0x180) bsf (EECON1 ^ 0x180),WR ;Begin eeprom write bsf INTCON,GIE ;Re-enable interrupts clrf STATUS ; Bank 0 movf ee_int,W skpnz goto $-2 ; ; read what we just wrote ; movf adr_cnt,W bsf STATUS,RP1 bcf STATUS,RP0 ; Bank 2 movwf EEADR bsf STATUS,RP0 ; Bank 3 bcf EECON1,EEPGD ; point ot data memory bsf EECON1,RD ; start read operation bcf STATUS,RP0 ; Bank 2 movf EEDATA,W ; Read data clrf STATUS ; Bank 0 xorwf data_cnt,W ; did we read what we wrote ? skpz goto fail incf adr_cnt,W andlw 0x7f movwf adr_cnt movwf data_cnt skpz goto l1 goto flash fail: .assert "\"*** FAILED wide EEPROM Compare written and read\"" goto $ ; ; test program FLASH read and writes ; read low program memory (0x00XX) ; write to higher memory (0x01XX) ; read and compare higher memory (0x1XX) flash: bsf STATUS,RP1 bcf STATUS,RP0 ; Bank 2 loop_prg: ; ; read low memory 0x00XX ; bsf STATUS,RP1 bcf STATUS,RP0 ; Bank 2 movwf adr_cnt movwf EEADR clrf EEADRH bsf STATUS,RP0 ; Bank 3 bsf EECON1,EEPGD ; point to program memory bsf EECON1,RD ; start read operation nop nop bcf STATUS,RP0 ; Bank 2 movf EEDATA,W ; save read data movwf datal movf EEDATH,W movwf datah ; ; Write to High address (0x01XX) data alredy in EEDATA, EEDATAH ; movlw 0x01 movwf EEADRH movf adr_cnt,W movwf EEADR ^ 0x100 bcf INTCON,GIE ;Disable interrupts while enabling write bsf STATUS,RP0 ; Bank 3 bsf (EECON1 ^ 0x180),EEPGD ;Point to program Memory bsf (EECON1 ^ 0x180),WREN ;Enable eeprom writes movlw 0x55 ;Magic sequence to enable write movwf (EECON2 ^ 0x180) movlw 0xaa movwf (EECON2 ^ 0x180) bsf (EECON1 ^ 0x180),WR ;Begin write nop nop bsf INTCON,GIE ;Re-enable interrupts bcf (EECON1 ^ 0x180),WREN ;Disable writes btfsc (EECON1 & 0x7f),WR goto $-1 ; ; read what we just wrote ; bcf STATUS,RP0 ; Bank 2 movf adr_cnt,W movwf EEADR movlw 0x01 movwf EEADRH bsf STATUS,RP0 ; Bank 3 bsf EECON1,EEPGD ; point to program memory bsf EECON1,RD ; start read operation bcf STATUS,RP0 ; Bank 2 movf EEDATA,W ; Read data xorwf datal,W skpz goto fail_prog ; low byte does not match movf EEDATH,W ; Read data xorwf datah,W skpz goto fail_prog ; low byte does not match nop nop incf adr_cnt,W andlw 0x3f movwf adr_cnt skpz goto loop_prg .assert "\"*** PASSED wide EEPROM and program FLASH read-write test\"" goto $ fail_prog: .assert "\"*** FAILED wide program FLASH Compare written and read\"" goto $ org 0x2100 de "0123456789ABCDEF" de "Linux is cool!",0 de 0xaa,0x55,0xf0,0x0f de 'g','p','s','i','m' end gpsim-0.30.0/regression/eeprom_wide/eeprom_wide.stc0000664000076400007640000000113013041763600017330 00000000000000 load eeprom_wide.cod # Module libraries: module library libgpsim_modules # Modules: #p16f877A.xpos=84. #p16f877A.ypos=36. module load pullup PU1 PU1.resistance=10000. #PU1.xpos=96. #PU1.ypos=312. module load pulldown PD2 PD2.resistance=10000. #PD2.xpos=96. #PD2.ypos=360. module load pullup PU2 #PU2.xpos=96. #PU2.ypos=420. # Connections: node nb0 attach nb0 porta0 portb0 PU1.pin PD2.pin #attach nb0 porta0 portb0 node nb1 attach nb1 porta1 portb1 node nb2 attach nb2 porta2 portb2 node nb3 attach nb3 porta3 portb3 node nb4 attach nb4 porta4 portb4 PU2.pin break c 1000000 # End. gpsim-0.30.0/regression/eeprom_wide/16f873.lkr0000664000076400007640000000530413041763600015675 00000000000000//********************************************************************* // * // Software License Agreement * // * // The software supplied herewith by Microchip Technology * // Incorporated (the "Company") for its PICmicro® Microcontroller * // is intended and supplied to you, the Company’s customer, for use * // solely and exclusively on Microchip PICmicro Microcontroller * // products. The software is owned by the Company and/or its * // supplier, and is protected under applicable copyright laws. All * // rights are reserved. Any use in violation of the foregoing * // restrictions may subject the user to criminal sanctions under * // applicable laws, as well as to civil liability for the breach of * // the terms and conditions of this license. * // * // THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO * // WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, * // BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND * // FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE * // COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, * // INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * // * //********************************************************************* // File: 16f873.lkr // Linker Script file, modified // Date: 06/07/2000 // Modified 7/18/2000 -.RLF LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x70 PROTECTED CODEPAGE NAME=page0 START=0x71 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF PROTECTED CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x7F DATABANK NAME=gpr1 START=0xA0 END=0xFF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/p16f628/0000775000076400007640000000000013117466027013127 500000000000000gpsim-0.30.0/regression/p16f628/p16f628.stc0000664000076400007640000000101313041763602014564 00000000000000 # Node Test # # This script will tie Port A and Port B together # # First, create 8 nodes: node loop_back0 node loop_back1 node loop_back2 node loop_back3 node loop_back4 node loop_back5 node loop_back6 node loop_back7 # Now tie the ports together: attach loop_back0 portb0 porta0 attach loop_back1 portb1 porta1 attach loop_back2 portb2 porta2 attach loop_back3 portb3 porta3 attach loop_back4 portb4 porta4 attach loop_back5 portb5 porta5 attach loop_back6 portb6 porta6 attach loop_back7 portb7 porta7 gpsim-0.30.0/regression/p16f628/p16f628.asm0000664000076400007640000000404313041763602014561 00000000000000 ;; 16F628 tests ;; ;; This regression test exercises the 16f628. ;; ;; Tests performed: ;; ;; 1) Verify Comparators can be disabled and that ;; PORTA can work as a digital I/O port. list p=16f628a include "p16f628a.inc" CONFIG_WORD EQU _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF __CONFIG CONFIG_WORD cblock 0x20 failures endc ORG 0 CLRF failures ;Assume success MOVLW 0xff BSF STATUS,RP0 CLRF TRISA^0x80 ;Port A is an output MOVWF TRISB^0x80 ;Port B is an input CLRF VRCON^0x80 ;Turn off the Voltage Reference module. BCF STATUS,RP0 ;; ;; Turn off the comparator module ;; MOVLW (1< ; processor specific variable definitions include ; Grab some useful macros ;; Suppress warnings of using 'option' instruction. errorlevel -224 __CONFIG _WDT_ON GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 temp4 RES 1 temp5 RES 1 adr_cnt RES 1 data_cnt RES 1 failures RES 1 w_temp RES 1 status_temp RES 1 GLOBAL temp,temp1,temp2,temp3,temp4,temp5, w_temp GLOBAL start ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp .assert "(w_temp) == 0x12,\"*** FAILED interrupt_14bit/int_sleep, w not set\"" nop check_rbi: btfsc INTCON,RBIF btfss INTCON,RBIE goto check_int bsf temp5,1 ;Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w check_int: btfsc INTCON,INTF btfss INTCON,INTE goto check_t0 bsf temp5,0 ;Set a flag to indicate rb0 int occured bcf INTCON,INTF check_t0: btfsc INTCON,T0IF btfss INTCON,T0IE goto exit_int ;; tmr0 has rolled over bcf INTCON,T0IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w clrwdt retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;; Assume no failures clrf failures ;; ;; inte test ;; ;; The following block of code tests the interrupt on ;; change for port b bit 0. It assumes that port a bit 4 ;; is the stimulus. This requires that the following ;; gpsim commands be invoked: ;; gpsim> node new_test_node ;; gpsim> attach new_test_node porta4 portb0 ;; ;; Also, recall that porta bit 4 is an open collector ;; output (it can't drive high). So to generate the ;; the logic highs, the portb weak pull-up resistors ;; need to be enabled. .sim "stimulus asynchronous_stimulus " .sim "initial_state 0" .sim "start_cycle 0" .sim "period 305" .sim "{ 38,1 , 76,0 , 114,1 , 152,0 , 190,1 , 228,0 , 266,1}" .sim "name portDrive" .sim "end" .sim "node stim" .sim "attach stim portDrive portb0" clrwdt test_inte: bsf STATUS,RP0 bsf (TRISB ^ 0x80),0 ;and portb bit 0 an input bcf (OPTION_REG^0x80),NOT_RBPU ;Enable the portb weak pull-ups bsf (OPTION_REG^0x80),INTEDG ;Interrupt on rising edge bcf STATUS,RP0 bcf INTCON,INTF bsf INTCON,INTE bsf INTCON,GIE movlw 0x12 x: btfss temp5,0 goto x clrf temp5 clrw rrr: sleep movlw 0x12 btfss temp5,0 ; did we interrupt? goto failed ; no clrw clrf temp5 nop movlw 0x12 sleep goto done goto failed ; no done: nop .assert "\"*** PASSED interrupt_14bit/int_sleep sleep interrupt test\"" nop goto $ failed: .assert "\"*** FAILED interrupt_14bit/int_sleep sleep interrupt test\"" goto $ ;; ;; This routine toggles one of the porta bits with the hope of generating ;; an interrupt on one of the portb bits. ;; temp1 counts the number of interrupts due to falling edges ;; temp2 counts the number of interrupts due to rising edges ;; test_int_pin: bsf STATUS,RP0 bcf (TRISA ^ 0x80),4 ;Make porta bit 4 an output bsf (TRISB ^ 0x80),0 ;and portb bit 0 an input bcf (OPTION_REG^0x80),NOT_RBPU ;Enable the portb weak pull-ups bcf STATUS,RP0 clrf temp1 clrf temp2 movlw 0x40 movwf temp3 ; used for counting movwf temp4 bcf PORTA,4 bcf INTCON,INTF bsf INTCON,INTE ;; ;; Now loop round 64 times toggling the pin and count the interrupts ;; inte_edgecount: bcf temp5,0 ;Interrupt flag clrz bsf PORTA,4 ;Falling edge btfsc temp5,0 incf temp2,f ;Falling edge caused the interrupt bcf temp5,0 bcf PORTA,4 ;Rising edge btfsc temp5,0 incf temp1,f ;Rising edge caused the interrupt decfsz temp3,f goto inte_edgecount return end gpsim-0.30.0/regression/interrupts_14bit/interrupts_14bit.stc0000664000076400007640000000165613041763600021213 00000000000000load interrupts_14bit.cod # another test stimulation file # # the '#' marks the beginning of a comment # # This stimulation file illustrates how two (or more) # iopins may be connected to one another. In this example, # port A bit 4 is tied to port B bit 0. # Also, note that this file does not define the processor # or the source .hex ... echo I/O pin Stimulus file that connects port A 4 echo port B 0. # Define a node to which the pins can attach. node test_node # Now specify which two I/O pins are attached to the # new node. Note, that it is possible to specify more # than two iopins (or two of any stimuli). The iopins # are assigned the names portxn - where x is a,b,c,d,e # and n is 0 through 7. attach test_node porta4 portb0 # Here are a couple of more stimuli that are used to # test rbif node n1 n2 n3 attach n1 portb1 portb5 attach n2 portb2 portb6 attach n3 portb3 portb7 attach test_node portb4 break c 0x200000 gpsim-0.30.0/regression/interrupts_14bit/16f84.lkr0000664000076400007640000000160413041763600016531 00000000000000// Sample linker command file for 16F84 // $Id: 16f84.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x3FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0xB PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x8B PROTECTED DATABANK NAME=gprs START=0xC END=0x4F SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/interrupts_14bit/interrupts_14bit.asm0000664000076400007640000002274413041763600021203 00000000000000 ;; The purpose of this program is to test gpsim's ability to ;; simulate interrupts on the midrange core (specifically the 'f84). list p=16f84 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;; Suppress warnings of using 'option' instruction. errorlevel -224 __CONFIG _WDT_ON GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 temp4 RES 1 temp5 RES 1 adr_cnt RES 1 data_cnt RES 1 failures RES 1 w_temp RES 1 status_temp RES 1 GLOBAL temp,temp1,temp2,temp3,temp4,temp5 GLOBAL start ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp check_rbi: btfsc INTCON,RBIF btfss INTCON,RBIE goto check_int bsf temp5,1 ;Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w check_int: btfsc INTCON,INTF btfss INTCON,INTE goto check_t0 bsf temp5,0 ;Set a flag to indicate rb0 int occured bcf INTCON,INTF check_t0: btfsc INTCON,T0IF btfss INTCON,T0IE goto exit_int ;; tmr0 has rolled over bcf INTCON,T0IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w clrwdt retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;; Assume no failures clrf failures ;; ;; tmr0 test ;; ;; The following block of code tests tmr0 together with interrupts. ;; Each prescale value (0-7) is loaded into the timer. The software ;; waits until the interrupt due to tmr0 rollover occurs before ;; loading the new prescale value. bsf INTCON,T0IE ;Enable TMR0 overflow interrupts bsf INTCON,GIE ;Global interrupts clrf temp1 ;Software flag used to monitor when the ;interrupt has been serviced. clrw test_tmr0: option ;Assign new prescale value btfss temp1,0 ;Wait for the interrupt to occur and goto $-1 ;get serviced clrf temp1 ;Clear flag for the next time bsf STATUS,RP0 incf (OPTION_REG^0x80),W bcf STATUS,RP0 andlw 0x7 ;Check the prescaler skpz goto test_tmr0 bcf INTCON,T0IE ;Disable tmr0 interrupts ;; Now check tmr0 with an external clock source ;; ;; It assumes that port b bit 0 is the stimulus. ;; This requires that the following gpsim commands be invoked: ;; gpsim> node new_test_node ;; gpsim> attach new_test_node porta4 portb0 bsf STATUS,RP0 bcf (TRISB ^ 0x80),0 ;portb bit 0 is an output bcf STATUS,RP0 ;; assign the prescaler to the wdt so that tmr0 counts every edge ;; select the clock source to be tocki ;; and capture low to high transitions (tose = 0) movlw (1< node new_test_node ;; gpsim> attach new_test_node porta4 portb0 ;; ;; Also, recall that porta bit 4 is an open collector ;; output (it can't drive high). So to generate the ;; the logic highs, the portb weak pull-up resistors ;; need to be enabled. clrwdt test_inte: bsf STATUS,RP0 bcf (TRISA ^ 0x80),4 ;Make porta bit 4 an output bsf (TRISB ^ 0x80),0 ;and portb bit 0 an input bcf (OPTION_REG^0x80),NOT_RBPU ;Enable the portb weak pull-ups bsf (OPTION_REG^0x80),INTEDG ;Interrupt on rising edge bcf STATUS,RP0 bcf PORTA,4 bcf INTCON,T0IE call test_int_pin .assert "(temp2) == 0x40,\"*** FAILED 14bit-interrupts, no int0 rising\"" nop .assert "(temp1) == 0x00,\"*** FAILED 14bit-interrupts, int0 interrupt on wrong edge\"" nop bcf INTCON,INTE ;Disable inte interrupt bsf STATUS,RP0 bcf (OPTION_REG^0x80),INTEDG ;Interrupt on falling edge bcf STATUS,RP0 call test_int_pin .assert "(temp1) == 0x40,\"*** FAILED 14bit-interrupts, no int0 falling\"" nop .assert "(temp2) == 0x00,\"*** FAILED 14bit-interrupts, int0 interrupt on wrong edge\"" nop ;; ;; test_rbif ;; ;; This next block tests the interrupt on change feature of ;; port b's I/O pins 4-7 ;; clrwdt test_rbif: bcf INTCON,INTE ;Disable the rb0 interrupt bsf STATUS,RP0 bsf (TRISA ^ 0x80),4 ;Porta bit 4 is now an input bcf STATUS,RP0 clrf temp5 ;Interrupt flag clrf temp1 movlw 0x10 movwf temp2 movlw 6 movwf PORTB clrwdt rbif_l1: bcf INTCON,RBIE movf temp2,w tris PORTB ; clrf PORTB movf PORTB,W clrf temp5 ;Interrupt flag bcf INTCON,RBIF bsf INTCON,RBIE swapf temp2,w xorwf PORTB,f btfsc temp5,1 iorwf temp1,f .assert "(temp5 & 2) == 2" clrc rlf temp2,f skpc goto rbif_l1 done: .assert "\"*** PASSED MidRange core interrupt test\"" goto $ failed: .assert "\"*** FAILED MidRange core interrupt test\"" goto $ ;; ;; This routine toggles one of the porta bits with the hope of generating ;; an interrupt on one of the portb bits. ;; temp1 counts the number of interrupts due to falling edges ;; temp2 counts the number of interrupts due to rising edges ;; test_int_pin: bsf STATUS,RP0 bcf (TRISA ^ 0x80),4 ;Make porta bit 4 an output bsf (TRISB ^ 0x80),0 ;and portb bit 0 an input bcf (OPTION_REG^0x80),NOT_RBPU ;Enable the portb weak pull-ups bcf STATUS,RP0 clrf temp1 clrf temp2 movlw 0x40 movwf temp3 ; used for counting movwf temp4 bcf PORTA,4 bcf INTCON,INTF bsf INTCON,INTE ;; ;; Now loop round 64 times toggling the pin and count the interrupts ;; inte_edgecount: bcf temp5,0 ;Interrupt flag clrz bsf PORTA,4 ;Falling edge btfsc temp5,0 incf temp2,f ;Falling edge caused the interrupt bcf temp5,0 bcf PORTA,4 ;Rising edge btfsc temp5,0 incf temp1,f ;Rising edge caused the interrupt decfsz temp3,f goto inte_edgecount return end gpsim-0.30.0/regression/interrupts_14bit/Makefile0000664000076400007640000000076013041763600016711 00000000000000include ../make.regression SCRIPT = 16f84.lkr PROJECT = interrupts_14bit OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod int_sleep.cod STC = $(PROJECT).stc all : $(COD) $(PROJECT).cod : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(PROJECT).cod $(OBJECTS) int_sleep.cod : int_sleep.o $(SCRIPT) gplink --map -s $(SCRIPT) -o int_sleep.cod int_sleep.o sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) $(GPSIM) -i -I $(STARTUP_STC) -D STC=int_sleep.cod gpsim-0.30.0/regression/p16f690/0000775000076400007640000000000013117466027013126 500000000000000gpsim-0.30.0/regression/p16f690/nwdt_16f631.asm0000664000076400007640000000241713041763600015427 00000000000000 ;; 16F631 tests ;; ;; This regression test exercises the 16f631. ;; ;; Tests performed: ;; ;; 1) Verify no WDT with _WDT_OFF in __CONFIG ;; 2) Verify WDT with WDTCON,SWDTEN set list p=16f631 include "p16f631.inc" include .command macro x .direct "C", x endm __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_OFF cblock 0x40 temp flag endc ORG 0 .sim "p16f631.BreakOnReset = false" .sim "break c 0x100000" .sim "p16f631.frequency=10000" btfss STATUS,NOT_TO goto wdt_reset clrf flag banksel OPTION_REG bcf OPTION_REG,PSA BANKSEL TRISA clrf TRISA ; bcf OPTION_REG,NOT_RABPU ; enable pullups on portA BANKSEL PORTA movlw 0xff movwf PORTA banksel PORTA call delay incf flag banksel WDTCON bsf WDTCON,SWDTEN ; turn on WDT bcf OPTION_REG,PSA banksel PORTA call delay .assert "\"*** FAILED p16f631 no WDT with SWDTEN\"" nop done: .assert "\"*** PASSED p16f631 no WDT test\"" nop GOTO $ wdt_reset: btfsc flag,0 goto done .assert "\"*** FAILED p16f631 unexpected WDT triggered\"" nop goto $ delay clrf temp ; LOOP2 goto $+1 goto $+1 goto $+1 decfsz temp, F goto LOOP2 return end gpsim-0.30.0/regression/p16f690/Makefile0000664000076400007640000000262013057411727014506 00000000000000 include ../make.regression # # Use 16f631.lkr for all processors in this family # SCRIPT = 16f631.lkr all : nwdt_16f631.cod wdt_16f677.cod p16f690.cod epwm.cod \ wdt_16f685.cod eusart.cod eusart_690.cod nwdt_16f631.cod: nwdt_16f631.o $(SCRIPT) gplink --map -s $(SCRIPT) -o nwdt_16f631.cod nwdt_16f631.o wdt_16f677.cod: wdt_16f677.o $(SCRIPT) gplink --map -s $(SCRIPT) -o wdt_16f677.cod wdt_16f677.o wdt_16f685.cod: wdt_16f685.o $(SCRIPT) gplink --map -s $(SCRIPT) -o wdt_16f685.cod wdt_16f685.o p16f690.cod: p16f690.o $(SCRIPT) gplink --map -s $(SCRIPT) -o p16f690.cod p16f690.o eusart.cod: eusart.o $(SCRIPT) gplink --map -s $(SCRIPT) -o eusart.cod eusart.o eusart_690.cod: eusart_690.o $(SCRIPT) gplink --map -s $(SCRIPT) -o eusart_690.cod eusart_690.o epwm.cod: epwm.o $(SCRIPT) gplink --map -s $(SCRIPT) -o epwm.cod epwm.o sim: sim_epwm sim_eusart sim_p16f690 sim_nwdt_16f631 sim_wdt_16f677 \ sim_wdt_16f685 sim_eusart_690 sim_epwm: epwm.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_eusart: eusart.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_p16f690: p16f690.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_nwdt_16f631: nwdt_16f631.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_wdt_16f677: wdt_16f677.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_wdt_16f685: wdt_16f685.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/p16f690/eusart.asm0000664000076400007640000001615113061215230015041 00000000000000 ;; EUSART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly when configured as an EUSART. ;; The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=16f687 include include __CONFIG _WDT_OFF & _FOSC_HS & _IESO_ON errorlevel -302 radix dec ; in following equation 100000 if Fosc/100, 48 is baud/100 BAUDHI equ ((100000/4)/48)-1 BAUDLO equ ((100000/16)/48)-1 ;---------------------------------------------------------------------- ; RAM Declarations ; GPR_DATA UDATA_SHR #define RX_BUF_SIZE 0x10 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"*** FAILED sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=10e6" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "U1.xpos = 84" .sim "U1.ypos = 276" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portb7 U1.RXPIN" .sim "attach PIC_rx portb5 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; BANKSEL OSCCON .assert "p16f687.frequency == 4000000., \"FALIED 16f687 default frequency\"" nop btfss OSCCON,OSTS ; wait for hs to be active with 2 speed start goto $-1 .assert "cycles > 1014 && cycles <1028, \"FALIED 16f687 2 speed start\"" nop .assert "p16f687.frequency == 10000000., \"FALIED 16f687 HS frequency\"" nop clrf STATUS bsf PORTB,7 ;Make sure the TX line drives high when ;it is programmed as an output. BANKSEL ANSELH bcf ANSELH,ANS11 BANKSEL TRISB bsf TRISB,5 ;RX is an input bsf TRISB,7 ;TX EUSART sets pin direction ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used BANKSEL TXSTA movlw (1< 9 bits ; and < 10 bits or between 1.87 and 2.08 msec. ; with oscillator at 10MHz and TMR0 / 64 expect between 73 and 81 ; TMR0 cycles. BANKSEL TMR0 movf TMR0,W .assert "tmr0 > 73 && tmr0 <= 81, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop ; Disable interrupts because the following tests don't give good receive bytes BANKSEL PIE1 bcf PIE1,RCIE BANKSEL TXSTA bsf TXSTA,SENB ; request a break sequence BANKSEL PORTB btfss PORTB,7 ; Shouldn't happen just yet .assert "\"*** FAILED break sent too soon\"" nop clrf TMR0 movlw 0x55 movwf TXREG call delay btfsc PORTB,7 ; Should happen by now .assert "\"*** FAILED to send break\"" nop btfss PORTB,7 ; Wait for stop bit goto $-1 ; ; At 4800 baud each bit takes 0.208 msec. Output will be low for ; start + 12 bit times or 2.70 msec. With 10Mhz TMR0 / 64 is 106 TMR0 counts. movf TMR0,W .assert "tmr0 > 101 && tmr0 < 111, \"*** FAILED sync pulse\"" nop done: .assert "\"*** PASSED E-Usart on 16F687\"" goto $ tx_message: incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw 0x30 return delay: decfsz temp2,f goto delay return TransmitNextByte: BANKSEL TXREG clrf rxFlag call tx_message movwf TXREG rx_loop: btfss rxFlag,0 goto rx_loop ; clrf temp2 ; call delay ;; Delay between bytes. btfss PIR1,TXIF goto $-1 return end gpsim-0.30.0/regression/p16f690/wdt_16f685.asm0000775000076400007640000000354713041763600015272 00000000000000 ;; 16F685 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=16f685 include "p16f685.inc" include .command macro x .direct "C", x endm cblock 0x40 temp tmp2 phase endc ORG 0 .sim "p16f685.BreakOnReset = false" .sim "break c 0x10000" .sim "p16f685.frequency=10000" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; My reading of the specs indicate sleep should continue (no reset) ; when the WDT goes off sleeps continue sleep nop .assert "(status & 0x18) == 0x00,\"*** FAILED 16f685 status after sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 16f685 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p16f685 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p16f685 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(status & 0x18) == 0x08,\"*** FAILED 16f685 status after WDT Reset\"" nop .assert "\"*** PASSED p16f685 WDT\"" goto $ end gpsim-0.30.0/regression/p16f690/eusart_690.asm0000644000076400007640000001554613057432455015463 00000000000000 ;; EUSART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly when configured as an EUSART. ;; The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=16f690 include include __CONFIG _WDT_OFF & _INTRC_OSC_NOCLKOUT errorlevel -302 radix dec BAUDHI equ ((40000/4)/48)-1 BAUDLO equ ((40000/16)/48)-1 ;BAUDLO equ 129 ;---------------------------------------------------------------------- ; RAM Declarations ; GPR_DATA UDATA_SHR #define RX_BUF_SIZE 0x10 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"*** FAILED 16F690 sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=10e6" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "U1.xpos = 84" .sim "U1.ypos = 276" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portb7 U1.RXPIN" .sim "attach PIC_rx portb5 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTB,7 ;Make sure the TX line drives high when ;it is programmed as an output. BANKSEL ANSELH bcf ANSELH,ANS11 BANKSEL TRISB bsf TRISB,5 ;RX is an input bsf TRISB,7 ;TX EUSART sets pin direction ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used BANKSEL TXSTA movlw (1< 9 bits ; and < 10 bits or between 1.87 and 2.08 msec. ; with oscillator at 4MHz and TMR0 / 64 expect between 27 and 32 ; TMR0 cycles. BANKSEL TMR0 movf TMR0,W .assert "tmr0 > 27 && tmr0 <= 32, \"*** FAILED P16F690 baud rate\"" nop clrf rxFlag call rx_loop ; Disable interrupts because the following tests don't give good receive bytes BANKSEL PIE1 bcf PIE1,RCIE BANKSEL TXSTA bsf TXSTA,SENB ; request a break sequence BANKSEL PORTB btfss PORTB,7 ; Shouldn't happen just yet .assert "\"*** FAILED 16F690 break sent too soon\"" nop clrf TMR0 movlw 0x55 movwf TXREG call delay btfsc PORTB,7 ; Should happen by now .assert "\"*** FAILED 16F690 to send break\"" nop btfss PORTB,7 ; Wait for stop bit goto $-1 ; ; At 4800 baud each bit takes 0.208 msec. Output will be low for ; start + 12 bit times or 2.70 msec. With 4Mhz TMR0 / 64 is 42 TMR0 counts. movf TMR0,W .assert "tmr0 > 37 && tmr0 < 43, \"*** FAILED 16F690 sync pulse\"" nop done: .assert "\"*** PASSED E-Usart on 16F690\"" goto $ tx_message: incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw 0x30 return delay: decfsz temp2,f goto delay return TransmitNextByte: BANKSEL TXREG clrf rxFlag call tx_message movwf TXREG rx_loop: btfss rxFlag,0 goto rx_loop ; clrf temp2 ; call delay ;; Delay between bytes. btfss PIR1,TXIF goto $-1 return end gpsim-0.30.0/regression/p16f690/16f631.lkr0000664000076400007640000000217613041763600014405 00000000000000// Sample linker command file for 16F677 LIBPATH . CODEPAGE NAME=page START=0x0 END=0x3FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=.calib START=0x2008 END=0x2008 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x217F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=gpr0 START=0x40 END=0x6F SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF PROTECTED SHAREBANK NAME=gprnobnk START=0x170 END=0x17F PROTECTED SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF PROTECTED SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CALIBR ROM=.calib // Calibration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/p16f690/p16f690.asm0000775000076400007640000005340413057614511014570 00000000000000 ;; Node test ;; ;; The purpose of this program is to verify that nodes ;; can interconnect I/O pins. list p=16f690 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CP_OFF & _WDT_ON & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _MCLRE_OFF ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm #define SDO_PORT PORTC,7 #define SDI_PORT PORTB,4 #define SCK_PORT PORTB,6 #define SS_PORT PORTC,6 #define SS_DRIVE PORTA,2 #define SDO_TRIS TRISC,7 #define SDI_TRIS TRISB,4 #define SCK_TRIS TRISB,6 #define SS_TRIS TRISC,6 #define SS_DRIVE_TRI TRISA,2 #define DRV_CLOCK PORTA,1 #define DRV_CLOCK_TRIS TRISA,1 radix dec BAUDHI equ ((80000/4)/48)-1 ;;BAUDLO equ 129 BAUDLO equ 103 radix hex ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 adc_cnt RES 1 rxFlag RES 1 rxLastByte RES 1 tx_ptr RES 1 temp2 RES 1 loopcnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup R1" .sim "R1.resistance = 10000.0" .sim "R1.voltage = 2.0" .sim "R1.xpos = 264" .sim "R1.ypos = 36" ; Use a pullup resistor as a voltage reference .sim "module load pullup R2" .sim "R2.resistance = 10000.0" .sim "R2.voltage = 2.5" .sim "R2.xpos = 252" .sim "R2.ypos = 96" .sim "module load not not" .sim "not.xpos=108." .sim "not.ypos=360." .sim "module load pu pu2" .sim "pu2.xpos = 96" .sim "pu2.ypos = 420" .sim "node n1" .sim "attach n1 porta2 porta3 portc6" .sim "node n2" .sim "attach n2 porta0 porta5 R1.pin" .sim "node n3" .sim "attach n3 porta1 porta4 portb6 R2.pin" .sim "node n4" ;; .sim ".frequency=10e6" .sim "break c 0x200000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "U1.xpos = 84" .sim "U1.ypos = 276" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portb7 U1.RXPIN" .sim "attach PIC_rx portb5 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" .sim "node sdo" .sim "attach sdo not.in0 portc7 pu2.pin" .sim "node sdi" .sim "attach sdi portb4 not.out" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W clrf STATUS movwf status_temp btfsc PIR2,C1IF goto cmif_int btfsc PIR1,RCIF goto rcif_int btfsc PIR1,TMR1IF goto tmr1_int btfsc PIR2,EEIF goto ee_int btfsc PIR1,ADIF goto adc_int btfsc INTCON,T0IF goto tmr0_int btfsc PIR1,TXIF goto txif_int .assert "\"***FAILED p16f690 unexpected interrupt\"" nop ; Interrupt from Comparator cmif_int incf cmif_cnt,F bcf PIR2,C1IF goto exit_int ; Interrupt from USART receive rcif_int .assert "rcreg == txreg, \"*** FAILED USART sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 goto exit_int ; Interrupt from USART transmitter txif_int goto exit_int ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from TMR1 tmr1_int incf tmr1_cnt,F bcf PIR1,TMR1IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR2,EEIF goto exit_int ; Interrupt from adc adc_int incf adc_cnt,F bcf PIR1,ADIF goto exit_int exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; BANKSEL VRCON ; bsf VRCON,VP6EN ; bsf VRCON,VRR ; bcf VRCON,VRR ; bsf VRCON,C1VREN ; .assert "p16f690.frequency == 4000000., \"FALIED 16f690 default frequency\"" nop BANKSEL OSCCON clrf OSCCON ; set 31 kHz .assert "(osccon & 6) == 2, \"FALIED 16f690 osccon just after h to l change\"" nop movlw 0x70 movwf OSCCON ; set 8 MHz .assert "(osccon & 6) == 0, \"FALIED 16f690 osccon just after l to h change\"" nop nop nop .assert "(osccon & 6) == 4, \"FALIED 16f690 osccon 1us after l to h change\"" nop .assert "p16f690.frequency == 8000000., \"FALIED 16f690 max internal oscilator frequency\"" nop ; test pins in analog mode return 0 on register read BANKSEL TRISA movlw 0xff movwf TRISA .assert "trisa == 0x3f, \"***FAILED 16f690 trisa 1 writable\"" nop clrf TRISA .assert "trisa == 0x08, \"***FAILED 16f690 trisa 0 writable\"" nop ; bcf OPTION_REG,NOT_RABPU ; enable pullups on portA BANKSEL PORTA movlw 0xff movwf PORTA .assert "(porta & 0x17) == 0, \"**FAILED 16f690 analog bits read 0\"" nop clrf PORTA movwf PORTA movf PORTA,W BANKSEL ANSEL clrf ANSEL ; turn off analog port selects clrf ANSELH ; ; test PORTA works as expected ; BANKSEL PORTA clrf PORTA BANKSEL TRISA movlw 0x38 movwf TRISA ;PORTA 0,1,2 output 3,4,5 input bcf STATUS,RP0 .assert "porta == 0x00, \"**FAILED 16f690 PORTA = 0x00\"" nop movlw 0x07 movwf PORTA ; drive 0,1,2 bits high .assert "porta == 0x3f, \"**FAILED 16f690 PORTA = 0x3f\"" nop movlw 0x0b movwf PORTA ; drive 0,1,3 bits high bsf STATUS,RP0 movlw 0x0b movwf TRISA ; PORTA 2, 4, 5 output 0,1,3 input (3 input only) bcf STATUS,RP0 .assert "porta == 0x00, \"**FAILED 16f690 PORTA = 0x00\"" nop movlw 0x34 movwf PORTA ; drive output 2, 4, 5 bits high .assert "porta == 0x3f, \"**FAILED 16f690 PORTA = 0x33\"" nop call test_compare call test_tmr1 call test_eerom call test_adc call test_eusart call test_ssp .assert "\"*** PASSED 16f690 Functionality\"" goto $ test_compare: BANKSEL TRISA movlw 0x33 movwf TRISA BANKSEL CM1CON0 movlw 0xff movwf CM2CON1 ; test writable bits movlw 0x03 movwf ANSEL ;Inputs analog .assert "cm2con1 == 0x03, \"*** FAILED 16f690 cm2con1 writable bits\"" nop clrf CM2CON1 bsf CM1CON0,C1POL ; toggle ouput polarity, not ON bsf CM1CON0,C1OE ; C1OUT t0 RA2 .assert "cm1con0 == 0x30, \"*** FAILED 16f690 cm1con0 off toggle\"" nop .assert "cm2con1 == 0x00, \"*** FAILED 16f690 cm2con1 mirror C1OUT\"" nop movlw (1< 9 bits and < 10 bits or between 1.875 and 2.083 msec. ; with oscillator at 8MHz and TMR0 / 64 expect between 58 and 65 ; TMR0 cycles. (time * 8000000) / (4 * 64) BANKSEL TMR0 movf TMR0,W .assert "tmr0 > 58 && tmr0 < 65, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop ; Disable interrupts because the following tests don't give good receive bytes BANKSEL PIE1 bcf PIE1,RCIE BANKSEL TXSTA bsf TXSTA,SENB ; request a break sequence BANKSEL PORTB btfss PORTB,7 ; Shouldn't happen just yet .assert "\"*** FAILED break sent too soon\"" nop clrf TMR0 movlw 0x55 movwf TXREG call delay btfsc PORTB,7 ; Should happen by now .assert "\"*** FAILED to send break\"" nop btfss PORTB,7 ; Wait for stop bit goto $-1 ; ; At 4800 baud each bit takes 0.208 msec. Output will be low for ; start + 12 bit times or 2.70 msec. With 8Mhz TMR0 / 64 is 84 TMR0 counts. ; 8Mhz * 0.00208 / (4 * 64) movf TMR0,W .assert "tmr0 > 80 && tmr0 < 88, \"*** FAILED sync pulse\"" nop return tx_message: incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw 0x30 return delay: decfsz temp2,f goto delay return TransmitNextByte: BANKSEL TXREG clrf rxFlag call tx_message movwf TXREG rx_loop: btfss rxFlag,0 goto rx_loop ; clrf temp2 ; call delay ;; Delay between bytes. btfss PIR1,TXIF goto $-1 return test_ssp: ;banksel WDTCON ;movlw 0x16 ;movwf WDTCON clrwdt banksel ANSEL clrf ANSEL clrf ANSELH banksel TRISA bcf SDO_TRIS ; SDO bcf SCK_TRIS ; SCK bcf OPTION_REG,NOT_RABPU movlw 0xff movwf SSPSTAT .assert "sspstat == 0xc0, \"SPI BSSP sspstat not writable\"" nop clrf SSPSTAT bcf STATUS,RP0 ; bank 0 ; ; Test SPI Master mode ; movlw 0x21 ; SSPEN | SPI master Fosc/16 movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF btfss PIR1,SSPIF goto $-1 .assert "(sspstat & 1) == 1, \"*** FAILED BSSP SPI Master BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"*** FAILED BSSP SPI Master BF not cleared\"" nop .assert "W == 0x54, \"*** FAILED BSSP SPI Master wrong data\"" nop ; ; TEST SPI Slave mode with SS ; clrf SSPCON bsf STATUS,RP0 ; bank 1 bcf DRV_CLOCK_TRIS ; external SCK drive bsf SCK_TRIS ; SCK bsf SS_TRIS ; SS bcf SS_DRIVE_TRI ; SS drive output bcf STATUS,RP0 ; bank 0 bcf SS_DRIVE ; drive SS low bcf DRV_CLOCK movlw 0x24 ; SSPEN | SPI slave mode SS enable movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF bsf DRV_CLOCK bcf DRV_CLOCK movwf SSPBUF ; test WCOL set .assert "(sspcon & 0x80) == 0x80, \"*** FAILED BSSP SPI WCOL set\"" nop bcf SSPCON,WCOL ; clear WCOL bit .assert "(sspcon & 0x80) == 0x00, \"*** FAILED BSSP SPI WCOL was cleared\"" nop clrf loopcnt loop2: incf loopcnt,F bsf DRV_CLOCK bcf DRV_CLOCK btfss PIR1,SSPIF goto loop2 movf SSPBUF,W .assert "W == 0x54, \"*** FAILED BSSP SPI Slave data\"" nop ; ; Test Slave receive overrun ; movlw 0x10 movwf loopcnt loop4: bsf DRV_CLOCK bcf DRV_CLOCK decfsz loopcnt,F goto loop4 .assert "(sspcon & 0x40) == 0x40, \"*** FAILED BSSP SPI SSPOV\"" nop ; ; Test SPI Master mode TMR2 ; clrf SSPCON bsf STATUS,RP0 ; bank 1 bsf DRV_CLOCK_TRIS ; external SCK drive off bcf SCK_TRIS ; SCK output movlw 0x1 movwf PR2 bcf STATUS,RP0 ; bank 0 clrf TMR2 movlw 0x3C ; prescale = 1 postscale 16 movwf T2CON movlw 0x23 ; SSPEN | SPI master TMR2 movwf SSPCON bcf PIR1,SSPIF movlw 0xab movwf SSPBUF loop3: btfss PIR1,SSPIF goto loop3 .assert "(sspstat & 1) == 1, \"*** FAILED BSSP SPI Master TMR2, BF not set\"" nop movf SSPBUF,W .assert "(sspstat & 1) == 0, \"*** FAILED BSSP SPI Master TMR2, BF not cleared\"" nop .assert "W == 0x54, \"*** FAILED BSSP SPI Master TMR2 wrong data\"" nop return end gpsim-0.30.0/regression/p16f690/epwm.asm0000775000076400007640000001647413116675476014550 00000000000000 list p=16f690 include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W clrf STATUS movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16F690 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc5\"" ; P1A .sim "scope.ch1 = \"portc4\"" ; P1B .sim "scope.ch2 = \"portc3\"" ; P1C .sim "scope.ch3 = \"portc2\"" ; P1D .sim "scope.ch4 = \"portb4\"" .sim "node na0" ; .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM .assert "\"*** PASSED 16f690 PWM test\"" nop goto $-0 pwm_shutdown BANKSEL CM1CON0 movlw (1< PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: banksel CCP1CON clrf CCP1CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 banksel ANSEL clrf ANSEL ; turn ports to digital clrf ANSELH banksel CCPR1L movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF banksel TRISC ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 5 ; P1A bcf TRISC,4 ; P1B bcf TRISC,3 ; P1C bcf TRISC,2 ; P1D clrf PIE1 ; Disable peripheral interrupts movlw 0x03 ; Port B pull-up Tmr0 internal clock prescaler 16 movwf OPTION_REG banksel PIR1 ; Bank0 clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/p16f690/wdt_16f677.asm0000664000076400007640000000354713041763600015270 00000000000000 ;; 16F677 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=16f677 include "p16f677.inc" include .command macro x .direct "C", x endm cblock 0x40 temp tmp2 phase endc ORG 0 .sim "p16f677.BreakOnReset = false" .sim "break c 0x10000" .sim "p16f677.frequency=10000" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; My reading of the specs indicate sleep should continue (no reset) ; when the WDT goes off sleeps continue sleep nop .assert "(status & 0x18) == 0x00,\"*** FAILED 16f677 status after sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 16f677 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p16f677 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p16f677 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(status & 0x18) == 0x08,\"*** FAILED 16f677 status after WDT Reset\"" nop .assert "\"*** PASSED p16f677 WDT\"" goto $ end gpsim-0.30.0/regression/assertions/0000775000076400007640000000000013117466027014305 500000000000000gpsim-0.30.0/regression/assertions/assertions.asm0000664000076400007640000000600313041763600017111 00000000000000;************************************************************************ ; ; Assertion test ; ;************************************************************************ list p=16f873 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG (_CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF) errorlevel -302 ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA var1 RES 1 var2 RES 1 var3 RES 1 failures RES 1 GLOBAL var1,var2,var3,failures GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; Create a script for controlling the simulation ; Any valid gpsim command can appear in the quotes (fixme - load???) ; When this file is loaded into gpsim, all of the commands are ; are collected. When the processor has been initialized, then ; the commands are played back. .sim "failures=1" ; Assume the test fails .sim "run" ; runs to the first assertion (that's designed to fail) .sim "failures=failures+1" .sim "run" ; runs to the second assertion .sim "failures=failures+1" .sim "run" .sim "failures" if 0 .sim "failures=42" ; gpasm should ignore this script command. endif clrf var1 clrf var2 clrf var3 ; var1 and var2 have just been cleared, so the following two ; assertions should fail. However the script controlling the ; this regression test expects this and will continue running .assert "var1!=0" nop .assert "var2==1" nop ; compound expression - this one shouldn't halt the simulation .assert "var2==0 || var1==0" nop ; failures has been set to 3 by the script. ; Let's set it back to 0. Note that if any of the ; assertions fail to behave as expected, then the ; value of failures (when the simulation does eventually ; stop) will be non-zero. movlw 3 xorwf failures,F done: ; If no expression is specified, then break unconditionally .assert "" goto done nop end gpsim-0.30.0/regression/assertions/Makefile0000664000076400007640000000034513041763600015660 00000000000000include ../make.regression SCRIPT = 16f873.lkr OBJECTS = assertions.o OUTPUT = assertions.hex all : $(OUTPUT) $(OUTPUT) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) assertions.o : assertions.asm gpsim-0.30.0/regression/assertions/16f873.lkr0000664000076400007640000000530413041763600015570 00000000000000//********************************************************************* // * // Software License Agreement * // * // The software supplied herewith by Microchip Technology * // Incorporated (the "Company") for its PICmicro® Microcontroller * // is intended and supplied to you, the Company’s customer, for use * // solely and exclusively on Microchip PICmicro Microcontroller * // products. The software is owned by the Company and/or its * // supplier, and is protected under applicable copyright laws. All * // rights are reserved. Any use in violation of the foregoing * // restrictions may subject the user to criminal sanctions under * // applicable laws, as well as to civil liability for the breach of * // the terms and conditions of this license. * // * // THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO * // WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, * // BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND * // FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE * // COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, * // INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * // * //********************************************************************* // File: 16f873.lkr // Linker Script file, modified // Date: 06/07/2000 // Modified 7/18/2000 -.RLF LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x70 PROTECTED CODEPAGE NAME=page0 START=0x71 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF PROTECTED CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x7F DATABANK NAME=gpr1 START=0xA0 END=0xFF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location gpsim-0.30.0/regression/p12f675/0000775000076400007640000000000013117466027013125 500000000000000gpsim-0.30.0/regression/p12f675/12f683.lkr0000664000076400007640000000145713041763600014410 00000000000000// Sample linker command file for 12F683 LIBPATH . CODEPAGE NAME=page START=0x0 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xBF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF PROTECTED SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/p12f675/12f675.lkr0000664000076400007640000000207713041763600014410 00000000000000// Sample linker command file for 12F675 LIBPATH . CODEPAGE NAME=page START=0x0 END=0x3FE CODEPAGE NAME=.oscval START=0x3FF END=0x3FF PROTECTED CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.icdinst START=0x2004 END=0x2004 PROTECTED CODEPAGE NAME=.mfgcode START=0x2005 END=0x2005 PROTECTED CODEPAGE NAME=.devid START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=.reserve START=0x2008 END=0x200F PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x217F PROTECTED DATABANK NAME=sfr0nobnk START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1nobnk START=0x80 END=0x9F PROTECTED SHAREBANK NAME=gpr0nobnk START=0x20 END=0x5F SHAREBANK NAME=gpr0nobnk START=0xA0 END=0xDF PROTECTED SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=OSCVAL ROM=.oscval // Oscillator Cal Value SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/p12f675/p12f675.asm0000664000076400007640000003204613041763600014557 00000000000000 ;; Node test ;; ;; The purpose of this program is to verify that nodes ;; can interconnect I/O pins. list p=12f675 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CP_OFF & _WDT_ON & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _BODEN_OFF & _MCLRE_OFF ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 adc_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup R1" .sim "R1.resistance = 10000.0" .sim "R1.voltage = 2.0" .sim "R1.xpos = 252" .sim "R1.ypos = 84" ; Use a pullup resistor as a voltage reference .sim "module load pullup R2" .sim "R2.resistance = 10000.0" .sim "R2.voltage = 4.0" .sim "R2.xpos = 252" .sim "R2.ypos = 120" .sim "node n1" .sim "attach n1 gpio2 gpio3" .sim "node n2" .sim "attach n2 gpio0 gpio5 R1.pin" .sim "node n3" .sim "attach n3 gpio1 gpio4 R2.pin" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W bcf STATUS,RP0 ; set bank 0 movwf status_temp btfsc PIR1,CMIF goto cmif_int btfsc PIR1,TMR1IF goto tmr1_int btfsc PIR1,EEIF goto ee_int btfsc PIR1,ADIF goto adc_int btfsc INTCON,T0IF goto tmr0_int .assert "\"***FAILED p12f675 unexpected interrupt\"" nop ; Interrupt from Comparator cmif_int incf cmif_cnt,F bcf PIR1,CMIF goto exit_int ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from TMR1 tmr1_int incf tmr1_cnt,F bcf PIR1,TMR1IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ; Interrupt from adc adc_int incf adc_cnt,F bcf PIR1,ADIF goto exit_int exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; ; test pins in analog mode return 0 on register read BANKSEL TRISIO clrf TRISIO BANKSEL GPIO movlw 0xff movwf GPIO .assert "gpio == 0x28, \"**FAILED 12f675 analog bits read 0\"" nop movf GPIO,W movlw 0xff movwf CMCON ; turn off Comparator .assert "cmcon == 0x1f, \"**FAILED 12f675 CMCON read 0 bits\"" nop BANKSEL ANSEL clrf ANSEL ; turn off ADC port selects BANKSEL GPIO ; ; test GPIO works as expected ; clrf GPIO bsf STATUS,RP0 movlw 0x38 movwf TRISIO ;GPIO 0,1,2 output 3,4,5 input bcf STATUS,RP0 .assert "gpio == 0x00, \"GPIO = 0x00\"" nop movlw 0x07 movwf GPIO ; drive 0,1,2 bits high .assert "gpio == 0x3f, \"GPIO = 0x3f\"" nop bsf STATUS,RP0 movlw 0x07 movwf TRISIO ; GPIO 4, 5 output 0,1,2,3 input (3 input only) bcf STATUS,RP0 .assert "gpio == 0x0c, \"GPIO = 0x0c\"" nop movlw 0x38 movwf GPIO ; drive output bits high .assert "gpio == 0x3f, \"GPIO = 0x3f\"" nop call test_compare call test_tmr1 call test_eerom call test_adc .assert "\"*** PASSED 12f675 Functionality\"" goto $ test_compare: ;; Comparator Tests ;; ;; Mode 1 (Comparator with Output) ;; CIN- > CIN+ COUT = 0 and gpio2 low unless CINV=1 ;; CIS has no effect on output ;; CIN- < CIN+ gives output ;; Mode 3 (Comparator with output and Vref) ;; CIN- high COUT = 0 ;; CІN- low COUT = 1 ;; CIS has no effect on COUT ;; Mode 5 (Mux input with output and Vref) ;; CIN- low, CIS = 0 COUT = 1 ;; CIN+ high (CIN- low) with CIS = 0 has no effect on COUT ;; CIN+ high, CIN- low, CIS 1 COUT = 0 ;; CIN+ low (CIN- high) CIS 1 COUT = 1 ;; CIN+ high (CIN- high) CIS 1 COUT = 0 ;; enable and catch interrupt when CINV set ; ; Test mode 1 Comparator with output ; bsf STATUS,RP0 movlw 0x03 movwf TRISIO ; GPIO 2, 4, 5 output 0,1,3 input (3 input only) bcf STATUS,RP0 movlw 0x20 movwf GPIO ; AN0 1 AN1 0 movlw 0x01 movwf CMCON .assert "cmcon == 1, \"*** FAILED 12f675 cmcon Comp mode 1 Cinv 0 v+ > v-\"" nop .assert "(gpio & 0x04) == 0, \"*** FAILED 12f675 gpio2 Comp mode 1 Cinv 0 v+ > v-\"" nop bsf CMCON,CINV ; Cinv = 1 .assert "cmcon == 0x51, \"*** FAILED 12f675 cmcon Comp mode 1 Cinv 1 v+ > v-\"" nop bsf CMCON,CIS ; CIS = 1 .assert "cmcon == 0x59, \"*** FAILED 12f675 cmcon Comp mode 1 Cinv 1 CIS 1 v+ > v-\"" nop .assert "(gpio & 0x04) == 0x04, \"*** FAILED 12f675 gpio2 Comp mode 1 Cinv 1 v+ > v-\"" nop movlw 0x01 movwf CMCON ; clear CINV and CIS movlw 0x10 movwf GPIO ; AN0 0 AN1 1 .assert "cmcon == 0x41, \"*** FAILED 12f675 Comp mode1 v+ < v-\"" nop .assert "(gpio & 0x04) == 0x04, \"*** FAILED 12f675 gpio2 Comp mode 1 Cinv 1 v+ < v-\"" nop bsf CMCON,CINV .assert "cmcon == 0x11, \"*** FAILED 12f675 cmcon Comp mode 1 Cinv 1 v+ < v-\"" nop .assert "(gpio & 0x04) == 0, \"*** FAILED 12f675 gpio2 Comp mode 1 Cinv 1 v+ < v-\"" nop nop ; ; Mode 3 internal reference with output ; BANKSEL VRCON bsf VRCON,VREN ; Voltage reference high range BANKSEL CMCON movlw 0x03 movwf CMCON .assert "cmcon == 0x03, \"*** FAILED 12f675 cmcon Comp mode 3 Cinv 0 AN1 5V\"" nop bcf GPIO,4 ; drive AN1 to low .assert "cmcon == 0x43, \"*** FAILED 12f675 cmcon Comp mode 3 Cinv 0 AN1 0V\"" nop bsf CMCON,CIS ; CIS should not change output .assert "cmcon == 0x4b, \"*** FAILED 12f675 cmcon Comp mode 3 Cinv 0 Cis 1 AN1 0V\"" nop ; ; test mode 5 - MUX input with Vref and Output ; movlw 0x05 movwf CMCON ; mode 5 and AN1 .assert "cmcon == 0x45, \"*** FAILED 12f675 cmcon Comp mode 5 CIS 0 AN0 0V AN1 0V\"" nop bsf GPIO,5 ; Drive AN0 high (AN1 low) .assert "cmcon == 0x45, \"*** FAILED 12f675 cmcon Comp mode 5 CIS 0 AN0 5V AN1 0V\"" nop bsf CMCON,CIS ; select AN0 (GPIO0) .assert "cmcon == 0x0d, \"*** FAILED 12f675 cmcon Comp mode 5 CIS 1 AN0 5V AN1 0V\"" nop movlw 0x10 ; Drive AN0 low AN1 High movwf GPIO .assert "cmcon == 0x4d, \"*** FAILED 12f675 cmcon Comp mode 5 CIS 1 AN0 0V AN1 5V\"" nop bsf GPIO,5 ; Drive AN0 high (AN1 high) .assert "cmcon == 0x0d, \"*** FAILED 12f675 cmcon Comp mode 5 CIS 1 AN0 5V AN1 5V\"" nop ; ; test comparator interupts ; bcf PIR1,CMIF BANKSEL PIE1 movlw (1 << GIE) | ( 1 << PEIE ) movwf INTCON bsf PIE1,CMIE BANKSEL CMCON bsf CMCON,CINV ; this should change output and cause interrupt cm_loop: movf cmif_cnt,W btfsc STATUS,Z goto cm_loop clrf INTCON movlw 0x07 ; turn off comparator movwf CMCON return test_tmr1: ;; Here are the tests performed: ;; ;; -- TMR1L and TMR1H can be read and written ;; -- TMR1 driven Fosc/4 with prescale of 8 and generates an interrupt ; Load TMR1H, TMR1L with 0x8000 CLRF TMR1L MOVLW 0x80 MOVWF TMR1H BCF PIR1,TMR1IF ;Clear any TMR1 pending interrupt BANKSEL PIE1 BSF PIE1,TMR1IE ;Enable TMR1 interrupts BANKSEL TMR1L BSF INTCON,PEIE ;Enable Peripheral interrupts BSF INTCON,GIE ;Enable Global interrupts ; TMR1 not running yet, TMR1H and TMR1L should be unchanged MOVF TMR1L,W ; test read .assert "W==0, \"*** FAILED 12f675 TMR1 test TMR1L read\"" nop MOVF TMR1H,W .assert "W==0x80, \"*** FAILED 12f675 TMR1 test TMR1H read\"" nop ; at 4Mhz prescale of 8 Fosc/4 should interrupt in 0.1 seconds movlw 0xcf movwf TMR1H movlw 0x2c movwf TMR1L MOVLW (1< ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CP_OFF & _WDT_ON & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _BODEN_OFF & _MCLRE_OFF ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 adc_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup R1" .sim "R1.resistance = 10000.0" .sim "R1.voltage = 2.0" .sim "R1.xpos = 252" .sim "R1.ypos = 84" ; Use a pullup resistor as a voltage reference .sim "module load pullup R2" .sim "R2.resistance = 10000.0" .sim "R2.voltage = 4.0" .sim "R2.xpos = 252" .sim "R2.ypos = 120" .sim "node n1" .sim "attach n1 gpio2 gpio3" .sim "node n2" .sim "attach n2 gpio0 gpio5 R1.pin" .sim "node n3" .sim "attach n3 gpio1 gpio4 R2.pin" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W bcf STATUS,RP0 ; set bank 0 movwf status_temp btfsc PIR1,CMIF goto cmif_int btfsc PIR1,TMR1IF goto tmr1_int btfsc PIR1,EEIF goto ee_int btfsc INTCON,T0IF goto tmr0_int .assert "\"***FAILED p12f629 unexpected interrupt\"" nop ; Interrupt from Comparator cmif_int incf cmif_cnt,F bcf PIR1,CMIF goto exit_int ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from TMR1 tmr1_int incf tmr1_cnt,F bcf PIR1,TMR1IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; ; test pins in analog mode return 0 on register read BANKSEL TRISIO clrf TRISIO BANKSEL GPIO movlw 0xff movwf GPIO .assert "gpio == 0x3c, \"**FAILED 12f629 analog bits read 0\"" nop movf GPIO,W movlw 0xff movwf CMCON ; turn off Comparator .assert "cmcon == 0x1f, \"**FAILED 12f629 CMCON read 0 bits\"" nop BANKSEL GPIO ; ; test GPIO works as expected ; clrf GPIO bsf STATUS,RP0 movlw 0x38 movwf TRISIO ;GPIO 0,1,2 output 3,4,5 input bcf STATUS,RP0 .assert "gpio == 0x00, \"GPIO = 0x00\"" nop movlw 0x07 movwf GPIO ; drive 0,1,2 bits high .assert "gpio == 0x3f, \"GPIO = 0x3f\"" nop bsf STATUS,RP0 movlw 0x07 movwf TRISIO ; GPIO 4, 5 output 0,1,2,3 input (3 input only) bcf STATUS,RP0 .assert "gpio == 0x0c, \"GPIO = 0x0c\"" nop movlw 0x38 movwf GPIO ; drive output bits high .assert "gpio == 0x3f, \"GPIO = 0x3f\"" nop call test_compare call test_tmr1 call test_eerom .assert "\"*** PASSED 12f629 Functionality\"" goto $ test_tmr1: ;; Here are the tests performed: ;; ;; -- TMR1L and TMR1H can be read and written ;; -- TMR1 driven Fosc/4 with prescale of 8 and generates an interrupt ; Load TMR1H, TMR1L with 0x8000 CLRF TMR1L MOVLW 0x80 MOVWF TMR1H BCF PIR1,TMR1IF ;Clear any TMR1 pending interrupt BANKSEL PIE1 BSF PIE1,TMR1IE ;Enable TMR1 interrupts BANKSEL TMR1L BSF INTCON,PEIE ;Enable Peripheral interrupts BSF INTCON,GIE ;Enable Global interrupts ; TMR1 not running yet, TMR1H and TMR1L should be unchanged MOVF TMR1L,W ; test read .assert "W==0, \"*** FAILED 12f629 TMR1 test TMR1L read\"" nop MOVF TMR1H,W .assert "W==0x80, \"*** FAILED 12f629 TMR1 test TMR1H read\"" nop ; at 4Mhz prescale of 8 Fosc/4 should interrupt in 0.1 seconds movlw 0xcf movwf TMR1H movlw 0x2c movwf TMR1L MOVLW (1< CIN+ COUT = 0 and gpio2 low unless CINV=1 ;; CIS has no effect on output ;; CIN- < CIN+ gives output ;; Mode 3 (Comparator with output and Vref) ;; CIN- high COUT = 0 ;; CІN- low COUT = 1 ;; CIS has no effect on COUT ;; Mode 5 (Mux input with output and Vref) ;; CIN- low, CIS = 0 COUT = 1 ;; CIN+ high (CIN- low) with CIS = 0 has no effect on COUT ;; CIN+ high, CIN- low, CIS 1 COUT = 0 ;; CIN+ low (CIN- high) CIS 1 COUT = 1 ;; CIN+ high (CIN- high) CIS 1 COUT = 0 ;; enable and catch interrupt when CINV set ; ; Test mode 1 Comparator with output ; bsf STATUS,RP0 movlw 0x03 movwf TRISIO ; GPIO 2, 4, 5 output 0,1,3 input (3 input only) bcf STATUS,RP0 movlw 0x20 movwf GPIO ; AN0 1 AN1 0 movlw 0x01 movwf CMCON .assert "cmcon == 1, \"*** FAILED 12f629 cmcon Comp mode 1 Cinv 0 v+ > v-\"" nop .assert "(gpio & 0x04) == 0, \"*** FAILED 12f629 gpio2 Comp mode 1 Cinv 0 v+ > v-\"" nop bsf CMCON,CINV ; Cinv = 1 .assert "cmcon == 0x51, \"*** FAILED 12f629 cmcon Comp mode 1 Cinv 1 v+ > v-\"" nop bsf CMCON,CIS ; CIS = 1 .assert "cmcon == 0x59, \"*** FAILED 12f629 cmcon Comp mode 1 Cinv 1 CIS 1 v+ > v-\"" nop .assert "(gpio & 0x04) == 0x04, \"*** FAILED 12f629 gpio2 Comp mode 1 Cinv 1 v+ > v-\"" nop movlw 0x01 movwf CMCON ; clear CINV and CIS movlw 0x10 movwf GPIO ; AN0 0 AN1 1 .assert "cmcon == 0x41, \"*** FAILED 12f629 Comp mode1 v+ < v-\"" nop .assert "(gpio & 0x04) == 0x04, \"*** FAILED 12f629 gpio2 Comp mode 1 Cinv 1 v+ < v-\"" nop bsf CMCON,CINV .assert "cmcon == 0x11, \"*** FAILED 12f629 cmcon Comp mode 1 Cinv 1 v+ < v-\"" nop .assert "(gpio & 0x04) == 0, \"*** FAILED 12f629 gpio2 Comp mode 1 Cinv 1 v+ < v-\"" nop nop ; ; Mode 3 internal reference with output ; BANKSEL VRCON bsf VRCON,VREN ; Voltage reference high range BANKSEL CMCON movlw 0x03 movwf CMCON .assert "cmcon == 0x03, \"*** FAILED 12f629 cmcon Comp mode 3 Cinv 0 AN1 5V\"" nop bcf GPIO,4 ; drive AN1 to low .assert "cmcon == 0x43, \"*** FAILED 12f629 cmcon Comp mode 3 Cinv 0 AN1 0V\"" nop bsf CMCON,CIS ; CIS should not change output .assert "cmcon == 0x4b, \"*** FAILED 12f629 cmcon Comp mode 3 Cinv 0 Cis 1 AN1 0V\"" nop ; ; test mode 5 - MUX input with Vref and Output ; movlw 0x05 movwf CMCON ; mode 5 and AN1 .assert "cmcon == 0x45, \"*** FAILED 12f629 cmcon Comp mode 5 CIS 0 AN0 0V AN1 0V\"" nop bsf GPIO,5 ; Drive AN0 high (AN1 low) .assert "cmcon == 0x45, \"*** FAILED 12f629 cmcon Comp mode 5 CIS 0 AN0 5V AN1 0V\"" nop bsf CMCON,CIS ; select AN0 (GPIO0) .assert "cmcon == 0x0d, \"*** FAILED 12f629 cmcon Comp mode 5 CIS 1 AN0 5V AN1 0V\"" nop movlw 0x10 ; Drive AN0 low AN1 High movwf GPIO .assert "cmcon == 0x4d, \"*** FAILED 12f629 cmcon Comp mode 5 CIS 1 AN0 0V AN1 5V\"" nop bsf GPIO,5 ; Drive AN0 high (AN1 high) .assert "cmcon == 0x0d, \"*** FAILED 12f629 cmcon Comp mode 5 CIS 1 AN0 5V AN1 5V\"" nop ; ; test comparator interupts ; bcf PIR1,CMIF BANKSEL PIE1 movlw (1 << GIE) | ( 1 << PEIE ) movwf INTCON bsf PIE1,CMIE BANKSEL CMCON bsf CMCON,CINV ; this should change output and cause interrupt cm_loop: movf cmif_cnt,W btfsc STATUS,Z goto cm_loop clrf INTCON movlw 0x07 ; turn off comparator movwf CMCON return test_eerom: ; ; test can write and read to all 128 eeprom locations ; using intterupts clrf adr_cnt clrf data_cnt ; setup interrupts bsf INTCON,PEIE bsf INTCON,GIE BANKSEL PIE1 bsf PIE1,EEIE BANKSEL PIR1 ; ; write to EEPROM starting at EEPROM address 0 ; value of address as data using interrupts to ; determine write complete. ; read and verify data l1: movf adr_cnt,W clrf eerom_cnt BANKSEL EEADR movwf EEADR movf data_cnt,W movwf EEDATA bcf INTCON,GIE ;Disable interrupts while enabling write bsf EECON1,WREN ;Enable eeprom writes movlw 0x55 ;Magic sequence to enable eeprom write movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR ;Begin eeprom write bsf INTCON,GIE ;Re-enable interrupts BANKSEL PIR1 clrf STATUS ; Bank 0 movf eerom_cnt,W skpnz goto $-2 ; ; read what we just wrote ; movf adr_cnt,W BANKSEL EEADR movwf EEADR bsf EECON1,RD ; start read operation movf EEDATA,W ; Read data BANKSEL PIR1 xorwf data_cnt,W ; did we read what we wrote ? skpz goto eefail incf adr_cnt,W andlw 0x7f movwf adr_cnt movwf data_cnt skpz goto l1 return eefail: .assert "\"***FAILED 12f629 eerom write/read error\"" nop test_tmr0: return end gpsim-0.30.0/regression/p12f675/p12f683.asm0000664000076400007640000003516613041763600014564 00000000000000 ;; Node test ;; ;; The purpose of this program is to verify that nodes ;; can interconnect I/O pins. list p=12f683 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _MCLRE_OFF #ifndef TMR1GE #define TMR1GE 6 #endif ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 cmif_cnt RES 1 tmr0_cnt RES 1 tmr1_cnt RES 1 tmr2_cnt RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 adc_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup R1" .sim "R1.resistance = 10000.0" .sim "R1.voltage = 2.0" .sim "R1.xpos = 252" .sim "R1.ypos = 84" ; Use a pullup resistor as a voltage reference .sim "module load pullup R2" .sim "R2.resistance = 10000.0" .sim "R2.voltage = 4.0" .sim "R2.xpos = 252" .sim "R2.ypos = 120" .sim "node n1" .sim "attach n1 gpio2 gpio3" .sim "node n2" .sim "attach n2 gpio0 gpio5 R1.pin" .sim "node n3" .sim "attach n3 gpio1 gpio4 R2.pin" ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W bcf STATUS,RP0 ; set bank 0 movwf status_temp btfsc PIR1,CMIF goto cmif_int btfsc PIR1,TMR1IF goto tmr1_int btfsc PIR1,TMR2IF goto tmr2_int btfsc PIR1,EEIF goto ee_int btfsc PIR1,ADIF goto adc_int btfsc INTCON,T0IF goto tmr0_int .assert "\"***FAILED p12f683 unexpected interrupt\"" nop ; Interrupt from Comparator cmif_int incf cmif_cnt,F bcf PIR1,CMIF goto exit_int ; Interrupt from TMR0 tmr0_int incf tmr0_cnt,F bcf INTCON,T0IF goto exit_int ; Interrupt from TMR1 tmr1_int incf tmr1_cnt,F bcf PIR1,TMR1IF goto exit_int ; Interrupt from TMR2 tmr2_int incf tmr2_cnt,F bcf PIR1,TMR2IF goto exit_int ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ; Interrupt from adc adc_int incf adc_cnt,F bcf PIR1,ADIF goto exit_int exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ; ; test pins in analog mode return 0 on register read BANKSEL TRISIO clrf TRISIO BANKSEL GPIO movlw 0xff movwf GPIO .assert "gpio == 0x28, \"**FAILED 12f683 analog bits read 0\"" nop movf GPIO,W movlw 0xff movwf CMCON0 ; turn off Comparator .assert "cmcon0 == 0x1f, \"**FAILED 12f683 CMCON0 read 0 bits\"" nop BANKSEL ANSEL clrf ANSEL ; turn off ADC port selects BANKSEL GPIO ; ; test GPIO works as expected ; clrf GPIO bsf STATUS,RP0 movlw 0x38 movwf TRISIO ;GPIO 0,1,2 output 3,4,5 input bcf STATUS,RP0 .assert "gpio == 0x00, \"GPIO = 0x00\"" nop movlw 0x07 movwf GPIO ; drive 0,1,2 bits high .assert "gpio == 0x3f, \"GPIO = 0x3f\"" nop bsf STATUS,RP0 movlw 0x07 movwf TRISIO ; GPIO 4, 5 output 0,1,2,3 input (3 input only) bcf STATUS,RP0 .assert "gpio == 0x0c, \"GPIO = 0x0c\"" nop movlw 0x38 movwf GPIO ; drive output bits high .assert "gpio == 0x3f, \"GPIO = 0x3f\"" nop call test_compare call test_tmr1 call test_tmr2 call test_eerom call test_adc .assert "\"*** PASSED 12f683 Functionality\"" goto $ test_compare: ;; Comparator Tests ;; ;; Mode 1 (Comparator with Output) ;; CIN- > CIN+ COUT = 0 and gpio2 low unless CINV=1 ;; CIS has no effect on output ;; CIN- < CIN+ gives output ;; Mode 3 (Comparator with output and Vref) ;; CIN- high COUT = 0 ;; CІN- low COUT = 1 ;; CIS has no effect on COUT ;; Mode 5 (Mux input with output and Vref) ;; CIN- low, CIS = 0 COUT = 1 ;; CIN+ high (CIN- low) with CIS = 0 has no effect on COUT ;; CIN+ high, CIN- low, CIS 1 COUT = 0 ;; CIN+ low (CIN- high) CIS 1 COUT = 1 ;; CIN+ high (CIN- high) CIS 1 COUT = 0 ;; enable and catch interrupt when CINV set ; ; Test mode 1 Comparator with output ; bsf STATUS,RP0 movlw 0x03 movwf TRISIO ; GPIO 2, 4, 5 output 0,1,3 input (3 input only) bcf STATUS,RP0 movlw 0x20 movwf GPIO ; AN0 1 AN1 0 movlw 0x01 movwf CMCON0 .assert "cmcon0 == 1, \"*** FAILED 12f683 cmcon0 Comp mode 1 Cinv 0 v+ > v-\"" nop .assert "(gpio & 0x04) == 0, \"*** FAILED 12f683 gpio2 Comp mode 1 Cinv 0 v+ > v-\"" nop bsf CMCON0,CINV ; Cinv = 1 .assert "cmcon0 == 0x51, \"*** FAILED 12f683 cmcon0 Comp mode 1 Cinv 1 v+ > v-\"" nop bsf CMCON0,CIS ; CIS = 1 .assert "cmcon0 == 0x59, \"*** FAILED 12f683 cmcon0 Comp mode 1 Cinv 1 CIS 1 v+ > v-\"" nop .assert "(gpio & 0x04) == 0x04, \"*** FAILED 12f683 gpio2 Comp mode 1 Cinv 1 v+ > v-\"" nop movlw 0x01 movwf CMCON0 ; clear CINV and CIS movlw 0x10 movwf GPIO ; AN0 0 AN1 1 .assert "cmcon0 == 0x41, \"*** FAILED 12f683 Comp mode1 v+ < v-\"" nop .assert "(gpio & 0x04) == 0x04, \"*** FAILED 12f683 gpio2 Comp mode 1 Cinv 1 v+ < v-\"" nop bsf CMCON0,CINV .assert "cmcon0 == 0x11, \"*** FAILED 12f683 cmcon0 Comp mode 1 Cinv 1 v+ < v-\"" nop .assert "(gpio & 0x04) == 0, \"*** FAILED 12f683 gpio2 Comp mode 1 Cinv 1 v+ < v-\"" nop nop ; ; Mode 3 internal reference with output ; BANKSEL VRCON bsf VRCON,VREN ; Voltage reference high range BANKSEL CMCON0 movlw 0x03 movwf CMCON0 .assert "cmcon0 == 0x03, \"*** FAILED 12f683 cmcon0 Comp mode 3 Cinv 0 AN1 5V\"" nop bcf GPIO,4 ; drive AN1 to low .assert "cmcon0 == 0x43, \"*** FAILED 12f683 cmcon0 Comp mode 3 Cinv 0 AN1 0V\"" nop bsf CMCON0,CIS ; CIS should not change output .assert "cmcon0 == 0x4b, \"*** FAILED 12f683 cmcon0 Comp mode 3 Cinv 0 Cis 1 AN1 0V\"" nop ; ; test mode 5 - MUX input with Vref and Output ; movlw 0x05 movwf CMCON0 ; mode 5 and AN1 .assert "cmcon0 == 0x45, \"*** FAILED 12f683 cmcon0 Comp mode 5 CIS 0 AN0 0V AN1 0V\"" nop bsf GPIO,5 ; Drive AN0 high (AN1 low) .assert "cmcon0 == 0x45, \"*** FAILED 12f683 cmcon0 Comp mode 5 CIS 0 AN0 5V AN1 0V\"" nop bsf CMCON0,CIS ; select AN0 (GPIO0) .assert "cmcon0 == 0x0d, \"*** FAILED 12f683 cmcon0 Comp mode 5 CIS 1 AN0 5V AN1 0V\"" nop movlw 0x10 ; Drive AN0 low AN1 High movwf GPIO .assert "cmcon0 == 0x4d, \"*** FAILED 12f683 cmcon0 Comp mode 5 CIS 1 AN0 0V AN1 5V\"" nop bsf GPIO,5 ; Drive AN0 high (AN1 high) .assert "cmcon0 == 0x0d, \"*** FAILED 12f683 cmcon0 Comp mode 5 CIS 1 AN0 5V AN1 5V\"" nop ; ; test comparator interupts ; bcf PIR1,CMIF BANKSEL PIE1 movlw (1 << GIE) | ( 1 << PEIE ) movwf INTCON bsf PIE1,CMIE BANKSEL CMCON0 bsf CMCON0,CINV ; this should change output and cause interrupt cm_loop: movf cmif_cnt,W btfsc STATUS,Z goto cm_loop nop ;RRR clrf INTCON movlw 0x07 ; turn off comparator movwf CMCON0 return test_tmr1: ;; Here are the tests performed: ;; ;; -- TMR1L and TMR1H can be read and written ;; -- TMR1 driven Fosc/4 with prescale of 8 and generates an interrupt ; Load TMR1H, TMR1L with 0x8000 CLRF TMR1L MOVLW 0x80 MOVWF TMR1H BCF PIR1,TMR1IF ;Clear any TMR1 pending interrupt BANKSEL PIE1 BSF PIE1,TMR1IE ;Enable TMR1 interrupts BANKSEL TMR1L BSF INTCON,PEIE ;Enable Peripheral interrupts BSF INTCON,GIE ;Enable Global interrupts ; TMR1 not running yet, TMR1H and TMR1L should be unchanged MOVF TMR1L,W ; test read .assert "W==0, \"*** FAILED 12f683 TMR1 test TMR1L read\"" nop MOVF TMR1H,W .assert "W==0x80, \"*** FAILED 12f683 TMR1 test TMR1H read\"" nop ; at 4Mhz prescale of 8 Fosc/4 should interrupt in 0.1 seconds movlw 0xcf movwf TMR1H movlw 0x2c movwf TMR1L MOVLW (1< $LOGFILE grep "PASSED" $LOGFILE if [ $? -ne 0 ] ; then echo "!!! FAILED $1/make $2" grep "FAILED" $LOGFILE fi gpsim-0.30.0/regression/usart_test/0000775000076400007640000000000013117466027014310 500000000000000gpsim-0.30.0/regression/usart_test/eusart_2455.asm0000664000076400007640000001537513041763600016720 00000000000000 ;; EUSART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly when configured as an EUSART. ;; The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=18f2455 include include CONFIG WDT=OFF ;; CONFIG MCLRE=ON CONFIG LPT1OSC=OFF CONFIG PBADEN=OFF CONFIG CCP2MX=ON, FOSC = INTOSCIO_EC ;; __CONFIG _CONFIG2H, _WDT_OFF_2H errorlevel -302 radix dec BAUDHI equ ((80000/4)/48)-1 ;;BAUDLO equ 129 BAUDLO equ 8000000/(4800*16)-1 ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x00 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x018 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"*** FAILED sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim ".xpos = 48" .sim ".ypos = 48" .sim "U1.xpos = 240.0" .sim "U1.ypos = 168" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. clrf TRISC ;RRR test bsf TRISC,6 ;RX is an input bsf TRISC,7 ;TX EUSART sets pin direction .assert "p18f2455.frequency == 1000000., \"FAILED 18f2455 default intrc frequency\"" nop movlw 0x70 movwf OSCCON .assert "p18f2455.frequency == 8000000., \"FAILED 18f2455 frequency osccon=070\"" nop ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 9 bits ; and < 10 bits or between 0.9375 and 1.041 msec. ; with oscillator at 8MHz and TMR0 / 64 expect between 58 and 65 ; TMR0 cycles. movf TMR0L,W .assert "tmr0 > 58 && tmr0 < 65, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop ; Disable interrupts because the following tests don't give good receive bytes bcf PIE1,RCIE bsf TXSTA,SENDB ; request a break sequence btfss PORTC,6 ; Shouldn't happen just yet .assert "\"*** FAILED break sent too soon\"" nop clrf TMR0L movlw 0x55 movwf TXREG rcall delay btfsc PORTC,6 ; Should happen by now .assert "\"*** FAILED to send break\"" nop btfss PORTC,6 ; Wait for stop bit bra $-2 ; ; At 4800 baud each bit takes 0.208 msec. Output will be low for ; start + 12 bit times or 2.70 msec. With 8Mhz TMR0 / 64 is 85 TMR0 counts. movf TMR0L,W .assert "tmr0 > 81 && tmr0 < 89, \"*** FAILED sync pulse\"" nop done: .assert "\"*** PASSED E-Usart on 18F2455\"" goto $ tx_message: incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw 0x30 return delay: decfsz temp2,f bra delay return TransmitNextByte: clrf rxFlag call tx_message btfss PIR1,TXIF bra $-2 movwf TXREG clrwdt rx_loop: btfss rxFlag,0 bra rx_loop return end gpsim-0.30.0/regression/usart_test/16f628.lkr0000664000076400007640000000250013041763600015564 00000000000000// Sample linker command file for 16F628 // $Id: 16f628.lkr 1828 2006-11-10 18:59:10Z borutr $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x217F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x11F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x19F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x120 END=0x14F SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/usart_test/Makefile0000664000076400007640000000156513041763600015670 00000000000000# USART module regression test # # include ../make.regression SCRIPT = 16f877.lkr PROJECT = usart_test OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : usart_pir1v1.cod usart_pir1v2.cod eusart.cod eusart_2455.cod sim: sim_pir1v1 sim_pir1v2 sim_eusart sim_eusart_2455 sim_pir1v1: usart_pir1v1.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_pir1v2: usart_pir1v2.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_eusart: eusart.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_eusart_2455: eusart_2455.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< usart_pir1v1.cod : usart_pir1v1.o gplink --map -s 16f628.lkr -o $@ $< usart_pir1v2.cod : usart_pir1v2.o gplink --map -s 16f877.lkr -o $@ $< eusart.cod : eusart.o gplink --map -s 18f2221.lkr -o $@ $< eusart_2455.cod : eusart_2455.o gplink --map -s 18f2455.lkr -o $@ $< gpsim-0.30.0/regression/usart_test/usart_pir1v1.asm0000664000076400007640000001407513041763600017272 00000000000000 ;; USART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly. The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=16f628 include include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x20 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 ;fsr_temp RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH bcf STATUS,RP0 btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=20e6" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" ; .sim "U1.xpos = 250.0" ; .sim "U1.ypos = 80.0" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portb2 U1.RXPIN" .sim "attach PIC_rx portb1 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 9600" .sim "U1.rxbaud = 9600" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTB,2 ;Make sure the TX line drives high when ;it is programmed as an output. bsf STATUS,RP0 ; select bank 0 ; bcf OPTION_REG,NOT_RBPU ; turn on B pullups bsf TRISB,1 ;RX is an input bcf TRISB,2 ;TX is an output ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 9 bits ; and < 10 bits or between 0.9375 and 1.041 msec. ; with oscillator at 20MHz and TMR0 / 64 expect between 73 and 81 ; TMR0 cycles. movf TMR0,W .assert "tmr0 > 73 && tmr0 < 81, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop done: .assert "\"*** PASSED Usart with PIR1V1\"" goto $ TransmitNextByte: clrf rxFlag call tx_message btfss PIR1,TXIF goto $-1 movwf TXREG rx_loop: btfss rxFlag,0 goto rx_loop return tx_message incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw TX_TABLE skpnc incf PCLATH,f movwf PCL TX_TABLE dt "0123456789ABCDEF",0 delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return end gpsim-0.30.0/regression/usart_test/eusart.asm0000664000076400007640000001461613041763600016236 00000000000000 ;; EUSART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly when configured as an EUSART. ;; The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=18f2221 include include CONFIG WDT=OFF CONFIG MCLRE=ON, LPT1OSC=OFF, PBADEN=DIG, CCP2MX=RC1 errorlevel -302 radix dec BAUDHI equ ((100000/4)/48)-1 BAUDLO equ 129 ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x00 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x018 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"*** FAILED sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=10e6" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" ; .sim "U1.xpos = 250.0" ; .sim "U1.ypos = 80.0" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. bsf TRISC,7 ;RX is an input bsf TRISC,6 ;TX EUSART sets pin direction ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 9 bits ; and < 10 bits or between 0.9375 and 1.041 msec. ; with oscillator at 20MHz and TMR0 / 64 expect between 73 and 81 ; TMR0 cycles. movf TMR0L,W .assert "tmr0 > 73 && tmr0 < 81, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop ; Disable interrupts because the following tests don't give good receive bytes bcf PIE1,RCIE bsf TXSTA,SENDB ; request a break sequence btfss PORTC,6 ; Shouldn't happen just yet .assert "\"*** FAILED break sent too soon\"" nop clrf TMR0L movlw 0x55 movwf TXREG rcall delay btfsc PORTC,6 ; Should happen by now .assert "\"*** FAILED to send break\"" nop btfss PORTC,6 ; Wait for stop bit bra $-2 ; ; At 4800 baud each bit takes 0.208 msec. Output will be low for ; start + 12 bit times or 2.70 msec. With 10Mhz TMR0 / 64 is 106 TMR0 counts. movf TMR0L,W .assert "tmr0 > 101 && tmr0 < 111, \"*** FAILED sync pulse\"" nop done: .assert "\"*** PASSED E-Usart on 18F2221\"" goto $ tx_message: incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw 0x30 return delay: decfsz temp2,f bra delay return TransmitNextByte: clrf rxFlag call tx_message btfss PIR1,TXIF bra $-1 movwf TXREG clrwdt rx_loop: btfss rxFlag,0 bra rx_loop return end gpsim-0.30.0/regression/usart_test/18f2455.lkr0000664000076400007640000000235013041763600015651 00000000000000// File: 18f2455.lkr // Sample linker script for the PIC18F2455 processor // Not intended for use with MPLAB C18. For C18 projects, // use the linker scripts provided with that product. LIBPATH . CODEPAGE NAME=page START=0x0 END=0x5FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x5F DATABANK NAME=gpr0 START=0x60 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=usb4 START=0x400 END=0x4FF PROTECTED DATABANK NAME=usb5 START=0x500 END=0x5FF PROTECTED DATABANK NAME=usb6 START=0x600 END=0x6FF PROTECTED DATABANK NAME=usb7 START=0x700 END=0x7FF PROTECTED ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED gpsim-0.30.0/regression/usart_test/usart_pir1v2.asm0000664000076400007640000001542513103735451017275 00000000000000 ;; USART test ;; ;; The purpose of this program is to verify that gpsim's ;; USART functions properly. The USART module is used to loop ;; characters back to the receiver testing RCIF interupts. ;; ;; ;; list p=16f877 include include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x20 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 ;fsr_temp RES 1 INT_VAR1 UDATA 0xA0 w_temp1 RES 1 ;Alias for w_temp at address 0x20 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rxLastByte RES 1 rxFlag RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH bcf STATUS,RP0 btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; Received a Character .assert "rcreg == txreg, \"sent character looped back\"" nop movf RCREG,W movwf rxLastByte bsf rxFlag,0 int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=10e6" .sim ".xpos = 48" .sim ".ypos = 36" .sim "break c 0x100000" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "U1.xpos = 240" .sim "U1.ypos = 204" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 4800" .sim "U1.rxbaud = 4800" .sim "U1.loop = true" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. bsf STATUS,RP0 bsf TRISC,7 ;RX is an input bcf TRISC,6 ;TX is an output ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 9 bits ; and < 10 bits or between 1.872 and 2.08 msec. ; with oscillator at 10MHz and TMR0 / 64 expect between 73 and 81 ; TMR0 cycles. Or 146 - 162 for 2 characters movf TMR0,W .assert "tmr0 > 146 && tmr0 < 162, \"*** FAILED baud rate\"" nop clrf rxFlag call rx_loop .assert "(pir1 & 0x10) == 0x10, \"*** FAILED TXIF low double send\"" nop done: .assert "\"*** PASSED Usart with PIR1V2\"" goto $ TransmitNextByte: clrf rxFlag call tx_message btfss PIR1,TXIF goto $-1 movwf TXREG rx_loop: btfss rxFlag,0 goto rx_loop return tx_message incf tx_ptr,w andlw 0x0f movwf tx_ptr addlw TX_TABLE skpnc incf PCLATH,f movwf PCL TX_TABLE dt "0123456789ABCDEF",0 delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return end gpsim-0.30.0/regression/usart_test/16f877.lkr0000664000076400007640000000330513041763600015576 00000000000000// Sample linker command file for 16F877 // $Id: 16f877.lkr 1250 2005-09-03 17:25:24Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=page2 START=0x1000 END=0x17FF CODEPAGE NAME=page3 START=0x1800 END=0x1FFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=PROG3 ROM=page2 // ROM code space - page2 SECTION NAME=PROG4 ROM=page3 // ROM code space - page3 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/usart_test/18f2221.lkr0000664000076400007640000000147713041763600015651 00000000000000// File: 18f2221.lkr // Sample linker script for the PIC18F2221 processor // Not intended for use with MPLAB C18. For C18 projects, // use the linker scripts provided with that product. LIBPATH . CODEPAGE NAME=page START=0x0 END=0xFFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED gpsim-0.30.0/regression/p16x71x/0000775000076400007640000000000013117466027013251 500000000000000gpsim-0.30.0/regression/p16x71x/Makefile0000664000076400007640000000040212636230133014615 00000000000000# P12f1822, P16F1823 processor regression tests # # include ../make.regression all : p16f716.cod p16c716.cod p16c712.cod pwm_712.cod pwm_f716.cod %.cod : %.o gplink --map -o $@ $< sim: sim_p16f716 sim_p16c716 sim_p16c712 sim_pwm_712 sim_pwm_f716 gpsim-0.30.0/regression/instructions_16bit/0000775000076400007640000000000013117466027015664 500000000000000gpsim-0.30.0/regression/instructions_16bit/18f452.lkr0000664000076400007640000000205213041763602017141 00000000000000// $Id: 18f452.lkr 2087 2010-03-29 20:37:10Z bdt-rob $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=page START=0x00 END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF DATABANK NAME=gpr2 START=0x200 END=0x2FF DATABANK NAME=gpr3 START=0x300 END=0x3FF DATABANK NAME=gpr4 START=0x400 END=0x4FF DATABANK NAME=gpr5 START=0x500 END=0x5FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config SECTION NAME=IDLOCS ROM=idlocs gpsim-0.30.0/regression/instructions_16bit/instructions_16bit.asm0000664000076400007640000004123313041763602022055 00000000000000 ;; it.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; a 16bit-core pic (like the 18cxxx family not the 17c family. ;; Nothing useful is performed - this program is only used to ;; debug gpsim. list p=18f452 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 GLOBAL done, temp ifndef __IDLOCS_START ; The following warning can be ignored the line is used where gpasm < 1.4.0 ; Warning[205] Found directive in column 1: "IDLOCS" IDLOCS CODE db "ID" else IDLOCS "ID" endif ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE clrf temp1 ;Assume clrf works... ; bra start failed1: ; a relatively local label bra failed start: ;; Perform some basic tests on some important instructions setc ;set the Carry flag skpc ;and verify that it happened bra failed1 bnc failed1 clrc ;Now try clearing the carry skpnc bra failed1 bc failed1 setz ;set the Zero flag skpz ;and verify that it happened bra failed1 bnz failed1 clrz ;Now try clearing it skpnz bra failed1 bz failed1 setdc ;set the Digit Carry flag skpdc ;and verify that it happened bra failed clrdc ;Now try clearing it skpndc bra failed setov ;set the Over Flow flag skpov ;and verify that it happened bra failed bnov failed1 clrov ;Now try clearing it skpnov bra failed bov failed1 setn ;set the negative flag skpn ;and verify that it happened bra failed bnn failed1 clrn ;Now try clearing it skpnn bra failed bn failed1 movlw 1 movwf temp movf temp,f bz failed1 movlw 0 movwf temp movf temp,f bnz failed1 clrf temp ;Clear a register bnz failed1 ;and verify that the Z bit is set movf temp,w ;Read the register that was just bnz failed1 ;and verify that the Z bit is set incf temp,w ;Now this should cause the Z bit to bz failed1 ;get cleared. movlw 0xff movwf temp incf temp,F bnz failed1 ;; ;; incfsz ;; movlw 0xff movwf temp movf temp,f ;Should clear Z incfsz temp,w bra failed bz failed1 ;incfsz shouldn't affect Z incfsz temp,f ;temp should now be zero bra failed incfsz temp,w ;the following inst. shouldn't be skipped skpnz ;Z should be clear from above. bra failed ;; ;; addwf test: ;; ;; The purpose of this test is to a) verify that the addwf instruction ;; adds correctly and b) that the appropriate status register bits are ;; set correctly. clrw clrf temp addwf temp,w ; 0+0 bc failed1 bnz failed1 skpndc bra failed movlw 1 ; 0+1 addwf temp,w bc failed1 bz failed1 bn failed1 bov failed1 skpndc bra failed movlw 8 ; 8+8 , test dc movwf temp addwf temp,w bc failed1 bz failed1 skpdc bra failed bn failed1 bov failed1 movlw 0x88 ; 0x88+0x88 movwf temp addwf temp,w bnc failed1 bz failed1 skpdc bra failed bn failed1 bnov failed1 movlw 0x80 ; 0x80+0x80 movwf temp addwf temp,w bnc failed1 bnz failed1 skpndc bra failed bn failed1 bnov failed1 clrw addwf temp,w ; 0x80+0 skpc skpnz bra failed skpndc bra failed skpnn skpov bra failed clrf temp addwf temp,w ; 0+0x80 skpc skpnz bra failed skpndc bra failed skpnn skpnov bra failed movlw 1 movwf temp movlw 0xff addwf temp,w skpc bra failed skpz bra failed skpdc bra failed clrc clrdc ;; ;; andwf test: ;; clrf temp movlw 1 andwf temp,f skpz bra failed skpc skpndc bra failed andwf temp,w skpz bra failed skpc skpndc bra failed movlw 1 movwf temp andwf temp,f skpnz bra failed skpc skpndc bra failed movlw 0xff andwf temp,f ;1 & 0xff should = 1 skpnz bra failed skpc skpndc bra failed movlw 0xff ;Now add 0xff to see if temp addwf temp,f ;really is 1. (should cause a carry) skpnz skpc bra failed ;; ;; decf ;; clrf temp decf temp,F ;0==>0xff skpc skpnz bra failed decf temp,F ;0xff==>0xfe skpnc skpnz bra failed incf temp,F skpc skpnz bra failed incf temp,F skpnc skpz bra failed ;; ;; iorwf ;; movlw 0 movwf temp iorwf temp,f skpz bra failed movlw 1 iorwf temp,f skpnz bra failed movlw 0xff addwf temp,f skpnz skpc bra failed ;; ;; rlcf ;; clrdc clrf temp clrc rlcf temp,w skpdc skpnc bra failed skpz bra failed setc rlcf temp,f skpdc skpnc bra failed skpnz bra failed movlw 0xff addwf temp,f skpnz skpc bra failed rlcf temp,f skpnc bra failed movlw 0x80 movwf temp rlcf temp,w skpc bra failed movwf temp addwf temp,w skpz bra failed ;; ;; rrcf ;; clrdc clrf temp clrc rrcf temp,w skpdc skpnc bra failed skpz bra failed setc rrcf temp,f skpdc skpnc bra failed skpnz bra failed movlw 0x80 addwf temp,f skpnz skpc bra failed rrcf temp,f skpnc bra failed movlw 1 movwf temp rrcf temp,w skpc bra failed movwf temp addwf temp,w skpz bra failed ;; ;; subwf test: ;; clrf WREG clrf temp subwf temp,w ; 0-0 skpc bra failed skpz bra failed skpdc bra failed movlw 1 ; 0-1 subwf temp,w skpnc bra failed skpnz bra failed skpndc bra failed movlw 0x10 ; 0x10-0x10 movwf temp subwf temp,w skpc bra failed skpz bra failed skpdc bra failed movlw 0x88 ; 0x88-0x88 movwf temp subwf temp,w skpc bra failed skpz bra failed skpdc bra failed clrf temp movlw 0x80 ; 0 - 0x80 subwf temp,f skpnc bra failed skpnz bra failed skpdc bra failed movlw 0 ; 0x80 - 0 subwf temp,w skpc bra failed skpnz bra failed skpdc bra failed movlw 1 ; 0x80 - 1 subwf temp,w skpc bra failed skpnz bra failed skpndc bra failed movlw 0x05 movwf temp ;; positive - positive => positive no overflow movlw 0x03 subwf temp,W bov failed2 ;; positive - positive => negative, no overflow movlw 0x07 subwf temp,W bov failed2 ;; positive - negative => positive, no overflow. movlw 0xff subwf temp,W bov failed2 ;; positive - negative => negative, overflow. movlw 0x81 subwf temp,W bnov failed2 movlw -0x05 movwf temp ;; negative - positive => positive, overflow movlw 0x7e subwf temp,W bnov failed2 ;; negative - positive => negative, no overflow movlw 0x02 subwf temp,W bov failed2 ;; negative - negative => positive, no overflow. movlw -0x07 subwf temp,W bov failed2 ;; negative - negative => negative, overflow. movlw -0x02 subwf temp,W bov failed2 ;; test subwfc movlw 0xf0 subwfb temp,W ;; temp=fb - W=f0 - B = W=a .assert "W == 0xa, \"*** FAILED subwfb fb - f0 - 1 = a\"" nop subwfb temp,F ;; temp=fb - W=a -0 = temp=f1 .assert "temp == 0xf1, \"*** FAILED subwfb fb - a - 0 = f1\"" nop clrc clrdc ;; ;; xorwf ;; clrf temp movlw 0xff xorwf temp,f skpc skpndc bra failed bz failed xorwf temp,f bnz failed xorwf temp,f incfsz temp,f bra failed ;; ;; swapf ;; movlw 0x0f movwf temp swapf temp,f xorwf temp,f incfsz temp,f bra failed ;; ;; daw ;; ; trivial case : 13+25=38, DAW makes no adjustment movlw 0x13 addlw 0x25 daw bc failed xorlw 0x38 bnz failed ; simple case : 28+39=67, DAW adjusts lower nibble only movlw 0x28 addlw 0x39 daw bc failed xorlw 0x67 bnz failed ; carry case : 84+39=123, DAW adjusts both nibbles and sets carry movlw 0x84 addlw 0x39 daw bnc failed xorlw 0x23 bnz failed ; corner case : 96+84=180, DAW adjusts both nibbles but must leave existing carry set movlw 0x96 addlw 0x84 daw bnc failed ; this used to fail xorlw 0x80 bnz failed if 0 ; subtract case : 47-19=28, DAW adjusts lower nibble only ; Not sure the real PIC works here - the data sheet says "addition" movlw 0x19 sublw 0x47 daw bnc failed xorlw 0x28 bnz failed endif ;; clrf temp negf temp bnz failed incf temp,f negf temp bz failed incfsz temp,f bra failed goto BranchTest failed2: ; interim label for tests above bra failed BranchTest: call CallTest bra MultiWordInstructions CallTest return MultiWordInstructions: movlw 0xa5 movwf temp1 movff WREG,temp2 xorwf temp2,W bnz failed ;; LFSR LFSR 0,temp1 MOVF INDF0,W xorwf INDF0,W bnz failed TableRead: ; get a pointer to the start of the table area clrf TBLPTRU movlw LOW(TableDATA) movwf TBLPTRL movlw HIGH(TableDATA) movwf TBLPTRH ; read the table and test the autoinc and autodec. tblrd *+ movlw 0x11 rcall TestTablat tblrd * movlw 0x22 rcall TestTablat tblrd *+ movlw 0x22 rcall TestTablat tblrd *- movlw 0x33 rcall TestTablat tblrd * movlw 0x22 rcall TestTablat tblrd +* movlw 0x33 rcall TestTablat clrf TBLPTRH setf TBLPTRL tblrd *+ movlw 1 cpfseq TBLPTRH .assert "\"FAILED tblrd increment over boundary\"" bra failed tblrd *- movlw 0 cpfseq TBLPTRH .assert "\"FAILED tblrd decrement over boundary\"" bra failed clrf TBLPTRL tblrd *- movlw 0xFF cpfseq TBLPTRH .assert "\"FAILED tblrd decrement over boundary\"" bra failed tblrd +* movlw 0 cpfseq TBLPTRH .assert "\"FAILED tblrd increment over boundary\"" bra failed ; Now a quick check of an ID location movlw 0x20 movwf TBLPTRU clrf TBLPTRH clrf TBLPTRL tblrd *+ movlw 0x49 rcall TestTablat tblrd * movlw 0x44 rcall TestTablat bra TableReadEnd TableDATA: db 0x11,0x22,0x33,0x44 TestTablat: cpfseq TABLAT .assert "\"FAILED tblrd indexing / value\"" bra failed return TableReadEnd: ; ; Now test 16-bit core SFRs (which should be done in an SFR test but there isn't one) ; movlw 0xFF movwf PCLATH .assert "pclath == 0xFF, \"*** FAILED 16-bit PCLATH masking\"" nop clrf PCLATH movlb 5 .assert "bsr == 5, \"*** FAILED movlb\"" nop done: .assert "\"*** PASSED 16bit-core instruction test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED 16bit-core instruction test\"" bra done if 0 ;; ;; Test indirect branching ;; test_pcl: clrf temp clrf temp1 tt1: movf temp,w call table_test xorwf temp,w skpz bsf temp1,0 incf temp,f btfss temp,4 goto tt1 goto test_pcl2 table_test: addwf PCL,f table: retlw 0 retlw 1 retlw 2 retlw 3 retlw 4 retlw 5 retlw 6 retlw 7 retlw 8 retlw 9 retlw 10 retlw 11 retlw 12 retlw 13 retlw 14 retlw 15 test_pcl2: btfsc temp2,0 goto test_pcl3 movlw 0x20 movwf FSR0L clrf FSR0H next clrf INDF0 incf FSR0L,1 btfss FSR0L,4 goto next bsf temp2,0 clrf PCL test_pcl3: movlw ly movwf PCL ; == goto ly lx goto test_pcl4 ly movlw lx movwf PCL test_pcl4: goto $ endif end gpsim-0.30.0/regression/instructions_16bit/Makefile0000664000076400007640000000052013041763602017234 00000000000000include ../make.regression SCRIPT = 18f452.lkr PROJECT = instructions_16bit OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/instructions_16bit/instructions_16bit.stc0000664000076400007640000000010713041763602022061 00000000000000# simple script to load the simulation load s instructions_16bit.cod gpsim-0.30.0/regression/make.regression0000664000076400007640000000162213041763577015061 00000000000000# Top-level make file included by all of the regression test makefiles ifdef GPSIM_PATH PATH := $(GPSIM_PATH):$(PATH) else PATH := ../../gpsim:$(PATH) endif ifdef EXTENDED_INSTRUCTIONS ASM_FLAGS = -c --extended else ASM_FLAGS = -c endif # The gpsim startup configuration script is loaded # at the invocation of each regression test. STARTUP_STC=../startup.stc GPSIM = gpsim %.o : %.asm gpasm $(ASM_FLAGS) $< # this rule will expands the sim_% target # for example, in the a2d regression test there are # several tests that have targets of the form 'sim_p16f88' # This rule will make that target depend on p16f88.cod # (which in turn has a dependency on p16f88.asm) and will # invoke the simulator sim_%: %.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC="$<" %.-: %.cod $(GPSIM) -s $< # Each regression test has a target 'all' top: all clean: rm -f *~ *.o *.lst *.map *.hex *.cod *.log startup.stc gpsim-0.30.0/regression/digital_stim/0000775000076400007640000000000013117466027014564 500000000000000gpsim-0.30.0/regression/digital_stim/16f84.lkr0000664000076400007640000000160413041763600015760 00000000000000// Sample linker command file for 16F84 // $Id: 16f84.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page START=0x5 END=0x3FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x213F PROTECTED DATABANK NAME=sfr0 START=0x0 END=0xB PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x8B PROTECTED DATABANK NAME=gprs START=0xC END=0x4F SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/digital_stim/Makefile0000664000076400007640000000051113041763600016132 00000000000000include ../make.regression SCRIPT = 16f84.lkr PROJECT = digital_stim OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/digital_stim/digital_stim.asm0000664000076400007640000000466413041763600017662 00000000000000 radix dec ;; The purpose of this regression test is to test ;; digital stimuli. ;; It also tests portb0 will cause interrupt on leading edge during ;; sleep. list p=16f84 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _WDT_ON ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 w_temp RES 1 status_temp RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program Interupt_vector CODE 0x004 goto interrupt ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf failures clrf temp1 ; a counter clrf temp2 ; a flag keeping track of the state of port b begin: ;; Count the rising edges on portb bit 0 movf PORTB,W xorwf temp2,w xorwf temp2,f andwf temp2,w andlw 1 skpz incf temp1,f btfss PORTB,1 goto begin movf temp1,W #define EXPECTED_PULSES .20 xorlw EXPECTED_PULSES skpz .assert "\"*** FAILED digital stimulus test\"" incf failures,F ; test interrupt movlw 0x90 movwf INTCON sleep clrf INTCON done: .assert "\"*** PASSED digital stimulus test\"" goto done interrupt movwf w_temp movf INTCON,W .assert "(portb & 1) == 1, \"*** FAILED digital stimulus test-interrupt not on rising edge\"" nop movlw 0x90 movwf INTCON swapf w_temp,F swapf w_temp,W retfie end gpsim-0.30.0/regression/digital_stim/digital_stim.stc0000664000076400007640000000234713041763600017667 00000000000000load digital_stim.cod # Digital Stimulus Test # # Two stimuli are created. One puts out a stream of # pulses and the other a single step. The firmware # will count the pulses until it sees the step. # echo Digital Stimulus test ############################################################ # define a stimulus to generate two pulses every 1000 # cycles stimulus asynchronous_stimulus # The initial state AND the state the stimulus is when # it rolls over initial_state 0 # all times are with respect to the cpu's cycle counter start_cycle 0 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 1000 { 100, 1, 200, 0, 300, 1, 400, 0 } # Give the stimulus a name: name two_pulse_repeat end ############################################################ # define a stimulus that generates a step function # stimulus asynchronous_stimulus initial_state 0 # all times are with respect to the cpu's cycle counter start_cycle 0 { 10000, 1 } # Give the stimulus a name: name step_function end # Create the nodes node pulse_node node step_node # attach the stimuli to the I/O pins attach pulse_node two_pulse_repeat portb0 attach step_node step_function portb1 gpsim-0.30.0/regression/p16f684/0000775000076400007640000000000013117466027013131 500000000000000gpsim-0.30.0/regression/p16f684/reset.asm0000664000076400007640000002015513041763603014674 00000000000000 ; 16f684 gpsim regression test ; ; The purpose of this test is to verify that the 16f684 ; is implemented correctly. Here's a list of specific things ; tested: ; ; 1) Power On Reset ; 2) WDT during sleep ; 3) WDT during execution ; 4) Interrupt on PIN change during sleep ; 5) MCLR during sleep ; 6) MCLR during execution list p=16f684 include include __CONFIG _WDT_ON & _MCLRE_ON radix dec ; Printf Command .command macro x .direct "C", x endm GPR_DATA UDATA_SHR ResetSequence RES 1 optionShadow RES 1 aint_cnt RES 1 w_temp RES 1 status_temp RES 1 GLOBAL optionShadow, ResetSequence, aint_cnt ; Define the reset conditions to be checked. eRSTSequence_PowerOnReset equ 1 eRSTSequence_AwakeMCLR equ 2 eRSTSequence_AwakeWDT equ 3 eRSTSequence_AwakeIO equ 4 eRSTSequence_WDTTimeOut equ 5 ;---------------------------------------------------------------------- ; ********************* Reset Vector LOCATION *************************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program NT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc INTCON,RAIF goto raif_int .assert "\"***FAILED p16f684 unexpected interrupt\"" nop exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ; Interrupt from porta state change raif_int incf aint_cnt,F bcf INTCON,RAIF .assert "(intcon & 1) == 1, \"***FAILED p16f684 RAIF not cleared on mismatch\"" nop movf PORTA,W ; reading ports should clear mismatch bcf INTCON,RAIF .assert "(intcon & 1) == 0, \"***FAILED p16f684 RAIF clear on read porta\"" nop goto exit_int ;############################################################ ;# Create a stimulus to simulate a switch ; .sim "module lib libgpsim_modules" .sim "p16f684.xpos = 72" .sim "p16f684.ypos = 72" .sim "module load pulsegen PG1" .sim "PG1.clear = 0" .sim "PG1.period = 0" .sim "PG1.set = 1" .sim "PG1.xpos = 228" .sim "PG1.ypos = 84" .sim "module load pulsegen MCLRE" .sim "MCLRE.clear = 0" .sim "MCLRE.period = 0" .sim "MCLRE.set = 1" .sim "MCLRE.xpos = 84" .sim "MCLRE.ypos = 204" .sim "MCLRE.initial = 5.0" ;############################################################ .sim "node nSwitch" .sim "attach nSwitch porta0 PG1.pin" .sim "node nMCLR" .sim "attach nMCLR MCLR MCLRE.pin" ;############################################################ .sim "symbol resetCounter=1" ; NOT_GPWU = 0 - Enable wakeup if I/O pins 0,1, or 3 change states ; NOT_GPPU = 1 - Disable weak pullups on I/O pins 0,1, and 3 ; TOCS = 0 - Let the clock source for TMR0 be the internal fosc/4 ; TOSE = 0 - don't care - TMR0 source edge. ; PSA = 1 - assign Prescale to the WDT ; PS2:0 = 000 - prescale = 2^0=1 .sim "optionShadow=8" ; PSA=1 .sim "ResetSequence=0" .sim ".BreakOnReset = false" ; Set a cycle break point far in the future in case the resets fail. .sim "break c 0x1000000" bSWITCH equ 0 start .assert "option_reg==0xff, \"*** FAILED p16f684 resets, option 0xff on reset\"" nop .assert "trisa==0x3f, \"*** FAILED p16f684 resets, trisa 0x3f on reset\"" nop ;RRR MOVWF OSCCAL ; put calibration into oscillator cal reg ; PORTA setup ; If this is a PowerOn reset, then the state of the PORTA output register ; is unknown. If this is not a PowerOn reset then the PORTA pins have ; the same state they had prior to the reset. ; ; TRIS register setup - The I/O pins are always configured as Inputs after ; any reset. MOVF optionShadow,W ;optionShadow is initialized by the gpsim script BANKSEL TRISA MOVWF OPTION_REG MOVLW 1< /MCLR while sleeping goto PowerOnReset ;/TO=1, /PD=1 ==> Power has just been applied TO_is_low BTFSS STATUS,NOT_PD goto AwakeWDT ;/TO=0, /PD=0 ==> WDT while sleeping goto WDTTimeOut ;/TO=0, /PD=1 ==> WDT while not sleeping ;======================================================================== ; ; PowerOnReset ; ;======================================================================== PowerOnReset: movf ResetSequence,W XORLW eRSTSequence_AwakeMCLR skpnz goto done .assert "resetCounter==1,\"*** FAILED Power On Reset\"" nop MOVLW eRSTSequence_PowerOnReset MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop SLEEP nop ;======================================================================== ; ; AwakeWDT - WDT timed out while we were sleeping. ; ;======================================================================== AwakeWDT: MOVLW eRSTSequence_AwakeWDT .assert "resetCounter==2,\"*** FAILED WDT Reset\"" nop MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT ; loop until WDT times out here: goto here ;======================================================================== ; ; WDTTimeOut - WatchDog timer timed out while we were awake. ; ;======================================================================== WDTTimeOut: .assert "resetCounter==3,\"*** FAILED WDT timeout\"" nop MOVLW eRSTSequence_WDTTimeOut MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT .command "PG1.clear = cycles+100" nop CLRF aint_cnt SLEEP nop ;======================================================================== ; ; AwakeIO - an I/O pin changed state when in analog mode ; This should not wakeup from sleep (continue with WDT wakeup) ; ;======================================================================== .assert "aint_cnt==0, \"*** FAILED Wakeup on analog pin change\"" nop BANKSEL ANSEL CLRF ANSEL ; turn off ADC BANKSEL PORTA CLRF aint_cnt ; we may get an interrupt on this change .command "PG1.set = cycles+100" nop SLEEP nop ;======================================================================== ; ; AwakeIO - an I/O pin changed states to awaken us from sleep. ; ;======================================================================== AwakeIO: .assert "aint_cnt==1, \"*** FAILED No Wakeup on I/O pin change\"" nop MOVLW eRSTSequence_AwakeIO .assert "resetCounter==4,\"*** FAILED Unexpected Wakeup on I/O pin change\"" nop MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT ; reset the processor by driving /MCLR low for a few cycles .command "MCLRE.clear = cycles+100" .command "MCLRE.set = cycles+110" nop SLEEP nop .assert "\"*** FAILED Unexpected Wakeup waiting for MCLR\"" nop ;======================================================================== ; ; AwakeMCLR - MCLR went low while we were sleeping. ; ;======================================================================== AwakeMCLR: MOVLW eRSTSequence_AwakeMCLR .assert "resetCounter==5,\"*** FAILED /MCLR Reset\"" nop MOVWF ResetSequence .command "resetCounter = resetCounter+1" nop CLRWDT ; reset the processor by driving /MCLR low for a few cycles .command "MCLRE.clear = cycles+100" .command "MCLRE.set = cycles+110" nop waitForMCLR: goto waitForMCLR .assert "\"*** PASSED 16f684 Sleep and Reset test\"" done: goto done end gpsim-0.30.0/regression/p16f684/16f684.lkr0000664000076400007640000000244413041763603014421 00000000000000// Sample linker command file for 16F684 LIBPATH . CODEPAGE NAME=page START=0x0 END=0x7FF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=icd_inst START=0x2004 END=0x2004 PROTECTED CODEPAGE NAME=mfg_code START=0x2005 END=0x2005 PROTECTED CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=.calib START=0x2008 END=0x2008 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xBF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF PROTECTED SECTION NAME=PROG ROM=page // ROM code space SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=ICD_INST ROM=icd_inst // ICD instruction SECTION NAME=MFG_CODE ROM=mfg_code // Manufacturing code SECTION NAME=DEVICEID ROM=.device_id // Device ID SECTION NAME=CALIBR ROM=.config // Calibration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/p16f684/Makefile0000664000076400007640000000232513041763603014507 00000000000000 include ../make.regression # # Use 16f684.lkr for all processors in this family # SCRIPT = 16f684.lkr all : nwdt_16f684.cod compar_684.cod wdt_16f684.cod epwm.cod a2d_684.cod reset.cod # wdt_16f685.cod eusart.cod nwdt_16f684.cod: nwdt_16f684.o $(SCRIPT) gplink --map -s $(SCRIPT) -o nwdt_16f684.cod nwdt_16f684.o wdt_16f684.cod: wdt_16f684.o $(SCRIPT) gplink --map -s $(SCRIPT) -o wdt_16f684.cod wdt_16f684.o a2d_684.cod: a2d_684.o $(SCRIPT) gplink --map -s $(SCRIPT) -o a2d_684.cod a2d_684.o compar_684.cod: compar_684.o $(SCRIPT) gplink --map -s $(SCRIPT) -o compar_684.cod compar_684.o epwm.cod: epwm.o $(SCRIPT) gplink --map -s $(SCRIPT) -o epwm.cod epwm.o reset.cod: reset.o $(SCRIPT) gplink --map -s $(SCRIPT) -o reset.cod reset.o sim: sim_epwm sim_nwdt_16f684 \ sim_wdt_16f684 sim_reset sim_compar_684 sim_epwm: epwm.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_reset: reset.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_compar_684: compar_684.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_nwdt_16f684: nwdt_16f684.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< sim_wdt_16f684: wdt_16f684.cod $(GPSIM) -i -I $(STARTUP_STC) -D STC=$< gpsim-0.30.0/regression/p16f684/compar_684.asm0000664000076400007640000002317413041763602015437 00000000000000 ;; Comparator test ;; ;; The purpose of this program is to verify the ;; comparator module of the processor list p=16f684 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros __CONFIG _EXTRC_OSC_NOCLKOUT ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm CMODE0 EQU H'0000' CMODE1 EQU H'0001' CMODE2 EQU H'0002' CMODE3 EQU H'0003' CMODE4 EQU H'0004' CMODE5 EQU H'0005' CMODE6 EQU H'0006' CMODE7 EQU H'0007' ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR temp RES 1 w_temp RES 1 status_temp RES 1 GLOBAL done1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc PIR1,C1IF goto icm1 goto exit_int icm1: bcf PIR1,C1IF goto done1 exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .sim "module library libgpsim_modules" .sim "p16f684.xpos = 60" .sim "p16f684.ypos = 84" .sim "module load pullup C1P" .sim "C1P.capacitance = 0" .sim "C1P.resistance = 10000" .sim "C1P.voltage = 1" .sim "C1P.xpos = 72" .sim "C1P.ypos = 24" .sim "module load pullup C1N" .sim "C1N.capacitance = 0" .sim "C1N.resistance = 10000" .sim "C1N.voltage = 2.5" .sim "C1N.xpos = 228" .sim "C1N.ypos = 36" .sim "module load pullup C2P" .sim "C2P.capacitance = 0" .sim "C2P.resistance = 10000" .sim "C2P.voltage = 2.8" .sim "C2P.xpos = 252" .sim "C2P.ypos = 96" .sim "module load pullup C2N" .sim "C2N.capacitance = 0" .sim "C2N.resistance = 10000" .sim "C2N.voltage = 2" .sim "C2N.xpos = 228" .sim "C2N.ypos = 144" .sim "node c1p" .sim "attach c1p C1P.pin porta0" .sim "node c1n" .sim "attach c1n C1N.pin porta1" .sim "node c2p" .sim "attach c2p C2P.pin portc0" .sim "node c2n" .sim "attach c2n C2N.pin portc1" .assert "cmcon0 == 0x00, \"FAILED 16f684 CMCON0 POR\"" ; Rest value nop BANKSEL PIR1 clrf PIR1 movlw CMODE7 ; turn off comparator movwf CMCON0 BANKSEL ANSEL clrf ANSEL movlw 0x0f ; RA3-RA0 are inputs movwf TRISA movlw 0xAB ; enable Vref 11 low range 2.29v movwf VRCON ; ; test mode 2 - Four Inputs muxed to two comparators with Vref ; movlw CMODE2 ; Comparator mux reference BANKSEL CMCON0 ; C1IN- = 2.5 + = 2.29 out = 0 ; C2IN- = 2.0 + = 2.29 out = 1 movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m2 C1OUT=0 C2OUT=1\"" nop .assert "(pir1 & 0x18) == 0x10, \"FAILED 16f684 C1if=0 C2IF=1\"" nop clrf PIR1 movlw 0x8B ; enable Vref 11 high range 2.92v BANKSEL VRCON movwf VRCON ; C1IN- = 2.5 + = 2.92 out = 1 ; C2IN- = 2.0 + = 2.92 out = 1 .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m2 C1OUT=1 C2OUT=1\"" nop bcf OPTION_REG,T0CS ; Timer not from RA4 movlw 0x03 movwf TRISC BCF STATUS,RP0 ; Select bank 0 .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m2 C1OUT=1 C2OUT=1\"" nop .assert "(pir1 & 0x18) == 0x08, \"FAILED 16f684 C1IF=1 C2IF=0\"" nop bcf PIR1,C1IF .assert "(pir1 & 0x18) == 0x00, \"FAILED 16f684 C1IF=0 C2IF=0\"" nop .command "C1N.voltage = 3.0" ; drive comp1 low (C1IN- > Vref) nop .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m2 C1OUT=0 C2OUT=1\"" nop .assert "(pir1 & 0x18) == 0x08, \"FAILED 16f684 C1IF=1\"" nop bcf PIR1,C1IF bsf CMCON0,C1INV ; invert output bsf CMCON0,C2INV .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f684 m2 invert C1OUT=1 C2OUT=0\"" nop .assert "(pir1 & 0x18) == 0x18, \"FAILED 16f684 C1IF=1\"" nop bcf PIR1,C1IF bcf PIR1,C2IF .command "C2N.voltage = 3.5" ; C2IN- > Vref nop .command "C1N.voltage = 2.5" ; C1IN- < Vref nop .command "C1P.voltage = 3.1" ; C1IN+ > Vref nop .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m2 new inputs C1OUT=0 C2OUT=1\"" nop .assert "(pir1 & 0x18) == 0x18, \"FAILED 16f684 C1IF=1 C2IF=1\"" nop bsf CMCON0,CIS ; switch pins .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f684 m2 new inputs C1OUT=1 C2OUT=0\"" nop movlw CMODE2 ; Comparator mux reference movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f684 m6 invert normal C1OUT=1 C2OUT=0\"" nop clrf PIR1 BANKSEL PIE1 bsf PIE1,C1IE ; enable Comparator interrupts bsf PIE1,C2IE ; enable Comparator interrupts bsf INTCON,PEIE ; enable Peripheral interrupts bsf INTCON,GIE ; and global interrupts BANKSEL CMCON0 bsf CMCON0,C1INV ; generate an interrupt nop nop .assert "\"*** FAILED Comparator no interrupt 16f684\"" nop goto $ done1: ; ; mode1 - 3 inputs mux to two comparators ; ; C2IN+(2.5V) to both comparator + ; C1IN-(3.1V), C1IN+(2.1V) muxed to C1 - by CIS ; C2in-(1.5V) connected to C2 - .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.1" nop .command "C1N.voltage = 3.1" nop movlw CMODE1 movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m1 CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m1 CIS=1 C1OUT=1 C2OUT=1\"" nop ; ; mode 4 - Two independent Comparators ; ; Both Comparator true ; C1IN-(2.1V), C1 - ; C1IN+(3.1V) C1 + thus C1 out=1 ; C2in-(1.5V) connected to C2 - ; C2IN+(2.5V) C2 + thus C2 out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 3.1" nop .command "C1N.voltage = 2.1" nop movlw CMODE4 movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m4 CIS=0 C1OUT=1 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m4 CIS=1 C1OUT=1 C2OUT=1\"" nop ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop nop .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f684 m4 C1OUT=1 C2OUT=0\"" nop ; C1+ < C1- C1 out=0 ; C2+ > C2- C2 out=1 .command "C1P.voltage = 2.0" nop .command "C2P.voltage = 2.5" nop .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m4 C1OUT=0 C2OUT=1\"" nop ; both low ; C2+ < C2- C2 out=0 .command "C2P.voltage = 1.4" nop .assert "(cmcon0 & 0xc0) == 0x00, \"FAILED 16f684 m4 C1OUT=0 C2OUT=0\"" nop ; ; mode 3 - Two common reference Comparators ; ; C2IN+(2.5V) to both comparator + ; C1IN-(3.1V),connected to C1 - out=0 ; C2in-(1.5V) connected to C2 - out=1 .command "C2P.voltage = 2.5" nop .command "C2N.voltage = 1.5" nop .command "C1P.voltage = 2.1" nop .command "C1N.voltage = 3.1" nop movlw CMODE3 movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m3 CIS=0 C1OUT=0 C2OUT=1\"" nop bsf CMCON0,CIS .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m3 CIS=1 C1OUT=0 C2OUT=1\"" nop ; C2+ > C1- C1 out=1 ; C2+ < C2- C2 out=0 .command "C1N.voltage = 1.7" nop .command "C2N.voltage = 2.7" nop .assert "(cmcon0 & 0xc0) == 0x40, \"FAILED 16f684 m3 C1OUT=1 C2OUT=0\"" nop ; C2+ > C1- C1 out=1 ; C2+ > C2- C2 out=1 .command "C2N.voltage = 2.3" nop .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m3 C1OUT=1 C2OUT=1\"" nop ; ; mode 5 - One independent Comparator ; movlw CMODE5 movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0x80, \"FAILED 16f684 m5 C1OUT=0 C2OUT=1\"" nop ; ; mode 6 two common reference Comparators with Outputs ; BANKSEL TRISA bcf TRISA,2 BANKSEL CMCON0 movlw CMODE6 movwf CMCON0 .assert "(cmcon0 & 0xc0) == 0xc0, \"FAILED 16f684 m6 C1OUT=1 C2OUT=1\"" nop .assert "(porta & 0x04) == 0x04, \"FAILED 16f684 m6 porta2=1\"" nop .assert "(portc & 0x10) == 0x10, \"FAILED 16f684 m6 portc4=1\"" nop ; C2+ < C1- out=0 ; C2+ < C2- out=0 .command "C2P.voltage = 1.5" nop .assert "(cmcon0 & 0xc0) == 0x00, \"FAILED 16f684 m6 C1OUT=0 C2OUT=0\"" nop .assert "(porta & 0x04) == 0x00, \"FAILED 16f684 m6 porta2=0\"" nop .assert "(portc & 0x10) == 0x00, \"FAILED 16f684 m6 portc4=0\"" nop .assert "\"*** PASSED Comparator on 16f684\"" goto $ FAILED: .assert "\"*** FAILED Comparator no interrupt 16f684\"" goto $ end gpsim-0.30.0/regression/p16f684/a2d_684.asm0000664000076400007640000001216713116675277014641 00000000000000 list p=16f684 include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability ;; to simulate a pic 16f684. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto inta2d .assert "\"FAILED 16F684 a2d unexpected interupt\"" nop goto check ;; An A/D interrupt has occurred inta2d: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 252" .sim "V1.ypos = 84" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 252" .sim "V2.ypos = 144" .sim "node na1" .sim "attach na1 V2.pin porta1" BANKSEL PIR1 clrf PIR1 movlw 0x07 ; turn off comparater movwf CMCON0 BANKSEL ANSEL movlw 0x03 ; an0 only movwf ANSEL ;; Let's use the ADC's interrupt ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; movwf TRISA bsf PIE1,ADIE ;A2D interrupts ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. movlw 0x60 ; FOSC/64 movwf ADCON1 ; ; Left justify results, use Vdd Reference, use AN0, and turn on A2D ; BANKSEL ADCON0 movlw (1< .command macro x .direct "C", x endm __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_OFF cblock 0x40 temp flag endc ORG 0 .sim "p16f684.BreakOnReset = false" .sim "break c 0x100000" .sim "p16f684.frequency=10000" btfss STATUS,NOT_TO goto wdt_reset clrf flag banksel OPTION_REG bcf OPTION_REG,PSA BANKSEL TRISA clrf TRISA ; bcf OPTION_REG,NOT_RABPU ; enable pullups on portA BANKSEL PORTA movlw 0xff movwf PORTA banksel PORTA call delay incf flag banksel WDTCON bsf WDTCON,SWDTEN ; turn on WDT bcf OPTION_REG,PSA banksel PORTA call delay .assert "\"*** FAILED p16f684 no WDT with SWDTEN\"" nop done: .assert "\"*** PASSED p16f684 no WDT test\"" nop GOTO $ wdt_reset: btfsc flag,0 goto done .assert "\"*** FAILED p16f684 unexpected WDT triggered\"" nop goto $ delay clrf temp ; LOOP2 goto $+1 goto $+1 goto $+1 decfsz temp, F goto LOOP2 return end gpsim-0.30.0/regression/p16f684/wdt_16f684.asm0000664000076400007640000000354713041763603015274 00000000000000 ;; 16F684 WDT tests ;; ;; This regression test, tests the following WDT functions ;; WDT enabled by default without configuration word ;; OPTION_REG Postscaler Rate select bits work ;; clrwdt works ;; WDT wakes up sleep without reset ;; WDT causes reset ;; ;; The test assumes that the clock speed is about 10 KHz ;; list p=16f684 include "p16f684.inc" include .command macro x .direct "C", x endm cblock 0x20 temp tmp2 phase endc ORG 0 .sim "p16f684.BreakOnReset = false" .sim "break c 0x10000" .sim "p16f684.frequency=10000" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto wdt_reset ; ; WDT should be about 2.3 seconds in gpsim with default postscaler of 128 ; (on real device may be soon as 0.9 sec) ; In the following test WDT should be longer then delay1, but shorter ; than twice delay1. The clrwdt thus prevents the WDT from going off. call delay1 clrwdt call delay1 ; ; My reading of the specs indicate sleep should continue (no reset) ; when the WDT goes off sleeps continue sleep nop .assert "(status & 0x18) == 0x00,\"*** FAILED 16f684 status after sleep\"" nop incf phase, F ; ; Test the WDT cause a reset in under 2 * delay1 clrwdt .assert "(status & 0x18) == 0x18,\"*** FAILED 16f684 status after clrwdt\"" nop call delay1 call delay1 FAILED: .assert "\"*** FAILED p16f684 no WDT reset\"" goto $ FAILED2: .assert "\"*** FAILED p16f684 unexpected WDT reset\"" goto $ ; delay about 1.85 seconds delay1 movlw 0x06 movwf tmp2 Oloop clrf temp ; LOOP1 decfsz temp, F goto LOOP1 decfsz tmp2,F goto Oloop return wdt_reset: btfss phase,0 goto FAILED2 .assert "(status & 0x18) == 0x08,\"*** FAILED 16f684 status after WDT Reset\"" nop .assert "\"*** PASSED p16f684 WDT\"" goto $ end gpsim-0.30.0/regression/p16f684/compar_684.stc0000664000076400007640000000130013041763603015434 00000000000000 #set verbose 2 load compar_684.cod U1 # Module libraries: module library libgpsim_modules # Modules: U1.xpos=84. U1.ypos=24. module load pullup PU1 PU1.capacitance = 0 PU1.resistance = 10000 PU1.voltage = 5 PU1.xpos = 300 PU1.ypos = 36 module load pulldown PD2 PD2.capacitance = 0 PD2.resistance = 10000 PD2.voltage = 0 PD2.xpos = 300 PD2.ypos = 96 #module load pullup PU2 # Connections: node nb0 attach nb0 porta1 portc5 PU1.pin PD2.pin #attach nb0 porta0 portc0 node nb1 attach nb1 porta0 portc3 # node nb2 attach nb2 portc0 portc2 # node nb3 attach nb3 portc1 porta4 # #node nb4 ##attach nb4 porta4 portc4 PU2.pin #attach nb4 porta4 portc4 # #node nb5 #attach nb5 porta5 portc5 # End. gpsim-0.30.0/regression/p16f684/epwm.asm0000775000076400007640000001656213116675327014544 00000000000000 list p=16f684 include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16f684. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W clrf STATUS movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16F684 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "scope.ch0 = \"portc5\"" ; P1A .sim "scope.ch1 = \"portc4\"" ; P1B .sim "scope.ch2 = \"portc3\"" ; P1C .sim "scope.ch3 = \"portc2\"" ; P1D ;.sim "scope.ch4 = \"portb4\"" .sim "node na0" ; .sim "attach na0 portb2 portb0" call setup call full_forward call full_reverse call wait_period call wait_period call half_mode call pwm_shutdown clrf CCP1CON ; turn off PWM .assert "\"*** PASSED 16f684 PWM test\"" nop goto $-0 pwm_shutdown BANKSEL CMCON0 ; movlw (1< PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop return setup: banksel CCP1CON clrf CCP1CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 movlw 0x07 movwf CMCON0 banksel ANSEL clrf ANSEL ; turn ports to digital banksel CCPR1L movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF banksel TRISC ; Make output pins bcf TRISC, 1 ; Make pin output bcf TRISC, 5 ; P1A bcf TRISC,4 ; P1B bcf TRISC,3 ; P1C bcf TRISC,2 ; P1D clrf PIE1 ; Disable peripheral interrupts movlw 0x03 ; Port B pull-up Tmr0 internal clock prescaler 16 movwf OPTION_REG banksel PIR1 ; Bank0 movlw 0xff movwf PIR1 clrf PIR1 ; Clear peripheral interrupts Flags return end gpsim-0.30.0/regression/interrupts_16bit/0000775000076400007640000000000013117466027015337 500000000000000gpsim-0.30.0/regression/interrupts_16bit/priority.asm0000664000076400007640000003462113041763600017641 00000000000000 ;; The purpose of this program is to test gpsim's ability to ;; simulate interrupts on the midrange core (specifically the 'f2321). list p=18f2321 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;; Suppress warnings of using 'option' instruction. errorlevel -224 CONFIG WDT=OFF CONFIG MCLRE=ON, LPT1OSC=OFF, PBADEN=DIG, CCP2MX=RC1 GPR_DATA UDATA intflags RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 temp4 RES 1 temp5 RES 1 adr_cnt RES 1 data_cnt RES 1 failures RES 1 w_temp RES 1 status_temp RES 1 GLOBAL temp1,temp2,temp3,temp4,temp5,intflags GLOBAL start ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ HI_PRI CODE 0x008 ; interrupt vector location bra hi_pri_isr LO_PRI CODE 0x018 ; interrupt vector location movwf w_temp movff STATUS,status_temp check_rbi: btfsc INTCON,RBIF btfss INTCON,RBIE bra check_int bsf intflags,0 ;Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w check_int: btfsc INTCON,INT0IF btfss INTCON,INT0IE bra check_t0 bsf intflags,1 ;Set a flag to indicate rb0 int occured bcf INTCON,INT0IF check_t0: btfsc PIR1,TMR2IF btfss PIE1,TMR2IE bra check_int1 ;; tmr0 has rolled over bcf PIR1,TMR2IF ; Clear the pending interrupt bsf intflags,2 ; Set a flag to indicate rollover check_int1: btfsc INTCON3,INT1IF btfss INTCON3,INT1IE bra check_int2 bsf temp3,0 ;Set a flag to indicate rb1 int occured bcf INTCON3,INT1IF check_int2: btfsc INTCON3,INT2IF btfss INTCON3,INT2IE bra exit_int bsf temp3,1 ;Set a flag to indicate rb2 int occured bcf INTCON3,INT2IF exit_int: movf w_temp,w movff status_temp,STATUS retfie hi_pri_isr: check_int1hi: btfsc INTCON3,INT1IF btfss INTCON3,INT1IE bra check_int2hi bsf temp3,2 ;Set a flag to indicate rb1 int occured bcf INTCON3,INT1IF check_int2hi: btfsc INTCON3,INT2IF btfss INTCON3,INT2IE bra check_rbih bsf temp3,3 ;Set a flag to indicate rb2 int occured bcf INTCON3,INT2IF check_rbih: btfsc INTCON,RBIF btfss INTCON,RBIE bra check_inth bsf intflags,4 ; Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w check_inth: btfsc INTCON,INT0IF btfss INTCON,INT0IE bra check_t0h bsf intflags,5 ; Set a flag to indicate rb0 int occured bcf INTCON,INT0IF check_t0h: btfsc PIR1,TMR2IF btfss PIE1,TMR2IE bra exit_inth ;; tmr1 has rolled over bcf PIR1,TMR2IF ; Clear the pending interrupt bsf intflags,6 ; Set a flag to indicate rollover btfsc temp5,7 ; Is a nesting test in progress? btg PORTB,2 nop nop btfsc intflags,0 .assert "\"*** FAILED - low priority PORTB interrupt serviced during high priority ISR\"" bsf failures,7 exit_inth: retfie FAST ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;; Assume no failures clrf failures clrf temp5 movlw 0Fh ; Configure all A/D movwf ADCON1 ; for digital inputs movwf 07h ; Configure comparators movwf CMCON ; for digital input clrf INTCON bsf RCON,IPEN ; Enable priority mode movlw 080h movwf INTCON2 clrf INTCON3 bsf RCON,IPEN bsf INTCON,GIE ;Enable high priority interrupts ;; First we test that with only high priority interrupts enabled, ;; those set to low priority are ignored ;; ;; inte test ;; ;; The following block of code tests the interrupt on ;; change for port b bit 0. It assumes that port a bit 4 ;; is the stimulus. This requires that the following ;; gpsim commands be invoked: ;; gpsim> node new_test_node ;; gpsim> attach new_test_node porta4 portb0 ;; ;; Also, recall that porta bit 4 is an open collector ;; output (it can't drive high). So to generate the ;; the logic highs, the portb weak pull-up resistors ;; need to be enabled. test_inte: bsf TRISB,0 ;and portb bit 0 an input bcf TRISA,4 ;Make porta bit 4 an output bcf INTCON2,NOT_RBPU ;Enable the portb weak pull-ups bsf INTCON2,INTEDG0 ;Interrupt on rising edge movlw 0xff movwf temp1 movwf temp2 movwf temp3 movwf temp4 bcf PORTA,4 bcf INTCON,INT0IF bsf INTCON,INT0IE ;; ;; This routine toggles porta bit 4 with the hope of generating ;; an interrupt on portb bit 0. Note that INT0 is ALWAYS high priority ;; inte_edgecount: clrf intflags ;Interrupt flag bsf PORTA,4 ;Rising edge bcf PORTA,4 ;Falling edge nop nop .assert "intflags == 0x20, \"*** FAILED INT0 interrupt not high priority\"" movlw 0x20 cpfseq intflags bra failed bcf INTCON,INT0IF bcf INTCON,INT0IE ;Disable the rb0 interrupt ;; ;; test_rbif ;; ;; This next block uses the interrupt on change feature of ;; port b's I/O pins 4-7 to confirm that a low priority interrupt ;; is masked. ;; test_rbif: bsf TRISA,4 ; Porta bit 4 is now an input movlw 0xF0 movwf TRISB ; Upper nibble of port B is connected to lower nibble movlw 0x10 movwf temp2 movlw 6 movwf PORTB rbif_l1: bcf INTCON,RBIE movf PORTB,W clrf intflags ; Interrupt flag bcf INTCON,RBIF bcf INTCON2,RBIP bsf INTCON,RBIE swapf temp2,w xorwf PORTB,f .assert "intflags == 0, \"*** FAILED low priority portB interrupt not masked\"" tstfsz intflags bra failed .assert "(intcon&1) == 1, \"*** FAILED Toggle of portb pin not detected\"" btfss INTCON,RBIF bra failed clrc rlcf temp2,f skpc bra rbif_l1 ;; ;; The following block of code tests tmr2 together with interrupts. bsf PIE1,TMR2IE ;Enable TMR2 overflow interrupts clrf intflags ;Software flag used to monitor when the ;interrupt has been serviced. movlw 0x04 movwf T2CON ;Assign new prescale value movlw 0x80 movwf PR2 clrf temp1 decfsz temp1,f ; Hang around long enough that an overflow should occur goto $-2 btfss PIR1,TMR2IF ; check the overflow happened .assert "\"*** FAILED no TMR2 overflow detected\"" bra failed .assert "intflags == 0, \"*** FAILED low priority TRM2 interrupt not masked\"" tstfsz intflags bra failed bcf PIE1,TMR2IE ;Disable TMR2 overflow interrupts clrf T2CON ; and switch off TMR2 ;; Next we test that with low priority interrupts enabled, ;; those set to low priority are handled by the low priority ISR ;; bsf INTCON,GIEL ;Enable low priority interrupts ;; ;; test_rbif ;; ;; This next block uses the interrupt on change feature of ;; port b's I/O pins 4-7 to confirm that a low priority interrupt ;; is responded to as such. ;; test_rbif_2: bsf TRISA,4 ; Porta bit 4 is now an input movlw 0xF0 movwf TRISB ; Upper nibble of port B is connected to lower nibble movlw 0x10 movwf temp2 movlw 6 movwf PORTB rbif_l2: bcf INTCON,RBIE movf PORTB,W clrf intflags ; Interrupt flag bcf INTCON,RBIF bcf INTCON2,RBIP bsf INTCON,RBIE swapf temp2,w xorwf PORTB,f .assert "intflags == 1, \"*** FAILED low priority portB interrupt not seen\"" decfsz intflags,w bra failed clrc rlcf temp2,f skpc bra rbif_l2 ;; ;; The following block of code tests tmr2 together with interrupts. bsf PIE1,TMR2IE ;Enable TMR2 overflow interrupts clrf intflags ;Software flag used to monitor when the ;interrupt has been serviced. movlw 0x04 movwf T2CON ;Assign new prescale value movlw 0x80 movwf PR2 clrf temp1 decfsz temp1,f ; Hang around long enough that an overflow should occur goto $-2 btfsc PIR1,TMR2IF ; check the overflow happened .assert "\"*** FAILED no TMR2 overflow detected\"" bra failed .assert "intflags == 4, \"*** FAILED low priority TMR2 interrupt not masked\"" bcf PIE1,TMR2IE ;Disable TMR2 overflow interrupts clrf T2CON ; and switch off TMR2 ;; Finally test that setting peripherals to high priority causes the ;; right ISR to be run ;; bsf INTCON,GIEL ;Enable low priority interrupts ;; ;; test_rbif ;; ;; This next block uses the interrupt on change feature of ;; port b's I/O pins 4-7 to confirm that a low priority interrupt ;; is responded to as such. ;; test_rbif_3: bsf TRISA,4 ; Porta bit 4 is now an input movlw 0xF0 movwf TRISB ; Upper nibble of port B is connected to lower nibble movlw 0x10 movwf temp2 movlw 6 movwf PORTB bsf INTCON2,RBIP rbif_l3: bcf INTCON,RBIE movf PORTB,W clrf intflags ; Interrupt flag bcf INTCON,RBIF bsf INTCON,RBIE swapf temp2,w xorwf PORTB,f .assert "intflags == 0x10, \"*** FAILED high priority portB interrupt not seen\"" ; decfsz intflags,w ; bra failed clrc rlcf temp2,f skpc bra rbif_l3 ;; ;; The following block of code tests tmr2 together with interrupts. bsf PIE1,TMR2IE ;Enable TMR2 overflow interrupts bsf IPR1,TMR2IP ; ... as high priority clrf intflags ;Software flag used to monitor when the ;interrupt has been serviced. movlw 0x04 movwf T2CON ;Assign new prescale value movlw 0x80 movwf PR2 clrf temp1 decfsz temp1,f ; Hang around long enough that an overflow should occur goto $-2 btfsc PIR1,TMR2IF ; check the overflow happened .assert "\"*** FAILED no TMR2 overflow detected\"" bra failed .assert "intflags == 0x40, \"*** FAILED high priority TMR2 interrupt not seen\"" ;; ;; The following block of code tests nesting of interrupts, by generating a ;; high priority TMR2 interrupt with the "cause PORTB interrupt" flag set. ;; The high priority ISR then triggers a low priority interrupt, which should ;; be handled after leaving the high priority but before doing any more of ;; the background stuff. bcf INTCON2,RBIP bsf temp5,7 ; TMR2 ISR triggers a PORTB event clrf intflags ;Software flag used to monitor when the ;interrupt has been serviced. ; clrf temp1 ; decfsz temp1,f ; Hang around long enough that an overflow should occur ; goto $-2 btfss intflags,6 ; Wait for the TMR2 interrupt (must only see one) goto $-2 .assert "intflags == 0x41, \"*** FAILED priority nesting test\"" nop bcf PIE1,TMR2IE ;Disable TMR2 overflow interrupts clrf T2CON ; and switch off TMR2 ;; Test int1 and int2 ;; 1> low priority with GIEL=0 (no inturrupt expected) ;; 2> log priority with GIEL=1 bcf INTCON,GIEL ;disable low priority interrupts movlw 0x6 ; b5 drives b1 b6 drives b2 movwf TRISB bcf PORTB,5 bcf PORTB,6 clrf temp3 movlw (1< ; processor specific variable definitions include ; Grab some useful macros ;; Suppress warnings of using 'option' instruction. errorlevel -224 CONFIG WDT=OFF CONFIG MCLRE=ON, LPT1OSC=OFF, PBADEN=DIG, CCP2MX=RC1 GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 temp4 RES 1 temp5 RES 1 adr_cnt RES 1 data_cnt RES 1 failures RES 1 w_temp RES 1 status_temp RES 1 GLOBAL temp,temp1,temp2,temp3,temp4,temp5 GLOBAL start ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; Hi priority interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp goto check_rbi LOW_INT_VECTOR CODE 0x018 ; Low priority interrupt vector .assert "\"*** FAILED 16bit-core basic interrupt test low interrupt\"" goto $ check_rbi: btfsc INTCON,RBIF btfss INTCON,RBIE bra check_int bsf temp5,1 ;Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w check_int: btfsc INTCON,INT0IF btfss INTCON,INT0IE bra check_b1 bsf temp5,0 ;Set a flag to indicate rb0 int occured bcf INTCON,INT0IF check_b1: btfsc INTCON3,INT1IF btfss INTCON3,INT1IE bra check_b2 bsf temp5,2 ;Set a flag to indicate rb1 int occured bcf INTCON3,INT1IF check_b2: btfsc INTCON3,INT2IF btfss INTCON3,INT2IE bra check_t0 bsf temp5,3 ;Set a flag to indicate rb2 int occured bcf INTCON3,INT2IF check_t0: btfsc INTCON,T0IF btfss INTCON,T0IE bra exit_int ;; tmr0 has rolled over bcf INTCON,T0IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;; Assume no failures clrf failures movlw 0Fh ; Configure all A/D movwf ADCON1 ; for digital inputs movwf 07h ; Configure comparators movwf CMCON ; for digital input ;; ;; tmr0 test ;; ;; The following block of code tests tmr0 together with interrupts. ;; Each prescale value (0-7) is loaded into the timer. The software ;; waits until the interrupt due to tmr0 rollover occurs before ;; loading the new prescale value. bsf INTCON,T0IE ;Enable TMR0 overflow interrupts bsf INTCON,GIE ;Global interrupts clrf temp1 ;Software flag used to monitor when the ;interrupt has been serviced. movlw 0xC0 movwf T0CON ;Assign new prescale value test_tmr0: btfss temp1,0 ;Wait for the interrupt to occur and bra test_tmr0 ;get serviced clrf temp1 ;Clear flag for the next time incf T0CON,f btfss T0CON,3 ; When we've done all prescaler values, PSA gets set bra test_tmr0 bcf INTCON,T0IE ;Disable tmr0 interrupts ;; Now check tmr0 with an external clock source ;; ;; It assumes that port b bit 0 is the stimulus. ;; This requires that the following gpsim commands be invoked: ;; gpsim> node new_test_node ;; gpsim> attach new_test_node porta4 portb0 bcf TRISB,0 ;portb bit 0 is an output ;; assign the prescaler to the wdt so that tmr0 counts every edge ;; select the clock source to be tocki ;; and capture low to high transitions (tose = 0) movlw (1< node new_test_node ;; gpsim> attach new_test_node porta4 portb0 ;; ;; Also, recall that porta bit 4 is an open collector ;; output (it can't drive high). So to generate the ;; the logic highs, the portb weak pull-up resistors ;; need to be enabled. test_inte: bsf TRISB,0 ;Make portb bit 0 an input bcf TRISA,4 ; and porta bit 4 an output bcf INTCON2,NOT_RBPU ;Enable the portb weak pull-ups bsf INTCON2,INTEDG0 ;Interrupt on rising edge rcall test_int_pin .assert "(temp2) == 0x40,\"*** FAILED 16bit-core, no int0 rising\"" nop .assert "(temp1) == 0x00,\"*** FAILED 16bit-core, int0 interrupt on wrong edge\"" nop bcf INTCON,INT0IE ;Disable inte interrupt bcf INTCON2,INTEDG0 ;Interrupt on falling edge rcall test_int_pin .assert "(temp1) == 0x40,\"*** FAILED 16bit-core, no int0 falling\"" nop .assert "(temp2) == 0x00,\"*** FAILED 16bit-core, int0 interrupt on wrong edge\"" nop ;; ;; test_rbif ;; ;; This next block tests the interrupt on change feature of ;; port b's I/O pins 4-7 ;; test_rbif: bcf INTCON,INT0IE ;Disable the rb0 interrupt bsf TRISA,4 ;Porta bit 4 is now an input clrf temp5 ;Interrupt flag clrf temp1 movlw 0x10 movwf temp2 movlw 6 movwf PORTB rbif_l1: bcf INTCON,RBIE movf temp2,w movwf TRISB ; clrf PORTB movf PORTB,W clrf temp5 ;Interrupt flag bcf INTCON,RBIF bsf INTCON,RBIE swapf temp2,w xorwf PORTB,f btfsc temp5,1 iorwf temp1,f .assert "(temp5 & 2) == 2" clrc rlcf temp2,f skpc bra rbif_l1 ;; Test int1, interrupts using intcon3 register ;; B5 drives B1 test_int1 bcf INTCON,RBIE ; turn off b 4-7 intterupts bsf TRISB,1 ; and portb bit 1 an input bcf PORTB,5 ; drive portb1 low clrf temp5 bcf INTCON3,INT1IF bsf INTCON3,INT1IP ; priority interrupt bsf INTCON3,INT1IE bsf PORTB,5 ; drive portb1 high .assert "(temp5) == 4,\"*** FAILED 16bit-core basic, no int1 interrupt\"" nop clrf temp5 bcf PORTB,5 ; drive portb1 low .assert "(temp5) == 0,\"*** FAILED 16bit-core basic, unexpected int1 interrupt\"" nop ;; Test int2, interrupts using intcon3 register ;; B6 drives B2 test_int2 bsf TRISB,2 ; and portb bit 2 an input bcf PORTB,6 ; drive portb2 low clrf temp5 bcf INTCON3,INT2IF bsf INTCON3,INT2IP ; priority interrupt bsf INTCON3,INT2IE bsf PORTB,6 ; drive portb2 high .assert "(temp5) == 8,\"*** FAILED 16bit-core basic, no int2 interrupt\"" nop clrf temp5 bcf PORTB,6 ; drive portb2 low .assert "(temp5) == 0,\"*** FAILED 16bit-core basic, unexpected int2 interrupt\"" nop done: .assert "\"*** PASSED 16bit-core basic interrupt test\"" goto $ failed: .assert "\"*** FAILED 16bit-core basic interrupt test\"" goto $ ;; ;; This routine toggles one of the porta bits with the hope of generating ;; an interrupt on one of the portb bits. ;; temp1 counts the number of interrupts due to falling edges ;; temp2 counts the number of interrupts due to rising edges ;; test_int_pin: bsf TRISB,0 ;and portb bit 0 an input bcf TRISA,4 ;Make porta bit 4 an output bcf INTCON2,NOT_RBPU ;Enable the portb weak pull-ups clrf temp1 clrf temp2 movlw 0x40 movwf temp3 ; used for counting movwf temp4 bcf PORTA,4 bcf INTCON,INT0IF bsf INTCON,INT0IE ;; ;; Now loop round 64 times toggling the pin and count the interrupts ;; inte_edgecount: bcf temp5,0 ;Interrupt flag clrz bsf PORTA,4 ;Falling edge btfsc temp5,0 incf temp2,f ;Falling edge caused the interrupt bcf temp5,0 bcf PORTA,4 ;Rising edge btfsc temp5,0 incf temp1,f ;Rising edge caused the interrupt decfsz temp3,f bra inte_edgecount return end gpsim-0.30.0/regression/interrupts_16bit/interrupts_16bit.stc0000664000076400007640000000165613041763600021217 00000000000000load interrupts_16bit.cod # another test stimulation file # # the '#' marks the beginning of a comment # # This stimulation file illustrates how two (or more) # iopins may be connected to one another. In this example, # port A bit 4 is tied to port B bit 0. # Also, note that this file does not define the processor # or the source .hex ... echo I/O pin Stimulus file that connects port A 4 echo port B 0. # Define a node to which the pins can attach. node test_node # Now specify which two I/O pins are attached to the # new node. Note, that it is possible to specify more # than two iopins (or two of any stimuli). The iopins # are assigned the names portxn - where x is a,b,c,d,e # and n is 0 through 7. attach test_node porta4 portb0 # Here are a couple of more stimuli that are used to # test rbif node n1 n2 n3 attach n1 portb1 portb5 attach n2 portb2 portb6 attach n3 portb3 portb7 attach test_node portb4 break c 0x200000 gpsim-0.30.0/regression/interrupts_16bit/priority.stc0000664000076400007640000000152313041763600017645 00000000000000load priority.cod # another test stimulation file # # the '#' marks the beginning of a comment # # This stimulation file illustrates how two (or more) # iopins may be connected to one another. In this example, # port A bit 4 is tied to port B bit 0. # Also, note that this file does not define the processor # or the source .hex ... # Define a node to which the pins can attach. node test_node # Now specify which two I/O pins are attached to the # new node. Note, that it is possible to specify more # than two iopins (or two of any stimuli). The iopins # are assigned the names portxn - where x is a,b,c,d,e # and n is 0 through 7. attach test_node porta4 portb0 # Here are a couple of more stimuli that are used to # test rbif node n1 n2 n3 attach n1 portb1 portb5 attach n2 portb2 portb6 attach n3 portb3 portb7 attach test_node portb4 gpsim-0.30.0/regression/interrupts_16bit/18f2321.lkr0000664000076400007640000000167313041763600016677 00000000000000// $Id: 18f2321.lkr 448 2006-08-19 02:52:41Z craigfranklin $ // File: 18f2321.lkr // Sample linker script for the PIC18F2321 processor // Not intended for use with MPLAB C18. For C18 projects, // use the linker scripts provided with that product. LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x1FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr0 START=0x80 END=0xFF DATABANK NAME=gpr1 START=0x100 END=0x1FF ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED gpsim-0.30.0/regression/node_test/0000775000076400007640000000000013117466027014077 500000000000000gpsim-0.30.0/regression/node_test/node_test.asm0000664000076400007640000000341113116714476016507 00000000000000 ;; Node test ;; ;; The purpose of this program is to verify that nodes ;; can interconnect I/O pins. list p=16f877 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location nop ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start MOVLW 0xff BSF STATUS,RP0 CLRF TRISB^0x80 ;Port B is an output MOVWF TRISC^0x80 ;Port C is an input BCF STATUS,RP0 b_to_c_loop: MOVWF PORTB ;Port B and Port C are externally XORWF PORTC,W ;connected. So we should see the SKPZ ;same thing on each port. GOTO FAILED DECFSZ PORTC,W goto b_to_c_loop done: .assert "\"*** PASSED Node Test on 16f877\"" goto $ FAILED: .assert "\"*** FAILED Node Test on 16f877\"" goto $ end gpsim-0.30.0/regression/node_test/node_test.stc0000664000076400007640000000103513041763600016506 00000000000000 # Node Test # # This script will tie Port B and Port C together # load node_test.cod # First, create 8 nodes: node loop_back0 node loop_back1 node loop_back2 node loop_back3 node loop_back4 node loop_back5 node loop_back6 node loop_back7 # Now tie the ports together: attach loop_back0 portb0 portc0 attach loop_back1 portb1 portc1 attach loop_back2 portb2 portc2 attach loop_back3 portb3 portc3 attach loop_back4 portb4 portc4 attach loop_back5 portb5 portc5 attach loop_back6 portb6 portc6 attach loop_back7 portb7 portc7 gpsim-0.30.0/regression/node_test/Makefile0000664000076400007640000000050713041763600015452 00000000000000include ../make.regression SCRIPT = 16f877.lkr PROJECT = node_test OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod STC = $(PROJECT).stc all : $(OUTPUT) $(OUTPUT) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -s $(SCRIPT) -o $(OUTPUT) $(OBJECTS) sim: $(COD) $(GPSIM) -i -I $(STARTUP_STC) -D STC=$(STC) gpsim-0.30.0/regression/node_test/16f877.lkr0000664000076400007640000000330513041763600015365 00000000000000// Sample linker command file for 16F877 // $Id: 16f877.lkr 1228 2005-08-23 16:36:11Z sdattalo $ LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED CODEPAGE NAME=page0 START=0x5 END=0x7FF CODEPAGE NAME=page1 START=0x800 END=0xFFF CODEPAGE NAME=page2 START=0x1000 END=0x17FF CODEPAGE NAME=page3 START=0x1800 END=0x1FFF CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED CODEPAGE NAME=.config START=0x2007 END=0x2007 PROTECTED CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED DATABANK NAME=gpr0 START=0x20 END=0x6F DATABANK NAME=gpr1 START=0xA0 END=0xEF DATABANK NAME=gpr2 START=0x110 END=0x16F DATABANK NAME=gpr3 START=0x190 END=0x1EF SHAREBANK NAME=gprnobnk START=0x70 END=0x7F SHAREBANK NAME=gprnobnk START=0xF0 END=0xFF SHAREBANK NAME=gprnobnk START=0x170 END=0x17F SHAREBANK NAME=gprnobnk START=0x1F0 END=0x1FF SECTION NAME=STARTUP ROM=vectors // Reset and interrupt vectors SECTION NAME=PROG1 ROM=page0 // ROM code space - page0 SECTION NAME=PROG2 ROM=page1 // ROM code space - page1 SECTION NAME=PROG3 ROM=page2 // ROM code space - page2 SECTION NAME=PROG4 ROM=page3 // ROM code space - page3 SECTION NAME=IDLOCS ROM=.idlocs // ID locations SECTION NAME=CONFIG ROM=.config // Configuration bits location SECTION NAME=DEEPROM ROM=eedata // Data EEPROM gpsim-0.30.0/regression/p16f873/0000775000076400007640000000000013117466027013131 500000000000000gpsim-0.30.0/regression/p16f873/Makefile0000644000076400007640000000021210644134037014475 00000000000000include ../make.regression SCRIPT = 16f873.lkr all : p16f873.cod %.cod : %.o gplink --map -s $(SCRIPT) -o $@ $< sim: sim_p16f873 gpsim-0.30.0/regression/p16f873/p16f873.asm0000664000076400007640000000556413041763600014574 00000000000000 list p=p16f873 radix dec __config _WDT_OFF include "p16f873.inc" ;Regression Test for 16f873's data EEPROM ; cblock 0x20 adr_cnt data_cnt status_temp endc ; W shadowing for interrupts ; When an interrupt occurs, we don't know what the current bank settings ; are. The solution here is to declare two temporaries that have the ; same base address. That way we don't need to worry about the bank setting. cblock 0x70 w_temp ; W is stored here during interrupts if the ; bank bits point to bank 0 or 2 endc cblock 0xf0 w_temp_shadow ; W is stored here during interrupts if the ; bank bits point to bank 0 or 2 endc ;;======================================================================== ;;======================================================================== ; ; Start ; org 0 goto start org 4 ;;************** ;; Interrupt ;;************* movwf w_temp swapf STATUS,W clrf STATUS ;Bank 0 movwf status_temp bsf STATUS,RP0 btfss (EECON1 & 0x7f),EEIF goto check ;;; eeprom has interrupted bcf (EECON1 & 0x7f),EEIF check: clrf STATUS ;bank 0 swapf status_temp,W movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;;************* ;; end of interrupt ;;************* start: clrf STATUS ;Point to Bank 0 clrf adr_cnt clrf data_cnt incf data_cnt,F bsf INTCON,EEIE l1: movf adr_cnt,W bcf STATUS,RP0 bsf STATUS,RP1 movwf EEADR ^ 0x100 movf data_cnt,W movwf EEDATA ^ 0x100 bcf INTCON,GIE ;Disable interrupts while enabling write bsf STATUS,RP0 bsf (EECON1 ^ 0x180),WREN ;Enable eeprom writes movlw 0x55 ;Magic sequence to enable eeprom write movwf (EECON2 ^ 0x180) movlw 0xaa movwf (EECON2 ^ 0x180) bsf (EECON1 ^ 0x180),WR ;Begin eeprom write bsf INTCON,GIE ;Re-enable interrupts btfsc (EECON1 & 0x7f),WR goto $-1 clrf STATUS ; Point back to bank0 incf adr_cnt,W andlw 0x3f movwf adr_cnt skpz goto l1 incfsz data_cnt,F goto l1 goto l1 ;A place to set a break point (for timing how long ;it takes to fill the eeprom 256 times org 0x2100 de "Linux is cool!",0 de 0xaa,0x55,0xf0,0x0f de 'g','p','s','i','m' end gpsim-0.30.0/regression/ccp/0000775000076400007640000000000013117466027012660 500000000000000gpsim-0.30.0/regression/ccp/pwm_26k22.asm0000664000076400007640000001733613041763600014736 00000000000000 list p=18f26k22 include include CONFIG WDTEN=OFF, PBADEN = OFF ;; The purpose of this program is to test gpsim's ability to simulate a ;; pic with more than two PWM channels. The 18F26k22 is such a device. ;; CCP1 is set with a 50% duty cycle and used to test timing ;; CCP2 is set with a 25% duty cycle and used to test order ;; CCP3 is set beyond the period and tied to INT0 to test 100% duty ;; CCP4 is set with a 75% duty cycle ;; CCP5 is set with a 75% duty cycle to test two simultaneous PWM edges errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- ;GPR_DATA UDATA GPR_DATA UDATA 0 t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program INTERRUPT CODE 0x008 ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp .assert "\"FAILED 18f26k22 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie .sim "node pwm3" .sim "attach pwm3 portb5 portb1" ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: BANKSEL CCP1CON clrf ANSELA clrf ANSELC clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf CCP3CON ; CCP Module is off clrf CCP4CON ; CCP Module is off clrf CCP5CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0L ; Clear Timer0 movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 50% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period movlw 0x4F ; movwf CCPR3L ; Duty Cycle is 125% of PWM Period movlw 0x2F ; movwf CCPR4L ; Duty Cycle is 75% of PWM Period movlw 0x2F ; movwf CCPR5L ; Duty Cycle is 75% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF clrf INTCON2 ; external interrupt pins trigger on falling edge movlw 0x3F ; movwf PR2 ; bcf TRISC, 2 ; Make pin output CCP1 bcf TRISC, 1 ; Make pin output CCP2 bcf TRISB, 5 ; Make pin output CCP3 bcf TRISB, 0 ; Make pin output CCP4 bcf TRISA, 4 ; Make pin output CCP5 clrf PIE1 ; Disable peripheral interrupts movlw 0x83 ; Tmr0 internal clock prescaler 16 movwf T0CON clrf PIR1 ; Clear peripheral interrupts Flags movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP1CON ; movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP2CON ; movwf CCP3CON ; movwf CCP4CON ; movwf CCP5CON ; .assert "ccpr1l != ccpr1h, \"CCPR1H before TMR2 reset\"" nop movlw 0x0f ; set CCP2 outputs to all pins movwf PSTR2CON movlw 0x06 ; Start Timer2 prescaler is 16 (to match TMR0) movwf T2CON ; ; The CCP1 interrupt is disabled, ; do polling on the TMR2 Interrupt flag bit ; PWM_Period_Match btfss PIR1, TMR2IF goto PWM_Period_Match clrf TMR0L .assert "ccpr1l == ccpr1h, \"CCPR1H loaded from CCPR1H\"" nop bcf INTCON3,INT1IF ; INT1 is tied to CCP3, which should remain always high .assert "(portc & 0x6) == 0x6, \"CCP1, CCP2 are high\"" nop ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x0f, \"CCP2 duty cycle\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x1f, \"CCP1 duty cycle\"" nop ; loop until CCP4 goes low btfsc PORTB,0 goto $-1 .assert "tmr0 == 0x2f, \"CCP4 duty cycle\"" nop ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "(intcon3 & 0x40) == 0, \"PWM duty > PR2 : pin goes low\"" nop .assert "tmr0 == 0x3f, \"TMR2 period\"" nop ; ; Increase TMR2 but less than first duty cycle ; movlw 0x0D movwf TMR2 ; update timer clrf TMR0L ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "(portc & 0x6) == 0x0, \"TMR2 put, only change period\"" nop ; loop until CCP5 goes low btfsc PORTA,4 goto $-1 .assert "tmr0 == 0x22, \"TMR2 put, only change period\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x33, \"TMR2 put, only change period\"" nop ; ; Increase TMR2 between first and second duty cycle ; clrf TMR0L movlw 0x1D movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "(portc & 0x6) == 0x2, \"TMR2 put, between duty cycles\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x23, \"TMR2 put, between duty cycles\"" nop ; ; in this test TMR2 > PR2, expect TMR2 to wrap around ; movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf T0CON clrf TMR0L movlw 0x40 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x6F, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop movlw 0x20 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop movlw 0x10 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM clrf CCP3CON ; turn off PWM clrf CCP4CON ; turn off PWM clrf CCP5CON ; turn off PWM call use_t4 .assert "\"*** PASSED 18f26k22 PWM test\"" goto $-1 use_t4: bsf CCPTMRS0,C3TSEL0 ; select T4 for CCP3 movlw 0x3F ; movwf PR4 ; movlw 0x1F ; movwf CCPR3L ; Duty Cycle is 50% of PWM Period movlw 0x06 ; Start Timer4 prescaler is 16 (to match TMR0, of course!) clrf T2CON ; turn off T2 movwf T4CON movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP3CON ; ; loop until CCP3 goes low btfsc PORTB,5 goto $-1 return end gpsim-0.30.0/regression/ccp/Makefile0000664000076400007640000000032513041763600014231 00000000000000include ../make.regression all : ccp_877a.cod pwm_877a.cod ccp_819.cod pwm_6520.cod pwm_26k22.cod %.cod : %.o gplink --map -o $@ $< sim: sim_ccp_877a sim_pwm_877a sim_ccp_819 sim_pwm_6520 sim_pwm_26k22 gpsim-0.30.0/regression/ccp/ccp.stc0000664000076400007640000000211713041763600014052 00000000000000# another test stimulation file # # the '#' marks the beginning of a comment # # This stimulus file is used for testing portc # echo I/O pin Stimulus file for port C. # Define a node to which the pins can attach. node test_node_C # Create an asynchronous stimulus that's 1000 cycles long # and attach it to portc bit 2. stimulus asynchronous_stimulus # or we could've used asy # The initial state AND the state the stimulus is when # it rolls over initial_state 0 # all times are with respect to the cpu's cycle counter start_cycle 0x10000 # the asynchronous stimulus will roll over in 'period' period 0x200 # Indicate that this is digital data (default): digital # Now the cycles at which stimulus changes states are # specified. The initial cycle was specified above. { 0x100, 1} # Give the stimulus a name: name asy1 # Finally, tell the command line interface that we're done # with the stimulus end # but we can still have more stuff echo asy should've been created stimulus # Attach the stimulus to the IO port attach test_node_C asy1 portc2 echo stimulus created gpsim-0.30.0/regression/ccp/pwm_6520.asm0000664000076400007640000001576213041763600014565 00000000000000 list p=18f6520 include include CONFIG WDT=OFF ;; The purpose of this program is to test gpsim's ability to simulate a ;; pic with more than two PWM channels. The 18F6520 is such a device. ;; CCP1 is set with a 50% duty cycle and used to test timing ;; CCP2 is set with a 25% duty cycle and used to test order ;; CCP3 is set beyond the period and tied to INT0 to test 100% duty ;; CCP4 is set with a 75% duty cycle ;; CCP5 is set with a 75% duty cycle to test two simultaneous PWM edges errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector goto start ; go to beginning of program INTERRUPT CODE 0x008 ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp .assert "\"FAILED 18f6520 unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie .sim "node pwm3" .sim "attach pwm3 portg0 portb0" ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf CCP3CON ; CCP Module is off clrf CCP4CON ; CCP Module is off clrf CCP5CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0L ; Clear Timer0 movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 50% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period movlw 0x4F ; movwf CCPR3L ; Duty Cycle is 125% of PWM Period movlw 0x2F ; movwf CCPR4L ; Duty Cycle is 75% of PWM Period movlw 0x2F ; movwf CCPR5L ; Duty Cycle is 75% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF clrf INTCON2 ; external interrupt pins trigger on falling edge movlw 0x3F ; movwf PR2 ; bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; Make pin output bcf TRISG, 0 ; Make pin output bcf TRISG, 3 ; Make pin output bcf TRISG, 4 ; Make pin output clrf PIE1 ; Disable peripheral interrupts movlw 0x83 ; Tmr0 internal clock prescaler 16 movwf T0CON clrf PIR1 ; Clear peripheral interrupts Flags movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP1CON ; movlw 0x06 ; Start Timer2 prescaler is 16 (to match TMR0, of course!) movwf T2CON movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP2CON ; movwf CCP3CON ; movwf CCP4CON ; movwf CCP5CON ; .assert "ccpr1l != ccpr1h, \"CCPR1H before TMR2 reset\"" nop ; ; The CCP1 interrupt is disabled, ; do polling on the TMR2 Interrupt flag bit ; PWM_Period_Match btfss PIR1, TMR2IF goto PWM_Period_Match clrf TMR0L .assert "ccpr1l == ccpr1h, \"CCPR1H loaded from CCPR1H\"" nop bcf INTCON,INT0IF ; INT0 is tied to CCP3, which should remain always high .assert "(portc & 0x6) == 0x6, \"CCP1, CCP2 are high\"" nop ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x0f, \"CCP2 duty cycle\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x1f, \"CCP1 duty cycle\"" nop ; loop until CCP4 goes low btfsc PORTG,3 goto $-1 .assert "tmr0 == 0x2f, \"CCP4 duty cycle\"" nop ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "(intcon & 2) == 0, \"PWM duty > PR2 : pin goes low\"" nop .assert "tmr0 == 0x3f, \"TMR2 period\"" nop ; ; Increase TMR2 but less than first duty cycle ; movlw 0x0D movwf TMR2 ; update timer clrf TMR0L ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "(portc & 0x6) == 0x0, \"TMR2 put, only change period\"" nop ; loop until CCP5 goes low btfsc PORTG,4 goto $-1 .assert "tmr0 == 0x22, \"TMR2 put, only change period\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x33, \"TMR2 put, only change period\"" nop ; ; Increase TMR2 between first and second duty cycle ; clrf TMR0L movlw 0x1D movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "(portc & 0x6) == 0x2, \"TMR2 put, between duty cycles\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x23, \"TMR2 put, between duty cycles\"" nop ; ; in this test TMR2 > PR2, expect TMR2 to wrap around ; movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf T0CON clrf TMR0L movlw 0x40 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x6F, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop movlw 0x20 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0L ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop movlw 0x10 movwf PR2 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM clrf CCP3CON ; turn off PWM clrf CCP4CON ; turn off PWM .assert "\"*** PASSED 18f6520 PWM test\"" goto $-1 end gpsim-0.30.0/regression/ccp/ccp_877a.stc0000664000076400007640000000006613041763600014621 00000000000000 #set verbose 1 load ccp_877a.cod load ccp_877a.cod gpsim-0.30.0/regression/ccp/ccp.asm0000664000076400007640000001577313041763600014055 00000000000000 list p=16c64 __config _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate ;; the Capture Compare peripherals in a midrange pic (e.g. pic16c64). include "p16c64.inc" cblock 0x20 status_temp,w_temp interrupt_temp failures ;; The capTime 16-bit register is a working register that keeps track ;; of the capture edge. capTimeH, capTimeL temp1,temp2 t1,t2,t3 kz endc cblock 0xa0 status_temp_alias,w_temp_alias endc org 0 goto main org 4 ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp ;; Are peripheral interrupts enabled? btfss INTCON,PEIE goto exit_int bsf STATUS,RP0 movf PIE1 ^ 0x80,W bcf STATUS,RP0 movwf interrupt_temp check_tmr1: btfsc PIR1,TMR1IF btfss interrupt_temp,TMR1IE goto check_ccp1 ;; tmr1 has rolled over bcf PIR1,TMR1IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover check_ccp1: btfsc PIR1,CCP1IF btfss interrupt_temp,CCP1IE goto exit_int bcf PIR1,CCP1IF ; Clear the pending interrupt bsf temp1,1 ; Set a flag to indicate match exit_int: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie main: clrf failures ;Assume success. clrf kz ;kz == Known Zero. ;; disable (primarily) global and peripheral interrupts clrf INTCON ;; ;; CCP test ;; ;; The CCP module is intricately intertwined with the TMR1 ;; module. So first, let's initialize TMR1: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale ;; In this mode, TMR1 will count instruction cycles. clrf T1CON ; clrf PIR1 ; Clear the interrupt/roll over flag ;; Zero TMR1 clrf TMR1L clrf TMR1H ;; Start the timer bsf T1CON,TMR1ON ccp_test1: movlw (1< include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA var1 RES 1 var2 RES 1 var3 RES 1 failures RES 1 status_temp RES 1 w_temp RES 1 interrupt_temp RES 1 GLOBAL var1,var2,var3,failures GLOBAL done ;; The capTime 16-bit register is a working register that keeps track ;; of the capture edge. capTimeH RES 1 capTimeL RES 1 capTimeHb RES 1 capTimeLb RES 1 GLOBAL capTimeH, capTimeL, capTimeHb, capTimeLb temp1 RES 1 temp2 RES 1 t1 RES 1 t2 RES 1 t3 RES 1 kz RES 1 GLOBAL temp1, temp2, t1, t2, t3, kz ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; Simulation Script .sim "node test_node_C" ;# Create an asynchronous stimulus that's 1000 cycles long ;# and attach it to portc bit 2. .sim "stimulus asynchronous_stimulus" .sim "initial_state 0" .sim "start_cycle 0x100" .sim "period 0x400" .sim "{ 0x200, 1}" ; .sim "0x300, 0," ; .sim "0x400, 1," ; .sim "0x600, 0," ; .sim "0x700, 1," ; .sim "0x800, 0}" .sim "name asy1" .sim "end" .sim "attach test_node_C asy1 portc2" ;---------------------------------------------------------------------- ; ******************* INTERRUPT VECTOR LOCATION ******************** ;---------------------------------------------------------------------- INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp ;; Are peripheral interrupts enabled? btfss INTCON,PEIE goto exit_int bsf STATUS,RP0 movf PIE1 ^ 0x80,W bcf STATUS,RP0 movwf interrupt_temp check_tmr1: btfsc PIR1,TMR1IF btfss interrupt_temp,TMR1IE goto check_ccp1 ;; tmr1 has rolled over bcf PIR1,TMR1IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover check_ccp1: btfsc PIR1,CCP1IF btfss interrupt_temp,CCP1IE goto check_ccp2 bcf PIR1,CCP1IF ; Clear the pending interrupt bsf temp1,1 ; Set a flag to indicate match check_ccp2: bsf STATUS,RP0 movf PIE2 ^ 0x80,W bcf STATUS,RP0 movwf interrupt_temp btfsc PIR2,CCP2IF btfss interrupt_temp,CCP2IE goto exit_int bcf PIR2,CCP2IF ; Clear the pending interrupt bsf temp1,2 ; Set a flag to indicate match exit_int: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf failures ;Assume success. clrf kz ;kz == Known Zero. ;; disable (primarily) global and peripheral interrupts clrf INTCON ;; ;; CCP test ;; ;; The CCP module is intricately intertwined with the TMR1 ;; module. So first, let's initialize TMR1: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale ;; In this mode, TMR1 will count instruction cycles. clrf T1CON ; clrf PIR1 ; Clear the interrupt/roll over flag clrf PIR2 ;; Zero TMR1 clrf TMR1L clrf TMR1H ;; Start the timer bsf T1CON,TMR1ON ccp_test1: movlw (1< 5 call ccpWaitForPORTC2_low call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==4), \"*** FAILED CCP 16f877a mode 5\"" nop clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 6 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x10), \"*** FAILED CCP 16f877a mode 6\"" nop clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 7 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x40), \"*** FAILED CCP 16f877a mode 7\"" nop goto test_ccp1_compare ;------------------------------------------------------------------------ ;ccpCaptureTwoEvents ; ; Capture two events for the current CCP setting and return the time ; difference between them ccpCaptureTwoEvents: call ccpWaitForCapture movf CCPR1L,W movwf capTimeLb movf CCPR1H,W movwf capTimeHb call ccpWaitForCapture movf CCPR1L,W movwf capTimeL movf CCPR1H,W movwf capTimeH ; Subtract the time of the most recently captured edge from the previous one movf capTimeLb,W subwf capTimeL,F movf capTimeHb,W skpc incfsz capTimeHb,W subwf capTimeH,F return ;------------------------------------------------------------------------ ;ccpWaitForCapture ; ; Spin loop that polls an interrupt flag that is set whenever a capture ; interrupt triggers. ccpWaitForCapture: clrf t1 ;A 16-bit software timeout counter clrf t2 ccpWaitLoop: ;; The watchdog counter ensures we don't loop forever! call ccpWDCounter ;; ;; when an edge is captured, the interrupt routine will ;; set a flag: ;; btfss temp1,1 goto ccpWaitLoop bcf temp1,1 return ;------------------------------------------------------------------------ ccpWaitForPORTC2_high: btfsc PORTC,2 return call ccpWDCounter goto ccpWaitForPORTC2_high ccpWaitForPORTC2_low: btfss PORTC,2 return call ccpWDCounter goto ccpWaitForPORTC2_high ;------------------------------------------------------------------------ ; ccpWDCounter ; a 16bit watch dog counter is incremented by 1. If it rolls over then we failed. ccpWDCounter: incfsz t1,f return incfsz t2,f return goto failed ;If we get here then we haven't caught anything! ;Either a) there's a gpsim bug or b) the stimulus ;file is incorrect. ; movlw 1 ;This 16-bit software counter ; addwf t1,f ;will time out if there's something wrong, ; rlf kz,w ; addwf t2,f ; skpc ; return ;; ;; Compare ;; ;; Now for the compare mode. test_ccp1_compare: clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf PORTC,2 ;CCP bit is an output bcf STATUS,RP0 ;; Start off the compare mode by setting the output on a compare match ;; ;; ccp = 8 <- Set output on match ;; ccp = 9 <- Clear output on match ;; ccp = 10 <- Just set the ccp1if flag, but don't change the output ;; ccp = 11 <- Reset tmr1 on a match movlw 0x8 movwf CCP1CON ;; clrf PIR1 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR1L movlw 0x12 movwf CCPR1H ;; Clear the interrupt flag clrf temp1 tt3: ;; Stop and clear tmr1 clrf T1CON clrf TMR1L clrf TMR1H ;; Now start it bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: btfss temp1,1 goto $-1 bcf temp1,1 ;; Try the next capture mode incf CCP1CON,F ;; If bit 2 of ccp1con is set then we're through with capture modes ;; (and are starting pwm modes) btfsc CCP1CON,2 goto done_ccp1 goto tt3 done_ccp1: ; goto done .assert "(tmr1h==0) && (tmr1l<0x40), \"*** FAILED CCP 16f877a ccp1con=b no tmr1 reset\"" nop clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf TRISC ^ 0x80, 1 ;CCP bit is an output bsf PIE2 ^ 0x80, CCP2IE bcf STATUS,RP0 ;; Start off the compare mode by setting the output on a compare match ;; ;; ccp = 8 <- Set output on match ;; ccp = 9 <- Clear output on match ;; ccp = 10 <- Just set the ccp1if flag, but don't change the output ;; ccp = 11 <- Reset tmr1 on a match movlw 0x8 movwf CCP2CON ;; clrf PIR2 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR2L movlw 0x0 movwf CCPR2H ;; Clear the interrupt flag clrf temp1 tt4: ;; Stop and clear tmr1 clrf T1CON clrf TMR1L clrf TMR1H ;; Now start it bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: btfss temp1,2 goto $-1 bcf temp1,2 ;; Try the next capture mode incf CCP2CON,F ;; If bit 2 of ccp2con is set then we're through with capture modes ;; (and are starting pwm modes) btfsc CCP2CON,2 goto done_ccp2 goto tt4 done_ccp2: ; ; test running both CCPs in compare mode at the same time ; clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf TRISC, 2 ;CCP bit is an output bcf TRISC, 1 ;CCP bit is an output bsf PIE2, CCP2IE bcf STATUS,RP0 movlw 0x8 movwf CCP2CON movwf CCP1CON ;; clrf PIR2 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR2L movlw 0x0 movwf CCPR2H movlw 0x34 movwf CCPR1L movlw 0x2 movwf CCPR1H ;; Clear the interrupt flag clrf temp1 ;; Now start T1 bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: ccp12_loop1: movf temp1,W btfsc STATUS,Z goto ccp12_loop1 ;; Now confirm that it wasn't CCP1 that happened first .assert "(temp1 & 0x3) != 2, \"*** FAILED CCP 877a test both CCP running\"" nop ;; Wait until the timer reaches 0x300 ccp12_loop2: movf TMR1H,W xorlw 3 btfss STATUS,Z goto ccp12_loop2 ;; and confirm that both CCPs have fired by now .assert "(temp1 == 6), \"*** FAILED CCP 877a test both CCP running\"" nop goto done failed: .assert "\"*** FAILED CCP 877a test\"" incf failures,F goto $ done: .assert "\"*** PASSED CCP 877a test\"" goto $ ; .sim "set verbose 4" end gpsim-0.30.0/regression/ccp/ccp_819.asm0000664000076400007640000002330113041763600014440 00000000000000 ;; ccp_819 ;; The purpose of this program is to test gpsim's ability to simulate ;; the Capture Compare peripherals in a midrange pic (e.g. pic16c64). list p=16f819 include include __CONFIG _WDT_OFF & _CCP1_RB3 errorlevel -302 radix dec ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR failures RES 1 status_temp RES 1 w_temp RES 1 interrupt_temp RES 1 GLOBAL failures GLOBAL done ;; The capTime 16-bit register is a working register that keeps track ;; of the capture edge. capTimeH RES 1 capTimeL RES 1 capTimeHb RES 1 capTimeLb RES 1 GLOBAL capTimeH, capTimeL, capTimeHb, capTimeLb temp1 RES 1 temp2 RES 1 t1 RES 1 t2 RES 1 t3 RES 1 kz RES 1 GLOBAL temp1, temp2, t1, t2, t3, kz ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;; Simulation Script .sim "node test_node_C" ;# Create an asynchronous stimulus that's 1000 cycles long ;# and attach it to portb bit 3. .sim "stimulus asynchronous_stimulus" .sim "initial_state 0" .sim "start_cycle 0x100" .sim "period 0x400" .sim "{ 0x200, 1}" ; .sim "0x300, 0," ; .sim "0x400, 1," ; .sim "0x600, 0," ; .sim "0x700, 1," ; .sim "0x800, 0}" .sim "name asy1" .sim "end" .sim "attach test_node_C asy1 portb3" ;---------------------------------------------------------------------- ; ******************* INTERRUPT VECTOR LOCATION ******************** ;---------------------------------------------------------------------- INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp ;; Are peripheral interrupts enabled? btfss INTCON,PEIE goto exit_int bsf STATUS,RP0 movf PIE1 ^ 0x80,W bcf STATUS,RP0 movwf interrupt_temp check_tmr1: btfsc PIR1,TMR1IF btfss interrupt_temp,TMR1IE goto check_ccp1 ;; tmr1 has rolled over bcf PIR1,TMR1IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover check_ccp1: btfsc PIR1,CCP1IF btfss interrupt_temp,CCP1IE goto exit_int bcf PIR1,CCP1IF ; Clear the pending interrupt bsf temp1,1 ; Set a flag to indicate match exit_int: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start clrf failures ;Assume success. clrf kz ;kz == Known Zero. ;; disable (primarily) global and peripheral interrupts clrf INTCON ;; ;; CCP test ;; ;; The CCP module is intricately intertwined with the TMR1 ;; module. So first, let's initialize TMR1: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale ;; In this mode, TMR1 will count instruction cycles. clrf T1CON ; clrf PIR1 ; Clear the interrupt/roll over flag ;; Zero TMR1 clrf TMR1L clrf TMR1H ;; Start the timer bsf T1CON,TMR1ON ccp_test1: movlw (1< 5 call ccpWaitForPORTC2_low call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==4)" clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 6 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x10)" clrf temp1 ;Clear the software interrupt flag. incf CCP1CON,F ;Next mode --> 7 call ccpWaitForPORTC2_high call ccpCaptureTwoEvents .assert "(capTimeL==0) && (capTimeH==0x40)" goto done ;------------------------------------------------------------------------ ;ccpCaptureTwoEvents ; ; Capture two events for the current CCP setting and return the time ; difference between them ccpCaptureTwoEvents: call ccpWaitForCapture movf CCPR1L,W movwf capTimeLb movf CCPR1H,W movwf capTimeHb call ccpWaitForCapture movf CCPR1L,W movwf capTimeL movf CCPR1H,W movwf capTimeH ; Subtract the time of the most recently captured edge from the previous one movf capTimeLb,W subwf capTimeL,F movf capTimeHb,W skpc incfsz capTimeHb,W subwf capTimeH,F return ;------------------------------------------------------------------------ ;ccpWaitForCapture ; ; Spin loop that polls an interrupt flag that is set whenever a capture ; interrupt triggers. ccpWaitForCapture: clrf t1 ;A 16-bit software timeout counter clrf t2 ccpWaitLoop: ;; The watchdog counter ensures we don't loop forever! call ccpWDCounter ;; ;; when an edge is captured, the interrupt routine will ;; set a flag: ;; btfss temp1,1 goto ccpWaitLoop bcf temp1,1 return ;------------------------------------------------------------------------ ccpWaitForPORTC2_high: btfsc PORTB,3 return call ccpWDCounter goto ccpWaitForPORTC2_high ccpWaitForPORTC2_low: btfss PORTB,3 return call ccpWDCounter goto ccpWaitForPORTC2_high ;------------------------------------------------------------------------ ; ccpWDCounter ; a 16bit watch dog counter is incremented by 1. If it rolls over then we failed. ccpWDCounter: incfsz t1,f return incfsz t2,f return goto failed ;If we get here then we haven't caught anything! ;Either a) there's a gpsim bug or b) the stimulus ;file is incorrect. ; movlw 1 ;This 16-bit software counter ; addwf t1,f ;will time out if there's something wrong, ; rlf kz,w ; addwf t2,f ; skpc ; return ;; ;; Compare ;; ;; Now for the compare mode. ccp_test2: goto done ;;########################################## clrf T1CON clrf TMR1L clrf TMR1H bsf STATUS,RP0 bcf PORTB,3 ;CCP bit is an output bcf STATUS,RP0 ;; Start off the compare mode by setting the output on a compare match ;; ;; ccp = 8 <- Set output on match ;; ccp = 9 <- Clear output on match ;; ccp = 10 <- Just set the ccp1if flag, but don't change the output ;; ccp = 11 <- Reset tmr1 on a match movlw 0x8 movwf CCP1CON ;; clrf PIR1 ;; Initialize the 16-bit compare register: movlw 0x34 movwf CCPR1L movlw 0x12 movwf CCPR1H ;; Clear the interrupt flag clrf temp1 tt3: ;; Stop and clear tmr1 clrf T1CON clrf TMR1L clrf TMR1H ;; Now start it bsf T1CON,TMR1ON ;; Wait for the interrupt routine to set the flag: btfss temp1,1 goto $-1 bcf temp1,1 ;; Try the next capture mode incf CCP1CON,F ;; If bit 2 of ccp1con is set then we're through with capture modes ;; (and are starting pwm modes) btfsc CCP1CON,2 goto done goto tt3 failed: .assert "\"*** FAILED CCP 819 test\"" incf failures,F goto $ done: .assert "\"*** PASSED CCP 819 test\"" goto $ end gpsim-0.30.0/regression/ccp/pwm_877a.asm0000664000076400007640000001361513116676401014657 00000000000000 list p=16f877a include include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the pwm is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR t0_1 RES 1 t0_2 RES 1 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 .assert "\"FAILED 16F877a unexpected interrupt\"" nop check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: clrf CCP1CON ; CCP Module is off clrf CCP2CON ; CCP Module is off clrf TMR2 ; Clear Timer2 clrf TMR0 ; Clear Timer0 movlw 0x1F ; movwf CCPR1L ; Duty Cycle is 25% of PWM Period movlw 0x0F ; movwf CCPR2L ; Duty Cycle is 25% of PWM Period clrf INTCON ; Disable interrupts and clear T0IF bsf STATUS, RP0 ; Bank1 movlw 0x2F ; movwf PR2 ; bcf TRISC, 1 ; Make pin output bcf TRISC, 2 ; Make pin output clrf PIE1 ; Disable peripheral interrupts movlw 0x83 ; Tmr0 internal clock prescaler 16 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf PIR1 ; Clear peripheral interrupts Flags movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 10 movwf CCP1CON ; movlw 0x06 ; Start Timer2 prescaler is 16, just like TMR0 movwf T2CON movlw 0x2C ; PWM mode, 2 LSbs of Duty cycle = 00 movwf CCP2CON ; .assert "ccpr1l != ccpr1h, \"CCPR1H before TRM2 reset\"" nop ; ; The CCP1 interrupt is disabled, ; do polling on the TMR2 Interrupt flag bit ; PWM_Period_Match btfss PIR1, TMR2IF goto PWM_Period_Match clrf TMR0 .assert "ccpr1l == ccpr1h, \"CCPR1H loaded from CCPR1H\"" nop .assert "(portc & 0x6) == 0x6, \"CCP1, CCP2 are high\"" nop ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x0f, \"CCP2 duty cycle\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x1f, \"CCP1 duty cycle\"" nop ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x2f, \"TMR2 period\"" nop ; ; Increase TMR2 but less than first duty cycle ; clrf TMR0 movlw 0x0D movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "(portc & 0x6) == 0x0, \"TMR2 put, only change period\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x23, \"TMR2 put, only change period\"" nop ; ; Increase TMR2 between first and second duty cycle ; clrf TMR0 movlw 0x1D movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "(portc & 0x6) == 0x2, \"TMR2 put, between duty cycles\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x13, \"TMR2 put, between duty cycles\"" nop ; ; in this test TMR2 > PR2, expect TMR2 to wrap around ; bsf STATUS, RP0 ; Bank1 movlw 0x84 ; Tmr0 internal clock prescaler 32 movwf OPTION_REG bcf STATUS, RP0 ; Bank0 clrf TMR0 movlw 0x30 movwf TMR2 ; update timer ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x77, \"CCP1 duty cycle after wrap\"" nop bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x80, \"TMR2 > PR2 causes wrap\"" nop ; ; write reduced PR2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x20\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x20\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x20 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x10, \"TMR2 period PR2 to 0x20\"" nop ; ; write reduced PR2 < TRM2 ; clrf TMR0 ; loop until CCP2 goes low btfsc PORTC,1 goto $-1 .assert "tmr0 == 0x07, \"CCP2 duty cycle PR2 to 0x10\"" nop ; loop until CCP1 goes low btfsc PORTC,2 goto $-1 .assert "tmr0 == 0x0f, \"CCP1 duty cycle PR2 to 0x10\"" nop bsf STATUS, RP0 ; Bank1 movlw 0x10 movwf PR2 bcf STATUS, RP0 ; Bank0 ; ; Wait for end of PWM cycle ; bcf PIR1, TMR2IF btfss PIR1, TMR2IF goto $-1 .assert "tmr0 == 0x88, \"TMR2 period PR2 to 0x10 wraps\"" nop clrf CCP1CON ; turn off PWM clrf CCP2CON ; turn off PWM .assert "\"*** PASSED 16f877a PWM test\"" goto $-1 end gpsim-0.30.0/regression/a2d/0000775000076400007640000000000013117466027012561 500000000000000gpsim-0.30.0/regression/a2d/p18f26k22.asm0000664000076400007640000001265613041763600014453 00000000000000 list p=18f26k22 ; list directive to define processor include ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA 0 temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 a2dIntFlag RES 1 ;LSB is set when an A2D interrupt occurs GLOBAL done GLOBAL a2dIntFlag CONFIG MCLRE=INTMCLR ;------------------------------------------------------------------------ STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: btfsc PIR1,ADIF ;If A2D int flag is not set btfsc PIE1,ADIE ;Or the interrupt is not enabled goto a2dint .assert "\"FAIL 18F26k22 unexpected interrupt\"" nop RETFIE 1 ; Then leave ;; An A/D interrupt has occurred a2dint: bsf a2dIntFlag,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt ExitInterrupt: RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE .sim "p18f26k22.xpos = 192" .sim "p18f26k22.ypos = 48" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 48" .sim "V1.ypos = 24" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 48" .sim "V2.ypos = 204" ; V3 and na1 required for A/D to see voltage bug ? ; RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 48" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "node na1" .sim "attach na1 V3.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" Start: ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; BANKSEL ANSELA movlw 0x01 ; RA0 analog movwf ANSELA clrf TRISA MOVLW 0xff movwf PORTA movf PORTA,W MOVLW 1< include __CONFIG _CONFIG1, _CP_OFF & _WDT_OFF & _INTRC_IO & _PWRTE_ON & _LVP_OFF & _BODEN_OFF & _MCLR_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F88. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F88 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f88.xpos = 72" .sim "p16f88.ypos = 72" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 240" .sim "V1.ypos = 72" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 84" .sim "V2.ypos = 24" ; V3 and node na0 required for A/D to see pin voltage ; this may be a bug RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 240" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V3.pin porta0" .sim "node na1" .sim "attach na1 V1.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA1 is an Analog Input. ; RA0, RA2 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; bsf STATUS,RP0 ;adcon1 is in bank 1 movlw 3 movwf ANSEL ; select AN0, AN1 movwf TRISA movlw (1< ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 a2dIntFlag RES 1 ;LSB is set when an A2D interrupt occurs GLOBAL done GLOBAL a2dIntFlag __CONFIG _CONFIG3H, _MCLRE_OFF_3H ;------------------------------------------------------------------------ STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: btfsc PIR1,ADIF ;If A2D int flag is not set btfsc PIE1,ADIE ;Or the interrupt is not enabled goto a2dint .assert "\"FAIL 18F4321 unexpected interrupt\"" nop RETFIE 1 ; Then leave ;; An A/D interrupt has occurred a2dint: bsf a2dIntFlag,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt ExitInterrupt: RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE .sim "p18f4321.xpos = 192" .sim "p18f4321.ypos = 48" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 48" .sim "V1.ypos = 24" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 48" .sim "V2.ypos = 204" ; V3 and na1 required for A/D to see voltage bug ? ; RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 48" .sim "V3.ypos = 120" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "node na1" .sim "attach na1 V3.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" Start: ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; clrf TRISA MOVLW 0xff movwf PORTA movf PORTA,W MOVLW 1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto inta2d .assert "\"FAILED 16F819 a2d unexpected interupt\"" nop goto check ;; An A/D interrupt has occurred inta2d: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "node na1" .sim "attach na1 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; bsf STATUS,RP0 ;adcon1 is in bank 1 movlw 1 movwf TRISA movlw (1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F873a unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "node na1" .sim "attach na1 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; bsf STATUS,RP0 ;adcon1 is in bank 1 movlw 1 movwf TRISA movlw (1< ; processor specific variable definitions include __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_ON & _MCPU_OFF & _IOFSCS_8MHZ ; The purpose of this test is to check the functioning of the ADC for a P10F222 ; 1> IO pin control ; 2> Channel 0 ; 3> Channel 1 ; 4> Internal reference on channels 2 and 3 ; 5> Sleep stops ADC and sets ADCON0 bits on waking ; Printf Command .command macro x .direct "C", x endm ;********************************************************************** RESET_VECTOR CODE 0x1FF ; processor reset vector ; Internal RC calibration value is placed at location 0xFF by Microchip ; as a movlw k, where the k is a literal value. MAIN CODE 0x000 .sim "p10f222.BreakOnReset = false" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "node na1" .sim "attach na1 V1.pin gpio0 gpio3" .sim "V1.voltage=1.0" .sim "module load pullup V2" .sim "V2.resistance = 1000.0" .sim "node na2" .sim "attach na2 V2.pin gpio1 gpio2" .sim "V2.voltage=2.0" .sim "V1.xpos = 72" .sim "V1.ypos = 36" .sim "V2.xpos = 72" .sim "V2.ypos = 156" ; are we seeing a WDT reset? btfss STATUS,NOT_TO goto after_sleep movlw 0x7f movwf OSCCAL ; update register with factory cal value movlw 0x81 movwf OSCCAL ; update register with factory cal value bcf OSCCAL,0 ; Make sure GP2 is not FOSC4 GOTO START ;================================================================ START ; No wakeup or pullup on pins ; clock T0 high to low, and T0 prescale 1 MOVLW 1< ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 a2dIntFlag RES 1 ;LSB is set when an A2D interrupt occurs GLOBAL done GLOBAL a2dIntFlag ; internal RC OSC PORTA 6,7 I/O __CONFIG _CONFIG1H, _INTIO2_OSC_1H ;------------------------------------------------------------------------ STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: btfsc PIR1,ADIF ;If A2D int flag is not set btfsc PIE1,ADIE ;Or the interrupt is not enabled goto a2dint .assert "\"FAIL 18F1220 unexpected interrupt\"" nop RETFIE 1 ; Then leave ;; An A/D interrupt has occurred a2dint: bsf a2dIntFlag,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt ExitInterrupt: RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE .sim "p18f1220.xpos = 192" .sim "p18f1220.ypos = 120" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 204" .sim "V1.ypos = 36" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 72" .sim "V2.ypos = 156" ; V3 and na1 required for A/D to see voltage bug ? ; RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 72" .sim "V3.ypos = 72" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "node na1" .sim "attach na1 V3.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" Start: .assert "p18f1220.frequency == 31000., \"FALIED 18F1220 a2d default frequency\"" nop movlw 0x70 movwf OSCCON .assert "p18f1220.frequency == 8000000., \"FALIED 18F1220 a2d full rc frequency\"" nop CLRF TRISA MOVLW 0xff MOVWF PORTA .assert "(porta & 0x0f) == 0, \"FALIED 18F1220 a2d analog pins read 0\"" nop CLRF TRISB MOVWF PORTB .assert "(portb & 0x13) == 0, \"FALIED 18F1220 a2d analog pins read 0\"" nop ; RA0 is an Analog Input. ; RA1 - RA6 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1111110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; MOVLW 1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F874a unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "node na1" .sim "attach na1 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; bsf STATUS,RP0 ;adcon1 is in bank 1 movlw 1 movwf TRISA movlw (1< ; processor specific variable definitions include ; Grab some useful macros .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 a2dIntFlag RES 1 ;LSB is set when an A2D interrupt occurs GLOBAL done GLOBAL a2dIntFlag ;------------------------------------------------------------------------ STARTUP CODE 0 bra Start ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location check_TMR0_interrupt: btfsc PIR1,ADIF ;If A2D int flag is not set btfsc PIE1,ADIE ;Or the interrupt is not enabled goto a2dint .assert "\"FAIL 18F452 unexpected interrupt\"" nop RETFIE 1 ; Then leave ;; An A/D interrupt has occurred a2dint: bsf a2dIntFlag,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt ExitInterrupt: RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE .sim "p18f452.xpos = 192" .sim "p18f452.ypos = 48" .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "V1.xpos = 48" .sim "V1.ypos = 36" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "V2.xpos = 48" .sim "V2.ypos = 168" ; V3 and na1 required for A/D to see voltage bug ? ; RRR 5/06 .sim "module load pullup V3" .sim "V3.resistance = 10e6" .sim "V3.xpos = 48" .sim "V3.ypos = 96" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "node na1" .sim "attach na1 V3.pin porta1" .sim "node na3" .sim "attach na3 V2.pin porta3" Start: ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; MOVLW 1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc ADCON0,ADIF goto a2dint .assert "\"p16c71 FAIL unexpected interrupt\"" nop ;; An A/D interrupt has occurred a2dint: bsf t1,0 ;Set a flag to indicate we got the int. bcf ADCON0,ADIF ;Clear the a/d interrupt swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "module load pullup V2" .sim "V2.voltage=2.0" .sim "V2.resistance = 100.0" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "node na1" .sim "attach na1 V2.pin porta3" ;; Let's use the ADC's interrupt clrf INTCON #define FAST_CONVERSION ((1< include __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c71. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA_SHR x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc INTCON,ADIE btfsc PIR1,ADIF goto inta2d .assert "\"FAILED 16F871 unexpected interupt\"" nop goto check ;; An A/D interrupt has occurred inta2d: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt check: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "module library libgpsim_modules" ; Use a pullup resistor as a voltage source .sim "module load pullup V1" .sim "V1.resistance = 100.0" .sim "node na0" .sim "attach na0 V1.pin porta0" .sim "module load pullup V2" .sim "V2.resistance = 100.0" .sim "node na1" .sim "attach na1 V2.pin porta3" ;; Let's use the ADC's interrupt ; RA0 is an Analog Input. ; RA1 - RA5 are all configured as outputs. ; ; Use VDD and VSS for Voltage references. ; ; PCFG = 1110 == AN0 is the only analog input ; ADCS = 110 == FOSC/64 ; ADFM = 0 == 6 LSB of ADRESL are 0. ; bsf STATUS,RP0 ;adcon1 is in bank 1 movlw 1 movwf TRISA movlw (1< ; processor specific variable definitions include ; Grab some useful macros ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 GLOBAL done ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE clrf temp1 ;Assume clrf works... ; bra start failed1: ; a relatively local label bra failed start: ;; Perform some basic tests on some important instructions done: .assert "\"*** PASSED 16bit-core instruction test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED 16bit-core instruction test\"" bra done end gpsim-0.30.0/regression/p18f/reset.asm0000664000076400007640000002404713041763603014440 00000000000000 ; 18f4321 gpsim regression test ; ; The purpose of this test is to verify that the 16bit processors ; is implemented correctly. Here's a list of specific things ; tested: ; ; 1) Reset conditions ; 2) WDT ; 3) Sleep ; 4) Wakeup on PIN change. list p=18f4321 include include ;__CONFIG _CONFIG2H, _WDT_ON_2H radix dec ; Printf Command .command macro x .direct "C", x endm GPR_DATA UDATA ResetSequence RES 1 optionShadow RES 1 w_temp RES 1 status_temp RES 1 temp1 RES 1 GLOBAL optionShadow, ResetSequence GLOBAL temp1 ; Define the reset conditions to be checked. eRSTSequence_PowerOnReset equ 1 eRSTSequence_AwakeMCLR equ 2 eRSTSequence_AwakeWDT equ 3 eRSTSequence_AwakeIO equ 4 eRSTSequence_WDTTimeOut equ 5 eRSTSequence_STKUNF equ 6 eRSTSequence_STKFUL equ 7 ;---------------------------------------------------------------------- ; ********************* STARTUP LOCATION *************************** ;---------------------------------------------------------------------- START CODE 0x000 ; ;############################################################ ;# Create a stimulus to simulate a switch ; .sim "p18f4321.xpos = 84" .sim "p18f4321.ypos = 96" .sim "module lib libgpsim_modules" .sim "module load pulsegen P_INTF" .sim "module load pulsegen P_RBIF" .sim "module load pulsegen RESET" .sim "RESET.initial = 5.0" .sim "RESET.xpos = 84" .sim "RESET.ypos = 36" .sim "P_INTF.clear = 0" ; At cycle 0, .sim "P_INTF.set = 1" .sim "P_INTF.xpos = 240" .sim "P_INTF.ypos = 192" .sim "P_RBIF.clear = 0" ; At cycle 0, .sim "P_RBIF.set = 1" .sim "P_RBIF.xpos = 240" .sim "P_RBIF.ypos = 132" ;############################################################ .sim "node nINTF" .sim "attach nINTF portb0 P_INTF.pin" .sim "node nRBIF" .sim "attach nRBIF portb4 P_RBIF.pin" .sim "node nRESET" ; .sim "attach nRESET p16f84.MCLR RESET.pin" .sim "attach nRESET MCLR RESET.pin" ;############################################################ .sim "symbol resetCounter=1" ; NOT_GPWU = 0 - Enable wakeup if I/O pins 0,1, or 3 change states ; NOT_GPPU = 1 - Disable weak pullups on I/O pins 0,1, and 3 ; TOCS = 0 - Let the clock source for TMR0 be the internal fosc/4 ; TOSE = 0 - don't care - TMR0 source edge. ; PSA = 1 - assign Prescale to the WDT ; PS2:0 = 000 - prescale = 2^0=1 .sim "optionShadow=8" ; PSA=1 .sim "ResetSequence=0" .sim ".BreakOnReset = false" .sim "p18f4321.frequency=100000" ; Set a cycle break point far in the future in case the resets fail. .sim "break c 0x1000000" RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x008 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp check_rbi: btfsc INTCON,RBIF btfss INTCON,RBIE goto check_int ; bsf temp5,1 ;Set a flag to indicate rb4-7 int occured bcf INTCON,RBIF movf PORTB,w check_int: btfsc INTCON,INT0IF btfss INTCON,INT0IE goto check_t0 ; bsf temp5,0 ;Set a flag to indicate rb0 int occured bcf INTCON,INT0IF check_t0: btfsc INTCON,T0IF btfss INTCON,T0IE goto exit_int ;; tmr0 has rolled over bcf INTCON,T0IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie bSWITCH equ 0 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start .assert "(trisa&0x1f)==0x1f, \"*** FAILED 18f4321 reset bad TRISA\"" nop .assert "trisb==0xff, \"*** FAILED 18f4321 reset bad TRISB\"" nop .assert "trisc==0xff, \"*** FAILED 18f4321 reset bad TRISC\"" nop .assert "trisd==0xff, \"*** FAILED 18f4321 reset bad TRISD\"" nop .assert "(trise&0x03)==0x03, \"*** FAILED 18f4321 reset bad TRISE\"" nop ; OPTION register setup MOVF optionShadow,W ;optionShadow is initialized by the gpsim script ; GPIO setup ; If this is a PowerOn reset, then the state of the GPIO output register ; is unknown. If this is not a PowerOn reset then the GPIO pins have ; the same state they had prior to the reset. ; ; TRIS register setup - The I/O pins are always configured as Inputs after ; any reset. MOVLW (1< /MCLR while sleeping ; -or- Interrupt wake-up from sleep btfsc STKPTR,STKUNF ; Stack undeflow has occured goto stack_underflow btfsc STKPTR,STKFUL ; Stack overflow has occured goto stack_overflow goto PowerOnReset ;/TO=1, /PD=1 ==> Power has just been applied TO_is_low BTFSS RCON,NOT_PD goto AwakeWDT ;/TO=0, /PD=0 ==> WDT while sleeping goto WDTTimeOut ;/TO=0, /PD=1 ==> WDT while not sleeping BTFSC INTCON, RBIF ;Did we just wake up from SLEEP due goto AwakeIO ;to a change in the I/O pins? ;======================================================================== ; ; PowerOnReset ; ;======================================================================== PowerOnReset: movf ResetSequence,W XORLW eRSTSequence_AwakeMCLR skpnz goto to_underflow movf PORTB,W ;Clear RBIF .assert "(intcon&1)==0, \"*** FAILED to clear INTCON\"" nop .assert "resetCounter==1,\"*** FAILED Power On Reset\"" nop MOVLW eRSTSequence_PowerOnReset MOVWF ResetSequence CLRWDT .command "resetCounter = resetCounter+1" SLEEP ; The WDT should cause a reset. So we shouldn't fall through ; (note, the instruction after the SLEEP should not be executed). ; RRR WDT will not cause a reset but will fall through nop .assert "(trisa&0x1f)==0x00, \"*** FAILED 18f4321 WDT sleep bad TRISA\"" nop .assert "trisb==0x11, \"*** FAILED 18f4321 WDT sleep bad TRISB\"" nop .assert "trisc==0x00, \"*** FAILED 18f4321 WDT sleep bad TRISC\"" nop .assert "trisd==0x00, \"*** FAILED 18f4321 WDT sleep bad TRISD\"" nop .assert "(trise&0x03)==0x00, \"*** FAILED 18f4321 WDT sleep bad TRISE\"" nop ;RRR .command "resetCounter = resetCounter+1" nop ;======================================================================== ; ; AwakeWDT - WDT timed out while we were sleeping. ; ;======================================================================== AwakeWDT: .assert "resetCounter==2,\"*** FAILED WDT Reset\"" nop MOVLW eRSTSequence_AwakeWDT MOVWF ResetSequence .command "resetCounter = resetCounter+1" CLRWDT ; loop until WDT times out here: goto here ;======================================================================== ; ; WDTTimeOut - WatchDog timer timed out while we were awake. ; ;======================================================================== WDTTimeOut: .assert "resetCounter==3,\"*** FAILED WDT timeout\"" nop MOVLW eRSTSequence_WDTTimeOut MOVWF ResetSequence CLRWDT .command "P_RBIF.clear = cycles+100" nop ; Keep interrupts enabled, but turn on RBIE. Changes on ; RB4-RB7 should wake us from sleep MOVLW 1< ; processor specific variable definitions include ; Grab some useful macros radix dec CONFIG XINST=ON ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- GPR_DATA UDATA temp RES 1 temp1 RES 1 temp2 RES 1 failures RES 1 dataStack RES 32 dataStackEnd RES 1 GLOBAL done GLOBAL temp1 GLOBAL dataStack GLOBAL dataStackEnd ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE bra start ;------------------------------------------------------------ ; function vectors ; The function vectors are branch instructions to functions ; that reside at addresses for which PC>256. They're used to ; make indirect calls with the extended CALLW instruction. vf1 bra f1 vf2 bra f2 vf3 bra f3 vf4 bra f4 vf5 bra f5 start: clrf temp1 ;Assume clrf works... ; lfsr 0,0 lfsr 1,0 lfsr 2,0x1ff clrf BSR addfsr 0,15 .assert "(fsr0l==15) && (fsr0h==0)" nop addfsr 1,15 .assert "(fsr1l==15) && (fsr1h==0)" nop addfsr 2,15 ; 0x1ff + 15 = 0x20e .assert "(fsr2l==0x0e) && (fsr2h==2)" nop subfsr 0,10 .assert "(fsr0l==5) && (fsr0h==0)" nop subfsr 1,10 .assert "(fsr1l==5) && (fsr1h==0)" nop subfsr 2,15 ; 0x20e - 15 = 0x1ff .assert "(fsr2l==0xff) && (fsr2h==1)" nop lfsr 2,0x80 movlw 0x10 movwf temp1 addwf [1],W .assert "W == 0x20" nop addwfc [1],W bsf [1],0 .assert "temp1 == 0x11" nop clrf [1] .assert "temp1==0" nop setf [1] .assert "temp1 == 0xff" nop call test_addulnk .assert "(fsr2l==0x81) && (fsr2h==0)" nop movlw 0xf0 andwf [0],W .assert "W==0xf0" nop bcf [0],0 .assert "temp1==0xfe" nop btfsc [0],0 goto failed btfss [0],1 goto failed btg [0],0 .assert "temp1==0xff" nop comf [0],F .assert "temp1==0x00" nop movlw 0 cpfseq [0] goto failed nop decf [0],F .assert "temp1==0xff" nop cpfsgt [0] goto failed cpfslt [0] goto $+8 goto failed decfsz [0],W goto $+8 goto failed dcfsnz [0],W goto failed incfsz [0],F goto failed infsnz [0],F goto failed iorwf [0],W .assert "W==0xff" nop movf [0],W .assert "W==0x01" nop movlw 2 movwf [0] mulwf [0] .assert "(prodl==4) && (prodh==0)" nop negf [0] .assert "temp1==0xfe" nop rlcf [0],W .assert "W==0xfc" nop rlncf [0],W .assert "W==0xfd" nop rrcf [0],W .assert "W==0xff" nop rrncf [0],W .assert "W==0x7f" nop subfwb [0],W .assert "W==0x80" nop subwfb [0],W .assert "W==0x7d" nop swapf [0],F .assert "temp1==0xef" nop tstfsz [0] goto $+8 goto failed xorwf [0],W .assert "W==0x92" nop ;; Also test that addfsr followed immediately by and INDF access works clrf dataStackEnd movlw 0x55 lfsr 1,dataStack addfsr 1,32 movwf POSTDEC1 .assert "dataStackEnd == 0x55" nop ;; Test postinc and addfsr interaction lfsr 1,0x80 movlw 0xBB movwf POSTINC1 addfsr 1,1 .assert "(fsr1h == 0x00) && (fsr1l == 0x82)" ;; Test postinc and subfsr interaction lfsr 1,0x80 movlw 0xBB movwf POSTINC1 subfsr 1,1 .assert "(fsr1h == 0x00) && (fsr1l == 0x80)" ;; CALLW test ;; This test makes 5 indirect calls using the callw instruction. ;; There is a function vector table in low memory that redirects ;; calls to high memory. The reason for this table is to allow the ;; destination address for the CALLW instruction to fit entirely ;; in the WREG clrf PCLATU clrf PCLATH movlw 5 movwf temp1 ;temp1 is used as the index into nop ;function vector table. callw_loop: rlncf temp1,W ;program memory indexes through even addresses addlw vf1-2 ;offset to the start of the function vectors. callw ;Make the indirect call decfsz temp1,F ;next vector bra callw_loop ;; Test interaction of postdec and movsf lfsr 2,dataStack+1 movlw 0xAA movwf POSTDEC2 movsf [1],temp1 .assert "temp1 == 0xAA" nop ;; lfsr 2, dataStack+10 clrf dataStack pushl 0x42 .assert "(fsr2l == ((&dataStack)+10-1))" nop movsf [1],WREG .assert "W == 0x42" nop ;; Test for the mixed-mode-repeat condition c.f. bug #3309120 pushl 0x01 pushl 0x02 pushl 0x03 movlw 3 movff PLUSW2,POSTDEC2 movff PLUSW2,POSTDEC2 pushl 0x04 pushl 0x05 .assert "(fsr2l == ((&dataStack)+10-8))" nop movsf [1],WREG .assert "W == 0x05" nop movss [1],[3] .assert "(*(fsr2l+1))==(*(fsr2l+3))" nop bra done ;------------------------------------------------------------ ; CALLW functions - here are 5 functions that are called indirectly ; by the callw instruction. All they do is return. However, the assertion ; verifies that the index (temp1) used to calculate the address of the ; indirect call is correct. f1: .assert "temp1==1" return f2: .assert "temp1==2" return f3: .assert "temp1==3" return f4: .assert "temp1==4" return f5: .assert "temp1==5" return failed1: ; a relatively local label bra failed ;; Perform some basic tests on some important instructions done: .assert "\"*** PASSED 16bit-core extended instruction test\"" bra $ failed: movlw 1 movwf failures .assert "\"*** FAILED 16bit-core extended instruction test\"" bra done test_addulnk: addulnk 1 ; should do return end gpsim-0.30.0/xpms/0000775000076400007640000000000013117465763010730 500000000000000gpsim-0.30.0/xpms/bullet.xpm0000664000076400007640000000163213041763637012664 00000000000000/* XPM */ static char * bullet_xpm[] = { "16 16 26 1", " c #FFFFFFFFFFFF", ". c #000000000000", "X c #0000E38D0000", "o c #0000EBAD0000", "O c #0000F7DE0000", "+ c #0000FFFF0000", "@ c #0000CF3C0000", "# c #0000D75C0000", "$ c #0000B6DA0000", "% c #0000C30B0000", "& c #0000A2890000", "* c #00009A690000", "= c #0000AEBA0000", "- c #00008E380000", "; c #000086170000", ": c #000079E70000", "> c #000071C60000", ", c #000065950000", "< c #000059650000", "1 c #000051440000", "2 c #000045140000", "3 c #00003CF30000", "4 c #000030C20000", "5 c #000028A20000", "6 c #00001C710000", "7 c #000014510000", " ...... ", " .XooO++. ", " ..@@@#XoO+.. ", " .$$$$$%@#XO++. ", " .&&*&&=$%@XO+. ", ".*-;;;-*&=%@XO+.", ".;:>>>:;-&=%#o+.", ".>,<<<,>:-&$@XO.", ".<12321<>;*=%#o.", ".1345431,:-&$@o.", ".2467642<>;&$@X.", " .57.753<>;*$@. ", " .467642<>;&$@. ", " ..5431,:-&.. ", " .21<>;*. ", " ...... "}; gpsim-0.30.0/xpms/stopp.xpm0000664000076400007640000000052413041763637012541 00000000000000/* XPM */ static const char * stopp_xpm[] = { "14 14 2 1", " c None", ". c #0000FF", " ..", " ...", " ... ", " ... ", " ... ", " ... ", " ... ", " ... ", " ... ", " ... ", " ... ", " ... ", " ...", " .."}; gpsim-0.30.0/xpms/font.xpm0000664000076400007640000000162613041763637012346 00000000000000/* XPM */ static char * font_xpm[] = { "26 26 3 1", " c #None", ". c #000000000000", "X c #000000000000", " ", " ", " ", " . ", " ... ", " ... ", " ..... ", " ..... ", " .. .... ", " .. .... ", " .. .... ", " ......... ", " ........... ", " .. .... ", " .. .... ", " .. .... ", " ..... ....... ", " ", " ", " ", " XXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXX ", " ", " ", " "}; gpsim-0.30.0/xpms/Makefile.in0000664000076400007640000003144113117441635012710 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = xpms ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = break.xpm bullet.xpm center.xpm font_large.xpm \ font.xpm left.xpm paint.xpm pc.xpm right.xpm startp.xpm \ stopp.xpm canbreak.xpm MOSTLYCLEANFILES = *~ CLEANFILES = *~ DISTCLEANFILES = *~ MAINTAINERCLEANFILES = *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xpms/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu xpms/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/xpms/Makefile.am0000664000076400007640000000036213041763637012702 00000000000000EXTRA_DIST = break.xpm bullet.xpm center.xpm font_large.xpm \ font.xpm left.xpm paint.xpm pc.xpm right.xpm startp.xpm \ stopp.xpm canbreak.xpm MOSTLYCLEANFILES = *~ CLEANFILES = *~ DISTCLEANFILES = *~ MAINTAINERCLEANFILES = *~ gpsim-0.30.0/xpms/paint.xpm0000775000076400007640000000215413041763637012513 00000000000000/* XPM */ static char *paint_xpm [] = { "26 26 6 1", ". c #None", "a c #000000000000", "e c #929292929292", "g c #DBDBDBDBDBDB", "h c #FFFFFFFFFFFF", "X c #FFFFFFFFFFFF", "............................", "............................", "............ee..............", "...........eeee.............", "..........eeggee............", "..........eegaee............", "..........eeahee............", "..........aahheeaa..........", "..........ahhgeegaaa........", ".........ahhghaeggaaa.......", "........ahhghagaggeaaa......", ".......ahhghggaggeeaaae.....", "......ahhghgggggeeaaaae.....", "......ahghgggggeeaeaaae.....", ".......ahgggggeeaeeaaae.....", "........ahgggeeaee.aaae.....", ".........aggeeaee..aaee.....", "..........aeeaee...aee......", "...........aaee.....e.......", "............ee..............", "............................", ".....XXXXXXXXXXXXXXXXXX....." ".....XXXXXXXXXXXXXXXXXX....." ".....XXXXXXXXXXXXXXXXXX....." ".....XXXXXXXXXXXXXXXXXX....." "............................", "............................", }; gpsim-0.30.0/xpms/center.xpm0000775000076400007640000000173713041763637012666 00000000000000/* XPM */ static char *center_xpm [] = { "26 26 2 1", ". c #None", "X c #000000000000", " ", " ", " ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXX ", " XXXXXXXXXXXX ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXX ", " XXXXXXXXXXXX ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXX ", " XXXXXXXXXXXX ", " ", " ", " ", " ", " ", }; gpsim-0.30.0/xpms/font_large.xpm0000664000076400007640000000166413041763637013522 00000000000000/* XPM */ static char * font_xpm[] = { "26 26 3 1", " c #None", ". c #000000000000", "X c #000000000000", " ", " . ", " . ", " ... ", " ... ", " ..... ", " ..... ", " ..... ", " .. .... ", " .. .... ", " .. .... ", " .. .... ", " .. .... ", " ......... ", " ........... ", " .. .... ", " .. .... ", " .. .... ", " .. .... ", " .... ...... ", " ", " XXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXX ", " ", " ", " "}; gpsim-0.30.0/xpms/canbreak.xpm0000664000076400007640000000054013041763637013140 00000000000000/* XPM */ static const char * canbreak_xpm[] = { "14 14 3 1", " c None", ". c gray", "X c white", " ", " ....... ", " ......... ", " ........... ", " ...XXXXX.... ", " ...XXXXX.... ", " ...XXXXX.... ", " ...XXXXX.... ", " ...XXXXX.... ", " ........... ", " ......... ", " ....... ", " ", " "}; gpsim-0.30.0/xpms/pc.xpm0000664000076400007640000000052013041763637011772 00000000000000/* XPM */ static const char * pc_xpm[] = { "14 14 2 1", " c None", ". c #009B1C", " ", " ", " . ", " .. ", " .. ", " ... ", "............ ", "............. ", "............ ", " ... ", " .. ", " .. ", " . ", " "}; gpsim-0.30.0/xpms/startp.xpm0000664000076400007640000000052413041763637012711 00000000000000/* XPM */ static const char * startp_xpm[] = { "14 14 2 1", " c #0000FF", ". c None", " ............", " ...........", ". ..........", ".. .........", "... ........", ".... .......", "..... ......", "..... ......", ".... .......", "... ........", ".. .........", ". ..........", " ...........", " ............"}; gpsim-0.30.0/xpms/break.xpm0000664000076400007640000000053413041763637012461 00000000000000/* XPM */ static const char * break_xpm[] = { "14 14 3 1", " c None", ". c red", "X c white", " ..... ", " ....... ", " ......... ", " .....X..... ", "....XXXXX.... ", "....XXXXX.... ", "...XXXXXXX... ", "....XXXXX.... ", "....XXXXX.... ", " .....X..... ", " ......... ", " ....... ", " ..... ", " "}; gpsim-0.30.0/xpms/right.xpm0000775000076400007640000000167413041763637012523 00000000000000/* XPM */ static char *right_xpm [] = { "26 26 2 1", ". c #None", "X c #000000000000", " ", " ", " ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXX ", " XXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXX ", " XXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXX ", " XXXXXXXXXXXXX ", " ", " ", " ", " ", }; gpsim-0.30.0/xpms/left.xpm0000775000076400007640000000173513041763637012336 00000000000000/* XPM */ static char *left_xpm [] = { "26 26 2 1", ". c #None", "X c #000000000000", " ", " ", " ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXX ", " XXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXX ", " XXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXXXXXXX ", " XXXXXXXXXXXXXXXXXX ", " ", " XXXXXXXXXXXXX ", " XXXXXXXXXXXXX ", " ", " ", " ", " ", " ", }; gpsim-0.30.0/m4/0000775000076400007640000000000013117465757010264 500000000000000gpsim-0.30.0/m4/ltoptions.m40000644000076400007640000003426213026757070012475 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) gpsim-0.30.0/m4/libtool.m40000644000076400007640000112530613026757070012107 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS gpsim-0.30.0/m4/ltsugar.m40000644000076400007640000001044013026757070012113 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) gpsim-0.30.0/m4/ltversion.m40000644000076400007640000000127313026757070012463 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) gpsim-0.30.0/m4/lt~obsolete.m40000644000076400007640000001377413026757070013021 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) gpsim-0.30.0/README0000664000076400007640000001520413041763641010533 00000000000000. gpsim - Gnu Pic Simulator, a simulator for Microchip's PIC microcontrollers. http://gpsim.sourceforge.net/ Please see the INSTALL.gpsim file to get instructions on how to install gpsim. Please see the TODO file to get an idea of the current status and a little background on how the code works. Please see the HISTORY file to see how gpsim has evolved. Please see the README.EXAMPLES file for information about the examples. Please see the PROCESSORS file to see a list of supported processors. Please see doc/gpsim.lyx or doc/gpsim.ps for the latest documentation Gpsim is licensed under GPLv2+ with the exception of eXdbm/ src/ and modules/ files which are under LGPLv2+. Please see COPYING and COPYING.LESSER for the terms of these licenses. System Requirements: -------------------- gpsim runs under Linux and Windows. For Windows, all non-standard dll's are packaged with gpsim. So the standard install should run. Borut Razem has the latest gpsim installer on his web page: http://gpsim.sourceforge.net/gpsimWin32/gpsimWin32.html For Linux, it's assumed that you have GTK+ 2.x and gtk+extra >= 2.1.2 or a patched version of gtk+extra-2.1.1 installed. Installing: ---------- See the INSTALL.gpsim file. Invoking: --------- Run gpsim by typing: $ gpsim --help gpsim - the GNUPIC simulator version: 0.22.0 type help for help Usage: lt-gpsim [OPTION...] -p, --processor= processor (e.g. -pp16c84 for the 'c84) -c, --command=STRING startup command file -s, --symbol=STRING .cod symbol file -L, -- colon separated list of directories to search. -v, --version gpsim version -i, --cli command line mode only -d, --icd=STRING use ICD (e.g. -d /dev/ttyS0). Examples: gpsim -s myprog.cod <-- loads a symbol file gpsim -p p16f877 myprog.hex <-- select processor and load hex gpsim -c myscript.stc <-- loads a script Help options: -?, --help Show this help message --usage Display brief usage message for example: $gpsim -pp16c61 pichexfile.hex will start the simulator, select a 'c61 as the target and load the program memory with pichexfile.hex hex file. There are several pic source files in the /examples subdirectory. or (preferred) $gpsim -s piccodfile.cod # note, you don't need to specify the processor for .cod files Once started, a very simple command line prompt will process your requests: gpsim> help ! Shell out to another program or module's command line interface attach Attach stimuli to nodes break Set a break point clear Remove a break point disassemble Disassemble the current cpu dump Display either the RAM or EEPROM frequency Set the clock frequency help Type help "command" for more help on a command icd ICD command. list Display source and list files load Load either a hex,command, or .cod file log Log/record events to a file macro macro definition and listing module Select & Display modules node Add or display stimulus nodes processor Select & Display processors quit Quit gpsim reset Reset all or parts of the simulation run Execute the pic program set display and control gpsim behavior flags step Execute one or more instructions. stimulus Create a stimulus symbol Add or display symbols trace Dump the trace history version Display the gpsim's version x examine and/or modify memory More help is available for each command by typing help "command". For example, help break prints this: gpsim> help break The 'break' command can be used to examine or set breakpoints. gpsim supports execution style breaks, register access breaks, complex expression breaks, attribute breaks, and other special breaks. Program Memory breaks: break e|r|w ADDRESS [expr] Halts when the address is executed, read, or written. The ADDRESS can be a symbol or a number. If the optional expr is specified, then it must evaluate to true before the simulation will halt. Register Memory breaks: break r|w REGISTER [expr] Halts when 'REGISTER' is read or written and the optional expression evaluates to true. break r|w boolean_expression older style to be deprecated...Cycle counter breaks: break c VALUE Halts when the cycle counter reaches 'VALUE'. Attribute breaks: break attribute Arms the breakpoint condition for those attributes that support breaks. For example, the stopwatch (help stopwatch) attribute can cause a break. Miscellaneous breaks: break so # halts on stack overflow. break su # halts on stack underflow. break wdt # halts on Watch Dog Timer timeout. Expressions: The conditional expressions mentioned above are syntactically similar to C's expressions. Examples: break # display all of the break points break e 0x20 # set an execution break point at address 0x20 break w reg1 == 0 # break if a zero is written to register reg1 break w reg2 & 0x30 == 0xf0 # break if '3' is written to the # upper nibble or reg2 break w reg3 (reg4 > 45) # break if reg4>45 while writing to reg3 break c 1000000 # break on the one million'th cycle The cli is available even when the gui is used. Major Features: -------------- Standard simulator stuff: o Breakpoints - execution, read and write memory, wdt, o Assertions o single stepping o step over o run until break o disassemble o dump memory/eeprom o Trace o stimulus files - analog and digital o configuration files o symbolic debugging Gui stuff: o Register viewer o Source file viewer o Program opcode window o Symbol viewer o Watch window o Pinout/breadboard window o Stack Viewer o Scope Viewer o Oscilloscope Viewer gpsim specific o Simulate multiple processors (not fully supported) o Dynamically loaded modules Peripherals supported: o eeprom o WDT o TMR0 o I/O Ports o TMR1 o TMR2 o CCP o PWM o A/D o UART o I2C BUGS: ---- I'm absolutely certain there are bugs. If you find one, send it to me at either scott@dattalo.com or post it to the gnupic mailing list: mailto:gnupic@linuxhacker.org Finally, see the file Contributions for people who have submitted suggestions and patches. NOTES: ----- gtk+extra2 is needed by gpsim. Please see the gpsim web page for more info gpsim-0.30.0/INSTALL0000644000076400007640000003661012734477075010721 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command `./configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX `make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as `configure' are involved. Use GNU `make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. gpsim-0.30.0/eXdbm/0000775000076400007640000000000013117465760010775 500000000000000gpsim-0.30.0/eXdbm/Makefile.orig0000664000076400007640000000302113041763641013303 00000000000000 .SUFFIXES: .SUFFIXES: .c .o CC = gcc AR = ar cru RANLIB = ranlib #CCFLAGS = -g -Wall CCFLAGS = -O3 -Wall CHECKOUT = co DEPEND = gccmakedep DATE = $$(date +%m%d%y) LFLAGS = -lm LIBSRCS = hash.c parse.c misc.c eXdbm.c LIBOBJS = hash.o parse.o misc.o eXdbm.o LIBINC = hash.h parse.h eXdbm.h eXdbmErrors.h eXdbmTypes.h misc.h INCPATH = ./ INCDIR = /usr/local/include/ LIBDIR = /usr/local/lib/ DOCDIR = /usr/local/doc/eXdbm LIBNAME = libeXdbm.a all : depend lib examples build : getheaders depend lib examples getheaders : $(LIBINC) $(CHECKOUT) $(LIBINC) depend : $(LIBSRCS) $(DEPEND) $(LIBSRCS) lib : $(LIBOBJS) $(AR) $(LIBNAME) $(LIBOBJS) $(RANLIB) $(LIBNAME) examples : test1 test2 test3 test1 : test1.o test1.cfg.orig cp test1.cfg.orig test1.cfg $(CC) $< $(LIBNAME) $(LFLAGS) -o $@ test2 : test2.o test1.cfg.orig cp test1.cfg.orig test1.cfg $(CC) $< $(LIBNAME) $(LFLAGS) -o $@ test3 : test3.o test1.cfg.orig cp test1.cfg.orig test1.cfg $(CC) $< $(LIBNAME) $(LFLAGS) -o $@ .c.o : $(CC) -I$(INCPATH) -c $(CCFLAGS) -o $@ $< archive : $(LIBINC) $(LIBSRCS) test1.c test2.c test3.c test1.cfg.orig eXdbm.txt cp Makefile.orig Makefile cp test1.cfg.orig test1.cfg tar cvzf eXdbm-beta-1.0b1.tar.gz $(LIBINC) $(LIBSRCS) test1.c test2.c test3.c test1.cfg eXdbm.txt install : cp eXdbmErrors.h eXdbmTypes.h eXdbm.h $(INCDIR) cp libeXdbm.a $(LIBDIR) mkdir $(DOCDIR) cp eXdbm.txt $(DOCDIR) @echo "installation done" clean : rm -f *.o *~ realclean : clean rm -f *.a test1 test1.cfg ; cp Makefile.orig Makefile gpsim-0.30.0/eXdbm/README.gpsim0000664000076400007640000000140713041763641012710 00000000000000eXdbm was not developed by the gpsim developers. It is only included with the gpsim distribution to make it easier to build gpsim. We do not intend to maintain or enhance this package in anyway specific to gpsim. If you find a bug in here, please contact either us or the eXdbm developers and we'll make sure the next version is fixed. gpsim version 0.20.14 Starting with this version, eXdbm will now be distributed as part of gpsim. The purpose for this is to simplify install issues that gpsim users have had with eXdbm in the past. Also, a few minor bugs have been fixed with eXdbm by the gpsim development team. Unfortunately, the original authors do not appear to be supporting eXdbm any longer (hmm, that's probably a hint). eXdbm, like gpsim, is licensed under GPL. gpsim-0.30.0/eXdbm/AUTHORS0000664000076400007640000000000013041763641011746 00000000000000gpsim-0.30.0/eXdbm/test2.c0000664000076400007640000000761613041763641012127 00000000000000 /* $Id: test2.c 230 2002-04-15 22:03:02Z linas $ */ /***** * test2.c : eXdbm example * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef lint static char vcid[] = "$Id: test2.c 230 2002-04-15 22:03:02Z linas $"; #endif /* lint */ #include #include "eXdbm.h" extern TDbmDbList *DbmDbList; int main(void) { DB_ID dbid; int ret; printf(" \n*************************************************************"); printf(" \n***** Test2.c : read the file test1.cfg, and rewrite it *****"); printf(" \n*************************************************************\n\n"); printf("**** Database manager initialization *****\n\n"); ret = eXdbmInit(); if(ret==-1) { fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("**** Opening database in file test1.cfg ****\n\n"); ret = eXdbmOpenDatabase("test1.cfg", &dbid); if(ret==-1) { fprintf(stderr, "\nParsing databases aborted line %d", eXdbmLastLineParsed()); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } fprintf(stderr, "%d lines parsed \n\n", eXdbmLastLineParsed()); printf("**** Updating database file ****\n\n"); ret = eXdbmUpdateDatabase(dbid); if(ret == -1) { fprintf(stderr, "\nUpdating databases aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("**** Make a backup copy of the database in test1.cfg.backup ****\n\n"); ret = eXdbmBackupDatabase(dbid, "test1.cfg.backup"); if(ret == -1) { fprintf(stderr, "\nDatabase Backup aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("**** Closing database (no update) ****\n\n"); ret = eXdbmCloseDatabase(dbid, 0); printf("**** Try to reload the database ****\n\n"); ret = eXdbmOpenDatabase("test1.cfg", &dbid); if(ret==-1) { fprintf(stderr, "\nParsing databases aborted line %d", eXdbmLastLineParsed()); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } fprintf(stderr, "%d lines parsed \n\n", eXdbmLastLineParsed()); printf("**** Reloading the database (no update) ****\n\n"); ret = eXdbmReloadDatabase(&dbid, 0); if(ret == -1) { fprintf(stderr, "\nReloading database aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("**** Reloading the database (with update) ****"); ret = eXdbmReloadDatabase(&dbid, 1); if(ret == -1) { fprintf(stderr, "\nReloading database aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("\n\n**** Closing the database (with update) ****\n\n"); ret = eXdbmCloseDatabase(dbid, 1); if(ret == -1) { fprintf(stderr, "\nClosing database aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("****** eXDbm exit without error *****\n\n"); return(0); } gpsim-0.30.0/eXdbm/Makefile.in0000664000076400007640000005426313117441634012766 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = eXdbm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(gpsim_eXdbminclude_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(gpsim_eXdbmincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsim_eXdbm_la_DEPENDENCIES = am_libgpsim_eXdbm_la_OBJECTS = hash.lo parse.lo misc.lo eXdbm.lo libgpsim_eXdbm_la_OBJECTS = $(am_libgpsim_eXdbm_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgpsim_eXdbm_la_SOURCES) DIST_SOURCES = $(libgpsim_eXdbm_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(gpsim_eXdbminclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp AUTHORS \ COPYING COPYING.LIB ChangeLog INSTALL NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim_eXdbm.la gpsim_eXdbmincludedir = $(includedir)/eXdbm libgpsim_eXdbm_la_SOURCES = hash.c parse.c misc.c eXdbm.c \ hash.h parse.h misc.h gpsim_eXdbminclude_HEADERS = eXdbm.h eXdbmErrors.h eXdbmTypes.h libgpsim_eXdbm_la_LIBADD = @X_LDFLAGS@ EXTRA_DIST = \ Makefile.orig README LICENSE COPYING.LIB eXdbm.txt \ test1.c test2.c test3.c test1.cfg.orig test2.cfg \ README.gpsim all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu eXdbm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu eXdbm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgpsim_eXdbm.la: $(libgpsim_eXdbm_la_OBJECTS) $(libgpsim_eXdbm_la_DEPENDENCIES) $(EXTRA_libgpsim_eXdbm_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libgpsim_eXdbm_la_OBJECTS) $(libgpsim_eXdbm_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eXdbm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-gpsim_eXdbmincludeHEADERS: $(gpsim_eXdbminclude_HEADERS) @$(NORMAL_INSTALL) @list='$(gpsim_eXdbminclude_HEADERS)'; test -n "$(gpsim_eXdbmincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(gpsim_eXdbmincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(gpsim_eXdbmincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(gpsim_eXdbmincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(gpsim_eXdbmincludedir)" || exit $$?; \ done uninstall-gpsim_eXdbmincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(gpsim_eXdbminclude_HEADERS)'; test -n "$(gpsim_eXdbmincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(gpsim_eXdbmincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(gpsim_eXdbmincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-gpsim_eXdbmincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-gpsim_eXdbmincludeHEADERS \ uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-gpsim_eXdbmincludeHEADERS install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ uninstall-gpsim_eXdbmincludeHEADERS uninstall-libLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/eXdbm/Makefile.am0000664000076400007640000000167013041763641012750 00000000000000## Process this file with automake to produce Makefile.in ## T. Scott Dattalo - created this makefile so that eXdbm ## could be packaged with the gpsim distribution. The source ## code was unchanged except for the following minor change: ## ## --- misc.h Mon Jan 17 20:25:24 2000 ## +++ misc.h~ Sat Dec 27 13:46:53 1997 ## @@ -35,7 +35,7 @@ ## #define MISC_H ## ## #include ## -#include "eXdbmTypes.h" ## +#include ## ## void RaiseError(int errorcode); ## int DbmIsInit(void); AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim_eXdbm.la gpsim_eXdbmincludedir = $(includedir)/eXdbm libgpsim_eXdbm_la_SOURCES = hash.c parse.c misc.c eXdbm.c \ hash.h parse.h misc.h gpsim_eXdbminclude_HEADERS = eXdbm.h eXdbmErrors.h eXdbmTypes.h libgpsim_eXdbm_la_LIBADD = @X_LDFLAGS@ EXTRA_DIST = \ Makefile.orig README LICENSE COPYING.LIB eXdbm.txt \ test1.c test2.c test3.c test1.cfg.orig test2.cfg \ README.gpsim gpsim-0.30.0/eXdbm/eXdbmTypes.h0000664000076400007640000000541213041763641013147 00000000000000 /* $Id: eXdbmTypes.h 230 2002-04-15 22:03:02Z linas $ */ /***** * eXdbmTypes.h : eXdbm private data types * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef EXDBM_TYPES_H #define EXDBM_TYPES_H /* defines */ #define HASH_LENGTH 8 /* the number of bits of the hash values */ #define HASH_MAX_ENTRIES (1 << HASH_LENGTH) /* number of elements in a hash tabl e */ #define MAX_ENTRY_LENGTH 64 /* maximum length for a token */ #define MIN_ORDER_SIZE 256 /* minimum size of the order array */ #define TRUE 1 #define FALSE 0 /* enumerations */ enum { DBM_ENTRY_NOT_FOUND=-1, DBM_ENTRY_VAR_INT = 0, DBM_ENTRY_VAR_REAL = 1, DBM_ENTRY_VAR_BOOL = 2, DBM_ENTRY_VAR_STRING = 3, DBM_ENTRY_VAR_IDENT = 4, DBM_ENTRY_LIST = 5, DBM_ENTRY_ROOT = 6 }; /* List entry typedefs */ typedef struct { double real_val; char *str_val; int int_val; } TDbmEntryValue; typedef struct DbmListEntry { char *key; /* key name */ char *comment; /* entry comment */ int entry_type; /* entry type */ TDbmEntryValue value; /* entry value */ struct DbmListEntry* next; /* next entry sharing the same key value */ struct DbmListEntry** child; /* children list */ int current_order; /* number of elemens in order array */ int size_order; /* size of the order array */ struct DbmListEntry** order; /* order array */ } TDbmListEntry; typedef TDbmListEntry *DB_LIST; /* Database typedefs */ typedef struct { char *filename; /* database filename */ TDbmListEntry *root; /* the root entry */ } TDbmDatabase; typedef struct { int nb_db; /* number of loaded databases */ int array_size; /* the size of the array of databases */ TDbmDatabase *dblist; /* list of databases */ } TDbmDbList; typedef int DB_ID; /* database identifier */ #endif gpsim-0.30.0/eXdbm/LICENSE0000664000076400007640000000174613041763641011725 00000000000000 This File: LICENSE for eXdbm Version 1.0 Beta 1 This is a public BETA release of eXdbm, a configuration library using a structured plain ascii file format. (C) Copyright 1997 Fred Pesch This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Fred Pesch eXode project coordinator pesch@club-internet.fr http://www.linux-france.com/pesch gpsim-0.30.0/eXdbm/eXdbm.c0000664000076400007640000011432613041763641012122 00000000000000 /***************************************************************************** * EXODE DATABASE MANAGER LIBRARY * * * * (C) 1997, Fred Pesch * *****************************************************************************/ /***** * eXdbm.c : eXdbm main source file * * This file Version $Revision: 2356 $ * * Last modification: $Date: 2015-10-29 17:47:26 +1100 (Thu, 29 Oct 2015) $ * By: $Author: errolv $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ /* $Id: eXdbm.c 2356 2015-10-29 06:47:26Z errolv $ */ /* includes */ #include #include #include #include "eXdbmTypes.h" #include "eXdbmErrors.h" #include "misc.h" #include "parse.h" /* error messages */ const char * DbmErrorMsgs[] = { "eXdbm : No error", "eXdbm : Memory allocation error", "eXdbm : Database manager not initialized", "eXdbmInit : Database manager already initialized", "eXdbm : Cannot access the specified file", "eXdbmOpenDatabase : Cannot parse comment", "eXdbmOpenDatabase : Cannot parse identifier", "eXdbmOpenDatabase : Cannot parse variable value", "eXdbmOpenDatabase : Unexpected End Of File", "eXdbm : Cannot access Database file", "eXdbm : Wrong database ID", "eXdbm : Write error", "eXdbm : Cannot destroy database", "eXdbm : wrong variable type", "eXdbm : entry not found", "eXdbm : Bad parameter in eXdbm function call", "eXdbmCreate : Duplicate entry identifier" }; /* global variables */ int DbmLastErrorCode = DBM_NO_ERROR; /* the current error value */ TDbmDbList *DbmDbList=NULL; /* private list variable */ unsigned long DbmParseLineNumber; /* line counter for parser */ /* public functions */ int eXdbmGetLastError(void); const char *eXdbmGetErrorString(int errorcode); int eXdbmLastLineParsed(void); int eXdbmInit(void); int eXdbmOpenDatabase(char *filename, DB_ID *dbid); int eXdbmNewDatabase(char *filename, DB_ID *dbid); int eXdbmUpdateDatabase(DB_ID dbid); int eXdbmBackupDatabase(DB_ID dbid, char *filename); int eXdbmCloseDatabase(DB_ID dbid, int update); int eXdbmReloadDatabase(DB_ID *dbid, int update); int eXdbmGetEntryType(DB_ID dbid, DB_LIST list, char *entryname); char *eXdbmGetEntryComment(DB_ID dbid, DB_LIST list, char *entryname); int eXdbmGetVarInt(DB_ID dbid, DB_LIST list, char *entryname, int *value); int eXdbmGetVarReal(DB_ID dbid, DB_LIST list, char *entryname, double *value); int eXdbmGetVarString(DB_ID dbid, DB_LIST list, char *entryname, char **value); int eXdbmGetVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char **value); int eXdbmGetVarBool(DB_ID dbid, DB_LIST list, char *entryname, int *value); DB_LIST eXdbmGetList(DB_ID dbid, DB_LIST list, char *listname); DB_LIST eXdbmSearchList(DB_ID dbid, DB_LIST list, char *listname); DB_LIST eXdbmPathList(DB_ID dbid, char *path); int eXdbmChangeEntryComment(DB_ID dbid, DB_LIST list, char *entryname, char *comment); int eXdbmChangeVarInt(DB_ID dbid, DB_LIST list, char *entryname, int newvalue); int eXdbmChangeVarReal(DB_ID dbid, DB_LIST list, char *entryname, double newvalue); int eXdbmChangeVarString(DB_ID dbid, DB_LIST list, char *entryname, char *newvalue); int eXdbmChangeVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char *newvalue); int eXdbmChangeVarBool(DB_ID dbid, DB_LIST list, char *entryname, int newvalue); int eXdbmCreateList(DB_ID dbid, DB_LIST list, char *entryname, char *comment); int eXdbmCreateVarInt(DB_ID dbid, DB_LIST list, char *entryname, char *comment, int value); int eXdbmCreateVarReal(DB_ID dbid, DB_LIST list, char *entryname, char *comment, double value); int eXdbmCreateVarBool(DB_ID dbid, DB_LIST list, char *entryname, char *comment, int value); int eXdbmCreateVarString(DB_ID dbid, DB_LIST list, char *entryname, char *comment, char *value); int eXdbmCreateVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char *comment, char *value); int eXdbmDeleteEntry(DB_ID dbid, DB_LIST list, char *entryname); /***************************************************************************** * ERROR HANDLING * *****************************************************************************/ int eXdbmGetLastError(void) { int temp; temp = DbmLastErrorCode; DbmLastErrorCode = DBM_NO_ERROR; return temp; } const char *eXdbmGetErrorString(int errorcode) { if(errorcodenb_db = 0; DbmDbList->dblist = NULL; DbmDbList->array_size = 0; return 1; } /***************************************************************************** * OPENING A NEW DATABASE * *****************************************************************************/ int eXdbmOpenDatabase(char *filename, DB_ID *dbid) { FILE *f; DB_ID temp_id = 0; int ret; int i; int addarray; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* try to open the file */ f = fopen(filename, "rt"); if(f==NULL) { RaiseError(DBM_OPEN_FILE); return -1; } /* search if there's an empty place in the array of databases */ addarray = 1; for(i=0;i< DbmDbList->array_size; i++) if(DbmDbList->dblist[i].root==NULL) { temp_id = i; addarray = 0; } if(addarray == 1) { DbmDbList->array_size++; DbmDbList->dblist = (TDbmDatabase *) realloc( DbmDbList->dblist, sizeof(TDbmDatabase) * DbmDbList->array_size); if(DbmDbList->dblist==NULL) { RaiseError(DBM_ALLOC); fclose(f); return -1; } temp_id = DbmDbList->array_size - 1; } /* create the database variable */ DbmDbList->dblist[temp_id].filename = (char *) malloc(sizeof(char)* (strlen(filename)+1)); if(DbmDbList->dblist[temp_id].filename == NULL) { RaiseError(DBM_ALLOC); fclose(f); return(-1); } strcpy(DbmDbList->dblist[temp_id].filename, filename); DbmDbList->nb_db++; /* initialize the root list entry */ DbmDbList->dblist[temp_id].root = (TDbmListEntry *) malloc (sizeof(TDbmListEntry)); if(DbmDbList->dblist[temp_id].root == NULL) { RaiseError(DBM_ALLOC); fclose(f); return -1; } DbmDbList->dblist[temp_id].root->key = NULL ; /* unique root identifier */ DbmDbList->dblist[temp_id].root->comment = NULL; DbmDbList->dblist[temp_id].root->entry_type = DBM_ENTRY_ROOT; DbmDbList->dblist[temp_id].root->value.int_val = -1; DbmDbList->dblist[temp_id].root->value.real_val = -1; DbmDbList->dblist[temp_id].root->value.str_val = NULL; DbmDbList->dblist[temp_id].root->next = NULL; DbmDbList->dblist[temp_id].root->order = (TDbmListEntry **) malloc(sizeof(TDbmListEntry *) * MIN_ORDER_SIZE); if(DbmDbList->dblist[temp_id].root->order == NULL) { RaiseError(DBM_ALLOC); fclose(f); return(-1); } DbmDbList->dblist[temp_id].root->size_order = MIN_ORDER_SIZE; DbmDbList->dblist[temp_id].root->current_order = 0; DbmDbList->dblist[temp_id].root->child = (TDbmListEntry **) malloc( sizeof(TDbmListEntry *) * HASH_MAX_ENTRIES); if(DbmDbList->dblist[temp_id].root->child == NULL) { RaiseError(DBM_ALLOC); fclose(f); return(-1); } for (i=0; i < HASH_MAX_ENTRIES ; i++) DbmDbList->dblist[temp_id].root->child[i]=NULL; /* now, parse the file */ DbmParseLineNumber=1; ret = ParseFile(f, DbmDbList->dblist[temp_id].root, 0); if(ret==-1) { fclose(f); return -1; } /* termination */ fclose(f); *dbid = temp_id; return 1; /* no error */ } /***************************************************************************** * CREATING A NEW DATABASE * *****************************************************************************/ int eXdbmNewDatabase(char *filename, DB_ID *dbid) { /* FILE *f; */ DB_ID temp_id = 0; int ret; int i; int addarray; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* try to open the file */ /* f = fopen(filename, "wt"); if(f==NULL) { RaiseError(DBM_OPEN_FILE); return -1; } fclose(f); */ /* search if there's an empty place in the array of databases */ addarray = 1; for(i=0;i< DbmDbList->array_size; i++) if(DbmDbList->dblist[i].root==NULL) { temp_id = i; addarray = 0; } if(addarray == 1) { DbmDbList->array_size++; DbmDbList->dblist = (TDbmDatabase *) realloc( DbmDbList->dblist, sizeof(TDbmDatabase) * DbmDbList->array_size); if(DbmDbList->dblist==NULL) { RaiseError(DBM_ALLOC); /* fclose(f); */ return -1; } temp_id = DbmDbList->array_size - 1; } /* create the database variable */ DbmDbList->dblist[temp_id].filename = (char *) malloc(sizeof(char)* (strlen(filename)+1)); if(DbmDbList->dblist[temp_id].filename == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(DbmDbList->dblist[temp_id].filename, filename); DbmDbList->nb_db++; /* initialize the root list entry */ DbmDbList->dblist[temp_id].root = (TDbmListEntry *) malloc (sizeof(TDbmListEntry)); if(DbmDbList->dblist[temp_id].root == NULL) { RaiseError(DBM_ALLOC); /* fclose(f); */ return -1; } DbmDbList->dblist[temp_id].root->key = NULL ; /* unique root identifier */ DbmDbList->dblist[temp_id].root->comment = NULL; DbmDbList->dblist[temp_id].root->entry_type = DBM_ENTRY_ROOT; DbmDbList->dblist[temp_id].root->value.int_val = -1; DbmDbList->dblist[temp_id].root->value.real_val = -1; DbmDbList->dblist[temp_id].root->value.str_val = NULL; DbmDbList->dblist[temp_id].root->next = NULL; DbmDbList->dblist[temp_id].root->order = (TDbmListEntry **) malloc(sizeof(TDbmListEntry *) * MIN_ORDER_SIZE); if(DbmDbList->dblist[temp_id].root->order == NULL) { RaiseError(DBM_ALLOC); /* fclose(f); */ return(-1); } DbmDbList->dblist[temp_id].root->size_order = MIN_ORDER_SIZE; DbmDbList->dblist[temp_id].root->current_order = 0; DbmDbList->dblist[temp_id].root->child = (TDbmListEntry **) malloc( sizeof(TDbmListEntry *) * HASH_MAX_ENTRIES); if(DbmDbList->dblist[temp_id].root->child == NULL) { RaiseError(DBM_ALLOC); /* fclose(f); */ return(-1); } for (i=0; i < HASH_MAX_ENTRIES ; i++) DbmDbList->dblist[temp_id].root->child[i]=NULL; /* termination */ *dbid = temp_id; return 1; /* no error */ } /***************************************************************************** * UPDATING A DATABASE * *****************************************************************************/ int eXdbmUpdateDatabase(DB_ID dbid) { FILE *f; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the database identifier */ ret = CheckDbIdent(dbid); if(ret==-1) { RaiseError(DBM_WRONG_ID); return(-1); } /* open the file for writing */ f = fopen(DbmDbList->dblist[dbid].filename, "wt"); if(f==NULL) { RaiseError(DBM_UPDATE_FILE); return -1; } ret = WriteDatabase(f, DbmDbList->dblist[dbid].root, 0); if(ret==-1) { RaiseError(DBM_UPDATE_WRITE_ERROR); return(-1); } fclose(f); return(1); } /***************************************************************************** * DATABASE BACKUP * *****************************************************************************/ int eXdbmBackupDatabase(DB_ID dbid, char *filename) { FILE *f; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the database identifier */ if(CheckDbIdent(dbid)==-1) { RaiseError(DBM_WRONG_ID); return(-1); } /* open the file for writing */ f = fopen(filename, "wt"); if(f==NULL) { RaiseError(DBM_UPDATE_FILE); return -1; } ret = WriteDatabase(f, DbmDbList->dblist[dbid].root, 0); if(ret==-1) { RaiseError(DBM_UPDATE_WRITE_ERROR); return(-1); } fclose(f); return(1); } /***************************************************************************** * CLOSING A DATABASE * *****************************************************************************/ int eXdbmCloseDatabase(DB_ID dbid, int update) { int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the database identifier */ if(CheckDbIdent(dbid)==-1) { RaiseError(DBM_WRONG_ID); return(-1); } /* update the database if asked */ if(update) ret = eXdbmUpdateDatabase(dbid); if(ret == -1) return (-1); /* now destroy the database entries */ ret = DestroyDatabase(DbmDbList->dblist[dbid].root); if( ret == -1) return(-1); /* and the database itself */ free(DbmDbList->dblist[dbid].root->child); free(DbmDbList->dblist[dbid].root->order); free(DbmDbList->dblist[dbid].root); DbmDbList->dblist[dbid].root=NULL; free(DbmDbList->dblist[dbid].filename); DbmDbList->nb_db--; return(1); } /***************************************************************************** * RELOAD A DATABASE * *****************************************************************************/ int eXdbmReloadDatabase(DB_ID *dbid, int update) { int ret; char *filename; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the database identifier */ if(CheckDbIdent(*dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* get the database file name */ filename = (char *) malloc(sizeof(char) * (strlen(DbmDbList->dblist[*dbid].filename)+1)); strcpy(filename, DbmDbList->dblist[*dbid].filename); /* first, close the database */ ret = eXdbmCloseDatabase(*dbid, update); if(ret == -1) { free(filename); return(-1); } /* then, reopen it */ ret = eXdbmOpenDatabase(filename, dbid); if(ret == -1) { free(filename); return(-1); } free(filename); return(1); } /***************************************************************************** * GET THE NAME OF THE FILE ASSOCIATED TO A DATABASE * *****************************************************************************/ char * eXdbmGetDatabaseFileName(DB_ID dbid) { int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(NULL); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(NULL); } return(DbmDbList->dblist[dbid].filename); } /***************************************************************************** * DATABASE QUERY FUNCTIONS * *****************************************************************************/ /************************/ /*** Entry type query ***/ /************************/ int eXdbmGetEntryType(DB_ID dbid, DB_LIST list, char *entryname) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); return (search->entry_type); } /***************************/ /*** Entry comment query ***/ /***************************/ char *eXdbmGetEntryComment(DB_ID dbid, DB_LIST list, char *entryname) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(NULL); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(NULL); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(NULL); /* a comment is available ? */ if(search->comment!=NULL) return(search->comment); return(NULL); } /***************************/ /*** integer value query ***/ /***************************/ int eXdbmGetVarInt(DB_ID dbid, DB_LIST list, char *entryname, int *value) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_INT) { *value = search->value.int_val; return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /************************/ /*** Real value query ***/ /************************/ int eXdbmGetVarReal(DB_ID dbid, DB_LIST list, char *entryname, double *value) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_REAL) { *value = search->value.real_val; return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /**************************/ /*** String value query ***/ /**************************/ int eXdbmGetVarString(DB_ID dbid, DB_LIST list, char *entryname, char **value) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_STRING) { *value = (char *) malloc(sizeof(char) *(strlen(search->value.str_val)+1)); if(*value == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(*value,search->value.str_val); return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /******************************/ /*** Identifier value query ***/ /******************************/ int eXdbmGetVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char **value) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_IDENT) { *value = (char *) malloc(sizeof(char) *(strlen(search->value.str_val)+1)); if(*value == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(*value,search->value.str_val); return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /***************************/ /*** Boolean value query ***/ /***************************/ int eXdbmGetVarBool(DB_ID dbid, DB_LIST list, char *entryname, int *value) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_BOOL) { *value = search->value.int_val; return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /********************/ /*** List queries ***/ /********************/ /* one level search */ DB_LIST eXdbmGetList(DB_ID dbid, DB_LIST list, char *listname) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(NULL); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(NULL); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, listname); else /* sublist search */ search = SearchListEntry(list, listname); if (search==NULL) return(NULL); /* check the variable type */ if(search->entry_type== DBM_ENTRY_LIST) return (search); /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(NULL); } /* recursive search */ DB_LIST eXdbmSearchList(DB_ID dbid, DB_LIST list, char *listname) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(NULL); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(NULL); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntryRec(DbmDbList->dblist[dbid].root, listname); else /* sublist search */ search = SearchListEntryRec(list, listname); if (search==NULL) return(NULL); /* check the variable type */ if(search->entry_type== DBM_ENTRY_LIST) return (search); /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(NULL); } /* one level search */ DB_LIST eXdbmPathList(DB_ID dbid, char *path) { TDbmListEntry *search; char *found; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(NULL); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(NULL); } /* parse the path string */ search = DbmDbList->dblist[dbid].root; found = strtok(path, ":"); while(found!=NULL) { /* search entryname in list */ search = SearchListEntry (search, found); if(search==NULL) return(NULL); found = strtok(NULL, ":"); } return(search); } /***************************************************************************** * ENTRY VALUE MODIFICATIONS * *****************************************************************************/ /****************************/ /*** Change entry comment ***/ /****************************/ int eXdbmChangeEntryComment(DB_ID dbid, DB_LIST list, char *entryname, char *comment) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* check the comment value */ if(comment==NULL) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* a comment is available ? */ if(search->comment!=NULL) free(search->comment); search->comment = (char *) malloc( sizeof(char) * (strlen(comment)+1)); if(search->comment == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(search->comment, comment); return(1); } /****************************/ /*** change integer value ***/ /****************************/ int eXdbmChangeVarInt(DB_ID dbid, DB_LIST list, char *entryname, int newvalue) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_INT) { search->value.int_val=newvalue; return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /*************************/ /*** change real value ***/ /*************************/ int eXdbmChangeVarReal(DB_ID dbid, DB_LIST list, char *entryname, double newvalue) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_REAL) { search->value.real_val=newvalue; return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /***************************/ /*** change string value ***/ /***************************/ int eXdbmChangeVarString(DB_ID dbid, DB_LIST list, char *entryname, char *newvalue) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* check the newvalue parameter */ if(newvalue==NULL) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_STRING) { if(search->value.str_val!=NULL) free(search->value.str_val); search->value.str_val = (char *) malloc(sizeof(char) * (strlen(newvalue)+1)); if(search->value.str_val==NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(search->value.str_val, newvalue); return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /*******************************/ /*** Change identifier value ***/ /*******************************/ int eXdbmChangeVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char *newvalue) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* check the string parameter */ if( newvalue==NULL) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_IDENT) { if(search->value.str_val!=NULL) free(search->value.str_val); search->value.str_val = (char *) malloc(sizeof(char) * (strlen(newvalue)+1)); if(search->value.str_val==NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(search->value.str_val, newvalue); return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /****************************/ /*** Change boolean value ***/ /****************************/ int eXdbmChangeVarBool(DB_ID dbid, DB_LIST list, char *entryname, int newvalue) { TDbmListEntry *search; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(DBM_ENTRY_NOT_FOUND); } /* check the newvalue parameter */ if(newvalue!=0 && newvalue!=1) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* search entryname in list */ if(list==NULL) /* level 0 search */ search = SearchListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ search = SearchListEntry(list, entryname); if (search==NULL) return(DBM_ENTRY_NOT_FOUND); /* check the variable type */ if(search->entry_type== DBM_ENTRY_VAR_BOOL) { search->value.int_val = newvalue; return (search->entry_type); } /* wrong type */ RaiseError(DBM_WRONG_TYPE); return(DBM_ENTRY_NOT_FOUND); } /***************************************************************************** * ENTRY CREATIONS * *****************************************************************************/ /***************************/ /*** Create a list entry ***/ /***************************/ int eXdbmCreateList(DB_ID dbid, DB_LIST list, char *entryname, char *comment) { TDbmListEntry *node; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* create entryname in list */ if(list==NULL) /* level 0 search */ node = CreateListEntry(DbmDbList->dblist[dbid].root, entryname, comment, DBM_ENTRY_LIST); else /* sublist search */ node = CreateListEntry(list, entryname, comment, DBM_ENTRY_LIST); if (node==NULL) return(-1); return (1); } /**********************************/ /*** Create an integer variable ***/ /**********************************/ int eXdbmCreateVarInt(DB_ID dbid, DB_LIST list, char *entryname, char *comment, int value) { TDbmListEntry *node; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* create entryname in list */ if(list==NULL) /* level 0 search */ node = CreateListEntry(DbmDbList->dblist[dbid].root, entryname, comment, DBM_ENTRY_VAR_INT); else /* sublist search */ node = CreateListEntry(list, entryname, comment, DBM_ENTRY_VAR_INT); if (node==NULL) return(-1); node->value.int_val = value; node->value.real_val = value; return (1); } /******************************/ /*** Create a real variable ***/ /******** *********************/ int eXdbmCreateVarReal(DB_ID dbid, DB_LIST list, char *entryname, char *comment, double value) { TDbmListEntry *node; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* create entryname in list */ if(list==NULL) /* level 0 search */ node = CreateListEntry(DbmDbList->dblist[dbid].root, entryname, comment, DBM_ENTRY_VAR_REAL); else /* sublist search */ node = CreateListEntry(list, entryname, comment, DBM_ENTRY_VAR_REAL); if (node==NULL) return(-1); node->value.int_val = (int)ceil(value); node->value.real_val = value; return (1); } /*********************************/ /*** Create a boolean variable ***/ /******** ************************/ int eXdbmCreateVarBool(DB_ID dbid, DB_LIST list, char *entryname, char *comment, int value) { TDbmListEntry *node; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* check the value parameter */ if(value!=0 && value!=1) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* create entryname in list */ if(list==NULL) /* level 0 search */ node = CreateListEntry(DbmDbList->dblist[dbid].root, entryname, comment, DBM_ENTRY_VAR_BOOL); else /* sublist search */ node = CreateListEntry(list, entryname, comment, DBM_ENTRY_VAR_BOOL); if (node==NULL) return(-1); node->value.int_val = value; return (1); } /***************** **************/ /*** Create a string variable ***/ /******** ***********************/ int eXdbmCreateVarString(DB_ID dbid, DB_LIST list, char *entryname, char *comment, char *value) { TDbmListEntry *node; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* check the value parameter */ if(value==NULL) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* create entryname in list */ if(list==NULL) /* level 0 search */ node = CreateListEntry(DbmDbList->dblist[dbid].root, entryname, comment, DBM_ENTRY_VAR_STRING); else /* sublist search */ node = CreateListEntry(list, entryname, comment, DBM_ENTRY_VAR_STRING); if (node==NULL) return(-1); node->value.str_val = (char *) malloc(sizeof(char) * (strlen(value)+1)); if(node->value.str_val==NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(node->value.str_val, value); return (1); } /*************************************/ /*** Create an identifier variable ***/ /******** ****************************/ int eXdbmCreateVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char *comment, char *value) { TDbmListEntry *node; int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* check the value parameter */ if(value==NULL) { RaiseError(DBM_BAD_PARAMETER); return(-1); } /* create entryname in list */ if(list==NULL) /* level 0 search */ node = CreateListEntry(DbmDbList->dblist[dbid].root, entryname, comment, DBM_ENTRY_VAR_IDENT); else /* sublist search */ node = CreateListEntry(list, entryname, comment, DBM_ENTRY_VAR_IDENT); if (node==NULL) return(-1); node->value.str_val = (char *) malloc(sizeof(char) * (strlen(value)+1)); if(node->value.str_val==NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(node->value.str_val, value); return (1); } /***************************************************************************** * DELETE ENTRY FUNCTION * *****************************************************************************/ int eXdbmDeleteEntry(DB_ID dbid, DB_LIST list, char *entryname) { int ret; /* the database manager must be initialized */ ret = DbmIsInit(); if( ret == -1) return(-1); /* check the dbid parameter */ if(CheckDbIdent(dbid) == -1) { RaiseError(DBM_WRONG_ID); return(-1); } /* search entryname in list */ if(list==NULL) /* level 0 search */ ret = DeleteListEntry(DbmDbList->dblist[dbid].root, entryname); else /* sublist search */ ret = DeleteListEntry(list, entryname); if (ret==-1) return(-1); return(1); } gpsim-0.30.0/eXdbm/ChangeLog0000664000076400007640000000000013041763641012450 00000000000000gpsim-0.30.0/eXdbm/parse.h0000664000076400007640000000231313041763641012172 00000000000000 /* $Id: parse.h 230 2002-04-15 22:03:02Z linas $ */ /***** * parse.h : eXdbm parser header * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef PARSE_H #define PARSE_H #include #include "eXdbmTypes.h" int ParseFile(FILE *f, TDbmListEntry *list, int level); #endif gpsim-0.30.0/eXdbm/eXdbm.h0000664000076400007640000000703013041763641012120 00000000000000 /***** * eXdbm.h : eXdbm main header * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef EXDBM_H #define EXDBM_H #include "eXdbmTypes.h" #include "eXdbmErrors.h" /* error handling */ int eXdbmGetLastError(void); const char *eXdbmGetErrorString(int errorcode); int eXdbmLastLineParsed(void); /* database functions */ int eXdbmInit(void); int eXdbmOpenDatabase(char *filename, DB_ID *dbid); int eXdbmNewDatabase(char *filename, DB_ID *dbid); int eXdbmUpdateDatabase(DB_ID dbid); int eXdbmBackupDatabase(DB_ID dbid, char *filename); int eXdbmCloseDatabase(DB_ID dbid, int update); int eXdbmReloadDatabase(DB_ID *dbid, int update); char *eXdbmGetDatabaseFileName(DB_ID dbid); /* get entry values functions */ int eXdbmGetEntryType(DB_ID dbid, DB_LIST list, char *entryname); char *eXdbmGetEntryComment(DB_ID dbid, DB_LIST list, char *entryname); int eXdbmGetVarInt(DB_ID dbid, DB_LIST list, char *entryname, int *value); int eXdbmGetVarReal(DB_ID dbid, DB_LIST list, char *entryname, double *value); int eXdbmGetVarString(DB_ID dbid, DB_LIST list, char *entryname, char **value); int eXdbmGetVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char **value); int eXdbmGetVarBool(DB_ID dbid, DB_LIST list, char *entryname, int *value); DB_LIST eXdbmGetList(DB_ID dbid, DB_LIST list, char *listname); DB_LIST eXdbmSearchList(DB_ID dbid, DB_LIST list, char *listname); DB_LIST eXdbmPathList(DB_ID dbid, char *path); /* change entry functions */ int eXdbmChangeEntryComment(DB_ID dbid, DB_LIST list, char *entryname, char *comment); int eXdbmChangeVarInt(DB_ID dbid, DB_LIST list, char *entryname, int newvalue); int eXdbmChangeVarReal(DB_ID dbid, DB_LIST list, char *entryname, double newvalue); int eXdbmChangeVarString(DB_ID dbid, DB_LIST list, char *entryname, char *newvalue); int eXdbmChangeVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char *newvalue); int eXdbmChangeVarBool(DB_ID dbid, DB_LIST list, char *entryname, int newvalue); /* create entry functions */ int eXdbmCreateList(DB_ID dbid, DB_LIST list, char *entryname, char *comment); int eXdbmCreateVarInt(DB_ID dbid, DB_LIST list, char *entryname, char *comment, int value); int eXdbmCreateVarReal(DB_ID dbid, DB_LIST list, char *entryname, char *comment, double value); int eXdbmCreateVarBool(DB_ID dbid, DB_LIST list, char *entryname, char *comment, int value); int eXdbmCreateVarString(DB_ID dbid, DB_LIST list, char *entryname, char *comment, char *value); int eXdbmCreateVarIdent(DB_ID dbid, DB_LIST list, char *entryname, char *comment, char *value); /* delete entry function */ int eXdbmDeleteEntry(DB_ID dbid, DB_LIST list, char *entryname); #endif /* end of eXdbm.h */ gpsim-0.30.0/eXdbm/eXdbmErrors.h0000664000076400007640000000306613041763641013322 00000000000000 /* $Id: eXdbmErrors.h 230 2002-04-15 22:03:02Z linas $ */ /***** * eXdbmErrors.h : eXdbm error numbers * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef EXDBM_ERRORS_H #define EXDBM_ERRORS_H enum { DBM_NO_ERROR = 0, DBM_ALLOC = 1, DBM_INIT_NEEDED = 2, DBM_INIT_REINIT = 3, DBM_OPEN_FILE = 4, DBM_PARSE_COMMENT = 5, DBM_PARSE_ID = 6, DBM_PARSE_VALUE = 7, DBM_PARSE_UNEXP_END = 8, DBM_UPDATE_FILE = 9, DBM_WRONG_ID = 10, DBM_UPDATE_WRITE_ERROR = 11, DBM_DESTROY = 12, DBM_WRONG_TYPE = 13, DBM_BAD_PARAMETER = 14, DBM_DUPLICATE_ENTRY = 15, DBM_END_ERROR = 16 }; #endif /* end of eXdbmErrors.h */ gpsim-0.30.0/eXdbm/hash.h0000664000076400007640000000050413041763641012003 00000000000000 #ifndef HASH_H #define HASH_H /* DON'T MODIFY THE FOLLOWING DEFINES ! */ #define HASH_LENGTH 8 /* the number of bits of the hash values */ #define HASH_MAX_ENTRIES (1 << HASH_LENGTH) /* number of elements in a hash table */ /* hash value function */ int HashValueGenerator( char *name ); #endif /* end of hash.h */ gpsim-0.30.0/eXdbm/hash.c0000664000076400007640000000103613041763641011777 00000000000000 #include #include #include "hash.h" #define HASH_THETA 0.6180339887 /* value used by the hash value generator */ /***** hash value calculation *****/ int HashValueGenerator( char *name ) { size_t len; size_t i; unsigned char cvalue; double mvalue; /* compression */ len = strlen(name); cvalue = 0; for(i=0; i a database identifier DB_LIST -> a list variable 4.2. error handling ------------------- The eXdbm functions return 0 on error and 1 on success. NAME eXdbmGetLastError() SYNOPSIS int eXdbmGetLastError(void); DESCRIPTION Get the last error code RETURN VALUE An eXode error code NAME eXdbmGetErrorString() SYNOPSIS const char * eXdbmGetErrorString(int errorcode); DESCRIPTION Get an error message corresponding to the error parameter RETURN VALUE A string containing the error message NAME eXdbmLastLineParsed(); SYNOPSIS int eXdbmLastLineParsed(void); DESCRIPTION This function returns the number of the last line parsed while reading the last database file. This is usefull to locate a parsing error. EXAMPLE The following code prints a detailed error message #include #include int ret; DB_ID dbid; int error; char *message; int last_line; ... ret = eXdbmOpenDatabse("mydb.cfg", &dbid); if(ret == -1) { printf("\nAn error has occured\n); /* get the error number */ error = eXdbmGetLastError(); /* get the standard error message */ message = eXdbmGetErrorString(error); /* get the last line parsed */ last_line = eXdbmLastLineParsed(); /* print a detailed error message */ printf("Error number %d : %s\n", error, message); printf("Last line parsed = %d\n", last_line); } ... Example of output : An error has occured eXdbmOpenDatabase : Cannot parse variable value Last line parsed = 25 RETURN VALUE -1 on error >0 on success 4.3. opening & closing a databases ---------------------------------- NAME eXdbmInit() SYNOPSIS int eXdbmInit(void); DESCRIPTION Initialize the database manager. This function must be call before any other eXdbm function call. RETURN VALUE -1 on error >0 on success NAME eXdbmOpenDatabase() SYNOPSIS int eXdbmOpenDatabase(char *filename, DBID *dbid); DESCRIPTION Open the filename database file. dbid is a pointer to an integer : an unique identifier for the opened database RETURN VALUE -1 on error >0 on success NAME eXdbmNewDatabase() SYNOPSIS int eXdbmOpenDatabase(char *filename, DB_ID *dbid); DESCRIPTION Create a new database which will use the file filename. dbid is a pointer to an integer : an unique identifier for the opened database RETURN VALUE -1 on error >0 on success NAME eXdbmUpdateDatabase() SYNOPSIS int eXdbmUpdateDatabase(DB_ID dbid); DESCRIPTION Save the database identified by dbid. This assure the actual database contents is the same in memory and on disk. RETURN VALUE -1 on error >0 on success NAME eXdbmBackupDatabase() SYNOPSIS int eXdbmBackupDatabase(DB_ID dbid, char *filename); DESCRIPTION Make a backup copy of the database identified by dbid in the file filename. This file must be writeable by the current user. RETURN VALUE -1 on error >0 on success NAME eXdbmCloseDatabase() SYNOPSIS int eXdbmCloseDatabase(DBID dbid, int update) DESCRIPTION The function you have to call to close a database. If udate = 1 (defined as TRUE in eXdbm.h), the database file will be updated, see eXdbmUpdateDatabase(). RETURN VALUE -1 on error >0 on success 4.4. Generic entry management ----------------------------- 4.4.1. get the type of an entry ------------------------------- NAME eXdbmGetEntryType() SYNOPSIS int eXdbmGetEntryType(DB_ID dbid, DB_LIST list, char *entryname); DESCRIPTION This function returns the type of the entry identified by : dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry RETURN VALUE -1 (DBM_ENTRY_NOT_FOUND) on error On succes, the type of the entry : - DBM_ENTRY_LIST : a list entry - DBM_ENTRY_VAR_INT : an integer variable - DBM_ENTRY_VAR_BOOL : a boolean variable - DBM_ENTRY_VAR_REAL : a real number variable - DBM_ENTRY_VAR_STRING : a string variable - DBM_ENTRY_VAR_ID : an identifier variable 4.4.2. Comments management -------------------------- NAME eXdbmGetEntryComment() SYNOPSIS char * eXdbmGetEntryComment(DB_ID dbid, DB_LIST list, char *entryname); DESCRIPTION Returns the associated comment of an entry if it exists, or NULL. The entry is specified by : dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry RETURN VALUE A pointer to the comment string or NULL NAME eXdbmChangeEntryComment() SYNOPSIS int eXdbmChangeEntryComment(DB_ID dbid, DB_LIST list, char *entryname, char *comment); DESCRIPTION Changes the associated comment of an entry. The entry is specified by : dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry comment is the new comment string NOTE The function allocates the memory needed for the comment and copy the string you provide. You must ensure the specifier string starts with a # character. If this is not the case, eXdbm won't be able to parse the database file containing a comment that is not starting with #. RETURN VALUE -1 on error >0 on success 4.4.3 delete an entry --------------------- NAME eXdbmDeleteEntry() SYNOPSIS int eXdbmDeleteEntry(DB_ID dbid, DB_LIST list, char *entryname); DESCRIPTION This function deletes the entry specified by dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry if the entry is a list, all the entries is contains are also destroyed, recursively. RETURN VALUE -1 on error >0 on sucess 4.5. list management -------------------- 4.5.1. get a list identifier ---------------------------- NAME eXdbmGetList() SYNOPSIS DB_LIST eXdbmGetList(DB_ID dbid, DB_LIST list, char *listname); DESCRIPTION get the identifier of the sublist of name listname in list. if list is NULL, sublistname is the name of a first level list RETURN VALUE A pointer to the found DB_LIST structure. If the value is NULL, the Sublist doesn't exist (an error is raised, the eXdbmGetError returns an error). NAME eXdbmSearchList() SYNOPSIS DB_LIST eXdbmSearchList(DB_ID dbid, DB_LIST list, char *listname); DESCRIPTION search recursively the list of name listname in list and all of its sublists. If list is NULL, search in all the lists of the database. NOTE The behaviour of this function is hard to predict if more than one list is of name listname. RETURN VALUE A pointer to the found LIST structure. If the value is NULL, the Sublist doesn't exist (an error is raised, the eXdbmGetError returns an error). NAME eXdbmPathList() SYNOPSIS DB_LIST eXdbmPathList(DB_ID dbid, char *path); DESCRIPTION This function returns the list referenced by its full path name in the database. A pathname is a serie of list names separated by colons. EXAMPLE list:sublist:susublist refers to the list of name subsublist defined in sublist which is defined in list. NOTE The root list (referenced as NULL) is implicit RETURN VALUE A pointer to the found LIST structure. If the value is NULL, the list doesn't exist (an error is raised, the eXdbmGetError returns an error). 4.5.2. create an empty list --------------------------- NAME eXdbmCreateList() SYNOPSIS int eXdbmCreateList(DBID dbid, LIST *list, char *entryname, char *comment); DESCRIPTION Create an empty list of name entryname list is the parent list (NULL is the new list is global) comment is a string to comment the new list RETURN VALUE -1 on error >0 on success 4.6. Variable management ------------------------ In the following functions : must be replaced by the type of the variable : Int, Real, Bool, Ident or String. is the corresponding C datatype. Int int Real double Bool int (0 = FALSE, 1 = TRUE) Ident char * String char * 4.6.1. read a value ------------------- NAME eXdbmGetVar() SYNOPSIS int eXdbmGetVar (DBID dbid, DB_LIST list, char *entryname, * value); DESCRIPTION Read the value of a variable. dbid is the database ID list is the parent's list entry is the name of the variable. V Value is a pointer to a variable of the desired C type. EXAMPLE ... int ival; double rval; char *sval; int bval; char *idval; int ret; ... ret = eXdbmGetVarInt(dbid, parent, "intvar", &ival); ret = eXdbmGetVarBool(dbid, parent, "boolvar", &bval); ret = eXdbmGetVarReal(dbid, parent, "realvar", &rval); ret = eXdbmGetVarString(dbid, parent, "stringvar", &sval); ret = eXdbmGetVarIdent(dbid, parent, "identvar", &idval); ... NOTE If is String or Ident, the value pointer references a copy of the value coded by the variable. You must free() this memory when you don't need it anymore. RETURN VALUE -1 on error >0 on success 4.6.2. create a variable ------------------------ NAME eXdbmCreateVar() SYNOPSIS int eXdbmCreateVar(DBID dbid, DB_LIST list, char *entryname, char *comment, value); DESCRIPTION Add a variable to the database. dbid is the database ID list is the parent list of the entry (NULL is root for parent) entryname is the name of the new variable comment is the comment string associated to the variable (or NULL) value is the value of the variable. NOTE The function allocates the memory needed for the comment and copy the string you provide. RETURN VALUE -1 on error >0 on success 4.6.3. Modify a variable ------------------------ NAME eXdbmChangeVar () SYNOPSIS int eXdbmChangeVar(DBID dbid, DB_LIST list, char *entryname, newvalue); DESCRIPTION Change the value of a variable in the database. dbid is the database ID list is the parent list of the entry (NULL is root for parent) entryname is the name of the variable to be modified newvalue is the new value of the variable. NOTE Use eXdbmChangeEntryComment() to change the comment associated to a variable. RETURN VALUE -1 on error >0 on success 5. Using the library -------------------- 5.1. Installation instructions ------------------------------ First, get the file : eXdbm-status-version.tar.gz where status is : alpha, beta or empty (final) version is the version number (1.0b1 is the last version) Then uncompress the file : gzip -d eXdbm-status-version.tar.gz tar xvf eXdbm-status-version.tar Now, cd to eXdbm-status-version/ Then type : make and, as root : make install The default installation directories are : /usr/local/include : header files /usr/local/lib : library /usr/local/doc/eXdbm : documentation You can change these defaults by modifying the LIBDIR, INCDIR and DOCDIR make variable in Makefile.orig 5.2. Linking programs with libeXdbm.a ------------------------------------- This is the command line you have to use in order to link your C programs with the eXdbm library : cc myprogram.c -I/usr/local/include -L/usr/local/lib -leXdbm -lm NOTE : Don't forget the -lm statement, eXdbm uses a few math functions. 5.3. Sample programs -------------------- The following programs demonstrates the use of the eXdbm library : - test1 (test1.c) Basic open/update/close functions - test2 (test2.c) Backup function test - test3 (test3.c) A console oriented small database manager that uses every functions provided in the eXdbm library. gpsim-0.30.0/eXdbm/INSTALL0000664000076400007640000000000013041763641011727 00000000000000gpsim-0.30.0/eXdbm/eXdbm.txt0000664000076400007640000004037113041763641012515 00000000000000 Editor: Fred Pesch, pech@club-internet.fr Copyright: eXode Developers Team Status of this document ----------------------- This is an eXode documentation for review by eXode members and other interested parties. It is a released document but may be updated, replaced or obsoleted by other documents in future relases. Abstract -------- This document explains the eXdbm (eXode Database Manager) file format. This is the configuration file format of the eXode clients (esp. the core tools). The provided API is also explained here. Table of contents ----------------- 1. Recent Changes 2. Introduction 3. eXdbm file format 3.1. general structure 3.2. special chararcters 3.3. comments 3.4. datatypes 3.5. variables 3.6. lists 3.7. keywords 4. Proposed API 4.1. new types 4.2. error handling 4.3. opening & closing a database 4.4. generic entry management 4.5. list management 4.6. variable management 5. Using the library 5.1. Installation 5.2. Linking programs with libeXdbm 5.3. Sample programs 1. Recent changes ----------------- Dec-27-97: - version 1.0beta1 to be released - removed keyword concept (too eXode specific) Dec-10-97: - new keyword specification. - few changes in the API - no more disk media - new error code (-1) Oct-04-97: - First draft translated and modified, renamed eXdbm July-xx-97: - First draft (was eXhcl) 2. Introduction --------------- The X Resource manager is a normal choice for Motif based applications configuration but it lacks of high level data structures like lists or trees. Derived from the fof's configuration file format, eXdbm is an ASCII-based database format. eXdbm will be used to manage the configuration files of the eXode clients. The resource files will also be generated by eXconfig from the eXdbm files. The proposed API for the eXdbm management follows the description of the format. The library uses a tree of hash tables structures stored in memory, favouring speed upon memory consumption. This is not a general purpose database library, its efficiency is based on the fact that the databases managed contain less than a few thousand entries. Note that eXdbm is a general purpose configuration library, it can be used in many other applications without relations to the eXode project. 3. eXdbm file format -------------------- 3.1. general structure ---------------------- The eXdbm files are standard text files. Each line of text is a definition (the end of line char is a delimiter). The possible definitions are : - comments - variable - list header - list footer An empty line doesn't contain any definition and is simply ignored. 3.2. special characters ----------------------- The following characters are reserved : - # : starts a comment - " : string definition delimiter - = : variable definition - { : starts a list definition - } : ends a list definition Exceptions : - in a string definition, the only reserved char are %, " and \ - in a comment, there is no reserved char 3.3. comments ------------- A comment begins with the reserved char # and continues until the next end of line character (this is a sh-like behaviour). Each comment is associated to the first entry definition that follows. Ex.: # I am a comment Variable = 12 3.4. datatypes -------------- The basic datatypes are : - Integer : [+-][0-9]+ - Real numbers : [+-][0-9]+.[0-9]+[[eE][+-][0-9]+] - Booleans : TRUE | FALSE - Strings : "string contents" - Identifiers : my_identifier (string without space) 3.5. variables -------------- You can declare a variable using the syntax : VarName = Value Where VarName is a string (no spaces or special chars) and Value is of type int, real, bool or string. note : the type of the variable is implicit Ex.: DefaultBackgroundColor = "Red" RefreshInterval = 1000 AlwaysConfirm = TRUE # according to eXdbm, pi is a variable ! PI = 3.14159265 3.6. lists ---------- A list definition starts on a new line by the name of the list followed by a {. Each element of a list is a variable definition or a sublist. A list is ended with a } on a new line. note : The variable declared outside a list is called a global variable. Ex.: FORMAT_LIST { TAR_GZ { Description = "gzipped tar archive" Magic = "\\032\\341" Pattern = "*.tar.gz:*.tgz:*_tar.gz" ViewCommand = "%DEFAULT" EditCommand = "eXtar" } IMAGE { Description = "graphic image" Magic = "%NONE" Pattern = "*.gif":"*.jpg":"*.tga" ViewCommand = "%DEFAULT" EditCommand = "gimp" } IMAGE_GIF { Description = "gif image" Magic = "\\0123\\0321" Pattern = "*.gif" ViewCommand = "%DEFAULT" EditCommand = "gimp" } } 4. Provided API --------------- 4.1. new types -------------- DB_ID -> a database identifier DB_LIST -> a list variable 4.2. error handling ------------------- The eXdbm functions return 0 on error and 1 on success. NAME eXdbmGetLastError() SYNOPSIS int eXdbmGetLastError(void); DESCRIPTION Get the last error code RETURN VALUE An eXode error code NAME eXdbmGetErrorString() SYNOPSIS const char * eXdbmGetErrorString(int errorcode); DESCRIPTION Get an error message corresponding to the error parameter RETURN VALUE A string containing the error message NAME eXdbmLastLineParsed(); SYNOPSIS int eXdbmLastLineParsed(void); DESCRIPTION This function returns the number of the last line parsed while reading the last database file. This is usefull to locate a parsing error. EXAMPLE The following code prints a detailed error message #include #include int ret; DB_ID dbid; int error; char *message; int last_line; ... ret = eXdbmOpenDatabse("mydb.cfg", &dbid); if(ret == -1) { printf("\nAn error has occured\n); /* get the error number */ error = eXdbmGetLastError(); /* get the standard error message */ message = eXdbmGetErrorString(error); /* get the last line parsed */ last_line = eXdbmLastLineParsed(); /* print a detailed error message */ printf("Error number %d : %s\n", error, message); printf("Last line parsed = %d\n", last_line); } ... Example of output : An error has occured eXdbmOpenDatabase : Cannot parse variable value Last line parsed = 25 RETURN VALUE -1 on error >0 on success 4.3. opening & closing a databases ---------------------------------- NAME eXdbmInit() SYNOPSIS int eXdbmInit(void); DESCRIPTION Initialize the database manager. This function must be call before any other eXdbm function call. RETURN VALUE -1 on error >0 on success NAME eXdbmOpenDatabase() SYNOPSIS int eXdbmOpenDatabase(char *filename, DBID *dbid); DESCRIPTION Open the filename database file. dbid is a pointer to an integer : an unique identifier for the opened database RETURN VALUE -1 on error >0 on success NAME eXdbmNewDatabase() SYNOPSIS int eXdbmOpenDatabase(char *filename, DB_ID *dbid); DESCRIPTION Create a new database which will use the file filename. dbid is a pointer to an integer : an unique identifier for the opened database RETURN VALUE -1 on error >0 on success NAME eXdbmUpdateDatabase() SYNOPSIS int eXdbmUpdateDatabase(DB_ID dbid); DESCRIPTION Save the database identified by dbid. This assure the actual database contents is the same in memory and on disk. RETURN VALUE -1 on error >0 on success NAME eXdbmBackupDatabase() SYNOPSIS int eXdbmBackupDatabase(DB_ID dbid, char *filename); DESCRIPTION Make a backup copy of the database identified by dbid in the file filename. This file must be writeable by the current user. RETURN VALUE -1 on error >0 on success NAME eXdbmCloseDatabase() SYNOPSIS int eXdbmCloseDatabase(DBID dbid, int update) DESCRIPTION The function you have to call to close a database. If udate = 1 (defined as TRUE in eXdbm.h), the database file will be updated, see eXdbmUpdateDatabase(). RETURN VALUE -1 on error >0 on success 4.4. Generic entry management ----------------------------- 4.4.1. get the type of an entry ------------------------------- NAME eXdbmGetEntryType() SYNOPSIS int eXdbmGetEntryType(DB_ID dbid, DB_LIST list, char *entryname); DESCRIPTION This function returns the type of the entry identified by : dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry RETURN VALUE -1 (DBM_ENTRY_NOT_FOUND) on error On succes, the type of the entry : - DBM_ENTRY_LIST : a list entry - DBM_ENTRY_VAR_INT : an integer variable - DBM_ENTRY_VAR_BOOL : a boolean variable - DBM_ENTRY_VAR_REAL : a real number variable - DBM_ENTRY_VAR_STRING : a string variable - DBM_ENTRY_VAR_ID : an identifier variable 4.4.2. Comments management -------------------------- NAME eXdbmGetEntryComment() SYNOPSIS char * eXdbmGetEntryComment(DB_ID dbid, DB_LIST list, char *entryname); DESCRIPTION Returns the associated comment of an entry if it exists, or NULL. The entry is specified by : dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry RETURN VALUE A pointer to the comment string or NULL NAME eXdbmChangeEntryComment() SYNOPSIS int eXdbmChangeEntryComment(DB_ID dbid, DB_LIST list, char *entryname, char *comment); DESCRIPTION Changes the associated comment of an entry. The entry is specified by : dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry comment is the new comment string NOTE The function allocates the memory needed for the comment and copy the string you provide. You must ensure the specifier string starts with a # character. If this is not the case, eXdbm won't be able to parse the database file containing a comment that is not starting with #. RETURN VALUE -1 on error >0 on success 4.4.3 delete an entry --------------------- NAME eXdbmDeleteEntry() SYNOPSIS int eXdbmDeleteEntry(DB_ID dbid, DB_LIST list, char *entryname); DESCRIPTION This function deletes the entry specified by dbid : the database identifier list : the parent's list of the entry (NULL for level 0 entry) entryname : the name of the entry if the entry is a list, all the entries is contains are also destroyed, recursively. RETURN VALUE -1 on error >0 on sucess 4.5. list management -------------------- 4.5.1. get a list identifier ---------------------------- NAME eXdbmGetList() SYNOPSIS DB_LIST eXdbmGetList(DB_ID dbid, DB_LIST list, char *listname); DESCRIPTION get the identifier of the sublist of name listname in list. if list is NULL, sublistname is the name of a first level list RETURN VALUE A pointer to the found DB_LIST structure. If the value is NULL, the Sublist doesn't exist (an error is raised, the eXdbmGetError returns an error). NAME eXdbmSearchList() SYNOPSIS DB_LIST eXdbmSearchList(DB_ID dbid, DB_LIST list, char *listname); DESCRIPTION search recursively the list of name listname in list and all of its sublists. If list is NULL, search in all the lists of the database. NOTE The behaviour of this function is hard to predict if more than one list is of name listname. RETURN VALUE A pointer to the found LIST structure. If the value is NULL, the Sublist doesn't exist (an error is raised, the eXdbmGetError returns an error). NAME eXdbmPathList() SYNOPSIS DB_LIST eXdbmPathList(DB_ID dbid, char *path); DESCRIPTION This function returns the list referenced by its full path name in the database. A pathname is a serie of list names separated by colons. EXAMPLE list:sublist:susublist refers to the list of name subsublist defined in sublist which is defined in list. NOTE The root list (referenced as NULL) is implicit RETURN VALUE A pointer to the found LIST structure. If the value is NULL, the list doesn't exist (an error is raised, the eXdbmGetError returns an error). 4.5.2. create an empty list --------------------------- NAME eXdbmCreateList() SYNOPSIS int eXdbmCreateList(DBID dbid, LIST *list, char *entryname, char *comment); DESCRIPTION Create an empty list of name entryname list is the parent list (NULL is the new list is global) comment is a string to comment the new list RETURN VALUE -1 on error >0 on success 4.6. Variable management ------------------------ In the following functions : must be replaced by the type of the variable : Int, Real, Bool, Ident or String. is the corresponding C datatype. Int int Real double Bool int (0 = FALSE, 1 = TRUE) Ident char * String char * 4.6.1. read a value ------------------- NAME eXdbmGetVar() SYNOPSIS int eXdbmGetVar (DBID dbid, DB_LIST list, char *entryname, * value); DESCRIPTION Read the value of a variable. dbid is the database ID list is the parent's list entry is the name of the variable. V Value is a pointer to a variable of the desired C type. EXAMPLE ... int ival; double rval; char *sval; int bval; char *idval; int ret; ... ret = eXdbmGetVarInt(dbid, parent, "intvar", &ival); ret = eXdbmGetVarBool(dbid, parent, "boolvar", &bval); ret = eXdbmGetVarReal(dbid, parent, "realvar", &rval); ret = eXdbmGetVarString(dbid, parent, "stringvar", &sval); ret = eXdbmGetVarIdent(dbid, parent, "identvar", &idval); ... NOTE If is String or Ident, the value pointer references a copy of the value coded by the variable. You must free() this memory when you don't need it anymore. RETURN VALUE -1 on error >0 on success 4.6.2. create a variable ------------------------ NAME eXdbmCreateVar() SYNOPSIS int eXdbmCreateVar(DBID dbid, DB_LIST list, char *entryname, char *comment, value); DESCRIPTION Add a variable to the database. dbid is the database ID list is the parent list of the entry (NULL is root for parent) entryname is the name of the new variable comment is the comment string associated to the variable (or NULL) value is the value of the variable. NOTE The function allocates the memory needed for the comment and copy the string you provide. RETURN VALUE -1 on error >0 on success 4.6.3. Modify a variable ------------------------ NAME eXdbmChangeVar () SYNOPSIS int eXdbmChangeVar(DBID dbid, DB_LIST list, char *entryname, newvalue); DESCRIPTION Change the value of a variable in the database. dbid is the database ID list is the parent list of the entry (NULL is root for parent) entryname is the name of the variable to be modified newvalue is the new value of the variable. NOTE Use eXdbmChangeEntryComment() to change the comment associated to a variable. RETURN VALUE -1 on error >0 on success 5. Using the library -------------------- 5.1. Installation instructions ------------------------------ First, get the file : eXdbm-status-version.tar.gz where status is : alpha, beta or empty (final) version is the version number (1.0b1 is the last version) Then uncompress the file : gzip -d eXdbm-status-version.tar.gz tar xvf eXdbm-status-version.tar Now, cd to eXdbm-status-version/ Then type : make and, as root : make install The default installation directories are : /usr/local/include : header files /usr/local/lib : library /usr/local/doc/eXdbm : documentation You can change these defaults by modifying the LIBDIR, INCDIR and DOCDIR make variable in Makefile.orig 5.2. Linking programs with libeXdbm.a ------------------------------------- This is the command line you have to use in order to link your C programs with the eXdbm library : cc myprogram.c -I/usr/local/include -L/usr/local/lib -leXdbm -lm NOTE : Don't forget the -lm statement, eXdbm uses a few math functions. 5.3. Sample programs -------------------- The following programs demonstrates the use of the eXdbm library : - test1 (test1.c) Basic open/update/close functions - test2 (test2.c) Backup function test - test3 (test3.c) A console oriented small database manager that uses every functions provided in the eXdbm library. gpsim-0.30.0/eXdbm/test3.c0000664000076400007640000004756713041763641012141 00000000000000 /* $Id: test3.c 230 2002-04-15 22:03:02Z linas $ */ /***** * test3.c : eXdbm database tool * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef lint static char vcid[] = "$Id: test3.c 230 2002-04-15 22:03:02Z linas $"; #endif /* lint */ #include #include #include #include #include "eXdbm.h" #define MAX_DB 16 int DbCount=0; DB_ID Databases[MAX_DB]; void ErrorMessage(void) { printf("\n*******************\n"); printf("Error received : \n"); printf(" ===> %s\n", eXdbmGetErrorString(eXdbmGetLastError())); printf("*******************\n"); } void HitKey(void) { char toto; printf("\nHit to continue"); scanf("%c",&toto); printf("\n"); } void OpenDatabase(void) { char fname[256]; int ret; int dbid; printf("\n\n"); printf("Opening a new database"); printf("----------------------\n"); if(DbCount>MAX_DB) { printf("Error ==> already %d databases in memory\n", DbCount); HitKey(); return; } printf("\nDatabase filename : "); scanf("%s", fname); ret = eXdbmOpenDatabase(fname, &dbid); if(ret==-1) { ErrorMessage(); HitKey(); return; } Databases[DbCount++] = dbid; printf("\nDatabase opened with identifier : %d\n\n", dbid); HitKey(); } void NewDatabase(void) { char fname[256]; int ret; int dbid; printf("\n\n"); printf("Creating a new database"); printf("-----------------------\n"); if(DbCount>MAX_DB) { printf("Error ==> already %d databases in memory\n", DbCount); HitKey(); return; } printf("\nDatabase filename : "); scanf("%s", fname); ret = eXdbmNewDatabase(fname, &dbid); if(ret==-1) { ErrorMessage(); HitKey(); return; } Databases[DbCount++] = dbid; printf("\nDatabase created with identifier : %d\n", dbid); HitKey(); } void PrintAvailableDatabases(void) { int i; printf("\nAvailable databases: \n\n"); if(DbCount==0) { printf("No available database\n"); HitKey(); return; } printf("Identifier\t\tFile name\n"); for(i=0;i<80;i++) printf("-"); for(i=0; i no database in memory\n"); HitKey(); return; } PrintAvailableDatabases(); printf("\n Choose a database ==> "); scanf("%d", &dbid); found = -1; for(i=0;i Wrong database ID\n"); HitKey(); return; } ret = eXdbmCloseDatabase(dbid, 0); if(ret==-1) { ErrorMessage(); return; } for(i=found; i < DbCount-1 ; i++) Databases[i] = Databases[i+1]; DbCount--; printf("\nDatabase %d removed\n", dbid); HitKey(); } void UpdateDatabase(void) { DB_ID dbid; int i; int found; int ret; printf("\n\n"); printf("Update a database file"); printf("----------------------"); if(DbCount==0) { printf("\n\nError ==> no database in memory\n"); HitKey(); return; } PrintAvailableDatabases(); printf("\n Choose a database ==> "); scanf("%d", &dbid); found = -1; for(i=0;i Wrong database ID\n"); HitKey(); return; } ret = eXdbmUpdateDatabase(dbid); if(ret==-1) { ErrorMessage(); return; } printf("\nDatabase %d updated\n", dbid); HitKey(); } void BackupDatabase(void) { DB_ID dbid; int i; int found; int ret; char fname[256]; printf("\n\n"); printf("Backup a database"); printf("-----------------"); if(DbCount==0) { printf("\n\nError ==> no database in memory\n"); HitKey(); return; } PrintAvailableDatabases(); printf("\n Choose a database ==> "); scanf("%d", &dbid); found = -1; for(i=0;i Wrong database ID\n"); HitKey(); return; } printf("\nChoose a backup file name ==> "); scanf("%s", fname); ret = eXdbmBackupDatabase(dbid, fname); if(ret==-1) { ErrorMessage(); HitKey(); return; } printf("\nDatabase %d backup successfull\n", dbid); HitKey(); } void ReloadDatabase(void) { DB_ID dbid; int i; int found; int ret; printf("\n\n"); printf("Reload a database file"); printf("----------------------"); if(DbCount==0) { printf("\n\nError ==> no database in memory\n"); HitKey(); return; } PrintAvailableDatabases(); printf("\n Choose a database ==> "); scanf("%d", &dbid); found = -1; for(i=0;i Wrong database ID\n"); HitKey(); return; } ret = eXdbmReloadDatabase(&Databases[found],0); if(ret==-1) { ErrorMessage(); return; } printf("\nDatabase %d realoaded\n", dbid); HitKey(); } void PrintDatabase(void) { DB_ID dbid; int i; int found; int ret; printf("\n\n"); printf("Printing a database contents"); printf("----------------------------"); if(DbCount==0) { printf("\n\nError ==> no database in memory\n"); HitKey(); return; } PrintAvailableDatabases(); printf("\n Choose a database ==> "); scanf("%d", &dbid); found = -1; for(i=0;i Wrong database ID\n"); HitKey(); return; } ret = eXdbmBackupDatabase(dbid, "test.database.tmp"); if(ret==-1) { ErrorMessage(); HitKey(); return; } system("less test.database.tmp"); printf("\n====================\n"); system("rm test.database.tmp"); } DB_ID ChooseDatabase(void) { DB_ID dbid; int i; int found; if(DbCount==0) { printf("\n\nError ==> no database in memory\n"); HitKey(); return(-1); } PrintAvailableDatabases(); printf("\n Choose a database ==> "); scanf("%d", &dbid); found = -1; for(i=0;i Wrong database ID\n"); HitKey(); return(-1); } return(dbid); } DB_LIST ChooseParentList(DB_ID dbid) { int choice = 0; char cbuf; char name[256]; char path[16384]; char searchpath[16384]; DB_LIST current = NULL; DB_LIST newlist; strcpy(path, "Root:"); while(1) { while (choice<1 || choice>5) { printf("\n"); printf("Choose the parent's list of the entry : \n\n"); printf("\nCurrent list = %s\n\n", path); printf("1) Root list\n"); printf("2) Get sublist\n"); printf("3) Search sublist recursively\n"); printf("4) Enter full path of list\n"); printf("\n5) Use the current list\n"); printf("\n Your choice ==> "); choice=0; scanf("%d", &choice); if(choice==0) scanf("%c", &cbuf); } switch(choice) { case 1 : strcpy(path,"Root:"); current = NULL; break; case 2: printf("\nEnter sublist name ==> "); scanf("%s", name); newlist = eXdbmGetList(dbid, current, name); if(newlist==NULL) { ErrorMessage(); } else { current = newlist; strcat(path,name); strcat(path,":"); } break; case 3: printf("\nEnter sublist name ==> "); scanf("%s", name); newlist = eXdbmSearchList(dbid, current, name); if(newlist==NULL) { ErrorMessage(); } else { current = newlist; strcat(path, "...:"); strcat(path, name); strcat(path,":"); } break; case 4: printf("\nEnter list path (except Root:) ==> "); scanf("%s", searchpath); newlist = eXdbmPathList(dbid, searchpath); if(newlist==NULL) { ErrorMessage(); } else { current = newlist; strcpy(path, "Root:"); strcat(path, searchpath); strcat(path, ":"); } break; case 5: return(current); } choice=0; } return(NULL); } void PrintValues(void) { int dbid; DB_LIST parent; char name[256]; int etype; char *comment; DB_LIST list; int ival; double rval; char *sval; printf("\n\n"); printf("Values of an entry\n"); printf("------------------\n"); dbid = ChooseDatabase(); if(dbid==-1) return; parent = ChooseParentList(dbid); printf("\nChoose entry name ==> "); scanf("%s", name); etype = eXdbmGetEntryType(dbid, parent, name); if(etype==-1) { ErrorMessage(); HitKey(); return; } printf("\nEntry values :\n"); printf( "------------\n\n"); printf("[NAME] = %s\n\n", name); comment = eXdbmGetEntryComment(dbid, parent, name); if(comment!=NULL) printf("[COMMENT] = %s\n\n", comment); switch(etype) { case DBM_ENTRY_LIST : printf("[TYPE] = List\n\n"); list = eXdbmGetList(dbid, parent, name); printf("Info : This list contains %d entries\n\n", list->current_order); break; case DBM_ENTRY_VAR_INT : printf("[TYPE] = integer variable\n\n"); eXdbmGetVarInt(dbid, parent, name, &ival); printf("[VALUE] = %d\n\n", ival); break; case DBM_ENTRY_VAR_REAL : printf("[TYPE] = real number variable\n\n"); eXdbmGetVarReal(dbid, parent, name, &rval); printf("[VALUE] = %f\n\n", rval); break; case DBM_ENTRY_VAR_BOOL : printf("[TYPE] = boolean variable\n\n"); eXdbmGetVarBool(dbid, parent, name, &ival); if(ival==0) printf("[VALUE] = FALSE\n\n"); else printf("[VALUE] = TRUE\n\n"); break; case DBM_ENTRY_VAR_STRING : printf("[TYPE] = string variable\n\n"); eXdbmGetVarString(dbid, parent, name, &sval); printf("[VALUE] = %s\n\n", sval); free(sval); break; case DBM_ENTRY_VAR_IDENT : printf("[TYPE] = identifier variable\n\n"); eXdbmGetVarIdent(dbid, parent, name, &sval); printf("[VALUE] = %s\n\n", sval); free(sval); break; } HitKey(); } void AddEntry(void) { int dbid; DB_LIST parent; char name[256]; int etype; char *comment; char comval[256]; int ival; double rval; char sval[256]; char choice[10]; int ret; printf("\n\n"); printf("Create an entry\n"); printf("---------------\n"); dbid = ChooseDatabase(); if(dbid==-1) return; parent = ChooseParentList(dbid); printf("\nChoose entry name ==> "); scanf("%s", name); etype = eXdbmGetEntryType(dbid, parent, name); if(etype!=-1) { printf("\nerror ==> entry already defined\n"); HitKey(); return; } printf("\nEntry values :\n"); printf( "------------\n\n"); printf("[NAME] = %s\n\n", name); printf("Do you want to specify a comment (y/n) ? "); scanf("%s", choice); comment = NULL; if(toupper(choice[0])=='Y') { printf("[COMMENT] = "); gets(comval); comment = comval; } etype = 0; while(etype<1 || etype > 6) { printf("\nChoose the type of the entry :\n\n"); printf("1 => integer\n"); printf("2 => real\n"); printf("3 => bool\n"); printf("4 => string\n"); printf("5 => idenfifier\n"); printf("6 => list\n"); printf("\n Your choice ==> "); etype=0; scanf("%d", &etype); if(etype==0) scanf("%s", choice); } etype--; switch(etype) { case DBM_ENTRY_LIST : printf("[TYPE] = List\n\n"); ret = eXdbmCreateList(dbid, parent, name, comment); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_INT : printf("[TYPE] = integer variable\n\n"); printf("[VALUE] = "); scanf("%d", &ival); ret = eXdbmCreateVarInt(dbid, parent, name, comment, ival); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_REAL : printf("[TYPE] = real number variable\n\n"); printf("[VALUE] = "); scanf("%lf", &rval); ret = eXdbmCreateVarReal(dbid, parent, name, comment, rval); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_BOOL : printf("[TYPE] = boolean variable\n\n"); printf("[VALUE] = "); scanf("%s", sval); if(strcmp(sval, "FALSE")==0) ret = eXdbmCreateVarBool(dbid, parent, name, comment, 0); else ret = eXdbmCreateVarBool(dbid, parent, name, comment, 1); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_STRING : printf("[TYPE] = string variable\n\n"); printf("[VALUE] = "); scanf("%s", sval); ret = eXdbmCreateVarString(dbid, parent, name, comment, sval); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_IDENT : printf("[TYPE] = identifier variable\n\n"); printf("[VALUE] = "); scanf("%s", sval); ret = eXdbmCreateVarIdent(dbid, parent, name, comment, sval); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; } HitKey(); } void ChangeEntry(void) { int dbid; DB_LIST parent; char name[256]; int etype; char *comment; char comval[256]; int ival; double rval; char sval[256]; char choice[10]; int ret; printf("\n\n"); printf("Change an entry\n"); printf("---------------\n"); dbid = ChooseDatabase(); if(dbid==-1) return; parent = ChooseParentList(dbid); printf("\nChoose entry name ==> "); scanf("%s", name); etype = eXdbmGetEntryType(dbid, parent, name); if(etype==-1) { printf("\nerror ==> entry not defined\n"); HitKey(); return; } printf("\nEntry values :\n"); printf( "------------\n\n"); printf("[NAME] = %s\n\n", name); comment = eXdbmGetEntryComment(dbid, parent, name); if(comment!=NULL) printf("[COMMENT] = %s\n\n", comment); printf("Do you want to specify a new comment (y/n) ? "); scanf("%s", choice); comment = NULL; if(toupper(choice[0])=='Y') { printf("[COMMENT] = "); gets(comval); comment = comval; } if(comment!=NULL) eXdbmChangeEntryComment(dbid, parent, name, comment); switch(etype) { case DBM_ENTRY_LIST : printf("[TYPE] = List\n\n"); printf("Cannot change a list entry\n"); break; case DBM_ENTRY_VAR_INT : printf("[TYPE] = integer variable\n\n"); printf("[VALUE] = "); scanf("%d", &ival); ret = eXdbmChangeVarInt(dbid, parent, name, ival); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_REAL : printf("[TYPE] = real number variable\n\n"); printf("[VALUE] = "); scanf("%lf", &rval); ret = eXdbmChangeVarReal(dbid, parent, name, rval); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_BOOL : printf("[TYPE] = boolean variable\n\n"); printf("[VALUE] = "); scanf("%s", sval); if(strcmp(sval, "FALSE")==0) ret = eXdbmChangeVarBool(dbid, parent, name, 0); else ret = eXdbmChangeVarBool(dbid, parent, name, 1); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_STRING : printf("[TYPE] = string variable\n\n"); printf("[VALUE] = "); gets(sval); ret = eXdbmChangeVarString(dbid, parent, name, sval); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; case DBM_ENTRY_VAR_IDENT : printf("[TYPE] = identifier variable\n\n"); printf("[VALUE] = "); gets(sval); ret = eXdbmChangeVarIdent(dbid, parent, name, sval); if(ret==-1) { ErrorMessage(); HitKey(); return; } break; } HitKey(); } void DeleteEntry(void) { int dbid; DB_LIST parent; char name[256]; int etype; char *comment; char choice[10]; int ret; printf("\n\n"); printf("Delete an entry\n"); printf("---------------\n"); dbid = ChooseDatabase(); if(dbid==-1) return; parent = ChooseParentList(dbid); printf("\nChoose entry name ==> "); scanf("%s", name); etype = eXdbmGetEntryType(dbid, parent, name); if(etype==-1) { printf("\nerror ==> entry not defined\n"); HitKey(); return; } printf("\nEntry values :\n"); printf( "------------\n\n"); printf("[NAME] = %s\n\n", name); if(comment!=NULL) eXdbmChangeEntryComment(dbid, parent, name, comment); switch(etype) { case DBM_ENTRY_LIST : printf("[TYPE] = List\n\n"); printf("Cannot change a list entry\n"); break; case DBM_ENTRY_VAR_INT : printf("[TYPE] = integer variable\n\n"); break; case DBM_ENTRY_VAR_REAL : printf("[TYPE] = real number variable\n\n"); break; case DBM_ENTRY_VAR_BOOL : printf("[TYPE] = boolean variable\n\n"); break; case DBM_ENTRY_VAR_STRING : printf("[TYPE] = string variable\n\n"); break; case DBM_ENTRY_VAR_IDENT : printf("[TYPE] = identifier variable\n\n"); break; } printf("Do you want to erase this variable (y/n) ? "); scanf("%s", choice); if(toupper(choice[0])=='Y') { ret = eXdbmDeleteEntry(dbid, parent, name); if(ret==-1) { ErrorMessage(); HitKey(); return; } printf("\nEntry deleted successfully\n"); } else printf("\nEntry not deleted\n"); HitKey(); } int MainMenu(void) { int choice=0; while(choice<1 || choice>12) { printf("\n\n"); printf("eXdbm test application main menu\n"); printf("================================\n"); printf("\n"); printf("%d database(s) in memory\n\n", DbCount); printf("Database management : \n"); printf("------------------- \n"); printf("1) Open a database\n"); printf("2) New database\n"); printf("3) Close a database\n"); printf("4) Update database\n"); printf("5) Backup database\n"); printf("6) Reload a database\n"); printf("7) Print database contents\n"); printf("Entry management :\n"); printf("----------------\n"); printf("8) Print entry values\n"); printf("9) Add an entry\n"); printf("10) Change entry values\n"); printf("11) Delete an entry\n"); printf("12) Quit\n"); printf("\n Make your choice ===> "); choice=0; scanf ("%d", &choice); if(choice==0) HitKey(); } return(choice); } int main(void) { int choice; int ret; ret = eXdbmInit(); if(ret==-1) { ErrorMessage(); return(EXIT_FAILURE); } choice=-1; while(choice!=12) { choice = MainMenu(); switch(choice) { case 1 : OpenDatabase(); break; case 2 : NewDatabase(); break; case 3 : CloseDatabase(); break; case 4 : UpdateDatabase(); break; case 5 : BackupDatabase(); break; case 6 : ReloadDatabase(); break; case 7 : PrintDatabase(); break; case 8 : PrintValues(); break; case 9 : AddEntry(); break; case 10: ChangeEntry(); break; case 11 : DeleteEntry(); break; } } printf("\n\nBye bye ...\n"); return(1); } gpsim-0.30.0/eXdbm/misc.h0000664000076400007640000000341413041763641012016 00000000000000 /* $Id: misc.h 230 2002-04-15 22:03:02Z linas $ */ /***** * misc.h : eXdbm misc. functions header * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef MISC_H #define MISC_H #include #include "eXdbmTypes.h" void RaiseError(int errorcode); int DbmIsInit(void); int CheckDbIdent(DB_ID dbid); int WriteDatabase(FILE *f, TDbmListEntry *list, int level); int DestroyDatabase(TDbmListEntry *list); void PrintDatabase(TDbmListEntry *list, int level); TDbmListEntry * SearchListEntry(TDbmListEntry *list, char *namevar); TDbmListEntry * SearchListEntryRec(TDbmListEntry *list, char *entryname); TDbmListEntry * CreateListEntry(TDbmListEntry *list, char *entryname, char *comment, int entrytype); int DeleteListEntry(TDbmListEntry *list, char *entryname); int AddOrderEntry(TDbmListEntry *list, TDbmListEntry *element); #endif /* end of misc.h */ gpsim-0.30.0/eXdbm/misc.c0000664000076400007640000002457213041763641012021 00000000000000 /* $Id: misc.c 2216 2013-06-30 00:56:58Z roy_r_rankin $ */ /***** * misc.c : eXdbm misc. functions * * This file Version $Revision: 2216 $ * * Last modification: $Date: 2013-06-30 10:56:58 +1000 (Sun, 30 Jun 2013) $ * By: $Author: roy_r_rankin $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #include #include #include #include "eXdbmTypes.h" #include "eXdbmErrors.h" #include "hash.h" #include "misc.h" /* externals */ extern int DbmLastErrorCode; extern TDbmDbList *DbmDbList; /* error handling */ void RaiseError(int errorcode) { DbmLastErrorCode = errorcode; } /* is the database initialized ? */ int DbmIsInit(void) { if(DbmDbList==NULL) { RaiseError(DBM_INIT_NEEDED); return(-1); } return(1); } /* check a database identifier */ int CheckDbIdent(DB_ID dbid) { if(dbid>=DbmDbList->array_size) return(-1); if(DbmDbList->dblist[dbid].root == NULL) return(-1); return(1); } /* write a database to a file */ int WriteDatabase(FILE *f, TDbmListEntry *list, int level) { int i; int j; TDbmListEntry *node; int ret; for(i=0; i< list->current_order; i++) { node = list->order[i]; switch(node->entry_type) { case DBM_ENTRY_VAR_INT : if(node->comment!=NULL) { fprintf(f, "\n"); for(j=0;jcomment); } fprintf(f,"\n"); for(j=0;jkey, node->value.int_val); break; case DBM_ENTRY_VAR_REAL : if(node->comment!=NULL) { fprintf(f, "\n"); for(j=0;jcomment); } fprintf(f,"\n"); for(j=0;jkey, node->value.real_val); break; case DBM_ENTRY_VAR_STRING : if(node->comment!=NULL) { fprintf(f, "\n"); for(j=0;jcomment); } fprintf(f,"\n"); for(j=0;jkey, node->value.str_val); break; case DBM_ENTRY_VAR_IDENT : if(node->comment!=NULL) { fprintf(f, "\n"); for(j=0;jcomment); } fprintf(f,"\n"); for(j=0;jkey, node->value.str_val); break; case DBM_ENTRY_VAR_BOOL : if(node->comment!=NULL) { fprintf(f, "\n"); for(j=0;jcomment); } fprintf(f,"\n"); for(j=0;jvalue.int_val==1) fprintf(f,"%s = TRUE\n", node->key); else fprintf(f,"%s = FALSE\n", node->key); break; case DBM_ENTRY_LIST : if(node->comment!=NULL) { fprintf(f, "\n"); for(j=0;jcomment); } fprintf(f,"\n"); for(j=0;jkey); ret = WriteDatabase(f, node, level+1); if(ret==-1) { RaiseError(DBM_UPDATE_WRITE_ERROR); return(-1); } fprintf(f,"\n"); for(j=0;jcurrent_order; i++) { node = list->order[i]; switch(node->entry_type) { case DBM_ENTRY_VAR_INT : if(node->comment!=NULL) free(node->comment); free(node->key); break; case DBM_ENTRY_VAR_REAL : if(node->comment!=NULL) free(node->comment); free(node->key); break; case DBM_ENTRY_VAR_STRING : if(node->comment!=NULL) free(node->comment); free(node->key); free(node->value.str_val); break; case DBM_ENTRY_VAR_IDENT : if(node->comment!=NULL) free(node->comment); free(node->key); free(node->value.str_val); break; case DBM_ENTRY_VAR_BOOL : if(node->comment!=NULL) free(node->comment); free(node->key); break; case DBM_ENTRY_LIST : if(node->comment!=NULL) free(node->comment); free(node->key); ret = DestroyDatabase(node); if(ret==-1) { RaiseError(DBM_DESTROY); return(-1); } free(node->child); free(node->order); break; default : RaiseError(DBM_DESTROY); return(-1); } } return(0); } /* search an entry in a list */ TDbmListEntry * SearchListEntry(TDbmListEntry *list, char *entryname) { int hash_value; TDbmListEntry *node; if(list==NULL || list->child==NULL || entryname==NULL) return(NULL); hash_value = HashValueGenerator(entryname); node = list->child[hash_value]; while(node!=NULL) { if(strcmp(node->key, entryname)==0) { /* we've found the entry */ return(node); } node=node->next; } return(NULL); } /* search an entry in a list and all sublists recursively */ TDbmListEntry * SearchListEntryRec(TDbmListEntry *list, char *entryname) { TDbmListEntry *node; int i; node = SearchListEntry(list, entryname); if(node!=NULL) return(node); /* search in sublists */ for(i=0;i< list->current_order ; i++) { if(list->order[i]->entry_type==DBM_ENTRY_LIST) { node = SearchListEntryRec(list->order[i], entryname); if(node!=NULL) return(node); } } return(NULL); } /* create a new entry */ TDbmListEntry * CreateListEntry(TDbmListEntry *list, char *entryname, char *comment, int entrytype) { int hash_value; TDbmListEntry *node; int i; int ret; node = SearchListEntry(list, entryname); if(node!=NULL) { RaiseError(DBM_DUPLICATE_ENTRY); return(NULL); } hash_value = HashValueGenerator(entryname); node = list->child[hash_value]; if(node!=NULL) { while(node->next!=NULL) node=node->next; /* create the new entry */ node->next = (TDbmListEntry *) malloc(sizeof(TDbmListEntry)); if(node->next==NULL) { RaiseError(DBM_ALLOC); return(NULL); } node=node->next; } else { node = (TDbmListEntry *) malloc(sizeof(TDbmListEntry)); if(node==NULL) { RaiseError(DBM_ALLOC); return(NULL); } list->child[hash_value]=node; } /* fill the new entry */ node->key = (char *) malloc(sizeof(char) * (strlen(entryname)+1)); if(node->key==NULL) { RaiseError(DBM_ALLOC); return(NULL); } strcpy(node->key, entryname); if(comment!=NULL) { node->comment = (char *) malloc(sizeof(char) * (strlen(comment)+1)); if(node->comment==NULL) { RaiseError(DBM_ALLOC); return(NULL); } strcpy(node->comment, comment); } else node->comment = NULL; node->entry_type = entrytype; node->value.str_val = NULL; node->value.int_val = -1; node->value.real_val = -1; node->child = NULL; if(node->entry_type == DBM_ENTRY_LIST) { node->child = (TDbmListEntry **) malloc( sizeof(TDbmListEntry *) * HASH_MAX_ENTRIES); if(node->child == NULL) { RaiseError(DBM_ALLOC); return(NULL); } for (i=0; i < HASH_MAX_ENTRIES ; i++) node->child[i] = NULL; node->order = (TDbmListEntry **) malloc( sizeof(TDbmListEntry *) * MIN_ORDER_SIZE); if(node->order == NULL) { RaiseError(DBM_ALLOC); return(NULL); } for(i=0; i < MIN_ORDER_SIZE ; i++) node->order[i] = NULL; node->size_order = MIN_ORDER_SIZE; node->current_order = 0; } else { node->size_order = 0; node->current_order = 0; node->order = NULL; } node->next = NULL; /* add the list to the order array */ list->current_order++; ret = AddOrderEntry( list, node); if(ret == -1) return(NULL); return(node); } /* Delete an entry in a list */ int DeleteListEntry(TDbmListEntry *list, char *entryname) { int hash_value; TDbmListEntry *node; int found; TDbmListEntry *before; TDbmListEntry *after; int i,j; if(list==NULL || list->child==NULL || entryname==NULL) return(-1); hash_value = HashValueGenerator(entryname); node = list->child[hash_value]; if(node==NULL) return(-1); found = 0; before = NULL; after = node->next; while(!found && node!=NULL) { if(strcmp(node->key, entryname)==0) /* we've found the entry */ found = 1; if(!found) { before = node; node=node->next; } after = node->next; } if(node==NULL) return(-1); /* remove the list order entry */ i=0; while(node!=list->order[i]) i++; for(j=i; j< list->current_order-1; j++) list->order[j] = list->order[j+1]; list->order[list->current_order-1] = NULL; list->current_order--; /* delete the entry */ free(node->key); if(node->comment!=NULL) free(node->comment); switch(node->entry_type) { case DBM_ENTRY_VAR_STRING : case DBM_ENTRY_VAR_IDENT : if(node->value.str_val!=NULL ) free(node->value.str_val); break; case DBM_ENTRY_LIST : DestroyDatabase(node); free(node->child); free(node->order); break; } /* update the chained list */ if(before!=NULL) before->next = after; else list->child[hash_value] = after; return(1); } /* add element in order array */ int AddOrderEntry(TDbmListEntry *list, TDbmListEntry *element) { /* need new elements in array ? */ if(list->current_order > list->size_order) { list->size_order *= 2; list->order = (TDbmListEntry **) realloc( list->order, sizeof(TDbmListEntry *) * (list->size_order)); if(list->order == NULL) { RaiseError(DBM_ALLOC); return(-1); } } /* fill the element */ (list->order)[list->current_order-1] = element; return(1); } gpsim-0.30.0/eXdbm/test1.c0000664000076400007640000000534613041763641012124 00000000000000 /* $Id: test1.c 230 2002-04-15 22:03:02Z linas $ */ /***** * test1.c : eXdbm example * * This file Version $Revision: 230 $ * * Last modification: $Date: 2002-04-16 08:03:02 +1000 (Tue, 16 Apr 2002) $ * By: $Author: linas $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #ifndef lint static char vcid[] = "$Id: test1.c 230 2002-04-15 22:03:02Z linas $"; #endif /* lint */ #include #include extern TDbmDbList *DbmDbList; int main(void) { DB_ID dbid; int ret; printf(" \n*********************************************"); printf(" \n***** Test1.c : read the file test1.cfg *****"); printf(" \n*********************************************\n\n"); printf("**** Database manager initialization *****\n\n"); ret = eXdbmInit(); if(ret==-1) { fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("**** Opening database in file test1.cfg ****\n\n"); ret = eXdbmOpenDatabase("test1.cfg", &dbid); if(ret==-1) { fprintf(stderr, "\nParsing databases aborted line %d", eXdbmLastLineParsed()); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } fprintf(stderr, "%d lines parsed \n\n", eXdbmLastLineParsed()); printf("**** Checking database contents ****\n"); WriteDatabase(stdout, DbmDbList->dblist[dbid].root, 0); printf("\n\n<<<>>>"); printf("\n\n**** Updating database file ****\n\n"); ret = eXdbmUpdateDatabase(dbid); if(ret == -1) { fprintf(stderr, "\nUpdating databases aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("**** Closing database (no update) ****\n\n"); ret = eXdbmCloseDatabase(dbid, 0); if(ret == -1) { fprintf(stderr, "\nClosing databases aborted"); fprintf(stderr, "\n%s\n", eXdbmGetErrorString(eXdbmGetLastError())); return(-1); } printf("****** eXDbm exit without error *****\n\n"); return(0); } gpsim-0.30.0/eXdbm/test2.cfg0000664000076400007640000000065013041763641012433 00000000000000 # a small list example ThisIsAList { # a boolean variable example BoolVariable = 1 StringVariable = "320" RealVariable = 1430000000000.000000 } Othervar = toto OtherVar2leRetour = "un autre toto" # this is a small example of configuration file ThisIsAnIntegerVar = 31 ThisIsAnIntegerVar = 31 #this comment is for the next variable ThisIsAStringVar = "This is a string" ThisisTheLastVariable = AnIdentifier gpsim-0.30.0/eXdbm/NEWS0000664000076400007640000000000013041763641011375 00000000000000gpsim-0.30.0/eXdbm/test1.cfg.orig0000664000076400007640000000054013041763641013367 00000000000000 # a small list example list1 { # a boolean variable example var1list1 = TRUE StringVar = "320" list2 { varlist2 = 14 list3 { varlist3 = "deepest var" } } # a real value var2list1 = 1430000000000.000000 } var1 = 31 #this comment is for the next variable var2 = "This is a string" var3 = AnIdentifier gpsim-0.30.0/eXdbm/parse.c0000664000076400007640000003364513041763641012201 00000000000000 /* $Id: parse.c 2216 2013-06-30 00:56:58Z roy_r_rankin $ */ /***** * parse.c : eXdbm parser * * This file Version $Revision: 2216 $ * * Last modification: $Date: 2013-06-30 10:56:58 +1000 (Sun, 30 Jun 2013) $ * By: $Author: roy_r_rankin $ * Current State: $State$ * * Copyright (C) 1997 Fred Pesch * All Rights Reserved * * This file is part of the eXdbm Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #include #include #include #include #include "eXdbmErrors.h" #include "eXdbmTypes.h" #include "parse.h" #include "misc.h" #include "hash.h" /* externals */ extern unsigned long DbmParseLineNumber; /* enumerations */ enum { DBM_TOKEN_LIST_ID = 0, DBM_TOKEN_VAR_ID = 1, DBM_TOKEN_INT = 2, DBM_TOKEN_REAL = 3, DBM_TOKEN_BOOL = 4, DBM_TOKEN_STRING = 5 }; /***** parse a comment *****/ int ParseComment(FILE *f, char *comment) { int current; int pos_in_comment=0; do { current=fgetc(f); if(current==EOF) { comment[pos_in_comment]=(char)0; return(EOF); } if(current!='\n') { comment[pos_in_comment]=current; pos_in_comment++; if(pos_in_comment+1>=MAX_ENTRY_LENGTH) return(-1); } } while(current!='\n'); DbmParseLineNumber++; comment[pos_in_comment]= (char) 0; return(1); } /***** parse an identifier *****/ int ParseIdentifier(FILE *f, char *token) { int current; int pos_in_token=0; /* the first char is available */ token[pos_in_token++] = fgetc(f); /* read the identifier name */ do { current = fgetc(f); if(current==EOF) return(-1); if(isalnum(current) || current=='_') token[pos_in_token++]=current; else if(!isspace(current)) return(-1); if(pos_in_token+1>=MAX_ENTRY_LENGTH) return(-1); } while(!isspace(current)); token[pos_in_token] = (char) 0; while(isspace(current)) { if(current=='\n') return(-1); current=fgetc(f); if(current==EOF) return(-1); } /* check if it's a list or a variable */ switch(current) { case '{': /* this is a list */ current=fgetc(f); while(current!='\n') { if(!isspace(current)) return(-1); current=fgetc(f); if(current==EOF) return(-1); } while(current=='\n') { DbmParseLineNumber++; current=fgetc(f); } return(DBM_TOKEN_LIST_ID); break; case '=' : /* this is a variable */ do { current=fgetc(f); if(current==EOF || current=='\n') return(-1); } while(isspace(current)); ungetc((int) current, f); return(DBM_TOKEN_VAR_ID); break; default : return(-1); } return(-1); } /***** parse an entry value *****/ int ParseEntryValue(FILE *f, TDbmEntryValue *value) { int current; int state; char value_string[MAX_ENTRY_LENGTH]; int pos_in_string = 0; state=0; while(1) { current = fgetc(f); if(current==EOF) return(-1); /* unexpected end of file */ switch(state) { case 0 : /* initial state */ if(isdigit(current)) { value_string[pos_in_string++] = current; state=2; } else if(current=='+' || current=='-') { value_string[pos_in_string++] = current; state=1; } else if (isalpha(current)) { value_string[pos_in_string++] = current; state=12; } else if (current == '"') state=14; else return(-1); break; case 1 : /* a '+' or a '-' starts the string */ while(isspace(current)) { if(current == '\n' || current == EOF) return(-1); current = fgetc(f); } ungetc(current, f); state=2; break; case 2 : /* read numbers */ while(isdigit(current)) { value_string[pos_in_string++] = current; if(pos_in_string+1>=MAX_ENTRY_LENGTH) return(-1); current = fgetc(f); } if(isspace(current) || current==EOF) { while(isspace(current)) { if(current=='\n') DbmParseLineNumber++; current=fgetc(f); } if(current!=EOF) ungetc(current, f); value_string[pos_in_string] = (char) 0; value->int_val = atoi(value_string); value->real_val = atof(value_string); value->str_val = NULL; return(DBM_ENTRY_VAR_INT); } if(current=='e' || current=='E') { value_string[pos_in_string++] = current; state=4; } else if(current=='.') { value_string[pos_in_string++] = current; state=7; } else return(-1); break; case 4 : /* an integer with exposant */ if(current=='+' || current=='-') { value_string[pos_in_string++] = current; current=fgetc(f); if(current==EOF || isspace(current)) return(-1); } if(!isdigit(current)) return(-1); while(isdigit(current)) { value_string[pos_in_string++] = current; if(pos_in_string+1>=MAX_ENTRY_LENGTH) return(-1); current=fgetc(f); } if(!isspace(current) && current!=EOF) return(-1); while(isspace(current)) { if(current=='\n') DbmParseLineNumber++; current=fgetc(f); } ungetc(current, f); value->int_val = atoi(value_string); value->real_val = atof(value_string); value->str_val = NULL; return(DBM_ENTRY_VAR_INT); break; case 7: /* a real number */ if(!isdigit(current)) return(-1); while(isdigit(current)) { value_string[pos_in_string++] = current; if(pos_in_string+1>=MAX_ENTRY_LENGTH) return -1; current = fgetc(f); } if(current=='e' || current=='E') { value_string[pos_in_string++] = current; current=fgetc(f); if(current=='+' || current=='-') { value_string[pos_in_string++] = current; current=fgetc(f); if(current==EOF || isspace(current)) return(-1); } if(!isdigit(current)) return(-1); while(isdigit(current)) { value_string[pos_in_string++] = current; if(pos_in_string+1>=MAX_ENTRY_LENGTH) return(-1); current=fgetc(f); } } if(isspace(current) || current==EOF) { while(isspace(current)) { if(current=='\n') DbmParseLineNumber++; current=fgetc(f); } if(current!=EOF) ungetc(current, f); value_string[pos_in_string] = (char) 0; value->real_val = atof(value_string); value->int_val = (int)ceil(value->real_val); value->str_val = NULL; return(DBM_ENTRY_VAR_REAL); } else return(-1); break; case 12 : /* an identifier string */ while(isalnum(current) || current=='_') { value_string[pos_in_string++] = current; if(pos_in_string+1>=MAX_ENTRY_LENGTH) return(-1); current=fgetc(f); } if(isspace(current) || current == EOF) { while(isspace(current)) { if(current=='\n') DbmParseLineNumber++; current=fgetc(f); } if(current!=EOF) ungetc(current, f); value_string[pos_in_string] = (char) 0; if(strcmp(value_string,"TRUE")==0) { /* a boolean value = TRUE */ value->real_val = -1; value->int_val = 1; value->str_val = NULL; return(DBM_ENTRY_VAR_BOOL); } if(strcmp(value_string,"FALSE")==0) { /* a boolean value = FALSE */ value->real_val = -1; value->int_val = 0; value->str_val = NULL; return(DBM_ENTRY_VAR_BOOL); } /* an identifier */ value->real_val = -1; value->int_val = -1; value->str_val = (char *) malloc(sizeof(char) * (strlen(value_string)+1)); if(value->str_val==NULL) return(-1); strcpy(value->str_val,value_string); return(DBM_ENTRY_VAR_IDENT); } else return(-1); break; case 14: /* a complete string */ while(current!='"') { if(current=='\n') DbmParseLineNumber++; if(current==EOF) return(-1); value_string[pos_in_string++] = current; if(pos_in_string+1>=MAX_ENTRY_LENGTH) return(-1); current = fgetc(f); } current = fgetc(f); if(isspace(current) || current == EOF) { while(isspace(current)) { if(current=='\n') DbmParseLineNumber++; current=fgetc(f); } if(current!=EOF) ungetc(current, f); value_string[pos_in_string] = (char) 0; value->real_val = -1; value->int_val = -1; value->str_val = (char *) malloc(sizeof(char) * (strlen(value_string)+1)); if(value->str_val==NULL) return(-1); strcpy(value->str_val,value_string); return(DBM_ENTRY_VAR_STRING); } else return(-1); break; default : return(-1); } if(pos_in_string+1>=MAX_ENTRY_LENGTH) return(-1); } return(-1); } /***** main parsing function *****/ int ParseFile(FILE *f, TDbmListEntry *list, int level) { static char current_token[MAX_ENTRY_LENGTH]; int token_type; static char last_comment[MAX_ENTRY_LENGTH]; static int last_comment_available = 0; int current; int hash_value; TDbmListEntry *newnode; int ret; int i; do { /* skip the preceeding spaces & empty lines (counted) */ current=fgetc(f); while(isspace(current)) { if(current=='\n') DbmParseLineNumber++; current=fgetc(f); } if(current == EOF || current=='}') continue; if(current=='#') { ungetc(current, f); /* parse a comment */ last_comment_available = ParseComment(f, last_comment); if(last_comment_available==-1) { RaiseError(DBM_PARSE_COMMENT); return(-1); } if(last_comment_available==EOF) { current=EOF; continue; } } else if(isalpha(current)) { ungetc(current, f); /* parse a variable or list identifier */ token_type = ParseIdentifier(f, current_token); switch(token_type) { case DBM_TOKEN_LIST_ID : /* new list entry */ hash_value = HashValueGenerator ( current_token ); if ( list->child[hash_value] == NULL ) { list->child[hash_value] = ( TDbmListEntry *) malloc( sizeof(TDbmListEntry) ); if(list->child[hash_value] == NULL) { RaiseError(DBM_ALLOC); return(-1); } newnode = list->child[hash_value]; newnode->next = NULL; } else { /* there's already an entry at this place */ newnode = list->child[hash_value]; while(newnode->next!=NULL) newnode = newnode->next; newnode->next = (TDbmListEntry *) malloc( sizeof(TDbmListEntry) ); if(newnode->next == NULL) { RaiseError(DBM_ALLOC); return(-1); } newnode=newnode->next; newnode->next = NULL; } /* fill the new entry */ /* key name */ newnode->key = (char *) malloc (sizeof(char) * (strlen(current_token) + 1)); if(newnode->key == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(newnode->key, current_token); /* comment */ if(last_comment_available) { newnode->comment = (char *) malloc (sizeof(char) * (strlen(last_comment) + 1)); if(newnode->comment == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(newnode->comment, last_comment); last_comment_available = 0; } else newnode->comment = NULL; /* entry type */ newnode->entry_type = DBM_ENTRY_LIST; /* child list */ newnode->child = (TDbmListEntry **) malloc( sizeof(TDbmListEntry *) * HASH_MAX_ENTRIES); if(newnode->child == NULL) { RaiseError(DBM_ALLOC); return(-1); } for (i=0; i < HASH_MAX_ENTRIES ; i++) newnode->child[i] = NULL; /* order array */ newnode->order = (TDbmListEntry **) malloc( sizeof(TDbmListEntry *) * MIN_ORDER_SIZE); if(newnode->order == NULL) { RaiseError(DBM_ALLOC); return(-1); } newnode->size_order = MIN_ORDER_SIZE; newnode->current_order = 0; /* add the list to the order array */ list->current_order++; ret = AddOrderEntry( list, newnode); if(ret==-1) return(-1); /* continue the parsing recursively */ ret = ParseFile(f, newnode, level+1); if(ret == -1) return(-1); break; case DBM_TOKEN_VAR_ID : /* new variable entry */ hash_value = HashValueGenerator ( current_token ); if ( list->child[hash_value] == NULL ) { list->child[hash_value] = ( TDbmListEntry *) malloc( sizeof(TDbmListEntry) ); if(list->child[hash_value] == NULL) { RaiseError(DBM_ALLOC); return(-1); } newnode = list->child[hash_value]; newnode->next = NULL; } else { /* there's already an entry at this place */ newnode = list->child[hash_value]; while(newnode->next!=NULL) newnode = newnode->next; newnode->next = (TDbmListEntry *) malloc( sizeof(TDbmListEntry) ); if(newnode->next == NULL) { RaiseError(DBM_ALLOC); return(-1); } newnode=newnode->next; } /* fill the new entry */ /* next */ newnode->next = NULL; /* key name */ newnode->key = (char *) malloc (sizeof(char) * (strlen(current_token) + 1)); if(newnode->key == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(newnode->key, current_token); /* comment */ if(last_comment_available) { newnode->comment = (char *) malloc (sizeof(char) * (strlen(last_comment) + 1)); if(newnode->comment == NULL) { RaiseError(DBM_ALLOC); return(-1); } strcpy(newnode->comment, last_comment); last_comment_available = 0; } else newnode->comment = NULL; /* entry type */ newnode->entry_type = ParseEntryValue(f, &newnode->value); if(newnode->entry_type == -1) { RaiseError(DBM_PARSE_VALUE); return(-1); } /* no child list for variable entries */ newnode->child = NULL; /* no order array */ newnode->order = NULL; newnode->size_order = 0; newnode->current_order = 0; /* add the variable to the order array */ list->current_order++; ret = AddOrderEntry( list, newnode); if(ret==-1) return(-1); break; default : /* unknown entry */ RaiseError(DBM_PARSE_ID); return(-1); } } else return(-1); } while(current!=EOF && current!='}'); if(current==EOF && level>0) { RaiseError(DBM_PARSE_UNEXP_END); return(-1); } return(1); } gpsim-0.30.0/eXdbm/COPYING.LIB0000664000076400007640000006126113041763641012356 00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! gpsim-0.30.0/eXdbm/COPYING0000664000076400007640000000000013041763641011731 00000000000000gpsim-0.30.0/depcomp0000755000076400007640000005601612734477075011247 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gpsim-0.30.0/examples/0000775000076400007640000000000013117465766011562 500000000000000gpsim-0.30.0/examples/16bit/0000775000076400007640000000000013117465766012507 500000000000000gpsim-0.30.0/examples/16bit/p18c242.inc0000664000076400007640000001604713041763642014123 00000000000000 ;; ;; Include file for the p18c242 ;; ;----- register files------------------------------------------------------ porta equ 0xf80 portb equ 0xf81 portc equ 0xf82 portd equ 0xf83 porte equ 0xf84 lata equ 0xf89 latb equ 0xf8a latc equ 0xf8b latd equ 0xf8c late equ 0xf8d trisa equ 0xf92 trisb equ 0xf93 trisc equ 0xf94 trisd equ 0xf95 trise equ 0xf96 pie1 equ 0xf9d pir1 equ 0xf9e ipr1 equ 0xf9f pie2 equ 0xfa0 pir2 equ 0xfa1 ipr2 equ 0xfa2 rcsta equ 0xfab txsta equ 0xfac txreg equ 0xfad rcreg equ 0xfae spbrg equ 0xfaf t3con equ 0xf91 tmr3l equ 0xf92 tmr3h equ 0xf93 rcon equ 0xfd0 wdtcon equ 0xfd1 lvdcon equ 0xfd2 osccon equ 0xfd3 tmr0con equ 0xfd5 t0con equ 0xfd5 tmr0l equ 0xfd6 tmr0h equ 0xfd7 status equ 0xfd8 fsr2l equ 0xfd9 fsr2h equ 0xfda plusw2 equ 0xfdb preinc2 equ 0xfdc postdec2 equ 0xfdd postinc2 equ 0xfde indf2 equ 0xfdf bsr equ 0xfe0 fsr1l equ 0xfe1 fsr1h equ 0xfe2 plusw1 equ 0xfe3 preinc1 equ 0xfe4 postdec1 equ 0xfe5 postinc1 equ 0xfe6 indf1 equ 0xfe7 wreg equ 0xfe8 fsr0l equ 0xfe9 fsr0h equ 0xfea plusw0 equ 0xfeb preinc0 equ 0xfec postdec0 equ 0xfed postinc0 equ 0xfee indf0 equ 0xfef intcon3 equ 0xff0 intcon2 equ 0xff1 intcon equ 0xff2 prodl equ 0xff3 prodh equ 0xff4 tablat equ 0xff5 tabptrl equ 0xff6 tabptrh equ 0xff7 tabptru equ 0xff8 pcl equ 0xff9 pclath equ 0xffa pclatu equ 0xffb stkptr equ 0xffc tosl equ 0xffd tosh equ 0xffe tosu equ 0xfff ;----- status bits -------------------------------------------------------- irp equ 7 rp1 equ 6 rp0 equ 5 not_to equ 4 to equ 4 not_pd equ 3 pd equ 3 z equ 2 dc equ 1 c equ 0 ; intcon bits gie equ 7 peie equ 6 t0ie equ 5 tmr0ie equ 5 int0e equ 4 rbie equ 3 t0if equ 2 tmr0if equ 2 int0f equ 1 rbif equ 0 ; t0con bits tmr0on equ 7 t08bit equ 6 t0cs equ 5 t0se equ 4 psa equ 3 t0ps2 equ 2 t0ps1 equ 1 t0ps0 equ 0 ; txsta bits csrc equ 7 tx9 equ 6 txen equ 5 sync equ 4 brgh equ 2 trmt equ 1 tx9d equ 0 ; rcsta bits spen equ 7 rx9 equ 6 sren equ 5 cren equ 4 ferr equ 2 oerr equ 1 rx9d equ 0 ; pir1 bits pspif equ 7 adif equ 6 rcif equ 5 txif equ 4 sspif equ 3 ccp1if equ 2 tmr2if equ 1 tmr1if equ 0 ; pie1 bits pspie equ 7 adie equ 6 rcie equ 5 txie equ 4 sspie equ 3 ccp1ie equ 2 tmr2ie equ 1 tmr1ie equ 0 ; intcon bits gie equ 7 gieh equ 7 peie equ 6 giel equ 6 t0ie equ 5 tmr0ie equ 5 int0ie equ 4 rbie equ 3 t0if equ 2 tmr0if equ 2 intf equ 1 int0f equ 1 rbif equ 0 ; intcon2 bits rbpu equ 7 intedg0 equ 6 intedg1 equ 5 intedg2 equ 4 tmr0ip equ 2 rbip equ 0 ; intcon3 bits int2ip equ 7 int1ip equ 6 int2ie equ 4 int1ie equ 3 int2if equ 1 int1if equ 0 ;---- Interrupt vectors ----------------------------------- #define INTERRUPT_VECTOR_LO 0x18 #define INTERRUPT_VECTOR_HI 0x08 ;; The following is a direct copy from the MPLAB include file. (Please ;; don't tell microchip ;). Immediately following are some of my ;; redefinitions that match the data sheet. ;========================================================================== ; ; Configuration Bits ; ;========================================================================== ; ;Configuration Byte 0 Options _CP_ON_0 EQU H'00' ; code protect _CP_OFF_0 EQU H'FF' ;Configuration Byte 1 Options _PLL_4MHZ_1 EQU H'3F' ; phase locked loop frequency _PLL_5MHZ_1 EQU H'7F' _PLL_6MHZ_1 EQU H'BF' _PLL_8MHZ_1 EQU H'FF' _LPSCEN_ON_1 EQU H'DF' ; low power system clock enable _LPSCEN_OFF_1 EQU H'FF' _LP_OSC_1 EQU H'F8' ; oscillator type _XT_OSC_1 EQU H'F9' _HS_OSC_1 EQU H'FA' _RC_OSC_1 EQU H'FB' _EC_OSC_1 EQU H'FC' ; w/OSC2 div by 4 _ECRA6_OSC_1 EQU H'FD' ; w/OSC2 as RA6 _HSPLL_OSC_1 EQU H'FE' ; HS PLL _RCRA6_OSC_1 EQU H'FF' ; RC w/OSC2 as RA6 ;Configuration Byte 2 Options _BOREN_ON_2 EQU H'FF' ; brown-out reset enable _BOREN_OFF_2 EQU H'FD' _PWRTE_OFF_2 EQU H'FF' ; Power up Timer enable _PWRTE_ON_2 EQU H'FE' _BORV_25_2 EQU H'FF' ; BOREN Voltage - 2.5v _BORV_27_2 EQU H'FB' ; 2.7v _BORV_42_2 EQU H'F7' ; 4.2v _BORV_45_2 EQU H'F3' ; 4.5v ;Configuration Byte 3 Options _WDT_ON_3 EQU H'FF' ; watch dog timer _WDT_OFF_3 EQU H'FE' _WDPS_128_3 EQU H'FF' ; watch dog timer postscaler _WDPS_64_3 EQU H'FD' _WDPS_32_3 EQU H'FB' _WDPS_16_3 EQU H'F9' _WDPS_8_3 EQU H'F7' _WDPS_4_3 EQU H'F5' _WDPS_2_3 EQU H'F3' _WDPS_1_3 EQU H'F1' ;Configuration Byte 5 Options _CCP2MX_ON_5 EQU H'FF' ; _CCP2MX_OFF_5 EQU H'FE' ;Configuration Byte 6 Options _LV_ON_6 EQU H'FD' ; low voltage _LV_OFF_6 EQU H'FF' _STVRE_ON_6 EQU H'FF' ; stack over/underflow reset enable _STVRE_OFF_6 EQU H'FE' ; To use the Configuration Bits, place the following lines in your source code ; in the following format, and change the configuration value to the desired ; setting (such as CP_OFF to CP_ON). These are currently commented out here ; and each __CONFIG line should have the preceding semicolon removed when ; pasted into your source code. ; The following is a assignment of address values for all of the configuration ; registers for the purpose of table reads _CONFIG0 EQU H'300000' _CONFIG1 EQU H'300001' _CONFIG2 EQU H'300002' _CONFIG3 EQU H'300003' _CONFIG4 EQU H'300004' _CONFIG5 EQU H'300005' _CONFIG6 EQU H'300006' _CONFIG7 EQU H'300007' ;Program Configuration Register 0 ; __CONFIG _CONFIG0,_CP_OFF_0 ;Program Configuration Register 1 ; __CONFIG _CONFIG1,_PLL_8MHZ_1 & _LPSCEN_OFF_1 & _RCRA6_OSC_1 ;Program Configuration Register 2 ; __CONFIG _CONFIG2, _BORV_25_2 & _BODEN_ON_2 & _PWRTE_OFF_2 ;Program Configuration Register 3 ; __CONFIG _CONFIG3, _WDPS_128_3 & _WDT_ON_3 ;Program Configuration Register 5 ;__CONFIG _CONFIG5, _CCP2MX_ON_5 ;Program Configuration Register 6 ; __CONFIG _CONFIG6, _LV_OFF_6 & _STVRE_ON_6 ;========================================================================== CONFIG1L EQU _CONFIG0 CONFIG1H EQU _CONFIG1 CONFIG2L EQU _CONFIG2 CONFIG2H EQU _CONFIG3 CONFIG4 EQU _CONFIG4 ;; not used according to data sheet. CONFIG3H EQU _CONFIG5 CONFIG4L EQU _CONFIG6 CONFIG7 EQU _CONFIG7 ;; not used according to data sheet. DEVID1 EQU 0x3ffffe DEVID2 EQU 0x3fffff gpsim-0.30.0/examples/16bit/Makefile.in0000664000076400007640000003165013117441634014465 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = examples/16bit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ bt18.asm \ calltest18.asm \ indtest18.asm \ it18.asm \ mul.asm \ p18.asm \ p18c242_test.asm \ sine18.asm \ tbl.asm \ tmr0_18.asm \ usart_18.asm \ p18c242.inc MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/16bit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/16bit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/examples/16bit/Makefile.am0000664000076400007640000000052713041763642014455 00000000000000EXTRA_DIST = \ bt18.asm \ calltest18.asm \ indtest18.asm \ it18.asm \ mul.asm \ p18.asm \ p18c242_test.asm \ sine18.asm \ tbl.asm \ tmr0_18.asm \ usart_18.asm \ p18c242.inc MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ gpsim-0.30.0/examples/16bit/p18.asm0000664000076400007640000000333713041763642013535 00000000000000 ;; 18.asm ;; ;; Test the 18c instruction set processor 18c452 cblock 0x0c temp,temp1,temp2 endc org 0 start addlw 4 addlw 0xff addlw 0x100 ; error addwf 0x11,1 addwf 0x11,1,0 addwf 0x11,1,1 addwf 0x11,1,b addwfc 0x11,w,0 addwfc 0x11,f,1 addwfc temp,w,b andlw 4 andlw 0xff andlw 0x100 ; error andwf 0x11,1,0 andwf 0x11,1,1 andwf 0x11,1,b bc $+5 bcf temp1,5,0 bcf temp1,7 bn $-5 bnc $+0x7f bnn $-0x7f bnov start bnz start bra start bra 0x3ff bsf temp2,1,b btfsc temp1,4,b btfss temp1,4 btg temp,0,b bov start bz $ call start call $+0x10001,s clrf temp clrf temp1,b clrf temp1,0 clrwdt comf temp,w,0 cpfseq temp1,0 cpfsgt temp,1 cpfslt temp,1 daw decf temp,w,0 decf temp1,f,1 decfsz temp,w,0 decfsz temp1,f,1 dcfsnz temp,w,0 dcfsnz temp1,f,1 goto 0xfffff incf temp,w,0 incf temp1,f,b incfsz temp,w,0 incfsz temp1,f,b infsnz temp,w,0 infsnz temp1,f,b iorlw 4 iorlw 0xff iorwf 0x11,1,0 iorwf 0x11,1,1 lfsr 3,0xfab movf temp,w,0 movf temp1,f,b movff temp1,temp2 movlb 0x55 movlw 0xab movwf temp movwf temp,b mullw 0x42 mulwf temp,b negf temp,0 nop pop push rcall -0x3ff rcall 0x7ff reset retfie 0 retlw 0xde return 1 rlcf temp,w,0 rlcf temp1,f,b rlncf temp,w,0 rlncf temp1,f,b rrcf temp,w,0 rrcf temp1,f,b rrncf temp,w,0 rrncf temp1,f,b setf temp1,b sleep subfwb temp,w,0 subfwb temp1,f,b sublw 0x33 subwf temp,w,0 subwf temp1,f,b subwfb temp,w,0 subwfb temp1,f,b swapf temp,w,0 swapf temp1,f,b sublw 0x33 | 0x0f sublw 5 * 8 tblrd * tblrd *+ tblrd *- tblrd +* tblwt * tblwt *+ tblwt *- tblwt +* tstfsz temp1,b xorlw 0xff xorwf temp,w,0 xorwf temp1,f,b end gpsim-0.30.0/examples/16bit/p18c242_test.asm0000664000076400007640000000037413041763642015165 00000000000000 ;; p18c242.asm list p=18c242 radix dec nolist include "p18c242.inc" list __config CONFIG2H,0 ;Disable WDT __config DEVID1,0xab __config DEVID2,0xcd cblock 0x02 temp,temp1,temp2 endc org 0 start bra start end gpsim-0.30.0/examples/16bit/tmr0_18.asm0000664000076400007640000000746013041763642014320 00000000000000 list p=18f452,t=ON,c=132,n=80 radix dec __CONFIG _CONFIG2H, _WDT_OFF_2H ; & _WDTPS_128_3 ; __config CONFIG2H,0 ;Disable WDT ; __config DEVID1,0xab ; __config DEVID2,0xcd ;; The purpose of this program is to test gpsim's ability to simulate ;; TMR0 in the 18cxxx core. include "p18f452.inc" cblock 0 temp1 temp2 temp3 temp4 temp5 adr_cnt data_cnt w_temp status_temp TenthsSeconds_HI TenthsSeconds_LO MilliSeconds MicroSeconds_HI MicroSeconds_LO endc org 0 goto start org 8 ;; Interrupt ;; ; movwf w_temp ; swapf status,w,0 ; movwf status_temp check_t0: btfsc INTCON,T0IF,0 btfss INTCON,T0IE,0 bra exit_int ;; tmr0 has rolled over bcf INTCON,T0IF,0 ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: movlw 0x55 ;test ; swapf status_temp,w,0 ; movwf STATUS,0 ; swapf w_temp,f ; swapf w_temp,w retfie 1 ;Restore from `fast stack' start ;; ;; tmr0 test ;; ;; The following block of code tests tmr0 together with interrupts. ;; Each prescale value (0-7) is loaded into the timer. The software ;; waits until the interrupt due to tmr0 rollover occurs before ;; loading the new prescale value. bsf INTCON,T0IE,0 ;Enable TMR0 overflow interrupts bsf INTCON,GIE,0 ;Global interrupts bra tmr0_done clrf temp1 ;Software flag used to monitor when the ;interrupt has been serviced. movlw (1< node new_test_node ;; gpsim> attach new_test_node porta4 portb0 bcf TRISB,0,0 ;portb bit 0 is an output ;; assign the prescaler to the wdt so that tmr0 counts every edge ;; select the clock source to be tocki ;; and capture low to high transitions (tose = 0) movlw (1< 1/2 btfsc prodl,7,0 incf prodh,w,0 btfss f_hi,ODD_QUADRANT addwf x1,W btfsc f_hi,ODD_QUADRANT subwf tablat,w,0 ;x2 is in the tablat register btfsc f_hi,NEG_QUADRANT sublw 0 return sine_table data 0,12 ;127*sin(0 * 90/16) ;127*sin(1 * 90/16) data 25,37 ;127*sin(2 * 90/16) ;127*sin(3 * 90/16) data 49,60 ;127*sin(4 * 90/16) ;127*sin(5 * 90/16) data 71,81 ;127*sin(6 * 90/16) ;127*sin(7 * 90/16) data 90,98 ;127*sin(8 * 90/16) ;127*sin(9 * 90/16) data 106,112 ;127*sin(10 * 90/16) ;127*sin(11 * 90/16) data 117,122 ;127*sin(12 * 90/16) ;127*sin(13 * 90/16) data 125,126 ;127*sin(14 * 90/16) ;127*sin(15 * 90/16) data 127,0 ;127*sin(16 * 90/16) END gpsim-0.30.0/examples/Makefile.in0000664000076400007640000004643313117441635013546 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = modules projects 12bit 14bit 16bit EXTRA_DIST = \ scripts/client2.cc \ scripts/client3.cc \ scripts/client_interface.h \ scripts/testgensquares.py \ scripts/testsocket.py \ scripts/testgensquares_init.py \ scripts/client.cc \ scripts/README \ scripts/client_interface.cc \ scripts/gensquares.asm \ scripts/makefile MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/examples/Makefile.am0000664000076400007640000000076113041763643013531 00000000000000SUBDIRS = modules projects 12bit 14bit 16bit EXTRA_DIST = \ scripts/client2.cc \ scripts/client3.cc \ scripts/client_interface.h \ scripts/testgensquares.py \ scripts/testsocket.py \ scripts/testgensquares_init.py \ scripts/client.cc \ scripts/README \ scripts/client_interface.cc \ scripts/gensquares.asm \ scripts/makefile MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ gpsim-0.30.0/examples/scripts/0000775000076400007640000000000013117465765013250 500000000000000gpsim-0.30.0/examples/scripts/client2.cc0000664000076400007640000000462113041763642015031 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Scripting client2.cc - a program to demonstrate gpsim scripting. */ #include #include #include "client_interface.h" #define PORT 0x1234 //======================================================================== // // // int main(int argc, char **argv) { bool bPassed = true; // regression test results - assume we pass ClientSocketInterface *sock = new ClientSocketInterface(argc>2 ? argv[2] : 0, PORT); /* Set up. Since we are controlling the simulator entirely from a script, there really is not much need for the command line output it provides. So we'll turn it off by setting the simulator attribute 'sim.verbosity' to zero. */ sock->WriteSymbolUInt32("sim.verbosity",0); /* The simulator's command line parser is still available for us to use. So we'll use it to load the source code and to set a break point. */ //sock->SendCmd("load s gensquares.cod\n"); unsigned int h_reg1 = sock->CreateLinkUInt32("reg1"); /* start running */ //sock->SendCmd("run\n"); if(!h_reg1) { printf("unable to create handles\n"); delete sock; exit(1); } unsigned int reg1=0; for(unsigned int i=0; i<256; i++) { printf("query link\n"); sock->WriteToLinkUInt32(h_reg1, i); printf("query link got %d\n",i); if(! sock->QueryLinkUInt32(h_reg1,reg1) ) printf("failed to decode reg1\n"); if(i != reg1) bPassed = false; } /* release the handle */ sock->RemoveLink(h_reg1); sock->WriteSymbolUInt32("sim.verbosity",1); delete sock; if(bPassed) printf("The simulation passed!\n"); else printf("The simulation failed\n"); return 0; } gpsim-0.30.0/examples/scripts/client3.cc0000664000076400007640000001320613063451146015026 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Scripting client2.cc - a program to demonstrate gpsim scripting. */ #include #include #include #include #include "client_interface.h" #define PORT 0x1234 pthread_t thThread1; pthread_attr_t thAttribute1; pthread_t thThread2; pthread_attr_t thAttribute2; pthread_t thThread3; pthread_attr_t thAttribute3; int something=1; ClientSocketInterface *sock1=0; ClientSocketInterface *sock2=0; ClientSocketInterface *sock3=0; void *thread1(void *ignored) { printf( "thread1 running\n"); sleep(1); bool bPassed = true; // regression test results - assume we pass ClientSocketInterface *sock=sock1; if(!sock) exit(1); /* Set up. Since we are controlling the simulator entirely from a script, there really is not much need for the command line output it provides. So we'll turn it off by setting the simulator attribute 'sim.verbosity' to zero. */ sock->WriteSymbolUInt32("sim.verbosity",0); /* The simulator's command line parser is still available for us to use. So we'll use it to load the source code and to set a break point. */ //sock->SendCmd("load s gensquares.cod\n"); unsigned int h_reg1 = sock->CreateLinkUInt32("reg1"); if(!h_reg1) { printf("unable to create handles\n"); delete sock; exit(1); } unsigned int reg1=0; for(unsigned int i=0; i<128; i++) { printf("t1 query link\n"); sock->WriteToLinkUInt32(h_reg1, i); printf("t1 query link got %u\n", i); if(! sock->QueryLinkUInt32(h_reg1,reg1) ) printf("failed to decode reg1\n"); if(i != reg1) { printf("t1 failed expected %u, but got %u\n", i, reg1); bPassed = false; break; } } /* release the handle */ sock->RemoveLink(h_reg1); sock->WriteSymbolUInt32("sim.verbosity",1); delete sock; if(bPassed) printf("The simulation passed!\n"); else printf("The simulation failed\n"); printf("thread 1 is complete\n"); return 0; } void *thread2(void *ignored) { printf( "thread2 running\n"); bool bPassed = true; // regression test results - assume we pass ClientSocketInterface *sock=sock2; if(!sock) exit(1); sleep(1); /* Set up. Since we are controlling the simulator entirely from a script, there really is not much need for the command line output it provides. So we'll turn it off by setting the simulator attribute 'sim.verbosity' to zero. */ sock->WriteSymbolUInt32("sim.verbosity",0); /* The simulator's command line parser is still available for us to use. So we'll use it to load the source code and to set a break point. */ //sock->SendCmd("load s gensquares.cod\n"); unsigned int h_reg2 = sock->CreateLinkUInt32("reg2"); /* start running */ //sock->SendCmd("run\n"); if(!h_reg2) { printf("unable to create handles\n"); delete sock; exit(1); } unsigned int reg2=0; for(unsigned int i=0; i<128; i++) { printf("t2 query link\n"); sock->WriteToLinkUInt32(h_reg2, i); printf("t2 query link got %u\n", i); if(! sock->QueryLinkUInt32(h_reg2,reg2) ) printf("failed to decode reg2\n"); if(i != reg2) { printf("t2 failed expected %u, but got %u\n", i, reg2); bPassed = false; break; } } /* release the handle */ sock->RemoveLink(h_reg2); sock->WriteSymbolUInt32("sim.verbosity",1); delete sock; if(bPassed) printf("The simulation passed!\n"); else printf("The simulation failed\n"); printf("thread 2 is complete\n"); return 0; } void *thread3(void *ignored) { printf( "thread3 running\n"); ClientSocketInterface *sock=sock3; if (!sock) exit(1); int i = 0; while (i++<4) sleep(1); if (sock->CreateCallbackLink(0x1000)) { printf("created callback link\n"); } while (1) { printf("thread 3 received%s\n", sock->Receive()); } printf("thread 3 is complete\n"); } void start_threads(void) { printf( "starting threads....\n"); pthread_attr_init(&thAttribute1); pthread_attr_setdetachstate(&thAttribute1, PTHREAD_CREATE_JOINABLE); pthread_create(&thThread1, &thAttribute1, thread1, (void *)&something); pthread_attr_init(&thAttribute2); pthread_attr_setdetachstate(&thAttribute2, PTHREAD_CREATE_JOINABLE); pthread_create(&thThread2, &thAttribute2, thread2, (void *)&something); pthread_attr_init(&thAttribute3); pthread_attr_setdetachstate(&thAttribute3, PTHREAD_CREATE_JOINABLE); pthread_create(&thThread3, &thAttribute3, thread3, (void *)&something); printf( "started threads\n"); } //======================================================================== // // // int main(int argc, char **argv) { sock1 = new ClientSocketInterface(argc>2 ? argv[2] : 0, PORT); sock2 = new ClientSocketInterface(argc>2 ? argv[2] : 0, PORT); sock3 = new ClientSocketInterface(argc>2 ? argv[2] : 0, PORT); start_threads(); while(1) { printf("main\n"); sleep(1); } return 0; } gpsim-0.30.0/examples/scripts/client_interface.h0000664000076400007640000000312213041763642016624 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(CLIENT_INTERFACE_H) #define CLIENT_INTERFACE_H #include class Packet; class ClientSocketInterface { public: ClientSocketInterface(const char *host, int port); bool SendCmd(const char *); /// Link interface unsigned int CreateCallbackLink(guint64); unsigned int CreateLinkUInt32(const char *sym_name); bool QueryLinkUInt32(unsigned int handle, unsigned int &i); void WriteToLinkUInt32(unsigned int handle, unsigned int val); void RemoveLink(unsigned int handle); /// Symbol interface bool QuerySymbolUInt32(const char *sym_name, unsigned int &i); bool WriteSymbolUInt32(const char *sym_name, unsigned int v); const char *Receive(); private: void Send(); int Send(const char *msg, int msgLength, char *response, int respLength); Packet *p; int sd; // Socket descriptor. }; #endif // CLIENT_INTERFACE_H gpsim-0.30.0/examples/scripts/testgensquares.py0000664000076400007640000000272713041763642016616 00000000000000# Sample client program to communicate with gpsim import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("", 0x1234)) s.send("help\n") print s.recv(20) # helper functions def ParseInt(buf): if buf[0:3] == "$03" : return eval("0x"+buf[3:11]) return 0 # Symbol Command s.send("$"+"97"+"0205start") r = s.recv(20) start_adr = ParseInt(r) print "Start address:" + str(start_adr) s.send("reset\n") print s.recv(20) s.send("step\n") print s.recv(20) s.send("step\n") print s.recv(20) # define an example input and send it to the simulator: x=4 count="0300000020" s.send("$"+"99"+ count + "03%08x"%x) # another example of assigning a memory location r = s.recv(20) s.send("$"+"99"+ "0300000040" + "03000000ff") r = s.recv(20) # Move the program counter (doesn't work right now) PCL="0300000002" # Assign RAM command #s.send("$"+"99"+ PCL +"03" + "%08x"%start_adr) #st = "%08x"%start_adr #s.send("$"+"99"+ PCL + "030000002") #r = s.recv(20) #print r # start the simulation: s.send("run\n") print s.recv(20) # Examine the results xsq_lo_adr = "0300000022" s.send("$"+"91"+xsq_lo_adr) r = s.recv(20) xsq_lo = ParseInt(r) print "received:" + r + " decoded as " + str(xsq_lo) xsq_hi_adr = "0300000023" s.send("$"+"91"+xsq_hi_adr) r = s.recv(20) xsq_hi = ParseInt(r) print "received:" + r + " decoded as " + str(xsq_hi) xsq = xsq_hi*256 + xsq_lo print " Sent " + str(x) print " Received " + str(xsq) if x*x == xsq : print "PASSED" s.close() gpsim-0.30.0/examples/scripts/testsocket.py0000664000076400007640000000162613041763642015726 00000000000000# Sample client program to communicate with gpsim import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("", 0x1234)) s.send("help\n") print s.recv(20) # helper functions def ParseInt(buf): if buf[0:3] == "$03" : return eval("0x"+buf[3:11]) return 0 # Object container s.send("$0105") print s.recv(20) # String object s.send("$0205HELLO") print s.recv(20) # Integer object s.send("$03DEADBEEF") print s.recv(20) # Command object s.send("$"+"80") print s.recv(20) # Symbol Command s.send("$"+"97"+"0208failures") r = s.recv(20) print "received:" + r + " decoded as " + str(ParseInt(r)) # Examine RAM command s.send("$"+"91"+"0300000020") r = s.recv(20) print "received:" + r + " decoded as " + str(ParseInt(r)) # Assign RAM command s.send("$"+"99"+ "0300000020"+"03000000FF") r = s.recv(20) print r # Integer object s.send("$0300000001") print s.recv(20) s.close() gpsim-0.30.0/examples/scripts/testgensquares_init.py0000664000076400007640000000044713041763642017636 00000000000000# Sample client program to communicate with gpsim import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("", 0x1234)) s.send("load s gensquares.cod\n") print s.recv(20) #s.send("break e start\n") #print s.recv(20) s.send("break e done\n") print s.recv(20) s.close() gpsim-0.30.0/examples/scripts/client.cc0000664000076400007640000001171613041763642014752 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Scripting client.cc - a program to demonstrate gpsim scripting. The purpose of this program is to demonstrate how one might write a script to perform regression testing on an algorithm. In this example, the algorithm is one that squares an 8-bit number. It is implemented in the PIC source code gensquares.asm. The scripting mechanism is implemented on top of a socket interface. When gpsim is started, it will act as a server and began listening to clients. This client will initiate the communication link. It probably goes with out saying, but gpsim needs to be running before this client script will even work! Once this client establishs a communication link, it will proceed to set up the simulation environment and perform a regression test. Technical details: The scripting interface is implemented with a gpsim specific protocol. This protocol is somewhat analogous to gdb's protocol. gpsim's protocol operates in two modes. In one mode, character strings are sent across the socket interface and sent through the command line parser. Thus, it's possible to issue any gpsim command through a socket that can be typed at the command line. As of this writing, this interface is only uni-directional though. In other words, the client can only issue commands, but can't see the response. However, the other mode of the protocol allows bi-directional communication. This other mode ties directly into gpsim symbols and attributes. In the attribute mode of the protocol, there are two ways to interface to the symbols. The first is by symbol name and the second is by a 'handle'. For either one of these, it's possible to read and write symbols. Handles are more efficient since they only have to be processed only one. Accessing by name on the other hand, requires string processing and symbol table accesses. */ #include #include #include "client_interface.h" #define PORT 0x1234 //======================================================================== // // // int main(int argc, char **argv) { bool bPassed = true; // regression test results - assume we pass ClientSocketInterface *sock = new ClientSocketInterface(argc>2 ? argv[2] : 0, PORT); /* Set up. Since we are controlling the simulator entirely from a script, there really is not much need for the command line output it provides. So we'll turn it off by setting the simulator attribute 'sim.verbosity' to zero. */ sock->WriteSymbolUInt32("sim.verbosity",0); /* The simulator's command line parser is still available for us to use. So we'll use it to load the source code and to set a break point. */ sock->SendCmd("load s gensquares.cod\n"); sock->SendCmd("break e start\n"); /* There's a break point set at the label 'start'. Run to it. */ sock->SendCmd("run\n"); /* Now, we'll establish links to some of the internal symbols we're interested in. These links are called 'handles'. */ unsigned int h_count = sock->CreateLinkUInt32("count"); unsigned int h_x_lo = sock->CreateLinkUInt32("x_lo"); unsigned int h_x_hi = sock->CreateLinkUInt32("x_hi"); if(!h_count || !h_x_lo || !h_x_hi) { printf("unable to create handles\n"); delete sock; exit(1); } /* */ unsigned int count; unsigned int x_lo=0; unsigned int x_hi=0; for(count=0; count < 128; count++) { sock->WriteToLinkUInt32(h_count, count); sock->SendCmd("run\n"); if(! sock->QueryLinkUInt32(h_x_lo,x_lo) ) printf("failed to decode x_lo"); if(! sock->QueryLinkUInt32(h_x_hi,x_hi) ) printf("failed to decode x_hi"); /* Check the results. */ if((count*count) != ((x_hi<<8) + x_lo)) { unsigned int a = count *count; unsigned int b = (x_hi<<8) + x_lo; printf("%x %x ", a, b); bPassed = false; printf("failed sent: 0x%02X received 0x%02X%02X\n",count, x_hi,x_lo); } } /* release the handles created above. */ sock->RemoveLink(h_count); sock->RemoveLink(h_x_lo); sock->RemoveLink(h_x_hi); sock->WriteSymbolUInt32("sim.verbosity",1); delete sock; if(bPassed) printf("The simulation passed!\n"); else printf("The simulation failed\n"); return 0; } gpsim-0.30.0/examples/scripts/README0000664000076400007640000000157413041763642014046 00000000000000Scripting DEC04 This directory illustrates some basic gpsim scripting. NOTE: As of this writing, the Python scripts are not working! What's here: ----------- The script 'client.cc' is a C++ program that's designed to interface with gpsim through a socket interface. This script will load the PIC program gensquares.cod and instrument it with some regression testing tools. The comments in client.cc discuss what exactly is tested in the example regression test. How to use it ------------- The makefile will do two things: it'll assemble the PIC program gensquares.asm and it will compile the C++ script client.cc. Typing 'make' at the command line should execute both of these rules. The script is designed to communicate with gpsim. So gpsim needs to be running first. Once that's done, the script can be run: $ make $ ./client And it should respond with: The simulation passed! gpsim-0.30.0/examples/scripts/client_interface.cc0000664000076400007640000001330413041763642016765 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "client_interface.h" #include #include #include #include #include #include #include #include #ifdef putc #undef putc #endif #include int ClientSocketInterface::Send(const char *msg, int msgLength, char *response, int respLength) { if(!sd || !msg || !msgLength || !response || !respLength) return 0; if (send(sd, msg, msgLength, 0) == -1) { perror("send"); exit(1); } int bytes = recv(sd, response, respLength, 0); if (bytes == -1) { perror("recv"); exit(1); } return bytes; } //======================================================================== bool ClientSocketInterface::SendCmd(const char *cmd) { if(cmd) { char response[256]; int len = Send(cmd, strlen(cmd), response, sizeof(response)); if(len && len txBuff()); if (send(sd, p->txBuff(), p->txBytesBuffered(), 0) == -1) { perror("send"); exit(1); } int bytes= recv(sd, p->rxBuff(), p->rxSize(), 0); if (bytes == -1) { perror("recv"); exit(1); } p->rxTerminate(bytes); printf("Send sock=%d rx data:%s\n",sd,p->rxBuff()); } //======================================================================== const char *ClientSocketInterface::Receive() { printf("Receive sock=%d data:%s\n",sd,p->txBuff()); p->prepare(); /* if (send(sd, p->txBuff(), p->txBytesBuffered(), 0) == -1) { perror("send"); exit(1); } */ int bytes= recv(sd, p->rxBuff(), p->rxSize(), 0); if (bytes == -1) { perror("recv"); exit(1); } p->rxTerminate(bytes); printf("Receive sock=%d rx data:%s\n",sd,p->rxBuff()); return p->rxBuff(); } //======================================================================== // unsigned int ClientSocketInterface::CreateCallbackLink(guint64 interval) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_CREATE_CALLBACK_LINK); p->EncodeUInt64(interval); Send(); unsigned int handle=0; if(p->DecodeHeader() && p->DecodeUInt32(handle) ) return handle; return 0; } unsigned int ClientSocketInterface::CreateLinkUInt32(const char *sym_name) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_CREATE_SOCKET_LINK); p->EncodeString(sym_name); Send(); unsigned int handle=0; if(p->DecodeHeader() && p->DecodeUInt32(handle) ) return handle; return 0; } void ClientSocketInterface::RemoveLink(unsigned int handle) { if(handle) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_REMOVE_SOCKET_LINK); p->EncodeUInt32(handle); Send(); } } bool ClientSocketInterface::QueryLinkUInt32(unsigned int handle, unsigned int &i) { if(handle) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_QUERY_SOCKET_LINK); p->EncodeUInt32(handle); Send(); if(p->DecodeHeader() && p->DecodeUInt32(i)) return true; } return false; } void ClientSocketInterface::WriteToLinkUInt32(unsigned int handle, unsigned int val) { if(handle) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_WRITE_TO_SOCKET_LINK); p->EncodeUInt32(handle); p->EncodeUInt32(val); Send(); } } bool ClientSocketInterface::QuerySymbolUInt32(const char *sym_name, unsigned int &i) { if(sym_name) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_QUERY_SYMBOL); p->EncodeString(sym_name); p->txTerminate(); Send(); if(p->DecodeHeader() && p->DecodeUInt32(i)) return true; } return false; } bool ClientSocketInterface::WriteSymbolUInt32(const char *sym_name, unsigned int v) { if(sym_name) { p->prepare(); p->EncodeObjectType(GPSIM_CMD_WRITE_TO_SYMBOL); p->EncodeString(sym_name); p->EncodeUInt32(v); p->txTerminate(); Send(); } } //------------------------------------------------------------------------ ClientSocketInterface::ClientSocketInterface(const char *hostname, int port) { struct sockaddr_in sin; struct sockaddr_in pin; struct hostent *hp; sd = 0; char hname_buff[256]; const char *hname; if(!hostname) { gethostname(hname_buff, sizeof(hname_buff)); hname = hname_buff; } else hname = hostname; if ((hp = gethostbyname(hname)) == 0) { perror("gethostbyname"); exit(1); } /* fill in the socket structure with host information */ memset(&pin, 0, sizeof(pin)); pin.sin_family = AF_INET; pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; pin.sin_port = htons(port); /* grab an Internet domain socket */ if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } /* connect to PORT on HOST */ if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { perror("connect"); exit(1); } printf("connected with socket %d\n",sd); p = new Packet(8192,8192); } gpsim-0.30.0/examples/scripts/gensquares.asm0000664000076400007640000000275113041763642016043 00000000000000 ;; 16F84 test program to generate squares using the ;; 'sum of odd integers' algorithm. ;; The main purpose of this program is to illustrate scripting. list p=16f84 include "p16f84.inc" CONFIG_WORD EQU _CP_OFF & _WDT_OFF __CONFIG CONFIG_WORD ;; Ram cblock 0x20 count odd_int x_lo, x_hi reg1 reg2 endc ORG 0 ;; Simple program to square a number: ;; This loop is designed to be easily controlled by the script. ;; The script will set a break point at the 'start:' label. Each ;; time the breakpoint is encounterd, the previous call to 'square' ;; is checked and the input for the next time is initialized. start: movf count,W call square goto start ;;------------------------------------------------------------------------ ;; ;; Square a number. ;; ;; INPUT: W - the number to be squared ;; OUTPUT: x_hi:lo square: clrf x_lo clrf x_hi movwf count ; if the input is 0, the 0*0 = 0 movf count,F skpnz return movlw -1 movwf odd_int square_loop: ; Generate the next odd integer: movlw 2 addwf odd_int,f ; Add it to the square so far: movf odd_int,w addwf x_lo,f skpnc incf x_hi,f ; Are we through? decfsz count,f goto square_loop return done: GOTO $ end gpsim-0.30.0/examples/scripts/makefile0000664000076400007640000000163413041763642014663 00000000000000#makefile for socket test. GCC = g++ CFLAGS = `pkg-config --cflags glib-2.0 gtk+-2.0` LIBS = -lstdc++ `pkg-config --libs glib-2.0 gtk+-2.0` -lgpsim ASM = gpasm PICSRC = gensquares all: client client2 client3 $(PICSRC).cod client_interface.o: client_interface.cc $(GCC) -c client_interface.cc $(CFLAGS) client.o: client.cc $(GCC) -c client.cc $(CFLAGS) client: client.o client_interface.o $(GCC) -o client client.o client_interface.o $(LIBS) client2.o: client2.cc $(GCC) -c client2.cc $(CFLAGS) client2: client2.o client_interface.o $(GCC) -o client2 client2.o client_interface.o $(LIBS) client3.o: client3.cc $(GCC) -c client3.cc $(CFLAGS) client3: client3.o client_interface.o $(GCC) -o client3 client3.o client_interface.o $(LIBS) $(PICSRC).cod: $(PICSRC).asm gpasm $(PICSRC).asm clean: rm -f $(PICSRC).lst $(PICSRC).hex $(PICSRC).cod rm -f client client2 client3 *.o rm *~ gpsim-0.30.0/examples/14bit/0000775000076400007640000000000013117465766012505 500000000000000gpsim-0.30.0/examples/14bit/sine.asm0000775000076400007640000001647413041763642014072 00000000000000 list p=16C84,t=ON,c=132,n=80,st=off radix dec include "p16c84.inc" cblock 0x20 f_hi ;Low byte of frequency variable f_lo x1 x2 interp index product fstep_lo fstep_hi endc ODD_QUADRANT equ 4 ;In f_hi NEG_QUADRANT equ 5 ;In f_hi INDEX_MASK equ 0x0f ;In f_hi INTERP_MASK equ 0xf0 ;In f_lo ORG 0 ;Reset Vector GOTO Main ORG 4 ;Interrupt Vector Main BCF STATUS,RP0 ;Point to BANK 0 ;Initialize the step in frequency MOVLW 0x10 MOVWF fstep_lo ;One unit of fstep corresponds to 360/16384 degrees CLRF fstep_hi ;i.e. 0.02197 degrees. Set fstep = 455 (1c7) to step ;10 degrees for example CLRF f_hi ;Start off at 0 degrees CLRF f_lo xxx CALL sine NOP ;Now that the sine has been calculated, we could do something with it other than ;throwing it away. ;Make a frequency step. Note, the frequency step doesn't necessarily have to be ;constant. E.g. it could be changed as part of a PLL algorithm. MOVF fstep_lo,W ADDWF f_lo,F SKPNC INCF f_hi,F MOVF fstep_hi,W ADDWF f_hi,F GOTO xxx ;-------------------------------------------------------- ;sine ; ; The purpose of this routine is to take the sine of the ;16-bit frequency variable f_hi:f_lo to produce a signed ;8-bit result that is within +/- 1 count of the true sine ;value. ; Only the lower 14 bits of the frequency variable are ;actually used. The frequency variable maps into degrees ;by the following transfer function: ; degrees = (f & 0x3fff) * 360 / 0x4000 ; The sine output is approximately ;sine = int(127*sin( (f & 0x3fff) * 360 / 0x4000) ) ; where ; sin() is the true sine function ; int() is the nearest integer function ; ;The technique used to obtain the sine value is a combination ;of table look-up and first order linear interpolation. Sixteen ;equidistant frequency samples of the first quadrant of sin(x) ;are stored in sine_table. ; ; The frequency variable is broken down as follows: ; xxQQTTTT IIIIPPPP ; where ; xx - don't care ; QQ - Quadrant: 00 = quadrant 1, 01 = quadrant 2, etc. ; TTTT - Index into the sine_table. ; IIII - Interpolation between successive entries in the table ; PPPP - Phase accumulation (not needed in this function, it's ; only used to increase the dynamic range in frequency ; steps). ;Once the frequency has been broken down in to these parts, the ;sine function for the first quadrant can be calculated as follows: ; x1 = sine_table[index] ; x2 = sine_table[index+1] ; sine = x1 + ((x2-x1) * interp) / 16 ;The first term, x1, is seen to be a first order approximation to ;sine function. The second term improves on that approximation by ;interpolating between x1 and x2. The interpolation variable interp ;is 0 <= interp <= 15 and it is divided by 16. Consequently, the ;interpolation factor ranges between 0 and 15/16. ; ;The sine function in the other three quadrants can be obtained ;from calculations based on the first quadrant by using the following ;trig identities: ; first, let 0 <= f <= 90, i.e. f covers the first quadrant. ; quadrant 2: u = 90 + f, 90 < u < 180 ; sin(u-90) = sin(f) ; x1 = sine_table(16-index), x2 = sine_table(15-index) ; quadrant 3: u = 180 + f, 180 < u < 270 ; sin(u) = sin(f+180) = -sin(f) ; x1 = -sine_table(index), x2 = -sine_table(index+1) ; quadrant 4: u = 270 + f, 270 < u < 360 ; sin(u-90) = sin(f+180) = -sin(f) ; x1 = -sine_table(16-index), x2 = -sine_table(15-index) ; ;Thus, for quadrants 2 and 4, the sine table is indexed in reverse ;order and for quadrants 3 and 4 the values from the sine table ;are negated. A slight change is made on this indexing and negation ;scheme so that the operation (x2-x1) * interp / 16 only deals with ;positive numbers. This significantly simplifies the multiplication. ;The modification changes the formula for each quadrant as follows: ; quadrant 1: (no change) ; x1 = sine_table[index], x2 = sine_table[index+1] ; sine = x1 + ((x2-x1) * interp) / 16 ; quadrant 2: ; x1 = sine_table[15-index], x2 = sine_table[16-index] ; sine = x2 - ((x2-x1) * interp) / 16 ; quadrant 3: ; x1 = sine_table[index], x2 = sine_table[index+1] ; sine = -(x1 + ((x2-x1) * interp) / 16) ; quadrant 4: ; x1 = sine_table[15-index], x2 = sine_table[16-index] ; sine = -(x2 - ((x2-x1) * interp) / 16) ; ;Input ; f_hi:f_lo - 16-bit frequency variable ;Output ; W = int(127*sin( (f & 0x3fff) * 360 / 0x4000) ) ; ;Execution time: 48 Cycles (for all cases) ; sine ;Get the 4-bit index and add 1 to it. MOVF f_hi,W ANDLW INDEX_MASK ADDLW 1 BTFSC f_hi,ODD_QUADRANT SUBLW 17 ;Odd quadrants, index = 16 - index ;Actually: (index + 1) = 17 - (index + 1) ; = 16 - index MOVWF index CALL sine_table ;Get x2=sin(index+1) MOVWF x2 DECF index,W CALL sine_table ;Get x1=sin(index) MOVWF x1 SUBWF x2,W ;W=x2-x1, This is always positive. ;Initialize the product of (x2-x1)*interp/16 to 1/2. Note 8/16 == 1/2 ;(This rounds the product to the nearest integer.) CLRF product BSF product,3 ;(note, product and index could be aliased to ; save one byte of ram). ;multiply interp and x2 - x1 and divide by 16. This is actually a 4 by 8 ;bit multiplication. The division by 16 is implemented with a shift right ;one position for each of the four multiplication iterations. clrc btfsc f_lo,4 addwf product,f ;Then add (x2-x1) to the product rrf product,f ;Divide the product by two clrc btfsc f_lo,5 addwf product,f rrf product,f ;Divide the product by four clrc btfsc f_lo,6 addwf product,f rrf product,f ;Divide the product by eight clrc btfsc f_lo,7 addwf product,f rrf product,w ;Divide the product by sixteen BTFSS f_hi,ODD_QUADRANT ADDWF x1,W BTFSC f_hi,ODD_QUADRANT SUBWF x2,W BTFSC f_hi,NEG_QUADRANT SUBLW 0 RETURN sine_table ADDWF PCL,F RETLW 0 ;127*sin(0 * 90/16) RETLW 12 ;127*sin(1 * 90/16) RETLW 25 ;127*sin(2 * 90/16) RETLW 37 ;127*sin(3 * 90/16) RETLW 49 ;127*sin(4 * 90/16) RETLW 60 ;127*sin(5 * 90/16) RETLW 71 ;127*sin(6 * 90/16) RETLW 81 ;127*sin(7 * 90/16) RETLW 90 ;127*sin(8 * 90/16) RETLW 98 ;127*sin(9 * 90/16) RETLW 106 ;127*sin(10 * 90/16) RETLW 112 ;127*sin(11 * 90/16) RETLW 117 ;127*sin(12 * 90/16) RETLW 122 ;127*sin(13 * 90/16) RETLW 125 ;127*sin(14 * 90/16) RETLW 126 ;127*sin(15 * 90/16) RETLW 127 ;127*sin(16 * 90/16) END gpsim-0.30.0/examples/14bit/usart.stc0000664000076400007640000000051113041763642014261 00000000000000# # Startup commands for testing a p16c74 usart # # uncomment for debugging gpsim # set verbose 3 # Source code: load s usart_14.cod # Stimuli: # All we do is tie rx and tx together to create a loop back. # This will cause whatever is transmitted to be received... node loop_back attach loop_back portc6 portc7 break c 1000 gpsim-0.30.0/examples/14bit/usart_14.asm0000664000076400007640000000364213041763642014564 00000000000000 ;; The purpose of this program is to test gpsim's ability to simulate ;; USART in the 14bit core. list p=16c74 __config _wdt_off include "p16c74.inc" #define RX_BUF_SIZE 0x10 cblock 0x20 temp1 temp2 w_temp status_temp fsr_temp tx_ptr rx_ptr rx_buffer : RX_BUF_SIZE endc org 0 goto start org 4 ;; Interrupt ;; movwf w_temp swapf status,w movwf status_temp bcf status,rp0 btfsc intcon,peie btfss pir1,rcif goto int_done ;;; movf fsr,w movwf fsr_temp incf rx_ptr,w andlw 0x0f movwf rx_ptr addlw rx_buffer movwf fsr movf rcreg,w movwf indf movf fsr_temp,w movwf fsr int_done: swapf status_temp,w movwf status swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; start ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf status bsf status,rp0 movlw (1<&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = examples/14bit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ analog_stim.stc analog_stim2.stc ap.stc async_pulse.stc async_stim.stc async_stim2.stc \ dtmf.stc iopin_stim.stc ioport_stim.stc module_test.stc \ p16c64_ccp.stc p16c64_pwm.stc \ p16c64_test.stc p16c65_pwm.stc p16c74_pwm.stc p16c74_test.stc p16f877_test2.stc \ portc_stim.stc usart.stc \ sync_stim.stc t.stc time_test.stc \ bcd.asm eetest.asm iopin_stim.asm it.asm loop_test.asm \ mod_test.asm \ p16c64_ccp.asm p16c64_pwm.asm p16c64_test.asm p16c64_tmr1.asm \ p16c65_pwm.asm p16c71_test.asm p16c74_test.asm pcl_test.asm \ p16f877_test.asm p16f877_test2.asm \ pulse_measure.asm sine.asm stim_test.asm twist.asm vertical_adder.asm wdt_test.asm \ usart_14.asm MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/14bit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/14bit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/examples/14bit/Makefile.am0000664000076400007640000000151413041763642014450 00000000000000 EXTRA_DIST = \ analog_stim.stc analog_stim2.stc ap.stc async_pulse.stc async_stim.stc async_stim2.stc \ dtmf.stc iopin_stim.stc ioport_stim.stc module_test.stc \ p16c64_ccp.stc p16c64_pwm.stc \ p16c64_test.stc p16c65_pwm.stc p16c74_pwm.stc p16c74_test.stc p16f877_test2.stc \ portc_stim.stc usart.stc \ sync_stim.stc t.stc time_test.stc \ bcd.asm eetest.asm iopin_stim.asm it.asm loop_test.asm \ mod_test.asm \ p16c64_ccp.asm p16c64_pwm.asm p16c64_test.asm p16c64_tmr1.asm \ p16c65_pwm.asm p16c71_test.asm p16c74_test.asm pcl_test.asm \ p16f877_test.asm p16f877_test2.asm \ pulse_measure.asm sine.asm stim_test.asm twist.asm vertical_adder.asm wdt_test.asm \ usart_14.asm MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ gpsim-0.30.0/examples/14bit/bcd.asm0000664000076400007640000000336513041763642013654 00000000000000 list p=16c84 __config _wdt_off include "p16c84.inc" cblock 0x0c hundreds,tens_and_ones bin,bint endc org 0 goto start org 4 start: clrf bint l1: call binary_to_bcd incf bint,f movf bint,w movwf bin goto l1 ;******************************************************** ;binary_to_bcd - 8-bits ; ;Input ; bin - 8-bit binary number ;Outputs ; hundreds - the hundreds digit of the BCD conversion ; tens_and_ones - the tens and ones digits of the BCD conversion binary_to_bcd: CLRF hundreds SWAPF bin,W ;Add the upper and lower nibbles ADDWF bin,W ;to get the one's digit ANDLW 0x0f SKPNDC ;Go through a binary to bcd ADDLW 0x16 ;conversion for just the one's SKPNDC ;digit ADDLW 0x06 ADDLW 0x06 SKPDC ADDLW -0x06 BTFSC bin,4 ;Bit 4 is a special case ADDLW 0x16 - 1 + 0x6 SKPDC ADDLW -0x06 ;Now adjust the ten's digit BTFSC bin,5 ;2^5 = 32, so add 3 to the ten's ADDLW 0x30 ;digit if bit 5 is set BTFSC bin,6 ;2^6 = 64, so add 6 ADDLW 0x60 ;if bit 6 is set BTFSC bin,7 ;2^7 = 128, so add 2 (the ten's ADDLW 0x20 ;digit) if bit 7 is set ADDLW 0x60 ;Convert the ten's digit to BCD RLF hundreds,F ;If there's a carry, then the input BTFSS hundreds,0 ;was greater than 99. ADDLW -0x60 MOVWF tens_and_ones BTFSC bin,7 ;If msb is set then the hundred's INCF hundreds,F ;digit is a '2' return end gpsim-0.30.0/examples/14bit/analog_stim2.stc0000664000076400007640000000462313041763642015512 00000000000000# gpsim # # This .stc illustrates how asynchronous analog data # is specified # # the '#' marks the beginning of a comment # # Define an asynchronus stimulus # # This stimulation file illustrates how the stimulus command # may span several lines of input. The only requirement # is that 'end' must be the last statement (of the stimulus) echo Sample asynchronous stimulus file # Create the processor that's to be simulated #processor p16c71 fred # Load the .hex file load s p16c71_test.cod stimulus asynchronous_stimulus # or we could've used asy # Specify the initial state of the stimulus. Note that this # is the value the stimulus is BEFORE start_cycle. initial_state 5.0 # all times are with respect to the cpu's cycle counter start_cycle 100 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 5000 analog # gpsim assumes digital data by default # Now specify the data points. Each point needs two values: # the time at which it changes and the value to which it # changes. (NOTE: starting with version 0.0.10 gpsim requires # both a time value (in cpu cycles) and a 'voltage' value. # Earlier versions assumed only digital data and hence the # 'voltage' values were not supplied. OLD STIMULUS FILES # WITH ASYNCHRONOUS STIMULI WILL NOT WORK WITH THE NEW # VERSIONS OF gpsim! ) # t v #--- ---------- { 3 4.0 300 1.2 400 3.14159265 600 1.61803399 1000 0.5772156649 3000 2.71828183 } # specify the ioport that this stimulus drives # starting with 0.0.5 # you'll want to specify the port connection # with the attach command - but, this still works. # port porta 0 # Give the stimulus a name: name asy_analog # Finally, tell the command line interface that we're done # with the stimulus end # Now let's create a voltage reference using an asynchronous # stimulus: stimulus asynchronous_stimulus initial_state 4.096 start_cycle 1 # A '0' length period means the asynchronous stimulus is not # periodic. period 0 analog # t v #--- ------- { 1 4.096 } name vref end # Create a stimulus node: node test_node node vref_node # Now attach the stimulus to an I/O port # Note, the I/O ports are given the name # portxn where x = a,b,c, etc # and n is the bit within the I/O port attach test_node asy_analog porta0 attach vref_node vref porta3 gpsim-0.30.0/examples/14bit/p16f877_test.asm0000664000076400007640000001543013041763642015201 00000000000000 list p=16f877 __config _wdt_off ;; The purpose of this program is to test gpsim's ability to simulate a pic 16f877. ;; (this was derived from the similar program for testing the c64). include "p16f877.inc" cblock 0x20 x,y t1,t2,t3 pma_string ; starting here's where a string will be copied from flash endc ;; Take advantage of the upper 16 bytes all banks being aliased cblock 0x70 adr_cnt data_cnt w_temp status_temp endc DATA14 macro _a, _b data (_a<<7) | (_b) endm org 0 goto main org 4 ;; Interrupt ;; movwf w_temp swapf status,w movwf status_temp btfss intcon,peie goto exit_int bcf status,rp1 bcf status,rp0 btfss (pir2 & 0x7f),eeif goto exit_int ;;; eeprom has interrupted bcf (pir2 & 0x7f),eeif exit_int: swapf status_temp,w movwf status swapf w_temp,f swapf w_temp,w retfie main: ;; clear ram movlw 0 call preset_ram movlw 0x55 call preset_ram movlw 0 call preset_ram ;; disable (primarily) global and peripheral interrupts clrf intcon call obliterate_data_eeprom call bank_access_test call read_program_flash ;; call tmr1_test ;; call tmr2_test ;; call tmr1_test2 ;; call tmr1_test3 ;; call pwm_test goto $ ;; ========================================================= ;; read_program_flash ;; ;; Copy a string from program memory to data memory read_program_flash ;;; ;;; clrf status ; Bank 0 movlw pma_string ; Pointer to where we'll copy the string movwf fsr movlw pgm_table_end - pgm_table ; Length of the string movwf adr_cnt ; (actually 1/2 string length) bsf status,rp1 ;Point to bank 2 bcf status,rp0 ; movlw LOW(pgm_table) ; Start of the string movwf eeadr ; in program memory movlw HIGH(pgm_table) movwf eeadrh pgm_flash_read_loop1: bsf status,rp0 ; bank 3 bsf eecon1,eepgd ; program memory (instead of data flash) bsf eecon1,rd ; start the read. bcf status,rp0 ; two cycle delay to read memory nop rlf eedata,w ; Copy the 14bit value that was read rlf eedath,w ; from program memory. It's broken into movwf indf ; two 7-bit values that are copied to incf fsr,f ; data memory movf eedata,w andlw 0x7f movwf indf incf fsr,f incf eeadrh,f ; Next program memory location incfsz eeadr,f decf eeadrh,f decfsz adr_cnt,f goto pgm_flash_read_loop1 return pgm_table DATA14 't','e' DATA14 's','t' pgm_table_end ;; ;; TMR1 test ;; tmr1_test: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale clrf t1con ; bcf pir1,tmr1if ; Clear the interrupt/roll over flag ;; Zero the TMR1 clrf tmr1l clrf tmr1h ;; Test rollover ;; the following block of code will test tmr1's rollover for ;; each of the 4 prescale values. clrf x ;; Start the timer bsf t1con,tmr1on tmr1_test1: ;; Loop until the timer rolls over: btfss pir1,tmr1if goto $-1 bcf pir1,tmr1if incf x,f btfss x,2 goto tmr1_test1 clrf x movf t1con,w addlw (1< fsr =0x110 cb2: movwf indf incf fsr,f btfss fsr,7 ;loop until fsr == 0x80 goto cb2 bsf fsr,4 ;fsr == 0x90 (but irp is still set) cb3: movwf indf incfsz fsr,f goto cb3 clrf status ;clear irp,rp0,rp1 return ;; ========================================================= ;; bank_access_test: ;; ;; use the indirect register to increment register 0x70. ;; This register is aliased in all four banks. ;; Then use direct addressing to verify that the increment ;; occurred. Note that bank switching is necessary to access ;; 0x70 directly in the other banks (that is to access 0xf0, ;; 0x170 and 0x1f0 directly, you need to switch to bank 1,2 ;; or 3 respectively). bank_access_test: bcf status,rp0 movlw 0x70 movwf fsr clrf 0x70 incf indf,f btfss 0x70,0 goto $-1 bsf status,rp0 ;bank 1 incf indf,f btfsc 0x70,0 goto $-1 bsf status,rp1 ;bank 3 incf indf,f btfss 0x70,0 goto $-1 bcf status,rp0 ;bank 2 incf indf,f btfsc 0x70,0 goto $-1 bcf status,rp1 ;bank 0 return obliterate_data_eeprom clrf adr_cnt clrf data_cnt incf data_cnt,f bsf intcon,eeie l1: bsf status,rp1 ;Point to bank 2 bcf status,rp0 ; movf adr_cnt,w movwf eeadr movf data_cnt,W movwf eedata bsf status,rp0 bcf intcon,gie ;Disable interrupts while enabling write bcf (eecon1 & 0x7f),eepgd ;Point to data and not program mem. bsf (eecon1 & 0x7f),wren ;Enable eeprom writes movlw 0x55 ;Magic sequence to enable eeprom write movwf (eecon2 & 0x7f) movlw 0xaa movwf (eecon2 & 0x7f) bsf (eecon1 & 0x7f),wr ;Begin eeprom write bsf intcon,gie ;Re-enable interrupts btfsc (eecon1 & 0x7f),wr ;Wait for the write to complete goto $-1 ;; bcf status,rp0 incfsz adr_cnt,f goto l1 incfsz data_cnt,F goto l1 return org 0x2100 de "Linux is cool!",0 de 0xaa,0x55,0xf0,0x0f de 'g','p','s','i','m' de "p16f877_test.asm - a program to test " de "eveything an 'f877 can possibly do." endgpsim-0.30.0/examples/14bit/twist.asm0000664000076400007640000000562313041763642014275 00000000000000 list p=16c84 __config _wdt_off nolist include "p16c84.inc" list cblock 0x0c x,y,A,B,num endc org 0 goto start org 4 start movlw 1 movwf A movlw 0x0f movwf B movlw 0x0a movwf x movlw 0x14 movwf y t1: call twist incf x,f incf y,f goto t1 ;;; -------------------------------------------------- ;;; twist ;;; ;;; The purpose of this routine is to evaluate: ;;; ;;; A*x + B*y ;;; ------------ ;;; A + B ;;; ;;; Such that A+B = 2^N ;;; ;;; This formula is useful for several applications. For example, ;;; DTMF generartors sometimes need to weight the individual sine ;;; waves differently. The term used to describe the difference in ;;; amplitudes is 'twist'. It's the ratio of the amplitudes in dB. ;;; Another application of this formulation is for low-pass filtering. ;;; If 'x' is the current filtered value, and 'y' is the latest ;;; sample, then this equation will be a recursive low-pass filter. ;;; z-transforms may be used to calculate the frequency response, ;;; but that's beyond the scope of this simple description. An intui- ;;; tive way to look at it is as weighted averages. If A is made ;;; large relative to B, then more emphasis is placed on the average. ;;; If B is large then the latest samples are given more weight. ;;; ;;; Algorithm: ;;; This algorithm exploits the relationship: A + B = 2^N. ;;; For example, consider N=4. Then the (A,B) pairs are: ;;; ;;; (1,15), (2,14), (3,13), (4,12), (5,11), (6,10), (7,9), (8,8) ;;; i.e. B = 2^N - A , and , A = 2^N - B ;;; ;;; Upon closer examination, it's observed that the (A,B) pairs ;;; are two's complements of one another (modulo 2^N). E.g., the 2's ;;; complement of 1 mod 16 is 15. In general: ;;; ;;; B = (~A + 1) % 2^N ;;; ;;; Substituting this into the twist formula yields: ;;; ;;; A*x + ((~A + 1) % 2^N)*y ;;; --------------------------- ;;; 2^N ;;; ;;; A modulo N operation means that only the lower N bits are significant. ;;; So dropping the notation and keeping this observation in mind we ;;; can simplify this equation: ;;; ;;; A*x + (~A + 1)*y A*x + ~A*y + y ;;; ------------------ = ---------------- ;;; 2^N 2^N ;;; ;;; Which can be evaluated in psuedo-C: ;;; ;;; int A; /* initialized somewhere's else */ ;;; int num; ;;; ;;; int twist ( int x, int y) ;;; { ;;; int num = y; ;;; ;;; num += (A & 0x01) ? x : y; ;;; num >>= 1 ;;; ;;; num += (A & 0x02) ? x : y; ;;; num >>= 1 ;;; ;;; num += (A & 0x04) ? x : y; ;;; num >>= 1 ;;; ;;; num += (A & 0x08) ? x : y; ;;; num >>= 1 ;;; ;;; return num; ;;; } ;;; ;;; Excution time: 1 + 5*N cycles (e.g. 21cycles for A+B=16=2^4) ;;; ;;; ;;; twist: movf y,w movwf num btfsc A,0 movf x,w addwf num,f rrf num,f movf y,w btfsc A,1 movf x,w addwf num,f rrf num,f movf y,w btfsc A,2 movf x,w addwf num,f rrf num,f movf y,w btfsc A,3 movf x,w addwf num,f rrf num,f return end gpsim-0.30.0/examples/14bit/ap.stc0000664000076400007640000000210013041763642013517 00000000000000# Stimulus file for testing 3-tcyc resolution # pulse measurements. echo Stimulus file for 3-tcyc pulse measurements # Define a node to which the pins can attach. node test_node # Create an asynchronous stimulus that's 0x10000 cycles long # and attach it to portb bit 0. stimulus asynchronous_stimulus # or we could've used asy # The initial state AND the state the stimulus is when # it rolls over initial_state 1 # all times are with respect to the cpu's cycle counter start_cycle 0x100 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 0x100 # Indicate that this is digital data (default): digital # Now the cycles at which stimulus changes states are # specified. The initial cycle was specified above. { 0x20 1 0x40 0 0x60 1 } # Give the stimulus a name: name asy1 # Finally, tell the command line interface that we're done # with the stimulus end # Attach the stimulus to the IO port attach test_node asy1 portb0 # but we can still have more stuff stimulus echo stimulus created gpsim-0.30.0/examples/14bit/iopin_stim.asm0000664000076400007640000000127213041763642015271 00000000000000 list p=16c84 ;; The purpose of this program is to test gpsim's stimulation capability ;; between iopins. In this example, the open collector iopin of porta (bit 4) ;; is toggled. The response is then examined at portb bit 0. ;; ;; ;; ;; include "p16c84.inc" cblock 0x20 temp1 temp2 temp3 endc org 0 goto start org 4 start clrf temp1 ; a counter clrf temp2 ; a flag keeping track of the state of port b clrf temp3 bsf status,rp0 bcf porta,4 bcf status,rp0 begin movf temp3,w movwf porta ;; Count the rising edges on portb bit 0 movf portb,w xorwf temp2,w xorwf temp2,f andwf temp2,w andlw 1 skpz incf temp1,f incf temp3 goto begin endgpsim-0.30.0/examples/14bit/p16c64_test.asm0000664000076400007640000000447613041763642015112 00000000000000 ;; gpasm bug --- c64 is not recognized... list p=16c64 __config _wdt_off ;; The purpose of this program is to test gpsim's ability to simulate a pic 16c64. include "p16c64.inc" cblock 0x20 x t1,t2,t3 endc org 0 goto main org 4 retfie main: ;; disable (primarily) global and peripheral interrupts clrf intcon goto pwm_test1 ;; ;; TMR1 test ;; ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale clrf t1con ; bcf pir1,tmr1if ; Clear the interrupt/roll over flag ;; Zero the TMR1 clrf tmr1l clrf tmr1h ;; Test rollover ;; the following block of code will test tmr1's rollover for ;; each of the 4 prescale values. clrf x ;; Start the timer bsf t1con,tmr1on tmr1_test1: ;; Loop until the timer rolls over: btfss pir1,tmr1if goto $-1 bcf pir1,tmr1if incf x,f btfss x,2 goto tmr1_test1 clrf x movf t1con,w addlw (1< stimulus sqw 200 portb 0 ;; this will create a synchronous square wave with a period of 200 ;; cpu cycles (and by default a 50% duty cycle) and will attach it to ;; bit 0 of port b. ;; OR ;; load the Startup command file 'sync_stim.stc': ;; gpsim> load c sync_stim.stc ;; This will create a stimulus and load the hex associated with this source. include "p16c84.inc" cblock 0x20 temp1 temp2 temp3 endc org 0 goto start org 4 start clrf temp1 ; a counter clrf temp2 ; a flag keeping track of the state of port b begin ;; Count the rising edges on portb bit 0 movf portb,w xorwf temp2,w xorwf temp2,f andwf temp2,w andlw 1 skpz incf temp1,f goto begin endgpsim-0.30.0/examples/14bit/p16c65_pwm.asm0000664000076400007640000000357513041763642014736 00000000000000 ;; gpasm bug --- c65 is not recognized... ;; (at least not in 0.0.2) list p=16c84 __config _wdt_off ;; The purpose of this program is to test gpsim's ability to simulate ;; the pwm's in the mid-range pic core (e.g. p16c65). #define __16c65 include "p16c65.inc" cblock 0x20 status_temp,w_temp interrupt_temp temp1,temp2 t1,t2,t3 endc cblock 0xa0 status_temp_alias,w_temp_alias endc org 0 goto main org 4 ;; ;; Interrupt ;; movwf w_temp swapf status,w movwf status_temp ;; Are peripheral interrupts enabled? btfss intcon,peie goto exit_int bsf status,rp0 movf pie1,w bcf status,rp0 movwf interrupt_temp check_tmr2: btfsc pir1,tmr2if btfss interrupt_temp,tmr2ie goto exit_int ;; tmr2 has rolled over bcf pir1,tmr2if ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover exit_int: swapf status_temp,w movwf status swapf w_temp,f swapf w_temp,w retfie ;; ;; ;; main: clrf temp1 clrf temp2 ;; disable (primarily) global and peripheral interrupts clrf intcon clrf pir1 pwm_test1: bsf pir1,tmr2if bsf intcon,peie bsf intcon,gie bsf status,rp0 bsf portc,2 ;CCP bit is an input ;; Set the pwm frequency to (fosc/4)/(PR2 + 1) ;; (note, TMR2 prescale is 1 on reset) ;; (note, there's only one period register for ;; both PWM modules. Hence, they have the same ;; frquency [and phase].) movlw 0x7f movwf pr2 ;; Enable the tmr2 interrupt bsf pie1,tmr2ie bcf status,rp0 movlw 0x20 movwf ccpr1l movlw 0x20 movwf ccpr2l movlw 4 movwf t2con ;; ;; Initialize the CCP module for PWM: ;; movlw 0xc movwf ccp1con movwf ccp2con ;; ;; Count the number of pwm cycles ;; btfss temp1,0 ; Interrupt routine will set this goto $-1 bcf temp1,0 ;; dynamically adjust pwm2's duty cycle: movlw 0x8 addwf ccpr2l,w andlw 0x7f incfsz temp2,f goto $-4 goto $ endgpsim-0.30.0/examples/14bit/analog_stim.stc0000664000076400007640000000077413041763642015433 00000000000000# gpsim # Startup command file to test analog stimuli # Create the processor that's to be simulated set verbose 3 # Load the .hex file load s p16c71_test.cod # Create a stimulus node: node analog_node # Create a triangle wave stimulus that's 1000 cycles long # and attach it to porta bit 0. The duty cycle is 30% # and the phase is 10%. echo stimulus create stimulus tri period 1000 high_time 300 phase 100 #port porta 0 name t_wave end echo stimulus created attach analog_node porta0 t_wave gpsim-0.30.0/examples/14bit/p16c64_ccp.asm0000664000076400007640000001362413041763642014673 00000000000000 list p=16c64 __config _WDT_OFF ;; The purpose of this program is to test gpsim's ability to simulate the ;; Capture Compare peripherals in a midrange pic (e.g. pic16c64). See ;; p16c64_tmr1.asm for additional tmr1 examples. ;; NOTE: The capture mode will only work if there is something to capture! ;; Hence this file should loaded into gpsim with the startup command file ;; p16c64_ccp.stc - this will give you a square wave that ccp can capture. include "p16c64.inc" cblock 0x20 status_temp,w_temp interrupt_temp temp1,temp2 t1,t2,t3 kz endc cblock 0xa0 status_temp_alias,w_temp_alias endc org 0 goto main org 4 ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp ;; Are peripheral interrupts enabled? btfss INTCON,PEIE goto exit_int bsf STATUS,RP0 movf PIE1 ^ 0x80,W bcf STATUS,RP0 movwf interrupt_temp check_tmr1: btfsc PIR1,TMR1IF btfss interrupt_temp,TMR1IE goto check_ccp1 ;; tmr1 has rolled over bcf PIR1,TMR1IF ; Clear the pending interrupt bsf temp1,0 ; Set a flag to indicate rollover check_ccp1: btfsc PIR1,CCP1IF btfss interrupt_temp,CCP1IE goto exit_int bcf PIR1,CCP1IF ; Clear the pending interrupt bsf temp1,1 ; Set a flag to indicate match exit_int: swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie main: clrf kz ;kz == Known Zero. ;; disable (primarily) global and peripheral interrupts clrf INTCON ;; ;; CCP test ;; ;; The CCP module is intricately intertwined with the TMR1 ;; module. So first, let's initialize TMR1: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale clrf T1CON ; clrf PIR1 ; Clear the interrupt/roll over flag ;; Zero TMR1 clrf TMR1L clrf TMR1H ;; Start the timer bsf T1CON,TMR1ON ccp_test1: movlw (1<&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = examples/12bit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ gpio_stim.stc \ p12_it.asm \ p12c508_test.asm \ p12c509_test.asm \ p12c508_test.stc \ p12x.inc \ pcl_test_12bit.asm MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/12bit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/12bit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/examples/12bit/Makefile.am0000664000076400007640000000045013041763642014444 00000000000000EXTRA_DIST = \ gpio_stim.stc \ p12_it.asm \ p12c508_test.asm \ p12c509_test.asm \ p12c508_test.stc \ p12x.inc \ pcl_test_12bit.asm MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ gpsim-0.30.0/examples/12bit/p12_it.asm0000664000076400007640000000310513041763642014210 00000000000000 ;; p12_it.asm ;; ;; The purpose of this program is to test how well gpsim can simulate ;; the instruction set of the 12bit core pics. Nothing useful is performed ;; - this program is only used to debug gpsim. list p=12c508 ;; include "p16c84.inc" #define indf 0 #define pcl 2 #define status 3 #define fsr 4 #define f 1 #define w 0 cblock 0x0c temp,temp1,temp2 endc org 0 goto test_pcl ;; addlw 0xaa addwf temp,w andlw 0xaa andwf temp,w bcf temp,5 bsf temp,5 btfsc temp,5 btfss temp,5 call routine clrf temp clrw clrwdt comf temp,w decf temp,w decfsz temp,w goto l1 nop nop nop l1: incf temp,w incfsz temp,w iorlw 0xaa iorwf temp,w movlw 0xaa movf temp,w movwf temp nop option goto r1 ; retfie retlw 0xaa routine retlw 0 r1: rlf temp,w rrf temp,w sleep ; sublw 0xaa subwf temp,w swapf temp,w tris 5 xorlw 0xaa xorwf temp,w ;; ;; Test indirect branching ;; test_pcl: clrf temp clrf temp1 tt1: movf temp,w call table_test xorwf temp,w skpz bsf temp1,0 incf temp,f btfss temp,4 goto tt1 goto test_pcl2 table_test: addwf pcl,f table: retlw 0 retlw 1 retlw 2 retlw 3 retlw 4 retlw 5 retlw 6 retlw 7 retlw 8 retlw 9 retlw 10 retlw 11 retlw 12 retlw 13 retlw 14 retlw 15 test_pcl2: btfsc temp2,0 goto test_pcl3 movlw 0x20 movwf fsr next clrf indf incf fsr,1 btfss fsr,4 goto next bsf temp2,0 clrf pcl test_pcl3: movlw ly movwf pcl ; == goto ly lx goto test_pcl4 ly movlw lx movwf pcl test_pcl4: goto $ endgpsim-0.30.0/examples/12bit/gpio_stim.stc0000664000076400007640000000256013041763642015121 00000000000000# another test stimulation file # # the '#' marks the beginning of a comment # # This stimulus file is used for testing the gpio # port on a 12c508 or 12c509 echo I/O pin Stimulus file for gpio. # Define a node to which the pins can attach. node a_gpio_node # Create an asynchronous stimulus that's 1000 cycles long # and attach it to portc bit 2. # stimulus asy 0x100 0x200 0x300 0x400 0x500 0x600 0x700 period 0x1000 name asy1 end stimulus asynchronous_stimulus # or we could've used asy # The initial state AND the state the stimulus is when # it rolls over initial_state 1 # all times are with respect to the cpu's cycle counter start_cycle 0x100 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 0x1000 # Now the cycles at which stimulus changes states are # specified. The initial cycle was specified above. So # the first cycle specified below will toggle this state. # In this example, the stimulus will go high at cycle 100 # and then go low at cycle 200, high at 300, and so on { 0x200 0 0x300 1 0x400 0 0x600 1 0x700 0 0x800 1 0x900 0 } # Give the stimulus a name: name asy1 # Finally, tell the command line interface that we're done # with the stimulus end # but we can still have more stuff # Attach the stimulus to the IO port attach a_gpio_node asy1 gpio4 echo stimulus created gpsim-0.30.0/examples/12bit/p12c509_test.asm0000664000076400007640000000026113041763642015154 00000000000000 ;; list p=12c509 radix dec nolist include "p12x.inc" list __config _wdt_on cblock 0x07 temp,temp1,temp2 endc org 0 start: goto start endgpsim-0.30.0/examples/12bit/p12x.inc0000775000076400007640000000227213041763642013704 00000000000000 LIST ; P12C508 & P12C509 Header file NOLIST ;----- register files indf equ 0x0 tmr0 equ 0x1 pcl equ 0x2 status equ 0x3 fsr equ 0x4 osccal equ 0x5 gpio equ 0x6 ;----- status bits -------------------------------------------------------- pa2 equ 7 gpwuf equ 7 pa1 equ 6 pa0 equ 5 not_to equ 4 to equ 4 not_pd equ 3 pd equ 3 z equ 2 dc equ 1 c equ 0 ;----- option bits -------------------------------------------------------- not_gpwu equ 7 ; gpwu is active low, but it's confusing to rbpu equ 7 ; specify this so verbosely. not_gppu equ 6 gppu equ 6 t0cs equ 5 t0se equ 4 psa equ 3 ps2 equ 2 ps1 equ 1 ps0 equ 0 ; configuration bits _cp_on equ 0xff7 _cp_off equ 0xfff _pwrte_on equ 0x3fff _pwrte_off equ 0x3ff7 _wdt_on equ 0xfff _wdt_off equ 0xffb _lp_osc equ 0xffc _xt_osc equ 0xffd _intrc_osc equ 0xffe _extrc_osc equ 0xfff ;========================================================================== ; ; Processor-dependent Definitions ; ;========================================================================== ifdef __12c508 __maxram h'01f' endif ifdef __12c509 __maxram h'03f' endif LIST gpsim-0.30.0/examples/projects/0000775000076400007640000000000013117465765013412 500000000000000gpsim-0.30.0/examples/projects/Makefile.in0000664000076400007640000003220113117441635015363 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = examples/projects ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ README \ digital_stim/Makefile digital_stim/digital_stim.asm digital_stim/digital_stim.stc \ digital_stim/README digital_stim/ChangeLog \ p16f628_test/Makefile p16f628_test/README p16f628_test/f628.asm p16f628_test/f628.stc \ p16f628_test/ChangeLog \ stack_test/Makefile stack_test/README stack_test/ChangeLog stack_test/stack_test.asm \ stack_test/stack_test.stc MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/projects/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/projects/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/examples/projects/Makefile.am0000664000076400007640000000103713041763643015357 00000000000000EXTRA_DIST = \ README \ digital_stim/Makefile digital_stim/digital_stim.asm digital_stim/digital_stim.stc \ digital_stim/README digital_stim/ChangeLog \ p16f628_test/Makefile p16f628_test/README p16f628_test/f628.asm p16f628_test/f628.stc \ p16f628_test/ChangeLog \ stack_test/Makefile stack_test/README stack_test/ChangeLog stack_test/stack_test.asm \ stack_test/stack_test.stc MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ gpsim-0.30.0/examples/projects/README0000664000076400007640000000165513041763643014211 00000000000000 gpsim/examples/projects/ In this directory you'll find sample projects that can serve as a template for creating a new project. Each project here attempts to be very simple to illustrate one or two new points. If you want to see an example of a more sophisticated project the please look at gpsim's CVS in the extras/ directory. In there you'll find the LCD module example. digital_stim/ - This project illustrates the use of asynchronous stimuli. The gpsim start up command script is also introduced. stack_test/ - This project illustrates the how gpsim simulates the mid-range core's stack. A trivial multi-tasking switcher is implemented by taking advantage of the circular stack. p16f628_test/ - This project tests all aspects of the 16f628. The '628 is rapidly replacing the 'f84 as the PIC of choice among hobbiest. gpsim-0.30.0/examples/projects/stack_test/0000775000076400007640000000000013117465765015556 500000000000000gpsim-0.30.0/examples/projects/stack_test/ChangeLog0000664000076400007640000000006513041763643017241 00000000000000Tue Dec 25 11:12:34 PST 2001 * Started this example gpsim-0.30.0/examples/projects/stack_test/Makefile0000664000076400007640000000275613041763643017140 00000000000000# Example # # # system programs RM = /bin/rm -f ARC = tar -cvf GZIP = gzip ZIP = zip # gpasm programs ASM = gpasm DIASM = gpdasm CODVIEWER = gpvc -d # simulator GPSIM = gpsim # Programmer DEVICE = 16F84 SERIAL_PORT = /dev/ttyS1 PROG = picp $(SERIAL_PORT) $(DEVICE) -wp # project data PROJECT = stack_test VERSION = 1 SOURCES = stack_test.asm stack_test.stc HEADER = /usr/local/share/gpasm/header DIST_FILES = $(SOURCES) \ stack_test.hex stack_test.asm stack_test.stc \ ChangeLog \ Makefile \ README # derived variables PROJ_VER = $(PROJECT)-$(VERSION) ARCHIVE = $(PROJ_VER).tar ZIP_PROJ_VER = $(PROJECT)$(VERSION) ZIPARCHIVE = $(ZIP_PROJ_VER) LATEST_HEX = $(PROJECT)$(VERSION).hex all: $(PROJECT).cod sim: $(PROJECT).cod $(GPSIM) -c $(PROJECT).stc $(PROJECT).cod: $(SOURCES) $(ASM) -I $(HEADER) $(PROJECT).asm #$(PROJECT).hex: $(PROJECT).asm # $(ASM) -I $(HEADER) $(PROJECT).asm $(ARCHIVE): $(DIST_FILES) mkdir $(PROJ_VER) cp $(DIST_FILES) $(PROJ_VER)/. $(ARC) $(ARCHIVE) $(PROJ_VER) rm -rf $(PROJ_VER) #zip: $(DIST_FILES) zip: $(PROJECT).cod mkdir $(ZIP_PROJ_VER) cp $(DIST_FILES) $(ZIP_PROJ_VER)/. cp $(PROJECT).hex $(ZIP_PROJ_VER)/$(LATEST_HEX) cp $(PROJECT).hex $(LATEST_HEX) $(ZIP) -r $(ZIP_PROJ_VER) $(ZIP_PROJ_VER) rm -rf $(ZIP_PROJ_VER) archive: $(ARCHIVE) $(GZIP) $(ARCHIVE) prog: $(PROJECT).cod $(PROG) $(PROJECT).hex clean: $(RM) *.lst *.cod $(PROJECT)*.gz *~ gpsim-0.30.0/examples/projects/stack_test/README0000664000076400007640000000031613041763643016346 00000000000000Sample project. This project illustrates interesting things you can do with the PIC's circular stack. Assemble the .cod file: $ make Simulate the program: $ make sim or $ gpsim -c stack_test.stc gpsim-0.30.0/examples/projects/stack_test/stack_test.stc0000664000076400007640000000403413041763643020346 00000000000000# another test stimulation file # # the '#' marks the beginning of a comment # # Define an asynchronus stimulus # # This stimulation file illustrates how the stimulus command # may span several lines of input. The only requirement # is that 'end' must be the last statement (of the stimulus) echo Sample asynchronous stimulus file # Create the processor that's to be simulated load s stack_test.cod # If you want to see gpsim spew a ton of debug junk, # then uncomment the next line. # set verbose 0xff stimulus asynchronous_stimulus # or we could've used asy # The initial state AND the state the stimulus is when # it rolls over initial_state 1 # all times are with respect to the cpu's cycle counter start_cycle 100 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 5000 # Now the cycles at which stimulus changes states are # specified. The initial cycle was specified above. So # the first cycle specified below will toggle this state. # In this example, the stimulus will go high at cycle 100 # and then go low at cycle 200, high at 300, and so on { 203, 0, 300, 1, 400, 0, 600, 1, 1000, 0, 3000, 1 } # specify the ioport that this stimulus drives # starting with 0.0.5 # you'll want to specify the port connection # with the attach command - but, this still works. # port portb 0 # Give the stimulus a name: name asy_test # Finally, tell the command line interface that we're done # with the stimulus end # but we can still have more stuff # Create a stimulus node: node test_node # Now attach the stimulus to an I/O port # Note, the I/O ports are given the name # portxn where x = a,b,c, etc # and n is the bit within the I/O port attach test_node asy_test portb0 # Just for the heck of it, let's set a break point # after we've counted the stimulus going high 16 times: break w temp2==0x10 # In case there's a bug in the program, let's halt simulation # after a million cycles. break c 1000000 set verbose 0 gpsim-0.30.0/examples/projects/stack_test/stack_test.asm0000664000076400007640000000271013041763643020334 00000000000000 list p=16f84 ;; The purpose of this program is to test gpsim's capability to simulate ;; the PIC's stack. ;; ;; Start gpsim: ;; $ gpsim ;; then load the Startup command file 'stack_test.stc': ;; gpsim> load c stack_test.stc ;; ;; OR ;; ;; invoke gpsim with the command file ;; $ gpsim -c stack_test.stc ;; ;; OR ;; ;; invoke the simualtion from the Makefile: ;; make sim ;; In all cases, the stimulus file will load the simulation ;; file and create the stimuli. In the Makefile case, the ;; simulation file will be (re)created if the .asm has been ;; been changed. ;; ;; include "p16f84.inc" cblock 0x20 temp1 temp2 temp3 endc org 0 goto start org 4 start clrf temp1 ; a counter clrf temp2 ; a flag keeping track of the state of port b init_tasks goto Task_0_init init_done return begin ;; Count the rising edges on portb bit 0 movf PORTB,w xorwf temp2,w xorwf temp2,f andwf temp2,w andlw 1 skpz incf temp1,f goto begin Task_0_init: call Task_1_init Task_0: return Task_1_init: call Task_2_init Task_1: btfsc PORTB,0 goto t1b call $+1 t1a movlw 2 return t1b movlw 3 return Task_2_init: call Task_3_init Task_2: return Task_3_init: call Task_4_init Task_3: return Task_4_init: call Task_5_init Task_4: return Task_5_init: call Task_6_init Task_5: return Task_6_init: call Task_7_init Task_6: return Task_7_init: call init_done Task_7: return end gpsim-0.30.0/examples/projects/digital_stim/0000775000076400007640000000000013117465765016063 500000000000000gpsim-0.30.0/examples/projects/digital_stim/ChangeLog0000664000076400007640000000016513041763643017547 00000000000000Wed Nov 28 06:44:31 PST 2001 * Started this example. This is mostly an organized copy of one of gpsim examples. gpsim-0.30.0/examples/projects/digital_stim/Makefile0000664000076400007640000000300113041763643017425 00000000000000# Module example # # # system programs RM = /bin/rm -f ARC = tar -cvf GZIP = gzip ZIP = zip # gpasm programs ASM = gpasm DISASM = gpdasm CODVIEWER = gpvc -d # simulator GPSIM = gpsim # Programmer DEVICE = 16F84 SERIAL_PORT = /dev/ttyS1 PROG = picp $(SERIAL_PORT) $(DEVICE) -wp # project data PROJECT = digital_stim VERSION = 1 SOURCES = digital_stim.asm digital_stim.stc HEADER = /usr/local/share/gpasm/header DIST_FILES = $(SOURCES) \ digital_stim.hex digital_stim.asm digital_stim.stc \ ChangeLog \ Makefile \ README # derived variables PROJ_VER = $(PROJECT)-$(VERSION) ARCHIVE = $(PROJ_VER).tar ZIP_PROJ_VER = $(PROJECT)$(VERSION) ZIPARCHIVE = $(ZIP_PROJ_VER) LATEST_HEX = $(PROJECT)$(VERSION).hex all: $(PROJECT).cod sim: $(PROJECT).cod $(GPSIM) -c $(PROJECT).stc $(PROJECT).cod: $(SOURCES) $(ASM) -I $(HEADER) $(PROJECT).asm #$(PROJECT).hex: $(PROJECT).asm # $(ASM) -I $(HEADER) $(PROJECT).asm $(ARCHIVE): $(DIST_FILES) mkdir $(PROJ_VER) cp $(DIST_FILES) $(PROJ_VER)/. $(ARC) $(ARCHIVE) $(PROJ_VER) rm -rf $(PROJ_VER) #zip: $(DIST_FILES) zip: $(PROJECT).cod mkdir $(ZIP_PROJ_VER) cp $(DIST_FILES) $(ZIP_PROJ_VER)/. cp $(PROJECT).hex $(ZIP_PROJ_VER)/$(LATEST_HEX) cp $(PROJECT).hex $(LATEST_HEX) $(ZIP) -r $(ZIP_PROJ_VER) $(ZIP_PROJ_VER) rm -rf $(ZIP_PROJ_VER) archive: $(ARCHIVE) $(GZIP) $(ARCHIVE) prog: $(PROJECT).cod $(PROG) $(PROJECT).hex clean: $(RM) *.lst *.cod $(PROJECT)*.gz *~ gpsim-0.30.0/examples/projects/digital_stim/README0000664000076400007640000000022413041763643016651 00000000000000Sample project. This project illustrates digital stimuli as used with gpsim. Assemble the .cod file: $ make Simulate the program: $ make sim gpsim-0.30.0/examples/projects/digital_stim/digital_stim.asm0000664000076400007640000000207113041763643021146 00000000000000 list p=16f84 ;; The purpose of this program is to test gpsim's stimulation capability ;; A stimulus is attached to PORTB pin 0 and this program will count ;; the rising edges that are seen on that pin. ;; ;; Start gpsim: ;; $ gpsim ;; then load the Startup command file 'digital_stim.stc': ;; gpsim> load c digital_stim.stc ;; ;; OR ;; ;; invoke gpsim with the command file ;; $ gpsim -c digital_stim.stc ;; ;; OR ;; ;; invoke the simulation from the Makefile: ;; make sim ;; In all cases, the stimulus file will load the simulation ;; file and create the stimuli. In the Makefile case, the ;; simulation file will be (re)created if the .asm has been ;; been changed. ;; ;; include "p16f84.inc" cblock 0x20 temp1 temp2 temp3 endc org 0 goto start org 4 start clrf temp1 ; a counter clrf temp2 ; a flag keeping track of the state of port b begin ;; Count the rising edges on portb bit 0 movf PORTB,w xorwf temp2,w xorwf temp2,f andwf temp2,w andlw 1 skpz incf temp1,f goto begin end gpsim-0.30.0/examples/projects/digital_stim/digital_stim.stc0000664000076400007640000000403513041763643021161 00000000000000# another test stimulation file # # the '#' marks the beginning of a comment # # Define an asynchronus stimulus # # This stimulation file illustrates how the stimulus command # may span several lines of input. The only requirement # is that 'end' must be the last statement (of the stimulus) echo Sample asynchronous stimulus file # Create the processor that's to be simulated load s digital_stim.cod # If you want to see gpsim spew a ton of debug junk, # then uncomment the next line. # set verbose 0xff stimulus asynchronous_stimulus # or we could've used asy # The initial state AND the state the stimulus is when # it rolls over initial_state 1 # all times are with respect to the cpu's cycle counter start_cycle 100 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 5000 # Now the cycles at which stimulus changes states are # specified. The initial cycle was specified above. So # the first cycle specified below will toggle this state. # In this example, the stimulus will go high at cycle 100 # and then go low at cycle 200, high at 300, and so on { 203, 0, 300, 1, 400, 0, 600, 1, 1000, 0, 3000, 1 } # specify the ioport that this stimulus drives # starting with 0.0.5 # you'll want to specify the port connection # with the attach command - but, this still works. # port portb 0 # Give the stimulus a name: name asy_test # Finally, tell the command line interface that we're done # with the stimulus end # but we can still have more stuff # Create a stimulus node: node test_node # Now attach the stimulus to an I/O port # Note, the I/O ports are given the name # portxn where x = a,b,c, etc # and n is the bit within the I/O port attach test_node asy_test portb0 # Just for the heck of it, let's set a break point # after we've counted the stimulus going high 16 times: break w temp1==0x10 # In case there's a bug in the program, let's halt simulation # after a million cycles. break c 1000000 set verbose 0 gpsim-0.30.0/examples/projects/p16f628_test/0000775000076400007640000000000013117465765015465 500000000000000gpsim-0.30.0/examples/projects/p16f628_test/f628.asm0000664000076400007640000001626113041763643016572 00000000000000 list p=16f628 __CONFIG _WDT_OFF ;; The purpose of this program is to test gpsim's stimulation capability ;; A stimulus is attached to PORTB pin 0 and this program will count ;; the rising edges that are seen on that pin. ;; ;; Start gpsim: ;; $ gpsim ;; then load the Startup command file 'digital_stim.stc': ;; gpsim> load c digital_stim.stc ;; ;; OR ;; ;; invoke gpsim with the command file ;; $ gpsim -c digital_stim.stc ;; ;; OR ;; ;; invoke the simualtion from the Makefile: ;; make sim ;; In all cases, the stimulus file will load the simulation ;; file and create the stimuli. In the Makefile case, the ;; simulation file will be (re)created if the .asm has been ;; been changed. ;; ;; ;; The purpose of this program is to test gpsim's ability to simulate a pic 16f627/8. ;; (this was derived from the similar program for testing the c64). include "p16f628.inc" cblock 0x20 x,y t1,t2,t3 pma_string ; starting here's where a string will be copied from flash endc ;; Take advantage of the upper 16 bytes all banks being aliased cblock 0x70 adr_cnt data_cnt w_temp status_temp endc DATA14 macro _a, _b data (_a<<7) | (_b) endm org 0 goto main org 4 ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp btfss INTCON,PEIE goto exit_int bcf STATUS,RP1 bcf STATUS,RP0 btfss PIR1,EEIF goto exit_int ;;; eeprom has interrupted bcf PIR1,EEIF exit_int: swapf status_temp,W movwf STATUS swapf w_temp,F swapf w_temp,W retfie main: ;; clear ram movlw 0 call preset_ram movlw 0x55 call preset_ram movlw 0 call preset_ram ;; disable (primarily) global and peripheral interrupts clrf INTCON call obliterate_data_eeprom call bank_access_test call tmr1_test call tmr2_test call tmr1_test2 call tmr1_test3 call pwm_test1 goto $ ;; ;; TMR1 test ;; tmr1_test: ;; Clear all of the bits of the TMR1 control register: ;; this will: ;; Turn the tmr off ;; Select Fosc/4 as the clock source ;; Disable the External oscillator feedback circuit ;; Select a 1:1 prescale clrf T1CON ; bcf PIR1,TMR1IF ; Clear the interrupt/roll over flag ;; Zero the TMR1 clrf TMR1L clrf TMR1H ;; Test rollover ;; the following block of code will test tmr1's rollover for ;; each of the 4 prescale values. clrf x ;; Start the timer bsf T1CON,TMR1ON tmr1_test1: ;; Loop until the timer rolls over: btfss PIR1,TMR1IF goto $-1 bcf PIR1,TMR1IF incf x,F btfss x,2 goto tmr1_test1 clrf x movf T1CON,W addlw (1< fsr =0x120 ;; write to address 0x120 - 0x14f cb2: movwf INDF incf FSR,F btfsc FSR,6 ;loop until fsr == 0x50 btfss FSR,4 ;i.e. check for the bit pattern x1x1xxxx goto cb2 bsf FSR,7 ;fsr == 0xd0 bsf FSR,5 ;fsr == 0xf0 ;; write to address 0x1f0 - 0x1ff cb3: movwf INDF incfsz FSR,F goto cb3 clrf STATUS ;clear irp,rp0,rp1 return ;; ========================================================= ;; bank_access_test: ;; ;; use the indirect register to increment register 0x70. ;; This register is aliased in all four banks. ;; Then use direct addressing to verify that the increment ;; occurred. Note that bank switching is necessary to access ;; 0x70 directly in the other banks (that is to access 0xf0, ;; 0x170 and 0x1f0 directly, you need to switch to bank 1,2 ;; or 3 respectively). bank_access_test: bcf STATUS,RP0 movlw 0x70 movwf FSR clrf 0x70 incf INDF,F btfss 0x70,0 goto $-1 bsf STATUS,RP0 ;bank 1 incf INDF,F btfsc 0x70,0 goto $-1 bsf STATUS,RP1 ;bank 3 incf INDF,F btfss 0x70,0 goto $-1 bcf STATUS,RP0 ;bank 2 incf INDF,F btfsc 0x70,0 goto $-1 bcf STATUS,RP1 ;bank 0 return ;------------------------------------------------------------- ; obliterate_data_eeprom ; ; This routine will loop 255 times and write the loop iteration ;number to the entire contents of the EEPROM. I.e. on the first ;pass all 1's are written, on the second pass all 2's are written ;and so on. obliterate_data_eeprom clrf adr_cnt clrf data_cnt incf data_cnt,f bcf STATUS,RP1 ;Point to bank 1 bsf STATUS,RP0 ;(That's where the EEPROM registers are) bsf PIE1,EEIE ;Enable eeprom interrupts bsf INTCON,PEIE ;The peripheral interrupt bit mus also be set ;to allow ints. l1: movf adr_cnt,W movwf EEADR movf data_cnt,W movwf EEDATA bcf INTCON,GIE ;Disable interrupts while enabling write bsf EECON1,WREN ;Enable eeprom writes movlw 0x55 ;Magic sequence to enable eeprom write movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR ;Begin eeprom write bsf INTCON,GIE ;Re-enable interrupts btfsc EECON1,WR ;Wait for the write to complete goto $-1 incf adr_cnt,f btfss adr_cnt,7 ;Does the address == 0x80? goto l1 clrf adr_cnt incfsz data_cnt,F goto l1 return org 0x2100 de "Linux is cool!",0 de 0xaa,0x55,0xf0,0x0f de 'g','p','s','i','m' de "f628.asm - a program to test " de "eveything an 'f877 can possibly do." end gpsim-0.30.0/examples/projects/p16f628_test/ChangeLog0000664000076400007640000000006613041763643017151 00000000000000Sat Dec 29 08:22:01 PST 2001 * Started this example. gpsim-0.30.0/examples/projects/p16f628_test/f628.stc0000664000076400007640000000345213041763643016601 00000000000000# another test stimulation file # # the '#' marks the beginning of a comment # # Define an asynchronus stimulus # # This stimulation file illustrates how the stimulus command # may span several lines of input. The only requirement # is that 'end' must be the last statement (of the stimulus) echo Sample asynchronous stimulus file # Create the processor that's to be simulated load s f628.cod # If you want to see gpsim spew a ton of debug junk, # then uncomment the next line. # set verbose 0xff stimulus asynchronous_stimulus # or we could've used asy # The initial state AND the state the stimulus is when # it rolls over initial_state 1 # all times are with respect to the cpu's cycle counter start_cycle 100 # the asynchronous stimulus will roll over in 'period' # cycles. Delete this line if you don't want a roll over. period 5000 # Now the cycles at which stimulus changes states are # specified. The initial cycle was specified above. So # the first cycle specified below will toggle this state. # In this example, the stimulus will go high at cycle 100 # and then go low at cycle 200, high at 300, and so on { 203, 0, 300, 1, 400, 0, 600, 1, 1000, 0, 3000, 1 } # specify the ioport that this stimulus drives # starting with 0.0.5 # you'll want to specify the port connection # with the attach command - but, this still works. # port portb 0 # Give the stimulus a name: name asy_test # Finally, tell the command line interface that we're done # with the stimulus end # but we can still have more stuff # Create a stimulus node: node test_node # Now attach the stimulus to an I/O port # Note, the I/O ports are given the name # portxn where x = a,b,c, etc # and n is the bit within the I/O port attach test_node asy_test portb0 set verbose 0 gpsim-0.30.0/examples/projects/p16f628_test/Makefile0000664000076400007640000000272113041763643017037 00000000000000# Module example # # # system programs RM = /bin/rm -f ARC = tar -cvf GZIP = gzip ZIP = zip # gpasm programs ASM = gpasm DISASM = gpdasm CODVIEWER = gpvc -d # simulator GPSIM = gpsim # Programmer DEVICE = 16F84 SERIAL_PORT = /dev/ttyS1 PROG = picp $(SERIAL_PORT) $(DEVICE) -wp # project data PROJECT = f628 VERSION = 1 SOURCES = f628.asm f628.stc HEADER = /usr/local/share/gpasm/header DIST_FILES = $(SOURCES) \ f628.hex f628.asm f628.stc \ ChangeLog \ Makefile \ README # derived variables PROJ_VER = $(PROJECT)-$(VERSION) ARCHIVE = $(PROJ_VER).tar ZIP_PROJ_VER = $(PROJECT)$(VERSION) ZIPARCHIVE = $(ZIP_PROJ_VER) LATEST_HEX = $(PROJECT)$(VERSION).hex all: $(PROJECT).cod sim: $(PROJECT).cod $(GPSIM) -c $(PROJECT).stc $(PROJECT).cod: $(SOURCES) $(ASM) -I $(HEADER) $(PROJECT).asm #$(PROJECT).hex: $(PROJECT).asm # $(ASM) -I $(HEADER) $(PROJECT).asm $(ARCHIVE): $(DIST_FILES) mkdir $(PROJ_VER) cp $(DIST_FILES) $(PROJ_VER)/. $(ARC) $(ARCHIVE) $(PROJ_VER) rm -rf $(PROJ_VER) #zip: $(DIST_FILES) zip: $(PROJECT).cod mkdir $(ZIP_PROJ_VER) cp $(DIST_FILES) $(ZIP_PROJ_VER)/. cp $(PROJECT).hex $(ZIP_PROJ_VER)/$(LATEST_HEX) cp $(PROJECT).hex $(LATEST_HEX) $(ZIP) -r $(ZIP_PROJ_VER) $(ZIP_PROJ_VER) rm -rf $(ZIP_PROJ_VER) archive: $(ARCHIVE) $(GZIP) $(ARCHIVE) prog: $(PROJECT).cod $(PROG) $(PROJECT).hex clean: $(RM) *.lst *.cod $(PROJECT)*.gz *~ gpsim-0.30.0/examples/projects/p16f628_test/README0000664000076400007640000000017613041763643016261 00000000000000Sample project. This project illustrates the p16f628. Assemble the .cod file: $ make Simulate the program: $ make sim gpsim-0.30.0/examples/modules/0000775000076400007640000000000013117465765013231 500000000000000gpsim-0.30.0/examples/modules/Makefile.in0000664000076400007640000003244513117441635015214 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = examples/modules ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ mod_test/mod_test.asm mod_test/mod_test.stc mod_test/Makefile mod_test/README \ led_test/led_mod.asm led_test/led_mod.stc led_test/Makefile led_test/README \ usart_test/16f877.lkr usart_test/Makefile usart_test/README \ usart_test/usart_test.asm usart_test/usart_test.stc \ usart_gui/Makefile usart_gui/README usart_gui/usart_gui.asm \ usart_gui/usart_gui.stc \ logic_test/logic_mod.asm logic_test/logic_mod.stc \ logic_test/Makefile logic_test/README \ paraface_test/partest.stc paraface_test/Makefile \ paraface_test/partest.asm MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/modules/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/modules/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/examples/modules/Makefile.am0000664000076400007640000000131513041763642015174 00000000000000EXTRA_DIST = \ mod_test/mod_test.asm mod_test/mod_test.stc mod_test/Makefile mod_test/README \ led_test/led_mod.asm led_test/led_mod.stc led_test/Makefile led_test/README \ usart_test/16f877.lkr usart_test/Makefile usart_test/README \ usart_test/usart_test.asm usart_test/usart_test.stc \ usart_gui/Makefile usart_gui/README usart_gui/usart_gui.asm \ usart_gui/usart_gui.stc \ logic_test/logic_mod.asm logic_test/logic_mod.stc \ logic_test/Makefile logic_test/README \ paraface_test/partest.stc paraface_test/Makefile \ paraface_test/partest.asm MOSTLYCLEANFILES = *.hex *.cod *.lst *~ CLEANFILES = *.hex *.cod *.lst *~ DISTCLEANFILES = *.hex *.cod *.lst *~ MAINTAINERCLEANFILES = *.hex *.cod *.lst *~ gpsim-0.30.0/examples/modules/mod_test/0000775000076400007640000000000013117465765015047 500000000000000gpsim-0.30.0/examples/modules/mod_test/mod_test.stc0000664000076400007640000000177613041763643017323 00000000000000# Script for testing modules # # The purpose of this script is to load a simple # program for a PIC (16F84), load the gpsim module library, # and illustrate how modules can be connected to pics. load s mod_test.cod # load the gpsim module library. Not that this is a 'shared library'. # If the library fails to load then 1) it's not installed (try installing # gpsim) 2) or the path to library is not available (see the documentation # on modules). module library libgpsim_modules.so # display all of the modules that are in the library: # module list # load a specific module from the module library and give it a name # In this case we're loading two pull up resistors and two pull downs # (notice the alias of pu for pullup) module load pullup R1 module load pu R2 module load pulldown R3 module load pd R4 # create nodes that can connect the Pic and the resistors node n1 node n2 node n3 node n4 attach n1 portb0 R1.pin attach n2 portb1 R2.pin attach n3 portb2 R3.pin attach n4 portb3 R4.pin gpsim-0.30.0/examples/modules/mod_test/Makefile0000664000076400007640000000125513041763643016422 00000000000000# Module example # # # system programs RM = /bin/rm -f ARC = tar -cvf ZIP = gzip # gpasm programs ASM = gpasm DIASM = gpdasm CODVIEWER = gpvc -d # simulator GPSIM = gpsim # project data PROJECT = mod_test VERSION = 0.0.1 HEADER = /usr/local/share/gpasm/header # derived variables ARCHIVE = $(PROJECT)-$(VERSION).tar all: $(PROJECT).cod sim: $(PROJECT).cod $(GPSIM) -c $(PROJECT).stc $(PROJECT).cod: $(PROJECT).asm $(ASM) -I $(HEADER) $(PROJECT).asm $(ARCHIVE): $(ARC) $(ARCHIVE) * archive: $(ARCHIVE) $(ZIP) $(ARCHIVE) clean: $(RM) *.hex *.lst *.cod $(PROJECT)*.gz *~ gpsim-0.30.0/examples/modules/mod_test/README0000664000076400007640000000054513041763643015643 00000000000000mod_test The mod_test is a very simple example of PIC code interfacing with gpsim modules. The modules illustrated are pullup and pulldown resistors. Two of each are instantiated and connected to the lower nibble of portb. The PIC program is a simple loop that writes values out to port B. RUNNING The example is run by: $ gpsim -c mod_test.stc gpsim-0.30.0/examples/modules/mod_test/mod_test.asm0000664000076400007640000000073113041763643017300 00000000000000 list p=16c84 ;; ;; mod_test.asm - a simple program to test gpsim's ability to interface ;; to modules ;; include "p16c84.inc" cblock 0x0c pb_shadow temp endc org 0 begin ;; Make all of portb I/O pins inputs movlw 0xff bsf STATUS,RP0 movwf TRISB^0x80 bcf STATUS,RP0 movf PORTB,w movwf pb_shadow bsf STATUS,RP0 clrf TRISB^0x80 bcf STATUS,RP0 bsf temp,4 l1: incf PORTB,f decfsz temp,f goto l1 clrf PORTB goto begin endgpsim-0.30.0/examples/modules/paraface_test/0000775000076400007640000000000013117465765016032 500000000000000gpsim-0.30.0/examples/modules/paraface_test/partest.stc0000664000076400007640000000254013041763642020137 00000000000000# Script for testing modules # # The purpose of this script is to load a simple # program for a PIC (16F84), load the gpsim module library, # and illustrate how modules can be connected to pics. load s partest.cod # load the gpsim module library. Not that this is a 'shared library'. # If the library fails to load then 1) it's not installed (try installing # gpsim) 2) or the path to library is not available (see the documentation # on modules). module library libgpsim_modules.so # display all of the modules that are in the library: # module list # load a specific module from the module library and give it a name module load parallel_interface paraface # create nodes for the output (data lines) and input (status lines) node paro0 node paro1 node paro2 node paro3 node paro4 node paro5 node paro6 node paro7 node pari0 node pari1 node pari2 node pari3 node pari4 # use portb as output lines attach paro0 portb0 paraface.out0 attach paro1 portb1 paraface.out1 attach paro2 portb2 paraface.out2 attach paro3 portb3 paraface.out3 attach paro4 portb4 paraface.out4 attach paro5 portb5 paraface.out5 attach paro6 portb6 paraface.out6 attach paro7 portb7 paraface.out7 # use porta as input lines attach pari0 porta0 paraface.in0 attach pari1 porta1 paraface.in1 attach pari2 porta2 paraface.in2 attach pari3 porta3 paraface.in3 attach pari4 porta4 paraface.in4 gpsim-0.30.0/examples/modules/paraface_test/Makefile0000664000076400007640000000075013041763642017403 00000000000000# USART module regression test # # PROJECT = partest OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).hex COD = $(PROJECT).cod GPSIM = gpsim STC = $(PROJECT).stc STARTUP_STC=partest.stc all : $(OUTPUT) $(OUTPUT) : $(OBJECTS) $(SCRIPT) gplink --map -o $(OUTPUT) $(OBJECTS) $(COD) : $(OBJECTS) $(SCRIPT) gplink --map -o $(OUTPUT) $(OBJECTS) %.o : %.asm gpasm -c $< clean: rm -f *~ *.o *.lst *.map *.hex *.cod $(PROJECT).o : $(PROJECT).asm sim: $(COD) $(GPSIM) -c $(STARTUP_STC) gpsim-0.30.0/examples/modules/paraface_test/partest.asm0000664000076400007640000000052213041763642020124 00000000000000 list p=16c84 __config _WDT_OFF & _RC_OSC include "p16c84.inc" org 0 goto start org 4 start bsf STATUS,RP0 clrf PORTB bcf STATUS,RP0 ; Every write to PORTB updates the parallel port data ; When the parallel port STATUS lines change, the ; change will be seen on porta begin incf PORTB,f goto begin end gpsim-0.30.0/examples/modules/usart_gui/0000775000076400007640000000000013117465765015233 500000000000000gpsim-0.30.0/examples/modules/usart_gui/usart_gui.stc0000664000076400007640000000253513041763642017664 00000000000000# # Startup commands for testing a p16f628 usart # # uncomment for debugging gpsim # set verbose 3 # Source code: load s usart_gui.cod # Set the Clock frequency to 4 Mhz. frequency 4000000 module library libgpsim_modules # load the usart module from the module library and give it a name module load usart U1 # Stimuli: # Tie rx and tx together to create a loop back. # This will cause whatever is transmitted to be received... #node loop_back #attach loop_back portc6 portc7 node PIC_tx node PIC_rx # usart pin out: # 1 - Tx - Transmit # 2 - Rx - Receive # 3 - CTS - Clear To Send # 4 - RTS - Request To Send # Let the usart receiver monitor the data flow. attach PIC_tx portb2 U1.RXPIN attach PIC_rx portb1 U1.TXPIN # set the usart module's baud rate U1.txbaud=9600 U1.rxbaud=9600 gpsim-0.30.0/examples/modules/usart_gui/Makefile0000664000076400007640000000034413041763642016603 00000000000000PROJECT = usart_gui OBJECTS = $(PROJECT).o OUTPUT = $(PROJECT).cod STC = $(PROJECT).stc SRC = $(PROJECT).asm GPSIM = gpsim all : $(OUTPUT) $(OUTPUT) : $(SRC) gpasm -w1 $(SRC) clean: rm -f *~ *.o *.lst *.map *.hex *.cod gpsim-0.30.0/examples/modules/usart_gui/usart_gui.asm0000664000076400007640000001201113041763642017641 00000000000000 ;; The purpose of this program is to test gpsim's ability to simulate ;; USART in the 14bit core. list p=16f628 __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC & _PWRTE_ON & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF include "p16f628.inc" #define RX_BUF_SIZE 0x10 #define ECHO 7 #define CTL_A 6 cblock 0x20 rx_buffer : RX_BUF_SIZE ; must start at 0xn0 line_buffer : RX_BUF_SIZE ; must start at 0xn0 temp1 temp2 temp3 status_temp fsr_temp line_ptr rx_ptr cmd_mode line_first ; first character in line buffer line_last ; last character in line buffer rx_first ; first character to rx rx_last ; last character to rx endc cblock 0x70 w_temp ; avalable at any bank endc org 0 goto start org 4 ;; Interrupt ;; movwf w_temp ; save W swapf STATUS,w bcf STATUS,RP0 movwf status_temp ; save STATUS btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; movf FSR,w movwf fsr_temp call rx_put movf fsr_temp,w movwf FSR int_done: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie GREET dt "If you can see this then USART module can receive data\n" dt "Focus on this window and type on keyboard. If charaters " dt "appear in window, USART module can send and reciever.\n", 0 send_greet movlw GREET movwf line_ptr goto prompt_loop ;; ---------------------------------------------------- ;; ;; start ;; start clrf STATUS call rx_init clrf cmd_mode ; initialize command mode clrf PORTA clrf PORTB movlw 0x07 ; turn off comparitor movwf CMCON ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; bsf STATUS,RP0 movlw (1< include __CONFIG _WDT_OFF errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x20 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 fsr_temp RES 1 INT_VAR1 UDATA 0xA0 w_temp1 RES 1 ;Alias for w_temp at address 0x20 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 temp3 RES 1 tx_ptr RES 1 rx_ptr RES 1 rx_buffer RES RX_BUF_SIZE ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,w clrf STATUS movwf status_temp movf PCLATH,w movwf pclath_temp clrf PCLATH bcf STATUS,RP0 btfsc INTCON,PEIE btfss PIR1,RCIF goto int_done ;;; movf FSR,w movwf fsr_temp incf rx_ptr,w andlw 0x0f movwf rx_ptr addlw rx_buffer movwf FSR movf RCREG,w movwf INDF movf fsr_temp,w movwf FSR int_done: clrf STATUS movf pclath_temp,w movwf PCLATH swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=20e6" .sim "module library libgpsim_modules" .sim "module load usart U1" ; .sim "U1.xpos = 250.0" ; .sim "U1.ypos = 80.0" .sim "node PIC_tx" .sim "node PIC_rx" ;; Tie the USART module to the PIC .sim "attach PIC_tx portc6 U1.RXPIN" .sim "attach PIC_rx portc7 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 9600" .sim "U1.rxbaud = 9600" .sim "U1.xpos = 216.0" .sim "U1.ypos = 48.0" ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf STATUS bsf PORTC,6 ;Make sure the TX line drives high when ;it is programmed as an output. bsf STATUS,RP0 bsf TRISC,7 ;RX is an input bcf TRISC,6 ;TX is an output ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 0.25.0-1 - Add LGPLv2+ license, do not include *.a files * Sun Mar 01 2009 Roy Rankin 0.23.0-1 - Convert doc files to UTF8 character set, version 0.23.0 * Thu Sep 27 2007 Alain Portal 0.22.0-5 - Add BR popt-devel * Tue Aug 21 2007 Alain Portal 0.22.0-4 - Licence tag clarification * Tue Feb 13 2007 Alain Portal 0.22.0-3 - Remove Makefiles that are in conflict between i386 and x86_64 arch Fix #228362 * Mon Feb 5 2007 Alain Portal 0.22.0-2 - FE7 rebuild * Tue Nov 14 2006 Alain Portal 0.22.0-1 - New upstream version - Remove patches that are no more needed (applied by upstream) * Thu Oct 05 2006 Christian Iseli 0.21.11-9 - rebuilt for unwind info generation, broken in gcc-4.1.1-21 * Sat Sep 23 2006 Alain Portal 0.21.11-8 - Add patch to fix a ktechlab crash, a ktechlab upstream contribution See http://ktechlab.org/download/gpsim.php - Use macros for rm and make - Use macro style instead of variable style * Fri Sep 1 2006 Alain Portal 0.21.11-7 - FE6 rebuild * Wed Mar 15 2006 Alain Portal 0.21.11-6 - Update Patch * Wed Mar 15 2006 Alain Portal 0.21.11-5 - Update Patch * Tue Mar 14 2006 Alain Portal 0.21.11-4 - Patch to make gcc-4.1.0 happy * Mon Mar 13 2006 Alain Portal 0.21.11-3 - Rebuild for FE5 * Thu Oct 6 2005 Alain Portal 0.21.11-2 - Remove useless Requires * Wed Oct 5 2005 Alain Portal 0.21.11-1 - New version - Improve download url * Fri Sep 30 2005 Alain Portal 0.21.4-5 - Improve prep section to make rpmlint happy - Contributions of Jose Pedro Oliveira Thanks to him. * Mon Sep 19 2005 Alain Portal 0.21.4-4 - Add missing a rm -rf RPM_BUILD_ROOT statement in the install section * Thu Sep 15 2005 Alain Portal 0.21.4-3 - Exclude .la file - Add examples * Tue Sep 13 2005 Alain Portal 0.21.4-2 - License is GPL - Add french summary and description * Mon Sep 12 2005 Alain Portal 0.21.4-1 - New version * Mon Nov 8 2004 Alain Portal 0:0.21.2-0.fdr.2 - Add BuildRequires flex, readline-devel * Wed Oct 27 2004 Alain Portal 0:0.21.2-0.fdr.1 - Initial Fedora RPM gpsim-0.30.0/HISTORY0000664000076400007640000001730613041763624010745 00000000000000gpsim - Gnu Pic Simulator, a simulator for Microchip's PIC microcontrollers. T. Scott Dattalo See the ChangeLog for changes since 0.20.0 28JUL00 gpsim-0.20.0 o Modules - gpsim now supports dynamically loaded modules -- module command o gui - upgraded to latest versions of gtk & gtkextra o gui - Menu items now work o gui - button bar o gui - now refreshes while simulating o gui - Stack Window has been added o BSD is now supported o numerous bug fixes 05APR00 gpsim-0.19.0 o Daniel Schudel joins gpsim development. -- Added support for the 16x5x family o Added 16f87x family o gui - Added Program Memory sheet -- Added support for program memory writes o gui - Added Breadboard window (graphical pinout) o Asynchronous mode of the usart fixed. o A/D converter enhanced o Analog Stimuli revisited. o Scripting was fixed. o cli - Once again, gpsim can be built without the gui. 03FEB00 gpsim-0.18.0 o cli - added 'processor pins' command to display the state of a pic's I/O pins o cli - added 'set' command for modifying gpsim behavior flags. set options supported: -- verbose - if set, diagnostic info will be displayed -- radix - not supported yet -- gui_update - controls the rate at which the gui is refreshed o cli - added 's' option to the dump command to display only the special function registers (and not the rest of ram). o 18cxxx: -- TBLRD & TBLWT instructions are now supported -- MULLW & MULWF instructions are now supported -- configuration word support -- tmr0 interrupt o Cycle counter - 64 bits is now fully supported o config word bug fixed o gui - added Watch window o gui - added more color coding to register window o gui - removed stagnant menu selections o gui - window state is saved between gpsim sessions -- This requires a new package `eXdbm'. o getopt is now used to process invocation options (now you can have spaces between the options and file names). o support >64k object code in .cod files o gtksheet has been removed from the distribution -- This means that you'll have to install gtk+-extra, the package that supports gtk-sheet (see INSTALL) o .cod file format bug fixes (you'll need the latest gpasm) o __config word for 18cxxx family is now supported 16NOV99 gpsim-0.17.0 o gui - Major overhaul of Register Window o gui - Symbol window added o 18Cxxx -- Interrupts are now supported -- TMR0 is implemented -- USART asynchronous mode is supported o automake is now used to create the makefiles o version numbering has changed so that 'minor releases' (which by definition are the only ones I've made) are now expressed in the middle revision instead of the last revision number. o numerous bug fixes o Cycle counter is now 64 bits. gpsim-0.0.16 o 18Cxxx core has been added o Ralf Forsberg has joined me in development. His major contributions have been in the gui code. Some of what he's done: - Wrote a new source browser with these features: -- Syntax highlighting (e.g. opcodes and comments are colored differently) -- Iconic indicators (e.g. bitmaps indicating breaks, current pc...) -- Multiple sources - Significant restructuring of the gpsim to gui interface 28JUL99 gpsim-0.0.15 o gui - asm source browser o gui - program memory browser o gui - register viewer enhancements o gui - control menu o numerous bug fixes 30JUN99 gpsim-0.0.14 o gui o numerous bug fixes 25APR99 gpsim-0.0.13 o Split the command line interface from simulator - created a `src' directory for the simulator - created a `cli' directory for the command line interface o Re-wrote the cli to use bison and flex (whew - whatabitch) o Hi-Tech C-compiler .cod files can be loaded by gpsim now. o Fixed C++ errors that egcs abhored but gcc ignored. 08MAR99 gpsim-0.0.12 o Added support for .cod files (mostly in cod.cc) o Added more symbolic debugging features o Added 'list' command for listing source files o Updated the 'load' command for loading .cod files o Repeat last command with carriage return o Added more documentation 10JAN99 gpsim-0.0.11 o Added support for the PIC16C74 o Fixed core dumps associated with the 12C50x (again, dammit) o Fundamentally changed the way registers are created. o Added a 'config' script 20DEC98 gpsim-0.0.10 o Added support for the PIC16C71 o Enhanced the asynchronous stimulus to support analog values o Added a triangle_wave stimulus (mainly for testing) o Changed the behavior of 'run' to ignore a breakpoint if there is one set at the current instruction (see below) o Added a few examples illustrating the use of analog stimuli 07DEC98 gpsim-0.0.9 o Added support for the 12c508 and 12c509 o Bug Fixes: - DC bit wasn't updated correctly in add's and sub's (if W was the destination) - stack was rolling over after 7 pushes - goto's and call's were limited to 10 bits o Added the command line option '-v' and the command version. Both echo gpsim's version. o Enhanced 'it.asm' and added 'it_12bit.asm' - two routines that exercise gpsim's ability to simulate the pic instructions. o Added a trace for skipped instructions (before you'd see skipped instructions the same as non skipped ones in the trace buffer). 16NOV98 gpsim-0.0.8 o Fixed pcl related bugs (see the new pcl_test.asm for examples) o Implemented the TMR2 peripheral o Implemented the CCP1 and CCP2 peripherals o Implemented the TMR1 peripheral o added more support for the PIC16C64 o began support for the PIC16C65 o fixed the configuration word loading that got broke in the last release 21OCT98 gpsim-0.0.7 o added new command 'processor' o added new command 'load' - Startup command files can now be loaded any time and can be nested. o added new command 'symbol' o added new command 'reset' o redesigned the pic processor base class o added new file p16x8x o added support for the PIC16CR83, PIC16CR84, PIC16F83, PIC16F84 o added new file p16x6x o added support for the PIC16C61 o began support for the PIC16C64 o Changed the command line invocation: -p now selects a processor and not a core (e.g. -p14 used to be the way gp sim liked to select a device within the midrange, 14-bit family; now you must specify the specific device you wish to simulate: -pp16c61 .) o Generally overhauled everything in anticipation of supporting the 12-bit core 30SEP98 gpsim-0.0.6 o now can asynchronously halt the execution. o Multiplexed I/O pins are now supported (better). It's possible to clock TMR0 from an external clock now o The c84 is now fully supported - though not thoroughly debugged o I fixed two nasty cycle breakpoint bugs, single-stepping during a pending interrupt, and a couple of other minor annoyances. o I've begun formal documentation, but it is not included with this release. 18SEP98 gpsim-0.0.5 o added new command 'node' o added new command 'attach' o redesigned the stimulus infrastructure. o added 'name' option to stimuli o iopins are now considered stimuli 04SEP98 gpsim-0.0.4 o added new command 'stimulus' o added new command 'echo' o redesigned the breakpoint mechanism for register breaks o added support for startup configuration files o began support for stimulus files o began support for symbols o interrupts are working 28AUG98 gpsim-0.0.3 o added support for interrupts o TMR0 and WDT are now working o added new command 'x' for examining/modifying registers o added a 'break wdt' - break on wdt timeout o now you can step over a breakpoint 17AUG98 gpsim-0.0.2 o added readline library and made the command line interface more robust o eeprom is now working 30JUL98 gpsim-0.0.1 o initial release - basic stuff gpsim-0.30.0/gui/0000775000076400007640000000000013117465764010526 500000000000000gpsim-0.30.0/gui/gui_symbols.h0000664000076400007640000000375113045306453013146 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_SYMBOLS_H__ #define __GUI_SYMBOLS_H__ #include "gui_object.h" class GUI_Processor; // // The symbol window // class Symbol_Window : public GUI_Object { public: GtkWidget *symbol_view; GtkListStore *symbol_list; GtkWidget *popup_menu; int filter_addresses; int filter_constants; int filter_registers; GtkWidget *addressesbutton; GtkWidget *constantsbutton; GtkWidget *registersbutton; int load_symbols; explicit Symbol_Window(GUI_Processor *gp); virtual void Build(); virtual void Update(); void NewSymbols(); protected: virtual const char *name(); // Signals static void toggle_addresses (GtkToggleButton *button, Symbol_Window *sw); static void toggle_constants (GtkToggleButton *button, Symbol_Window *sw); static void toggle_registers (GtkToggleButton *button, Symbol_Window *sw); static gboolean do_popup(GtkWidget *widget, GdkEventButton *event, Symbol_Window *sw); static void symbol_list_row_selected(GtkTreeSelection *treeselection, gpointer user_data); static gboolean delete_event(GtkWidget *widget, GdkEvent *event, Symbol_Window *sw); GtkWidget *build_menu(GtkWidget *sheet); void do_symbol_select(Value *e); }; #endif // __GUI_SYMBOLS_H__ gpsim-0.30.0/gui/gui_statusbar.cc0000664000076400007640000001175113041763637013632 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include "gui.h" #include "gui_statusbar.h" #include "../src/processor.h" #include #include #include //======================================================================== class StatusBarXREF : public CrossReferenceToGUI { public: void Update(int new_value) { StatusBar_Window *sbw; sbw = static_cast(parent_window); sbw->Update(); } }; //------------------------------------------------------------------------ static void LabeledEntry_callback(GtkWidget *entry, LabeledEntry *le) { const char *text; unsigned long value; char *bad_position; if(!gpGuiProcessor || !gpGuiProcessor->cpu || !le || !le->entry) return; text=gtk_entry_get_text (GTK_ENTRY (le->entry)); value = strtoul(text, &bad_position, 16); if (*bad_position != '\0') return; /* string contains an invalid number */ le->put_value(value); } //======================================================================== EntryWidget::EntryWidget() { entry = gtk_entry_new(); gtk_widget_show(entry); } EntryWidget::~EntryWidget() { } void EntryWidget::SetEntryWidth(int string_width) { gtk_entry_set_width_chars(GTK_ENTRY(entry), string_width); } void EntryWidget::set_editable(bool Editable) { gtk_editable_set_editable(GTK_EDITABLE(entry), Editable ? TRUE : FALSE); } //======================================================================== LabeledEntry::LabeledEntry(GtkWidget *box, const char *clabel) { label = gtk_label_new(clabel); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); } void LabeledEntry::Update() { } void LabeledEntry::put_value(unsigned int new_value) { } //------------------------------------------------------------------------ RegisterLabeledEntry::RegisterLabeledEntry(GtkWidget *box, Register *new_reg, bool isEditable=false) : LabeledEntry(box, new_reg->name().c_str()), reg(new_reg) { g_snprintf(pCellFormat, sizeof(pCellFormat), "0x%%0%dx",reg->register_size()*2); SetEntryWidth(2 + reg->register_size() * 2); Update(); set_editable(isEditable); g_signal_connect(entry, "activate", G_CALLBACK(LabeledEntry_callback), this); } RegisterLabeledEntry::~RegisterLabeledEntry() { } void RegisterLabeledEntry::put_value(unsigned int new_value) { reg->put_value(new_value); } void RegisterLabeledEntry::Update() { char buffer[32]; unsigned int value = reg->get_value(); g_snprintf(buffer, sizeof(buffer), pCellFormat, value); gtk_entry_set_text(GTK_ENTRY(entry), buffer); } //------------------------------------------------------------------------ void StatusBar_Window::Update() { //update the displayed values if(!gp || !gp->cpu) return; std::vector::iterator iRLE; for(iRLE = entries.begin(); iRLE != entries.end(); ++iRLE) (*iRLE)->Update(); } /* NewProcessor * */ void StatusBar_Window::NewProcessor(GUI_Processor *_gp, MemoryAccess *_ma) { if(!_gp || !_gp->cpu || !_ma) return; if(ma) return; gp = _gp; ma = _ma; Dprintf((" %s\n",__FUNCTION__)); list::iterator iReg; for(iReg = ma->SpecialRegisters.begin(); iReg != ma->SpecialRegisters.end(); ++iReg) entries.push_back(new RegisterLabeledEntry(hbox, *iReg)); /* Now create a cross-reference link that the simulator can use to * send information back to the gui */ ProgramMemoryAccess* pPMA; pPMA = dynamic_cast(ma); if(gp->cpu && gp->cpu->pc) { Program_Counter *pPC = pPMA == NULL ? gp->cpu->pc : pPMA->GetProgramCounter(); StatusBarXREF *cross_reference; cross_reference = new StatusBarXREF(); cross_reference->parent_window = (gpointer) this; cross_reference->data = (gpsimObject *) this; pPC->add_xref((gpointer) cross_reference); } Update(); } StatusBar_Window::StatusBar_Window(GtkWidget *vbox_main) : gp(0), ma(0) { /* --- Create h-box for holding the status line --- */ hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_end(GTK_BOX(vbox_main), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_src_opcode.cc0000664000076400007640000006744713041763637013757 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg Copyright (C) 2011 Roy R Rankin This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include "gui.h" #include "gui_src.h" #include "preferences.h" #include "../xpms/break.xpm" #include "../xpms/pc.xpm" #include #include #include #include #include #define OPCODES_PER_ROW 16 // // Notes: // Changing the opcodes for a program dose not make sense for a high level // language like C, JAL or even assembly source. Would be OK for a .HEX file. // Doing this crashes within src/processor.cc so has been removed for now. // Will reintroduce when both problems can be solved, as it can be usefull // for some PICs which can write to their own program memory. // // Removed Add Watch as this is not implemented // Removed "Set break on read" and "Set break on write" popup options/ // They are marked as not implemented and do not do the expected thing. // // Removed the different ASCII views. Missing out data is wrong and flipping // data around is confusing. // TODO: Fix the above. // TODO: Use the systems (users theme) mono-space font? or one global setting enum { ADDRESS_COLUMN, // Address - integer OPCODE_COLUMN, // Opcode - integer MNEMONIC_COLUMN, // Mnemonic - string PC_PIX_COLUMN, // PC marker - pixbuf BREAK_PIX_COLUMN, // Break point - pixbuf NUM_COLUMNS }; typedef enum { MENU_BREAK_CLEAR, MENU_BREAK_EXECUTE, MENU_ASM_BREAK_CLEAR, MENU_ASM_BREAK_EXECUTE, MENU_SETTINGS, } menu_id; typedef struct _menu_item { const char *name; const menu_id id; } menu_item; static const menu_item sheet_menu_items[] = { {"Set break points", MENU_BREAK_EXECUTE}, {"Clear break points", MENU_BREAK_CLEAR}, {"Settings...",MENU_SETTINGS} }; static menu_item const list_menu_items[] = { {"Set break points", MENU_ASM_BREAK_EXECUTE}, {"Clear break points", MENU_ASM_BREAK_CLEAR}, {"Settings...",MENU_SETTINGS} }; //======================================================================== class SourceOpcodeXREF : public CrossReferenceToGUI { public: void Update(int new_value) { SourceBrowserOpcode_Window *sbow; sbow = static_cast(parent_window); sbow->SetPC(new_value); } void Remove() { } }; //======================================================================== // update ascii column in sheet void SourceBrowserOpcode_Window::update_ascii(gint row) { gchar name[45]; unsigned char byte; int i; for (i = 0; i < 32; i++) { if (i % 2) byte = memory[row * 16 + i / 2] & 0xff; else byte = (memory[row * 16 + i / 2] & 0xff00) >> 8; if (g_ascii_isprint(byte)) name[i] = byte; else name[i] = '.'; } name[i] = '\0'; gtk_sheet_set_cell(GTK_SHEET(sheet), row, OPCODES_PER_ROW, GTK_JUSTIFY_RIGHT, name); } // called when user has selected a menu item void SourceBrowserOpcode_Window::popup_activated(GtkWidget *widget, SourceBrowserOpcode_Window *sbow) { GtkTreeSelection *sel; GtkTreeModel *model; GtkTreeIter iter; int i,j; if(!sbow->gp || !sbow->gp->cpu) { return; } GtkSheet *sheet = GTK_SHEET(sbow->sheet); GtkSheetRange range = sheet->range; gsize data = GPOINTER_TO_SIZE(g_object_get_data(G_OBJECT(widget), "item")); switch(data) { case MENU_BREAK_EXECUTE: for(j=range.row0;j<=range.rowi;j++) for(i=range.col0;i<=range.coli;i++) { unsigned address = sbow->gp->cpu->map_pm_index2address(j*16+i); if (!sbow->gp->cpu->pma->address_has_break(address)) sbow->gp->cpu->pma->set_break_at_address(address); } break; case MENU_BREAK_CLEAR: for(j=range.row0;j<=range.rowi;j++) for(i=range.col0;i<=range.coli;i++) { unsigned address = sbow->gp->cpu->map_pm_index2address(j*16+i); sbow->gp->cpu->pma->clear_break_at_address(address, instruction::BREAKPOINT_INSTRUCTION); } break; case MENU_ASM_BREAK_CLEAR: sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(sbow->tree)); if (gtk_tree_selection_get_selected(sel, &model, &iter)) { gint break_row; gtk_tree_model_get(model, &iter, gint(ADDRESS_COLUMN), &break_row, -1); unsigned address = sbow->gp->cpu->map_pm_index2address(break_row); sbow->gp->cpu->pma->clear_break_at_address(address, instruction::BREAKPOINT_INSTRUCTION); } break; case MENU_ASM_BREAK_EXECUTE: sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(sbow->tree)); if (gtk_tree_selection_get_selected(sel, &model, &iter)) { gint break_row; gtk_tree_model_get(model, &iter, gint(ADDRESS_COLUMN), &break_row, -1); unsigned address = sbow->gp->cpu->map_pm_index2address(break_row); if (!sbow->gp->cpu->pma->address_has_break(address)) sbow->gp->cpu->pma->set_break_at_address(address); } break; case MENU_SETTINGS: sbow->settings_dialog(); break; default: break; } } GtkWidget * SourceBrowserOpcode_Window::build_menu_for_sheet() { GtkWidget *menu = gtk_menu_new(); for (gsize i = 0; i < G_N_ELEMENTS(sheet_menu_items); i++) { GtkWidget *item = gtk_menu_item_new_with_label(sheet_menu_items[i].name); g_signal_connect(item,"activate", G_CALLBACK (popup_activated), this); g_object_set_data(G_OBJECT(item), "item", GSIZE_TO_POINTER(sheet_menu_items[i].id)); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),item); } return menu; } GtkWidget * SourceBrowserOpcode_Window::build_menu_for_list() { GtkWidget *menu = gtk_menu_new(); for (gsize i = 0; i < G_N_ELEMENTS(list_menu_items); i++) { GtkWidget *item = gtk_menu_item_new_with_label(list_menu_items[i].name); g_signal_connect (item, "activate", G_CALLBACK (popup_activated), this); g_object_set_data(G_OBJECT(item), "item", GSIZE_TO_POINTER(list_menu_items[i].id)); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),item); } return menu; } void SourceBrowserOpcode_Window::do_popup_menu(GtkWidget *widget, GdkEventButton *event) { int button, event_time; if (event) { button = event->button; event_time = event->time; } else { button = 0; event_time = gtk_get_current_event_time(); } if (GTK_IS_TREE_VIEW(GTK_OBJECT(widget))) { gtk_menu_popup(GTK_MENU(list_popup_menu), 0, 0, 0, 0, button, event_time); } else { gtk_menu_popup(GTK_MENU(sheet_popup_menu), 0, 0, 0, 0, button, event_time); } } // button press signal handler (static) gint SourceBrowserOpcode_Window::button_press(GtkWidget *widget, GdkEventButton *event, SourceBrowserOpcode_Window *sbow) { if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { sbow->do_popup_menu(widget, event); return TRUE; } return FALSE; } // Popup menu keyboard signal handler (static) gboolean SourceBrowserOpcode_Window::popup_menu_handler(GtkWidget *widget, SourceBrowserOpcode_Window *sbw) { sbw->do_popup_menu(widget, NULL); return TRUE; } // Row selection handle (static) void SourceBrowserOpcode_Window::row_selected(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, SourceBrowserOpcode_Window *sbow) { GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(tree_view); if (gtk_tree_model_get_iter(model, &iter, path)) { gint break_row; gtk_tree_model_get(model, &iter, gint(ADDRESS_COLUMN), &break_row, -1); unsigned address = sbow->gp->cpu->map_pm_index2address(break_row); sbow->gp->cpu->pma->toggle_break_at_address(address); } } static void filter(std::string &clean, const char *dirty) { if (!dirty) return; for (int i = 0 ; *dirty; ++dirty, ++i) { if (*dirty == '\t') { for (int j = 0; j < 8 && i % 8; ++j, ++i) clean += ' '; } else if (g_ascii_isprint(*dirty)) { clean += *dirty; } } } void SourceBrowserOpcode_Window::update_styles(int address) { GtkSheetRange range; int index = address; if (gp->cpu) index = gp->cpu->map_pm_address2index(address); int row = index/16; int column = index%16; range.row0=row; range.rowi=row; range.col0=column; range.coli=column; if(!gp->cpu) { gtk_sheet_range_set_background(GTK_SHEET(sheet), &range, gColors.normal_bg()); return; } GtkTreeIter iter; GdkPixbuf *pix = NULL; if (gp->cpu && gp->cpu->pma->address_has_break(address)) { pix = break_pix; gtk_sheet_range_set_background(GTK_SHEET(sheet), &range, gColors.breakpoint()); } else { if(gp->cpu->pma->isModified(address)) gtk_sheet_range_set_background(GTK_SHEET(sheet), &range, gColors.sfr_bg()); else gtk_sheet_range_set_background(GTK_SHEET(sheet), &range, gColors.normal_bg()); } if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list), &iter, NULL, index)) { gtk_list_store_set(list, &iter, gint(BREAK_PIX_COLUMN), pix, -1); } } void SourceBrowserOpcode_Window::update_label(int address) { std::string labeltext; char entrytext[128]; GtkEntry *sheet_entry; if (!gp || !gp->cpu) return; if(address<0) { entrytext[0] = '\0'; labeltext = "ASCII"; } else { unsigned int oc = gp->cpu->pma->get_opcode(address); filter(labeltext, gp->cpu->pma->get_opcode_name(address,entrytext,sizeof(entrytext))); g_snprintf(entrytext, sizeof(entrytext), "0x%04X", oc); } sheet_entry = GTK_ENTRY(gtk_sheet_get_entry(GTK_SHEET(sheet))); gtk_label_set_text(GTK_LABEL(label), labeltext.c_str()); gtk_entry_set_max_length(GTK_ENTRY(entry), gtk_entry_buffer_get_max_length(gtk_entry_get_buffer(sheet_entry))); gtk_entry_set_text(GTK_ENTRY(entry), entrytext); } void SourceBrowserOpcode_Window::update_values(int address) { if (!gp || !gp->cpu || !memory) return; unsigned uMemoryIndex = gp->cpu->map_pm_address2index(address); int row = uMemoryIndex / 16; int column = uMemoryIndex % 16; unsigned int oc = gp->cpu->pma->get_opcode(address); if (oc != memory[uMemoryIndex]) { memory[address] = oc; // Put new values, in case they changed char oc_buf[128]; std::string mn_buf; char buf[128]; g_snprintf(oc_buf, sizeof(oc_buf), "%04X", oc); filter(mn_buf, gp->cpu->pma->get_opcode_name(address, buf, sizeof(buf))); GtkTreeIter iter; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list), &iter, NULL, address); gtk_list_store_set(list, &iter, OPCODE_COLUMN, oc, MNEMONIC_COLUMN, mn_buf.c_str(), -1); gtk_sheet_set_cell(GTK_SHEET(sheet), row, column, GTK_JUSTIFY_RIGHT, oc_buf); } } void SourceBrowserOpcode_Window::update(int address) { if(!gp->cpu) return; update_values(address); update_styles(address); } void SourceBrowserOpcode_Window::load_styles() { PangoFontDescription *font = pango_font_description_from_string(normalfont_string.c_str()); gtk_widget_modify_font(tree, font); pango_font_description_free(normalPFD); normalPFD = pango_font_description_copy(font); } /********************** Settings dialog ***************************/ void SourceBrowserOpcode_Window::settings_dialog() { GtkWidget *dialog = gtk_dialog_new_with_buttons( "Opcode browser settings", GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL ); GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *table = gtk_table_new(3, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 6); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_add(GTK_CONTAINER(content_area), table); gtk_container_set_border_width(GTK_CONTAINER(table), 18); GtkWidget *label; GtkWidget *normal_font_btn; // Normal font label = gtk_label_new("Normal font"); normal_font_btn = gtk_font_button_new_with_font(normalfont_string.c_str()); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); gtk_table_attach_defaults(GTK_TABLE(table), normal_font_btn, 1, 2, 0, 1); gtk_widget_show_all(dialog); int retval = gtk_dialog_run(GTK_DIALOG(dialog)); if (retval == GTK_RESPONSE_OK) { const char *fontname = gtk_font_button_get_font_name(GTK_FONT_BUTTON(normal_font_btn)); normalfont_string = fontname; config_set_string(name(), "normalfont", fontname); load_styles(); Fill(); } gtk_widget_destroy(dialog); } // // Signal handler // we get here when the entry in a cell is changed (typed a digit), we // copy it to the entry above the sheet. // void SourceBrowserOpcode_Window::show_entry(GtkWidget *widget, SourceBrowserOpcode_Window *sbow) { const char *text; GtkSheet *sheet; GtkWidget * sheet_entry; if(!gtk_widget_has_focus(widget)) return; sheet=GTK_SHEET(sbow->sheet); sheet_entry = gtk_sheet_get_entry(sheet); if((text=gtk_entry_get_text (GTK_ENTRY(sheet_entry)))) gtk_entry_set_text(GTK_ENTRY(sbow->entry), text); } // Signal handler - static // when a cell is activated, we set the label and entry above the sheet // gint SourceBrowserOpcode_Window::activate_sheet_cell(GtkWidget *widget, gint row, gint column, SourceBrowserOpcode_Window *sbow) { GtkSheet *sheet; GtkSheetCellAttr attributes; if (!sbow->gp || ! sbow->gp->cpu) return 0; sheet=GTK_SHEET(sbow->sheet); if(row>sheet->maxrow || row<0|| column>sheet->maxcol || column<0) { printf("Warning activate_sheet_cell(%x,%x)\n",row,column); return 0; } if(column<16) { sbow->update_label(sbow->gp->cpu->map_pm_index2address(row*16+column)); } else sbow->update_label(-1); gtk_sheet_get_attributes(sheet,sheet->active_cell.row, sheet->active_cell.col, &attributes); //gtk_editable_set_editable(GTK_EDITABLE(sbow->entry), attributes.is_editable); gtk_sheet_range_set_justification(sheet, &sheet->range, GTK_JUSTIFY_RIGHT); return TRUE; } void SourceBrowserOpcode_Window::SelectAddress(int address) { if(!enabled) return; unsigned int row = address; if(gp->cpu) row = gp->cpu->map_pm_address2index(address); GtkTreeIter iter; GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_unselect_all(sel); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list), &iter, NULL, row); gtk_tree_selection_select_iter(sel, &iter); GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(list), &iter); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tree), path, NULL, FALSE, 0.5, 0.0); gtk_tree_path_free(path); } void SourceBrowserOpcode_Window::UpdateLine(int address) { if (!enabled) return; if (address >= 0) update(address); } void SourceBrowserOpcode_Window::SetPC(int address) { gint last_address = current_address; if(!enabled) return; current_address = address; if(address != last_address) { UpdateLine(last_address); int index = last_address; if (gp->cpu) index = gp->cpu->map_pm_address2index(last_address); GtkTreeIter iter; if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list), &iter, NULL, index)) { gtk_list_store_set(list, &iter, gint(PC_PIX_COLUMN), NULL, -1); } } UpdateLine(address); int index = address; if(gp->cpu) index = gp->cpu->map_pm_address2index(address); GtkTreeIter iter; if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list), &iter, NULL, index)) { gtk_list_store_set(list, &iter, gint(PC_PIX_COLUMN), pc_pix, -1); GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(list), &iter); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tree), path, NULL, FALSE, 0.5, 0.0); gtk_tree_path_free(path); } GtkSheetRange range; range.row0 = range.rowi = index / 16; range.col0 = range.coli = index % 16; gtk_sheet_range_set_background(GTK_SHEET(sheet), &range, gColors.sfr_bg()); } //======================================================================== // Fill() // // copy the processor's program memory contents to the both the disassembly // and opcode windows. void SourceBrowserOpcode_Window::Fill() { GtkSheetRange range; if(!bIsBuilt) Build(); if(!gp || !gp->cpu) return; char buf[128]; gint i; int pm_size; int pc; gint column_width,char_width; // Clearing list gtk_list_store_clear(list); pm_size = gp->cpu->program_memory_size(); delete[] memory; memory = new unsigned int[pm_size]; gchar name_buf[10]; gtk_sheet_freeze(GTK_SHEET(sheet)); PangoRectangle rect; PangoLayout *layout; layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), "A"); pango_layout_set_font_description (layout, normalPFD); pango_layout_get_extents (layout, NULL, &rect); char_width = PANGO_PIXELS(rect.width); column_width = 4 * char_width + 5; g_object_unref(layout); for(i=0; imaxcol; i++){ g_snprintf(name_buf, sizeof(name_buf), "%02x", gp->cpu->map_pm_index2address(i)); gtk_sheet_column_button_add_label(GTK_SHEET(sheet), i, name_buf); gtk_sheet_set_column_title(GTK_SHEET(sheet), i, name_buf); gtk_sheet_set_column_width (GTK_SHEET(sheet), i, column_width); } for(i=0; i < pm_size; i++) { int address = gp->cpu->map_pm_index2address(i); unsigned int opcode = gp->cpu->pma->get_opcode(address); memory[i]=opcode; char oc_buf[128]; std::string mn_buf; g_snprintf(oc_buf, sizeof(oc_buf), "%04X", opcode); filter(mn_buf, gp->cpu->pma->get_opcode_name(address, buf, sizeof(buf))); if(GTK_SHEET(sheet)->maxrow < i/16) { int j = i/16; gtk_sheet_add_row(GTK_SHEET(sheet),1); g_snprintf(name_buf, sizeof(name_buf), "%04x", gp->cpu->map_pm_index2address(i)); gtk_sheet_row_button_add_label(GTK_SHEET(sheet), j, name_buf); gtk_sheet_set_row_title(GTK_SHEET(sheet), j, name_buf); } gtk_sheet_set_cell(GTK_SHEET(sheet), i/16, i%16, GTK_JUSTIFY_RIGHT, oc_buf); GtkTreeIter iter; gtk_list_store_append(list, &iter); gtk_list_store_set(list, &iter, gint(ADDRESS_COLUMN), address, gint(OPCODE_COLUMN), opcode, gint(MNEMONIC_COLUMN), mn_buf.c_str(), -1); update_styles(address); } for(i=0;imaxrow; range.coli=GTK_SHEET(sheet)->maxcol; gtk_sheet_range_set_font(GTK_SHEET(sheet), &range, normalPFD); gtk_sheet_thaw(GTK_SHEET(sheet)); pc=gp->cpu->pma->get_PC(); SetPC(pc); update_label(pc); } void SourceBrowserOpcode_Window::NewSource(GUI_Processor *_gp) { if(!gp) return; current_address=0; if(!enabled) return; if(!bIsBuilt) Build(); /* Now create a cross-reference link that the * simulator can use to send information back to the gui */ if(gp->cpu && gp->cpu->pc) { SourceOpcodeXREF *cross_reference; cross_reference = new SourceOpcodeXREF(); cross_reference->parent_window = (gpointer) this; cross_reference->data = (gpsimObject *) this; gp->cpu->pc->add_xref((gpointer) cross_reference); } Fill(); } void SourceBrowserOpcode_Window::NewProcessor(GUI_Processor *_gp) { GtkSheetRange range; if(!gp || !gp->cpu) return; current_address=0; if(!enabled) return; if(!bIsBuilt) Build(); pma = gp->cpu->pma; range.row0=0;range.col0=0; range.rowi=GTK_SHEET(sheet)->maxrow; range.coli=GTK_SHEET(sheet)->maxcol; gtk_sheet_range_set_background(GTK_SHEET(sheet), &range, gColors.normal_bg()); range.row0=range.rowi=0; range.col0=range.coli=0; gtk_sheet_select_range(GTK_SHEET(sheet),&range); update_label(0); } void SourceBrowserOpcode_Window::cell_renderer(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { gint addr; gchar buf[64]; gtk_tree_model_get(tree_model, iter, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "col")), &addr, -1); g_snprintf(buf, sizeof(buf), "0x%04x", addr); g_object_set(cell, "text", buf, NULL); } void SourceBrowserOpcode_Window::Build() { if(bIsBuilt) return; GtkWidget *hbox; GtkWidget *scrolled_win; GtkRequisition request; gchar _name[10]; gint column_width,char_width; gint i; if(window!=0) gtk_widget_destroy(window); SourceBrowser_Window::Create(); gtk_window_set_title (GTK_WINDOW (window), "Program memory"); notebook = gtk_notebook_new(); gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); // // create list // scrolled_win = gtk_scrolled_window_new (0, 0); gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 6); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); list = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list)); // TODO: Add selecting multiple lines of code //GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); //gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); GtkCellRenderer *renderer; GtkTreeViewColumn *column; column = gtk_tree_view_column_new(); renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", BREAK_PIX_COLUMN, NULL); renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", PC_PIX_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("address", renderer, "text", ADDRESS_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(gint(ADDRESS_COLUMN))); gtk_tree_view_column_set_cell_data_func(column, renderer, cell_renderer, NULL, NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("opcode", renderer, "text", OPCODE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(gint(OPCODE_COLUMN))); gtk_tree_view_column_set_cell_data_func(column, renderer, cell_renderer, NULL, NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("instruction", renderer, "text", MNEMONIC_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); /**************************** load fonts *********************************/ char *fontstring; GtkStyle *style = gtk_widget_get_default_style(); normalfont_string = pango_font_description_to_string(style->font_desc); if(config_get_string(name(),"normalfont",&fontstring)) normalfont_string = fontstring; load_styles(); gtk_container_add (GTK_CONTAINER (scrolled_win), tree); /* Add a signal handler for button press events. This will capture * commands for setting and/or clearing break points */ g_signal_connect (tree, "button_press_event", G_CALLBACK (button_press), (gpointer) this); g_signal_connect(tree, "popup-menu", G_CALLBACK(popup_menu_handler), this); g_signal_connect(tree, "row-activated", G_CALLBACK(row_selected), gpointer(this)); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_win, gtk_label_new("Assembly")); // // create sheet // vbox=gtk_vbox_new(FALSE,1); // Create entry bar hbox=gtk_hbox_new(FALSE,1); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); label = gtk_label_new(NULL); gtk_widget_modify_font(label, normalPFD); gtk_widget_size_request(label, &request); gtk_widget_set_size_request(label, 160, request.height); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0); entry = gtk_entry_new(); gtk_widget_modify_font(entry, normalPFD); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); // Create sheet scrolled_win=gtk_scrolled_window_new(0, 0); gtk_box_pack_start(GTK_BOX(vbox), scrolled_win, TRUE, TRUE, 0); GtkSheetRange sheet_range = {0, 0, 16, 0}; sheet=gtk_sheet_new(1,17,"where does this string go?"); gtk_sheet_range_set_editable(GTK_SHEET(sheet), &sheet_range, FALSE); gtk_container_add(GTK_CONTAINER(scrolled_win), sheet); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, gtk_label_new("Opcodes")); PangoRectangle rect; PangoLayout *layout; layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), "A"); pango_layout_set_font_description (layout, normalPFD); pango_layout_get_extents (layout, NULL, &rect); char_width = PANGO_PIXELS(rect.width); column_width = 4 * char_width + 5; g_object_unref(layout); for(i=0; imaxcol; i++){ g_snprintf(_name, sizeof(_name), "%02x", i); gtk_sheet_column_button_add_label(GTK_SHEET(sheet), i, _name); gtk_sheet_set_column_title(GTK_SHEET(sheet), i, _name); gtk_sheet_set_column_width (GTK_SHEET(sheet), i, column_width); } const char * ascii_name = "ASCII"; gtk_sheet_column_button_add_label(GTK_SHEET(sheet), i, ascii_name); gtk_sheet_set_column_title(GTK_SHEET(sheet), i, ascii_name); gtk_sheet_set_row_titles_width(GTK_SHEET(sheet), column_width); gtk_sheet_set_column_width(GTK_SHEET(sheet), i, 32 * char_width + 5); g_signal_connect(sheet, "button_press_event", G_CALLBACK(button_press), this); g_signal_connect(sheet, "popup-menu", G_CALLBACK(popup_menu_handler), this); g_signal_connect(gtk_sheet_get_entry(GTK_SHEET(sheet)), "changed", G_CALLBACK (show_entry), this); g_signal_connect(sheet, "activate", G_CALLBACK (activate_sheet_cell), (gpointer) this); ///////////////////////////////////////////////////////////////// g_signal_connect_after(window, "configure_event", G_CALLBACK (gui_object_configure_event), this); gtk_widget_show_all(window); bIsBuilt = true; NewProcessor(gp); NewSource(gp); // create popupmenu for sheet sheet_popup_menu = build_menu_for_sheet(); // create popupmenu for clist list_popup_menu = build_menu_for_list(); UpdateMenuItem(); } const char *SourceBrowserOpcode_Window::name() { return "program_memory"; } SourceBrowserOpcode_Window::SourceBrowserOpcode_Window(GUI_Processor *_gp) : current_address(0), normalPFD(0), memory(0) { menu = "/menu/Windows/Program memory"; pma = 0; gp = _gp; break_pix = gdk_pixbuf_new_from_xpm_data(break_xpm); pc_pix = gdk_pixbuf_new_from_xpm_data(pc_xpm); get_config(); if(enabled) Build(); } SourceBrowserOpcode_Window::~SourceBrowserOpcode_Window() { pango_font_description_free(normalPFD); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_statusbar.h0000664000076400007640000000237113045306453013463 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_STATUSBAR_H__ #define __GUI_STATUSBAR_H__ #include class RegisterLabeledEntry; // in gui_statusbar.cc class MemoryAccess; // in src/processor.h class GUI_Processor; // // The Status Bar window // class StatusBar_Window { public: explicit StatusBar_Window(GtkWidget *vbox_main); void NewProcessor(GUI_Processor *_gp, MemoryAccess *); void Update(); private: GUI_Processor *gp; MemoryAccess *ma; GtkWidget *hbox; std::vector entries; }; #endif //__GUI_STATUSBAR_H__ gpsim-0.30.0/gui/gui_callbacks.cc0000664000076400007640000000363613041763637013544 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* gui_callbacks.cc * * callback functions for the register viewer */ #include "../config.h" #ifdef HAVE_GUI #include #include /*---------------------------------------------------* * * gui_cb_quit - 'quit' callback * *---------------------------------------------------*/ void gui_cb_quit (GtkWidget *widget, gpointer data) { gtk_main_quit (); } /*---------------------------------------------------* * * gui_cb_break - 'break' callback * *---------------------------------------------------*/ void gui_cb_break (GtkWidget *widget, gpointer data) { printf("break\n"); } /*---------------------------------------------------* * * gui_cb_break_r - 'break_r' callback for break on read * *---------------------------------------------------*/ void gui_cb_break_r (GtkWidget *widget, gpointer data) { printf("break on read\n"); } /*---------------------------------------------------* * * gui_cb_break_w - 'break_w' callback for break on write * *---------------------------------------------------*/ void gui_cb_break_w (GtkWidget *widget, gpointer data) { printf("break on write\n"); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_regwin.h0000664000076400007640000000667013045306453012754 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_REGWIN_H__ #define __GUI_REGWIN_H__ #include "gui_object.h" #include "gui_register.h" #include "gtkextra/gtksheet.h" #include class GUI_Processor; //====================================================================== // The register window // #define REGISTERS_PER_ROW 16 #define MAX_ROWS ((MAX_REGISTERS)/(REGISTERS_PER_ROW)) // Base class for RAM_RegisterWindow and EEPROM_RegisterWindow class Register_Window : public GUI_Object { public: // This array is indexed with row, and gives the address of the // first cell in the given row. int row_to_address[MAX_ROWS]; std::string normalfont_string; PangoFontDescription *normalfont; GtkStyle *current_line_number_style; GtkStyle *breakpoint_line_number_style; REGISTER_TYPE type; GUIRegisterList *registers; GtkSheet *register_sheet; RegisterMemoryAccess *rma; // Apointer to the Processor's rma or ema. GtkWidget *entry; GtkWidget *location; GtkWidget *popup_menu; int registers_loaded; // non zero when registers array is loaded virtual void Build(); int LoadStyles(); int SettingsDialog(); void UpdateStyle(); void SetRegisterSize(); virtual void Update(); virtual void UpdateASCII(int row); virtual void UpdateLabel(); virtual void UpdateEntry(); virtual void UpdateLabelEntry(); virtual void SelectRegister(Value *); virtual void SelectRegister(int reg_number); virtual void NewProcessor(GUI_Processor *gp); virtual GUIRegister *getRegister(int row, int col); virtual gboolean UpdateRegisterCell(int reg_number); GUIRegister *operator [] (int address); int column_width(int col); int row_height(int row); protected: Register_Window(GUI_Processor *gp, REGISTER_TYPE type); private: GtkWidget *build_menu(); void do_popup(GtkWidget *widget, GdkEventButton *event); static gboolean button_press(GtkWidget *widget, GdkEventButton *event, Register_Window *rw); static gboolean popup_menu_handler(GtkWidget *widget, Register_Window *rw); // Formatting int register_size; // The size (in bytes) of a single register int char_width; // nominal character width. int char_height; // nominal character height int chars_per_column; // width of 1 column }; class RAM_RegisterWindow : public Register_Window { public: explicit RAM_RegisterWindow(GUI_Processor *gp); virtual void NewProcessor(GUI_Processor *gp); virtual void Update(); protected: virtual const char *name(); }; class EEPROM_RegisterWindow : public Register_Window { public: explicit EEPROM_RegisterWindow(GUI_Processor *gp); virtual void NewProcessor(GUI_Processor *gp); protected: virtual const char *name(); }; #endif // __GUI_REGWIN_H__ gpsim-0.30.0/gui/gui_main.cc0000664000076400007640000002006513045306453012535 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "../config.h" #ifdef HAVE_GUI #include #include "../src/gpsim_interface.h" #include "gui.h" #include "gui_breadboard.h" #include "gui_processor.h" #include "gui_profile.h" #include "gui_regwin.h" #include "gui_scope.h" #include "gui_src.h" #include "gui_stack.h" #include "gui_stopwatch.h" #include "gui_symbols.h" #include "gui_trace.h" #include "gui_watch.h" #ifndef _WIN32 #undef TRUE #undef FALSE #include "settings_exdbm.h" #else #include "settings_reg.h" #endif extern int gui_animate_delay; // in milliseconds /* * --- Function prototypes */ void init_link_to_gpsim(GUI_Processor *gp); void link_src_to_gpsim(GUI_Processor *gp); /* * --- Global variables */ GUI_Processor *gpGuiProcessor=0; unsigned int interface_id=0; Settings *settings; extern GtkWidget *dispatcher_window; extern void dispatch_Update(); //------------------------------------------------------------------------ CrossReferenceToGUI::CrossReferenceToGUI() : XrefObject() { } CrossReferenceToGUI::~CrossReferenceToGUI() { } void CrossReferenceToGUI::Remove() { } //------------------------------------------------------------------------ // class GUI_Interface : public Interface { private: GUI_Processor *gp; public: virtual void UpdateObject (gpointer xref,int new_value); virtual void RemoveObject (gpointer xref); virtual void SimulationHasStopped (gpointer object); virtual void NewProcessor (Processor *); virtual void NewModule (Module *module); virtual void NodeConfigurationChanged (Stimulus_Node *node); virtual void NewProgram (Processor *); virtual void Update (gpointer object); virtual ~GUI_Interface(); explicit GUI_Interface(GUI_Processor *_gp); }; GUI_Interface::GUI_Interface(GUI_Processor *_gp) : Interface ( (gpointer *) _gp) { gp = _gp; } GUI_Interface::~GUI_Interface() { if(gp) { gp->regwin_ram->set_config(); gp->regwin_eeprom->set_config(); gp->program_memory->set_config(); gp->source_browser->set_config(); gp->watch_window->set_config(); gp->stack_window->set_config(); gp->breadboard_window->set_config(); gp->trace_window->set_config(); gp->profile_window->set_config(); gp->stopwatch_window->set_config(); gp->scope_window->set_config(); } } /*------------------------------------------------------------------ * UpdateObject * * Each 'thing' that the gui displays about a simulated pic has an * associated cross reference structure. Sometimes these 'things' * displayed in more than one place (like the status register). * Each graphical instance has its own structure. All of the structures * pertaining to the same pic object (again, like the status register) * are stored in a singly-linked list. This routine scans through * this list and updates each instance of the object. */ void GUI_Interface::UpdateObject(gpointer gui_xref,int new_value) { CrossReferenceToGUI *xref = static_cast(gui_xref); xref->Update(new_value); } /*------------------------------------------------------------------ * RemoveObject * */ void GUI_Interface::RemoveObject(gpointer gui_xref) { CrossReferenceToGUI *xref = static_cast(gui_xref); xref->Remove(); } extern int gui_animate_delay; // in milliseconds /*------------------------------------------------------------------ * SimulationHasStopped * */ void GUI_Interface::SimulationHasStopped(gpointer callback_data) { if(callback_data) { GUI_Processor *lgp = static_cast(callback_data); while (gtk_events_pending()) gtk_main_iteration(); lgp->regwin_ram->Update(); lgp->regwin_eeprom->Update(); lgp->program_memory->Update(); lgp->source_browser->Update(); lgp->watch_window->Update(); lgp->stack_window->Update(); lgp->breadboard_window->Update(); lgp->trace_window->Update(); lgp->profile_window->Update(); lgp->stopwatch_window->Update(); lgp->scope_window->Update(); if (gui_animate_delay!=0) g_usleep(1000 * gui_animate_delay); dispatch_Update(); } } /*------------------------------------------------------------------ * NewProcessor - Add a new processor * * This routine adds another processor to the list of currently * simulated processors (as of 0.0.14 though, you're still limited * to a list of one). It then notifies each child window. Finally * a communication link between the gui and the simulator is established. */ void GUI_Interface::NewProcessor (Processor *new_cpu) { // Create a gui representation of the new processor if(gp) { gp->SetCPU(new_cpu); gp->regwin_ram->NewProcessor(gp); // RRR gp->program_memory->NewProcessor(gp); gp->source_browser->CloseSource(); gp->source_browser->NewProcessor(gp); gp->symbol_window->NewSymbols(); //gp->watch_window->NewProcessor(gp); gp->breadboard_window->NewProcessor(gp); gp->stack_window->NewProcessor(gp); gp->trace_window->NewProcessor(gp); gp->profile_window->NewProcessor(gp); gp->stopwatch_window->NewProcessor(gp); //gp->scope_window->NewProcessor(gp); Dprintf((" New processor has been added")); } } /*------------------------------------------------------------------ * */ void GUI_Interface::NewModule (Module *module) { // FIX ME - need to search for *p in the gp list... if(gp) gp->breadboard_window->NewModule(module); } /*------------------------------------------------------------------ * */ void GUI_Interface::NodeConfigurationChanged (Stimulus_Node *node) { // FIX ME - need to search for *p in the gp list... if(gp) gp->breadboard_window->NodeConfigurationChanged(node); } /*------------------------------------------------------------------ * */ void GUI_Interface::NewProgram (Processor *new_cpu) { if(gp) { gp->regwin_eeprom->NewProcessor(gp); gp->source_browser->CloseSource(); gp->source_browser->NewSource(gp); gp->symbol_window->NewSymbols(); gp->program_memory->NewSource(gp); gp->profile_window->NewProgram(gp); gp->watch_window->NewProcessor(gp); link_src_to_gpsim( gp); } } void GUI_Interface::Update(gpointer object) { SimulationHasStopped(object); } /*------------------------------------------------------------------ * quit_gui * */ void quit_gui(void) { if(!get_interface().bUsingGUI()) return; int x, y, width, height; gtk_window_get_position(GTK_WINDOW(dispatcher_window), &x, &y); gtk_window_get_size(GTK_WINDOW(dispatcher_window), &width, &height); config_set_variable("dispatcher", "enable", 1); config_set_variable("dispatcher", "x", x); config_set_variable("dispatcher", "y", y); config_set_variable("dispatcher", "width", width); config_set_variable("dispatcher", "height", height); get_interface().remove_interface(interface_id); gtk_main_quit(); } /*------------------------------------------------------------------ * gui_init * */ int gui_init (int argc, char **argv) { #ifndef _WIN32 settings = new SettingsEXdbm("gpsim"); #else settings = new SettingsReg("gpsim"); #endif if (!gtk_init_check (&argc, &argv)) { return -1; } // standardize IO format ref bug 1832702 setlocale(LC_NUMERIC, "C"); gpGuiProcessor = new GUI_Processor(); interface_id = get_interface().add_interface(new GUI_Interface(gpGuiProcessor)); return(0); } void gui_main() { gtk_main (); } #endif //HAVE_GUI gpsim-0.30.0/gui/gui_stack.cc0000664000076400007640000002046213041763637012726 00000000000000/* Copyright (C) 2000,2001 Ralf Forsberg Copyright (c) 2013 Roy R Rankin This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include "../src/sim_context.h" #include "../src/interface.h" #include "../src/pic-processor.h" #include "../src/symbol.h" #include "gui.h" #include "gui_stack.h" #include "gui_src.h" enum { COLUMN_DEPTH, COLUMN_RETADDRESS, N_COLUMNS }; #define COLUMNS 2 /* */ static void sigh_button_event( GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, Stack_Window *sw) { assert(sw); if(!sw->gp || !sw->gp->cpu) return; GtkTreeModel *model = gtk_tree_view_get_model(treeview); GtkTreeIter iter; if (gtk_tree_model_get_iter(model, &iter, path)) { gint retaddress; gtk_tree_model_get(model, &iter, gint(COLUMN_RETADDRESS), &retaddress, -1); sw->gp->cpu->pma->toggle_break_at_address(retaddress); } } static void stack_list_row_selected(GtkTreeSelection *selection, Stack_Window *sw) { GtkTreeIter iter; GtkTreeModel *model; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gint retaddress; gtk_tree_model_get(model, &iter, gint(COLUMN_RETADDRESS), &retaddress, -1); sw->gp->source_browser->SelectAddress(retaddress); sw->gp->program_memory->SelectAddress(retaddress); } } static int delete_event(GtkWidget *widget, GdkEvent *event, Stack_Window *sw) { sw->ChangeView(VIEW_HIDE); return TRUE; } // find name of label closest before 'address' and copy found data // into name and offset static int get_closest_label(Stack_Window *sw, int address, char *name, int *offset) { // this function assumes that address symbols are sorted Value *closest_symbol = 0; #if 0 int minimum_delta=0x2000000; int delta; Symbol_Table &st = CSimulationContext::GetContext()->GetSymbolTable(); Symbol_Table::iterator symIt; Symbol_Table::iterator symItEnd = st.end(); for(symIt=st.begin(); symIt != symItEnd; symIt++) { Value *s = *symIt; if( (typeid(*s) == typeid(AddressSymbol)) /*|| (typeid(*s) == typeid(line_number_symbol))*/) { int i; s->get(i); delta = abs( i - address); if(delta < minimum_delta) { minimum_delta = delta; closest_symbol = s; } } } #endif if(verbose) g_print("FIXME gui_stack.cc get closest label\n"); if(closest_symbol) { strcpy(name,closest_symbol->name().data()); int i; closest_symbol->get(i); *offset=address-i; return 1; } return 0; } void Stack_Window::Update(void) { int nrofentries; if(!gp || !enabled) return; pic_processor *pic = dynamic_cast(gp->cpu); if(!pic) return; // Enhanced 14bit processors use 0x1f(31) for empty index which is // also P18 max stack slot, so we mask with 0x1f nrofentries = pic->stack->pointer & 0x1f; if (nrofentries && ((nrofentries-1) > (int)pic->stack->stack_mask)) return; // Do if stack has shrunk for ( ; last_stacklen > nrofentries; --last_stacklen) { GtkTreeIter iter; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(stack_list), &iter)) { gtk_list_store_remove(stack_list, &iter); } } // Do if stack has grown for ( ; last_stacklen < nrofentries; ++last_stacklen) { GtkTreeIter iter; gint retaddress = pic->stack->contents[last_stacklen & pic->stack->stack_mask]; gtk_list_store_prepend(stack_list, &iter); gtk_list_store_set(stack_list, &iter, gint(COLUMN_DEPTH), last_stacklen, gint(COLUMN_RETADDRESS), retaddress, -1); } } static void depth_cell_data_function( GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { gint depth; gchar buf[64]; gtk_tree_model_get(model, iter, COLUMN_DEPTH, &depth, -1); g_snprintf(buf, sizeof(buf), "#%d", depth); g_object_set(renderer, "text", buf, NULL); } static void retaddr_cell_data_function( GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { gint addr; gchar buf[64]; char labelname[64]; int labeloffset; Stack_Window *sw; sw = static_cast(user_data); gtk_tree_model_get(model, iter, COLUMN_RETADDRESS, &addr, -1); if (get_closest_label(sw, addr, labelname, &labeloffset)) g_snprintf(buf, sizeof(buf), "0x%04x (%s+%d)", addr, labelname, labeloffset); else g_snprintf(buf, sizeof(buf), "0x%04x", addr); g_object_set(renderer, "text", buf, NULL); } void Stack_Window::Build(void) { if(bIsBuilt) return; GtkWidget *vbox; GtkWidget *scrolled_window; window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Stack Viewer"); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect (window, "destroy", G_CALLBACK(gtk_widget_destroyed), &window); g_signal_connect (window, "delete_event", G_CALLBACK(delete_event), (gpointer)this); g_signal_connect_after(window, "configure_event", G_CALLBACK(gui_object_configure_event), this); stack_list = gtk_list_store_new(gint(N_COLUMNS), G_TYPE_INT, G_TYPE_INT); sort_stack_list = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(stack_list)); tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(sort_stack_list)); g_object_unref(stack_list); g_object_unref(sort_stack_list); GtkTreeViewColumn *col; GtkCellRenderer *renderer; col = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col, "depth"); gtk_tree_view_column_set_sort_indicator(col, TRUE); gtk_tree_view_column_set_sort_column_id(col, gint(COLUMN_DEPTH)); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_set_cell_data_func(col, renderer, depth_cell_data_function, NULL, NULL); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col, "return address"); gtk_tree_view_column_set_sort_indicator(col, TRUE); gtk_tree_view_column_set_sort_column_id(col, gint(COLUMN_RETADDRESS)); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_set_cell_data_func(col, renderer, retaddr_cell_data_function, this, NULL); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); g_signal_connect(selection, "changed", G_CALLBACK(stack_list_row_selected), this); g_signal_connect(tree, "row-activated", G_CALLBACK(sigh_button_event), this); scrolled_window=gtk_scrolled_window_new(0, 0); vbox = gtk_vbox_new(FALSE,1); gtk_container_add(GTK_CONTAINER(scrolled_window), tree); gtk_container_add(GTK_CONTAINER(window),vbox); gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0); gtk_widget_show_all (window); bIsBuilt = true; UpdateMenuItem(); Update(); } const char *Stack_Window::name() { return "stack_viewer"; } //------------------------------------------------------------------------ // Create // // Stack_Window::Stack_Window(GUI_Processor *_gp) : last_stacklen(0) { menu = "/menu/Windows/Stack"; gp = _gp; get_config(); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_scope.cc0000664000076400007640000007533613045306453012735 00000000000000/* Copyright (C) 2004 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* S C O P E A simple waveform viewer for gpsim. Inspired from Nuno Sucena Almeida's gpsim_la - plug in. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include "../src/bitlog.h" #include "../src/symbol.h" #include "../src/value.h" #include "../src/stimuli.h" #include "../src/gpsim_object.h" #include #include #include #include #include "gui.h" #include "gui_scope.h" static GdkColor signal_line_color, grid_line_color; class WaveformSink; class Waveform; /*********************************************************************** timeMap - a structure that's used to map horizontal screen coordinates into simulation time. */ class timeMap { public: timeMap() : time(0.0), pos(0), eventIndex(0), event(0) {} // simulation time double time; // pixel x-coordinate int pos; // index into array holding event (fixme - exposes Logger implementation) unsigned int eventIndex; // The event int event; }; /*********************************************************************** WaveSource This is an attribute that provides the interface between the WaveForm class (below) and the names of nodes or stimuli that source information. */ class WaveformSource : public String { public: WaveformSource(Waveform *pParent, const char *_name); // Override the String::set method so that name assignments can // be intercepted. virtual void set(const char *cp, int len=0); private: Waveform *m_pParent; bool m_bHaveSource; }; /*********************************************************************** zoom */ class ZoomAttribute : public Integer { public: explicit ZoomAttribute(Scope_Window *); virtual void set(gint64 i); private: Scope_Window *m_pSW; }; /*********************************************************************** pan */ class PanAttribute : public Integer { public: explicit PanAttribute(Scope_Window *); virtual void set(gint64 i); private: Scope_Window *m_pSW; }; /*********************************************************************** */ GtkWidget *waveDrawingArea=0; GtkWidget *signalDrawingArea=0; /*********************************************************************** Wavebase class */ class WaveBase { public: WaveBase(Scope_Window *parent, const char *name); virtual ~WaveBase() { } virtual void Update(guint64 start=0, guint64 stop=0)=0; virtual void Build(gint w, gint h, gint y); const char *get_text() { return m_label_name.c_str(); } gint get_yoffset() { return yoffset; } virtual void setSource(const char *) { } protected: Scope_Window *sw; // Parent guint64 m_start; // Start time of plotted waveform guint64 m_stop; // Stop time of plotted waveform gint width; gint height; gint yoffset; std::string m_label_name; }; /*********************************************************************** TimeAxis - A special 'Waveform' for plotting the time */ class TimeAxis : public WaveBase { public: TimeAxis(Scope_Window *parent, const char *name); virtual ~TimeAxis() { } virtual void Build(gint w, gint h, gint y); virtual void Update(guint64 start=0, guint64 stop=0); void draw(cairo_t *cr); private: PangoLayout *m_TicText; }; /*********************************************************************** Waveform class This holds the gui information related with a gpsim waveform */ class Waveform : public WaveBase { public: Waveform(Scope_Window *parent, const char *name); virtual ~Waveform() { } virtual void Update(guint64 start=0, guint64 stop=0); virtual void Build(gint w, gint h, gint y); void draw(cairo_t *cr); void setData(char c); virtual void setSource(const char *); protected: void PlotTo(cairo_t *cr, timeMap &left, timeMap &right); void SearchAndPlot(cairo_t *cr, timeMap &left, timeMap &right); void updateLayout(); PinMonitor *m_ppm; WaveformSink *m_pSink; ThreeStateEventLogger m_logger; timeMap m_last; WaveformSource m_pSourceName; }; /*********************************************************************** WaveformSink - A "sink" is an object that receives data from a "source". In the context of waveform viewer, a source is a stimulus and the viewer is the sink. */ class WaveformSink : public SignalSink { public: explicit WaveformSink(Waveform *pParent); virtual void setSinkState(char); virtual void release() {} protected: Waveform *m_pWaveform; }; // // SignalNameEntry - a class to control gui editing of signal names // class SignalNameEntry { public: SignalNameEntry(); ~SignalNameEntry(); bool Select(WaveBase *); bool unSelect(); bool isSelected(WaveBase *pWave) { return pWave == m_selectedWave; } WaveBase *getSelected() { return m_selectedWave; } GtkWidget *m_entry; protected: WaveBase *m_selectedWave; }; //======================================================================== gboolean Scope_Window::key_press(GtkWidget *widget, GdkEventKey *key, Scope_Window *sw) { Dprintf (("press 0x%x\n", key->keyval)); switch (key->keyval) { case 'z': sw->zoom(2); break; case 'Z': sw->zoom(-2); break; case 'l': sw->pan(-( (gint64) sw->getSpan()/4)); break; case 'r': sw->pan( (gint64) sw->getSpan()/4); break; default: return FALSE; } return TRUE; } //======================================================================== // WaveformSource WaveformSource::WaveformSource(Waveform *pParent, const char *_name) : String(_name, "", "view or set gui scope waveforms"), m_pParent(pParent), m_bHaveSource(false) { assert(m_pParent); // Prevent removal from the symbol table (all clearable symbols are // removed from the symbol table when a new processor is loaded). } void WaveformSource::set(const char *cp, int len) { if (!m_bHaveSource) { String::set(cp,len); m_pParent->setSource(cp); m_bHaveSource = true; } } //======================================================================== ZoomAttribute::ZoomAttribute(Scope_Window *pSW) : Integer("scope.zoom",0,"Scope Zoom; positive values zoom in, negative values zoom out"), m_pSW(pSW) { assert(m_pSW); } void ZoomAttribute::set(gint64 i) { Integer::set(i); m_pSW->zoom(i); } //======================================================================== PanAttribute::PanAttribute(Scope_Window *pSW) : Integer("scope.pan",0,"Scope Pan; positive values pan right, negative values pan left"), m_pSW(pSW) { assert(m_pSW); } void PanAttribute::set(gint64 i) { Integer::set(i); m_pSW->pan(i); } //======================================================================== WaveformSink::WaveformSink(Waveform *pParent) : SignalSink(), m_pWaveform(pParent) { assert(m_pWaveform); } void WaveformSink::setSinkState(char c) { m_pWaveform->setData(c); } //************************************************************************ WaveBase::WaveBase(Scope_Window *parent, const char *name) : sw(parent), m_start(1), m_stop(1) { } void WaveBase::Build(gint w, gint h, gint y) { width = w; height = h; yoffset = y; Update(0,0); } //************************************************************************ Waveform::Waveform(Scope_Window *parent, const char *name) : WaveBase(parent,name), m_ppm(0), m_pSourceName(this, name) { m_pSink = new WaveformSink(this); globalSymbolTable().addSymbol(&m_pSourceName); m_logger.event('0'); } void Waveform::Build(gint w, gint h, gint y) { WaveBase::Build(w, h, y); updateLayout(); } void Waveform::setData(char c) { m_logger.event(c); } void Waveform::updateLayout() { char buffer[100]; m_pSourceName.get(buffer, sizeof(buffer)); m_label_name = buffer; } void Waveform::setSource(const char *sourceName) { //IOPIN *ppin = dynamic_cast(get_symbol_table().findStimulus(sourceName)); IOPIN *ppin = dynamic_cast(globalSymbolTable().find(string(sourceName))); if (ppin) { if (m_ppm) m_ppm->removeSink(m_pSink); m_ppm = ppin->getMonitor(); if (m_ppm) m_ppm->addSink(m_pSink); updateLayout(); // Invalidate wave area. m_start = m_stop = 1; Update(0,0); if (sw) { if (signalDrawingArea) gtk_widget_queue_draw(signalDrawingArea); if (waveDrawingArea) gtk_widget_queue_draw(waveDrawingArea); } } else if(sourceName) printf("'%s' is not a valid source for the scope\n",sourceName); } //---------------------------------------- // void Waveform::PlotTo(cairo_t *cr, timeMap &left, timeMap &right) { // Event(s) has(have) been found. // The plotting region has been subdivided as finely as possible // and there are one or more events. // First draw a horizontal line from the last known event to here: cairo_move_to(cr, m_last.pos, m_last.event + yoffset); cairo_line_to(cr, right.pos, m_last.event + yoffset); // Now draw a vertical line for the event int nextEvent = (m_logger.get_state(right.eventIndex) == '1') ? 1 : (height - 3); // Draw a thicker line if there is more than one event. unsigned int nEvents = m_logger.get_nEvents(left.eventIndex, right.eventIndex); if (nEvents > 1) { cairo_save(cr); guint16 c = (nEvents < 4) ? (0x4000 * nEvents + 0x8000) : 0xffff; if (left.pos != right.pos) { cairo_move_to(cr, left.pos, 1 + yoffset); cairo_line_to(cr, left.pos, height - 3 + yoffset); cairo_stroke(cr); } // variations of yellow cairo_set_source_rgb(cr, 1.0, 1.0, double(c) / 65535.0); cairo_move_to(cr, right.pos, 1 + yoffset); cairo_line_to(cr, right.pos, height - 3 + yoffset); cairo_stroke(cr); cairo_restore(cr); } else { cairo_move_to(cr, right.pos, m_last.event + yoffset); cairo_line_to(cr, right.pos, nextEvent + yoffset); } cairo_stroke(cr); m_last = right; m_last.event = nextEvent; } //---------------------------------------- // // Waveform SearchAndPlot // // Recursively divide the plotting area into smaller and smaller // regions until either only one event exists or the region can // be divided no smaller. // void Waveform::SearchAndPlot(cairo_t *cr, timeMap &left, timeMap &right) { if (right.eventIndex == left.eventIndex) // The time span cannot be divided any smaller. // If there are no events in this subdivided region // So just return. // m_last = left; ; else if (left.pos+1 >= right.pos) PlotTo(cr, left,right); else { // the subdivided region is larger than 1-pixel wide // and there is at least one event. So subdivide even smaller // and recursively call timeMap mid; mid.time = (left.time + right.time) / 2; mid.pos = (left.pos + right.pos) / 2; mid.eventIndex = m_logger.get_index ((guint64)mid.time); SearchAndPlot(cr, left, mid); SearchAndPlot(cr, mid, right); } } //---------------------------------------- // // Waveform Update // void Waveform::Update(guint64 uiStart, guint64 uiEnd) { if (uiEnd == 0) uiEnd = get_cycles().get(); if (m_start == uiStart && m_stop == uiEnd) return; m_start = uiStart; m_stop = uiEnd; updateLayout(); } void Waveform::draw(cairo_t *cr) { cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_rectangle(cr, 0.0, yoffset, width, yoffset + height); cairo_fill(cr); // Draw vertical grid lines gdk_cairo_set_source_color(cr, &grid_line_color); for (int i = 0; i < sw->MajorTicks().sze(); ++i) { int x = sw->MajorTicks().pixel(i); cairo_move_to(cr, x, yoffset + 1); cairo_line_to(cr, x, yoffset + height - 1); } // Draw horizontal grid lines cairo_move_to(cr, 0.0, yoffset + height - 1); cairo_line_to(cr, width, yoffset + height - 1); cairo_stroke(cr); if (m_stop == 0) return; // Draw signal timeMap left; timeMap right; left.pos = 0; left.time = m_start; left.eventIndex = m_logger.get_index(m_start); left.event = (m_logger.get_state(left.eventIndex) == '1') ? 1 : (height - 3); m_last = left; right.pos = width; right.time = m_stop; right.eventIndex = m_logger.get_index(m_stop); gdk_cairo_set_source_color(cr, &signal_line_color); SearchAndPlot(cr, left, right); if (right.pos > m_last.pos) { cairo_move_to(cr, m_last.pos, yoffset + m_last.event); cairo_line_to(cr, right.pos, yoffset + m_last.event); cairo_stroke(cr); } } //======================================================================== TimeAxis::TimeAxis(Scope_Window *parent, const char *name) : WaveBase(parent,name), m_TicText(0) { } //---------------------------------------- // // TimeAxis Update // void TimeAxis::Update(guint64 uiStart, guint64 uiEnd) { if (uiEnd == 0) uiEnd = get_cycles().get(); if (m_start == uiStart && m_stop == uiEnd) return; m_start = uiStart; m_stop = uiEnd; } void TimeAxis::Build(gint w, gint h, gint y) { WaveBase::Build(w, h, y); // Invalidate the start time after the build. // This is for the case where the scope window gets opened after // the simulation has already been started. m_start=m_stop=0; /* if (m_layout) pango_layout_set_text(m_layout,"Time", -1); */ m_TicText = gtk_widget_create_pango_layout (GTK_WIDGET (waveDrawingArea), NULL); } //------------------------------------------------------------------------ // Signals //---------------------------------------- // // When a user clicks on the "X" in the window managers border of the // scope window, we'll capture that event and hide the scope. // static int delete_event(GtkWidget *widget, GdkEvent *event, Scope_Window *sw) { sw->ChangeView(VIEW_HIDE); return TRUE; } //------------------------------------------------------------------------ class TimeMarker : public Integer { public: TimeMarker(Scope_Window *parent, const char *_name, const char *desc); virtual void set(gint64 i); private: Scope_Window *m_pParent; }; TimeMarker::TimeMarker(Scope_Window *parent, const char *_name, const char *desc) : Integer(_name,0,desc), m_pParent(parent) { assert(m_pParent); } void TimeMarker::set(gint64 i) { Integer::set(i); m_pParent->Update(); } //======================================================================== GridPointMapping::GridPointMapping(int nPointsToMap) : m_nPoints(0), m_pixel(nPointsToMap), m_cycle(nPointsToMap) { } GridPointMapping::~GridPointMapping() { } //======================================================================== // SignalNameEntry SignalNameEntry::SignalNameEntry() : m_selectedWave(0) { m_entry = gtk_entry_new(); } SignalNameEntry::~SignalNameEntry() { gtk_widget_destroy(m_entry); } bool SignalNameEntry::Select(WaveBase *pWave) { if (pWave) { gtk_entry_set_text(GTK_ENTRY(m_entry), pWave->get_text()); gtk_widget_show(m_entry); gtk_widget_grab_focus(m_entry); m_selectedWave = pWave; return true; } return unSelect(); } bool SignalNameEntry::unSelect() { gtk_widget_hide(m_entry); m_selectedWave = 0; return false; } //======================================================================== void Scope_Window::gridPoints(guint64 *uiStart, guint64 *uiEnd) { guint64 start = m_Markers[eStart]->getVal(); guint64 stop = m_Markers[eStop]->getVal(); if (!stop) stop = get_cycles().get(); if (uiStart) *uiStart = start; if (uiEnd) *uiEnd = stop; // // Draw Vertical Grid Lines: // double t1 = (double) start; double t2 = (double) stop; double dt = t2-t1; int iMajor=0; int iMinor=0; m_MajorTicks.m_nPoints = 0; m_MinorTicks.m_nPoints = 0; if (dt > 1.0) { double exp1 = floor(log10(dt)); double dt_tic = pow(10.0,exp1); double nTics = floor(dt/dt_tic); if (nTics < 5.0 && exp1>0.0) dt_tic /= 2.0; const int nMinorTics=5; const double dt_minor= dt_tic/nMinorTics; double ta = ceil(t1/dt_tic); double tb = floor(t2/dt_tic); for (double t=ta; t<=tb; t+=1.0) { double ttic=t*dt_tic; guint64 uiTime = (guint64)(floor(ttic)); m_MajorTicks.m_pixel[iMajor] = mapTimeToPixel(uiTime); m_MajorTicks.m_cycle[iMajor] = uiTime; /* printf ("t=%g dt_tic=%g tmajor=%g %d %lld\n", t,dt_tic,ttic,m_MajorTicks.m_pixel[iMajor],uiTime); */ iMajor++; ttic+=dt_minor; for (int it=1; itgetSelected(); if (pwf) { if (bAccept) pwf->setSource(gtk_entry_get_text(GTK_ENTRY(m_entry->m_entry))); m_entry->Select(0); return true; } return false; } //------------------------------------------------------------------------ bool Scope_Window::selectSignalName(int y) { int timeHeight=15; int waveHeight=20; bool bRet=true; y = (y > timeHeight) ? ((y-timeHeight)/waveHeight) : -1; if (y >= 0 && y < int(signals.size())) { if (m_entry->isSelected(signals[y])) return false; m_entry->unSelect(); gtk_layout_move(GTK_LAYOUT(signalDrawingArea), m_entry->m_entry, 0, signals[y]->get_yoffset() - 2); bRet = m_entry->Select(signals[y]); } else bRet = endSignalNameSelection(true); if (bRet) gtk_widget_queue_draw(signalDrawingArea); return bRet; } //************************************************************************ // S I G N A L S //************************************************************************ gint Scope_Window::signalEntryKeyPress(GtkEntry *widget, GdkEventKey *key, Scope_Window *sw) { Dprintf (("Entry keypress 0x%x\n",key->keyval)); if (key->keyval == GDK_KEY_Return) sw->endSignalNameSelection(true); if (key->keyval == GDK_KEY_Escape) sw->endSignalNameSelection(false); return FALSE; } gint Scope_Window::signalButtonPress(GtkWidget *widget, GdkEventButton *pEventButton, Scope_Window *sw) { Dprintf ((" Signal: button:%d x=%g y=%g evt=%d modifier=0x%x\n", pEventButton->button, pEventButton->x,pEventButton->y,pEventButton->type,pEventButton->state)); sw->selectSignalName((int)(pEventButton->y)); return TRUE; } gboolean Scope_Window::signal_name_expose(GtkWidget *widget, GdkEventExpose *event, Scope_Window *sw) { cairo_t *cr = gdk_cairo_create(gtk_layout_get_bin_window(GTK_LAYOUT(widget))); std::vector::iterator i = sw->signals.begin(); PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL); for ( ; i != sw->signals.end(); ++i) { if (!sw->m_entry->isSelected(*i)) { Waveform *p = *i; double yoffset = p->get_yoffset(); pango_layout_set_text(layout, p->get_text(), -1); cairo_move_to(cr, 0.0, yoffset); pango_cairo_update_layout(cr, layout); pango_cairo_show_layout(cr, layout); } } g_object_unref(layout); cairo_destroy(cr); return TRUE; } void TimeAxis::draw(cairo_t *cr) { // Draw major ticks for (int i = 0; i < sw->MajorTicks().sze(); ++i) { gdk_cairo_set_source_color(cr, &grid_line_color); int x = sw->MajorTicks().pixel(i); cairo_move_to(cr, x, height - 3); cairo_line_to(cr, x, height - 1); char buff[100]; g_snprintf(buff, sizeof(buff),"%" PRINTF_GINT64_MODIFIER "d", sw->MajorTicks().cycle(i)); pango_layout_set_text(m_TicText, buff, -1); int text_height; int text_width; pango_layout_get_pixel_size(m_TicText, &text_width, &text_height); text_width /= 2; x = ((x - text_width) < 0) ? 0 : (x - text_width); x = ((x + text_width) > width) ? (x - text_width) : x; cairo_move_to(cr, x, (height - text_height)/2); pango_cairo_update_layout(cr, m_TicText); pango_cairo_show_layout(cr, m_TicText); } gdk_cairo_set_source_color(cr, &grid_line_color); // Draw minor ticks for (int i = 0; i < sw->MinorTicks().sze(); ++i) { double x = sw->MinorTicks().pixel(i); cairo_move_to(cr, x, height - 3); cairo_line_to(cr, x, height - 1); } // Draw horizontal grid line cairo_move_to(cr, 0.0, height - 1); cairo_line_to(cr, width, height - 1); cairo_stroke(cr); } gboolean Scope_Window::signal_expose(GtkWidget *widget, GdkEventExpose *event, Scope_Window *sw) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); sw->m_TimeAxis->draw(cr); std::vector::iterator i = sw->signals.begin(); for (; i != sw->signals.end(); ++i) { (*i)->draw(cr); } double xpos = sw->mapTimeToPixel(sw->m_Markers[eLeftButton]->getVal() + sw->waveXoffset()); cairo_move_to(cr, xpos, 0.0); cairo_line_to(cr, xpos, 1000.0); cairo_stroke(cr); cairo_destroy(cr); return TRUE; } //------------------------------------------------------------------------ // // Scope_Window member functions // // // ------------------------------------------ // | Window // | -------------------------------------- // | | Horizontal pane // | | ---------------+ +------------------------+ // | | | signal name | | Wave layout // | | | drawing area | | +--------------------- // | | | // //------------------------------------------------------------------------ void Scope_Window::Build() { window = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (!window) return; gtk_window_set_title(GTK_WINDOW(window), "Scope"); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); g_signal_connect(window, "delete_event", G_CALLBACK(delete_event), this); // // Define the drawing colors // // The signal color is bright red signal_line_color.red = 0xff00; signal_line_color.green = 0x0000; signal_line_color.blue = 0x0000; // The grid color is bright green grid_line_color.red = 0x4000; grid_line_color.green = 0x4000; grid_line_color.blue = 0x4000; waveDrawingArea = gtk_drawing_area_new(); gint dawidth = 400; gint daheight = 100; gtk_widget_set_size_request(waveDrawingArea, dawidth, daheight); gtk_widget_set_events(waveDrawingArea, GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK ); signalDrawingArea = gtk_layout_new(NULL, NULL); gtk_widget_set_size_request(signalDrawingArea, 100, daheight); gtk_widget_set_events(signalDrawingArea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK ); GtkWidget *pvbox = gtk_vbox_new(FALSE,0); gtk_container_add (GTK_CONTAINER (window), pvbox); m_pHpaned = gtk_hpaned_new(); gtk_box_pack_start(GTK_BOX (pvbox), m_pHpaned, TRUE, TRUE, 0); m_hAdj = gtk_adjustment_new (0.0, // value 0.0, // lower m_PixmapWidth, // upper m_PixmapWidth/100.0,// step_increment m_PixmapWidth/10.0, // page_increment m_PixmapWidth/5.0); // page_size m_phScrollBar = gtk_hscrollbar_new(GTK_ADJUSTMENT(m_hAdj)); // TODO: Pan GUI widget is disabled for now. // Work must be done to do this correctly and add zoom widgets #if 0 gtk_box_pack_start(GTK_BOX(pvbox), m_phScrollBar, TRUE, TRUE, 0); g_signal_connect(m_hAdj, "value-changed", G_CALLBACK(hAdjVChange), this); #endif // Add the drawing areas to theUnread panes gtk_paned_add1(GTK_PANED(m_pHpaned), signalDrawingArea); gtk_paned_add2(GTK_PANED(m_pHpaned), waveDrawingArea); gtk_paned_set_position(GTK_PANED(m_pHpaned),50); guint64 start,stop; gridPoints(&start,&stop); int timeHeight = 15; m_TimeAxis->Build(m_PixmapWidth, timeHeight, 0); m_TimeAxis->Update(start,stop); std::vector::iterator i = signals.begin(); int yoffset = timeHeight; for (; i != signals.end(); ++i) { const int waveHeight = 20; yoffset += waveHeight; (*i)->Build(m_PixmapWidth, waveHeight, yoffset); } g_signal_connect(waveDrawingArea, "expose-event", G_CALLBACK(signal_expose), this); g_signal_connect(signalDrawingArea, "expose-event", G_CALLBACK(signal_name_expose), this); /* Add a signal handler for key press events. This will capture * key commands for single stepping, running, etc. */ g_signal_connect(waveDrawingArea, "key_press_event", G_CALLBACK(key_press), (gpointer) this); gtk_widget_set_can_focus(waveDrawingArea, TRUE); g_signal_connect(signalDrawingArea, "button_press_event", G_CALLBACK(signalButtonPress), (gpointer) this); bIsBuilt = true; UpdateMenuItem(); gtk_widget_show_all(window); m_entry = new SignalNameEntry(); gtk_layout_put(GTK_LAYOUT(signalDrawingArea), m_entry->m_entry, 0,0); g_signal_connect(m_entry->m_entry, "key_press_event", G_CALLBACK(signalEntryKeyPress), (gpointer) this); } void Scope_Window::Update() { if(!enabled) return; if(!bIsBuilt) Build(); if(m_bFrozen) return; // Compute the grid points guint64 start,stop; gridPoints(&start,&stop); // Horizontal scroll // the scroll bar maps pixel positions into time. // the span of the scroll bar is the span of time that is currently // cached (or soon to be cached) in the waveform pixmaps. // the thumb position is the current view into the cache. // the page-size property is 20% of the span double dspan = stop-start; dspan = (dspanUpdate(start,stop); std::vector::iterator i = signals.begin(); for ( ; i != signals.end(); ++i) { (*i)->Update(start,stop); } if (m_entry->isSelected(0)) { gtk_widget_hide(m_entry->m_entry); } } const char *Scope_Window::name() { return "scope"; } Scope_Window::Scope_Window(GUI_Processor *_gp) : m_pHpaned(0), m_phScrollBar(0), m_PixmapWidth(1024), m_MajorTicks(32), m_MinorTicks(256), m_entry(0) { gp = _gp; menu = "/menu/Windows/Scope"; get_config(); m_Markers[eStart] = new TimeMarker(this, "scope.start", "Scope window start time"); m_Markers[eStop] = new TimeMarker(this, "scope.stop", "Scope window stop time"); m_Markers[eLeftButton] = new TimeMarker(this, "scope.left", "Scope window left marker"); m_Markers[eRightButton] = new TimeMarker(this, "scope.right", "Scope window right marker"); m_zoom = new ZoomAttribute(this); m_pan = new PanAttribute(this); globalSymbolTable().addSymbol(m_Markers[eStart]); globalSymbolTable().addSymbol(m_Markers[eStop]); globalSymbolTable().addSymbol(m_Markers[eLeftButton]); globalSymbolTable().addSymbol(m_Markers[eRightButton]); globalSymbolTable().addSymbol(m_zoom); globalSymbolTable().addSymbol(m_pan); m_bFrozen = false; // // Create the signals for the scope window. // signals.push_back(new Waveform(this,"scope.ch0")); signals.push_back(new Waveform(this,"scope.ch1")); signals.push_back(new Waveform(this,"scope.ch2")); signals.push_back(new Waveform(this,"scope.ch3")); signals.push_back(new Waveform(this,"scope.ch4")); signals.push_back(new Waveform(this,"scope.ch5")); signals.push_back(new Waveform(this,"scope.ch6")); signals.push_back(new Waveform(this,"scope.ch7")); m_TimeAxis = new TimeAxis(this,"scope.time"); if(enabled) Build(); } // zoom(i) // const int minSpan = 10; void Scope_Window::zoom(int i) { m_bFrozen = true; gint64 start = (gint64) m_Markers[eStart]->getVal(); gint64 stop = (gint64) m_Markers[eStop]->getVal(); gint64 now = (gint64) get_cycles().get(); if (!stop) stop = now; gint64 mid = (start + stop)/2; gint64 span = (stop - start)/2; if (i>0) span /= i; else span *= -i; span = span < minSpan ? minSpan : span; start = mid - span; stop = mid + span; if (start > stop) { start = mid - 1; stop = mid + 1; } start = (start < 0) ? 0 : start; stop = (stop >= now) ? 0 : stop; m_Markers[eStart]->set(start); m_Markers[eStop]->set(stop); m_bFrozen = false; Update(); } void Scope_Window::pan(int i) { gint64 start = i + (gint64) m_Markers[eStart]->getVal(); gint64 stop = (gint64) m_Markers[eStop]->getVal(); gint64 now = (gint64) get_cycles().get(); if (start < 0 || !stop || ((stop + i) > now)) return; m_Markers[eStart]->set(start); m_Markers[eStop]->set(stop + i); } gdouble Scope_Window::getSpan() { guint64 start = m_Markers[eStart]->getVal(); guint64 stop = m_Markers[eStop]->getVal(); stop = stop ? stop : get_cycles().get(); return start > stop ? 0.0 : ((gdouble)(stop-start)); } /// mapTimeToPixel - convert time to a pixel horizontal offset. int Scope_Window::mapTimeToPixel(guint64 time) { gdouble span = getSpan(); guint64 start = m_Markers[eStart]->getVal(); return (int) ((time>start && time<=(start+span)) ? ((time-start)*m_PixmapWidth)/span : 0); } #endif //HAVE_GUI gpsim-0.30.0/gui/Makefile.in0000664000076400007640000006562613117441635012521 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # gpsim gui VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = gui ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsimgui_la_DEPENDENCIES = ../eXdbm/libgpsim_eXdbm.la \ ../src/libgpsim.la ../cli/libgpsimcli.la am__dirstamp = $(am__leading_dot)dirstamp am_libgpsimgui_la_OBJECTS = gui_break.lo gui_callbacks.lo \ gui_dialog.lo gui_init.lo gui_main.lo gui_menu.lo \ gui_processor.lo gui_regwin.lo gui_src.lo gui_src_asm.lo \ gui_src_opcode.lo gui_statusbar.lo gui_symbols.lo gui_watch.lo \ gui_breadboard.lo gui_stack.lo gui_trace.lo gui_profile.lo \ gui_stopwatch.lo gui_object.lo gui_scope.lo settings_exdbm.lo \ preferences.lo gtkextra/gtkextra-marshal.lo \ gtkextra/gtkitementry.lo gtkextra/gtksheet.lo \ gtkextra/gtkextra.lo libgpsimgui_la_OBJECTS = $(am_libgpsimgui_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libgpsimgui_la_SOURCES) DIST_SOURCES = $(libgpsimgui_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ @Y_CFLAGS@ lib_LTLIBRARIES = libgpsimgui.la libgpsimgui_la_SOURCES = gui_break.cc gui_callbacks.cc gui_dialog.cc gui_init.cc gui_main.cc \ gui_menu.cc gui_processor.cc gui_regwin.cc gui_src.cc gui_src_asm.cc \ gui_src_opcode.cc gui_statusbar.cc gui.h gui_callbacks.h \ gui_interface.h gui_symbols.cc gui_watch.cc gui_breadboard.cc \ gui_stack.cc gui_trace.cc gui_profile.cc \ gui_stopwatch.cc gui_object.cc gui_scope.cc settings_exdbm.cc \ gui_breadboard.h gui_object.h gui_processor.h gui_profile.h \ gui_register.h gui_regwin.h \ gui_scope.h gui_src.h gui_stack.h gui_statusbar.h gui_stopwatch.h \ gui_symbols.h gui_trace.h gui_watch.h \ preferences.cc preferences.h \ settings.h settings_exdbm.h \ gtkextra/gtkextra-marshal.c gtkextra/gtkextra-marshal.h \ gtkextra/gtkitementry.c gtkextra/gtkitementry.h \ gtkextra/gtksheet.c gtkextra/gtksheet.h \ gtkextra/gtkextra.c gtkextra/gtkextrafeatures.h libgpsimgui_la_LIBADD = @X_LDFLAGS@ @Y_LDFLAGS@ @GTK@ @GDK@ @GLIB@ @LIBREADLINE@ ../eXdbm/libgpsim_eXdbm.la ../src/libgpsim.la ../cli/libgpsimcli.la pixmapdir = $(datadir)/gpsim AM_CFLAGS = AM_CXXFLAGS = EXTRA_DIST = makefile.mingw gtkextra/COPYING all: all-am .SUFFIXES: .SUFFIXES: .c .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu gui/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } gtkextra/$(am__dirstamp): @$(MKDIR_P) gtkextra @: > gtkextra/$(am__dirstamp) gtkextra/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) gtkextra/$(DEPDIR) @: > gtkextra/$(DEPDIR)/$(am__dirstamp) gtkextra/gtkextra-marshal.lo: gtkextra/$(am__dirstamp) \ gtkextra/$(DEPDIR)/$(am__dirstamp) gtkextra/gtkitementry.lo: gtkextra/$(am__dirstamp) \ gtkextra/$(DEPDIR)/$(am__dirstamp) gtkextra/gtksheet.lo: gtkextra/$(am__dirstamp) \ gtkextra/$(DEPDIR)/$(am__dirstamp) gtkextra/gtkextra.lo: gtkextra/$(am__dirstamp) \ gtkextra/$(DEPDIR)/$(am__dirstamp) libgpsimgui.la: $(libgpsimgui_la_OBJECTS) $(libgpsimgui_la_DEPENDENCIES) $(EXTRA_libgpsimgui_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(libgpsimgui_la_OBJECTS) $(libgpsimgui_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f gtkextra/*.$(OBJEXT) -rm -f gtkextra/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_breadboard.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_break.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_callbacks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_dialog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_main.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_menu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_object.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_processor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_profile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_regwin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_scope.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_src.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_src_asm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_src_opcode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_stack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_statusbar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_stopwatch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_symbols.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_trace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui_watch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preferences.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings_exdbm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gtkextra/$(DEPDIR)/gtkextra-marshal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gtkextra/$(DEPDIR)/gtkextra.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gtkextra/$(DEPDIR)/gtkitementry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gtkextra/$(DEPDIR)/gtksheet.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf gtkextra/.libs gtkextra/_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f gtkextra/$(DEPDIR)/$(am__dirstamp) -rm -f gtkextra/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) gtkextra/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) gtkextra/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/gui/Makefile.am0000664000076400007640000000227013041763637012477 00000000000000# gpsim gui AM_CPPFLAGS = @X_CFLAGS@ @Y_CFLAGS@ lib_LTLIBRARIES = libgpsimgui.la libgpsimgui_la_SOURCES = gui_break.cc gui_callbacks.cc gui_dialog.cc gui_init.cc gui_main.cc \ gui_menu.cc gui_processor.cc gui_regwin.cc gui_src.cc gui_src_asm.cc \ gui_src_opcode.cc gui_statusbar.cc gui.h gui_callbacks.h \ gui_interface.h gui_symbols.cc gui_watch.cc gui_breadboard.cc \ gui_stack.cc gui_trace.cc gui_profile.cc \ gui_stopwatch.cc gui_object.cc gui_scope.cc settings_exdbm.cc \ gui_breadboard.h gui_object.h gui_processor.h gui_profile.h \ gui_register.h gui_regwin.h \ gui_scope.h gui_src.h gui_stack.h gui_statusbar.h gui_stopwatch.h \ gui_symbols.h gui_trace.h gui_watch.h \ preferences.cc preferences.h \ settings.h settings_exdbm.h \ gtkextra/gtkextra-marshal.c gtkextra/gtkextra-marshal.h \ gtkextra/gtkitementry.c gtkextra/gtkitementry.h \ gtkextra/gtksheet.c gtkextra/gtksheet.h \ gtkextra/gtkextra.c gtkextra/gtkextrafeatures.h libgpsimgui_la_LIBADD = @X_LDFLAGS@ @Y_LDFLAGS@ @GTK@ @GDK@ @GLIB@ @LIBREADLINE@ ../eXdbm/libgpsim_eXdbm.la ../src/libgpsim.la ../cli/libgpsimcli.la pixmapdir = $(datadir)/gpsim AM_CFLAGS = AM_CXXFLAGS = EXTRA_DIST = makefile.mingw gtkextra/COPYING gpsim-0.30.0/gui/gui_processor.h0000664000076400007640000000415613045306453013475 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_PROCESSOR_H__ #define __GUI_PROCESSOR_H__ #define NEW_SOURCE_BROWSER // Forward references to all of the classes. class RAM_RegisterWindow; class EEPROM_RegisterWindow; class SourceWindow; class SourceBrowser_Window; class SourceBrowserParent_Window; class Symbol_Window; class Watch_Window; class Stack_Window; class Breadboard_Window; class Trace_Window; class Profile_Window; class StopWatch_Window; class Scope_Window; class Processor; class GUIRegisterList; // The gui_processor structure ties the gui window(s) // to a pic that is being simulated. // class GUI_Processor { public: GUI_Processor(); void SetCPU(Processor *new_cpu); RAM_RegisterWindow *regwin_ram; EEPROM_RegisterWindow *regwin_eeprom; SourceWindow *source_window; SourceBrowser_Window *program_memory; SourceBrowserParent_Window *source_browser; Symbol_Window *symbol_window; Watch_Window *watch_window; Stack_Window *stack_window; Breadboard_Window *breadboard_window; Trace_Window *trace_window; Profile_Window *profile_window; StopWatch_Window *stopwatch_window; Scope_Window *scope_window; // The pic that's associated with the gui Processor *cpu; GUIRegisterList * m_pGUIRamRegisters; GUIRegisterList * m_pGUIEEPromRegisters; private: GUI_Processor(const GUI_Processor&); // Mark non-copiable }; #endif //__GUI_PROCESSOR_H__ gpsim-0.30.0/gui/gui_menu.cc0000664000076400007640000012226413045306453012561 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include "gui.h" #include "preferences.h" #include "gui_callbacks.h" #include "gui_breadboard.h" #include "gui_processor.h" #include "gui_profile.h" #include "gui_register.h" #include "gui_regwin.h" #include "gui_scope.h" #include "gui_src.h" #include "gui_stack.h" #include "gui_stopwatch.h" #include "gui_symbols.h" #include "gui_trace.h" #include "gui_watch.h" #include "../cli/input.h" // for gpsim_open() #include "../src/gpsim_interface.h" #include "../src/processor.h" GtkUIManager *ui; extern GUI_Processor *gpGuiProcessor; static void do_quit_app(GtkWidget *widget) { exit_gpsim(0); } //======================================================================== static const gchar * const authors[] = { "Scott Dattalo - ", "Ralf Forsberg - ", "Borut Ra" "\xc5\xbe" "em - ", NULL }; static void about_cb(GtkAction *action, gpointer user_data) { gtk_show_about_dialog(NULL, "authors", authors, "comments", "A simulator for Microchip PIC microcontrollers.", "version", VERSION, "website", "http://gpsim.sourceforge.net/gpsim.html", "program-name", "The GNUPIC Simulator", NULL); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //======================================================================== // // class ColorButton // // Creates a GtkColorButton and places it into a parent widget. // When the color button is clicked and changed, the signal will // call back into this class and keep track of the selected // color state. class SourceBrowserPreferences; class ColorButton { public: ColorButton (GtkWidget *pParent, GtkTextTag *pStyle, const char *label, SourceBrowserPreferences * ); ~ColorButton(); void cancel(); private: static void setColor_cb(GtkColorButton *widget, ColorButton *This); GtkTextTag *m_pStyle; GdkColor *old_color; }; //======================================================================== // // class MarginButton // // Creates a GtkCheckButton that is used to select whether line numbers, // addresses or opcodes will be displayed in the source browser margin. class MarginButton { public: enum eMarginType { eLineNumbers, eAddresses, eOpcodes }; MarginButton (GtkWidget *pParent, const char *pName, eMarginType id, SourceBrowserPreferences * ); static void toggle_cb(GtkToggleButton *widget, MarginButton *This); void set_active(); private: GtkWidget *m_button; SourceBrowserPreferences *m_prefs; eMarginType m_id; }; //======================================================================== // // class TabButton // // Creates a GtkCheckButton that is used to select whether line numbers, // addresses or opcodes will be displayed in the source browser margin. class TabButton { public: TabButton (GtkWidget *pParent, GtkWidget *pButton, int id, SourceBrowserPreferences * ); static void toggle_cb(GtkToggleButton *widget, TabButton *This); void set_active(); private: GtkWidget *m_button; SourceBrowserPreferences *m_prefs; int m_id; }; //======================================================================== // // class FontSelection // class FontSelection { public: FontSelection (GtkWidget *pParent, SourceBrowserPreferences * ); static void setFont_cb(GtkFontButton *widget, FontSelection *This); void setFont(); private: SourceBrowserPreferences *m_prefs; GtkWidget *m_fontButton; }; //======================================================================== // class SourceBrowserPreferences : public SourceWindow { public: explicit SourceBrowserPreferences(GtkWidget *pParent); ~SourceBrowserPreferences(); void apply(); void cancel(); void update(); void toggleBreak(int line); void movePC(int line); virtual int getPCLine(int page); virtual int getAddress(NSourcePage *pPage, int line); virtual bool bAddressHasBreak(int address); virtual int getOpcode(int address); void setTabPosition(int); void setFont(const char *); const char *getFont(); private: ColorButton * m_LabelColor; ColorButton * m_MnemonicColor; ColorButton * m_SymbolColor; ColorButton * m_CommentColor; ColorButton * m_ConstantColor; MarginButton * m_LineNumbers; MarginButton * m_Addresses; MarginButton * m_Opcodes; int m_currentTabPosition; int m_originalTabPosition; TabButton *m_Up; TabButton *m_Left; TabButton *m_Down; TabButton *m_Right; TabButton *m_None; FontSelection *m_FontSelector; }; //------------------------------------------------------------------------ class gpsimGuiPreferences { public: gpsimGuiPreferences(); ~gpsimGuiPreferences(); static void setup (GtkAction *action, gpointer user_data); private: gpsimGuiPreferences(const gpsimGuiPreferences&); // Non-copiable SourceBrowserPreferences *m_SourceBrowser; static void response_cb(GtkDialog *dialog, gint response_id, gpsimGuiPreferences *Self); void apply() { m_SourceBrowser->apply();} void cancel() { m_SourceBrowser->cancel();} GtkWidget *window; }; void gpsimGuiPreferences::setup (GtkAction *action, gpointer user_data) { new gpsimGuiPreferences(); } void gpsimGuiPreferences::response_cb(GtkDialog *dialog, gint response_id, gpsimGuiPreferences *Self) { if (response_id == gint(GTK_RESPONSE_CANCEL)) Self->cancel(); if (response_id == gint(GTK_RESPONSE_APPLY)) Self->apply(); delete Self; } //------------------------------------------------------------------------ // ColorButton Constructor ColorButton::ColorButton(GtkWidget *pParent, GtkTextTag *pStyle, const char *colorName, SourceBrowserPreferences *prefs) : m_pStyle(pStyle) { GtkWidget *hbox = gtk_hbox_new(0,0); gtk_box_pack_start (GTK_BOX (pParent), hbox, FALSE, TRUE, 0); g_object_get(m_pStyle, "foreground-gdk", &old_color, NULL); GtkWidget *colorButton = gtk_color_button_new_with_color(old_color); gtk_color_button_set_title(GTK_COLOR_BUTTON(colorButton), colorName); gtk_box_pack_start(GTK_BOX(hbox), colorButton, FALSE, FALSE, 0); g_signal_connect (colorButton, "color-set", G_CALLBACK(setColor_cb), this); GtkWidget *label = gtk_label_new(colorName); gtk_box_pack_start (GTK_BOX(hbox),label,FALSE,FALSE, 10); gtk_widget_show_all(hbox); } ColorButton::~ColorButton() { gdk_color_free(old_color); } //------------------------------------------------------------------------ void ColorButton::setColor_cb(GtkColorButton *widget, ColorButton *This) { GdkColor newColor; gtk_color_button_get_color (widget, &newColor); g_object_set(This->m_pStyle, "foreground-gdk", &newColor, NULL); } void ColorButton::cancel() { g_object_set(m_pStyle, "foreground-gdk", old_color, NULL); } //------------------------------------------------------------------------ MarginButton::MarginButton(GtkWidget *pParent, const char *pName, eMarginType id, SourceBrowserPreferences *prefs) : m_prefs(prefs), m_id(id) { m_button = gtk_check_button_new_with_label (pName); bool bState = false; switch (m_id) { case eLineNumbers: bState = m_prefs->margin().bLineNumbers(); break; case eAddresses: bState = m_prefs->margin().bAddresses(); break; case eOpcodes: bState = m_prefs->margin().bOpcodes(); break; } gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(m_button), bState); gtk_box_pack_start (GTK_BOX (pParent), m_button, FALSE, TRUE, 10); g_signal_connect (m_button, "toggled", G_CALLBACK(toggle_cb), this); } //------------------------------------------------------------------------ void MarginButton::toggle_cb(GtkToggleButton *widget, MarginButton *This) { This->set_active(); } void MarginButton::set_active() { bool bNewState = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_button)) ? true : false; switch (m_id) { case eLineNumbers: m_prefs->margin().enableLineNumbers(bNewState); break; case eAddresses: m_prefs->margin().enableAddresses(bNewState); break; case eOpcodes: m_prefs->margin().enableOpcodes(bNewState); break; } } //------------------------------------------------------------------------ TabButton::TabButton(GtkWidget *pParent, GtkWidget *pButton, int id, SourceBrowserPreferences *prefs) : m_button(pButton), m_prefs(prefs), m_id(id) { gtk_box_pack_start (GTK_BOX (pParent), m_button, FALSE, TRUE, 5); g_signal_connect (m_button, "toggled", G_CALLBACK(toggle_cb), this); } //------------------------------------------------------------------------ void TabButton::toggle_cb(GtkToggleButton *widget, TabButton *This) { This->set_active(); } void TabButton::set_active() { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_button))) m_prefs->setTabPosition(m_id); } //------------------------------------------------------------------------ FontSelection::FontSelection (GtkWidget *pParent, SourceBrowserPreferences *pPrefs) : m_prefs(pPrefs) { GtkWidget *frame = gtk_frame_new ("Font"); gtk_box_pack_start (GTK_BOX (pParent), frame, FALSE, TRUE, 0); GtkWidget *hbox = gtk_hbox_new(0,0); gtk_container_add (GTK_CONTAINER (frame), hbox); m_fontButton = gtk_font_button_new_with_font (m_prefs->getFont()); const char *fontDescription = "Font Selector"; gtk_font_button_set_title (GTK_FONT_BUTTON(m_fontButton), fontDescription); gtk_box_pack_start (GTK_BOX(hbox),m_fontButton,FALSE, FALSE, 0); gtk_widget_show(m_fontButton); g_signal_connect (m_fontButton, "font-set", G_CALLBACK(setFont_cb), this); GtkWidget *label = gtk_label_new("font"); gtk_box_pack_start (GTK_BOX(hbox),label,TRUE, TRUE, 10); gtk_widget_show (label); gtk_widget_show (hbox); } //------------------------------------------------------------------------ void FontSelection::setFont_cb (GtkFontButton *pFontButton, FontSelection *This) { This->setFont(); } void FontSelection::setFont() { m_prefs->setFont(gtk_font_button_get_font_name (GTK_FONT_BUTTON(m_fontButton))); } //------------------------------------------------------------------------ void SourceBrowserPreferences::toggleBreak(int line) { } void SourceBrowserPreferences::movePC(int line) { } //======================================================================== SourceBrowserPreferences::SourceBrowserPreferences(GtkWidget *pParent) : SourceWindow(0,0,false,0) { if (!gpGuiProcessor && !gpGuiProcessor->source_browser) return; GtkWidget *notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos((GtkNotebook*)notebook,GTK_POS_TOP); gtk_box_pack_start (GTK_BOX (pParent), notebook, TRUE, TRUE, 0); gtk_widget_show(notebook); m_pParent = gpGuiProcessor->source_browser; GtkWidget *label; { // Color Frame for Source Browser configuration GtkWidget *vbox = gtk_vbox_new(0,0); GtkWidget *colorFrame = gtk_frame_new ("Colors"); gtk_box_pack_start (GTK_BOX (vbox), colorFrame, FALSE, TRUE, 0); GtkWidget *colorVbox = gtk_vbox_new(0,0); gtk_container_add (GTK_CONTAINER (colorFrame), colorVbox); GtkTextTagTable *tag_table = m_pParent->getTagTable(); m_LabelColor = new ColorButton(colorVbox, gtk_text_tag_table_lookup(tag_table, "Label"), "Label", this); m_MnemonicColor = new ColorButton(colorVbox, gtk_text_tag_table_lookup(tag_table, "Mnemonic"), "Mnemonic", this); m_SymbolColor = new ColorButton(colorVbox, gtk_text_tag_table_lookup(tag_table, "Symbols"), "Symbols", this); m_ConstantColor = new ColorButton(colorVbox, gtk_text_tag_table_lookup(tag_table, "Constants"), "Constants", this); m_CommentColor = new ColorButton(colorVbox, gtk_text_tag_table_lookup(tag_table, "Comments"), "Comments", this); // Font selector m_FontSelector = new FontSelection(vbox, this); label = gtk_label_new("Font"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook),vbox,label); } { // Tab Frame for the Source browser m_currentTabPosition = m_pParent->getTabPosition(); m_originalTabPosition = m_currentTabPosition; GtkWidget *hbox = gtk_hbox_new(0,0); GtkWidget *tabFrame = gtk_frame_new ("Notebook Tabs"); gtk_box_pack_start (GTK_BOX (hbox), tabFrame, FALSE, TRUE, 0); GtkWidget *radioUp = gtk_radio_button_new_with_label (NULL,"up"); GtkRadioButton *rb = GTK_RADIO_BUTTON(radioUp); GtkWidget *tabVbox = gtk_vbox_new(0,0); gtk_container_add (GTK_CONTAINER (tabFrame), tabVbox); m_Up = new TabButton(tabVbox, radioUp, GTK_POS_TOP, this); m_Left = new TabButton(tabVbox, gtk_radio_button_new_with_label_from_widget (rb,"left"), GTK_POS_LEFT, this); m_Down = new TabButton(tabVbox, gtk_radio_button_new_with_label_from_widget (rb,"down"), GTK_POS_BOTTOM, this); m_Right = new TabButton(tabVbox, gtk_radio_button_new_with_label_from_widget (rb,"right"), GTK_POS_RIGHT, this); m_None = new TabButton(tabVbox, gtk_radio_button_new_with_label_from_widget (rb,"none"), -1, this); // Source browser margin GtkWidget *marginFrame = gtk_frame_new ("Margin"); gtk_box_pack_start (GTK_BOX (hbox), marginFrame, FALSE, TRUE, 0); GtkWidget *marginVbox = gtk_vbox_new(0,0); gtk_container_add (GTK_CONTAINER (marginFrame), marginVbox); m_LineNumbers = new MarginButton(marginVbox, "Line Numbers", MarginButton::eLineNumbers, this); m_Addresses = new MarginButton(marginVbox, "Addresses", MarginButton::eAddresses, this); m_Opcodes = new MarginButton(marginVbox, "Opcodes", MarginButton::eOpcodes, this); label = gtk_label_new("Margins"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook),hbox,label); } { SourceBuffer *pBuffer = new SourceBuffer (m_pParent->getTagTable(),0,m_pParent); GtkWidget *frame = gtk_frame_new ("Sample"); gtk_box_pack_start (GTK_BOX (pParent), frame, TRUE, TRUE, 0); m_Notebook = gtk_notebook_new(); //m_currentTabPosition = m_pParent->getTabPosition(); //gtk_notebook_set_tab_pos((GtkNotebook*)m_Notebook,m_TabPosition); setTabPosition(m_pParent->getTabPosition()); gtk_container_add (GTK_CONTAINER (frame), m_Notebook); bIsBuilt = true; AddPage (pBuffer, "file1.asm"); pBuffer->parseLine( " MOVLW 0x34 ; Comment\n",1); pBuffer->parseLine( "; Comment only\n",1); pBuffer->parseLine( "Label: ADDWF Variable,F ; Comment\n",1); gtk_widget_show_all(frame); label = gtk_label_new("file2.asm"); GtkWidget *emptyBox = gtk_hbox_new(0,0); gtk_notebook_append_page(GTK_NOTEBOOK(m_Notebook),emptyBox,label); } gtk_widget_show_all(notebook); } SourceBrowserPreferences::~SourceBrowserPreferences() { delete m_Left; delete m_Down; delete m_Right; delete m_None; delete m_Up; delete m_LabelColor; delete m_MnemonicColor; delete m_SymbolColor; delete m_CommentColor; delete m_ConstantColor; delete m_LineNumbers; delete m_Addresses; delete m_Opcodes; delete m_FontSelector; } void SourceBrowserPreferences::setTabPosition(int tabPosition) { m_currentTabPosition = tabPosition; m_pParent->setTabPosition(tabPosition); if (tabPosition >= 0) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_Notebook),TRUE); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(m_Notebook), (GtkPositionType) m_currentTabPosition); } else { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_Notebook),FALSE); } Update(); } void SourceBrowserPreferences::setFont(const char *cpFont) { m_pParent->setFont(cpFont); } const char *SourceBrowserPreferences::getFont() { return m_pParent->getFont(); } void SourceBrowserPreferences::apply() { m_pParent->setTabPosition(m_currentTabPosition); } void SourceBrowserPreferences::cancel() { m_LabelColor->cancel(); m_MnemonicColor->cancel(); m_SymbolColor->cancel(); m_ConstantColor->cancel(); m_CommentColor->cancel(); m_pParent->setTabPosition(m_originalTabPosition); } int SourceBrowserPreferences::getPCLine(int page) { return 1; } int SourceBrowserPreferences::getAddress(NSourcePage *pPage, int line) { return 0x1234; } bool SourceBrowserPreferences::bAddressHasBreak(int address) { return false; } int SourceBrowserPreferences::getOpcode(int address) { return 0xABCD; } //======================================================================== gpsimGuiPreferences::gpsimGuiPreferences() { window = gtk_dialog_new_with_buttons("Source Browser configuration", NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, gint(GTK_RESPONSE_CANCEL), GTK_STOCK_APPLY, gint(GTK_RESPONSE_APPLY), NULL); g_signal_connect(window, "response", G_CALLBACK(gpsimGuiPreferences::response_cb), this); GtkWidget *box = gtk_dialog_get_content_area(GTK_DIALOG(window)); m_SourceBrowser = new SourceBrowserPreferences(box); gtk_widget_show_all(window); } gpsimGuiPreferences::~gpsimGuiPreferences() { gtk_widget_destroy (window); delete m_SourceBrowser; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //======================================================================== void gui_message(const char *message); static void update_preview(GtkFileChooser *file_chooser, gpointer data) { gchar *file = gtk_file_chooser_get_preview_filename(file_chooser); gboolean show = FALSE; if (file) { size_t len = strlen(file); if (len >= 4) { gchar *p = file + len - 4; if (!strcmp(p, ".hex") || !strcmp(p, ".HEX")) { show = TRUE; } } } g_free(file); gtk_file_chooser_set_preview_widget_active(file_chooser, show); } static void file_selection_changed(GtkTreeSelection *sel, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; gchar *processor; gchar **d = (gchar **)data; if (gtk_tree_selection_get_selected(sel, &model, &iter)) { gtk_tree_model_get (model, &iter, 0, &processor, -1); gchar *p = *d; if (p) { g_free(p); } *d = processor; } } static void fileopen_dialog(GtkAction *action, gpointer user_data) { GtkWidget *dialog = gtk_file_chooser_dialog_new("Open file", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); GtkFileFilter *filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, "Gpsim"); gtk_file_filter_add_pattern(filter, "*.cod"); gtk_file_filter_add_pattern(filter, "*.COD"); gtk_file_filter_add_pattern(filter, "*.stc"); gtk_file_filter_add_pattern(filter, "*.STC"); gtk_file_filter_add_pattern(filter, "*.hex"); gtk_file_filter_add_pattern(filter, "*.HEX"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*"); gtk_file_filter_set_name(filter, "All files"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); GtkListStore *pic_list = gtk_list_store_new(1, G_TYPE_STRING); ProcessorConstructorList::iterator processor_iterator; ProcessorConstructorList *pl = ProcessorConstructor::GetList(); for (processor_iterator = pl->begin(); processor_iterator != pl->end(); ++processor_iterator) { ProcessorConstructor *p = *processor_iterator; GtkTreeIter iter; gtk_list_store_append(pic_list, &iter); gtk_list_store_set(pic_list, &iter, 0, p->names[1], -1); } GtkWidget *scroll_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(pic_list)); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("Processor", renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), TRUE); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_container_add(GTK_CONTAINER(scroll_window), tree); gtk_widget_show_all(scroll_window); gchar *processor = NULL; gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), scroll_window); gtk_file_chooser_set_use_preview_label(GTK_FILE_CHOOSER(dialog), FALSE); g_signal_connect(selection, "changed", G_CALLBACK(file_selection_changed), (gpointer)&processor); g_signal_connect(dialog, "update-preview", G_CALLBACK(update_preview), NULL); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *use_processor = NULL; if (filename) { size_t len = strlen(filename); if (len >= 4) { gchar *p = filename + len - 4; if (!strcmp(p, ".hex") || !strcmp(p, ".HEX")) { use_processor = processor; } } } if (!gpsim_open(gpGuiProcessor->cpu, filename, use_processor, 0)) { gchar *msg = g_strdup_printf( "Open failed. Could not open \"%s\"", filename); gui_message(msg); g_free(msg); } g_free(filename); } g_free(processor); g_object_unref(pic_list); gtk_widget_destroy(tree); gtk_widget_destroy(dialog); } // Menuhandler for Windows menu buttons static void toggle_window(GtkToggleAction *action, gpointer user_data) { if (gpGuiProcessor) { std::string item = gtk_action_get_name(GTK_ACTION(action)); gboolean view_state = gtk_toggle_action_get_active(action); if (item == "Program memory") { gpGuiProcessor->program_memory->ChangeView(view_state); } else if (item == "Source") { gpGuiProcessor->source_browser->ChangeView(view_state); } else if (item == "Ram") { gpGuiProcessor->regwin_ram->ChangeView(view_state); } else if (item == "EEPROM") { gpGuiProcessor->regwin_eeprom->ChangeView(view_state); } else if (item == "Watch") { gpGuiProcessor->watch_window->ChangeView(view_state); } else if (item == "Symbols") { gpGuiProcessor->symbol_window->ChangeView(view_state); } else if (item == "Breadboard") { gpGuiProcessor->breadboard_window->ChangeView(view_state); } else if (item == "Stack") { gpGuiProcessor->stack_window->ChangeView(view_state); } else if (item == "Trace") { gpGuiProcessor->trace_window->ChangeView(view_state); } else if (item == "Profile") { gpGuiProcessor->profile_window->ChangeView(view_state); } else if (item == "Stopwatch") { gpGuiProcessor->stopwatch_window->ChangeView(view_state); } else if (item == "Scope") { gpGuiProcessor->scope_window->ChangeView(view_state); } } } //======================================================================== // Button callbacks static void runbutton_cb(GtkWidget *widget) { get_interface().start_simulation(); } static void stopbutton_cb(GtkWidget *widget) { if(gpGuiProcessor && gpGuiProcessor->cpu) gpGuiProcessor->cpu->pma->stop(); } static void stepbutton_cb(GtkWidget *widget) { if(gpGuiProcessor && gpGuiProcessor->cpu) gpGuiProcessor->cpu->pma->step(1); } static void overbutton_cb(GtkWidget *widget) { if(gpGuiProcessor && gpGuiProcessor->cpu) gpGuiProcessor->cpu->pma->step_over(); } static void finishbutton_cb(GtkWidget *widget) { if(gpGuiProcessor && gpGuiProcessor->cpu) gpGuiProcessor->cpu->pma->finish(); } static void resetbutton_cb(GtkWidget *widget) { if(gpGuiProcessor && gpGuiProcessor->cpu) gpGuiProcessor->cpu->reset(POR_RESET); } int gui_animate_delay; // in milliseconds //======================================================================== //======================================================================== // // UpdateRateMenuItem //======================================================================== // // Class declaration -- probaby should move to a .h file. class UpdateRateMenuItem { public: UpdateRateMenuItem(GtkWidget *,char, const char *, int update_rate=0, bool _bRealTime=false, bool _bWithGui=false); void Select(); private: int update_rate; public: char id; private: bool bAnimate; bool bRealTime; bool bWithGui; }; UpdateRateMenuItem::UpdateRateMenuItem(GtkWidget *parent, char _id, const char *label, int _update_rate, bool _bRealTime, bool _bWithGui) : update_rate(_update_rate), id(_id), bRealTime(_bRealTime), bWithGui(_bWithGui) { if (update_rate < 0) { bAnimate = true; update_rate = -update_rate; } else bAnimate = false; gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(parent), label); } void UpdateRateMenuItem::Select() { EnableRealTimeMode(bRealTime); EnableRealTimeModeWithGui(bWithGui); if(bAnimate) { gui_animate_delay = update_rate; get_interface().set_update_rate(1); } else { gui_animate_delay = 0; get_interface().set_update_rate(update_rate); } if(gpGuiProcessor && gpGuiProcessor->cpu) gpGuiProcessor->cpu->pma->stop(); config_set_variable("dispatcher", "SimulationMode", id); } //======================================================================== //======================================================================== class TimeWidget; class TimeFormatter { public: enum eMenuID { eCyclesHex=0, eCyclesDec, eMicroSeconds, eMilliSeconds, eSeconds, eHHMMSS } time_format; TimeFormatter(TimeWidget *_tw,GtkWidget *menu, const char*menu_text) : tw(_tw) { AddToMenu(menu,menu_text); } virtual ~TimeFormatter() { } void ChangeFormat(); void AddToMenu(GtkWidget *menu, const char*menu_text); virtual void Format(char *, int)=0; TimeWidget *tw; }; class TimeWidget : public EntryWidget { public: TimeWidget(); void Create(GtkWidget *); virtual void Update(); void NewFormat(TimeFormatter *tf); TimeFormatter *current_format; GtkWidget *menu; }; class TimeMicroSeconds : public TimeFormatter { public: TimeMicroSeconds(TimeWidget *tw, GtkWidget *menu) : TimeFormatter(tw,menu,"MicroSeconds") {} virtual ~TimeMicroSeconds() { } void Format(char *buf, int size) { double time_db = 0.; if(gpGuiProcessor && gpGuiProcessor->cpu) time_db = gpGuiProcessor->cpu->get_InstPeriod() * get_cycles().get() * 1e6; g_snprintf(buf,size, "%19.2f us",time_db); } }; class TimeMilliSeconds : public TimeFormatter { public: TimeMilliSeconds(TimeWidget *tw, GtkWidget *menu) : TimeFormatter(tw,menu,"MilliSeconds") {} virtual ~TimeMilliSeconds() { } void Format(char *buf, int size) { double time_db = 0.; if(gpGuiProcessor && gpGuiProcessor->cpu) time_db = gpGuiProcessor->cpu->get_InstPeriod() * get_cycles().get() * 1e3; g_snprintf(buf,size, "%19.3f ms",time_db); } }; class TimeSeconds : public TimeFormatter { public: TimeSeconds(TimeWidget *tw, GtkWidget *menu) : TimeFormatter(tw,menu,"Seconds") {} virtual ~TimeSeconds() { } void Format(char *buf, int size) { double time_db = 0.; if(gpGuiProcessor && gpGuiProcessor->cpu) time_db = gpGuiProcessor->cpu->get_InstPeriod() * get_cycles().get(); g_snprintf(buf,size, "%19.3f Sec",time_db); } }; class TimeHHMMSS : public TimeFormatter { public: TimeHHMMSS(TimeWidget *tw, GtkWidget *menu) : TimeFormatter(tw,menu,"HH:MM:SS.mmm") {} virtual ~TimeHHMMSS() { } void Format(char *buf, int size) { double time_db = 0.; if(gpGuiProcessor && gpGuiProcessor->cpu) time_db = gpGuiProcessor->cpu->get_InstPeriod() * get_cycles().get(); double v=time_db + 0.005; // round msec int hh=(int)(v/3600),mm,ss,cc; v-=hh*3600.0; mm=(int)(v/60); v-=mm*60.0; ss=(int)v; cc=(int)((v-ss)*100.0); g_snprintf(buf,size," %02d:%02d:%02d.%02d",hh,mm,ss,cc); } }; class TimeCyclesHex : public TimeFormatter { public: TimeCyclesHex(TimeWidget *tw, GtkWidget *menu) : TimeFormatter(tw,menu,"Cycles (Hex)") {} virtual ~TimeCyclesHex() { } void Format(char *buf, int size) { g_snprintf(buf,size,"0x%016" PRINTF_GINT64_MODIFIER "x",get_cycles().get()); } }; class TimeCyclesDec : public TimeFormatter { public: TimeCyclesDec(TimeWidget *tw, GtkWidget *menu) : TimeFormatter(tw,menu,"Cycles (Dec)") {} virtual ~TimeCyclesDec() { } void Format(char *buf, int size) { g_snprintf(buf,size,"%016" PRINTF_GINT64_MODIFIER "d",get_cycles().get()); } }; //======================================================================== // called when user has selected a menu item from the time format menu static void cbTimeFormatActivated(GtkWidget *widget, gpointer data) { if(!widget || !data) return; TimeFormatter *tf = static_cast(data); tf->ChangeFormat(); } // button press handler static gint cbTimeFormatPopup(GtkWidget *widget, GdkEventButton *event, TimeWidget *tw) { if(!widget || !event || !tw) return 0; if(event->type == GDK_BUTTON_PRESS) { gtk_menu_popup(GTK_MENU(tw->menu), 0, 0, 0, 0, 3, event->time); // It looks like we need it to avoid a selection in the entry. // For this we tell the entry to stop reporting this event. g_signal_stop_emission_by_name(tw->entry, "button_press_event"); } return FALSE; } void TimeFormatter::ChangeFormat() { if(tw) tw->NewFormat(this); } void TimeFormatter::AddToMenu(GtkWidget *menu, const char*menu_text) { GtkWidget *item = gtk_menu_item_new_with_label(menu_text); g_signal_connect(item, "activate", G_CALLBACK(cbTimeFormatActivated), this); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } void TimeWidget::Create(GtkWidget *container) { set_editable(false); gtk_container_add(GTK_CONTAINER(container),entry); SetEntryWidth(18); menu = gtk_menu_new(); // Create an entry for each item in the formatter pop up window. new TimeMicroSeconds(this,menu); new TimeMilliSeconds(this,menu); new TimeSeconds(this,menu); new TimeHHMMSS(this,menu); new TimeCyclesHex(this,menu); NewFormat(new TimeCyclesDec(this,menu)); // Associate a callback with the user button-click actions g_signal_connect(entry, "button_press_event", G_CALLBACK(cbTimeFormatPopup), this); } void TimeWidget::NewFormat(TimeFormatter *tf) { if(tf && tf != current_format) { current_format = tf; Update(); } } void TimeWidget::Update() { if(!current_format) return; char buffer[32]; current_format->Format(buffer, sizeof(buffer)); gtk_entry_set_text (GTK_ENTRY (entry), buffer); } TimeWidget::TimeWidget() { menu = 0; current_format =0; } //======================================================================== static int dispatcher_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { do_quit_app(0); return 0; } static const GtkActionEntry entries[] = { {"FileMenu", NULL, "_File"}, {"Open", GTK_STOCK_OPEN, "_Open", "O", NULL, G_CALLBACK(fileopen_dialog)}, {"Quit", GTK_STOCK_QUIT, "_Quit", "Q", "Quit", G_CALLBACK(do_quit_app)}, {"Windows", NULL, "_Windows"}, {"Edit", NULL, "_Edit"}, {"Preferences", GTK_STOCK_PREFERENCES, "Preferences", NULL, NULL, G_CALLBACK(gpsimGuiPreferences::setup)}, {"Help", NULL, "_Help"}, {"About", GTK_STOCK_ABOUT, "_About", NULL, NULL, G_CALLBACK(about_cb)} }; static const GtkToggleActionEntry toggle_entries[] = { {"Program memory", NULL, "Program _memory", NULL, NULL, G_CALLBACK(toggle_window)}, {"Source", NULL, "_Source", NULL, NULL, G_CALLBACK(toggle_window)}, {"Ram", NULL, "_Ram", NULL, NULL, G_CALLBACK(toggle_window)}, {"EEPROM", NULL, "_EEPROM", NULL, NULL, G_CALLBACK(toggle_window)}, {"Watch", NULL, "_Watch", NULL, NULL, G_CALLBACK(toggle_window)}, {"Stack", NULL, "Sta_ck", NULL, NULL, G_CALLBACK(toggle_window)}, {"Symbols", NULL, "Symbo_ls", NULL, NULL, G_CALLBACK(toggle_window)}, {"Breadboard", NULL, "_Breadboard", NULL, NULL, G_CALLBACK(toggle_window)}, {"Trace", NULL, "_Trace", NULL, NULL, G_CALLBACK(toggle_window)}, {"Profile", NULL, "Pro_file", NULL, NULL, G_CALLBACK(toggle_window)}, {"Stopwatch", NULL, "St_opwatch", NULL, NULL, G_CALLBACK(toggle_window)}, {"Scope", NULL, "Sco_pe", NULL, NULL, G_CALLBACK(toggle_window)} }; static const gchar *ui_info = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; GtkWidget *dispatcher_window = 0; //======================================================================== //======================================================================== class MainWindow { public: void Update(); MainWindow(); ~MainWindow(); private: static void gui_update_cb(GtkWidget *widget, gpointer data); TimeWidget timeW; std::vector rate_menu_items; }; MainWindow * TheWindow; MainWindow::~MainWindow() { } void MainWindow::Update() { timeW.Update(); } void MainWindow::gui_update_cb(GtkWidget *widget, gpointer data) { gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); MainWindow *main_window = static_cast(data); main_window->rate_menu_items[index].Select(); } MainWindow::MainWindow() { GtkWidget *box1; GtkWidget *buttonbox; GtkWidget *separator; GtkWidget *button; GtkWidget *frame; int x,y,width,height; GtkWidget *update_rate_menu; int SimulationMode; dispatcher_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); if(!config_get_variable("dispatcher", "x", &x)) x=10; if(!config_get_variable("dispatcher", "y", &y)) y=10; if(!config_get_variable("dispatcher", "width", &width)) width=1; if(!config_get_variable("dispatcher", "height", &height)) height=1; gtk_window_resize(GTK_WINDOW(dispatcher_window), width, height); gtk_window_move(GTK_WINDOW(dispatcher_window), x, y); g_signal_connect (dispatcher_window, "delete-event", G_CALLBACK(dispatcher_delete_event), 0); GtkActionGroup *actions = gtk_action_group_new("Actions"); gtk_action_group_add_actions(actions, entries, G_N_ELEMENTS(entries), NULL); gtk_action_group_add_toggle_actions(actions, toggle_entries, G_N_ELEMENTS(toggle_entries), NULL); ui = gtk_ui_manager_new(); gtk_ui_manager_insert_action_group(ui, actions, 0); g_object_unref(actions); gtk_window_add_accel_group(GTK_WINDOW(dispatcher_window), gtk_ui_manager_get_accel_group(ui)); if (!gtk_ui_manager_add_ui_from_string(ui, ui_info, -1, NULL)) { g_error("building menus failed"); } gtk_window_set_title (GTK_WINDOW (dispatcher_window), VERSION); gtk_container_set_border_width (GTK_CONTAINER (dispatcher_window), 0); box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (dispatcher_window), box1); gtk_box_pack_start (GTK_BOX (box1), gtk_ui_manager_get_widget(ui, "/menu"), FALSE, FALSE, 0); buttonbox = gtk_hbox_new(FALSE,0); gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 1); gtk_box_pack_start (GTK_BOX (box1), buttonbox, TRUE, TRUE, 0); // Buttons button = gtk_button_new_with_label ("step"); g_signal_connect(button, "clicked", G_CALLBACK(stepbutton_cb), 0); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_label ("over"); g_signal_connect(button, "clicked", G_CALLBACK(overbutton_cb), 0); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_label ("finish"); g_signal_connect(button, "clicked", G_CALLBACK(finishbutton_cb), 0); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_label ("run"); g_signal_connect(button, "clicked", G_CALLBACK(runbutton_cb), 0); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_label ("stop"); g_signal_connect(button, "clicked", G_CALLBACK(stopbutton_cb), 0); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_label ("reset"); g_signal_connect(button, "clicked", G_CALLBACK(resetbutton_cb), 0); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); // // Simulation Mode Frame // frame = gtk_frame_new("Simulation mode"); if(!config_get_variable("dispatcher", "SimulationMode", &SimulationMode)) { SimulationMode='4'; } // // Gui Update Rate // update_rate_menu = gtk_combo_box_text_new(); gtk_container_add(GTK_CONTAINER(frame),update_rate_menu); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'5',"Without gui (fastest simulation)",0)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'4',"2000000 cycles/gui update",2000000)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'3',"100000 cycles/gui update",100000)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'2',"1000 cycles/gui update",1000)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'1',"Update gui every cycle",1)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'b',"100ms animate",-100)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'c',"300ms animate",-300)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'d',"700ms animate",-700)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'r',"Realtime without gui",0,true)); rate_menu_items.push_back( UpdateRateMenuItem(update_rate_menu,'R',"Realtime with gui",0,true,true)); for (size_t i = 0 ; i < rate_menu_items.size(); ++i) { if (rate_menu_items[i].id == SimulationMode) { rate_menu_items[i].Select(); gtk_combo_box_set_active(GTK_COMBO_BOX(update_rate_menu), i); } } g_signal_connect(update_rate_menu, "changed", G_CALLBACK(gui_update_cb), this); gtk_box_pack_start (GTK_BOX (buttonbox), frame, FALSE, FALSE, 5); // // Simulation Time Frame // frame = gtk_frame_new("Simulation Time"); gtk_box_pack_start (GTK_BOX (buttonbox), frame, FALSE, FALSE, 5); timeW.Create(frame); timeW.Update(); //gtk_box_pack_start (GTK_BOX (buttonbox), frame, TRUE, TRUE, 5); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5); button = gtk_button_new_with_label ("Quit gpsim"); g_signal_connect(button, "clicked", G_CALLBACK(do_quit_app), 0); gtk_box_pack_start (GTK_BOX (box1), button, FALSE, TRUE, 5); gtk_widget_show_all (dispatcher_window); } //======================================================================== void create_dispatcher () { if (!TheWindow) TheWindow = new MainWindow; } void dispatch_Update() { if (TheWindow && gpGuiProcessor && gpGuiProcessor->cpu) { TheWindow->Update(); } } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_src_asm.cc0000664000076400007640000016476413041763636013265 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include "gui.h" #include "gui_src.h" #include "gui_profile.h" #include "gui_symbols.h" #include "gui_statusbar.h" #include "gui_watch.h" #include #include #include #include #include #include #include "../src/fopen-path.h" //====================================================================== // // When a user right-clicks in the source browser, a menu will popup. // There can only be one menu active at any given time. // // 'aPopupMenu' pointer is a local pointer to a GtkMenu. // static GtkWidget *aPopupMenu; // // 'pViewContainingPopup' is a pointer to the GtkTextView that was active // when the popup menu was opened. // static GtkTextView *pViewContainingPopup; //------------------------------------------------------------------------ // static char *strReverse(const char *start, char *dest, int nChars) { *dest-- = 0; while (nChars--) *dest-- = *start++; dest++; return dest; } //======================================================================== class SourceXREF : public CrossReferenceToGUI { public: void Update(int new_value) { SourceWindow *sbaw = static_cast(parent_window); if(sbaw->bSourceLoaded()) sbaw->SetPC(new_value); } void Remove() {} }; #define BP_PIXEL_SIZE 10 #define PC_PIXEL_SIZE 10 #define MARGIN_WIDTH (PC_PIXEL_SIZE + BP_PIXEL_SIZE) #define PC_START (MARGIN_WIDTH - PC_PIXEL_SIZE) #define BP_START (MARGIN_WIDTH - PC_PIXEL_SIZE-BP_PIXEL_SIZE) /* This function is taken from gtk+/tests/testtext.c */ static void gtk_source_view_get_lines(GtkTextView *text_view, gint first_y, gint last_y, std::vector &buffer_coords, std::vector &numbers) { GtkTextIter iter; gint last_line_num = -1; buffer_coords.clear(); numbers.clear(); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, first_y, NULL); /* For each iter, get its location and add it to the arrays. * Stop when we pass last_y */ while (!gtk_text_iter_is_end (&iter)) { gint y, height; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); last_line_num = gtk_text_iter_get_line (&iter); buffer_coords.push_back(y); numbers.push_back(last_line_num); if ((y + height) >= last_y) break; gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { buffer_coords.push_back(y); numbers.push_back(line_num); } } } //------------------------------------------------------------------------ // gboolean NSourcePage::KeyPressHandler(GtkTextView *pView, GdkEventKey *key, NSourcePage *page) { guint modifiers = gtk_accelerator_get_default_mod_mask(); if ((key->state & modifiers) != 0) { return FALSE; } GtkTextBuffer *pBuffer = gtk_text_view_get_buffer(pView); GtkTextMark *pMark = gtk_text_buffer_get_insert(pBuffer); GtkTextIter iter; gtk_text_buffer_get_iter_at_mark (pBuffer, &iter, pMark); int line = gtk_text_iter_get_line (&iter); Dprintf(("Received key press for view. line=%d page%p\n",line,page)); switch (key->keyval) { case 'b': case 'B': page->m_Parent->toggleBreak(page, line); break; default: return FALSE; } return TRUE; } gint NSourcePage::ViewExposeEventHandler(GtkTextView *pView, GdkEventExpose *pEvent, NSourcePage *pPage) { if (pEvent->window == gtk_text_view_get_window (pView, GTK_TEXT_WINDOW_LEFT)) { //gtk_source_view_paint_margin (view, event); //event_handled = TRUE; Dprintf(("Expose event for view margin %p\n",pSW)); gint y1 = pEvent->area.y; gint y2 = y1 + pEvent->area.height; gtk_text_view_window_to_buffer_coords (pView, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (pView, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); pPage->updateMargin(y1,y2); } else { Dprintf(("Expose event for view %p\n",pSW)); } return FALSE; } //------------------------------------------------------------------------ // gboolean SourceWindow::KeyPressHandler(GtkWidget *widget, GdkEventKey *key, SourceWindow *pSW) { if (!pSW || !key) return FALSE; guint modifiers = gtk_accelerator_get_default_mod_mask(); if ((key->state & modifiers) == GDK_CONTROL_MASK && key->keyval == 'f') { NSourcePage *page = pSW->pages[pSW->m_currentPage]; if (!page) return FALSE; pViewContainingPopup = page->getView(); pSW->findText(); return TRUE; } if ((key->state & modifiers) != 0) { return FALSE; } switch (key->keyval) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': pSW->step(key->keyval - '0'); break; case 's': case 'S': case GDK_KEY_F7: pSW->step(); break; case 'o': case 'O': case GDK_KEY_F8: pSW->step_over(); break; case 'r': case 'R': case GDK_KEY_F9: pSW->run(); break; case 'f': case 'F': pSW->finish(); break; case GDK_KEY_Escape: pSW->stop(); break; default: return FALSE; } return TRUE; } typedef enum { MENU_FIND_TEXT, MENU_FIND_PC, MENU_MOVE_PC, MENU_RUN_HERE, MENU_BP_HERE, MENU_SELECT_SYMBOL, MENU_STEP, MENU_STEP_OVER, MENU_RUN, MENU_STOP, MENU_FINISH, MENU_RESET, MENU_PROFILE_START_HERE, MENU_PROFILE_STOP_HERE, MENU_ADD_TO_WATCH, } menu_id; typedef struct _menu_item { const char *name; menu_id id; } menu_item; static const menu_item menu_items[] = { {"Find PC", MENU_FIND_PC}, {"Run to here", MENU_RUN_HERE}, {"Move PC here", MENU_MOVE_PC}, {"Breakpoint here", MENU_BP_HERE}, {"Profile start here", MENU_PROFILE_START_HERE}, {"Profile stop here", MENU_PROFILE_STOP_HERE}, {"Add to watch", MENU_ADD_TO_WATCH}, {"Find text...", MENU_FIND_TEXT}, }; static const menu_item submenu_items[] = { {"Step", MENU_STEP}, {"Step Over", MENU_STEP_OVER}, {"Run", MENU_RUN}, {"Stop", MENU_STOP}, {"Reset", MENU_RESET}, {"Finish", MENU_FINISH}, }; //------------------------------------------------------------------------ // ButtonPressHandler // Event handler for text view mouse clicks. gint NSourcePage::ButtonPressHandler(GtkTextView *pView, GdkEventButton *pButton, NSourcePage *pPage) { if (pButton->window == gtk_text_view_get_window (pView, GTK_TEXT_WINDOW_LEFT)) { // Margin gint y; gtk_text_view_window_to_buffer_coords (pView, GTK_TEXT_WINDOW_LEFT, (gint) pButton->x, (gint) pButton->y, NULL, &y); GtkTextIter iter; gtk_text_view_get_line_at_y (pView, &iter, y, NULL); gint line = gtk_text_iter_get_line (&iter); pPage->m_Parent->toggleBreak(pPage, line); } else { // Text (i.e. not the margin if (pButton->button == 3 && aPopupMenu && GTK_IS_TEXT_VIEW(pView)) { GtkTextIter iter; gint y; pViewContainingPopup = pView; gtk_text_view_window_to_buffer_coords(pView, GTK_TEXT_WINDOW_LEFT, (gint) pButton->x, (gint) pButton->y, NULL, &y); gtk_text_view_get_line_at_y(pView, &iter, y, NULL); pPage->getParent()->m_LineAtButtonClick = gtk_text_iter_get_line(&iter); gtk_menu_popup(GTK_MENU(aPopupMenu), 0, 0, 0, 0, 3, pButton->time); GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(pView); gboolean selected = gtk_text_buffer_get_has_selection(text_buffer); // Move cursor if no text is selected if (!selected) { gtk_text_buffer_place_cursor(text_buffer, &iter); } return TRUE; } } return FALSE; } //======================================================================== int SourceWindow::DeleteEventHandler(GtkWidget *widget, GdkEvent *event, SourceWindow *sw) { sw->ChangeView(VIEW_HIDE); return TRUE; } //======================================================================== // Helper functions for parsing static int isString(const char *cP) { int i=0; if (isalpha(*cP) || *cP=='_') while (isalnum(cP[i]) || cP[i]=='_') i++; return i; } static int isWhiteSpace(const char *cP) { int i=0; while (cP[i]==' ' || cP[i]=='\t') i++; return i; } static int isHexNumber(const char *c) { const char *start = c; if (*c == '0') { ++c; if (*c == 'x' || *c == 'X') ++c; else return 1; } else if (*c == '$') { ++c; } else if (*c == 'H') { ++c; if (*c == '\'') ++c; else return 0; } if (!isxdigit(*c)) return 0; while (isxdigit(*c)) { ++c; } return c - start; } static int isNumber(const char *cP) { int i=isHexNumber(cP); if (!i) while (isdigit(cP[i])) i++; return i; } static bool isEnd(const char c) { return c=='\n' || c==0; } static int isComment(const char *cP) { int i = (*cP==';') ? 1 : 0; if (i) while (!isEnd(cP[i])) i++; return i; } //------------------------------------------------------------------------ class SearchDialog { public: SearchDialog(); void Show(SourceWindow *); bool bDirection(); bool bCase(); private: int m_iStart; GtkWidget *m_Window; // The Search Dialog Window GtkWidget *m_Entry; // Widget that holds the search text. GtkWidget *m_BackButton; // GtkWidget *m_CaseButton; // SourceWindow *m_pSourceWindow; // The last source window that requested a search. void find(const char *); static void response(GtkDialog *dialog, gint response, SearchDialog *sd); static void activate(GtkEntry *entry, SearchDialog *sd); static void icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data); }; //------------------------------------------------------------------------ SearchDialog::SearchDialog() : m_iStart(0), m_pSourceWindow(0) { m_Window = gtk_dialog_new_with_buttons( "Find", NULL, GtkDialogFlags(0), "_Find", 1, "_Close", GTK_RESPONSE_CLOSE, NULL); GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(m_Window)); gtk_dialog_set_default_response(GTK_DIALOG(m_Window), 1); g_signal_connect(m_Window, "response", G_CALLBACK(response), this); g_signal_connect_swapped(m_Window, "delete_event", G_CALLBACK (gtk_widget_hide), GTK_OBJECT(m_Window)); GtkWidget *hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(content_area), hbox, FALSE, TRUE, 0); GtkWidget *label = gtk_label_new("Find:"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); m_Entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox), m_Entry, TRUE, TRUE, 0); gtk_widget_grab_focus(m_Entry); gtk_entry_set_icon_from_stock(GTK_ENTRY(m_Entry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND); gtk_entry_set_icon_from_stock(GTK_ENTRY(m_Entry), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); gtk_entry_set_icon_activatable(GTK_ENTRY(m_Entry), GTK_ENTRY_ICON_SECONDARY, TRUE); gtk_entry_set_icon_sensitive(GTK_ENTRY(m_Entry), GTK_ENTRY_ICON_SECONDARY, TRUE); gtk_entry_set_icon_tooltip_text(GTK_ENTRY(m_Entry), GTK_ENTRY_ICON_SECONDARY, "Clear text"); g_signal_connect(m_Entry, "activate", G_CALLBACK(activate), this); g_signal_connect(m_Entry, "icon-press", G_CALLBACK(icon_press), NULL); hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(content_area), hbox, FALSE, TRUE, 0); m_CaseButton = gtk_check_button_new_with_label("Case Sensitive"); gtk_box_pack_start(GTK_BOX(hbox), m_CaseButton, FALSE, FALSE, 0); m_BackButton = gtk_check_button_new_with_label("Find Backwards"); gtk_box_pack_start(GTK_BOX(hbox), m_BackButton, FALSE, FALSE, 0); } bool SearchDialog::bDirection() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_BackButton)) == TRUE; } bool SearchDialog::bCase() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_CaseButton)) == TRUE; } void SearchDialog::find(const char *cpPattern) { if (m_pSourceWindow) m_iStart = m_pSourceWindow->findText(cpPattern,m_iStart,!bDirection(), bCase()); } void SearchDialog::response(GtkDialog *dialog, gint response, SearchDialog *sd) { switch (response) { case 1: { const char *p = gtk_entry_get_text(GTK_ENTRY(sd->m_Entry)); sd->find(p); } break; default: gtk_widget_hide(GTK_WIDGET(dialog)); } } void SearchDialog::activate(GtkEntry *entry, SearchDialog *sd) { const char *p = gtk_entry_get_text(entry); sd->find(p); } void SearchDialog::icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data) { gtk_entry_set_text(entry, ""); } void SearchDialog::Show(SourceWindow *pSourceWindow) { m_pSourceWindow = pSourceWindow; m_iStart = 0; gtk_widget_show_all(m_Window); } //======================================================================== //======================================================================== SourcePageMargin::SourcePageMargin() : m_bShowLineNumbers(true), m_bShowAddresses(false), m_bShowOpcodes(true) { } //======================================================================== //======================================================================== SourceBuffer::SourceBuffer(GtkTextTagTable *pTagTable, FileContext *pFC, SourceBrowserParent_Window *pParent) : m_pParent(pParent), m_pFC(pFC), m_bParsed(false) { assert(pTagTable); assert(pParent); m_buffer = gtk_text_buffer_new (pTagTable); assert(m_buffer); } // Addtag range applies the tag state to a range of text in the buffer // using a given text style (i.e. the style contains a gtkTextTag) void SourceBuffer::addTagRange(const char *pStyle, int start_index, int end_index) { if (!pStyle) return; GtkTextIter start; GtkTextIter end; gtk_text_buffer_get_iter_at_offset (m_buffer, &start, start_index); gtk_text_buffer_get_iter_at_offset (m_buffer, &end, end_index); gtk_text_buffer_apply_tag_by_name(m_buffer, pStyle, &start, &end); } //------------------------------------------------------------------------ bool SourceBuffer::IsParsed() { return m_bParsed; } //------------------------------------------------------------------------ void SourceBuffer::parse() { if (IsParsed() || !m_pParent || !m_pFC) return; Dprintf(("parsing source buffer %s\n",m_pFC->name().c_str())); m_pParent->parseSource(this, m_pFC); m_bParsed = true; } GtkTextBuffer *SourceBuffer::getBuffer() { parse(); return m_buffer; } const char *SourceWindow::name() { return m_name.c_str(); } //------------------------------------------------------------------------ SourceWindow::SourceWindow(GUI_Processor *pgp, SourceBrowserParent_Window *pParent, bool bUseConfig, const char *newName) : GUI_Object (), m_bLoadSource(false), m_bSourceLoaded(false), m_LineAtButtonClick(-1), pma(0), status_bar(0), last_simulation_mode(eSM_INITIAL), stPSearchDialog(0), m_Notebook(0), m_pParent(pParent) { Dprintf(("Constructor \n")); gp = pgp; if (newName) m_name = newName; else m_name = "source_browser"; mProgramCounter.bIsActive = false; if (bUseConfig) { get_config(); if (enabled) Build(); } } //------------------------------------------------------------------------ void SourceWindow::step(int n) { if (pma) pma->step(n); } //------------------------------------------------------------------------ void SourceWindow::step_over() { if (pma) pma->step_over(); } //------------------------------------------------------------------------ void SourceWindow::stop() { if (pma) pma->stop(); } //------------------------------------------------------------------------ void SourceWindow::run() { // if (pma) // pma->run(); get_interface().start_simulation(); } //------------------------------------------------------------------------ void SourceWindow::finish() { if (pma) pma->finish(); } //------------------------------------------------------------------------ void SourceWindow::reset() { if (gp && gp->cpu) gp->cpu->reset(POR_RESET); } //------------------------------------------------------------------------ // toggleBreak // // void SourceWindow::toggleBreak(NSourcePage *pPage, int line) { if (pma && pPage) { int address = pma->find_address_from_line(pPage->getFC(),line+1); if (address >= 0) pma->toggle_break_at_address(address); } } //------------------------------------------------------------------------ // movePC // // void SourceWindow::movePC(int line) { } //------------------------------------------------------------------------ void SourceWindow::findText() { if (!stPSearchDialog) stPSearchDialog = new SearchDialog(); stPSearchDialog->Show(this); } //------------------------------------------------------------------------ // strcasestr is a non standard function // #if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ char *strcasestr(const char *searchee, const char *lookfor) { if (*searchee == '\0') { if (*lookfor) return NULL; return (char *) searchee; } while (*searchee != '\0') { size_t i; for (i = 0; ; ++i) { if (lookfor[i] == '\0') return (char *) searchee; if (tolower(lookfor[i]) != tolower(searchee[i])) break; } searchee++; } return NULL; } #endif //------------------------------------------------------------------------ // findText // // Search for the pattern 'pText' in the source window. // if bDirection is true then search forward. int SourceWindow::findText(const char *pText, int start, bool bDirection, bool bCase) { if (!pText) return 0; unsigned int patternLen = strlen(pText); char buff[1024]; patternLen = (patternLen < sizeof(buff)) ? patternLen : sizeof(buff) -1; const char *pattern = bDirection ? pText : strReverse(pText, &buff[patternLen], patternLen); //printf("findText %s view:%p\n",pattern,pViewContainingPopup); NSourcePage *pPage = pages[gtk_notebook_get_current_page(GTK_NOTEBOOK(m_Notebook))]; if (!pPage) return 0; GtkTextIter iStart; GtkTextIter iEnd; int line = 0; int offset = 0; int totalLines = gtk_text_buffer_get_line_count(pPage->buffer()); if (!start) { if (bDirection) { gtk_text_buffer_get_start_iter(pPage->buffer(), &iStart); gtk_text_buffer_get_iter_at_line(pPage->buffer(), &iEnd, line+1); } else { gtk_text_buffer_get_end_iter(pPage->buffer(), &iEnd); gtk_text_buffer_get_end_iter(pPage->buffer(), &iStart); gtk_text_iter_backward_line (&iStart); line = totalLines-2; } } else { gtk_text_buffer_get_iter_at_offset(pPage->buffer(), &iStart, start); line = gtk_text_iter_get_line (&iStart); if (bDirection) { if (line >= totalLines) { line = 0; gtk_text_buffer_get_iter_at_offset(pPage->buffer(), &iStart, 0); } } else { if (line <= 0) { line = totalLines-1; gtk_text_buffer_get_iter_at_line(pPage->buffer(), &iStart, line--); } } gtk_text_buffer_get_iter_at_line(pPage->buffer(), &iEnd, line); offset = start - gtk_text_iter_get_offset (&iEnd); gtk_text_buffer_get_iter_at_line(pPage->buffer(), &iEnd, line+1); } while (totalLines--) { char *str = gtk_text_buffer_get_text(pPage->buffer(), &iStart, &iEnd, FALSE); unsigned int srcLen = strlen(str); const char *cpSource = str; char buffer2[1024]; if (!bDirection) { srcLen = (srcLen < sizeof(buffer2)) ? srcLen : sizeof(buffer2)-1; cpSource = strReverse(cpSource, &buffer2[srcLen], srcLen); } const char *pFound = bCase ? strstr(cpSource, pattern) : strcasestr(cpSource, pattern); if (pFound) { int pos = bDirection ? (pFound - cpSource) : (srcLen - (pFound - cpSource)); pos += offset; //printf("Found %s in %s starting at %s, pos=%d\n",pattern, str, pFound,pos); gtk_text_view_scroll_to_iter (pViewContainingPopup, &iStart, 0.0, TRUE, 0.0, 0.3); gtk_text_buffer_get_iter_at_line_offset(pPage->buffer(), &iStart, line, pos); gtk_text_buffer_get_iter_at_line_offset(pPage->buffer(), &iEnd, line, pos+ (bDirection ? patternLen : -patternLen)); gtk_text_buffer_select_range (pPage->buffer(), &iStart, &iEnd); g_free(str); return gtk_text_iter_get_offset(bDirection ? &iEnd : &iStart); } g_free(str); // Now we'll search whole lines. offset = 0; if (bDirection) { if (gtk_text_iter_forward_line (&iStart)==FALSE) return 0; gtk_text_iter_forward_line (&iEnd); line++; } else { if (gtk_text_iter_backward_line (&iStart)==FALSE) return gtk_text_buffer_get_char_count(pPage->buffer()) - 1; gtk_text_iter_backward_line (&iEnd); line--; } } printf("Did not find %s\n",pattern); return 0; } //------------------------------------------------------------------------ void SourceWindow::cb_notebook_switchpage(GtkNotebook *notebook, gpointer page, guint page_num, SourceWindow *pSW) { pSW->switch_page_cb(page_num); } gint SourceWindow::switch_page_cb(guint newPage) { Dprintf((" Switch page call back-- page=%d\n",newPage)); if (m_currentPage != newPage) { m_currentPage = newPage; NSourcePage *pPage = pages[m_currentPage]; if (!pPage || !gp->cpu->files[pPage->get_file_id()]) return TRUE; if(gp->cpu->files[pPage->get_file_id()]->IsHLL()) pma->set_hll_mode(ProgramMemoryAccess::HLL_MODE); else pma->set_hll_mode(ProgramMemoryAccess::ASM_MODE); pPage->invalidateView(); } return TRUE; } //------------------------------------------------------------------------ static Register *findRegister(string text) { Register *pReg = dynamic_cast(globalSymbolTable().find(text)); if (!pReg) pReg = dynamic_cast(globalSymbolTable().find(text+string("_"))); if (!pReg) { toupper(text); pReg = dynamic_cast(globalSymbolTable().find(text)); } if (!pReg) pReg = dynamic_cast(globalSymbolTable().find(text+string("_"))); return pReg; } //------------------------------------------------------------------------ void SourceWindow::PopupMenuHandler(GtkWidget *widget, gpointer data) { SourceWindow *This = static_cast(data); unsigned int address; SourceWindow *pSW = 0; NSourcePage *pPage = 0; // pViewContainingPopup is initialized when the view_button_press() // event handler is called. That function also initiates the event // that invokes this callback. if (!pViewContainingPopup) { printf("Warning popup without a textview\n"); } else { pPage = This->pages[gtk_notebook_get_current_page(GTK_NOTEBOOK(This->m_Notebook))]; pSW = pPage ? pPage->getParent() : 0; } if (!pSW) { printf ("Warning (bug?): popup cannot be associate with any source\n"); return; } switch (GPOINTER_TO_SIZE(g_object_get_data(G_OBJECT(widget), "item"))) { case MENU_FIND_TEXT: pSW->findText(); break; case MENU_FIND_PC: address=pSW->pma->get_PC(); pSW->SetPC(address); break; case MENU_MOVE_PC: if(-1 != pSW->m_LineAtButtonClick) { address = pSW->pma->find_closest_address_to_line( pPage->get_file_id(), pSW->m_LineAtButtonClick + 1); if(address!=INVALID_VALUE) { pSW->pma->set_PC(address); pSW->SetPC(pSW->pma->get_PC()); } } break; case MENU_RUN_HERE: if(-1 != pSW->m_LineAtButtonClick) { address = pSW->pma->find_closest_address_to_line( pPage->get_file_id(), pSW->m_LineAtButtonClick + 1); if(address!=INVALID_VALUE) { pSW->gp->cpu->run_to_address(address); pSW->SetPC(pSW->pma->get_PC()); // RP - update GUI after running } } break; case MENU_BP_HERE: if(-1 != pSW->m_LineAtButtonClick) { pSW->toggleBreak(pPage, pSW->m_LineAtButtonClick); } break; case MENU_PROFILE_START_HERE: if(-1 != pSW->m_LineAtButtonClick) { address = pSW->pma->find_closest_address_to_line( pPage->get_file_id(), pSW->m_LineAtButtonClick + 1); pSW->gp->profile_window->StartExe(address); } break; case MENU_PROFILE_STOP_HERE: if(-1 != pSW->m_LineAtButtonClick) { address = pSW->pma->find_closest_address_to_line( pPage->get_file_id(), pSW->m_LineAtButtonClick + 1); pSW->gp->profile_window->StopExe(address); } break; case MENU_SELECT_SYMBOL: case MENU_ADD_TO_WATCH: { GtkTextBuffer *pBuffer = pPage->buffer(); GtkTextIter itBegin, itEnd; if (gtk_text_buffer_get_selection_bounds(pBuffer, &itBegin, &itEnd)) { gchar *text = gtk_text_buffer_get_text(pBuffer, &itBegin, &itEnd, FALSE); TrimWhiteSpaceFromString(text); if (text[0] != '\0') { Register *pReg = findRegister(std::string(text)); if(!pReg) { GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(pSW->window), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "The symbol '%s' does not exist as a register symbol.\n" "Only register based symbols may be added to the Watch window.", text); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } else { pSW->gp->watch_window->Add(pReg); } } g_free(text); } } break; case MENU_STEP: pSW->step(); break; case MENU_STEP_OVER: pSW->step_over(); break; case MENU_RUN: pSW->run(); break; case MENU_STOP: pSW->stop(); break; case MENU_RESET: pSW->reset(); break; case MENU_FINISH: pSW->finish(); break; default: puts("Unhandled menuitem?"); break; } } //------------------------------------------------------------------------ GtkWidget * SourceWindow::BuildPopupMenu() { GtkWidget *menu; GtkWidget *submenu; GtkWidget *item; unsigned int i; menu = gtk_menu_new(); for (i = 0; i < G_N_ELEMENTS(menu_items); ++i) { item = gtk_menu_item_new_with_label(menu_items[i].name); g_object_set_data(G_OBJECT(item), "item", GSIZE_TO_POINTER(menu_items[i].id)); g_signal_connect(item, "activate", G_CALLBACK(PopupMenuHandler), this); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } submenu = gtk_menu_new(); for (i = 0; i < G_N_ELEMENTS(submenu_items); ++i) { item = gtk_menu_item_new_with_label(submenu_items[i].name); g_object_set_data(G_OBJECT(item), "item", GSIZE_TO_POINTER(submenu_items[i].id)); g_signal_connect(item, "activate", G_CALLBACK (PopupMenuHandler), this); gtk_widget_set_can_focus(item, TRUE); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); } item = gtk_menu_item_new_with_label ("Controls"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_widget_show (item); gtk_menu_item_set_submenu(GTK_MENU_ITEM (item), submenu); return menu; } //------------------------------------------------------------------------ // Build // // void SourceWindow::Build() { Dprintf((" \n")); if(bIsBuilt) return; Dprintf((" \n")); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); // get_config(); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect(window,"key_press_event", G_CALLBACK (KeyPressHandler), (gpointer) this); g_signal_connect (window, "delete_event", G_CALLBACK (DeleteEventHandler), (gpointer) this); gtk_container_set_border_width (GTK_CONTAINER (window), 0); SetTitle(); GtkWidget *vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show(vbox); gtk_container_add (GTK_CONTAINER (window), vbox); m_Notebook = gtk_notebook_new(); m_currentPage = 0; g_signal_connect (m_Notebook, "switch-page", G_CALLBACK (cb_notebook_switchpage), (gpointer) this); gtk_notebook_set_tab_pos((GtkNotebook*)m_Notebook, GTK_POS_LEFT); gtk_notebook_set_scrollable ((GtkNotebook*)m_Notebook, TRUE); gtk_box_pack_start (GTK_BOX (vbox), m_Notebook, TRUE, TRUE, 0); status_bar = new StatusBar_Window(vbox); gtk_widget_show_all(window); gtk_widget_show_all(vbox); gtk_widget_show_all(m_Notebook); aPopupMenu = BuildPopupMenu(); bIsBuilt = true; menu = "/menu/Windows/Source"; gtk_window_set_title (GTK_WINDOW (window), "Source Browser"); UpdateMenuItem(); if(m_bLoadSource) { Dprintf((" \n")); NewSource(gp); } } //------------------------------------------------------------------------ // void SourceWindow::SetTitle() { if (!gp || !gp->cpu || !pma) return; if (last_simulation_mode != eSM_INITIAL && ((last_simulation_mode == eSM_RUNNING && gp->cpu->simulation_mode == eSM_RUNNING) || (last_simulation_mode != eSM_RUNNING && gp->cpu->simulation_mode != eSM_RUNNING)) && sLastPmaName == pma->name()) { return; } last_simulation_mode = gp->cpu->simulation_mode; const char * sStatus; if (gp->cpu->simulation_mode == eSM_RUNNING) sStatus = "Run"; else // if (gp->cpu->simulation_mode == eSM_STOPPED) sStatus = "Stopped"; char buffer[256]; g_snprintf(buffer, sizeof(buffer), "Source Browser: [%s] %s", sStatus, pma != NULL ? pma->name().c_str() : "" ); sLastPmaName = pma->name(); gtk_window_set_title (GTK_WINDOW (window), buffer); } //------------------------------------------------------------------------ // void SourceWindow::set_pma(ProgramMemoryAccess *new_pma) { Dprintf((" \n")); pma = new_pma; if(window && pma) { SetTitle(); } if(status_bar) status_bar->NewProcessor(gp, pma); } void SourceWindow::SelectAddress(int address) { Dprintf((" \n")); } void SourceWindow::SelectAddress(Value *) { Dprintf((" \n")); } //------------------------------------------------------------------------ // Update // // Called whenever the source window needs to be updated (like after break points). void SourceWindow::Update() { Dprintf((" \n")); if (!window || !enabled) return; if (m_Notebook && ((gtk_notebook_get_show_tabs(GTK_NOTEBOOK(m_Notebook))==false && m_pParent->getTabPosition()<0) || (m_pParent->getTabPosition() != gtk_notebook_get_tab_pos(GTK_NOTEBOOK(m_Notebook))))) { if (m_pParent->getTabPosition()<0) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_Notebook),FALSE); } else { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_Notebook),TRUE); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(m_Notebook), (GtkPositionType) m_pParent->getTabPosition()); } } if (m_Notebook) { gint currPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(m_Notebook)); if (currPage >= 0) { pages[currPage]->setFont(m_pParent->getFont()); } } if(!gp || !pma || ! window) return; SetTitle(); SetPC(pma->get_PC()); if(status_bar) status_bar->Update(); } //------------------------------------------------------------------------ void SourceWindow::UpdateLine(int address) { assert(address>=0); Dprintf((" UpdateLine at address=%d\n",address)); if(!bSourceLoaded() || !pma || !enabled) return; gint currPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(m_Notebook)); if (currPage < 0) return; NSourcePage *pPage = pages[currPage]; if (!pPage) return; int line = (pPage->getFC()->IsList()) ? pma->getFromAddress(address)->get_lst_line() : pma->get_src_line(address); //int line = pma->get_src_line(address) - 1; line -= 1; GtkTextIter iBegin; gtk_text_buffer_get_iter_at_line (gtk_text_view_get_buffer(pPage->getView()), &iBegin, line); int y, h; gtk_text_view_get_line_yrange (pPage->getView(), &iBegin, &y, &h); if (pPage->get_margin_width()) { GdkRectangle vRect; gtk_text_view_buffer_to_window_coords (pPage->getView(), GTK_TEXT_WINDOW_LEFT, 0, y, NULL, &y); vRect.x=0; vRect.y=y; vRect.width = pPage->get_margin_width(); vRect.height=h; Dprintf((" UpdateLine line=%d invalidating region %d,%d %d,%d\n",line,0,y,vRect.width,h)); // Send an expose event to repaint the whole margin gdk_window_invalidate_rect (gtk_text_view_get_window (pPage->getView(), GTK_TEXT_WINDOW_LEFT), &vRect, TRUE); } return; } //------------------------------------------------------------------------ // int SourceWindow::getPCLine(int page) { if (mProgramCounter.bIsActive && mProgramCounter.page == page) return mProgramCounter.line; NSourcePage *pPage = pages[page]; return (pPage->getFC()->IsList()) ? pma->getFromAddress(pma->get_PC())->get_lst_line() : pma->get_src_line(pma->get_PC()); } int SourceWindow::getAddress(NSourcePage *pPage, int line) { return pma->find_address_from_line(pPage->getFC(),line); } bool SourceWindow::bAddressHasBreak(int address) { return address>=0 && pma->address_has_break(address); } int SourceWindow::getOpcode(int address) { return (address >= 0) ? gp->cpu->pma->get_opcode(address) : address; } //------------------------------------------------------------------------ bool SourcePageMargin::formatMargin(char *str, int len, int line, int addr, int opcode, bool bBreak) { if (str) { int pos = 0; int npos = 0; *str=0; npos = bBreak ? g_snprintf(&str[pos], len, "") : 0; pos += npos; len -= npos; npos = m_bShowLineNumbers ? g_snprintf(&str[pos], len, "%d",line) : 0; pos += npos; len -= npos; npos = (m_bShowAddresses && addr >= 0) ? g_snprintf(&str[pos], len, " %04X",addr) : 0; pos += npos; len -= npos; npos = (m_bShowOpcodes && opcode >= 0) ? g_snprintf(&str[pos], len, "%c%04X ", m_bShowAddresses?':':' ', opcode) : 0; pos += npos; len -= npos; pos += bBreak ? g_snprintf(&str[pos], len, "") : 0; return pos != 0; } return false; } //======================================================================== NSourcePage::NSourcePage(SourceWindow *pParent, SourceBuffer *pBuffer, int file_id, GtkWidget *pContainer) : m_pBuffer(pBuffer), m_Parent(pParent), m_fileid(file_id), m_marginWidth(0) { if (!m_pBuffer || !pContainer || !m_Parent) return; m_pBuffer->parse(); m_view = (GtkTextView *)gtk_text_view_new_with_buffer(m_pBuffer->getBuffer()); Dprintf(("NSourcePage::setSource() - view=%p\n",m_view)); gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (m_view), GTK_TEXT_WINDOW_LEFT, MARGIN_WIDTH); g_signal_connect(GTK_OBJECT(m_view), "key_press_event", G_CALLBACK(KeyPressHandler), this); g_signal_connect(GTK_OBJECT(m_view), "button_press_event", G_CALLBACK(ButtonPressHandler), this); g_signal_connect(GTK_OBJECT(m_view), "expose_event", G_CALLBACK(ViewExposeEventHandler), this); GtkWidget *pSW = gtk_scrolled_window_new (0,0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pSW), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (pContainer), pSW); gtk_container_add (GTK_CONTAINER (pSW), GTK_WIDGET(m_view)); gtk_text_view_set_wrap_mode (m_view, GTK_WRAP_NONE); gtk_text_view_set_editable (m_view, FALSE); setFont(m_Parent->getFont()); gtk_widget_show_all(pContainer); } void NSourcePage::invalidateView() { if (m_view) { GdkRectangle vRect; vRect.x=0; vRect.y=0; vRect.width=100; vRect.height=100; gdk_window_invalidate_rect (gtk_text_view_get_window (m_view, GTK_TEXT_WINDOW_LEFT), &vRect, TRUE); } } SourceWindow *NSourcePage::getParent() { return m_Parent; } GtkTextBuffer *NSourcePage::buffer() { return m_pBuffer ? m_pBuffer->getBuffer() : 0; } FileContext * NSourcePage::getFC() { return m_pBuffer ? m_pBuffer->m_pFC : 0; } //------------------------------------------------------------------------ GtkTextView *NSourcePage::getView() { return m_view; } //------------------------------------------------------------------------ void NSourcePage::updateMargin(int y1, int y2) { Dprintf((" updateMargin y1=%d y2=%d\n",y1,y2)); GtkTextView * text_view = m_view; std::vector numbers; std::vector pixels; int PCline = m_Parent->getPCLine(m_fileid); GdkWindow *win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); /* get the line numbers and y coordinates. */ gtk_source_view_get_lines (text_view, y1, y2, pixels, numbers); /* set size. */ gchar str [256]; PangoLayout *layout=0; gint text_width=0; FileContext *pFC = getFC(); gint addr_opcode = (pFC && !pFC->IsList()) ? 0x9999 : -1; if ( m_Parent->margin().formatMargin(str, sizeof(str), MAX (99, gtk_text_buffer_get_line_count (gtk_text_view_get_buffer(text_view))), addr_opcode, addr_opcode,false) ) { layout = gtk_widget_create_pango_layout (GTK_WIDGET (text_view), str); pango_layout_get_pixel_size (layout, &text_width, NULL); text_width+=2; } m_marginWidth = text_width + MARGIN_WIDTH; gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_LEFT, m_marginWidth); for (size_t i = 0; i < numbers.size(); ++i) { gint pos; gint line = numbers[i] + 1; gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, pixels[i], NULL, &pos); int address = pFC && !pFC->IsList() ? m_Parent->getAddress(this,line) : - 1; int opcode = pFC && !pFC->IsList() && !pFC->IsHLL() ? m_Parent->getOpcode(address) : -1; bool bHasBreak = m_Parent->bAddressHasBreak(m_Parent->getAddress(this,line)); if (layout) { if ( m_Parent->margin().formatMargin(str, sizeof(str), line, address,opcode,bHasBreak)) { pango_layout_set_markup (layout, str, -1); gtk_paint_layout(gtk_widget_get_style(GTK_WIDGET(text_view)), win, GTK_STATE_NORMAL, FALSE, NULL, GTK_WIDGET (text_view), NULL, 2, //text_width + 2, pos, layout); } } if (line == PCline) { gtk_paint_arrow( gtk_widget_get_style(GTK_WIDGET(text_view)), win, GTK_STATE_NORMAL, GTK_SHADOW_OUT, // GtkShadowType shadow_type, NULL, GTK_WIDGET (text_view), NULL, GTK_ARROW_RIGHT, //GtkArrowType arrow_type, TRUE, //gboolean fill, text_width+PC_START,pos, PC_PIXEL_SIZE,15); Dprintf((" updating PC at line %d\n", line)); } if (m_Parent->getAddress(this,line) >= 0) { // There is code associated with this line. gtk_paint_diamond( gtk_widget_get_style(GTK_WIDGET(text_view)), win, GTK_STATE_NORMAL, bHasBreak ? GTK_SHADOW_IN : GTK_SHADOW_OUT, NULL, GTK_WIDGET (text_view), NULL, text_width+BP_START, pos, BP_PIXEL_SIZE, BP_PIXEL_SIZE); } } if (layout) g_object_unref(layout); } //------------------------------------------------------------------------ void NSourcePage::setFont(const char *cp_newFont) { if (m_view && cp_newFont) { if (m_cpFont == cp_newFont) return; m_cpFont = cp_newFont; /* Change default font throughout the widget */ PangoFontDescription *font_desc; font_desc = pango_font_description_from_string (m_cpFont.c_str()); gtk_widget_modify_font (GTK_WIDGET (m_view), font_desc); pango_font_description_free (font_desc); } } //------------------------------------------------------------------------ // SetPC // // Highlight the line corresponding to the current program counter. // void SourceWindow::SetPC(int address) { Dprintf((" \n")); if (!bSourceLoaded() || !pma) return; int currPage = m_Notebook ? gtk_notebook_get_current_page (GTK_NOTEBOOK(m_Notebook)) : -1; // Get the file id associated with the program counter address unsigned int sbawFileId = pma->get_file_id(address); if(sbawFileId == 0xffffffff) return; int id = -1; int PCline=-1; if (currPage>=0 && pages[currPage]->getFC()->IsList()) { // Don't automatically switch away from a page if it is a list file id = currPage; PCline = pma->getFromAddress(address)->get_lst_line(); } else { std::map::iterator i = pages.begin(); for ( ; i != pages.end(); ++i) { if (i->second->get_file_id() == sbawFileId) { id = i->first; break; } } if (id < 0) return; // page was not found. // Switch to the source browser page that contains the program counter. if (currPage != id) gtk_notebook_set_current_page(GTK_NOTEBOOK(m_Notebook), id); // Get the source line number associated with the program counter address. PCline = pma->get_src_line(address); if(PCline==(int)INVALID_VALUE) return; //PCline--; } bool bFirstUpdate=true; if (mProgramCounter.bIsActive) { bFirstUpdate=false; } else { while (gtk_events_pending()) gtk_main_iteration(); } mProgramCounter.page = id; mProgramCounter.line = PCline; // Get a pointer to text_view margin window. GdkWindow *win = gtk_text_view_get_window (pages[id]->getView(), GTK_TEXT_WINDOW_LEFT); GdkRectangle PCloc; mProgramCounter.bIsActive = true; mProgramCounter.pBuffer = pages[id]->buffer(); gtk_text_buffer_get_iter_at_line(mProgramCounter.pBuffer, &mProgramCounter.iBegin, PCline); // Now we're going to check if the program counter is in view or not. // Get the program counter location gtk_text_view_get_iter_location (pages[id]->getView(), &mProgramCounter.iBegin, &PCloc); // Get the viewable region of the text buffer. The region is in buffer coordinates. GdkRectangle vRect; gtk_text_view_get_visible_rect (pages[id]->getView(), &vRect); // Now normalize the program counter's location. If yloc is between // 0 and 1.0 then the program counter is viewable. If not, then we // we need to scroll the text view so that the program counter is // viewable. double yloc = (PCloc.y - vRect.y) / (double) (vRect.height); if ( yloc < 0.05 || yloc > 0.95 || bFirstUpdate) { gtk_text_view_scroll_to_iter (pages[id]->getView(), &mProgramCounter.iBegin, 0.0, TRUE, 0.0, 0.3); gtk_text_view_get_visible_rect (pages[id]->getView(), &vRect); } // If there is a margin, then invalidate it so gtk will go off and redraw it. if (pages[id]->get_margin_width()) { vRect.x=0; vRect.y=0; vRect.width = pages[id]->get_margin_width(); // Send an expose event to repaint the whole margin gdk_window_invalidate_rect (win, &vRect, TRUE); } } void SourceWindow::CloseSource() { Dprintf((" \n")); } SourcePageMargin &SourceWindow::margin() { return m_pParent->margin(); } const char *SourceWindow::getFont() { return m_pParent->getFont(); } void SourceWindow::NewSource(GUI_Processor *gp) { Dprintf((" \n")); unsigned int address; if(!gp || !gp->cpu || !gp->cpu->pma) return; Dprintf((" \n")); Processor * pProc = gp->cpu; if(!enabled) { m_bLoadSource=true; return; } Dprintf((" \n")); if(!pma) pma = pProc->pma; CloseSource(); m_bLoadSource=true; Dprintf(("NewSource\n")); /* Now create a cross-reference link that the * simulator can use to send information back to the gui */ if(pProc->pc) { SourceXREF *cross_reference = new SourceXREF(); cross_reference->parent_window = (gpointer) this; cross_reference->data = 0; pProc->pc->add_xref((gpointer) cross_reference); if(pProc->pc != pma->GetProgramCounter()) { pma->GetProgramCounter()->add_xref((gpointer) cross_reference); } } std::vector::iterator i = m_pParent->ppSourceBuffers.begin(); std::vector::iterator iend = m_pParent->ppSourceBuffers.end(); for ( ; i != iend; ++i) { AddPage(*i); } m_bSourceLoaded = 1; // update breakpoint widgets unsigned uPMMaxIndex = pProc->program_memory_size(); for(unsigned int uPMIndex=0; uPMIndex < uPMMaxIndex; uPMIndex++) { int address = pProc->map_pm_index2address(uPMIndex); if(pma->address_has_break(address)) UpdateLine(address); } address=pProc->pma->get_PC(); if(address==INVALID_VALUE) puts("Warning, PC is invalid?"); else SetPC(address); Dprintf((" Source is loaded\n")); } //------------------------------------------------------------------------ // AddPage // Adds a page to the notebook, and returns notebook-id for that page. // int SourceWindow::AddPage(SourceBuffer *pSourceBuffer) { if (pSourceBuffer && pSourceBuffer->m_pFC) return AddPage(pSourceBuffer, pSourceBuffer->m_pFC->name()); return -1; } int SourceWindow::AddPage(SourceBuffer *pSourceBuffer, const std::string &fName) { if (!bIsBuilt || !pSourceBuffer) return -1; GtkWidget *label; std::string::size_type pos = fName.find_last_of("/\\"); if (pos != std::string::npos) label = gtk_label_new(fName.substr(pos + 1).c_str()); else label = gtk_label_new(fName.c_str()); GtkWidget *pFrame = gtk_frame_new(NULL); int id = gtk_notebook_append_page(GTK_NOTEBOOK(m_Notebook),pFrame,label); pages[id] = new NSourcePage(this, pSourceBuffer, id, pFrame); gtk_widget_show_all(pFrame); return id; } /*********************** gui message dialog *************************/ void gui_message(const char *message) { GtkWidget *dialog = gtk_dialog_new_with_buttons( "", NULL, GTK_DIALOG_DESTROY_WITH_PARENT, "_OK", GTK_RESPONSE_OK, NULL ); GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *label = gtk_label_new(message); gtk_container_add(GTK_CONTAINER(content_area), label); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } // gui question dialog // modal dialog, asking a yes/no question int gui_question(const char *question, const char *a, const char *b) { GtkWidget *dialog = gtk_dialog_new_with_buttons( "", NULL, GTK_DIALOG_DESTROY_WITH_PARENT, a, TRUE, b, FALSE, NULL ); GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *label = gtk_label_new(question); gtk_container_add(GTK_CONTAINER(content_area), label); gtk_widget_show_all(dialog); int retval = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return retval; } void SourceBrowser_Window::set_pma(ProgramMemoryAccess *new_pma) { pma = new_pma; if(window && pma) { SetTitle(); } } const char *SourceBrowserParent_Window::name() { return "source_browser_parent"; } //======================================================================== // // SourceBrowserParent_Window // // Here is some experimental code that allows multiple source browser // windows. SourceBrowserParent_Window::SourceBrowserParent_Window(GUI_Processor *_gp) : GUI_Object() { gp = _gp; pma = 0; m_TabType = GTK_POS_BOTTOM; mpTagTable = gtk_text_tag_table_new(); const char *sName = "source_config"; char *fg=0; GdkColor color; GtkTextTag *tag; tag = gtk_text_tag_new("Label"); gdk_color_parse(config_get_string(sName, "label_fg", &fg) ? fg : "orange" , &color); g_object_set(tag, "foreground-gdk", &color, NULL); gtk_text_tag_table_add(mpTagTable, tag); tag = gtk_text_tag_new("Mnemonic"); gdk_color_parse(config_get_string(sName, "mnemonic_fg", &fg) ? fg : "red" , &color); g_object_set(tag, "foreground-gdk", &color, NULL); gtk_text_tag_table_add(mpTagTable, tag); tag = gtk_text_tag_new("Symbols"); gdk_color_parse(config_get_string(sName, "symbol_fg", &fg) ? fg : "dark green" , &color); g_object_set(tag, "foreground-gdk", &color, NULL); gtk_text_tag_table_add(mpTagTable, tag); tag = gtk_text_tag_new("Comments"); gdk_color_parse(config_get_string(sName, "comment_fg", &fg) ? fg : "dim gray" , &color); g_object_set(tag, "foreground-gdk", &color, NULL); gtk_text_tag_table_add(mpTagTable, tag); tag = gtk_text_tag_new("Constants"); gdk_color_parse(config_get_string(sName, "constant_fg", &fg) ? fg : "blue" , &color); g_object_set(tag, "foreground-gdk", &color, NULL); gtk_text_tag_table_add(mpTagTable, tag); if (!config_get_variable(sName, "tab_position", &m_TabType)) m_TabType = GTK_POS_LEFT; int b=1; config_get_variable(sName, "line_numbers", &b); margin().enableLineNumbers(b!=0); config_get_variable(sName, "addresses", &b); margin().enableAddresses(b!=0); config_get_variable(sName, "opcodes", &b); margin().enableOpcodes(b!=0); if (config_get_string(sName, "font", &fg)) setFont(fg); else setFont("Serif 8"); children.push_back(new SourceWindow(_gp, this, true)); } void SourceBrowserParent_Window::Build() { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end();++sbaw_iterator) (*sbaw_iterator)->Build(); UpdateMenuItem(); } void SourceBrowserParent_Window::NewProcessor(GUI_Processor *gp) { std::vector::iterator sbaw_iterator = children.begin(); std::list ::iterator pma_iterator = gp->cpu->pma_context.begin(); CreateSourceBuffers(gp); int child = 1; SourceWindow *sbaw=0; while( (sbaw_iterator != children.end()) || (pma_iterator != gp->cpu->pma_context.end())) { if(sbaw_iterator == children.end()) { char child_name[64]; child++; g_snprintf(child_name, sizeof(child_name), "source_browser%d", child); sbaw = new SourceWindow(gp,this, true, child_name); children.push_back(sbaw); } else sbaw = *sbaw_iterator++; if(pma_iterator != gp->cpu->pma_context.end()) { sbaw->set_pma(*pma_iterator); ++pma_iterator; } else { sbaw->set_pma(gp->cpu->pma); } } } void SourceBrowserParent_Window::SelectAddress(int address) { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->SelectAddress(address); } void SourceBrowserParent_Window::SelectAddress(Value *addrSym) { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->SelectAddress(addrSym); } void SourceBrowserParent_Window::Update() { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->Update(); } void SourceBrowserParent_Window::UpdateLine(int address) { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->UpdateLine(address); } void SourceBrowserParent_Window::SetPC(int address) { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->SetPC(address); } void SourceBrowserParent_Window::CloseSource() { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->CloseSource(); } void SourceBrowserParent_Window::NewSource(GUI_Processor *gp) { std::vector::iterator sbaw_iterator = children.begin(); CreateSourceBuffers(gp); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->NewSource(gp); } void SourceBrowserParent_Window::ChangeView(int view_state) { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->ChangeView(view_state); } gchar *SourceBrowserParent_Window::get_color_string(const char *tag_name) { GdkColor *gdk_color; g_object_get(gtk_text_tag_table_lookup(mpTagTable, tag_name), "foreground-gdk", &gdk_color, NULL); gchar *color_string = gdk_color_to_string(gdk_color); gdk_color_free(gdk_color); return color_string; } int SourceBrowserParent_Window::set_config() { std::vector::iterator sbaw_iterator = children.begin(); for ( ; sbaw_iterator != children.end(); ++sbaw_iterator) (*sbaw_iterator)->set_config(); const char *sName = "source_config"; char *buff; buff = get_color_string("Mnemonic"); config_set_string(sName,"mnemonic_fg", buff); g_free(buff); buff = get_color_string("Label"); config_set_string(sName,"label_fg", buff); g_free(buff); buff = get_color_string("Symbols"); config_set_string(sName,"symbol_fg", buff); g_free(buff); buff = get_color_string("Comments"); config_set_string(sName,"comment_fg", buff); g_free(buff); buff = get_color_string("Constants"); config_set_string(sName,"constant_fg", buff); g_free(buff); config_set_string(sName,"font", getFont()); config_set_variable(sName, "tab_position", getTabPosition()); config_set_variable(sName, "line_numbers", margin().bLineNumbers()); config_set_variable(sName, "addresses", margin().bAddresses()); config_set_variable(sName, "opcodes", margin().bOpcodes()); return 0; } //------------------------------------------------------------------------ // parseLine // // Added a line of text to the source buffer. Apply syntax highlighting. // void SourceBuffer::parseLine(const char *cP, int parseStyle) { GtkTextIter iEnd; GtkTextBuffer *pTextBuffer = m_buffer; gtk_text_buffer_get_end_iter (pTextBuffer, &iEnd); int offset = gtk_text_iter_get_offset (&iEnd); gtk_text_buffer_insert (pTextBuffer, &iEnd, cP, -1); if (parseStyle<0) { addTagRange("Comments", offset, offset + strlen(cP)); return; } int i=0; int j=0; bool bHaveMnemonic = false; if (i != (j = isString(cP))) { addTagRange("Label", i + offset, j + offset); i=j; } while (!isEnd(cP[i])) { if ( (j=isWhiteSpace(&cP[i])) != 0) { i += j; } else if ( (j=isString(&cP[i])) != 0) { if (bHaveMnemonic) addTagRange("Symbols", i + offset, i + j + offset); else addTagRange("Mnemonic", i + offset, i + j + offset); bHaveMnemonic = true; i += j; } else if ( (j=isNumber(&cP[i])) != 0) { addTagRange("Constants", i + offset, i + j + offset); i += j; } else if ( (j=isComment(&cP[i])) != 0) { addTagRange("Comments", i + offset, i + j + offset); i += j; return; } else i++; } } //------------------------------------------------------------------------ SourcePageMargin &SourceBrowserParent_Window::margin() { return m_margin; } //------------------------------------------------------------------------ void SourceBrowserParent_Window::setTabPosition(int tt) { m_TabType = tt; Update(); } //------------------------------------------------------------------------ void SourceBrowserParent_Window::setFont(const char *cpNewFont) { if (cpNewFont) { m_FontDescription = cpNewFont; Update(); } } const char *SourceBrowserParent_Window::getFont() { return m_FontDescription.c_str(); } //------------------------------------------------------------------------ // parseSource void SourceBrowserParent_Window::parseSource(SourceBuffer *pBuffer,FileContext *pFC) { pFC->rewind(); char text_buffer[256]; int line = 1; while(pFC->gets(text_buffer, sizeof(text_buffer))) { int address; // The syntax highlighting doesn't work on list files or hll files address = pFC->IsList()||pFC->IsHLL() ? -1 : 1;//gp->cpu->pma->find_address_from_line(pFC,line); // check if text_buffer in uft8 character set if (!g_utf8_validate(text_buffer, -1, NULL)) { gsize bytes_read, bytes_written; gchar *new_buffer; // try to convert to uft8 using current locale // if we succeed, do normal processing on converted text if ((new_buffer = g_locale_to_utf8((const gchar *)text_buffer, -1, &bytes_read, &bytes_written, NULL))) { pBuffer->parseLine(new_buffer,address); g_free(new_buffer); } // Conversion based on locale did not work else { // replace comment which may have unknown character set if((new_buffer = strchr(text_buffer, ';'))) { *new_buffer = 0; strcat(text_buffer, "; comment stripped, characters from unknown locale\n"); } // if still not OK replace entire line so line numbering still OK if (!g_utf8_validate(text_buffer, -1, NULL)) { strcpy(text_buffer, "; non-comment characters from unknow locale\n"); } pBuffer->parseLine(text_buffer,address); } } else pBuffer->parseLine(text_buffer,address); line++; } } //------------------------------------------------------------------------ void SourceBrowserParent_Window::CreateSourceBuffers(GUI_Processor *gp) { Dprintf((" \n")); if(!gp || !gp->cpu || !gp->cpu->pma) return; Dprintf((" \n")); Processor * pProc = gp->cpu; if(!pma) pma = pProc->pma; CloseSource(); Dprintf(("NewSource\n")); if(pProc->files.nsrc_files() != 0) { for(int i = 0; ifiles.nsrc_files(); i++) { FileContext *fc = pProc->files[i]; int pos = fc->name().size() - 4; if (pos > 0 && fc->name().compare(pos, 4, ".cod") && fc->name().compare(pos, 4, ".COD")) { ppSourceBuffers.push_back(new SourceBuffer(mpTagTable, fc, this)); } else { if(verbose) printf ("SourceBrowserAsm_new_source: skipping file: <%s>\n", fc->name().c_str()); } } } Dprintf((" Source is loaded\n")); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_callbacks.h0000664000076400007640000000066013041763637013400 00000000000000 #ifndef __GUI_CALLBACKS_H__ #define __GUI_CALLBACKS_H__ //#ifdef __cplusplus //extern "C" { //#endif /* __cplusplus */ void gui_cb_quit (GtkWidget *widget, gpointer data); void gui_cb_break (GtkWidget *widget, gpointer data); void gui_cb_break_r (GtkWidget *widget, gpointer data); void gui_cb_break_w (GtkWidget *widget, gpointer data); //#ifdef __cplusplus //} //#endif /* __cplusplus */ #endif /* __GUI_CALLBACKS_H__ */ gpsim-0.30.0/gui/settings.h0000664000076400007640000000244713041763636012461 00000000000000/* Copyright (C) 2004 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SETTINGS_H #define _SETTINGS_H #include using namespace std; class Settings { public: Settings() { } virtual bool set(const char *module, const char *entry, const char *string) = 0; virtual bool set(const char *module, const char *entry, int value) = 0; virtual bool get(const char *module, const char *entry, char **string) = 0; virtual bool get(const char *module, const char *entry, int *value) = 0; virtual bool remove(const char *module, const char *entry) = 0; virtual ~Settings() { } protected: string name; }; #endif //_SETTINGS_H gpsim-0.30.0/gui/gui_profile.cc0000664000076400007640000006570113041763636013265 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // The code below is currently stubs which are unable to operate. // It so far is unable to extract profiling data except for the // routine profile tab #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include #include #include #include "gui.h" #include "gui_profile.h" enum { PROFILE_ADDRESS, PROFILE_CYCLES, PROFILE_INSTRUCTION, PROFILE_COLUMNS }; enum { PROFILE_REGISTER_ADDRESS, PROFILE_REGISTER_REGISTER, PROFILE_REGISTER_READ, PROFILE_REGISTER_WRITE, PROFILE_REGISTER_COLUMNS }; enum { PROFILE_EXESTATS_FADDRESS, PROFILE_EXESTATS_TADDRESS, PROFILE_EXESTATS_EXECUTIONS, PROFILE_EXESTATS_MIN, PROFILE_EXESTATS_MAX, PROFILE_EXESTATS_MEDIAN, PROFILE_EXESTATS_AVERAGE, PROFILE_EXESTATS_STDDEV, PROFILE_EXESTATS_TOTAL, PROFILE_EXESTATS_COLUMNS }; gint histogram_list_compare_func_cycles(gconstpointer a, gconstpointer b) { const struct cycle_histogram_counter *h1=(struct cycle_histogram_counter*)a; const struct cycle_histogram_counter *h2=(struct cycle_histogram_counter*)b; if(h1->histo_cycles > h2->histo_cycles) return 1; if(h1->histo_cycles == h2->histo_cycles) return 0; return -1; } gint histogram_list_compare_func(gconstpointer a, gconstpointer b) { const struct cycle_histogram_counter *h1=(struct cycle_histogram_counter*)a; const struct cycle_histogram_counter *h2=(struct cycle_histogram_counter*)b; if(h1->start_address > h2->start_address) return 1; if(h1->start_address == h2->start_address) { if(h1->stop_address > h2->stop_address) return 1; if(h1->stop_address == h2->stop_address) { if(h1->histo_cycles*h1->count > h2->histo_cycles*h2->count) return 1; if(h1->histo_cycles*h1->count == h2->histo_cycles*h2->count) return 0; } } return -1; } double calculate_median(GList *start, GList *stop) { GList *sorted_list=0; struct cycle_histogram_counter *chc_start, *chc_stop;//, *chc_result; // GList *result; int count_sum=0; if(start==0) return -4.2; if(stop==0) { stop=start; while(stop->next!=0) stop=stop->next; } // Copy list and sort it on cycles while(start!=stop) { sorted_list=g_list_append(sorted_list,start->data); start=start->next; } sorted_list=g_list_append(sorted_list,start->data); sorted_list=g_list_sort(sorted_list,histogram_list_compare_func_cycles); start=sorted_list; stop=start; while(stop->next!=0) stop=stop->next; chc_start=(struct cycle_histogram_counter*)start->data; chc_stop=(struct cycle_histogram_counter*)stop->data; while(start!=stop) { if(count_sum>=0) { // Move start to right start = start->next; count_sum-=chc_start->count; chc_start=(struct cycle_histogram_counter*)start->data; continue; } else { // Move stop to left stop=stop->prev; count_sum+=chc_stop->count; chc_stop=(struct cycle_histogram_counter*)stop->data; continue; } } if(count_sum>(int)chc_start->count) { start=start->next; chc_start=(struct cycle_histogram_counter*)start->data; g_list_free(sorted_list); return (double)chc_start->histo_cycles; } if(-count_sum>(int)chc_start->count) { start=start->prev; chc_start=(struct cycle_histogram_counter*)start->data; g_list_free(sorted_list); return (double)chc_start->histo_cycles; } if(-count_sum==(int)chc_start->count) { stop=stop->prev; chc_stop=(struct cycle_histogram_counter*)stop->data; g_list_free(sorted_list); return (chc_start->histo_cycles+chc_stop->histo_cycles)/2.0; } if(count_sum==(int)chc_start->count) { stop=stop->next; chc_stop=(struct cycle_histogram_counter*)stop->data; g_list_free(sorted_list); return (chc_start->histo_cycles+chc_stop->histo_cycles)/2.0; } if((unsigned int)abs(count_sum)count) { g_list_free(sorted_list); return (double)chc_start->histo_cycles; } assert(0); return 0.0; } double calculate_stddev(GList *start, GList *stop, double average) { int count=0; double sum = 0.0; struct cycle_histogram_counter *chc_start; if (start == stop) return 0.0; if (stop == 0) { stop = start; while (stop->next != 0) stop = stop->next; } while (start != stop) { double diff, diff2; chc_start = (struct cycle_histogram_counter*)start->data; diff = chc_start->histo_cycles-average; diff2 = diff * diff; sum += diff2 * chc_start->count; count += chc_start->count; start = start->next; } double variance = sum / count; return sqrt(variance); } void Profile_Window::Update() { if(!enabled) return; if(!gp || !gp->cpu) { return; } // Update profile list GtkTreeIter titer; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(profile_list), &titer)) { do { guint instruction_address; guint64 last_count; gtk_tree_model_get(GTK_TREE_MODEL(profile_list), &titer, PROFILE_ADDRESS, &instruction_address, PROFILE_CYCLES, &last_count, -1); guint64 count; count = gp->cpu->cycles_used(gp->cpu->map_pm_address2index(instruction_address)); if (last_count != count) { gtk_list_store_set(profile_list, &titer, PROFILE_CYCLES, count, -1); } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(profile_list), &titer)); } // Update register list if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(profile_register_list), &titer)) { do { guint register_address; guint64 last_count_read; guint64 last_count_write; gtk_tree_model_get(GTK_TREE_MODEL(profile_register_list), &titer, PROFILE_REGISTER_ADDRESS, ®ister_address, PROFILE_REGISTER_READ, &last_count_read, PROFILE_REGISTER_WRITE, &last_count_write, -1); Register *reg = gp->cpu->rma.get_register(register_address); guint64 count_read = reg->read_access_count; guint64 count_write = reg->write_access_count; if (last_count_read != count_read || last_count_write != count_write) { gtk_list_store_set(profile_register_list, &titer, PROFILE_REGISTER_READ, count_read, -1); gtk_list_store_set(profile_register_list, &titer, PROFILE_REGISTER_WRITE, count_write, -1); } } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(profile_register_list), &titer)); } // Update cummulative statistics list histogram_profile_list = g_list_sort(histogram_profile_list, histogram_list_compare_func); // Remove all of list (for now) gtk_list_store_clear(profile_exestats_list); if(histogram_profile_list!=0) { struct cycle_histogram_counter *chc; int count_sum = 0; unsigned int start = 0xffffffff, stop = 0xffffffff; guint64 min = 0xffffffffffffffffULL, max = 0; guint64 cycles_sum = 0; GList *list_start = 0, *list_end = 0; GList *iter = histogram_profile_list; list_start = iter; while(iter!=0) { chc=(struct cycle_histogram_counter*)iter->data; if(start==chc->start_address && stop==chc->stop_address) { // Add data to statistics count_sum+=chc->count; if(chc->histo_cycleshisto_cycles; if(chc->histo_cycles>max) max=chc->histo_cycles; cycles_sum+=chc->histo_cycles*chc->count; } else { if(count_sum!=0) { // We have data, display it. GtkTreeIter titer; gtk_list_store_append(profile_exestats_list, &titer); gtk_list_store_set(profile_exestats_list, &titer, PROFILE_EXESTATS_FADDRESS, start, PROFILE_EXESTATS_TADDRESS, stop, PROFILE_EXESTATS_EXECUTIONS, count_sum, PROFILE_EXESTATS_MIN, min, PROFILE_EXESTATS_MAX, max, PROFILE_EXESTATS_MEDIAN, calculate_median(list_start , list_end), PROFILE_EXESTATS_AVERAGE, cycles_sum / (double)count_sum, PROFILE_EXESTATS_STDDEV, calculate_stddev(list_start , list_end , cycles_sum / (double)count_sum), PROFILE_EXESTATS_TOTAL, cycles_sum, -1); } // Start new calculation count_sum=chc->count; start = chc->start_address; stop = chc->stop_address; min=chc->histo_cycles; max=chc->histo_cycles; cycles_sum=chc->histo_cycles*chc->count; list_start = iter; } list_end=iter; iter=iter->next; } // add current to list GtkTreeIter titer; gtk_list_store_append(profile_exestats_list, &titer); gtk_list_store_set(profile_exestats_list, &titer, PROFILE_EXESTATS_FADDRESS, start, PROFILE_EXESTATS_TADDRESS, stop, PROFILE_EXESTATS_EXECUTIONS, count_sum, PROFILE_EXESTATS_MIN, min, PROFILE_EXESTATS_MAX, max, PROFILE_EXESTATS_MEDIAN, calculate_median(list_start , list_end), PROFILE_EXESTATS_AVERAGE, cycles_sum / (double)count_sum, PROFILE_EXESTATS_STDDEV, calculate_stddev(list_start , list_end ,cycles_sum / (double)count_sum), PROFILE_EXESTATS_TOTAL, cycles_sum, -1); } } #define END_OF_TIME 0xFFFFFFFFFFFFFFFFULL static guint64 startcycle=END_OF_TIME; static unsigned int startaddress; static guint64 stopcycle=END_OF_TIME; static unsigned int stopaddress; //------------------------------------------------------------------------ // // ProfileStart class // class ProfileStart : public TriggerObject { public: ProfileStart(Profile_Window *_pw, int _address) { pw = _pw; address = _address; } void callback(void) { if(!gpGuiProcessor || !gpGuiProcessor->cpu || !pw->gp->cpu) return; if(startcycle==END_OF_TIME) { startcycle = get_cycles().get(); startaddress = pw->gp->cpu->pma->get_PC(); } } private: Profile_Window *pw; int address; }; //------------------------------------------------------------------------ // // ProfileStop class // class ProfileStop : public TriggerObject { public: ProfileStop(Profile_Window *_pw, int _address) { pw = _pw; address = _address; } void callback(void) { if(!gpGuiProcessor || !gpGuiProcessor->cpu || !pw->gp->cpu) return; if(stopcycle==END_OF_TIME && startcycle!=END_OF_TIME) { stopcycle = get_cycles().get(); if(startcycle==stopcycle) // This was probably an attempt to measure the whole loop. // Set stopcycle to unset, and wait for the next one stopcycle=END_OF_TIME; else { guint64 cycles; GList *iter; stopaddress=pw->gp->cpu->pma->get_PC(); // We have a new measurement cycles=(int)stopcycle-(int)startcycle; // Search to see if there are an entry with this startaddress, // stopaddress and cycle count. iter=pw->histogram_profile_list; while(iter!=0) { struct cycle_histogram_counter *chc; chc=(struct cycle_histogram_counter*)iter->data; if(chc->start_address == startaddress && chc->stop_address == stopaddress && chc->histo_cycles == cycles) { // If so then add 1 to the counter chc->count++; break; } iter=iter->next; } if(iter==0) { // Else create a new struct, fill with values and add (sorted) to list struct cycle_histogram_counter *chc = new cycle_histogram_counter; chc->start_address=startaddress; chc->stop_address=stopaddress; chc->histo_cycles=cycles; chc->count=1; pw->histogram_profile_list=g_list_append(pw->histogram_profile_list,chc); } startcycle=stopcycle=END_OF_TIME; } } } private: Profile_Window *pw; int address; }; /***************************************************************** * StartExe * * Create a 'profile start' object for the program memory. * */ void Profile_Window::StartExe(int address) { if(!enabled) ChangeView(VIEW_SHOW); if(gp->cpu->pma->address_has_profile_start(address)) gp->cpu->pma->clear_profile_start_at_address(address); else { if(gp->cpu->pma->address_has_profile_stop(address)) // Can't have both start and stop at the same address // ..it becomes difficult to calculate the cycles gp->cpu->pma->clear_profile_stop_at_address(address); // FIXME -- memory leak... gp->cpu->pma->set_profile_start_at_address(address, new ProfileStart(this,address)); } } /***************************************************************** * SopExe * * Create a 'profile stop' object for the program memory. * */ void Profile_Window::StopExe(int address) { if(enabled) ChangeView(VIEW_SHOW); if(gp->cpu->pma->address_has_profile_stop(address)) gp->cpu->pma->clear_profile_stop_at_address(address); else { if(gp->cpu->pma->address_has_profile_start(address)) // Can't have both start and stop at the same address // ..it becomes difficult to calculate the cycles gp->cpu->pma->clear_profile_start_at_address(address); // FIXME -- memory leak... gp->cpu->pma->set_profile_stop_at_address(address, new ProfileStop(this,address)); } } /***************************************************************** * ProfileWindow_new_program * * */ void Profile_Window::NewProgram(GUI_Processor *_gp) { unsigned int uPMIndex; if(!_gp) return; gp = _gp; if(!gp->cpu) return; program=1; if(!enabled) return; profile_keeper.enable_profiling(); // Instruction list store Processor *pProcessor = gp->cpu; ProgramMemoryAccess *pPMA = pProcessor->pma; for (uPMIndex = 0; uPMIndex < pProcessor->program_memory_size(); uPMIndex++) { guint64 cycles; instruction * pInstruction = pProcessor->pma->getFromIndex(uPMIndex); guint uAddress = pProcessor->map_pm_index2address(uPMIndex); if(pPMA->hasValid_opcode_at_index(uPMIndex)) { cycles = pProcessor->cycles_used(uPMIndex); GtkTreeIter iter; gtk_list_store_append(profile_list, &iter); gtk_list_store_set(profile_list, &iter, PROFILE_ADDRESS, uAddress, PROFILE_CYCLES, cycles, PROFILE_INSTRUCTION, pInstruction->name().c_str(), -1); } } // Register list for(unsigned int i = 0; i < pProcessor->rma.get_size(); i++) { Register *reg = pProcessor->rma.get_register(i); // // If the register is valid, but it's not aliased and it's not a special function // register, then we can profile it. // if(reg && reg->isa() != Register::INVALID_REGISTER // i.e. the register is valid && !((reg->isa() == Register::SFR_REGISTER) || (i != reg->address)) ) { guint64 read_cycles = reg->read_access_count; guint64 write_cycles = reg->write_access_count; GtkTreeIter iter; gtk_list_store_append(profile_register_list, &iter); gtk_list_store_set(profile_register_list, &iter, PROFILE_REGISTER_ADDRESS, i, PROFILE_REGISTER_REGISTER, reg->name().c_str(), PROFILE_REGISTER_READ, read_cycles, PROFILE_REGISTER_WRITE, write_cycles, -1); } } } /***************************************************************** * ProfileWindow_new_processor * * */ void Profile_Window::NewProcessor(GUI_Processor *_gp) { if(!gp) return; if(!enabled) return; } static int delete_event(GtkWidget *widget, GdkEvent *event, Profile_Window *rw) { rw->ChangeView(VIEW_HIDE); return TRUE; } // Call-back to format an address for the cell renderer static void address_data_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { guint addr; gchar buf[64]; int position = GPOINTER_TO_INT(data); gtk_tree_model_get(tree_model, iter, position, &addr, -1); g_snprintf(buf, sizeof(buf), "0x%04x", addr); g_object_set(renderer, "text", buf, NULL); } // Call-back to format the count for the cell renderer static void cycles_data_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { guint64 addr; gchar buf[64]; int position = GPOINTER_TO_INT(data); gtk_tree_model_get(tree_model, iter, position, &addr, -1); g_snprintf(buf, sizeof(buf), "0x%" PRINTF_GINT64_MODIFIER "x", addr); g_object_set(renderer, "text", buf, NULL); } // Call-back to formation floating point information static void float_data_func(GtkTreeViewColumn *tree_column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { gdouble floating_data; gchar buf[64]; int position = GPOINTER_TO_INT(data); gtk_tree_model_get(tree_model, iter, position, &floating_data, -1); g_snprintf(buf, sizeof(buf), "%.1f", floating_data); g_object_set(renderer, "text", buf, NULL); } void Profile_Window::Build() { if(bIsBuilt) return; GtkWidget *label; GtkWidget *main_vbox; GtkWidget *scrolled_window; window=gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "delete_event", G_CALLBACK (delete_event), this); main_vbox=gtk_vbox_new(FALSE,1); gtk_container_set_border_width(GTK_CONTAINER(main_vbox),0); gtk_container_add(GTK_CONTAINER(window), main_vbox); gtk_widget_show(main_vbox); gtk_window_set_title(GTK_WINDOW(window), "profile viewer"); notebook = gtk_notebook_new(); gtk_widget_show(notebook); gtk_box_pack_start (GTK_BOX (main_vbox), notebook, TRUE, TRUE, 0); GtkCellRenderer *renderer; GtkTreeViewColumn *column; // Instruction profile list profile_list = gtk_list_store_new(PROFILE_COLUMNS, G_TYPE_UINT, G_TYPE_UINT64, G_TYPE_STRING); profile_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(profile_list)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", PROFILE_ADDRESS, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, address_data_func, GINT_TO_POINTER(PROFILE_ADDRESS), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Cycles", renderer, "text", PROFILE_CYCLES, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, cycles_data_func, GINT_TO_POINTER(PROFILE_CYCLES), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Instruction", renderer, "text", PROFILE_INSTRUCTION, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_tree), column); scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolled_window), profile_tree); gtk_widget_show(profile_tree); gtk_widget_show(scrolled_window); // gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 0); label=gtk_label_new("Instruction profile"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrolled_window,label); /////////////////////////////////////////////////// // Register profile list profile_register_list = gtk_list_store_new(PROFILE_REGISTER_COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_UINT64); profile_register_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(profile_register_list)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Address", renderer, "text", PROFILE_REGISTER_ADDRESS, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_register_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, address_data_func, GINT_TO_POINTER(PROFILE_REGISTER_ADDRESS), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Register", renderer, "text", PROFILE_REGISTER_REGISTER, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_register_tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Read count", renderer, "text", PROFILE_REGISTER_READ, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_register_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, cycles_data_func, GINT_TO_POINTER(PROFILE_REGISTER_READ), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Write count", renderer, "text", PROFILE_REGISTER_WRITE, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_register_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, cycles_data_func, GINT_TO_POINTER(PROFILE_REGISTER_WRITE), NULL); scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolled_window), profile_register_tree); gtk_widget_show(profile_register_tree); gtk_widget_show(scrolled_window); // gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 0); label=gtk_label_new("Register profile"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrolled_window,label); // Execution time statistics tab profile_exestats_list = gtk_list_store_new(PROFILE_EXESTATS_COLUMNS, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INT, G_TYPE_UINT64, G_TYPE_UINT64, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_UINT64); profile_exestats_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(profile_exestats_list)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("From address", renderer, "text", PROFILE_EXESTATS_FADDRESS, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, address_data_func, GINT_TO_POINTER(PROFILE_EXESTATS_FADDRESS), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("To address", renderer, "text", PROFILE_EXESTATS_TADDRESS, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, address_data_func, GINT_TO_POINTER(PROFILE_EXESTATS_TADDRESS), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Executions", renderer, "text", PROFILE_EXESTATS_EXECUTIONS, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Min", renderer, "text", PROFILE_EXESTATS_MIN, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Max", renderer, "text", PROFILE_EXESTATS_MAX, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Median", renderer, "text", PROFILE_EXESTATS_MEDIAN, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, float_data_func, GINT_TO_POINTER(PROFILE_EXESTATS_MEDIAN), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Average", renderer, "text", PROFILE_EXESTATS_AVERAGE, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, float_data_func, GINT_TO_POINTER(PROFILE_EXESTATS_AVERAGE), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Std. Dev.", renderer, "text", PROFILE_EXESTATS_STDDEV, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); gtk_tree_view_column_set_cell_data_func( column, renderer, float_data_func, GINT_TO_POINTER(PROFILE_EXESTATS_STDDEV), NULL); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Total", renderer, "text", PROFILE_EXESTATS_TOTAL, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(profile_exestats_tree), column); scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolled_window), profile_exestats_tree); gtk_widget_show(profile_exestats_tree); gtk_widget_show(scrolled_window); label=gtk_label_new("Routine profile"); gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrolled_window,label); /////////////////////////////////////////////////// gtk_window_set_default_size(GTK_WINDOW(window), width, height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window), name(), "Gpsim"); g_signal_connect_after(window, "configure_event", G_CALLBACK (gui_object_configure_event),this); gtk_widget_show (window); bIsBuilt=true; NewProcessor(gp); if(program) NewProgram(gp); Update(); UpdateMenuItem(); } const char *Profile_Window::name() { return "profile"; } Profile_Window::Profile_Window(GUI_Processor *_gp) : program(0), histogram_profile_list(0) { menu = "/menu/Windows/Profile"; gp = _gp; get_config(); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_breadboard.cc0000664000076400007640000027574213115236636013717 00000000000000/* Copyright (C) 2000,2001,2002 Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include #include #include #include #include #include #include "../src/modules.h" #include "../src/stimuli.h" #include "../src/processor.h" #include "../src/symbol.h" #include "../src/stimuli.h" #include "../src/value.h" #include "../src/errors.h" #include "../src/packages.h" #include #include #include "gui.h" #include "gui_breadboard.h" #include "gui_processor.h" #define PINLINEWIDTH 3 #define CASELINEWIDTH 4 #define CASEOFFSET (CASELINEWIDTH/2) #define FOORADIUS (CASELINEWIDTH) // radius of center top milling #define LABELPAD 4 // increase this so wide lines doesn't clutter labels static GdkColor high_output_color; static GdkColor low_output_color; #define PINLENGTH (4*PINLINEWIDTH) static int pinspacing = PINLENGTH; #define LAYOUTSIZE_X 800 #define LAYOUTSIZE_Y 800 #define STRING_SIZE 128 #define ROUTE_RES (2*PINLINEWIDTH) // grid spacing static void treeselect_module(GtkItem *item, GuiModule *p); #define XSIZE LAYOUTSIZE_X/ROUTE_RES // grid size #define YSIZE LAYOUTSIZE_Y/ROUTE_RES /* If HMASK is set in board_matrix, then this position is unavailable for horizontal track */ #define HMASK 1 #define VMASK 2 /* board matrix contains information about how a track can be routed. */ static unsigned char *board_matrix; // mask_matrix is used by trace_two_poins to know where is has been, and // how quickly it came here. (depth is stored here if lower) static unsigned short *mask_matrix; static unsigned int xsize; static unsigned int ysize; //======================================================================== class BreadBoardXREF : public CrossReferenceToGUI { public: void Update(int new_value) { Breadboard_Window *bbw = static_cast(parent_window); bbw->Update(); } void Remove() { } }; //======================================================================== BB_ModuleLabel::BB_ModuleLabel(const std::string &text, PangoFontDescription *font) { m_label = gtk_label_new(text.c_str()); gtk_widget_modify_font(m_label, font); gtk_widget_show(m_label); } BB_ModuleLabel::~BB_ModuleLabel() { gtk_widget_destroy(m_label); } static inline unsigned char *board_matrix_pt(unsigned int x, unsigned int y) { if (x < xsize && y < ysize) { return board_matrix + y*xsize + x; } else { return NULL; } } static inline unsigned short *mask_matrix_pt(unsigned int x, unsigned int y) { if (x < xsize && y < ysize) { return mask_matrix + (y*xsize + x); } else { return NULL; } } /* Check the flags in board_matrix to see if we are allowed to route horizontally here */ static inline int allow_horiz(point &p) { unsigned char *pt = board_matrix_pt(p.x, p.y); if (pt && ! (*pt & HMASK)) return TRUE; return FALSE; } /* Check the flags in board_matrix to see if we are allowed to route vertically here */ static inline int allow_vert(point &p) { unsigned char *pt = board_matrix_pt(p.x, p.y); if (pt && ! (*pt & VMASK)) return TRUE; return FALSE; } // Find the direction to go to get from s to e if there are no obstacles. static inline route_direction calculate_route_direction(point s, point e) { if(abs(s.x-e.x) > abs(s.y-e.y)) { // Left or right if(s.xp); if(dir==R_NONE) { // Both X and Y has changed. add_point=1; } else if(*pat!=0 && (*pat)->next!=0) { if((*pat)->p.x == p.x && (*pat)->next->p.x == p.x && (*pat)->dir==dir) { // same x, just change y (*pat)->p.y=p.y; } else if((*pat)->p.y == p.y && (*pat)->next->p.y == p.y && (*pat)->dir==dir) { // same y, just change x (*pat)->p.x=p.x; } else { add_point=1; } } else { add_point=1; } } else { add_point=1; } if(add_point)*/ // { // Lots and lots of mallocs, FIXME new_point = new path; new_point->p = p; new_point->next = *pat; if((*pat) != 0) { dir = calculate_route_direction(p, (*pat)->p); if ((*pat)->dir == R_NONE) (*pat)->dir = dir; } new_point->dir = dir; *pat = new_point; // } } // Free all memory in pat static void clear_path(path **pat) { path *next; if (*pat==0) return; path *current_path = *pat; *pat = 0; while(current_path!=0) { next = current_path->next; delete current_path; current_path = next; } } #if 0 /* failed attempt to remove unnessessary points in paths. FIXME bug*/ // Compress sequences with same x or y to one sequence static void compress_path(path **pat) { int x,y; path *current_path; current_path = *pat; x=current_path->p.x; y=current_path->p.y; while(current_path!=0) { path *next_path = current_path->next; path *next2_path = next_path->next; if(next_path==0 || next2_path==0) break; if(current_path->p.x==next_path->p.x && current_path->p.x==next2_path->p.x && current_path->dir==next_path->dir && current_path->dir==next2_path->dir) { current_path->next=next2_path; free(next_path); continue; } if(current_path->p.y==next_path->p.y && current_path->p.y==next2_path->p.y && current_path->dir==next_path->dir && current_path->dir==next2_path->dir) { current_path->next=next2_path; free(next_path); continue; } current_path = current_path->next; } } #endif // maxdepth is shortest path from start to end static unsigned short maxdepth; // Penalty for making a turn in a trace #define turnq(a,b) (((a)!=(b))*10) static unsigned long calls; /* This is an recursive routine that tries to find a path between p and end. */ static int trace_two_points(path **pat, // Pointer to resulting path point p, // Where we are now point end, // Where we want to go int depth, route_direction lastdir) // How deep in we are { int retval; route_direction dir; point up, left, right, down; if(depth==0) { // Initialize mask_matrix and maxdepth on first call int x,y; // Initialize mask_matrix and maxdepth //maxdepth=500; for(x=0;x<(int)xsize;x++) for(y=0;y<(int)ysize;y++) *mask_matrix_pt(x, y) = maxdepth; clear_path(pat); calls=0; } calls++; //////////////////////////////////////// // Recusion termination //////////////////////////////////////// if(depth>maxdepth) return FALSE; if(depth>*mask_matrix_pt(p.x, p.y)) return FALSE; if(abs(p.x-end.x)+abs(p.y-end.y)+depth>maxdepth) return FALSE; if(p.x == end.x && p.y==end.y) { // We are at end point if(depth < maxdepth) { // We found a new shortest path. //printf("Found path with length %d\n",depth); maxdepth = depth; clear_path(pat); prepend_point_to_path(pat, p); return TRUE; } return FALSE; } // Store new (closer) depth in mask_matrix. *mask_matrix_pt(p.x, p.y) = depth; // Find the general direction we want to go dir = calculate_route_direction(p,end); // Recursion return value retval=0; // Convenience up=p;up.y++; down=p;down.y--; left=p;left.x--; right=p;right.x++; /* Depending on where we wish to go, do recursion so that we likely will quickly find at least some kind of path to end. If we don't do that maxdepth will stay large, and the traceing will likely take a long time. We use allow_vert and allow_horiz to determine if the movement is allowed, of if there is something in our way. */ switch(dir) { case R_UP: if(allow_vert(up)) retval|=trace_two_points(pat,up,end,depth+1+turnq(lastdir,R_UP),R_UP); if(p.xnext!=0) { // If there are point in pat already, then check if // we can use that and just change the coords there. if((*pat)->p.x == p.x && (*pat)->next->p.x == p.x && (*pat)->dir==dir) { // same x, just change y (*pat)->p.y=p.y; } else if((*pat)->p.y == p.y && (*pat)->next->p.y == p.y) { // same y, just change x (*pat)->p.x=p.x; } else { // This is a turn in the trace. We need another point. prepend_point_to_path(pat, p, dir); } } else*/ { // This is first or second point. prepend_point_to_path(pat, p); } // if(depth==0) // { // printf("Successful trace with %ld steps\n",calls); // } return TRUE; } // if(depth==0) // { // printf("Unsuccessful trace with %ld steps\n",calls); // } return FALSE; } static std::vector nodepath_list; // Clear nodes in nodepath_list void Breadboard_Window::clear_nodes() { std::vector::iterator iter = nodepath_list.begin(); for ( ; iter != nodepath_list.end(); ++iter) { path *nodepath = *iter; clear_path(&nodepath); } nodepath_list.clear(); } // Draw node in nodepath_list void Breadboard_Window::draw_nodes() { gtk_widget_queue_draw(layout); } gboolean Breadboard_Window::layout_expose(GtkWidget *widget, GdkEventExpose *event, Breadboard_Window *bbw) { cairo_t *cr = gdk_cairo_create(gtk_layout_get_bin_window(GTK_LAYOUT(bbw->layout))); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); std::vector::iterator iter = nodepath_list.begin(); for ( ; iter != nodepath_list.end(); ++iter) { path *nodepath = *iter; path *current_path = nodepath; int last_x = current_path->p.x * ROUTE_RES; int last_y = current_path->p.y * ROUTE_RES; cairo_move_to(cr, last_x, last_y); current_path = current_path->next; while (current_path) { int x = current_path->p.x * ROUTE_RES; int y = current_path->p.y * ROUTE_RES; cairo_line_to(cr, x, y); current_path = current_path->next; } } cairo_stroke(cr); cairo_destroy(cr); return FALSE; } // Here we fill board_matrix with module packages, so that trace_two_points // know not to trace over them. void Breadboard_Window::update_board_matrix() { int x,y, width, height; int i; gtk_window_get_size(GTK_WINDOW(window), &width, &height); if (width/ROUTE_RES > (int)xsize || height/ROUTE_RES > (int)ysize) { xsize = width/ROUTE_RES; ysize = height/ROUTE_RES; void *realloc_temp = realloc(board_matrix, xsize * ysize); if (realloc_temp) { board_matrix = (unsigned char *)realloc_temp; } realloc_temp = realloc(mask_matrix, xsize * ysize * sizeof(unsigned short)); if (realloc_temp) { mask_matrix = (unsigned short *)realloc_temp; } } // Clear first. for(y=ysize-1;y>=0;y--) { for(x=0; x < (int)xsize; x++) *board_matrix_pt(x, y) = 0; } // Mark board outline, so we limit traces here for(x=0; x < (int)xsize; x++) { *board_matrix_pt(x, 0) = (HMASK|VMASK); *board_matrix_pt(x, ysize-1) = (HMASK|VMASK); } for(y=0; y < (int)ysize; y++) { *board_matrix_pt(0, y) = (HMASK|VMASK); *board_matrix_pt(xsize-1, y) = (HMASK|VMASK); } // Loop all modules, and put its package and pins to board_matrix std::vector::iterator mi = modules.begin(); for ( ; mi != modules.end(); ++mi) { GuiModule *p = *mi; if(p && p->IsBuilt()) { x=p->x(); y=p->y(); width=p->width(); height=p->height(); for(y = p->y() - ROUTE_RES; y < p->y() + height + ROUTE_RES && y/ROUTE_RES < (int)ysize; y += ROUTE_RES) { for(x = p->x(); x < p->x() + width && x/ROUTE_RES < (int)xsize; x += ROUTE_RES) { unsigned char *pt = board_matrix_pt(x/ROUTE_RES, y/ROUTE_RES); if(pt) *pt = (HMASK|VMASK); } } // Draw barriers around pins so the tracker can only get in // straigt to the pin and not from the side. for (i = 1; i <= p->pin_count(); i++) { std::vector *e = p->pins(); GuiPin *gp = (*e)[i - 1]; switch(gp->orientation) { case LEFT: y = gp->y() - gp->height() / 2; for(x = gp->x() - PINLENGTH; x < gp->x() + gp->width(); x += ROUTE_RES) { unsigned char *pt = board_matrix_pt(x/ROUTE_RES, y/ROUTE_RES); if (pt) *pt = (HMASK|VMASK); } y = gp->y() + gp->height() / 2; for(x = gp->x() - PINLENGTH; x < gp->x() + gp->width(); x += ROUTE_RES) { unsigned char *pt = board_matrix_pt(x/ROUTE_RES, y/ROUTE_RES); if (pt) *pt = (HMASK|VMASK); } break; case RIGHT: y = gp->y() - gp->height() / 2; for(x = gp->x() - PINLENGTH; x < gp->x() + gp->width(); x += ROUTE_RES) { unsigned char *pt = board_matrix_pt(x/ROUTE_RES, y/ROUTE_RES); if (pt) *pt = (HMASK|VMASK); } y = gp->y() + gp->height() / 2; for(x = gp->x() - PINLENGTH; x < gp->x() + gp->width(); x += ROUTE_RES) { unsigned char *pt = board_matrix_pt(x/ROUTE_RES, y/ROUTE_RES); if (pt) *pt = (HMASK|VMASK); } break; default: assert(0); } } } } clear_nodes(); draw_nodes(); } // Add path to board_matrix. This will make trace_two_point to not trace // at its place. It can trace over it when in straight angle. static void add_path_to_matrix(path *pat) { int x=-1, y=-1; if(pat!=0) { x=pat->p.x; y=pat->p.y; pat=pat->next; } while(pat!=0) { unsigned char *pt = board_matrix_pt(x, y); if(pt && (pat->dir==R_LEFT || pat->dir==R_RIGHT)) *pt |= HMASK; if(pt && (pat->dir==R_DOWN || pat->dir==R_UP)) *pt |= VMASK; while(x!=pat->p.x || y!=pat->p.y) { if(xp.x) x++; if(x>pat->p.x) x--; if(yp.y) y++; if(y>pat->p.y) y--; pt = board_matrix_pt(x, y); if(pt && (pat->dir==R_LEFT || pat->dir==R_RIGHT)) *pt |= HMASK; if(pt && (pat->dir==R_DOWN || pat->dir==R_UP)) *pt |= VMASK; } pat = pat->next; } } static GuiPin *find_gui_pin(Breadboard_Window *bbw, stimulus *pin); static path *shortest_path[100][100]; static int pathlen[100][100]; #include static void reverse_path(path **pat) { path *next, *last=0; while(*pat != 0) { // Keep a pointer to next next = (*pat)->next; // New next poins to last (reversing the list) (*pat)->next = last; last = *pat; *pat = next; } *pat = last; } static void reverse_path_if_endpoint(point startpoint, path **pat) { point pat_start, pat_end; int dist_start, dist_end; path *iter; iter = *pat; pat_start = iter->p; while(iter->next!=0) iter=iter->next; pat_end = iter->p; dist_start = abs(pat_start.x-startpoint.x) + abs(pat_start.y-startpoint.y); dist_end = abs(pat_end.x-startpoint.x) + abs(pat_end.y-startpoint.y); if(dist_start > dist_end && dist_end<5) { // Reverse the list *pat reverse_path(pat); } } static void reverse_path_if_startpoint(point startpoint, path **pat) { point pat_start, pat_end; int dist_start, dist_end; path *iter; iter = *pat; pat_start = iter->p; while(iter->next!=0) iter=iter->next; pat_end = iter->p; dist_start = abs(pat_start.x-startpoint.x) + abs(pat_start.y-startpoint.y); dist_end = abs(pat_end.x-startpoint.x) + abs(pat_end.y-startpoint.y); if(dist_start < dist_end && dist_start<5) { // Reverse the list *pat reverse_path(pat); } } static void path_copy_and_cat(path **pat, path **source) { path *dest, *prev=0; dest = *pat; if(dest!=0) { reverse_path_if_startpoint((*source)->p, pat); while(dest->next!=0) { dest=dest->next; } reverse_path_if_endpoint(dest->p, source); if((abs((*source)->p.x-dest->p.x) + abs((*source)->p.y-dest->p.y)) > 5) { puts("Assert failure"); printf("%d, %d\n", abs((*source)->p.x-dest->p.x), abs((*source)->p.y-dest->p.y)); } prev = dest; dest=dest->next; } path *sourceiter = *source; while(sourceiter!=0) { dest = new path; memcpy(dest, sourceiter, sizeof(path)); dest->next = 0; if(*pat==0) *pat=dest; if(prev!=0) { prev->next = dest; } prev = dest; sourceiter=sourceiter->next; } } // // Trace a node, and add result to nodepath_list // return true if OK, false if it could not find a route // static bool trace_node(struct gui_node *gn) { Breadboard_Window *bbw; bool did_work = true; point start = {-1, -1}, end; bbw = gn->bbw; stimulus *stimulus = gn->node->stimuli; std::vector pinlist; // Make a glist of all gui_pins in the node while (stimulus) { GuiPin *p = find_gui_pin(bbw, stimulus); if (p) { pinlist.push_back(p); } stimulus = stimulus->next; } // Allocate an array of shortest_paths, indexed with 2x glist position. //FIXME shortest_path = (path***) malloc(nr_of_nodes*nr_of_nodes*sizeof(path*)); int *permutations = new int[pinlist.size()]; int *shortest_permutation = new int[pinlist.size()]; for (int i = 0; i < (int)pinlist.size(); i++) permutations[i] = i; // Trace between all stimulus, and store the distances in the array. for (int i = 0; i < (int)pinlist.size(); i++) { GuiPin *pi = pinlist[i]; for (int j = i + 1; j < (int)pinlist.size(); j++) { GuiPin *pj = pinlist[j]; start.x = pi->x() / ROUTE_RES; start.y = pi->y() / ROUTE_RES; end.x = pj->x() / ROUTE_RES; end.y = pj->y() / ROUTE_RES; // printf("Tracing from %d,%d to %d,%d\n",start.x,start.y,end.x,end.y); maxdepth = abs(start.x - end.x) + abs(start.y - end.y); maxdepth = maxdepth * 2 + 100; // Twice the distance, and 5 turns // printf("Trying maxdepth %d\n",maxdepth); trace_two_points(&shortest_path[i][j], start, end,0,R_UP); if (shortest_path[i][j] == 0) { //printf("\n### Couldn't trace from pin %s to pin %s!\n", // pi->getIOpin()->name().c_str(), // pj->getIOpin()->name().c_str()); did_work = false; } pathlen[i][j] = maxdepth; pathlen[j][i] = maxdepth; shortest_path[j][i] = shortest_path[i][j]; } } if (!did_work) { //printf("\n###### Couldn't trace node %s!\n",gn->node->name().c_str()); for (int i = 0; i < (int)pinlist.size(); i++) for (int j = i + 1; j < (int)pinlist.size(); j++) clear_path(&shortest_path[i][j]); delete[] permutations; delete[] shortest_permutation; return false; } // Find the combination that produces the shortest node. int minlen = 100000; do { int sum=0; // printf(" size %ld permutations[0] %d ",pinlist.size(), permutations[0]); for (int i = 0; i < (int)pinlist.size() - 1; i++) { // printf("%d-%d ",i, permutations[i+1]); // fflush(stdout); sum += pathlen[permutations[i]][permutations[i+1]]; } // printf("length %d\n",sum); if (sum < minlen) { minlen = sum; for (int i = 0; i < (int)pinlist.size(); i++) { shortest_permutation[i] = permutations[i]; } } // Fixme, I'd rather use next_combination(). } while ( next_permutation( permutations, permutations + pinlist.size())); // printf(" : Length %d\n", minlen); // for(i=0;i::iterator iter = bbw->modules.begin(); for ( ; iter != bbw->modules.end(); ++iter) { GuiModule *m = *iter; for (int i = 1; i <= m->module()->get_pin_count(); ++i) { stimulus *p; p = m->module()->get_pin(i); if (p == pin) { return (*m->pins())[i - 1]; } } } return 0; } static void treeselect_stimulus(GtkItem *item, GuiPin *pin) { char text[STRING_SIZE]; char string[STRING_SIZE]; const char *pText = "Not connected"; const char *pString = "Stimulus"; if(!pin) return; gtk_widget_show(pin->bbw()->stimulus_frame); gtk_widget_hide(pin->bbw()->node_frame); gtk_widget_hide(pin->bbw()->module_frame); if(pin->getIOpin()) { g_snprintf(string, sizeof(string), "Stimulus %s", pin->getIOpin()->name().c_str()); pString = string; if(pin->getSnode()!=0) g_snprintf(text, sizeof(text), "Connected to node %s", pin->getSnode()->name().c_str()); else g_snprintf(text, sizeof(text), "Not connected"); pText = text; } gtk_frame_set_label(GTK_FRAME(pin->bbw()->stimulus_frame),pString); gtk_label_set_text(GTK_LABEL(pin->bbw()->stimulus_settings_label), pText); pin->bbw()->selected_pin = pin; } static stimulus *stim; static string module_name; static string full_name; static void dumpStimulus(const SymbolEntry_t &sym) { stimulus *ps = dynamic_cast(sym.second); if (ps == stim) { full_name = module_name + "." + ps->name(); } } static void scanModules(const SymbolTableEntry_t &st) { module_name = st.first; (st.second)->ForEachSymbolTable(dumpStimulus); } static const char * stim_full_name(stimulus *stimulus) { stim = stimulus; globalSymbolTable().SymbolTable::ForEachModule(scanModules); return full_name.c_str(); } static void treeselect_node(GtkItem *item, struct gui_node *gui_node) { stimulus *stimulus; GtkListStore *list_store; // printf("treeselect_node %p\n",gui_node); if(gui_node->node!=0) { char str[STRING_SIZE]; g_snprintf(str, sizeof(str), "Node %s", gui_node->node->name().c_str()); gtk_frame_set_label(GTK_FRAME(gui_node->bbw->node_frame),str); gtk_widget_show(gui_node->bbw->node_frame); } else { gtk_widget_hide(gui_node->bbw->node_frame); } gtk_widget_hide(gui_node->bbw->stimulus_frame); gtk_widget_hide(gui_node->bbw->module_frame); // Clear node_clist g_object_get(gui_node->bbw->node_clist, "model", &list_store, NULL); gtk_list_store_clear(list_store); if(gui_node->node!=0) { // Add to node_clist stimulus = gui_node->node->stimuli; while(stimulus!=0) { GtkTreeIter iter; gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, 0, stim_full_name(stimulus), 1, stimulus, -1); stimulus = stimulus->next; } } gui_node->bbw->selected_node = gui_node; } static void treeselect_cb(GtkTreeSelection *selection, gpointer user_data) { GtkTreeModel *model; GtkTreeIter iter; gtk_tree_selection_get_selected(selection, &model, &iter); if (!iter.stamp) return; GtkTreePath *path = gtk_tree_model_get_path(model, &iter); gchar *spath = gtk_tree_path_to_string(path); if (spath[0] == '0') { struct gui_node *gn; gtk_tree_model_get (model, &iter, 1, &gn, -1); if (strlen (spath) > 1) treeselect_node (NULL, gn); else gtk_widget_hide (gn->bbw->node_frame); } else { if (strlen (spath) > 1) { GuiPin *gp; gtk_tree_model_get (model, &iter, 1, &gp, -1); treeselect_stimulus (NULL, gp); } else { GuiModule *module; gtk_tree_model_get (model, &iter, 1, &module, -1); treeselect_module (NULL, module); } } g_free(spath); gtk_tree_path_free(path); } static const char *mod_name; static void settings_clist_cb(GtkTreeSelection *selection, Breadboard_Window *bbw) { // Save the Attribute* Value *attr; char str[256]; char val[256]; GtkTreeIter iter; GtkTreeModel *model; gtk_tree_selection_get_selected (selection, &model, &iter); if (!iter.stamp) // check if iter is valid return; gtk_tree_model_get(model, &iter, 1, &attr, -1); attr->get(val, sizeof(val)); if (mod_name) { g_snprintf(str, sizeof(str), "%s.%s = %s", mod_name, attr->name().c_str(), val); } else { g_snprintf(str, sizeof(str), "%s = %s", attr->name().c_str(), val); } gtk_entry_set_text(GTK_ENTRY(bbw->attribute_entry), str); } static void settings_set_cb(GtkWidget *button, Breadboard_Window *bbw) { const char *entry_string; char attribute_name[256]; char attribute_newval[256]; // We get here from both the button and entry->enter // Check the entry. entry_string=gtk_entry_get_text(GTK_ENTRY(bbw->attribute_entry)); sscanf(entry_string, "%255s = %255s", attribute_name, attribute_newval); printf("change attribute \"%s\" to \"%s\"\n",attribute_name, attribute_newval); Value *attr; // Change the Attribute //attr = bbw->selected_module->module->get_attribute(attribute_name); attr = globalSymbolTable().findValue(attribute_name); if(attr) { try { // Set attribute attr->set(attribute_newval); // Update clist treeselect_module(0, bbw->selected_module); } catch (Error *err) { if(err) cout << __FUNCTION__ <<": " << err->toString() << endl; delete err; } } else { printf("Could not find attribute \"%s\"\n",attribute_name); } } //static Breadboard_Window *lpBW; static GtkWidget *attribute_clist; static void clistOneAttribute(const SymbolEntry_t &sym) { Value *pVal = dynamic_cast(sym.second); if (attribute_clist && pVal) { // read attributes and add to clist char attribute_value[STRING_SIZE]; char attribute_string[STRING_SIZE]; GtkListStore *list_store; GtkTreeIter iter; // Filter out non-attributes if ( !strstr(typeid(*pVal).name(), "Attribute") ) return; pVal->get(attribute_value, sizeof(attribute_value)); g_snprintf(attribute_string, sizeof(attribute_string), "%s = %s", pVal->name().c_str(), attribute_value); g_object_get(attribute_clist, "model", &list_store, NULL); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, 0, attribute_string, 1, (gpointer) pVal, -1); } } static void buildCLISTAttribute(const SymbolTableEntry_t &st) { if (st.first == mod_name) { if (verbose) cout << " gui Module Attribute Window: " << st.first << endl; (st.second)->ForEachSymbolTable(clistOneAttribute); } } static void UpdateModuleFrame(GuiModule *p, Breadboard_Window *bbw) { char buffer[STRING_SIZE]; g_snprintf(buffer, sizeof(buffer), "%s settings", p->module()->name().c_str()); gtk_frame_set_label(GTK_FRAME(p->bbw()->module_frame),buffer); if (!gtk_widget_get_visible(p->bbw()->attribute_clist)) return; // clear clist gtk_list_store_clear((GtkListStore*) gtk_tree_view_get_model((GtkTreeView*)p->bbw()->attribute_clist)); attribute_clist = p->bbw()->attribute_clist; mod_name = p->module()->name().c_str(); globalSymbolTable().ForEachModule(buildCLISTAttribute); attribute_clist = NULL; gtk_entry_set_text(GTK_ENTRY(p->bbw()->attribute_entry), ""); } static void treeselect_module(GtkItem *item, GuiModule *p) { if (p) { gtk_widget_hide(p->bbw()->stimulus_frame); gtk_widget_hide(p->bbw()->node_frame); gtk_widget_show(p->bbw()->module_frame); UpdateModuleFrame(p, p->bbw()); p->bbw()->selected_module = p; } } void GuiModule::SetPosition(int nx, int ny) { nx=nx-nx%pinspacing; ny=ny-ny%pinspacing; if(nx != m_x || ny != m_y) { m_x=nx; m_y=ny; Value *xpos = dynamic_cast (m_module->findSymbol("xpos")); Value *ypos = dynamic_cast (m_module->findSymbol("ypos")); if(xpos) xpos->set(m_x); if(ypos) ypos->set(m_y); // Position module_widget if (m_pinLabel_widget) gtk_layout_move(GTK_LAYOUT(m_bbw->layout), m_pinLabel_widget, m_x, m_y); if (m_module_widget) gtk_layout_move(GTK_LAYOUT(m_bbw->layout), m_module_widget, m_x + m_module_x, m_y + m_module_y); // Position module_name gtk_layout_move(GTK_LAYOUT(m_bbw->layout), m_name_widget->gobj(), m_x, m_y-20); // Position pins std::vector::iterator piniter = m_pins.begin(); for ( ; piniter != m_pins.end(); ++piniter) { GuiPin *pin = *piniter; if(pin->orientation==RIGHT) pin->SetPosition(m_x + pin->module_x()+PINLENGTH,m_y + pin->module_y() + pin->height()/2); else pin->SetPosition(m_x + pin->module_x(), m_y + pin->module_y() + pin->height()/2); gtk_layout_move(GTK_LAYOUT(m_bbw->layout), pin->m_pinDrawingArea,m_x+pin->module_x(),m_y+pin->module_y()); } } } void GuiModule::GetPosition(int &x, int &y) { Value *xpos = dynamic_cast (m_module->findSymbol("xpos")); Value *ypos = dynamic_cast (m_module->findSymbol("ypos")); x = xpos ? (gint64)*xpos : m_x; y = ypos ? (gint64)*ypos : m_y; } /* FIXME: calculate distance to the edges instead of the corners. */ double GuiModule::Distance(int px, int py) { double distance; double min_distance=100000000; // Upper left distance=sqrt((double)abs(m_x-px)*abs(m_x-px) + abs(m_y-py)*abs(m_y-py)); if(distance::iterator mi = bbw->modules.begin(); for ( ; mi != bbw->modules.end(); ++mi) { GuiModule *p = *mi; double distance = p->Distance(x,y); if (distance < min_distance) { closest = p; min_distance = distance; } } return closest; } // FIXME static GuiModule *dragged_module=0; static int dragging=0; static int all_trace = 0; static int grab_next_module=0; void grab_module(GuiModule *p) { dragged_module = p; gdk_pointer_grab(gtk_widget_get_window(p->bbw()->layout), TRUE, (GdkEventMask)(GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK), gtk_widget_get_window(p->bbw()->layout), 0, GDK_CURRENT_TIME); treeselect_module(0,dragged_module); dragging = 1; p->bbw()->clear_nodes(); p->bbw()->draw_nodes(); gtk_widget_set_app_paintable(p->bbw()->layout, FALSE); } static void trace_all(GtkWidget *button, Breadboard_Window *bbw); void Breadboard_Window::pointer_cb(GtkWidget *w, GdkEventButton *event, Breadboard_Window *bbw) { int x,y; x = (int) (event->x); y = (int) (event->y); switch(event->type) { case GDK_MOTION_NOTIFY: if(dragging && 0 != dragged_module) { dragged_module->SetPosition(x+pinspacing, y+pinspacing); } break; case GDK_BUTTON_PRESS: if(grab_next_module) { if(dragging) { gdk_pointer_ungrab(GDK_CURRENT_TIME); dragging = 0; gtk_widget_set_app_paintable(bbw->layout, TRUE); grab_next_module=0; bbw->update_board_matrix(); } } else { dragged_module = find_closest_module(bbw, x, y); if (0 != dragged_module) { gdk_pointer_grab(gtk_widget_get_window(w), TRUE, (GdkEventMask)(GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK), gtk_widget_get_window(w), 0, GDK_CURRENT_TIME); treeselect_module(0,dragged_module); dragging = 1; bbw->clear_nodes(); bbw->draw_nodes(); gtk_widget_set_app_paintable(bbw->layout, FALSE); } } break; case GDK_2BUTTON_PRESS: break; case GDK_BUTTON_RELEASE: if(dragging) { gdk_pointer_ungrab(GDK_CURRENT_TIME); bbw->update_board_matrix(); dragging = 0; gtk_widget_set_app_paintable(bbw->layout, TRUE); if (all_trace) trace_all(w, bbw); UpdateModuleFrame(dragged_module, bbw); } break; default: printf("Whoops? event type %d\n",event->type); break; } } // When clicked on a pin static gint button(GtkWidget *widget, GdkEventButton *event, GuiPin *p) { if(event->type==GDK_BUTTON_PRESS && event->button==1) { if(p->getSnode()) { struct gui_node *gn; gn = (struct gui_node *) g_object_get_data((GObject*)p->bbw()->tree, p->getSnode()->name().c_str()); if(gn!=0) { treeselect_node(0, gn); return 1; } } treeselect_stimulus(0, p); //puts("Stimulus should now be selected"); return 1; } if(event->type==GDK_2BUTTON_PRESS && event->button==1) { p->toggleState(); return 1; } if(event->type==GDK_BUTTON_PRESS && event->button==2) { if(p->getSnode()) { struct gui_node *gn; gn = (struct gui_node *) g_object_get_data((GObject*)p->bbw()->tree, p->getSnode()->name().c_str()); if (gn) { trace_node(gn); gn->bbw->draw_nodes(); } } return 1; } return 0; } // get_string static void a_cb(GtkWidget *w, GtkDialog *dialog) { gtk_dialog_response (dialog, GTK_RESPONSE_ACCEPT); } // used for reading a value from user when break on value is requested static std::string gui_get_string(const char *prompt, const char *initial_text) { GtkWidget *dialog = gtk_dialog_new_with_buttons("enter value", NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *hbox = gtk_hbox_new(FALSE, 12); GtkWidget *label = gtk_label_new("Enter string:"); GtkWidget *label2 = gtk_label_new(prompt); GtkWidget *entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), initial_text); gtk_widget_grab_focus(entry); g_signal_connect(entry, "activate", G_CALLBACK(a_cb), (gpointer)dialog); gtk_box_pack_start(GTK_BOX(content_area), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(content_area), hbox, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label2, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0); gtk_widget_show_all(dialog); gint retval = gtk_dialog_run(GTK_DIALOG(dialog)); std::string string; if (retval == GTK_RESPONSE_ACCEPT) string = gtk_entry_get_text(GTK_ENTRY(entry)); gtk_widget_destroy(dialog); return string; } static void add_new_snode(GtkWidget *button, Breadboard_Window *bbw) { std::string node_name = gui_get_string("Node name", ""); if(!node_name.empty()) new Stimulus_Node(node_name.c_str()); } //////////////////////////////////////////////////////////////////// static void select_node_ok_cb(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, GtkDialog *dialog) { Stimulus_Node* snode; GtkTreeModel *model; GtkTreeIter iter; model = gtk_tree_view_get_model (tree_view); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, 1, &snode, -1); g_object_set_data ((GObject*)dialog, "snode", snode); gtk_dialog_response(dialog, GTK_RESPONSE_ACCEPT); } static void select_module_ok_cb(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, GtkDialog *dialog) { gtk_dialog_response (dialog, GTK_RESPONSE_ACCEPT); } static void copy_tree_to_clist(GtkTreeModel *model, GtkListStore *list_store) { struct gui_node *gn; GtkTreeIter node_iter, iter, new_iter; if (gtk_tree_model_get_iter_first (model, &node_iter)) { if (gtk_tree_model_iter_n_children (model, &node_iter) > 0) { gtk_tree_model_iter_children (model, &iter, &node_iter); do { gtk_tree_model_get (model, &iter, 1, &gn, -1); gtk_list_store_append(list_store, &new_iter); gtk_list_store_set(list_store, &new_iter, 0, gn->node->name().c_str(), 1, (gpointer) gn->node, -1); if (!iter.stamp) break; } while (gtk_tree_model_iter_next (model, &iter)); } } } static Stimulus_Node *select_node_dialog(Breadboard_Window *bbw) { GtkWidget *dialog = gtk_dialog_new_with_buttons("Select node to connect to", GTK_WINDOW(bbw->window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); GtkWidget *vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *scrolledwindow = gtk_scrolled_window_new (0, 0); gtk_box_pack_start(GTK_BOX(vbox), scrolledwindow, TRUE, TRUE, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkListStore *list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); GtkWidget *node_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store)); g_object_unref(list_store); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(node_list), FALSE); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(node_list), 0, "Nodes", renderer, "text", 0, NULL); gtk_container_add(GTK_CONTAINER(scrolledwindow), node_list); gtk_window_set_default_size(GTK_WINDOW(dialog), 220, 400); copy_tree_to_clist( gtk_tree_view_get_model((GtkTreeView*) bbw->tree), list_store); g_signal_connect(node_list, "row-activated", G_CALLBACK(select_node_ok_cb), dialog); gtk_widget_show_all(dialog); int resp = gtk_dialog_run((GtkDialog*)dialog); Stimulus_Node *snode = static_cast(g_object_get_data((GObject*) dialog, "snode")); gtk_widget_destroy(dialog); if (resp == GTK_RESPONSE_ACCEPT) return snode; return 0; } static std::string select_module_dialog(Breadboard_Window *bbw) { GtkWidget *dialog = gtk_dialog_new_with_buttons("Select module to load", GTK_WINDOW(bbw->window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); GtkWidget *vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *scrolledwindow = gtk_scrolled_window_new(0, 0); gtk_box_pack_start(GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); const gchar *module_clist_titles[] = {"Name1","Name2", "Library"}; #ifdef OLD_MODULE_LIBRARY int n_columns = 2; GtkListStore *list_store = gtk_list_store_new(n_columns + 1, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); int width = 220; #else int n_columns = 3; GtkListStore *list_store = gtk_list_store_new(n_columns + 1, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); int width = 320; #endif GtkWidget *module_clist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store)); g_object_unref(list_store); for (int col = 0; col < n_columns; ++col) { GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes( module_clist_titles[col], renderer, "text", col, NULL); g_object_set(column, "resizable", TRUE, "sort-indicator", TRUE, "sort-column-id", col, NULL); gtk_tree_view_append_column((GtkTreeView*) module_clist, column); } gtk_container_add (GTK_CONTAINER(scrolledwindow), module_clist); g_signal_connect(module_clist, "row-activated", G_CALLBACK(select_module_ok_cb), dialog); gtk_window_set_default_size(GTK_WINDOW(dialog), width, 400); #ifdef OLD_MODULE_LIBRARY ModuleLibrary::FileList::iterator mi; ModuleLibrary::FileList::iterator itFileListEnd(ModuleLibrary::GetFileList().end()); // Add all modules for (mi = ModuleLibrary::GetFileList().begin(); mi != itFileListEnd; ++mi) { ModuleLibrary::File *t = *mi; cout << t->name() << '\n'; Module_Types * pFileTypes; if((pFileTypes = t->get_mod_list())) { // Loop through the list and display all of the modules. int i=0; while(pFileTypes[i].names[0]) { char name[STRING_SIZE]; char library[STRING_SIZE]; char *text[2]={name, library}; GtkTreeIter iter; g_strlcpy(name, pFileTypes[i].names[0], STRING_SIZE); g_strlcpy(library, t->name(), STRING_SIZE); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, 0, name, 1, library, 2, pFileTypes[i].names[1], -1); i++; } } } #else //OLD_MODULE_LIBRARY extern ModuleLibraries_t ModuleLibraries; for ( ModuleLibraries_t::iterator mti = ModuleLibraries.begin(); mti != ModuleLibraries.end(); ++mti) { const char *text[3]; Module_Types * (*get_mod_list)(void) = mti->second->mod_list(); Module_Types *pLibModList = get_mod_list(); text[2] = mti->second->user_name().c_str(); if(pLibModList) for(Module_Types *pModTypes = pLibModList; pModTypes->names[0]; pModTypes++) { GtkTreeIter iter; text[0] = pModTypes->names[0]; text[1] = pModTypes->names[1]; gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, 0, text[0], 1, text[1], 2, text[2], 3, text[0], -1); } } #endif gtk_widget_show_all(dialog); int resp = gtk_dialog_run((GtkDialog*)dialog); if (resp == GTK_RESPONSE_ACCEPT) { GtkTreeIter iter; GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(module_clist)); if (!gtk_tree_selection_get_selected(sel, NULL, &iter)) { gtk_widget_destroy(dialog); return ""; } gchar *s; gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, 0, &s, -1); std::string str = s; g_free(s); gtk_widget_destroy(dialog); return str; } gtk_widget_destroy(dialog); return ""; } #if 0 // Display a file in a text widget. static void text_dialog(const char *filename) { static GtkWidget *dialog; GtkWidget *cancelbutton; GtkWidget *vbox; GtkWidget *scrolledwindow; GtkWidget *text; char string[STRING_SIZE]; FILE *fi=fopen(filename,"r"); if(fi==0) return; if(dialog!=0) gtk_widget_destroy(dialog); // Build window dialog = gtk_dialog_new(); gtk_window_set_title (GTK_WINDOW (dialog), filename); vbox = GTK_DIALOG(dialog)->vbox; scrolledwindow = gtk_scrolled_window_new (0, 0); gtk_widget_show (scrolledwindow); gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); text = gtk_text_new(0,0); gtk_container_add (GTK_CONTAINER(scrolledwindow), text); gtk_widget_show(text); cancelbutton = gtk_button_new_with_label ("Ok"); gtk_widget_show (cancelbutton); gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->action_area), cancelbutton, FALSE, FALSE, 0); gtk_signal_connect_object(GTK_OBJECT(cancelbutton),"clicked", GTK_SIGNAL_FUNC(gtk_widget_hide),GTK_OBJECT(dialog)); gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 400); while(fgets(string, sizeof(string), fi)!=0) { gtk_text_insert(GTK_TEXT(text), 0, 0, 0, string, strlen(string)); } fclose(fi); gtk_widget_show(dialog); return; } #endif static void stimulus_add_node(GtkWidget *button, Breadboard_Window *bbw) { Stimulus_Node *node; node = select_node_dialog(bbw); if(node!=0 && bbw->selected_pin!=0) { node->attach_stimulus(bbw->selected_pin->getIOpin()); // Update stimulus frame treeselect_stimulus(0, bbw->selected_pin); } } static void add_library(GtkWidget *button, Breadboard_Window *bbw) { std::string library_name = gui_get_string("Module library name (e.g. libgpsim_modules)",""); #ifdef OLD_MODULE_LIBRARY if(!library_name.empty()) ModuleLibrary::LoadFile(library_name.c_str()); #else if(!library_name.empty()) { ModuleLibrary::LoadFile(library_name); } #endif } static void add_module(GtkWidget *button, Breadboard_Window *bbw) { std::string module_type = select_module_dialog(bbw); if (!module_type.empty()) { std::string module_name = gui_get_string("Module name", module_type.c_str()); grab_next_module = 1; if(!module_name.empty()) #ifdef OLD_MODULE_LIBRARY ModuleLibrary::NewObject(module_type.c_str(), module_name.c_str()); #else { if(!ModuleLibrary::InstantiateObject(module_type, module_name)) fprintf(stderr, "Module load of %s %s failed\n", module_type.c_str(), module_name.c_str()); } #endif } } static void remove_module(GtkWidget *button, Breadboard_Window *bbw) { delete(bbw->selected_module->module()); // FIXME the rest should be as callback from src // Remove pins std::vector *e = bbw->selected_module->pins(); std::vector::iterator pin_iter = e->begin(); for ( ; pin_iter != e->end(); ++pin_iter) { GuiPin *pin = *pin_iter; gtk_widget_destroy(GTK_WIDGET(pin->m_pinDrawingArea)); } // Remove widget if (bbw->selected_module->module_widget()) gtk_container_remove(GTK_CONTAINER(bbw->layout), bbw->selected_module->module_widget()); if (bbw->selected_module->pinLabel_widget()) gtk_container_remove(GTK_CONTAINER(bbw->layout), bbw->selected_module->pinLabel_widget()); gtk_container_remove(GTK_CONTAINER(bbw->layout), bbw->selected_module->name_widget()); // Remove module from tree GtkTreeModel *model; GtkTreeSelection *selection; GtkTreeIter iter; selection = gtk_tree_view_get_selection ((GtkTreeView*) bbw->tree); gtk_tree_selection_get_selected (selection, &model, &iter); gtk_tree_store_set ((GtkTreeStore*) model, &iter, 1, NULL, -1); gtk_tree_store_remove ((GtkTreeStore*) model, &iter); // Remove from local list of modules std::vector::iterator mi = std::find(bbw->modules.begin(), bbw->modules.end(), bbw->selected_module); if (mi != bbw->modules.end()) bbw->modules.erase(mi); gtk_widget_hide(bbw->module_frame); delete bbw->selected_module; bbw->selected_module=0; } static void remove_node(GtkWidget *button, Breadboard_Window *bbw) { GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; struct gui_node *gn; selection = gtk_tree_view_get_selection ((GtkTreeView*) bbw->tree); gtk_tree_selection_get_selected (selection, &model, &iter); gtk_tree_model_get (model, &iter, 1, &gn, -1); gtk_tree_store_remove ((GtkTreeStore*) model, &iter); g_object_set_data (G_OBJECT (bbw->tree), gn->node->name().c_str(), NULL); delete gn; gtk_widget_hide(bbw->node_frame); gtk_widget_hide(bbw->stimulus_frame); gtk_widget_hide(bbw->module_frame); } static void remove_node_stimulus(GtkWidget *button, Breadboard_Window *bbw) { stimulus *s; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; selection = gtk_tree_view_get_selection ((GtkTreeView*) bbw->node_clist); gtk_tree_selection_get_selected (selection, &model, &iter); gtk_tree_model_get (model, &iter, 1, &s, -1); bbw->selected_node->node->detach_stimulus(s); gtk_list_store_remove ((GtkListStore*) model, &iter); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // Returns a file name which must be freed with g_free() or NULL static char *gui_get_filename(const char *filename) { GtkWidget *dialog = gtk_file_chooser_dialog_new("Log settings", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); if (filename) { gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename); } else { gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), "."); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "netlist.stc"); } char *file = NULL; if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); } gtk_widget_destroy(dialog); return file; } static FILE *fo; static void OneAttribute(const SymbolEntry_t &sym) { Value *pVal = dynamic_cast(sym.second); if (pVal && fo) { // read attributes and add to clist if ( strstr(typeid(*pVal).name(), "Attribute") ) { char attribute_value[STRING_SIZE]; pVal->get(attribute_value, sizeof(attribute_value)); fprintf(fo, "%s.%s = %s\n", mod_name, pVal->name().c_str(), attribute_value); } } } static char *stc_file = 0; ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// static void save_stc(GtkWidget *button, Breadboard_Window *bbw) { Module *m; char *filename = gui_get_filename(stc_file); if(!filename) return; if ((fo = fopen(filename, "w")) == NULL) { perror(filename); g_free(filename); return; } if (stc_file) free(stc_file); stc_file = strdup(filename); g_free(filename); fprintf(fo, "\n# This file was written by gpsim.\n"); fprintf(fo, "\n# You can use this file for example like this:"); fprintf(fo, "\n# gpsim -s mycode.cod -c netlist.stc\n"); fprintf(fo, "\n# If you want to add commands, you can create another .stc file"); fprintf(fo, "\n# and load this file from it. Something like this:"); fprintf(fo, "\n# ----------- myproject.stc ---------------"); fprintf(fo, "\n# load s mycode.cod"); fprintf(fo, "\n# frequency 12000000"); fprintf(fo, "\n# load c netlist.stc"); fprintf(fo, "\n# -----------------------------------------"); fprintf(fo, "\n# You can then just load this new file:"); fprintf(fo, "\n# gpsim -c myproject.stc"); fprintf(fo, "\n# and use netlist.stc whenever you save from the breadboard."); fprintf(fo, "\n#"); fprintf(fo, "\n"); fprintf(fo, "\n\n# Processor position:\n"); #ifdef OLD_MODULE_LIBRARY // Save module libraries fprintf(fo, "\n\n# Module libraries:\n"); ModuleLibrary::FileList::iterator mi; // Add all modules for (mi = ModuleLibrary::GetFileList().begin(); mi != ModuleLibrary::GetFileList().end(); ++mi) { ModuleLibrary::File *t = *mi; fprintf(fo, "module library %s\n", t->name()); } #else extern ModuleLibraries_t ModuleLibraries; for ( ModuleLibraries_t::iterator mti = ModuleLibraries.begin(); mti != ModuleLibraries.end(); ++mti) { fprintf(fo, "module library %s\n", mti->second->user_name().c_str()); } #endif // Save modules fprintf(fo, "\n\n# Modules:\n"); std::vector::iterator module_iterator = bbw->modules.begin(); for ( ; module_iterator != bbw->modules.end(); ++module_iterator) { GuiModule *p = *module_iterator; m = p->module(); SymbolTable_t *st = &m->getSymbolTable(); Processor *cpu; cpu=dynamic_cast(m); if(cpu==0) { // Module, not a processor, so add the load command fprintf(fo, "module load %s %s\n", m->type(), m->name().c_str()); } mod_name = m->name().c_str(); st->ForEachSymbolTable(OneAttribute); fprintf(fo, "\n"); } // Save nodes and connections fprintf(fo, "\n\n# Connections:\n"); std::vector::iterator list = bbw->nodes.begin(); for ( ; list != bbw->nodes.end(); ++list) { Stimulus_Node *node = *list; stimulus *stimulus; fprintf(fo, "node %s\n",node->name().c_str()); if(node->stimuli!=0) { fprintf(fo, "attach %s",node->name().c_str()); for (stimulus = node->stimuli; stimulus; stimulus = stimulus->next) fprintf(fo, " %s",stim_full_name(stimulus)); } fprintf(fo, "\n\n"); } fprintf(fo, "\n\n# End.\n"); fclose(fo); fo = NULL; //text_dialog(filename); } static void clear_traces(GtkWidget *button, Breadboard_Window *bbw) { all_trace = 0; bbw->update_board_matrix(); } static void trace_all(GtkWidget *button, Breadboard_Window *bbw) { struct gui_node *gn; GtkTreeModel *model; GtkTreeIter p_iter, c_iter; bool did_work = true; bbw->update_board_matrix(); if ((model = gtk_tree_view_get_model ((GtkTreeView*) bbw->tree)) == NULL) return; if(!gtk_tree_model_get_iter_first (model, &p_iter)) return; if (!gtk_tree_model_iter_children (model, &c_iter, &p_iter)) return; do { gtk_tree_model_get (model, &c_iter, 1, &gn, -1); if (!trace_node(gn)) did_work = false; } while (gtk_tree_model_iter_next (model, &c_iter)); bbw->draw_nodes(); if (!did_work) gtk_label_set_text(GTK_LABEL(bbw->status_line), "Can not trace all nodes"); else gtk_label_set_text(GTK_LABEL(bbw->status_line), ""); all_trace = 1; if (verbose) puts("Trace all is done."); } //======================================================================== GuiBreadBoardObject::GuiBreadBoardObject(Breadboard_Window *bbw,int x, int y) : m_bbw(bbw), m_x(x), m_y(y), m_width(0), m_height(0), m_bIsBuilt(false) { } GuiBreadBoardObject::~GuiBreadBoardObject() { } void GuiBreadBoardObject::SetPosition(int x, int y) { m_x = x; m_y = y; } void GuiPin::SetModulePosition(int x, int y) { m_module_x = x; m_module_y = y; } //======================================================================== GuiPin::GuiPin(Breadboard_Window *_bbw, GuiModule *pModule, Package *_package, unsigned int pin_number) : GuiBreadBoardObject(_bbw, 0, 0), package(_package), m_pModule(pModule), m_module_x(0), m_module_y(0), m_label_x(0), m_label_y(0), m_pkgPinNumber(pin_number) { IOPIN *iopin = getIOpin(); m_width=pinspacing; m_height=pinspacing; orientation = LEFT; if(iopin) { value=iopin->getState(); direction=iopin->get_direction()==0?PIN_INPUT:PIN_OUTPUT; //orientation=_orientation; type=PIN_DIGITAL; } else { value=false; direction=PIN_INPUT; //orientation=_orientation; type=PIN_OTHER; } // Create widget m_pinDrawingArea = gtk_drawing_area_new(); gtk_widget_set_events(m_pinDrawingArea, gtk_widget_get_events(m_pinDrawingArea)| GDK_BUTTON_PRESS_MASK); g_signal_connect(m_pinDrawingArea, "button_press_event", G_CALLBACK(button), this); gtk_widget_set_size_request(m_pinDrawingArea, m_width, m_height); g_signal_connect(m_pinDrawingArea, "expose_event", G_CALLBACK(expose_pin), this); gtk_widget_show(m_pinDrawingArea); } const char *GuiPin::pinName() { IOPIN *iopin = getIOpin(); return iopin ? iopin->name().c_str() : 0; } //------------------------------------------------------------------------ // GuiPin::update() - check the state of the iopin and make the gui match // void GuiPin::Update() { IOPIN *iopin = getIOpin(); if(iopin) { bool value=iopin->getState(); eDirection dir=iopin->get_direction()==0?PIN_INPUT:PIN_OUTPUT; if(value!=getState() || dir!=direction) { putState(value); direction=dir; Draw(); } } } //------------------------------------------------------------------------ void GuiPin::toggleState() { IOPIN *iopin = getIOpin(); if(iopin) { char cPinState = iopin->getForcedDrivenState(); switch (cPinState) { case '0': case 'Z': case 'X': iopin->forceDrivenState('1'); break; case '1': iopin->forceDrivenState('0'); break; case 'W': iopin->forceDrivenState('w'); break; case 'w': iopin->forceDrivenState('W'); break; } m_bbw->Update(); } } //------------------------------------------------------------------------ // GuiPin::draw() - draw a single pin // // void GuiPin::Draw() { GdkWindow *gdk_win = gtk_widget_get_window(m_pinDrawingArea); if (!gdk_win) return; gdk_window_invalidate_rect(gdk_win, NULL, FALSE); } gboolean GuiPin::expose_pin(GtkWidget *widget, GdkEventExpose *event, GuiPin *p) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); int pointx; int wingheight, wingx; int casex, endx; switch (p->orientation) { case LEFT: casex = p->m_width; endx = 0; break; default: casex = 0; endx = p->m_width; break; } int y = p->m_height / 2; if (p->type != PIN_OTHER) gdk_cairo_set_source_color(cr, p->getState() ? &high_output_color : &low_output_color); // Draw actual pin cairo_set_line_width(cr, PINLINEWIDTH); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_move_to(cr, casex, y); cairo_line_to(cr, endx, y); cairo_stroke(cr); if (p->type == PIN_OTHER) { cairo_destroy(cr); return FALSE; } // Draw direction arrow wingheight = p->m_height / 3; if (casex > endx) { if (p->direction == PIN_OUTPUT) { pointx = endx + PINLENGTH /3; wingx = endx + (PINLENGTH * 2) / 3; } else { pointx = endx + (PINLENGTH * 2) / 3; wingx = endx + PINLENGTH / 3; } } else { if (p->direction == PIN_OUTPUT) { pointx = casex + (PINLENGTH * 2) / 3; wingx = casex + PINLENGTH / 3; } else { pointx = casex + PINLENGTH / 3; wingx = casex + (PINLENGTH * 2) / 3; } } // Draw an arrow poining at (endx,endy) cairo_move_to(cr, wingx, wingheight + y); cairo_line_to(cr, pointx, y); cairo_line_to(cr, wingx, wingheight - y); cairo_stroke(cr); cairo_destroy(cr); return FALSE; } void GuiPin::SetLabelPosition(int x, int y) { m_label_x = x; m_label_y = y; } //------------------------------------------------------------------------ // GuiPin::DrawLabel() - draw the label for a single pin // // void GuiPin::DrawLabel(cairo_t *cr) { IOPIN *iopin = getIOpin(); if (!iopin || !m_bbw) return; const char *name = iopin->GUIname().empty() ? iopin->name().c_str() : iopin->GUIname().c_str(); if (*name) { PangoLayout *layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, m_bbw->pinnamefont); pango_layout_set_text(layout, name, -1); pango_cairo_update_layout(cr, layout); cairo_move_to(cr, m_label_x, m_label_y - pango_layout_get_baseline(layout) / PANGO_SCALE); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } } //------------------------------------------------------------------------ // GuiPin::DrawGUIlabel() - Gte it pin has changed since last access // // bool GuiPin::DrawGUIlabel() { IOPIN *iopin = getIOpin(); if (iopin && iopin->is_newGUIname()) { iopin->clr_is_newGUIname(); return true; } return false; } //------------------------------------------------------------------------ void GuiPin::addXref(CrossReferenceToGUI *newXref) { xref = newXref; } //------------------------------------------------------------------------ void GuiPin::Destroy() { if(xref) getIOpin()->remove_xref(xref); gtk_widget_destroy(m_pinDrawingArea); } //------------------------------------------------------------------------ gboolean GuiModule::module_expose(GtkWidget *widget, GdkEventExpose *event, GuiModule *p) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); p->DrawCaseOutline(cr); std::vector::iterator pin_iter = p->m_pins.begin(); for ( ; pin_iter != p->m_pins.end(); ++pin_iter) { GuiPin *pin = *pin_iter; pin->DrawLabel(cr); } cairo_destroy(cr); return FALSE; } void GuiModule::Draw() { } void GuiModule::Destroy() { } #define PACKAGESPACING 15 void GuiModule::Update() { g_object_ref(m_pinLabel_widget); gtk_container_remove(GTK_CONTAINER(m_bbw->layout),m_pinLabel_widget); // Delete the static module pixmap if there is no widget // in the module. if(m_module->get_widget()==0) { gtk_widget_destroy(m_pinLabel_widget); } // Delete the pins std::vector::iterator pin_iter = m_pins.begin(); for ( ; pin_iter != m_pins.end(); ++pin_iter) { GuiPin *pin = *pin_iter; pin->Destroy(); } // Destroy name widget delete m_name_widget; // Remove module from list std::vector::iterator iter = std::find(m_bbw->modules.begin(), m_bbw->modules.end(), this); if (iter != m_bbw->modules.end()) m_bbw->modules.erase(iter); // rebuild module Build(); g_object_unref(m_pinLabel_widget); } void GuiModule::UpdatePins() { bool change = false; std::vector::iterator pin_iter = m_pins.begin(); for ( ; pin_iter != m_pins.end(); ++pin_iter) { GuiPin *pin = *pin_iter; change |= pin->DrawGUIlabel(); pin->Update(); } if (change) { gtk_widget_queue_draw(m_pinLabel_widget); } } //======================================================================== //======================================================================== class PositionAttribute : public Float { protected: Breadboard_Window *bbw; public: PositionAttribute(Breadboard_Window *_bbw,const char *n, double v); void set(Value *v); }; PositionAttribute::PositionAttribute(Breadboard_Window *_bbw, const char *n, double v) : Float(v), bbw(_bbw) { new_name((char*)n); } void PositionAttribute::set(Value *v) { Float::set(v); if(bbw) bbw->Update(); } //------------------------------------------------------------------------ void GuiModule::DrawCaseOutline(cairo_t *cr) { cairo_rectangle(cr, CASEOFFSET,CASEOFFSET, m_width-2*CASEOFFSET, m_height-2*CASEOFFSET); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); } //------------------------------------------------------------------------ // static float hackPackageHeight=0.0; void GuiModule::AddPin(unsigned int pin_number) { IOPIN *iopin = m_module->get_pin(pin_number); BreadBoardXREF *cross_reference = 0; if(iopin) { // Create xref cross_reference = new BreadBoardXREF(); cross_reference->parent_window = (gpointer) m_bbw; cross_reference->data = NULL; iopin->add_xref(cross_reference); } GuiPin *pin = new GuiPin(m_bbw, this, m_module->package, pin_number); pin->addXref(cross_reference); m_pins.push_back(pin); } void GuiModule::AddPinGeometry(GuiPin *pin) { eOrientation orientation; unsigned int pin_number = pin->number(); // Get the X and Y coordinates for this pin // (the coordinates are referenced to the module's origin) int pin_x, pin_y; int label_x, label_y; const PinGeometry *pPinGeometry = m_module->package->getPinGeometry(pin_number); if (pPinGeometry->bNew) { switch (pPinGeometry->m_orientation) { case UP: pin_x = (int)pPinGeometry->m_x; pin_y = (int)pPinGeometry->m_y; label_x = pin_x + LABELPAD + CASELINEWIDTH; label_y = pin_y + LABELPAD + CASELINEWIDTH; orientation = UP; break; case LEFT: pin_x = (int)pPinGeometry->m_x - pinspacing; pin_y = (int)pPinGeometry->m_y; label_x = LABELPAD + CASELINEWIDTH; label_y = pin_y + LABELPAD + CASELINEWIDTH; orientation = LEFT; break; case RIGHT: pin_x = m_width + (int)pPinGeometry->m_x; pin_y = (int)pPinGeometry->m_y; label_x = pin_x + LABELPAD + CASELINEWIDTH + m_width/2; label_y = pin_y + LABELPAD + CASELINEWIDTH; orientation = RIGHT; break; case DOWN: pin_x = (int)pPinGeometry->m_x; pin_y = m_height + (int)pPinGeometry->m_y; label_x = pin_x + LABELPAD + CASELINEWIDTH; label_y = pin_y + LABELPAD + CASELINEWIDTH; orientation = DOWN; break; default: printf("################### Error:\n"); printf("Undefined orientation.\n"); assert(0); } } else { // old style -- to be deprecated. float pin_position=m_module->package->get_pin_position(pin_number); // Put pin in layout if(pin_position>=0.0 && pin_position<1.0) { pin_x=-pinspacing; pin_y=(int)(m_height/2+((pin_position-0.5)*hackPackageHeight))-pinspacing/2; orientation = LEFT; label_x=LABELPAD+CASELINEWIDTH; label_y=(int)(pin_position*hackPackageHeight); label_y+=LABELPAD+CASELINEWIDTH+pinspacing/2-m_bbw->pinnameheight/3; label_y+=PINLENGTH/2; } else if(pin_position>=2.0 && pin_position<3.0) { pin_x=m_width; pin_y=(int)(m_height/2+((3.0-pin_position-0.5)*hackPackageHeight))-pinspacing/2; orientation = RIGHT; label_x= m_width/2 + CASELINEWIDTH; label_y=(int)((3.0-pin_position)*hackPackageHeight); label_y+=LABELPAD+CASELINEWIDTH+pinspacing/2-m_bbw->pinnameheight/3; label_y+=PINLENGTH/2; } else { // FIXME printf("################### Error:\n"); printf("Number of pins %u\n", m_module->package->number_of_pins); printf("pin_position %f\n",pin_position); printf("pin_position2 %f\n",m_module->package->get_pin_position(pin_number)); printf("pin_number %u\n", pin_number); assert(0); } } pin->SetModulePosition(pin_x,pin_y); pin->SetLabelPosition(label_x,label_y); pin->SetOrientation(orientation); pin->Draw(); } //------------------------------------------------------------------------ void GuiModule::Build() { if(m_bIsBuilt || !m_bbw) return; if(!m_bbw->enabled) return; int nx, ny; BreadBoardXREF *cross_reference; m_width=50; m_height=18; Package *package = m_module->package; if(!package) return; // embedded module m_module_widget = (GtkWidget *)m_module->get_widget(); m_pin_count = m_module->get_pin_count(); /* Value *xpos = m_module->get_attribute("xpos", false); Value *ypos = m_module->get_attribute("ypos", false); xpos->get(nx); ypos->get(ny); */ GetPosition(nx,ny); GtkTreeIter module_titer, pin_titer; GtkTreeStore *tree_store; g_object_get (m_bbw->tree, "model", &tree_store, NULL); gtk_tree_store_append (tree_store, &module_titer, NULL); gtk_tree_store_set (tree_store, &module_titer, 0, m_module->name().c_str(), 1, this, -1); hackPackageHeight=(float)((m_pin_count/2+(m_pin_count&1)-1)*pinspacing); // Find the length of the longest pin name in each direction // The directions are in the order of left, up , right, down. cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(m_bbw->window)); PangoLayout *layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, m_bbw->pinnamefont); for (int i = 1; i <= m_pin_count; i++) { PinGeometry *pPinGeometry = m_module->package->getPinGeometry(i); pPinGeometry->convertToNew(); int w = 0; std::string name = m_module->get_pin_name(i); if (!name.empty() && pPinGeometry->m_bShowPinname) { pango_layout_set_text(layout, name.c_str(), -1); pango_layout_get_size(layout, &w, NULL); w /= PANGO_SCALE; } if(w > pinnameWidths[pPinGeometry->m_orientation]) pinnameWidths[pPinGeometry->m_orientation]= w; AddPin(i); } g_object_unref(layout); cairo_destroy(cr); if(!m_module_widget) { // Create a static representation. m_width = pinnameWidths[0] + pinnameWidths[2] + 2 * FOORADIUS; m_width += 2*CASELINEWIDTH+2*LABELPAD; m_height = m_module->get_pin_count()/2*pinspacing; // pin name height if(m_module->get_pin_count()%2) m_height += pinspacing; m_height+=2*CASELINEWIDTH+2*LABELPAD; m_pinLabel_widget = gtk_drawing_area_new(); gtk_widget_set_size_request(m_pinLabel_widget, m_width, m_height); gtk_widget_show_all (m_pinLabel_widget); g_signal_connect(m_pinLabel_widget, "expose_event", G_CALLBACK(module_expose), this); gtk_widget_show(m_pinLabel_widget); } else { // Get the [from the module] provided widget's size GtkRequisition req; gtk_widget_size_request(m_module_widget, &req); m_width=req.width; m_height=req.height; gtk_widget_show(m_module_widget); } // Create xref cross_reference = new BreadBoardXREF(); cross_reference->parent_window = (gpointer) m_bbw; cross_reference->data = 0; m_module->xref->_add(cross_reference); // Create name_widget m_name_widget = new BB_ModuleLabel(m_module->name(), m_bbw->pinnamefont); std::vector::iterator pin_iter = m_pins.begin(); for ( ; pin_iter != m_pins.end(); ++pin_iter) { GuiPin *pin = *pin_iter; AddPinGeometry(pin); gtk_layout_put(GTK_LAYOUT(m_bbw->layout),pin->m_pinDrawingArea,0,0); // Add pin to tree const char *name = pin->pinName(); if(name) { gtk_tree_store_append (tree_store, &pin_titer, &module_titer); gtk_tree_store_set (tree_store, &pin_titer, 0, name, 1, pin, -1); } } if (m_pinLabel_widget) gtk_layout_put(GTK_LAYOUT(m_bbw->layout), m_pinLabel_widget, 0, 0); if (m_module_widget) gtk_layout_put(GTK_LAYOUT(m_bbw->layout), m_module_widget, 0, 0); gtk_layout_put(GTK_LAYOUT(m_bbw->layout), m_name_widget->gobj(), 0,0); SetPosition(nx, ny); m_bIsBuilt = true; m_bbw->update_board_matrix(); } //======================================================================== //======================================================================== GuiModule::GuiModule(Module *_module, Breadboard_Window *_bbw) : GuiBreadBoardObject(_bbw,0,0), m_module(_module), m_module_widget(0), m_pinLabel_widget(0), m_module_x(0), m_module_y(0), m_name_widget(0), m_pin_count(0) { m_width=0; m_height=0; pinnameWidths[0] = 0; pinnameWidths[1] = 0; pinnameWidths[2] = 0; pinnameWidths[3] = 0; if(m_bbw) { m_bbw->modules.push_back(this); if (m_module) { Value *xpos = dynamic_cast (m_module->findSymbol("xpos")); Value *ypos = dynamic_cast (m_module->findSymbol("xpos")); if(!xpos || !ypos) { xpos = new PositionAttribute(m_bbw, "xpos", 80.0); ypos = new PositionAttribute(m_bbw, "ypos", 80.0); m_module->addSymbol(xpos); m_module->addSymbol(ypos); } } } } //======================================================================== GuiDipModule::GuiDipModule(Module *_module, Breadboard_Window *_bbw) : GuiModule(_module, _bbw) { } void GuiDipModule::DrawCaseOutline(cairo_t *cr) { cairo_line_to (cr, CASEOFFSET, CASEOFFSET); cairo_line_to (cr, CASEOFFSET, m_height-2*CASEOFFSET); cairo_line_to (cr, m_width-CASEOFFSET, m_height-2*CASEOFFSET); cairo_line_to (cr, m_width-CASEOFFSET, CASEOFFSET); cairo_arc (cr, m_width/2-CASEOFFSET, CASEOFFSET, FOORADIUS, 0, M_PI); cairo_close_path (cr); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); } //======================================================================== void Breadboard_Window::Update(void) { int x,y; // loop all modules and look for changes if(!enabled) return; if(!gtk_widget_get_visible(window)) return; std::vector::iterator iter = modules.begin(); for ( ; iter != modules.end(); ++iter) { GuiModule *p = *iter; if(p->IsBuilt()) { // Check if module has changed number of pins if(p->pin_count()!=p->module()->get_pin_count()) // If so, refresh the gui widget p->Update(); // Check if module has changed its position p->GetPosition(x,y); if(p->x()!=x || p->y()!=y) { // If so, move the module p->SetPosition(x, y); p->bbw()->update_board_matrix(); } // Check if pins have changed state p->UpdatePins(); } else { p->Build(); Update(); } } } static int delete_event(GtkWidget *widget, GdkEvent *event, Breadboard_Window *bww) { bww->ChangeView(VIEW_HIDE); return TRUE; } /* When a processor is created */ void Breadboard_Window::NewProcessor(GUI_Processor *_gp) { m_MainCpuModule = new GuiDipModule(gp->cpu, this); if(!enabled) return; m_MainCpuModule->Build(); if(!gp || !gp->cpu) return; Update(); } /* When a module is created */ void Breadboard_Window::NewModule(Module *module) { GuiModule *p=new GuiModule(module, this); if(!enabled) return; p->Build(); if(grab_next_module) grab_module(p); Update(); } /* When a stimulus is being connected or disconnected, or a new node is created */ void Breadboard_Window::NodeConfigurationChanged(Stimulus_Node *node) { if (std::find(nodes.begin(), nodes.end(), node) == nodes.end()) nodes.push_back(node); if (!node_iter) return; struct gui_node *gn = (struct gui_node*) g_object_get_data (G_OBJECT (tree), node->name().c_str()); GtkTreeStore *tree_store; g_object_get (tree, "model", &tree_store, NULL); if (!gn) { GtkTreeIter parent_iter, iter; gn = new gui_node; gn->bbw = this; gn->node = node; g_object_set_data(G_OBJECT(tree), node->name().c_str(), gn); gtk_tree_model_get_iter_first ((GtkTreeModel*) tree_store, &parent_iter); gtk_tree_store_append (tree_store, &iter, &parent_iter); gtk_tree_store_set (tree_store, &iter, 0, node->name().c_str(), 1, gn, -1); } } static GtkWidget *bb_vbox(GtkWidget *window) { GtkWidget *vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); return vbox; } static GtkWidget *bb_hbox(GtkWidget *window) { GtkWidget *hbox = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox); return hbox; } GtkWidget* Breadboard_Window::add_button(const char *label, GCallback f, GtkWidget *box) { GtkWidget *button = gtk_button_new_with_label (label); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); g_signal_connect(button, "clicked", G_CALLBACK(f), this); return button; } void Breadboard_Window::Build(void) { if(bIsBuilt) return; if(!enabled) return; GtkWidget *hpaned1; GtkWidget *vbox9; GtkWidget *vbox13; GtkWidget *scrolledwindow4; GtkWidget *tree1; GtkWidget *hbox12; GtkWidget *hbox15; GtkWidget *vbox11; GtkWidget *scrolledwindow2; GtkWidget *viewport7; GtkWidget *hbox10; GtkWidget *vbox14; GtkWidget *hbox13; GtkWidget *vbox10; GtkWidget *scrolledwindow1; GtkWidget *viewport6; GtkWidget *hbox9; GtkWidget *hbox14; GtkWidget *scrolledwindow5; GtkCellRenderer *renderer; GtkListStore *list_store; GtkTreeStore *tree_store; GtkTreeSelection *selection; gdk_color_parse("red",&high_output_color); gdk_color_parse("green",&low_output_color); // // Top level window // window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_object_set_data (G_OBJECT (window), "window", window); gtk_window_set_title (GTK_WINDOW (window), "Breadboard"); // // Status line // GtkWidget *base_box = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(window), base_box); status_line = gtk_label_new(""); gtk_box_pack_end(GTK_BOX(base_box), status_line, FALSE, FALSE, 0); gtk_widget_show_all(base_box); // // Horizontal pane // hpaned1 = gtk_hpaned_new (); gtk_widget_show (hpaned1); gtk_box_pack_end(GTK_BOX(base_box), hpaned1, TRUE, TRUE, 0); //gtk_container_add (GTK_CONTAINER (window), hpaned1); gtk_paned_set_position (GTK_PANED (hpaned1), 196); // vbox9 holds the left pane. vbox9 = bb_vbox(window); gtk_paned_pack1 (GTK_PANED (hpaned1), vbox9, FALSE, TRUE); vbox13 = bb_vbox(window); gtk_box_pack_start (GTK_BOX (vbox9), vbox13, TRUE, TRUE, 2); scrolledwindow4 = gtk_scrolled_window_new (0, 0); gtk_widget_show (scrolledwindow4); gtk_box_pack_start (GTK_BOX (vbox13), scrolledwindow4, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); renderer = gtk_cell_renderer_text_new (); tree_store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); tree = tree1 = gtk_tree_view_new_with_model ((GtkTreeModel*) tree_store); gtk_tree_view_insert_column_with_attributes ((GtkTreeView*) tree1, 0, "", renderer, "text", 0, NULL); g_object_set (tree1, "headers-visible", FALSE, "enable-tree-lines", TRUE, NULL); g_signal_connect (gtk_tree_view_get_selection ((GtkTreeView*) tree1), "changed", (GCallback) treeselect_cb, NULL); gtk_widget_show (tree1); gtk_container_add (GTK_CONTAINER (scrolledwindow4), tree1); hbox12 = bb_hbox(window); gtk_box_pack_start (GTK_BOX (vbox13), hbox12, FALSE, FALSE, 0); add_button("Add node", G_CALLBACK(add_new_snode), hbox12); add_button("Add module", G_CALLBACK(add_module), hbox12); add_button("Add library", G_CALLBACK(add_library), hbox12); hbox15 = bb_hbox(window); gtk_box_pack_start (GTK_BOX (vbox13), hbox15, FALSE, FALSE, 0); add_button("Trace all", G_CALLBACK(trace_all), hbox15); add_button("Clear traces", G_CALLBACK(clear_traces), hbox15); node_frame = gtk_frame_new ("Node connections"); gtk_box_pack_start (GTK_BOX (vbox9), node_frame, TRUE, TRUE, 0); vbox11 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox11); gtk_container_add (GTK_CONTAINER (node_frame), vbox11); scrolledwindow2 = gtk_scrolled_window_new (0, 0); gtk_widget_show (scrolledwindow2); gtk_box_pack_start (GTK_BOX (vbox11), scrolledwindow2, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); viewport7 = gtk_viewport_new (0, 0); gtk_widget_show (viewport7); gtk_container_add (GTK_CONTAINER (scrolledwindow2), viewport7); renderer = gtk_cell_renderer_text_new(); list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); node_clist = gtk_tree_view_new_with_model((GtkTreeModel*) list_store); gtk_tree_view_insert_column_with_attributes((GtkTreeView*) node_clist, 0, "Nodes", renderer, "text", 0, NULL); g_object_set(node_clist, "headers-visible", FALSE, NULL); g_object_ref(node_clist); g_object_set_data_full (G_OBJECT (window), "node_clist", node_clist, (GDestroyNotify) g_object_unref); gtk_widget_show (node_clist); gtk_container_add (GTK_CONTAINER (viewport7), node_clist); hbox10 = bb_hbox(window); gtk_box_pack_start (GTK_BOX (vbox11), hbox10, FALSE, FALSE, 0); add_button("Remove stimulus", G_CALLBACK(remove_node_stimulus), hbox10); add_button("Remove node", G_CALLBACK(remove_node), hbox10); stimulus_frame = gtk_frame_new ("Stimulus settings"); gtk_box_pack_start (GTK_BOX (vbox9), stimulus_frame, FALSE, FALSE, 0); vbox14 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox14); gtk_container_add (GTK_CONTAINER (stimulus_frame), vbox14); stimulus_settings_label=gtk_label_new(""); gtk_widget_show(stimulus_settings_label); gtk_box_pack_start(GTK_BOX(vbox14), stimulus_settings_label, FALSE,FALSE,0); hbox13 = bb_hbox(window); gtk_box_pack_start (GTK_BOX (vbox14), hbox13, FALSE, FALSE, 0); add_button("Connect stimulus to node", G_CALLBACK(stimulus_add_node), hbox13); module_frame = gtk_frame_new ("Module settings"); gtk_box_pack_start (GTK_BOX (vbox9), module_frame, TRUE, TRUE, 0); vbox10 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox10); gtk_container_add (GTK_CONTAINER (module_frame), vbox10); scrolledwindow1 = gtk_scrolled_window_new (0, 0); gtk_widget_show (scrolledwindow1); gtk_box_pack_start (GTK_BOX (vbox10), scrolledwindow1, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); viewport6 = gtk_viewport_new (0, 0); gtk_widget_show (viewport6); gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport6); renderer = gtk_cell_renderer_text_new(); list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); attribute_clist = gtk_tree_view_new_with_model((GtkTreeModel*) list_store); gtk_tree_view_insert_column_with_attributes((GtkTreeView*) attribute_clist, 0, "Attributes", renderer, "text", 0, NULL); g_object_set(attribute_clist, "headers-visible", FALSE, NULL); gtk_widget_show (attribute_clist); gtk_container_add (GTK_CONTAINER (viewport6), attribute_clist); selection = gtk_tree_view_get_selection ((GtkTreeView*) attribute_clist); g_signal_connect (selection, "changed", (GCallback) settings_clist_cb, this); hbox9 = bb_hbox(window); gtk_box_pack_start (GTK_BOX (vbox10), hbox9, FALSE, FALSE, 0); attribute_entry = gtk_entry_new (); gtk_widget_show (attribute_entry); gtk_box_pack_start (GTK_BOX (hbox9), attribute_entry, FALSE, FALSE, 0); g_signal_connect(attribute_entry, "activate", G_CALLBACK(settings_set_cb), this); add_button("Set", G_CALLBACK(settings_set_cb), hbox9); hbox14 = bb_hbox(window); gtk_box_pack_start (GTK_BOX (vbox10), hbox14, FALSE, FALSE, 0); add_button("Remove module", G_CALLBACK(remove_module), hbox14); add_button("Save Configuration ...", G_CALLBACK(save_stc), vbox9); scrolledwindow5 = gtk_scrolled_window_new (0, 0); gtk_widget_show (scrolledwindow5); gtk_paned_pack2 (GTK_PANED (hpaned1), scrolledwindow5, TRUE, TRUE); vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolledwindow5)); hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scrolledwindow5)); layout = gtk_layout_new (hadj, vadj); gtk_container_add (GTK_CONTAINER (scrolledwindow5), layout); gtk_layout_set_size (GTK_LAYOUT (layout), LAYOUTSIZE_X, LAYOUTSIZE_Y); gtk_widget_add_events(layout, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK); g_signal_connect(layout, "motion-notify-event", G_CALLBACK(pointer_cb), this); g_signal_connect(layout, "button_press_event", G_CALLBACK(pointer_cb), this); g_signal_connect(layout, "button_release_event", G_CALLBACK(pointer_cb), this); g_signal_connect(layout, "expose_event", G_CALLBACK(layout_expose), this); GtkAdjustment *xadj = gtk_layout_get_hadjustment(GTK_LAYOUT(layout)); gtk_adjustment_set_step_increment(xadj, 10.0); GtkAdjustment *yadj = gtk_layout_get_vadjustment(GTK_LAYOUT(layout)); gtk_adjustment_set_step_increment(yadj, 10.0); gtk_widget_set_app_paintable(layout, TRUE); gtk_widget_show (layout); unsigned int rrx, rry; gtk_layout_get_size(GTK_LAYOUT(layout), &rrx, &rry); xsize = ((width < LAYOUTSIZE_X)?LAYOUTSIZE_X:width)/ROUTE_RES; ysize = ((height < LAYOUTSIZE_Y)?LAYOUTSIZE_Y:height)/ROUTE_RES; board_matrix = (unsigned char *)malloc(xsize*ysize); mask_matrix = (unsigned short *)realloc(NULL, xsize*ysize*sizeof(unsigned short)); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect (window, "delete_event", G_CALLBACK(delete_event), (gpointer)this); g_signal_connect_after(window, "configure_event", G_CALLBACK(gui_object_configure_event), this); gtk_widget_realize(window); pinstatefont = pango_font_description_from_string("Courier Bold 8"); pinnamefont = pango_font_description_from_string("Courier Bold 8"); cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(window)); PangoLayout *pang_layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(pang_layout, pinnamefont); pango_layout_set_text(pang_layout, "9y", -1); pango_layout_get_size(pang_layout, &pinnameheight, NULL); pinnameheight /= PANGO_SCALE; g_object_unref(pang_layout); cairo_destroy(cr); if(pinspacingbbw=this; gn->node=0; // indicates that this is the root node. GtkTreeIter iter; gtk_tree_store_append (tree_store, &iter, NULL); gtk_tree_store_set (tree_store, &iter, 0, "nodes", 1, gn, -1); node_iter = &iter; // Handle nodes added before breadboard GUI enabled std::vector::iterator list = nodes.begin(); for ( ; list != nodes.end(); ++list) NodeConfigurationChanged(*list); bIsBuilt = true; UpdateMenuItem(); draw_nodes(); // cout << "FIXME gui_breadboard.cc " << __FUNCTION__ << endl; /* // Loop module list Symbol_Table::module_symbol_iterator mi = get_symbol_table().beginModuleSymbol(); Symbol_Table::module_symbol_iterator itModEnd = get_symbol_table().endModuleSymbol(); for(mi = get_symbol_table().beginModuleSymbol(); mi!=itModEnd; mi++) { NewModule((*mi)->get_module()); } // Loop node list Symbol_Table &ST = get_symbol_table(); Symbol_Table::node_symbol_iterator it; Symbol_Table::node_symbol_iterator itEnd = ST.endNodeSymbol(); for(it = ST.beginNodeSymbol(); it != itEnd; it++) { Stimulus_Node *node = (*it)->getNode(); assert(node != NULL); if(node != NULL) { NodeConfigurationChanged(node); } } */ //gtk_widget_show_all(window); gtk_widget_show(window); Update(); } const char *Breadboard_Window::name() { return "pinout"; } Breadboard_Window::~Breadboard_Window() { if (mask_matrix) free(mask_matrix); if (board_matrix) free(board_matrix); mask_matrix = 0; board_matrix = 0; } Breadboard_Window::Breadboard_Window(GUI_Processor *_gp) : pinstatefont(0), pinnamefont(0), node_clist(0), stimulus_settings_label(0), stimulus_add_node_button(0), hadj(0), vadj(0), node_iter(0), selected_pin(0), selected_node(0), selected_module(0) { menu = "/menu/Windows/Breadboard"; mask_matrix = 0; board_matrix = 0; gp = _gp; if(!get_config()) printf("warning: %s\n",__FUNCTION__); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_scope.h0000664000076400007640000000720713045306453012567 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_SCOPE_H__ #define __GUI_SCOPE_H__ #include #include #include "gui_object.h" class GUI_Processor; class TimeMarker; class ZoomAttribute; class PanAttribute; class Waveform; class SignalNameEntry; class TimeAxis; class GridPointMapping { public: explicit GridPointMapping(int nPointsToMap); ~GridPointMapping(); int pixel(int index) { return (index m_pixel; std::valarray m_cycle; }; // // The Scope Window // class Scope_Window : public GUI_Object { public: explicit Scope_Window(GUI_Processor *gp); virtual void Build(); virtual void Update(); /// zoom - positive values mean zoom in, negative values mean zoom out void zoom(int); /// pan - positive values mean pan right, negative values mean pan left. void pan(int); /// getSpan - returns time span currently cached (essentially tStop-tStart). gdouble getSpan(); /// mapTimeToPixel - convert time to a pixel horizontal offset. int mapTimeToPixel(guint64 time); GridPointMapping &MajorTicks() { return m_MajorTicks; } GridPointMapping &MinorTicks() { return m_MinorTicks; } private: /// Signals for the scope window static gint signalButtonPress(GtkWidget *,GdkEventButton *, Scope_Window *sw); static gint signalEntryKeyPress(GtkEntry *, GdkEventKey *, Scope_Window *sw); static gboolean signal_name_expose(GtkWidget *widget, GdkEventExpose *event, Scope_Window *sw); static gboolean signal_expose(GtkWidget *widget, GdkEventExpose *event, Scope_Window *sw); static gboolean key_press(GtkWidget *widget, GdkEventKey *key, Scope_Window *sw); /// selectSignalName - begin the signal name editing mode /// returns true if selection state has changed. bool selectSignalName(int y); /// endSignalNameSelection - end the signal name editing mode. bool endSignalNameSelection(bool bAccept); /// int waveXoffset(); /// gridPoints - Fill the major and minor axis grid point arrays /// These arrays map time values into pixel coordinates. void gridPoints(guint64 *start, guint64 *stop); enum { eStart=0, eStop, eLeftButton, eRightButton, eNumMarkers } MarkerLabels; TimeMarker *m_Markers[eNumMarkers]; ZoomAttribute *m_zoom; PanAttribute *m_pan; GtkWidget *m_pHpaned; /* The signal names and waves are rendered in a horizontal pane */ GtkWidget *m_phScrollBar; // scroll bar for the waves int m_PixmapWidth; // Width of waveform pixmaps. GridPointMapping m_MajorTicks; GridPointMapping m_MinorTicks; bool m_bFrozen; GtkObject *m_hAdj; SignalNameEntry *m_entry; TimeAxis *m_TimeAxis; std::vector signals; protected: virtual const char *name(); }; #endif // __GUI_SCOPE_H__ gpsim-0.30.0/gui/gui_breadboard.h0000664000076400007640000001755013045306453013545 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_BREADBOARD_H__ #define __GUI_BREADBOARD_H__ #include "../src/packages.h" #include "../src/stimuli.h" #include "gui_object.h" #include #include class CrossReferenceToGUI; class GUI_Processor; class Module; // // The Breadboard window data // class Breadboard_Window; enum eOrientation {LEFT, UP, RIGHT, DOWN}; enum eDirection {PIN_INPUT, PIN_OUTPUT}; typedef enum {PIN_DIGITAL, PIN_ANALOG, PIN_OTHER} pintype; // Routing types typedef enum {R_NONE,R_LEFT, R_RIGHT, R_UP, R_DOWN} route_direction; class point { public: int x; int y; }; class path { public: point p; route_direction dir; path *next; }; // End routing types class GuiModule; //======================================================================== // // GuiBreadBoardObject - Base class for things that can be drawn in the // breadboard window. // class GuiBreadBoardObject { public: GuiBreadBoardObject(Breadboard_Window *,int x, int y); virtual ~GuiBreadBoardObject(); virtual void Draw()=0; virtual void Update()=0; virtual void Destroy()=0; bool IsBuilt() { return m_bIsBuilt;} Breadboard_Window *bbw() { return m_bbw;} void SetPosition(int x, int y); int x() { return m_x;} int y() { return m_y;} int width() { return m_width; } int height() { return m_height; } protected: Breadboard_Window *m_bbw; int m_x; // Position in layout widget int m_y; // Position in layout widget int m_width; // int m_height; // bool m_bIsBuilt; // True after the object gets displayed. }; //------------------------------------------------------------------------ // GuiPin class GuiPin : public GuiBreadBoardObject { public: GuiPin(Breadboard_Window *, GuiModule *,Package *, unsigned int pin_number); bool getState() {return value;} void putState(bool bNewState) { value = bNewState;} void toggleState(); void toggleDirection(); void addXref(CrossReferenceToGUI *); virtual void Draw(); virtual void Update(); virtual void Destroy(); void SetModulePosition(int x, int y); int module_x() { return m_module_x; } int module_y() { return m_module_y; } void SetLabelPosition(int x, int y); int label_x() { return m_label_x; } int label_y() { return m_label_y; } bool DrawGUIlabel(); void DrawLabel(cairo_t *cr); void SetOrientation(eOrientation o) { orientation = o; } unsigned int number() { return m_pkgPinNumber; } Stimulus_Node *getSnode() {return getIOpin() ? getIOpin()->snode : 0;} IOPIN *getIOpin() {return package->get_pin(m_pkgPinNumber);} const char *pinName(); GtkWidget *m_pinDrawingArea; eDirection direction; eOrientation orientation; pintype type; protected: bool value; // IOPIN *iopin; Package *package; CrossReferenceToGUI *xref; GuiModule *m_pModule; // Module to which this pin belongs. int m_module_x; // Pin coordinates within parent module int m_module_y; // int m_label_x; // Pin Label coordinates (within parent module). int m_label_y; int m_pkgPinNumber; // private: static gboolean expose_pin(GtkWidget *widget, GdkEventExpose *event, GuiPin *p); }; enum module_type {PIC_MODULE, EXTERNAL_MODULE}; class BB_ModuleLabel { public: BB_ModuleLabel(const std::string &text, PangoFontDescription *font); ~BB_ModuleLabel(); GtkWidget *gobj() {return m_label;} private: GtkWidget *m_label; }; //------------------------------------------------------------------------ // GuiModule // // The GuiModule holds the graphics for a gpsim module that is displayed in // the bread board window. The GuiModule serves as the link between the gui // and the simulation engine. In other words, the GuiModule provides an // interface through which the simulation engine may be accessed. // // All GuiModules have a one-to-one with a gpsim Module. (see src/modules.h) // The GuiModule knows how to get access to a Module's pin information. // class GuiModule : public GuiBreadBoardObject { public: GuiModule(Module *, Breadboard_Window *); void SetPosition(int x, int y); void GetPosition(int &x, int &y); double Distance(int x, int y); virtual void Update(); virtual void UpdatePins(); virtual void Build(); virtual void Draw(); virtual void Destroy(); virtual void DrawCaseOutline(cairo_t *); virtual void AddPin(unsigned int); virtual void AddPinGeometry(GuiPin *); int pin_count() { return m_pin_count; } std::vector * pins() { return &m_pins; } Module *module() { return m_module; } GtkWidget *module_widget() { return m_module_widget; } GtkWidget *pinLabel_widget() { return m_pinLabel_widget; } GtkWidget *name_widget() { return m_name_widget->gobj(); } protected: Module *m_module; GtkWidget *m_module_widget; // As returned from module. If NULL, it becomes a static GtkPixmap GtkWidget *m_pinLabel_widget;// A drawing area for pin labels. int m_module_x; // These coordinates are an offset from m_x and m_y defined in int m_module_y; /* GuiBreadBoardObject. Their purpose is to allow clients to * reposition a customly created module_widget */ BB_ModuleLabel *m_name_widget; // Name of widget, positioned above module_widget. int pinnameWidths[4]; int m_pin_count; std::vector m_pins; private: static gboolean module_expose(GtkWidget *widget, GdkEventExpose *event, GuiModule *p); }; class GuiDipModule : public GuiModule { public: GuiDipModule(Module *, Breadboard_Window *); virtual void DrawCaseOutline(cairo_t *); }; struct gui_node { Breadboard_Window *bbw; Stimulus_Node *node; GtkWidget *tree_item; }; class Breadboard_Window : public GUI_Object { public: PangoFontDescription *pinstatefont; PangoFontDescription *pinnamefont; int pinnameheight; GtkWidget *layout; std::vector modules; std::vector nodes; GtkWidget *tree; GtkWidget *pic_frame; GtkWidget *node_frame; GtkWidget *module_frame; GtkWidget *stimulus_frame; GtkWidget *attribute_clist; GtkWidget *attribute_entry; GtkWidget *attribute_button; GtkWidget *node_clist; GtkWidget *stimulus_settings_label; GtkWidget *stimulus_add_node_button; GtkAdjustment *hadj, *vadj; GtkTreeIter *node_iter; GuiPin *selected_pin; struct gui_node *selected_node; GuiModule *selected_module; explicit Breadboard_Window(GUI_Processor *gp); ~Breadboard_Window(); virtual void Build(void); virtual void NewProcessor(GUI_Processor *gp); virtual void Update(void); virtual void NewModule(Module *module); virtual void NodeConfigurationChanged(Stimulus_Node *node); void draw_nodes(); void update_board_matrix(); void clear_nodes(); GtkWidget *status_line; protected: virtual const char *name(); private: GtkWidget *add_button(const char *label, GCallback f, GtkWidget *box); static void pointer_cb(GtkWidget *w, GdkEventButton *event, Breadboard_Window *bbw); GuiModule *m_MainCpuModule; static gboolean layout_expose(GtkWidget *widget, GdkEventExpose *event, Breadboard_Window *bbw); }; #endif //__GUI_BREADBOARD_H__ gpsim-0.30.0/gui/gui_trace.cc0000664000076400007640000001661613041763636012724 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include "../src/interface.h" #include "../src/trace.h" #include "gui.h" #include "gui_trace.h" #define MAXTRACES 100 #define TRACE_STRING 100 typedef enum { MENU_BREAK_CLEAR, MENU_BREAK_READ, MENU_BREAK_WRITE, MENU_BREAK_READ_VALUE, MENU_BREAK_WRITE_VALUE, MENU_ADD_WATCH, } menu_id; // gui trace flags: #define GTF_ENABLE_XREF_UPDATES (1<<0) enum {CYCLE_COLUMN, TRACE_COLUMN, N_COLUMNS}; //======================================================================== class TraceXREF : public CrossReferenceToGUI { public: /***************************************************************** * Update * * This is called by the simulator when it has been determined that * that the trace buffer has changed and needs to be updated */ void Update(int new_value) { Trace_Window *tw = static_cast(parent_window); if(!tw || !tw->enabled) return; if(!tw->gp || !tw->gp->cpu) { puts("Warning gp or gp->cpu == NULL in TraceWindow_update"); return; } // If we're not allowing xref updates then exit if( !(tw->trace_flags & GTF_ENABLE_XREF_UPDATES)) return; if (get_trace().string_buffer[0] && (get_trace().string_cycle >= tw->last_cycle)) { tw->last_cycle = get_trace().string_cycle; tw->trace_map[tw->trace_map_index].cycle = get_trace().string_cycle; tw->trace_map[tw->trace_map_index].simulation_trace_index = get_trace().string_index; // Advance the trace_map_index using rollover arithmetic if(++tw->trace_map_index >= MAXTRACES) tw->trace_map_index = 0; GtkListStore *list = tw->trace_list; GtkTreeIter iter; gtk_list_store_append(list, &iter); gtk_list_store_set(list, &iter, CYCLE_COLUMN, guint64(get_trace().string_cycle), TRACE_COLUMN, get_trace().string_buffer, -1); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list), NULL) > MAXTRACES) { gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list), &iter); gtk_list_store_remove(list, &iter); } } } }; //======================================================================== /***************************************************************** * TraceWindow_update * * The purpose of this routine is to refresh the trace window with * the latest trace information. The current pic simulation cycle (should * this be change to real time???) is examined and compared to what * is currently displayed in the trace window. If the info in the * trace window is really old, this the entire window is deleted and * the trace is redrawn with the latest. If the trace window is rather * recent then the older trace info is deleted and the new is appended * to the end. * * INPUTS: *tw a pointer to a Trace_Window structure. */ void Trace_Window::Update(void) { //guint64 cycle; if(!enabled) return; if(!gp || !gp->cpu) { g_print("Warning gp or gp->cpu == NULL in TraceWindow_update"); return; } trace_flags |= GTF_ENABLE_XREF_UPDATES; if(get_cycles().get()-last_cycle>=MAXTRACES) // redraw the whole thing get_trace().dump(MAXTRACES, 0); else get_trace().dump(get_cycles().get()-last_cycle, 0); trace_flags &= ~GTF_ENABLE_XREF_UPDATES; last_cycle = get_cycles().get(); } /***************************************************************** * TraceWindow_new_processor * * */ void Trace_Window::NewProcessor(GUI_Processor *_gp) { #define NAME_SIZE 32 TraceXREF *cross_reference; if(!gp) return; if(!enabled) return; cross_reference = new TraceXREF(); cross_reference->parent_window = (gpointer) this; cross_reference->data = 0; if(get_trace().xref) get_trace().xref->_add((gpointer) cross_reference); } static int delete_event(GtkWidget *widget, GdkEvent *event, Trace_Window *rw) { rw->ChangeView(VIEW_HIDE); return TRUE; } void Trace_Window::cycle_cell_data_function( GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { guint64 cycle; gchar buf[TRACE_STRING]; gtk_tree_model_get(model, iter, gint(CYCLE_COLUMN), &cycle, -1); g_snprintf(buf, sizeof(buf),"0x%016" PRINTF_GINT64_MODIFIER "x", cycle); g_object_set(renderer, "text", buf, NULL); } void Trace_Window::Build(void) { if(bIsBuilt) return; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *main_vbox = gtk_vbox_new(FALSE, 1); gtk_container_add(GTK_CONTAINER(window), main_vbox); gtk_window_set_title(GTK_WINDOW(window), "trace viewer"); // Trace list trace_list = gtk_list_store_new(N_COLUMNS, G_TYPE_UINT64, G_TYPE_STRING); GtkWidget *trace_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(trace_list)); g_object_unref(trace_list); GtkTreeViewColumn *col; GtkCellRenderer *renderer; renderer = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new_with_attributes("Cycle", renderer, "text", CYCLE_COLUMN, NULL); gtk_tree_view_column_set_cell_data_func(col, renderer, Trace_Window::cycle_cell_data_function, NULL, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(trace_view), col); renderer = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new_with_attributes("Trace", renderer, "text", gint(TRACE_COLUMN), NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(trace_view), col); gtk_window_set_default_size(GTK_WINDOW(window), width, height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect(window, "delete_event", G_CALLBACK(delete_event), this); GtkWidget *scrolled_window = gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(trace_view)); gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 0); g_signal_connect_after(window, "configure_event", G_CALLBACK(gui_object_configure_event), this); gtk_widget_show_all(window); if(!trace_map) { trace_map = new TraceMapping[MAXTRACES]; trace_map_index = 0; } enabled=1; bIsBuilt = true; last_cycle = 0; NewProcessor(gp); Update(); UpdateMenuItem(); } const char *Trace_Window::name() { return "trace"; } //------------------------------------------------------------------------ // // // Trace_Window::Trace_Window(GUI_Processor *_gp) : trace_flags(0), trace_map(0) { menu = "/menu/Windows/Trace"; gp = _gp; get_config(); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_regwin.cc0000664000076400007640000014331013045306453013103 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include "../src/interface.h" #include "../src/trace.h" #include "../src/breakpoints.h" #include "gui.h" #include "preferences.h" #include "gui_register.h" #include "gui_regwin.h" #include "gui_watch.h" #include #include #define TRACE_FILE_FORMAT_ASCII 0 #define TRACE_FILE_FORMAT_LXT 1 extern int gui_question(const char *question, const char *a, const char *b); // extern GUI_Processor *gp; typedef enum { MENU_BREAK_CLEAR, MENU_BREAK_READ, MENU_BREAK_WRITE, MENU_BREAK_ON_CHANGE, MENU_BREAK_READ_VALUE, MENU_BREAK_WRITE_VALUE, MENU_ADD_WATCH, MENU_SETTINGS, MENU_LOG_SETTINGS, MENU_LOG_READ, MENU_LOG_WRITE, MENU_LOG_READ_VALUE, MENU_LOG_WRITE_VALUE, MENU_REGWIN_REFRESH, } menu_id; typedef struct _menu_item { const char *name; const menu_id id; } menu_item; static const menu_item menu_items[] = { {"Clear breakpoints", MENU_BREAK_CLEAR}, {"Set break on read", MENU_BREAK_READ}, {"Set break on write", MENU_BREAK_WRITE}, {"Set break on change", MENU_BREAK_ON_CHANGE}, {"Set break on read value...", MENU_BREAK_READ_VALUE}, {"Set break on write value...", MENU_BREAK_WRITE_VALUE}, {"Set log settings...", MENU_LOG_SETTINGS}, {"Set log on read", MENU_LOG_READ}, {"Set log on write", MENU_LOG_WRITE}, {"Set log on read value...", MENU_LOG_READ_VALUE}, {"Set log on write value...", MENU_LOG_WRITE_VALUE}, {"Add watch", MENU_ADD_WATCH}, {"Refresh", MENU_REGWIN_REFRESH}, {"Settings...", MENU_SETTINGS} }; //======================================================================== // //-------------------------------------------------- // get_register // get the "real" register. If 'bTopLevelOnly' is true // Register *GUIRegister::get_register() { if(!rma) return 0; return rma->get_register(address); } void GUIRegister::put_value(unsigned int new_value) { Register *reg = get_register(); if(reg) { reg->put_value(new_value); // Shadow a copy of the register value so that we can tell if it has changed // when we go to perform an update in the future. shadow = reg->getRV_notrace(); } } void GUIRegister::put_shadow(RegisterValue new_value) { // Update the shadow copy of the register without updating the register. shadow = new_value; } unsigned int GUIRegister::get_value() { Register *reg = get_register(); if(reg) return reg->get_value(); return 0; } RegisterValue GUIRegister::getRV() { Register *reg = get_register(); if(reg) { return reg->getRV_notrace(); } return RegisterValue(0,0); } char * GUIRegister::getValueAsString(char *str, int len, RegisterValue value) { if (!str || len <= 0) return 0; if (bIsValid()) { const char hex2ascii[] = "0123456789ABCDEF"; const int min = (len < register_size * 2) ? len : register_size * 2; if (value.data == INVALID_VALUE) value.init = 0xfffffff; for (int i = 0; i < min; i++) { if (value.init & 0x0f) str[min - i - 1] = '?'; else str[min - i - 1] = hex2ascii[value.data & 0x0f]; value >>= 4; } str[min] = 0; } else *str = '\0'; return str; } bool GUIRegister::hasChanged(RegisterValue ¤t_value) const { return (shadow != current_value); } void GUIRegister::Clear_xref() { Register *reg = get_register(); if(reg) reg->remove_xref((gpointer *)xref); } void GUIRegister::Assign_xref(CrossReferenceToGUI *new_xref) { Register *reg = get_register(); if(reg) reg->add_xref( (gpointer *)new_xref); xref = new_xref; } bool GUIRegister::hasBreak() { if(rma) return rma->hasBreak(address); return false; } std::string GUIRegister::name() { Register *reg = get_register(); if (!reg) { return "NULL"; } //register_symbol * pRegSym = get_symbol_table().findRegisterSymbol(reg->address); if (!reg || reg->isa() == Register::INVALID_REGISTER) return ""; std::string buffer; if (bIsAliased) buffer = "alias (" + reg->name() + ")"; else buffer = reg->name(); return buffer; } bool GUIRegister::bIsValid() { if(rma && (*rma)[address].getReg()) return true; return false; } bool GUIRegister::bIsSFR() { if(rma && (*rma)[address].isa() == Register::SFR_REGISTER) return true; return false; } GUIRegister::GUIRegister() : rma(0), address(0), row(0), col(0), register_size(0), bUpdateFull(false), bIsAliased(false), xref(0) { } GUIRegister::~GUIRegister() { rma = 0; if(xref != NULL) { delete xref; } } //======================================================================== class RegisterWindowXREF : public CrossReferenceToGUI { public: virtual void Update(int new_value) { GUIRegister *reg; Register_Window *rw; int address; reg = (GUIRegister *) (data); rw = (Register_Window *) (parent_window); if(reg->row > GTK_SHEET(rw->register_sheet)->maxrow) { puts("Warning reg->row > maxrow in xref_update_cell"); return; } address = rw->row_to_address[reg->row]+reg->col; rw->registers->Get(address)->bUpdateFull=true; rw->UpdateRegisterCell(address); rw->UpdateASCII(reg->row); } }; //======================================================================== // // Create a class for an invalid register and instantiate a single instance // of it. The purpose of this is to provide a place holder for the gui // register array. // class InvalidGuiRegister : public GUIRegister { public: void put_value(unsigned int new_value) { printf("(gui_regwin)Warning: writing to invalid register\n"); }; unsigned int get_value() { return 0;}; InvalidGuiRegister() { rma=0; } private: void operator delete(void *ignore) {}; }; static InvalidGuiRegister THE_invalid_register; //======================================================================== // GtkSheet extensions // // The gtk_sheet api does not provide access to row and column labels. // This means we can manipulate the font the way the cells can be manipulated #if 0 // defined but not used static GtkSheetButton * gtk_sheet_row_button_get(GtkSheet *sheet, gint row) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); if(row < 0 || row > sheet->maxrow) return NULL; return (&sheet->row[row].button); } #endif static void gtk_sheet_REALLY_set_row_height(GtkSheet *sheet, gint row, gint height) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (row < 0 || row > sheet->maxrow) return; sheet->row[row].height = height; } // Sanatize the numeric text input // Only checks that the input is less that 0xffff static void sanatize_numeric(GtkEditable *editable, gchar *new_text, gint new_text_length, gint *position, gpointer user_data) { bool ok = true; char *current_text = gtk_editable_get_chars(editable, 0, -1); std::string text(current_text); text.insert(*position, new_text); g_free(current_text); if (text != "0x" && text != "0X") { char *end_char; unsigned long value = strtoul(text.c_str(), &end_char, 0); if (value > 0xffff || *end_char != '\0') ok = false; } if (ok) { g_signal_handlers_block_by_func(G_OBJECT(editable), gpointer(sanatize_numeric), user_data); gtk_editable_insert_text(editable, new_text, new_text_length, position); g_signal_handlers_unblock_by_func(G_OBJECT(editable), gpointer(sanatize_numeric), user_data); } g_signal_stop_emission_by_name(G_OBJECT(editable), "insert-text"); } static void sanatize_numeric_0x(GtkEditable *editable, gchar *new_text, gint new_text_length, gint *position, gpointer user_data) { bool ok = true; char *current_text = gtk_editable_get_chars(editable, 0, -1); std::string text(current_text); text.insert(*position, new_text); g_free(current_text); char *end_char; unsigned long value = strtoul(text.c_str(), &end_char, 16); if (value > 0xffff || *end_char != '\0') ok = false; if (ok) { g_signal_handlers_block_by_func(G_OBJECT(editable), gpointer(sanatize_numeric_0x), user_data); gtk_editable_insert_text(editable, new_text, new_text_length, position); g_signal_handlers_unblock_by_func(G_OBJECT(editable), gpointer(sanatize_numeric_0x), user_data); } g_signal_stop_emission_by_name(G_OBJECT(editable), "insert-text"); } //======================================================================== // get_value // used for reading a value from user when break on value is requested int gui_get_value(const char *prompt) { GtkWidget *dialog; dialog = gtk_dialog_new_with_buttons("enter value", NULL, GTK_DIALOG_MODAL, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *label = gtk_label_new("values can be entered in decimal, hexadecimal, and octal.\nFor example: 31 is the same as 0x1f and 037"); gtk_box_pack_start(GTK_BOX(area), label, FALSE, FALSE, 18); GtkWidget *hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(area), hbox, FALSE, FALSE, 18); label = gtk_label_new(prompt); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); GtkWidget *entry = gtk_entry_new(); g_signal_connect(entry, "insert-text", G_CALLBACK(sanatize_numeric), NULL); gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) { gtk_widget_destroy(dialog); return -1; } const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); if (*entry_text == '\0') { gtk_widget_destroy(dialog); return -1; } int value = strtoul(entry_text, NULL, 0); gtk_widget_destroy(dialog); return value; } // used for reading a value from user when break on value is requested void gui_get_2values(const char *prompt1, int *value1, const char *prompt2, int *value2) { GtkWidget *dialog = gtk_dialog_new_with_buttons("enter values", NULL, GTK_DIALOG_MODAL, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *label = gtk_label_new("values can be entered in decimal, hexadecimal, and octal.\nFor example: 31 is the same as 0x1f and 037"); gtk_box_pack_start(GTK_BOX(area), label, FALSE, FALSE, 18); GtkWidget *hbox, *entry1, *entry2; hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(area), hbox, FALSE, FALSE, 18); label = gtk_label_new(prompt1); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); entry1 = gtk_entry_new(); g_signal_connect(entry1, "insert-text", G_CALLBACK(sanatize_numeric), NULL); gtk_box_pack_start(GTK_BOX(hbox), entry1, FALSE, FALSE, 0); hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(area), hbox, FALSE, FALSE, 18); label = gtk_label_new(prompt2); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); entry2 = gtk_entry_new(); g_signal_connect(entry2, "insert-text", G_CALLBACK(sanatize_numeric), NULL); gtk_box_pack_start(GTK_BOX(hbox), entry2, FALSE, FALSE, 0); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) { *value1 = -1; *value2 = -1; gtk_widget_destroy(dialog); return; } const gchar *entry_text; entry_text = gtk_entry_get_text(GTK_ENTRY(entry1)); if (*entry_text == '\0') { *value1 = -1; *value2 = -1; gtk_widget_destroy(dialog); return; } *value1 = strtoul(entry_text, NULL, 0); entry_text = gtk_entry_get_text(GTK_ENTRY(entry2)); if (*entry_text == '\0') { *value1 = -1; *value2 = -1; gtk_widget_destroy(dialog); return; } *value2 = strtoul(entry_text, NULL, 0); gtk_widget_destroy(dialog); } // Select logging file. // Returns pointer to file name. This needs to be freed with g_free() // Can return the optional mode static char *gui_get_log_settings(int *mode) { GtkWidget *dialog = gtk_file_chooser_dialog_new("Log settings", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); GtkWidget *combo_text; if (mode) { combo_text = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_text), "ASCII"); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_text), "LXT"); gtk_combo_box_set_active(GTK_COMBO_BOX(combo_text), 0); GtkWidget *hbox = gtk_hbox_new(FALSE, 12); GtkWidget *label = gtk_label_new("File format:"); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); gtk_box_pack_end(GTK_BOX(hbox), combo_text, FALSE, FALSE, 0); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), hbox); gtk_widget_show_all(hbox); } char *file = NULL; if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if (mode) { gint position = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_text)); if (position == 0) *mode = TRACE_FILE_FORMAT_ASCII; if (position == 1) *mode = TRACE_FILE_FORMAT_LXT; } } gtk_widget_destroy(dialog); return file; } // called when user has selected a menu item static void popup_activated(GtkWidget *widget, Register_Window *rw) { GtkSheet *sheet; int i,j; GtkSheetRange range; unsigned int address; int value, mask; char *filename; int mode; Dprintf((" popup_activated\n")); if (!rw->gp || !rw->gp->cpu) { printf(" no cpu\n"); return; } sheet = GTK_SHEET(rw->register_sheet); range = sheet->range; gsize item = GPOINTER_TO_SIZE(g_object_get_data(G_OBJECT(widget), "item")); for (j = range.row0; j <= range.rowi; j++) for (i = range.col0; i <= range.coli; i++) { address = rw->row_to_address[j] + i; switch (item) { case MENU_BREAK_READ: get_bp().set_read_break(rw->gp->cpu, address); break; case MENU_BREAK_WRITE: get_bp().set_write_break(rw->gp->cpu, address); break; case MENU_BREAK_ON_CHANGE: get_bp().set_change_break(rw->gp->cpu, address); break; case MENU_BREAK_READ_VALUE: value = gui_get_value("value to read for breakpoint:"); if(value<0) break; // Cancel get_bp().set_read_value_break(rw->gp->cpu,address,value); break; case MENU_BREAK_WRITE_VALUE: value = gui_get_value("value to write for breakpoint:"); if(value<0) break; // Cancel get_bp().set_write_value_break(rw->gp->cpu,address,value); break; case MENU_BREAK_CLEAR: get_bp().clear_all_register(rw->gp->cpu,address); break; case MENU_ADD_WATCH: rw->gp->watch_window->Add(rw->type, rw->registers->Get(address)); break; case MENU_LOG_READ: GetTraceLog().enable_logging(); // FIXME the register type is ignored here (and in all other cases // where we're logging -- it's assumed that the register address is // for ram, even if in fact the user requests eeprom. get_bp().set_notify_read(rw->gp->cpu,address); break; case MENU_LOG_WRITE: get_bp().set_notify_write(rw->gp->cpu,address); break; case MENU_LOG_READ_VALUE: gui_get_2values("Value that the read must match for logging it:", &value, "Bitmask that specifies the bits to bother about:", &mask); if(value<0) break; // Cancel get_bp().set_notify_read_value(rw->gp->cpu,address, value, mask); break; case MENU_LOG_WRITE_VALUE: gui_get_2values("Value that the write must match for logging it:", &value, "Bitmask that specifies the bits to bother about:", &mask); if(value<0) break; // Cancel get_bp().set_notify_write_value(rw->gp->cpu,address, value, mask); break; case MENU_SETTINGS: rw->SettingsDialog(); return; break; case MENU_LOG_SETTINGS: filename = gui_get_log_settings(&mode); if (filename) GetTraceLog().enable_logging(filename,mode); g_free(filename); return; break; case MENU_REGWIN_REFRESH: rw->Update(); return; break; default: puts("Unhandled menuitem?"); break; } } } GtkWidget *Register_Window::build_menu() { GtkWidget *menu = gtk_menu_new(); for (gsize i = 0; i < G_N_ELEMENTS(menu_items); i++) { GtkWidget *item = gtk_menu_item_new_with_label(menu_items[i].name); g_signal_connect(item, "activate", G_CALLBACK (popup_activated), this); g_object_set_data(G_OBJECT(item), "item", GSIZE_TO_POINTER(menu_items[i].id)); if (type == REGISTER_EEPROM && menu_items[i].id!=MENU_ADD_WATCH &&menu_items[i].id!=MENU_SETTINGS) { gtk_widget_set_sensitive(item, FALSE); } gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } return menu; } // button press handler void Register_Window::do_popup(GtkWidget *widget, GdkEventButton *event) { int button, event_time; if (event) { button = event->button; event_time = event->time; } else { button = 0; event_time = gtk_get_current_event_time(); } gtk_menu_popup(GTK_MENU(popup_menu), 0, 0, 0, 0, button, event_time); } // button press signal handler (static) gboolean Register_Window::button_press(GtkWidget *widget, GdkEventButton *event, Register_Window *rw) { if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { rw->do_popup(widget, event); return TRUE; } return FALSE; } // Popup menu keyboard signal handler (static) gboolean Register_Window::popup_menu_handler(GtkWidget *widget, Register_Window *rw) { rw->do_popup(widget, NULL); return TRUE; } // when a new cell is selected, we write changes in // previously selected cell to gpsim // (the name of the signal seems a bit strange) static void set_cell(GtkWidget *widget, int row, int col, Register_Window *rw) { Dprintf((" set_cell\n")); GtkSheet *sheet; const gchar *text; int n=0; //int crow, ccol; sheet=GTK_SHEET(widget); if(widget==0 || row>sheet->maxrow || row<0 || col>sheet->maxcol || col<0 || rw==0) { printf("Warning set_cell(%p,%x,%x,%p)\n",widget,row,col,rw); return; } GUIRegister *reg = rw->getRegister(row,col); if(!reg) return; // ignore user changes in ascii column for right now // extract value from sheet cell GtkWidget * sheet_entry = gtk_sheet_get_entry(sheet); if (!sheet_entry) return; text = gtk_entry_get_text(GTK_ENTRY(sheet_entry)); n = strtoul(text, NULL, 16); if (*text == '\0') { n = reg->get_value(); reg->put_shadow(RegisterValue(INVALID_VALUE,INVALID_VALUE)); } else if (n != (int) reg->get_shadow().data) { reg->put_value(n & gpGuiProcessor->cpu->register_mask()); rw->UpdateASCII(row); } } //------------------------------------------------------------------------ // int column_width(int col) // // Return the width of one of the register sheet columns. // // Column = -1 is the row label // Columns 0-REGISTERS_PER_ROW are ram/registers // Column REGISTERS_PER_ROW is an ASCII string of the row data. // // The width of the column is based on width of a single character, // char_width. This width is depends on the font and is computed in // LoadStyles() // // FIXME: column_width assumes there are fewer than 0x1000 registers. int Register_Window::column_width(int col) { if(!char_width) return 0; // Row Labels if(col < 0) return char_width * 3; // Register data if(col < REGISTERS_PER_ROW) return char_width * chars_per_column; // ASCII column return char_width * (REGISTERS_PER_ROW + 1) + char_width/2; } //------------------------------------------------------------------------ int Register_Window::row_height(int row) { return char_height ? char_height : 20; } //------------------------------------------------------------------------ // UpdateLabel // // void Register_Window::UpdateLabel() { int row = -1, col = -1; if(register_sheet != 0) { gtk_sheet_get_active_cell(register_sheet, &row, &col); if(col > -1 && row > -1) { if(col >= REGISTERS_PER_ROW) gtk_label_set_text(GTK_LABEL(location), " ascii "); else { GUIRegister *reg = getRegister(row,col); std::string n = reg ? reg->name() : "INVALID_REGISTER"; gtk_label_set_text(GTK_LABEL(location), n.c_str()); } } } } //------------------------------------------------------------------------ // UpdateEntry // // void Register_Window::UpdateEntry() { gint row, col; if (register_sheet != 0) { GtkWidget *sheet_entry = gtk_sheet_get_entry(register_sheet); gtk_sheet_get_active_cell(register_sheet, &row, &col); if (row_to_address[row] < 0) return; GUIRegister *reg = getRegister(row,col); if(reg && reg->bIsValid() ) { const char *text = gtk_entry_get_text(GTK_ENTRY(sheet_entry)); gtk_entry_set_text(GTK_ENTRY(entry), text); } } } //------------------------------------------------------------------------ // UpdateLabelEntry // // void Register_Window::UpdateLabelEntry() { UpdateLabel(); UpdateEntry(); } //------------------------------------------------------------------------ void Register_Window::UpdateStyle() { if (!register_sheet || !normalfont) return; GtkSheetRange range; //gtk_sheet_freeze(register_sheet); // Update the font for the cells range.row0=0; range.rowi=register_sheet->maxrow; range.col0=0; range.coli=register_sheet->maxcol; gtk_sheet_range_set_font(register_sheet, &range, normalfont); // Update the font for the row and column labels gtk_widget_modify_font(GTK_WIDGET(register_sheet),normalfont); // Adjust the cell sizes based on the font size int i; for(i=0; i<=register_sheet->maxcol; i++) gtk_sheet_set_column_width (register_sheet, i, column_width(i)); for(i=0; i<=register_sheet->maxrow; i++) gtk_sheet_REALLY_set_row_height (register_sheet, i, row_height(i)); gtk_sheet_set_row_titles_width(register_sheet, column_width(-1)); gtk_sheet_set_column_titles_height(register_sheet, row_height(0)); //gtk_sheet_thaw(register_sheet); } //------------------------------------------------------------------------ int Register_Window::LoadStyles() { normalfont = pango_font_description_from_string(normalfont_string.c_str()); if(!normalfont) { char_width = 0; char_height = 0; return 0; } { PangoRectangle rect; PangoLayout *layout; layout = gtk_widget_create_pango_layout (GTK_WIDGET(register_sheet), "A"); pango_layout_set_font_description (layout, normalfont); pango_layout_get_extents (layout, NULL, &rect); char_width = PANGO_PIXELS(rect.width); char_height = PANGO_PIXELS(rect.height + (rect.height<<1))>>1; g_object_unref(G_OBJECT(layout)); } return 1; } /********************** Settings dialog ***************************/ int Register_Window::SettingsDialog() { GtkWidget *dialog; dialog = gtk_dialog_new_with_buttons("Register window settings", NULL, GTK_DIALOG_MODAL, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); GtkWidget *hbox = gtk_hbox_new(FALSE, 6); GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_box_pack_start(GTK_BOX(area), hbox, FALSE, FALSE, 18); GtkWidget *label = gtk_label_new("Normal font:"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); GtkWidget *font_btn = gtk_font_button_new_with_font(normalfont_string.c_str()); gtk_box_pack_start(GTK_BOX(hbox), font_btn, FALSE, FALSE, 0); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) { gtk_widget_destroy(dialog); return 0; } PangoFontDescription *font; const gchar *font_name = gtk_font_button_get_font_name(GTK_FONT_BUTTON(font_btn)); font = pango_font_description_from_string(font_name); if (font) { pango_font_description_free(font); normalfont_string = font_name; config_set_string(name(), "normalfont", normalfont_string.c_str()); gtk_sheet_freeze(register_sheet); UpdateStyle(); gtk_sheet_thaw(register_sheet); } gtk_widget_destroy(dialog); return 0; } static gboolean clipboard_handler(GtkWidget *widget, GdkEventKey *key) { Dprintf((" clipboard_handler\n")); GtkSheet *sheet; sheet = GTK_SHEET(widget); if(key->state & GDK_CONTROL_MASK || key->keyval==GDK_Control_L || key->keyval==GDK_Control_R){ if((key->keyval=='c' || key->keyval == 'C') && sheet->state != gint(GTK_STATE_NORMAL)){ /* --- tsd - commented out because this function is not defined in the official gtkextra-2.0 release. if (gtk_sheet_in_clip(sheet)) gtk_sheet_unclip_range(sheet); */ gtk_sheet_clip_range(sheet, &sheet->range); } if(key->keyval=='x' || key->keyval == 'X') gtk_sheet_unclip_range(sheet); } return 0; } static void resize_handler(GtkWidget *widget, GtkSheetRange *old_range, GtkSheetRange *new_range, Register_Window *rw) { Dprintf((" resize_handler\n")); int i, j, cti, ctj; int from, to; if(widget==0 || old_range==0 || new_range==0 || rw==0) { printf("Warning resize_handler(%p,%p,%p,%p)\n",widget,old_range,new_range,rw); return; } cti = new_range->coli - new_range->col0 + 1; ctj = new_range->rowi - new_range->row0 + 1; // We always copy from this one cell. from = rw->row_to_address[old_range->row0]+old_range->col0; for(j=0;jrow_to_address[new_range->row0+j]+new_range->col0+i; rw->registers->Get(to)->put_value(rw->registers->Get(from)->get_value()); } } } static void move_handler(GtkWidget *widget, GtkSheetRange *old_range, GtkSheetRange *new_range, Register_Window *rw) { Dprintf((" move_handler\n")); int i, j, cti, ctj; int from, to; if(!widget || !old_range || !new_range || !rw) return; if (old_range->row0 < 0 || old_range->col0 < 0 || new_range->row0 < 0 || new_range->col0) return; cti = new_range->coli - new_range->col0 + 1; ctj = new_range->rowi - new_range->row0 + 1; for(j=0;jrow_to_address[old_range->row0+j]+old_range->col0+i; to = rw->row_to_address[new_range->row0+j]+new_range->col0+i; rw->registers->Get(to)->put_value(rw->registers->Get(from)->get_value()); } } } /* when the entry above the sheet is changed (typed a digit), we copy it to the cell entry */ static void show_sheet_entry(GtkWidget *widget, Register_Window *rw) { Dprintf((" show_sheet_entry\n")); int row,col; if(!widget || !rw) { printf("Warning show_sheet_entry(%p,%p)\n",widget,rw); return; } if(!gtk_widget_has_focus(widget)) return; GtkSheet *sheet = GTK_SHEET(rw->register_sheet); GtkEntry *sheet_entry = GTK_ENTRY(gtk_sheet_get_entry(sheet)); //row=sheet->active_cell.row; col=sheet->active_cell.col; gtk_sheet_get_active_cell(sheet, &row, &col); GUIRegister *reg = rw->getRegister(row,col); if (reg && reg->bIsValid()) { const char *text = gtk_entry_get_text(GTK_ENTRY(rw->entry)); if (sheet_entry) gtk_entry_set_text(sheet_entry, text); } } /* when we have new data in the entry above the sheet, we copy the data to the cells/registers this don't get called when it is clicked in, only when we hit return */ static void activate_sheet_entry(GtkWidget *widget, Register_Window *rw) { Dprintf((" activity_sheet_entry\n")); GtkSheet *sheet; gint row, col; if(widget==0|| rw==0) { printf("Warning activate_sheet_entry(%p,%p)\n",widget,rw); return; } sheet=GTK_SHEET(rw->register_sheet); //row=sheet->active_cell.row; col=sheet->active_cell.col; gtk_sheet_get_active_cell(sheet, &row, &col); // if there are text written in the entry above the sheet, then // the same data is in the sheet cell (because of show_sheet_entry()) // so we use set_cell() to write the changes from the sheet cell to gpsim set_cell(GTK_WIDGET(sheet),row,col,rw); rw->UpdateASCII(row); } /* we get here when the entry in a cell is changed (typed a digit), we copy it to the entry above the sheet. */ static void show_entry(GtkWidget *widget, Register_Window *rw) { Dprintf((" show_entry\n")); if(widget==0|| rw==0) { printf("Warning show_entry(%p,%p)\n",widget,rw); return; } if(!gtk_widget_has_focus(widget)) return; rw->UpdateEntry(); } /* when the sheet cursor has activated a new cell, we set the label and entry above the sheet */ static gint activate_sheet_cell(GtkWidget *widget, gint row, gint column, Register_Window *rw) { Dprintf((" activate_sheet_cell rma=%p\n",(rw? rw->rma :0))); GtkSheet *sheet = rw ? rw->register_sheet : 0; if(!sheet) return 0; if(widget==0 || row>sheet->maxrow || row<0|| column>sheet->maxcol || column<0 || rw==0) { printf("Warning activate_sheet_cell(%p,%x,%x,%p)\n",widget,row,column,rw); return 0; } GUIRegister *reg = rw->getRegister(row,column); if(reg && reg->bIsValid() ) // enable editing valid cells gtk_editable_set_editable(GTK_EDITABLE(gtk_sheet_get_entry(rw->register_sheet)), TRUE); else // disable editing invalid cells gtk_editable_set_editable(GTK_EDITABLE(gtk_sheet_get_entry(rw->register_sheet)), FALSE); rw->UpdateLabelEntry(); return TRUE; } GUIRegister *Register_Window::getRegister(int row, int col) { if(registers && col < REGISTERS_PER_ROW && row < MAX_ROWS) { int reg_address = row_to_address[row]; if(reg_address < 0) return 0; if(reg_address+ col < MAX_REGISTERS) return registers->Get(reg_address+col); } return 0; } //------------------------------------------------------------------- GUIRegister *Register_Window::operator [] (int address) { if(!registers || address>=MAX_REGISTERS || address<0) return 0; return registers->Get(address); } void Register_Window::SelectRegister(int regnumber) { GtkSheetRange range; int row, col; if(regnumber > MAX_REGISTERS || regnumber<0) { printf("Warning: %s - regnumber = %x\n",__FUNCTION__,regnumber); return; } if(!gp || !gp->cpu ||!registers || !registers->Get(regnumber)) { printf("SelectRegister is not ready yet\n"); return; } row=registers->Get(regnumber)->row; col=registers->Get(regnumber)->col; range.row0=range.rowi=row; range.col0=range.coli=col; gtk_sheet_select_range(GTK_SHEET(register_sheet),&range); if(register_sheet != NULL && (GTK_SHEET(register_sheet)->view.col0>range.col0 || GTK_SHEET(register_sheet)->view.coliview.row0>range.row0 || GTK_SHEET(register_sheet)->view.rowi(regSym); if (pReg && register_sheet) SelectRegister(pReg->getAddress()); /* if(regSym && typeid(*regSym) == typeid(register_symbol) && register_sheet != NULL) { Register* pReg = (Register*)((register_symbol*)regSym)->getReg(); SelectRegister(pReg->address); } */ } static void build_entry_bar(GtkWidget *main_vbox, Register_Window *rw) { Dprintf((" build_entry_bar\n")); GtkRequisition request; GtkWidget *status_box; if(main_vbox == 0 || rw==0) { printf("Warning build_entry_bar(%p,%p)\n",main_vbox,rw); return; } status_box=gtk_hbox_new(FALSE, 1); gtk_container_set_border_width(GTK_CONTAINER(status_box),0); gtk_box_pack_start(GTK_BOX(main_vbox), status_box, FALSE, TRUE, 0); gtk_widget_show(status_box); rw->location=gtk_label_new(""); gtk_widget_size_request(rw->location, &request); gtk_widget_set_size_request(rw->location, 160, request.height); gtk_box_pack_start(GTK_BOX(status_box), rw->location, FALSE, TRUE, 0); gtk_widget_set_can_default(rw->location, TRUE); gtk_widget_show(rw->location); rw->entry = gtk_entry_new(); g_signal_connect(rw->entry, "insert-text", G_CALLBACK(sanatize_numeric_0x), NULL); gtk_box_pack_start(GTK_BOX(status_box), rw->entry, TRUE, TRUE, 0); gtk_widget_show(rw->entry); } void Register_Window::UpdateASCII(gint row) { gint i; gchar name[32]; if(row<0 || row > register_sheet->maxrow) { printf("Warning update_ascii(%x)\n",row); return; } if(!registers_loaded) return; for(i=0; iGet(row_to_address[row] + i)->get_shadow().data; if( (name[i] < ' ') || (name[i]>'~')) name[i] = '.'; } name[REGISTERS_PER_ROW] = 0; gtk_sheet_set_cell(GTK_SHEET(register_sheet), row,REGISTERS_PER_ROW, GTK_JUSTIFY_RIGHT,name); } gboolean Register_Window::UpdateRegisterCell(int reg_number) { static gboolean bTrace = false; gchar name[16]; GtkSheetRange range; gboolean retval=FALSE; if(reg_number<0 || reg_number>=MAX_REGISTERS) { printf("Warning update_register_cell(%x)\n",reg_number); return 0; } if(!enabled) return 0; // Don't read registers when hidden. Esp with ICD. GUIRegister *guiReg = registers->Get(reg_number); if (!guiReg || !guiReg->rma) return 0; if((unsigned int)reg_number >= guiReg->rma->get_size()) return 0; range.row0=guiReg->row; range.rowi=guiReg->row; range.col0=guiReg->col; range.coli=guiReg->col; // bulk mode stuff is for the ICD. gpsim_set_bulk_mode(1); RegisterValue new_value = guiReg->getRV(); gpsim_set_bulk_mode(0); RegisterValue last_value=guiReg->get_shadow(); if(bTrace) printf("UpdateRegisterCell() Entry: regID=%3d, Full=%s, hasChanged=%s\n", reg_number, guiReg->bUpdateFull ? "true " : "false",\ guiReg->hasChanged(new_value) ? "true " : "false"); if(guiReg->bUpdateFull) { // A 'Full Update' means that the foreground and background colors // need to be repainted. guiReg->bUpdateFull=false; if(guiReg->row<=register_sheet->maxrow) { guiReg->getValueAsString(name, sizeof(name), new_value); gtk_sheet_set_cell(GTK_SHEET(register_sheet), guiReg->row, guiReg->col, GTK_JUSTIFY_RIGHT,name); } // else the register is invalid and out of the register sheet //if(new_value != last_value) if(guiReg->hasChanged(new_value)) { guiReg->put_shadow(new_value); guiReg->bUpdateFull=true; if(bTrace) printf("UpdateRegisterCell() regID=3%d, bUpdateFull set to true 1\n", reg_number); gtk_sheet_range_set_foreground(GTK_SHEET(register_sheet), &range, gColors.item_has_changed()); } else gtk_sheet_range_set_foreground(GTK_SHEET(register_sheet), &range, gColors.normal_fg()); if(bTrace) printf("UpdateRegisterCell() Background\n"); if(guiReg->hasBreak()) gtk_sheet_range_set_background(GTK_SHEET(register_sheet), &range, gColors.breakpoint()); else if(!guiReg->bIsValid()) gtk_sheet_range_set_background(GTK_SHEET(register_sheet), &range, gColors.invalid()); else if(guiReg->bIsAliased) gtk_sheet_range_set_background(GTK_SHEET(register_sheet), &range, gColors.alias()); else if(guiReg->bIsSFR()) gtk_sheet_range_set_background(GTK_SHEET(register_sheet), &range, gColors.sfr_bg()); else gtk_sheet_range_set_background(GTK_SHEET(register_sheet), &range, gColors.normal_bg()); retval=TRUE; } else if(guiReg->hasChanged(new_value)) { //new_value!=last_value) { if(new_value.data==INVALID_VALUE) { guiReg->put_shadow(RegisterValue(INVALID_VALUE,INVALID_VALUE)); g_snprintf(name, sizeof(name), "??"); } else { // the register has changed since last update guiReg->put_shadow(new_value); guiReg->getValueAsString(name, sizeof(name), new_value); } gtk_sheet_set_cell(GTK_SHEET(register_sheet), guiReg->row, guiReg->col, GTK_JUSTIFY_RIGHT,name); guiReg->bUpdateFull=true; if(bTrace) printf("UpdateRegisterCell() regID=3%d, bUpdateFull set to true 2\n", reg_number); gtk_sheet_range_set_foreground(GTK_SHEET(register_sheet), &range, gColors.item_has_changed()); retval=TRUE; } gint row,col; gtk_sheet_get_active_cell(register_sheet, &row, &col); if((int)reg_number==(row_to_address[row]+col)) { // if sheet cursor is standing on a cell that is changed, then // we update the entry above the sheet if(new_value.data!=last_value.data) UpdateEntry(); } if(bTrace) printf("UpdateRegisterCell() Exit: regID=%3d, Full=%s, hasChanged=%s, retval=%s\n", reg_number, guiReg->bUpdateFull ? "true " : "false", guiReg->hasChanged(new_value) ? "true " : "false", retval ? "true " : "false"); return retval; } void Register_Window::Update() { int address; bool bRowChanged; int j, i; if(!enabled) return; if(!gtk_widget_get_visible(window)) return; if(!registers_loaded) return; if(!gp || !gp->cpu || !register_sheet || !gp->cpu->isHardwareOnline()) { puts("Warning can't update register window"); return; } gtk_sheet_freeze(register_sheet); for(j = 0; j<=GTK_SHEET(register_sheet)->maxrow; j++) { if(row_to_address[j]==-1) continue; bRowChanged = false; for(i = 0; iGet(address); if(pGuiReg != &THE_invalid_register && (pGuiReg->get_shadow().data!=INVALID_VALUE || pGuiReg->bUpdateFull)) { if(UpdateRegisterCell(address) == (gboolean)true) bRowChanged = true; } } if(bRowChanged) UpdateASCII(j); } gtk_sheet_thaw(register_sheet); } //------------------------------------------------------------------------ void Register_Window::SetRegisterSize() { if (gp && gp->cpu) register_size = gp->cpu->register_size(); else register_size = 1; chars_per_column = 1 + 2*register_size; if(register_sheet) { // Column labels for (int i = 0; i < register_sheet->maxcol; i++) { char buffer[10]; g_snprintf(buffer, sizeof(buffer), "%02x", i); gtk_sheet_column_button_add_label(register_sheet, i, buffer); gtk_sheet_set_column_title(register_sheet, i, buffer); gtk_sheet_set_column_width (register_sheet, i, column_width(i)); } // ASCII column int i = REGISTERS_PER_ROW; const char *ascii = "ASCII"; gtk_sheet_column_button_add_label(register_sheet, i, ascii); gtk_sheet_set_column_title(register_sheet, i, ascii); gtk_sheet_set_column_width (register_sheet, i, column_width(i)); gtk_sheet_set_row_titles_width(register_sheet, column_width(-1)); } } GUIRegisterList::GUIRegisterList(RegisterMemoryAccess *pRMA) { m_pRMA = pRMA; unsigned int uAddress; unsigned int uRegisterSize; uRegisterSize = (pRMA->get_size() < MAX_REGISTERS) ? (pRMA->get_size()) : MAX_REGISTERS; for(uAddress=0; uAddress < uRegisterSize; uAddress++) { GUIRegister *pReg = new GUIRegister(); pReg->rma = m_pRMA; pReg->address = uAddress; pReg->register_size = m_pRMA->get_cpu()->register_size(); pReg->bIsAliased = (*m_pRMA)[uAddress].address != (unsigned int)uAddress; m_paRegisters[uAddress] = pReg; } for(;uAddress < MAX_REGISTERS; uAddress++) m_paRegisters[uAddress] = &THE_invalid_register; } GUIRegisterList::~GUIRegisterList() { unsigned int nRegs; unsigned int uAddress; nRegs = (m_pRMA->get_size() < MAX_REGISTERS) ? (m_pRMA->get_size()) : MAX_REGISTERS; for(uAddress=0; uAddress < nRegs; uAddress++) { if (m_paRegisters[uAddress] != &THE_invalid_register) { delete m_paRegisters[uAddress]; m_paRegisters[uAddress] = 0; } } } //------------------------------------------------------------------------ void Register_Window::NewProcessor(GUI_Processor *_gp) { gint i,j, border_mask, border_width; unsigned int reg_number; CrossReferenceToGUI *cross_reference; gboolean row_created; GtkSheetRange range; if(!gp || !gp->cpu || !rma || !gp->cpu->isHardwareOnline()) return; if( !enabled) return; if(!register_sheet){ printf("Warning %s:%d\n",__FUNCTION__,__LINE__); return; } row_created=FALSE; unsigned int nRegs; nRegs = (rma->get_size() < MAX_REGISTERS) ? (rma->get_size()) : MAX_REGISTERS; if (!nRegs) return; gtk_sheet_freeze(register_sheet); j=0; i=0; gtk_sheet_REALLY_set_row_height (register_sheet, j, row_height(i)); SetRegisterSize(); for(reg_number=0;reg_numberGet(reg_number); pGReg->row = j; pGReg->col = i; pGReg->put_shadow(RegisterValue(INVALID_VALUE,INVALID_VALUE)); pGReg->bUpdateFull=true; if(pGReg->bIsValid()) { gpsim_set_bulk_mode(1); pGReg->put_shadow(registers->Get(reg_number)->getRV()); gpsim_set_bulk_mode(0); /* Now create a cross-reference link that the simulator can use to * send information back to the gui */ cross_reference = new RegisterWindowXREF(); cross_reference->parent_window = (gpointer) this; cross_reference->data = (gpsimObject *) pGReg; pGReg->Assign_xref(cross_reference); if(!row_created) { char row_label[100]; if(register_sheet->maxrowmaxrow) gtk_sheet_delete_rows(register_sheet,j,register_sheet->maxrow-j); registers_loaded = 1; range.row0=0; range.rowi=register_sheet->maxrow; range.col0=0; range.coli=register_sheet->maxcol; UpdateStyle(); border_mask = GTK_SHEET_RIGHT_BORDER | GTK_SHEET_LEFT_BORDER | GTK_SHEET_BOTTOM_BORDER | GTK_SHEET_TOP_BORDER; border_width = 1; gtk_sheet_range_set_border(register_sheet, &range, border_mask, border_width, 0); border_mask = GTK_SHEET_LEFT_BORDER; border_width = 3; range.col0=REGISTERS_PER_ROW; range.coli=REGISTERS_PER_ROW; gtk_sheet_range_set_border(register_sheet, &range, border_mask, border_width, 0); gtk_sheet_thaw(register_sheet); // set values in the sheet Update(); SelectRegister(0); } static int show_event(GtkWidget *widget, Register_Window *rw) { Dprintf((" show_event\n")); rw->Update(); return TRUE; } static int delete_event(GtkWidget *widget, GdkEvent *event, Register_Window *rw) { Dprintf((" delete_event\n")); rw->ChangeView(VIEW_HIDE); return TRUE; } //------------------------------------------------------------------------ // Build // // void Register_Window::Build() { if(bIsBuilt) return; Dprintf((" Register_Window::Build()\n")); GtkWidget *main_vbox; GtkWidget *scrolled_window; #define MAXROWS (MAX_REGISTERS/REGISTERS_PER_ROW) #define MAXCOLS (REGISTERS_PER_ROW+1) char *fontstring; if (window) { gtk_widget_destroy(window); } window=gtk_window_new(GTK_WINDOW_TOPLEVEL); main_vbox=gtk_vbox_new(FALSE,1); gtk_container_set_border_width(GTK_CONTAINER(main_vbox),0); gtk_container_add(GTK_CONTAINER(window), main_vbox); gtk_widget_show(main_vbox); if(type==REGISTER_RAM) { register_sheet=GTK_SHEET(gtk_sheet_new(1,MAXCOLS,"gpsim Register Viewer [RAM]")); gtk_window_set_title(GTK_WINDOW(window), "register viewer [RAM]"); } else { register_sheet=GTK_SHEET(gtk_sheet_new(1,MAXCOLS,"gpsim Register Viewer [EEPROM]")); gtk_window_set_title(GTK_WINDOW(window), "register viewer [EEPROM]"); } //gtk_sheet_hide_column_titles(register_sheet); //gtk_sheet_hide_row_titles(register_sheet); /* create popupmenu */ popup_menu=build_menu(); build_entry_bar(main_vbox,this); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); /**************************** load fonts *********************************/ #define DEFAULT_NORMALFONT "Monospace 10" normalfont_string = DEFAULT_NORMALFONT; if(config_get_string(name(),"normalfont",&fontstring)) normalfont_string = fontstring; while(!LoadStyles()) { if(gui_question("Some fonts did not load.","Open font dialog","Try defaults")==FALSE) { normalfont_string = DEFAULT_NORMALFONT; config_set_string(name(),"normalfont", normalfont_string.c_str()); } else { SettingsDialog(); } } UpdateStyle(); g_signal_connect(window, "delete_event", G_CALLBACK(delete_event), this); g_signal_connect(window, "show", G_CALLBACK(show_event), this); scrolled_window=gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(register_sheet)); GTK_SHEET_CLIP_TEXT(register_sheet); gtk_widget_show(GTK_WIDGET(register_sheet)); gtk_widget_show(scrolled_window); gtk_box_pack_start(GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 0); // RP - I think this is wrong. The sheet's entry widget seems to get // replaced every time a new cell is selected, so this signal can't // work. Should it be hooked to the "changed" signal of the whole sheet? g_signal_connect(gtk_sheet_get_entry(GTK_SHEET(register_sheet)), "changed", G_CALLBACK(show_entry), this); g_signal_connect(register_sheet, "activate", G_CALLBACK(activate_sheet_cell), this); g_signal_connect(entry, "changed", G_CALLBACK(show_sheet_entry), this); g_signal_connect(entry, "activate", G_CALLBACK(activate_sheet_entry), this); g_signal_connect(register_sheet, "key_press_event", G_CALLBACK(clipboard_handler), 0); g_signal_connect(register_sheet, "resize_range", G_CALLBACK(resize_handler), this); g_signal_connect(register_sheet, "move_range", G_CALLBACK(move_handler), this); g_signal_connect(register_sheet, "button_press_event", G_CALLBACK(button_press), this); g_signal_connect(register_sheet, "popup-menu", G_CALLBACK(popup_menu_handler), this); g_signal_connect(register_sheet, "set_cell", G_CALLBACK(set_cell), this); g_signal_connect_after(window, "configure_event", G_CALLBACK(gui_object_configure_event), this); SetRegisterSize(); gtk_widget_show (window); gtk_widget_grab_default(location); bIsBuilt = true; NewProcessor(gp); UpdateMenuItem(); Dprintf((" regwin is built\n")); } //------------------------------------------------------------------------ Register_Window::Register_Window(GUI_Processor *_gp, REGISTER_TYPE _type) : normalfont(0), current_line_number_style(0), breakpoint_line_number_style(0), type(_type), registers(0), register_sheet(NULL), rma(0), entry(0), location(0), popup_menu(0), registers_loaded(0), register_size(0), char_width(0), char_height(0), chars_per_column(3) { gp = _gp; std::fill_n(row_to_address, MAX_ROWS, -1); } const char *RAM_RegisterWindow::name() { return "register_viewer_ram"; } RAM_RegisterWindow::RAM_RegisterWindow(GUI_Processor *_gp) : Register_Window(_gp, REGISTER_RAM) { menu = "/menu/Windows/Ram"; get_config(); if(enabled) Build(); } void RAM_RegisterWindow::NewProcessor(GUI_Processor *_gp) { if(!_gp || !_gp->cpu) return; rma = &_gp->cpu->rma; registers = _gp->m_pGUIRamRegisters; Dprintf((" RAM_RegisterWindow::NewProcessor rma=%p\n",rma)); Register_Window::NewProcessor(_gp); } void RAM_RegisterWindow::Update() { Register_Window::Update(); } const char *EEPROM_RegisterWindow::name() { return "register_viewer_eeprom"; } EEPROM_RegisterWindow::EEPROM_RegisterWindow(GUI_Processor *_gp) : Register_Window(_gp, REGISTER_EEPROM) { menu = "/menu/Windows/EEPROM"; get_config(); if(enabled) Build(); } void EEPROM_RegisterWindow::NewProcessor(GUI_Processor *_gp) { if(!_gp || !_gp->cpu) return; rma = &_gp->cpu->ema; registers = _gp->m_pGUIEEPromRegisters; Dprintf((" EEPROM_RegisterWindow::NewProcessor rma=%p\n",rma)); Register_Window::NewProcessor(_gp); } #endif // HAVE_GUI gpsim-0.30.0/gui/gtkextra/0000775000076400007640000000000013117465764012357 500000000000000gpsim-0.30.0/gui/gtkextra/gtkitementry.h0000664000076400007640000000512313041763636015172 00000000000000/* GtkItemEntry - widget for gtk+ * Copyright (C) 1999-2001 Adrian E. Feiguin * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * GtkItemEntry widget by Adrian E. Feiguin * Based on GtkEntry widget * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __GTK_ITEM_ENTRY_H__ #define __GTK_ITEM_ENTRY_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define GTK_TYPE_ITEM_ENTRY (gtk_item_entry_get_type ()) #define GTK_ITEM_ENTRY(obj) (GTK_CHECK_CAST (obj, gtk_item_entry_get_type (), GtkItemEntry)) #define GTK_ITEM_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, gtk_item_entry_get_type (), GtkItemEntryClass)) #define GTK_IS_ITEM_ENTRY(obj) (GTK_CHECK_TYPE (obj, gtk_item_entry_get_type ())) #define GTK_IS_ITEM_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ENTRY)) typedef struct _GtkItemEntry GtkItemEntry; typedef struct _GtkItemEntryClass GtkItemEntryClass; struct _GtkItemEntry { GtkEntry parent; gint text_max_size; gint16 item_text_size; gint16 item_n_bytes; GtkJustification justification; }; struct _GtkItemEntryClass { GtkEntryClass parent_class; }; GtkType gtk_item_entry_get_type (void); GtkWidget* gtk_item_entry_new (void); GtkWidget* gtk_item_entry_new_with_max_length (gint max); void gtk_item_entry_set_text (GtkItemEntry *item_entry, const gchar *text, GtkJustification justification); void gtk_item_entry_set_justification (GtkItemEntry *item_entry, GtkJustification justification); void gtk_item_entry_set_cursor_visible (GtkItemEntry *entry, gboolean visible); gboolean gtk_item_entry_get_cursor_visible (GtkItemEntry *entry); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __GTK_ITEM_ENTRY_H__ */ gpsim-0.30.0/gui/gtkextra/gtkextrafeatures.h0000664000076400007640000000361613041763636016041 00000000000000/* gtkextra - set of widgets for gtk+ * Copyright 1999-2001 Adrian E. Feiguin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef GTK_EXTRA_FEATURES_H #define GTK_EXTRA_FEATURES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* GtkExtra version. */ #define GTKEXTRA_MAJOR_VERSION (2) #define GTKEXTRA_MINOR_VERSION (1) #define GTKEXTRA_MICRO_VERSION (2) #define GTKEXTRA_BINARY_AGE (1) #define GTKEXTRA_INTERFACE_AGE (1) #define GTKEXTRA_CHECK_VERSION(major,minor,micro) \ (GTKEXTRA_MAJOR_VERSION > (major) || \ (GTKEXTRA_MAJOR_VERSION == (major) && GTKEXTRA_MINOR_VERSION > (minor)) || \ (GTKEXTRA_MAJOR_VERSION == (major) && GTKEXTRA_MINOR_VERSION == (minor) && \ GTKEXTRA_MICRO_VERSION >= (micro))) extern const guint gtkextra_major_version; extern const guint gtkextra_minor_version; extern const guint gtkextra_micro_version; extern const guint gtkextra_binary_age; extern const guint gtkextra_interface_age; gchar* gtkextra_check_version (guint required_major, guint required_minor, guint required_micro); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* GTK_EXTRA_FEATURES_H */ gpsim-0.30.0/gui/gtkextra/gtkextra.c0000664000076400007640000001051613041763636014272 00000000000000/* gtkextra * Copyright 1999-2001 Adrian E. Feiguin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include "gtkextrafeatures.h" #include const guint gtkextra_major_version = GTKEXTRA_MAJOR_VERSION; const guint gtkextra_minor_version = GTKEXTRA_MINOR_VERSION; const guint gtkextra_micro_version = GTKEXTRA_MICRO_VERSION; const guint gtkextra_binary_age = GTKEXTRA_BINARY_AGE; const guint gtkextra_interface_age = GTKEXTRA_INTERFACE_AGE; gchar * gtkextra_check_version (guint required_major, guint required_minor, guint required_micro) { if (required_major > GTKEXTRA_MAJOR_VERSION) return "GtkExtra version too old (major mismatch)"; if (required_major < GTKEXTRA_MAJOR_VERSION) return "GtkExtra version too new (major mismatch)"; if (required_minor > GTKEXTRA_MINOR_VERSION) return "GtkExtra version too old (minor mismatch)"; if (required_minor < GTKEXTRA_MINOR_VERSION) return "GtkExtra version too new (minor mismatch)"; if (required_micro < GTKEXTRA_MICRO_VERSION - GTKEXTRA_BINARY_AGE) return "GtkExtra version too new (micro mismatch)"; if (required_micro > GTKEXTRA_MICRO_VERSION) return "GtkExtra version too old (micro mismatch)"; return NULL; } /* void _gtkextra_signal_test(GtkObject *object, guint signal_id, gint arg1, gint arg2, gboolean *default_ret) { gboolean result; GValue ret = { 0, }; GValue instance_and_param[3] = { { 0, }, {0, }, {0, } }; g_value_init(instance_and_param + 0, GTK_OBJECT_TYPE(object)); g_value_set_instance(instance_and_param + 0, G_OBJECT(object)); g_value_init(instance_and_param + 1, G_TYPE_INT); g_value_set_int(instance_and_param + 1, arg1); g_value_init(instance_and_param + 2, G_TYPE_INT); g_value_set_int(instance_and_param + 2, arg2); g_value_init(&ret, G_TYPE_BOOLEAN); g_value_set_boolean(&ret, *default_ret); g_signal_emitv(instance_and_param, signal_id, 0, &ret); *default_ret = g_value_get_boolean(&ret); g_value_unset(instance_and_param + 0); g_value_unset(instance_and_param + 1); g_value_unset(instance_and_param + 2); } */ void _gtkextra_signal_emit(GtkObject *object, guint signal_id, ...) { gboolean *result; GValue ret = { 0, }; GValue instance_and_params [10] = { {0, }, }; va_list var_args; GSignalQuery query; gchar *error; int i; va_start (var_args, signal_id); g_value_init(instance_and_params + 0, GTK_OBJECT_TYPE(object)); g_value_set_instance (instance_and_params + 0, G_OBJECT(object)); g_signal_query(signal_id, &query); for (i = 0; i < query.n_params; i++) { gboolean static_scope = query.param_types[i]&~G_SIGNAL_TYPE_STATIC_SCOPE; g_value_init(instance_and_params + i + 1, query.param_types[i]); G_VALUE_COLLECT (instance_and_params + i + 1, var_args, static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); g_free (error); while (i-- > 0) g_value_unset (instance_and_params + i); va_end (var_args); return; } } g_value_init(&ret, query.return_type); result = va_arg(var_args,gboolean *); g_value_set_boolean(&ret, *result); g_signal_emitv(instance_and_params, signal_id, 0, &ret); *result = g_value_get_boolean(&ret); g_value_unset (&ret); for (i = 0; i < query.n_params; i++) g_value_unset (instance_and_params + 1 + i); g_value_unset (instance_and_params + 0); va_end (var_args); } #endif // HAVE_GUI gpsim-0.30.0/gui/gtkextra/gtksheet.c0000664000076400007640000075312313045306453014261 00000000000000/* GtkSheet widget for Gtk+. * Copyright (C) 1999-2001 Adrian E. Feiguin * * Based on GtkClist widget by Jay Painter, but major changes. * Memory allocation routines inspired on SC (Spreadsheet Calculator) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /** * SECTION:gtksheet * @short_description: spreadsheet widget for gtk2 * * GtkSheet is a matrix widget for GTK+. It consists of an scrollable grid of * cells where you can allocate text. Cell contents can be edited interactively * through a specially designed entry, GtkItemEntry. It is also a container * subclass, allowing you to display buttons, curves, pixmaps and any other * widgets in it. * * You can also set many attributes as: border, foreground and background color, * text justification, and more. * * The testgtksheet program shows how easy is to create a spreadsheet-like GUI * using this widget. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gtkitementry.h" #include "gtksheet.h" #include "gtkextra-marshal.h" /* sheet flags */ enum { GTK_SHEET_IS_LOCKED = 1 << 0, GTK_SHEET_IS_FROZEN = 1 << 1, GTK_SHEET_IN_XDRAG = 1 << 2, GTK_SHEET_IN_YDRAG = 1 << 3, GTK_SHEET_IN_DRAG = 1 << 4, GTK_SHEET_IN_SELECTION = 1 << 5, GTK_SHEET_IN_RESIZE = 1 << 6, GTK_SHEET_IN_CLIP = 1 << 7, GTK_SHEET_REDRAW_PENDING = 1 << 8, }; #define GTK_SHEET_FLAGS(sheet) (GTK_SHEET (sheet)->flags) #define GTK_SHEET_SET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) |= (flag)) #define GTK_SHEET_UNSET_FLAGS(sheet,flag) (GTK_SHEET_FLAGS (sheet) &= ~(flag)) #define GTK_SHEET_IS_FROZEN(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IS_FROZEN) #define GTK_SHEET_IN_XDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_XDRAG) #define GTK_SHEET_IN_YDRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_YDRAG) #define GTK_SHEET_IN_DRAG(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_DRAG) #define GTK_SHEET_IN_SELECTION(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_SELECTION) #define GTK_SHEET_IN_RESIZE(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_RESIZE) #define GTK_SHEET_IN_CLIP(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_IN_CLIP) #define GTK_SHEET_REDRAW_PENDING(sheet) (GTK_SHEET_FLAGS (sheet) & GTK_SHEET_REDRAW_PENDING) #define CELL_SPACING 1 #define DRAG_WIDTH 6 #define TIMEOUT_SCROLL 20 #define TIMEOUT_FLASH 200 #define TIME_INTERVAL 8 #define COLUMN_MIN_WIDTH 10 #define MINROWS 0 #define MINCOLS 0 #define MAXLENGTH 30 #define CELLOFFSET 4 #define DEFAULT_COLUMN_WIDTH 80 static inline gint gtk_sheet_row_height(GtkSheet *sheet, gint row) { return sheet->row[row].height; } static inline gint gtk_sheet_column_width(GtkSheet *sheet, gint col) { return sheet->column[col].width; } static inline guint DEFAULT_ROW_HEIGHT(GtkWidget *widget) { if(!widget->style->font_desc) return 24; else { PangoContext *context = gtk_widget_get_pango_context(widget); PangoFontMetrics *metrics = pango_context_get_metrics(context, widget->style->font_desc, pango_context_get_language(context)); guint val = pango_font_metrics_get_descent(metrics) + pango_font_metrics_get_ascent(metrics); pango_font_metrics_unref(metrics); return PANGO_PIXELS(val)+2*CELLOFFSET; } } static inline guint DEFAULT_FONT_ASCENT(GtkWidget *widget) { if(!widget->style->font_desc) return 12; else { PangoContext *context = gtk_widget_get_pango_context(widget); PangoFontMetrics *metrics = pango_context_get_metrics(context, widget->style->font_desc, pango_context_get_language(context)); guint val = pango_font_metrics_get_ascent(metrics); pango_font_metrics_unref(metrics); return PANGO_PIXELS(val); } } static inline guint STRING_WIDTH(GtkWidget *widget, PangoFontDescription *font, const gchar *text) { PangoRectangle rect; PangoLayout *layout; layout = gtk_widget_create_pango_layout (widget, text); pango_layout_set_font_description (layout, font); pango_layout_get_extents (layout, NULL, &rect); g_object_unref(G_OBJECT(layout)); return PANGO_PIXELS(rect.width); } static inline guint DEFAULT_FONT_DESCENT(GtkWidget *widget) { if(!widget->style->font_desc) return 12; else { PangoContext *context = gtk_widget_get_pango_context(widget); PangoFontMetrics *metrics = pango_context_get_metrics(context, widget->style->font_desc, pango_context_get_language(context)); guint val = pango_font_metrics_get_descent(metrics); pango_font_metrics_unref(metrics); return PANGO_PIXELS(val); } } /* gives the top pixel of the given row in context of * the sheet's voffset */ static inline gint ROW_TOP_YPIXEL(GtkSheet *sheet, gint nrow) { return (sheet->voffset + sheet->row[nrow].top_ypixel); } /* returns the row index from a y pixel location in the * context of the sheet's voffset */ static inline gint ROW_FROM_YPIXEL(GtkSheet *sheet, gint y) { gint i, cy; cy = sheet->voffset; if(sheet->column_titles_visible) cy += sheet->column_title_area.height; if(y < cy) return 0; for (i = 0; i <= sheet->maxrow; i++) { if (y >= cy && y <= (cy + sheet->row[i].height) && sheet->row[i].is_visible) return i; if(sheet->row[i].is_visible) cy += sheet->row[i].height; } /* no match */ return sheet->maxrow; } /* gives the left pixel of the given column in context of * the sheet's hoffset */ static inline gint COLUMN_LEFT_XPIXEL(GtkSheet *sheet, gint ncol) { return (sheet->hoffset + sheet->column[ncol].left_xpixel); } /* returns the column index from a x pixel location in the * context of the sheet's hoffset */ static inline gint COLUMN_FROM_XPIXEL (GtkSheet * sheet, gint x) { gint i, cx; cx = sheet->hoffset; if(sheet->row_titles_visible) cx += sheet->row_title_area.width; if(x < cx) return 0; for (i = 0; i <= sheet->maxcol; i++) { if (x >= cx && x <= (cx + sheet->column[i].width) && sheet->column[i].is_visible) return i; if(sheet->column[i].is_visible) cx += sheet->column[i].width; } /* no match */ return sheet->maxcol; } /* returns the total height of the sheet */ static inline gint SHEET_HEIGHT(GtkSheet *sheet) { gint i,cx; cx = ( sheet->column_titles_visible ? sheet->column_title_area.height : 0); for (i=0;i<=sheet->maxrow; i++) if(sheet->row[i].is_visible) cx += sheet->row[i].height; return cx; } /* returns the total width of the sheet */ static inline gint SHEET_WIDTH(GtkSheet *sheet) { gint i,cx; cx = ( sheet->row_titles_visible ? sheet->row_title_area.width : 0); for (i=0;i<=sheet->maxcol; i++) if(sheet->column[i].is_visible) cx += sheet->column[i].width; return cx; } #define MIN_VISIBLE_ROW(sheet) sheet->view.row0 #define MAX_VISIBLE_ROW(sheet) sheet->view.rowi #define MIN_VISIBLE_COLUMN(sheet) sheet->view.col0 #define MAX_VISIBLE_COLUMN(sheet) sheet->view.coli static inline gint POSSIBLE_XDRAG(GtkSheet *sheet, gint x, gint *drag_column) { gint column, xdrag; column=COLUMN_FROM_XPIXEL(sheet, x); *drag_column=column; xdrag=COLUMN_LEFT_XPIXEL(sheet,column)+CELL_SPACING; if(x <= xdrag+DRAG_WIDTH/2 && column != 0){ while(!sheet->column[column-1].is_visible && column>0) column--; *drag_column=column-1; return sheet->column[column-1].is_sensitive; } xdrag+=sheet->column[column].width; if(x >= xdrag-DRAG_WIDTH/2 && x <= xdrag+DRAG_WIDTH/2) return sheet->column[column].is_sensitive; return FALSE; } static inline gint POSSIBLE_YDRAG(GtkSheet *sheet, gint y, gint *drag_row) { gint row, ydrag; row=ROW_FROM_YPIXEL(sheet, y); *drag_row=row; ydrag=ROW_TOP_YPIXEL(sheet,row)+CELL_SPACING; if(y <= ydrag+DRAG_WIDTH/2 && row != 0){ while(!sheet->row[row-1].is_visible && row>0) row--; *drag_row=row-1; return sheet->row[row-1].is_sensitive; } ydrag+=sheet->row[row].height; if(y >= ydrag-DRAG_WIDTH/2 && y <= ydrag+DRAG_WIDTH/2) return sheet->row[row].is_sensitive; return FALSE; } static inline gint POSSIBLE_DRAG(GtkSheet *sheet, gint x, gint y, gint *drag_row, gint *drag_column) { gint ydrag, xdrag; *drag_column=COLUMN_FROM_XPIXEL(sheet,x); *drag_row=ROW_FROM_YPIXEL(sheet,y); if(x>=COLUMN_LEFT_XPIXEL(sheet,sheet->range.col0)-DRAG_WIDTH/2 && x<=COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+ sheet->column[sheet->range.coli].width+DRAG_WIDTH/2){ ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.row0); if(y>=ydrag-DRAG_WIDTH/2 && y<=ydrag+DRAG_WIDTH/2){ *drag_row=sheet->range.row0; return TRUE; } ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+ sheet->row[sheet->range.rowi].height; if(y>=ydrag-DRAG_WIDTH/2 && y<=ydrag+DRAG_WIDTH/2){ *drag_row=sheet->range.rowi; return TRUE; } } if(y>=ROW_TOP_YPIXEL(sheet,sheet->range.row0)-DRAG_WIDTH/2 && y<=ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+ sheet->row[sheet->range.rowi].height+DRAG_WIDTH/2){ xdrag=COLUMN_LEFT_XPIXEL(sheet,sheet->range.col0); if(x>=xdrag-DRAG_WIDTH/2 && x<=xdrag+DRAG_WIDTH/2){ *drag_column=sheet->range.col0; return TRUE; } xdrag=COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+ sheet->column[sheet->range.coli].width; if(x>=xdrag-DRAG_WIDTH/2 && x<=xdrag+DRAG_WIDTH/2){ *drag_column=sheet->range.coli; return TRUE; } } return FALSE; } static inline gint POSSIBLE_RESIZE(GtkSheet *sheet, gint x, gint y, gint *drag_row, gint *drag_column) { gint xdrag, ydrag; xdrag=COLUMN_LEFT_XPIXEL(sheet,sheet->range.coli)+ sheet->column[sheet->range.coli].width; ydrag=ROW_TOP_YPIXEL(sheet,sheet->range.rowi)+ sheet->row[sheet->range.rowi].height; if(sheet->state == GTK_SHEET_COLUMN_SELECTED) ydrag = ROW_TOP_YPIXEL(sheet, sheet->view.row0); if(sheet->state == GTK_SHEET_ROW_SELECTED) xdrag = COLUMN_LEFT_XPIXEL(sheet, sheet->view.col0); *drag_column=COLUMN_FROM_XPIXEL(sheet,x); *drag_row=ROW_FROM_YPIXEL(sheet,y); if(x>=xdrag-DRAG_WIDTH/2 && x<=xdrag+DRAG_WIDTH/2 && y>=ydrag-DRAG_WIDTH/2 && y<=ydrag+DRAG_WIDTH/2) return TRUE; return FALSE; } static void gtk_sheet_class_init (GtkSheetClass * klass); static void gtk_sheet_init (GtkSheet * sheet); static void gtk_sheet_destroy (GtkObject * object); static void gtk_sheet_finalize (GObject * object); static void gtk_sheet_style_set (GtkWidget *widget, GtkStyle *previous_style); static void gtk_sheet_realize (GtkWidget * widget); static void gtk_sheet_unrealize (GtkWidget * widget); static void gtk_sheet_map (GtkWidget * widget); static void gtk_sheet_unmap (GtkWidget * widget); static gint gtk_sheet_expose (GtkWidget * widget, GdkEventExpose * event); static void gtk_sheet_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); static void gtk_sheet_set_scroll_adjustments (GtkSheet *sheet, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment); static gint gtk_sheet_button_press (GtkWidget * widget, GdkEventButton * event); static gint gtk_sheet_button_release (GtkWidget * widget, GdkEventButton * event); static gint gtk_sheet_motion (GtkWidget * widget, GdkEventMotion * event); static gint gtk_sheet_entry_key_press (GtkWidget *widget, GdkEventKey *key); static gint gtk_sheet_key_press (GtkWidget *widget, GdkEventKey *key); static void gtk_sheet_size_request (GtkWidget * widget, GtkRequisition * requisition); static void gtk_sheet_size_allocate (GtkWidget * widget, GtkAllocation * allocation); /* Sheet queries */ static gint gtk_sheet_range_isvisible (GtkSheet * sheet, GtkSheetRange range); static gint gtk_sheet_cell_isvisible (GtkSheet * sheet, gint row, gint column); /* Clipped Range */ static gint gtk_sheet_scroll (gpointer data); static gint gtk_sheet_flash (gpointer data); /* Drawing Routines */ /* draw cell background and frame */ static void gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint column); /* draw cell border */ static void gtk_sheet_cell_draw_border (GtkSheet *sheet, gint row, gint column, gint mask); /* draw cell contents */ static void gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint column); /* draw visible part of range. If range==NULL then draw the whole screen */ static void gtk_sheet_range_draw (GtkSheet *sheet, const GtkSheetRange *range); /* highlight the visible part of the selected range */ static void gtk_sheet_range_draw_selection (GtkSheet *sheet, GtkSheetRange range); /* Selection */ static gint gtk_sheet_move_query (GtkSheet *sheet, gint row, gint column); static void gtk_sheet_real_select_range (GtkSheet * sheet, GtkSheetRange * range); static void gtk_sheet_real_unselect_range (GtkSheet * sheet, const GtkSheetRange * range); static void gtk_sheet_extend_selection (GtkSheet *sheet, gint row, gint column); static void gtk_sheet_new_selection (GtkSheet *sheet, GtkSheetRange *range); static void gtk_sheet_draw_border (GtkSheet *sheet, GtkSheetRange range); static void gtk_sheet_draw_corners (GtkSheet *sheet, GtkSheetRange range); /* Active Cell handling */ static void gtk_sheet_entry_changed (GtkWidget *widget, gpointer data); static gboolean gtk_sheet_deactivate_cell (GtkSheet *sheet); static void gtk_sheet_hide_active_cell (GtkSheet *sheet); static gboolean gtk_sheet_activate_cell (GtkSheet *sheet, gint row, gint col); static void gtk_sheet_draw_active_cell (GtkSheet *sheet); static void gtk_sheet_show_active_cell (GtkSheet *sheet); static void gtk_sheet_click_cell (GtkSheet *sheet, gint row, gint column, gboolean *veto); /* Backing Pixmap */ static void gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height); static void gtk_sheet_draw_backing_pixmap (GtkSheet *sheet, GtkSheetRange range); /* Scrollbars */ static void adjust_scrollbars (GtkSheet * sheet); static void vadjustment_changed (GtkAdjustment * adjustment, gpointer data); static void hadjustment_changed (GtkAdjustment * adjustment, gpointer data); static void vadjustment_value_changed (GtkAdjustment * adjustment, gpointer data); static void hadjustment_value_changed (GtkAdjustment * adjustment, gpointer data); static void draw_xor_vline (GtkSheet * sheet); static void draw_xor_hline (GtkSheet * sheet); static void draw_xor_rectangle (GtkSheet *sheet, GtkSheetRange range); static void gtk_sheet_draw_flashing_range (GtkSheet *sheet, GtkSheetRange range); static guint new_column_width (GtkSheet * sheet, gint column, gint * x); static guint new_row_height (GtkSheet * sheet, gint row, gint * y); /* Sheet Button */ static void create_global_button (GtkSheet *sheet); static void global_button_clicked (GtkWidget *widget, gpointer data); /* Sheet Entry */ static void create_sheet_entry (GtkSheet *sheet); static void gtk_sheet_size_allocate_entry (GtkSheet *sheet); static void gtk_sheet_entry_set_max_size (GtkSheet *sheet); /* Sheet button gadgets */ static void size_allocate_column_title_buttons (GtkSheet * sheet); static void size_allocate_row_title_buttons (GtkSheet * sheet); static void gtk_sheet_recalc_top_ypixels (GtkSheet *sheet, gint row); static void gtk_sheet_recalc_left_xpixels (GtkSheet *sheet, gint column); static void row_button_set (GtkSheet *sheet, gint row); static void column_button_set (GtkSheet *sheet, gint column); static void row_button_release (GtkSheet *sheet, gint row); static void column_button_release (GtkSheet *sheet, gint column); static void gtk_sheet_button_draw (GtkSheet *sheet, gint row, gint column); static void size_allocate_global_button (GtkSheet *sheet); static void gtk_sheet_button_size_request (GtkSheet *sheet, GtkSheetButton *button, GtkRequisition *requisition); /* Attributes routines */ static void gtk_sheet_set_cell_attributes (GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr attributes); static void init_attributes (GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes); /* Memory allocation routines */ static void gtk_sheet_real_range_clear (GtkSheet *sheet, const GtkSheetRange *range, gboolean delete); static void gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column, gboolean delete); static GtkSheetCell * gtk_sheet_cell_new (void); static gint AddRow (GtkSheet *sheet, gint nrows); static gint AddColumn (GtkSheet *sheet, gint ncols); static gint InsertRow (GtkSheet *sheet, gint row, gint nrows); static gint InsertColumn (GtkSheet *sheet, gint col, gint ncols); static gint DeleteRow (GtkSheet *sheet, gint row, gint nrows); static gint DeleteColumn (GtkSheet *sheet, gint col, gint ncols); static gint GrowSheet (GtkSheet *sheet, gint newrows, gint newcols); static gint CheckBounds (GtkSheet *sheet, gint row, gint col); /* Container Functions */ static void gtk_sheet_remove (GtkContainer *container, GtkWidget *widget); static void gtk_sheet_realize_child (GtkSheet *sheet, GtkSheetChild *child); static void gtk_sheet_position_child (GtkSheet *sheet, GtkSheetChild *child); static void gtk_sheet_position_children (GtkSheet *sheet); static void gtk_sheet_child_show (GtkSheetChild *child); static void gtk_sheet_child_hide (GtkSheetChild *child); static void gtk_sheet_column_size_request (GtkSheet *sheet, gint col, guint *requisition); static void gtk_sheet_row_size_request (GtkSheet *sheet, gint row, guint *requisition); /* Signals */ extern void _gtkextra_signal_emit(GtkObject *object, guint signal_id, ...); enum { SELECT_ROW, SELECT_COLUMN, SELECT_RANGE, CLIP_RANGE, RESIZE_RANGE, MOVE_RANGE, TRAVERSE, DEACTIVATE, ACTIVATE, SET_CELL, CLEAR_CELL, CHANGED, NEW_COL_WIDTH, NEW_ROW_HEIGHT, LAST_SIGNAL }; static GtkContainerClass *parent_class = NULL; static guint sheet_signals[LAST_SIGNAL] = {0}; GType gtk_sheet_get_type () { static GType sheet_type = 0; if (!sheet_type) { static const GTypeInfo sheet_info = { sizeof (GtkSheetClass), NULL, NULL, (GClassInitFunc) gtk_sheet_class_init, NULL, NULL, sizeof (GtkSheet), 0, (GInstanceInitFunc) gtk_sheet_init, NULL, }; sheet_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkSheet", &sheet_info, 0); } return sheet_type; } static GtkSheetRange* gtk_sheet_range_copy (const GtkSheetRange *range) { GtkSheetRange *new_range; g_return_val_if_fail (range != NULL, NULL); new_range = g_new (GtkSheetRange, 1); *new_range = *range; return new_range; } static void gtk_sheet_range_free (GtkSheetRange *range) { g_return_if_fail (range != NULL); g_free (range); } GType gtk_sheet_range_get_type (void) { static GType sheet_range_type=0; if(!sheet_range_type) { sheet_range_type = g_boxed_type_register_static("GtkSheetRange", (GBoxedCopyFunc)gtk_sheet_range_copy, (GBoxedFreeFunc)gtk_sheet_range_free); } return sheet_range_type; } static void gtk_sheet_class_init (GtkSheetClass * klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; GObjectClass *gobject_class = G_OBJECT_CLASS (klass); object_class = (GtkObjectClass *) klass; widget_class = (GtkWidgetClass *) klass; container_class = (GtkContainerClass *) klass; parent_class = g_type_class_peek_parent (klass); /** * GtkSheet::select-row * @sheet: the sheet widget that emitted the signal * @row: the newly selected row index * * A row has been selected. */ sheet_signals[SELECT_ROW] = gtk_signal_new ("select-row", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, select_row), gtkextra_VOID__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); /** * GtkSheet::select-column * @sheet: the sheet widget that emitted the signal * @column: the newly selected column index * * A column has been selected. */ sheet_signals[SELECT_COLUMN] = gtk_signal_new ("select-column", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, select_column), gtkextra_VOID__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); sheet_signals[SELECT_RANGE] = gtk_signal_new ("select-range", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, select_range), gtkextra_VOID__BOXED, GTK_TYPE_NONE, 1, GTK_TYPE_SHEET_RANGE); sheet_signals[CLIP_RANGE] = gtk_signal_new ("clip-range", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, clip_range), gtkextra_VOID__BOXED, GTK_TYPE_NONE, 1, GTK_TYPE_SHEET_RANGE); sheet_signals[RESIZE_RANGE] = gtk_signal_new ("resize-range", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, resize_range), gtkextra_VOID__BOXED_BOXED, GTK_TYPE_NONE, 2, GTK_TYPE_SHEET_RANGE, GTK_TYPE_SHEET_RANGE); sheet_signals[MOVE_RANGE] = gtk_signal_new ("move-range", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, move_range), gtkextra_VOID__BOXED_BOXED, GTK_TYPE_NONE, 2, GTK_TYPE_SHEET_RANGE, GTK_TYPE_SHEET_RANGE); sheet_signals[TRAVERSE] = gtk_signal_new ("traverse", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, traverse), gtkextra_BOOLEAN__INT_INT_POINTER_POINTER, GTK_TYPE_BOOL, 4, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_POINTER); sheet_signals[DEACTIVATE] = gtk_signal_new ("deactivate", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, deactivate), gtkextra_BOOLEAN__INT_INT, GTK_TYPE_BOOL, 2, GTK_TYPE_INT, GTK_TYPE_INT); sheet_signals[ACTIVATE] = gtk_signal_new ("activate", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, activate), gtkextra_BOOLEAN__INT_INT, GTK_TYPE_BOOL, 2, GTK_TYPE_INT, GTK_TYPE_INT); sheet_signals[SET_CELL] = gtk_signal_new ("set-cell", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, set_cell), gtkextra_VOID__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); sheet_signals[CLEAR_CELL] = gtk_signal_new ("clear-cell", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, clear_cell), gtkextra_VOID__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); sheet_signals[CHANGED] = gtk_signal_new ("changed", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, changed), gtkextra_VOID__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); sheet_signals[NEW_COL_WIDTH] = gtk_signal_new ("new-column-width", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, changed), gtkextra_VOID__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); sheet_signals[NEW_ROW_HEIGHT] = gtk_signal_new ("new-row-height", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, changed), gtkextra_VOID__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); widget_class->set_scroll_adjustments_signal = gtk_signal_new ("set-scroll-adjustments", GTK_RUN_LAST, GTK_CLASS_TYPE(object_class), GTK_SIGNAL_OFFSET (GtkSheetClass, set_scroll_adjustments), gtkextra_VOID__OBJECT_OBJECT, GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); container_class->add = NULL; container_class->remove = gtk_sheet_remove; container_class->forall = gtk_sheet_forall; object_class->destroy = gtk_sheet_destroy; gobject_class->finalize = gtk_sheet_finalize; widget_class->realize = gtk_sheet_realize; widget_class->unrealize = gtk_sheet_unrealize; widget_class->map = gtk_sheet_map; widget_class->unmap = gtk_sheet_unmap; widget_class->style_set = gtk_sheet_style_set; widget_class->button_press_event = gtk_sheet_button_press; widget_class->button_release_event = gtk_sheet_button_release; widget_class->motion_notify_event = gtk_sheet_motion; widget_class->key_press_event = gtk_sheet_key_press; widget_class->expose_event = gtk_sheet_expose; widget_class->size_request = gtk_sheet_size_request; widget_class->size_allocate = gtk_sheet_size_allocate; widget_class->focus_in_event = NULL; widget_class->focus_out_event = NULL; klass->set_scroll_adjustments = gtk_sheet_set_scroll_adjustments; klass->select_row = NULL; klass->select_column = NULL; klass->select_range = NULL; klass->clip_range = NULL; klass->resize_range = NULL; klass->move_range = NULL; klass->traverse = NULL; klass->deactivate = NULL; klass->activate = NULL; klass->set_cell = NULL; klass->clear_cell = NULL; klass->changed = NULL; } static void gtk_sheet_init (GtkSheet *sheet) { sheet->children = NULL; sheet->flags = 0; sheet->selection_mode = GTK_SELECTION_BROWSE; sheet->freeze_count = 0; sheet->state = GTK_SHEET_NORMAL; GTK_WIDGET_UNSET_FLAGS (sheet, GTK_NO_WINDOW); GTK_WIDGET_SET_FLAGS (sheet, GTK_CAN_FOCUS); sheet->maxrow = 0; sheet->maxcol = 0; sheet->view.row0 = 0; sheet->view.col0 = 0; sheet->view.rowi = 0; sheet->view.coli = 0; sheet->maxallocrow = 0; sheet->maxalloccol = 0; sheet->column_title_window=NULL; sheet->column_title_area.x=0; sheet->column_title_area.y=0; sheet->column_title_area.width=0; sheet->column_title_area.height=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet)); sheet->row_title_window=NULL; sheet->row_title_area.x=0; sheet->row_title_area.y=0; sheet->row_title_area.width=DEFAULT_COLUMN_WIDTH; sheet->row_title_area.height=0; sheet->active_cell.row=0; sheet->active_cell.col=0; sheet->selection_cell.row=0; sheet->selection_cell.col=0; sheet->sheet_entry=NULL; sheet->pixmap=NULL; sheet->range.row0=0; sheet->range.rowi=0; sheet->range.col0=0; sheet->range.coli=0; sheet->state=GTK_SHEET_NORMAL; sheet->sheet_window = NULL; sheet->sheet_window_width = 0; sheet->sheet_window_height = 0; sheet->sheet_entry = NULL; sheet->button = NULL; sheet->hoffset = 0; sheet->voffset = 0; sheet->hadjustment = NULL; sheet->vadjustment = NULL; sheet->cursor_drag = gdk_cursor_new(GDK_PLUS); sheet->xor_gc = NULL; sheet->fg_gc = NULL; sheet->bg_gc = NULL; sheet->x_drag = 0; sheet->y_drag = 0; gdk_color_parse("white", &sheet->bg_color); gdk_color_alloc(gdk_colormap_get_system(), &sheet->bg_color); gdk_color_parse("gray", &sheet->grid_color); gdk_color_alloc(gdk_colormap_get_system(), &sheet->grid_color); sheet->show_grid = TRUE; } /** * gtk_sheet_new: * @rows: initial number of rows * @columns: initial number of columns * @title: sheet title * * Creates a new sheet widget with the given number of rows and columns. * * Returns: the new sheet widget */ GtkWidget * gtk_sheet_new (guint rows, guint columns, const gchar *title) { GtkWidget *widget; /* sanity check */ g_return_val_if_fail (columns >= MINCOLS, NULL); g_return_val_if_fail (rows >= MINROWS, NULL); widget = gtk_type_new (gtk_sheet_get_type ()); gtk_sheet_construct(GTK_SHEET(widget), rows, columns, title); return widget; } void gtk_sheet_construct (GtkSheet *sheet, guint rows, guint columns, const gchar *title) { sheet->row=(GtkSheetRow *)g_malloc(sizeof(GtkSheetRow)); sheet->column=(GtkSheetColumn *)g_malloc(sizeof(GtkSheetColumn)); sheet->data=(GtkSheetCell ***)g_malloc(sizeof(GtkSheetCell **)); sheet->data[0] = (GtkSheetCell **)g_malloc(sizeof(GtkSheetCell *)+sizeof(gdouble)); sheet->data[0][0] = NULL; sheet->columns_resizable = TRUE; sheet->rows_resizable = TRUE; sheet->row_titles_visible = TRUE; sheet->column_titles_visible = TRUE; sheet->autoscroll = TRUE; sheet->justify_entry = TRUE; sheet->locked = FALSE; /* set number of rows and columns */ GrowSheet(sheet, MINROWS, MINCOLS); /* Init row an column zero */ AddRow(sheet,-1); AddColumn(sheet,-1); /* Add rows and columns */ AddRow(sheet,rows-1); AddColumn(sheet,columns-1); /* create sheet entry */ sheet->entry_type = 0; create_sheet_entry (sheet); /* create global selection button */ create_global_button(sheet); if(title) sheet->name = g_strdup(title); } GtkWidget * gtk_sheet_new_browser(guint rows, guint columns, const gchar *title) { GtkWidget *widget; widget = gtk_type_new (gtk_sheet_get_type ()); gtk_sheet_construct_browser(GTK_SHEET(widget), rows, columns, title); return widget; } void gtk_sheet_construct_browser(GtkSheet *sheet, guint rows, guint columns, const gchar *title) { gtk_sheet_construct(sheet, rows, columns, title); gtk_sheet_set_locked(sheet, TRUE); sheet->autoresize = TRUE; } GtkWidget * gtk_sheet_new_with_custom_entry (guint rows, guint columns, const gchar *title, GtkType entry_type) { GtkWidget *widget; widget = gtk_type_new (gtk_sheet_get_type ()); gtk_sheet_construct_with_custom_entry(GTK_SHEET(widget), rows, columns, title, entry_type); return widget; } void gtk_sheet_construct_with_custom_entry (GtkSheet *sheet, guint rows, guint columns, const gchar *title, GtkType entry_type) { gtk_sheet_construct(sheet, rows, columns, title); sheet->entry_type = entry_type; create_sheet_entry(sheet); } void gtk_sheet_change_entry(GtkSheet *sheet, GtkType entry_type) { gint state; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); state = sheet->state; if(sheet->state == GTK_SHEET_NORMAL) gtk_sheet_hide_active_cell(sheet); sheet->entry_type = entry_type; create_sheet_entry(sheet); if(state == GTK_SHEET_NORMAL) { gtk_sheet_show_active_cell(sheet); gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet)), "changed", (GtkSignalFunc)gtk_sheet_entry_changed, GTK_OBJECT(GTK_WIDGET(sheet))); } } void gtk_sheet_show_grid(GtkSheet *sheet, gboolean show) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(show == sheet->show_grid) return; sheet->show_grid = show; if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, NULL); } gboolean gtk_sheet_grid_visible(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); return sheet->show_grid; } void gtk_sheet_set_background(GtkSheet *sheet, GdkColor *color) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!color) { gdk_color_parse("white", &sheet->bg_color); gdk_color_alloc(gdk_colormap_get_system(), &sheet->bg_color); } else sheet->bg_color = *color; if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, NULL); } void gtk_sheet_set_grid(GtkSheet *sheet, GdkColor *color) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!color){ gdk_color_parse("black", &sheet->grid_color); gdk_color_alloc(gdk_colormap_get_system(), &sheet->grid_color); }else sheet->grid_color = *color; if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, NULL); } guint gtk_sheet_get_columns_count(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); return sheet->maxcol + 1; } guint gtk_sheet_get_rows_count(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); return sheet->maxrow + 1; } gint gtk_sheet_get_state(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); return (sheet->state); } void gtk_sheet_set_selection_mode(GtkSheet *sheet, gint mode) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(GTK_WIDGET_REALIZED(sheet)) gtk_sheet_real_unselect_range(sheet, NULL); sheet->selection_mode = mode; } void gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->autoresize = autoresize; } gboolean gtk_sheet_autoresize (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->autoresize; } static void gtk_sheet_autoresize_column (GtkSheet *sheet, gint column) { gint text_width = 0; gint row; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (column > sheet->maxcol || column < 0) return; for (row = 0; row < sheet->maxrow; row++){ GtkSheetCell **cell = &sheet->data[row][column]; if (*cell && (*cell)->text && strlen((*cell)->text) > 0){ GtkSheetCellAttr attributes; gtk_sheet_get_attributes(sheet, row, column, &attributes); if(attributes.is_visible){ gint width = STRING_WIDTH(GTK_WIDGET(sheet), attributes.font_desc, (*cell)->text) + 2*CELLOFFSET + attributes.border.width; text_width = MAX (text_width, width); } } } if(text_width > (gint)sheet->column[column].width){ gtk_sheet_set_column_width(sheet, column, text_width); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_REDRAW_PENDING); } } void gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->autoscroll = autoscroll; } gboolean gtk_sheet_autoscroll (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->autoscroll; } void gtk_sheet_set_clip_text (GtkSheet *sheet, gboolean clip_text) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->clip_text = clip_text; } gboolean gtk_sheet_clip_text (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->clip_text; } void gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->justify_entry = justify; } gboolean gtk_sheet_justify_entry (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->justify_entry; } void gtk_sheet_set_locked (GtkSheet *sheet, gboolean locked) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->locked = locked; } gboolean gtk_sheet_locked (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->locked; } /* This routine has problems with gtk+-1.2 related with the * label/button drawing - I think it's a bug in gtk+-1.2 */ void gtk_sheet_set_title(GtkSheet *sheet, const gchar *title) { g_return_if_fail (sheet != NULL); g_return_if_fail (title != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (sheet->name) g_free (sheet->name); sheet->name = g_strdup (title); if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) || !title) return; size_allocate_global_button(sheet); } void gtk_sheet_freeze (GtkSheet *sheet) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->freeze_count++; GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IS_FROZEN); } void gtk_sheet_thaw(GtkSheet *sheet) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(sheet->freeze_count == 0) return; sheet->freeze_count--; if(sheet->freeze_count > 0) return; adjust_scrollbars(sheet); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IS_FROZEN); sheet->old_vadjustment = -1.; sheet->old_hadjustment = -1.; if(sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); if(sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); if(sheet->state == GTK_STATE_NORMAL) if(sheet->sheet_entry && GTK_WIDGET_MAPPED(sheet->sheet_entry)){ gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); /* gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet)), "changed", (GtkSignalFunc)gtk_sheet_entry_changed, GTK_OBJECT(GTK_WIDGET(sheet))); gtk_sheet_show_active_cell(sheet); */ } } void gtk_sheet_set_row_titles_width(GtkSheet *sheet, guint width) { if(width < COLUMN_MIN_WIDTH) return; sheet->row_title_area.width = width; sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, sheet->row_title_area.width+1); sheet->view.coli=COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width); gtk_sheet_recalc_top_ypixels(sheet, 0); gtk_sheet_recalc_left_xpixels(sheet, 0); adjust_scrollbars(sheet); sheet->old_hadjustment = -1.; if(sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); size_allocate_global_button(sheet); } void gtk_sheet_set_column_titles_height(GtkSheet *sheet, guint height) { if(height < DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet))) return; sheet->column_title_area.height = height; sheet->view.row0=ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height+1); sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height-1); gtk_sheet_recalc_top_ypixels(sheet, 0); gtk_sheet_recalc_left_xpixels(sheet, 0); adjust_scrollbars(sheet); sheet->old_vadjustment = -1.; if(sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); size_allocate_global_button(sheet); } void gtk_sheet_show_column_titles(GtkSheet *sheet) { gint col; if(sheet->column_titles_visible) return; sheet->column_titles_visible = TRUE; gtk_sheet_recalc_top_ypixels(sheet, 0); gtk_sheet_recalc_left_xpixels(sheet, 0); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))){ gdk_window_show(sheet->column_title_window); gdk_window_move_resize (sheet->column_title_window, sheet->column_title_area.x, sheet->column_title_area.y, sheet->column_title_area.width, sheet->column_title_area.height); for(col = MIN_VISIBLE_COLUMN(sheet); col <= MAX_VISIBLE_COLUMN(sheet); col++){ GtkSheetChild *child; child = sheet->column[col].button.child; if(child){ gtk_sheet_child_show(child); } } adjust_scrollbars(sheet); } sheet->old_vadjustment = -1.; if(sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); size_allocate_global_button(sheet); } void gtk_sheet_show_row_titles(GtkSheet *sheet) { gint row; if(sheet->row_titles_visible) return; sheet->row_titles_visible = TRUE; gtk_sheet_recalc_top_ypixels(sheet, 0); gtk_sheet_recalc_left_xpixels(sheet, 0); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))){ gdk_window_show(sheet->row_title_window); gdk_window_move_resize (sheet->row_title_window, sheet->row_title_area.x, sheet->row_title_area.y, sheet->row_title_area.width, sheet->row_title_area.height); for(row = MIN_VISIBLE_ROW(sheet); row <= MAX_VISIBLE_ROW(sheet); row++){ GtkSheetChild *child; child = sheet->row[row].button.child; if(child){ gtk_sheet_child_show(child); } } adjust_scrollbars(sheet); } sheet->old_hadjustment = -1.; if(sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); size_allocate_global_button(sheet); } void gtk_sheet_hide_column_titles(GtkSheet *sheet) { gint col; if(!sheet->column_titles_visible) return; sheet->column_titles_visible = FALSE; gtk_sheet_recalc_top_ypixels(sheet, 0); gtk_sheet_recalc_left_xpixels(sheet, 0); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))){ if(sheet->column_title_window) gdk_window_hide(sheet->column_title_window); if(GTK_WIDGET_VISIBLE(sheet->button)) gtk_widget_hide(sheet->button); for(col = MIN_VISIBLE_COLUMN(sheet); col <= MAX_VISIBLE_COLUMN(sheet); col++){ GtkSheetChild *child; child = sheet->column[col].button.child; if(child){ gtk_sheet_child_hide(child); } } adjust_scrollbars(sheet); } sheet->old_vadjustment = -1.; if(sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); } void gtk_sheet_hide_row_titles(GtkSheet *sheet) { gint row; if(!sheet->row_titles_visible) return; sheet->row_titles_visible = FALSE; gtk_sheet_recalc_top_ypixels(sheet, 0); gtk_sheet_recalc_left_xpixels(sheet, 0); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))){ if(sheet->row_title_window) gdk_window_hide(sheet->row_title_window); if(GTK_WIDGET_VISIBLE(sheet->button)) gtk_widget_hide(sheet->button); for(row = MIN_VISIBLE_ROW(sheet); row <= MAX_VISIBLE_ROW(sheet); row++){ GtkSheetChild *child; child = sheet->row[row].button.child; if(child){ gtk_sheet_child_hide(child); } } adjust_scrollbars(sheet); } sheet->old_hadjustment = -1.; if(sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); } gboolean gtk_sheet_column_titles_visible(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->column_titles_visible; } gboolean gtk_sheet_row_titles_visible(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->row_titles_visible; } void gtk_sheet_set_column_title (GtkSheet * sheet, gint column, const gchar * title) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (sheet->column[column].name) g_free (sheet->column[column].name); sheet->column[column].name = g_strdup(title); } void gtk_sheet_set_row_title (GtkSheet * sheet, gint row, const gchar * title) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (sheet->row[row].name) g_free (sheet->row[row].name); sheet->row[row].name = g_strdup (title); } const gchar * gtk_sheet_get_row_title (GtkSheet * sheet, gint row) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); return(sheet->row[row].name); } const gchar * gtk_sheet_get_column_title (GtkSheet * sheet, gint column) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); return(sheet->column[column].name); } void gtk_sheet_row_button_add_label(GtkSheet *sheet, gint row, const gchar *label) { GtkSheetButton *button; GtkRequisition req; gboolean aux; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(row < 0 || row > sheet->maxrow) return; button = &sheet->row[row].button; if (button->label) g_free (button->label); button->label = g_strdup (label); aux = gtk_sheet_autoresize(sheet); gtk_sheet_set_autoresize(sheet, TRUE); gtk_sheet_button_size_request(sheet, button, &req); gtk_sheet_set_autoresize(sheet, aux); if(req.height > sheet->row[row].height) gtk_sheet_set_row_height(sheet, row, req.height); if(req.width > sheet->row_title_area.width){ gtk_sheet_set_row_titles_width(sheet, req.width); } if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_button_draw(sheet, row, -1); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], row, -1); } } const gchar * gtk_sheet_row_button_get_label(GtkSheet *sheet, gint row) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); if(row < 0 || row > sheet->maxrow) return NULL; return (sheet->row[row].button.label); } void gtk_sheet_row_label_set_visibility(GtkSheet *sheet, gint row, gboolean visible) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(row < 0 || row > sheet->maxrow) return; sheet->row[row].button.label_visible = visible; if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_button_draw(sheet, row, -1); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], row, -1); } } void gtk_sheet_rows_labels_set_visibility(GtkSheet *sheet, gboolean visible) { gint i; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); for(i = 0; i <= sheet->maxrow; i++) gtk_sheet_row_label_set_visibility(sheet, i, visible); } void gtk_sheet_column_button_add_label(GtkSheet *sheet, gint column, const gchar *label) { GtkSheetButton *button; GtkRequisition req; gboolean aux; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(column < 0 || column >sheet->maxcol) return; button = &sheet->column[column].button; if (button->label) g_free (button->label); button->label = g_strdup (label); aux = gtk_sheet_autoresize(sheet); gtk_sheet_set_autoresize(sheet, TRUE); gtk_sheet_button_size_request(sheet, button, &req); gtk_sheet_set_autoresize(sheet, aux); if(req.width > sheet->column[column].width) gtk_sheet_set_column_width(sheet, column, req.width); if(req.height > sheet->column_title_area.height) gtk_sheet_set_column_titles_height(sheet, req.height); if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_button_draw(sheet, -1, column); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], -1, column); } } const gchar * gtk_sheet_column_button_get_label(GtkSheet *sheet, gint column) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); if(column < 0 || column >sheet->maxcol) return NULL; return(sheet->column[column].button.label); } void gtk_sheet_column_label_set_visibility(GtkSheet *sheet, gint col, gboolean visible) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(col < 0 || col > sheet->maxcol) return; sheet->column[col].button.label_visible = visible; if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_button_draw(sheet, -1, col); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], -1, col); } } void gtk_sheet_columns_labels_set_visibility(GtkSheet *sheet, gboolean visible) { gint i; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); for(i = 0; i <= sheet->maxcol; i++) gtk_sheet_column_label_set_visibility(sheet, i, visible); } void gtk_sheet_row_button_justify(GtkSheet *sheet, gint row, GtkJustification justification) { GtkSheetButton *button; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(row < 0 || row > sheet->maxrow) return; button = &sheet->row[row].button; button->justification = justification; if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_button_draw(sheet, row, -1); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], row, -1); } } void gtk_sheet_column_button_justify(GtkSheet *sheet, gint column, GtkJustification justification) { GtkSheetButton *button; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(column < 0 || column > sheet->maxcol) return; button = &sheet->column[column].button; button->justification = justification; if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_button_draw(sheet, -1, column); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], -1, column); } } void gtk_sheet_moveto (GtkSheet * sheet, gint row, gint column, gfloat row_align, gfloat col_align) { gint x, y; guint width, height; gint adjust; gint min_row, min_col; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); g_return_if_fail (sheet->hadjustment != NULL); g_return_if_fail (sheet->vadjustment != NULL); if (row < 0 || row > sheet->maxrow) return; if (column < 0 || column > sheet->maxcol) return; height = sheet->sheet_window_height; width = sheet->sheet_window_width; /* adjust vertical scrollbar */ if (row >= 0 && row_align >=0.) { /* y = ROW_TOP_YPIXEL(sheet, row) - sheet->voffset - row_align*height- (1.-row_align)*sheet->row[row].height; */ y = ROW_TOP_YPIXEL (sheet, row) - sheet->voffset - (gint) ( row_align*height + (1. - row_align) * sheet->row[row].height); /* This forces the sheet to scroll when you don't see the entire cell */ min_row = row; adjust = 0; if(row_align == 1.){ while(min_row >= 0 && min_row > MIN_VISIBLE_ROW(sheet)){ if(sheet->row[min_row].is_visible) adjust += sheet->row[min_row].height; if(adjust >= height){ break; } min_row--; } min_row = MAX(min_row, 0); y = ROW_TOP_YPIXEL(sheet, min_row) - sheet->voffset + sheet->row[min_row].height - 1; } if (y < 0) sheet->vadjustment->value = 0.0; else sheet->vadjustment->value = y; sheet->old_vadjustment = -1.; gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); } /* adjust horizontal scrollbar */ if (column >= 0 && col_align >= 0.) { /* x = COLUMN_LEFT_XPIXEL (sheet, column) - sheet->hoffset - col_align*width - (1.-col_align)*sheet->column[column].width; */ x = COLUMN_LEFT_XPIXEL (sheet, column) - sheet->hoffset - (gint) ( col_align*width + (1.-col_align)*sheet->column[column].width); /* This forces the sheet to scroll when you don't see the entire cell */ min_col = column; adjust = 0; if(col_align == 1.){ while(min_col >= 0 && min_col > MIN_VISIBLE_COLUMN(sheet)){ if(sheet->column[min_col].is_visible) adjust += sheet->column[min_col].width; if(adjust >= width){ break; } min_col--; } min_col = MAX(min_col, 0); x = COLUMN_LEFT_XPIXEL(sheet, min_col) - sheet->hoffset + sheet->column[min_col].width - 1; } if (x < 0) sheet->hadjustment->value = 0.0; else sheet->hadjustment->value = x; sheet->old_vadjustment = -1.; gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); } } void gtk_sheet_column_set_sensitivity(GtkSheet *sheet, gint column, gboolean sensitive) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(column < 0 || column > sheet->maxcol) return; sheet->column[column].is_sensitive=sensitive; if(!sensitive) sheet->column[column].button.state=GTK_STATE_INSENSITIVE; else sheet->column[column].button.state=GTK_STATE_NORMAL; if(GTK_WIDGET_REALIZED(sheet) && !GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_button_draw(sheet, -1, column); } void gtk_sheet_columns_set_sensitivity(GtkSheet *sheet, gboolean sensitive) { gint i; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); for(i=0; i<=sheet->maxcol; i++) gtk_sheet_column_set_sensitivity(sheet, i, sensitive); } void gtk_sheet_columns_set_resizable (GtkSheet *sheet, gboolean resizable) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->columns_resizable = resizable; } gboolean gtk_sheet_columns_resizable (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->columns_resizable; } void gtk_sheet_row_set_sensitivity(GtkSheet *sheet, gint row, gboolean sensitive) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(row < 0 || row > sheet->maxrow) return; sheet->row[row].is_sensitive=sensitive; if(!sensitive) sheet->row[row].button.state=GTK_STATE_INSENSITIVE; else sheet->row[row].button.state=GTK_STATE_NORMAL; if(GTK_WIDGET_REALIZED(sheet) && !GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_button_draw(sheet, row, -1); } void gtk_sheet_rows_set_sensitivity(GtkSheet *sheet, gboolean sensitive) { gint i; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); for(i=0; i<=sheet->maxrow; i++) gtk_sheet_row_set_sensitivity(sheet, i, sensitive); } void gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); sheet->rows_resizable = resizable; } gboolean gtk_sheet_rows_resizable (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return sheet->rows_resizable; } void gtk_sheet_column_set_visibility(GtkSheet *sheet, gint column, gboolean visible) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(column < 0 || column > sheet->maxcol) return; if(sheet->column[column].is_visible == visible) return; sheet->column[column].is_visible = visible; gtk_sheet_recalc_left_xpixels(sheet, column); if(!GTK_SHEET_IS_FROZEN(sheet) && gtk_sheet_cell_isvisible(sheet, MIN_VISIBLE_ROW(sheet), column)){ gtk_sheet_range_draw(sheet, NULL); size_allocate_column_title_buttons(sheet); } } void gtk_sheet_row_set_visibility(GtkSheet *sheet, gint row, gboolean visible) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(row < 0 || row > sheet->maxrow) return; if(sheet->row[row].is_visible == visible) return; sheet->row[row].is_visible = visible; gtk_sheet_recalc_top_ypixels(sheet, row); if(!GTK_SHEET_IS_FROZEN(sheet) && gtk_sheet_cell_isvisible(sheet, row, MIN_VISIBLE_COLUMN(sheet))){ gtk_sheet_range_draw(sheet, NULL); size_allocate_row_title_buttons(sheet); } } void gtk_sheet_select_row (GtkSheet * sheet, gint row) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (row < 0 || row > sheet->maxrow) return; if(sheet->state != GTK_SHEET_NORMAL) gtk_sheet_real_unselect_range(sheet, NULL); else { gboolean veto; veto = gtk_sheet_deactivate_cell(sheet); if(!veto) return; } sheet->state=GTK_SHEET_ROW_SELECTED; sheet->range.row0=row; sheet->range.col0=0; sheet->range.rowi=row; sheet->range.coli=sheet->maxcol; sheet->active_cell.row=row; sheet->active_cell.col=0; gtk_signal_emit (GTK_OBJECT (sheet), sheet_signals[SELECT_ROW], row); gtk_sheet_real_select_range(sheet, NULL); } void gtk_sheet_select_column (GtkSheet * sheet, gint column) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (column < 0 || column > sheet->maxcol) return; if(sheet->state != GTK_SHEET_NORMAL) gtk_sheet_real_unselect_range(sheet, NULL); else { gboolean veto; veto = gtk_sheet_deactivate_cell(sheet); if(!veto) return; } sheet->state=GTK_SHEET_COLUMN_SELECTED; sheet->range.row0=0; sheet->range.col0=column; sheet->range.rowi=sheet->maxrow; sheet->range.coli=column; sheet->active_cell.row=0; sheet->active_cell.col=column; gtk_signal_emit (GTK_OBJECT (sheet), sheet_signals[SELECT_COLUMN], column); gtk_sheet_real_select_range(sheet, NULL); } void gtk_sheet_clip_range (GtkSheet *sheet, const GtkSheetRange *range) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(GTK_SHEET_IN_CLIP(sheet)) return; GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_CLIP); if(range == NULL) sheet->clip_range = sheet->range; else sheet->clip_range=*range; sheet->interval=0; sheet->clip_timer=gtk_timeout_add(TIMEOUT_FLASH, gtk_sheet_flash, sheet); gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[CLIP_RANGE], &sheet->clip_range); } void gtk_sheet_unclip_range(GtkSheet *sheet) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!GTK_SHEET_IN_CLIP(sheet)) return; GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_CLIP); gtk_timeout_remove(sheet->clip_timer); gtk_sheet_range_draw(sheet, &sheet->clip_range); if(gtk_sheet_range_isvisible(sheet, sheet->range)) gtk_sheet_range_draw(sheet, &sheet->range); } gboolean gtk_sheet_in_clip (GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); return GTK_SHEET_IN_CLIP(sheet); } static gint gtk_sheet_flash(gpointer data) { GtkSheet *sheet; gint x,y,width,height; GdkRectangle clip_area; sheet=GTK_SHEET(data); if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return TRUE; if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet))) return TRUE; if(!gtk_sheet_range_isvisible(sheet, sheet->clip_range)) return TRUE; if(GTK_SHEET_IN_XDRAG(sheet)) return TRUE; if(GTK_SHEET_IN_YDRAG(sheet)) return TRUE; GDK_THREADS_ENTER(); x=COLUMN_LEFT_XPIXEL(sheet,sheet->clip_range.col0)+1; y=ROW_TOP_YPIXEL(sheet,sheet->clip_range.row0)+1; width=COLUMN_LEFT_XPIXEL(sheet,sheet->clip_range.coli)-x+ sheet->column[sheet->clip_range.coli].width-1; height=ROW_TOP_YPIXEL(sheet,sheet->clip_range.rowi)-y+ sheet->row[sheet->clip_range.rowi].height-1; clip_area.x=COLUMN_LEFT_XPIXEL(sheet, MIN_VISIBLE_COLUMN(sheet)); clip_area.y=ROW_TOP_YPIXEL(sheet, MIN_VISIBLE_ROW(sheet)); clip_area.width=sheet->sheet_window_width; clip_area.height=sheet->sheet_window_height; if(x<0) { width=width+x+1; x=-1; } if(width>clip_area.width) width=clip_area.width+10; if(y<0) { height=height+y+1; y=-1; } if(height>clip_area.height) height=clip_area.height+10; gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x, y, x, y, 1, height); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x, y, x, y, width, 1); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x, y+height, x, y+height, width, 1); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x+width, y, x+width, y, 1, height); sheet->interval=sheet->interval+1; if(sheet->interval==TIME_INTERVAL) sheet->interval=0; gdk_gc_set_dashes(sheet->xor_gc, sheet->interval, (gint8*)"\4\4", 2); gtk_sheet_draw_flashing_range(sheet,sheet->clip_range); gdk_gc_set_dashes(sheet->xor_gc, 0, (gint8*)"\4\4", 2); GDK_THREADS_LEAVE(); return TRUE; } static void gtk_sheet_draw_flashing_range(GtkSheet *sheet, GtkSheetRange range) { GdkRectangle clip_area; gint x,y,width,height; if(!gtk_sheet_range_isvisible(sheet, sheet->clip_range)) return; clip_area.x=COLUMN_LEFT_XPIXEL(sheet, MIN_VISIBLE_COLUMN(sheet)); clip_area.y=ROW_TOP_YPIXEL(sheet, MIN_VISIBLE_ROW(sheet)); clip_area.width=sheet->sheet_window_width; clip_area.height=sheet->sheet_window_height; gdk_gc_set_clip_rectangle(sheet->xor_gc, &clip_area); x=COLUMN_LEFT_XPIXEL(sheet,sheet->clip_range.col0)+1; y=ROW_TOP_YPIXEL(sheet,sheet->clip_range.row0)+1; width=COLUMN_LEFT_XPIXEL(sheet,sheet->clip_range.coli)-x+ sheet->column[sheet->clip_range.coli].width-1; height=ROW_TOP_YPIXEL(sheet,sheet->clip_range.rowi)-y+ sheet->row[sheet->clip_range.rowi].height-1; if(x<0) { width=width+x+1; x=-1; } if(width>clip_area.width) width=clip_area.width+10; if(y<0) { height=height+y+1; y=-1; } if(height>clip_area.height) height=clip_area.height+10; gdk_gc_set_line_attributes(sheet->xor_gc, 1, 1, 0 ,0 ); gdk_draw_rectangle(sheet->sheet_window, sheet->xor_gc, FALSE, x, y, width, height); gdk_gc_set_line_attributes (sheet->xor_gc, 1, 0, 0, 0); gdk_gc_set_clip_rectangle(sheet->xor_gc, NULL); } static gint gtk_sheet_range_isvisible (GtkSheet * sheet, GtkSheetRange range) { g_return_val_if_fail (sheet != NULL, FALSE); if (range.row0 < 0 || range.row0 > sheet->maxrow) return FALSE; if (range.rowi < 0 || range.rowi > sheet->maxrow) return FALSE; if (range.col0 < 0 || range.col0 > sheet->maxcol) return FALSE; if (range.coli < 0 || range.coli > sheet->maxcol) return FALSE; if (range.rowi < MIN_VISIBLE_ROW (sheet)) return FALSE; if (range.row0 > MAX_VISIBLE_ROW (sheet)) return FALSE; if (range.coli < MIN_VISIBLE_COLUMN (sheet)) return FALSE; if (range.col0 > MAX_VISIBLE_COLUMN (sheet)) return FALSE; return TRUE; } static gint gtk_sheet_cell_isvisible (GtkSheet * sheet, gint row, gint column) { GtkSheetRange range; range.row0 = row; range.col0 = column; range.rowi = row; range.coli = column; return gtk_sheet_range_isvisible(sheet, range); } void gtk_sheet_get_visible_range(GtkSheet *sheet, GtkSheetRange *range) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)) ; g_return_if_fail (range != NULL); range->row0 = MIN_VISIBLE_ROW(sheet); range->col0 = MIN_VISIBLE_COLUMN(sheet); range->rowi = MAX_VISIBLE_ROW(sheet); range->coli = MAX_VISIBLE_COLUMN(sheet); } GtkAdjustment * gtk_sheet_get_vadjustment (GtkSheet * sheet) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); return sheet->vadjustment; } GtkAdjustment * gtk_sheet_get_hadjustment (GtkSheet * sheet) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); return sheet->hadjustment; } void gtk_sheet_set_vadjustment (GtkSheet *sheet, GtkAdjustment *adjustment) { GtkAdjustment *old_adjustment; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (adjustment) g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (sheet->vadjustment == adjustment) return; old_adjustment = sheet->vadjustment; if (sheet->vadjustment) { gtk_signal_disconnect_by_data (GTK_OBJECT (sheet->vadjustment), sheet); gtk_object_unref (GTK_OBJECT (sheet->vadjustment)); } sheet->vadjustment = adjustment; if (sheet->vadjustment) { gtk_object_ref (GTK_OBJECT (sheet->vadjustment)); gtk_object_sink (GTK_OBJECT (sheet->vadjustment)); gtk_signal_connect (GTK_OBJECT (sheet->vadjustment), "changed", (GtkSignalFunc) vadjustment_changed, (gpointer) sheet); gtk_signal_connect (GTK_OBJECT (sheet->vadjustment), "value_changed", (GtkSignalFunc) vadjustment_value_changed, (gpointer) sheet); } if (!sheet->vadjustment || !old_adjustment) { gtk_widget_queue_resize (GTK_WIDGET (sheet)); return; } sheet->old_vadjustment = sheet->vadjustment->value; } void gtk_sheet_set_hadjustment (GtkSheet *sheet, GtkAdjustment *adjustment) { GtkAdjustment *old_adjustment; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (adjustment) g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (sheet->hadjustment == adjustment) return; old_adjustment = sheet->hadjustment; if (sheet->hadjustment) { gtk_signal_disconnect_by_data (GTK_OBJECT (sheet->hadjustment), sheet); gtk_object_unref (GTK_OBJECT (sheet->hadjustment)); } sheet->hadjustment = adjustment; if (sheet->hadjustment) { gtk_object_ref (GTK_OBJECT (sheet->hadjustment)); gtk_object_sink (GTK_OBJECT (sheet->hadjustment)); gtk_signal_connect (GTK_OBJECT (sheet->hadjustment), "changed", (GtkSignalFunc) hadjustment_changed, (gpointer) sheet); gtk_signal_connect (GTK_OBJECT (sheet->hadjustment), "value_changed", (GtkSignalFunc) hadjustment_value_changed, (gpointer) sheet); } if (!sheet->hadjustment || !old_adjustment) { gtk_widget_queue_resize (GTK_WIDGET (sheet)); return; } sheet->old_hadjustment = sheet->hadjustment->value; } static void gtk_sheet_set_scroll_adjustments (GtkSheet *sheet, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment) { if(sheet->hadjustment != hadjustment) gtk_sheet_set_hadjustment (sheet, hadjustment); if(sheet->vadjustment != vadjustment) gtk_sheet_set_vadjustment (sheet, vadjustment); } static void gtk_sheet_finalize (GObject * object) { GtkSheet *sheet; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_SHEET (object)); sheet = GTK_SHEET (object); /* get rid of all the cells */ gtk_sheet_range_clear (sheet, NULL); gtk_sheet_range_delete(sheet, NULL); gtk_sheet_delete_rows (sheet, 0, sheet->maxrow + 1); gtk_sheet_delete_columns (sheet, 0, sheet->maxcol + 1); DeleteRow (sheet, 0, sheet->maxrow + 1); DeleteColumn (sheet, 0, sheet->maxcol + 1); g_free(sheet->row); sheet->row = NULL; g_free(sheet->column); sheet->column = NULL; g_free(sheet->data); sheet->data = NULL; if(sheet->name){ g_free(sheet->name); sheet->name = NULL; } if (G_OBJECT_CLASS (parent_class)->finalize) (*G_OBJECT_CLASS (parent_class)->finalize) (object); } static void gtk_sheet_destroy (GtkObject * object) { GtkSheet *sheet; GList *children; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_SHEET (object)); sheet = GTK_SHEET (object); /* destroy the entry */ if(sheet->sheet_entry && GTK_IS_WIDGET(sheet->sheet_entry)){ gtk_widget_destroy (sheet->sheet_entry); sheet->sheet_entry = NULL; } /* destroy the global selection button */ if(sheet->button && GTK_IS_WIDGET(sheet->button)){ gtk_widget_destroy (sheet->button); sheet->button = NULL; } if(sheet->timer){ gtk_timeout_remove(sheet->timer); sheet->timer = 0; } if(sheet->clip_timer){ gtk_timeout_remove(sheet->clip_timer); sheet->clip_timer = 0; } /* unref adjustments */ if (sheet->hadjustment) { gtk_signal_disconnect_by_data (GTK_OBJECT (sheet->hadjustment), sheet); gtk_object_unref (GTK_OBJECT (sheet->hadjustment)); sheet->hadjustment = NULL; } if (sheet->vadjustment) { gtk_signal_disconnect_by_data (GTK_OBJECT (sheet->vadjustment), sheet); gtk_object_unref (GTK_OBJECT (sheet->vadjustment)); sheet->vadjustment = NULL; } children = sheet->children; while(children){ GtkSheetChild *child = (GtkSheetChild *)children->data; if(child && child->widget) gtk_sheet_remove(GTK_CONTAINER(sheet), child->widget); children = sheet->children; } sheet->children = NULL; if (GTK_OBJECT_CLASS (parent_class)->destroy) (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void gtk_sheet_style_set (GtkWidget *widget, GtkStyle *previous_style) { g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); if (GTK_WIDGET_CLASS (parent_class)->style_set) (*GTK_WIDGET_CLASS (parent_class)->style_set) (widget, previous_style); if(GTK_WIDGET_REALIZED(widget)) { gtk_style_set_background (widget->style, widget->window, widget->state); } } static void gtk_sheet_realize (GtkWidget * widget) { GtkSheet *sheet; GdkWindowAttr attributes; gint attributes_mask; GdkGCValues values, auxvalues; GdkColormap *colormap; gchar *name; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); sheet = GTK_SHEET (widget); GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR; attributes.cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW); /* main window */ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, sheet); widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); attributes.x = 0; if(sheet->row_titles_visible) attributes.x = sheet->row_title_area.width; attributes.y = 0; attributes.width = sheet->column_title_area.width; attributes.height = sheet->column_title_area.height; /* column-title window */ sheet->column_title_window = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (sheet->column_title_window, sheet); gtk_style_set_background (widget->style, sheet->column_title_window, GTK_STATE_NORMAL); attributes.x = 0; attributes.y = 0; if(sheet->column_titles_visible) attributes.y = sheet->column_title_area.height; attributes.width = sheet->row_title_area.width; attributes.height = sheet->row_title_area.height; /* row-title window */ sheet->row_title_window = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (sheet->row_title_window, sheet); gtk_style_set_background (widget->style, sheet->row_title_window, GTK_STATE_NORMAL); /* sheet-window */ attributes.cursor = gdk_cursor_new(GDK_PLUS); attributes.x = 0; attributes.y = 0; attributes.width = sheet->sheet_window_width, attributes.height = sheet->sheet_window_height; sheet->sheet_window = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (sheet->sheet_window, sheet); gdk_window_set_background (sheet->sheet_window, &widget->style->white); gdk_window_show (sheet->sheet_window); /* backing_pixmap */ gtk_sheet_make_backing_pixmap(sheet, 0, 0); /* GCs */ if(sheet->fg_gc) gdk_gc_unref(sheet->fg_gc); if(sheet->bg_gc) gdk_gc_unref(sheet->bg_gc); sheet->fg_gc = gdk_gc_new (widget->window); sheet->bg_gc = gdk_gc_new (widget->window); colormap = gtk_widget_get_colormap(widget); gdk_color_white(colormap, &widget->style->white); gdk_color_black(colormap, &widget->style->black); gdk_gc_get_values(sheet->fg_gc, &auxvalues); values.foreground = widget->style->white; values.function = GDK_INVERT; values.subwindow_mode = GDK_INCLUDE_INFERIORS; if(sheet->xor_gc) gdk_gc_unref(sheet->xor_gc); sheet->xor_gc = gdk_gc_new_with_values (widget->window, &values, GDK_GC_FOREGROUND | GDK_GC_FUNCTION | GDK_GC_SUBWINDOW); if(sheet->sheet_entry->parent){ gtk_widget_ref(sheet->sheet_entry); gtk_widget_unparent(sheet->sheet_entry); } gtk_widget_set_parent_window (sheet->sheet_entry, sheet->sheet_window); gtk_widget_set_parent(sheet->sheet_entry, GTK_WIDGET(sheet)); if(sheet->button && sheet->button->parent){ gtk_widget_ref(sheet->button); gtk_widget_unparent(sheet->button); } gtk_widget_set_parent_window(sheet->button, sheet->sheet_window); gtk_widget_set_parent(sheet->button, GTK_WIDGET(sheet)); /* gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); */ if(!sheet->cursor_drag) sheet->cursor_drag = gdk_cursor_new(GDK_PLUS); if(sheet->column_titles_visible) gdk_window_show(sheet->column_title_window); if(sheet->row_titles_visible) gdk_window_show(sheet->row_title_window); size_allocate_row_title_buttons(sheet); size_allocate_column_title_buttons(sheet); name = g_strdup(sheet->name); gtk_sheet_set_title(sheet, name); g_free(name); children = sheet->children; while(children) { GtkSheetChild *child = children->data; children = children->next; gtk_sheet_realize_child(sheet, child); } } static void create_global_button(GtkSheet *sheet) { sheet->button = gtk_button_new_with_label(" "); gtk_signal_connect (GTK_OBJECT (sheet->button), "pressed", (GtkSignalFunc) global_button_clicked, (gpointer) sheet); } static void size_allocate_global_button(GtkSheet *sheet) { GtkAllocation allocation; if(!sheet->column_titles_visible) return; if(!sheet->row_titles_visible) return; gtk_widget_size_request(sheet->button, NULL); allocation.x=0; allocation.y=0; allocation.width=sheet->row_title_area.width; allocation.height=sheet->column_title_area.height; gtk_widget_size_allocate(sheet->button, &allocation); gtk_widget_show(sheet->button); } static void global_button_clicked(GtkWidget *widget, gpointer data) { gboolean veto; gtk_sheet_click_cell(GTK_SHEET(data), -1, -1, &veto); gtk_widget_grab_focus(GTK_WIDGET(data)); } static void gtk_sheet_unrealize (GtkWidget * widget) { GtkSheet *sheet; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); sheet = GTK_SHEET (widget); gdk_cursor_destroy (sheet->cursor_drag); gdk_gc_destroy (sheet->xor_gc); gdk_gc_destroy (sheet->fg_gc); gdk_gc_destroy (sheet->bg_gc); gdk_window_destroy (sheet->sheet_window); gdk_window_destroy (sheet->column_title_window); gdk_window_destroy (sheet->row_title_window); if (sheet->pixmap){ g_object_unref (G_OBJECT(sheet->pixmap)); sheet->pixmap = NULL; } sheet->column_title_window=NULL; sheet->sheet_window = NULL; sheet->cursor_drag = NULL; sheet->xor_gc = NULL; sheet->fg_gc = NULL; sheet->bg_gc = NULL; if (GTK_WIDGET_CLASS (parent_class)->unrealize) (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); } static void gtk_sheet_map (GtkWidget * widget) { GtkSheet *sheet; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); sheet = GTK_SHEET (widget); if (!GTK_WIDGET_MAPPED (widget)) { GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); if(!sheet->cursor_drag) sheet->cursor_drag=gdk_cursor_new(GDK_PLUS); gdk_window_show (widget->window); gdk_window_show (sheet->sheet_window); if(sheet->column_titles_visible){ size_allocate_column_title_buttons(sheet); gdk_window_show (sheet->column_title_window); } if(sheet->row_titles_visible){ size_allocate_row_title_buttons(sheet); gdk_window_show (sheet->row_title_window); } if(!GTK_WIDGET_MAPPED (sheet->sheet_entry)){ gtk_widget_show (sheet->sheet_entry); gtk_widget_map (sheet->sheet_entry); } if (GTK_WIDGET_VISIBLE (sheet->button) && !GTK_WIDGET_MAPPED (sheet->button)){ gtk_widget_show(sheet->button); gtk_widget_map (sheet->button); } if(GTK_BIN(sheet->button)->child) if (GTK_WIDGET_VISIBLE (GTK_BIN(sheet->button)->child) && !GTK_WIDGET_MAPPED (GTK_BIN(sheet->button)->child)) gtk_widget_map (GTK_BIN(sheet->button)->child); gtk_sheet_range_draw(sheet, NULL); gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); children = sheet->children; while (children) { GtkSheetChild *child = children->data; children = children->next; if (GTK_WIDGET_VISIBLE (child->widget) && !GTK_WIDGET_MAPPED (child->widget)){ gtk_widget_map (child->widget); gtk_sheet_position_child(sheet, child); } } } } static void gtk_sheet_unmap (GtkWidget * widget) { GtkSheet *sheet; GList *children; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); sheet = GTK_SHEET (widget); if (GTK_WIDGET_MAPPED (widget)) { GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); gdk_window_hide (sheet->sheet_window); if(sheet->column_titles_visible) gdk_window_hide (sheet->column_title_window); if(sheet->row_titles_visible) gdk_window_hide (sheet->row_title_window); gdk_window_hide (widget->window); if (GTK_WIDGET_MAPPED (sheet->sheet_entry)) gtk_widget_unmap (sheet->sheet_entry); if (GTK_WIDGET_MAPPED (sheet->button)) gtk_widget_unmap (sheet->button); children = sheet->children; while (children) { GtkSheetChild *child = children->data; children = children->next; if (GTK_WIDGET_VISIBLE (child->widget) && GTK_WIDGET_MAPPED (child->widget)) { gtk_widget_unmap (child->widget); } } } } static void gtk_sheet_cell_draw_default (GtkSheet *sheet, gint row, gint col) { GdkGC *bg_gc; GtkSheetCellAttr attributes; GdkRectangle area; g_return_if_fail (sheet != NULL); /* bail now if we arn't drawable yet */ if (!GTK_WIDGET_DRAWABLE (sheet)) return; if (row < 0 || row > sheet->maxrow) return; if (col < 0 || col > sheet->maxcol) return; if (!sheet->column[col].is_visible) return; if (!sheet->row[row].is_visible) return; gtk_sheet_get_attributes(sheet, row, col, &attributes); /* select GC for background rectangle */ gdk_gc_set_foreground (sheet->fg_gc, &attributes.foreground); gdk_gc_set_foreground (sheet->bg_gc, &attributes.background); bg_gc = sheet->bg_gc; area.x=COLUMN_LEFT_XPIXEL(sheet,col); area.y=ROW_TOP_YPIXEL(sheet,row); area.width=sheet->column[col].width; area.height=sheet->row[row].height; gdk_draw_rectangle (sheet->pixmap, bg_gc, TRUE, area.x, area.y, area.width, area.height); gdk_gc_set_line_attributes (sheet->fg_gc, 1, 0, 0, 0); if(sheet->show_grid){ gdk_gc_set_foreground (sheet->bg_gc, &sheet->grid_color); gdk_draw_rectangle (sheet->pixmap, sheet->bg_gc, FALSE, area.x, area.y, area.width, area.height); } } static void gtk_sheet_cell_draw_border (GtkSheet *sheet, gint row, gint col, gint mask) { GtkSheetCellAttr attributes; GdkRectangle area; guint width; g_return_if_fail (sheet != NULL); /* bail now if we arn't drawable yet */ if (!GTK_WIDGET_DRAWABLE (sheet)) return; if (row < 0 || row > sheet->maxrow) return; if (col < 0 || col > sheet->maxcol) return; if (!sheet->column[col].is_visible) return; if (!sheet->row[row].is_visible) return; gtk_sheet_get_attributes(sheet, row, col, &attributes); /* select GC for background rectangle */ gdk_gc_set_foreground (sheet->fg_gc, &attributes.border.color); gdk_gc_set_foreground (sheet->bg_gc, &attributes.background); area.x=COLUMN_LEFT_XPIXEL(sheet,col); area.y=ROW_TOP_YPIXEL(sheet,row); area.width=sheet->column[col].width; area.height=sheet->row[row].height; width = attributes.border.width; gdk_gc_set_line_attributes(sheet->fg_gc, attributes.border.width, attributes.border.line_style, attributes.border.cap_style, attributes.border.join_style); if(width>0){ if(attributes.border.mask & GTK_SHEET_LEFT_BORDER & mask) gdk_draw_line(sheet->pixmap, sheet->fg_gc, area.x, area.y-width/2, area.x, area.y+area.height+width/2+1); if(attributes.border.mask & GTK_SHEET_RIGHT_BORDER & mask) gdk_draw_line(sheet->pixmap, sheet->fg_gc, area.x+area.width, area.y-width/2, area.x+area.width, area.y+area.height+width/2+1); if(attributes.border.mask & GTK_SHEET_TOP_BORDER & mask) gdk_draw_line(sheet->pixmap, sheet->fg_gc, area.x-width/2,area.y, area.x+area.width+width/2+1, area.y); if(attributes.border.mask & GTK_SHEET_BOTTOM_BORDER & mask) gdk_draw_line(sheet->pixmap, sheet->fg_gc, area.x-width/2, area.y+area.height, area.x+area.width+width/2+1, area.y+area.height); } } static void gtk_sheet_cell_draw_label (GtkSheet *sheet, gint row, gint col) { GdkRectangle area, clip_area; gint i; gint text_width, y; gint xoffset=0; gint size, sizel, sizer; GdkGC *fg_gc; GtkSheetCellAttr attributes; PangoLayout *layout; PangoRectangle rect; PangoRectangle logical_rect; PangoLayoutLine *line; PangoFontMetrics *metrics; PangoContext *context = gtk_widget_get_pango_context(GTK_WIDGET(sheet)); gint y_pos; char *label; g_return_if_fail (sheet != NULL); /* bail now if we aren't drawable yet */ if (!GTK_WIDGET_DRAWABLE (sheet)) return; if (row > sheet->maxallocrow) return; if (col > sheet->maxalloccol) return; if (!sheet->data[row]) return; if (!sheet->data[row][col]) return; if (!sheet->data[row][col]->text || strlen(sheet->data[row][col]->text)==0) return; if (row < 0 || row > sheet->maxrow) return; if (col < 0 || col > sheet->maxcol) return; if (!sheet->column[col].is_visible) return; if (!sheet->row[row].is_visible) return; label = sheet->data[row][col]->text; gtk_sheet_get_attributes(sheet, row, col, &attributes); /* select GC for background rectangle */ gdk_gc_set_foreground (sheet->fg_gc, &attributes.foreground); gdk_gc_set_foreground (sheet->bg_gc, &attributes.background); fg_gc = sheet->fg_gc; area.x=COLUMN_LEFT_XPIXEL(sheet,col); area.y=ROW_TOP_YPIXEL(sheet,row); area.width=sheet->column[col].width; area.height=sheet->row[row].height; clip_area = area; layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), label); pango_layout_set_font_description (layout, attributes.font_desc); pango_layout_get_pixel_extents (layout, NULL, &rect); line = pango_layout_get_lines (layout)->data; pango_layout_line_get_extents (line, NULL, &logical_rect); metrics = pango_context_get_metrics(context, attributes.font_desc, pango_context_get_language(context)); pango_font_metrics_unref(metrics); /* Align primarily for locale's ascent/descent */ logical_rect.height /= PANGO_SCALE; logical_rect.y /= PANGO_SCALE; y_pos = area.height - logical_rect.height; if (logical_rect.height > area.height) y_pos = (logical_rect.height - area.height - 2*CELLOFFSET) / 2; else if (y_pos < 0) y_pos = 0; else if (y_pos + logical_rect.height > area.height) y_pos = area.height - logical_rect.height; text_width = rect.width; y = area.y + y_pos - CELLOFFSET; switch(attributes.justification){ case GTK_JUSTIFY_RIGHT: size=area.width; area.x+=area.width; if(!gtk_sheet_clip_text(sheet)){ for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; if(size>=text_width+CELLOFFSET) break; size+=sheet->column[i].width; sheet->column[i].right_text_column = MAX(col, sheet->column[i].right_text_column); } area.width=size; } area.x-=size; xoffset+=area.width-text_width - 2 * CELLOFFSET - attributes.border.width/2; break; case GTK_JUSTIFY_CENTER: sizel=area.width/2; sizer=area.width/2; area.x+=area.width/2; if(!gtk_sheet_clip_text(sheet)){ for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; if(sizer>=text_width/2) break; sizer+=sheet->column[i].width; sheet->column[i].left_text_column = MIN(col, sheet->column[i].left_text_column); } for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; if(sizel>=text_width/2) break; sizel+=sheet->column[i].width; sheet->column[i].right_text_column = MAX(col, sheet->column[i].right_text_column); } size=MIN(sizel, sizer); } area.x-=sizel; xoffset+= sizel - text_width/2 - CELLOFFSET; area.width=sizel+sizer; break; case GTK_JUSTIFY_LEFT: default: size=area.width; if(!gtk_sheet_clip_text(sheet)){ for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; if(size>=text_width+CELLOFFSET) break; size+=sheet->column[i].width; sheet->column[i].left_text_column = MIN(col, sheet->column[i].left_text_column); } area.width=size; } xoffset += attributes.border.width/2; break; } if(!gtk_sheet_clip_text(sheet)) clip_area = area; gdk_gc_set_clip_rectangle(fg_gc, &clip_area); gdk_draw_layout (sheet->pixmap, fg_gc, area.x + xoffset + CELLOFFSET, y, layout); gdk_gc_set_clip_rectangle(fg_gc, NULL); g_object_unref(G_OBJECT(layout)); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, area.x, area.y, area.x, area.y, area.width, area.height); } static void gtk_sheet_range_draw(GtkSheet *sheet, const GtkSheetRange *range) { gint i,j; GtkSheetRange drawing_range; GdkRectangle area; g_return_if_fail(sheet != NULL); g_return_if_fail(GTK_SHEET(sheet)); if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet))) return; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; if(!GTK_WIDGET_MAPPED(GTK_WIDGET(sheet))) return; if(range == NULL) { drawing_range.row0=MIN_VISIBLE_ROW(sheet); drawing_range.col0=MIN_VISIBLE_COLUMN(sheet); drawing_range.rowi=MAX_VISIBLE_ROW(sheet); drawing_range.coli=MAX_VISIBLE_COLUMN(sheet); /* gdk_draw_rectangle (sheet->pixmap, GTK_WIDGET(sheet)->style->white_gc, TRUE, 0,0, sheet->sheet_window_width,sheet->sheet_window_height); */ } else { drawing_range.row0=MAX(range->row0, MIN_VISIBLE_ROW(sheet)); drawing_range.col0=MAX(range->col0, MIN_VISIBLE_COLUMN(sheet)); drawing_range.rowi=MIN(range->rowi, MAX_VISIBLE_ROW(sheet)); drawing_range.coli=MIN(range->coli, MAX_VISIBLE_COLUMN(sheet)); } if(drawing_range.coli == sheet->maxcol){ area.x=COLUMN_LEFT_XPIXEL(sheet,sheet->maxcol)+ sheet->column[sheet->maxcol].width+1; area.y=0; gdk_gc_set_foreground(sheet->fg_gc, &sheet->bg_color); gdk_draw_rectangle (sheet->pixmap, sheet->fg_gc, TRUE, area.x,area.y, sheet->sheet_window_width - area.x, sheet->sheet_window_height); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, area.x, area.y, area.x, area.y, sheet->sheet_window_width - area.x, sheet->sheet_window_height); } if(drawing_range.rowi == sheet->maxrow){ area.x=0; area.y=ROW_TOP_YPIXEL(sheet,sheet->maxrow)+sheet->row[sheet->maxrow].height+1; gdk_gc_set_foreground(sheet->fg_gc, &sheet->bg_color); gdk_draw_rectangle (sheet->pixmap, sheet->fg_gc, TRUE, area.x,area.y, sheet->sheet_window_width, sheet->sheet_window_height - area.y); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, area.x, area.y, area.x, area.y, sheet->sheet_window_width, sheet->sheet_window_height - area.y); } for(i=drawing_range.row0; i<=drawing_range.rowi; i++) for(j=drawing_range.col0; j<=drawing_range.coli; j++){ gtk_sheet_cell_draw_default(sheet, i, j); } for(i=drawing_range.row0; i<=drawing_range.rowi; i++) for(j=drawing_range.col0; j<=drawing_range.coli; j++){ gtk_sheet_cell_draw_border(sheet, i-1, j, GTK_SHEET_BOTTOM_BORDER); gtk_sheet_cell_draw_border(sheet, i+1, j, GTK_SHEET_TOP_BORDER); gtk_sheet_cell_draw_border(sheet, i, j-1, GTK_SHEET_RIGHT_BORDER); gtk_sheet_cell_draw_border(sheet, i, j+1, GTK_SHEET_LEFT_BORDER); gtk_sheet_cell_draw_border(sheet, i, j, 15); } for(i=drawing_range.row0; i<=drawing_range.rowi; i++) for(j=drawing_range.col0; j<=drawing_range.coli; j++) if(i<=sheet->maxallocrow && j<=sheet->maxalloccol && sheet->data[i] && sheet->data[i][j]) gtk_sheet_cell_draw_label (sheet, i, j); for(i=drawing_range.row0; i<=drawing_range.rowi; i++) for(j=sheet->column[drawing_range.col0].left_text_column; jmaxallocrow && j<=sheet->maxalloccol && sheet->data[i] && sheet->data[i][j]) gtk_sheet_cell_draw_label (sheet, i, j); for(i=drawing_range.row0; i<=drawing_range.rowi; i++) { for(j=drawing_range.coli+1; j<=sheet->column[drawing_range.coli].right_text_column; j++) if(i<=sheet->maxallocrow && j<=sheet->maxalloccol && sheet->data[i] && sheet->data[i][j]) gtk_sheet_cell_draw_label (sheet, i, j); } gtk_sheet_draw_backing_pixmap(sheet, drawing_range); if(sheet->state != GTK_SHEET_NORMAL && gtk_sheet_range_isvisible(sheet, sheet->range)) gtk_sheet_range_draw_selection(sheet, drawing_range); if(sheet->state == GTK_STATE_NORMAL && sheet->active_cell.row >= drawing_range.row0 && sheet->active_cell.row <= drawing_range.rowi && sheet->active_cell.col >= drawing_range.col0 && sheet->active_cell.col <= drawing_range.coli) gtk_sheet_show_active_cell(sheet); } static void gtk_sheet_range_draw_selection(GtkSheet *sheet, GtkSheetRange range) { GdkRectangle area; gint i,j; if(range.col0 > sheet->range.coli || range.coli < sheet->range.col0 || range.row0 > sheet->range.rowi || range.rowi < sheet->range.row0) return; if(!gtk_sheet_range_isvisible(sheet, range)) return; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; range.col0=MAX(sheet->range.col0, range.col0); range.coli=MIN(sheet->range.coli, range.coli); range.row0=MAX(sheet->range.row0, range.row0); range.rowi=MIN(sheet->range.rowi, range.rowi); range.col0=MAX(range.col0, MIN_VISIBLE_COLUMN(sheet)); range.coli=MIN(range.coli, MAX_VISIBLE_COLUMN(sheet)); range.row0=MAX(range.row0, MIN_VISIBLE_ROW(sheet)); range.rowi=MIN(range.rowi, MAX_VISIBLE_ROW(sheet)); for(i=range.row0; i<=range.rowi; i++){ for(j=range.col0; j<=range.coli; j++){ if(gtk_sheet_cell_get_state(sheet, i, j)==GTK_STATE_SELECTED && sheet->column[j].is_visible && sheet->row[i].is_visible){ row_button_set(sheet, i); column_button_set(sheet, j); area.x=COLUMN_LEFT_XPIXEL(sheet,j); area.y=ROW_TOP_YPIXEL(sheet,i); area.width=sheet->column[j].width; area.height=sheet->row[i].height; if(i==sheet->range.row0){ area.y=area.y+2; area.height=area.height-2; } if(i==sheet->range.rowi) area.height=area.height-3; if(j==sheet->range.col0){ area.x=area.x+2; area.width=area.width-2; } if(j==sheet->range.coli) area.width=area.width-3; if(i!=sheet->active_cell.row || j!=sheet->active_cell.col){ gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, area.x+1,area.y+1, area.width,area.height); } } } } gtk_sheet_draw_border(sheet, sheet->range); } static void gtk_sheet_draw_backing_pixmap(GtkSheet *sheet, GtkSheetRange range) { gint x,y,width,height; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; x=COLUMN_LEFT_XPIXEL(sheet,range.col0); y=ROW_TOP_YPIXEL(sheet, range.row0); width=COLUMN_LEFT_XPIXEL(sheet, range.coli)-x+sheet->column[range.coli].width; height=ROW_TOP_YPIXEL(sheet, range.rowi)-y+sheet->row[range.rowi].height; if(range.row0==sheet->range.row0){ y=y-5; height=height+5; } if(range.rowi==sheet->range.rowi) height=height+5; if(range.col0==sheet->range.col0){ x=x-5; width=width+5; } if(range.coli==sheet->range.coli) width=width+5; width=MIN(width, sheet->sheet_window_width-x); height=MIN(height, sheet->sheet_window_height-y); x--; y--; width+=2; height+=2; x = (sheet->row_titles_visible) ? MAX(x, sheet->row_title_area.width) : MAX(x, 0); y = (sheet->column_titles_visible) ? MAX(y, sheet->column_title_area.height) : MAX(y, 0); if(range.coli==sheet->maxcol) width=sheet->sheet_window_width-x; if(range.rowi==sheet->maxrow) height=sheet->sheet_window_height-y; gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x, y, x, y, width+1, height+1); } static GtkSheetCell * gtk_sheet_cell_new() { GtkSheetCell *cell; cell = g_new(GtkSheetCell, 1); cell->text = NULL; cell->link = NULL; cell->attributes = NULL; return cell; } void gtk_sheet_set_cell_text(GtkSheet *sheet, gint row, gint col, const gchar *text) { GtkSheetCellAttr attributes; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (col > sheet->maxcol || row > sheet->maxrow) return; if (col < 0 || row < 0) return; gtk_sheet_get_attributes(sheet, row, col, &attributes); gtk_sheet_set_cell(sheet, row, col, attributes.justification, text); } void gtk_sheet_set_cell(GtkSheet *sheet, gint row, gint col, GtkJustification justification, const gchar *text) { GtkSheetCell **cell; GtkSheetRange range; gint text_width; GtkSheetCellAttr attributes; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (col > sheet->maxcol || row > sheet->maxrow) return; if (col < 0 || row < 0) return; CheckBounds(sheet, row, col); cell=&sheet->data[row][col]; if(*cell==NULL) (*cell) = gtk_sheet_cell_new(); gtk_sheet_get_attributes(sheet, row, col, &attributes); (*cell)->row = row; (*cell)->col = col; attributes.justification = justification; gtk_sheet_set_cell_attributes(sheet, row, col, attributes); if((*cell)->text){ g_free((*cell)->text); (*cell)->text = NULL; } if(text) (*cell)->text=g_strdup(text); if(attributes.is_visible){ text_width = 0; if((*cell)->text && strlen((*cell)->text) > 0) { text_width = STRING_WIDTH(GTK_WIDGET(sheet), attributes.font_desc, (*cell)->text); } range.row0 = row; range.rowi = row; range.col0 = sheet->view.col0; range.coli = sheet->view.coli; if(gtk_sheet_autoresize(sheet) && text_width > sheet->column[col].width-2*CELLOFFSET-attributes.border.width){ gtk_sheet_set_column_width(sheet, col, text_width+2*CELLOFFSET+attributes.border.width); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_REDRAW_PENDING); } else if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CHANGED], row, col); } void gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint column) { GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (column > sheet->maxcol || row > sheet->maxrow) return; if (column > sheet->maxalloccol || row > sheet->maxallocrow) return; if (column < 0 || row < 0) return; range.row0 = row; range.rowi = row; range.col0 = sheet->view.col0; range.coli = sheet->view.coli; gtk_sheet_real_cell_clear(sheet, row, column, FALSE); if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_range_draw(sheet, &range); } } void gtk_sheet_cell_delete (GtkSheet *sheet, gint row, gint column) { GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (column > sheet->maxcol || row > sheet->maxrow) return; if (column > sheet->maxalloccol || row > sheet->maxallocrow) return; if (column < 0 || row < 0) return; range.row0 = row; range.rowi = row; range.col0 = sheet->view.col0; range.coli = sheet->view.coli; gtk_sheet_real_cell_clear(sheet, row, column, TRUE); if(!GTK_SHEET_IS_FROZEN(sheet)){ gtk_sheet_range_draw(sheet, &range); } } static void gtk_sheet_real_cell_clear (GtkSheet *sheet, gint row, gint column, gboolean delete) { gchar *text; if(row > sheet->maxallocrow || column > sheet->maxalloccol) return; if(!sheet->data[row]) return; if(!sheet->data[row][column]) return; text = gtk_sheet_cell_get_text(sheet, row, column); if(text){ g_free(sheet->data[row][column]->text); sheet->data[row][column]->text = NULL; if(GTK_IS_OBJECT(sheet) && G_OBJECT(sheet)->ref_count > 0) gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[CLEAR_CELL], row, column); } if(delete){ if(sheet->data[row][column]->attributes){ g_free(sheet->data[row][column]->attributes); sheet->data[row][column]->attributes = NULL; } sheet->data[row][column]->link = NULL; if(sheet->data[row][column]) g_free(sheet->data[row][column]); sheet->data[row][column] = NULL; } } void gtk_sheet_range_clear (GtkSheet *sheet, const GtkSheetRange *range) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); gtk_sheet_real_range_clear(sheet, range, FALSE); } void gtk_sheet_range_delete (GtkSheet *sheet, const GtkSheetRange *range) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); gtk_sheet_real_range_clear(sheet, range, TRUE); } static void gtk_sheet_real_range_clear (GtkSheet *sheet, const GtkSheetRange *range, gboolean delete) { gint i, j; GtkSheetRange clear; if(!range){ clear.row0=0; clear.rowi=sheet->maxallocrow; clear.col0=0; clear.coli=sheet->maxalloccol; }else clear=*range; clear.row0=MAX(clear.row0, 0); clear.col0=MAX(clear.col0, 0); clear.rowi=MIN(clear.rowi, sheet->maxallocrow); clear.coli=MIN(clear.coli, sheet->maxalloccol); for(i=clear.row0; i<=clear.rowi; i++) for(j=clear.col0; j<=clear.coli; j++){ gtk_sheet_real_cell_clear(sheet, i, j, delete); } gtk_sheet_range_draw(sheet, NULL); } gchar * gtk_sheet_cell_get_text (GtkSheet *sheet, gint row, gint col) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); if(col > sheet->maxcol || row > sheet->maxrow) return NULL; if(col < 0 || row < 0) return NULL; if(row > sheet->maxallocrow || col > sheet->maxalloccol) return NULL; if(!sheet->data[row]) return NULL; if(!sheet->data[row][col]) return NULL; if(!sheet->data[row][col]->text) return NULL; if(strlen(sheet->data[row][col]->text) == 0) return NULL; return (sheet->data[row][col]->text); } void gtk_sheet_link_cell(GtkSheet *sheet, gint row, gint col, gpointer link) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(col > sheet->maxcol || row > sheet->maxrow) return; if(col < 0 || row < 0) return; if(row > sheet->maxallocrow || col > sheet->maxalloccol || !sheet->data[row] || !sheet->data[row][col]) gtk_sheet_set_cell_text(sheet, row, col, ""); sheet->data[row][col]->link = link; } gpointer gtk_sheet_get_link(GtkSheet *sheet, gint row, gint col) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); if(col > sheet->maxcol || row > sheet->maxrow) return NULL; if(col < 0 || row < 0) return NULL; if (row > sheet->maxallocrow || col > sheet->maxalloccol) return NULL; if (!sheet->data[row]) return NULL; /* Added by Chris Howell */ if (!sheet->data[row][col]) return NULL; /* Added by Bob Lissner */ return(sheet->data[row][col]->link); } void gtk_sheet_remove_link(GtkSheet *sheet, gint row, gint col) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(col > sheet->maxcol || row > sheet->maxrow) return; if(col < 0 || row < 0) return; /* Fixed by Andreas Voegele */ if(row < sheet->maxallocrow && col < sheet->maxalloccol && sheet->data[row] && sheet->data[row][col] && sheet->data[row][col]->link) sheet->data[row][col]->link = NULL; } GtkStateType gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col) { gint state; GtkSheetRange *range; g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); if(col > sheet->maxcol || row > sheet->maxrow) return 0; if(col < 0 || row < 0) return 0; state = sheet->state; range = &sheet->range; switch (state){ case GTK_SHEET_NORMAL: return GTK_STATE_NORMAL; break; case GTK_SHEET_ROW_SELECTED: if(row>=range->row0 && row<=range->rowi) return GTK_STATE_SELECTED; break; case GTK_SHEET_COLUMN_SELECTED: if(col>=range->col0 && col<=range->coli) return GTK_STATE_SELECTED; break; case GTK_SHEET_RANGE_SELECTED: if(row >= range->row0 && row <= range->rowi && \ col >= range->col0 && col <= range->coli) return GTK_STATE_SELECTED; break; } return GTK_STATE_NORMAL; } gboolean gtk_sheet_get_pixel_info (GtkSheet * sheet, gint x, gint y, gint * row, gint * column) { gint trow, tcol; g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); /* bounds checking, return false if the user clicked * on a blank area */ trow = ROW_FROM_YPIXEL (sheet, y); if (trow > sheet->maxrow) return FALSE; *row = trow; tcol = COLUMN_FROM_XPIXEL (sheet, x); if (tcol > sheet->maxcol) return FALSE; *column = tcol; return TRUE; } gboolean gtk_sheet_get_cell_area (GtkSheet * sheet, gint row, gint column, GdkRectangle *area) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); if(row > sheet->maxrow || column > sheet->maxcol) return FALSE; area->x = (column == -1) ? 0 : (COLUMN_LEFT_XPIXEL(sheet, column) - (sheet->row_titles_visible ? sheet->row_title_area.width : 0)); area->y = (row == -1) ? 0 : (ROW_TOP_YPIXEL(sheet, row) - (sheet->column_titles_visible ? sheet->column_title_area.height : 0)); area->width= (column == -1) ? sheet->row_title_area.width : sheet->column[column].width; area->height= (row == -1) ? sheet->column_title_area.height : sheet->row[row].height; /* if(row < 0 || column < 0) return FALSE; area->x = COLUMN_LEFT_XPIXEL(sheet, column); area->y = ROW_TOP_YPIXEL(sheet, row); if(sheet->row_titles_visible) area->x -= sheet->row_title_area.width; if(sheet->column_titles_visible) area->y -= sheet->column_title_area.height; area->width=sheet->column[column].width; area->height=sheet->row[row].height; */ return TRUE; } gboolean gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column) { g_return_val_if_fail (sheet != NULL, 0); g_return_val_if_fail (GTK_IS_SHEET (sheet), 0); if(row < 0 || column < 0) return FALSE; if(row > sheet->maxrow || column > sheet->maxcol) return FALSE; if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) { if(!gtk_sheet_deactivate_cell(sheet)) return FALSE; } sheet->active_cell.row=row; sheet->active_cell.col=column; if(!gtk_sheet_activate_cell(sheet, row, column)) return FALSE; return TRUE; } void gtk_sheet_get_active_cell (GtkSheet *sheet, gint *row, gint *column) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); *row = sheet->active_cell.row; *column = sheet->active_cell.col; } static void gtk_sheet_entry_changed(GtkWidget *widget, gpointer data) { GtkSheet *sheet; gint row,col; const char *text; GtkJustification justification; GtkSheetCellAttr attributes; g_return_if_fail (data != NULL); g_return_if_fail (GTK_IS_SHEET (data)); sheet=GTK_SHEET(data); if(!GTK_WIDGET_VISIBLE(widget)) return; if(sheet->state != GTK_STATE_NORMAL) return; row=sheet->active_cell.row; col=sheet->active_cell.col; if(row<0 || col<0) return; sheet->active_cell.row=-1; sheet->active_cell.col=-1; text=gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet))); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IS_FROZEN); if(text && strlen(text)!=0){ gtk_sheet_get_attributes(sheet, row, col, &attributes); justification=attributes.justification; gtk_sheet_set_cell(sheet, row, col, justification, text); } else { /* Added by Matias Mutchinick */ if(row < sheet->maxallocrow && col < sheet->maxalloccol && sheet->data[row] && sheet->data[row][col] && sheet->data[row][col]->text) { g_free(sheet->data[row][col]->text); sheet->data[row][col]->text = NULL; } } if(sheet->freeze_count == 0) GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IS_FROZEN); sheet->active_cell.row=row;; sheet->active_cell.col=col; } static gboolean gtk_sheet_deactivate_cell(GtkSheet *sheet) { gboolean veto = TRUE; g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return FALSE; if(sheet->state != GTK_SHEET_NORMAL) return FALSE; _gtkextra_signal_emit(GTK_OBJECT(sheet),sheet_signals[DEACTIVATE], sheet->active_cell.row, sheet->active_cell.col, &veto); if(!veto) return FALSE; gtk_signal_disconnect_by_func(GTK_OBJECT(gtk_sheet_get_entry(sheet)), (GtkSignalFunc) gtk_sheet_entry_changed, GTK_OBJECT(GTK_WIDGET(sheet))); gtk_sheet_hide_active_cell(sheet); sheet->active_cell.row=-1; sheet->active_cell.col=-1; if(GTK_SHEET_REDRAW_PENDING(sheet)){ GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_REDRAW_PENDING); gtk_sheet_range_draw(sheet, NULL); } return TRUE; } static void gtk_sheet_hide_active_cell(GtkSheet *sheet) { const char *text; gint row,col; GtkJustification justification; GtkSheetCellAttr attributes; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; row=sheet->active_cell.row; col=sheet->active_cell.col; if(row < 0 || col < 0) return; if(sheet->freeze_count == 0) GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IS_FROZEN); text=gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet))); gtk_sheet_get_attributes(sheet, row, col, &attributes); justification=attributes.justification; if(text && strlen(text)!=0){ gtk_sheet_set_cell(sheet, row, col, justification, text); gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[SET_CELL], row, col); } else { gtk_sheet_cell_clear(sheet, row, col); } row=sheet->active_cell.row; col=sheet->active_cell.col; column_button_release(sheet, col); row_button_release(sheet, row); gtk_widget_unmap(sheet->sheet_entry); if(row != -1 && col != -1) gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, COLUMN_LEFT_XPIXEL(sheet,col)-1, ROW_TOP_YPIXEL(sheet,row)-1, COLUMN_LEFT_XPIXEL(sheet,col)-1, ROW_TOP_YPIXEL(sheet,row)-1, sheet->column[col].width+4, sheet->row[row].height+4); gtk_widget_grab_focus(GTK_WIDGET(sheet)); GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(sheet->sheet_entry), GTK_VISIBLE); } static gboolean gtk_sheet_activate_cell(GtkSheet *sheet, gint row, gint col) { gboolean veto = TRUE; g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); if(row < 0 || col < 0) return FALSE; if(row > sheet->maxrow || col > sheet->maxcol) return FALSE; /* _gtkextra_signal_emit(GTK_OBJECT(sheet),sheet_signals[ACTIVATE], row, col, &veto); if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return veto; */ if(!veto) return FALSE; if(sheet->state != GTK_SHEET_NORMAL){ sheet->state=GTK_SHEET_NORMAL; gtk_sheet_real_unselect_range(sheet, NULL); } sheet->range.row0=row; sheet->range.col0=col; sheet->range.rowi=row; sheet->range.coli=col; sheet->active_cell.row=row; sheet->active_cell.col=col; sheet->selection_cell.row=row; sheet->selection_cell.col=col; row_button_set(sheet, row); column_button_set(sheet, col); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); gtk_sheet_show_active_cell(sheet); gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(sheet)), "changed", (GtkSignalFunc)gtk_sheet_entry_changed, GTK_OBJECT(GTK_WIDGET(sheet))); _gtkextra_signal_emit(GTK_OBJECT(sheet),sheet_signals[ACTIVATE], row, col, &veto); return TRUE; } static void gtk_sheet_show_active_cell(GtkSheet *sheet) { GtkEntry *sheet_entry; GtkSheetCellAttr attributes; gchar *text = NULL; const gchar *old_text; GtkJustification justification; gint row, col; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); row = sheet->active_cell.row; col = sheet->active_cell.col; /* Don't show the active cell, if there is no active cell: */ if(!(row >= 0 && col >= 0)) /* e.g row or coll == -1. */ return; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; if(sheet->state != GTK_SHEET_NORMAL) return; if(GTK_SHEET_IN_SELECTION(sheet)) return; GTK_WIDGET_SET_FLAGS(GTK_WIDGET(sheet->sheet_entry), GTK_VISIBLE); sheet_entry = GTK_ENTRY(gtk_sheet_get_entry(sheet)); gtk_sheet_get_attributes(sheet, row, col, &attributes); justification = GTK_JUSTIFY_LEFT; if(gtk_sheet_justify_entry(sheet)) justification = attributes.justification; if(row <= sheet->maxallocrow && col <= sheet->maxalloccol) { if(sheet->data[row]) { if(sheet->data[row][col]) { GtkSheetCell *cell = sheet->data[row][col]; if(cell->text) text = g_strdup(cell->text); } } } if(!text) text = g_strdup(""); gtk_entry_set_visibility(GTK_ENTRY(sheet_entry), attributes.is_visible); if(gtk_sheet_locked(sheet) || !attributes.is_editable){ gtk_entry_set_editable(GTK_ENTRY(sheet_entry), FALSE); }else{ gtk_entry_set_editable(GTK_ENTRY(sheet_entry), TRUE); } /*** Added by John Gotts. Mar 25, 2005 *********/ old_text = gtk_entry_get_text(GTK_ENTRY(sheet_entry)); if (strcmp(old_text, text) != 0) { if(!GTK_IS_ITEM_ENTRY(sheet_entry)) gtk_entry_set_text(GTK_ENTRY(sheet_entry), text); else gtk_item_entry_set_text(GTK_ITEM_ENTRY(sheet_entry), text, justification); } gtk_sheet_entry_set_max_size(sheet); gtk_sheet_size_allocate_entry(sheet); gtk_widget_map(sheet->sheet_entry); gtk_sheet_draw_active_cell(sheet); gtk_widget_grab_focus(GTK_WIDGET(sheet_entry)); g_free(text); } static void gtk_sheet_draw_active_cell(GtkSheet *sheet) { gint row, col; if(!GTK_WIDGET_DRAWABLE(GTK_WIDGET(sheet))) return; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; row = sheet->active_cell.row; col = sheet->active_cell.col; if(row<0 || col<0) return; if(!gtk_sheet_cell_isvisible(sheet, row, col)) return; row_button_set(sheet, row); column_button_set(sheet, col); gtk_sheet_draw_backing_pixmap(sheet, sheet->range); gtk_sheet_draw_border(sheet, sheet->range); } static void gtk_sheet_make_backing_pixmap (GtkSheet *sheet, guint width, guint height) { gint pixmap_width, pixmap_height; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; if(width == 0 && height == 0){ width=sheet->sheet_window_width+80; height=sheet->sheet_window_height+80; } if (!sheet->pixmap) { /* allocate */ sheet->pixmap = gdk_pixmap_new (sheet->sheet_window, width, height, -1); if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, NULL); } else { /* reallocate if sizes don't match */ gdk_window_get_size (sheet->pixmap, &pixmap_width, &pixmap_height); if ((pixmap_width != width) || (pixmap_height != height)) { g_object_unref(G_OBJECT(sheet->pixmap)); sheet->pixmap = gdk_pixmap_new (sheet->sheet_window, width, height, -1); if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, NULL); } } } static void gtk_sheet_new_selection(GtkSheet *sheet, GtkSheetRange *range) { gint i,j, mask1, mask2; gint state, selected; gint x,y,width,height; GtkSheetRange new_range, aux_range; g_return_if_fail (sheet != NULL); if(range==NULL) range=&sheet->range; new_range=*range; range->row0=MIN(range->row0, sheet->range.row0); range->rowi=MAX(range->rowi, sheet->range.rowi); range->col0=MIN(range->col0, sheet->range.col0); range->coli=MAX(range->coli, sheet->range.coli); range->row0=MAX(range->row0, MIN_VISIBLE_ROW(sheet)); range->rowi=MIN(range->rowi, MAX_VISIBLE_ROW(sheet)); range->col0=MAX(range->col0, MIN_VISIBLE_COLUMN(sheet)); range->coli=MIN(range->coli, MAX_VISIBLE_COLUMN(sheet)); aux_range.row0=MAX(new_range.row0, MIN_VISIBLE_ROW(sheet)); aux_range.rowi=MIN(new_range.rowi, MAX_VISIBLE_ROW(sheet)); aux_range.col0=MAX(new_range.col0, MIN_VISIBLE_COLUMN(sheet)); aux_range.coli=MIN(new_range.coli, MAX_VISIBLE_COLUMN(sheet)); for(i=range->row0; i<=range->rowi; i++){ for(j=range->col0; j<=range->coli; j++){ state=gtk_sheet_cell_get_state(sheet, i, j); selected=(i<=new_range.rowi && i>=new_range.row0 && j<=new_range.coli && j>=new_range.col0) ? TRUE : FALSE; if(state==GTK_STATE_SELECTED && selected && sheet->column[j].is_visible && sheet->row[i].is_visible && (i==sheet->range.row0 || i==sheet->range.rowi || j==sheet->range.col0 || j==sheet->range.coli || i==new_range.row0 || i==new_range.rowi || j==new_range.col0 || j==new_range.coli)){ mask1 = i==sheet->range.row0 ? 1 : 0; mask1 = i==sheet->range.rowi ? mask1+2 : mask1; mask1 = j==sheet->range.col0 ? mask1+4 : mask1; mask1 = j==sheet->range.coli ? mask1+8 : mask1; mask2 = i==new_range.row0 ? 1 : 0; mask2 = i==new_range.rowi ? mask2+2 : mask2; mask2 = j==new_range.col0 ? mask2+4 : mask2; mask2 = j==new_range.coli ? mask2+8 : mask2; if(mask1 != mask2){ x=COLUMN_LEFT_XPIXEL(sheet,j); y=ROW_TOP_YPIXEL(sheet, i); width=COLUMN_LEFT_XPIXEL(sheet, j)-x+sheet->column[j].width; height=ROW_TOP_YPIXEL(sheet, i)-y+sheet->row[i].height; if(i==sheet->range.row0){ y=y-3; height=height+3; } if(i==sheet->range.rowi) height=height+3; if(j==sheet->range.col0){ x=x-3; width=width+3; } if(j==sheet->range.coli) width=width+3; gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x+1, y+1, x+1, y+1, width, height); if(i != sheet->active_cell.row || j != sheet->active_cell.col){ x=COLUMN_LEFT_XPIXEL(sheet,j); y=ROW_TOP_YPIXEL(sheet, i); width=COLUMN_LEFT_XPIXEL(sheet, j)-x+sheet->column[j].width; height=ROW_TOP_YPIXEL(sheet, i)-y+sheet->row[i].height; if(i==new_range.row0){ y=y+2; height=height-2; } if(i==new_range.rowi) height=height-3; if(j==new_range.col0){ x=x+2; width=width-2; } if(j==new_range.coli) width=width-3; gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x+1,y+1, width,height); } } } } } for(i=range->row0; i<=range->rowi; i++){ for(j=range->col0; j<=range->coli; j++){ state=gtk_sheet_cell_get_state(sheet, i, j); selected=(i<=new_range.rowi && i>=new_range.row0 && j<=new_range.coli && j>=new_range.col0) ? TRUE : FALSE; if(state==GTK_STATE_SELECTED && !selected && sheet->column[j].is_visible && sheet->row[i].is_visible){ x=COLUMN_LEFT_XPIXEL(sheet,j); y=ROW_TOP_YPIXEL(sheet, i); width=COLUMN_LEFT_XPIXEL(sheet, j)-x+sheet->column[j].width; height=ROW_TOP_YPIXEL(sheet, i)-y+sheet->row[i].height; if(i==sheet->range.row0){ y=y-3; height=height+3; } if(i==sheet->range.rowi) height=height+3; if(j==sheet->range.col0){ x=x-3; width=width+3; } if(j==sheet->range.coli) width=width+3; gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x+1, y+1, x+1, y+1, width, height); } } } for(i=range->row0; i<=range->rowi; i++){ for(j=range->col0; j<=range->coli; j++){ state=gtk_sheet_cell_get_state(sheet, i, j); selected=(i<=new_range.rowi && i>=new_range.row0 && j<=new_range.coli && j>=new_range.col0) ? TRUE : FALSE; if(state!=GTK_STATE_SELECTED && selected && sheet->column[j].is_visible && sheet->row[i].is_visible && (i != sheet->active_cell.row || j != sheet->active_cell.col)){ x=COLUMN_LEFT_XPIXEL(sheet,j); y=ROW_TOP_YPIXEL(sheet, i); width=COLUMN_LEFT_XPIXEL(sheet, j)-x+sheet->column[j].width; height=ROW_TOP_YPIXEL(sheet, i)-y+sheet->row[i].height; if(i==new_range.row0){ y=y+2; height=height-2; } if(i==new_range.rowi) height=height-3; if(j==new_range.col0){ x=x+2; width=width-2; } if(j==new_range.coli) width=width-3; gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x+1,y+1, width,height); } } } for(i=aux_range.row0; i<=aux_range.rowi; i++){ for(j=aux_range.col0; j<=aux_range.coli; j++){ if(sheet->column[j].is_visible && sheet->row[i].is_visible){ state=gtk_sheet_cell_get_state(sheet, i, j); mask1 = i==sheet->range.row0 ? 1 : 0; mask1 = i==sheet->range.rowi ? mask1+2 : mask1; mask1 = j==sheet->range.col0 ? mask1+4 : mask1; mask1 = j==sheet->range.coli ? mask1+8 : mask1; mask2 = i==new_range.row0 ? 1 : 0; mask2 = i==new_range.rowi ? mask2+2 : mask2; mask2 = j==new_range.col0 ? mask2+4 : mask2; mask2 = j==new_range.coli ? mask2+8 : mask2; if (mask2 != mask1 || state != GTK_STATE_SELECTED) { x=COLUMN_LEFT_XPIXEL(sheet,j); y=ROW_TOP_YPIXEL(sheet, i); width=sheet->column[j].width; height=sheet->row[i].height; if(mask2 & 1) gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x+1,y-1, width,3); if(mask2 & 2) gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x+1,y+height-1, width,3); if(mask2 & 4) gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x-1,y+1, 3,height); if(mask2 & 8) gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x+width-1,y+1, 3,height); } } } } *range=new_range; gtk_sheet_draw_corners(sheet, new_range); } static void gtk_sheet_draw_border (GtkSheet *sheet, GtkSheetRange new_range) { GdkRectangle area; gint i; gint x,y,width,height; x=COLUMN_LEFT_XPIXEL(sheet,new_range.col0); y=ROW_TOP_YPIXEL(sheet,new_range.row0); width=COLUMN_LEFT_XPIXEL(sheet,new_range.coli)-x+ sheet->column[new_range.coli].width; height=ROW_TOP_YPIXEL(sheet,new_range.rowi)-y+ sheet->row[new_range.rowi].height; area.x=COLUMN_LEFT_XPIXEL(sheet, MIN_VISIBLE_COLUMN(sheet)); area.y=ROW_TOP_YPIXEL(sheet, MIN_VISIBLE_ROW(sheet)); area.width=sheet->sheet_window_width; area.height=sheet->sheet_window_height; if(x<0) { width=width+x; x=0; } if(width>area.width) width=area.width+10; if(y<0) { height=height+y; y=0; } if(height>area.height) height=area.height+10; gdk_gc_set_clip_rectangle(sheet->xor_gc, &area); for(i=-1; i<=1; ++i) gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, FALSE, x+i,y+i, width-2*i,height-2*i); gdk_gc_set_clip_rectangle(sheet->xor_gc, NULL); gtk_sheet_draw_corners(sheet, new_range); } static void gtk_sheet_draw_corners(GtkSheet *sheet, GtkSheetRange range) { gint x,y; guint width = 1; if(gtk_sheet_cell_isvisible(sheet, range.row0, range.col0)){ x=COLUMN_LEFT_XPIXEL(sheet,range.col0); y=ROW_TOP_YPIXEL(sheet,range.row0); gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x-1, y-1, x-1, y-1, 3, 3); gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x-1,y-1, 3,3); } if(gtk_sheet_cell_isvisible(sheet, range.row0, range.coli) || sheet->state == GTK_SHEET_COLUMN_SELECTED){ x=COLUMN_LEFT_XPIXEL(sheet,range.coli)+ sheet->column[range.coli].width; y=ROW_TOP_YPIXEL(sheet,range.row0); width = 1; if(sheet->state == GTK_SHEET_COLUMN_SELECTED) { y = ROW_TOP_YPIXEL(sheet, sheet->view.row0)+3; width = 3; } gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x-width, y-width, x-width, y-width, 2*width+1, 2*width+1); gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x-width+width/2,y-width+width/2, 2+width,2+width); } if(gtk_sheet_cell_isvisible(sheet, range.rowi, range.col0) || sheet->state == GTK_SHEET_ROW_SELECTED){ x=COLUMN_LEFT_XPIXEL(sheet,range.col0); y=ROW_TOP_YPIXEL(sheet,range.rowi)+ sheet->row[range.rowi].height; width = 1; if(sheet->state == GTK_SHEET_ROW_SELECTED) { x = COLUMN_LEFT_XPIXEL(sheet, sheet->view.col0)+3; width = 3; } gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x-width, y-width, x-width, y-width, 2*width+1, 2*width+1); gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x-width+width/2,y-width+width/2, 2+width,2+width); } if(gtk_sheet_cell_isvisible(sheet, range.rowi, range.coli)){ x=COLUMN_LEFT_XPIXEL(sheet,range.coli)+ sheet->column[range.coli].width; y=ROW_TOP_YPIXEL(sheet,range.rowi)+ sheet->row[range.rowi].height; width = 1; if(sheet->state == GTK_SHEET_RANGE_SELECTED) width = 3; if(sheet->state == GTK_SHEET_NORMAL) width = 3; gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, x-width, y-width, x-width, y-width, 2*width+1, 2*width+1); gdk_draw_rectangle (sheet->sheet_window, sheet->xor_gc, TRUE, x-width+width/2,y-width+width/2, 2+width,2+width); } } static void gtk_sheet_real_select_range (GtkSheet * sheet, GtkSheetRange * range) { gint i; gint state; g_return_if_fail (sheet != NULL); if(range==NULL) range=&sheet->range; if(range->row0 < 0 || range->rowi < 0) return; if(range->col0 < 0 || range->coli < 0) return; state=sheet->state; if(state==GTK_SHEET_COLUMN_SELECTED || state==GTK_SHEET_RANGE_SELECTED){ for(i=sheet->range.col0; i< range->col0; i++) column_button_release(sheet, i); for(i=range->coli+1; i<= sheet->range.coli; i++) column_button_release(sheet, i); for(i=range->col0; i<=range->coli; i++){ column_button_set(sheet, i); } } if(state==GTK_SHEET_ROW_SELECTED || state==GTK_SHEET_RANGE_SELECTED){ for(i=sheet->range.row0; i< range->row0; i++) row_button_release(sheet, i); for(i=range->rowi+1; i<= sheet->range.rowi; i++) row_button_release(sheet, i); for(i=range->row0; i<=range->rowi; i++){ row_button_set(sheet, i); } } if(range->coli != sheet->range.coli || range->col0 != sheet->range.col0 || range->rowi != sheet->range.rowi || range->row0 != sheet->range.row0) { gtk_sheet_new_selection(sheet, range); sheet->range.col0=range->col0; sheet->range.coli=range->coli; sheet->range.row0=range->row0; sheet->range.rowi=range->rowi; } else { gtk_sheet_draw_backing_pixmap(sheet, sheet->range); gtk_sheet_range_draw_selection(sheet, sheet->range); } gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[SELECT_RANGE], range); } void gtk_sheet_select_range(GtkSheet * sheet, const GtkSheetRange *range) { g_return_if_fail (sheet != NULL); if(range==NULL) range=&sheet->range; if(range->row0 < 0 || range->rowi < 0) return; if(range->col0 < 0 || range->coli < 0) return; if(sheet->state != GTK_SHEET_NORMAL) gtk_sheet_real_unselect_range(sheet, NULL); else { gboolean veto; veto = gtk_sheet_deactivate_cell(sheet); if(!veto) return; } sheet->range.row0=range->row0; sheet->range.rowi=range->rowi; sheet->range.col0=range->col0; sheet->range.coli=range->coli; sheet->active_cell.row=range->row0; sheet->active_cell.col=range->col0; sheet->selection_cell.row=range->rowi; sheet->selection_cell.col=range->coli; sheet->state = GTK_SHEET_RANGE_SELECTED; gtk_sheet_real_select_range(sheet, NULL); } void gtk_sheet_unselect_range (GtkSheet * sheet) { gtk_sheet_real_unselect_range(sheet, NULL); sheet->state = GTK_STATE_NORMAL; gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); } static void gtk_sheet_real_unselect_range (GtkSheet * sheet, const GtkSheetRange *range) { gint i; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))); if(range==NULL){ range=&sheet->range; } if(range->row0 < 0 || range->rowi < 0) return; if(range->col0 < 0 || range->coli < 0) return; if (gtk_sheet_range_isvisible (sheet, *range)){ gtk_sheet_draw_backing_pixmap(sheet, *range); } for(i=range->col0; i<=range->coli; i++){ column_button_release(sheet, i); } for(i=range->row0; i<=range->rowi; i++){ row_button_release(sheet, i); } gtk_sheet_position_children(sheet); } static gint gtk_sheet_expose (GtkWidget * widget, GdkEventExpose * event) { GtkSheet *sheet; GtkSheetRange range; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); sheet = GTK_SHEET (widget); if (GTK_WIDGET_DRAWABLE (widget)) { range.row0=ROW_FROM_YPIXEL(sheet,event->area.y); range.col0=COLUMN_FROM_XPIXEL(sheet,event->area.x); range.rowi=ROW_FROM_YPIXEL(sheet,event->area.y+event->area.height); range.coli=COLUMN_FROM_XPIXEL(sheet,event->area.x+event->area.width); /* exposure events on the sheet */ if(event->window == sheet->row_title_window && sheet->row_titles_visible){ gint i; for(i = MIN_VISIBLE_ROW(sheet); i <= MAX_VISIBLE_ROW(sheet); i++) gtk_sheet_button_draw(sheet,i,-1); } if(event->window == sheet->column_title_window && sheet->column_titles_visible){ gint i; for(i = MIN_VISIBLE_COLUMN(sheet); i <= MAX_VISIBLE_COLUMN(sheet); i++) gtk_sheet_button_draw(sheet,-1,i); } if (event->window == sheet->sheet_window){ gtk_sheet_draw_backing_pixmap(sheet, range); if(sheet->state != GTK_SHEET_NORMAL){ if(gtk_sheet_range_isvisible(sheet, sheet->range)) gtk_sheet_draw_backing_pixmap(sheet, sheet->range); if(GTK_SHEET_IN_RESIZE(sheet) || GTK_SHEET_IN_DRAG(sheet)) gtk_sheet_draw_backing_pixmap(sheet, sheet->drag_range); if(gtk_sheet_range_isvisible(sheet, sheet->range)) gtk_sheet_range_draw_selection(sheet, sheet->range); if(GTK_SHEET_IN_RESIZE(sheet) || GTK_SHEET_IN_DRAG(sheet)) draw_xor_rectangle(sheet, sheet->drag_range); } if((!GTK_SHEET_IN_XDRAG(sheet)) && (!GTK_SHEET_IN_YDRAG(sheet))){ if(sheet->state == GTK_SHEET_NORMAL){ gtk_sheet_draw_active_cell(sheet); if(!GTK_SHEET_IN_SELECTION(sheet)) gtk_widget_queue_draw(sheet->sheet_entry); } } } } if(sheet->state != GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION(sheet)) gtk_widget_grab_focus(GTK_WIDGET(sheet)); (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); return FALSE; } static gint gtk_sheet_button_press (GtkWidget * widget, GdkEventButton * event) { GtkSheet *sheet; GdkModifierType mods; gint x, y, row, column; gboolean veto; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); /* if(event->type != GDK_BUTTON_PRESS) return TRUE; */ gdk_window_get_pointer(widget->window, NULL, NULL, &mods); if(!(mods & GDK_BUTTON1_MASK)) return TRUE; sheet = GTK_SHEET (widget); /* press on resize windows */ if (event->window == sheet->column_title_window && gtk_sheet_columns_resizable(sheet)) { gtk_widget_get_pointer (widget, &sheet->x_drag, NULL); if(POSSIBLE_XDRAG(sheet, sheet->x_drag, &sheet->drag_cell.col)){ guint req; if (event->type == GDK_2BUTTON_PRESS){ gtk_sheet_autoresize_column (sheet, sheet->drag_cell.col); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_XDRAG); return TRUE; } gtk_sheet_column_size_request(sheet, sheet->drag_cell.col, &req); GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_XDRAG); gdk_pointer_grab (sheet->column_title_window, FALSE, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); draw_xor_vline (sheet); return TRUE; } } if (event->window == sheet->row_title_window && gtk_sheet_rows_resizable(sheet)) { gtk_widget_get_pointer (widget, NULL, &sheet->y_drag); if(POSSIBLE_YDRAG(sheet, sheet->y_drag, &sheet->drag_cell.row)){ guint req; gtk_sheet_row_size_request(sheet, sheet->drag_cell.row, &req); GTK_SHEET_SET_FLAGS (sheet, GTK_SHEET_IN_YDRAG); gdk_pointer_grab (sheet->row_title_window, FALSE, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); draw_xor_hline (sheet); return TRUE; } } /* the sheet itself does not handle other than single click events */ if(event->type != GDK_BUTTON_PRESS) return FALSE; /* selections on the sheet */ if(event->window == sheet->sheet_window){ gtk_widget_get_pointer (widget, &x, &y); gtk_sheet_get_pixel_info (sheet, x, y, &row, &column); gdk_pointer_grab (sheet->sheet_window, FALSE, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); gtk_grab_add(GTK_WIDGET(sheet)); sheet->timer=gtk_timeout_add(TIMEOUT_SCROLL, gtk_sheet_scroll, sheet); gtk_widget_grab_focus(GTK_WIDGET(sheet)); if(sheet->selection_mode != GTK_SELECTION_SINGLE && sheet->cursor_drag->type==GDK_SIZING && !GTK_SHEET_IN_SELECTION(sheet) && !GTK_SHEET_IN_RESIZE(sheet)){ if(sheet->state==GTK_STATE_NORMAL) { row=sheet->active_cell.row; column=sheet->active_cell.col; if(!gtk_sheet_deactivate_cell(sheet)) return FALSE; sheet->active_cell.row=row; sheet->active_cell.col=column; sheet->drag_range=sheet->range; sheet->state=GTK_SHEET_RANGE_SELECTED; gtk_sheet_select_range(sheet, &sheet->drag_range); } sheet->x_drag=x; sheet->y_drag=y; if(row > sheet->range.rowi) row--; if(column > sheet->range.coli) column--; sheet->drag_cell.row = row; sheet->drag_cell.col = column; sheet->drag_range=sheet->range; draw_xor_rectangle(sheet, sheet->drag_range); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_RESIZE); } else if(sheet->cursor_drag->type==GDK_TOP_LEFT_ARROW && !GTK_SHEET_IN_SELECTION(sheet) && !GTK_SHEET_IN_DRAG(sheet)) { if(sheet->state==GTK_STATE_NORMAL) { row=sheet->active_cell.row; column=sheet->active_cell.col; if(!gtk_sheet_deactivate_cell(sheet)) return FALSE; sheet->active_cell.row=row; sheet->active_cell.col=column; sheet->drag_range=sheet->range; sheet->state=GTK_SHEET_RANGE_SELECTED; gtk_sheet_select_range(sheet, &sheet->drag_range); } sheet->x_drag=x; sheet->y_drag=y; if(row < sheet->range.row0) row++; if(row > sheet->range.rowi) row--; if(column < sheet->range.col0) column++; if(column > sheet->range.coli) column--; sheet->drag_cell.row=row; sheet->drag_cell.col=column; sheet->drag_range=sheet->range; draw_xor_rectangle(sheet, sheet->drag_range); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_DRAG); } else { gtk_sheet_click_cell(sheet, row, column, &veto); if(veto) GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); } } if(event->window == sheet->column_title_window){ gtk_widget_get_pointer (widget, &x, &y); column = COLUMN_FROM_XPIXEL(sheet, x); if(sheet->column[column].is_sensitive){; gtk_sheet_click_cell(sheet, -1, column, &veto); gtk_grab_add(GTK_WIDGET(sheet)); sheet->timer=gtk_timeout_add(TIMEOUT_SCROLL, gtk_sheet_scroll, sheet); gtk_widget_grab_focus(GTK_WIDGET(sheet)); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); } } if(event->window == sheet->row_title_window){ gtk_widget_get_pointer (widget, &x, &y); row = ROW_FROM_YPIXEL(sheet, y); if(sheet->row[row].is_sensitive){ gtk_sheet_click_cell(sheet, row, -1, &veto); gtk_grab_add(GTK_WIDGET(sheet)); sheet->timer=gtk_timeout_add(TIMEOUT_SCROLL, gtk_sheet_scroll, sheet); gtk_widget_grab_focus(GTK_WIDGET(sheet)); GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); } } return TRUE; } static gint gtk_sheet_scroll(gpointer data) { GtkSheet *sheet; gint x,y,row,column; gint move; sheet=GTK_SHEET(data); GDK_THREADS_ENTER(); gtk_widget_get_pointer (GTK_WIDGET(sheet), &x, &y); gtk_sheet_get_pixel_info (sheet, x, y, &row, &column); move=TRUE; if(GTK_SHEET_IN_SELECTION(sheet)) gtk_sheet_extend_selection(sheet, row, column); if(GTK_SHEET_IN_DRAG(sheet) || GTK_SHEET_IN_RESIZE(sheet)){ move=gtk_sheet_move_query(sheet, row, column); if(move) draw_xor_rectangle(sheet, sheet->drag_range); } GDK_THREADS_LEAVE(); return TRUE; } static void gtk_sheet_click_cell(GtkSheet *sheet, gint row, gint column, gboolean *veto) { *veto = TRUE; if(row > sheet->maxrow || column > sheet->maxcol){ *veto = FALSE; return; } if(column >= 0 && row >= 0) if(!sheet->column[column].is_visible || !sheet->row[row].is_visible) { *veto = FALSE; return; } _gtkextra_signal_emit(GTK_OBJECT(sheet), sheet_signals[TRAVERSE], sheet->active_cell.row, sheet->active_cell.col, &row, &column, veto); if(!*veto){ if(sheet->state == GTK_STATE_NORMAL) return; row = sheet->active_cell.row; column = sheet->active_cell.col; gtk_sheet_activate_cell(sheet, row, column); return; } if(row == -1 && column >= 0){ if(gtk_sheet_autoscroll(sheet)) gtk_sheet_move_query(sheet, row, column); gtk_sheet_select_column(sheet, column); return; } if(column == -1 && row >= 0){ if(gtk_sheet_autoscroll(sheet)) gtk_sheet_move_query(sheet, row, column); gtk_sheet_select_row(sheet, row); return; } if(row==-1 && column ==-1){ sheet->range.row0=0; sheet->range.col0=0; sheet->range.rowi=sheet->maxrow; sheet->range.coli=sheet->maxcol; sheet->active_cell.row=0; sheet->active_cell.col=0; gtk_sheet_select_range(sheet, NULL); return; } if(row!=-1 && column !=-1){ if(sheet->state != GTK_SHEET_NORMAL){ sheet->state = GTK_SHEET_NORMAL; gtk_sheet_real_unselect_range(sheet, NULL); } else { if(!gtk_sheet_deactivate_cell(sheet)){ *veto = FALSE; return; } } if(gtk_sheet_autoscroll(sheet)) gtk_sheet_move_query(sheet, row, column); sheet->active_cell.row=row; sheet->active_cell.col=column; sheet->selection_cell.row=row; sheet->selection_cell.col=column; sheet->range.row0=row; sheet->range.col0=column; sheet->range.rowi=row; sheet->range.coli=column; sheet->state=GTK_SHEET_NORMAL; GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); gtk_sheet_draw_active_cell(sheet); return; } gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); } static gint gtk_sheet_button_release (GtkWidget * widget, GdkEventButton * event) { GtkSheet *sheet; gint x,y; sheet=GTK_SHEET(widget); /* release on resize windows */ if (GTK_SHEET_IN_XDRAG (sheet)){ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_XDRAG); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); gtk_widget_get_pointer (widget, &x, NULL); gdk_pointer_ungrab (event->time); draw_xor_vline (sheet); gtk_sheet_set_column_width (sheet, sheet->drag_cell.col, new_column_width (sheet, sheet->drag_cell.col, &x)); sheet->old_hadjustment = -1.; gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); return TRUE; } if (GTK_SHEET_IN_YDRAG (sheet)){ GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_YDRAG); GTK_SHEET_UNSET_FLAGS (sheet, GTK_SHEET_IN_SELECTION); gtk_widget_get_pointer (widget, NULL, &y); gdk_pointer_ungrab (event->time); draw_xor_hline (sheet); gtk_sheet_set_row_height (sheet, sheet->drag_cell.row, new_row_height (sheet, sheet->drag_cell.row, &y)); sheet->old_vadjustment = -1.; gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); return TRUE; } if (GTK_SHEET_IN_DRAG(sheet)){ GtkSheetRange old_range; draw_xor_rectangle(sheet, sheet->drag_range); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_DRAG); gdk_pointer_ungrab (event->time); gtk_sheet_real_unselect_range(sheet, NULL); sheet->active_cell.row = sheet->active_cell.row + (sheet->drag_range.row0 - sheet->range.row0); sheet->active_cell.col = sheet->active_cell.col + (sheet->drag_range.col0 - sheet->range.col0); sheet->selection_cell.row = sheet->selection_cell.row + (sheet->drag_range.row0 - sheet->range.row0); sheet->selection_cell.col = sheet->selection_cell.col + (sheet->drag_range.col0 - sheet->range.col0); old_range=sheet->range; sheet->range=sheet->drag_range; sheet->drag_range=old_range; gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[MOVE_RANGE], &sheet->drag_range, &sheet->range); gtk_sheet_select_range(sheet, &sheet->range); } if (GTK_SHEET_IN_RESIZE(sheet)){ GtkSheetRange old_range; draw_xor_rectangle(sheet, sheet->drag_range); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_RESIZE); gdk_pointer_ungrab (event->time); gtk_sheet_real_unselect_range(sheet, NULL); sheet->active_cell.row = sheet->active_cell.row + (sheet->drag_range.row0 - sheet->range.row0); sheet->active_cell.col = sheet->active_cell.col + (sheet->drag_range.col0 - sheet->range.col0); if(sheet->drag_range.row0 < sheet->range.row0) sheet->selection_cell.row = sheet->drag_range.row0; if(sheet->drag_range.rowi >= sheet->range.rowi) sheet->selection_cell.row = sheet->drag_range.rowi; if(sheet->drag_range.col0 < sheet->range.col0) sheet->selection_cell.col = sheet->drag_range.col0; if(sheet->drag_range.coli >= sheet->range.coli) sheet->selection_cell.col = sheet->drag_range.coli; old_range = sheet->range; sheet->range = sheet->drag_range; sheet->drag_range = old_range; if(sheet->state==GTK_STATE_NORMAL) sheet->state=GTK_SHEET_RANGE_SELECTED; gtk_signal_emit(GTK_OBJECT(sheet),sheet_signals[RESIZE_RANGE], &sheet->drag_range, &sheet->range); gtk_sheet_select_range(sheet, &sheet->range); } if(sheet->state == GTK_SHEET_NORMAL && GTK_SHEET_IN_SELECTION(sheet)){ GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); gdk_pointer_ungrab (event->time); gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); } if(GTK_SHEET_IN_SELECTION) gdk_pointer_ungrab (event->time); if(sheet->timer) gtk_timeout_remove(sheet->timer); gtk_grab_remove(GTK_WIDGET(sheet)); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); return TRUE; } static gint gtk_sheet_motion (GtkWidget * widget, GdkEventMotion * event) { GtkSheet *sheet; GdkModifierType mods; GdkCursorType new_cursor; gint x, y, row, column; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); sheet = GTK_SHEET (widget); /* selections on the sheet */ x = event->x; y = event->y; if(event->window == sheet->column_title_window && gtk_sheet_columns_resizable(sheet)){ gtk_widget_get_pointer(widget, &x, &y); if(!GTK_SHEET_IN_SELECTION(sheet) && POSSIBLE_XDRAG(sheet, x, &column)){ new_cursor=GDK_SB_H_DOUBLE_ARROW; if(new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW); gdk_window_set_cursor(sheet->column_title_window,sheet->cursor_drag); } }else{ new_cursor=GDK_TOP_LEFT_ARROW; if(!GTK_SHEET_IN_XDRAG(sheet) && new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW); gdk_window_set_cursor(sheet->column_title_window,sheet->cursor_drag); } } } if(event->window == sheet->row_title_window && gtk_sheet_rows_resizable(sheet)){ gtk_widget_get_pointer(widget, &x, &y); if(!GTK_SHEET_IN_SELECTION(sheet) && POSSIBLE_YDRAG(sheet,y, &column)){ new_cursor=GDK_SB_V_DOUBLE_ARROW; if(new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW); gdk_window_set_cursor(sheet->row_title_window,sheet->cursor_drag); } }else{ new_cursor=GDK_TOP_LEFT_ARROW; if(!GTK_SHEET_IN_YDRAG(sheet) && new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW); gdk_window_set_cursor(sheet->row_title_window,sheet->cursor_drag); } } } new_cursor=GDK_PLUS; if(!POSSIBLE_DRAG(sheet,x,y,&row,&column) && !GTK_SHEET_IN_DRAG(sheet) && !POSSIBLE_RESIZE(sheet,x,y,&row,&column) && !GTK_SHEET_IN_RESIZE(sheet) && event->window == sheet->sheet_window && new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_PLUS); gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag); } new_cursor=GDK_TOP_LEFT_ARROW; if(!(POSSIBLE_RESIZE(sheet,x,y,&row,&column) || GTK_SHEET_IN_RESIZE(sheet)) && (POSSIBLE_DRAG(sheet, x,y,&row,&column) || GTK_SHEET_IN_DRAG(sheet)) && event->window == sheet->sheet_window && new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_TOP_LEFT_ARROW); gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag); } new_cursor=GDK_SIZING; if(!GTK_SHEET_IN_DRAG(sheet) && (POSSIBLE_RESIZE(sheet,x,y,&row,&column) || GTK_SHEET_IN_RESIZE(sheet)) && event->window == sheet->sheet_window && new_cursor != sheet->cursor_drag->type){ gdk_cursor_destroy(sheet->cursor_drag); sheet->cursor_drag=gdk_cursor_new(GDK_SIZING); gdk_window_set_cursor(sheet->sheet_window,sheet->cursor_drag); } gdk_window_get_pointer (widget->window, &x, &y, &mods); if(!(mods & GDK_BUTTON1_MASK)) return FALSE; if (GTK_SHEET_IN_XDRAG (sheet)){ if (event->is_hint || event->window != widget->window) gtk_widget_get_pointer (widget, &x, NULL); else x = event->x; new_column_width (sheet, sheet->drag_cell.col, &x); if (x != sheet->x_drag) { draw_xor_vline (sheet); sheet->x_drag = x; draw_xor_vline (sheet); } return TRUE; } if (GTK_SHEET_IN_YDRAG (sheet)){ if (event->is_hint || event->window != widget->window) gtk_widget_get_pointer (widget, NULL, &y); else y = event->y; new_row_height (sheet, sheet->drag_cell.row, &y); if (y != sheet->y_drag) { draw_xor_hline (sheet); sheet->y_drag = y; draw_xor_hline (sheet); } return TRUE; } if (GTK_SHEET_IN_DRAG(sheet)){ GtkSheetRange aux; column=COLUMN_FROM_XPIXEL(sheet,x)-sheet->drag_cell.col; row=ROW_FROM_YPIXEL(sheet,y)-sheet->drag_cell.row; if(sheet->state==GTK_SHEET_COLUMN_SELECTED) row=0; if(sheet->state==GTK_SHEET_ROW_SELECTED) column=0; sheet->x_drag=x; sheet->y_drag=y; aux=sheet->range; if(aux.row0+row >= 0 && aux.rowi+row <= sheet->maxrow && aux.col0+column >= 0 && aux.coli+column <= sheet->maxcol){ aux=sheet->drag_range; sheet->drag_range.row0=sheet->range.row0+row; sheet->drag_range.col0=sheet->range.col0+column; sheet->drag_range.rowi=sheet->range.rowi+row; sheet->drag_range.coli=sheet->range.coli+column; if(aux.row0 != sheet->drag_range.row0 || aux.col0 != sheet->drag_range.col0){ draw_xor_rectangle (sheet, aux); draw_xor_rectangle (sheet, sheet->drag_range); } } return TRUE; } if (GTK_SHEET_IN_RESIZE(sheet)){ GtkSheetRange aux; gint v_h, current_col, current_row, col_threshold, row_threshold; v_h=1; if(abs(x-COLUMN_LEFT_XPIXEL(sheet,sheet->drag_cell.col)) > abs(y-ROW_TOP_YPIXEL(sheet,sheet->drag_cell.row))) v_h=2; current_col = COLUMN_FROM_XPIXEL(sheet,x); current_row = ROW_FROM_YPIXEL(sheet,y); column = current_col-sheet->drag_cell.col; row = current_row-sheet->drag_cell.row; /*use half of column width resp. row height as threshold to expand selection*/ col_threshold = COLUMN_LEFT_XPIXEL(sheet,current_col)+gtk_sheet_column_width (sheet,current_col)/2; if (column > 0){ if (x < col_threshold) column-=1; } else if (column < 0){ if (x > col_threshold) column+=1; } row_threshold = ROW_TOP_YPIXEL(sheet,current_row)+gtk_sheet_row_height (sheet, current_row)/2; if (row > 0){ if(y < row_threshold) row-=1; } else if (row < 0){ if(y > row_threshold) row+=1; } if(sheet->state==GTK_SHEET_COLUMN_SELECTED) row=0; if(sheet->state==GTK_SHEET_ROW_SELECTED) column=0; sheet->x_drag=x; sheet->y_drag=y; aux=sheet->range; if(v_h==1) column=0; else row=0; if(aux.row0+row >= 0 && aux.rowi+row <= sheet->maxrow && aux.col0+column >= 0 && aux.coli+column <= sheet->maxcol){ aux=sheet->drag_range; sheet->drag_range=sheet->range; if(row<0) sheet->drag_range.row0=sheet->range.row0+row; if(row>0) sheet->drag_range.rowi=sheet->range.rowi+row; if(column<0) sheet->drag_range.col0=sheet->range.col0+column; if(column>0) sheet->drag_range.coli=sheet->range.coli+column; if(aux.row0 != sheet->drag_range.row0 || aux.rowi != sheet->drag_range.rowi || aux.col0 != sheet->drag_range.col0 || aux.coli != sheet->drag_range.coli){ draw_xor_rectangle (sheet, aux); draw_xor_rectangle (sheet, sheet->drag_range); } } return TRUE; } gtk_sheet_get_pixel_info (sheet, x, y, &row, &column); if(sheet->state==GTK_SHEET_NORMAL && row==sheet->active_cell.row && column==sheet->active_cell.col) return TRUE; if(GTK_SHEET_IN_SELECTION(sheet) && mods&GDK_BUTTON1_MASK) gtk_sheet_extend_selection(sheet, row, column); return TRUE; } static gint gtk_sheet_move_query(GtkSheet *sheet, gint row, gint column) { gint row_move, column_move; gfloat row_align, col_align; guint height, width; gint new_row = row; gint new_col = column; row_move=FALSE; column_move=FALSE; row_align=-1.; col_align=-1.; height = sheet->sheet_window_height; width = sheet->sheet_window_width; if(row>=MAX_VISIBLE_ROW(sheet) && sheet->state!=GTK_SHEET_COLUMN_SELECTED) { row_align = 1.; new_row = MIN(sheet->maxrow, row + 1); row_move = TRUE; if(MAX_VISIBLE_ROW(sheet) == sheet->maxrow && ROW_TOP_YPIXEL(sheet, sheet->maxrow) + sheet->row[sheet->maxrow].height < height){ row_move = FALSE; row_align = -1.; } } if(rowstate!=GTK_SHEET_COLUMN_SELECTED) { row_align= 0.; row_move = TRUE; } if(column>=MAX_VISIBLE_COLUMN(sheet) && sheet->state!=GTK_SHEET_ROW_SELECTED) { col_align = 1.; new_col = MIN(sheet->maxcol, column + 1); column_move = TRUE; if(MAX_VISIBLE_COLUMN(sheet) == sheet->maxcol && COLUMN_LEFT_XPIXEL(sheet, sheet->maxcol) + sheet->column[sheet->maxcol].width < width){ column_move = FALSE; col_align = -1.; } } if(columnstate!=GTK_SHEET_ROW_SELECTED) { col_align = 0.; column_move = TRUE; } if(row_move || column_move){ gtk_sheet_moveto(sheet, new_row, new_col, row_align, col_align); } return(row_move || column_move); } static void gtk_sheet_extend_selection(GtkSheet *sheet, gint row, gint column) { GtkSheetRange range; gint state; gint r,c; if(row == sheet->selection_cell.row && column == sheet->selection_cell.col) return; if(sheet->selection_mode == GTK_SELECTION_SINGLE) return; gtk_sheet_move_query(sheet, row, column); gtk_widget_grab_focus(GTK_WIDGET(sheet)); if(GTK_SHEET_IN_DRAG(sheet)) return; state=sheet->state; switch(sheet->state){ case GTK_SHEET_ROW_SELECTED: column = sheet->maxcol; break; case GTK_SHEET_COLUMN_SELECTED: row = sheet->maxrow; break; case GTK_SHEET_NORMAL: sheet->state=GTK_SHEET_RANGE_SELECTED; r=sheet->active_cell.row; c=sheet->active_cell.col; sheet->range.col0=c; sheet->range.row0=r; sheet->range.coli=c; sheet->range.rowi=r; gdk_draw_pixmap(sheet->sheet_window, GTK_WIDGET(sheet)->style->fg_gc[GTK_STATE_NORMAL], sheet->pixmap, COLUMN_LEFT_XPIXEL(sheet,c)-1, ROW_TOP_YPIXEL(sheet,r)-1, COLUMN_LEFT_XPIXEL(sheet,c)-1, ROW_TOP_YPIXEL(sheet,r)-1, sheet->column[c].width+4, sheet->row[r].height+4); gtk_sheet_range_draw_selection(sheet, sheet->range); case GTK_SHEET_RANGE_SELECTED: sheet->state=GTK_SHEET_RANGE_SELECTED; } sheet->selection_cell.row = row; sheet->selection_cell.col = column; range.col0=MIN(column,sheet->active_cell.col); range.coli=MAX(column,sheet->active_cell.col); range.row0=MIN(row,sheet->active_cell.row); range.rowi=MAX(row,sheet->active_cell.row); if(range.row0 != sheet->range.row0 || range.rowi != sheet->range.rowi || range.col0 != sheet->range.col0 || range.coli != sheet->range.coli || state==GTK_SHEET_NORMAL) gtk_sheet_real_select_range(sheet, &range); } static gint gtk_sheet_entry_key_press(GtkWidget *widget, GdkEventKey *key) { gboolean focus; gtk_signal_emit_by_name(GTK_OBJECT(widget), "key_press_event", key, &focus); return focus; } static gint gtk_sheet_key_press(GtkWidget *widget, GdkEventKey *key) { GtkSheet *sheet; gint row, col; gint state; gboolean extend_selection = FALSE; gboolean force_move = FALSE; gboolean in_selection = FALSE; gboolean veto = TRUE; gint scroll = 1; sheet = GTK_SHEET(widget); if(key->state & GDK_CONTROL_MASK || key->keyval==GDK_Control_L || key->keyval==GDK_Control_R) return FALSE; /* { if(key->keyval=='c' || key->keyval == 'C' && sheet->state != GTK_STATE_NORMAL) gtk_sheet_clip_range(sheet, sheet->range); if(key->keyval=='x' || key->keyval == 'X') gtk_sheet_unclip_range(sheet); return FALSE; } */ extend_selection = (key->state & GDK_SHIFT_MASK) || key->keyval==GDK_Shift_L || key->keyval==GDK_Shift_R; state=sheet->state; in_selection = GTK_SHEET_IN_SELECTION(sheet); GTK_SHEET_UNSET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); switch(key->keyval){ case GDK_Return: case GDK_KP_Enter: if(sheet->state == GTK_SHEET_NORMAL && !GTK_SHEET_IN_SELECTION(sheet)) gtk_signal_emit_stop_by_name(GTK_OBJECT(gtk_sheet_get_entry(sheet)), "key_press_event"); row = sheet->active_cell.row; col = sheet->active_cell.col; if(sheet->state == GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet)-1; if(sheet->state == GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet); if(row < sheet->maxrow){ row = row + scroll; while(!sheet->row[row].is_visible && rowmaxrow) row++; } gtk_sheet_click_cell(sheet, row, col, &veto); extend_selection = FALSE; break; case GDK_ISO_Left_Tab: row = sheet->active_cell.row; col = sheet->active_cell.col; if(sheet->state == GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet)-1; if(sheet->state == GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet); if(col > 0){ col = col - scroll; while(!sheet->column[col].is_visible && col>0) col--; col=MAX(0, col); } gtk_sheet_click_cell(sheet, row, col, &veto); extend_selection = FALSE; break; case GDK_Tab: row = sheet->active_cell.row; col = sheet->active_cell.col; if(sheet->state == GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet)-1; if(sheet->state == GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet); if(col < sheet->maxcol){ col = col + scroll; while(!sheet->column[col].is_visible && colmaxcol) col++; } gtk_sheet_click_cell(sheet, row, col, &veto); extend_selection = FALSE; break; /* case GDK_BackSpace: if(sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0){ if(sheet->active_cell.col > 0){ col = sheet->active_cell.col - scroll; row = sheet->active_cell.row; while(!sheet->column[col].is_visible && col > 0) col--; } } gtk_sheet_click_cell(sheet, row, col, &veto); extend_selection = FALSE; break; */ case GDK_Page_Up: scroll=MAX_VISIBLE_ROW(sheet)-MIN_VISIBLE_ROW(sheet)+1; case GDK_Up: if(extend_selection){ if(state==GTK_STATE_NORMAL){ row=sheet->active_cell.row; col=sheet->active_cell.col; gtk_sheet_click_cell(sheet, row, col, &veto); if(!veto) break; } if(sheet->selection_cell.row > 0){ row = sheet->selection_cell.row - scroll; while(!sheet->row[row].is_visible && row > 0) row--; row = MAX(0, row); gtk_sheet_extend_selection(sheet, row, sheet->selection_cell.col); } return TRUE; } col = sheet->active_cell.col; row = sheet->active_cell.row; if(state==GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet); if(state==GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet); row = row - scroll; while(!sheet->row[row].is_visible && row > 0) row--; row = MAX(0,row); gtk_sheet_click_cell(sheet, row, col, &veto); extend_selection = FALSE; break; case GDK_Page_Down: scroll=MAX_VISIBLE_ROW(sheet)-MIN_VISIBLE_ROW(sheet)+1; case GDK_Down: if(extend_selection){ if(state==GTK_STATE_NORMAL){ row=sheet->active_cell.row; col=sheet->active_cell.col; gtk_sheet_click_cell(sheet, row, col, &veto); if(!veto) break; } if(sheet->selection_cell.row < sheet->maxrow){ row = sheet->selection_cell.row + scroll; while(!sheet->row[row].is_visible && row < sheet->maxrow) row++; row = MIN(sheet->maxrow, row); gtk_sheet_extend_selection(sheet, row, sheet->selection_cell.col); } return TRUE; } col = sheet->active_cell.col; row = sheet->active_cell.row; if(sheet->active_cell.row < sheet->maxrow){ if(state==GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet)-1; if(state==GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet); row = row + scroll; while(!sheet->row[row].is_visible && row < sheet->maxrow) row++; row = MIN(sheet->maxrow, row); } gtk_sheet_click_cell(sheet, row, col, &veto); extend_selection = FALSE; break; case GDK_Right: if(extend_selection){ if(state==GTK_STATE_NORMAL){ row=sheet->active_cell.row; col=sheet->active_cell.col; gtk_sheet_click_cell(sheet, row, col, &veto); if(!veto) break; } if(sheet->selection_cell.col < sheet->maxcol){ col = sheet->selection_cell.col + 1; while(!sheet->column[col].is_visible && col < sheet->maxcol) col++; gtk_sheet_extend_selection(sheet, sheet->selection_cell.row, col); } return TRUE; } col = sheet->active_cell.col; row = sheet->active_cell.row; if(sheet->active_cell.col < sheet->maxcol){ col ++; if(state==GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet)-1; if(state==GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet); while(!sheet->column[col].is_visible && col < sheet->maxcol) col++; if(strlen(gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet)))) == 0 || force_move) { gtk_sheet_click_cell(sheet, row, col, &veto); } else return FALSE; } extend_selection = FALSE; break; case GDK_Left: if(extend_selection){ if(state==GTK_STATE_NORMAL){ row=sheet->active_cell.row; col=sheet->active_cell.col; gtk_sheet_click_cell(sheet, row, col, &veto); if(!veto) break; } if(sheet->selection_cell.col > 0){ col = sheet->selection_cell.col - 1; while(!sheet->column[col].is_visible && col > 0) col--; gtk_sheet_extend_selection(sheet, sheet->selection_cell.row, col); } return TRUE; } col = sheet->active_cell.col - 1; row = sheet->active_cell.row; if(state==GTK_SHEET_ROW_SELECTED) col = MIN_VISIBLE_COLUMN(sheet)-1; if(state==GTK_SHEET_COLUMN_SELECTED) row = MIN_VISIBLE_ROW(sheet); while(!sheet->column[col].is_visible && col > 0) col--; col = MAX(0, col); if(strlen(gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet)))) == 0 || force_move){ gtk_sheet_click_cell(sheet, row, col, &veto); } else return FALSE; extend_selection = FALSE; break; case GDK_Home: row=0; while(!sheet->row[row].is_visible && row < sheet->maxrow) row++; gtk_sheet_click_cell(sheet, row, sheet->active_cell.col, &veto); extend_selection = FALSE; break; case GDK_End: row=sheet->maxrow; while(!sheet->row[row].is_visible && row > 0) row--; gtk_sheet_click_cell(sheet, row, sheet->active_cell.col, &veto); extend_selection = FALSE; break; default: if(in_selection) { GTK_SHEET_SET_FLAGS(sheet, GTK_SHEET_IN_SELECTION); if(extend_selection) return TRUE; } if(state == GTK_SHEET_ROW_SELECTED) sheet->active_cell.col=MIN_VISIBLE_COLUMN(sheet); if(state == GTK_SHEET_COLUMN_SELECTED) sheet->active_cell.row=MIN_VISIBLE_ROW(sheet); return FALSE; } if(extend_selection) return TRUE; gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); return TRUE; } static void gtk_sheet_size_request (GtkWidget * widget, GtkRequisition * requisition) { GtkSheet *sheet; GList *children; GtkRequisition child_requisition; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); g_return_if_fail (requisition != NULL); sheet = GTK_SHEET (widget); requisition->width = 3*DEFAULT_COLUMN_WIDTH; requisition->height = 3*DEFAULT_ROW_HEIGHT(widget); /* compute the size of the column title area */ if(sheet->column_titles_visible) requisition->height += sheet->column_title_area.height; /* compute the size of the row title area */ if(sheet->row_titles_visible) requisition->width += sheet->row_title_area.width; sheet->view.row0=ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height+1); sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height-1); sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, sheet->row_title_area.width+1); sheet->view.coli=COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width); if(!sheet->column_titles_visible) sheet->view.row0=ROW_FROM_YPIXEL(sheet, 1); if(!sheet->row_titles_visible) sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, 1); children = sheet->children; while (children) { GtkSheetChild *child = children->data; children = children->next; gtk_widget_size_request(child->widget, &child_requisition); } } static void gtk_sheet_size_allocate (GtkWidget * widget, GtkAllocation * allocation) { GtkSheet *sheet; GtkAllocation sheet_allocation; gint border_width; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_SHEET (widget)); g_return_if_fail (allocation != NULL); sheet = GTK_SHEET (widget); widget->allocation = *allocation; border_width = GTK_CONTAINER(widget)->border_width; if (GTK_WIDGET_REALIZED (widget)) gdk_window_move_resize (widget->window, allocation->x + border_width, allocation->y + border_width, allocation->width - 2*border_width, allocation->height - 2*border_width); /* use internal allocation structure for all the math * because it's easier than always subtracting the container * border width */ sheet->internal_allocation.x = 0; sheet->internal_allocation.y = 0; sheet->internal_allocation.width = allocation->width - 2*border_width; sheet->internal_allocation.height = allocation->height - 2*border_width; sheet_allocation.x = 0; sheet_allocation.y = 0; sheet_allocation.width = allocation->width - 2*border_width; sheet_allocation.height = allocation->height - 2*border_width; sheet->sheet_window_width = sheet_allocation.width; sheet->sheet_window_height = sheet_allocation.height; if (GTK_WIDGET_REALIZED (widget)) gdk_window_move_resize (sheet->sheet_window, sheet_allocation.x, sheet_allocation.y, sheet_allocation.width, sheet_allocation.height); /* position the window which holds the column title buttons */ sheet->column_title_area.x = 0; sheet->column_title_area.y = 0; if(sheet->row_titles_visible) sheet->column_title_area.x = sheet->row_title_area.width; sheet->column_title_area.width = sheet_allocation.width - sheet->column_title_area.x; if(GTK_WIDGET_REALIZED(widget) && sheet->column_titles_visible) gdk_window_move_resize (sheet->column_title_window, sheet->column_title_area.x, sheet->column_title_area.y, sheet->column_title_area.width, sheet->column_title_area.height); sheet->sheet_window_width = sheet_allocation.width; sheet->sheet_window_height = sheet_allocation.height; /* column button allocation */ size_allocate_column_title_buttons (sheet); /* position the window which holds the row title buttons */ sheet->row_title_area.x = 0; sheet->row_title_area.y = 0; if(sheet->column_titles_visible) sheet->row_title_area.y = sheet->column_title_area.height; sheet->row_title_area.height = sheet_allocation.height - sheet->row_title_area.y; if(GTK_WIDGET_REALIZED(widget) && sheet->row_titles_visible) gdk_window_move_resize (sheet->row_title_window, sheet->row_title_area.x, sheet->row_title_area.y, sheet->row_title_area.width, sheet->row_title_area.height); /* row button allocation */ size_allocate_row_title_buttons (sheet); sheet->view.row0=ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height+1); sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height-1); sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, sheet->row_title_area.width+1); sheet->view.coli=COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width); if(!sheet->column_titles_visible) sheet->view.row0=ROW_FROM_YPIXEL(sheet, 1); if(!sheet->row_titles_visible) sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, 1); size_allocate_column_title_buttons(sheet); size_allocate_row_title_buttons(sheet); /* re-scale backing pixmap */ gtk_sheet_make_backing_pixmap(sheet, 0, 0); gtk_sheet_position_children(sheet); /* set the scrollbars adjustments */ adjust_scrollbars (sheet); } static void size_allocate_column_title_buttons (GtkSheet * sheet) { gint i; gint x,width; if (!sheet->column_titles_visible) return; if (!GTK_WIDGET_REALIZED (sheet)) return; width = sheet->sheet_window_width; x = 0; if(sheet->row_titles_visible) { width -= sheet->row_title_area.width; x = sheet->row_title_area.width; } if(sheet->column_title_area.width != width || sheet->column_title_area.x != x) { sheet->column_title_area.width = width; sheet->column_title_area.x = x; gdk_window_move_resize (sheet->column_title_window, sheet->column_title_area.x, sheet->column_title_area.y, sheet->column_title_area.width, sheet->column_title_area.height); } if(MAX_VISIBLE_COLUMN(sheet) == sheet->maxcol) gdk_window_clear_area (sheet->column_title_window, 0,0, sheet->column_title_area.width, sheet->column_title_area.height); if(!GTK_WIDGET_DRAWABLE(sheet)) return; for (i = MIN_VISIBLE_COLUMN(sheet); i <= MAX_VISIBLE_COLUMN(sheet); i++) gtk_sheet_button_draw(sheet,-1,i); } static void size_allocate_row_title_buttons (GtkSheet * sheet) { gint i; gint y, height; if (!sheet->row_titles_visible) return; if (!GTK_WIDGET_REALIZED (sheet)) return; height = sheet->sheet_window_height; y = 0; if(sheet->column_titles_visible) { height -= sheet->column_title_area.height; y = sheet->column_title_area.height; } if(sheet->row_title_area.height != height || sheet->row_title_area.y != y){ sheet->row_title_area.y = y; sheet->row_title_area.height = height; gdk_window_move_resize (sheet->row_title_window, sheet->row_title_area.x, sheet->row_title_area.y, sheet->row_title_area.width, sheet->row_title_area.height); } if(MAX_VISIBLE_ROW(sheet) == sheet->maxrow) gdk_window_clear_area (sheet->row_title_window, 0,0, sheet->row_title_area.width, sheet->row_title_area.height); if(!GTK_WIDGET_DRAWABLE(sheet)) return; for(i = MIN_VISIBLE_ROW(sheet); i <= MAX_VISIBLE_ROW(sheet); i++) gtk_sheet_button_draw(sheet,i,-1); } static void gtk_sheet_recalc_top_ypixels(GtkSheet *sheet, gint row) { gint i, cy; cy = sheet->column_title_area.height; if(!sheet->column_titles_visible) cy = 0; for(i=0; i<=sheet->maxrow; i++){ sheet->row[i].top_ypixel=cy; if(sheet->row[i].is_visible) cy+=sheet->row[i].height; } } static void gtk_sheet_recalc_left_xpixels(GtkSheet *sheet, gint column) { gint i, cx; cx = sheet->row_title_area.width; if(!sheet->row_titles_visible) cx = 0; for(i=0; i<=sheet->maxcol; i++){ sheet->column[i].left_xpixel=cx; if(sheet->column[i].is_visible) cx+=sheet->column[i].width; } } static void gtk_sheet_size_allocate_entry(GtkSheet *sheet) { GtkAllocation shentry_allocation; GtkSheetCellAttr attributes; GtkEntry *sheet_entry; GtkStyle *style = NULL, *previous_style = NULL; gint size, max_size, text_size, column_width; const gchar *text; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; if(!GTK_WIDGET_MAPPED(GTK_WIDGET(sheet))) return; sheet_entry = GTK_ENTRY(gtk_sheet_get_entry(sheet)); gtk_sheet_get_attributes(sheet, sheet->active_cell.row, sheet->active_cell.col, &attributes); if(GTK_WIDGET_REALIZED(sheet->sheet_entry)){ if(!GTK_WIDGET(sheet_entry)->style) gtk_widget_ensure_style(GTK_WIDGET(sheet_entry)); previous_style = GTK_WIDGET(sheet_entry)->style; style = gtk_style_copy(previous_style); style->bg[GTK_STATE_NORMAL] = attributes.background; style->fg[GTK_STATE_NORMAL] = attributes.foreground; style->text[GTK_STATE_NORMAL] = attributes.foreground; style->bg[GTK_STATE_ACTIVE] = attributes.background; style->fg[GTK_STATE_ACTIVE] = attributes.foreground; style->text[GTK_STATE_ACTIVE] = attributes.foreground; pango_font_description_free(style->font_desc); style->font_desc = pango_font_description_copy(attributes.font_desc); GTK_WIDGET(sheet_entry)->style = style; gtk_widget_size_request(sheet->sheet_entry, NULL); GTK_WIDGET(sheet_entry)->style = previous_style; if(style != previous_style){ if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){ style->bg[GTK_STATE_NORMAL] = previous_style->bg[GTK_STATE_NORMAL]; style->fg[GTK_STATE_NORMAL] = previous_style->fg[GTK_STATE_NORMAL]; style->bg[GTK_STATE_ACTIVE] = previous_style->bg[GTK_STATE_ACTIVE]; style->fg[GTK_STATE_ACTIVE] = previous_style->fg[GTK_STATE_ACTIVE]; } gtk_widget_set_style(GTK_WIDGET(sheet_entry), style); } } if(GTK_IS_ITEM_ENTRY(sheet_entry)) max_size = GTK_ITEM_ENTRY(sheet_entry)->text_max_size; else max_size = 0; text_size = 0; text = gtk_entry_get_text(GTK_ENTRY(sheet_entry)); if(text && strlen(text) > 0){ text_size = STRING_WIDTH(GTK_WIDGET(sheet), attributes.font_desc, text); } column_width=sheet->column[sheet->active_cell.col].width; size=MIN(text_size, max_size); size=MAX(size,column_width-2*CELLOFFSET); shentry_allocation.x = COLUMN_LEFT_XPIXEL(sheet,sheet->active_cell.col); shentry_allocation.y = ROW_TOP_YPIXEL(sheet,sheet->active_cell.row); shentry_allocation.width = column_width; shentry_allocation.height = sheet->row[sheet->active_cell.row].height; if(GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){ shentry_allocation.height -= 2*CELLOFFSET; shentry_allocation.y += CELLOFFSET; if(gtk_sheet_clip_text(sheet)) shentry_allocation.width = column_width - 2*CELLOFFSET; else shentry_allocation.width = size; switch(GTK_ITEM_ENTRY(sheet_entry)->justification){ case GTK_JUSTIFY_CENTER: shentry_allocation.x += (column_width)/2 - size/2; break; case GTK_JUSTIFY_RIGHT: shentry_allocation.x += column_width - size - CELLOFFSET; break; case GTK_JUSTIFY_LEFT: case GTK_JUSTIFY_FILL: shentry_allocation.x += CELLOFFSET; break; } } if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry)){ shentry_allocation.x += 2; shentry_allocation.y += 2; shentry_allocation.width -= MIN(shentry_allocation.width, 3); shentry_allocation.height -= MIN(shentry_allocation.height, 3); } gtk_widget_size_allocate(sheet->sheet_entry, &shentry_allocation); if(previous_style == style) gtk_style_unref(previous_style); } static void gtk_sheet_entry_set_max_size(GtkSheet *sheet) { gint i; gint size=0; gint sizel=0, sizer=0; gint row,col; GtkJustification justification; row=sheet->active_cell.row; col=sheet->active_cell.col; if(!GTK_IS_ITEM_ENTRY(sheet->sheet_entry) || gtk_sheet_clip_text(sheet)) return; justification = GTK_ITEM_ENTRY(sheet->sheet_entry)->justification; switch(justification){ case GTK_JUSTIFY_FILL: case GTK_JUSTIFY_LEFT: for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; size+=sheet->column[i].width; } size = MIN(size, sheet->sheet_window_width - COLUMN_LEFT_XPIXEL(sheet, col)); break; case GTK_JUSTIFY_RIGHT: for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; size+=sheet->column[i].width; } break; case GTK_JUSTIFY_CENTER: for(i=col+1; i<=MAX_VISIBLE_COLUMN(sheet); i++){ /* if(gtk_sheet_cell_get_text(sheet, row, i)) break; */ sizer+=sheet->column[i].width; } for(i=col-1; i>=MIN_VISIBLE_COLUMN(sheet); i--){ if(gtk_sheet_cell_get_text(sheet, row, i)) break; sizel+=sheet->column[i].width; } size=2*MIN(sizel, sizer); break; } if(size!=0) size+=sheet->column[col].width; GTK_ITEM_ENTRY(sheet->sheet_entry)->text_max_size=size; } static void create_sheet_entry(GtkSheet *sheet) { GtkWidget *parent; GtkWidget *entry; gint found_entry = FALSE; if(sheet->sheet_entry){ /* avoids warnings */ gtk_widget_ref(sheet->sheet_entry); gtk_widget_unparent(sheet->sheet_entry); gtk_widget_destroy(sheet->sheet_entry); } if(sheet->entry_type){ if(!g_type_is_a (sheet->entry_type, GTK_TYPE_ENTRY)){ parent = GTK_WIDGET(gtk_type_new(sheet->entry_type)); sheet->sheet_entry = parent; entry = gtk_sheet_get_entry (sheet); if(GTK_IS_ENTRY(entry)) found_entry = TRUE; } else { parent = GTK_WIDGET(gtk_type_new(sheet->entry_type)); entry = parent; found_entry = TRUE; } if(!found_entry){ g_warning ("Entry type must be GtkEntry subclass, using default"); entry = gtk_item_entry_new(); sheet->sheet_entry = entry; } else { sheet->sheet_entry = parent; } } else { entry = gtk_item_entry_new(); sheet->sheet_entry = entry; } gtk_widget_size_request(sheet->sheet_entry, NULL); if(GTK_WIDGET_REALIZED(sheet)) { gtk_widget_set_parent_window (sheet->sheet_entry, sheet->sheet_window); gtk_widget_set_parent(sheet->sheet_entry, GTK_WIDGET(sheet)); gtk_widget_realize(sheet->sheet_entry); } gtk_signal_connect_object(GTK_OBJECT(entry),"key_press_event", (GtkSignalFunc) gtk_sheet_entry_key_press, GTK_OBJECT(sheet)); gtk_widget_show (sheet->sheet_entry); } GtkWidget * gtk_sheet_get_entry(GtkSheet *sheet) { GtkWidget *parent; GtkWidget *entry = NULL; GtkTableChild *table_child; GtkBoxChild *box_child; GList *children = NULL; g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); g_return_val_if_fail (sheet->sheet_entry != NULL, NULL); if(GTK_IS_ENTRY(sheet->sheet_entry)) return (sheet->sheet_entry); parent = GTK_WIDGET(sheet->sheet_entry); if(GTK_IS_TABLE(parent)) children = GTK_TABLE(parent)->children; if(GTK_IS_BOX(parent)) children = GTK_BOX(parent)->children; if(!children) return NULL; while(children){ if(GTK_IS_TABLE(parent)) { table_child = children->data; entry = table_child->widget; } if(GTK_IS_BOX(parent)){ box_child = children->data; entry = box_child->widget; } if(GTK_IS_ENTRY(entry)) break; children = children->next; } if(!GTK_IS_ENTRY(entry)) return NULL; return (entry); } GtkWidget * gtk_sheet_get_entry_widget(GtkSheet *sheet) { g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GTK_IS_SHEET (sheet), NULL); g_return_val_if_fail (sheet->sheet_entry != NULL, NULL); return (sheet->sheet_entry); } /* BUTTONS */ static void row_button_set (GtkSheet *sheet, gint row) { if(sheet->row[row].button.state == GTK_STATE_ACTIVE) return; sheet->row[row].button.state = GTK_STATE_ACTIVE; gtk_sheet_button_draw(sheet, row, -1); } static void column_button_set (GtkSheet *sheet, gint column) { if(sheet->column[column].button.state == GTK_STATE_ACTIVE) return; sheet->column[column].button.state = GTK_STATE_ACTIVE; gtk_sheet_button_draw(sheet, -1, column); } static void row_button_release (GtkSheet *sheet, gint row) { if(sheet->row[row].button.state == GTK_STATE_NORMAL) return; sheet->row[row].button.state = GTK_STATE_NORMAL; gtk_sheet_button_draw(sheet, row, -1); } static void column_button_release (GtkSheet *sheet, gint column) { if(sheet->column[column].button.state == GTK_STATE_NORMAL) return; sheet->column[column].button.state = GTK_STATE_NORMAL; gtk_sheet_button_draw(sheet, -1, column); } static void gtk_sheet_button_draw (GtkSheet *sheet, gint row, gint column) { GdkWindow *window = NULL; GtkShadowType shadow_type; guint width = 0, height = 0; gint x = 0, y = 0; gint index = 0; gint text_width = 0, text_height = 0; GtkSheetButton *button = NULL; GtkSheetChild *child = NULL; GdkRectangle allocation; gboolean is_sensitive = FALSE; gint state = 0; gint len = 0; PangoAlignment align = PANGO_ALIGN_LEFT; gboolean rtl; rtl = gtk_widget_get_direction(GTK_WIDGET(sheet)) == GTK_TEXT_DIR_RTL; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) return; if(row >= 0 && !sheet->row[row].is_visible) return; if(column >= 0 && !sheet->column[column].is_visible) return; if(row >= 0 && !sheet->row_titles_visible) return; if(column >= 0 && !sheet->column_titles_visible) return; if(column>=0 && column =0 && column >MAX_VISIBLE_COLUMN(sheet)) return; if(row>=0 && row =0 && row >MAX_VISIBLE_ROW(sheet)) return; if( (row == -1) && (column == -1) ) return; if(row==-1){ window=sheet->column_title_window; button=&sheet->column[column].button; index=column; x = COLUMN_LEFT_XPIXEL(sheet, column)+CELL_SPACING; if(sheet->row_titles_visible) x -= sheet->row_title_area.width; y = 0; width = sheet->column[column].width; height = sheet->column_title_area.height; is_sensitive=sheet->column[column].is_sensitive; } else if(column==-1){ window=sheet->row_title_window; button=&sheet->row[row].button; index=row; x = 0; y = ROW_TOP_YPIXEL(sheet, row)+CELL_SPACING; if(sheet->column_titles_visible) y-=sheet->column_title_area.height; width = sheet->row_title_area.width; height = sheet->row[row].height; is_sensitive=sheet->row[row].is_sensitive; } allocation.x = x; allocation.y = y; allocation.width = width; allocation.height = height; gdk_window_clear_area (window, x, y, width, height); gtk_paint_box (sheet->button->style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, &allocation, GTK_WIDGET(sheet->button), "buttondefault", x, y, width, height); state = button->state; if(!is_sensitive) state=GTK_STATE_INSENSITIVE; if (state == GTK_STATE_ACTIVE) shadow_type = GTK_SHADOW_IN; else shadow_type = GTK_SHADOW_OUT; if(state != GTK_STATE_NORMAL && state != GTK_STATE_INSENSITIVE) gtk_paint_box (sheet->button->style, window, button->state, shadow_type, &allocation, GTK_WIDGET(sheet->button), "button", x, y, width, height); if(button->label_visible){ text_height=DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet))-2*CELLOFFSET; gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->fg_gc[button->state], &allocation); gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->white_gc, &allocation); /* y += DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet))/2 + sheet->button->style->ythickness + DEFAULT_FONT_DESCENT(GTK_WIDGET(sheet)); */ y += 2*sheet->button->style->ythickness; if(button->label && strlen(button->label)>0){ PangoLayout *layout = NULL; gint real_x = x, real_y = y; gchar *words=button->label; gchar *line = g_new(gchar, 1); line[0]='\0'; while(words && *words != '\0'){ if(*words != '\n'){ len=strlen(line); line=g_realloc(line, len+2); line[len]=*words; line[len+1]='\0'; } if(*words == '\n' || *(words+1) == '\0'){ text_width = STRING_WIDTH(GTK_WIDGET(sheet), GTK_WIDGET(sheet)->style->font_desc, line); layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), line); switch(button->justification){ case GTK_JUSTIFY_LEFT: real_x = x + CELLOFFSET; align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; break; case GTK_JUSTIFY_RIGHT: real_x = x + width - text_width - CELLOFFSET; align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT; break; case GTK_JUSTIFY_CENTER: default: real_x = x + (width - text_width)/2; align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; pango_layout_set_justify (layout, TRUE); } pango_layout_set_alignment (layout, align); gtk_paint_layout (GTK_WIDGET(sheet)->style, window, state, FALSE, &allocation, GTK_WIDGET(sheet), "label", real_x, real_y, layout); g_object_unref(G_OBJECT(layout)); real_y += text_height + 2; g_free(line); line = g_new(gchar, 1); line[0]='\0'; } words++; } g_free(line); }else{ PangoLayout *layout = NULL; gint real_x = x, real_y = y; gchar *label; label = g_strdup_printf("%d",index); text_width = STRING_WIDTH(GTK_WIDGET(sheet), GTK_WIDGET(sheet)->style->font_desc, label); layout = gtk_widget_create_pango_layout (GTK_WIDGET(sheet), label); switch(button->justification){ case GTK_JUSTIFY_LEFT: real_x = x + CELLOFFSET; align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; break; case GTK_JUSTIFY_RIGHT: real_x = x + width - text_width - CELLOFFSET; align = rtl ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT; break; case GTK_JUSTIFY_CENTER: default: real_x = x + (width - text_width)/2; align = rtl ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT; pango_layout_set_justify (layout, TRUE); } pango_layout_set_alignment (layout, align); gtk_paint_layout (GTK_WIDGET(sheet)->style, window, state, FALSE, &allocation, GTK_WIDGET(sheet), "label", real_x, real_y, layout); g_object_unref(G_OBJECT(layout)); g_free(label); } gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->fg_gc[button->state], NULL); gdk_gc_set_clip_rectangle(GTK_WIDGET(sheet)->style->white_gc, NULL); } if((child = button->child) && (child->widget)){ child->x = allocation.x; child->y = allocation.y; child->x += (width - child->widget->requisition.width) / 2; child->y += (height - child->widget->requisition.height) / 2; allocation.x = child->x; allocation.y = child->y; allocation.width = child->widget->requisition.width; allocation.height = child->widget->requisition.height; x = child->x; y = child->y; gtk_widget_set_state(child->widget, button->state); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && GTK_WIDGET_MAPPED(child->widget)) { gtk_widget_size_allocate(child->widget, &allocation); gtk_widget_queue_draw(child->widget); } } } /* SCROLLBARS * * functions: * adjust_scrollbars * vadjustment_changed * hadjustment_changed * vadjustment_value_changed * hadjustment_value_changed */ static void adjust_scrollbars (GtkSheet * sheet) { if(sheet->vadjustment){ sheet->vadjustment->page_size = sheet->sheet_window_height; sheet->vadjustment->page_increment = sheet->sheet_window_height / 2; sheet->vadjustment->step_increment = DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet)); sheet->vadjustment->lower = 0; sheet->vadjustment->upper = SHEET_HEIGHT (sheet) + 80; /* if (sheet->sheet_window_height - sheet->voffset > SHEET_HEIGHT (sheet)) { sheet->vadjustment->value = MAX(0, SHEET_HEIGHT (sheet) - sheet->sheet_window_height); gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); } */ gtk_signal_emit_by_name (GTK_OBJECT(sheet->vadjustment), "changed"); } if(sheet->hadjustment){ sheet->hadjustment->page_size = sheet->sheet_window_width; sheet->hadjustment->page_increment = sheet->sheet_window_width / 2; sheet->hadjustment->step_increment = DEFAULT_COLUMN_WIDTH; sheet->hadjustment->lower = 0; sheet->hadjustment->upper = SHEET_WIDTH (sheet)+ 80; /* if (sheet->sheet_window_width - sheet->hoffset > SHEET_WIDTH (sheet)) { sheet->hadjustment->value = MAX(0, SHEET_WIDTH (sheet) - sheet->sheet_window_width); gtk_signal_emit_by_name (GTK_OBJECT(sheet->hadjustment), "value_changed"); } */ gtk_signal_emit_by_name (GTK_OBJECT(sheet->hadjustment), "changed"); } /* if(GTK_WIDGET_REALIZED(sheet)) { if(sheet->row_titles_visible){ size_allocate_row_title_buttons(sheet); gdk_window_show(sheet->row_title_window); } if(sheet->column_titles_visible){ size_allocate_column_title_buttons(sheet); gdk_window_show(sheet->column_title_window); } gtk_sheet_range_draw(sheet, NULL); } */ } static void vadjustment_changed (GtkAdjustment * adjustment, gpointer data) { g_return_if_fail (adjustment != NULL); g_return_if_fail (data != NULL); } static void hadjustment_changed (GtkAdjustment * adjustment, gpointer data) { g_return_if_fail (adjustment != NULL); g_return_if_fail (data != NULL); } static void vadjustment_value_changed (GtkAdjustment * adjustment, gpointer data) { GtkSheet *sheet; gint value; gint i; gint row, new_row; gint y=0; g_return_if_fail (adjustment != NULL); g_return_if_fail (data != NULL); g_return_if_fail (GTK_IS_SHEET (data)); sheet = GTK_SHEET (data); if(GTK_SHEET_IS_FROZEN(sheet)) return; row=ROW_FROM_YPIXEL(sheet,sheet->column_title_area.height + CELL_SPACING); if(!sheet->column_titles_visible) row=ROW_FROM_YPIXEL(sheet,CELL_SPACING); for(i=0; i<= sheet->maxrow; i++){ if(sheet->row[i].is_visible) y+=sheet->row[i].height; if(y > adjustment->value) break; } y-=sheet->row[i].height; new_row=i; if (adjustment->value > sheet->old_vadjustment && sheet->old_vadjustment > 0. && sheet->row[i].height > sheet->vadjustment->step_increment){ /* This avoids embarrassing twitching */ if(row == new_row && row != sheet->maxrow && adjustment->value - sheet->old_vadjustment >= sheet->vadjustment->step_increment && new_row + 1 != MIN_VISIBLE_ROW(sheet)){ new_row+=1; y=y+sheet->row[row].height; } } /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */ if(sheet->old_vadjustment >= 0. && row == new_row){ sheet->old_vadjustment = sheet->vadjustment->value; return; } sheet->old_vadjustment = sheet->vadjustment->value; adjustment->value=y; if(new_row == 0){ sheet->vadjustment->step_increment= sheet->row[0].height; }else{ sheet->vadjustment->step_increment= MIN(sheet->row[new_row].height, sheet->row[new_row-1].height); } sheet->vadjustment->value=adjustment->value; value = adjustment->value; sheet->voffset = -value; sheet->view.row0=ROW_FROM_YPIXEL(sheet, sheet->column_title_area.height+1); sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height-1); if(!sheet->column_titles_visible) sheet->view.row0=ROW_FROM_YPIXEL(sheet, 1); if(GTK_WIDGET_REALIZED(sheet->sheet_entry) && sheet->state == GTK_SHEET_NORMAL && sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 && !gtk_sheet_cell_isvisible(sheet, sheet->active_cell.row, sheet->active_cell.col)) { const gchar *text; text = gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet))); if(!text || strlen(text)==0) gtk_sheet_cell_clear(sheet, sheet->active_cell.row, sheet->active_cell.col); gtk_widget_unmap(sheet->sheet_entry); } gtk_sheet_position_children(sheet); gtk_sheet_range_draw(sheet, NULL); size_allocate_row_title_buttons(sheet); size_allocate_global_button(sheet); } static void hadjustment_value_changed (GtkAdjustment * adjustment, gpointer data) { GtkSheet *sheet; gint i, value; gint column, new_column; gint x=0; g_return_if_fail (adjustment != NULL); g_return_if_fail (data != NULL); g_return_if_fail (GTK_IS_SHEET (data)); sheet = GTK_SHEET (data); if(GTK_SHEET_IS_FROZEN(sheet)) return; column=COLUMN_FROM_XPIXEL(sheet,sheet->row_title_area.width + CELL_SPACING); if(!sheet->row_titles_visible) column=COLUMN_FROM_XPIXEL(sheet, CELL_SPACING); for(i=0; i<= sheet->maxcol; i++){ if(sheet->column[i].is_visible) x+=sheet->column[i].width; if(x > adjustment->value) break; } x-=sheet->column[i].width; new_column=i; if (adjustment->value > sheet->old_hadjustment && sheet->old_hadjustment > 0 && sheet->column[i].width > sheet->hadjustment->step_increment){ /* This avoids embarrassing twitching */ if(column == new_column && column != sheet->maxcol && adjustment->value - sheet->old_hadjustment >= sheet->hadjustment->step_increment && new_column + 1 != MIN_VISIBLE_COLUMN(sheet)){ new_column+=1; x=x+sheet->column[column].width; } } /* Negative old_adjustment enforces the redraw, otherwise avoid spureous redraw */ if(sheet->old_hadjustment >= 0. && new_column == column){ sheet->old_hadjustment = sheet->hadjustment->value; return; } sheet->old_hadjustment = sheet->hadjustment->value; adjustment->value=x; if(new_column == 0){ sheet->hadjustment->step_increment= sheet->column[0].width; }else{ sheet->hadjustment->step_increment= MIN(sheet->column[new_column].width, sheet->column[new_column-1].width); } sheet->hadjustment->value=adjustment->value; value = adjustment->value; sheet->hoffset = -value; sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, sheet->row_title_area.width+1); sheet->view.coli=COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width); if(!sheet->row_titles_visible) sheet->view.col0=COLUMN_FROM_XPIXEL(sheet, 1); if(GTK_WIDGET_REALIZED(sheet->sheet_entry) && sheet->state == GTK_SHEET_NORMAL && sheet->active_cell.row >= 0 && sheet->active_cell.col >= 0 && !gtk_sheet_cell_isvisible(sheet, sheet->active_cell.row, sheet->active_cell.col)) { const gchar *text; text = gtk_entry_get_text(GTK_ENTRY(gtk_sheet_get_entry(sheet))); if(!text || strlen(text)==0) gtk_sheet_cell_clear(sheet, sheet->active_cell.row, sheet->active_cell.col); gtk_widget_unmap(sheet->sheet_entry); } gtk_sheet_position_children(sheet); gtk_sheet_range_draw(sheet, NULL); size_allocate_column_title_buttons(sheet); } /* COLUMN RESIZING */ static void draw_xor_vline (GtkSheet * sheet) { GtkWidget *widget; g_return_if_fail (sheet != NULL); widget = GTK_WIDGET (sheet); gdk_draw_line (widget->window, sheet->xor_gc, sheet->x_drag, sheet->column_title_area.height, sheet->x_drag, sheet->sheet_window_height + 1); } /* ROW RESIZING */ static void draw_xor_hline (GtkSheet * sheet) { GtkWidget *widget; g_return_if_fail (sheet != NULL); widget = GTK_WIDGET (sheet); gdk_draw_line (widget->window, sheet->xor_gc, sheet->row_title_area.width, sheet->y_drag, sheet->sheet_window_width + 1, sheet->y_drag); } /* SELECTED RANGE */ static void draw_xor_rectangle(GtkSheet *sheet, GtkSheetRange range) { gint i; GdkRectangle clip_area, area; GdkGCValues values; area.x=COLUMN_LEFT_XPIXEL(sheet, range.col0); area.y=ROW_TOP_YPIXEL(sheet, range.row0); area.width=COLUMN_LEFT_XPIXEL(sheet, range.coli)-area.x+ sheet->column[range.coli].width; area.height=ROW_TOP_YPIXEL(sheet, range.rowi)-area.y+ sheet->row[range.rowi].height; clip_area.x=sheet->row_title_area.width; clip_area.y=sheet->column_title_area.height; clip_area.width=sheet->sheet_window_width; clip_area.height=sheet->sheet_window_height; if(!sheet->row_titles_visible) clip_area.x = 0; if(!sheet->column_titles_visible) clip_area.y = 0; if(area.x<0) { area.width=area.width+area.x; area.x=0; } if(area.width>clip_area.width) area.width=clip_area.width+10; if(area.y<0) { area.height=area.height+area.y; area.y=0; } if(area.height>clip_area.height) area.height=clip_area.height+10; clip_area.x--; clip_area.y--; clip_area.width+=3; clip_area.height+=3; gdk_gc_get_values(sheet->xor_gc, &values); gdk_gc_set_clip_rectangle(sheet->xor_gc, &clip_area); for(i=-1;i<=1;++i) gdk_draw_rectangle(sheet->sheet_window, sheet->xor_gc, FALSE, area.x+i, area.y+i, area.width-2*i, area.height-2*i); gdk_gc_set_clip_rectangle(sheet->xor_gc, NULL); gdk_gc_set_foreground(sheet->xor_gc, &values.foreground); } /* this function returns the new width of the column being resized given * the column and x position of the cursor; the x cursor position is passed * in as a pointer and automaticaly corrected if it's beyond min/max limits */ static guint new_column_width (GtkSheet * sheet, gint column, gint * x) { gint cx, width; GtkRequisition requisition; cx = *x; requisition.width = sheet->column[column].requisition; /* you can't shrink a column to less than its minimum width */ if (cx < COLUMN_LEFT_XPIXEL (sheet, column) + requisition.width) { *x = cx = COLUMN_LEFT_XPIXEL (sheet, column) + requisition.width; } /* don't grow past the end of the window */ /* if (cx > sheet->sheet_window_width) { *x = cx = sheet->sheet_window_width; } */ /* calculate new column width making sure it doesn't end up * less than the minimum width */ width = cx - COLUMN_LEFT_XPIXEL (sheet, column); if (width < requisition.width) width = requisition.width; sheet->column[column].width = width; gtk_sheet_recalc_left_xpixels(sheet, column+1); sheet->view.coli=COLUMN_FROM_XPIXEL(sheet, sheet->sheet_window_width); size_allocate_column_title_buttons (sheet); return width; } /* this function returns the new height of the row being resized given * the row and y position of the cursor; the y cursor position is passed * in as a pointer and automaticaly corrected if it's beyond min/max limits */ static guint new_row_height (GtkSheet * sheet, gint row, gint * y) { GtkRequisition requisition; gint cy, height; cy = *y; requisition.height = sheet->row[row].requisition; /* you can't shrink a row to less than its minimum height */ if (cy < ROW_TOP_YPIXEL (sheet, row) + requisition.height) { *y = cy = ROW_TOP_YPIXEL (sheet, row) + requisition.height; } /* don't grow past the end of the window */ /* if (cy > sheet->sheet_window_height) { *y = cy = sheet->sheet_window_height; } */ /* calculate new row height making sure it doesn't end up * less than the minimum height */ height = (cy - ROW_TOP_YPIXEL (sheet, row)); if (height < requisition.height) height = requisition.height; sheet->row[row].height = height; gtk_sheet_recalc_top_ypixels(sheet, row); sheet->view.rowi=ROW_FROM_YPIXEL(sheet, sheet->sheet_window_height-1); size_allocate_row_title_buttons (sheet); return height; } void gtk_sheet_set_column_width (GtkSheet * sheet, gint column, guint width) { guint min_width; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (column < 0 || column > sheet->maxcol) return; gtk_sheet_column_size_request(sheet, column, &min_width); if(width < min_width) return; sheet->column[column].width = width; gtk_sheet_recalc_left_xpixels(sheet, column+1); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && !GTK_SHEET_IS_FROZEN(sheet)){ size_allocate_column_title_buttons (sheet); adjust_scrollbars (sheet); gtk_sheet_size_allocate_entry(sheet); gtk_sheet_range_draw (sheet, NULL); } else gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[CHANGED], -1, column); gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[NEW_COL_WIDTH], column, width); } void gtk_sheet_set_row_height (GtkSheet * sheet, gint row, guint height) { guint min_height; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if (row < 0 || row > sheet->maxrow) return; gtk_sheet_row_size_request(sheet, row, &min_height); if(height < min_height) return; sheet->row[row].height = height; gtk_sheet_recalc_top_ypixels(sheet, row+1); if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && !GTK_SHEET_IS_FROZEN(sheet)){ size_allocate_row_title_buttons (sheet); adjust_scrollbars (sheet); gtk_sheet_size_allocate_entry(sheet); gtk_sheet_range_draw (sheet, NULL); } gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[CHANGED], row, -1); gtk_signal_emit(GTK_OBJECT(sheet), sheet_signals[NEW_ROW_HEIGHT], row, height); } void gtk_sheet_add_column(GtkSheet *sheet, guint ncols) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); AddColumn(sheet, ncols); if(!GTK_WIDGET_REALIZED(sheet)) return; adjust_scrollbars(sheet); if(sheet->state==GTK_SHEET_ROW_SELECTED) sheet->range.coli+=ncols; sheet->old_hadjustment = -1.; if(!GTK_SHEET_IS_FROZEN(sheet) && sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); } void gtk_sheet_add_row(GtkSheet *sheet, guint nrows) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); AddRow(sheet, nrows); if(!GTK_WIDGET_REALIZED(sheet)) return; if(sheet->state==GTK_SHEET_COLUMN_SELECTED) sheet->range.rowi+=nrows; adjust_scrollbars(sheet); sheet->old_vadjustment = -1.; if(!GTK_SHEET_IS_FROZEN(sheet) && sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); } void gtk_sheet_insert_rows(GtkSheet *sheet, guint row, guint nrows) { GList *children; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(GTK_WIDGET_REALIZED(sheet)) gtk_sheet_real_unselect_range(sheet, NULL); InsertRow(sheet, row, nrows); children = sheet->children; while(children) { GtkSheetChild *child = (GtkSheetChild *)children->data; if(child->attached_to_cell) if(child->row >= row) child->row += nrows; children = children->next; } if(!GTK_WIDGET_REALIZED(sheet)) return; if(sheet->state==GTK_SHEET_COLUMN_SELECTED) sheet->range.rowi+=nrows; adjust_scrollbars(sheet); sheet->old_vadjustment = -1.; if(!GTK_SHEET_IS_FROZEN(sheet) && sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); } void gtk_sheet_insert_columns(GtkSheet *sheet, guint col, guint ncols) { GList *children; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(GTK_WIDGET_REALIZED(sheet)) gtk_sheet_real_unselect_range(sheet, NULL); InsertColumn(sheet, col, ncols); children = sheet->children; while(children) { GtkSheetChild *child = (GtkSheetChild *)children->data; if(child->attached_to_cell) if(child->col >= col) child->col += ncols; children = children->next; } if(!GTK_WIDGET_REALIZED(sheet)) return; if(sheet->state==GTK_SHEET_ROW_SELECTED) sheet->range.coli+=ncols; adjust_scrollbars(sheet); sheet->old_hadjustment = -1.; if(!GTK_SHEET_IS_FROZEN(sheet) && sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); } void gtk_sheet_delete_rows(GtkSheet *sheet, guint row, guint nrows) { GList *children; GtkSheetChild *child; gint irow, icol; gboolean veto; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); nrows = MIN(nrows, sheet->maxrow-row+1); if(GTK_WIDGET_REALIZED(sheet)) gtk_sheet_real_unselect_range(sheet, NULL); DeleteRow(sheet, row, nrows); children = sheet->children; while(children) { child = (GtkSheetChild *)children->data; if(child->attached_to_cell && child->row >= row && child->row < row+nrows){ gtk_container_remove(GTK_CONTAINER(sheet), child->widget); children = sheet->children; } else children = children->next; } children = sheet->children; while(children) { child = (GtkSheetChild *)children->data; if(child->attached_to_cell && child->row > row) child->row -= nrows; children = children->next; } if(!GTK_WIDGET_REALIZED(sheet)) return; irow = sheet->active_cell.row; icol = sheet->active_cell.col; sheet->active_cell.row = -1; sheet->active_cell.col = -1; /* if(sheet->state == GTK_SHEET_ROW_SELECTED) */ irow = MIN(irow, sheet->maxrow); irow = MAX(irow, 0); gtk_sheet_click_cell(sheet, irow, icol, &veto); gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); adjust_scrollbars(sheet); sheet->old_vadjustment = -1.; if(!GTK_SHEET_IS_FROZEN(sheet) && sheet->vadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->vadjustment), "value_changed"); } void gtk_sheet_delete_columns(GtkSheet *sheet, guint col, guint ncols) { GList *children; GtkSheetChild *child; gint irow, icol; gboolean veto; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); ncols = MIN(ncols, sheet->maxcol-col+1); if(GTK_WIDGET_REALIZED(sheet)) gtk_sheet_real_unselect_range(sheet, NULL); DeleteColumn(sheet, col, ncols); children = sheet->children; while(children) { child = (GtkSheetChild *)children->data; if(child->attached_to_cell && child->col >= col && child->col < col+ncols){ gtk_container_remove(GTK_CONTAINER(sheet), child->widget); children = sheet->children; } else children = children->next; } children = sheet->children; while(children) { child = (GtkSheetChild *)children->data; if(child->attached_to_cell && child->col > col) child->col -= ncols; children = children->next; } if(!GTK_WIDGET_REALIZED(sheet)) return; irow = sheet->active_cell.row; icol = sheet->active_cell.col; sheet->active_cell.row = -1; sheet->active_cell.col = -1; /* if(sheet->state == GTK_SHEET_COLUMN_SELECTED) */ icol = MIN(icol, sheet->maxcol); icol = MAX(icol, 0); gtk_sheet_click_cell(sheet, irow, icol, &veto); gtk_sheet_activate_cell(sheet, sheet->active_cell.row, sheet->active_cell.col); adjust_scrollbars(sheet); sheet->old_hadjustment = -1.; if(!GTK_SHEET_IS_FROZEN(sheet) && sheet->hadjustment) gtk_signal_emit_by_name (GTK_OBJECT (sheet->hadjustment), "value_changed"); } void gtk_sheet_range_set_background(GtkSheet *sheet, const GtkSheetRange *urange, const GdkColor *color) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); if(color != NULL) attributes.background = *color; else attributes.background = sheet->bg_color; gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } range.row0--; range.col0--; range.rowi++; range.coli++; if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_range_set_foreground(GtkSheet *sheet, const GtkSheetRange *urange, const GdkColor *color) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); if(color != NULL) attributes.foreground = *color; else gdk_color_black(gdk_colormap_get_system(), &attributes.foreground); gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_range_set_justification(GtkSheet *sheet, const GtkSheetRange *urange, GtkJustification just) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); attributes.justification = just; gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } range.col0 = sheet->view.col0; range.coli = sheet->view.coli; if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_column_set_justification(GtkSheet *sheet, gint col, GtkJustification justification) { g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(col > sheet->maxcol) return; sheet->column[col].justification = justification; if(GTK_WIDGET_REALIZED(sheet) && !GTK_SHEET_IS_FROZEN(sheet) && col >= MIN_VISIBLE_COLUMN(sheet) && col <= MAX_VISIBLE_COLUMN(sheet)) gtk_sheet_range_draw(sheet, NULL); } void gtk_sheet_range_set_editable(GtkSheet *sheet, const GtkSheetRange *urange, gboolean editable) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); attributes.is_editable = editable; gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_range_set_visible(GtkSheet *sheet, const GtkSheetRange *urange, gboolean visible) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); attributes.is_visible=visible; gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_range_set_border(GtkSheet *sheet, const GtkSheetRange *urange, gint mask, guint width, gint line_style) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); attributes.border.mask = mask; attributes.border.width = width; attributes.border.line_style=line_style; attributes.border.cap_style=GDK_CAP_NOT_LAST; attributes.border.join_style=GDK_JOIN_MITER; gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } range.row0--; range.col0--; range.rowi++; range.coli++; if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_range_set_border_color(GtkSheet *sheet, const GtkSheetRange *urange, const GdkColor *color) { gint i, j; GtkSheetCellAttr attributes; GtkSheetRange range; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); attributes.border.color = *color; gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } if(!GTK_SHEET_IS_FROZEN(sheet)) gtk_sheet_range_draw(sheet, &range); } void gtk_sheet_range_set_font(GtkSheet *sheet, const GtkSheetRange *urange, PangoFontDescription *font) { gint i, j; gint font_height; GtkSheetCellAttr attributes; GtkSheetRange range; PangoContext *context; PangoFontMetrics *metrics; g_return_if_fail (sheet != NULL); g_return_if_fail (GTK_IS_SHEET (sheet)); if(!urange) range = sheet->range; else range = *urange; gtk_sheet_freeze(sheet); context = gtk_widget_get_pango_context(GTK_WIDGET(sheet)); metrics = pango_context_get_metrics(context, font, pango_context_get_language(context)); font_height = pango_font_metrics_get_descent(metrics) + pango_font_metrics_get_ascent(metrics); font_height = PANGO_PIXELS(font_height) + 2*CELLOFFSET; for (i=range.row0; i<=range.rowi; i++) for (j=range.col0; j<=range.coli; j++){ gtk_sheet_get_attributes(sheet, i, j, &attributes); attributes.font_desc = font; if(font_height > sheet->row[i].height){ sheet->row[i].height = font_height; gtk_sheet_recalc_top_ypixels(sheet, i); } gtk_sheet_set_cell_attributes(sheet, i, j, attributes); } gtk_sheet_thaw(sheet); pango_font_metrics_unref(metrics); } static void gtk_sheet_set_cell_attributes(GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr attributes) { GtkSheetCell **cell; if(row > sheet->maxrow || col >sheet->maxcol) return; CheckBounds(sheet, row, col); cell = &sheet->data[row][col]; if(*cell==NULL){ (*cell) = gtk_sheet_cell_new(); (*cell)->row = row; (*cell)->col = col; } if((*cell)->attributes == NULL) (*cell)->attributes = g_new(GtkSheetCellAttr, 1); *((*cell)->attributes) = attributes; } gboolean gtk_sheet_get_attributes(GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr *attributes) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (GTK_IS_SHEET (sheet), FALSE); if(row < 0 || col < 0) return FALSE; if(row > sheet->maxallocrow || col > sheet->maxalloccol){ init_attributes(sheet, col, attributes); return FALSE; } if(row <= sheet->maxallocrow && col <= sheet->maxalloccol){ GtkSheetCell **cell = NULL; if(sheet->data[row] && sheet->data[row][col]) cell = &sheet->data[row][col]; if(cell == NULL || *cell == NULL){ init_attributes(sheet, col, attributes); return FALSE; } else if((*cell)->attributes == NULL){ init_attributes(sheet, col, attributes); return FALSE; }else{ *attributes = *(sheet->data[row][col]->attributes); if(sheet->column[col].justification != GTK_JUSTIFY_FILL) attributes->justification = sheet->column[col].justification; } } return TRUE; } static void init_attributes(GtkSheet *sheet, gint col, GtkSheetCellAttr *attributes) { /* DEFAULT VALUES */ attributes->foreground = GTK_WIDGET(sheet)->style->black; attributes->background = sheet->bg_color; if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))){ GdkColormap *colormap; colormap=gdk_colormap_get_system(); gdk_color_black(colormap, &attributes->foreground); attributes->background = sheet->bg_color; } attributes->justification = sheet->column[col].justification; attributes->border.width = 0; attributes->border.line_style = GDK_LINE_SOLID; attributes->border.cap_style = GDK_CAP_NOT_LAST; attributes->border.join_style = GDK_JOIN_MITER; attributes->border.mask = 0; attributes->border.color = GTK_WIDGET(sheet)->style->black; attributes->is_editable = TRUE; attributes->is_visible = TRUE; attributes->font = GTK_WIDGET(sheet)->style->private_font; attributes->font_desc = GTK_WIDGET(sheet)->style->font_desc; } /********************************************************************** * Memory allocation routines: * AddRow & AddColumn allocate memory for GtkSheetColumn & GtkSheetRow structs. * InsertRow * InsertColumn * DeleteRow * DeleteColumn * GrowSheet allocates memory for the sheet cells contents using an array of * pointers. Alternative to this could be a linked list or a hash table. * CheckBounds checks whether the given cell is currently allocated or not. * If not, it calls to GrowSheet. **********************************************************************/ static gint AddColumn(GtkSheet *tbl, gint ncols) { gint i; if(ncols == -1 && tbl->maxcol == 0) { ncols = 1; } else { tbl->maxcol += ncols; tbl->column = (GtkSheetColumn *)g_realloc(tbl->column,(tbl->maxcol+1)* sizeof(GtkSheetColumn)); } for(i=tbl->maxcol-ncols+1; i<= tbl->maxcol; i++){ tbl->column[i].width=DEFAULT_COLUMN_WIDTH; tbl->column[i].button.label=NULL; tbl->column[i].button.child=NULL; tbl->column[i].button.state=GTK_STATE_NORMAL; tbl->column[i].button.justification=GTK_JUSTIFY_CENTER; tbl->column[i].button.label_visible = TRUE; tbl->column[i].name=NULL; tbl->column[i].is_visible=TRUE; tbl->column[i].is_sensitive=TRUE; tbl->column[i].left_text_column=i; tbl->column[i].right_text_column=i; tbl->column[i].justification=GTK_JUSTIFY_FILL; tbl->column[i].requisition=DEFAULT_COLUMN_WIDTH; if(i>0) { tbl->column[i].left_text_column=tbl->column[i-1].left_text_column; tbl->column[i].left_xpixel=tbl->column[i-1].left_xpixel + tbl->column[i-1].width; } else { tbl->column[i].left_xpixel=tbl->row_title_area.width; if(!tbl->row_titles_visible) tbl->column[i].left_xpixel=0; } } return TRUE; } static gint AddRow(GtkSheet *tbl, gint nrows) { gint i; if(nrows == -1 && tbl->maxrow == 0) { nrows = 1; } else { tbl->maxrow += nrows; tbl->row = (GtkSheetRow *)g_realloc(tbl->row,(tbl->maxrow+1)* sizeof(GtkSheetRow)); } for(i=tbl->maxrow-nrows+1; i<= tbl->maxrow; i++){ tbl->row[i].requisition=tbl->row[i].height=DEFAULT_ROW_HEIGHT(GTK_WIDGET(tbl)); tbl->row[i].button.label=NULL; tbl->row[i].button.child=NULL; tbl->row[i].button.state=GTK_STATE_NORMAL; tbl->row[i].button.justification=GTK_JUSTIFY_CENTER; tbl->row[i].button.label_visible = TRUE; tbl->row[i].name=NULL; tbl->row[i].is_visible=TRUE; tbl->row[i].is_sensitive=TRUE; if(i>0) tbl->row[i].top_ypixel=tbl->row[i-1].top_ypixel+tbl->row[i-1].height; else { tbl->row[i].top_ypixel=tbl->column_title_area.height; if(!tbl->column_titles_visible) tbl->row[i].top_ypixel=0; } } return TRUE; } static gint InsertRow(GtkSheet *tbl, gint row, gint nrows) { gint i,j; GtkSheetCell **auxdata; GtkSheetRow auxrow; AddRow(tbl,nrows); for(i=tbl->maxrow; i>=row+nrows; i--){ auxrow = tbl->row[i]; tbl->row[i]=tbl->row[i-nrows]; tbl->row[i].is_visible=tbl->row[i-nrows].is_visible; tbl->row[i].is_sensitive=tbl->row[i-nrows].is_sensitive; if(auxrow.is_visible) tbl->row[i].top_ypixel+=nrows*DEFAULT_ROW_HEIGHT(GTK_WIDGET(tbl)); tbl->row[i-nrows]=auxrow; } if(row <= tbl->maxallocrow){ GrowSheet(tbl,nrows,0); for(i=tbl->maxallocrow; i>=row+nrows; i--){ GtkSheetCell **pp; auxdata = tbl->data[i]; tbl->data[i]=tbl->data[i-nrows]; pp= tbl->data[i]; for(j=0; j<=tbl->maxalloccol; j++,pp++){ if(*pp!=(GtkSheetCell *)NULL) (*pp)->row=i; } tbl->data[i-nrows]=auxdata; } } gtk_sheet_recalc_top_ypixels(tbl, 0); return TRUE; } static gint InsertColumn(GtkSheet *tbl, gint col, gint ncols) { gint i,j; GtkSheetColumn auxcol; AddColumn(tbl,ncols); for(i=tbl->maxcol; i>=col+ncols; i--){ auxcol = tbl->column[i]; tbl->column[i]=tbl->column[i-ncols]; tbl->column[i].is_visible=tbl->column[i-ncols].is_visible; tbl->column[i].is_sensitive=tbl->column[i-ncols].is_sensitive; tbl->column[i].left_text_column=tbl->column[i-ncols].left_text_column; tbl->column[i].right_text_column=tbl->column[i-ncols].right_text_column; tbl->column[i].justification=tbl->column[i-ncols].justification; if(auxcol.is_visible) tbl->column[i].left_xpixel+=ncols*DEFAULT_COLUMN_WIDTH; tbl->column[i-ncols]=auxcol; } if(col <= tbl->maxalloccol){ GrowSheet(tbl,0,ncols); for(i=0; i<=tbl->maxallocrow; i++){ for(j=tbl->maxalloccol; j>=col+ncols; j--){ gtk_sheet_real_cell_clear(tbl, i, j, TRUE); tbl->data[i][j]=tbl->data[i][j-ncols]; if(tbl->data[i][j]) tbl->data[i][j]->col=j; tbl->data[i][j-ncols]=NULL; } } } gtk_sheet_recalc_left_xpixels(tbl, 0); return TRUE; } static gint DeleteRow(GtkSheet *tbl, gint row, gint nrows) { GtkSheetCell **auxdata = NULL; gint i,j; if(nrows <= 0 || row > tbl->maxrow) return TRUE; nrows=MIN(nrows,tbl->maxrow-row+1); for(i=row; irow[i].name){ g_free(tbl->row[i].name); tbl->row[i].name = NULL; } if(tbl->row[i].button.label){ g_free(tbl->row[i].button.label); tbl->row[i].button.label = NULL; } } for(i=row; i<=tbl->maxrow-nrows; i++){ if(i+nrows <= tbl->maxrow){ tbl->row[i]=tbl->row[i+nrows]; } } if(row <= tbl->maxallocrow){ for(i=row; i<=tbl->maxrow-nrows; i++){ if(i<=tbl->maxallocrow){ auxdata=tbl->data[i]; for(j=0; j<=tbl->maxalloccol; j++){ gtk_sheet_real_cell_clear(tbl, i, j, TRUE); } } if(i+nrows<=tbl->maxallocrow){ tbl->data[i]=tbl->data[i+nrows]; tbl->data[i+nrows]=auxdata; for(j=0; j<=tbl->maxalloccol; j++){ if(tbl->data[i][j]) tbl->data[i][j]->row=i; } } } for(i=tbl->maxrow-nrows+1; i<=tbl->maxallocrow; i++){ if(i > 0 && tbl->data[i]){ g_free(tbl->data[i]); tbl->data[i] = NULL; } } tbl->maxallocrow-=MIN(nrows,tbl->maxallocrow-row+1); } tbl->maxrow-=nrows; tbl->maxallocrow = MIN(tbl->maxallocrow, tbl->maxrow); gtk_sheet_recalc_top_ypixels(tbl, 0); return TRUE; } static gint DeleteColumn(GtkSheet *tbl, gint column, gint ncols) { gint i,j; ncols = MIN(ncols,tbl->maxcol-column+1); if(ncols <= 0 || column > tbl->maxcol) return TRUE; for(i=column; icolumn[i].name){ g_free(tbl->column[i].name); tbl->column[i].name = NULL; } if(tbl->column[i].button.label){ g_free(tbl->column[i].button.label); tbl->column[i].button.label = NULL; } } for(i=column; i<=tbl->maxcol-ncols; i++){ if(i+ncols <= tbl->maxcol){ tbl->column[i]=tbl->column[i+ncols]; } } if(column <= tbl->maxalloccol){ for(i=column; i<=tbl->maxcol-ncols; i++){ if(i<=tbl->maxalloccol){ for(j=0; j<=tbl->maxallocrow; j++){ gtk_sheet_real_cell_clear(tbl, j, i, TRUE); if(i+ncols <= tbl->maxalloccol){ tbl->data[j][i] = tbl->data[j][i+ncols]; tbl->data[j][i+ncols] = NULL; if(tbl->data[j][i]) tbl->data[j][i]->col=i; } } } } tbl->maxalloccol-=MIN(ncols,tbl->maxalloccol-column+1); tbl->maxalloccol = MIN(tbl->maxalloccol, tbl->maxcol); } tbl->maxcol-=ncols; gtk_sheet_recalc_left_xpixels(tbl, 0); return TRUE; } static gint GrowSheet(GtkSheet *tbl, gint newrows, gint newcols) { gint i,j; gint inirow, inicol; inirow = tbl->maxallocrow + 1; inicol = tbl->maxalloccol + 1; tbl->maxalloccol = tbl->maxalloccol + newcols; tbl->maxallocrow = tbl->maxallocrow + newrows; if(newrows>0){ tbl->data = (GtkSheetCell***) g_realloc(tbl->data,(tbl->maxallocrow+1)*sizeof(GtkSheetCell **)+sizeof(double)); for(i=inirow; i <= tbl->maxallocrow; i++){ tbl->data[i] = (GtkSheetCell **) \ g_malloc((tbl->maxcol+1)*sizeof(GtkSheetCell *)+sizeof(double)); for(j=0; jdata[i][j] = NULL; } } } if(newcols>0){ for(i=0; i <= tbl->maxallocrow; i++) { tbl->data[i] = (GtkSheetCell **) \ g_realloc(tbl->data[i],(tbl->maxalloccol+1)*sizeof(GtkSheetCell *)+sizeof(double)); for(j=inicol; j <= tbl->maxalloccol; j++) { tbl->data[i][j] = NULL; } } } return(0); } static gint CheckBounds(GtkSheet *tbl, gint row, gint col) { gint newrows=0,newcols=0; if(col>tbl->maxalloccol) newcols=col-tbl->maxalloccol; if(row>tbl->maxallocrow) newrows=row-tbl->maxallocrow; if(newrows>0 || newcols>0) GrowSheet(tbl, newrows, newcols); return(0); } /******************************************************************** * Container Functions: * gtk_sheet_add * gtk_sheet_put * gtk_sheet_attach * gtk_sheet_remove * gtk_sheet_move_child * gtk_sheet_position_child * gtk_sheet_position_children * gtk_sheet_realize_child * gtk_sheet_get_child_at ********************************************************************/ GtkSheetChild * gtk_sheet_put(GtkSheet *sheet, GtkWidget *child, gint x, gint y) { GtkRequisition child_requisition; GtkSheetChild *child_info; g_return_val_if_fail(sheet != NULL, NULL); g_return_val_if_fail(GTK_IS_SHEET(sheet), NULL); g_return_val_if_fail(child != NULL, NULL); g_return_val_if_fail(child->parent == NULL, NULL); child_info = g_new (GtkSheetChild, 1); child_info->widget = child; child_info->x = x; child_info->y = y; child_info->attached_to_cell = FALSE; child_info->floating = TRUE; child_info->xpadding = child_info->ypadding = 0; child_info->xexpand = child_info->yexpand = FALSE; child_info->xshrink = child_info->yshrink = FALSE; child_info->xfill = child_info->yfill = FALSE; sheet->children = g_list_append(sheet->children, child_info); gtk_widget_set_parent (child, GTK_WIDGET(sheet)); gtk_widget_size_request(child, &child_requisition); if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet))) { if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && (!GTK_WIDGET_REALIZED(child) || GTK_WIDGET_NO_WINDOW(child))) gtk_sheet_realize_child(sheet, child_info); if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet)) && !GTK_WIDGET_MAPPED(child)) gtk_widget_map(child); } gtk_sheet_position_child(sheet, child_info); /* This will avoid drawing on the titles */ if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) { if(sheet->row_titles_visible) gdk_window_show(sheet->row_title_window); if(sheet->column_titles_visible) gdk_window_show(sheet->column_title_window); } return (child_info); } void gtk_sheet_attach_floating (GtkSheet *sheet, GtkWidget *widget, gint row, gint col) { GdkRectangle area; GtkSheetChild *child; if(row < 0 || col < 0){ gtk_sheet_button_attach(sheet, widget, row, col); return; } gtk_sheet_get_cell_area(sheet, row, col, &area); child = gtk_sheet_put(sheet, widget, area.x, area.y); child->attached_to_cell = TRUE; child->row = row; child->col = col; } void gtk_sheet_attach_default (GtkSheet *sheet, GtkWidget *widget, gint row, gint col) { if(row < 0 || col < 0){ gtk_sheet_button_attach(sheet, widget, row, col); return; } gtk_sheet_attach(sheet, widget, row, col, GTK_EXPAND|GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0); } void gtk_sheet_attach (GtkSheet *sheet, GtkWidget *widget, gint row, gint col, gint xoptions, gint yoptions, gint xpadding, gint ypadding) { GdkRectangle area; GtkSheetChild *child = NULL; if(row < 0 || col < 0){ gtk_sheet_button_attach(sheet, widget, row, col); return; } child = g_new0(GtkSheetChild, 1); child->attached_to_cell = TRUE; child->floating = FALSE; child->widget = widget; child->row = row; child->col = col; child->xpadding = xpadding; child->ypadding = ypadding; child->xexpand = (xoptions & GTK_EXPAND) != 0; child->yexpand = (yoptions & GTK_EXPAND) != 0; child->xshrink = (xoptions & GTK_SHRINK) != 0; child->yshrink = (yoptions & GTK_SHRINK) != 0; child->xfill = (xoptions & GTK_FILL) != 0; child->yfill = (yoptions & GTK_FILL) != 0; sheet->children = g_list_append(sheet->children, child); gtk_sheet_get_cell_area(sheet, row, col, &area); child->x = area.x + child->xpadding; child->y = area.y + child->ypadding; if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet))) { if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && (!GTK_WIDGET_REALIZED(widget) || GTK_WIDGET_NO_WINDOW(widget))) gtk_sheet_realize_child(sheet, child); if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet)) && !GTK_WIDGET_MAPPED(widget)) gtk_widget_map(widget); } gtk_sheet_position_child(sheet, child); /* This will avoid drawing on the titles */ if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet))) { if(GTK_SHEET_ROW_TITLES_VISIBLE(sheet)) gdk_window_show(sheet->row_title_window); if(GTK_SHEET_COL_TITLES_VISIBLE(sheet)) gdk_window_show(sheet->column_title_window); } } void gtk_sheet_button_attach (GtkSheet *sheet, GtkWidget *widget, gint row, gint col) { GtkSheetButton *button; GtkSheetChild *child; GtkRequisition button_requisition; if(row >= 0 && col >= 0) return; if(row < 0 && col < 0) return; child = g_new (GtkSheetChild, 1); child->widget = widget; child->x = 0; child->y = 0; child->attached_to_cell = TRUE; child->floating = FALSE; child->row = row; child->col = col; child->xpadding = child->ypadding = 0; child->xshrink = child->yshrink = FALSE; child->xfill = child->yfill = FALSE; if(row == -1){ button = &sheet->column[col].button; button->child = child; } else { button = &sheet->row[row].button; button->child = child; } sheet->children = g_list_append(sheet->children, child); gtk_sheet_button_size_request(sheet, button, &button_requisition); if(row == -1){ if(button_requisition.height > sheet->column_title_area.height) sheet->column_title_area.height = button_requisition.height; if(button_requisition.width > sheet->column[col].width) sheet->column[col].width = button_requisition.width; } if(col == -1){ if(button_requisition.width > sheet->row_title_area.width) sheet->row_title_area.width = button_requisition.width; if(button_requisition.height > sheet->row[row].height) sheet->row[row].height = button_requisition.height; } if (GTK_WIDGET_VISIBLE(GTK_WIDGET(sheet))) { if(GTK_WIDGET_REALIZED(GTK_WIDGET(sheet)) && (!GTK_WIDGET_REALIZED(widget) || GTK_WIDGET_NO_WINDOW(widget))) gtk_sheet_realize_child(sheet, child); if(GTK_WIDGET_MAPPED(GTK_WIDGET(sheet)) && !GTK_WIDGET_MAPPED(widget)) gtk_widget_map(widget); } if(row == -1) size_allocate_column_title_buttons(sheet); if(col == -1) size_allocate_row_title_buttons(sheet); } static void label_size_request(GtkSheet *sheet, gchar *label, GtkRequisition *req) { gchar *words; gchar word[1000]; gint n = 0; gint row_height = DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet)) - 2*CELLOFFSET + 2; req->height = 0; req->width = 0; words=label; while(words && *words != '\0'){ if(*words == '\n' || *(words+1) == '\0'){ req->height += row_height; word[n] = '\0'; req->width = MAX(req->width, STRING_WIDTH(GTK_WIDGET(sheet), GTK_WIDGET(sheet)->style->font_desc, word)); n = 0; } else { word[n++] = *words; } words++; } if(n > 0) req->height -= 2; } static void gtk_sheet_button_size_request (GtkSheet *sheet, GtkSheetButton *button, GtkRequisition *button_requisition) { GtkRequisition requisition; GtkRequisition label_requisition; if(gtk_sheet_autoresize(sheet) && button->label && strlen(button->label) > 0){ label_size_request(sheet, button->label, &label_requisition); label_requisition.width += 2*CELLOFFSET; label_requisition.height += 2*CELLOFFSET; } else { label_requisition.height = DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet)); label_requisition.width = COLUMN_MIN_WIDTH; } if(button->child) { gtk_widget_size_request(button->child->widget, &requisition); requisition.width += 2*button->child->xpadding; requisition.height += 2*button->child->ypadding; requisition.width += 2*sheet->button->style->xthickness; requisition.height += 2*sheet->button->style->ythickness; } else { requisition.height = DEFAULT_ROW_HEIGHT(GTK_WIDGET(sheet)); requisition.width = COLUMN_MIN_WIDTH; } *button_requisition = requisition; button_requisition->width = MAX(requisition.width, label_requisition.width); button_requisition->height = MAX(requisition.height, label_requisition.height); } static void gtk_sheet_row_size_request (GtkSheet *sheet, gint row, guint *requisition) { GtkRequisition button_requisition; GList *children; gtk_sheet_button_size_request(sheet, &sheet->row[row].button, &button_requisition); *requisition = button_requisition.height; children = sheet->children; while(children){ GtkSheetChild *child = (GtkSheetChild *)children->data; GtkRequisition child_requisition; if(child->attached_to_cell && child->row == row && child->col != -1 && !child->floating && !child->yshrink){ gtk_widget_get_child_requisition(child->widget, &child_requisition); if(child_requisition.height + 2 * child->ypadding > *requisition) *requisition = child_requisition.height + 2 * child->ypadding; } children = children->next; } sheet->row[row].requisition = *requisition; } static void gtk_sheet_column_size_request (GtkSheet *sheet, gint col, guint *requisition) { GtkRequisition button_requisition; GList *children; gtk_sheet_button_size_request(sheet, &sheet->column[col].button, &button_requisition); *requisition = button_requisition.width; children = sheet->children; while(children){ GtkSheetChild *child = (GtkSheetChild *)children->data; GtkRequisition child_requisition; if(child->attached_to_cell && child->col == col && child->row != -1 && !child->floating && !child->xshrink){ gtk_widget_get_child_requisition(child->widget, &child_requisition); if(child_requisition.width + 2 * child->xpadding > *requisition) *requisition = child_requisition.width + 2 * child->xpadding; } children = children->next; } sheet->column[col].requisition = *requisition; } void gtk_sheet_move_child(GtkSheet *sheet, GtkWidget *widget, gint x, gint y) { GList *children; g_return_if_fail(sheet != NULL); g_return_if_fail(GTK_IS_SHEET(sheet)); children = sheet->children; while(children) { GtkSheetChild *child = children->data; if(child->widget == widget){ child->x = x; child->y = y; child->row = ROW_FROM_YPIXEL(sheet, y); child->col = COLUMN_FROM_XPIXEL(sheet, x); gtk_sheet_position_child(sheet, child); return; } children = children->next; } g_warning("Widget must be a GtkSheet child"); } static void gtk_sheet_position_child(GtkSheet *sheet, GtkSheetChild *child) { GtkRequisition child_requisition; GtkAllocation child_allocation; gint xoffset = 0; gint yoffset = 0; GdkRectangle area; gtk_widget_get_child_requisition(child->widget, &child_requisition); if(sheet->column_titles_visible) yoffset = sheet->column_title_area.height; if(sheet->row_titles_visible) xoffset = sheet->row_title_area.width; if(child->attached_to_cell){ /* child->x = COLUMN_LEFT_XPIXEL(sheet, child->col); child->y = ROW_TOP_YPIXEL(sheet, child->row); if(sheet->row_titles_visible) child->x-=sheet->row_title_area.width; if(sheet->column_titles_visible) child->y-=sheet->column_title_area.height; width = sheet->column[child->col].width; height = sheet->row[child->row].height; */ gtk_sheet_get_cell_area(sheet, child->row, child->col, &area); child->x = area.x + child->xpadding; child->y = area.y + child->ypadding; if(!child->floating){ if(child_requisition.width + 2*child->xpadding <= sheet->column[child->col].width){ if(child->xfill){ child_requisition.width = child_allocation.width = sheet->column[child->col].width - 2*child->xpadding; } else { if(child->xexpand){ child->x = area.x + sheet->column[child->col].width / 2 - child_requisition.width / 2; } child_allocation.width = child_requisition.width; } } else { if(!child->xshrink){ gtk_sheet_set_column_width(sheet, child->col, child_requisition.width + 2 * child->xpadding); } child_allocation.width = sheet->column[child->col].width - 2*child->xpadding; } if(child_requisition.height + 2*child->ypadding <= sheet->row[child->row].height){ if(child->yfill){ child_requisition.height = child_allocation.height = sheet->row[child->row].height - 2*child->ypadding; } else { if(child->yexpand){ child->y = area.y + sheet->row[child->row].height / 2 - child_requisition.height / 2; } child_allocation.height = child_requisition.height; } } else { if(!child->yshrink){ gtk_sheet_set_row_height(sheet, child->row, child_requisition.height + 2 * child->ypadding); } child_allocation.height = sheet->row[child->row].height - 2*child->ypadding; } } else { child_allocation.width = child_requisition.width; child_allocation.height = child_requisition.height; } child_allocation.x = child->x + xoffset; child_allocation.y = child->y + yoffset; } else { child_allocation.x = child->x + xoffset; child_allocation.y = child->y + yoffset; child_allocation.width = child_requisition.width; child_allocation.height = child_requisition.height; } gtk_widget_size_allocate(child->widget, &child_allocation); gtk_widget_queue_draw(child->widget); } static void gtk_sheet_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { GtkSheet *sheet; GList *children; g_return_if_fail (GTK_IS_SHEET (container)); g_return_if_fail (callback != NULL); sheet = GTK_SHEET (container); children = sheet->children; while (children) { GtkSheetChild *child = children->data; children = children->next; (* callback) (child->widget, callback_data); } if(sheet->button) (* callback) (sheet->button, callback_data); if(sheet->sheet_entry) (* callback) (sheet->sheet_entry, callback_data); } static void gtk_sheet_position_children(GtkSheet *sheet) { GList *children; children = sheet->children; while(children) { GtkSheetChild *child = (GtkSheetChild *)children->data; if(child->col !=-1 && child->row != -1) gtk_sheet_position_child(sheet, child); if(child->row == -1){ if(child->col < MIN_VISIBLE_COLUMN(sheet) || child->col > MAX_VISIBLE_COLUMN(sheet)) gtk_sheet_child_hide(child); else gtk_sheet_child_show(child); } if(child->col == -1){ if(child->row < MIN_VISIBLE_ROW(sheet) || child->row > MAX_VISIBLE_ROW(sheet)) gtk_sheet_child_hide(child); else gtk_sheet_child_show(child); } children = children->next; } } static void gtk_sheet_remove (GtkContainer *container, GtkWidget *widget) { GtkSheet *sheet; GList *children; GtkSheetChild *child = 0; g_return_if_fail(container != NULL); g_return_if_fail(GTK_IS_SHEET(container)); sheet = GTK_SHEET(container); children = sheet->children; while(children) { child = (GtkSheetChild *)children->data; if(child->widget == widget) break; children = children->next; } if (children) { if(child->row == -1) sheet->row[child->col].button.child = NULL; if(child->col == -1) sheet->column[child->row].button.child = NULL; gtk_widget_unparent (widget); child->widget = NULL; sheet->children = g_list_remove_link (sheet->children, children); g_list_free_1 (children); g_free(child); } } static void gtk_sheet_realize_child(GtkSheet *sheet, GtkSheetChild *child) { GtkWidget *widget; widget = GTK_WIDGET(sheet); if(GTK_WIDGET_REALIZED(widget)){ if(child->row == -1) gtk_widget_set_parent_window(child->widget, sheet->column_title_window); else if(child->col == -1) gtk_widget_set_parent_window(child->widget, sheet->row_title_window); else gtk_widget_set_parent_window(child->widget, sheet->sheet_window); } gtk_widget_set_parent(child->widget, widget); } GtkSheetChild * gtk_sheet_get_child_at(GtkSheet *sheet, gint row, gint col) { GList *children; GtkSheetChild *child = 0; g_return_val_if_fail(sheet != NULL, NULL); g_return_val_if_fail(GTK_IS_SHEET(sheet), NULL); children = sheet->children; while(children) { child = (GtkSheetChild *)children->data; if(child->attached_to_cell) if(child->row == row && child->col == col) break; children = children->next; } if(children) return child; return NULL; } static void gtk_sheet_child_hide(GtkSheetChild *child) { g_return_if_fail(child != NULL); gtk_widget_hide(child->widget); } static void gtk_sheet_child_show(GtkSheetChild *child) { g_return_if_fail(child != NULL); gtk_widget_show(child->widget); } #endif // HAVE_GUI gpsim-0.30.0/gui/gtkextra/gtksheet.h0000664000076400007640000005522413041763636014271 00000000000000/* GtkSheet widget for Gtk+. * Copyright (C) 1999-2001 Adrian E. Feiguin * * Based on GtkClist widget by Jay Painter, but major changes. * Memory allocation routines inspired on SC (Spreadsheet Calculator) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __GTK_SHEET_H__ #define __GTK_SHEET_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef enum { GTK_SHEET_FOREGROUND, GTK_SHEET_BACKGROUND, GTK_SHEET_FONT, GTK_SHEET_JUSTIFICATION, GTK_SHEET_BORDER, GTK_SHEET_BORDER_COLOR, GTK_SHEET_IS_EDITABLE, GTK_SHEET_IS_VISIBLE } GtkSheetAttrType; /* sheet->state */ enum { GTK_SHEET_NORMAL, GTK_SHEET_ROW_SELECTED, GTK_SHEET_COLUMN_SELECTED, GTK_SHEET_RANGE_SELECTED }; enum { GTK_SHEET_LEFT_BORDER = 1 << 0, GTK_SHEET_RIGHT_BORDER = 1 << 1, GTK_SHEET_TOP_BORDER = 1 << 2, GTK_SHEET_BOTTOM_BORDER = 1 << 3 }; #define GTK_TYPE_SHEET_RANGE (gtk_sheet_range_get_type ()) #define GTK_TYPE_SHEET (gtk_sheet_get_type ()) #define GTK_SHEET(obj) GTK_CHECK_CAST (obj, gtk_sheet_get_type (), GtkSheet) #define GTK_SHEET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_sheet_get_type (), GtkSheetClass) #define GTK_IS_SHEET(obj) GTK_CHECK_TYPE (obj, gtk_sheet_get_type ()) /* Public flags, for compatibility */ #define GTK_SHEET_IS_LOCKED(sheet) gtk_sheet_locked(sheet) #define GTK_SHEET_ROW_FROZEN(sheet) !gtk_sheet_rows_resizable(sheet) #define GTK_SHEET_COLUMN_FROZEN(sheet) !gtk_sheet_columns_resizable(sheet) #define GTK_SHEET_AUTORESIZE(sheet) gtk_sheet_autoresize(sheet) #define GTK_SHEET_CLIP_TEXT(sheet) gtk_sheet_clip_text(sheet) #define GTK_SHEET_ROW_TITLES_VISIBLE(sheet) gtk_sheet_row_titles_visible(sheet) #define GTK_SHEET_COL_TITLES_VISIBLE(sheet) gtk_sheet_column_titles_visible(sheet) #define GTK_SHEET_AUTO_SCROLL(sheet) gtk_sheet_autoscroll(sheet) #define GTK_SHEET_JUSTIFY_ENTRY(sheet) gtk_sheet_justify_entry(sheet) typedef struct _GtkSheet GtkSheet; typedef struct _GtkSheetClass GtkSheetClass; typedef struct _GtkSheetChild GtkSheetChild; typedef struct _GtkSheetRow GtkSheetRow; typedef struct _GtkSheetColumn GtkSheetColumn; typedef struct _GtkSheetCell GtkSheetCell; typedef struct _GtkSheetRange GtkSheetRange; typedef struct _GtkSheetButton GtkSheetButton; typedef struct _GtkSheetCellAttr GtkSheetCellAttr; typedef struct _GtkSheetCellBorder GtkSheetCellBorder; struct _GtkSheetChild { GtkWidget *widget; gint x,y ; gboolean attached_to_cell; gboolean floating; gint row, col; guint16 xpadding; guint16 ypadding; gboolean xexpand; gboolean yexpand; gboolean xshrink; gboolean yshrink; gboolean xfill; gboolean yfill; }; struct _GtkSheetButton { GtkStateType state; gchar *label; gboolean label_visible; GtkSheetChild *child; GtkJustification justification; }; struct _GtkSheetCellBorder { gint8 mask; guint width; GdkLineStyle line_style; GdkCapStyle cap_style; GdkJoinStyle join_style; GdkColor color; }; struct _GtkSheetCellAttr { GtkJustification justification; GdkFont *font; PangoFontDescription *font_desc; GdkColor foreground; GdkColor background; GtkSheetCellBorder border; gboolean is_editable; gboolean is_visible; }; struct _GtkSheetCell { GdkRectangle area; gint row; gint col; GtkSheetCellAttr *attributes; gchar *text; gpointer link; }; struct _GtkSheetRange { gint row0,col0; /* upper-left cell */ gint rowi,coli; /* lower-right cell */ }; struct _GtkSheetRow { gchar *name; gint height; gint top_ypixel; guint16 requisition; GtkSheetButton button; gboolean is_sensitive; gboolean is_visible; }; struct _GtkSheetColumn { gchar *name; gint width; gint left_xpixel; guint16 requisition; GtkSheetButton button; gint left_text_column; /* min left column displaying text on this column */ gint right_text_column; /* max right column displaying text on this column */ GtkJustification justification; gboolean is_sensitive; gboolean is_visible; }; struct _GtkSheet{ GtkContainer container; guint16 flags; GtkSelectionMode selection_mode; gboolean autoresize; gboolean autoscroll; gboolean clip_text; gboolean justify_entry; gboolean locked; guint freeze_count; /* Background colors */ GdkColor bg_color; GdkColor grid_color; gboolean show_grid; /* sheet children */ GList *children; /* allocation rectangle after the container_border_width and the width of the shadow border */ GdkRectangle internal_allocation; gchar *name; GtkSheetRow *row; GtkSheetColumn *column; gboolean rows_resizable; gboolean columns_resizable; /* max number of diplayed cells */ gint maxrow; gint maxcol; /* Displayed range */ GtkSheetRange view; /* sheet data: dynamically allocated array of cell pointers */ GtkSheetCell ***data; /* max number of allocated cells */ gint maxallocrow; gint maxalloccol; /* active cell */ GtkSheetCell active_cell; GtkWidget *sheet_entry; GtkType entry_type; /* expanding selection */ GtkSheetCell selection_cell; /* timer for automatic scroll during selection */ gint32 timer; /* timer for flashing clipped range */ gint32 clip_timer; gint interval; /* global selection button */ GtkWidget *button; /* sheet state */ gint state; /* selected range */ GtkSheetRange range; /*the scrolling window and it's height and width to * make things a little speedier */ GdkWindow *sheet_window; guint sheet_window_width; guint sheet_window_height; /* sheet backing pixmap */ GdkWindow *pixmap; /* offsets for scrolling */ gint hoffset; gint voffset; gfloat old_hadjustment; gfloat old_vadjustment; /* border shadow style */ GtkShadowType shadow_type; /* Column Titles */ GdkRectangle column_title_area; GdkWindow *column_title_window; gboolean column_titles_visible; /* Row Titles */ GdkRectangle row_title_area; GdkWindow *row_title_window; gboolean row_titles_visible; /*scrollbars*/ GtkAdjustment *hadjustment; GtkAdjustment *vadjustment; /* xor GC for the verticle drag line */ GdkGC *xor_gc; /* gc for drawing unselected cells */ GdkGC *fg_gc; GdkGC *bg_gc; /* cursor used to indicate dragging */ GdkCursor *cursor_drag; /* the current x-pixel location of the xor-drag vline */ gint x_drag; /* the current y-pixel location of the xor-drag hline */ gint y_drag; /* current cell being dragged */ GtkSheetCell drag_cell; /* current range being dragged */ GtkSheetRange drag_range; /* clipped range */ GtkSheetRange clip_range; }; struct _GtkSheetClass { GtkContainerClass parent_class; void (*set_scroll_adjustments) (GtkSheet *sheet, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment); void (*select_row) (GtkSheet *sheet, gint row); void (*select_column) (GtkSheet *sheet, gint column); void (*select_range) (GtkSheet *sheet, GtkSheetRange *range); void (*clip_range) (GtkSheet *sheet, GtkSheetRange *clip_range); void (*resize_range) (GtkSheet *sheet, GtkSheetRange *old_range, GtkSheetRange *new_range); void (*move_range) (GtkSheet *sheet, GtkSheetRange *old_range, GtkSheetRange *new_range); gboolean (*traverse) (GtkSheet *sheet, gint row, gint column, gint *new_row, gint *new_column); gboolean (*deactivate) (GtkSheet *sheet, gint row, gint column); gboolean (*activate) (GtkSheet *sheet, gint row, gint column); void (*set_cell) (GtkSheet *sheet, gint row, gint column); void (*clear_cell) (GtkSheet *sheet, gint row, gint column); void (*changed) (GtkSheet *sheet, gint row, gint column); void (*new_column_width) (GtkSheet *sheet, gint col, guint width); void (*new_row_height) (GtkSheet *sheet, gint row, guint height); }; GType gtk_sheet_get_type (void); GtkType gtk_sheet_range_get_type (void); /* create a new sheet */ GtkWidget * gtk_sheet_new (guint rows, guint columns, const gchar *title); void gtk_sheet_construct (GtkSheet *sheet, guint rows, guint columns, const gchar *title); /* create a new browser sheet. It cells can not be edited */ GtkWidget * gtk_sheet_new_browser (guint rows, guint columns, const gchar *title); void gtk_sheet_construct_browser (GtkSheet *sheet, guint rows, guint columns, const gchar *title); /* create a new sheet with custom entry */ GtkWidget * gtk_sheet_new_with_custom_entry (guint rows, guint columns, const gchar *title, GtkType entry_type); void gtk_sheet_construct_with_custom_entry (GtkSheet *sheet, guint rows, guint columns, const gchar *title, GtkType entry_type); /* change scroll adjustments */ void gtk_sheet_set_hadjustment (GtkSheet *sheet, GtkAdjustment *adjustment); void gtk_sheet_set_vadjustment (GtkSheet *sheet, GtkAdjustment *adjustment); /* Change entry */ void gtk_sheet_change_entry (GtkSheet *sheet, GtkType entry_type); /* Returns sheet's entry widget */ GtkWidget * gtk_sheet_get_entry (GtkSheet *sheet); GtkWidget * gtk_sheet_get_entry_widget (GtkSheet *sheet); /* Returns sheet->state * Added by Steven Rostedt */ gint gtk_sheet_get_state (GtkSheet *sheet); /* Returns sheet's ranges * Added by Murray Cumming */ guint gtk_sheet_get_columns_count (GtkSheet *sheet); guint gtk_sheet_get_rows_count (GtkSheet *sheet); void gtk_sheet_get_visible_range (GtkSheet *sheet, GtkSheetRange *range); void gtk_sheet_set_selection_mode (GtkSheet *sheet, gint mode); void gtk_sheet_set_autoresize (GtkSheet *sheet, gboolean autoresize); gboolean gtk_sheet_autoresize (GtkSheet *sheet); void gtk_sheet_set_autoscroll (GtkSheet *sheet, gboolean autoscroll); gboolean gtk_sheet_autoscroll (GtkSheet *sheet); void gtk_sheet_set_clip_text (GtkSheet *sheet, gboolean clip_text); gboolean gtk_sheet_clip_text (GtkSheet *sheet); void gtk_sheet_set_justify_entry (GtkSheet *sheet, gboolean justify); gboolean gtk_sheet_justify_entry (GtkSheet *sheet); void gtk_sheet_set_locked (GtkSheet *sheet, gboolean lock); gboolean gtk_sheet_locked (GtkSheet *sheet); /* set sheet title */ void gtk_sheet_set_title (GtkSheet *sheet, const gchar *title); /* freeze all visual updates of the sheet. * Then thaw the sheet after you have made a number of changes. * The updates will occure in a more efficent way than if * you made them on a unfrozen sheet */ void gtk_sheet_freeze (GtkSheet *sheet); void gtk_sheet_thaw (GtkSheet *sheet); /* Background colors */ void gtk_sheet_set_background (GtkSheet *sheet, GdkColor *bg_color); void gtk_sheet_set_grid (GtkSheet *sheet, GdkColor *grid_color); void gtk_sheet_show_grid (GtkSheet *sheet, gboolean show); gboolean gtk_sheet_grid_visible (GtkSheet *sheet); /* set/get column title */ void gtk_sheet_set_column_title (GtkSheet * sheet, gint column, const gchar * title); const gchar * gtk_sheet_get_column_title (GtkSheet * sheet, gint column); /* set/get row title */ void gtk_sheet_set_row_title (GtkSheet * sheet, gint row, const gchar * title); const gchar * gtk_sheet_get_row_title (GtkSheet * sheet, gint row); /* set/get button label */ void gtk_sheet_row_button_add_label (GtkSheet *sheet, gint row, const gchar *label); void gtk_sheet_column_button_add_label (GtkSheet *sheet, gint column, const gchar *label); const gchar * gtk_sheet_row_button_get_label (GtkSheet *sheet, gint row); const gchar * gtk_sheet_column_button_get_label (GtkSheet *sheet, gint column); void gtk_sheet_row_button_justify (GtkSheet *sheet, gint row, GtkJustification justification); void gtk_sheet_column_button_justify (GtkSheet *sheet, gint column, GtkJustification justification); /* scroll the viewing area of the sheet to the given column * and row; row_align and col_align are between 0-1 representing the * location the row should appear on the screnn, 0.0 being top or left, * 1.0 being bottom or right; if row or column is negative then there * is no change */ void gtk_sheet_moveto (GtkSheet * sheet, gint row, gint column, gfloat row_align, gfloat col_align); /* resize column/row titles window */ void gtk_sheet_set_row_titles_width(GtkSheet *sheet, guint width); void gtk_sheet_set_column_titles_height(GtkSheet *sheet, guint height); /* show/hide column/row titles window */ void gtk_sheet_show_column_titles (GtkSheet *sheet); void gtk_sheet_show_row_titles (GtkSheet *sheet); void gtk_sheet_hide_column_titles (GtkSheet *sheet); void gtk_sheet_hide_row_titles (GtkSheet *sheet); gboolean gtk_sheet_column_titles_visible (GtkSheet *sheet); gboolean gtk_sheet_row_titles_visible (GtkSheet *sheet); /* set column button sensitivity. If sensitivity is TRUE it can be toggled, * otherwise it acts as a title */ void gtk_sheet_column_set_sensitivity (GtkSheet *sheet, gint column, gboolean sensitive); /* set sensitivity for all column buttons */ void gtk_sheet_columns_set_sensitivity (GtkSheet *sheet, gboolean sensitive); void gtk_sheet_columns_set_resizable (GtkSheet *sheet, gboolean resizable); gboolean gtk_sheet_columns_resizable (GtkSheet *sheet); /* set row button sensitivity. If sensitivity is TRUE can be toggled, * otherwise it acts as a title */ void gtk_sheet_row_set_sensitivity (GtkSheet *sheet, gint row, gboolean sensitive); /* set sensitivity for all row buttons */ void gtk_sheet_rows_set_sensitivity (GtkSheet *sheet, gboolean sensitive); void gtk_sheet_rows_set_resizable (GtkSheet *sheet, gboolean resizable); gboolean gtk_sheet_rows_resizable (GtkSheet *sheet); /* set column visibility. The default value is TRUE. If FALSE, the * column is hidden */ void gtk_sheet_column_set_visibility (GtkSheet *sheet, gint column, gboolean visible); void gtk_sheet_column_label_set_visibility (GtkSheet *sheet, gint column, gboolean visible); void gtk_sheet_columns_labels_set_visibility (GtkSheet *sheet, gboolean visible); /* set row visibility. The default value is TRUE. If FALSE, the * row is hidden */ void gtk_sheet_row_set_visibility (GtkSheet *sheet, gint row, gboolean visible); void gtk_sheet_row_label_set_visibility (GtkSheet *sheet, gint row, gboolean visible); void gtk_sheet_rows_labels_set_visibility (GtkSheet *sheet, gboolean visible); /* select the row. The range is then highlighted, and the bounds are stored * in sheet->range */ void gtk_sheet_select_row (GtkSheet * sheet, gint row); /* select the column. The range is then highlighted, and the bounds are stored * in sheet->range */ void gtk_sheet_select_column (GtkSheet * sheet, gint column); /* save selected range to "clipboard" */ void gtk_sheet_clip_range (GtkSheet *sheet, const GtkSheetRange *range); /* free clipboard */ void gtk_sheet_unclip_range (GtkSheet *sheet); gboolean gtk_sheet_in_clip (GtkSheet *sheet); /* get scrollbars adjustment */ GtkAdjustment * gtk_sheet_get_vadjustment (GtkSheet * sheet); GtkAdjustment * gtk_sheet_get_hadjustment (GtkSheet * sheet); /* highlight the selected range and store bounds in sheet->range */ void gtk_sheet_select_range (GtkSheet *sheet, const GtkSheetRange *range); /* obvious */ void gtk_sheet_unselect_range (GtkSheet *sheet); /* set active cell where the entry will be displayed * returns FALSE if current cell can't be deactivated or * requested cell can't be activated */ gboolean gtk_sheet_set_active_cell (GtkSheet *sheet, gint row, gint column); void gtk_sheet_get_active_cell (GtkSheet *sheet, gint *row, gint *column); /* set cell contents and allocate memory if needed */ void gtk_sheet_set_cell (GtkSheet *sheet, gint row, gint col, GtkJustification justification, const gchar *text); void gtk_sheet_set_cell_text (GtkSheet *sheet, gint row, gint col, const gchar *text); /* get cell contents */ gchar * gtk_sheet_cell_get_text (GtkSheet *sheet, gint row, gint col); /* clear cell contents */ void gtk_sheet_cell_clear (GtkSheet *sheet, gint row, gint col); /* clear cell contents and remove links */ void gtk_sheet_cell_delete (GtkSheet *sheet, gint row, gint col); /* clear range contents. If range==NULL the whole sheet will be cleared */ void gtk_sheet_range_clear (GtkSheet *sheet, const GtkSheetRange *range); /* clear range contents and remove links */ void gtk_sheet_range_delete (GtkSheet *sheet, const GtkSheetRange *range); /* get cell state: GTK_STATE_NORMAL, GTK_STATE_SELECTED */ GtkStateType gtk_sheet_cell_get_state (GtkSheet *sheet, gint row, gint col); /* Handles cell links */ void gtk_sheet_link_cell (GtkSheet *sheet, gint row, gint col, gpointer link); gpointer gtk_sheet_get_link (GtkSheet *sheet, gint row, gint col); void gtk_sheet_remove_link (GtkSheet *sheet, gint row, gint col); /* get row and column correspondig to the given position in the screen */ gboolean gtk_sheet_get_pixel_info (GtkSheet * sheet, gint x, gint y, gint * row, gint * column); /* get area of a given cell */ gboolean gtk_sheet_get_cell_area (GtkSheet *sheet, gint row, gint column, GdkRectangle *area); /* set column width */ void gtk_sheet_set_column_width (GtkSheet * sheet, gint column, guint width); /* set row height */ void gtk_sheet_set_row_height (GtkSheet * sheet, gint row, guint height); /* append ncols columns to the end of the sheet */ void gtk_sheet_add_column (GtkSheet *sheet, guint ncols); /* append nrows row to the end of the sheet */ void gtk_sheet_add_row (GtkSheet *sheet, guint nrows); /* insert nrows rows before the given row and pull right */ void gtk_sheet_insert_rows (GtkSheet *sheet, guint row, guint nrows); /* insert ncols columns before the given col and pull down */ void gtk_sheet_insert_columns (GtkSheet *sheet, guint col, guint ncols); /* delete nrows rows starting in row */ void gtk_sheet_delete_rows (GtkSheet *sheet, guint row, guint nrows); /* delete ncols columns starting in col */ void gtk_sheet_delete_columns (GtkSheet *sheet, guint col, guint ncols); /* set abckground color of the given range */ void gtk_sheet_range_set_background (GtkSheet *sheet, const GtkSheetRange *range, const GdkColor *color); /* set foreground color (text color) of the given range */ void gtk_sheet_range_set_foreground (GtkSheet *sheet, const GtkSheetRange *range, const GdkColor *color); /* set text justification (GTK_JUSTIFY_LEFT, RIGHT, CENTER) of the given range. * The default value is GTK_JUSTIFY_LEFT. If autoformat is on, the * default justification for numbers is GTK_JUSTIFY_RIGHT */ void gtk_sheet_range_set_justification (GtkSheet *sheet, const GtkSheetRange *range, GtkJustification justification); void gtk_sheet_column_set_justification (GtkSheet *sheet, gint column, GtkJustification justification); /* set if cell contents can be edited or not in the given range: * accepted values are TRUE or FALSE. */ void gtk_sheet_range_set_editable (GtkSheet *sheet, const GtkSheetRange *range, gint editable); /* set if cell contents are visible or not in the given range: * accepted values are TRUE or FALSE.*/ void gtk_sheet_range_set_visible (GtkSheet *sheet, const GtkSheetRange *range, gboolean visible); /* set cell border style in the given range. * mask values are CELL_LEFT_BORDER, CELL_RIGHT_BORDER, CELL_TOP_BORDER, * CELL_BOTTOM_BORDER * width is the width of the border line in pixels * line_style is the line_style for the border line */ void gtk_sheet_range_set_border (GtkSheet *sheet, const GtkSheetRange *range, gint mask, guint width, gint line_style); /* set border color for the given range */ void gtk_sheet_range_set_border_color (GtkSheet *sheet, const GtkSheetRange *range, const GdkColor *color); /* set font for the given range */ void gtk_sheet_range_set_font (GtkSheet *sheet, const GtkSheetRange *range, PangoFontDescription *font); /* get cell attributes of the given cell */ /* TRUE means that the cell is currently allocated */ gboolean gtk_sheet_get_attributes (GtkSheet *sheet, gint row, gint col, GtkSheetCellAttr *attributes); GtkSheetChild * gtk_sheet_put (GtkSheet *sheet, GtkWidget *widget, gint x, gint y); void gtk_sheet_attach_floating (GtkSheet *sheet, GtkWidget *widget, gint row, gint col); void gtk_sheet_attach_default (GtkSheet *sheet, GtkWidget *widget, gint row, gint col); void gtk_sheet_attach (GtkSheet *sheet, GtkWidget *widget, gint row, gint col, gint xoptions, gint yoptions, gint xpadding, gint ypadding); void gtk_sheet_move_child (GtkSheet *sheet, GtkWidget *widget, gint x, gint y); GtkSheetChild * gtk_sheet_get_child_at (GtkSheet *sheet, gint row, gint col); void gtk_sheet_button_attach (GtkSheet *sheet, GtkWidget *widget, gint row, gint col); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __GTK_SHEET_H__ */ gpsim-0.30.0/gui/gtkextra/gtkextra-marshal.h0000664000076400007640000002555413041763636015734 00000000000000 #ifndef __gtkextra_MARSHAL_H__ #define __gtkextra_MARSHAL_H__ #include G_BEGIN_DECLS /* BOOL:INT,INT,POINTER,POINTER (gtkextra-marshal.list:1) */ extern void gtkextra_BOOLEAN__INT_INT_POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__INT_INT_POINTER_POINTER gtkextra_BOOLEAN__INT_INT_POINTER_POINTER /* BOOL:BOXED,POINTER (gtkextra-marshal.list:2) */ extern void gtkextra_BOOLEAN__BOXED_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__BOXED_POINTER gtkextra_BOOLEAN__BOXED_POINTER /* BOOL:BOXED,STRING (gtkextra-marshal.list:3) */ extern void gtkextra_BOOLEAN__BOXED_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__BOXED_STRING gtkextra_BOOLEAN__BOXED_STRING /* BOOL:BOXED,BOXED (gtkextra-marshal.list:4) */ extern void gtkextra_BOOLEAN__BOXED_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__BOXED_BOXED gtkextra_BOOLEAN__BOXED_BOXED /* BOOL:BOXED,DOUBLE,DOUBLE (gtkextra-marshal.list:5) */ extern void gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__BOXED_DOUBLE_DOUBLE gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE /* BOOL:POINTER,POINTER (gtkextra-marshal.list:6) */ extern void gtkextra_BOOLEAN__POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__POINTER_POINTER gtkextra_BOOLEAN__POINTER_POINTER /* BOOL:POINTER,BOXED (gtkextra-marshal.list:7) */ extern void gtkextra_BOOLEAN__POINTER_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__POINTER_BOXED gtkextra_BOOLEAN__POINTER_BOXED /* BOOL:POINTER,STRING (gtkextra-marshal.list:8) */ extern void gtkextra_BOOLEAN__POINTER_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__POINTER_STRING gtkextra_BOOLEAN__POINTER_STRING /* BOOL:POINTER (gtkextra-marshal.list:9) */ extern void gtkextra_BOOLEAN__POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__POINTER gtkextra_BOOLEAN__POINTER /* BOOL:BOXED (gtkextra-marshal.list:10) */ extern void gtkextra_BOOLEAN__BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__BOXED gtkextra_BOOLEAN__BOXED /* BOOL:INT,INT (gtkextra-marshal.list:11) */ extern void gtkextra_BOOLEAN__INT_INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define gtkextra_BOOL__INT_INT gtkextra_BOOLEAN__INT_INT /* VOID:INT (gtkextra-marshal.list:12) */ #define gtkextra_VOID__INT g_cclosure_marshal_VOID__INT /* VOID:INT,STRING (gtkextra-marshal.list:13) */ extern void gtkextra_VOID__INT_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:BOXED (gtkextra-marshal.list:14) */ #define gtkextra_VOID__BOXED g_cclosure_marshal_VOID__BOXED /* VOID:VOID (gtkextra-marshal.list:15) */ #define gtkextra_VOID__VOID g_cclosure_marshal_VOID__VOID /* VOID:BOOL (gtkextra-marshal.list:16) */ #define gtkextra_VOID__BOOLEAN g_cclosure_marshal_VOID__BOOLEAN #define gtkextra_VOID__BOOL gtkextra_VOID__BOOLEAN /* VOID:POINTER (gtkextra-marshal.list:17) */ #define gtkextra_VOID__POINTER g_cclosure_marshal_VOID__POINTER /* VOID:INT,INT (gtkextra-marshal.list:18) */ extern void gtkextra_VOID__INT_INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:INT,POINTER (gtkextra-marshal.list:19) */ extern void gtkextra_VOID__INT_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:INT,BOXED (gtkextra-marshal.list:20) */ extern void gtkextra_VOID__INT_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:POINTER,POINTER (gtkextra-marshal.list:21) */ extern void gtkextra_VOID__POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:BOXED,POINTER (gtkextra-marshal.list:22) */ extern void gtkextra_VOID__BOXED_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:BOXED,BOXED (gtkextra-marshal.list:23) */ extern void gtkextra_VOID__BOXED_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:OBJECT,OBJECT (gtkextra-marshal.list:24) */ extern void gtkextra_VOID__OBJECT_OBJECT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:DOUBLE,DOUBLE,DOUBLE,DOUBLE (gtkextra-marshal.list:25) */ extern void gtkextra_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); G_END_DECLS #endif /* __gtkextra_MARSHAL_H__ */ gpsim-0.30.0/gui/gtkextra/gtkextra-marshal.c0000664000076400007640000010025713041763636015721 00000000000000#include "../config.h" #ifdef HAVE_GUI #include #ifdef G_ENABLE_DEBUG #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) #define g_marshal_value_peek_char(v) g_value_get_char (v) #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) #define g_marshal_value_peek_int(v) g_value_get_int (v) #define g_marshal_value_peek_uint(v) g_value_get_uint (v) #define g_marshal_value_peek_long(v) g_value_get_long (v) #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) #define g_marshal_value_peek_enum(v) g_value_get_enum (v) #define g_marshal_value_peek_flags(v) g_value_get_flags (v) #define g_marshal_value_peek_float(v) g_value_get_float (v) #define g_marshal_value_peek_double(v) g_value_get_double (v) #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) #define g_marshal_value_peek_param(v) g_value_get_param (v) #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) #define g_marshal_value_peek_object(v) g_value_get_object (v) #else /* !G_ENABLE_DEBUG */ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. * Do not access GValues directly in your code. Instead, use the * g_value_get_*() functions */ #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int #define g_marshal_value_peek_char(v) (v)->data[0].v_int #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint #define g_marshal_value_peek_int(v) (v)->data[0].v_int #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint #define g_marshal_value_peek_long(v) (v)->data[0].v_long #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 #define g_marshal_value_peek_enum(v) (v)->data[0].v_int #define g_marshal_value_peek_flags(v) (v)->data[0].v_uint #define g_marshal_value_peek_float(v) (v)->data[0].v_float #define g_marshal_value_peek_double(v) (v)->data[0].v_double #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer #endif /* !G_ENABLE_DEBUG */ /* BOOL:INT,INT,POINTER,POINTER (gtkextra-marshal.list:1) */ void gtkextra_BOOLEAN__INT_INT_POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_POINTER_POINTER) (gpointer data1, gint arg_1, gint arg_2, gpointer arg_3, gpointer arg_4, gpointer data2); register GMarshalFunc_BOOLEAN__INT_INT_POINTER_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 5); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__INT_INT_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_int (param_values + 2), g_marshal_value_peek_pointer (param_values + 3), g_marshal_value_peek_pointer (param_values + 4), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:BOXED,POINTER (gtkextra-marshal.list:2) */ void gtkextra_BOOLEAN__BOXED_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__BOXED_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:BOXED,STRING (gtkextra-marshal.list:3) */ void gtkextra_BOOLEAN__BOXED_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__BOXED_STRING callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__BOXED_STRING) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_string (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:BOXED,BOXED (gtkextra-marshal.list:4) */ void gtkextra_BOOLEAN__BOXED_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_BOXED) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__BOXED_BOXED callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_boxed (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:BOXED,DOUBLE,DOUBLE (gtkextra-marshal.list:5) */ void gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_DOUBLE_DOUBLE) (gpointer data1, gpointer arg_1, gdouble arg_2, gdouble arg_3, gpointer data2); register GMarshalFunc_BOOLEAN__BOXED_DOUBLE_DOUBLE callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 4); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__BOXED_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_double (param_values + 2), g_marshal_value_peek_double (param_values + 3), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:POINTER,POINTER (gtkextra-marshal.list:6) */ void gtkextra_BOOLEAN__POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__POINTER_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_pointer (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:POINTER,BOXED (gtkextra-marshal.list:7) */ void gtkextra_BOOLEAN__POINTER_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_BOXED) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__POINTER_BOXED callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__POINTER_BOXED) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_pointer (param_values + 1), g_marshal_value_peek_boxed (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:POINTER,STRING (gtkextra-marshal.list:8) */ void gtkextra_BOOLEAN__POINTER_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_STRING) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__POINTER_STRING callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__POINTER_STRING) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_pointer (param_values + 1), g_marshal_value_peek_string (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:POINTER (gtkextra-marshal.list:9) */ void gtkextra_BOOLEAN__POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1, gpointer arg_1, gpointer data2); register GMarshalFunc_BOOLEAN__POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 2); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_pointer (param_values + 1), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:BOXED (gtkextra-marshal.list:10) */ void gtkextra_BOOLEAN__BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer data1, gpointer arg_1, gpointer data2); register GMarshalFunc_BOOLEAN__BOXED callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 2); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__BOXED) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_boxed (param_values + 1), data2); g_value_set_boolean (return_value, v_return); } /* BOOL:INT,INT (gtkextra-marshal.list:11) */ void gtkextra_BOOLEAN__INT_INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT) (gpointer data1, gint arg_1, gint arg_2, gpointer data2); register GMarshalFunc_BOOLEAN__INT_INT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__INT_INT) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_int (param_values + 2), data2); g_value_set_boolean (return_value, v_return); } /* VOID:INT (gtkextra-marshal.list:12) */ /* VOID:INT,STRING (gtkextra-marshal.list:13) */ void gtkextra_VOID__INT_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT_STRING) (gpointer data1, gint arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__INT_STRING callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__INT_STRING) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_string (param_values + 2), data2); } /* VOID:BOXED (gtkextra-marshal.list:14) */ /* VOID:VOID (gtkextra-marshal.list:15) */ /* VOID:BOOL (gtkextra-marshal.list:16) */ /* VOID:POINTER (gtkextra-marshal.list:17) */ /* VOID:INT,INT (gtkextra-marshal.list:18) */ void gtkextra_VOID__INT_INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, gint arg_1, gint arg_2, gpointer data2); register GMarshalFunc_VOID__INT_INT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_int (param_values + 2), data2); } /* VOID:INT,POINTER (gtkextra-marshal.list:19) */ void gtkextra_VOID__INT_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1, gint arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__INT_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__INT_POINTER) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); } /* VOID:INT,BOXED (gtkextra-marshal.list:20) */ void gtkextra_VOID__INT_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT_BOXED) (gpointer data1, gint arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__INT_BOXED callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__INT_BOXED) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_boxed (param_values + 2), data2); } /* VOID:POINTER,POINTER (gtkextra-marshal.list:21) */ void gtkextra_VOID__POINTER_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__POINTER_POINTER) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__POINTER_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_pointer (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); } /* VOID:BOXED,POINTER (gtkextra-marshal.list:22) */ void gtkextra_VOID__BOXED_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__BOXED_POINTER) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__BOXED_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); } /* VOID:BOXED,BOXED (gtkextra-marshal.list:23) */ void gtkextra_VOID__BOXED_BOXED (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__BOXED_BOXED) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__BOXED_BOXED callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_boxed (param_values + 1), g_marshal_value_peek_boxed (param_values + 2), data2); } /* VOID:OBJECT,OBJECT (gtkextra-marshal.list:24) */ void gtkextra_VOID__OBJECT_OBJECT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__OBJECT_OBJECT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_object (param_values + 1), g_marshal_value_peek_object (param_values + 2), data2); } /* VOID:DOUBLE,DOUBLE,DOUBLE,DOUBLE (gtkextra-marshal.list:25) */ void gtkextra_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE) (gpointer data1, gdouble arg_1, gdouble arg_2, gdouble arg_3, gdouble arg_4, gpointer data2); register GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 5); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_double (param_values + 1), g_marshal_value_peek_double (param_values + 2), g_marshal_value_peek_double (param_values + 3), g_marshal_value_peek_double (param_values + 4), data2); } #endif // HAVE_GUI gpsim-0.30.0/gui/gtkextra/gtkitementry.c0000664000076400007640000020576213045306453015172 00000000000000/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include "gtkitementry.h" #define MIN_ENTRY_WIDTH 150 #define DRAW_TIMEOUT 20 #define INNER_BORDER 0 /* Initial size of buffer, in bytes */ #define MIN_SIZE 16 /* Maximum size of text buffer, in bytes */ #define MAX_SIZE G_MAXUSHORT typedef enum { CURSOR_STANDARD, CURSOR_DND } CursorType; /* GObject, GtkObject methods */ static void gtk_item_entry_class_init (GtkItemEntryClass *klass); static void gtk_item_entry_init (GtkItemEntry *entry); static void gtk_item_entry_editable_init (GtkEditableClass *iface); /* GtkWidget methods */ static void gtk_entry_realize (GtkWidget *widget); static void gtk_entry_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static void gtk_entry_draw_frame (GtkWidget *widget); static gint gtk_entry_expose (GtkWidget *widget, GdkEventExpose *event); static void gtk_entry_grab_focus (GtkWidget *widget); static void gtk_entry_style_set (GtkWidget *widget, GtkStyle *previous_style); static void gtk_entry_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir); static void gtk_entry_state_changed (GtkWidget *widget, GtkStateType previous_state); /* GtkEditable method implementations */ static void gtk_entry_insert_text (GtkEditable *editable, const gchar *new_text, gint new_text_length, gint *position); static void gtk_entry_delete_text (GtkEditable *editable, gint start_pos, gint end_pos); static void gtk_entry_real_set_position (GtkEditable *editable, gint position); static gint gtk_entry_get_position (GtkEditable *editable); /* Default signal handlers */ static void gtk_entry_real_insert_text (GtkEditable *editable, const gchar *new_text, gint new_text_length, gint *position); static void gtk_entry_real_delete_text (GtkEditable *editable, gint start_pos, gint end_pos); static void gtk_entry_move_cursor (GtkEntry *entry, GtkMovementStep step, gint count, gboolean extend_selection); static void gtk_entry_insert_at_cursor (GtkEntry *entry, const gchar *str); static void gtk_entry_delete_from_cursor (GtkEntry *entry, GtkDeleteType type, gint count); /* IM Context Callbacks */ static void gtk_entry_commit_cb (GtkIMContext *context, const gchar *str, GtkEntry *entry); static void gtk_entry_preedit_changed_cb (GtkIMContext *context, GtkEntry *entry); static gboolean gtk_entry_retrieve_surrounding_cb (GtkIMContext *context, GtkEntry *entry); static gboolean gtk_entry_delete_surrounding_cb (GtkIMContext *context, gint offset, gint n_chars, GtkEntry *entry); /* Internal routines */ static void gtk_entry_enter_text (GtkEntry *entry, const gchar *str); static void gtk_entry_set_positions (GtkEntry *entry, gint current_pos, gint selection_bound); static void gtk_entry_draw_text (GtkEntry *entry); static void gtk_entry_draw_cursor (GtkEntry *entry, CursorType type); static PangoLayout *gtk_entry_ensure_layout (GtkEntry *entry, gboolean include_preedit); static void gtk_entry_queue_draw (GtkEntry *entry); static void gtkextra_entry_reset_im_context (GtkEntry *entry); static void gtk_entry_recompute (GtkEntry *entry); static void gtk_entry_get_cursor_locations (GtkEntry *entry, CursorType type, gint *strong_x, gint *weak_x); static void gtk_entry_adjust_scroll (GtkEntry *entry); static gint gtk_entry_move_visually (GtkEntry *editable, gint start, gint count); static gint gtk_entry_move_logically (GtkEntry *entry, gint start, gint count); static gint gtk_entry_move_forward_word (GtkEntry *entry, gint start); static gint gtk_entry_move_backward_word (GtkEntry *entry, gint start); static void gtk_entry_delete_whitespace (GtkEntry *entry); static char * gtk_entry_get_public_chars (GtkEntry *entry, gint start, gint end); static void gtk_entry_update_primary_selection (GtkEntry *entry); static void gtk_entry_state_changed (GtkWidget *widget, GtkStateType previous_state); static void gtk_entry_check_cursor_blink (GtkEntry *entry); static void gtk_entry_pend_cursor_blink (GtkEntry *entry); static void get_text_area_size (GtkEntry *entry, gint *x, gint *y, gint *width, gint *height); static void get_widget_window_size (GtkEntry *entry, gint *x, gint *y, gint *width, gint *height); static GtkEntryClass *parent_class = NULL; #ifdef GTK_TYPE_ENTRY_BUFFER // In GTK+ 2.18, changes were made to GtkEntry. This caused gtk+extra // to crash. So from 2.18 call the appropriate buffer routines in GTK+ // gtk/gtkentrybuffer.c. // // rrankin AT ihug DOT com DOT au 21/12/09 // typedef struct _GtkEntryPrivate GtkEntryPrivate; struct _GtkEntryPrivate { GtkEntryBuffer* buffer; // The remainder of this structure has been truncated }; #define GTK_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY, GtkEntryPrivate)) #endif GtkType gtk_item_entry_get_type (void) { static GtkType item_entry_type = 0; if (!item_entry_type) { static const GtkTypeInfo item_entry_info = { "GtkItemEntry", sizeof (GtkItemEntry), sizeof (GtkItemEntryClass), (GtkClassInitFunc) gtk_item_entry_class_init, (GtkObjectInitFunc) gtk_item_entry_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; static const GInterfaceInfo item_editable_info = { (GInterfaceInitFunc) gtk_item_entry_editable_init, /* interface_init */ NULL, /* interface_finalize */ NULL /* interface_data */ }; item_entry_type = gtk_type_unique (GTK_TYPE_ENTRY, &item_entry_info); g_type_add_interface_static (item_entry_type, GTK_TYPE_EDITABLE, &item_editable_info); } return item_entry_type; } static void gtk_item_entry_class_init (GtkItemEntryClass *class) { GtkWidgetClass *widget_class; GtkEntryClass *entry_class; widget_class = (GtkWidgetClass*) class; parent_class = gtk_type_class (GTK_TYPE_ENTRY); entry_class = (GtkEntryClass *) class; widget_class->realize = gtk_entry_realize; widget_class->size_request = gtk_entry_size_request; widget_class->size_allocate = gtk_entry_size_allocate; widget_class->expose_event = gtk_entry_expose; widget_class->grab_focus = gtk_entry_grab_focus; widget_class->style_set = gtk_entry_style_set; widget_class->direction_changed = gtk_entry_direction_changed; widget_class->state_changed = gtk_entry_state_changed; entry_class->move_cursor = gtk_entry_move_cursor; entry_class->insert_at_cursor = gtk_entry_insert_at_cursor; entry_class->delete_from_cursor = gtk_entry_delete_from_cursor; } static void gtk_item_entry_editable_init (GtkEditableClass *iface) { iface->do_insert_text = gtk_entry_insert_text; iface->do_delete_text = gtk_entry_delete_text; iface->insert_text = gtk_entry_real_insert_text; iface->delete_text = gtk_entry_real_delete_text; iface->set_position = gtk_entry_real_set_position; iface->get_position = gtk_entry_get_position; } static void gtk_item_entry_init (GtkItemEntry *entry) { entry->justification = GTK_JUSTIFY_LEFT; entry->text_max_size = 0; entry->item_text_size = 0; entry->item_n_bytes = 0; GTK_ENTRY(entry)->has_frame = FALSE; g_object_unref(G_OBJECT(GTK_ENTRY(entry)->im_context)); GTK_ENTRY(entry)->im_context = gtk_im_multicontext_new (); g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "commit", G_CALLBACK (gtk_entry_commit_cb), entry); g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "preedit_changed", G_CALLBACK (gtk_entry_preedit_changed_cb), entry); g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "retrieve_surrounding", G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry); g_signal_connect (G_OBJECT (GTK_ENTRY(entry)->im_context), "delete_surrounding", G_CALLBACK (gtk_entry_delete_surrounding_cb), entry); } static void gtk_entry_realize (GtkWidget *widget) { GtkEntry *entry; GdkWindowAttr attributes; gint attributes_mask; GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); entry = GTK_ENTRY (widget); attributes.window_type = GDK_WINDOW_CHILD; get_widget_window_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, entry); get_text_area_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); attributes.cursor = gdk_cursor_new (GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (entry->text_area, entry); gdk_cursor_unref (attributes.cursor); widget->style = gtk_style_attach (widget->style, widget->window); gdk_window_set_background (widget->window, &widget->style->bg[GTK_WIDGET_STATE(widget)]); gdk_window_set_background (entry->text_area, &widget->style->bg[GTK_WIDGET_STATE (widget)]); gdk_window_show (entry->text_area); gtk_im_context_set_client_window (entry->im_context, entry->text_area); gtk_entry_adjust_scroll (entry); } static void get_borders (GtkEntry *entry, gint *xborder, gint *yborder) { GtkWidget *widget = GTK_WIDGET (entry); gint focus_width; gboolean interior_focus; gtk_widget_style_get (widget, "interior-focus", &interior_focus, "focus-line-width", &focus_width, NULL); if (entry->has_frame) { *xborder = widget->style->xthickness; *yborder = widget->style->ythickness; } else { *xborder = 0; *yborder = 0; } if (!interior_focus) { *xborder += focus_width; *yborder += focus_width; } } static void gtk_entry_size_request (GtkWidget *widget, GtkRequisition *requisition) { GtkEntry *entry = GTK_ENTRY (widget); PangoFontMetrics *metrics; gint xborder, yborder; PangoContext *context; context = gtk_widget_get_pango_context (widget); metrics = pango_context_get_metrics (context, widget->style->font_desc, pango_context_get_language (context)); entry->ascent = pango_font_metrics_get_ascent (metrics); entry->descent = pango_font_metrics_get_descent (metrics); get_borders (entry, &xborder, &yborder); xborder += INNER_BORDER; yborder += INNER_BORDER; if (entry->width_chars < 0) requisition->width = MIN_ENTRY_WIDTH + xborder * 2; else { gint char_width = pango_font_metrics_get_approximate_char_width (metrics); requisition->width = PANGO_PIXELS (char_width) * entry->width_chars + xborder * 2; } requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2; pango_font_metrics_unref (metrics); } static void get_text_area_size (GtkEntry *entry, gint *x, gint *y, gint *width, gint *height) { gint xborder, yborder; GtkRequisition requisition; GtkWidget *widget = GTK_WIDGET (entry); gtk_widget_get_child_requisition (widget, &requisition); get_borders (entry, &xborder, &yborder); if (x) *x = xborder; if (y) *y = yborder; if (width) *width = GTK_WIDGET (entry)->allocation.width - xborder * 2; if (height) *height = requisition.height - yborder * 2; } static void get_widget_window_size (GtkEntry *entry, gint *x, gint *y, gint *width, gint *height) { GtkRequisition requisition; GtkWidget *widget = GTK_WIDGET (entry); gtk_widget_get_child_requisition (widget, &requisition); if (x) *x = widget->allocation.x; if (y) { if (entry->is_cell_renderer) *y = widget->allocation.y; else *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2; } if (width) *width = widget->allocation.width; if (height) { if (entry->is_cell_renderer) *height = widget->allocation.height; else *height = requisition.height; } } static void gtk_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GtkEntry *entry = GTK_ENTRY (widget); GtkItemEntry *ientry = GTK_ITEM_ENTRY (widget); if(ientry->text_max_size > 0) allocation->width = MIN(ientry->text_max_size, allocation->width); widget->allocation = *allocation; if (GTK_WIDGET_REALIZED (widget)) { /* We call gtk_widget_get_child_requisition, since we want (for * backwards compatibility reasons) the realization here to * be affected by the usize of the entry, if set */ gint x, y, width, height; get_widget_window_size (entry, &x, &y, &width, &height); gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height); get_text_area_size (entry, &x, &y, &width, &height); gdk_window_move_resize (entry->text_area, 0, allocation->height - height, allocation->width, height); gtk_entry_recompute (entry); } } static void gtk_entry_draw_frame (GtkWidget *widget) { } static gint gtk_entry_expose (GtkWidget *widget, GdkEventExpose *event) { GtkEntry *entry = GTK_ENTRY (widget); if (widget->window == event->window) gtk_entry_draw_frame (widget); else if (entry->text_area == event->window) { gint area_width, area_height; get_text_area_size (entry, NULL, NULL, &area_width, &area_height); gdk_draw_rectangle (entry->text_area, widget->style->bg_gc[GTK_WIDGET_STATE(widget)], TRUE, 0, 0, area_width, area_height); if ((entry->visible || entry->invisible_char != 0) && GTK_WIDGET_HAS_FOCUS (widget) && entry->selection_bound == entry->current_pos && entry->cursor_visible) gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD); if (entry->dnd_position != -1) gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_DND); gtk_entry_draw_text (GTK_ENTRY (widget)); } return FALSE; } static void gtk_entry_grab_focus (GtkWidget *widget) { GtkEntry *entry = GTK_ENTRY (widget); gboolean select_on_focus; GTK_WIDGET_CLASS (parent_class)->grab_focus (widget); g_object_get (G_OBJECT (gtk_settings_get_default ()), "gtk-entry-select-on-focus", &select_on_focus, NULL); if (select_on_focus && entry->editable && !entry->in_click) gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1); } static void gtk_entry_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir) { GtkEntry *entry = GTK_ENTRY (widget); gtk_entry_recompute (entry); GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir); } static void gtk_entry_state_changed (GtkWidget *widget, GtkStateType previous_state) { GtkEntry *entry = GTK_ENTRY (widget); if (GTK_WIDGET_REALIZED (widget)) { gdk_window_set_background (widget->window, &widget->style->bg[GTK_WIDGET_STATE (widget)]); gdk_window_set_background (entry->text_area, &widget->style->bg[GTK_WIDGET_STATE (widget)]); } if (!GTK_WIDGET_IS_SENSITIVE (widget)) { /* Clear any selection */ gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos); } gtk_widget_queue_clear (widget); } /* GtkEditable method implementations */ static void gtk_entry_insert_text (GtkEditable *editable, const gchar *new_text, gint new_text_length, gint *position) { GtkEntry *entry = GTK_ENTRY (editable); gchar buf[64]; gchar *text; if (*position < 0 || *position > entry->text_length) *position = entry->text_length; g_object_ref (G_OBJECT (editable)); if (new_text_length <= 63) text = buf; else text = g_new (gchar, new_text_length + 1); text[new_text_length] = '\0'; strncpy (text, new_text, new_text_length); g_signal_emit_by_name (editable, "insert_text", text, new_text_length, position); if (new_text_length > 63) g_free (text); g_object_unref (G_OBJECT (editable)); } static void gtk_entry_delete_text (GtkEditable *editable, gint start_pos, gint end_pos) { GtkEntry *entry = GTK_ENTRY (editable); if (end_pos < 0 || end_pos > entry->text_length) end_pos = entry->text_length; if (start_pos < 0) start_pos = 0; if (start_pos > end_pos) start_pos = end_pos; g_object_ref (G_OBJECT (editable)); g_signal_emit_by_name (editable, "delete_text", start_pos, end_pos); g_object_unref (G_OBJECT (editable)); } static void gtk_entry_style_set (GtkWidget *widget, GtkStyle *previous_style) { GtkEntry *entry = GTK_ENTRY (widget); if (previous_style && GTK_WIDGET_REALIZED (widget)) { gtk_entry_recompute (entry); gdk_window_set_background (widget->window, &widget->style->bg[GTK_WIDGET_STATE(widget)]); gdk_window_set_background (entry->text_area, &widget->style->bg[GTK_WIDGET_STATE (widget)]); } } static void gtk_entry_real_set_position (GtkEditable *editable, gint position) { GtkEntry *entry = GTK_ENTRY (editable); if (position < 0 || position > entry->text_length) position = entry->text_length; if (position != entry->current_pos || position != entry->selection_bound) { gtkextra_entry_reset_im_context (entry); gtk_entry_set_positions (entry, position, position); } } static gint gtk_entry_get_position (GtkEditable *editable) { return GTK_ENTRY (editable)->current_pos; } #ifdef GTK_TYPE_ENTRY_BUFFER // // Get_buffer copied from gtk/gtkentry.c // static GtkEntryBuffer* get_buffer (GtkEntry *entry) { GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); if (priv->buffer == NULL) { GtkEntryBuffer *buffer; buffer = gtk_entry_buffer_new (NULL, 0); gtk_entry_set_buffer (entry, buffer); g_object_unref (buffer); } return priv->buffer; } #endif //GTK_TYPE_ENTRY_BUFFER /* Default signal handlers */ static void gtk_entry_real_insert_text (GtkEditable *editable, const gchar *new_text, gint new_text_length, gint *position) { gint n_chars; GtkItemEntry *ientry = GTK_ITEM_ENTRY (editable); GtkEntry *entry = GTK_ENTRY (editable); if (new_text_length < 0) new_text_length = strlen (new_text); n_chars = g_utf8_strlen (new_text, new_text_length); if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length) { gdk_beep (); n_chars = entry->text_max_length - entry->text_length; new_text_length = g_utf8_offset_to_pointer (new_text, n_chars) - new_text; } #ifdef GTK_TYPE_ENTRY_BUFFER GtkEntryBuffer *buffer = get_buffer(entry); n_chars = gtk_entry_buffer_insert_text(buffer, *position, new_text, new_text_length); #else if (new_text_length + ientry->item_n_bytes + 1 > ientry->item_text_size) { while (new_text_length + ientry->item_n_bytes + 1 > ientry->item_text_size) { if (ientry->item_text_size == 0) ientry->item_text_size = MIN_SIZE; else { if (2 * (guint)ientry->item_text_size < MAX_SIZE && 2 * (guint)ientry->item_text_size > ientry->item_text_size) ientry->item_text_size *= 2; else { ientry->item_text_size = MAX_SIZE; if (new_text_length > (gint)ientry->item_text_size - (gint)ientry->item_n_bytes - 1) { new_text_length = (gint)ientry->item_text_size - (gint)ientry->item_n_bytes - 1; new_text_length = g_utf8_find_prev_char (new_text, new_text + new_text_length + 1) - new_text; n_chars = g_utf8_strlen (new_text, new_text_length); } break; } } } entry->text = g_realloc (entry->text, ientry->item_text_size); } gint index; index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text; g_memmove (entry->text + index + new_text_length, entry->text + index, ientry->item_n_bytes - index); memcpy (entry->text + index, new_text, new_text_length); #endif //GTK_TYPE_ENTRY_BUFFER ientry->item_n_bytes += new_text_length; entry->text_length += n_chars; /* NUL terminate for safety and convenience */ entry->text[ientry->item_n_bytes] = '\0'; if (entry->current_pos > *position) entry->current_pos += n_chars; if (entry->selection_bound > *position) entry->selection_bound += n_chars; *position += n_chars; gtk_entry_recompute (entry); g_signal_emit_by_name (editable, "changed"); g_object_notify (G_OBJECT (editable), "text"); } static void gtk_entry_real_delete_text (GtkEditable *editable, gint start_pos, gint end_pos) { GtkEntry *entry = GTK_ENTRY (editable); if (start_pos < 0) start_pos = 0; if (end_pos < 0 || end_pos > entry->text_length) end_pos = entry->text_length; if (start_pos < end_pos) { #ifdef GTK_TYPE_ENTRY_BUFFER GtkEntryBuffer *buffer = get_buffer(entry); gtk_entry_buffer_delete_text (buffer, start_pos, end_pos-start_pos); #else GtkItemEntry *ientry = GTK_ITEM_ENTRY (editable); gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text; gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text; g_memmove (entry->text + start_index, entry->text + end_index, ientry->item_n_bytes + 1 - end_index); entry->text_length -= (end_pos - start_pos); ientry->item_n_bytes -= (end_index - start_index); if (entry->current_pos > start_pos) entry->current_pos -= MIN (entry->current_pos, end_pos) - start_pos; if (entry->selection_bound > start_pos) entry->selection_bound -= MIN (entry->selection_bound, end_pos) - start_pos; #endif // GTK_TYPE_ENTRY_BUFFER /* We might have deleted the selection */ gtk_entry_update_primary_selection (entry); gtk_entry_recompute (entry); g_signal_emit_by_name (editable, "changed"); g_object_notify (G_OBJECT (editable), "text"); } } /* Compute the X position for an offset that corresponds to the "more important * cursor position for that offset. We use this when trying to guess to which * end of the selection we should go to when the user hits the left or * right arrow key. */ static gint get_better_cursor_x (GtkEntry *entry, gint offset) { GtkTextDirection keymap_direction = (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry)); gboolean split_cursor; PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE); gint index = g_utf8_offset_to_pointer (entry->text, offset) - entry->text; PangoRectangle strong_pos, weak_pos; g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)), "gtk-split-cursor", &split_cursor, NULL); pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos); if (split_cursor) return strong_pos.x / PANGO_SCALE; else return (keymap_direction == widget_direction) ? strong_pos.x / PANGO_SCALE : weak_pos.x / PANGO_SCALE; } static void gtk_entry_move_cursor (GtkEntry *entry, GtkMovementStep step, gint count, gboolean extend_selection) { gint new_pos = entry->current_pos; gtkextra_entry_reset_im_context (entry); if (entry->current_pos != entry->selection_bound && !extend_selection) { /* If we have a current selection and aren't extending it, move to the * start/or end of the selection as appropriate */ switch (step) { case GTK_MOVEMENT_VISUAL_POSITIONS: { gint current_x = get_better_cursor_x (entry, entry->current_pos); gint bound_x = get_better_cursor_x (entry, entry->selection_bound); if (count < 0) new_pos = current_x < bound_x ? entry->current_pos : entry->selection_bound; else new_pos = current_x > bound_x ? entry->current_pos : entry->selection_bound; break; } case GTK_MOVEMENT_LOGICAL_POSITIONS: case GTK_MOVEMENT_WORDS: if (count < 0) new_pos = MIN (entry->current_pos, entry->selection_bound); else new_pos = MAX (entry->current_pos, entry->selection_bound); break; case GTK_MOVEMENT_DISPLAY_LINE_ENDS: case GTK_MOVEMENT_PARAGRAPH_ENDS: case GTK_MOVEMENT_BUFFER_ENDS: new_pos = count < 0 ? 0 : entry->text_length; break; case GTK_MOVEMENT_DISPLAY_LINES: case GTK_MOVEMENT_PARAGRAPHS: case GTK_MOVEMENT_PAGES: case GTK_MOVEMENT_HORIZONTAL_PAGES: break; } } else { switch (step) { case GTK_MOVEMENT_LOGICAL_POSITIONS: new_pos = gtk_entry_move_logically (entry, new_pos, count); break; case GTK_MOVEMENT_VISUAL_POSITIONS: new_pos = gtk_entry_move_visually (entry, new_pos, count); break; case GTK_MOVEMENT_WORDS: while (count > 0) { new_pos = gtk_entry_move_forward_word (entry, new_pos); count--; } while (count < 0) { new_pos = gtk_entry_move_backward_word (entry, new_pos); count++; } break; case GTK_MOVEMENT_DISPLAY_LINE_ENDS: case GTK_MOVEMENT_PARAGRAPH_ENDS: case GTK_MOVEMENT_BUFFER_ENDS: new_pos = count < 0 ? 0 : entry->text_length; break; case GTK_MOVEMENT_DISPLAY_LINES: case GTK_MOVEMENT_PARAGRAPHS: case GTK_MOVEMENT_PAGES: case GTK_MOVEMENT_HORIZONTAL_PAGES: break; } } if (extend_selection) gtk_editable_select_region (GTK_EDITABLE (entry), entry->selection_bound, new_pos); else gtk_editable_set_position (GTK_EDITABLE (entry), new_pos); gtk_entry_pend_cursor_blink (entry); } static void gtk_entry_insert_at_cursor (GtkEntry *entry, const gchar *str) { GtkEditable *editable = GTK_EDITABLE (entry); gint pos = entry->current_pos; if (entry->editable) { gtkextra_entry_reset_im_context (entry); gtk_editable_insert_text (editable, str, -1, &pos); gtk_editable_set_position (editable, pos); } } static void gtk_entry_delete_from_cursor (GtkEntry *entry, GtkDeleteType type, gint count) { GtkEditable *editable = GTK_EDITABLE (entry); gint start_pos = entry->current_pos; gint end_pos = entry->current_pos; gtkextra_entry_reset_im_context (entry); if (!entry->editable) return; if (entry->selection_bound != entry->current_pos) { gtk_editable_delete_selection (editable); return; } switch (type) { case GTK_DELETE_CHARS: end_pos = gtk_entry_move_logically (entry, entry->current_pos, count); gtk_editable_delete_text (editable, MIN (start_pos, end_pos), MAX (start_pos, end_pos)); break; case GTK_DELETE_WORDS: if (count < 0) { /* Move to end of current word, or if not on a word, end of previous word */ end_pos = gtk_entry_move_backward_word (entry, end_pos); end_pos = gtk_entry_move_forward_word (entry, end_pos); } else if (count > 0) { /* Move to beginning of current word, or if not on a word, begining of next word */ start_pos = gtk_entry_move_forward_word (entry, start_pos); start_pos = gtk_entry_move_backward_word (entry, start_pos); } /* Fall through */ case GTK_DELETE_WORD_ENDS: while (count < 0) { start_pos = gtk_entry_move_backward_word (entry, start_pos); count++; } while (count > 0) { end_pos = gtk_entry_move_forward_word (entry, end_pos); count--; } gtk_editable_delete_text (editable, start_pos, end_pos); break; case GTK_DELETE_DISPLAY_LINE_ENDS: case GTK_DELETE_PARAGRAPH_ENDS: if (count < 0) gtk_editable_delete_text (editable, 0, entry->current_pos); else gtk_editable_delete_text (editable, entry->current_pos, -1); break; case GTK_DELETE_DISPLAY_LINES: case GTK_DELETE_PARAGRAPHS: gtk_editable_delete_text (editable, 0, -1); break; case GTK_DELETE_WHITESPACE: gtk_entry_delete_whitespace (entry); break; } gtk_entry_pend_cursor_blink (entry); } /* IM Context Callbacks */ static void gtk_entry_commit_cb (GtkIMContext *context, const gchar *str, GtkEntry *entry) { gtk_entry_enter_text (entry, str); } static void gtk_entry_preedit_changed_cb (GtkIMContext *context, GtkEntry *entry) { gchar *preedit_string; gint cursor_pos; gtk_im_context_get_preedit_string (entry->im_context, &preedit_string, NULL, &cursor_pos); entry->preedit_length = strlen (preedit_string); cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); entry->preedit_cursor = cursor_pos; g_free (preedit_string); gtk_entry_recompute (entry); } static gboolean gtk_entry_retrieve_surrounding_cb (GtkIMContext *context, GtkEntry *entry) { GtkItemEntry *ientry = GTK_ITEM_ENTRY (entry); gtk_im_context_set_surrounding (context, entry->text, ientry->item_n_bytes, g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text); return TRUE; } static gboolean gtk_entry_delete_surrounding_cb (GtkIMContext *slave, gint offset, gint n_chars, GtkEntry *entry) { gtk_editable_delete_text (GTK_EDITABLE (entry), entry->current_pos + offset, entry->current_pos + offset + n_chars); return TRUE; } /* Internal functions */ /* Used for im_commit_cb and inserting Unicode chars */ static void gtk_entry_enter_text (GtkEntry *entry, const gchar *str) { GtkEditable *editable = GTK_EDITABLE (entry); gint tmp_pos; if (gtk_editable_get_selection_bounds (editable, NULL, NULL)) gtk_editable_delete_selection (editable); else { if (entry->overwrite_mode) gtk_entry_delete_from_cursor (entry, GTK_DELETE_CHARS, 1); } tmp_pos = entry->current_pos; gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos); gtk_editable_set_position (editable, tmp_pos); } /* All changes to entry->current_pos and entry->selection_bound * should go through this function. */ static void gtk_entry_set_positions (GtkEntry *entry, gint current_pos, gint selection_bound) { gboolean changed = FALSE; g_object_freeze_notify (G_OBJECT (entry)); if (current_pos != -1 && entry->current_pos != current_pos) { entry->current_pos = current_pos; changed = TRUE; g_object_notify (G_OBJECT (entry), "cursor_position"); } if (selection_bound != -1 && entry->selection_bound != selection_bound) { entry->selection_bound = selection_bound; changed = TRUE; g_object_notify (G_OBJECT (entry), "selection_bound"); } g_object_thaw_notify (G_OBJECT (entry)); if (changed) gtk_entry_recompute (entry); } static void gtk_entry_reset_layout (GtkEntry *entry) { if (entry->cached_layout) { g_object_unref (G_OBJECT (entry->cached_layout)); entry->cached_layout = NULL; } } static void update_im_cursor_location (GtkEntry *entry) { GdkRectangle area; gint strong_x; gint strong_xoffset; gint x, y, area_width, area_height; gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL) ; get_text_area_size (entry, &x, &y, &area_width, &area_height); strong_xoffset = strong_x - entry->scroll_offset; if (strong_xoffset < 0) { strong_xoffset = 0; } else if (strong_xoffset > area_width) { strong_xoffset = area_width; } area.x = x + strong_xoffset; area.y = y + area_height; area.width = area_width; area.height = area_height; gtk_im_context_set_cursor_location (entry->im_context, &area); } static gboolean recompute_idle_func (gpointer data) { GtkEntry *entry; GDK_THREADS_ENTER (); entry = GTK_ENTRY (data); gtk_entry_adjust_scroll (entry); gtk_entry_queue_draw (entry); entry->recompute_idle = FALSE; update_im_cursor_location (entry); GDK_THREADS_LEAVE (); return FALSE; } static void gtk_entry_recompute (GtkEntry *entry) { gtk_entry_reset_layout (entry); gtk_entry_check_cursor_blink (entry); if (!entry->recompute_idle) { entry->recompute_idle = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */ recompute_idle_func, entry, NULL); } } static void append_char (GString *str, gunichar ch, gint count) { gint i; gint char_len; gchar buf[7]; char_len = g_unichar_to_utf8 (ch, buf); i = 0; while (i < count) { g_string_append_len (str, buf, char_len); ++i; } } static PangoLayout * gtk_entry_create_layout (GtkEntry *entry, gboolean include_preedit) { GtkItemEntry *ientry = GTK_ITEM_ENTRY (entry); PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (entry), NULL); PangoAttrList *tmp_attrs = pango_attr_list_new (); gchar *preedit_string = NULL; gint preedit_length = 0; PangoAttrList *preedit_attrs = NULL; pango_layout_set_single_paragraph_mode (layout, TRUE); if (include_preedit) { gtk_im_context_get_preedit_string (entry->im_context, &preedit_string, &preedit_attrs, NULL); preedit_length = entry->preedit_length; } if (preedit_length) { GString *tmp_string = g_string_new (NULL); gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text; if (entry->visible) { g_string_prepend_len (tmp_string, entry->text, ientry->item_n_bytes); g_string_insert (tmp_string, cursor_index, preedit_string); } else { gint ch_len; gint preedit_len_chars; gunichar invisible_char; ch_len = g_utf8_strlen (entry->text, ientry->item_n_bytes); preedit_len_chars = g_utf8_strlen (preedit_string, -1); ch_len += preedit_len_chars; if (entry->invisible_char != 0) invisible_char = entry->invisible_char; else invisible_char = ' '; /* just pick a char */ append_char (tmp_string, invisible_char, ch_len); /* Fix cursor index to point to invisible char corresponding * to the preedit, fix preedit_length to be the length of * the invisible chars representing the preedit */ cursor_index = g_utf8_offset_to_pointer (tmp_string->str, entry->current_pos) - tmp_string->str; preedit_length = preedit_len_chars * g_unichar_to_utf8 (invisible_char, NULL); } pango_layout_set_text (layout, tmp_string->str, tmp_string->len); pango_attr_list_splice (tmp_attrs, preedit_attrs, cursor_index, preedit_length); g_string_free (tmp_string, TRUE); } else { if (entry->visible) { pango_layout_set_text (layout, entry->text, ientry->item_n_bytes); } else { GString *str = g_string_new (NULL); gunichar invisible_char; if (entry->invisible_char != 0) invisible_char = entry->invisible_char; else invisible_char = ' '; /* just pick a char */ append_char (str, invisible_char, entry->text_length); pango_layout_set_text (layout, str->str, str->len); g_string_free (str, TRUE); } } pango_layout_set_attributes (layout, tmp_attrs); if (preedit_string) g_free (preedit_string); if (preedit_attrs) pango_attr_list_unref (preedit_attrs); pango_attr_list_unref (tmp_attrs); return layout; } static PangoLayout * gtk_entry_ensure_layout (GtkEntry *entry, gboolean include_preedit) { if (entry->preedit_length > 0 && !include_preedit != !entry->cache_includes_preedit) gtk_entry_reset_layout (entry); if (!entry->cached_layout) { entry->cached_layout = gtk_entry_create_layout (entry, include_preedit); entry->cache_includes_preedit = include_preedit; } return entry->cached_layout; } static void get_layout_position (GtkEntry *entry, gint *x, gint *y) { PangoLayout *layout; PangoRectangle logical_rect; gint area_width, area_height; gint y_pos; PangoLayoutLine *line; layout = gtk_entry_ensure_layout (entry, TRUE); get_text_area_size (entry, NULL, NULL, &area_width, &area_height); area_height = PANGO_SCALE * (area_height); line = pango_layout_get_lines (layout)->data; pango_layout_line_get_extents (line, NULL, &logical_rect); /* Align primarily for locale's ascent/descent */ y_pos = ((area_height - entry->ascent - entry->descent) / 2 + entry->ascent + logical_rect.y); /* Now see if we need to adjust to fit in actual drawn string */ if (logical_rect.height > area_height) y_pos = (area_height - logical_rect.height) / 2; else if (y_pos < 0) y_pos = 0; else if (y_pos + logical_rect.height > area_height) y_pos = area_height - logical_rect.height; y_pos = y_pos / PANGO_SCALE; if (x) *x = - entry->scroll_offset; if (y) *y = y_pos; } static void gtk_entry_draw_text (GtkEntry *entry) { GtkWidget *widget; if (!entry->visible && entry->invisible_char == 0) return; if (GTK_WIDGET_DRAWABLE (entry)) { PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE); gint area_width, area_height; gint x, y; gint start_pos, end_pos; widget = GTK_WIDGET (entry); get_layout_position (entry, &x, &y); get_text_area_size (entry, NULL, NULL, &area_width, &area_height); gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state], x, y, layout); if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos)) { gint *ranges; gint n_ranges, i; PangoRectangle logical_rect; const gchar *text = pango_layout_get_text (layout); gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text; gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text; GdkRegion *clip_region = gdk_region_new (); GdkGC *text_gc; GdkGC *selection_gc; PangoLayoutLine *line = pango_layout_get_lines (layout)->data; pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges); pango_layout_get_extents (layout, NULL, &logical_rect); if (GTK_WIDGET_HAS_FOCUS (entry)) { selection_gc = widget->style->base_gc [GTK_STATE_SELECTED]; text_gc = widget->style->text_gc [GTK_STATE_SELECTED]; } else { selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE]; text_gc = widget->style->text_gc [GTK_STATE_ACTIVE]; } for (i=0; i < n_ranges; i++) { GdkRectangle rect; rect.x = INNER_BORDER - entry->scroll_offset + ranges[2*i] / PANGO_SCALE; rect.y = y; rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE; rect.height = logical_rect.height / PANGO_SCALE; gdk_draw_rectangle (entry->text_area, selection_gc, TRUE, rect.x, rect.y, rect.width, rect.height); gdk_region_union_with_rect (clip_region, &rect); } gdk_gc_set_clip_region (text_gc, clip_region); gdk_draw_layout (entry->text_area, text_gc, x, y, layout); gdk_gc_set_clip_region (text_gc, NULL); gdk_region_destroy (clip_region); g_free (ranges); } } } /* * From _gtk_get_insertion_cursor_gc */ typedef struct _CursorInfo CursorInfo; struct _CursorInfo { GType for_type; GdkGC *primary_gc; GdkGC *secondary_gc; }; static GdkGC * make_cursor_gc (GtkWidget *widget, const gchar *property_name, GdkColor *fallback) { GdkGCValues gc_values; GdkGCValuesMask gc_values_mask; GdkColor *cursor_color; gtk_widget_style_get (widget, property_name, &cursor_color, NULL); gc_values_mask = GDK_GC_FOREGROUND; if (cursor_color) { gc_values.foreground = *cursor_color; gdk_color_free (cursor_color); } else gc_values.foreground = *fallback; gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground); return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask); } static GdkGC * _gtkextra_get_insertion_cursor_gc (GtkWidget *widget, gboolean is_primary) { CursorInfo *cursor_info; cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info"); if (!cursor_info) { cursor_info = g_new (CursorInfo, 1); g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info); cursor_info->primary_gc = NULL; cursor_info->secondary_gc = NULL; cursor_info->for_type = G_TYPE_INVALID; } /* We have to keep track of the type because gtk_widget_style_get() * can return different results when called on the same property and * same style but for different widgets. :-(. That is, * GtkEntry::cursor-color = "red" in a style will modify the cursor * color for entries but not for text view. */ if (cursor_info->for_type != G_OBJECT_TYPE (widget)) { cursor_info->for_type = G_OBJECT_TYPE (widget); if (cursor_info->primary_gc) { gtk_gc_release (cursor_info->primary_gc); cursor_info->primary_gc = NULL; } if (cursor_info->secondary_gc) { gtk_gc_release (cursor_info->secondary_gc); cursor_info->secondary_gc = NULL; } } if (is_primary) { if (!cursor_info->primary_gc) cursor_info->primary_gc = make_cursor_gc (widget, "cursor-color", &widget->style->black); return g_object_ref (cursor_info->primary_gc); } else { static GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 }; if (!cursor_info->secondary_gc) cursor_info->secondary_gc = make_cursor_gc (widget, "secondary-cursor-color", &gray); return g_object_ref (cursor_info->secondary_gc); } } /* * From _gtk_draw_insertion_cursor */ static void _gtkextra_draw_insertion_cursor (GtkWidget *widget, GdkDrawable *drawable, GdkGC *gc, GdkRectangle *location, GtkTextDirection direction, gboolean draw_arrow) { gint stem_width; gint arrow_width; gint x, y; gint i; gfloat cursor_aspect_ratio; gint offset; g_return_if_fail (direction != GTK_TEXT_DIR_NONE); gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL); stem_width = location->height * cursor_aspect_ratio + 1; arrow_width = stem_width + 1; /* put (stem_width % 2) on the proper side of the cursor */ if (direction == GTK_TEXT_DIR_LTR) offset = stem_width / 2; else offset = stem_width - stem_width / 2; for (i = 0; i < stem_width; i++) gdk_draw_line (drawable, gc, location->x + i - offset, location->y, location->x + i - offset, location->y + location->height - 1); if (draw_arrow) { if (direction == GTK_TEXT_DIR_RTL) { x = location->x - offset - 1; y = location->y + location->height - arrow_width * 2 - arrow_width + 1; for (i = 0; i < arrow_width; i++) { gdk_draw_line (drawable, gc, x, y + i + 1, x, y + 2 * arrow_width - i - 1); x --; } } else if (direction == GTK_TEXT_DIR_LTR) { x = location->x + stem_width - offset; y = location->y + location->height - arrow_width * 2 - arrow_width + 1; for (i = 0; i < arrow_width; i++) { gdk_draw_line (drawable, gc, x, y + i + 1, x, y + 2 * arrow_width - i - 1); x++; } } } } static void gtk_entry_draw_cursor (GtkEntry *entry, CursorType type) { GtkTextDirection keymap_direction = (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry)); if (GTK_WIDGET_DRAWABLE (entry) && GTK_ENTRY(entry)->cursor_visible) { GtkWidget *widget = GTK_WIDGET (entry); GdkRectangle cursor_location; gboolean split_cursor; gint xoffset = INNER_BORDER - entry->scroll_offset; gint strong_x, weak_x; gint text_area_height; GtkTextDirection dir1; GtkTextDirection dir2 = GTK_TEXT_DIR_NONE; gint x1 = 0; gint x2 = 0; GdkGC *gc; gdk_window_get_size (entry->text_area, NULL, &text_area_height); gtk_entry_get_cursor_locations (entry, type, &strong_x, &weak_x); g_object_get (gtk_widget_get_settings (widget), "gtk-split-cursor", &split_cursor, NULL); dir1 = widget_direction; if (split_cursor) { x1 = strong_x; if (weak_x != strong_x) { dir2 = (widget_direction == GTK_TEXT_DIR_LTR) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR; x2 = weak_x; } } else { if (keymap_direction == widget_direction) x1 = strong_x; else x1 = weak_x; } cursor_location.x = xoffset + x1; cursor_location.y = INNER_BORDER; cursor_location.width = 0; cursor_location.height = text_area_height - 2 * INNER_BORDER ; gc = _gtkextra_get_insertion_cursor_gc (widget, TRUE); _gtkextra_draw_insertion_cursor (widget, entry->text_area, gc, &cursor_location, dir1, dir2 != GTK_TEXT_DIR_NONE); g_object_unref (gc); if (dir2 != GTK_TEXT_DIR_NONE) { cursor_location.x = xoffset + x2; gc = _gtkextra_get_insertion_cursor_gc (widget, FALSE); _gtkextra_draw_insertion_cursor (widget, entry->text_area, gc, &cursor_location, dir2, TRUE); g_object_unref (gc); } } } static void gtk_entry_queue_draw (GtkEntry *entry) { if (GTK_WIDGET_REALIZED (entry)) gdk_window_invalidate_rect (entry->text_area, NULL, FALSE); } static void gtkextra_entry_reset_im_context (GtkEntry *entry) { if (entry->need_im_reset) { entry->need_im_reset = 0; gtk_im_context_reset (entry->im_context); } } static void gtk_entry_get_cursor_locations (GtkEntry *entry, CursorType type, gint *strong_x, gint *weak_x) { PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE); PangoRectangle strong_pos, weak_pos; gint index; if (type == CURSOR_STANDARD) { const gchar *text = pango_layout_get_text (layout); index = g_utf8_offset_to_pointer (text, entry->current_pos + entry->preedit_cursor) - text; } else /* type == CURSOR_DND */ { index = g_utf8_offset_to_pointer (entry->text, entry->dnd_position) - entry->text; if (entry->dnd_position > entry->current_pos) index += entry->preedit_length; } pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos); if (strong_x) *strong_x = strong_pos.x / PANGO_SCALE; if (weak_x) *weak_x = weak_pos.x / PANGO_SCALE; } static void gtk_entry_adjust_scroll (GtkEntry *entry) { gint min_offset, max_offset; gint text_area_width; gint strong_x, weak_x; PangoLayout *layout; PangoLayoutLine *line; PangoRectangle logical_rect; GtkItemEntry *item_entry; gint text_width; if (!GTK_WIDGET_REALIZED (entry)) return; item_entry = GTK_ITEM_ENTRY(entry); gdk_window_get_size (entry->text_area, &text_area_width, NULL); text_area_width -= 2 * INNER_BORDER; layout = gtk_entry_ensure_layout (entry, TRUE); line = pango_layout_get_lines (layout)->data; pango_layout_line_get_extents (line, NULL, &logical_rect); text_width = logical_rect.width / PANGO_SCALE + 2; /* 2 for cursor */ gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x); /* Display as much text as we can */ if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_LTR) { entry->scroll_offset = 0; switch(item_entry->justification){ case GTK_JUSTIFY_FILL: case GTK_JUSTIFY_LEFT: /* LEFT JUSTIFICATION */ strong_x -= entry->scroll_offset; if (strong_x < 0) entry->scroll_offset += strong_x; else if (strong_x > text_area_width){ if(item_entry->text_max_size != 0 && text_area_width + 2 <= item_entry->text_max_size){ GtkAllocation allocation; allocation = GTK_WIDGET(entry)->allocation; allocation.width += text_width - text_area_width; entry->scroll_offset = 0; gtk_entry_size_allocate(GTK_WIDGET(entry), &allocation); }else{ entry->scroll_offset += (strong_x - text_area_width) + 1; } } break; case GTK_JUSTIFY_RIGHT: /* RIGHT JUSTIFICATION FOR NUMBERS */ if(entry->text){ entry->scroll_offset= -(text_area_width - text_width) + 1; if(entry->scroll_offset > 0){ if(item_entry->text_max_size != 0 && text_area_width + 2 <= item_entry->text_max_size){ GtkAllocation allocation; allocation = GTK_WIDGET(entry)->allocation; allocation.x -= text_width - text_area_width; allocation.width += text_width - text_area_width; entry->scroll_offset = 0; gtk_entry_size_allocate(GTK_WIDGET(entry), &allocation); } else { entry->scroll_offset= -(text_area_width - strong_x) + 1; if(entry->scroll_offset < 0) entry->scroll_offset = 0; } } } else entry->scroll_offset=0; break; case GTK_JUSTIFY_CENTER: if(entry->text){ entry->scroll_offset= -(text_area_width - text_width)/2; if(entry->scroll_offset > 0){ if(item_entry->text_max_size != 0 && text_area_width+1<=item_entry->text_max_size){ GtkAllocation allocation; allocation = GTK_WIDGET(entry)->allocation; allocation.x += (text_area_width/2 - text_width/2); allocation.width += text_width - text_area_width; entry->scroll_offset = 0; gtk_entry_size_allocate(GTK_WIDGET(entry), &allocation); } else { entry->scroll_offset= -(text_area_width - strong_x) + 1; if(entry->scroll_offset < 0) entry->scroll_offset = 0; } } } else entry->scroll_offset=0; break; } } else { max_offset = text_width - text_area_width; min_offset = MIN (0, max_offset); entry->scroll_offset = CLAMP (entry->scroll_offset, min_offset, max_offset); } g_object_notify (G_OBJECT (entry), "scroll_offset"); } static gint gtk_entry_move_visually (GtkEntry *entry, gint start, gint count) { gint index; PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); const gchar *text; text = pango_layout_get_text (layout); index = g_utf8_offset_to_pointer (text, start) - text; while (count != 0) { int new_index, new_trailing; gboolean split_cursor; gboolean strong; g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)), "gtk-split-cursor", &split_cursor, NULL); if (split_cursor) strong = TRUE; else { GtkTextDirection keymap_direction = (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; strong = keymap_direction == gtk_widget_get_direction (GTK_WIDGET (entry)); } if (count > 0) { pango_layout_move_cursor_visually (layout, strong, index, 0, 1, &new_index, &new_trailing); count--; } else { pango_layout_move_cursor_visually (layout, strong, index, 0, -1, &new_index, &new_trailing); count++; } if (new_index < 0 || new_index == G_MAXINT) break; index = new_index; while (new_trailing--) index = g_utf8_next_char (entry->text + new_index) - entry->text; } return g_utf8_pointer_to_offset (text, text + index); } static gint gtk_entry_move_logically (GtkEntry *entry, gint start, gint count) { gint new_pos = start; /* Prevent any leak of information */ if (!entry->visible) { new_pos = CLAMP (start + count, 0, entry->text_length); } else if (entry->text) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; gint n_attrs; pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); while (count > 0 && new_pos < entry->text_length) { do new_pos++; while (new_pos < entry->text_length && !log_attrs[new_pos].is_cursor_position); count--; } while (count < 0 && new_pos > 0) { do new_pos--; while (new_pos > 0 && !log_attrs[new_pos].is_cursor_position); count++; } g_free (log_attrs); } return new_pos; } static gint gtk_entry_move_forward_word (GtkEntry *entry, gint start) { gint new_pos = start; /* Prevent any leak of information */ if (!entry->visible) { new_pos = entry->text_length; } else if (entry->text && (new_pos < entry->text_length)) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; gint n_attrs; pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); /* Find the next word end */ new_pos++; while (new_pos < n_attrs && !log_attrs[new_pos].is_word_end) new_pos++; g_free (log_attrs); } return new_pos; } static gint gtk_entry_move_backward_word (GtkEntry *entry, gint start) { gint new_pos = start; /* Prevent any leak of information */ if (!entry->visible) { new_pos = 0; } else if (entry->text && start > 0) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; gint n_attrs; pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); new_pos = start - 1; /* Find the previous word beginning */ while (new_pos > 0 && !log_attrs[new_pos].is_word_start) new_pos--; g_free (log_attrs); } return new_pos; } static void gtk_entry_delete_whitespace (GtkEntry *entry) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; gint n_attrs; gint start, end; pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); start = end = entry->current_pos; while (start > 0 && log_attrs[start-1].is_white) start--; while (end < n_attrs && log_attrs[end].is_white) end++; g_free (log_attrs); if (start != end) gtk_editable_delete_text (GTK_EDITABLE (entry), start, end); } /* * Like gtk_editable_get_chars, but if the editable is not * visible, return asterisks; also convert result to UTF-8. */ static char * gtk_entry_get_public_chars (GtkEntry *entry, gint start, gint end) { if (end < 0) end = entry->text_length; if (entry->visible) return gtk_editable_get_chars (GTK_EDITABLE (entry), start, end); else { gchar *str; gint i; gint n_chars = end - start; str = g_malloc (n_chars + 1); for (i = 0; i < n_chars; i++) str[i] = '*'; str[i] = '\0'; return str; } } static void primary_get_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer data) { GtkEntry *entry = GTK_ENTRY (data); gint start, end; if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end)) { gchar *str = gtk_entry_get_public_chars (entry, start, end); gtk_selection_data_set_text (selection_data, str, -1); g_free (str); } } static void primary_clear_cb (GtkClipboard *clipboard, gpointer data) { GtkEntry *entry = GTK_ENTRY (data); gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos); } static void gtk_entry_update_primary_selection (GtkEntry *entry) { static const GtkTargetEntry targets[] = { { "UTF8_STRING", 0, 0 }, { "STRING", 0, 0 }, { "TEXT", 0, 0 }, { "COMPOUND_TEXT", 0, 0 } }; GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); gint start, end; if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end)) { if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets), primary_get_cb, primary_clear_cb, G_OBJECT (entry))) primary_clear_cb (clipboard, entry); } else { if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry)) gtk_clipboard_clear (clipboard); } } /* Public API */ GtkWidget* gtk_item_entry_new (void) { GtkWidget *widget; widget = GTK_WIDGET (gtk_type_new (GTK_TYPE_ITEM_ENTRY)); return widget; } GtkWidget* gtk_item_entry_new_with_max_length (gint max) { GtkItemEntry *entry; entry = gtk_type_new (GTK_TYPE_ITEM_ENTRY); gtk_entry_set_max_length(GTK_ENTRY(entry), max); return GTK_WIDGET (entry); } void gtk_item_entry_set_text (GtkItemEntry *entry, const gchar *text, GtkJustification justification) { gint tmp_pos; g_return_if_fail (GTK_IS_ITEM_ENTRY (entry)); g_return_if_fail (text != NULL); entry->justification = justification; /* Actually setting the text will affect the cursor and selection; * if the contents don't actually change, this will look odd to the user. */ if (GTK_ENTRY(entry)->text && strcmp (GTK_ENTRY(entry)->text, text) == 0) return; if (GTK_ENTRY(entry)->recompute_idle){ g_source_remove (GTK_ENTRY(entry)->recompute_idle); GTK_ENTRY(entry)->recompute_idle = 0; } if (GTK_ENTRY(entry)->blink_timeout){ g_source_remove (GTK_ENTRY(entry)->blink_timeout); GTK_ENTRY(entry)->blink_timeout = 0; } gtk_editable_delete_text (GTK_EDITABLE (entry), 0, -1); tmp_pos = 0; gtk_editable_insert_text (GTK_EDITABLE (entry), text, strlen (text), &tmp_pos); } /** * gtk_entry_get_layout_offsets: * @entry: a #GtkEntry * @x: location to store X offset of layout, or %NULL * @y: location to store Y offset of layout, or %NULL * * * Obtains the position of the #PangoLayout used to render text * in the entry, in widget coordinates. Useful if you want to line * up the text in an entry with some other text, e.g. when using the * entry to implement editable cells in a sheet widget. * * Also useful to convert mouse events into coordinates inside the * #PangoLayout, e.g. to take some action if some part of the entry text * is clicked. * * Note that as the user scrolls around in the entry the offsets will * change; you'll need to connect to the "notify::scroll_offset" * signal to track this. Remember when using the #PangoLayout * functions you need to convert to and from pixels using * PANGO_PIXELS() or #PANGO_SCALE. * * Keep in mind that the layout text may contain a preedit string, so * gtk_entry_layout_index_to_text_index() and * gtk_entry_text_index_to_layout_index() are needed to convert byte * indices in the layout to byte indices in the entry contents. * **/ void gtk_item_entry_get_layout_offsets (GtkItemEntry *entry, gint *x, gint *y) { gint text_area_x, text_area_y; g_return_if_fail (GTK_IS_ITEM_ENTRY (entry)); /* this gets coords relative to text area */ get_layout_position (GTK_ENTRY(entry), x, y); /* convert to widget coords */ get_text_area_size (GTK_ENTRY(entry), &text_area_x, &text_area_y, NULL, NULL); if (x) *x += text_area_x; if (y) *y += text_area_y; } void gtk_item_entry_set_justification(GtkItemEntry *entry, GtkJustification just) { g_return_if_fail (GTK_IS_ITEM_ENTRY (entry)); entry->justification = just; } /* We display the cursor when * * - the selection is empty, AND * - the widget has focus */ #define CURSOR_ON_MULTIPLIER 0.66 #define CURSOR_OFF_MULTIPLIER 0.34 #define CURSOR_PEND_MULTIPLIER 1.0 static gboolean cursor_blinks (GtkEntry *entry) { GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry)); gboolean blink; if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos) { g_object_get (G_OBJECT (settings), "gtk-cursor-blink", &blink, NULL); return blink; } else return FALSE; } static gint get_cursor_time (GtkEntry *entry) { GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry)); gint time; g_object_get (G_OBJECT (settings), "gtk-cursor-blink-time", &time, NULL); return time; } static void show_cursor (GtkEntry *entry) { if (!entry->cursor_visible) { entry->cursor_visible = TRUE; if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos) gtk_widget_queue_draw (GTK_WIDGET (entry)); } } static void hide_cursor (GtkEntry *entry) { if (entry->cursor_visible) { entry->cursor_visible = FALSE; if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos) gtk_widget_queue_draw (GTK_WIDGET (entry)); } } /* * Blink! */ static gint blink_cb (gpointer data) { GtkEntry *entry; GDK_THREADS_ENTER (); entry = GTK_ENTRY (data); g_assert (GTK_WIDGET_HAS_FOCUS (entry)); g_assert (entry->selection_bound == entry->current_pos); if (entry->cursor_visible) { hide_cursor (entry); entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER, blink_cb, entry); } else { show_cursor (entry); entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER, blink_cb, entry); } GDK_THREADS_LEAVE (); /* Remove ourselves */ return FALSE; } static void gtk_entry_check_cursor_blink (GtkEntry *entry) { if (cursor_blinks (entry)) { if (!entry->blink_timeout) { entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER, blink_cb, entry); show_cursor (entry); } } else { if (entry->blink_timeout) { gtk_timeout_remove (entry->blink_timeout); entry->blink_timeout = 0; } entry->cursor_visible = TRUE; } } static void gtk_entry_pend_cursor_blink (GtkEntry *entry) { if (cursor_blinks (entry)) { if (entry->blink_timeout != 0) gtk_timeout_remove (entry->blink_timeout); entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER, blink_cb, entry); show_cursor (entry); } } void gtk_item_entry_set_cursor_visible(GtkItemEntry *entry, gboolean visible) { g_return_if_fail (GTK_IS_ITEM_ENTRY (entry)); GTK_ENTRY(entry)->cursor_visible = visible; } gboolean gtk_item_entry_get_cursor_visible(GtkItemEntry *entry) { g_return_val_if_fail (GTK_IS_ITEM_ENTRY (entry), FALSE); return(GTK_ENTRY(entry)->cursor_visible); } #endif // HAVE_GUI gpsim-0.30.0/gui/gtkextra/COPYING0000664000076400007640000006131413041763636013332 00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! gpsim-0.30.0/gui/gui_stopwatch.h0000664000076400007640000000421013045306453013461 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_STOPWATCH_H__ #define __GUI_STOPWATCH_H__ #include "gui_object.h" #include class GUI_Processor; // // The stopwatch window // class StopWatch_Window : public GUI_Object { public: int count_dir; long long rollover; long long cyclecounter; long long offset; GtkWidget *cycleentry; GtkWidget *timeentry; GtkWidget *frequencyentry; GtkWidget *offsetentry; GtkWidget *rolloverentry; GtkWidget *option_menu; explicit StopWatch_Window(GUI_Processor *gp); virtual void Build(); virtual void Update(); void EnterUpdate() { assert(from_update >= 0); ++from_update; } void ExitUpdate() { assert(from_update > 0); --from_update; } bool IsUpdate() const { assert(from_update >= 0); return from_update != 0; } // Signal call-backs static void modepopup_activated(GtkWidget *widget, StopWatch_Window *sww); static int delete_event(GtkWidget *widget, GdkEvent *event, StopWatch_Window *sww); static void zero_cb(GtkWidget *w, StopWatch_Window *sww); static void cyclechanged(GtkWidget *widget, StopWatch_Window *sww); static void offsetchanged(GtkWidget *widget, StopWatch_Window *sww); static void rolloverchanged(GtkWidget *widget, StopWatch_Window *sww); private: int from_update; long long cyclecounter_last; protected: virtual const char *name(); }; #endif // __GUI_STOPWATCH_H__ gpsim-0.30.0/gui/gui_symbols.cc0000664000076400007640000002665113041763636013316 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include #include #include "../src/sim_context.h" #include "../src/interface.h" #include "gui.h" #include "gui_regwin.h" #include "gui_symbols.h" #include "gui_watch.h" #include "gui_processor.h" #include "gui_src.h" // TODO: Use a GtkTreeModelSort so that the view can return back to an unsorted // view. Use our own Cell Renderer to display Value. This would have less data // to store and variable data can then use the most upto date values. typedef enum { MENU_ADD_WATCH, } menu_id; typedef struct _menu_item { const char *name; menu_id id; GtkWidget *item; } menu_item; static menu_item menu_items[] = { {"Add to watch window", MENU_ADD_WATCH}, }; // Used only in popup menus Symbol_Window *popup_sw; static void update_menus(Symbol_Window *sw) { gboolean r = gtk_tree_selection_get_selected( gtk_tree_view_get_selection(GTK_TREE_VIEW(sw->symbol_view)), NULL, NULL); for (size_t i=0; i < (sizeof(menu_items)/sizeof(menu_items[0])) ; ++i) { GtkWidget *item = menu_items[i].item; if (r) gtk_widget_set_sensitive(item, TRUE); else gtk_widget_set_sensitive(item, FALSE); } } // called when user has selected a menu item static void popup_activated(GtkWidget *widget, gpointer data) { menu_item *item = (menu_item *)data; GtkTreeIter iter; GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(popup_sw->symbol_view)); if (!gtk_tree_selection_get_selected(sel, NULL, &iter)) return; Value *entry; gtk_tree_model_get(GTK_TREE_MODEL(popup_sw->symbol_list), &iter, 3, &entry, -1); if(!entry) return; switch(item->id) { case MENU_ADD_WATCH: { popup_sw->gp->watch_window->Add(entry); } break; default: puts("Unhandled menuitem?"); break; } } // helper function, called from do_popup GtkWidget * Symbol_Window::build_menu(GtkWidget *sheet) { popup_sw = this; GtkWidget *menu = gtk_menu_new(); for (size_t i=0; i < G_N_ELEMENTS(menu_items); ++i){ GtkWidget *item = gtk_menu_item_new_with_label(menu_items[i].name); menu_items[i].item = item ; g_signal_connect (item, "activate", G_CALLBACK (popup_activated), &menu_items[i]); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),item); } return menu; } // button press handler gboolean Symbol_Window::do_popup(GtkWidget *widget, GdkEventButton *event, Symbol_Window *sw) { GtkWidget *popup = sw->popup_menu; if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { update_menus(sw); gtk_menu_popup(GTK_MENU(popup), 0, 0, 0, 0, 3, event->time); return TRUE; } return FALSE; } static Symbol_Window *lpSW=0; static string table; void updateOneSymbol(const SymbolEntry_t &sym) { Value *pVal = dynamic_cast(sym.second); if (lpSW && pVal) { Register *pReg = dynamic_cast(pVal); if((typeid(*pVal) == typeid(LineNumberSymbol) ) | (lpSW->filter_addresses && (typeid(*pVal) == typeid(AddressSymbol))) || (lpSW->filter_constants && (typeid(*pVal) == typeid(Integer))) || (lpSW->filter_constants && (typeid(*pVal) == typeid(Boolean))) || (lpSW->filter_registers && (pReg))) return; #define SYM_LEN 32 std::string symbol_name; GtkTreeIter iter; char value[SYM_LEN]; if (table != "__global__") symbol_name = table + "." + pVal->name(); else symbol_name = pVal->name(); if (pReg) { g_snprintf(value, sizeof(value), "%02x / %d (0x%02x)", pReg->getAddress(), pReg->get_value(), pReg->get_value()); } else { pVal->get(value,sizeof(value)); } char *pLF = strchr(value, '\n'); if(pLF) *pLF = 0; gtk_list_store_append(lpSW->symbol_list, &iter); gtk_list_store_set(lpSW->symbol_list, &iter, 0, symbol_name.c_str(), 1, pVal->showType().c_str(), 2, value, 3, pVal, -1); } } static void updateSymbolTables(const SymbolTableEntry_t &st) { if(verbose)cout << " gui Symbol Window: " << st.first << endl; table = st.first; (st.second)->ForEachSymbolTable(updateOneSymbol); } void Symbol_Window::Update() { load_symbols=1; if(!enabled) return; gtk_list_store_clear(symbol_list); lpSW = this; globalSymbolTable().ForEachModule(updateSymbolTables); lpSW = 0; } void Symbol_Window::do_symbol_select(Value *e) { if(!gp) return; // Do what is to be done when a symbol is selected. // Except for selecting the symbol row in the symbol_clist if(typeid(*e) == typeid(LineNumberSymbol) || typeid(*e) == typeid(AddressSymbol)) { if(gp->source_browser) gp->source_browser->SelectAddress(e); if(gp->program_memory) gp->program_memory->SelectAddress(e); } else if(typeid(*e) == typeid(Register)) if(gp->regwin_ram) gp->regwin_ram->SelectRegister(e); } void Symbol_Window::symbol_list_row_selected(GtkTreeSelection *treeselection, gpointer user_data) { Symbol_Window *sw = static_cast(user_data); GtkTreeIter iter; if (!gtk_tree_selection_get_selected(treeselection, NULL, &iter)) return; Value *e; gtk_tree_model_get(GTK_TREE_MODEL(sw->symbol_list), &iter, 3, &e, -1); sw->do_symbol_select(e); } void Symbol_Window::NewSymbols() { Update(); } gboolean Symbol_Window::delete_event(GtkWidget *widget, GdkEvent *event, Symbol_Window *sw) { sw->ChangeView(VIEW_HIDE); return TRUE; } void Symbol_Window::toggle_addresses (GtkToggleButton *button, Symbol_Window *sw) { sw->filter_addresses = !sw->filter_addresses; config_set_variable(sw->name(), "filter_addresses", sw->filter_addresses); sw->Update(); } void Symbol_Window::toggle_constants (GtkToggleButton *button, Symbol_Window *sw) { sw->filter_constants = !sw->filter_constants; config_set_variable(sw->name(), "filter_constants", sw->filter_constants); sw->Update(); } void Symbol_Window::toggle_registers (GtkToggleButton *button, Symbol_Window *sw) { sw->filter_registers = !sw->filter_registers; config_set_variable(sw->name(), "filter_registers", sw->filter_registers); sw->Update(); } //------------------------------------------------------------------------ // Build // void Symbol_Window::Build() { if(bIsBuilt) return; GtkWidget *vbox; GtkWidget *scrolled_window; GtkWidget *hbox; window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Symbol Viewer"); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect (window, "delete_event", G_CALLBACK (delete_event), (gpointer)this); symbol_list = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); symbol_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(symbol_list)); g_object_unref(symbol_list); GtkTreeViewColumn *column; GtkCellRenderer *renderer; renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_indicator(column, TRUE); gtk_tree_view_column_set_sort_column_id(column, 0); gtk_tree_view_append_column(GTK_TREE_VIEW(symbol_view), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Type", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_indicator(column, TRUE); gtk_tree_view_column_set_sort_column_id(column, 1); gtk_tree_view_append_column(GTK_TREE_VIEW(symbol_view), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Address/Value", renderer, "text", 2, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(symbol_view), column); g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(symbol_view)), "changed", G_CALLBACK (symbol_list_row_selected), this); g_signal_connect(symbol_view, "button_press_event", G_CALLBACK (do_popup), this); scrolled_window=gtk_scrolled_window_new(0, 0); vbox = gtk_vbox_new(FALSE,1); gtk_container_add(GTK_CONTAINER(scrolled_window), symbol_view); gtk_container_add(GTK_CONTAINER(window),vbox); hbox = gtk_hbox_new(FALSE,1); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0); addressesbutton = gtk_check_button_new_with_label ("addresses"); gtk_box_pack_start (GTK_BOX (hbox), addressesbutton, TRUE, TRUE, 5); if(filter_addresses) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (addressesbutton), FALSE); else gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (addressesbutton), TRUE); g_signal_connect (addressesbutton, "toggled", G_CALLBACK (toggle_addresses), (gpointer)this); constantsbutton = gtk_check_button_new_with_label ("constants"); gtk_box_pack_start (GTK_BOX (hbox), constantsbutton, TRUE, TRUE, 5); if(filter_constants) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (constantsbutton), FALSE); else gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (constantsbutton), TRUE); g_signal_connect (constantsbutton, "toggled", G_CALLBACK (toggle_constants), (gpointer)this); registersbutton = gtk_check_button_new_with_label ("registers"); gtk_box_pack_start (GTK_BOX (hbox), registersbutton, TRUE, TRUE, 5); if(filter_registers) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (registersbutton), FALSE); else gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (registersbutton), TRUE); g_signal_connect (registersbutton, "toggled", G_CALLBACK (toggle_registers), (gpointer)this); g_signal_connect_after(window, "configure_event", G_CALLBACK (gui_object_configure_event), this); gtk_widget_show_all (window); bIsBuilt = true; if(load_symbols) Update(); UpdateMenuItem(); popup_menu = build_menu(window); } const char *Symbol_Window::name() { return "symbol_viewer"; } Symbol_Window::Symbol_Window(GUI_Processor *_gp) : filter_addresses(0), filter_constants(1), filter_registers(0), load_symbols(0) { menu = "/menu/Windows/Symbols"; gp = _gp; get_config(); config_get_variable(name(), "filter_addresses", &filter_addresses); config_get_variable(name(), "filter_constants", &filter_constants); config_get_variable(name(), "filter_registers", &filter_registers); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_object.cc0000664000076400007640000001027213041763636013064 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include #include "gui_object.h" #include "settings.h" extern GtkUIManager *ui; //------------------------------------------------------------------------ // Helper functions for setting and retrieving variables stored in // gpsim configuration file. extern Settings *settings; int config_set_string(const char *module, const char *entry, const char *str) { return settings->set(module, entry, str); } int config_set_variable(const char *module, const char *entry, int value) { return settings->set(module, entry, value); } int config_get_variable(const char *module, const char *entry, int *value) { return settings->get(module, entry, value); } int config_get_string(const char *module, const char *entry, char **str) { return settings->get(module, entry, str); } int config_remove(const char *module, const char *entry) { return settings->remove(module, entry); } GUI_Object::GUI_Object() : gp(0), window(0), menu(0), x(0), y(0), width(100), height(100), enabled(0), bIsBuilt(false) { } GUI_Object::~GUI_Object() { } void GUI_Object::UpdateMenuItem() { if (menu) { GtkAction *menu_item = gtk_ui_manager_get_action(ui, menu); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(menu_item), enabled); } } void GUI_Object::ChangeView(gboolean view_state) { if (view_state) { if(!bIsBuilt) { if(!get_config()) { g_print("warning %s\n",__FUNCTION__); set_default_config(); } enabled = TRUE; Build(); } else { // hmm, this call shouldn't be necessary, but I (Scott) found that // in GTK+ 2.2.1 under Linux that it is. gtk_window_move(GTK_WINDOW(window), x, y); gtk_widget_show(window); enabled = TRUE; // Update the config database set_config(); } } else if (window && gtk_widget_get_visible(window)) { enabled = FALSE; // Update the config database set_config(); gtk_widget_hide(window); } // Update menu item UpdateMenuItem(); } int GUI_Object::get_config() { const char *pName = name(); if(!pName) return 0; if(!config_get_variable(pName, "enabled", &enabled)) enabled=0; if(!config_get_variable(pName, "x", &x)) x=10; if(!config_get_variable(pName, "y", &y)) y=10; if(!config_get_variable(pName, "width", &width)) width=300; if(!config_get_variable(pName, "height", &height)) height=100; check(); return 1; } void GUI_Object::check() { #define MAX_REASONABLE 2000 if((x+width < 0 || x > MAX_REASONABLE) || (y+height < 0 || y > MAX_REASONABLE) || (width < 0 || width > MAX_REASONABLE) || (height < 0 || height > MAX_REASONABLE) ) set_default_config(); } int GUI_Object::set_default_config() { static int defaultX = 100; static int defaultY = 100; enabled = 0; x = defaultX; y = defaultY; defaultX += 100; defaultY += 100; width = 100; height = 100; return 1; } int GUI_Object::set_config() { check(); const char *pName = name(); if(!pName) return 0; if(window) { gtk_window_get_position(GTK_WINDOW(window), &x, &y); gtk_window_get_size(GTK_WINDOW(window), &width, &height); } config_set_variable(pName, "enabled", ((enabled) ? 1 : 0) ); config_set_variable(pName, "x", x); config_set_variable(pName, "y", y); config_set_variable(pName, "width", width); config_set_variable(pName, "height", height); return 1; } #endif // HAVE_GUI gpsim-0.30.0/gui/gui.h0000664000076400007640000000730613041763637011405 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_H__ #define __GUI_H__ #include "../config.h" #ifdef HAVE_GUI #include #include #include #include "../src/processor.h" #include "settings.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------------ // // Create structures to generically access the pic-processor // // // This structure will cross reference the data in the simulator // to its gui representation. There are cases when the same data // appears in more than one place (e.g. the status register is in // both the status bar and register windows). gpsim accomodates this // with a singly-linked list. In other words, for each data element // that is presented graphically there's a pointer within the simulator // to reference it. The simulator keeps a linked listed of pointers // to all instances of these graphical representations class CrossReferenceToGUI : public XrefObject { public: gpointer parent_window; CrossReferenceToGUI(); ~CrossReferenceToGUI(); virtual void Update(int new_value) = 0; virtual void Remove(); }; #include "gui_object.h" #include "gui_processor.h" //======================================================================== class EntryWidget { public: EntryWidget(); virtual ~EntryWidget(); virtual void Update()=0; virtual void set_editable(bool Editable = true); void SetEntryWidth(int string_width); GtkWidget *entry; }; //======================================================================== // // A LabeledEntry is an object consisting of gtk entry // widget that is labeled (with a gtk lable widget) // class LabeledEntry : public EntryWidget { public: LabeledEntry(GtkWidget *box, const char *clabel); virtual ~LabeledEntry() { } virtual void Update(); virtual void put_value(unsigned int); private: GtkWidget *label; }; class RegisterLabeledEntry : public LabeledEntry { public: RegisterLabeledEntry(GtkWidget *, Register *, bool); virtual ~RegisterLabeledEntry(); virtual void put_value(unsigned int); virtual void Update(); private: Register *reg; char pCellFormat[10]; }; // // External references and function prototypes // extern GtkUIManager *ui; extern GUI_Processor *gpGuiProcessor; void exit_gpsim(); // Configuration -- records window states. extern Settings *settings; int config_get_variable(const char *module, const char *entry, int *value); int config_set_variable(const char *module, const char *entry, int value); int config_get_string(const char *module, const char *entry, char **string); int config_set_string(const char *module, const char *entry, const char *string); int config_remove(const char *module, const char *entry); gboolean gui_object_configure_event(GtkWidget *widget, GdkEventConfigure *e, GUI_Object *go); int gui_get_value(const char *prompt); #endif // __GUI_H__ #endif // HAVE_GUI gpsim-0.30.0/gui/settings_exdbm.cc0000664000076400007640000001173213051705743013767 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "settings_exdbm.h" #include #include #include SettingsEXdbm::SettingsEXdbm(const char *appl_name) { int ret; const char *homedir; string path; ret = eXdbmInit(); if (ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); } homedir = getenv("HOME"); if (homedir == 0) homedir = "."; path = string(homedir) + "/." + appl_name; ret = eXdbmOpenDatabase((char *)path.c_str(), &dbid); if(ret == -1) { int error = eXdbmGetLastError(); if(error == DBM_OPEN_FILE) { ret = eXdbmNewDatabase((char *)path.c_str(), &dbid); if (ret == -1) puts(eXdbmGetErrorString(eXdbmGetLastError())); else { ret = eXdbmUpdateDatabase(dbid); if(ret == -1) puts(eXdbmGetErrorString(eXdbmGetLastError())); } } else puts(eXdbmGetErrorString(eXdbmGetLastError())); } } bool SettingsEXdbm::set(const char *module, const char *entry, const char *str) { int ret; DB_LIST list; list = eXdbmGetList(dbid, 0, (char *)module); if (!list) { ret = eXdbmCreateList(dbid, 0, (char *)module, 0); if(ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } list = eXdbmGetList(dbid, 0, (char *)module); if (!list) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } } // We have the list ret = eXdbmChangeVarString(dbid, list, (char *)entry, (char *)str); if (ret == -1) { ret = eXdbmCreateVarString(dbid, list, (char *)entry, 0, (char *)str); if (ret == -1) { puts("\n\n\n\ndidn't work"); puts(eXdbmGetErrorString(eXdbmGetLastError())); puts("\n\n\n\n"); return false; } } ret = eXdbmUpdateDatabase(dbid); if (ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } return true; } bool SettingsEXdbm::set(const char *module, const char *entry, int value) { int ret; DB_LIST list; if(!module || !entry) return false; list = eXdbmGetList(dbid, 0, (char *)module); if (!list) { ret = eXdbmCreateList(dbid, 0, (char *)module, 0); if (ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } list = eXdbmGetList(dbid, 0, (char *)module); if (!list) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } } // We have the list ret = eXdbmChangeVarInt(dbid, list, (char *)entry, value); if (ret == -1) { ret = eXdbmCreateVarInt(dbid, list, (char *)entry, 0, value); if (ret == -1) { puts("\n\n\n\ndidn't work"); puts(eXdbmGetErrorString(eXdbmGetLastError())); puts("\n\n\n\n"); return false; } } ret = eXdbmUpdateDatabase(dbid); if (ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } return true; } bool SettingsEXdbm::get(const char *module, const char *entry, char **str) { int ret; DB_LIST list; list = eXdbmGetList(dbid, 0, (char *)module); if (!list) return false; // We have the list ret = eXdbmGetVarString(dbid, list, (char *)entry, str); if (ret == -1) return false; return true; } bool SettingsEXdbm::get(const char *module, const char *entry, int *value) { int ret; DB_LIST list; list = eXdbmGetList(dbid, 0, (char *)module); if (!list) return false; // We have the list ret = eXdbmGetVarInt(dbid, list, (char *)entry, value); if (ret == -1) return false; return true; } bool SettingsEXdbm::remove(const char *module, const char *entry) { int ret; DB_LIST list; list = eXdbmGetList(dbid, 0, (char *)module); if (!list) { ret = eXdbmCreateList(dbid, 0, (char *)module, 0); if(ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } list = eXdbmGetList(dbid, 0, (char *)module); if (!list) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } } // We have the list ret = eXdbmDeleteEntry(dbid, list, (char *)entry); if (ret == -1) { return false; } ret = eXdbmUpdateDatabase(dbid); if (ret == -1) { puts(eXdbmGetErrorString(eXdbmGetLastError())); return false; } return true; } gpsim-0.30.0/gui/gui_break.cc0000664000076400007640000000431313041763637012702 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "../config.h" #ifdef HAVE_GUI #include "gui.h" #include "gui_src.h" class linkXREF : public CrossReferenceToGUI { public: GUI_Processor *gp; virtual void Update(int new_value) { int address; if(!gp) { printf("gp == null in linkXREF\n"); return;} address = *(int *)data; if(gp->source_browser) gp->source_browser->UpdateLine(address); if(gp->program_memory) gp->program_memory->UpdateLine(address); } }; /* * link_src_to_gpsim * * After a new program has been loaded by gpsim, this routine is called * so that the gui can create links to it. This consists of creating * a 'cross_reference' structure and attaching it to each pic instruction. * The information in the cross_reference structure is a pointer to the * gp. */ void link_src_to_gpsim(GUI_Processor *gp) { if(gp) { // Create a cross reference between the pic's program memory and the gui. int pm_size = gp->cpu->program_memory_size(); if(verbose) { printf("link_src_to_gpsim\n"); printf(" processor pma = %d\n",pm_size); } for(int i = 0; i < pm_size; i++) { linkXREF *cross_reference = new linkXREF(); cross_reference->gp = gp; int *address = new int; *address = gp->cpu->map_pm_index2address(i); cross_reference->data = (gpsimObject*) address; gp->cpu->pma->assign_xref(*address, (CrossReferenceToGUI *) cross_reference); } } } #endif //HAVE_GUI gpsim-0.30.0/gui/gui_watch.cc0000664000076400007640000004437413041763637012737 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "../config.h" #ifdef HAVE_GUI #include #include #include #include #include #include "../src/interface.h" #include "../src/cmd_gpsim.h" #include "gui.h" #include "preferences.h" #include "gui_register.h" #include "gui_regwin.h" #include "gui_watch.h" enum { NAMECOL, ADDRESSCOL, DECIMALCOL, HEXCOL, ASCIICOL, BITCOL, ENTRYCOL, N_COLUMNS }; static const gchar *watch_titles[]={"name","address","dec","hex","ascii","bits"}; #define COLUMNS sizeof(watch_titles)/sizeof(char*) class ColumnData { public: ColumnData(GtkTreeViewColumn *_tc, int col, bool visible); void SetVisibility(bool bVisibility); bool GetVisibility() { return isVisible;} private: GtkTreeViewColumn *tc; int column; bool isVisible; }; typedef enum { MENU_REMOVE, MENU_SET_VALUE, MENU_BREAK_CLEAR, MENU_BREAK_READ, MENU_BREAK_WRITE, MENU_BREAK_READ_VALUE, MENU_BREAK_WRITE_VALUE, MENU_COLUMNS, } menu_id; typedef struct _menu_item { const char *name; menu_id id; } menu_item; static const menu_item menu_items[] = { {"Remove watch", MENU_REMOVE}, {"Set value...", MENU_SET_VALUE}, {"Clear breakpoints", MENU_BREAK_CLEAR}, {"Set break on read", MENU_BREAK_READ}, {"Set break on write", MENU_BREAK_WRITE}, {"Set break on read value...", MENU_BREAK_READ_VALUE}, {"Set break on write value...", MENU_BREAK_WRITE_VALUE}, {"Columns...", MENU_COLUMNS}, }; //======================================================================== class WatchWindowXREF : public CrossReferenceToGUI { public: virtual ~WatchWindowXREF(); void Update(int new_value); }; WatchWindowXREF::~WatchWindowXREF() { gtk_tree_row_reference_free(static_cast((void *)data)); } void WatchWindowXREF::Update(int new_value) { Watch_Window *ww = static_cast(parent_window); if (ww) { GtkTreePath *path = gtk_tree_row_reference_get_path(static_cast((void *)data)); GtkTreeIter iter; if (gtk_tree_model_get_iter(GTK_TREE_MODEL(ww->watch_list), &iter, path)) ww->UpdateWatch(&iter); } } //======================================================================== WatchEntry::WatchEntry(REGISTER_TYPE _type, Register *_pRegister) : cpu(0), type(_type), pRegister(_pRegister) { } WatchEntry::~WatchEntry() { Clear_xref(); } //======================================================================== ColumnData::ColumnData(GtkTreeViewColumn *_tc, int col, bool visible) : tc(_tc), column(col), isVisible(visible) { int show = isVisible; gtk_tree_view_column_set_visible(tc, show); } void ColumnData::SetVisibility(bool bVisibility) { isVisible = bVisibility; int show = isVisible; gtk_tree_view_column_set_visible(tc, show); } //======================================================================== void Watch_Window::ClearWatch(GtkTreeIter *iter) { WatchEntry *entry; gtk_tree_model_get(GTK_TREE_MODEL(watch_list), iter, ENTRYCOL, &entry, -1); delete entry; gtk_list_store_remove(watch_list, iter); } void Watch_Window::UpdateMenus(void) { GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(watch_tree)); GtkTreeIter iter; gboolean selected = gtk_tree_selection_get_selected(sel, NULL, &iter); WatchEntry *entry; if (selected) { gtk_tree_model_get(GTK_TREE_MODEL(watch_list), &iter, ENTRYCOL, &entry, -1); } for (size_t i = 0; i < G_N_ELEMENTS(menu_items); ++i) { GtkWidget *item = popup_items[i]; if (menu_items[i].id != MENU_COLUMNS) { if(menu_items[i].id!=MENU_COLUMNS && (!selected || (entry->type==REGISTER_EEPROM && menu_items[i].id==MENU_BREAK_CLEAR)|| (entry->type==REGISTER_EEPROM && menu_items[i].id==MENU_BREAK_READ)|| (entry->type==REGISTER_EEPROM && menu_items[i].id==MENU_BREAK_WRITE)|| (entry->type==REGISTER_EEPROM && menu_items[i].id==MENU_BREAK_READ_VALUE)|| (entry->type==REGISTER_EEPROM && menu_items[i].id==MENU_BREAK_WRITE_VALUE) )) gtk_widget_set_sensitive (item, FALSE); else gtk_widget_set_sensitive (item, TRUE); } } } int Watch_Window::set_config(void) { int iRet = GUI_Object::set_config(); WriteSymbolList(); return iRet; } gboolean Watch_Window::do_symbol_write(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { Watch_Window *ww = static_cast(data); WatchEntry *entry; gtk_tree_model_get(GTK_TREE_MODEL(ww->watch_list), iter, ENTRYCOL, &entry, -1); if (entry && entry->pRegister) { char cwv[100]; g_snprintf(cwv, sizeof(cwv), "WV%d", ww->count); config_set_string(ww->name(), cwv, entry->pRegister->name().c_str()); } ww->count += 1; return FALSE; } void Watch_Window::WriteSymbolList() { // delete previous list DeleteSymbolList(); // write the current list count = 0; if (watch_list) gtk_tree_model_foreach(GTK_TREE_MODEL(watch_list), do_symbol_write, this); } void Watch_Window::DeleteSymbolList() { char cwv[100]; for (int i = 0; i < 1000; ++i) { g_snprintf(cwv, sizeof(cwv), "WV%d", i); if (config_remove(name(), cwv) == 0 ) { break; } } } void Watch_Window::ReadSymbolList() { // now read symbols watched from a prior simulation session char cwv[100]; char *vname; for (int i = 0; i < 1000; ++i) { g_snprintf(cwv, sizeof(cwv), "WV%d", i); vname = 0; if (config_get_string(name(), cwv, &vname) ) { Value *val = globalSymbolTable().findValue(vname); if(val) Add(val); } else break; } } // called when user has selected a menu item void Watch_Window::popup_activated(GtkWidget *widget, gpointer data) { Watch_Window *ww = static_cast(data); WatchEntry *entry = NULL; int value; GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(ww->watch_tree)); GtkTreeIter iter; gboolean selected = gtk_tree_selection_get_selected(sel, NULL, &iter); if (selected) { gtk_tree_model_get(GTK_TREE_MODEL(ww->watch_list), &iter, ENTRYCOL, &entry, -1); } int id = GPOINTER_TO_SIZE(g_object_get_data(G_OBJECT(widget), "id")); if (id == MENU_COLUMNS) { ww->select_columns(); return; } if (!entry || !entry->cpu) return; switch(id) { case MENU_REMOVE: ww->ClearWatch(&iter); break; case MENU_SET_VALUE: value = gui_get_value("value:"); if(value<0) break; // Cancel entry->put_value(value); break; case MENU_BREAK_READ: get_bp().set_read_break(entry->cpu,entry->address); break; case MENU_BREAK_WRITE: get_bp().set_write_break(entry->cpu,entry->address); break; case MENU_BREAK_READ_VALUE: value = gui_get_value("value to read for breakpoint:"); if(value<0) break; // Cancel get_bp().set_read_value_break(entry->cpu,entry->address,value); break; case MENU_BREAK_WRITE_VALUE: value = gui_get_value("value to write for breakpoint:"); if(value<0) break; // Cancel get_bp().set_write_value_break(entry->cpu,entry->address,value); break; case MENU_BREAK_CLEAR: get_bp().clear_all_register(entry->cpu,entry->address); break; default: break; } } //------------------------------------------------------------ // call back function to toggle column visibility in the configuration popup void Watch_Window::set_column(GtkCheckButton *button, Watch_Window *ww) { int id = GPOINTER_TO_SIZE(g_object_get_data(G_OBJECT(button), "id")); gboolean vis = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); ww->coldata[id].SetVisibility(vis != 0); config_set_variable(ww->name(), watch_titles[id], vis); } void Watch_Window::select_columns() { GtkWidget *dialog; dialog = gtk_dialog_new_with_buttons("", GTK_WINDOW(window), GTK_DIALOG_MODAL, "_Close", GTK_RESPONSE_CLOSE, NULL); GtkWidget *area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(dialog), 30); for (size_t i = 0; i < COLUMNS; ++i) { GtkWidget *button = gtk_check_button_new_with_label((gchar *)watch_titles[i]); g_object_set_data(G_OBJECT(button), "id", GSIZE_TO_POINTER(i)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), coldata[i].GetVisibility()); gtk_box_pack_start(GTK_BOX(area), button, FALSE, FALSE, 0); g_signal_connect(button, "clicked", G_CALLBACK(set_column), this); } gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } // helper function, called from do_popup void Watch_Window::build_menu() { GtkWidget *menu = gtk_menu_new(); popup_menu = menu; popup_items.reserve(G_N_ELEMENTS(menu_items)); for (size_t i = 0; i < G_N_ELEMENTS(menu_items); ++i) { GtkWidget *item = gtk_menu_item_new_with_label(menu_items[i].name); popup_items.push_back(item); g_object_set_data(G_OBJECT(item), "id", GSIZE_TO_POINTER(i)); g_signal_connect(item, "activate", G_CALLBACK(popup_activated), this); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } UpdateMenus(); } // button press handler gboolean Watch_Window::do_popup(GtkWidget *widget, GdkEventButton *event, Watch_Window *ww) { GtkWidget *popup = ww->popup_menu; if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) { gtk_menu_popup(GTK_MENU(popup), 0, 0, 0, 0, 3, event->time); return TRUE; } return FALSE; } static gint key_press(GtkWidget *widget, GdkEventKey *key, gpointer data) { Watch_Window *ww = static_cast(data); if (!ww || !ww->gp || !ww->gp->cpu) return FALSE; switch(key->keyval) { case GDK_KEY_Delete: GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(ww->watch_tree)); GtkTreeIter iter; if (gtk_tree_selection_get_selected(sel, NULL, &iter)) ww->ClearWatch(&iter); break; } return TRUE; } void Watch_Window::watch_list_row_selected(GtkTreeSelection *sel, Watch_Window *ww) { WatchEntry *entry; GUI_Processor *gp = ww->gp; GtkTreeIter iter; if (!gtk_tree_selection_get_selected(sel, NULL, &iter)) return; gtk_tree_model_get(GTK_TREE_MODEL(ww->watch_list), &iter, ENTRYCOL, &entry, -1); if (entry->type == REGISTER_RAM) gp->regwin_ram->SelectRegister(entry->address); else if (entry->type == REGISTER_EEPROM) gp->regwin_eeprom->SelectRegister(entry->address); ww->UpdateMenus(); } static int delete_event(GtkWidget *widget, GdkEvent *event, Watch_Window *ww) { ww->ChangeView(VIEW_HIDE); return TRUE; } //======================================================================== // UpdateWatch // A single watch entry is updated here. Here's what's done: // // If the value has not changed since the last update, then the // foreground and background colors are refreshed and we return. // // If the value has changed, then each of the value fields are refreshed. // Then the foreground and background are refreshed. void Watch_Window::UpdateWatch(GtkTreeIter *iter) { WatchEntry *entry; gtk_tree_model_get(GTK_TREE_MODEL(watch_list), iter, ENTRYCOL, &entry, -1); RegisterValue rvNewValue = entry->getRV(); // If the value has not changed, then simply update the foreground and background // colors and return. if (entry->get_shadow() == rvNewValue) { // Disable colour change for now return; } RegisterValue rvMaskedNewValue; unsigned int uBitmask; entry->put_shadow(rvNewValue); if(entry->pRegister) { rvMaskedNewValue = entry->pRegister->getRV_notrace(); uBitmask = entry->pRegister->mValidBits; //getBitmask(); } else { rvMaskedNewValue = entry->getRV(); uBitmask = entry->cpu->register_mask(); } char str[80] = "?"; if (!(rvNewValue.init & uBitmask)) g_snprintf(str, sizeof(str), "%d", rvNewValue.data); // Hexadecimal representation: char hStr[80]; rvMaskedNewValue.toString(hStr, 80); // ASCII representation char aStr[2]; aStr[0] = ( rvNewValue.data>0x20 && rvNewValue.data<0x7F ) ? rvNewValue.data : 0; aStr[1] = 0; // Bit representation char sBits[25]; rvNewValue.toBitStr(sBits, 25, entry->cpu->register_mask(), NULL); gtk_list_store_set(watch_list, iter, DECIMALCOL, str, HEXCOL, hStr, ASCIICOL, aStr, BITCOL, sBits, -1); // Set foreground and background colors // Diable colour change for now } //------------------------------------------------------------------------ // Update // // static gboolean do_an_update(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { Watch_Window *ww = static_cast(data); ww->UpdateWatch(iter); return FALSE; } void Watch_Window::Update() { if (watch_list) gtk_tree_model_foreach(GTK_TREE_MODEL(watch_list), do_an_update, this); } void Watch_Window::Add(REGISTER_TYPE type, GUIRegister *reg, Register * pReg) { if(!gp || !gp->cpu || !reg || !reg->bIsValid()) return; if(!enabled) Build(); pReg = pReg ? pReg : reg->get_register(); if (!pReg) return; unsigned int uAddrMask = 0; unsigned int uLastAddr = gp->cpu->register_memory_size() - 1; while (uLastAddr) { uLastAddr>>=4; uAddrMask<<=4; uAddrMask |= 0xf; } WatchEntry *watch_entry = new WatchEntry(type, pReg); watch_entry->address=reg->address; watch_entry->cpu = gp->cpu; watch_entry->rma = reg->rma; GtkTreeIter iter; gtk_list_store_append(watch_list, &iter); gtk_list_store_set(watch_list, &iter, NAMECOL, pReg ? pReg->name().c_str() : "NULLREG", ADDRESSCOL, GetUserInterface().FormatProgramAddress(pReg->getAddress(), uAddrMask, IUserInterface::eHex), ENTRYCOL, gpointer(watch_entry), -1); UpdateWatch(&iter); GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(watch_list), &iter); WatchWindowXREF *cross_reference = new WatchWindowXREF(); cross_reference->parent_window = (gpointer) this; cross_reference->data = (gpsimObject *) gtk_tree_row_reference_new(GTK_TREE_MODEL(watch_list), path); gtk_tree_path_free(path); watch_entry->Assign_xref(cross_reference); UpdateMenus(); } //--- // Add - given a symbol, verify that it is a RAM or EEPROM register // symbol. If it is then extract the register and use it's address // to get the GUI representation of the register. void Watch_Window::Add( Value *regSym) { if(regSym && gp) { Register *reg = dynamic_cast(regSym); if(reg) { GUIRegister *greg = gp->m_pGUIRamRegisters->Get(reg->getAddress()); Add(REGISTER_RAM, greg, reg); } } } //------------------------------------------------------------------------ // NewSymbols // void Watch_Window::NewProcessor(GUI_Processor *_gp) { if (!gp || !gp->cpu) return; ReadSymbolList(); } //------------------------------------------------------------------------ // Build // // void Watch_Window::Build(void) { if(bIsBuilt) return; GtkWidget *vbox; GtkWidget *scrolled_window; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Watch Viewer"); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect (window, "delete_event", G_CALLBACK(delete_event), (gpointer)this); g_signal_connect_after(window, "configure_event", G_CALLBACK(gui_object_configure_event), this); watch_list = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); watch_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(watch_list)); coldata.reserve(COLUMNS); for (size_t i = 0; i < COLUMNS; i++) { GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes( watch_titles[i], renderer, "text", int(i), NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(watch_tree), column); int vis; if (!config_get_variable(name(), (gchar *)watch_titles[i], &vis)) config_set_variable(name(), (gchar *)watch_titles[i], 1); coldata.push_back(ColumnData(column, i, vis)); } { // Fix a db error in previous versions of gpsim int j; while (config_get_variable(name(),"hex",&j)) config_remove(name(), "hex"); const int hexIndex=3; config_set_variable(name(),(gchar *)watch_titles[hexIndex],coldata[hexIndex].GetVisibility()); } // TODO:No column sorting for now GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(watch_tree)); g_signal_connect(sel, "changed", G_CALLBACK(watch_list_row_selected), this); g_signal_connect(watch_tree, "button_press_event", G_CALLBACK(do_popup), this); g_signal_connect(watch_tree, "key_press_event", G_CALLBACK(key_press), this); scrolled_window = gtk_scrolled_window_new(NULL, NULL); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(scrolled_window), watch_tree); gtk_container_add(GTK_CONTAINER(window),vbox); gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0); build_menu(); gtk_widget_show_all(window); enabled=1; bIsBuilt = true; UpdateMenuItem(); } const char *Watch_Window::name() { return "watch_viewer"; } Watch_Window::Watch_Window(GUI_Processor *_gp) { menu = "/menu/Windows/Watch"; gp = _gp; watch_list = 0; get_config(); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/makefile.mingw0000664000076400007640000000303013113676116013251 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw TOP = ../.. include ../plat/win32/make.mingw ################################################################ # Nothing much configurable below INCLUDES = -I . -I ../plat/win32 \ -I $(GLIB_PATH)/include/glib-2.0 -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GTK_PATH)/include/gtk-2.0 -I $(GTK_PATH)/lib/gtk-2.0/include \ -I $(ATK_PATH)/include/atk-1.0 \ -I $(PANGO_PATH)/include/pango-1.0 \ -I $(CAIRO_PATH)/include/cairo \ -I $(GDK_PIXBUF_PATH)/include/gdk-pixbuf-2.0 DEFINES += -DHAVE_GUI all : \ ../config.h \ libgui.a gui_OBJECTS = \ gui_breadboard.o \ gui_break.o \ gui_callbacks.o \ gui_dialog.o \ gui_init.o \ gui_main.o \ gui_menu.o \ gui_object.o \ gui_processor.o \ gui_profile.o \ gui_regwin.o \ gui_scope.o \ gui_src.o \ gui_src_asm.o \ gui_src_opcode.o \ gui_stack.o \ gui_statusbar.o \ gui_stopwatch.o \ gui_symbols.o \ gui_trace.o \ gui_watch.o \ preferences.o \ settings_reg.o \ gtkextra/gtkextra-marshal.o \ gtkextra/gtkitementry.o \ gtkextra/gtksheet.o \ gtkextra/gtkextra.o ../config.h : ../config_win32.h.in (cd .. ; $(AWK) -f plat/win32/configure_win32.awk config_win32.h.in > config.h) settings_reg.o : ../plat/win32/settings_reg.cpp $(CXX) $(CFLAGS) -c -o settings_reg.o ../plat/win32/settings_reg.cpp ################ The libgui LIB libgui.a : $(gui_OBJECTS) $(RM) -f $@ $(AR) $(ARFLAGS) $@ $(gui_OBJECTS) gpsim-0.30.0/gui/gui_processor.cc0000664000076400007640000000416013041763637013635 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include #include "gui.h" #include "gui_breadboard.h" #include "gui_profile.h" #include "gui_register.h" #include "gui_regwin.h" #include "gui_scope.h" #include "gui_src.h" #include "gui_stack.h" #include "gui_stopwatch.h" #include "gui_symbols.h" #include "gui_trace.h" #include "gui_watch.h" #include "gui_processor.h" void create_dispatcher (); GUI_Processor::GUI_Processor() : source_window(0), cpu(0), m_pGUIRamRegisters(0), m_pGUIEEPromRegisters(0) { create_dispatcher(); regwin_ram = new RAM_RegisterWindow(this); regwin_eeprom = new EEPROM_RegisterWindow(this); program_memory = new SourceBrowserOpcode_Window(this); source_browser = new SourceBrowserParent_Window(this); symbol_window = new Symbol_Window(this); watch_window = new Watch_Window(this); stack_window = new Stack_Window(this); breadboard_window = new Breadboard_Window(this); trace_window = new Trace_Window(this); profile_window = new Profile_Window(this); stopwatch_window = new StopWatch_Window(this); scope_window = new Scope_Window(this); } void GUI_Processor::SetCPU(Processor *new_cpu) { cpu = new_cpu; delete m_pGUIRamRegisters; m_pGUIRamRegisters = new GUIRegisterList(&new_cpu->rma); delete m_pGUIEEPromRegisters; m_pGUIEEPromRegisters = new GUIRegisterList(&new_cpu->ema); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_src.cc0000664000076400007640000001006113041763636012401 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "../config.h" #ifdef HAVE_GUI #include #include #include #include "gui_src.h" static gint key_press(GtkWidget *widget, GdkEventKey *key, gpointer data) { SourceBrowser_Window *sbw = static_cast(data); if (!sbw) return FALSE; if (!sbw->pma) return FALSE; if (!sbw->gp) return FALSE; if (!sbw->gp->cpu) return FALSE; switch (key->keyval) { case 's': case 'S': case GDK_KEY_F7: sbw->pma->step(1); break; case 'o': case 'O': case 'n': case GDK_KEY_F8: sbw->pma->step_over(); break; case 'r': case 'R': case GDK_KEY_F9: get_interface().start_simulation(); break; case GDK_KEY_Escape: sbw->pma->stop(); break; case 'f': case 'F': sbw->pma->finish(); break; default: return FALSE; } return TRUE; } static int delete_event(GtkWidget *widget, GdkEvent *event, SourceBrowser_Window *sbw) { sbw->ChangeView(VIEW_HIDE); return TRUE; } void SourceBrowser_Window::Update() { if(!gp || !gp->cpu) return; SetPC(gp->cpu->pma->get_PC()); } void SourceBrowser_Window::Create() { last_simulation_mode = eSM_INITIAL; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect (window, "delete_event", G_CALLBACK(delete_event), (gpointer) this); /* Add a signal handler for key press events. This will capture * key commands for single stepping, running, etc. */ g_signal_connect(window, "key_press_event", G_CALLBACK(key_press), (gpointer) this); gtk_container_set_border_width (GTK_CONTAINER (window), 0); vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show(vbox); gtk_container_add (GTK_CONTAINER (window), vbox); } void SourceBrowser_Window::SetTitle() { if (!gp->cpu || !pma) { return; } if (last_simulation_mode != eSM_INITIAL && ((last_simulation_mode == eSM_RUNNING && gp->cpu->simulation_mode == eSM_RUNNING) || (last_simulation_mode != eSM_RUNNING && gp->cpu->simulation_mode != eSM_RUNNING)) && sLastPmaName == pma->name()) { return; } last_simulation_mode = gp->cpu->simulation_mode; const char * sStatus; if (gp->cpu->simulation_mode == eSM_RUNNING) sStatus = "Run"; else // if (gp->cpu->simulation_mode == eSM_STOPPED) sStatus = "Stopped"; char *buffer = g_strdup_printf("Source Browser: [%s] %s", sStatus, pma->name().c_str()); sLastPmaName = pma->name(); gtk_window_set_title (GTK_WINDOW (window), buffer); g_free(buffer); } void SourceBrowser_Window::SelectAddress(Value *addrSym) { if(typeid(*addrSym) == typeid(LineNumberSymbol) || typeid(*addrSym) == typeid(AddressSymbol)) { int i; addrSym->get(i); SelectAddress(i); } } gboolean gui_object_configure_event(GtkWidget *widget, GdkEventConfigure *e, GUI_Object *go) { gtk_window_get_position(GTK_WINDOW(widget), &go->x, &go->y); gtk_window_get_size(GTK_WINDOW(widget), &go->width, &go->height); go->set_config(); return FALSE; } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_stopwatch.cc0000664000076400007640000002372113041763637013636 00000000000000/* Copyright (C) 2000,2001 Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "../config.h" #ifdef HAVE_GUI #include #include #include #include "gui.h" #include "gui_stopwatch.h" int StopWatch_Window::delete_event(GtkWidget *widget, GdkEvent *event, StopWatch_Window *sww) { sww->ChangeView(VIEW_HIDE); return TRUE; } void StopWatch_Window::Update() { long long _cyclecounter; double timevalue; char frequencystring[100]; char cyclestring[100]; char timestring[100]; char offsetstring[100]; char rolloverstring[100]; if(!gp || !gp->cpu) return; if(!enabled) return; if(!bIsBuilt) Build(); if(rollover<=0) rollover=1; if(offset>rollover) offset%=rollover; double frequency = gp->cpu->get_frequency(); unsigned int cycle_per_inst = gp->cpu->get_ClockCycles_per_Instruction(); _cyclecounter=cyclecounter; //////////////////////// if(count_dir<0) _cyclecounter -= get_cycles().get() - cyclecounter_last; else _cyclecounter += get_cycles().get() - cyclecounter_last; cyclecounter_last = get_cycles().get(); // %%% FIXME %%% - This surely must be wrong, given that we're working with // the local copy ('_cyclecounter') while(cyclecounteroffset = sww->cyclecounter; sww->Update(); } void StopWatch_Window::modepopup_activated(GtkWidget *widget, StopWatch_Window *sww) { gint dir = gtk_combo_box_get_active(GTK_COMBO_BOX(sww->option_menu)); switch(dir) { case 0: sww->count_dir = 1; config_set_variable(sww->name(), "count_dir", sww->count_dir); break; case 1: sww->count_dir = -1; config_set_variable(sww->name(), "count_dir", sww->count_dir); break; default: break; } sww->Update(); } void StopWatch_Window::cyclechanged(GtkWidget *widget, StopWatch_Window *sww) { if(!sww->IsUpdate()) { const char *text = gtk_entry_get_text(GTK_ENTRY(widget)); long long v = ::strtoll(text,0,10); if(v!=(sww->cyclecounter-sww->offset)%sww->rollover) { v=(v+sww->offset)%sww->rollover; sww->cyclecounter=v; sww->Update(); } } } void StopWatch_Window::offsetchanged(GtkWidget *widget, StopWatch_Window *sww) { if(!sww->IsUpdate()) { const char *text = gtk_entry_get_text(GTK_ENTRY(widget)); long long v = ::strtoll(text,0,10); if(v!=sww->offset) { sww->offset=v; sww->Update(); } } } void StopWatch_Window::rolloverchanged(GtkWidget *widget, StopWatch_Window *sww) { if(!sww->IsUpdate()) { const char *text = gtk_entry_get_text(GTK_ENTRY(widget)); long long v = ::strtoll(text,0,10); if(v!=sww->rollover) { sww->rollover=v; config_set_string(sww->name(),"rollover",text); sww->Update(); } } } void StopWatch_Window::Build() { if(bIsBuilt) return; GtkWidget *vbox, *button, *label, *entry; GtkWidget *table; window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "StopWatch"); gtk_window_set_default_size(GTK_WINDOW(window), width,height); gtk_window_move(GTK_WINDOW(window), x, y); gtk_window_set_wmclass(GTK_WINDOW(window),name(),"Gpsim"); g_signal_connect (window, "delete_event", G_CALLBACK(StopWatch_Window::delete_event), (gpointer)this); g_signal_connect_after(window, "configure_event", G_CALLBACK(gui_object_configure_event), this); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), vbox); table = gtk_table_new (6, 2, FALSE); gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0); label = gtk_label_new ("Cycles"); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new ("Time"); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new ("Processor frequency"); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); cycleentry = entry = gtk_entry_new (); gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); g_signal_connect(entry, "changed", G_CALLBACK(StopWatch_Window::cyclechanged), this); timeentry = entry = gtk_entry_new (); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_widget_set_sensitive(entry, FALSE); gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); frequencyentry = entry = gtk_entry_new (); gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); gtk_widget_set_sensitive(entry, FALSE); gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new ("Count direction"); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); option_menu = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(option_menu), "Up"); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(option_menu), "Down"); gtk_combo_box_set_active(GTK_COMBO_BOX(option_menu), (count_dir > 0) ? 0 : 1); g_signal_connect(option_menu, "changed", G_CALLBACK(StopWatch_Window::modepopup_activated), this); gtk_table_attach (GTK_TABLE (table), option_menu, 1, 2, 4, 5, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); label = gtk_label_new ("Cycle offset"); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); offsetentry = entry = gtk_entry_new (); gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 3, 4, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); g_signal_connect(entry, "changed", G_CALLBACK(StopWatch_Window::offsetchanged), this); label = gtk_label_new ("Rollover"); gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); rolloverentry = entry = gtk_entry_new (); gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 5, 6, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0); g_signal_connect(entry, "changed", G_CALLBACK(StopWatch_Window::rolloverchanged), this); button = gtk_button_new_with_label ("Zero"); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 4); g_signal_connect(button, "clicked", G_CALLBACK(StopWatch_Window::zero_cb), this); gtk_widget_show_all (window); bIsBuilt=true; UpdateMenuItem(); Update(); } const char *StopWatch_Window::name() { return "stopwatch_viewer"; } //------------------------------------------------------------------------ // // StopWatch_Window::StopWatch_Window(GUI_Processor *_gp) : count_dir(1), rollover(1000000), cyclecounter(0), offset(0), from_update(0), cyclecounter_last(0) { char *string; menu = "/menu/Windows/Stopwatch"; gp = _gp; get_config(); if(config_get_string(name(),"rollover",&string)) rollover = ::strtoll(string,0,10); config_get_variable(name(),"count_dir",&count_dir); if(enabled) Build(); } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_interface.h0000664000076400007640000000063513041763637013423 00000000000000#ifndef __GUI_INTERFACE_H__ #define __GUI_INTERFACE_H__ #ifdef __cplusplus //extern "C" { #endif /* __cplusplus */ void gui_new_processor (unsigned int pic_id); void gui_new_source (unsigned int pic_id); void update_register(unsigned int reg_number); void update_program_memory(GUI_Processor *gp, unsigned int reg_number); #ifdef __cplusplus //} #endif /* __cplusplus */ #endif /* __GUI_INTERFACE_H__ */ gpsim-0.30.0/gui/gui_object.h0000664000076400007640000000442113041763637012726 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_OBJECT_H__ #define __GUI_OBJECT_H__ // // Forward reference // class GUI_Processor; //======================================================================== // GUI_Object // All window attributes that are common are placed into the GUI_Object // structure. This structure is then include in each of the other structures. // It's also the very first item in these 'derived' structures. Consequently a // pointer to one object may be type cast into another. // class GUI_Object { public: GUI_Processor *gp; GtkWidget *window; const char *menu; // Window geometry. This info is saved when the window associated // with this gui object is hidden. Note: gtk saves the window origin // (x,y) but doesn't save the size (width,height). int x,y,width,height; int enabled; // Whether or not the window is up on the screen bool bIsBuilt; // Whether or not the window is built // A pointer to a function that will allow the window associated // with this gui object to be viewable or hidden. #define VIEW_HIDE 0 #define VIEW_SHOW 1 #define VIEW_TOGGLE 2 GUI_Object(); virtual ~GUI_Object(); virtual void ChangeView(gboolean view_state); int get_config(); void check(); int set_default_config(); virtual int set_config(); virtual void Build() = 0; virtual void UpdateMenuItem(); virtual void Update() = 0; virtual void NewProcessor(GUI_Processor *_gp) { gp = _gp; } protected: virtual const char *name() = 0; private: }; #endif // __GUI_OBJECT_H__ gpsim-0.30.0/gui/gui_register.h0000664000076400007640000000646613045306453013310 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_REGISTER_H__ #define __GUI_REGISTER_H__ #include "gui.h" #include //======================================================================== // // A GUI register is a shadow of a register in a simulated cpu (or module). // // // FIXME -- why not just derive from the Register base class? class GUIRegister { public: RegisterMemoryAccess *rma; // Pointer to the rma that controls this register. int address; // index in rma register array. int row; // row & col in register window int col; RegisterValue shadow;// value displayed in register window. // This shadows the real register value. It's used // to monitor if register has changed between gui updates int register_size; // The size (in bytes) of a single register bool bUpdateFull; // true if a full update needs to be performed bool bIsAliased; // true if this register is aliased // and this instance is not the base. bool bIsValid(void); // true if this register is a valid one (i.e. // there's a defined register at the address). bool bIsSFR(void); // true if this register is a special function register bool hasBreak(void); // True if there's a breakpoint set on this register. bool hasChanged(RegisterValue ¤t_value) const; // True if register has changed values since last updated. CrossReferenceToGUI *xref; char *getValueAsString(char *, int, RegisterValue value); void put_value(unsigned int new_value); unsigned int get_value(void); RegisterValue getRV(void); inline operator RegisterValue() { return getRV(); } Register *get_register(); // put and get for updating the shadow void put_shadow(RegisterValue new_value); RegisterValue get_shadow(void) { return shadow; } void Clear_xref(void); void Assign_xref(CrossReferenceToGUI *); std::string name(); GUIRegister(); ~GUIRegister(); }; #define MAX_REGISTERS 0x10000 class GUIRegisterList { public: explicit GUIRegisterList(RegisterMemoryAccess *pRMA); ~GUIRegisterList(); RegisterMemoryAccess *m_pRMA; // Apointer to the Processor's rma or ema. GUIRegister * m_paRegisters[MAX_REGISTERS]; GUIRegister * Get(int iAddress); GUIRegister * Get(unsigned int uAddress); }; inline GUIRegister *GUIRegisterList::Get(int iAddress) { return m_paRegisters[iAddress]; } inline GUIRegister *GUIRegisterList::Get(unsigned int uAddress) { return m_paRegisters[uAddress]; } #endif // __GUI_REGISTER_H__ gpsim-0.30.0/gui/gui_watch.h0000664000076400007640000000466213045306453012566 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_WATCH_H__ #define __GUI_WATCH_H__ #include "gui_register.h" class WatchEntry : public GUIRegister { public: WatchEntry(REGISTER_TYPE _type, Register *_pRegister); virtual ~WatchEntry(); Processor *cpu; REGISTER_TYPE type; //register_symbol *pRegSymbol; Register *pRegister; }; class Value; class ColumnData; // // The watch window // class Watch_Window : public GUI_Object { public: GtkListStore *watch_list; GtkWidget *watch_tree; explicit Watch_Window(GUI_Processor *gp); virtual void Build(); virtual void ClearWatch(GtkTreeIter *iter); virtual void UpdateWatch(GtkTreeIter *iter); virtual void Add(REGISTER_TYPE type, GUIRegister *reg, Register * pReg=0); virtual void Add(Value *); virtual void Update(); virtual void UpdateMenus(); virtual void NewProcessor(GUI_Processor *gp); // Override set_config() to save variable list on app exit virtual int set_config(); void ReadSymbolList(); void WriteSymbolList(); void DeleteSymbolList(); protected: virtual const char *name(); private: void build_menu(); static void popup_activated(GtkWidget *widget, gpointer data); static gboolean do_popup(GtkWidget *widget, GdkEventButton *event, Watch_Window *ww); static void set_column(GtkCheckButton *button, Watch_Window *ww); void select_columns(); static gboolean do_symbol_write(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); static void watch_list_row_selected(GtkTreeSelection *sel, Watch_Window *ww); int count; GtkWidget *popup_menu; std::vector popup_items; std::vector coldata; }; #endif //__GUI_WATCH_H__ gpsim-0.30.0/gui/gui_profile.h0000664000076400007640000000406113045306453013111 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_PROFILE_H__ #define __GUI_PROFILE_H__ #include "gui_object.h" #include class GUI_Processor; // // The profile window // struct cycle_histogram_counter{ // Three variables that determine which cycle_histogram_counter we add // the differences in cycle counter to: unsigned int start_address; // Start profile address unsigned int stop_address; // Stop profile address guint64 histo_cycles; // The number of cycles that this counter counts. unsigned int count; // The number of time 'cycles' cycles are used. }; class Profile_Window : public GUI_Object { public: int program; // if non-zero window has program GtkListStore *profile_list; GtkWidget *profile_tree; GtkListStore *profile_register_list; GtkWidget *profile_register_tree; GtkListStore *profile_exestats_list; GtkWidget *profile_exestats_tree; GtkWidget *notebook; // List of cycle_count structs GList *histogram_profile_list; explicit Profile_Window(GUI_Processor *gp); virtual void Build(); virtual void Update(); virtual void NewProcessor(GUI_Processor *gp); virtual void NewProgram(GUI_Processor *gp); virtual void StopExe(int address); virtual void StartExe(int address); protected: virtual const char *name(); }; #endif // __GUI_PROFILE_H__ gpsim-0.30.0/gui/gui_init.cc0000664000076400007640000000163513041763637012565 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI // FIXME: This file should be removed as the function is not used void gui_styles_init() { } #endif // HAVE_GUI gpsim-0.30.0/gui/gui_trace.h0000664000076400007640000000370213045306453012550 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_TRACE_H__ #define __GUI_TRACE_H__ #include "gui_object.h" class GUI_Processor; // // The trace window // struct TraceMapping { TraceMapping() : cycle(0), simulation_trace_index(0) {} guint64 cycle; int simulation_trace_index; }; class Trace_Window : public GUI_Object { public: GtkListStore *trace_list; guint64 last_cycle; // The cycle of the last trace in the window. GtkWidget *location; GtkWidget *popup_menu; /* trace_flags bit definitions bit0 - enable xref updates to refresh the display 0 disables, 1 enables bit1-bit31 are unused. */ int trace_flags; /* trace_map is a pointer to an array of cross references * between the trace window and gpsim trace buffer */ struct TraceMapping *trace_map; int trace_map_index; explicit Trace_Window(GUI_Processor *gp); virtual void Build(void); virtual void Update(void); virtual void NewProcessor(GUI_Processor *gp); protected: virtual const char *name(); private: static void cycle_cell_data_function(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data); }; #endif // __GUI_TRACE_H__ gpsim-0.30.0/gui/settings_exdbm.h0000664000076400007640000000250613045306453013626 00000000000000/* Copyright (C) 2004 Borut Razem This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SETTINGS_EXDBM_H #define _SETTINGS_EXDBM_H extern "C" { #include "../eXdbm/eXdbm.h" } #include "settings.h" class SettingsEXdbm: public Settings { public: explicit SettingsEXdbm(const char *appl_name); virtual bool set(const char *module, const char *entry, const char *str); virtual bool set(const char *module, const char *entry, int value); virtual bool get(const char *module, const char *entry, char **str); virtual bool get(const char *module, const char *entry, int *value); virtual bool remove(const char *module, const char *entry); private: DB_ID dbid; }; #endif //_SETTINGS_EXDBM_H gpsim-0.30.0/gui/gui_stack.h0000664000076400007640000000224513045306453012560 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_STACK_H__ #define __GUI_STACK_H__ // // The stack window // class Stack_Window : public GUI_Object { public: int last_stacklen; explicit Stack_Window(GUI_Processor *gp); virtual void Build(void); virtual void Update(void); GtkListStore *stack_list; GtkTreeModel *sort_stack_list; GtkWidget *tree; protected: virtual const char *name(); }; #endif //__GUI_STACK_H__ gpsim-0.30.0/gui/preferences.h0000664000076400007640000000320313041763636013111 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2005 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __PREFERENCES__ #define __PREFERENCES__ #include "../config.h" #ifdef HAVE_GUI #include //======================================================================== class GuiColor { public: GuiColor (const char *_name, const char *_description); private: const char *name; const char *description; GdkColor *color; }; class GuiColors { public: GuiColors(); GdkColor *breakpoint(); GdkColor *item_has_changed(); GdkColor *normal_fg(); GdkColor *normal_bg(); GdkColor *sfr_bg(); GdkColor *alias(); GdkColor *invalid(); void initialize(); private: bool m_bInitialized; GdkColor breakpoint_color; GdkColor item_has_changed_color; GdkColor normal_fg_color; GdkColor normal_bg_color; GdkColor sfr_bg_color; GdkColor alias_color; GdkColor invalid_color; }; extern GuiColors gColors; #endif // __PREFERENCES__ #endif // HAVE_GUI gpsim-0.30.0/gui/preferences.cc0000664000076400007640000000512613041763636013255 00000000000000/* Copyright (C) 2005 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include "preferences.h" //======================================================================== // Colors (probably should be in a separate file) GuiColors gColors; GuiColors::GuiColors() : m_bInitialized(false) { } void GuiColors::initialize() { GdkColormap *colormap = gdk_colormap_get_system(); gdk_color_parse("light cyan", &normal_bg_color); gdk_color_parse("black", &normal_fg_color); gdk_color_parse("blue", &item_has_changed_color); gdk_color_parse("red1", &breakpoint_color); gdk_color_parse("light gray", &alias_color); gdk_color_parse("black", &invalid_color); gdk_color_parse("cyan", &sfr_bg_color); gdk_colormap_alloc_color(colormap, &normal_bg_color,FALSE,TRUE ); gdk_colormap_alloc_color(colormap, &normal_fg_color,FALSE,TRUE ); gdk_colormap_alloc_color(colormap, &item_has_changed_color,FALSE,TRUE); gdk_colormap_alloc_color(colormap, &breakpoint_color,FALSE,TRUE); gdk_colormap_alloc_color(colormap, &alias_color,FALSE,TRUE); gdk_colormap_alloc_color(colormap, &invalid_color,FALSE,TRUE); gdk_colormap_alloc_color(colormap, &sfr_bg_color,FALSE,TRUE); } GdkColor *GuiColors::breakpoint() { if (!m_bInitialized) initialize(); return &breakpoint_color; } GdkColor *GuiColors::item_has_changed() { if (!m_bInitialized) initialize(); return &item_has_changed_color; } GdkColor *GuiColors::normal_fg() { if (!m_bInitialized) initialize(); return &normal_fg_color; } GdkColor *GuiColors::normal_bg() { if (!m_bInitialized) initialize(); return &normal_bg_color; } GdkColor *GuiColors::sfr_bg() { if (!m_bInitialized) initialize(); return &sfr_bg_color; } GdkColor *GuiColors::alias() { if (!m_bInitialized) initialize(); return &alias_color; } GdkColor *GuiColors::invalid() { if (!m_bInitialized) initialize(); return &invalid_color; } #endif //HAVE_GUI gpsim-0.30.0/gui/gui_dialog.cc0000664000076400007640000000176713041763636013066 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../config.h" #ifdef HAVE_GUI #include /* * GtkDialog */ // TODO: remove file - unused functions void create_labeled_boxes(GtkWidget *box, const char **labels, int num_labels) { } void fill_range (void) { } #endif gpsim-0.30.0/gui/gui_src.h0000664000076400007640000002514413045306453012245 00000000000000/* Copyright (C) 1998,1999,2000,2001,2002,2003,2004 T. Scott Dattalo and Ralf Forsberg This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __GUI_SRC_H__ #define __GUI_SRC_H__ #include "../src/processor.h" #include "gui_object.h" #include "gui_processor.h" #include #include #include // forward references class SourceBrowserParent_Window; class StatusBar_Window; class Value; class SourceWindow; //======================================================================== class SourceBuffer { public: SourceBuffer(GtkTextTagTable *,FileContext *,SourceBrowserParent_Window *); void parseLine(const char*, int parseStyle); void addTagRange(const char *pStyle, int start_index, int end_index); GtkTextBuffer *getBuffer(); SourceBrowserParent_Window *m_pParent; FileContext *m_pFC; bool IsParsed(); void parse(); private: bool m_bParsed; GtkTextBuffer *m_buffer; }; //======================================================================== // The SourcePageMargin holds configuration information for the left margin // of a SourcePage. The left margin is where line numbers, addresses, opcodes, // breakpoints, and current program counter are all shown. class SourcePageMargin { public: SourcePageMargin(); void enableLineNumbers(bool b) { m_bShowLineNumbers = b; } void enableAddresses(bool b) { m_bShowAddresses = b; } void enableOpcodes(bool b) { m_bShowOpcodes = b; } bool formatMargin(char *,int, int line,int addr,int opcode,bool bBreak); bool bLineNumbers() { return m_bShowLineNumbers; } bool bAddresses() { return m_bShowAddresses; } bool bOpcodes() { return m_bShowOpcodes; } private: bool m_bShowLineNumbers; bool m_bShowAddresses; bool m_bShowOpcodes; }; //======================================================================== // SourcePage // A single source file. // // The SourcePage class associates a single file with a single GtkTextBuffer. // manages class NSourcePage { public: NSourcePage(SourceWindow *, SourceBuffer *, int file_id, GtkWidget *); GtkTextBuffer *buffer(); GtkTextView *getView(); SourceWindow *getParent(); void invalidateView(); void updateMargin(int y1, int y2); void Close(); void setFont(const char *); FileContext *getFC(); unsigned int get_file_id() { return m_fileid; } int get_margin_width() { return m_marginWidth; } private: // callbacks static gboolean KeyPressHandler(GtkTextView *pView, GdkEventKey *key, NSourcePage *page); static gint ButtonPressHandler(GtkTextView *pView, GdkEventButton *pButton, NSourcePage *pPage); static gint ViewExposeEventHandler(GtkTextView *pView, GdkEventExpose *pEvent, NSourcePage *pPage); GtkTextView *m_view; SourceBuffer *m_pBuffer; SourceWindow *m_Parent; unsigned int m_fileid; int m_marginWidth; std::string m_cpFont; }; class SearchDialog; class SourceWindow : public GUI_Object { public: SourceWindow(GUI_Processor *gp, SourceBrowserParent_Window *, bool bUseConfig, const char *newName=0); virtual void Build(); virtual void SetTitle(); void set_pma(ProgramMemoryAccess *new_pma); virtual void SelectAddress(int address); virtual void SelectAddress(Value *); virtual void Update(); virtual void UpdateLine(int address); virtual void SetPC(int address); virtual void CloseSource(void); virtual void NewSource(GUI_Processor *gp); virtual int getPCLine(int page); virtual int getAddress(NSourcePage *pPage, int line); virtual bool bAddressHasBreak(int address); virtual int getOpcode(int address); int AddPage(SourceBuffer *pSourceBuffer, const std::string &fName); void step(int n=1); void step_over(); void stop(); void run(); void finish(); void reset(); void toggleBreak(NSourcePage *pPage, int line); void movePC(int line); bool bSourceLoaded() { return m_bSourceLoaded; } void findText(); int findText(const char *, int, bool bDir, bool bCase); GtkTextTagTable *getTagTable(); SourcePageMargin &margin(); const char *getFont(); gint switch_page_cb(guint newPage); // do we need this: bool m_bLoadSource; bool m_bSourceLoaded; int m_LineAtButtonClick; private: int AddPage(SourceBuffer *pSourceBuffer); ProgramMemoryAccess *pma; // pointer to the processor's pma. StatusBar_Window *status_bar; // display's PC, status, etc. SIMULATION_MODES last_simulation_mode; string sLastPmaName; unsigned int m_currentPage; // Notebook page currently displayed. struct _PC { bool bIsActive; int page; // Notebook page containing the source int line; // Line within the page. GtkTextBuffer *pBuffer; // Buffer containing the Program Counter GtkTextIter iBegin; // Start of where highlight begins GtkTextIter iEnd; // End of highlight } mProgramCounter; // Popup Menu SearchDialog *stPSearchDialog; GtkWidget * BuildPopupMenu(); static void PopupMenuHandler(GtkWidget *widget, gpointer data); // Callbacks static gboolean KeyPressHandler(GtkWidget *widget, GdkEventKey *key, SourceWindow *pSW); static int DeleteEventHandler(GtkWidget *widget, GdkEvent *event, SourceWindow *sw); static void cb_notebook_switchpage(GtkNotebook *notebook, gpointer page, guint page_num, SourceWindow *pSW); std::string m_name; protected: std::map pages; GtkWidget *m_Notebook; GtkPositionType m_TabPosition; SourceBrowserParent_Window *m_pParent; virtual const char *name(); public: const char *name_pub() {return name();} }; class SourceBrowser_Window : public GUI_Object { public: GtkWidget *vbox; // for children to put widgets in ProgramMemoryAccess *pma; // pointer to the processor's pma. SIMULATION_MODES last_simulation_mode; std::string sLastPmaName; void set_pma(ProgramMemoryAccess *new_pma); void Create(); virtual void NewProcessor(GUI_Processor *gp) = 0; virtual void SetTitle(); virtual void SelectAddress(int address) = 0; virtual void SelectAddress(Value *); virtual void Update(); virtual void UpdateLine(int address) = 0; virtual void SetPC(int address) = 0; virtual void CloseSource(){}; virtual void NewSource(GUI_Processor *gp){}; }; // // The Source Opcode Browser Data // class SourceBrowserOpcode_Window : public SourceBrowser_Window { public: explicit SourceBrowserOpcode_Window(GUI_Processor *gp); ~SourceBrowserOpcode_Window(); virtual void Build(); virtual void NewProcessor(GUI_Processor *gp); virtual void SelectAddress(int address); virtual void SetPC(int address); virtual void NewSource(GUI_Processor *gp); virtual void UpdateLine(int address); virtual void Fill(); void update_ascii(gint row); void load_styles(); void settings_dialog(); protected: virtual const char *name(); private: GtkWidget *build_menu_for_sheet(); GtkWidget *build_menu_for_list(); void update_values(int address); void update_styles(int address); void update(int address); void update_label(int address); void do_popup_menu(GtkWidget *my_widget, GdkEventButton *event); static void popup_activated(GtkWidget *widget, SourceBrowserOpcode_Window *sbow); static void cell_renderer(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data); static void show_entry(GtkWidget *widget, SourceBrowserOpcode_Window *sbow); static gint activate_sheet_cell(GtkWidget *widget, gint row, gint column, SourceBrowserOpcode_Window *sbow); static gint button_press(GtkWidget *widget, GdkEventButton *event, SourceBrowserOpcode_Window *sbow); static gboolean popup_menu_handler(GtkWidget *widget, SourceBrowserOpcode_Window *sbw); static void row_selected(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, SourceBrowserOpcode_Window *sbow); GtkListStore *list; GtkWidget *tree; unsigned int current_address; // current PC std::string normalfont_string; PangoFontDescription *normalPFD; GtkWidget *notebook; GtkWidget *sheet; GtkWidget *entry; GtkWidget *label; GtkWidget *sheet_popup_menu; GtkWidget *list_popup_menu; GdkPixbuf *break_pix; GdkPixbuf *pc_pix; unsigned int *memory; }; // // The Source Browser Child window. // // The gui supports "context" debugging, where a context // may be code written for interrupt routines, non-interrupt // routines, high versus low interrupt priorities, etc. Each // context has a dedicated source browser. The SourceBrowserChild_Window // class manages this. class SourceBrowserParent_Window : public GUI_Object { public: explicit SourceBrowserParent_Window(GUI_Processor *gp); virtual void Build(); virtual void NewProcessor(GUI_Processor *gp); virtual void SelectAddress(int address); virtual void SelectAddress(Value *); virtual void Update(); virtual void UpdateLine(int address); virtual void SetPC(int address); virtual void CloseSource(); virtual void NewSource(GUI_Processor *gp); virtual void ChangeView(int view_state); virtual int set_config(); GtkTextTagTable *getTagTable() { return mpTagTable; } void CreateSourceBuffers(GUI_Processor *gp); void parseSource(SourceBuffer *pBuffer,FileContext *pFC); SourcePageMargin &margin(); void setTabPosition(int tt); int getTabPosition() { return m_TabType; } void setFont(const char *); const char *getFont(); private: gchar *get_color_string(const char *tag_name); GtkTextTagTable *mpTagTable; std::vector children; ProgramMemoryAccess *pma; // pointer to the processor's pma. private: SourcePageMargin m_margin; int m_TabType; std::string m_FontDescription; public: std::vector ppSourceBuffers; protected: virtual const char *name(); }; #endif // __GUI_SRC_H__ gpsim-0.30.0/config.guess0000755000076400007640000012367212734477075012215 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gpsim-0.30.0/config_win32.h.in0000664000076400007640000001007113041763636012721 00000000000000/* config_win32.h.in. Generated by configure, */ /* ./configure CC=cl CXX=cl, */ /* manually renamed from config.h, */ /* some stuff added at the end */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ #ifndef __CONFIG_H__ /* Define if you have alloca, as a function or macro. */ #define HAVE_ALLOCA 1 /* Define if you have and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if lex declares yytext as a char * by default, not a char[]. */ #define YYTEXT_POINTER 1 /* #undef HAVE_LIBREADLINE */ /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the strstr function. */ #define HAVE_STRSTR 1 /* Define if you have the strtod function. */ #define HAVE_STRTOD 1 /* Define if you have the strtol function. */ #define HAVE_STRTOL 1 /* Define if you have the strtoul function. */ #define HAVE_STRTOUL 1 /* Define if you have the header file. */ /* #undef HAVE_DLFCN_H */ /* Define if you have the header file. */ /* #undef HAVE_GETOPT_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_CHARDEFS_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_HISTORY_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_KEYMAPS_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_READLINE_H */ /* Define if you have the header file. */ /* #undef HAVE_READLINE_TILDE_H */ /* manually added stuff */ /* the version number and package values should be replaced with values from configure.ac during the generation of config.h from config_win32.h.in */ /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Version number of package */ #undef VERSION #if defined _MSC_VER || defined __MINGW32__ /* * The following define causes the following warning: * warning: `I' flag used with `%x' printf format * when copiled with mingw or cygwin -mno-cygwin gcc. * This is correct, because the mingw compilation links against msvcrt.dll, * which uses "I46" for 64 bit integer (long long) printf lenght modifier, * instead of "ll" used by libc. */ #define PRINTF_INT64_MODIFIER "I64" #define PRINTF_GINT64_MODIFIER "I64" #else #define PRINTF_INT64_MODIFIER "ll" #define PRINTF_GINT64_MODIFIER "ll" #endif #ifdef _MSC_VER #ifndef __FUNCTION__ #define __FUNCTION__ __FILE__ #endif #define snprintf _snprintf #ifndef strcasecmp #define strcasecmp _stricmp #endif #define strncasecmp _strnicmp #define bzero(dest, count) memset(dest, 0, count) #define strtoll _strtoi64 #define strdup _strdup #define chdir _chdir #define fileno _fileno #define isatty _isatty #define snprintf _snprintf #define getcwd _getcwd #define _USE_MATH_DEFINES #endif #endif // __CONFIG_H__gpsim-0.30.0/makefile.mingw0000664000076400007640000000257313041763624012501 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw PARTS=cli src src/dspic gui gpsim modules CLEAN_PARTS=$(PARTS) .PHONY: all doc setup clean all: for D in $(PARTS); do $(MAKE) -C $$D -f makefile.mingw all; done doc: $(MAKE) -C doc -f makefile.mingw all setup: all doc extras $(MAKE) -C plat/win32 -f makefile.mingw all clean: clean-extras rm -f config.h for D in $(CLEAN_PARTS); do $(MAKE) -C $$D -f makefile.mingw clean; done ################ # The mingw makefiles don't handle dependencies well. However this little # hack can work around this: # # $ make -f makefile.mingw depend # $ make -f mf MF=mf depend: for D in $(PARTS); do $(MAKE) -C $$D -f makefile.mingw depend; done @echo "# Automatically generated makefile" > ${MF} @echo "include makefile.mingw" >> ${MF} ################ The extras modules .PHONY: extras extras-usart-con extras-graphic-lcd extras-lcd EXTRAS=extras/graphic_lcd/src extras/lcd extras/ds1307 extras/ds1820 extras/dht11 extras/i2c2par include/gpsim: mkdir -p include; ln -s ../src include/gpsim extras: include/gpsim extras-dht11 extras-dht11: export GPSIM_DEF_PATH=../plat/win32; \ export GPSIM_LIB_PATH=../src; \ $(MAKE) -C extras -f makefile.mingw clean-extras: for D in $(EXTRAS); do $(MAKE) -C $$D -f makefile.mingw clean; done; \ rm -rf include gpsim-0.30.0/extras/0000775000076400007640000000000013117466030011233 500000000000000gpsim-0.30.0/extras/solar/0000775000076400007640000000000013117466031012354 500000000000000gpsim-0.30.0/extras/solar/solar.cc0000664000076400007640000004005113065704622013726 00000000000000/* Copyright (C) 2016 Roy R Rankin This file is part of the libgpsim_extras library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include #include #ifdef HAVE_GUI #include #endif #include #include #include "src/gpsim_time.h" #include #include #include #include //---------------------------------------- class VSscaleAttribute : public Float { public: SolarModule *pur; VSscaleAttribute(SolarModule *ppur) : Float("VSscale",0.0,"Solar Panel Voltage scale factor"), pur(ppur) { if(pur) Float::set(pur->VSscale); } virtual void set(double r) { Float::set(r); if(pur) { pur->VSscale = r; } }; }; //---------------------------------------- class inductorAttribute : public Float { public: SolarModule *pur; inductorAttribute(SolarModule *ppur) : Float("inductor",0.0,"Buck converter inductor"), pur(ppur) { if(pur) Float::set(pur->inductor); } virtual void set(double r) { Float::set(r); if(pur) { pur->inductor = r; } }; }; //---------------------------------------- class VBscaleAttribute : public Float { public: SolarModule *pur; VBscaleAttribute(SolarModule *ppur) : Float("VBscale",0.0,"Battery Voltage scale factor"), pur(ppur) { if(pur) Float::set(pur->VBscale); } virtual void set(double r) { Float::set(r); if(pur) { pur->VBscale = r; } }; }; //---------------------------------------- class AscaleAttribute : public Float { public: SolarModule *pur; AscaleAttribute(SolarModule *ppur) : Float("Ascale",0.0,"panel current scale factor"), pur(ppur) { if(pur) Float::set(pur->Ascale); } virtual void set(double r) { Float::set(r); if(pur) { pur->Ascale = r; } }; }; //---------------------------------------- class AoffAttribute : public Float { public: SolarModule *pur; AoffAttribute(SolarModule *ppur) : Float("Aoffset",0.0,"panel zero current Voltage"), pur(ppur) { if(pur) Float::set(pur->Aoffset); } virtual void set(double r) { Float::set(r); if(pur) { pur->Aoffset = r; } }; }; //---------------------------------------- class DOCAttribute : public Float { public: SolarModule *pur; DOCAttribute(SolarModule *ppur) : Float("BDOC",0.0,"Battery degree of charge"), pur(ppur) { if(pur) Float::set(pur->BDOC); } virtual void set(double r) { Float::set(r); if(pur) { pur->set_BDOC(r); } }; }; //-------------------------------------------------------------- // SolarModule::create_iopin_map // class PCM : public IOPIN { public: PCM(const char *name, SolarModule *parent); virtual void setDrivenState(bool); private: SolarModule *m_Parent; }; PCM::PCM(const char *name, SolarModule *Parent) : IOPIN(name), m_Parent(Parent) { } void PCM::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_Parent) m_Parent->setPcm(bNewState); } class PCM_ENABLE : public IOPIN { public: PCM_ENABLE(const char *name, SolarModule *parent); virtual void setDrivenState(bool); private: SolarModule *m_Parent; }; PCM_ENABLE::PCM_ENABLE(const char *name, SolarModule *Parent) : IOPIN(name), m_Parent(Parent) { } void PCM_ENABLE::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_Parent) m_Parent->setPcmEnable(bNewState); } void SolarModule::setPcmEnable(bool bNewState) { enabled = bNewState; if (!enabled) { active = false; Solar_panel(0.); } } void SolarModule::setPcm(bool bNewState) { guint64 now = get_cycles().get(); static int duty_last = -1; if (!enabled) { start_cycle = now; return; } if (bNewState) { if (active) { int duty; double freq = 0.; Tperiod = now - start_cycle; if (Tperiod > 0) { freq = 1./(Tperiod*get_cycles().seconds_per_cycle()); duty = (100*Thigh)/Tperiod; delta_mah += Isp * 1000. * Tperiod*get_cycles().seconds_per_cycle() / 3600.; if (delta_mah > 0.1) { cur_mah += delta_mah; set_BDOC(100.*cur_mah/cap_mah); } } else { freq = 0.; duty = 0; } start_cycle = now; if (duty != duty_last) { printf("%" PRINTF_GINT64_MODIFIER "d cycles %2" PRINTF_GINT64_MODIFIER "d/%2" PRINTF_GINT64_MODIFIER "d Duty %2d F=%.2fkHz Vsp %.2f Isp %.2f Pout %5.2f Vbat %.2f\n", now, Thigh, Tperiod, duty, freq/1000., Vsp, Isp, Vsp*Isp, VbatOC + Isp*Rbat); duty_last = duty; } } else { active = true; start_cycle = now; } } else if (active) // signal has gone low { Thigh = now - start_cycle; Solar_panel(Thigh * get_cycles().seconds_per_cycle()); } } void SolarModule::create_iopin_map(void) { // The solar controller has 4 pins. // 1 Solar panel voltage readout // 2 solar panel current readout // 3 battery volgage readout // 4 PWM input create_pkg(6); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created.The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. assign_pin(1, Vsol); assign_pin(2, Asol); assign_pin(3, Vbat); assign_pin(4, pwm); assign_pin(5, pwm_enable); } //-------------------------------------------------------------- Module * SolarModule::construct(const char *_new_name) { SolarModule *pur = new SolarModule(_new_name, "Solar Module"); return pur; } //-------------------------------------------------------------- SolarModule::SolarModule(const char *init_name, const char * desc) : Module(init_name, desc), Voc(21.60), Isc(1.27), Vmp(17.3), Imp(1.16), Rbat(1.5), cap_mah(20.), enabled(false) { Vsol = new IO_bi_directional_pu("Vsol"); addSymbol(Vsol); Asol = new IO_bi_directional_pu("Asol"); addSymbol(Asol); Vbat = new IO_bi_directional_pu("Vbat"); addSymbol(Vbat); pwm = new PCM("PWM", this); addSymbol(pwm); pwm_enable = new PCM_ENABLE("OK", this); addSymbol(pwm_enable); //res->set_Vpullup(vinit); create_iopin_map(); // Default module attributes. //initializeAttributes(); set_description("\ pullup resistor or generic voltage source\n\ Attributes:\n\ .resistance - pullup resistance\n\ .voltage - pullup or drive voltage\n\ .capacitance - pin capacitance\n\ "); if(verbose)cout << description() << endl; // Note ResistanceAttribute is designed to give access // to res.Zth with a symbol name of "modulename + '.resistance'". VSattr = new VSscaleAttribute(this); VBattr = new VBscaleAttribute(this); AVattr = new AscaleAttribute(this); Aoffattr = new AoffAttribute(this); indattr = new inductorAttribute(this); docattr = new DOCAttribute(this); addSymbol(VSattr); addSymbol(VBattr); addSymbol(AVattr); addSymbol(Aoffattr); addSymbol(indattr); addSymbol(docattr); VSattr->set(0.1667); VBattr->set(0.1667); AVattr->set(0.5); Aoffattr->set(2.5); indattr->set(47e-6); docattr->set(45.); pvi_init(); start_cycle = 0; future_cycle = 0; Vsol->set_Vth(Voc*VSscale); Vsol->set_Vpullup(Voc*VSscale); Vsol->setDriving(false); Vsol->update_pullup('1',true); Vsol->updateNode(); Asol->set_Vth(Aoffset); Asol->set_Vpullup(Aoffset); Asol->setDriving(false); Asol->update_pullup('1',true); Asol->updateNode(); Vbat->set_Vth(VbatOC*VBscale); Vbat->set_Vpullup(VbatOC*VBscale); Vbat->setDriving(false); Vbat->update_pullup('1',true); Vbat->updateNode(); #ifdef MANAGING_GUI pu_window = 0; if(get_interface().bUsingGUI()) build_window(); #endif } SolarModule::~SolarModule() { removeSymbol(VSattr); removeSymbol(VBattr); removeSymbol(AVattr); removeSymbol(Aoffattr); removeSymbol(indattr); removeSymbol(docattr); removeSymbol(Vsol); removeSymbol(Asol); removeSymbol(Vbat); removeSymbol(pwm); removeSymbol(pwm_enable); delete VSattr; delete VBattr; delete AVattr; delete Aoffattr; delete indattr; delete docattr; } void SolarModule::pvi_init() { // the following is N*f*k*T/q where // N Number of in series solar cells 36 for 12 volt panel // f is a device fudge factor 1.5 typical but 2 gives better results // k boltzmann constant 1.3806488E-23 // T temp in kelvin 27C = 300 K // q electron charge 1.60217657E-19 Nvt = 36*(2.0*1.3806488E-23*300.)/1.60217657E-19; Isat = Isc /(exp(Voc/Nvt)-1.); v3 = 1.10*Vmp; i3 = Isc - Isat*(exp(v3/Nvt)-1.); v2 = Vmp; i2 = Imp; v1 = 0.95*Vmp; i1 = Isc - Isat*(exp(v1/Nvt)-1.); r0 = v1/(Isc - i1); r1 = (v2 -v1)/(Isc- i2 - (v2)/r0); r2 = (v3-v2)/(Isc-i3 - (v3-v1)/r1 - v3/r0); r3 = (Voc-v3)/(Isc - (Voc-v2)/r2 - (Voc-v1)/r1 - Voc/r0); } // Model Solar panel VI characteristics, Return estimate of current for // given voltage. // pvi_init() must first be call to compute r0-r3 and v0-v3 // this model follows the work of Mohamed Azab in "Improved Circuit Model // of Photovoltaic Array" in International Journal of Electrical Power // and Energy Systems Engineering 2:3 2009 double SolarModule::pvi(double volts) { double di0, di1, di2, di3; if (volts >= Voc) return 0; di1 = di2 = di3 = 0.0; di0 = volts / r0; if (volts > v1) { di1 = ( volts - v1)/r1; } if (volts > v2) di2 = (volts - v2)/r2; if (volts > v3) di3 = (volts-v3)/r3; return(Isc - di0 - di1 -di2 - di3); } // Given the solar panel current, return the voltage double SolarModule::piv(double I) { double num, denom; if (I >= Isc) return 0; num = Isc - I; denom = 1./r0; if (I < i3) { num += v3/r3; denom += 1./r3; } if (I < i2) { num += v2/r2; denom += 1./r2; } if (I < i1) { num += v1/r1; denom += 1./r1; } return num/denom; } void SolarModule::set_BDOC(double soc) { BDOC = soc; cur_mah = cap_mah * soc /100.; delta_mah = 0.; VbatOC = battery_voltage(soc); Vbat->set_Vth(VbatOC*VBscale); Vbat->set_Vpullup(VbatOC*VBscale); Vbat->updateNode(); } double SolarModule::battery_voltage(double soc) { static double bat_soc[] = { 6., 11.51, 11.66, 11.81, 11.96, 12.10, 12.24, 12.37, 12.50, 12.62, 12.7, 13.5}; int i1, i2; double V; if (soc > 110.) soc = 110.; i1 = soc/10.; // index 0-11 i2 = i1 +1; if (i1 >= 11) { i2 = 11; i1 = 10; } V = (bat_soc[i2] - bat_soc[i1])*(soc - i1*10.)/(10.) + bat_soc[i1]; return V; } /* * Given the time in seconds that the drive pulse is high (in seconds), * compute the solar panel current voltage operating point. * * This function views a solar panel as having 3 regions * Region 1 Voltage between 0 and 0.95 * Vmppt where panel acts as * a current source. (voltage changes faster than current) * In this region we hunt for the voltage where the panel * current and inductor current match. * Region 2 Voltage is between Voc and 1.1 * Vmppt and panel acts * like a Voltage source (current changes faster than voltage) * In this region we hunt for the current which matches the * panel and inductor voltages * Region 3 is the transition between the two regions and is where the * maximum power point lies. * This region is a hystorises region of the computation. * If the initial voltage is less than Vmppt we use the region * 1 algorithm unless we go into region 2 in which case we * change to that algorithm. Comversly if the inital voltage * for the interations is greater than Vmppt we use the region 2 * algorithm unless we go into region 1 in which case we change * to that algorithm. */ void SolarModule::Solar_panel(double Ton) { double dv = 1.; double Vfirst = Vsp; int i; double vbat = VbatOC; guint64 cycle_off; Rbat = 0.0005*exp(0.11*BDOC); // The following is an estimate of the average current // through an inductor when a constant voltage is applied if (Ton) { for(i = 0; i < 50 && fabs(dv) > 0.005; i++) { double Isol; if (Vsp< vbat) { Isp = pvi(vbat); Vsp = vbat + Isp*Rbat; } else if (Vsp > Voc) { Vsp = Voc; Isp = pvi(vbat); } if (Vfirst < v2 && Vsp < v3) // Solar panel acting as current source { Isol = pvi(Vsp); dv = Isp * (2*inductor/Ton + Rbat) + vbat - Vsp; if (dv > Voc - Vsp) dv = Voc - Vsp; else if (dv < vbat - Vsp) dv = vbat - Vsp; Vsp += dv/3; Isp = pvi(Vsp); if (Vsp > v3) { // fprintf(stderr, "Switch R1 to R2 i = %d\n", i); Vfirst = Vsp; } } // else if (Vsp >= v3) // Solar panel more like voltage source else { double Iind; if (Isp > Isc) Isp = Isc; else if (Isp < 0) Isp = 0.1; Vsp = piv(Isp); if (Vsp < vbat + Isp * Rbat) Vsp = vbat + Isp * Rbat; Iind = (Vsp - vbat)/(2*inductor/Ton + Rbat); Isol = pvi(Vsp); dv = Iind - Isol; Isp += dv/6.; Vsp = piv(Isp); if (Vsp < v1) { // fprintf(stderr, "Switch R2 to R1 i=%d\n", i); Vfirst = Vsp; } } if (Vsp > Voc) { Vsp = Voc; } else if (Vsp < 0.) { Vsp = vbat; } } if ( i > 49) { fprintf(stderr, "%s did not converge Vsp %.2f Isp %.2f\n", __FUNCTION__, Vsp, Isp); } } else //Ton == 0 { Vsp = Voc; Isp = 0.; } if (Ton) cycle_off = 2200; else cycle_off = 0; Vsol->set_Vth(Vsp*VSscale); Vsol->set_Vpullup(Vsp*VSscale); Vsol->updateNode(); Vbat->set_Vth((vbat + Rbat*Isp)*VBscale); Vbat->set_Vpullup((vbat + Rbat*Isp)*VBscale); Vbat->updateNode(); Asol->set_Vth(Aoffset + Isp*Ascale); Asol->set_Vpullup(Aoffset+Isp*Ascale); Asol->updateNode(); if (future_cycle) { if (cycle_off) { guint64 fc = cycle_off + get_cycles().get(); get_cycles().reassign_break(future_cycle, fc, this); future_cycle = fc; } else { get_cycles().clear_break(this); future_cycle = 0; } } else if (cycle_off) { future_cycle = cycle_off + get_cycles().get(); get_cycles().set_break(future_cycle, this); } } void SolarModule::callback() { get_cycles().clear_break(this); future_cycle = 0; Solar_panel(0.); } #ifdef MANAGING_GUI static void pu_cb(GtkWidget *button, gpointer pur_class) { SolarModule *pur = (SolarModule *)pur_class; } void SolarModule::build_window(void) { GtkWidget *buttonbox; GtkWidget *button; pu_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); buttonbox = gtk_hbox_new(FALSE,0); gtk_container_add (GTK_CONTAINER (pu_window), buttonbox); gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 1); button = gtk_button_new_with_label (name().c_str()); g_signal_connect(button, "clicked", G_CALLBACK(pu_cb), (gpointer)this); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); gtk_widget_show_all (pu_window); set_widget(pu_window); } #endif gpsim-0.30.0/extras/solar/Makefile.in0000664000076400007640000004523713117441635014357 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile for the Solar module # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras/solar ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = solar.h README SUBDIRS = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/solar/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/solar/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/solar/Makefile.am0000664000076400007640000000011513041763631014327 00000000000000# Makefile for the Solar module # EXTRA_DIST = solar.h README SUBDIRS = gpsim-0.30.0/extras/solar/README0000664000076400007640000000233213041763631013156 00000000000000This modules simulates a Solar panel controller with a lead-acid battery, solar panel, and voltage and current sensors. The module has three sensor pins and two control pins. The three sensor pins are Vsol - Solar panel Voltage Asol - Solar panel Current Vbat - Battery voltage The two control pins are PWM - Pulse with modulated signal to controler OK - PWM signal is used (if low PWM is don't care) Attributes are as follows Aoffset - Voltage on Asol when current is zero Ascale - Volts/Amp scale factor for Asol BDOC - Battery degree of charge (determines battery voltage) VBscale - Vbat (volts) = battery voltage * VBscale VSscale - Vsol (volts) = solar panel voltage * VScale inductor - controller inductor in Henrys The module simulates a 12 solar panel with the following specs open circuit voltage 21.6V Short circuit current 1.27A Max power point 17.3V 1.16A The simulated panel VI is an approximation and is OK for the current purpose but should not be taken a correct for design purposes. The battery uses a simple model for a 12V lead-acid (or SLA) battery with a 20 mah capacity and a 1.5 ohm internal resistance. The small battery capacity is to allow the battery to quickly change state. gpsim-0.30.0/extras/solar/solar.h0000664000076400007640000000671313065705542013601 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __SOLAR_H__ #define __SOLAR_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #ifdef HAVE_GUI #include #else struct GtkToggleButton; #endif #include #include #include "src/modules.h" #include "src/stimuli.h" class VSscaleAttribute; class VBscaleAttribute; class AscaleAttribute; class AoffAttribute; class inductorAttribute; class DOCAttribute; class PCM; class PCM_ENABLE; class SolarModule : public Module , public TriggerObject { public: IO_bi_directional_pu *Vsol; IO_bi_directional_pu *Vbat; IO_bi_directional_pu *Asol; PCM *pwm; PCM_ENABLE *pwm_enable; #ifdef MANAGING_GUI GtkWidget *pu_window; #endif SolarModule(const char *init_name=NULL, const char *desc=NULL); ~SolarModule(); // Inheritances from the Package class virtual void create_iopin_map(void); void setPcm(bool); void setPcmEnable(bool); double battery_voltage(double soc); void Solar_panel(double Ton); void callback(); void set_BDOC(double); double pvi(double); double piv(double); void pvi_init(); static Module *construct(const char *new_name=NULL); double Voc; // Solar panel open circuit voltage double Isc; // Solar panel short circuit current double Vmp; // Solar panel Voltage of max power point double Imp; // Solar panel Current at max power point double VbatOC; // OC Battery voltage double Rbat; // Internal battery resistance double Vscale; // Voltage scale factor double VSscale; // Panel Voltage scale factor double VBscale; // Battery Voltage scale factor double Ascale; // Current scale factor V/A double Aoffset; // Zero current offset voltage double BcapMax; // Max battery capacity amp-hours double BDOC; // Battery Degree of charge double cap_mah; // Battery capacity mAH double cur_mah; // Battery current charge double delta_mah; // accumulate charge added to battery bool enabled; bool active; double Nvt; double Isat; double Vsp; // Present solar panel output voltage double Isp; // Present solar panel output current double inductor; // controler inductor #ifdef MANAGING_GUI void build_window(void); #endif private: VSscaleAttribute *VSattr; VBscaleAttribute *VBattr; AscaleAttribute *AVattr; AoffAttribute *Aoffattr; inductorAttribute *indattr; DOCAttribute *docattr; guint64 future_cycle; double r0, r1, r2, r3; double v1, v2, v3; double i1, i2, i3; // Variables double Vsolar; // Present panel output voltage double Asolar; // Present panel output current double VBterm; // Present Baterry terminal voltage gint64 Tperiod; // cycles PWM period gint64 Thigh; // cycles PWM high guint64 start_cycle; // }; #endif // __SOLAR_H__ gpsim-0.30.0/extras/Makefile.in0000664000076400007640000007514313117441635013236 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile for the extras module library # #AUTOMAKE_OPTIONS = subdir-objects VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsim_extras_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp am_libgpsim_extras_la_OBJECTS = module_manager.lo ds1820/bit1w.lo \ ds1820/ds1820.lo ds1820/rom1w.lo ds1307/ds1307.lo \ solar/solar.lo lcd/hd44780.lo lcd/lcdgui.lo lcd/lcd.lo \ dht11/dht11.lo lcd/raw_lcd.lo \ graphic_lcd/src/glcd_100X32_sed1520.lo graphic_lcd/src/glcd.lo \ graphic_lcd/src/osram.lo graphic_lcd/src/sed1520.lo \ graphic_lcd/src/ssd0323.lo libgpsim_extras_la_OBJECTS = $(am_libgpsim_extras_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libgpsim_extras_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libgpsim_extras_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libgpsim_extras_la_SOURCES) DIST_SOURCES = $(libgpsim_extras_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ -Ids1820 -Ilcd -Ids1307 -Idht11 \ -Isolar -Igraphic_lcd/src lib_LTLIBRARIES = libgpsim_extras.la libgpsim_extras_la_SOURCES = \ module_manager.cc ds1820/bit1w.cc ds1820/ds1820.cc \ ds1820/rom1w.cc ds1307/ds1307.cc solar/solar.cc \ lcd/hd44780.cc lcd/lcdgui.cc lcd/lcd.cc dht11/dht11.cc \ lcd/raw_lcd.cc \ graphic_lcd/src/glcd_100X32_sed1520.cc graphic_lcd/src/glcd.cc \ graphic_lcd/src/osram.cc graphic_lcd/src/sed1520.cc \ graphic_lcd/src/ssd0323.cc libgpsim_extras_la_LDFLAGS = @X_LDFLAGS@ EXTRA_DIST = makefile.mingw \ rs232-gen/rs232-gen.c rs232-gen/Makefile rs232-gen/README \ rs232-gen/example/Makefile rs232-gen/example/README \ rs232-gen/example/example.stc rs232-gen/example/example.asm SUBDIRS = dht11 graphic_lcd ds1820 ds1307 lcd solar all: all-recursive .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } ds1820/$(am__dirstamp): @$(MKDIR_P) ds1820 @: > ds1820/$(am__dirstamp) ds1820/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ds1820/$(DEPDIR) @: > ds1820/$(DEPDIR)/$(am__dirstamp) ds1820/bit1w.lo: ds1820/$(am__dirstamp) \ ds1820/$(DEPDIR)/$(am__dirstamp) ds1820/ds1820.lo: ds1820/$(am__dirstamp) \ ds1820/$(DEPDIR)/$(am__dirstamp) ds1820/rom1w.lo: ds1820/$(am__dirstamp) \ ds1820/$(DEPDIR)/$(am__dirstamp) ds1307/$(am__dirstamp): @$(MKDIR_P) ds1307 @: > ds1307/$(am__dirstamp) ds1307/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ds1307/$(DEPDIR) @: > ds1307/$(DEPDIR)/$(am__dirstamp) ds1307/ds1307.lo: ds1307/$(am__dirstamp) \ ds1307/$(DEPDIR)/$(am__dirstamp) solar/$(am__dirstamp): @$(MKDIR_P) solar @: > solar/$(am__dirstamp) solar/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) solar/$(DEPDIR) @: > solar/$(DEPDIR)/$(am__dirstamp) solar/solar.lo: solar/$(am__dirstamp) solar/$(DEPDIR)/$(am__dirstamp) lcd/$(am__dirstamp): @$(MKDIR_P) lcd @: > lcd/$(am__dirstamp) lcd/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) lcd/$(DEPDIR) @: > lcd/$(DEPDIR)/$(am__dirstamp) lcd/hd44780.lo: lcd/$(am__dirstamp) lcd/$(DEPDIR)/$(am__dirstamp) lcd/lcdgui.lo: lcd/$(am__dirstamp) lcd/$(DEPDIR)/$(am__dirstamp) lcd/lcd.lo: lcd/$(am__dirstamp) lcd/$(DEPDIR)/$(am__dirstamp) dht11/$(am__dirstamp): @$(MKDIR_P) dht11 @: > dht11/$(am__dirstamp) dht11/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) dht11/$(DEPDIR) @: > dht11/$(DEPDIR)/$(am__dirstamp) dht11/dht11.lo: dht11/$(am__dirstamp) dht11/$(DEPDIR)/$(am__dirstamp) lcd/raw_lcd.lo: lcd/$(am__dirstamp) lcd/$(DEPDIR)/$(am__dirstamp) graphic_lcd/src/$(am__dirstamp): @$(MKDIR_P) graphic_lcd/src @: > graphic_lcd/src/$(am__dirstamp) graphic_lcd/src/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) graphic_lcd/src/$(DEPDIR) @: > graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) graphic_lcd/src/glcd_100X32_sed1520.lo: \ graphic_lcd/src/$(am__dirstamp) \ graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) graphic_lcd/src/glcd.lo: graphic_lcd/src/$(am__dirstamp) \ graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) graphic_lcd/src/osram.lo: graphic_lcd/src/$(am__dirstamp) \ graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) graphic_lcd/src/sed1520.lo: graphic_lcd/src/$(am__dirstamp) \ graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) graphic_lcd/src/ssd0323.lo: graphic_lcd/src/$(am__dirstamp) \ graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) libgpsim_extras.la: $(libgpsim_extras_la_OBJECTS) $(libgpsim_extras_la_DEPENDENCIES) $(EXTRA_libgpsim_extras_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgpsim_extras_la_LINK) -rpath $(libdir) $(libgpsim_extras_la_OBJECTS) $(libgpsim_extras_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f dht11/*.$(OBJEXT) -rm -f dht11/*.lo -rm -f ds1307/*.$(OBJEXT) -rm -f ds1307/*.lo -rm -f ds1820/*.$(OBJEXT) -rm -f ds1820/*.lo -rm -f graphic_lcd/src/*.$(OBJEXT) -rm -f graphic_lcd/src/*.lo -rm -f lcd/*.$(OBJEXT) -rm -f lcd/*.lo -rm -f solar/*.$(OBJEXT) -rm -f solar/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@dht11/$(DEPDIR)/dht11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ds1307/$(DEPDIR)/ds1307.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ds1820/$(DEPDIR)/bit1w.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ds1820/$(DEPDIR)/ds1820.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ds1820/$(DEPDIR)/rom1w.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@graphic_lcd/src/$(DEPDIR)/glcd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@graphic_lcd/src/$(DEPDIR)/glcd_100X32_sed1520.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@graphic_lcd/src/$(DEPDIR)/osram.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@graphic_lcd/src/$(DEPDIR)/sed1520.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@graphic_lcd/src/$(DEPDIR)/ssd0323.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lcd/$(DEPDIR)/hd44780.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lcd/$(DEPDIR)/lcd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lcd/$(DEPDIR)/lcdgui.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lcd/$(DEPDIR)/raw_lcd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@solar/$(DEPDIR)/solar.Plo@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf dht11/.libs dht11/_libs -rm -rf ds1307/.libs ds1307/_libs -rm -rf ds1820/.libs ds1820/_libs -rm -rf graphic_lcd/src/.libs graphic_lcd/src/_libs -rm -rf lcd/.libs lcd/_libs -rm -rf solar/.libs solar/_libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f dht11/$(DEPDIR)/$(am__dirstamp) -rm -f dht11/$(am__dirstamp) -rm -f ds1307/$(DEPDIR)/$(am__dirstamp) -rm -f ds1307/$(am__dirstamp) -rm -f ds1820/$(DEPDIR)/$(am__dirstamp) -rm -f ds1820/$(am__dirstamp) -rm -f graphic_lcd/src/$(DEPDIR)/$(am__dirstamp) -rm -f graphic_lcd/src/$(am__dirstamp) -rm -f lcd/$(DEPDIR)/$(am__dirstamp) -rm -f lcd/$(am__dirstamp) -rm -f solar/$(DEPDIR)/$(am__dirstamp) -rm -f solar/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) dht11/$(DEPDIR) ds1307/$(DEPDIR) ds1820/$(DEPDIR) graphic_lcd/src/$(DEPDIR) lcd/$(DEPDIR) solar/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) dht11/$(DEPDIR) ds1307/$(DEPDIR) ds1820/$(DEPDIR) graphic_lcd/src/$(DEPDIR) lcd/$(DEPDIR) solar/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libLTLIBRARIES \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/Makefile.am0000664000076400007640000000166213117107176013217 00000000000000# Makefile for the extras module library # #AUTOMAKE_OPTIONS = subdir-objects AM_CPPFLAGS = @X_CFLAGS@ -Ids1820 -Ilcd -Ids1307 -Idht11 \ -Isolar -Igraphic_lcd/src lib_LTLIBRARIES = libgpsim_extras.la libgpsim_extras_la_SOURCES = \ module_manager.cc ds1820/bit1w.cc ds1820/ds1820.cc \ ds1820/rom1w.cc ds1307/ds1307.cc solar/solar.cc \ lcd/hd44780.cc lcd/lcdgui.cc lcd/lcd.cc dht11/dht11.cc \ lcd/raw_lcd.cc \ graphic_lcd/src/glcd_100X32_sed1520.cc graphic_lcd/src/glcd.cc \ graphic_lcd/src/osram.cc graphic_lcd/src/sed1520.cc \ graphic_lcd/src/ssd0323.cc libgpsim_extras_la_LDFLAGS = @X_LDFLAGS@ EXTRA_DIST = makefile.mingw \ rs232-gen/rs232-gen.c rs232-gen/Makefile rs232-gen/README \ rs232-gen/example/Makefile rs232-gen/example/README \ rs232-gen/example/example.stc rs232-gen/example/example.asm SUBDIRS = dht11 graphic_lcd ds1820 ds1307 lcd solar CFLAGS = @CFLAGS@ gpsim-0.30.0/extras/lcd/0000775000076400007640000000000013117466030011775 500000000000000gpsim-0.30.0/extras/lcd/caps.pl0000775000076400007640000000645713041763633013224 00000000000000#!perl # caps.pl - cheesy ass perl script :) [I'm serious]... # # When writing lcd.c, I was faced with the arduous task # of creating the font for the display. So rather than use # an error prone method of typing in the bit maps for # the display, I decided to write this really cheesy # perl script instead. Peer Ou?????land's LCD web page # has a .gif file with all of the characters of the LCD # display. So I downloaded that and converted it to an # .xpm (using gimp). The purpose of this script is to # confer that xpm into a file that can be included by lcd.c # # ps. This is my first perl program more than three lines # long - you'll do yourself injustice trying to learn # anything from it. open(LCDXPM, "lcd.xpm") || die("unable to open lcd.xpm\n"); print("Opened lcd.xpm\n"); $first = 0; $chars = 0; $line = ; while ($first eq 0) { chop ($line); $_ = $line; $dots = tr/././; $line = $_; if ( $dots > 196) { $first = 1; $start_col = index($line, "......"); $end_col = rindex($line, "."); print("First, start column $start_col\n"); $line_no = 0; } $line = ; } for($row = 0; $row<16; $row++) { $line = ; for($line_no = 1; $line_no < 8; $line_no++) { $line = ; $col = 0; for($i = $start_col; $i < $end_col; $i+=15) { $rc = ""; for($j=3; $j<13; $j+=2) { $rc .= substr($line, $i+$j, 1); } print("$rc"); $el[$col*16 + $row][$line_no] = $rc; $col++; if($col eq 1) {$col++;} if($col eq 8) {$col = $col + 2;} } $line = ; print("\n"); } $line = ; $line = ; $line = ; $line = ; $line = ; $line = ; $line = ; } # at this point, the .xpm file has been parsed and the # array $el[][] contains the font # # As a test, write this string using the font: $s= "LCD display"; for ($j=1; $j<8; $j++) { for ($i=0; $ilcdfont.h")) { die ("can't open lcdfont.h\n"); } print LCDFONTFILE ("#define FONT_LEN 256\n") ; print LCDFONTFILE ("_5X7 test[FONT_LEN] = {\n"); for($i=0; $i<256; $i++) { #if( (i>=0x20) && (i<0x80)) printf LCDFONTFILE (" { /* %x */\n",$i); for($j=1; $j<8; $j++) { print LCDFONTFILE (" \"$el[$i][$j]\",\n"); } print LCDFONTFILE (" },\n"); } print LCDFONTFILE (" };\n"); # Just for kicks, create an include file for # a pic: unless (open (LCDFONTINCFILE, ">lcdfont.inc")) { die ("can't open lcdfont.inc\n"); } print LCDFONTINCFILE ("\n;;\n;; LCD Font file for 7x5 characters\n"); print LCDFONTINCFILE (";; Automatically created from a perl script\n") ; print LCDFONTINCFILE (";; T. Scott Dattalo http://www.dattalo.com/gnupic/lcd.html\n") ; print LCDFONTINCFILE (";;\n\n"); for($i=0; $i<256; $i++) { print LCDFONTINCFILE ("\n\tdt "); for($k = 0; $k <= 4; $k++) { $c = 0; for($j=1; $j<8; $j++) { $c = $c * 2; if(substr($el[$i][$j], $k, 1) eq ".") {$c = $c+1;} $t = substr($el[$i][$j], $k, 1); #print "$t $c"; } printf LCDFONTINCFILE ("0x%02x",$c); if($k eq 4) { print LCDFONTINCFILE (" ; $i"); } else { print LCDFONTINCFILE (", "); } } } print LCDFONTINCDFILE ("\n"); gpsim-0.30.0/extras/lcd/lcd.cc0000664000076400007640000003067413041763633013005 00000000000000/* Copyright (C) 2000 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* lcd.cc This is a fairly complete/complicated gpsim module that simulates an LCD display. This version is currently hardcoded for the Hitachi style 2 row by 20 column display. The font is also hardcoded to 5 by 7 pixels. Hardware simulation: The Hitachi displays commonly have a 14pin interface: 8 data lines 3 control lines (E,RS,R/W) pwr gnd contrast This version only supports the 8 data and 3 control lines. Software simulation: This software uses an event driven behavior model to simulate the LCD display. This means that when one of the I/O lines toggle the module will be notified and will respond to the event. A state machine is used to control the behavior. */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "config.h" #ifdef HAVE_GUI #include #include "hd44780.h" #include "lcd.h" #include #include Trace *gTrace=0; // Points to gpsim's global trace object. //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif //------------------------------------------------------------------------ // I/O pins for the LCD //------------------------------------------------------------------------ // The LCD_InputPin is the base class for the E, RW and DC // pins. This class is derived from the IO_bi_directional class, // although the pins are never driven as outputs. The setDrivenState // method is overridden to capture when this pin is driven. class LCD_InputPin : public IO_bi_directional { public: LCD_InputPin (LcdDisplay *, const char *pinName, ePins pin); // Capture when a node drives this pin. virtual void setDrivenState(bool new_dstate); char CurrentState() { return m_cDrivenState; } private: // The IO_bi_directional constructor will initialize the direction // to be an input. We'll override the update_direction method so that // this will never change. virtual void update_direction(unsigned int,bool refresh) { // Disallow pin direction changes. } LcdDisplay *m_pLCD; ePins m_pin; char m_cDrivenState; }; //------------------------------------------------------------------------ // class LCDSignalControl : public SignalControl { public: LCDSignalControl(LcdDisplay *pLCD) : m_pLCD(pLCD) { assert(m_pLCD); } virtual void release() { } virtual char getState() { // returning a 1 indicates the data bus is an input (the LCD module // is being written to). char state = m_pLCD->dataBusDirection() ? '1' : '0'; //Dprintf(("LCDSignalControl returning:%c\n",state)); return state; } private: LcdDisplay *m_pLCD; }; //------------------------------------------------------------------------ // LCD_InputPin::LCD_InputPin (LcdDisplay *pLCD, const char *pinName, ePins pin) : IO_bi_directional(pinName), m_pLCD(pLCD), m_pin(pin),m_cDrivenState(0) { } void LCD_InputPin::setDrivenState(bool new_dstate) { IO_bi_directional::setDrivenState(new_dstate); char cState = getBitChar(); Dprintf(("LCD_InputPin setDrivenState:%d, cState:%c\n",new_dstate,cState)); if (m_cDrivenState != cState) { m_cDrivenState = cState; m_pLCD->UpdatePinState(m_pin, cState); } } //------------------------------------------------------------------------ // Tracing // LcdWriteTO::LcdWriteTO(LcdDisplay *_lcd) : LcdTraceObject(_lcd) { } void LcdWriteTO::print(FILE *fp) { fprintf(fp, " Wrote: LCD"); } LcdReadTO::LcdReadTO(LcdDisplay *_lcd) : LcdTraceObject(_lcd) { } void LcdReadTO::print(FILE *fp) { fprintf(fp, " Read: LCD"); } //---------------------------------------- LcdWriteTT::LcdWriteTT(LcdDisplay *_lcd, unsigned int s) : LcdTraceType(_lcd,s) { } TraceObject *LcdWriteTT::decode(unsigned int tbi) { LcdWriteTO *lto = new LcdWriteTO(lcd); gTrace->addToCurrentFrame(lto); return lto; } int LcdWriteTT::dump_raw(unsigned tbi, char *buf, int bufsize) { int n = TraceType::dump_raw(gTrace,tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int tv = gTrace->get(tbi); int m = g_snprintf(buf, bufsize, " LCD Write 0x%08x", tv); if (m < bufsize) n += m; return n; } //---------------------------------------- LcdReadTT::LcdReadTT(LcdDisplay *_lcd, unsigned int s) : LcdTraceType(_lcd,s) { } TraceObject *LcdReadTT::decode(unsigned int tbi) { LcdReadTO *lto = new LcdReadTO(lcd); gTrace->addToCurrentFrame(lto); return lto; } int LcdReadTT::dump_raw(unsigned tbi, char *buf, int bufsize) { int n = TraceType::dump_raw(gTrace, tbi,buf,bufsize); buf += n; bufsize -= n; unsigned int tv = gTrace->get(tbi); int m = g_snprintf(buf, bufsize, " LCD Read 0x%08x", tv); if (m < bufsize) n += m; return n; } //------------------------------------------------------------------------ // // LCD interface to the simulator // LCD_Interface::LCD_Interface(LcdDisplay *_lcd) : Interface ( (gpointer *) _lcd) { lcd = _lcd; } //-------------------------------------------------- // SimulationHasStopped (gpointer) // // gpsim will call this function when the simulation // has halt (e.g. a break point was hit.) void LCD_Interface::SimulationHasStopped (gpointer) { if (lcd) lcd->update(); } void LCD_Interface::Update (gpointer) { if (lcd) lcd->update(); } //--------------------------------------------------------------- void LcdDisplay::update() { gtk_widget_queue_draw(darea); } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void LcdDisplay::create_iopin_map(void) { // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // create_pkg(14); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created. For the binary // indicator, both pins are inputs. The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. m_E = new LCD_InputPin(this, "E", eE); m_RW = new LCD_InputPin(this, "RW", eRW); m_DC = new LCD_InputPin(this, "DC", eDC); addSymbol(m_E); addSymbol(m_RW); addSymbol(m_DC); // Control assign_pin(4, m_DC); assign_pin(5, m_RW); assign_pin(6, m_E); char text[] = "d0"; for(int i = 0; i<8; i++) { text[1] = '0' + i; lcd_bus[i] = new IO_bi_directional(text); addSymbol(lcd_bus[i]); assign_pin(i+7, m_dataBus->addPin(lcd_bus[i], i)); } // Provide a SignalControl object that the dataBus port can query // to determine which direction to drive the data bus. // (See for more documentation on port behavior. // But in summary, when an I/O port updates its I/O pins, it will // query the pin drive direction via the SignalControl object. ) SignalControl *pPortDirectionControl = new LCDSignalControl(this); for (int i=0; i<8; i++) (*m_dataBus)[i].setControl(pPortDirectionControl); } //-------------------------------------------------------------- TraceType *LcdDisplay::getWriteTT() { if(!writeTT) { writeTT = new LcdWriteTT(this,1); gTrace->allocateTraceType(writeTT); } return writeTT; } TraceType *LcdDisplay::getReadTT() { if(!readTT) { readTT = new LcdReadTT(this,1); gTrace->allocateTraceType(readTT); } return readTT; } //-------------------------------------------------------------- // construct Module * LcdDisplay::construct(const char *new_name=NULL) { LcdDisplay *lcdP = new LcdDisplay(new_name,2,20); lcdP->set_pixel_resolution(5,8); return lcdP; } LcdDisplay::LcdDisplay(const char *_name, int aRows, int aCols, unsigned aType) : Module(_name), data_latch(0), data_latch_phase(1), debug(0), rows(aRows), cols(aCols), disp_type(aType), contrast(1.0), fontP(NULL), readTT(new LcdReadTT(this,1)), writeTT(new LcdWriteTT(this,1)), m_controlState(0), cgram_updated(false) { if (verbose) cout << "LcdDisplay constructor\n"; new_name(_name); m_dataBus = new PortRegister(this, "data", "LCD Data Port", 8, 0); m_hd44780 = new HD44780(); // mode_flag = _8BIT_MODE_FLAG; last_event = eWC; set_pixel_resolution(); set_crt_resolution(); cursor.row = 0; cursor.col = 0; // If you want to get diagnostic info, change debug to non-zero. if (getenv("GPSIM_LCD_DEBUG")) debug = atoi(getenv("GPSIM_LCD_DEBUG")); gTrace = &get_trace(); interface_seq_number = get_interface().add_interface(new LCD_Interface(this)); addSymbol(m_dataBus); m_dataBus->setEnableMask(0xff); CreateGraphics(); create_iopin_map(); } LcdDisplay::~LcdDisplay() { if (verbose) cout << "LcdDisplay destructor\n"; removeSymbol(m_E); removeSymbol(m_RW); removeSymbol(m_DC); for(int i = 0; i<8; i++) { removeSymbol(lcd_bus[i]); } removeSymbol(m_dataBus); delete m_dataBus; delete m_hd44780; get_interface().remove_interface(interface_seq_number); gtk_widget_destroy(window); if (fontP) delete fontP; } //------------------------------------------------------------------------ bool LcdDisplay::dataBusDirection() { return m_hd44780->dataBusDirection(); } //------------------------------------------------------------------------ void LcdDisplay::UpdatePinState(ePins pin, char cState) { // One of the control lines has changed states. So refresh the // hd44780 with the most current data bus value. // If the data bus I/O's are inputs, then copy the I/O pin // data bus state to the chip data bus: if (m_hd44780->dataBusDirection()) m_hd44780->driveDataBus(m_dataBus->get()); bool bState = (cState =='1') || (cState =='W'); switch (pin) { case eDC: m_hd44780->setDC(bState); break; case eE: m_hd44780->setE(bState); break; case eRW: m_hd44780->setRW(bState); break; } // If the hd44780 is driving, then place that // data onto the data bus. if (m_hd44780->dataBusDirection()) m_dataBus->put(m_hd44780->getDataBus()); m_dataBus->updatePort(); Dprintf(("Control pin:%d is %c and Databus is 0x%02X\n",pin, cState,m_dataBus->get_value())); } //------------------------------------------------------------------------ void LcdDisplay::testHD44780() { m_hd44780->test(); } //----------------------------------------------------------------- // Displaytech 161A, added by Salvador E. Tropea // construct Module * LcdDisplayDisplaytech161A::construct(const char *new_name=NULL) { if (verbose) cout << " LCD 161A display constructor\n"; LcdDisplayDisplaytech161A *lcdP = new LcdDisplayDisplaytech161A(new_name,2,8,TWO_ROWS_IN_ONE); return lcdP; } LcdDisplayDisplaytech161A::LcdDisplayDisplaytech161A(const char *pN, int aRows, int aCols, unsigned aType) : LcdDisplay(pN,aRows,aCols,aType) { } LcdDisplayDisplaytech161A::~LcdDisplayDisplaytech161A() { } //----------------------------------------------------------------- // HD44780 controller with 20x2 display // Module * LcdDisplay20x2::construct(const char *new_name=NULL) { if (verbose) cout << " LCD 20x2 display constructor\n"; LcdDisplay20x2 *lcdP = new LcdDisplay20x2(new_name, 2, 20); lcdP->set_pixel_resolution(5,8); return lcdP; } //----------------------------------------------------------------- // HD44780 controller with 20x4 display // Module * LcdDisplay20x4::construct(const char *new_name=NULL) { if (verbose) cout << " LCD 20x4 display constructor\n"; LcdDisplay20x4 *lcdP = new LcdDisplay20x4(new_name, 4, 20); lcdP->set_pixel_resolution(5,8); return lcdP; } #endif //HVAE_GUI gpsim-0.30.0/extras/lcd/raw_lcd.h0000664000076400007640000000616113117437752013516 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo Copyright (C) 2017 Roy R. Rankin This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __RAW_LCD_H__ #define __RAW_LCD_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include class LCD_7Segments; class CC_stimulus : public stimulus, TriggerObject { public: CC_stimulus(LCD_7Segments *arg, const char *name=0, double _Vth=0.0, double _Zth=1e12 ); ~CC_stimulus(); LCD_7Segments *_lcd_7seg; virtual void set_nodeVoltage(double v); virtual void callback(); guint64 future_cycle; }; //------------------------------------------------------------------------ // RAW_LCD base class class RAW_LCD_base { public: virtual ~RAW_LCD_base() {} virtual void build_window() = 0; virtual void update() = 0; unsigned int interface_seq_no; }; //------------------------------------------------------------------------ // 7-segment lcds // define a point typedef struct { double x; double y; } XfPoint; #define MAX_PTS 6 /* max # of pts per segment polygon */ #define NUM_SEGS 7 /* number of segments in a digit */ /* * These constants give the bit positions for the segmask[] * digit masks. */ #define TOP 0 #define TOP_RIGHT 1 #define BOT_RIGHT 2 #define BOTTOM 3 #define BOT_LEFT 4 #define TOP_LEFT 5 #define MIDDLE 6 //#define DECIMAL_POINT 7 typedef XfPoint segment_pts[NUM_SEGS][MAX_PTS]; class LCD_7Segments : public Module, public RAW_LCD_base { public: guint w_width; guint w_height; segment_pts seg_pts; GtkWidget *darea; LCD_7Segments(const char *); ~LCD_7Segments(); void build_segments( int w, int h); virtual void build_window(); virtual void update(); void set_cc_stimulus(); void new_cc_voltage(double Vcc); // Inheritances from the Package class virtual void create_iopin_map(); // Inheritance from Module class const virtual char *type() { return ("lcd_7segments"); }; static Module *construct(const char *new_name); private: static gboolean lcd7_expose_event(GtkWidget *widget, GdkEvent *event, gpointer user_data); //unsigned int m_segmentStates; //PinModule *m_pins[8]; IOPIN *m_pins[8]; int m_nPins; unsigned int segments; CC_stimulus *cc_stimulus; }; #endif // __RAW_LCD_H__ gpsim-0.30.0/extras/lcd/AUTHORS0000664000076400007640000000011013041763633012762 00000000000000Scott Dattalo Salvador Eduardo Tropea Robert Pearce gpsim-0.30.0/extras/lcd/hd44780.cc0000664000076400007640000004053513045306452013236 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define IN_MODULE #include "config.h" #ifdef HAVE_GUI #include #include #include #include #include #include #include "hd44780.h" #include //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif /**************************************************************** * * HD44780 - gpsim module */ /* * LCD Command "Set Display Data RAM Address" = 10000000 */ static const unsigned int LCD_CMD_SET_DDRAM = 0x80; static const unsigned int LCD_MASK_SET_DDRAM = 0x80; /* * LCD Command "Set Display Character Generator RAM Address" = 01aaaaaa */ static const unsigned int LCD_CMD_SET_CGRAM = 0x40; static const unsigned int LCD_MASK_SET_CGRAM = 0xc0; /* * LCD Command Function Set = 001dnfxx * d = 1 for 8-bit interface or 0 for 4-bit interface * n = for 2 line displays, n=1 allows both lines to be displayed * while n=0 only allows the first. * f = font size. f=1 is for 5x11 dots while f=0 is for 5x8 dots. */ static const unsigned int LCD_CMD_FUNC_SET = 0x20; // LCD Command "Function Set" static const unsigned int LCD_MASK_FUNC_SET = 0xe0; // static const unsigned int LCD_4bit_MODE = 0x00; // d=0 static const unsigned int LCD_8bit_MODE = 0x10; // d=1 static const unsigned int LCD_1_LINE = 0x00; // n=0 static const unsigned int LCD_2_LINES = 0x08; // n=1 static const unsigned int LCD_SMALL_FONT = 0x00; // f=0 static const unsigned int LCD_LARGE_FONT = 0x04; // f=1 /* * LCD Command "Cursor Display" = 0001sdxx * s = 1 Sets cursor-move or display-shift * d = 1 Shift right 0 = shift left */ static const unsigned int LCD_CMD_CURSOR_DISPLAY = 0x10; // LCD Command "Cursor Display" static const unsigned int LCD_MASK_CURSOR_DISPLAY = 0xf0; // /* * LCD Command Display Control = 00001dcb * d = 1 turn display on or 0 to turn display off * c = 1 turn cursor on or 0 to turn cursor off * b = 1 blinking cursor or 0 non-blinking cursor */ static const unsigned int LCD_CMD_DISPLAY_CTRL = 0x08; // LCD Command "Display Control" static const unsigned int LCD_MASK_DISPLAY_CTRL = 0xf8; // static const unsigned int LCD_DISPLAY_OFF = 0x00; // d=0 static const unsigned int LCD_DISPLAY_ON = 0x04; // d=1 static const unsigned int LCD_CURSOR_OFF = 0x00; // c=0 static const unsigned int LCD_CURSOR_ON = 0x02; // c=1 static const unsigned int LCD_BLINK_OFF = 0x00; // b=0 static const unsigned int LCD_BLINK_ON = 0x01; // b=1 /* * LCD Command "Entry Mode" = 000001is * i = 1 to increment or 0 to decrement the DDRAM address after each DDRAM access. * s = 1 to scroll the display in the direction specified by the i-bit when the * cursor reaches the edge of the display window. */ static const unsigned int LCD_CMD_ENTRY_MODE = 0x04; // LCD Command "Entry Mode" static const unsigned int LCD_MASK_ENTRY_MODE = 0xfc; // static const unsigned int LCD_DEC_CURSOR_POS = 0x00; // i=0 static const unsigned int LCD_INC_CURSOR_POS = 0x02; // i=1 static const unsigned int LCD_NO_SCROLL = 0x00; // s=0 static const unsigned int LCD_SCROLL = 0x01; // s=1 /* * LCD Command "Cursor Home" = 0000001x */ static const unsigned int LCD_CMD_CURSOR_HOME = 0x02; // LCD Command "Cursor Home" static const unsigned int LCD_MASK_CURSOR_HOME = 0xfe; // // LCD Command Clear Display = 00000001 static const unsigned int LCD_CMD_CLEAR_DISPLAY = 0x01; static const unsigned int LCD_MASK_CLEAR_DISPLAY = 0xff; //======================================================================== // Busy - a class to handle the HD44780's busy flag // // This class is essentially a timer. When the LCD requests that the // busy flag be set for a period of time, it will call the set() method // and pass the amount of time it wishes the flag to be busy. When // this time expires, the flag will get cleared. class HD44780Busy : public TriggerObject { public: HD44780Busy() : bBusyState(false) {} void set(double waitTime); void clear(); inline bool isBusy() { return bBusyState; } virtual void callback(); private: bool bBusyState; }; //-------------------------------------------------------------- void HD44780Busy::set(double waitTime) { if(!bBusyState) { bBusyState = true; get_cycles().set_break(get_cycles().get(waitTime), this); } } void HD44780Busy::clear() { clear_trigger(); bBusyState = false; } //-------------------------------------------------------------- void HD44780Busy::callback() { bBusyState = false; } //------------------------------------------------------------------------ HD44780::HD44780() : m_bE(true), m_controlState(0), m_chipState(ePowerON), m_dataBus(0), m_phasedData(0), m_bBitMode(true), // 8-bit mode m_bLineMode(false), // 1-line mode m_bFontMode(false), // small font m_bDisplayOn(false), // display is off m_bCursorBlink(false),// no cursor blink m_bCursorOn(false), // cursor is off m_bDataBusPhase(false), m_DDRamAdd(0), m_CGRamAdd(0), m_bInCGRam(false), m_CGRamupdate(false) { m_busyTimer = new HD44780Busy(); memset(&m_CGRam[0], 0xff, sizeof(m_CGRam)); memset(&m_DDRam[0], 0xff, sizeof(m_DDRam)/2); memset(&m_DDRam[DDRAM_SIZE/2], 0, sizeof(m_DDRam)/2); row_offset[0] = 0; row_offset[1] = 0x40; row_offset[2] = 0x14; row_offset[3] = 0x54; } HD44780::~HD44780() { delete m_busyTimer; } //------------------------------------------------------------------------ void HD44780::setDC(bool newDC) { m_controlState &= ~eDC; m_controlState |= (newDC ? eDC : 0); } void HD44780::setRW(bool newRW) { m_controlState &= ~eRW; m_controlState |= (newRW ? eRW : 0); } void HD44780::setE(bool newE) { bool bRW = (m_controlState & eRW) != 0; if (m_bE != newE && m_bE^bRW ) { // Only act if there was a change in E // FIXME: what happens on the real chip if DC or RW change while E is high? // There are only 4 states corresponding to the combinations of RW and DC. // Note. For reads, we act on the rising edge of E while for writes on // the falling edge. switch (m_controlState) { case eDataRead: driveDataBus(getData()); advanceColumnAddress(); break; case eCommandRead: driveDataBus(getStatus()); break; case eDataWrite: storeData(); advanceColumnAddress(); break; case eCommandWrite: executeCommand(); break; default: Dprintf((" unhandled control state:%u\n", m_controlState)); } } m_bE = newE; } //------------------------------------------------------------------------ // driveDataBus - place an 8-bit value on the data bus. // Note that this routine doesn't directly affect the I/O pins of an LCD module. // The Pin control code resides elsewhere (lcd.cc) and will read the HD44780 // data bus to determine how the pins should be driven void HD44780::driveDataBus(unsigned int d) { //RRR Dprintf(("driveDataBus 0x%02x\n",d)); m_dataBus = d; } //------------------------------------------------------------------------ // advanceColumnAddress() - A read or write from the DDRAM increments // the column address. If we're in 4-bit mode, then only increment after // the 2nd read or write. void HD44780::advanceColumnAddress() { if (b8BitMode() || m_bDataBusPhase) { if (m_bInCGRam) m_CGRamAdd = (m_CGRamAdd + 1) & CGRAM_MASK; else m_DDRamAdd = (m_DDRamAdd + 1) & DDRAM_MASK; } } //------------------------------------------------------------------------ // phasedDataWrite - returns true if a write operation complements. The data // written is returned by reference. // Write operations always complete in 8-bit mode, but take two phases in // 4-bit mode. bool HD44780::phasedDataWrite(unsigned int &data) { if (b8BitMode()) { data = m_dataBus & 0xff; return true; } // In 4-bit mode, the upper nibble is written first. // First, move the last nibble written to the upper half of phasedData m_phasedData &= 0x0f; m_phasedData <<= 4; // Next, get the nibble on the data bus and put it in the lower half of phasedData. m_phasedData |= ((m_dataBus>>4) & 0x0f); data = m_phasedData; // Toggle the phase. // FIXME - The phase logic needs more attention. There should be a method for // setting the phase. m_bDataBusPhase = !m_bDataBusPhase; return m_bDataBusPhase; } //------------------------------------------------------------------------ // storeData - write a byte to the DDRAM or CGRAM // void HD44780::storeData() { unsigned int d; if (phasedDataWrite(d)) { if (m_bInCGRam) { m_CGRam[m_CGRamAdd] = d; m_CGRamupdate = true; } else { m_DDRam[m_DDRamAdd] = d; } } } //------------------------------------------------------------------------ // getData - get a byte from tehe DDRAM unsigned int HD44780::getData() { if (m_bInCGRam) return m_CGRam[m_CGRamAdd]; else return m_DDRam[m_CGRamAdd]; } void HD44780::executeCommand() { unsigned int command; // command is set in the following call if (!phasedDataWrite(command)) return; // // Determine the command type // Dprintf(("Execute Command:0x%u\n", command)); if( (command & LCD_MASK_SET_DDRAM) == LCD_CMD_SET_DDRAM) { Dprintf(("LCD_CMD_SET_DDRAM\n")); writeDDRamAddress(command & DDRAM_MASK); m_busyTimer->set(39e-6); // busy for 39 usec after set DDRAM addr } else if( (command & LCD_MASK_SET_CGRAM) == LCD_CMD_SET_CGRAM) { Dprintf(("LCD_CMD_SET_CGRAM\n")); writeCGRamAddress(command & CGRAM_MASK); } else if( (command & LCD_MASK_FUNC_SET) == LCD_CMD_FUNC_SET) { Dprintf(("LCD_CMD_FUNC_SET\n")); // // Check the bits in the command // if(command & LCD_8bit_MODE) set8bitMode(); else { set4bitMode(); // If the lcd is in '4-bit' mode, then this flag // will tell us which four bits are being written. m_bDataBusPhase = true; } if(command & LCD_2_LINES) set2LineMode(); else set1LineMode(); if(command & LCD_LARGE_FONT) setLargeFontMode(); else setSmallFontMode(); m_busyTimer->set(39e-6); // busy for 39 usec after DDRAM write } else if( (command & LCD_MASK_CURSOR_DISPLAY) == LCD_CMD_CURSOR_DISPLAY) { printf("LCD_CMD_CURSOR_DISPLAY\n"); printf("NOT SUPPORTED\n"); } else if( (command & LCD_MASK_DISPLAY_CTRL) == LCD_CMD_DISPLAY_CTRL) { Dprintf(("LCD_CMD_DISPLAY_CTRL\n")); if(command & LCD_DISPLAY_ON) setDisplayOn(); else setDisplayOff(); if(command & LCD_CURSOR_ON) setCursorOn(); else setCursorOff(); if(command & LCD_BLINK_ON) setBlinkOn(); else setBlinkOff(); } else if( (command & LCD_MASK_ENTRY_MODE) == LCD_CMD_ENTRY_MODE) { if ((command & ~LCD_MASK_ENTRY_MODE) != LCD_INC_CURSOR_POS) { cout << "LCD_CMD_ENTRY_MODE\n"; cout << "NOT SUPPORTED\n"; } else { Dprintf(("LCD_CMD_ENTRY_MODE cursorpos=inc scroll=no\n")); } } else if( (command & LCD_MASK_CURSOR_HOME) == LCD_CMD_CURSOR_HOME) { Dprintf(("LCD_CMD_CURSOR_HOME\n")); m_DDRamAdd = 0; } else if( (command & LCD_MASK_CLEAR_DISPLAY) == LCD_CMD_CLEAR_DISPLAY) { Dprintf(("LCD_CMD_CLEAR_DISPLAY\n")); clearDisplay(); m_busyTimer->set(1350e-6); // busy for 1.3 msec after clear screen } else Dprintf(("UNKOWN command : 0x%x\n", command)); debugChipState(__FUNCTION__); } //------------------------------------------------------------------------ // dataBusDirection() - returns true if the data bus is an input bool HD44780::dataBusDirection() { return ! ((m_controlState & eRW) && m_bE); } //------------------------------------------------------------------------ unsigned int HD44780::getDataBus() { return m_dataBus; } //------------------------------------------------------------------------ // // send_status unsigned int HD44780::getStatus() { unsigned short status; if (m_bInCGRam) status = m_CGRamAdd; else status = m_DDRamAdd; if (m_busyTimer->isBusy()) status |= 0x80; return dataPhase(status); } //------------------------------------------------------------------------ // unsigned int HD44780::dataPhase(unsigned int d) { if (b8BitMode()) return d; m_bDataBusPhase = !m_bDataBusPhase; return !m_bDataBusPhase ? ((d<<4) & 0xf0) : d; } //------------------------------------------------------------------------ void HD44780::writeDDRamAddress(int data) { // // The first 0x40 memory locations are mapped to // row 0 and the second 0x40 to row 1. Now only // the first 40 (decimal not hex) locations are // valid RAM. And of course, only the first 20 //of these can be displayed in a 2x20 display. // data &= DDRAM_MASK; m_DDRamAdd = data; m_bInCGRam = false; } unsigned char HD44780::getDDRam(unsigned int r, unsigned int c) { int add; if ( r>=4) { fprintf(stderr, "%s row %u not supported\n", __FUNCTION__, r); return 0; } add = row_offset[r] + c; return m_DDRam[add & DDRAM_MASK]; } //------------------------------------------------------------------------ void HD44780::writeCGRamAddress(int data) { data &= CGRAM_MASK; m_CGRamAdd = data; m_bInCGRam = true; } //------------------------------------------------------------------------ void HD44780::clearDisplay() { memset(&m_DDRam[0], ' ', sizeof(m_DDRam)); m_DDRamAdd = 0; } //------------------------------------------------------------------------ void HD44780::debugChipState(const char *pCFrom) { #ifdef DEBUG printf("Chip state from %s\n",pCFrom); printf(" ControlState: %u dataBus:0x%x phase:%d\n", m_controlState, m_dataBus, m_bDataBusPhase); printf(" Mode: %dbit %dLine Display-%s\n", (b8BitMode() ? 8 : 4), (b1LineMode() ? 1 : 2), (bDisplayOn() ? "ON" : "OFF")); printf(" DDRam Address:0x%02x CGRam Address:0x%02x CGRam active %d\n", m_DDRamAdd, m_CGRamAdd, m_bInCGRam); #endif } static void printTestResult(bool b, const char * testName) { printf(" %s:%s\n", testName, (b ? "PASSED" : "FAILED") ); } //------------------------------------------------------------------------ void HD44780::test() { printf("HD44780 self test\n"); set8bitMode(); setRW(false); setDC(false); driveDataBus(LCD_CMD_FUNC_SET | LCD_8bit_MODE); setE(true); setE(false); printTestResult(b8BitMode(),"setting 8-bit mode"); driveDataBus(LCD_CMD_FUNC_SET | LCD_4bit_MODE); setE(true); setE(false); printTestResult(b4BitMode(),"setting 4-bit mode"); driveDataBus(LCD_CMD_FUNC_SET | LCD_4bit_MODE | LCD_2_LINES | LCD_SMALL_FONT); setE(true); setE(false); driveDataBus((LCD_CMD_FUNC_SET | LCD_4bit_MODE | LCD_2_LINES | LCD_SMALL_FONT)<<4); setE(true); setE(false); printTestResult(b2LineMode(),"setting small font & 2-line modes"); driveDataBus(LCD_CMD_DISPLAY_CTRL | LCD_DISPLAY_ON); setE(true); setE(false); driveDataBus((LCD_CMD_DISPLAY_CTRL | LCD_DISPLAY_ON)<<4); setE(true); setE(false); printTestResult(bDisplayOn(),"turning on display"); driveDataBus(LCD_CMD_CLEAR_DISPLAY); setE(true); setE(false); driveDataBus(LCD_CMD_CLEAR_DISPLAY<<4); setE(true); setE(false); const char *s ="ASHLEY & AMANDA"; int l = strlen(s); int i; setDC(true); for(i=0; i=0x20 ? ch : '.')); } printf("\n"); set8bitMode(); #if 0 set_8bit_mode(); viewInternals(0xff); #endif } #endif // HAVE_GUI gpsim-0.30.0/extras/lcd/Makefile.in0000664000076400007640000004610013117441635013767 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile for the LCD module # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras/lcd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = lcd.gif caps.pl lcd.xpm lcdfont.h lcdfont.inc README \ hd44780.h lcdfont.h lcd.h raw_lcd.h t.gif examples/lcdmemtest.c \ examples/lcdmemtest.stc examples/lcd_917.asm examples/lcd_916.asm \ examples/Makefile examples/lcd.inc examples/lcd_mod.asm\ examples/lcd.asm examples/screen.inc examples/screen.asm \ examples/lcd_mod20x4.stc examples/lcd_mod.stc examples/icons.inc \ examples/README SUBDIRS = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/lcd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/lcd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/lcd/Makefile.am0000664000076400007640000000071213114511616013747 00000000000000# Makefile for the LCD module # EXTRA_DIST = lcd.gif caps.pl lcd.xpm lcdfont.h lcdfont.inc README \ hd44780.h lcdfont.h lcd.h raw_lcd.h t.gif examples/lcdmemtest.c \ examples/lcdmemtest.stc examples/lcd_917.asm examples/lcd_916.asm \ examples/Makefile examples/lcd.inc examples/lcd_mod.asm\ examples/lcd.asm examples/screen.inc examples/screen.asm \ examples/lcd_mod20x4.stc examples/lcd_mod.stc examples/icons.inc \ examples/README SUBDIRS = gpsim-0.30.0/extras/lcd/raw_lcd.cc0000664000076400007640000003316313117440707013650 00000000000000/* Copyright (C) 2017 Roy R. Rankin Copyright (C) 2000 T. Scott Dattalo This file is part of the libgpsim_extras library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* lcd.cc This is an example module illustrating how gpsim modules may be created. Additional examples may also be found with the gpsim. This particular example creates a 7-segment, common cathode LCD display. Pin Numbering of LCD: -------------------- a --- f | g | b --- e | | c --- d cc = common cathode Electrical: ---------- a ---|>|---+ b ---|>|---+ c ---|>|---+ d ---|>|---+ e ---|>|---+ f ---|>|---+ g ---|>|---+ | cc How It Works: ------------ Once the LCD module has been built (and optionally installcd), you can include it in your .stc file. See the examples subdirectory. */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include #include #include "../config.h" // get the definition for HAVE_GUI //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif #ifdef HAVE_GUI #include #include #include "../src/stimuli.h" #include "../src/value.h" #include "../src/gpsim_interface.h" #include "../src/gpsim_time.h" #include "raw_lcd.h" #include "../src/packages.h" //-------------------------------------------------------------- // // Create an "interface" to gpsim // class RAW_LCD_Interface : public Interface { private: RAW_LCD_base *lcd; public: virtual void SimulationHasStopped(gpointer object) { Update(object); } virtual void Update(gpointer object) { if(lcd) lcd->update(); } RAW_LCD_Interface(RAW_LCD_base *_lcd) : Interface((gpointer *) _lcd), lcd(_lcd) { } }; //------------------------------------------------------------------------ void LCD_7Segments::update() { if(get_interface().bUsingGUI()) gtk_widget_queue_draw(darea); } gboolean LCD_7Segments::lcd7_expose_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { LCD_7Segments *lcd = static_cast(user_data); unsigned int segment_states; g_return_val_if_fail (widget != NULL, TRUE); g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); guint max_width = allocation.width; guint max_height = allocation.height; // not a very O-O way of doing it... but here we go directly // to the I/O port and get the values of the segments lcd->set_cc_stimulus(); segment_states = lcd->segments; cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, 0.0, 0.0, max_width, max_height); cairo_fill(cr); for (int i = 0; i < 7; ++i) { if ((segment_states & 1) == 0 && segment_states & (2 << i)) { cairo_set_source_rgb(cr, 0.750, 0.750, 0.750); } else { cairo_set_source_rgb(cr, 0.00, 0.0, 0.0); } XfPoint *pts = &(lcd->seg_pts[i][0]); cairo_move_to(cr, pts[0].x, pts[0].y); for (int j = 1; j < MAX_PTS; ++j) { cairo_line_to(cr, pts[j].x, pts[j].y); } cairo_line_to(cr, pts[0].x, pts[0].y); cairo_fill(cr); } cairo_destroy(cr); return TRUE; } //------------------------------------------------------------------- // build_segments // // from Dclock.c (v.2.0) -- a digital clock widget. // Copyright (c) 1988 Dan Heller // Modifications 2/93 by Tim Edwards // And further modifications by Scott Dattalo // // Each segment on the LCD is comprised of a 6 point polygon. // This routine will calculate what those points should be and // store them an arrary. void LCD_7Segments::build_segments( int w, int h) { XfPoint *pts; float spacer, hskip, fslope, bslope, midpt, seg_width, segxw; float invcosphi, invsinphi, invcospsi, invsinpsi, slope; float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy5, dy6; float xfactor, temp_xpts[4]; w_width = w; w_height = h; // Hard code the display parameters... float space_factor = 0.13; float width_factor = 0.13; float sxw = 0.13; float angle = 6; /* define various useful constants */ segxw = sxw * w; slope = angle; seg_width = width_factor * w; spacer = w * space_factor; hskip = seg_width * 0.125; fslope = 1 / (segxw/seg_width + 1/slope); bslope = -1 / (segxw/seg_width - 1/slope); midpt = h / 2; /* define some trigonometric values */ /* phi is the forward angle separating two segments; psi is the reverse angle separating two segments. */ invsinphi = sqrt(1 + fslope * fslope) / fslope; invcosphi = sqrt(1 + 1/(fslope * fslope)) * fslope; invsinpsi = sqrt(1 + bslope * bslope) / -bslope; invcospsi = sqrt(1 + 1/(bslope * bslope)) * bslope; /* define offsets from easily-calculated points for 6 situations */ dx1 = hskip * invsinphi / (slope/fslope - 1); dy1 = hskip * invcosphi / (1 - fslope/slope); dx2 = hskip * invsinpsi / (1 - slope/bslope); dy2 = hskip * invcospsi / (bslope/slope - 1); dx3 = hskip * invsinphi; dx4 = hskip * invsinpsi; dx5 = hskip * invsinpsi / (1 - fslope/bslope); dy5 = hskip * invcospsi / (bslope/fslope - 1); dx6 = dy5; dy6 = dx5; /* calculate some simple reference points */ temp_xpts[0] = spacer + (h - seg_width)/slope; temp_xpts[1] = spacer + (h - seg_width/2)/slope + segxw/2; temp_xpts[2] = spacer + h/slope + segxw; temp_xpts[3] = temp_xpts[0] + segxw; xfactor = w - 2 * spacer - h / slope - segxw; // calculate the digit positions pts = seg_pts[TOP]; pts[0].y = pts[1].y = 0; pts[0].x = temp_xpts[2] - dx3; pts[1].x = w - spacer - segxw + dx4; pts[2].y = pts[5].y = (seg_width / 2) - dy5 - dy6; pts[5].x = temp_xpts[1] + dx5 - dx6; pts[2].x = pts[5].x + xfactor; pts[3].y = pts[4].y = seg_width; pts[4].x = temp_xpts[3] + dx4; pts[3].x = temp_xpts[0] + xfactor - dx3; pts = &(seg_pts[MIDDLE][0]); pts[0].y = pts[1].y = midpt - seg_width/2; pts[0].x = spacer + (h - pts[0].y)/slope + segxw; pts[1].x = pts[0].x - segxw + xfactor; pts[2].y = pts[5].y = midpt; pts[3].y = pts[4].y = midpt + seg_width/2; pts[5].x = spacer + (h - pts[5].y)/slope + segxw/2; pts[2].x = pts[5].x + xfactor; pts[4].x = pts[0].x - seg_width/slope; pts[3].x = spacer + (h - pts[3].y)/slope + xfactor; pts = &(seg_pts[BOTTOM][0]); pts[3].y = pts[4].y = (float)h; pts[2].y = pts[5].y = h - (seg_width / 2) + dy5 + dy6; pts[0].y = pts[1].y = h - seg_width; pts[0].x = spacer + segxw + seg_width/slope + dx3; pts[1].x = spacer + (h - pts[1].y)/slope + xfactor - dx4; pts[4].x = spacer + segxw - dx4; pts[5].x = spacer + segxw/2 + (h - pts[5].y)/slope + dx6 - dx5; pts[2].x = pts[5].x + xfactor; pts[3].x = spacer + xfactor + dx3; pts = &(seg_pts[TOP_LEFT][0]); pts[0].y = seg_width / 2 - dy6 + dy5; pts[1].y = seg_width + dy2; pts[2].y = seg_pts[MIDDLE][0].y - 2 * dy1; pts[3].y = seg_pts[MIDDLE][5].y - 2 * dy6; pts[4].y = seg_pts[MIDDLE][0].y; pts[5].y = seg_width - dy1; pts[0].x = temp_xpts[1] - dx5 - dx6; pts[1].x = temp_xpts[3] - dx2; pts[2].x = seg_pts[MIDDLE][0].x + 2 * dx1; pts[3].x = seg_pts[MIDDLE][5].x - 2 * dx6; pts[4].x = spacer + (h - pts[4].y)/slope; pts[5].x = temp_xpts[0] + dx1; pts = &(seg_pts[BOT_LEFT][0]); pts[0].y = seg_pts[MIDDLE][5].y + 2 * dy5; pts[1].y = seg_pts[MIDDLE][4].y + 2 * dy2; pts[2].y = seg_pts[BOTTOM][0].y - dy1; pts[3].y = seg_pts[BOTTOM][5].y - 2 * dy6; pts[4].y = h - seg_width + dy2; pts[5].y = midpt + seg_width/2; pts[0].x = seg_pts[MIDDLE][5].x - 2 * dx5; pts[1].x = seg_pts[MIDDLE][4].x - 2 * dx2; pts[2].x = seg_pts[BOTTOM][0].x - dx3 + dx1; pts[3].x = seg_pts[BOTTOM][5].x - 2 * dx6; pts[4].x = spacer + seg_width / slope - dx2; pts[5].x = spacer + (midpt - seg_width/2) / slope; pts = &(seg_pts[TOP_RIGHT][0]); pts[0].y = seg_width/2 - dy5 + dy6; pts[1].y = seg_width - dy2; pts[2].y = midpt - seg_width/2; pts[3].y = midpt - 2 * dy5; pts[4].y = pts[2].y - 2 * dy2; pts[5].y = seg_width + dy1; pts[0].x = temp_xpts[1] + xfactor + dx5 + dx6; pts[1].x = temp_xpts[3] + xfactor + dx1; pts[2].x = seg_pts[MIDDLE][0].x + xfactor; pts[3].x = seg_pts[MIDDLE][5].x + xfactor + dx5 * 2; pts[4].x = seg_pts[TOP_LEFT][4].x + xfactor + dx2 * 2; pts[5].x = temp_xpts[0] + xfactor - dx1; pts = &(seg_pts[BOT_RIGHT][0]); pts[0].y = seg_pts[MIDDLE][2].y + 2 * dy6; pts[1].y = midpt + seg_width / 2; pts[2].y = h - seg_width + dy1; pts[3].y = h - (seg_width / 2) + dy6 - dy5; pts[4].y = h - seg_width - dy2; pts[5].y = seg_pts[MIDDLE][3].y + 2 * dy1; pts[0].x = seg_pts[MIDDLE][2].x + 2 * dx6; pts[1].x = seg_pts[MIDDLE][3].x + segxw; pts[2].x = seg_pts[BOTTOM][1].x + dx4 + segxw - dx1; pts[3].x = seg_pts[BOTTOM][2].x + 2 * dx5; pts[4].x = seg_pts[BOTTOM][1].x + dx4 + dx2; pts[5].x = seg_pts[MIDDLE][3].x - 2 * dx1; } void LCD_7Segments::build_window() { darea = gtk_drawing_area_new(); gtk_widget_set_size_request(darea, 100, 110); g_signal_connect(darea, "expose_event", G_CALLBACK(lcd7_expose_event), this); gtk_widget_set_events(darea, GDK_EXPOSURE_MASK); gtk_widget_show(darea); set_widget(darea); } //-------------------------------------------------------------- LCD_7Segments::LCD_7Segments(const char *name) : Module(name, "7 Segment LCD"), cc_stimulus(0) { segments = 0; if(get_interface().bUsingGUI()) { build_segments(100, 110); build_window(); } interface_seq_no = get_interface().add_interface(new RAW_LCD_Interface(this)); create_iopin_map(); } LCD_7Segments::~LCD_7Segments() { if (m_pins[0]->snode) { (m_pins[0]->snode)->detach_stimulus(cc_stimulus); delete cc_stimulus; } for(int i = 0; i < 8; i++) { removeSymbol(m_pins[i]); delete m_pins[i]; } get_interface().remove_interface(interface_seq_no); } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void LCD_7Segments::create_iopin_map() { // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // // The 7-segment LCD has 8 pins create_pkg(8); float ypos = 6.0; for (int i = 1; i <= 8; i++) { package->setPinGeometry(i, 0.0, ypos, 0, false); ypos += 12.; } // Here, we create and name the I/O pins. In gpsim, we will reference // the bit positions as LCD.seg0, LCD.seg1, ..., where LCD is the // user-assigned name of the 7-segment LCD m_pins[0] = new IOPIN("cc", 0.0); addSymbol(m_pins[0]); assign_pin(1, m_pins[0]); int i; char ch; for (ch = '0', i = 1; i < 8; i++, ch++) { char seg_name[] = "seg0"; seg_name[3] = ch; //m_pins[i] = new PinModule(seg_name, 0.0); m_pins[i] = new IOPIN(seg_name, 0.0); addSymbol(m_pins[i]); assign_pin(i+1, m_pins[i]); } } void LCD_7Segments::new_cc_voltage(double Vcc) { unsigned int s = 0; if (Vcc > 2.5) { for (int i = 1; i < 8; i++) { double delta_v = Vcc - m_pins[i]->get_nodeVoltage(); s = (s >> 1) | (delta_v > 1.5 ? 0x80 : 0); } if (s != segments) { segments = s; lcd7_expose_event(darea, 0, this); } } } //-------------------------------------------------------------- void LCD_7Segments::set_cc_stimulus() { if (m_pins[0]->snode && ! cc_stimulus) { cc_stimulus = new CC_stimulus(this, "cc_stimulus", 0, 1e12); (m_pins[0]->snode)->attach_stimulus(cc_stimulus); } } //-------------------------------------------------------------- // construct Module * LCD_7Segments::construct(const char *_new_name=0) { return new LCD_7Segments(_new_name); } CC_stimulus::CC_stimulus(LCD_7Segments * arg, const char *cPname,double _Vth, double _Zth) : stimulus(cPname, _Vth, _Zth), future_cycle(0) { _lcd_7seg = arg; } CC_stimulus::~CC_stimulus() { } void CC_stimulus::set_nodeVoltage(double v) { if (nodeVoltage != v) { nodeVoltage = v; if (future_cycle) get_cycles().clear_break(future_cycle); future_cycle = get_cycles().get(2e-3); // 2ms get_cycles().set_break(future_cycle, this); } } void CC_stimulus::callback() { Dprintf(("callback %s\n", name().c_str())); future_cycle = 0; Dprintf(("set_nodeVoltage %s _lcd_7seg %p %s v=%.2f\n", name().c_str(), _lcd_7seg, _lcd_7seg->name().c_str(), nodeVoltage)); _lcd_7seg->new_cc_voltage(nodeVoltage); } #endif //HAVE_GUI gpsim-0.30.0/extras/lcd/t.gif0000664000076400007640000002152713041763633012663 00000000000000GIF87aP_÷dŠdDB7T”BüÂT$$$dddÜ‚ , lB„b<äää4"´˘ŚT. dR<434D¤j$Ś‚tÜŞ|  ÄÄÄ|+, „jTäÝÔtrt´˛´”–”D" TST„V$tR4ÔŐÔtDüů×T:$TD3|bDŚŽŚ<D2 „vdl¬‚TD* Ħ„d\PÔČĽ´™zD, Äł ¬R TJ=śbś‚dd: T<dI3üćĚ<*¬¬¬„^<|Jôóň„zl śF¤xHŚ8|||¤¤¤L;,D,Ä–ddjd\6 ĚËĚ4 ”WtZ<ÜÜÜtmcüţü2,dUI\=#\D/Äş¤dLML„jLěěę<#<<$śžś¤N Ěžl„2t&´ž„tJ!”>T6 ôŢÄ”~d,&Śf<<6$”†|\RDŚT|V0$ |Z<śj<< <4 ¬r,üîŕÜÎĽěćÜĽ¤ŤlS9¬n'ŚnTěÚĚśšśL" ”’“L- ̢|\M?¤…jl>\lJ,´«Ąüöđ ¤JL.lll|mclVDĚĽ«lB|fT DDD\4 „fLT2Lچ„„.tFTF<$ t"´š„<.$Śvl”:t^L\>,<&¤šŚÜÖÔl^TĚÄÄŚN4”Š„´ž”ěľ”´Žl¤ŠllN4ŚjLL$,&$4üĆ\„fDT2چ|Ü®€, „n\tvt´¶´D&tV<,P_ţŚ8ĘT)’ ‚#TˇzˇQ—B] |”đ5ˇ4’ß“üҤä·,Kš,Y”ĹĚrŕNÍćp&’±s'*¨şEETGѢŔt$]Ş´iŇ/JOHťJőɉ'Xłj}ÂkW®nX„+¶,ٱPÜ@aÁB[·mˇ‘K.Üd,đÖ­‹·Ż›PÝxаáÂ…«• p߼sç6(3y2¬2ôÜĐĚyłçúč…Ö‹4}«2¤^­şőj8Ç 9„(1ᆠ֦Čp¶îoÔŻ_‡C†tpâ$S&~‰†?ž|yó牌i1fÄ‘2FţĐ"CkCyZXĘmp¸aĂš ęߏXCͬűłhđŃĎ?>‚ŃŚ€`Câ  s,Řŕ‡<ČŕÎá…:P‹†tčI †G ’8â‰5¤˘;’°8Ę‹0ň0 4C㌣ŚáÇŽ~Ś‘‹Ź;*â‡"D‰ÂH^ÁŠ’W¨Ň¤’˙°ĺ?NŠ`‹•"Ľ#1Yv Ä;@‡dމ‡&xÁɰ™Ě=ÉTc¡xńWcnř# eřÓge\&h „z3đqĆ!§sÎA']ŁŐAŠťtTTéuM€0 ¤?ŃaF"ü4Ń?b ňé ţH Ëv ©ŃŞFh1„Ĺ«9ĂŞÓ$ęP ěq%ΑĆË´ĐBהŖpűF8ć€ÎĚ„#Ăçvń†ş]@ŕ.íĘŕ.*Ŕ@€Ę»ďÖ; 0ű~á/0_śpŔxśP°'xGš §é0šhš ±ĂSL,±†™°Ř=»q 0°ĺK^,řҦ/B¤ś2 B”ÁçË{ş,ó2űYč͆ş‹Î<ĂË ĄUqĐUčC4,* ­tŇI»REŃPťApPť<\`­uÖ\·q #ôŔŘŘD·F#E­~?ü H MŇ„R°ę*ţ¨)đŞ…u®wŘ)bIĚ0)ä-E4v„m@"đŠ9’ŚqÂ*¤Ú1řÜKÔčb ˘Q§ pBęR©^•UZą•)łĎWP’űî¦Äu±,DB2|•QÖ ËOFŮó>űěŮ ¤ü¬ŮϢeOÚ Z”öóĎZ„ŻEEk·j«¤Żľ>úTíľűV[í>×p$÷ËcÖ č?<˙ Ú0@nŁ ”Ç ČŔ¶A|ŕAĐk<é°‚c¬€á;8ÂŇalź€.@7)á ¦Â*śą°Ŕgł[”‘8otŽpţ)`@&…&`‡üx\äúáĂá˘+,¨Ţ’($„mp„1ćĐ‚O DS0‹;HvYíÖ8;6š",laÁMqŹŢ˝1/ÉŔ‹ÉLĆ–ýîŹrńĆÁ˛BĘěe4{ É'š9˛ ° ô Ĺł*8í’ĆŔŇ´P…±Ŕ;Ó‚'9©<­ ä3š*ź&5TV ŻŚ%,ąŽ ¤c–ݬĄ,oůĘţŮď—[ĂÚý†‰ż_ÖŻ~ÂLŔ6”ÉLý93< 4ىŔlÚؼć5W hH.‰ E⸰ŠM fŘBŘ8RnI€/ ‚* #ţh‚qU%Q 0@Ř8€tA cBîHÁ V‚˛Đ…'Ŕbyľ€/|3 8@…7r×SP@) ™Ň¶řŃ-!cČ@VČ”ůC.+[éJ÷3íT‘~z¤P˙”H—5˛ 6@*R]ń¦BR©4KjS§ĘTW¸B”6pEV3é X®Č¤WU dő fUZm ÖR˘Ő”p­B\ç*×*Ľ"ݰk:T€W˝ňŐ”y ¬]{׼N ‡MGn™ŘĹ:V±Ś}ěb‹ŘL#Ídć27«Ů|lý0ÆЏ Ś ˝2DĂ& čmţ|a >4ŃŠý(řa†hđ“ŕÇ J…Îj0‚đ‰LM îřáç¤`mN  .` $ `'xň÷Eä oxĚeř$łC.ŇOA%ęźůTšÁ·˝öu™ xń9|€űÝď `9ŘŔżN°€Ě`÷÷Á–C&l`U®đ…ĺpa GŘĂ>CÉW¬âÇŁ­lE«ŚŰ*Hŕ5αŤw¬ă«őg2ŹmśŽŕuŻ@ň‘“\X%3É—]Á .0„x l€)Lµ¶î^ )8€|A‚2“ŕ #ČDţ"Ě€ * n# U4‘‚~JaÍH¸€€'<#K¸„*ŠP8VTp‚ůˇF ¨ o€*jŕ†ď-z@«dô|(CŠg…’jUŁęŠ2”zŞP­jRĄŠÔóÁţďůË`Y'xÖ Î5­˙‹aQú@żÎ$°lüZÂĆöŻ—=le;›Ů‡â19D»ÚŘ–¶¶§íi{{Űŕ涵叛»Ü#އFlŤ3´[ÝěńşE|źá7–ľqĚo}_3Ń`3†#DA? @!đ¡‘h»%čH… ‡L Ň ÂG]ˇ pwŽ@žţť`‡c°€ ¸„RaC °ŇóĄ0SĽ WP†2î +(‚Fű\éJŁ}•uĄ«Îš¶4ĄYµÂlÍŞÔÍŞŐŞG]«T˙°Ö=Ěő­Ů`¶ł…˝lQ>ŰěżF»†±ö¶ł}ow»ÜăN÷ąŰ}†¤1Ľă]ď|÷{Ţ÷Ţ÷Ľđ{O<âżwj[ăÚŹŹ<äđxÇ[ă۸@&  †,Ľ¸‡0@‚"hV€pÂůQ…T ©đ„2± OD"€†&x€çH„šIA …… VŘA*˘ĐŹAX@óíŘQHâ ŕąđţ`ČŹ ň›_pIţX¦˛htMŇÓşVöĂřýle±×»Îő°Ű_ěĚö5Ű}ɶkÁüglüçPw¸vĂ ¸€ Ř€ ř€8X ŇҀ؂#Ř%¸—'š'ŁUZ§Ő+%>Χy”ŔIPgčĐ™  0·wż»0.¤{@Čh°p=P©°0ŽŔ[đ|™  ` ›Pů† (ŕ‰``"„?[sL\Ł?Çd?‡•X¶dKĺK{u‡‚UXzuW*d86d36cčvn„n-¶bţá¶mř·vÚˇč۱‰‘8‰hx.›Ř‰śř‰žŠ 8Š˘XФȉ.ŠŞ¸Š¬¨Š¨Šź¨8‹xy©çI0Y¶ef7[€ š×I°÷`„ Ş€Š0‘f…ŞBÎŃ#Ŕ,H{d(|ws0Đ đ…đv‡B@%Pzđ…;0„pv`BĐUĐ@ň0MÓÔYo¸ŹĆ‡”叹XJfdFĆd„5X>–(îÖ)–nô–n֖ܦmrŕI€©w€‘™ř‘Ă`Š"yŠ#Y’¨Č .€’*™Š+ŮŠ,©Š-™ţ’)É ťĐ Ü@“7i“6‰Đ™ş` A°ů° › ­0N0äŘ«ŕ ~`o¶ Ą `Đ׸ ŔTÖXsF{ `¸ŔDp“2€ Pzŕ€âhL„nŕVŢX0dXePŮÔTA”@Ä@ôLŚéKňpY—Y’ĹXUdYdIP–oű–o<‘ôÖn˘ŮíFy“g ńävmä&m…ç0„‡w´h‚&H ¸. ›H‚ľů›Ŕ ‹/ą’4Ů .P“ÇiśĐ Ëٜ̉Řťś0ťśŔÖÉŐyťLţŰ ŢůťL á)žŢžÖ™Š błŕ^ îiV0 ńh–¶€dŔŚwĐT°…đ(—7n6Ń0´G{­’ą•}xC N ýş   ) ĘÎń+ÚuZş UĐt#z % #z˘t &JB"B.:BDÚ”M6ZŁ8ş :ŞLúĂY=ęiYB¤D: ?`¤Hz¤OĆ™ů†co` Qj RJĄ‘‡š¦ůx¦©†Çw^ÚĄ]* Ö d*‹¶‰ ¸›˘H‚ť@‚()“*É ÎťtŠ Ř0ťŘ‰ť°§ }Ú§š  J¨ţ„Z¨„šJ€Ă[C°]/ášpwFgŰuÚ˝} Cş§{ z…b Ą‚+f0°ę|IĐb ­şe¦€6 «3ŕ5 ż:6Ŕ:¬ÁJ¬+z¬(š¬Čş¬Ęš¬2ú¬3ú¬RĆA%„Ł7z­9ŞŁÚş­:: Ó° Ţ ®ßę­–•¤ćz¤GŞoOŞ®řÖ®úvyTúń:ŻđZĄVĄSjĄbşŻT*¦’—w8¦|§€Ň›(’ĆY“°°ťťĐ‰ÔYťÜ |ş§š€ ;¨+¨Č€Ă0 ´ `*$«ż8«.d«$»e¶ţ«€˛«Ş `¸«P…IŔé++˛‚ ¸`/ :«‹[ŕł±"´BOÝT¬żJ¬Pë´QŰMĚZµÍjµČ*ŁŃşµĐúAÖúµÜú­ŕڭܶâ:¶ŢŠ®çŞ¶čúnű¶p·r;·okĄv+ŻvkŻykĄ¦Iy\Z‚ X°źřŠ(Y“ »° ±xZťŮ©ťŽË Řđ+P´p´> ´€ IO”{´=++™»´Dkv°=űą ›ąVÖâÓş®ŰşćóşáĂş‘H»¬k>¸[»‘hÚÁ»ĽŇ»Ŕű»Âë»ÄĽĹ;ĽĆ›ĽČ«»ľ{»şëĽĆ˝ÂËşĹŰ+Íţ˝Ř›˝Ú»˝Ů»Ůk˝Üń»áŰĽĎ[ľŇ{ľĺë7˛‰®Ű+áăľ°k»ë+>ć㾱뺽Kżëk ? ZŔŚ Ŕ<Ŕě|Ŕ ŚŔ |ŔLŔüŔá\Á|Á<ą±ÁÜÁ§ĺÁüÁ1ÂT0Â&|Â%ś)‘Â+ÜÂ/Ă™2Ă4\Ă6|Ă™9Ś<\: ÄB<ÄD\ÄF|ġJśÄNĽÄÚĹ(ÚUS,ĹýĹWśĹűĹTĽĹŚÂĹĹŃżţ‹8ŚĂ?ěĂ;|Ćj|ÄlÜĆŰĹÄpÜ©C,ÇAÜ©v Ĺx ĹZŚĹ_ Ć~ěĹţYěI~ܰŠ6ƑȇěI‡ĽČcÓȉ¬Ę”,ÉÔqÉ—lÉɱɜĚÉNźü+ <ʢĚżňɦʨěɢ ĘĚńʰ˲<ËÎqÍaË™pËąĽËÎQËą\]ŔŁÄelĆiŚĆĆ>lÄo\ÇÎÜĚĐŚÄŇÍo ÇM<ÍuĚÇÚ|ĹQśÇ_lĹ{ÜĹĽĹ…Ě(¤EČç ‡Ü¤ĹÎę|…LČÇAČě\“śÉ•LÉúlÉóĚĘ­ĽĘ›¬Ę¤ĘĄ\Đ«|ЧlĐł<ËuË ÍýĐş<ŃĽĽË¸LŃŐĺ ĚcŁXPĚÇśĚ"ťĆj,GÜĚs,ţÄt¬ŇĎŚÍŃěŇÎĚÍÜěÍ4MYüÍ7-ÎŕlĹ€°Č\Ď…ěÎőlĎD=…lÔ@í(¤ĹÉőĽÔěĽĎ™ÜÉRÝÉ=ŐŤĐXmĐĄ,Ë Ń^˝Đ˘ËľLѶL֝љŃ=Ć6|ƵĚ<üĂm,ÍsÍŇÖŚÍ0MÍM<Ó2ťÇ}]Ĺ€¬T ŘáÎŤÜČG]ÔĆQȉíÔC éüÔęěÔ“üÔšŚě<Ő˙¬ŐU-Ő¨,ĐśÚ`=Ú ÝĐ}µLŃ˝<Öż¬Ń˝ěŤÖŤ‘SŰńt۵mŰ´˝ŰĽÝŰždeVöŰc۸íŰĆ}ÜÇ ÜĂ˝ÜČÝÜŚśÔD˝ĹKţťŘ~śńlÝ’<ŮνÝÄ­Űą­ÜŢ˝Ýâ=Ţä]ŢĽťIžżŻ«Ţę=żî=żííľňýľó{żú‹ľö-»ó­ľíŤżć;»‰íÜŘŇMÎlĎL ŮúüÎčÜě‹ßŕů˝ßNßâÓßűŕůýşą áěŕú«»ţßů­=JmlBlzMÍŐ¬Ä0ľÄÓ Í/ÇMlÓ8ťÓ€=ĹâěÇ;ÝăüÇí<äŃ-Ôí\äFMMäHŤŮʡŕIž™­ŮTNŐźťĐ©|ĺYľĺ°ěËý娍˼ŚÚ§˝Úf~ć« Űi˝ćjĚlţć° Ěqîź4J4<Ňo Äu˝çţ-ýŇvěĚx}ă5=č8žÓ…ÍÓ…­Ř\|ä‹.6GţčĹ1ŮčśŮI­É’®ÎM=ĐšžŐť˝Ůž.Đ Ф=ę±üĺcć¨nËhŤć¬ÎęŔĽ t.Jcc +^Ň|N×lüçÖÜâ3ă=Ó…ľă7Íă‚ÍĹ?®ĹAÝ”]ŕŽ-6Éě’NZ“ÝÔ´­äcÓé ­ĘýĐé˝ŐX®ĐˇťË·ĚŐŻ,Ń]ęfć^®Úmćnţîpďs>çi]ç=ŇąŽë·ľëyÝďŐLÓ:>ě~MŘČ.ŘÂŽěÉŢěĚ^äC}SľÉNnŮMťĎŹâ٤\嬜ʢ˝ń¤îçÖí>ŃdmÖdžţći˝ęŻ])ŻŃóŰlëţ‹âĚ č|^ăvíď.]Ó:>č:Ý×]LěźđS>ÔŠ.äRŢÉCMŮ•Lé’ÜíŁLĐÜnń˙ô/ĘâÖ]MÚéÎÚ¦žęŻmňrîîń~ň'ßćl>ç°žööľŇuíÄ8Ďë<żă:˙Í|Î@˙Ĺ?˝ÎK­đŤţ÷Hß÷‰śéM]řNĐoŐZMőśľŐaýĘąlÚ/ËWo)gn)bÝőbíćkîÚoţőŐĄňdßćëđţîi_ú±žŢ·ţĚL|ó}ž×đď×Ćě2]đ?ĆĽěŚř`,řGoř.Ɇż­\ĺ ­řŤ_őźţŤőoů¬=î¦Ný%Ďů®ö(Ě*ßňŁ˙ꤏöŞŰ–şöZPčźţężţěßţî˙ţđ˙ň?˙ô_˙ö˙řź˙úż˙üß˙ţ˙˙QG @ZÔ2PáB† >„QâDŠ-^ÄQăFŽ=~tŔŘAF@žD™RĺJ–-]ľüXdB5;łŽN›=}ţä©S¨@ž‹. ްhŇťE’4ůS*ȡM­^e*±ęÖśJ§jíj•+QŻa±nĚz”ěUŹ2š­¸4ěرl9Ň] öc]Ş'ńŠ]«öëŕŠOFE`ËĹŚ“myq㆒_V:Yó–̉nţľHŮ!eË–+oýůréǬWO»©kÓ©Úv}úµgÂpí6t[pôd «s˘}9ďť[,”& ˝9óĘHçLűşőÝA—×ţ^ܶŃď ÇwîlznyÎľGÇŤ(¸zYĂ%GŔźżRýý÷ßöŻżśü/:ý<0®ĉ@ ?'ś04 óŰ©@—rÁ ßË«¬łn[)8c­,ŇRdkĹö@TÎÝ„JńĽř¶[ʱČdsQÄéBÜ‘»ŞÜËČFÜŇó*H$űŤČľ ’/Ä:ęCLµ‡z¬,2Ň|ÄN·ă^TrDî®l G!Ă„ĚĚ ·óîE)ďšN.4żôţR97{ňJ‚Ł Aß"ĽŻA ŤĘ°A *C˝ }CEł4ĘýdP¸˛’Ň+5PS”˘$Q϶F:Ś?5ëôŇĆů¬´óRUď;uÍěbýńU#ŐÄŹV´Đk5K6éLL×P‡]µIPaśŹO!‹Ur©2ÁDŠĚ;U“O´cż¬v˛9­´őÔ9·m#kyµ Í\Űs–±<‹\©ÚHµ/S­8EđA‹‹ŢN‘ĄČýđEP¬đ5P0‚×uňP75^‚‡DřÓh5R–\Ú´SWČä|Í\;Ź55‘źÍ Ř{Őx·{ĄU ă[;ţxcbąśřÍ'ť‚·ĘsŁ[.Ξcţ¦.]qDTŘŮĽngŚ=3ŻóΕě9Ł)şUęµÁźiŢëOKC2č ĺ-Ôż˛ „TŕJ×öTÁ˙˝pŇűUxĂŚQ/LRCѶáká <Úúj“DĄ[“ DC_>ŐÁGóYžŃđ×̧ÝŮéĹŤo<­łLVTEMĆÁ§Ş[ě:GJ˘©Eąvň*ĎŘEa¦ýt“™.\ÔŹm>N §¦:ůĐŢ…Şîr˙Ő×ÂA'-XDęť®{AGu8zG!\ŘĄąçŢ×y®ÉžpLkž9ŻÖYM•E´°†ţáăBwŘÚţß˙Öę„v?đv„S×ţ,BĄ¦ mVÓJ_‹®Wu‰U‹ă›şĹą--)\„ŇÓT»Ô+Uy»Gާ·´Lpć«Űdč®ę±p{Ců®7ľčQĺ`äc! …7>Ť¬nQc Ó–VÁË•¬h*ăßć„§˘¤Ťk„¸éY¶8Č&˛~%lѶµ,ÖD.Ĺâ”Â&śeqjK!Ř»ĐäĎ,™őäG-äXÍľŁă˛řČ8žĎ,gd— s;&5ńqÜW f˝‰K€ SËśdÉů„ “S\žG@µB˘’^sˇĹYV8PöQôR…(>{cÎ".4źÄŠe&EI1[6›,ń$@ËuŇú2ĄÇdč:?ůQn*sp'K1ŞRjô‘^¤)E_S‡8%mß$#şSZ át'J}ĚlVSżü) ŻOźh•¦0k1ŻúM\v´ŞN˝ć!1ĘQć•ęžŐDkXS©Ô®ÖsŞV%+BĘţTžŢu!\Ő(QMŞÓk ‘Ëśé9ÝcQős¬9\K‰„Č –Şý©LĘÖĽ"V¬őKO芓ŕT‰ŻĚÄ&˙W ĽŐ˛e=í*é™–Îîő¨3¬]ŤJÉŔĘ5Ş˝ÍmmŞ××>¤´®Ąfeu*%ˇ–Ók= ­lź+ŮÝf–µ ‰ěY_KWĐƶ»Ľ„­Z§[ÝËöݍUă6kÚľrµ­ îoĎ«ŰŕQ6›gdç?é»_}úȫޕďrŞŐf¶„ß%/Nw:ÚcęŇ ó4oU}[3—ö7ş˛„jFô;Ňű×ĂČŤj†7)Ţ—÷™A±„IŘFΫžYs¬PţĎ6ŐŻ™}ńu;%¤’—ż6°YSlL§Šř‘ů4¬T'śŢ·,8­?†îŚĄňUŻÔÂô•qCŤL‘ Źx»syr‰oV#*×ŵíu‡ąĎ3ăĹR¶ç—×KÝëµĚQ>0”ëŚáĎ+‰j>±©Lł-K,µń]n…Ű|Ţc˝9Ě"5qś%]JîV׾x¦q+ťÚeáfŇ@ ď”ë¬caúÁň´ę ÷l—ŕÄŐŻ†u¬e=kZ×ÚÖ·Ću®u˝k^÷Ú׿v°…=lZ“J Ć8v˛‘­…d3ŮĎVv´ˇ=mi;»ÚË^vł©Ťmm_ŰŰжö¶ż=nq‹{Üç.7ąŁîfţ{[Ýé¦6»ĺÍlvsŢí¶÷»«­îz XÁ.@… ôcĐ‚Ȱp†7Ľá _8@‰WÜâÇxĹGp€3ŕßX`@Ŕ7.r’S #8ąÉQžň•|ŕx9Áes—»ć7Ç9Ěq@ěĽç<ďy?!t˘ÝčF/z?”ľt¦7ÝéO‡úÓ‡ u©aşŐ žu®[Ýë_‚Âv'˝ěg{&ś µł}íoo;Ü×Îvş×ÝîwÇ;ŮĂţtŁ_ üyŔoţŕ_şŐťŔŹD(ĺ+<ËIŢr“›<ç—Ç<ćwÎs #=ęTďú×™v°›ţÝôz?{ęUżúÔ×îj—{Üń>ű»{ Ŕ}îqűŰëŢöľ÷} < üáăžřÂOAň•ż|ć7ßůĎW~ ’/ýH )@Cöµż}íW?ßř«?~ä'ßî‹7CŔ‡ľőL ęgüúaü@4!bF@ö˛×!öxŻ]Ŕ»ßë=ŕÓ=č#?éSŔń „¨żďsŔ&żď“@ ¤Ŕ@ŕ‡&¨ŔÜ@ € ü@űË@~řŔ4A~@ÁLAdÁ&AĚ@dÁ¤ÁDAeP~ŔAĚA´Á”‚ ä‡ Be(B"DÂ$TÂ%L„ lB)8(”‚&¤Â)´ţÂDŔÂ,ÔÂ-ÔÂŕÂ/C0ĽÂ$¬A3HůľęÓ@ü@đ1€L13€A Hđ»:ŕ=¶Ó˝Ţ+@ä+>BLCć TÄ?đc@´Ŕ ?lŔ ¤ÄI ż ě@ ŚÄ& N”Ä EđłŔĐ@”A”AśA ŚÁAVDAU|EWDEĽĹ\„EZÁV”ĹYÜĹ`<Ĺ^üE)đAcBDFd´?T´Ä Ś€$C:´Ă;ÔĂiÔC0-0$@ ĐC†-@\HpG\@Çt´uL‚w<ÇsÔC=”Çy|G{„Ç|ĚG|¤GxěÇ$\€| H€$Č,H}4H}|Ç€dH†$H…„ČŚÇ}¬ÇxśÇuÄHt´Č\Č„”ČŹTH‡ôČ…É…´Gp´Č’äČ’ôÇ”ÄGxtH‰ÄGĐFnôĆvH~ŘF€ ;gpsim-0.30.0/extras/lcd/ChangeLog0000664000076400007640000001105013041763633013471 000000000000002010-05-17 Roy Rankin * hd44780.cc lcd.cc lcd.h lcdgui.cc module_manager.cc - Config now from gpsim root, so include paths change and may be built without GUI. 2007-02-22 Scott Dattalo * lcd.cc: API sync 2006-11-08 Scott Dattalo * lcd.h, lcd.cc: Updated to newer Trace API. 2006-09-11 Scott Dattalo * lcd.cc: Fixed API call to gpsim core (Trace::dump_all() ). 2006-05-28 Borut Razem * hd44780.cc: removed unneeded inclusion of config.h * extras/lcd/makefile.mingw: corrected, thanks to Xiaofan Chen * INSTALL: CVS replaced with Subversion 2006-04-23 Scott Dattalo * configure.in: changed version to 0.2.6 * Makefile.am: removed lcdengine.cc added hd44780.[cc,h] * hd44780.cc, hd44780.h: The HD44780 logic formerly coded in lcdengined now resides in it's on file. Furthermore, the logic has been greatly simplified. Now the LCD display features are distinct from the HD44780 chip features. * lcd.h, lcd.cc: Utilize the new hd44780 chip model. Also, the I/O ports no longer use the deprecated IOPORT class. * lcdgui.cc: DDRAM accesses now are made through the HD44780 class. * lcdengine.cc: removed from the repository. 2006-01-18 Scott Dattalo * lcd.cc: updated to new gpsim trigger object API (clear_break was renamed to clear_trigger). 2005-12-06 Scott Dattalo * lcd.cc: updated to new gpsim iopin API 2005-11-20 Scott Dattalo * lcd.cc: updated to new gpsim stimulus API. 2005-08-30 Scott Dattalo * configure.in: changed version to 0.2.5 2005-08-30 Scott Dattalo * lcd.cc: updated to new gpsim iopin API. 2005-04-29 Scott Dattalo * configure.in: Changed the revision to 0.2.4 2004-11-24 Scott Dattalo * lcd.cc: Fixed LCD ports so that they conform to recent gpsim changes. 2004-09-28 Scott Dattalo * configure.in: Added support for gtk-2.x. Changed the LCD version to 0.2.3 2004-09-13 Scott Dattalo * lcd.h: TriggerObjects used to be called BreakpointObjects in gpsim. 2004-09-05 Robert Pearce * lcd.cc, lcd.h, lcdengine.cc, lcdgui.cc: I/O pins and stimuli. (patch applied by Scott). 2004-09-01 Scott Dattalo * lcd.cc, lcd.h: updated the LCD module with the current gpsim trace implementation. * examples/lcd_mod.stc: The node name 'DC' conflicts with the status flag DC bit name. (They're both symbols). 2004-07-23 Scott Dattalo * lcd.cc, lcd.h, lcdengine.cc: updated the LCD I/O pins to the current gpsim implementation. 2004-05-12 Bert Driehuis * lcd.cc: CGRAM initial value should be 0xff and not 0. 2004-06-14 Scott Dattalo * INSTALL: Updated CVS instructions. 2004-05-12 Bert Driehuis * lcd.cc, lcd.h, lcdengine.cc: support CGRAM 2004-04-13 Scott Dattalo * lcd.h: updated to latest simulator interface changes (The BreakCallBack class has been renamed). 2004-03-30 Scott Dattalo * lcd.cc: updated to latest simulator interface changes (where char *'s were changed to strings) 2004-03-08 Scott Dattalo * lcd.h, lcd.cc, lcdengine.cc, examples/lcd.asm: Fixed the busy bit logic. 2004-03-08 Scott Dattalo * lcd.h, lcd.cc, lcdengine.cc: Merged a portion of a patch from Robert Pearce. 2004-03-05 Scott Dattalo * configure.in: changed revision to 0.2.2 2004-02-08 Scott Dattalo * configure.in: changed revision to 0.2.1 * updated to the new gpsim API 2003-09-14 Scott Dattalo * lcd.h - Renamed "enum Event" to "enum ControlLineEvent" because of a conflict with the "class Event" in stimuli.h. 0.2.0 Robert Pearce Fixed bug with 4-bit/8-bit startup mode. ?.?.? Salvador Eduardo Tropea: Added support for DisplayTech 161A displays, these displays are 2x8 displays but externally looks like a 1x16. Name: lcd_dt161A. 0.1.1 2nd line offset bug 0.1.0 Major overhaul. Now the LCD works as a gpsim module. 0.0.3 extra_dist should have been EXTRA_DIST in Makefile.am. caps.pl will now also generate a file that may be included in a pic microcontroller program. 0.0.2 Added the rest of the 5x7 font. Added caps.pl (Cheesy-ass perl script) that will read a specially formatted .xpm of the LCD's font and convert it to form usable by lcd.c gpsim-0.30.0/extras/lcd/lcd.xpm0000664000076400007640000061254013041763633013222 00000000000000/* XPM */ static char * ll_xpm[] = { "400 500 2 1", " g None", ". g #000000", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ...... .. .. ", " ...... .. .. ", " .. .. .. .. ", " .. .. .. .. ", " .. .. .... ...... .. .... ...... ...... .... .. ...... ", " .. .. .... ...... .. .... ...... ...... .... .. ...... ", " .. .... .. .. .... .. .. .. .. .. .... .. .. ", " .. .... .. .. .... .. .. .. .. .. .... .. .. ", " .. .. .. ........ .. .. .. .. .. .. .......... ", " .. .. .. ........ .. .. .. .. .. .. .......... ", " .. .. .. .. .. .. .. .. .. .. .. .. .. .. ", " .. .. .. .. .. .. .. .. .. .. .. .. .. .. ", " ...... .. .. ........ .. .. ...... ...... ........ ...... ", " ...... .. .. ........ .. .. ...... ...... ........ ...... ", " ", " ", " ... ... ... ... ... ... ... . . . . . . ", " . . . . . . . . . . . . . . .. .. .. .. .. .. ", " . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " ....................................................................... . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . ", " . ... ... ... ... ... ... ... . . . . . . ", " . ", " . ", " . ... ... ... . . . . ... ... . . . . ", " . . . . . . . .. .. .. .. . . . . .. .. .. .. ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . ", " . .............................................................. . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " . . ... ... ... . . . . ... ... . . . . ", " . . ", " . . ", " . . ... . . ... ... . . . . ... ... . . ", " . . . . .. .. . . . . .. .. .. .. . . . . .. .. ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " . . ..................................................... . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . ", " . . . ... . . ... ... . . . . ... ... . . ", " . . . ", " . . . ", " . . . ... ... . ... . ... . ... . ... . ... . ", " . . . . . . . .. . . .. . . .. . . .. . . .. . . .. ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . ", " . . . ............................................ . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . ... ... . ... . ... . ... . ... . ... . ", " . . . . ", " . . . . ", " . . . . .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . ...... . ...... . ........ . .. . . . . . . . . ", " ... ... ... ... . . . ...... . ...... . ........ . .. . . . . . . . . ", " . . . . . . . .. .. . .. .. . .. .. . .. . . . . ........ . ...... . . .. .... . ", " . . . .. .. . .. .. . .. .. . .. . . . . ........ . ...... . . .. .... . ", " ... ... ... ... . . . .. .... . .. . .. .. . .. . ........ . . . .. .. . . .. .. . .... .. . ", " . . . . . . . . . . . .. .... . .. . .. .. . .. . ........ . . . .. .. . . .. .. . .... .. . ", " . . . . . . . . . . . . . . . . . . . .. .. .. . .... .. . ........ . . .. .. . . . .. .. .. . ...... . .. .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . . . .. .. .. . .... .. . ........ . . .. .. . . . .. .. .. . ...... . .. .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . . . .... .. . .. .. .. . .. . . ........ . . .......... . .... . . .. .. . .. .. . ", " . . . . . . . . . . . . . . . .... .. . .. .. .. . .. . . ........ . . .......... . .... . . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . . . .. .. . .. .. .. . .. . . .. . . . .. . ...... . .. .. . ........ . ", " . . . . . . . . . . . . . . . . . . . .. .. . .. .. .. . .. . . .. . . . .. . ...... . .. .. . ........ . ", " . . . . . . . . ... ... ... ... . . . ...... . ...... . .. . . .. . . . .... . .. . .... .. . .. . ", " . . . ...... . ...... . .. . . .. . . . .... . .. . .... .. . .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .. . .. . ...... . ...... . . . . .......... . .. . . .. .. . . ", " . . .. . .. . ...... . ...... . . . . .......... . .. . . .. .. . . ", " . . .. . .... . .. .. . .. .. . . . . .. . ...... . .. . . .... .. . ", " . . .. . .... . .. .. . .. .. . . . . .. . ...... . .. . . .... .. . ", " ... ... ... . . . .. . .. . .. .. . .. .. . ...... . .... .. . . .. .. . .. . .. . ...... . .. .... . ", " . . . . . . .. . . .. . .. . .. .. . .. .. . ...... . .... .. . . .. .. . .. . .. . ...... . .. .... . ", " . . . . . . . . . . . . . . . . . . .. . .. . .. .. . .. .. . .. . .. .... . . .... . .......... . .. . .. . .. .. . ", " . . . . . . . . . . . . . . . . . .. . .. . .. .. . .. .. . .. . .. .... . . .... . .......... . .. . .. . .. .. . ", " . . . . . . . . . . . . . . . . . .. . .. . .......... . .. .. .. . ........ . ........ . ...... . .. . .. . .. .. . ........ . .. .. . ", " . . . . . . . . . . . . . .. . .. . .......... . .. .. .. . ........ . ........ . ...... . .. . .. . .. .. . ........ . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. . .. .. . .. . .. . .......... . .. .. . ........ . ", " . . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. . .. .. . .. . .. . .......... . .. .. . ........ . ", " . . . . . . . . ... ... ... . . . .. . ...... . .. .. . .... .. . ........ . .. . ...... . .. . .. . .. . ........ . .. . ", " . . .. . ...... . .. .. . .... .. . ........ . .. . ...... . .. . .. . .. . ........ . .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .. .. . ...... . ........ . ........ . .. . . ...... . .. . . . . ...... . ", " . . .. .. . ...... . ........ . ........ . .. . . ...... . .. . . . . ...... . ", " . . .. .. . .. .. . .. .. . .. .. . .. . . .. . .. . .. .. .. . .. . ...... . .. .. . ", " . . .. .. . .. .. . .. .. . .. .. . .. . . .. . .. . .. .. .. . .. . ...... . .. .. . ", " ... ... . ... . . .. .. . .. . .. .. . .. .. . .. .... . .. .... . .. . .. . .. .. .. . .. . .. .. . .......... . ", " . . . . .. . . . . .. .. . .. . .. .. . .. .. . .. .... . .. .... . .. . .. . .. .. .. . .. . .. .. . .......... . ", " . . . . . . . . . . . . . . . . . . . .. . ........ . ........ . .... .. . .... .. . .. . .... . .. . .. .. . ........ . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . ........ . ........ . .... .. . .... .. . .. . .... . .. . .. .. . ........ . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. . . .. .. . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. . . .. .. . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. . . .. . .. . .. .. . ........ . ...... . ", " . . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. . . .. . .. . .. .. . ........ . ...... . ", " . . . . . . . . ... ... . ... . . . .......... . ........ . .. .. . ........ . .. . . .. . .. . .. . .. . . ", " . . . .......... . ........ . .. .. . ........ . .. . . .. . .. . .. . .. . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .. .. . .......... . ...... . ........ . . . . .. . ...... . . . . ", " . . .. .. . .......... . ...... . ........ . . . . .. . ...... . . . . ", " . . .. .. . .. . .. .. . .. . . . . .......... . . .......... . . . ", " ... ... . . . . .. .. . .. . .. .. . .. . . . . .......... . . .......... . . . ", " . . . . .. .. . . .......... . .. . .. . .. . ...... . ........ . . .. .. . .......... . .. . ...... . . ", " . . . . . . . . . . . . . . . . . . .......... . .. . .. . .. . ...... . ........ . . .. .. . .......... . .. . ...... . . ", " . . . . . . . . . . . . . . . . .. .. . .. . .. . ...... . .. . .. . .. . .. .. . .. . .......... . .. . . ", " . . . . . . . . . . . . . . . . .. .. . .. . .. . ...... . .. . .. . .. . .. .. . .. . .......... . .. . . ", " . . . . . . . . . . . . .......... . .. . .. . .. . .. . ...... . .. . .. . .. . .. . .... . .. .... . ", " . . . . . . . . . . . . . . . . .......... . .. . .. . .. . .. . ...... . .. . .. . .. . .. . .... . .. .... . ", " . . . . . . . . . . . . . . . . .. .. . .. .. . .. .. . .. . .. .. . .. . .. . .. . .. . .. . .. .. . .. .. .. . ", " . . . . . . . . ... ... . . . . .. .. . .. .. . .. .. . .. . .. .. . .. . .. . .. . .. . .. . .. .. . .. .. .. . ", " . . .. .. . ...... . ...... . ........ . ...... . ........ . ...... . .. . .. . ...... . ...... . .... .. . ", " . . .. .. . ...... . ...... . ........ . ...... . ........ . ...... . .. . .. . ...... . ...... . .... .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .. . .. . ........ . .......... . .. . .. . . . .. . .. . . . ", " . . .. . .. . ........ . .......... . .. . .. . . . .. . .. . . . ", " . . ........ . .... . .. .. . .. . .. . ...... . . . .. . .. . .. .. . ...... . ", " . . ........ . .... . .. .. . .. . .. . ...... . . . .. . .. . .. .. . ...... . ", " ... . ... ... . . .. .. . .. .. . .. .. . .. . .... .. . .. . . .......... . .. . .......... . .. .. . .. .. . ", " . . .. . . . . . . .. .. . .. .. . .. .. . .. . .... .. . .. . . .......... . .. . .......... . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . . ...... . .. .. . .. .. . .. . .. .... . .. . . .. . .... . .. .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . ...... . .. .. . .. .. . .. . .. .... . .. . . .. . .... . .. .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . .. .. . .......... . .. .. . .. . .. .. . .. . .. . .. . .. .. . .. .. . .. .... . .. .. . ", " . . . . . . . . . . . . . .. .. . .......... . .. .. . .. . .. .. . .. . .. . .. . .. .. . .. .. . .. .... . .. .. . ", " . . . . . . . . . . . . . . . . . ........ . .. . .. .. . .. . .. .. . .. .. . .. . .. . .. . .. . ...... .. . .... .... . ", " . . . . . . . . . . . . . . . . . ........ . .. . .. .. . .. . .. .. . .. .. . .. . .. . .. . .. . ...... .. . .... .... . ", " . . . . . . . . ... . ... ... . . .. . .. . ........ . .. . ........ . .... . .. . .......... . .. . .. . .. . . ", " . . .. . .. . ........ . .. . ........ . .... . .. . .......... . .. . .. . .. . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .... . .......... . .......... . .. .. . . . . .. . .. . . . .. .. . ", " . . .... . .......... . .......... . .. .. . . . . .. . .. . . . .. .. . ", " . . .... .. . .. . .. . .. .. . . . . .......... . .. . ...... . . . ", " . . .... .. . .. . .. . .. .. . . . . .......... . .. . ...... . . . ", " ... . ... . . . .. . ........ . .. . .. .. . ...... . .. .. . . .. . .......... . .. . ........ . .. .. . ", " . . .. . . .. . . .. . ........ . .. . .. .. . ...... . .. .. . . .. . .......... . .. . ........ . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . .. . ........ . .. .. . .. .. . .. .. . .... . .... . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. . ........ . .. .. . .. .. . .. .. . .... . .... . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. . .. . .. .. . .......... . .. .. . .... . .. .. . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . .. . .. . .. . .. .. . .......... . .. .. . .... . .. .. . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . .. .... . .. .. . .. . .. .. . .. . .. .... . . .. .. . .. . .. . .. .. . .. .... . ", " . . . . . . . . . . . . . . . . .. .... . .. .. . .. . .. .. . .. . .. .... . . .. .. . .. . .. . .. .. . .. .... . ", " . . . . . . . . ... . ... . . . .... . ...... . .......... . ...... . ...... . .... .. . . .. . .. . .......... . ...... . .... .. . ", " . . .... . ...... . .......... . ...... . ...... . .... .. . . .. . .. . .......... . ...... . .... .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .... . .... . .......... . .. .. . .... . . . .. . . . . .......... . ", " . . .... . .... . .......... . .. .. . .... . . . .. . . . . .......... . ", " . . .. .. . .. . .. . .. .. . .. .. . . .......... . .......... . ...... . .......... . .... . .. . ", " . . .. .. . .. . .. . .. .. . .. .. . . .......... . .......... . ...... . .......... . .... . .. . ", " . . .. .. . .. . .. . .. .. . .. . .. .. . .. . .. .. . . .. . .. .. . .. . ", " ... . . ... . . .. .. . .. . .. . .. .. . .. . .. .. . .. . .. .. . . .. . .. .. . .. . ", " . . .. .. . . . . .. . ........ . ........ . .. .. . ...... . .. .. . .......... . .. .. . . .......... . .. .. . .. . ", " . . . . . . . . . . . . . . . . . . .. . ........ . ........ . .. .. . ...... . .. .. . .......... . .. .. . . .......... . .. .. . .. . ", " . . . . . . . . . . . . . . . . .. .. .. . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . . .. . .. .. . .. . ", " . . . . . . . . . . . . . . . . .. .. .. . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . . .. . .. .. . .. . ", " . . . . . . . . . . . . .. .. . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . . .. . ........ . .. . ", " . . . . . . . . . . . . . . . . .. .. . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . . .. . ........ . .. . ", " . . . . . . . . . . . . . . . . .... .. . ...... . .. . .. . .. . .. . .. . .. .. . .......... . .......... . .. . .......... . ", " . . . . . . . . ... . . ... . . .... .. . ...... . .. . .. . .. . .. . .. . .. .. . .......... . .......... . .. . .......... . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .... . .......... . ...... . .. .. . ........ . . . .. . . ...... . . . ", " . . .... . .......... . ...... . .. .. . ........ . . . .. . . ...... . . . ", " . . .. . .. . .. .. . .. .. . .. .. . . . .......... . .......... . . ........ . .......... . ", " . . .. . .. . .. .. . .. .. . .. .. . . . .......... . .......... . . ........ . .......... . ", " . . .. . .. . .. . .. .. . .. .. . .. .. . .......... . .. . .. . .......... . .. .. . .. .. . ", " ... . . . . . .. . .. . .. . .. .. . .. .. . .. .. . .......... . .. . .. . .......... . .. .. . .. .. . ", " . . .. .. .. . . . .. . .. ...... . .. .. .. . ........ . .. .. . .. . .......... . .. .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . . . .. . .. ...... . .. .. .. . ........ . .. .. . .. . .......... . .. .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. .. . .. .. .. . .. . .. .. .. . .... . .. . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. .. . .. .. .. . .. . .. .. .. . .... . .. . .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . .. . .. .. . .. .. .. . .. . .. .. .. . .. . .. . .. .. . .. . ........ . .. .... . ", " . . . . . . . . . . . . . . . . .. . .. .. . .. .. .. . .. . .. .. .. . .. . .. . .. .. . .. . ........ . .. .... . ", " . . . . . . . . . . . . . . . . .. . ........ . .. .. . ...... . .. .. . .. . .. . .. . .. . .. . . ", " . . . . . . . . ... . . . . . . .. . ........ . .. .. . ...... . .. .. . .. . .. . .. . .. . .. . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .. . ...... . .. .. . .. .. . .. . . . . .. . .. .. . . .......... . ", " . . .. . ...... . .. .. . .. .. . .. . . . . .. . .. .. . . .......... . ", " . . .. . .. .. . .. .. . .. .. . .. . . . ........ . .......... . .. .. . . . ", " . . .. . .. .. . .. .. . .. .. . .. . . . ........ . .......... . .. .. . . . ", " . . .. . .. .. . .. .. . .. .. . .. .... . .. .. . .. . .. .. . .. . .. .. . ...... . .. .. . ", " . ... ... ... . . .. . .. .. . .. .. . .. .. . .. .... . .. .. . .. . .. .. . .. . .. .. . ...... . .. .. . ", " .. . . . . . . . . .. . ...... . .......... . .. . .... .. . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . ...... . .......... . .. . .... .. . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . ", " . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. .. . .. . .... . .. . ...... . .. . .. . .. . ", " . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. .. . .. . .... . .. . ...... . .. . .. . .. . ", " . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. .. . .. .. . .. .. . .. . .. .. .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . .. .. . .. .. . .. .. . .. .. . .. . .. .. .. . .. . .. .. . .. .. . ", " . . . . . . . . . . . . . . . . . .. . ...... . .. .. . .. .. . .. .. . .. .. . .. . .... . .. . .. . .. . .. .. . ", " . . . . . . . . . ... ... ... . . .. . ...... . .. .. . .. .. . .. .. . .. .. . .. . .... . .. . .. . .. . .. .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . .. . ...... . ...... . .. .. . .. . . . .. . .. . . .. . . ", " . . .. . ...... . ...... . .. .. . .. . . . .. . .. . . .. . . ", " . . .. . .. .. . .. . .. .. . . . . ........ . .. . .. . .... .. . .. .. . ", " . . .. . .. .. . .. . .. .. . . . . ........ . .. . .. . .... .. . .. .. . ", " . ... ... . . . .. . .. .. . .. . .. .. . .... . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . ", " .. . . . . .. . . .. . .. .. . .. . .. .. . .... . .. .. . .. . .. .. . .. . .. .. . .. . .. .. . ", " . . . . . . . . . . . . . . . . . . .. . ........ . .. . .. .. . .. . .. .. . .......... . .. . .. . .. .. . . .. .. . ", " . . . . . . . . . . . . . . . . .. . ........ . .. . .. .. . .. . .. .. . .......... . .. . .. . .. .. . . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. . .. . .. . .. . ........ . .. .. . .. . .. . .. .. .. . . .. .. . ", " . . . . . . . . . . . . .. . .. . .. . .. . .. . ........ . .. .. . .. . .. . .. .. .. . . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. . .. . .. . .. . .. . .. . .. . .. . .. .. .. . . ........ . ", " . . . . . . . . . . . . . . . . .. . .. . .. . .. . .. . .. . .. . .. . .. . .. .. .. . . ........ . ", " . . . . . . . . . ... ... . . . .. . .... . ...... . .. . ...... . ...... . .... . .. . .. . .. .... . . .. . ", " . . .. . .... . ...... . .. . ...... . ...... . .... . .. . .. . .. .... . . .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . . . ...... . .......... . .. . . . . . . .. . .. . ", " . . . . ...... . .......... . .. . . . . . . .. . .. . ", " . . .. . .... . .. . .. . . . . .......... . .. . .. . . ........ . ", " . . .. . .... . .. . .. . .... . . . .......... . .. . .. . . ........ . ", " . ... . ... . . .. .. .. . .... . .. . .. . .... . .......... . . .. . .. . .. . .... . .. . ", " .. . . .. . . . . .. .. .. . .... . .. . .. . .. . .......... . . .. . .. . .. . .... . .. . ", " . . . . . . . . . . . . . . . . . . ...... . . .. . .. . .. . .. . .......... . .. . .. .. . .. .. . .. . .......... . ", " . . . . . . . . . . . . . . . . ...... . . .. . .. . .. . .. . .......... . .. . .. .. . .. .. . .. . .......... . ", " . . . . . . . . . . . . . . . . .. .. .. . .... . .. . .. . .. . .. . .. . .. . .. .. . .. .. . .. . .. . ", " . . . . . . . . . . . . .. .. .. . .... . .. . .. . .. . .. . .. . .. . .. .. . .. .. . .. . .. . ", " . . . . . . . . . . . . . . . . .. . .... . .. .. . .. . .. .. . .. . .. . .. . .. .. . .. .. . .. . .. . ", " . . . . . . . . . . . . . . . . .. . .... . .. .. . .. . .. .. . .. . .. . .. . .. .. . .. .. . .. . .. . ", " . . . . . . . . . ... . ... . . . . .... . .......... . .... . .......... . .......... . .......... . .. .. . .... . .. . . ", " . . . . .... . .......... . .... . .......... . .......... . .......... . .. .. . .... . .. . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . . . .. .. . ...... . .. . .. . . .. .. . .. . . . . ", " . . . . .. .. . ...... . .. . .. . . .. .. . .. . . . . ", " . . .. . .... . .. .. . .. . .. . .. . . .......... . .. . .......... . .. .. . .......... . ", " . ... . . . . .. . .... . .. .. . .. . .. . .. . . .......... . .. . .......... . .. .. . .......... . ", " .. . . .. .. . . .. . .... . .. .. . .. . .. .. . .. . .. . .. .. . .......... . .. .. . .. . .. . ", " . . . . . . . . . . . . . . . . . . .. . .... . .. .. . .. . .. .. . .. . .. . .. .. . .......... . .. .. . .. . .. . ", " . . . . . . . . . . . . . . . .......... . . .... . .. . .. .. . .. . .......... . .. .. . .. . .. .. . .. .. . ........ . ", " . . . . . . . . . . . . . . . .......... . . .... . .. . .. .. . .. . .......... . .. .. . .. . .. .. . .. .. . ........ . ", " . . . . . . . . . . . .. . .... . .. .. . .. . .... . .. . .... . .. . .. . .. .. . . .. .. . ", " . . . . . . . . . . . . . . . .. . .... . .. .. . .. . .... . .. . .... . .. . .. . .. .. . . .. .. . ", " . . . . . . . . . . . . . . . .. . .. . .. .. . .. . .. .. . .. . .. .. . .. . .. . .. .. . . .. .. . ", " . . . . . . . . . ... . . . . .. . .. . .. .. . .. . .. .. . .. . .. .. . .. . .. . .. .. . . .. .. . ", " . . . .. . .. .. . ...... . .. .. . .. . .. .. . .. . ........ . .......... . . . ", " . . . .. . .. .. . ...... . .. .. . .. . .. .. . .. . ........ . .......... . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . . .. . .. . .. .. . .... . .. . . . . . .. . . ", " . . . .. . .. . .. .. . .... . .. . . . . . .. . . ", " . . . .. . .. . .. .. . .. . .. . . .... . .......... . .......... . ...... . . ", " . . ... ... . . . .. . .. . .. .. . .. . .. . . .... . .......... . .......... . ...... . .......... . ", " .. .. . . . . . . . .. . .. . .......... . .. . .. . .. . .. . .. . .. .. . .. .. . .......... . ", " . . . . . . . . . . . . . . . . . . . .. . .. . .......... . .. . .. . .. . .. . .. . .. .. . .. .. . .. .. .. . ", " . . . . . . . . . . . . . . . . . .. . .. . .. . .. . .. . .......... . .... .. . .. . .. .. . .. .. .. . .. .. .. . ", " . . . . . . . . . . . . . . . . . .. . .. . .. . .. . .. . .......... . .... .. . .. . .. .. . .. .. .. . .......... . ", " . . . . . . . . . . . . .... . .. . .. . .......... . .. . .. . .. .. . .. . .. . .. . ...... . .......... . ", " . . . . . . . . . . . . . . . . .... . .. . .. . .......... . .. . .. . .. .. . .. . .. . .. . ...... . .. .. . ", " . . . . . . . . . . . . . . . . .. . .. . .. . .. . .. . .. . .. .. . .. . .. . .. . .. . .. .. . ", " . . . . . . . . . . ... ... . . .. . .. . .. . .. . .. . .. . .. .. . .. . .. . .. . .. . .. .. . ", " . . .. . .. . .......... . .. . ...... . .. . .. . ...... . .... . .. . . .. .. . ", " . . .. . .. . .......... . .. . ...... . .. . .. . ...... . .... . .. . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . . . .. .. . ...... . . .. . . . . . .. . . ", " . . . . .... .... . ...... . . .. . . . . . .. . . ", " . . ... . . . . . .... .... . .. . . .. . . .......... . .. . .... . .. . . ", " .. .. . . .. . . . . .. .. .. . .. . . .. . . .......... . .. . .... . .. . . ", " . . . . . . . . . . . . . . . . . . . .......... . .. .. .. . .. . .... .. . .. . . .. . .. .. . . ...... . .. . ", " . . . . . . . . . . . . . . . . .......... . .. .. . .. . .... .. . .. . . .. . .. .. . . ...... . .. . ", " . . . . . . . . . . . . . . . .......... . . .. .. . .. . .. .. .. . .. . ...... . .. . .. . .. . .. . . ", " . . . . . . . . . . . .......... . . .. .. . .. . .. .. .. . .. . ...... . .. . .. . .. . .. . . ", " . . . . . . . . . . . . . . . . .......... . .. .. . .. . .. .. .. . .. . .. . .. . .. . .. . ...... . .......... . ", " . . . . . . . . . . . . . . . . .......... . .. .. . .. . .. .. .. . .. . .. . .. . .. . .. . ...... . .......... . ", " . . . . . . . . . . ... . . . . . .. .. . .. . .. .. . .. . .. . .. .. . .. . .. . .. . . ", " . . . . .. .. . .. . .. .. . .. . .. . .. .. . .. . .. . .. . . ", " . . . . .. .. . ...... . .. .. . .. . .......... . .. .. . . ...... . ........ . .. . ", " . . . . .. .. . ...... . .. .. . .. . .......... . .. .. . . ...... . ........ . .. . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . . .. . .. .. . .. . . . . .. . .. . .. . ...... . . ", " . . . .. . .. .. . .. . . . . .. . .. . .. . ...... . . ", " . . . ... . . . .. . .. .. . .. .. . . .. . . .......... . .......... . .. .. . . . ", " .. .. .. . . . . . .. . .. .. . .. .. . . .. . . .......... . .......... . .. .. . . . ", " . . . . . . . . . . . . . . . . . . . .. . .... .. . .. .. . .. .... . .. . ........ . .. .. . .. . .. . .. .... . . ", " . . . . . . . . . . . . . . . . .. . .... .. . .. .. . .. .... . .. . ........ . .. .. . .. . .. . .. .... . . ", " . . . . . . . . . . . . . . . . .. . .. .. .. . . .... .. . .......... . .. . .. .. . .. . . .... .. . . ", " . . . . . . . . . . . . .. . .. .. .. . . .... .. . .......... . .. . .. .. . .. . . .... .. . . ", " . . . . . . . . . . . . . . . . .. . .. .... . . .. .. . .. . ........ . .. . .. .. .. . . .. .. . . ", " . . . . . . . . . . . . . . . . .. . .. .... . . .. .. . .. . ........ . .. . .. .. .. . . .. .. . . ", " . . . . . . . . . . . ... . . .... . .. . .. .. . . .. .. . .. . .. . .. . .. .. .. . . .. .. . . ", " . . .... . .. . .. .. . . .. .. . .. . .. . .. . .. .. .. . . .. .. . . ", " . . .... . .. . .. .. . . .. .. . . ........ . ...... . .. . . .. .. . . ", " . . .... . .. . .. .. . . .. .. . . ........ . ...... . .. . . .. .. . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " . . . . . . . . . . . . . . ", " . . . ...... . ...... . . . . . . . ...... . .. .. . .......... . ", " . . . . . . . ...... . ...... . . . . . . . ...... . .. .. . .......... . ", " .. .. .. .. . . .. . .. .. . .. .. . . . .. . . .. .. . .......... . .. .. . . .......... . ", " . . . . . . . . . . . . . . . . . . .. . .. .. . .. .. . . . .. . . .. .. . .......... . .. .. . . .......... . ", " . . . . . . . . . . . . . . .. . .. . .. .. . . ...... . .. . . .. .. . .. . ...... . ...... . .......... . ", " . . . . . . . . . . . . . . .. . .. . .. .. . . ...... . .. . . .. .. . .. . ...... . ...... . .......... . ", " . . . . . . . . . . .. . .. . .. .. . . .. .. . .......... . .. .. .. . .. .. . .. . . .. .. . .......... . ", " . . . . . . . . . . . . . . .. . .. . .. .. . . .. .. . .......... . .. .. .. . .. .. . .. . . .. .. . .......... . ", " . . . . . . . . . . . . . . .. . .. . .. .. . . .. .. . .. . .. .. .. . .. . .. .. . . .. .. . .......... . ", " . . . . . . . . . . . . . . .. . .. . .. .. . . .. .. . .. . .. .. .. . .. . .. .. . . .. .. . .......... . ", " . . .. . . .. .. . . .. .. . .. . .. . .. . .. . . .. .. . .......... . ", " . . .. . . .. .. . . .. .. . .. . .. . .. . .. . . .. .. . .......... . ", " . . . .. . ...... . .......... . ...... . . .... . .... . .. . . ...... . .......... . ", " . . . .. . ...... . .......... . ...... . . .... . .... . .. . . ...... . .......... . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . ", " .................................................................................................................................................................................................... ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; gpsim-0.30.0/extras/lcd/lcd.h0000664000076400007640000001652413041763633012645 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __LCD_H__ #define __LCD_H__ #include #include #include #include #include #include #include #include #include class LcdDisplay; class LCD_InputPin; class HD44780; // Create an interface to the simulator class LCD_Interface : public Interface { private: LcdDisplay *lcd; public: //virtual void UpdateObject (gpointer xref,int new_value); //virtual void RemoveObject (gpointer xref); virtual void SimulationHasStopped (gpointer object); //virtual void NewProcessor (unsigned int processor_id); //virtual void NewModule (Module *module); //virtual void NodeConfigurationChanged (Stimulus_Node *node); //virtual void NewProgram (unsigned int processor_id); virtual void Update (gpointer object); LCD_Interface(LcdDisplay *_gp); }; typedef char _5X7 [7][6]; typedef char _5X8 [8][6]; class LcdFont { public: LcdFont(gint, GtkWidget *, LcdDisplay *); ~LcdFont(); void update_pixmap(int, _5X8 *, LcdDisplay *); cairo_surface_t *getPixMap(unsigned int); private: GdkWindow *mywindow; // stashed to allow font regenaration std::vector pixmaps; cairo_surface_t *create_image(LcdDisplay *lcdP, _5X8 *ch); }; //------------------------------------------------------------------------ // // lcd tracing // class LcdDisplay; class LcdTraceType : public TraceType { public: LcdDisplay *lcd; LcdTraceType(LcdDisplay *_lcd, unsigned int s) : TraceType(s, "LCD"), lcd(_lcd) { } virtual TraceObject *decode(unsigned int tbi) = 0; }; class LcdWriteTT : public LcdTraceType { public: LcdWriteTT(LcdDisplay *lcd, unsigned int s); virtual TraceObject *decode(unsigned int tbi); virtual int dump_raw(unsigned tbi, char *buf, int bufsize); }; class LcdReadTT : public LcdTraceType { public: LcdReadTT(LcdDisplay *lcd, unsigned int s); virtual TraceObject *decode(unsigned int tbi); virtual int dump_raw(unsigned tbi, char *buf, int bufsize); }; class LcdTraceObject : public TraceObject { public: LcdDisplay *lcd; LcdTraceObject(LcdDisplay *_lcd) : TraceObject() , lcd(_lcd) { } virtual void print(FILE *)=0; }; class LcdWriteTO : public LcdTraceObject { public: LcdWriteTO(LcdDisplay *_lcd); virtual void print(FILE *); }; class LcdReadTO : public LcdTraceObject { public: LcdReadTO(LcdDisplay *_lcd); virtual void print(FILE *); }; // // State Machine Events // enum ControlLineEvent { ERD = 0, ERC, EWD, EWC, eRD, eRC, eWD, eWC, DataChange, BAD_EVENT }; // // State Machine States // enum State { POWERON, ST_INITIALIZED, ST_COMMAND_PH0, ST_STATUS_READ, ST_DATA_READ, //_8BITMODE_START, //_8BITMODE, }; enum ePins { eDC, eE, eRW }; //======================================================================== class LcdDisplay : public Module { public: #define _8BIT_MODE_FLAG (1<<0) #define LARGE_FONT_MODE_FLAG (1<<1) #define _2LINE_MODE_FLAG (1<<2) #define DISPLAY_ON_FLAG (1<<3) #define CURSOR_ON_FLAG (1<<4) #define BLINK_ON_FLAG (1<<5) State current_state, previous_state; ControlLineEvent last_event; // int mode_flag; int data_latch; int data_latch_phase; int debug; struct { int row; int col; } cursor; // // Here's the graphical portion // guint rows,cols; // e.g. 2x20 would be 2 rows, 20 columns #define TWO_ROWS_IN_ONE 1 unsigned disp_type; struct { // Resolution in lcd pixels e.g. 5x7 gint x; gint y; } dots; struct { // Resolution in crt pixels - scaled gint x; gint y; } pixels; gfloat contrast; // pixel on/off ratio LcdFont *fontP; GtkWidget *window; GtkWidget *darea; gint w_width,w_height; // // Tracing // TraceType *readTT, *writeTT; TraceType *getWriteTT(); TraceType *getReadTT(); // // Graphics member functions // void set_pixel_resolution(gint _x=5, gint _y=7) { dots.x =_x; dots.y = _y; }; void set_crt_resolution(gint _x=3, gint _y=3) { pixels.x = _x; pixels.y= _y; }; void set_contrast(gfloat _contrast=1.0) { contrast = _contrast; }; gint get_char_width() { return (1+dots.x * pixels.x); }; gint get_char_height() { return (dots.y * pixels.y); }; gint get_border() { return 5; }; cairo_surface_t *get_pixmap(gint row, gint col); void move_cursor(unsigned int new_row, unsigned int new_column); void write_data(int new_data); LcdDisplay(const char *, int aRows, int aCols, unsigned aType=0); ~LcdDisplay(); void CreateGraphics(); //void InitStateMachine(void); //void test(void); void build_window(); void update(); void update(cairo_t *cr); void update_cgram_pixmaps(); // Inheritances from the Package class virtual void create_iopin_map(); // Inheritance from Module class const virtual char *type() { return ("lcd_display"); }; static Module *construct(const char *new_name); void testHD44780(); bool dataBusDirection(); void UpdatePinState(ePins, char); protected: LCD_InputPin * m_E; LCD_InputPin * m_RW; LCD_InputPin * m_DC; PortRegister *m_dataBus; IO_bi_directional *lcd_bus[8]; HD44780 *m_hd44780; unsigned int m_controlState; bool cgram_updated; unsigned int interface_seq_number; }; class LcdDisplay20x2 : public LcdDisplay { public: LcdDisplay20x2(const char *_name, int _rows, int _cols, unsigned int _type = 0) : LcdDisplay(_name, _rows, _cols) {} ~LcdDisplay20x2() {} // Inheritance from Module class const virtual char *type() { return ("lcd_20x2"); }; static Module *construct(const char *new_name); }; class LcdDisplay20x4 : public LcdDisplay { public: LcdDisplay20x4(const char *_name, int _rows, int _cols, unsigned int _type = 0) : LcdDisplay(_name, _rows, _cols) {} ~LcdDisplay20x4() {} // Inheritance from Module class const virtual char *type() { return ("lcd_20x4"); }; static Module *construct(const char *new_name); }; class LcdDisplayDisplaytech161A : public LcdDisplay { public: LcdDisplayDisplaytech161A(const char *, int aRows, int aCols, unsigned aType); ~LcdDisplayDisplaytech161A(); // Inheritance from Module class const virtual char *type() { return ("lcd_dt161A"); }; static Module *construct(const char *new_name); }; // bit flags that can be set in the GPSIM_LCD_DEBUG environment variable #define LCD_DEBUG_ENABLE 0x01 // Enable debug printfs #define LCD_DEBUG_DUMP_PINS 0x02 // Dump changes in the LCD pins #define LCD_DEBUG_TRACE_DATA 0x04 // Trace changes in CGRAM/DDRAM #define LCD_DEBUG_TRACE_PORT 0x08 // Trace data on port #endif // __LCD_H__ gpsim-0.30.0/extras/lcd/lcdfont.h0000664000076400007640000005322113041763633013527 00000000000000#define FONT_LEN 256 _5X8 test[FONT_LEN] = { { /* 0 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 1 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 2 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 3 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 4 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 5 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 6 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 7 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 8 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 9 */ " ", " ", " ", " ", " ", " ", " ", }, { /* a */ " ", " ", " ", " ", " ", " ", " ", }, { /* b */ " ", " ", " ", " ", " ", " ", " ", }, { /* c */ " ", " ", " ", " ", " ", " ", " ", }, { /* d */ " ", " ", " ", " ", " ", " ", " ", }, { /* e */ " ", " ", " ", " ", " ", " ", " ", }, { /* f */ " ", " ", " ", " ", " ", " ", " ", }, { /* 10 */ "", "", "", "", "", "", "", }, { /* 11 */ "", "", "", "", "", "", "", }, { /* 12 */ "", "", "", "", "", "", "", }, { /* 13 */ "", "", "", "", "", "", "", }, { /* 14 */ "", "", "", "", "", "", "", }, { /* 15 */ "", "", "", "", "", "", "", }, { /* 16 */ "", "", "", "", "", "", "", }, { /* 17 */ "", "", "", "", "", "", "", }, { /* 18 */ "", "", "", "", "", "", "", }, { /* 19 */ "", "", "", "", "", "", "", }, { /* 1a */ "", "", "", "", "", "", "", }, { /* 1b */ "", "", "", "", "", "", "", }, { /* 1c */ "", "", "", "", "", "", "", }, { /* 1d */ "", "", "", "", "", "", "", }, { /* 1e */ "", "", "", "", "", "", "", }, { /* 1f */ "", "", "", "", "", "", "", }, { /* 20 */ " ", " ", " ", " ", " ", " ", " ", }, { /* 21 */ " . ", " . ", " . ", " . ", " . ", " ", " . ", }, { /* 22 */ " . . ", " . . ", " . . ", " ", " ", " ", " ", }, { /* 23 */ " . . ", " . . ", ".....", " . . ", ".....", " . . ", " . . ", }, { /* 24 */ " . ", " ....", ". . ", " ... ", " . .", ".... ", " . ", }, { /* 25 */ ".. ", ".. .", " . ", " . ", " . ", ". ..", " ..", }, { /* 26 */ " .. ", ". . ", ". . ", " . ", ". . .", ". . ", " .. .", }, { /* 27 */ " .. ", " . ", " . ", " ", " ", " ", " ", }, { /* 28 */ " . ", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* 29 */ " . ", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* 2a */ " ", " . ", ". . .", " ... ", ". . .", " . ", " ", }, { /* 2b */ " ", " . ", " . ", ".....", " . ", " . ", " ", }, { /* 2c */ " ", " ", " ", " ", " .. ", " . ", " . ", }, { /* 2d */ " ", " ", " ", ".....", " ", " ", " ", }, { /* 2e */ " ", " ", " ", " ", " ", " .. ", " .. ", }, { /* 2f */ " ", " .", " . ", " . ", " . ", ". ", " ", }, { /* 30 */ " ... ", ". .", ". ..", ". . .", ".. .", ". .", " ... ", }, { /* 31 */ " . ", " .. ", " . ", " . ", " . ", " . ", " ... ", }, { /* 32 */ " ... ", ". .", " .", " . ", " . ", " . ", ".....", }, { /* 33 */ ".....", " . ", " . ", " . ", " .", ". .", " ... ", }, { /* 34 */ " . ", " .. ", " . . ", ". . ", ".....", " . ", " . ", }, { /* 35 */ ".....", ". ", ".... ", " .", " .", ". .", " ... ", }, { /* 36 */ " .. ", " . ", ". ", ".... ", ". .", ". .", " ... ", }, { /* 37 */ ".....", " .", " . ", " . ", " . ", " . ", " . ", }, { /* 38 */ " ... ", ". .", ". .", " ... ", ". .", ". .", " ... ", }, { /* 39 */ " ... ", ". .", ". .", " ....", " .", " . ", " .. ", }, { /* 3a */ " ", " .. ", " .. ", " ", " .. ", " .. ", " ", }, { /* 3b */ " ", " .. ", " .. ", " ", " .. ", " . ", " . ", }, { /* 3c */ " . ", " . ", " . ", ". ", " . ", " . ", " . ", }, { /* 3d */ " ", " ", ".....", " ", ".....", " ", " ", }, { /* 3e */ ". ", " . ", " . ", " . ", " . ", " . ", ". ", }, { /* 3f */ " ... ", ". .", " .", " . ", " . ", " ", " . ", }, { /* 40 */ " ... ", ". .", " .", " .. .", ". . .", ". . .", " ... ", }, { /* 41 */ " ... ", ". .", ". .", ". .", ".....", ". .", ". .", }, { /* 42 */ ".... ", ". .", ". .", ".... ", ". .", ". .", ".... ", }, { /* 43 */ " ... ", ". .", ". ", ". ", ". ", ". .", " ... ", }, { /* 44 */ ".... ", ". .", ". .", ". .", ". .", ". .", ".... ", }, { /* 45 */ ".....", ". ", ". ", ".... ", ". ", ". ", ".....", }, { /* 46 */ ".....", ". ", ". ", ".... ", ". ", ". ", ". ", }, { /* 47 */ " ... ", ". .", ". ", ". ...", ". .", ". .", " ....", }, { /* 48 */ ". .", ". .", ". .", ".....", ". .", ". .", ". .", }, { /* 49 */ " ... ", " . ", " . ", " . ", " . ", " . ", " ... ", }, { /* 4a */ " ...", " . ", " . ", " . ", " . ", ". . ", " .. ", }, { /* 4b */ ". .", ". . ", ". . ", ".. ", ". . ", ". . ", ". .", }, { /* 4c */ ". ", ". ", ". ", ". ", ". ", ". ", ".....", }, { /* 4d */ ".. ..", ". . .", ". .", ". .", ". .", ". .", ". .", }, { /* 4e */ ". .", ". .", ".. .", ". . .", ". ..", ". .", ". .", }, { /* 4f */ " ... ", ". .", ". .", ". .", ". .", ". .", " ... ", }, { /* 50 */ ".... ", ". .", ". .", ".... ", ". ", ". ", ". ", }, { /* 51 */ " ... ", ". .", ". .", ". .", ". . .", ". . ", " .. .", }, { /* 52 */ ".... ", ". .", ". .", ".... ", ". . ", ". . ", ". .", }, { /* 53 */ " ....", ". ", ". ", " ... ", " .", " .", ".... ", }, { /* 54 */ ".....", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* 55 */ ". .", ". .", ". .", ". .", ". .", ". .", " ... ", }, { /* 56 */ ". .", ". .", ". .", ". .", ". .", " . . ", " . ", }, { /* 57 */ ". .", ". .", ". .", ". . .", ". . .", ". . .", " . . ", }, { /* 58 */ ". .", ". .", " . . ", " . ", " . . ", ". .", ". .", }, { /* 59 */ ". .", ". .", ". .", " . . ", " . ", " . ", " . ", }, { /* 5a */ ".....", " .", " . ", " . ", " . ", ". ", ".....", }, { /* 5b */ " ... ", " . ", " . ", " . ", " . ", " . ", " ... ", }, { /* 5c */ ". .", " . . ", ".....", " . ", ".....", " . ", " . ", }, { /* 5d */ " ... ", " . ", " . ", " . ", " . ", " . ", " ... ", }, { /* 5e */ " . ", " . . ", ". .", " ", " ", " ", " ", }, { /* 5f */ " ", " ", " ", " ", " ", " ", ".....", }, { /* 60 */ " . ", " . ", " . ", " ", " ", " ", " ", }, { /* 61 */ " ", " ", " ... ", " .", " ....", ". .", " ....", }, { /* 62 */ ". ", ". ", ". .. ", ".. .", ". .", ". .", ".... ", }, { /* 63 */ " ", " ", " ... ", ". ", ". ", ". .", " ... ", }, { /* 64 */ " .", " .", " .. .", ". ..", ". .", ". .", " ....", }, { /* 65 */ " ", " ", " ... ", ". .", ".....", ". ", " ... ", }, { /* 66 */ " .. ", " . .", " . ", "... ", " . ", " . ", " . ", }, { /* 67 */ " ....", ". .", ". .", " ....", " .", " .", " ... ", }, { /* 68 */ ". ", ". ", ". .. ", ".. .", ". .", ". .", ". .", }, { /* 69 */ " . ", " ", " .. ", " . ", " . ", " . ", " ... ", }, { /* 6a */ " . ", " .. ", " . ", " . ", " . ", ". . ", " .. ", }, { /* 6b */ ". ", ". ", ". . ", ". . ", ".. ", ". . ", ". . ", }, { /* 6c */ " .. ", " . ", " . ", " . ", " . ", " . ", " ... ", }, { /* 6d */ " ", " ", ".. . ", ". . .", ". . .", ". .", ". .", }, { /* 6e */ " ", " ", ". .. ", ".. .", ". .", ". .", ". .", }, { /* 6f */ " ", " ", " ... ", ". .", ". .", ". .", " ... ", }, { /* 70 */ " ", " ", ".... ", ". .", ".... ", ". ", ". ", }, { /* 71 */ " ", " ", " .. .", ". ..", " ....", " .", " .", }, { /* 72 */ " ", " ", ". .. ", ".. .", ". ", ". ", ". ", }, { /* 73 */ " ", " ", " ....", ". ", " ... ", " .", ".... ", }, { /* 74 */ " . ", "... ", " . ", " . ", " . ", " . .", " .. ", }, { /* 75 */ " ", " ", ". .", ". .", ". .", ". ..", " .. .", }, { /* 76 */ " ", " ", ". .", ". .", ". .", " . . ", " . ", }, { /* 77 */ " ", " ", ". .", ". .", ". . .", ". . .", " . . ", }, { /* 78 */ " ", " ", ". .", " . . ", " . ", " . . ", ". .", }, { /* 79 */ " ", " ", ". .", ". .", " ....", " .", " ... ", }, { /* 7a */ " ", " ", ".....", " . ", " . ", " . ", ".....", }, { /* 7b */ " . ", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* 7c */ " . ", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* 7d */ " . ", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* 7e */ " ", " . ", " . ", ".....", " . ", " . ", " ", }, { /* 7f */ " ", " . ", " . ", ".....", " . ", " . ", " ", }, { /* 80 */ "", "", "", "", "", "", "", }, { /* 81 */ "", "", "", "", "", "", "", }, { /* 82 */ "", "", "", "", "", "", "", }, { /* 83 */ "", "", "", "", "", "", "", }, { /* 84 */ "", "", "", "", "", "", "", }, { /* 85 */ "", "", "", "", "", "", "", }, { /* 86 */ "", "", "", "", "", "", "", }, { /* 87 */ "", "", "", "", "", "", "", }, { /* 88 */ "", "", "", "", "", "", "", }, { /* 89 */ "", "", "", "", "", "", "", }, { /* 8a */ "", "", "", "", "", "", "", }, { /* 8b */ "", "", "", "", "", "", "", }, { /* 8c */ "", "", "", "", "", "", "", }, { /* 8d */ "", "", "", "", "", "", "", }, { /* 8e */ "", "", "", "", "", "", "", }, { /* 8f */ "", "", "", "", "", "", "", }, { /* 90 */ "", "", "", "", "", "", "", }, { /* 91 */ "", "", "", "", "", "", "", }, { /* 92 */ "", "", "", "", "", "", "", }, { /* 93 */ "", "", "", "", "", "", "", }, { /* 94 */ "", "", "", "", "", "", "", }, { /* 95 */ "", "", "", "", "", "", "", }, { /* 96 */ "", "", "", "", "", "", "", }, { /* 97 */ "", "", "", "", "", "", "", }, { /* 98 */ "", "", "", "", "", "", "", }, { /* 99 */ "", "", "", "", "", "", "", }, { /* 9a */ "", "", "", "", "", "", "", }, { /* 9b */ "", "", "", "", "", "", "", }, { /* 9c */ "", "", "", "", "", "", "", }, { /* 9d */ "", "", "", "", "", "", "", }, { /* 9e */ "", "", "", "", "", "", "", }, { /* 9f */ "", "", "", "", "", "", "", }, { /* a0 */ " ", " ", " ", " ", " ", " ", " ", }, { /* a1 */ " ", " ", " ", " ", "... ", ". . ", "... ", }, { /* a2 */ " ...", " . ", " . ", " . ", " ", " ", " ", }, { /* a3 */ " ", " ", " ", " . ", " . ", " . ", "... ", }, { /* a4 */ " ", " ", " ", " ", ". ", " . ", " . ", }, { /* a5 */ " ", " ", " ", " .. ", " .. ", " ", " ", }, { /* a6 */ " ", ".....", " .", ".....", " .", " . ", " . ", }, { /* a7 */ " ", " ", ".....", " .", " .. ", " . ", " . ", }, { /* a8 */ " ", " ", " . ", " . ", " .. ", ". . ", " . ", }, { /* a9 */ " ", " ", " . ", ".....", ". .", " .", " .. ", }, { /* aa */ " ", " ", " ", ".....", " . ", " . ", ".....", }, { /* ab */ " ", " ", " . ", ".....", " .. ", " . . ", ". . ", }, { /* ac */ " ", " ", " . ", ".....", " . .", " . . ", " . ", }, { /* ad */ " ", " ", " ", " ... ", " . ", " . ", ".....", }, { /* ae */ " ", " ", ".... ", " . ", ".... ", " . ", ".... ", }, { /* af */ " ", " ", " ", ". . .", ". . .", " .", " .. ", }, { /* b0 */ " ", " ", " ", " ", ".....", " ", " ", }, { /* b1 */ ".....", " .", " . .", " .. ", " . ", " . ", " . ", }, { /* b2 */ " .", " . ", " . ", " .. ", ". . ", " . ", " . ", }, { /* b3 */ " . ", ".....", ". .", ". .", " .", " . ", " . ", }, { /* b4 */ " ", " ", ".....", " . ", " . ", " . ", ".....", }, { /* b5 */ " . ", ".....", " . ", " .. ", " . . ", ". . ", " . ", }, { /* b6 */ " . ", ".....", " . .", " . .", " . .", " . .", ". . ", }, { /* b7 */ " . ", ".....", " . ", ".....", " . ", " . ", " . ", }, { /* b8 */ " ", " ....", " . .", ". .", " .", " . ", " .. ", }, { /* b9 */ " . ", " ....", ". . ", " . ", " . ", " . ", " . ", }, { /* ba */ " ", ".....", " .", " .", " .", " .", ".....", }, { /* bb */ " . . ", ".....", " . . ", " . . ", " . ", " . ", " . ", }, { /* bc */ " ", ".. ", " .", ".. .", " .", " . ", "... ", }, { /* bd */ " ", ".....", " .", " . ", " . ", " . . ", ". .", }, { /* be */ " . ", ".....", " . .", " . . ", " . ", " . ", " ...", }, { /* bf */ " ", ". .", ". .", " . .", " .", " . ", " .. ", }, { /* c0 */ " ", " ....", " . .", ". . .", " ..", " . ", " .. ", }, { /* c1 */ " . ", "... ", " . ", ".....", " . ", " . ", " . ", }, { /* c2 */ " ", ". . .", ". . .", " .", " .", " . ", " . ", }, { /* c3 */ " ... ", " ", ".....", " . ", " . ", " . ", " . ", }, { /* c4 */ " . ", " . ", " . ", " .. ", " . . ", " . ", " . ", }, { /* c5 */ " . ", " . ", ".....", " . ", " . ", " . ", ". ", }, { /* c6 */ " ", " ... ", " ", " ", " ", " ", ".....", }, { /* c7 */ " ", ".....", " .", " . . ", " . ", " . . ", ". ", }, { /* c8 */ " . ", ".....", " . ", " . ", " ... ", ". . .", " . ", }, { /* c9 */ " . ", " . ", " . ", " . ", " . ", " . ", " . ", }, { /* ca */ " ", " . ", " . ", ". .", ". .", ". .", ". .", }, { /* cb */ ". ", ". ", ".....", ". ", ". ", ". ", " ....", }, { /* cc */ " ", ".....", " .", " .", " .", " . ", " .. ", }, { /* cd */ " ", " . ", ". . ", " . ", " .", " .", " ", }, { /* ce */ " . ", ".....", " . ", " . ", ". . .", ". . .", " . ", }, { /* cf */ " ", ".....", " .", " .", " . . ", " . ", " . ", }, { /* d0 */ " ", " ... ", " ", " ... ", " ", " ... ", " .", }, { /* d1 */ " ", " . ", " . ", ". ", ". .", ".....", " .", }, { /* d2 */ " ", " .", " .", " . . ", " . ", " . . ", ". ", }, { /* d3 */ " ", ".....", " . ", ".....", " . ", " . ", " ...", }, { /* d4 */ " . ", " . ", ".....", " . .", " . . ", " . ", " . ", }, { /* d5 */ " ", " ... ", " . ", " . ", " . ", " . ", ".....", }, { /* d6 */ " ", ".....", " .", ".....", " .", " .", ".....", }, { /* d7 */ " ... ", " ", ".....", " .", " .", " . ", " . ", }, { /* d8 */ ". . ", ". . ", ". . ", ". . ", " . ", " . ", " . ", }, { /* d9 */ " ", " . ", ". . ", ". . ", ". . .", ". . .", ". .. ", }, { /* da */ " ", ". ", ". ", ". .", ". . ", ". . ", ".. ", }, { /* db */ " ", ".....", ". .", ". .", ". .", ". .", ".....", }, { /* dc */ " ", ".....", ". .", ". .", " .", " . ", " . ", }, { /* dd */ " ", ".. ", " ", " .", " .", " . ", "... ", }, { /* de */ " . ", ". . ", " . ", " ", " ", " ", " ", }, { /* df */ "... ", ". . ", "... ", " ", " ", " ", " ", }, { /* e0 */ " ", " ", " . .", ". . .", ". . ", ". . ", " .. .", }, { /* e1 */ " . . ", " ", " ... ", " .", " ....", ". .", " ....", }, { /* e2 */ " ", " ... ", ". .", ".... ", ". .", ".... ", ". ", }, { /* e3 */ " ", " ", " ... ", ". ", " .. ", ". .", " ... ", }, { /* e4 */ " ", ". .", ". .", ". .", ". ..", "... .", ". ", }, { /* e5 */ " ", " ", " ....", ". . ", ". . ", ". .", " ... ", }, { /* e6 */ " ", " .. ", " . .", ". .", ". .", ".... ", ". ", }, { /* e7 */ " ", " ....", ". .", ". .", ". .", " ....", " .", }, { /* e8 */ " ", " ", " ...", " . ", " . ", ". . ", " . ", }, { /* e9 */ " . ", ".. . ", " . ", " ", " ", " ", " ", }, { /* ea */ " . ", " ", " .. ", " . ", " . ", " . ", " . ", }, { /* eb */ " ", ". . ", " . ", ". . ", " ", " ", " ", }, { /* ec */ " . ", " ... ", ". . ", ". . .", " ... ", " . ", " ", }, { /* ed */ " . ", " . ", "... ", " . ", "... ", " . ", " ....", }, { /* ee */ " ... ", " ", ". .. ", ".. .", ". .", ". .", ". .", }, { /* ef */ " . . ", " ", " ... ", ". .", ". .", ". .", " ... ", }, { /* f0 */ " ", ". .. ", ".. .", ". .", ". .", ".... ", ". ", }, { /* f1 */ " ", " .. .", ". ..", ". .", ". .", " ....", " .", }, { /* f2 */ " ... ", ". .", ".....", ". .", ". .", " ... ", " ", }, { /* f3 */ " ", " ", " ", " ", " . ..", ". . .", ".. . ", }, { /* f4 */ " ", " ... ", ". .", ". .", " . . ", ".. ..", " ", }, { /* f5 */ " . . ", " ", ". .", ". .", ". .", ". ..", " .. .", }, { /* f6 */ ".....", ". ", " . ", " . ", " . ", ". ", ".....", }, { /* f7 */ " ", ".....", " . . ", " . . ", " . . ", ". ..", " ", }, { /* f8 */ ".....", " ", ". .", " . . ", " . ", " . . ", ". .", }, { /* f9 */ " ", ". .", ". .", ". .", ". .", " ....", " .", }, { /* fa */ " .", ".... ", " . ", ".....", " . ", " . ", " ", }, { /* fb */ " ", ".....", " . ", " ....", " . .", ". .", " ", }, { /* fc */ " ", ".....", ". . .", ".....", ". .", ". .", " ", }, { /* fd */ " ", " ", " . ", " ", ".....", " ", " . ", }, { /* fe */ " ", " ", " ", " ", " ", " ", " ", }, { /* ff */ ".....", ".....", ".....", ".....", ".....", ".....", ".....", }, }; gpsim-0.30.0/extras/lcd/README0000664000076400007640000000052113041763633012600 00000000000000lcd-0.2.1 - An LCD emulator for gpsim The purpose of this program is to emulate the ubiquitous character type LCD displays. Most, but not all of the LCD's features are emulated. The notably absent feature is the ability to read the CGRAM and DDRAM. These will get added. See INSTALL for instructions on running the examples. Scott gpsim-0.30.0/extras/lcd/INSTALL0000664000076400007640000000213513041763633012754 00000000000000 Installation instructions ------------------------- You'll need at least gpsim-0.21.2 for this to work. un tar the lcd-0.2.1.tar.gz tarball and then: $ cd lcd-0.2.1 $ make $ su # make install # exit At this point, the LCD module has been compiled and installed as a shared library that can be loaded by gpsim. If you want to see if it works, then run the example: $ cd lcd-0.2.1/examples $ gpasm lcd_mod.asm $ gpsim -c lcd_mod.stc This will assemble the pic assembly code that test the LCD module. This code is fairly complete and can be used as an LCD driver for a real PIC/LCD board. When gpsim comes up, you should see the LCD display. A dark line will appear on the first row just like it does for a real LCD. When the test program is executed, the LCD will be initialized and the message "GPSIM WROTE THIS" will be repeatedly written. The LCD is not automatically updated, so you'll have to force a manual refresh by partially hiding the LCD window and then re-exposing it. This module has been integrated into the gpsim sources, so no seperate processes are required to build or install this module. gpsim-0.30.0/extras/lcd/examples/0000775000076400007640000000000013117466030013613 500000000000000gpsim-0.30.0/extras/lcd/examples/lcd_mod.asm0000664000076400007640000000726313116670631015651 00000000000000 list p=16C64,t=ON,c=132,n=80 title "lcd module test" radix dec ;******************************************************************************** include "p16c64.inc" include __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF& _HS_OSC ;LCD Module DDRAM Address is formed by adding the row and column EQU SCR_ROW0 EQU 0x00 ;Row 0 starts at LCD DDRAM Address 0 SCR_ROW1 EQU 0x40 ;Row 1 " " 64 SCR_ROW2 EQU 0x14 ;Row 2 " " 20 SCR_ROW3 EQU 0x54 ;Row 3 " " 84 SCR_COL0 EQU 0x00 START_OF_RAM_LO equ 0x20 END_OF_RAM_LO equ 0x7f START_OF_RAM_HI equ 0xa0 END_OF_RAM_HI equ 0xbf cblock START_OF_RAM_LO test index1,index2 max1,max2 loop_count_lo,loop_count_hi N_4_lo,N_4_hi buffer0,buffer1,buffer2,buffer3 buffer4,buffer5,buffer6,buffer7 LCD_CHAR ;A Temporary register. LCD_CTRL ;YATR LCD_init_loop temp ;Temporary reg tmp ;Temporary reg field_flag endc include "lcd.inc" include "screen.inc" RESET_VECTOR CODE 0x000 ; processor reset vector goto main INT_VECTOR CODE 0x004 ; interrupt vector location nop ;*********************************************************************** main BCF STATUS,RP0 ;Point to BANK 0 CLRF FSR ;Clear File Select Register CALL Clear_Regs ;Clear General Purpose Registers 20-0x7f, A0-C0 BSF STATUS,RP0 ;Point to BANK 1 MOVLW (1 << T0SE) | (1 << PSA) MOVWF OPTION_REG & 0x7f MOVLW 0x1 ;Make all of PORTA an input MOVWF TRISA ^ 0x80 MOVLW 0 MOVWF TRISB ^ 0x80 MOVLW 0 MOVWF TRISC ^ 0x80 MOVLW 0 MOVWF TRISD ^ 0x80 MOVLW 0 MOVWF TRISE ^ 0x80 BCF STATUS,RP0 ;Point to BANK 0 CALL LCD_INITIALIZE movlw 0 call createChar movlw 1 call createChar movlw 2 call createChar t1 ; CALL LCD_CLEAR_SCREEN movlw 1 call LCD_WRITE_CMD ;; write a string on row 0 movlw LCD_CMD_SET_DDRAM | SCR_ROW0 | SCR_COL0 call LCD_WRITE_CMD movlw 0 call write_string ;; write another string, but to row 1 movlw LCD_CMD_SET_DDRAM | SCR_ROW1 | SCR_COL0 call LCD_WRITE_CMD movlw 1 call write_string ;; write another string, but to row 2 movlw LCD_CMD_SET_DDRAM | SCR_ROW2 | SCR_COL0 call LCD_WRITE_CMD movlw 2 call write_string ;; write another string, but to row 3 movlw LCD_CMD_SET_DDRAM | SCR_ROW3 | SCR_COL0 call LCD_WRITE_CMD movlw 3 call write_string .assert "\"Check if display OK\"" nop call LCD_DELAY call LCD_DELAY call LCD_DELAY goto t1 ;*********************************************************************** ; Clear File Registers 20-0x7fh, A0-C0 in PIC's memory Clear_Regs MOVLW START_OF_RAM_LO ;First regs to clear in Bank 0 MOVWF FSR cr1 CLRF INDF ;Clear reg INCF FSR,F ;point to next reg to clear MOVLW END_OF_RAM_LO+1 ; SUBWF FSR,W SKPC goto cr1 MOVLW START_OF_RAM_HI ;First regs to clear in Bank 1 MOVWF FSR cr2 CLRF INDF ;Clear reg INCF FSR, F ;point to next reg to clear MOVLW END_OF_RAM_HI+1 ; SUBWF FSR,W SKPC goto cr2 RETURN include "lcd.asm" include "screen.asm" include "icons.inc" END gpsim-0.30.0/extras/lcd/examples/lcdmemtest.c0000664000076400007640000001013013041763633016040 00000000000000#ifdef EEE #include #include "delay.h" #endif #include #ifdef RRR __CONFIG(LVPDIS & BOREN & PWRTEN & WDTDIS & HS); #endif /* * lcdmemtest.c * * Test the memory of an LCD display. * Converted to PIC 16F870 May 2004 * Copyright (c) 2003-2004, Bert Driehuis * * This code is subject to the BSD license. */ #define RS_0 0 // bit #5 off #define RS_1 0x10 // bit #5 on #define RW_0 0 // bit 6 off #define RW_1 0x40 // bit 6 on #define E_0 0x00 #define E_1 0x20 #define usleep(n) DelayUs(n * 4) #define sleep_1ms() DelayMs(1) #define sleep_100ms() DelayMs(100) /* * Bang out D0-D7 with RS=0 on the 4-bit parallel lcd bus */ static void bang_rs0(unsigned char arg) { PORTC = ((arg & 0xf0) >> 4) | RW_0 | RS_0 | E_1; usleep(1); PORTC &= ~E_1; usleep(1); PORTC = (arg & 0x0f) | RW_0 | RS_0 | E_1; usleep(1); PORTC &= ~E_1; usleep(40); } static unsigned char read_rs0(void) { unsigned char rv = 0; TRISC = 0x0f; // PORTC<3:0> as input PORTC = RW_1 | RS_0 | E_0; // Raise RW to select read mode PORTC = RW_1 | RS_0 | E_1; // Raise E usleep(1); PORTC = RW_1 | RS_0 | E_0; // Drop E. Could read BF,AC<6:4> now usleep(1); PORTC = RW_1 | RS_0 | E_1; // Raise E usleep(1); PORTC = RW_1 | RS_0 | E_0; // Drop E. Could read AC<3:0> now usleep(1); PORTC = RW_1 | RS_1 | E_0; // Raise RS (data mode) PORTC = RW_1 | RS_1 | E_1; // Raise E usleep(1); // Wait for IO lines to settle rv = (PORTC & 0x0f) << 4; PORTC = RW_1 | RS_1 | E_0; // Drop E usleep(1); PORTC = RW_1 | RS_1 | E_1; // Raise E usleep(1); // Wait for IO lines to settle rv |= (PORTC & 0x0f); usleep(1); PORTC = RW_1 | RS_0 | E_0; // Drop all lines to steady state PORTC = RW_0 | RS_0 | E_0; // Drop all lines to steady state TRISC = 0; return rv; } static void bang_rs1(unsigned char arg) { PORTC = ((arg & 0xf0) >> 4) | RW_0 | RS_1 | E_1; usleep(1); PORTC &= ~E_1; usleep(1); PORTC = (arg & 0x0f) | RW_0 | RS_1 | E_1; usleep(1); PORTC &= ~E_1; usleep(40); } static unsigned char read_cgram(unsigned char pos) { unsigned char da_ta; if (pos > 64) return 0; bang_rs0(0x40 + pos); // set cgram address da_ta = read_rs0(); bang_rs0(0x80); // home cursor; data output return da_ta; } static void erase_cgram() { unsigned char i; bang_rs0(0x40); // Set CGRAM cursor to 0 for (i = 0; i < 64; i++) { bang_rs1(0x00); } } #define write_ddram_at(where, what) \ bang_rs0(0x80 + where); \ bang_rs1(what); /* * Set up the character locations that point to the user defined * fonts. Yes, this table is weird, but the most logical mapping * (sequential) causes aliasing of LCD segments. */ static void init_special_ddram() { write_ddram_at(66, 0); write_ddram_at(75, 1); write_ddram_at(68, 2); write_ddram_at(69, 3); write_ddram_at(70, 4); write_ddram_at(79, 5); write_ddram_at(72, 6); write_ddram_at(77, 7); } main() { static unsigned char i; unsigned char cgram_byte; i = 0; TRISC = 0; TRISA = 0xfe; PORTC = 0; sleep_1ms(); bang_rs0(0x33); // FN SET DL=1 N=0 F=0 DB1=1 DB0=1 bang_rs0(0x32); // FN SET DL=0 N=0 F=0 DB1=1 DB0=1 (set 4bit) bang_rs0(0x28); // FN SET DL=0 N=1 F=0 DB1=0 DB0=0 bang_rs0(0x01); // Clear screen sleep_1ms(); sleep_1ms(); bang_rs0(0x02); // Unshift sleep_1ms(); sleep_1ms(); bang_rs0(0x06); // Entry mode I/D=1 S=0 bang_rs0(0x0c); // DISPCTL on=1 curs=1 blink=0 bang_rs1('A'); bang_rs1('a'); bang_rs1('p'); bang_rs1(' '); //sendstring("Noot"); bang_rs1('.'); erase_cgram(); init_special_ddram(); bang_rs0(0x90); bang_rs1('-'); bang_rs1('-'); for (i = 0; i < 64; i++) { bang_rs0(0x40 | i); bang_rs1(i); } for (i = 0; i < 64; i++) { cgram_byte = read_cgram(i); if (cgram_byte != i) { bang_rs0(0x90); bang_rs1('0' + ((cgram_byte & 0xf0) >> 4)); bang_rs1('0' + (cgram_byte & 0x0f)); bang_rs1('0' + ((i & 0xf0) >> 4)); bang_rs1('0' + (i & 0x0f)); } } erase_cgram(); while (1) { PORTA = 1; sleep_100ms(); sleep_100ms(); sleep_100ms(); sleep_100ms(); bang_rs0(0x8d); bang_rs1('+'); PORTA = 0; sleep_100ms(); sleep_100ms(); sleep_100ms(); sleep_100ms(); bang_rs0(0x8d); bang_rs1('*'); } } gpsim-0.30.0/extras/lcd/examples/lcd_mod.stc0000664000076400007640000000241313041763633015654 00000000000000# Script for testing modules # # The purpose of this script is to load a simple # program for a PIC, load the gpsim module library, # and illustrate how modules can be connected to pics. set verbose 1 load s lcd_mod.cod set verbose 0 p16c64.xpos = 72 p16c64.ypos = 72 # load the gpsim module library. Not that this is a 'shared library'. # If the library fails to load then 1) it's not installed (try installing # gpsim) 2) or the path to library is not available (see the documentation # on modules). #module library libgpsim_lcd module library libgpsim_extras # display all of the modules that are in the library: # module list # load a specific module from the module library and give it a name module load lcd_display lcd1 lcd1.xpos = 240 lcd1.ypos = 120 # create nodes that can connect the Pic and the module. node nE node nRW node nDC # Define the data bus nodes. # since we'll only use '4-bit' we won't need all 8 data lines # # node d0 # node d1 # node d2 # node d3 node n_d4 node n_d5 node n_d6 node n_d7 attach nE portb3 lcd1.E attach nRW portb2 lcd1.RW attach nDC portb1 lcd1.DC # 4-bit mode - only the upper half of the data # bus needs to be connected. attach n_d4 portb4 lcd1.d4 attach n_d5 portb5 lcd1.d5 attach n_d6 portb6 lcd1.d6 attach n_d7 portb7 lcd1.d7 gpsim-0.30.0/extras/lcd/examples/screen.inc0000664000076400007640000000606013041763633015514 00000000000000 ;Screens ; ; ;*********************************************************************** ;Screen driver EQUates FIELD_START_ADDR EQU 0x14 ;Screen objects 2 or 3 bytes ; first byte FRTCCCCC ; F = 1 if this the last screen object in a list of screen objects ; R = Row location. 0 = Row 0, 1 = Row 1 ; CCCCC = Column location 0 = column 0, 0x13 = column 19 ; T = Type of object. 0 = String object, 1 = Field Object ; Second byte ; If the object is a string object (T=0), then this byte is the string number ; that the object references. ; Otherwise, if this object is a field object (T=1), then this byte defines the ; the type of the field with the following bit definition: ; xMESHHLx ; x = don't care ; M = Edit Mode. M=1 means field is being edited. ; E = Editable. If E=1 the object can be edited. ; S = Size of Variable reference by the variable pointer. S=0 for a byte S=1 for a word ; HH = 1x Display as Hex ; = 01 Display as Decimal ; = 00 Display as Decimal, but first, scale Hex value to decimal ; L = Suppress leading zeroes. ; Third byte (Field objects only) ; For field objects, this byte is pointer to the variable that is to be displayed in ; the field. SCR_IS_STRING_OBJECT EQU 0x00 SCR_IS_FIELD_OBJECT EQU 0x20 SCR_IS_EDITABLE EQU 0x20 SCR_IS_EDITABLEb EQU 5 SCR_IS_WORD EQU 0x10 SCR_IS_BYTE EQU 0x00 SCR_IS_WORDb EQU 4 SCR_IS_HEX EQU 0x08 SCR_IS_HEXb EQU 3 SCR_IS_DEC EQU 0x00 SCR_IS_SCALED EQU 0x04 SCR_IS_SCALEDb EQU 2 SCR_NO_ZEROES EQU 0x02 SCR_NO_ZEROESb EQU 1 ;LCD Module DDRAM Address is formed by adding the row and column EQU SCR_ROW0 EQU 0x00 ;Row 0 starts at LCD DDRAM Address 0 SCR_ROW1 EQU 0x40 ;Row 1 " " 0x40 SCR_COL0 EQU 0x00 SCR_COL1 EQU 0x01 SCR_COL2 EQU 0x02 SCR_COL3 EQU 0x03 SCR_COL4 EQU 0x04 SCR_COL5 EQU 0x05 SCR_COL6 EQU 0x06 SCR_COL7 EQU 0x07 SCR_COL8 EQU 0x08 SCR_COL9 EQU 0x09 SCR_COL10 EQU 0x0a SCR_COL11 EQU 0x0b SCR_COL12 EQU 0x0c SCR_COL13 EQU 0x0d SCR_COL14 EQU 0x0e SCR_COL15 EQU 0x0f SCR_COL16 EQU 0x10 SCR_COL17 EQU 0x11 SCR_COL18 EQU 0x12 SCR_COL19 EQU 0x13 SCR_STRING_OBJECT macro row, column, string_num RETLW row | column RETLW string_num endm SCR_FIELD_OBJECT macro row, column, variable_ptr, type RETLW row | column | SCR_IS_FIELD_OBJECT RETLW type RETLW variable_ptr endm SCR_NULL_OBJECT macro RETLW 0xff endm gpsim-0.30.0/extras/lcd/examples/icons.inc0000664000076400007640000000214213041763633015345 00000000000000; ; createChar is called with W between 0 and 7 (0-2) with current bitmaps ; It loads 8 bytes from a bitmask into the display CGRam starting at ; address (W<<3) ie 0, 8, 16, 24, 32, 40, 48 or 56 createChar: movwf buffer1 movwf buffer2 bcf STATUS,C rlf buffer1,F rlf buffer1,F rlf buffer1,F ; buffer1 contains CGRam address movf buffer1,W addlw LCD_CMD_SET_CGRAM call LCD_WRITE_CMD movlw HIGH(battery) movwf PCLATH movlw LOW(battery) addwf buffer1,W ; pixmap battery address + CGRam address btfsc STATUS,C incf PCLATH,F movwf buffer2 movlw 8 ; pixmap has 8 bytes to download movwf buffer1 char_loop movf buffer2,W call ws2 call LCD_WRITE_DATA incf PCLATH,F incfsz buffer2,F decf PCLATH,F decfsz buffer1,F goto char_loop return pix_table: ; retlw LOW(battery) ; retlw HIGH(battery) ; retlw LOW(solar) ; retlw HIGH(solar) ; retlw LOW(pwm) ; retlw HIGH(pwm) battery: dt 01110b, 11011b, 10001b, 10001b, 11111b, 11111b, 11111b, 11111b solar: dt 11111b, 10101b, 11111b, 10101b, 11111b, 10101b, 11111b, 00000b pwm: dt 11101b, 10101b, 10101b, 10101b, 10101b, 10101b, 10101b, 10111b gpsim-0.30.0/extras/lcd/examples/lcdmemtest.stc0000664000076400007640000000224413041763633016416 00000000000000# Script for testing modules processor p16f873 frequency 20000000 set verbose 0 load h lcdmemtest.hex set verbose 0 # load the gpsim module library. Not that this is a 'shared library'. # If the library fails to load then 1) it's not installed (try installing # gpsim) 2) or the path to library is not available (see the documentation # on modules). #module library libgpsim_lcd.so module library libgpsim_extras.so # display all of the modules that are in the library: # module list # load a specific module from the module library and give it a name module load lcd_display lcd1 # create nodes that can connect the Pic and the module. node E node RW node DC # Define the data bus nodes. # since we'll only use '4-bit' we won't need all 8 data lines # # node d0 # node d1 # node d2 # node d3 node n_d4 node n_d5 node n_d6 node n_d7 attach DC portc4 lcd1.DC attach E portc5 lcd1.E attach RW portc6 lcd1.RW # 4-bit mode - only the upper half of the n_data # bus needs to be connected. attach n_d4 portc0 lcd1.d4 attach n_d5 portc1 lcd1.d5 attach n_d6 portc2 lcd1.d6 attach n_d7 portc3 lcd1.d7 #node serial_in #load c serial.stimulus #attach serial_in portb6 rs232_stimulus gpsim-0.30.0/extras/lcd/examples/Makefile0000664000076400007640000000056313112633657015205 00000000000000EXTRA_DIST = MOSTLYCLEANFILES = *.o *.hex *.cod *.lst *.map *~ CLEANFILES = *.o *.hex *.cod *.lst *.map *~ DISTCLEANFILES = *.o *.hex *.cod *.lst *.map *~ MAINTAINERCLEANFILES = *.o *.hex *.cod *.lst *.map *~ .SUFFIXES: .o .asm .cod all: lcd_mod.cod lcd_917.cod lcd_916.cod %.cod: %.o gplink --map -o $@ $< %.o: %.asm gpasm -c $< clean: rm -f ${CLEANFILES} gpsim-0.30.0/extras/lcd/examples/README0000664000076400007640000000071313041763633014421 00000000000000LCD Example This is a full-blown example of an PIC LCD interface. It's here to illustrace the LCD module interface to gpsim. However, the code doesn't know it's running on a module! In other words, you can use this code in a real PIC driving a real LCD. --------- Building The Makefile in this directory is for the top level packager. So to "build" the project, do this: $ gpasm lcd_mod.asm This should assemble with no errors. $ gpsim -c lcd_mod.stc gpsim-0.30.0/extras/lcd/examples/lcd_mod20x4.stc0000664000076400007640000000230613041763633016273 00000000000000# Script for testing modules # # The purpose of this script is to load a simple # program for a PIC, load the gpsim module library, # and illustrate how modules can be connected to pics. set verbose 1 load s lcd_mod.cod set verbose 0 # load the gpsim module library. Not that this is a 'shared library'. # If the library fails to load then 1) it's not installed (try installing # gpsim) 2) or the path to library is not available (see the documentation # on modules). #module library libgpsim_lcd module library libgpsim_extras # display all of the modules that are in the library: # module list # load a specific module from the module library and give it a name module load lcd_20x4 lcd1 # create nodes that can connect the Pic and the module. node nE node nRW node nDC # Define the data bus nodes. # since we'll only use '4-bit' we won't need all 8 data lines # # node d0 # node d1 # node d2 # node d3 node n_d4 node n_d5 node n_d6 node n_d7 attach nE portb3 lcd1.E attach nRW portb2 lcd1.RW attach nDC portb1 lcd1.DC # 4-bit mode - only the upper half of the n_data # bus needs to be connected. attach n_d4 portb4 lcd1.d4 attach n_d5 portb5 lcd1.d5 attach n_d6 portb6 lcd1.d6 attach n_d7 portb7 lcd1.d7 gpsim-0.30.0/extras/lcd/examples/lcd.asm0000664000076400007640000002501613041763633015010 00000000000000;******************************************************************************** ; ; The file contains code to control an LCD module. ; ; T. Scott Dattalo ; ;******************************************************************************** ;******************************************************************* ; ; EQUates T0CKI equ H'0004' UF_SELECTED_FIELD equ 0x0f UF_SELECT_MODE equ 4 UF_EDIT_MODE equ 5 UF_ON_SELECTED_FIELD equ 6 UF_IS_EDITABLE equ 7 UF_SELECT_NEXT equ 0 UF_SELECT_PREV equ 1 ;******************************************************************* ; ;LCD_INITIALIZE ; Right now, the display could be either in 8-bit mode if we ; just powered up, or it could be in 4-bit mode if we just ; experienced a reset. So to begin, we have to initialize the ; display to a known state: the 8-bit mode. This is done by ; sending the LCD command "Function Set" with the 8-bit mode ; bit set. We need to do this 3 times! LCD_INITIALIZE ;Initialize the LCD_PORT control and data lines to outputs MOVLW ~LCD_CONTROL_MASK ANDWF LCD_CONTROL_PORT,F ;Clear the control lines BSF STATUS, RP0 ;Select Register page 1 ANDWF LCD_CONTROL_TRIS,F ;Make LCD_PORT IO lines outputs BCF STATUS, RP0 ;Select Register page 0 MOVLW ~LCD_DATA_MASK ANDWF LCD_DATA_PORT,F ;Clear the control lines BSF STATUS, RP0 ;Select Register page 1 ANDWF LCD_DATA_TRIS,F ;Make LCD_PORT IO lines outputs BCF STATUS, RP0 ;Select Register page 0 MOVLW 3 MOVWF LCD_init_loop ;Use temp as a loop counter BCF LCD_CONTROL_PORT, LCD_E BCF LCD_CONTROL_PORT, LCD_RS BCF LCD_CONTROL_PORT, LCD_R_W init_8bit: CALL LCD_DELAY MOVF LCD_DATA_PORT,W ANDLW ~LCD_DATA_MASK IORLW (LCD_CMD_FUNC_SET | LCD_8bit_MODE) >> LCD_DATA_SHIFT MOVWF LCD_DATA_PORT ;Put command on the bus GOTO $+1 BSF LCD_CONTROL_PORT, LCD_E ;Enable the LCD, i.e. write the command. GOTO $+1 ;NOP's are only needed for 20Mhz crystal GOTO $+1 BCF LCD_CONTROL_PORT, LCD_E ;Disable the LCD DECFSZ LCD_init_loop, F GOTO init_8bit ;We should now have the LCD module in 8-bit mode. Now let's put it in 4-bit mode CALL LCD_DELAY MOVF LCD_DATA_PORT,W ANDLW ~LCD_DATA_MASK IORLW (LCD_CMD_FUNC_SET | LCD_4bit_MODE) >> LCD_DATA_SHIFT MOVWF LCD_DATA_PORT ;Put command on the bus GOTO $+1 BSF LCD_CONTROL_PORT, LCD_E ;Enable the LCD, i.e. write the command. GOTO $+1 ;NOP's are only needed for 20Mhz crystal GOTO $+1 BCF LCD_CONTROL_PORT, LCD_E ;Disable the LCD CALL LCD_DELAY ;Now we are in 4-bit mode. This means that all reads and writes of bytes have to be done ;a nibble at a time. But that's all taken care of by the read/write functions. ;Set up the display to have 2 lines and the small (5x7 dot) font. MOVLW LCD_CMD_FUNC_SET | LCD_4bit_MODE | LCD_2_LINES | LCD_SMALL_FONT CALL LCD_WRITE_CMD ;Turn on the display and turn off the cursor. Set the cursor to the non-blink mode MOVLW LCD_CMD_DISPLAY_CTRL | LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINK_OFF CALL LCD_WRITE_CMD ;Clear the display memory. This command also moves the cursor to the home position. MOVLW LCD_CMD_CLEAR_DISPLAY CALL LCD_WRITE_CMD ;Set up the cursor mode. MOVLW LCD_CMD_ENTRY_MODE | LCD_INC_CURSOR_POS | LCD_NO_SCROLL CALL LCD_WRITE_CMD ;Set the Display Data RAM address to 0 MOVLW LCD_CMD_SET_DDRAM CALL LCD_WRITE_CMD CALL LCD_CLEAR_SCREEN RETURN ;******************************************************************* ;LCD_DELAY ; This routine takes the calculated times that the delay loop needs to ;be executed, based on the LCD_INIT_DELAY EQUate that includes the ;frequency of operation. ; LCD_DELAY MOVLW LCD_INIT_DELAY ; A_DELAY MOVWF tmp ; Use tmp and temp CLRF temp ; LOOP2 DECFSZ temp, F ; Delay time = tmp * ((3 * 256) + 3) * Tcy GOTO LOOP2 ; = tmp * 154.2 (20Mhz clock) DECFSZ tmp, F ; GOTO LOOP2 ; RETURN ;******************************************************************* ;LCD_TOGGLE_E ; This routine toggles the "E" bit (enable) on the LCD module. The contents ;of W contain the state of the R/W and RS bits along with the data that's ;to be written (that is if data is to be written). The contents of the LCD port ;while E is active are returned in W. LCD_TOGGLE_E BCF LCD_CONTROL_PORT,LCD_E ;Make sure E is low ; movlw 0 LTE1: GOTO $+1 ;Delays needed primarily for 10Mhz and faster clocks GOTO $+1 GOTO $+1 BTFSC LCD_CONTROL_PORT, LCD_E ;E is low the first time through the loop goto LTE2 BSF LCD_CONTROL_PORT, LCD_E ;Make E high and go through the loop again GOTO LTE1 LTE2: ; addlw 1 ; skpz ; goto LTE2 MOVF LCD_DATA_PORT, W ;Read the LCD Data bus ANDLW LCD_DATA_MASK ;We're only interested in the data lines BCF LCD_CONTROL_PORT, LCD_E ;Turn off E RETURN LCD_DROP_E BCF LCD_CONTROL_PORT,LCD_E ;Make sure E is low GOTO $+1 ;Delays needed primarily for 10Mhz and faster clocks GOTO $+1 GOTO $+1 GOTO $+1 RETURN LCD_RAISE_E BSF LCD_CONTROL_PORT,LCD_E ;Make sure E is high GOTO $+1 ;Delays needed primarily for 10Mhz and faster clocks GOTO $+1 GOTO $+1 GOTO $+1 RETURN ;******************************************************************* ;LCD_WRITE_DATA - Sends a character to LCD ; This routine splits the character into the upper and lower ;nibbles and sends them to the LCD, upper nibble first. ; ; Memory used: ; LCD_CHAR, ; Calls ; LCD_TOGGLE_E ; LCD_WRITE_DATA MOVWF LCD_CHAR ;Character to be sent is in W CALL LCD_BUSY_CHECK ;Wait for LCD to be ready BSF LCD_CONTROL_PORT,LCD_RS BCF LCD_CONTROL_PORT,LCD_R_W LCD_WRITE if LCD_DATA_MASK == 0x0f SWAPF LCD_CHAR,F endif ;First, write the upper nibble CALL LCD_RAISE_E MOVF LCD_CHAR, w ANDLW LCD_DATA_MASK MOVWF temp MOVF LCD_DATA_PORT,W ANDLW ~LCD_DATA_MASK IORWF temp,W MOVWF LCD_DATA_PORT ;CALL LCD_TOGGLE_E CALL LCD_DROP_E ;Next, write the lower nibble CALL LCD_RAISE_E SWAPF LCD_CHAR, w ANDLW LCD_DATA_MASK MOVWF temp MOVF LCD_DATA_PORT,W ANDLW ~LCD_DATA_MASK IORWF temp,W MOVWF LCD_DATA_PORT ;GOTO LCD_TOGGLE_E GOTO LCD_DROP_E ;******************************************************************* ;LCD_WRITE_CMD ; ; This routine splits the command into the upper and lower ;nibbles and sends them to the LCD, upper nibble first. LCD_WRITE_CMD MOVWF LCD_CHAR ;Character to be sent is in W CALL LCD_BUSY_CHECK ;Wait for LCD to be ready ;Both R_W and RS should be low BCF LCD_CONTROL_PORT,LCD_RS BCF LCD_CONTROL_PORT,LCD_R_W GOTO LCD_WRITE ;******************************************************************* ;LCD_READ_DATA ;This routine will read 8 bits of data from the LCD. Since we're using ;4-bit mode, two passes have to be made. On the first pass we read the ;upper nibble, and on the second the lower. ; LCD_READ_DATA CALL LCD_BUSY_CHECK ;For a data read, RS and R/W should be high BSF LCD_CONTROL_PORT,LCD_RS BSF LCD_CONTROL_PORT,LCD_R_W LCD_READ BSF STATUS, RP0 ;Select Register page 1 MOVF LCD_DATA_TRIS,W ;Get the current setting for the whole register IORLW LCD_DATA_MASK ;Set the TRIS bits- make all of the data MOVWF LCD_DATA_TRIS ; lines inputs. BCF STATUS, RP0 ;Select Register page 0 CALL LCD_TOGGLE_E ;Toggle E and read upper nibble MOVWF tmp ;Save the upper nibble CALL LCD_TOGGLE_E ;Toggle E and read lower nibble MOVWF temp ;Save the lower nibble SWAPF temp, W ;Put the lower nibble of data in lower half of W IORWF tmp, F ;Combine nibbles BSF STATUS, RP0 ;Select Register page 1 MOVLW ~LCD_DATA_MASK ;Clear the TRIS bits- make all of the data ANDWF LCD_DATA_TRIS,F ; lines outputs. BCF STATUS, RP0 ;Select Register page 0 MOVF tmp,W if LCD_DATA_MASK == 0x0f SWAPF tmp,W endif RETURN ;******************************************************************* ;LCD_BUSY_CHECK ;This routine checks the busy flag, returns when not busy LCD_BUSY_CHECK ;For a busy check, RS is low and R/W is high BCF LCD_CONTROL_PORT,LCD_RS BSF LCD_CONTROL_PORT,LCD_R_W CALL LCD_READ ANDLW 0x80 ;Check busy flag, high = busy SKPNZ RETURN MOVLW 5 CALL A_DELAY GOTO LCD_BUSY_CHECK ;If busy, check again ;******************************************************************* ;LCD_CLEAR_SCREEN LCD_CLEAR_SCREEN MOVLW 20-1 MOVWF buffer0 MOVLW LCD_CMD_SET_DDRAM | SCR_ROW0 | SCR_COL0 lcs1: CALL LCD_WRITE_CMD lcs2: MOVLW 0x20 ;ASCII space CALL LCD_WRITE_DATA DECF buffer0,W MOVWF buffer0 BTFSS buffer0,6 ;See if we generated a borrow goto lcs2 BTFSS buffer0,7 ;First time through, borrow should be in 7 too RETURN MOVLW 20-1 + 0x80 ;Reload count and set bit 7 (borrow will clear it) MOVWF buffer0 MOVLW LCD_CMD_SET_DDRAM | SCR_ROW1 | SCR_COL0 GOTO lcs1 gpsim-0.30.0/extras/lcd/examples/lcd.inc0000664000076400007640000000721513041763633015002 00000000000000 ;******************************************************************* ; ; LCD ; The information for the LCD software comes from several places: Microchip's AN587, ; Optrex Data Book, Christopher J. Burian's LCD Technical FAQ, and Peer Ouwehand's "How to ; Control HD44780-based Character-LCD". ; ; Microchip can be reached at ; http://www.ultranet.com/biz/mchip/ ; Burian's FAQ is located at ; http://www.paranoia.com/~filipg/HTML/LINK/F_LCD_tech.html ; Ouwehand's document is located at ; http://www.iaehv.nl/users/pouweha/lcd.htm ; ;******************************************************************* Dev_Tcyc EQU 400 ;Tcyc = 400 ns, Instruction Cycle time Inner_delay EQU (256*3 + 3)*Dev_Tcyc ;The amount of time spent in inner delay loop LCD_INIT_DELAY EQU 15000000/Inner_delay ;15ms LCD_CONTROL_PORT EQU PORTB ;LCD control lines interface to PORTB LCD_DATA_PORT EQU PORTB ;PORTB<7:4> == LCD_DB<7:4> (4 bit mode) LCD_E EQU 3 ;PORTB<1> == LCD Enable control line LCD_Eb EQU (1< == LCD Read/Write control line LCD_RS EQU 1 ;PORTB<3> == LCD Register Select control line LCD_CONTROL_MASK EQU (1< include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;& _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F917. ;; Specifically, the a/d converter is tested. errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- INT_VAR IDATA 0x20 zero DW 0x1f one DW 0x06 two DW 0x5b three DW 0x4f GPR_DATA UDATA_SHR 0x70 x RES 1 t1 RES 1 t2 RES 1 avg_lo RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 eerom_cnt RES 1 adr_cnt RES 1 data_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp bcf STATUS,RP0 ;adcon0 is in bank 0 btfsc PIR1,EEIF goto ee_int btfsc INTCON,ADIE btfsc PIR1,ADIF goto check .assert "\"FAILED 16F917 unexpected interrupt\"" nop ;; An A/D interrupt has occurred check: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt exit_int swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f917.xpos = 120" .sim "p16f917.ypos = 36" .sim "module library libgpsim_modules" .sim "module library libgpsim_extras" .sim "module load lcd_7seg lcd1" .sim "lcd1.xpos = 300" .sim "lcd1.ypos = 108" .sim "module load lcd_7seg lcd2" .sim "lcd2.xpos = 300" .sim "lcd2.ypos = 276" .sim "module load pullup V1" .sim "V1.voltage = 1.0" .sim "V1.resistance = 1000.0" .sim "V1.xpos = 84" .sim "V1.ypos = 420" .sim "module load pullup V2" .sim "V2.voltage = 2.0" .sim "V2.resistance = 1000.0" .sim "V2.xpos = 84" .sim "V2.ypos = 372" .sim "module load pullup V3" .sim "V3.voltage = 3.0" .sim "V3.resistance = 1000.0" .sim "V3.xpos = 84" .sim "V3.ypos = 324" .sim "node vlcd3 vlcd2 vlcd1" .sim "attach vlcd3 V3.pin portc2" .sim "attach vlcd2 V2.pin portc1" .sim "attach vlcd1 V1.pin portc0" .sim "node Com0 Com1 nSeg0 nSeg1 nSeg2 nSeg3 nSeg4 nSeg5 nSeg6" .sim "attach Com0 lcd1.cc portb4 " .sim "attach Com1 lcd2.cc portb5 " .sim "attach nSeg0 lcd1.seg0 lcd2.seg0 portb0" .sim "attach nSeg1 lcd1.seg1 lcd2.seg1 portb1" .sim "attach nSeg2 lcd1.seg2 lcd2.seg2 portb2" .sim "attach nSeg3 lcd1.seg3 lcd2.seg3 portb3" .sim "attach nSeg4 lcd1.seg4 lcd2.seg4 porta4" .sim "attach nSeg5 lcd1.seg5 lcd2.seg5 porta5" .sim "attach nSeg6 lcd1.seg6 lcd2.seg6 portc3" .sim "scope.ch0 = \"portb4\"" .sim "scope.ch1 = \"portb0\"" BANKSEL WPUB clrf WPUB BANKSEL OSCCON bsf OSCCON,IRCF0 ; 8Mhz RC clock BANKSEL LCDSE0 bcf LCDCON,VLCDEN bsf LCDCON,VLCDEN movlw 0x7f movwf LCDSE0 bsf LCDPS,LP1 ; LPx = 2 ; movlw (1<> 6 ;The program divides the shifting as follows so that carries are automatically ;taken care of: ; d = (h + (h + (h>>3)) >> 1) >> 2 ; ;Inputs: W - should contain 'h', the hexadecimal value to be scaled ;Outputs: W - The scaled hexadecimal value is returned in W ;Memory: temp ;Calls: none scale_hex2dec ifdef __scale_hex2dec__ MOVWF temp ;Hex value is in W. CLRC ;Clear the Carry bit so it doesn't affect RRF RRF temp,F CLRC RRF temp,F CLRC RRF temp,F ;temp = h>>3 ADDWF temp,F ;temp = h + (h>>3) RRF temp,F ;temp = (h + (h>>3)) >> 1 ADDWF temp,F ;temp = h + ((h + (h>>3)) >> 1) RRF temp,F CLRC RRF temp,W ;d = W = (h + (h + (h>>3)) >> 1) >> 2 endif RETURN ;******************************************************************* ;write_word_as_hex ; The purpose of this routine is to convert the word pointed to by W to a ;4 digit ASCII string representing the hexadecimal value of the word. ;Note, words are stored in RAM with the least significant byte first. ; ; Memory used ; buffer2 ; Calls ; write_byte_as_hex ; write_word_as_hex ifdef __write_word_as_hex__ ifndef __write_byte_as_hex__ #define __write_byte_as_hex__ 1 endif MOVWF FSR ;W points to the word MOVWF buffer2 ;Save a copy of the pointer INCF FSR, F ;Point to the MSB MOVF INDF,W ;Get the MSB CALL write_byte_as_hex ;And print it. MOVF buffer2,W ;Get pointer to the word. MOVWF FSR ;W now points to the LSB MOVF INDF,W ;Get the LSB goto write_byte_as_hex ;And print it. else RETURN endif ;******************************************************************* ;write_byte_as_hex ; ; The purpose of this routine is to convert the byte in W to a 2 digit ;ASCII string representing the hexadecimal value of the byte. For example, ;0xf9 is converted to 0x45 0x39. The ASCII digits are then written to the ;LCD module. ; ; Memory used ; buffer0, string_number ; Calls ; LCD_WRITE_DATA ; write_byte_as_hex ifdef __write_byte_as_hex__ CLRF buffer0 ;Used as temporary storage to keep track of loop count MOVWF buffer1 ;Save byte to be written here wbah1: SWAPF buffer1,W ;Write the high nibble first. ANDLW 0x0f ;Get the lower nibble of W ADDLW -0xa ;If it is >= 0xa, then BTFSC STATUS, C ; the carry will get set. ADDLW 'A'-'9' - 1 ;The digit is between 0xa and 0xf ADDLW '9'+ 1 ;Convert it to ASCII CALL LCD_WRITE_DATA BTFSC buffer0,1 ;This bit is clear the first time through the loop. RETURN SWAPF buffer1,F ;Get the low nibble BSF buffer0,1 ;Set so next time through we will return. goto wbah1 else RETURN endif ;******************************************************************* ;write_byte_as_dec ; ; The purpose of this routine is to convert a byte to a 3 digit ASCII string ;representing the decimal value of the byte. For example, 0xff = 255 is converted ;to 0x32 0x35 0x35. ; ; Memory used ; buffer0 - buffer5 ; Calls ; BCD_2_ASCII, BCD_adjust ; write_byte_as_dec BCF STATUS,C ;Clear the carry so the first shift is not corrupted CLRF buffer0 CLRF buffer1 CLRF buffer2 CLRF buffer3 MOVWF buffer4 ;Save copy of input MOVLW 6 ; MOVWF buffer5 ;Number of times we'll loop. RLF buffer4,F ;The first two shifts do not need BCD adjusting RLF buffer1,F RLF buffer4,F RLF buffer1,F wbad1 RLF buffer4,F RLF buffer1,F RLF buffer0,F DECFSZ buffer5,F goto wbad2 MOVLW buffer1+1 MOVWF FSR MOVF buffer1,W CALL BCD_2_ASCII MOVLW '0' ADDWF buffer0,F GOTO write_buffer wbad2 MOVLW buffer1 CALL BCD_adjust GOTO wbad1 ;******************************************************************* ;BCD_2_ASCII ; ; The purpose of this routine is to convert the BCD byte in W into two ASCII bytes. The ; ASCII data is written to the indirect address contained in FSR. ; ; Memory used ; temp ; Calls ; none ; Inputs ; W = BCD data ; FSR = points to where ASCII data is to be written ; BCD_2_ASCII MOVWF temp ANDLW 0x0f ADDLW '0' MOVWF INDF DECF FSR,F SWAPF temp,W ANDLW 0x0f ADDLW '0' MOVWF INDF RETURN ;******************************************************************* ;write_word_as_dec ; ; Memory used ; buffer0 - buffer5 ; Calls ; BCD_2_ASCII, BCD_adjust ; Inputs ; FSR = pointer to the word to be written ; write_word_as_dec CLRF buffer0 CLRF buffer1 CLRF buffer2 MOVWF FSR ;Save copy of input MOVF INDF,W ;Get the Least significant Byte MOVWF buffer3 INCF FSR,F MOVF INDF,W ;Get the MSB MOVWF buffer4 MOVLW 14 ; MOVWF buffer5 ;Number of times we'll loop. BCF STATUS,C ;Clear the carry so the first shift is not corrupted RLF buffer3,F ;The first two shifts do not need BCD adjusting RLF buffer4,F RLF buffer2,F RLF buffer3,F RLF buffer4,F RLF buffer2,F wwad1 RLF buffer3,F RLF buffer4,F RLF buffer2,F RLF buffer1,F RLF buffer0,F DECFSZ buffer5,F goto wwad2 MOVLW buffer3+1 MOVWF FSR MOVF buffer2,W CALL BCD_2_ASCII MOVLW buffer1+1 MOVWF FSR MOVF buffer1,W CALL BCD_2_ASCII MOVLW '0' ADDWF buffer0,F GOTO write_buffer wwad2 MOVLW buffer2 CALL BCD_adjust MOVLW buffer1 CALL BCD_adjust GOTO wwad1 ;******************************************************************* ;BCD_adjust ; ; This routine will 'adjust' the byte that W points to to BCD. The ;algorithm is based on converting hexadecimal into decimal. Normally, to ;convert a hex digit (i.e. a nibble) to binary coded decimal, you add ;6 to it if it is greater than or equal 0xa. So, 0x0 through 0x9 convert ;to 0 through 9 while 0xa through 0xf convert to 0x10 through 0x15. ;Now, this routine adds 3 instead of 6. Also, instead of checking ;to see if the digit is >= 0xa, this routine checks for > 0x7. However, ;the caller will perform a left shift after calling this routine. Thus, ;the 3 is multiplyed by two to get 6. BCD_adjust MOVWF FSR MOVLW 0x03 ADDWF INDF,F BTFSS INDF,3 SUBWF INDF,F MOVLW 0x30 ADDWF INDF,F BTFSS INDF,7 SUBWF INDF,F RETURN ;******************************************************************* ;write_buffer ; ; The purpose of this routine is to display the contents of 'buffer' on ;the LCD module. buffer0 is the first element of the string. The string ;is assumed to be zero terminated. If it isn't, then the whole buffer will ;get displayed. (Note, there's a check to insure that no more than 'buffer' ;is written.) ; ; Memory used ; buffer0 ; Calls ; LCD_WRITE_DATA ; write_buffer MOVLW buffer0 ;Get a pointer to the first buffer location MOVWF FSR ; wb1: MOVF INDF,W ;Get a byte from the buffer BTFSC STATUS,Z ;If it is zero, then that's the last byte RETURN CALL LCD_WRITE_DATA ; INCF FSR,F ;Point to the next buffer entry MOVF FSR,W ; SUBLW buffer7 ;If we're pointing to the last buffer entry BTFSS STATUS,Z ;then we need to quit writing. goto wb1 RETURN ;******************************************************************* ;write_string ; ; The purpose of this routine is to display a string on the LCD module. ;On entry, W contains the string number to be displayed. The current cursor ;location is the destination of the output. ; This routine can be located anywhere in the code space and may be ;larger than 256 bytes. ; ; psuedo code: ; ; char *string0 = "foo"; ; char *string1 = "bar"; ; ; char *strings[] = { string0, string1}; ; char num_strings = sizeof(strings)/sizeof(char *); ; ; void write_string(char string_num) ; { ; char *str; ; ; str = strings[string_num % num_strings]; ; ; for( ; *str; str++) ; LCD_WRITE_DATA(*str); ; ; } ; ; Memory used ; buffer2, buffer3 ; Calls ; LCD_WRITE_DATA ; Inputs ; W = String Number ; write_string andlw WS_TABLE_MASK ;Make sure the string is in range movwf buffer3 ;Used as an index into the string table addwf buffer3,w ;to get the string offset ; addlw LOW(ws_table) ;First, get a pointer to the string movwf buffer3 ; ; movlw HIGH(ws_table) ; skpnc ; movlw HIGH(ws_table)+1 ; movwf PCLATH movf buffer3,w call ws2 ;First call is to get string offset in table movwf buffer2 incf PCLATH,f incfsz buffer3,w decf PCLATH,f call ws2 ;get the high word (of the offset) movwf PCLATH ; ws1: ;Now loop through the string movf buffer2,w call ws2 andlw 0xff skpnz ;If the returned byte is zero, return ; we've reached the end call LCD_WRITE_DATA incf PCLATH,f ;Point to the next character in the string incfsz buffer2,f decf PCLATH,f goto ws1 ws2 movwf PCL WS_TABLE_MASK equ 3 ; This should equal 2^number of strings ; The first part of the table contains pointers to the start of the ; strings. Note that each string has a two word pointer for the low ; and high bytes. ws_table: retlw LOW(string0) retlw HIGH(string0) retlw LOW(string1) retlw HIGH(string1) retlw LOW(string2) retlw HIGH(string2) retlw LOW(string3) retlw HIGH(string3) string0: dt "GPSIM WROTE THIS",0 string1: dt "A STRING ON ROW 2 ", 8 ,0 string2: dt "If we have row 3 ", 9, 0 string3: dt "and row 4 ", 2 ,0 gpsim-0.30.0/extras/lcd/examples/lcd_916.asm0000664000076400007640000001266613116670055015414 00000000000000 list p=16f916 include include __CONFIG _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;& _MCLRE_OFF ;; The purpose of this program is to test gpsim's ability to ;; simulate a pic 16F916. ;; Specifically, the LCD type B drive errorlevel -302 ; Printf Command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ;---------------------------------------------------------------------- INT_VAR IDATA 0x20 zero DW 0x1f one DW 0x06 two DW 0x5b three DW 0x4f GPR_DATA UDATA_SHR 0x70 x RES 1 t1 RES 1 t2 RES 1 digit1 RES 1 avg_hi RES 1 w_temp RES 1 status_temp RES 1 eerom_cnt RES 1 adr_cnt RES 1 lcd_cnt RES 1 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program INT_VECTOR CODE 0x004 ; interrupt vector location ;; ;; Interrupt ;; movwf w_temp swapf STATUS,W movwf status_temp BANKSEL PIR1 btfsc PIR1,EEIF goto ee_int btfsc INTCON,ADIE btfsc PIR1,ADIF goto ad_int btfsc PIR2,LCDIF goto lcd_int btfsc PIR1,TMR1IF goto tmr1_int .assert "\"FAILED 16F916 unexpected interrupt\"" nop goto exit_int lcd_int: bcf PIR2,LCDIF incf lcd_cnt,F goto exit_int tmr1_int: bcf PIR1,TMR1IF BANKSEL TMR1H movlw 0xfc movwf TMR1H goto exit_int ;; An A/D interrupt has occurred ad_int: bsf t1,0 ;Set a flag to indicate we got the int. bcf PIR1,ADIF ;Clear the a/d interrupt exit_int swapf status_temp,w movwf STATUS swapf w_temp,F swapf w_temp,W retfie ; Interrupt from eerom ee_int incf eerom_cnt,F bcf PIR1,EEIF goto exit_int ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start: .sim "p16f916.xpos = 120" .sim "p16f916.ypos = 36" .sim "module library libgpsim_modules" .sim "module library libgpsim_extras" .sim "module load lcd_7seg lcd1" .sim "lcd1.xpos = 300" .sim "lcd1.ypos = 108" .sim "module load lcd_7seg lcd2" .sim "lcd2.xpos = 300" .sim "lcd2.ypos = 276" .sim "module load pullup V1" .sim "V1.voltage = 1.0" .sim "V1.resistance = 1000.0" .sim "V1.xpos = 84" .sim "V1.ypos = 420" .sim "module load pullup V2" .sim "V2.voltage = 2.0" .sim "V2.resistance = 1000.0" .sim "V2.xpos = 84" .sim "V2.ypos = 372" .sim "module load pullup V3" .sim "V3.voltage = 3.0" .sim "V3.resistance = 1000.0" .sim "V3.xpos = 84" .sim "V3.ypos = 324" .sim "node vlcd3 vlcd2 vlcd1" .sim "attach vlcd3 V3.pin portc2" .sim "attach vlcd2 V2.pin portc1" .sim "attach vlcd1 V1.pin portc0" .sim "node Com0 Com1 nSeg0 nSeg1 nSeg2 nSeg3 nSeg4 nSeg5 nSeg6" .sim "attach Com0 lcd1.cc portb4 " .sim "attach Com1 lcd2.cc portb5 " .sim "attach nSeg0 lcd1.seg0 lcd2.seg0 portb0" .sim "attach nSeg1 lcd1.seg1 lcd2.seg1 portb1" .sim "attach nSeg2 lcd1.seg2 lcd2.seg2 portb2" .sim "attach nSeg3 lcd1.seg3 lcd2.seg3 portb3" .sim "attach nSeg4 lcd1.seg4 lcd2.seg4 porta4" .sim "attach nSeg5 lcd1.seg5 lcd2.seg5 porta5" .sim "attach nSeg6 lcd1.seg6 lcd2.seg6 portc3" .sim "scope.ch0 = \"portb4\"" .sim "scope.ch1 = \"portb0\"" BANKSEL WPUB clrf WPUB BANKSEL OSCCON bsf OSCCON,IRCF0 ; 8Mhz RC clock movlw (1< #include "lcd.h" #include "lcdfont.h" #include "hd44780.h" cairo_surface_t *LcdFont::create_image(LcdDisplay *lcdP, _5X8 *ch) { int rows = 6 + lcdP->dots.y * lcdP->pixels.y; int cols = 1 + lcdP->dots.x * lcdP->pixels.x; cairo_surface_t *image = gdk_window_create_similar_surface(mywindow, CAIRO_CONTENT_COLOR_ALPHA, cols, rows); cairo_t *cr = cairo_create(image); cairo_set_line_width(cr, .5); for (int j = 0; j < lcdP->dots.y; j++) { for (int i = 0; i < lcdP->dots.x; i++) { if (ch[0][j][i] == '.') { double y = 5 + lcdP->pixels.y * j; double x = i * lcdP->pixels.x; cairo_set_source_rgb(cr, double(0x11) / 255, double(0x33) / 255, double(0x11)/255); cairo_rectangle(cr, x, y, lcdP->pixels.x, lcdP->pixels.y); cairo_fill_preserve(cr); cairo_set_source_rgb(cr, double(0x66) / 255, double(0x88) / 255, double(0x66)/255); cairo_stroke(cr); } } } cairo_destroy(cr); return image; } /*************************************************************** * CreateFont * Here we read the lcdfont.h file and build LCD character * pixmaps. * */ LcdFont::LcdFont(gint characters, GtkWidget *parent_window, LcdDisplay *lcdP) { pixmaps.reserve(characters); mywindow = gtk_widget_get_window(parent_window); for (gint i = 0; i < characters; i++) { if (strlen(test[i][0]) < 5) pixmaps.push_back(NULL); else pixmaps.push_back(create_image(lcdP, &test[i])); } } LcdFont::~LcdFont() { for (size_t i = 0; i < pixmaps.size(); ++i) { if (pixmaps[i]) { cairo_surface_destroy(pixmaps[i]); } } } void LcdFont::update_pixmap(int pos, _5X8 *tempchar, LcdDisplay *lcdP) { if (pixmaps[pos]) { cairo_surface_destroy(pixmaps[pos]); pixmaps[pos] = NULL; } pixmaps[pos] = create_image(lcdP, tempchar); } cairo_surface_t *LcdFont::getPixMap(unsigned int index) { return ( (index < pixmaps.size()) && pixmaps[index]) ? pixmaps[index] : pixmaps[0]; } void LcdDisplay::update_cgram_pixmaps() { int i, j, k; _5X8 tempchar; if (fontP == NULL) return; for (i = 0; i < CGRAM_SIZE / 8; i++) { for (j = 0; j < 8; j++) { for (k = 0; k < 5; k++) { if (m_hd44780->getCGRam(8 * i + j) & (1 << (4 - k))) tempchar[j][k] = '.'; else tempchar[j][k] = ' '; } tempchar[j][5] = 0; } fontP->update_pixmap(i, &tempchar, this); fontP->update_pixmap(i+8, &tempchar, this); } m_hd44780->setCGRamupdate(false); } cairo_surface_t *LcdDisplay::get_pixmap(gint row, gint col) { if (m_hd44780->CGRamupdate()) update_cgram_pixmaps(); return fontP ? fontP->getPixMap(m_hd44780->getDDRam(row,col)) : 0; } static gboolean lcd_expose_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) { LcdDisplay *lcdP = static_cast(user_data); // If there is no font, then go create it. if (!lcdP->fontP) { lcdP->fontP = new LcdFont(FONT_LEN, widget, lcdP); } GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); lcdP->w_width = allocation.width; lcdP->w_height = allocation.height; cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); lcdP->update(cr); cairo_destroy(cr); return FALSE; } void LcdDisplay::update(cairo_t *cr) { guint i,j; cairo_set_source_rgb(cr, double(0x78) / 255, double(0xa8) / 255, double(0x78) / 255); cairo_rectangle(cr, 0.0, 0.0, w_width, w_height); cairo_fill(cr); gint cw = get_char_width(); gint ch = get_char_height(); gint border = get_border(); if (!(disp_type & TWO_ROWS_IN_ONE)) { for(j=0; jtype == GDK_BUTTON_PRESS) && ((event->button.button == 1) || (event->button.button == 3))) { return TRUE; } return FALSE; } /********************************************************** * * */ void LcdDisplay::CreateGraphics() { window = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (window) { char title[128]; gtk_window_set_wmclass(GTK_WINDOW(window),type(),"Gpsim"); g_snprintf(title, sizeof(title), "%d X %d", rows, cols); if (disp_type & TWO_ROWS_IN_ONE) g_strlcat(title, " (in one row)", sizeof(title)); gtk_widget_realize (window); gtk_window_set_title(GTK_WINDOW(window), "LCD"); GtkWidget *main_vbox = gtk_vbox_new (FALSE, 5); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0); gtk_container_add (GTK_CONTAINER (window), main_vbox); GtkWidget *vbox = gtk_widget_new (gtk_vbox_get_type (), "GtkBox::homogeneous", FALSE, //"GtkBox::spacing", 5, //"GtkContainer::border_width", 10, "GtkWidget::parent", main_vbox, "GtkWidget::visible", TRUE, NULL); GtkWidget *frame = gtk_widget_new (gtk_frame_get_type (), "GtkFrame::shadow", GTK_SHADOW_ETCHED_IN, "GtkFrame::label_xalign", 0.5, "GtkFrame::label", title, //"GtkContainer::border_width", 10, "GtkWidget::parent", vbox, "GtkWidget::visible", TRUE, NULL); darea = gtk_drawing_area_new (); if (!(disp_type & TWO_ROWS_IN_ONE)) { gtk_widget_set_size_request(darea, cols*get_char_width()+2*get_border(), rows*(get_char_height()+get_border())+get_border()); } else { gtk_widget_set_size_request(darea, rows*cols*get_char_width()+2*get_border(), get_char_height()+2*get_border()); } gtk_container_add (GTK_CONTAINER (frame), darea); g_signal_connect (darea, "expose_event", G_CALLBACK (lcd_expose_event), this); gtk_widget_add_events(darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); g_signal_connect (darea, "button_press_event", G_CALLBACK (cursor_event), NULL); gtk_widget_show_all (window); } } #endif //HAVE_GUI gpsim-0.30.0/extras/lcd/hd44780.h0000664000076400007640000001051613041763633013100 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __HD44780_H__ #define __HD44780_H__ #include //======================================================================== // class HD44780Busy; class HD44780 { enum { eDC = 1, eRW = 2, eE = 4, }; enum eControlStates { eDataRead = eDC | eRW, eDataWrite = eDC, eCommandRead = eRW, eCommandWrite = 0 //DC and RW low }; enum eChipStates { ePowerON, eInitialized, eCommandPH0, eStatusRead, eDatabusRead, }; public: HD44780(); ~HD44780(); void setDC(bool); void setE(bool); void setRW(bool); void driveDataBus(unsigned int); bool dataBusDirection(); unsigned int getDataBus(); void storeData(); void advanceColumnAddress(); void executeCommand(); unsigned int getData(); unsigned int getStatus(); // void advanceState(eControlStates newControlState); void set8bitMode() { m_bBitMode = true;}; void set4bitMode() { m_bBitMode = false; } void set2LineMode() { m_bLineMode = true; } void set1LineMode() { m_bLineMode = false;} void setLargeFontMode() { m_bFontMode = true; } void setSmallFontMode() { m_bFontMode = false; } void setDisplayOn() { m_bDisplayOn = true;} void setDisplayOff() { m_bDisplayOn = false;} void setBlinkOn() { m_bCursorBlink = true; } void setBlinkOff() { m_bCursorBlink = false;} void setCursorOn() { m_bCursorOn = true; } void setCursorOff() { m_bCursorOn = false; } bool b8BitMode() {return m_bBitMode; } bool b4BitMode() {return !m_bBitMode; } bool b2LineMode() {return m_bLineMode; } bool b1LineMode() {return !m_bLineMode; } bool bLargeFontMode() {return m_bFontMode; } bool bSmallFontMode() {return !m_bFontMode; } bool bDisplayOn() {return m_bDisplayOn; } bool bDisplayOff() {return !m_bDisplayOn; } bool CGRamupdate() {return m_CGRamupdate;} void setCGRamupdate(bool state) { m_CGRamupdate = state;} // Memory in a HD44780U 128 bytes of display RAM, // and 64 bytes of character RAM #define DDRAM_SIZE 0x80 #define DDRAM_MASK (DDRAM_SIZE - 1) #define CGRAM_ADDR_BITS 6 #define CGRAM_SIZE (1 << CGRAM_ADDR_BITS) #define CGRAM_MASK (CGRAM_SIZE - 1) unsigned char getDDRam(unsigned int r, unsigned int c); unsigned char getCGRam(unsigned int i) {return i < CGRAM_SIZE ? m_CGRam[i] : 0; } void writeCGRamAddress(int addr); void writeDDRamAddress(int addr); void clearDisplay(); void test(); protected: unsigned int dataPhase(unsigned int); bool phasedDataWrite(unsigned int &data); private: //Data /// I/O pin interface bool m_bE; unsigned int m_controlState; eChipStates m_chipState; unsigned int m_dataBus; // Data placed onto the I/O pins unsigned int m_phasedData; // Data constructed during 4-bit mode. /// Various modes bool m_bBitMode; // true == 8-bit mode, false == 4-bit mode bool m_bLineMode; // true == 2-line mode, false == 1-line mode bool m_bFontMode; // true == Large Font, false == small font bool m_bDisplayOn; bool m_bCursorBlink; bool m_bCursorOn; /// Data phase /// In 4-bit mode, data reads and writes happen in 2 phases /// m_bDataPhase is true if this is the first phase, false for the second. bool m_bDataBusPhase; HD44780Busy *m_busyTimer; /// Display Data RAM unsigned char m_DDRam[DDRAM_SIZE]; unsigned char m_DDRamAdd; /// Character Generator RAM unsigned char m_CGRam[CGRAM_SIZE]; unsigned char m_CGRamAdd; bool m_bInCGRam; // true when a write to CGRAM is selected bool m_CGRamupdate; int row_offset[4]; // support up to 4 rows /// Debug void debugChipState(const char *); }; #endif // __HD44780_H__ gpsim-0.30.0/extras/lcd/NEWS0000664000076400007640000000002413041763633012415 00000000000000No news is good newsgpsim-0.30.0/extras/lcd/lcdfont.inc0000664000076400007640000002444513041763633014057 00000000000000 ;; ;; LCD Font file for 7x5 characters ;; Automatically created from a perl script ;; T. Scott Dattalo http://www.dattalo.com/gnupic/lcd.html ;; dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 0 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 1 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 2 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 3 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 4 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 5 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 6 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 7 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 8 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 9 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 10 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 11 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 12 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 13 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 14 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 15 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 16 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 17 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 18 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 19 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 20 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 21 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 22 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 23 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 24 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 25 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 26 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 27 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 28 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 29 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 30 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 31 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 32 dt 0x00, 0x00, 0x7d, 0x00, 0x00 ; 33 dt 0x00, 0x70, 0x00, 0x70, 0x00 ; 34 dt 0x14, 0x7f, 0x14, 0x7f, 0x14 ; 35 dt 0x12, 0x2a, 0x7f, 0x2a, 0x24 ; 36 dt 0x62, 0x64, 0x08, 0x13, 0x23 ; 37 dt 0x36, 0x49, 0x55, 0x22, 0x05 ; 38 dt 0x00, 0x50, 0x60, 0x00, 0x00 ; 39 dt 0x00, 0x1c, 0x22, 0x41, 0x00 ; 40 dt 0x00, 0x41, 0x22, 0x1c, 0x00 ; 41 dt 0x14, 0x08, 0x3e, 0x08, 0x14 ; 42 dt 0x08, 0x08, 0x3e, 0x08, 0x08 ; 43 dt 0x00, 0x05, 0x06, 0x00, 0x00 ; 44 dt 0x08, 0x08, 0x08, 0x08, 0x08 ; 45 dt 0x00, 0x03, 0x03, 0x00, 0x00 ; 46 dt 0x02, 0x04, 0x08, 0x10, 0x20 ; 47 dt 0x3e, 0x45, 0x49, 0x51, 0x3e ; 48 dt 0x00, 0x21, 0x7f, 0x01, 0x00 ; 49 dt 0x21, 0x43, 0x45, 0x49, 0x31 ; 50 dt 0x42, 0x41, 0x51, 0x69, 0x46 ; 51 dt 0x0c, 0x14, 0x24, 0x7f, 0x04 ; 52 dt 0x72, 0x51, 0x51, 0x51, 0x4e ; 53 dt 0x1e, 0x29, 0x49, 0x49, 0x06 ; 54 dt 0x40, 0x47, 0x48, 0x50, 0x60 ; 55 dt 0x36, 0x49, 0x49, 0x49, 0x36 ; 56 dt 0x30, 0x49, 0x49, 0x4a, 0x3c ; 57 dt 0x00, 0x36, 0x36, 0x00, 0x00 ; 58 dt 0x00, 0x35, 0x36, 0x00, 0x00 ; 59 dt 0x08, 0x14, 0x22, 0x41, 0x00 ; 60 dt 0x14, 0x14, 0x14, 0x14, 0x14 ; 61 dt 0x41, 0x22, 0x14, 0x08, 0x00 ; 62 dt 0x20, 0x40, 0x45, 0x48, 0x30 ; 63 dt 0x26, 0x49, 0x4f, 0x41, 0x3e ; 64 dt 0x3f, 0x44, 0x44, 0x44, 0x3f ; 65 dt 0x7f, 0x49, 0x49, 0x49, 0x36 ; 66 dt 0x3e, 0x41, 0x41, 0x41, 0x22 ; 67 dt 0x7f, 0x41, 0x41, 0x41, 0x3e ; 68 dt 0x7f, 0x49, 0x49, 0x49, 0x41 ; 69 dt 0x7f, 0x48, 0x48, 0x48, 0x40 ; 70 dt 0x3e, 0x41, 0x49, 0x49, 0x2f ; 71 dt 0x7f, 0x08, 0x08, 0x08, 0x7f ; 72 dt 0x00, 0x41, 0x7f, 0x41, 0x00 ; 73 dt 0x02, 0x01, 0x41, 0x7e, 0x40 ; 74 dt 0x7f, 0x08, 0x14, 0x22, 0x41 ; 75 dt 0x7f, 0x01, 0x01, 0x01, 0x01 ; 76 dt 0x7f, 0x40, 0x20, 0x40, 0x7f ; 77 dt 0x7f, 0x10, 0x08, 0x04, 0x7f ; 78 dt 0x3e, 0x41, 0x41, 0x41, 0x3e ; 79 dt 0x7f, 0x48, 0x48, 0x48, 0x30 ; 80 dt 0x3e, 0x41, 0x45, 0x42, 0x3d ; 81 dt 0x7f, 0x48, 0x4c, 0x4a, 0x31 ; 82 dt 0x31, 0x49, 0x49, 0x49, 0x46 ; 83 dt 0x40, 0x40, 0x7f, 0x40, 0x40 ; 84 dt 0x7e, 0x01, 0x01, 0x01, 0x7e ; 85 dt 0x7c, 0x02, 0x01, 0x02, 0x7c ; 86 dt 0x7e, 0x01, 0x0e, 0x01, 0x7e ; 87 dt 0x63, 0x14, 0x08, 0x14, 0x63 ; 88 dt 0x70, 0x08, 0x07, 0x08, 0x70 ; 89 dt 0x43, 0x45, 0x49, 0x51, 0x61 ; 90 dt 0x00, 0x7f, 0x41, 0x41, 0x00 ; 91 dt 0x54, 0x34, 0x1f, 0x34, 0x54 ; 92 dt 0x00, 0x41, 0x41, 0x7f, 0x00 ; 93 dt 0x10, 0x20, 0x40, 0x20, 0x10 ; 94 dt 0x01, 0x01, 0x01, 0x01, 0x01 ; 95 dt 0x00, 0x40, 0x20, 0x10, 0x00 ; 96 dt 0x02, 0x15, 0x15, 0x15, 0x0f ; 97 dt 0x7f, 0x09, 0x11, 0x11, 0x0e ; 98 dt 0x0e, 0x11, 0x11, 0x11, 0x02 ; 99 dt 0x0e, 0x11, 0x11, 0x09, 0x7f ; 100 dt 0x0e, 0x15, 0x15, 0x15, 0x0c ; 101 dt 0x08, 0x3f, 0x48, 0x40, 0x20 ; 102 dt 0x30, 0x49, 0x49, 0x49, 0x7e ; 103 dt 0x7f, 0x08, 0x10, 0x10, 0x0f ; 104 dt 0x00, 0x11, 0x5f, 0x01, 0x00 ; 105 dt 0x02, 0x01, 0x21, 0x7e, 0x00 ; 106 dt 0x7f, 0x04, 0x0a, 0x11, 0x00 ; 107 dt 0x00, 0x41, 0x7f, 0x01, 0x00 ; 108 dt 0x1f, 0x10, 0x0c, 0x10, 0x0f ; 109 dt 0x1f, 0x08, 0x10, 0x10, 0x0f ; 110 dt 0x0e, 0x11, 0x11, 0x11, 0x0e ; 111 dt 0x1f, 0x14, 0x14, 0x14, 0x08 ; 112 dt 0x08, 0x14, 0x14, 0x0c, 0x1f ; 113 dt 0x1f, 0x08, 0x10, 0x10, 0x08 ; 114 dt 0x09, 0x15, 0x15, 0x15, 0x12 ; 115 dt 0x20, 0x7e, 0x21, 0x01, 0x02 ; 116 dt 0x1e, 0x01, 0x01, 0x02, 0x1f ; 117 dt 0x1c, 0x02, 0x01, 0x02, 0x1c ; 118 dt 0x1e, 0x01, 0x06, 0x01, 0x1e ; 119 dt 0x11, 0x0a, 0x04, 0x0a, 0x11 ; 120 dt 0x18, 0x05, 0x05, 0x05, 0x1e ; 121 dt 0x11, 0x13, 0x15, 0x19, 0x11 ; 122 dt 0x00, 0x08, 0x36, 0x41, 0x00 ; 123 dt 0x00, 0x00, 0x7f, 0x00, 0x00 ; 124 dt 0x00, 0x41, 0x36, 0x08, 0x00 ; 125 dt 0x08, 0x08, 0x2a, 0x1c, 0x08 ; 126 dt 0x08, 0x1c, 0x2a, 0x08, 0x08 ; 127 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 128 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 129 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 130 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 131 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 132 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 133 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 134 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 135 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 136 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 137 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 138 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 139 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 140 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 141 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 142 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 143 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 144 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 145 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 146 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 147 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 148 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 149 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 150 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 151 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 152 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 153 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 154 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 155 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 156 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 157 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 158 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 159 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 160 dt 0x07, 0x05, 0x07, 0x00, 0x00 ; 161 dt 0x00, 0x00, 0x78, 0x40, 0x40 ; 162 dt 0x01, 0x01, 0x0f, 0x00, 0x00 ; 163 dt 0x04, 0x02, 0x01, 0x00, 0x00 ; 164 dt 0x00, 0x0c, 0x0c, 0x00, 0x00 ; 165 dt 0x28, 0x28, 0x29, 0x2a, 0x3c ; 166 dt 0x10, 0x11, 0x16, 0x14, 0x18 ; 167 dt 0x02, 0x04, 0x0f, 0x10, 0x00 ; 168 dt 0x0c, 0x08, 0x19, 0x09, 0x0e ; 169 dt 0x09, 0x09, 0x0f, 0x09, 0x09 ; 170 dt 0x09, 0x0a, 0x0c, 0x1f, 0x08 ; 171 dt 0x08, 0x1f, 0x08, 0x0a, 0x0c ; 172 dt 0x01, 0x09, 0x09, 0x0f, 0x01 ; 173 dt 0x15, 0x15, 0x15, 0x1f, 0x00 ; 174 dt 0x0c, 0x00, 0x0d, 0x01, 0x0e ; 175 dt 0x04, 0x04, 0x04, 0x04, 0x04 ; 176 dt 0x40, 0x41, 0x5e, 0x48, 0x70 ; 177 dt 0x04, 0x08, 0x1f, 0x20, 0x40 ; 178 dt 0x38, 0x20, 0x61, 0x22, 0x3c ; 179 dt 0x11, 0x11, 0x1f, 0x11, 0x11 ; 180 dt 0x22, 0x24, 0x28, 0x7f, 0x20 ; 181 dt 0x21, 0x7e, 0x20, 0x21, 0x3e ; 182 dt 0x28, 0x28, 0x7f, 0x28, 0x28 ; 183 dt 0x08, 0x31, 0x21, 0x22, 0x3c ; 184 dt 0x10, 0x60, 0x21, 0x3e, 0x20 ; 185 dt 0x21, 0x21, 0x21, 0x21, 0x3f ; 186 dt 0x20, 0x79, 0x22, 0x7c, 0x20 ; 187 dt 0x29, 0x29, 0x01, 0x02, 0x1c ; 188 dt 0x21, 0x22, 0x24, 0x2a, 0x31 ; 189 dt 0x20, 0x7e, 0x21, 0x29, 0x31 ; 190 dt 0x30, 0x09, 0x01, 0x02, 0x3c ; 191 dt 0x08, 0x31, 0x29, 0x26, 0x3c ; 192 dt 0x28, 0x29, 0x3e, 0x48, 0x08 ; 193 dt 0x30, 0x00, 0x31, 0x02, 0x3c ; 194 dt 0x10, 0x51, 0x5e, 0x50, 0x10 ; 195 dt 0x00, 0x7f, 0x08, 0x04, 0x00 ; 196 dt 0x11, 0x12, 0x7c, 0x10, 0x10 ; 197 dt 0x01, 0x21, 0x21, 0x21, 0x01 ; 198 dt 0x21, 0x2a, 0x24, 0x2a, 0x30 ; 199 dt 0x22, 0x24, 0x6f, 0x34, 0x22 ; 200 dt 0x00, 0x01, 0x02, 0x7c, 0x00 ; 201 dt 0x0f, 0x00, 0x20, 0x10, 0x0f ; 202 dt 0x7e, 0x11, 0x11, 0x11, 0x11 ; 203 dt 0x20, 0x21, 0x21, 0x22, 0x3c ; 204 dt 0x10, 0x20, 0x10, 0x08, 0x06 ; 205 dt 0x26, 0x20, 0x7f, 0x20, 0x26 ; 206 dt 0x20, 0x24, 0x22, 0x25, 0x38 ; 207 dt 0x00, 0x2a, 0x2a, 0x2a, 0x01 ; 208 dt 0x0e, 0x12, 0x22, 0x02, 0x07 ; 209 dt 0x01, 0x0a, 0x04, 0x0a, 0x30 ; 210 dt 0x28, 0x3e, 0x29, 0x29, 0x29 ; 211 dt 0x10, 0x7f, 0x10, 0x14, 0x18 ; 212 dt 0x01, 0x21, 0x21, 0x3f, 0x01 ; 213 dt 0x29, 0x29, 0x29, 0x29, 0x3f ; 214 dt 0x10, 0x50, 0x51, 0x52, 0x1c ; 215 dt 0x78, 0x01, 0x02, 0x7c, 0x00 ; 216 dt 0x1f, 0x00, 0x3f, 0x01, 0x06 ; 217 dt 0x3f, 0x01, 0x02, 0x04, 0x08 ; 218 dt 0x3f, 0x21, 0x21, 0x21, 0x3f ; 219 dt 0x38, 0x20, 0x21, 0x22, 0x3c ; 220 dt 0x21, 0x21, 0x01, 0x02, 0x0c ; 221 dt 0x20, 0x10, 0x40, 0x20, 0x00 ; 222 dt 0x70, 0x50, 0x70, 0x00, 0x00 ; 223 dt 0x0e, 0x11, 0x09, 0x06, 0x19 ; 224 dt 0x02, 0x55, 0x15, 0x55, 0x0f ; 225 dt 0x1f, 0x2a, 0x2a, 0x2a, 0x14 ; 226 dt 0x0a, 0x15, 0x15, 0x11, 0x02 ; 227 dt 0x3f, 0x02, 0x02, 0x04, 0x3e ; 228 dt 0x0e, 0x11, 0x19, 0x15, 0x12 ; 229 dt 0x0f, 0x12, 0x22, 0x22, 0x1c ; 230 dt 0x1c, 0x22, 0x22, 0x22, 0x3f ; 231 dt 0x02, 0x01, 0x1e, 0x10, 0x10 ; 232 dt 0x20, 0x20, 0x00, 0x70, 0x00 ; 233 dt 0x00, 0x00, 0x10, 0x5f, 0x00 ; 234 dt 0x28, 0x10, 0x28, 0x00, 0x00 ; 235 dt 0x18, 0x24, 0x7e, 0x24, 0x08 ; 236 dt 0x14, 0x7f, 0x15, 0x01, 0x01 ; 237 dt 0x1f, 0x48, 0x50, 0x50, 0x0f ; 238 dt 0x0e, 0x51, 0x11, 0x51, 0x0e ; 239 dt 0x3f, 0x12, 0x22, 0x22, 0x1c ; 240 dt 0x1c, 0x22, 0x22, 0x12, 0x3f ; 241 dt 0x3c, 0x52, 0x52, 0x52, 0x3c ; 242 dt 0x03, 0x05, 0x02, 0x05, 0x06 ; 243 dt 0x1a, 0x26, 0x20, 0x26, 0x1a ; 244 dt 0x1e, 0x41, 0x01, 0x42, 0x1f ; 245 dt 0x63, 0x55, 0x49, 0x41, 0x41 ; 246 dt 0x22, 0x3c, 0x20, 0x3e, 0x22 ; 247 dt 0x51, 0x4a, 0x44, 0x4a, 0x51 ; 248 dt 0x3c, 0x02, 0x02, 0x02, 0x3f ; 249 dt 0x28, 0x28, 0x3e, 0x28, 0x48 ; 250 dt 0x22, 0x3c, 0x28, 0x28, 0x2e ; 251 dt 0x3e, 0x28, 0x38, 0x28, 0x3e ; 252 dt 0x04, 0x04, 0x15, 0x04, 0x04 ; 253 dt 0x00, 0x00, 0x00, 0x00, 0x00 ; 254 dt 0x7f, 0x7f, 0x7f, 0x7f, 0x7f ; 255gpsim-0.30.0/extras/lcd/COPYING0000664000076400007640000004310613041763633012761 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gpsim-0.30.0/extras/lcd/lcd.gif0000664000076400007640000002074113041763633013157 00000000000000GIF89aôłżżżżżżżżżŔŔŔ€€€˙˙˙˙˙˙˙˙˙˙˙˙!ů,ôţđČI«˝8ëÍ»˙`(ŽdižhŞ®lëľp,Ďtmßx®ď|ď˙Ŕ pH,ŹČ¤rÉl:źĐ¨tJ­ZŻŘ¬vËízżŕ°xL.›Ďč´zÍn»ßđ¸|NŻŰďřĽŔďSřX€zt}~‚{„Śo‰‹ŹT“Ť–f•‚•R›—ž`ťš‡†‘˘‘†¦§ŞŻŹ¬ź´Yˇ’©¤®şŁ·¨ŻĄŔ»¨ÁşµÇQ·ÂĘą˛­Ą™ąĹİĎČŘJĚÎŃÍ­ťĚŁÔ¸â×ŮčEáÖűçëĐĺ츬ľéř<ńí‡÷ň¤U“gĎXľ>Î#xmÜ…NCHŃHDsů-ěp‘^ÇŠţ ‡ĚҰž©Śô¬ űe°`ż0wŚDąŃĺĆ”/U¶´—3¦Ďź@ J”ŤAsď‚­şwTĺҤ°<@ý#µ*Ǣ\NAŐ QWQ_%…ÝęuĂżłSi^@‹UËłwoF];W\Ý»béR…—·kÚEűň ś¶m“¸zËÚÝ»X1^¸x –{µň*«—‹ÜĚąłçĎ6'Cfü˛dÉŁO%mÚ,f×–a-ĚqăŐ·'Łn­·oÖc‡•M|¸PÚKl—Nü{7óޢyĎL˝8_áA‘'W­lsĆޡă_¶ů×ĆŻĎŢŇT©Y¦đ˙ĆGŻŢ:ďúéj7ĚÎţţ®ţń_íąň}÷%řÜZóa§`nřeçw㍵Gĺe(yvř†X hQdżĄöťW„]–"~&Š'ÖŠ~©˘-$F÷Ütö-ř ŤąáźŽ@úhDY¤s=JWÝŹî¨pKF¸#kyÄ“H.ÇdŤMZ‰e‰QNI!—1µ¸•`ަ•hzYă—d¶ŮĺśeŠ©Î\©W‚lŽŮ‡kŇ)gś!™Y[Ýśç`ź'ş—(ź‚ú))H†h)•^Şé™řŹ‹ţr࢑6Jh˘’J(Ąv‘g7 Z¨§‡°Ň ĎTŻ&&_¬ë1*™€ÉȢ’ Łkáť'X0ţŐ顂Šç›§BşŞ‹p.;©´¬iä·ßfŮj˛Đikj´çNۦąÜ¶KQĄ"ÎŔ®˘Ä&™c©í’ۢŹRţď•ŐŞšmŔ^«o˝ýâű®‚ńĘ;)˝¦zŻÁÖţ)ëÄčVô/¨n+ßÇ{rǧk˛Ć oŞ˛Żěr )sŚ(ĆőŚü)ČŞ¦Z°Î4wŰeĂ2äÚخߺˇ­C#]Ńł~¨YĚw® ,¶S\ě°W#l—ŐrŤLË®R-× óXöĽĆń eĎ({¸p3đŘiŚ6Ö[Ţ­µŻ »Í÷ sKJ¶“«9±Ţ†o ŘĂxş»I7ŢgnŻâţ…B}m B/ťsçl‚.¨čq’ŞéŰöýs«AĎŚyÉŇÂŽóÎ5ç\;í>‹­đËĽ'¤y㽯㩯÷ńČ'ŻüňĚ7ďďďĹ«1ć'O_vĆÖŹňÉ_żHU°( ¬× dĎÜLâźTVhéko{őŰç+¤4Őźů·ˇ˙Ťú«±żżű¸“ßűX'żíNzń›Ah˘ ¦#ŕţF2A^XĄß^đ78°iN&ř›TPôđV¶ű9{)$ÇVx“y i/ţ#!IlXÂ˙ĺe4Ô`Ňşž"Ь2Îh Ń~ÂreĐ$ËĐaF”Xn0ŃŠäÓţb¶ŘÁ.âĐ‹ëóś«á ’‘%QDb9ÉPŠO,# =¸8ÇäęŽDü˘Ăhĺэ2ś#OŽHG?’»@ˇ YČĚ5D7ŕűŢÚ¸¸Ç ŤŃ$ \äkC8*23śQ–?b¸Cj$‹„ ^šřČĘţ‰Ń<ĺ!7©ŚęĎ–ŇżbEB•Z„¤0ůÄVţŚ–„%ĺčËë­Ź\Î%inY“8’{ÇŔŁo´)>;zs›ßTćgÉCNšÄÉ ­Yo¤1wǬd<íH?¤Řł“Uä_úŇXK5RŹ€±ÔÝŃLÖ ‘l¤ç;áŘĆš_[ ¶ţ‚K%öó 8H(ü. ËŽ˛MŁîÂ(9úQ)–”¤ŤźHGęŃ”˘4šuiKW4“Ęô¤3MçM˙IS€ô§6…)P_jĐž–`¨9őRqĘTžő¨Í‹ŞT§JŐŞzć©#ŞRŞSˇrőoXőF“męsťřµ…÷ĽśućşĂ‚ĘҰ˝kE!Ď–µ}ç;ëGŮSn“±~e gźůËîÓ‚=ě}\KWŘćO¶Őn>(ţiĚÇ:7Mʉdn »[ÓҲ°o3m,$«H˝ŞO‚ěmÁIŢn&Ó•ňśětI«[ÔZ·śŮe˘ ąkM~×TĹ®#·Ćߨ˝ÍmzŘK]OŇ–™żÝn"¬OŞ·˝Ť´Ż{CÚ=j ŔfZŰ[\wŞďŹ›D#mEśßĹV’‚Ťp.} ĚXţúßÎľ¬ęĽä™ż|ĚŻ„uMÎÜFnűPä!ţ±őóĄŕ™¬#1cľWymĹnŠź a˛#VŮ€69a×Moxrg_ČÔđ*/íd¶—ÝîgG÷ ŐŽu‹·}a[÷/׏žż¤ßÔĎ ·zâ[-őř®Yń6×66kˇń˘WţĽH’9Ąov w^ÓŤgµ=ŻZŐ˛ć¨ç2ĎVš„ëĐ»WyČ»­j+Źť—čó»~ď‡}üčżú§Ď~óg?ýí˙ú­?÷ţ¸×řĎżţ—gĄ×?üń€ô€ć§p‡qĄ'h›Ćw \ HaÇg€5‡€Ő{ŰWecVĘ·BxoV·[z^Ř·Q°J›!€ŃŁ2·:ŤµpęÔpą÷7Gdj´r#ř2—÷g“ (%zýÄn H&ČvČfSŮw.§„«ä=‚×I=xwÄ—,Ařm°qq hN’w~ËND—L„§;~ĺq˘'{â\?MĂ—u>x‚QFlŘđbN(ctŘe_—8—mŽ÷†gXs¸7`·Wp<×{1¸9q=Mz,xN6ry#‚Fqţ¶sˇ÷]S7z%$ĂÄu0ćuTwţ5…xç$؇š7‰Qçc~¦s¨`™S^_8s˛: Ož7Š”‹©(•ř‚Że}×cGhu†aČzMQ‹yx‹'tŽČ‹׋ítbŔh†ÂH\ýzd8p 8čtüÔ`@Ögf"„|BŰŤŚ—ŽUčŤv…sđh{Ç%v®xŽ7ç‚ę8€ú(xű8yX~ţČŹ˙Č…č}‰‚ i™8m‘ é …9‘É©‘îG‘é‘©R×·$Y’&.ů( ů€+éŮX?ĂláŘ”¸ŠLe“6ąö“o"“hč†{g\ýX\ʧ’)ąŽ˘HţrúĆs gŹůgBŚqfzG‰mćČŠ|¸‹¨nâ¸T89eöI4•ڎe P¨w !•‡Ugx•Ś…ś‡eşpŐ9;č…g©Šz¸oÔHEA=—‚¶xtyĆČ„f#]Çh•?9Ť|ů‹ł%o]Ĺ–lůŚ–™‹C—d—‡%2§zŚé‡ďö8uŐmÇU™~7—p†rŘš›(.FÖrŃçZ„ŤRȆśóř§]#Ö›Hyh6rg‡I¦›\)—ĐX`*FĹ'qŔůtě\i™‚´ŕšW‡ś9I†7…TÉŚlx›5ůtD9ޏ›AÖ–"WŹmsdš‰——‹<ţy{‚ ¸cUu9 ť_霦Y:GŚ…€Çx;čBłén¤w„”i…XYr3h…ý©ĎYTyc z€ šW©”yůIŽţ©“ů‘&’(ęj#y˘,ɢ.Y™˘/ş‘-I˘)Ł6ZŁ7X‘+ŠŁ;ę˘9*’ϧŁäע>jˇ»w’Jş¤L* pE¤đ×@z1j‚‚IµąśEę‹Ly“{y”oéźX¦śáůŁexź [b ¦ó™sĎ–•k§ĄQşmIŮ kJĄ=jĄäů¦üfŤ…9§čX§ę€3Ú;d fLÖ/îŘSŤ´W¦ ă“ěšL§«i¨­g%g>ţ‹ š#Ę‹ŹŠ™‘ÚtIé‚d*Ş]^Đ…ťŘ„/Ć“>¨á¨šĄ¨ź›Ąźˇ ą†¨šŞîiyEWśŰŮoz]ˇ*Ś—i«¶w§“¸«©ťś8‡Ä›Ĺ Pű™¬q:{yg¨É¬ş:ťŕŮ«†9śO‚tźlť’_ŘŚ@ą”÷xŕ“}ç©äĘšŻY‡­Z­ťfź 0Ř®ÚZŻż)°Ľ™­‡‹“­đy^9yxh° FjY«Űš‰ţD©ZXźKťŻ`Ć©Pô¸7‘*o3 —߲Řř#öšžćX…»’śú›ŕ(ˇ*K¨u~-KXřŽ+[•SşĄAz¤şGţnPj”D‹´*:¤A ¨iz´™§…ú´M«´S[ĄS µRš´†Č´\»µF¶ť6’MZ¶fŰk` ¶Y[µCY~X;&†«tŠĄmqé„°H…@kn·J˛mBg·Úř,4zf—Z˘kŞ`éÍyŻs ¸ďş`¤ÚˇłŠ„R+±˙•›Ť Ş{ާtŰł?i•‹¤FKJĽzr›‹›‹k›ś ­t"™ăIş—r¨Âw—{ş‹şŞűŻä »1ë%!ę»]»)vy¶k­őqĄˇ |î·Xř˛ť{…‘¸Ĺš‡©Ş‰™ŻÝÉ»;Ë®ÉűĄ{Jš§¸÷ ^»łě Ňú„Úy‡¬©›°î ·<ˇwęÁŽ›v*ÂÖIÂę›´X/|†Ęʨb‡žX»Ü© vŞÝ»°ľ*›![WĐăz|‹ŤÇ:Ä"ŠpîĆ«F\bć띥šŹZ[¸_ ĆK{ˇkĆO)¶ĆGĆC‹ĆfĘƲ‹l_|ĆeěĆEkmqLµfŚÇcĽ{l«¶k<Çc;¤g;Č„,Ui+Ć€üÇŠŚ§^›OW†˛ßűĂJL}čŰŤ=,ţo›ÁŹ ˝‘<•]LÉŐKm‚‹É—+f Śź¨śżOI4yšŰĘ/)Y§¬Ę´lźxĚĘźLŽź›ËýÇ˝=)•›Ę¶ěa“ş•ZL·ó‹Ź"E»b­đ"®L«Âl¸¬eĚš…̭˛˜©gJWtŘ,Ĺ[LľÇlłĘ¬­°ĂK¬MĚÎţK­ţűͨÎffđJ„({Ω™Íęě«ňٰÜĚ^IżĎřł]ĎÚ—Ú”ŤŰĎ]ť]wÂéÁÍ»×Đ-<ŚHqŠW\˝Ľ»Úěvʢ5í±›GĐűlĐ)ŤŃňXĹę,–§:É=­%śĺB˛kŃ\ ż MeúÓŐ)ţM–üŃű±˙ ‹|Ó&}·&R„›˛2LÄąKĹřËŁ ˛ĘĚRٶ_9ľOýŽQMŐ~š«łlŐjÜƉŚÖ‹üĆżvÇnÝÇ™ÉB«Öt=×l}koťÇy˝ÇĄ«×p-ÇkíĹ­Çim×u Ç…śŘŠ7‡ Řuí´{Čg=Ş–̵|_„Ťś{–°ÜË|ÓĚ‹ÎëǦ|±=ąş·jŔȺϋČc:Î! ‡ĄÄSMÔ­ťŰm[©ÄĚ`Žů€r[:ŤŰžĚŚť¬\  ­ö ®›ŔuY–ČxĽËÍ ŇÎzÁ—ܨşÜÝܬ»Ěšúžĺ5Ý®śĹŐťÍĘä, ΨĎţ,ŢîľTNŕo—ąˇíÚ\Žäçmâ+î–iŮN*× ˛ąŠ fů~ }Ü4~Ů6®—-}žUâ‡{Łtlµ­ç–ŰČ… Ů}ÇÁÍç†Mč€>@ľŰnčŚ>Ľ|ěמçQëçţ{®č•NÚwýj‹˝éśţŤťŮŹÝčî´‰N碌ł[^⊎°§ťĺ0ZŰ ®Ë¨îćnR¬Žĺ9ž¦Ą®âd®ĐÎxčĽÍ±šł5~ȰĘŢ_>㎉©­ĚŹ<® |PjÎz6MŮĹކó‹»í]Ä=ě¬ôŠě,NĽEŽy71ł˝>ěŢzät‰ĹÝîäß~í§gßhN­ôÍ.ąľNŰ>ŕd­ě5\°ëh'@ż>ĺŔŠÔ)ĚÄ̲ZNąQţŢę^ÎJüŇîÎ=Ó&ĚáđN›Ö>QµľĐ˝Ä*ń§Ňv^q ëâŤă(Ś|ťďűóCýć{uďG‚ŹŻäJ˝ţŞť ďľŢߥ߽ݧ&/ë2]ŕG]ĺ«ÂŐjŰ.óC/Ťő;ňG_ňÍěKź gľń6íë§^ŢY_Ůhög?ć#7ĘTîvě`~ęN÷ O¨ ňšëöUýé‘}é ř+éŁ.ęßç“ ě‹néˇîč}Mř‡_茟é¦ö÷Ť_ř“/Ř‘ľřßů;Ůé ú°łëË®ř‚ę”ďi:şË*ĺ™/~/Źň±ě٬ßěłmúĆűpÇ2^öż<á ©·¸ËŮG(ł˝ß€A”ő빣éRÎöYĐť©öqő· (ě~Űďw®üÂţś’ĘÂsĽ›Şńíţ*ÎM>ő®ţ¸]OĂ5§iľöÁ™áŽ˝˙ŰgőÍißé-ň˙ţţçZ­Rď™'ö6 ąŽ4OÍłZ6…cy¦kűĆó0üPźßĄ€žŻ·BÖ€-‘­¸źĎRŇ4Jş.GáK%ňbÁĆqV‹ĄćÔkvŰËLą$y:jĹĘ*Ú Ă+3 lę2üR,c™ [B”’¬˘|»ÄĚÔ´$cś“Ô»˘ÜŁqěűë(ü¬äRíd}ť$’Ací˝›íTMŰüúŚ­Ń%ő”M$¬ ”ľĄ]ś†Bľ’ÔFńkŢ%Ţ.7&=ş[F¤ %tň®Ü–Žr5KŚlw^ţĹîѫۢWÖćq:—P!x «Áł­3|Ńł¦W=Ď6¦Ňňí ¤3"ç9Ęg'ś…-]ľ„‰0\-yíŤôxłd@śĄŞTëV®FłZýŠěX±eY^=6mW¶m‘2ećt­YŻdçŢ­Kw˘Ţ™nýţ5·`߼x÷&|¸đbĹŤ†ŮŤŕŹĺ2¶ÜTsÜÍ/;ţ,Yôh´Cźî\5gÖžSS†MZöěR#mßĆť[÷nŢ˝}˙śöpâ­Użžj×4ňŇ ™«-=rěćŃbµb˘ĎđµŻŕ´/7ţN]úřéÉů>Ľľd‹ÉíE'zgŢuxňő‹J˘ˇ{úŤćă…«l‹Ży˘F¨ŽŽłŻÁ»öű¬"ł>ŞÇş}ü)°/ ě ¨˙:<Ĺşź$ń†Bҡ† üÔč&óCďBq âN…kô ~ÂI©D¶âď!ŚŠdcž1' ÂîCýQÉ?@Z0G\’Ěc(»J§Ë<IFŔe Â±¦ő†Ôľ,?QG|.˛ŇĆѬrË•9˛ -ÉłH3A$B)—ܰG*łăçF8¨Đ´ÓĄ=#\KÂ,-ĚŃŹÔ|†ÍI_l!EźhľNuŚ”+"ő4¦Ő÷ţäútE&ŐsqV }úÔV)j”@J®?HS=ÇËxŽ]˘wň’uĂ…=•Đ>…ĺ ď LďĎ“M Č,„ŚH›\ů4OW(s4Fs±LtĄMťRłĺ¶^`d­ËĐR±;3G^aôWC9’HADË•Ď^…vnMl·µiT€‰âoÇ&ß{Ôŕ-đmxaŹ•ëxXŽ3ŁŻşŐL™áŹW™d”G>9e“‘<Źf–o®ądčB†Ůć„{ÖgˇV9f _.Úgž“úćŁeŢŮe¨[6ši¤›ĆZi©źćÚę©sľ:ë¬#»lłĎF;mµĹ»ë™űkÄŞ~e¶ëuŰÚţ8+†¸BXű$şîq¶ľëĽĹŮűÚ+ýŽđĄżNëÂ>üYxç PCÇELĐ2#vOęÉąĚT L?—I)˙uvÝyőőP‚+nstŃ\9ńKd©N—ďł>O=xŐUł…› ĺ´Q§ŚmĂŰoŔý2Ď9äEqîŢGŻvv­Ťö´â)ţµ̵óŽ2ćÓbÇŠô)ősz¸‡××ČiýÝ6ű•ŘxŮ+ÎďĎgĂŞ =:0&Lä ‡ć5ˇi5su‰řŚ>T%ďJŔ` ™I9OÁÔĹ–ä) TÖČźÁ'T,H$ÚË đä*V5ć€îKŕ™şç;lFţC“ AĽVpvŘű_ M¤»V0qY{1VŃRżZ•NsW â”ô>ą«ŠFT˘y¨‡@Kĺ*„‚j–ŐeĹżaquîůWµ†ą5‚1ŚÄÂĎŔG°ŤqŹ_šßÍ Ă?ş±dű2ßÉ“ÇqM 't!Ż÷Â3†ŞŤt‹š"IT9ë˝/p™”\(ŤŁÉńpň“Ľó$ęP™Ŕ¸‘R:¦TeÜ`I8Čy͕љ%&W)·SĘŇk‰Ľĺpr)JVv˛˝4ć°‚Iśa¦’– t¦.}ąL©Íš×Äf6µ™jVó—߬e8ˇyĚXvł>Í<Ţ˙"ÉHd¶cî4'.ÁI•Ť¬Eqţ|g9á™ĹgĆó%fÔ#/WĎ$NlŠ›ËŢň°DÉ|5RtţÔî”Ĺ=tţŞs”[ëzŘDž⪡űĽĄÇĂŇâ†%Ť&íZľ"*JMčăDťHŇ15šŚâú>“¶oś¸‚ "ąčQ-nĎdĹă”Ěj*ÉQât†&Ą!ű8&zĘNúۢ‘—Ő#vQTˇŰęđžćĘF:´°˘Ű#á×·=jµ rěęĄŕVu:4f¤ JUQQŐ§»Ô=÷'Wß]Ô„=¬!¶ÔŔľµ›9uGdyJŹ'¦t+ĄWVYjSO°ˇŽ•)![ÄeŠ”Śh=L§ Xmaµ­Býţa”†Ďŵ5E1…(m*:Ó–ľ‰­'|’V=ăŘ4™ą•Ěn•‰ v÷Ë,‡D{OÁ&ąşťçUť›ťt¶°sĐý-ü¦ ş‚jôşłQ®8Y«ŢiţçuKzÝ›Ýö®wľđ-Ž|í»ßúö7™ďĹ/éŘű_úxŔ mj€ďt`}6¸źţE°ÝĽŕűVż¶0„C6ámÓĂqwĂaô8¸%&Š-+akĹmň[.SÉŮOăR‘GÜUq‹|_¦ú­±őÓ/[ęa=Ť;ÇÖ—–ËĽôáç •ceą6MR÷ ;&űËÉUiPc\ —zĎ ţ(žZĂ©rŇ~‰Š1PŚŃŔ¦«ĽârWŚW'Jö6Ěe üf ÂÖřt)Ž-vç;IĎ3¦f^?@ŔIođU~ľ°7«T@’Dˇ\®Ś9-¬±ňĐŽ)+Ua)1ĂJ·â(¨›Ű?‘şČŠ”t®×,Ő! zŔď˛$MŁŰ«G ’rn­bŹ‹ë>«Óťe/ l›\ ¶š-¶ŐŐęş¶•w4-ËhiŤčrĽ·ĺ­µ‡í:ÄŠŐ¤­cmżmĺŁ0’ZóöZómŢâ.٭ɶă˛é{q„w´˛7ęĹXµŞáMŘŔë Bj'ářV8¶Ö)®ę:\»¨Äţ˙ibKĂ™.ůME>r?řäe6ů‰Ľň„čć)¶ůËiľ•śËśä.÷ůÎ)Śr §|Ď=ß°Đ‚ô˘7=ćF‡´Ň˙)bŞWÝęÚ”şŞ~ţt§ă|ë)Îz±˛»qĐy˝ĺiĹń©]°ď,ŐfŹ+­hËuş3‡±Ťx Ű>Ô…J”îHĄ×µ§ f$zZĚŔď§ýîpëŐń•†ŞäżŘu#óÉńFž”gZkĹ/ľŮvödOťĘąO>ß ť3ş.oýÝ˝ě—e;DuMiIÓÜä,ý@2~ăÔ»;PŻ ëăÎÇŽçöíŹ9ľSŇČSßžăÁóżoĐbđzŹçěůţ yŃwżünţî­oř(ËŮ»âŻ>ˇŹýÇ~~§ çu_‘äłŢâµÍ3·];뇷ުŮ?ł€@ÇIľ©ˇżńS·.s4ýŰ.¸ú¸Đ꼽cąţ Áë6e»<âň"Z2´˙“@IY=´ľú +ÄË8ĎâŔŔóŔ\7Ă3E#ľşę=ę7đ›?„µâcÁ´ś3 ";µč˝sł­± ;µÚÁšűşŁ[¨cBÁIÂjB*cşş{Â(äÁł;˘łB'ôB,Ě„*Ü›»B.ĂMĂ2$Ă/¬¨3lž)LC6„Ă[sĂ5¸ş;ÄĂ<ôŤ:äĂ>ôĂ?Ä@ÄA$ÄB4ÄŻCDÄDTÄEdÄFtÄG„ÄH”ÄI¤ÄJ´ÄKÄÄLÔÄMäÄNôÄOĹPĹQ$ĹR4ĹSDĹTTĹUdĹVtĹW„ĹX”ĹY¤ĹZ´Ĺ[ÄĹ\ÔĹ]äĹ^ôĹ_Ć`Ća$Ćb4ĆcDĆdTĆedĆftĆg„Ćh”Ći¤Ćj´ĆkÄĆlÔĆmäĆnôĆoÇpÇq$Çr4ÇsDÇtTÇudÇvtÇw„Çx”Çy¤Çz´Ç{ÄÇëŠ;gpsim-0.30.0/extras/dht11/0000775000076400007640000000000013117466030012154 500000000000000gpsim-0.30.0/extras/dht11/AUTHORS0000664000076400007640000000004013041763631013141 00000000000000Dave Gilbert gpsim-0.30.0/extras/dht11/dht11.h0000664000076400007640000000410113041763631013165 00000000000000/* Copyright (C) 2014 Dr. David Alan Gilbert (dave@treblig.org) This file is part of the libgpsim_modules library of gpsim and was originally based on the usart module The dht11 is a cheap temperature and humidity sensor, this model is based vaguely on the datasheet at: http://akizukidenshi.com/download/ds/aosong/DHT11.pdf It expects the data pin to have a resistor pulling it up. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __dht11_MODULE_H__ #define __dht11_MODULE_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include class dht11Module : public TriggerObject, public Module { public: void CreateGraphics(void); // Inheritances from the Package class virtual void create_iopin_map(); dht11Module(const char *new_name); ~dht11Module(); const virtual char *type() { return ("dht11"); }; static Module *construct(const char *new_name); virtual void callback(void); private: class IntegerAttribute; guint8 state; /* Idle = 0 */ guint8 byte; /* current byte being transmitted */ guint8 checksum; IntegerAttribute* m_tempAttribute; IntegerAttribute* m_humidityAttribute; class Pin; Pin* m_pin; void start(void); /* Callback from Pin to indicate start sequence received */ void set_state_callback(guint8 new_state, double delay, bool level); void callback_end(void); void callback_intro(void); }; #endif // __dht11_MODULE_H__ gpsim-0.30.0/extras/dht11/Makefile.in0000664000076400007640000004536613117441635014163 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile for the DHT11 module # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras/dht11 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in AUTHORS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = dht11.h README AUTHORS \ examples/dht11_example.asm examples/Makefile examples/README SUBDIRS = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/dht11/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/dht11/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/dht11/Makefile.am0000664000076400007640000000023513041763631014133 00000000000000# Makefile for the DHT11 module # EXTRA_DIST = dht11.h README AUTHORS \ examples/dht11_example.asm examples/Makefile examples/README SUBDIRS = gpsim-0.30.0/extras/dht11/dht11.cc0000664000076400007640000002346613041763631013342 00000000000000/* Copyright (C) 2014 Dr. David Alan Gilbert (dave@treblig.org) This file is part of the libgpsim_modules library of gpsim and was originally based on the usart module This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* dht11.cc The dht11 is a cheap temperature and humidity sensor, this model is based vaguely on the datasheet at: http://akizukidenshi.com/download/ds/aosong/DHT11.pdf It expects the data pin to have a resistor pulling it up. */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include "dht11.h" #include #include #include #include #include #include #include #include #include #include #include //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("module-%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif static const double host_start_sig_len = 0.018; /* 18ms minimum low */ /* High nybble used for major states, bottom nybble for the current bit * OR with STATE_TEMP_DATA_LOW for the first (low) half of each bit that's * always the same length */ enum { STATE_IDLE = 0, STATE_INTRO = 0x10, STATE_HUMIDITY_INT = 0x20, STATE_HUMIDITY_DEC = 0x30, STATE_TEMP_INT = 0x40, STATE_TEMP_DEC = 0x50, STATE_CHECKSUM = 0x60, STATE_END = 0x70, STATE_TEMP_DATA_LOW = 8 }; //-------------------------------------------------------------- class dht11Module::Pin : public IO_open_collector { public: Pin(dht11Module* new_parent) : IO_open_collector("data") { parent = new_parent; parent->addSymbol(this); lastState = true; lastLowTransition = 0; bDrivingState = true; bDrivenState = true; update_direction(IO_bi_directional::DIR_OUTPUT,true); // Based on the code from modules/i2c.cc // Set the pullup resistance to 10k ohms: set_Zpullup(10e3); update_pullup('1', // Turn on the pullup resistor. false); // Don't update the node. (none is attached). } ~Pin() {}; /* This gets called whenever the pin voltage changes */ virtual void set_nodeVoltage(double newvolts) { bool newState = newvolts > 1.5; guint64 now = get_cycles().get(); Dprintf(("Times: instruction-cps=%lf seconds-per-cycle=%lf\n", get_cycles().instruction_cps(), get_cycles().seconds_per_cycle())); Dprintf(("dht11 Pin/set_nodeVoltage %lf / %d at %" PRINTF_GINT64_MODIFIER "d\n", newvolts, newState, now)); if (lastState != newState) { if (lastState && !newState) { /* High->Low transition */ lastLowTransition = now; } if (!lastState && newState) { /* Low->High transition */ guint64 delta = now - lastLowTransition; double delta_s = delta*get_cycles().seconds_per_cycle(); Dprintf(("dht11 l->h low period=%" PRINTF_GINT64_MODIFIER "d=%lf s\n", delta, delta_s)); if (delta_s > host_start_sig_len) { parent->start(); } } lastState = newState; } } void setDrivingState(bool new_state) { Dprintf(("new_state=%d\n",new_state)); bDrivingState = new_state; //bDrivenState = new_state; // if (snode) snode->update(); } private: dht11Module* parent; guint64 lastLowTransition; bool lastState; }; class dht11Module::IntegerAttribute : public Integer { public: IntegerAttribute(const char *_name, gint64 newValue = 0, const char *desc=0) : Integer(_name, newValue, desc) { } }; //-------------------------------------------------------------- // Handler for the intro states // Initially (0) we're just after the start signal and we're high // so then we pull low for 80us // 1 we've been low, now pull high void dht11Module::callback_intro(void) { switch (state & 0xf) { case 0: set_state_callback(STATE_INTRO + 1, 80.0, 0); break; case 1: set_state_callback(STATE_HUMIDITY_INT | STATE_TEMP_DATA_LOW, 80.0,1); default: Dprintf(("Bad state\n")); break; } } //-------------------------------------------------------------- // Handler for the end states - 50us low pulse at the end // 0 - Where we pull it low // 1 - We're done, release and no more callbacks void dht11Module::callback_end(void) { switch (state & 0xf) { case 0: set_state_callback(STATE_END + 1, 50.0, 0); break; case 1: state = STATE_IDLE; m_pin->setDrivingState(true); Dprintf(("All done\n")); break; default: Dprintf(("Bad state\n")); break; } } //-------------------------------------------------------------- // Gets called on 'set_break' timeouts void dht11Module::callback(void) { Dprintf(("at %" PRINTF_GINT64_MODIFIER "d in 0x%x\n", get_cycles().get(), state)); /* Handle the intro sequence separately */ if ((state & 0xf0) == STATE_INTRO) { callback_intro(); return; } if ((state & 0xf0) == STATE_END) { callback_end(); return; } /* In that case it's data */ if (state & STATE_TEMP_DATA_LOW) { /* The first half of each bit is always the same, 50us low */ set_state_callback(state & ~STATE_TEMP_DATA_LOW, 50.0, 0); return; } else { /* The 'high' part of each bit - the length determines the data */ guint8 next_state = (state+1) | STATE_TEMP_DATA_LOW; gint64 tmp; bool bit_value; if ((state & 7) == 0) { /* First bit of the byte - figure out what to send */ switch (state & 0xf0) { case STATE_HUMIDITY_INT: checksum = 0; /* 1st Byte */ m_humidityAttribute->get(tmp); /* e.g. 1234 */ tmp /= 100; /* e.g. 12 */ byte = tmp & 255; break; case STATE_HUMIDITY_DEC: byte = 0; /* DHT11 doesn't really do dec */ break; case STATE_TEMP_INT: m_tempAttribute->get(tmp); /* e.g. 1234 */ tmp /= 100; /* e.g. 12 */ byte = tmp & 255; break; case STATE_TEMP_DEC: m_tempAttribute->get(tmp); /* e.g. 1234 */ byte = 0; /* DHT11 doesn't really do dec */ break; case STATE_CHECKSUM: byte = checksum; break; } checksum += byte; } bit_value = (byte & 0x80) != 0; byte = (byte<<1) & 0xff; if ((state & 7) == 7) { /* Last bit of the byte - figure out what happens next */ next_state = state & 0xf0; next_state += 0x10; if (next_state != STATE_END) { next_state |= STATE_TEMP_DATA_LOW; } } set_state_callback(next_state, bit_value?70.0:27.0, 1); } } //-------------------------------------------------------------- // Set the state, set the pin and register a callback for sometime in the future void dht11Module::set_state_callback(guint8 new_state, double delay_us, bool level) { guint64 now = get_cycles().get(); guint64 future_time; future_time = now+1+((delay_us/1000000.0)*get_cycles().instruction_cps()); Dprintf(("State: %d->%d wait %lf s pin->%d now=%" PRINTF_GINT64_MODIFIER "d future=%" PRINTF_GINT64_MODIFIER "d\n", state, new_state, delay_us, level, now, future_time)); state = new_state; m_pin->setDrivingState(level); get_cycles().set_break(future_time, this); } //-------------------------------------------------------------- // Called by the pin to indicate reception of start signal void dht11Module::start(void) { if (state != STATE_IDLE) { /* I don't see anything to indicate what should happen here */ Dprintf(("Start detected but not idle - ignoring (state=%d)\n", state)); return; } Dprintf(("Start received!\n")); /* It takes some time for the dht to notice the START, so this is high for a while */ set_state_callback(STATE_INTRO, 30.0, 1); } //-------------------------------------------------------------- Module * dht11Module::construct(const char *_new_name) { Dprintf(("dht11 construct\n")); dht11Module *um = new dht11Module( (_new_name ?_new_name:"dht11")); um->create_iopin_map(); um->state = STATE_IDLE; return um; } dht11Module::dht11Module(const char *_name) : TriggerObject(), Module(_name, "dht11") { /* DHT11's actually never do the decimal part of either the humidity or temperature, even * though the protocol allows it; I've seen reference to a DHT22 that does, but don't * have one. */ m_tempAttribute = new IntegerAttribute("temperature", 1300, "Temperature in hundredths of degree C"); addSymbol(m_tempAttribute); m_humidityAttribute = new IntegerAttribute("humidity", 4200, "Humidity in hundredths of percent"); addSymbol(m_humidityAttribute); assert(m_tempAttribute); assert(m_humidityAttribute); } dht11Module::~dht11Module() { removeSymbol(m_tempAttribute); removeSymbol(m_humidityAttribute); delete m_tempAttribute; delete m_humidityAttribute; } void dht11Module::create_iopin_map() { create_pkg(1); m_pin = new dht11Module::Pin(this); package->setPinGeometry(0, 0.5, 0, 0 /* orientiation ? */, false /* Don't show name */); assign_pin(1, m_pin); } gpsim-0.30.0/extras/dht11/README0000664000076400007640000000076513041763631012767 00000000000000This is an emulation of the DHT11 type temperature and humidity sensors based off the data sheet. I've got two devices that claim to be DHT11 off online retailers, and the PIC code seems to work on real hardware with both of them, however one of them needs a delay between reads to be stable while the other doesn't. My suspicion (since the cases and labelling are quite different) is that one or both isn't really an original DHT11 but a clone. The PIC code started off as the usart_test.asm code gpsim-0.30.0/extras/dht11/examples/0000775000076400007640000000000013117466030013772 500000000000000gpsim-0.30.0/extras/dht11/examples/dht11_example.asm0000664000076400007640000002022713041763631017056 00000000000000 ;; DHT11 temperature sensor read->uart ;; ;; Reads from a DHT11 temperature sensor and outputs as ASCII ;; on a 9600 baud uart ;; ;; dave@treblig.org ;; based on the usart_test.asm code in gpsim list p=16f627 include include __CONFIG ( _WDT_OFF & _HS_OSC ) errorlevel -302 radix dec ;---------------------------------------------------------------------- ; RAM Declarations ; INT_VAR UDATA 0x20 w_temp RES 1 status_temp RES 1 pclath_temp RES 1 fsr_temp RES 1 INT_VAR1 UDATA 0xA0 w_temp1 RES 1 ;Alias for w_temp at address 0x20 GPR_DAT UDATA #define RX_BUF_SIZE 0x10 temp1 RES 1 temp2 RES 1 humid_int RES 1 humid_dec RES 1 tempe_int RES 1 tempe_dec RES 1 dht_sum RES 1 tx_ptr RES 1 rx_ptr RES 1 rx_buffer RES RX_BUF_SIZE ; RB1 on the 627 #define rx_pin 1 ; RB2 on the 627 #define tx_pin 2 ; RB5 on the 627 #define dht_pin 5 ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location retfie ; We're not using any ;; ---------------------------------------------------- ;; ;; start ;; MAIN CODE start .sim ".frequency=4e6" .sim "module library libgpsim_modules" .sim "module load usart U1" .sim "node PIC_tx" .sim "node PIC_rx" .sim "p16f627.xpos = 192.0" .sim "p16f627.ypos = 156.0" ;; Tie the USART module to the PIC .sim "attach PIC_tx portb2 U1.RXPIN" .sim "attach PIC_rx portb1 U1.TXPIN" ;; Set the USART module's Baud Rate .sim "U1.txbaud = 9600" .sim "U1.rxbaud = 9600" .sim "U1.xpos = 192.0" .sim "U1.ypos = 48.0" .sim "module load pullup DHTPull" .sim "DHTPull.xpos = 228.0" .sim "DHTPull.ypos = 340.0" .sim "module library libgpsim_extras" .sim "module load dht11 D1" .sim "node dhtdata" .sim "attach dhtdata portb5 D1.data DHTPull.pin" .sim "D1.xpos = 228.0" .sim "D1.ypos = 312.0" clrf STATUS bsf PORTB,tx_pin ;Make sure the TX line drives high when ;it is programmed as an output. bcf PORTB,dht_pin ;The only time we drive DHT is to drive it low bsf STATUS,RP0 ;TRIS* is bank 1 bsf TRISB,rx_pin ;RX is an input bcf TRISB,tx_pin ;TX is an output bsf TRISB,dht_pin ;Make DHT input for now - it'll get pulled up ;; CSRC - clock source is a don't care ;; TX9 - 0 8-bit data ;; TXEN - 0 don't enable the transmitter. ;; SYNC - 0 Asynchronous ;; BRGH - 1 Select high baud rate divisor ;; TRMT - x read only ;; TX9D - 0 not used movlw (1< 18ms here with it low call delay bsf TRISB,dht_pin ;Make DHT input - pulled up bcf STATUS,RP0 ; back to bank 0- it has timers and port reg ; line is currently high, DHT will shortly realise and pull it low for ; ~80us, then high for 80us and then send data call waitDHT0 call waitDHT1 call waitDHT0 ; and now we should be at the start of the 1st bit of the 1st byte call DHTbyte movwf humid_int call DHTbyte movwf humid_dec call DHTbyte movwf tempe_int call DHTbyte movwf tempe_dec call DHTbyte movwf dht_sum return end gpsim-0.30.0/extras/dht11/examples/Makefile0000664000076400007640000000056513041763631015363 00000000000000 MOSTLYCLEANFILES = *.o *.hex *.cod *.lst *.map *~ CLEANFILES = *.o *.hex *.cod *.lst *.map *~ DISTCLEANFILES = *.o *.hex *.cod *.lst *.map *~ MAINTAINERCLEANFILES = *.o *.hex *.cod *.lst *.map *~ .SUFFIXES: .asm .cod all: dht11_example.cod dht11_example.cod: dht11_example.o %.cod: %.o gplink --map $< -o $@ %.o : %.asm gpasm -c $< clean: rm -f ${CLEANFILES} gpsim-0.30.0/extras/dht11/examples/README0000664000076400007640000000034013041763631014572 00000000000000This example constantly reads from the DHT11 and spits the output on the UART producing output like: ***H2A.00T0D.00+37 ^ ^ ^ | | Checksum (from DHT11) | \- Temperature | \- Humidity gpsim-0.30.0/extras/module_manager.cc0000664000076400007640000000640213117107640014442 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* gpsim_modules.cc gpsim supports modules, or thingies, that are not part of gpsim proper. This is to say, that the modules are not compiled and linked with the core gpsim software. Instead, they are compiled and linked separately and then dynamically loaded by gpsim. This approach provides a flexibility to the user to create customized objects for simulation purposes. The big benefit of course, is that the user doesn't have to get bogged down in to the nitty-gritty details of the way gpsim is designed. The templates provided here can serve as a relatively simple example of how one may go about creating customized modules. Please see the README.MODULES for more details on how modules are intended to be used. Here are a list of functions that a gpsim compliant module library should support: void mod_list(void) - Prints a list of the modules in a library Module_Types * get_mod_list(void) - Obtain pointer to the list of modules */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include #include "config.h" #include "dht11.h" #include "ds1820.h" #include "ds1307.h" #include "solar.h" #ifdef HAVE_GUI #include "lcd.h" #include "raw_lcd.h" #include "glcd_100X32_sed1520.h" #include "osram.h" #endif Module_Types available_modules[] = { { {"dht11", "dht11"}, dht11Module::construct}, { {"DS1307", "ds1307"}, DS1307_Modules::ds1307::construct_ds1307}, { {"DS1820", "ds1820"}, DS1820_Modules::DS1820::construct}, { {"DS18S20", "ds18s20"}, DS1820_Modules::DS1820::construct}, { {"DS18B20", "ds18b20"}, DS1820_Modules::DS1820::constructB}, #ifdef HAVE_GUI { {"lcd_display", "lcd_2X20"}, LcdDisplay::construct}, { {"lcd_20x4", "lcd_20x4"}, LcdDisplay20x4::construct}, { {"lcd_dt161A", "lcd_2X8"}, LcdDisplayDisplaytech161A::construct}, { {"LCD100X32", "LCD100X32"}, gLCD_100X32_SED1520::construct }, { {"OSRAM128X64", "OSRAM128X64"}, OSRAM::PK27_Series::construct }, { {"lcd_7Seg", "lcd_7seg"}, LCD_7Segments::construct}, #endif { {"Solar", "Solar"}, SolarModule::construct}, // No more modules { {NULL, NULL}, NULL} }; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /******************************************************************************** * get_mod_list - Display all of the modules in this library. * * This is a required function for gpsim compliant libraries. */ Module_Types * get_mod_list(void) { return available_modules; } #ifdef __cplusplus } #endif /* __cplusplus */ gpsim-0.30.0/extras/graphic_lcd/0000775000076400007640000000000013117466030013472 500000000000000gpsim-0.30.0/extras/graphic_lcd/utils/0000775000076400007640000000000013117466030014632 500000000000000gpsim-0.30.0/extras/graphic_lcd/utils/gpsim1.png0000664000076400007640000000044313041763626016470 00000000000000‰PNG  IHDR@ SěÇPLTE˙˙˙UÂÓ~ŘIDAT•c`@€‚ 0ĹŢ>ă?Ás„Ą‰źs>D ow`€ '[Á C˛‰EÁA@-á3‹BGz #“‚çf0_…Ě`3 )ŚŤ† C3#›qڎŽdŽr#Čd;Á/ŕaîŃŻ`°i>ÇÔ9%Ç!Ą‰›Éc’‡ C/SĆ$‡6Ö&ýÉç*\Xš4;<ň\8@Ś7Î¦Ś‰. *‡ň™NLśáÂ`óű sÇDy¸ůÝ0@é}±yIEND®B`‚gpsim-0.30.0/extras/graphic_lcd/utils/konqueror16X16.png0000664000076400007640000000035213041763626017762 00000000000000‰PNG  IHDRbťňgAMA±Ź üa PLTE˙˙˙ÝĎŇtRNS@ćŘfbKGDH pHYs  ŇÝ~ütIMEŃ9-ăľl«JIDATxśʱ Ŕ ŔW:a$żP*"%S°ÄSĐSŕ)cš«;ŇcŮ[Áđ—Á"n_ş‚iÓˇľ@Ś"n"Ó wĹĄŃ)m›\QĽŞIEND®B`‚gpsim-0.30.0/extras/graphic_lcd/utils/fontimage.png0000664000076400007640000000024713041763626017243 00000000000000‰PNG  IHDR@ SěÇPLTE˙˙˙UÂÓ~\IDAT•c` `üe0˙a``3xŔ óů6`Ć?űy@ŚźÇ ç2ضĎůb0¶%Ϩ2Ř€ 0Ł/Y‚ĚřóX¤‹ŹáĂsŮÔr0q“‘ťČ™TIEND®B`‚gpsim-0.30.0/extras/graphic_lcd/utils/konqueror.png0000664000076400007640000000045113041763626017314 00000000000000‰PNG  IHDR ’ggAMA±Ź üa PLTE˙˙˙˙˙˙~ďŹOtRNS@ćŘfbKGDH pHYs  d_‘tIMEŇ ("ą$‰IDATxś]Đ=Â0 `«[{Ź,ÜçUĹ =E/ć.‘ŕť?TŃ,ů$˙$¶™iy.Ŕ+QY÷ä¬ŘeĄcQDŘŕ¤Wl cÇMąÂrQͦŢ\)‰·#θţ0·D|UĂ?ä[ŁĐâCÇv ę¬gX÷>2źß%ÜűúZ>_|[Ńę§ąIEND®B`‚gpsim-0.30.0/extras/graphic_lcd/utils/README0000664000076400007640000000404513041763626015444 00000000000000pngtopic ABOUT: Convert a png formatted graphics file into a format that may be inserted into a Microchip PIC .asm file. The main purpose is to allow graphics to be easily used with gpsim's graphic LCD driver. The gpsim graphics LCD driver supports only monochrome displays. Each pixel is thus either on or off. pngtopic will convert color to black and white by thresholding a color image. Or, if an image is already monochrome, pngtopic should handle it just fine too. COMPILE Compile with: gcc -g -o pngtopic pngtopic.c -lpng USAGE usage: pngtopic [-i] filename.png options: -i - invert pixels -p - preview ASCII image The optional '-i' will invert the pixel color (black and white are exchanged). The optional '-p' will display an ASCII image. This is useful for previewing the image to see if the color-to-monochrome conversion looks good or not. Also, the ASCII image can serve as assembly documentation. EXAMPLES: KDE has some small black and white icons. Here's one for konqueror: $ ./pngtopic -p -i konqueror16X16.png ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from konqueror16X16.png ; ; ; [] [][] . ; [] [] [] [] . ; [] [][][][] [] [] . ; [] [][][][][] [][] []. ; [] [][][][][][][] []. ; [][][][][][][][] . ; [][][][][][] . ; [][] [][] . ; [] . ; [] . ; [][][] . ; [] [][][] []. ; [] [][][][] []. ; [] [][][][][] [] . ; [] [][][][] [] . ; [][] [] [][] . ; db 0x10,0x02 ;width in pixels and height in bytes db 0x18,0x04,0x22,0xf8,0xfd,0x7e,0xfc,0xfe db 0x70,0x3c,0x08,0x01,0x01,0x02,0x04,0x18 db 0x18,0x20,0x40,0x80,0x81,0x06,0x04,0x7c db 0xf8,0x78,0x70,0xa0,0x80,0x40,0x20,0x18 gpsim-0.30.0/extras/graphic_lcd/utils/konqueror3.png0000664000076400007640000000035213041763626017377 00000000000000‰PNG  IHDRbťňgAMA±Ź üa PLTE˙˙˙ÝĎŇtRNS@ćŘfbKGDH pHYs  ŇÝ~ütIMEŃ8:yvŘ-JIDATxśʡŔ @ÁŹ`„tF@zú^;O1ő2e9u ŇĄ…ě˝rřÝ‚Ů8}*ć#řTѱé›'‹"¶ŮĽ’l—l„í˝uCPIEND®B`‚gpsim-0.30.0/extras/graphic_lcd/utils/custom.png0000664000076400007640000000045313041763626016603 00000000000000‰PNG  IHDRH ‹„¬3PLTE˙˙˙UÂÓ~ŕIDAT•c` °?“üüăGaŹ›¸`ęĽÂ lf ‡Ů>Ĺ,xĚŽł]˛ xŚcŰ f)ăŮĘb%¶ńî˛dĎ˝xŘ9Č’gďolü8Ĺ6†f† ’Ť 7Ěx$0$¤IłÜ`ÄŰŔĐ ÁÂČŕŔĂ„¬˙ś˝ý v‰ô ĽgžXĎ`çńYŔ ‘s q7OĐ}9’ ¤ůűA,›zÁvö /ř2 ěŰ0HÜ`K0HncH`0ž9ç@Şc›ŕ{Éę{ä±1=Bl°¦xvIEND®B`‚gpsim-0.30.0/extras/graphic_lcd/utils/pngtopic.c0000664000076400007640000001554513041763626016562 00000000000000/* pngtopic Convert a png formatted graphics file into a format that may be inserted into a Microchip PIC .asm file. The main purpose is to allow graphics to be easily used with gpsim's graphic LCD driver. Compile with: gcc -g -o pngtopic pngtopic.c -lpng */ #include #define ERROR 0xffff //#define DEBUG /* Globals */ png_bytep *gRowPointers; /* Dynamically allocated by libpng. .png file is stored here*/ png_uint_32 gWidth; /* Image width (in pixels) */ png_uint_32 gHeight; /* Image height (in pixels) */ int gBitDepth; /* Color depth for each pixel */ int gColorType; /* 3-bit field describing png color type */ int byte_to_nibble(int byte); void usage() { printf ("usage: pngtopic [-i] filename.png\n"); printf (" options:\n"); printf (" -i - invert pixels\n"); printf (" -p - preview ASCII image\n"); } void help() { usage(); printf("\n pngtopic converts png files to gpasm include files.\n"); printf(" These files are compatible with gpsim's graphics LCD driver\n"); printf(" Copyright - T. Scott Dattalo\n"); } void error(const char *cPerrmsg) { printf("%s\n",cPerrmsg); usage(); exit(1); } /* getPixel(unsigned int row, unsigned int col) Extract a single pixel from the image. */ int getPixel(unsigned int row, unsigned int col) { if (row < gHeight && col < gWidth) { if (gColorType & PNG_COLOR_MASK_ALPHA) { /* This probably is not exactly correct. */ int pixel_byte_index = col * 4; int byte = gRowPointers[row][pixel_byte_index]; return (byte>127); } else { int pixels_per_byte = 8/gBitDepth; if (pixels_per_byte) { int pixel_byte_index = col / pixels_per_byte; int pixel_bit_index = col % pixels_per_byte; int byte = gRowPointers[row][pixel_byte_index]; int pixel = byte >> ((pixels_per_byte - pixel_bit_index-1)*gBitDepth); int mask = (1< (mask/2)) ? 1 : 0; } } } return 0; } /*************************************************************************/ int main(int argc, char **argv) { char header[8]; int number = 8; int is_png = 0; if (argc < 2) { usage(); return ERROR; } int bInvert=0; /* Command line argument for inverting the image */ int bPreview=0; /* Command line option for getting an ASCII image */ int argCounter = 1; while (argCounter < (argc-1)) { if (*argv[argCounter] == '-') { switch (*(argv[argCounter]+1)) { case 'i': bInvert = 1; break; case 'h': help(); return 0; case 'p': bPreview = 1; break; } argCounter++; } else break; } /* Open the file containing the image */ /* A few preliminary checks are made to ensure the file is valid. */ const char *file_name = argv[argc-1]; FILE *fp = fopen(file_name, "rb"); if (!fp) error ("File not found"); fread(header, 1, number, fp); is_png = !png_sig_cmp(header, 0, number); if (!is_png) error("File is not png compatible\n"); /* Much of what follows comes straight from the png documentation. */ png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return (ERROR); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (ERROR); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, number); png_read_info(png_ptr, info_ptr); int interlace_type; int compression_type; int filter_method; png_get_IHDR(png_ptr, info_ptr, &gWidth, &gHeight, &gBitDepth, &gColorType, &interlace_type, &compression_type, &filter_method); if (!(gWidth <= 100 && gHeight <= 32)) { printf (" Image is too large (%dX%d)\n",gWidth,gHeight); return (ERROR); } /* One way to handle png files is by allocating memory for holding the image. This is recommended for small files like the ones we're dealing with. */ gRowPointers = png_malloc(png_ptr, gHeight*png_sizeof(png_bytep)); int i,j; int pixel_size = 1; int pixel_depth = (gColorType & PNG_COLOR_MASK_ALPHA) ? 4 : 1; for (i=0; i>= 1; db |= (getPixel(i+k,j) ^ bInvert) ? 0 : 0x80; } if (dbcount == 0) printf (" db 0x%02x",db); else printf (",0x%02x",db); if (++dbcount >= DBS_PER_ROW) { printf("\n"); dbcount = 0; } } } return 0; } gpsim-0.30.0/extras/graphic_lcd/AUTHORS0000664000076400007640000000004213041763630014460 00000000000000Scott Dattalo gpsim-0.30.0/extras/graphic_lcd/doc/0000775000076400007640000000000013117466030014237 500000000000000gpsim-0.30.0/extras/graphic_lcd/doc/mgls10032a.pdf0000664000076400007640000020506413041763630016354 00000000000000%PDF-1.4 %âăĎÓ 4 0 obj << /Linearized 1 /O 6 /H [ 593 155 ] /L 68148 /E 66760 /N 1 /T 67951 >> endobj xref 4 9 0000000016 00000 n 0000000523 00000 n 0000000748 00000 n 0000000963 00000 n 0000001085 00000 n 0000001104 00000 n 0000001126 00000 n 0000000593 00000 n 0000000728 00000 n trailer << /Size 13 /Info 2 0 R /Root 5 0 R /Prev 67942 /ID[<39a282b91eca3589d16ada50e93aecd8>] >> startxref 0 %%EOF 5 0 obj << /Type /Catalog /Pages 1 0 R /Metadata 3 0 R >> endobj 11 0 obj << /S 36 /Filter /FlateDecode /Length 12 0 R >> stream H‰b```g`` d```dśĂ€ p@i f…baA†$É@¦C@€Nl* endstream endobj 12 0 obj 51 endobj 6 0 obj << /Type /Page /MediaBox [ 0 0 587.52 829.44 ] /Parent 1 0 R /Resources << /XObject << /Im1 10 0 R >> /ProcSet [ /PDF /ImageB ] >> /Contents 7 0 R /CropBox [ 0 0 587.52 829.44 ] /Rotate 0 >> endobj 7 0 obj << /Filter /FlateDecode /Length 8 0 R >> stream H‰*äĺ2µ0×35R0B #K=039——Kß3×PÁ%ź—+— Ŕ¤Ę endstream endobj 8 0 obj 46 endobj 9 0 obj 65311 endobj 10 0 obj << /Type /XObject /Subtype /Image /Name /Im1 /Width 2448 /Height 3456 /BitsPerComponent 1 /Filter /CCITTFaxDecode /DecodeParms << /K -1 /Columns 2448 /Rows 3456 >> /Decode [ 1 0 ] /ColorSpace /DeviceGray /Length 9 0 R >> stream & l#€Ő˙˙˙Č-ˇÉą‡0ä‡$9Ç*°D‚Ër‡"ącś|ŕ°ěşiÁ¦PB’Ď9NBG DAâo/š,DD3?‰!ĘYFxš€H ř‘áCźhÓ!Ç9§‰îaO ¸+üE®ż˙˙˙˙˙ׯţýß_ëŻţż˙ű˙´ż˙_ňPä=š r-–9‡(r9PA ĺ9ř§!śr"SňĚ9^y”ĺ*ˇ:!'A„",¨)Ę‚‚óÂzYĂ)Ęr¦D9\'EŇJCEŃ!B3hTˇС©tCŘ"čG×é đE@G–¨1a‚ 8aIŃ 6Bi Dv‚#ű8ĺk /ź»ŕÄ`ý°N:Ĺ›˘äŕ­B, Zob-‡8ôŚH":ýEÝ Š#łtˇ qaDgpč0‚жЏNŃ„4"î]8ëďňhNşÂ":ţ„‹3ůGâ—"ń"MBDvc ‘âD]dqˇ ¸7#†Ď¨‰8Źö7îżý˙ďőőŻ˙­˙őŢźď˙×˙'™A™Ěç‡*/Ň‘».‹˘ńpČ˙ÄDDŃEăx-+Ţm€x6ýhŽGŽXä{SrÇëĽDD†“–9[âś/ţÄHĺRUĂ·˙Ʋ†_é‘*•ő‰îGÇs?˙hDC•WS˙ÄZ{˙ď§ßű˙¨3 ÇČăˇ_âěđťń„<ť~ż|˙ű]˙Öţ—ôżşúź Ű_˙ ľ÷ëţżő˙—ýú˙˙ďµţ˝'˙÷ëúë»~×ďţ·Żż„Ňň1ŽChr‡!G!\†hä4C0rd“8ä[ @ä8ĺVr Ç @ćă”9Ç'‡‚9CŁ®|#®+ …ÁNR rÇ<Ęrőrrś´Ö¬Č Ç8ĺpGóČDDDŁ.!)ŚŽÎčŽÄ""""""""""""""""/ő'¬GLPä(çsą‡(rPXä ĺqČ[*…Aܧ"Ůc“ăĹ‘-Ęr oÎ9 @Ô ĺÁPGçˇÎä2Ç,r c“›‘Ăś2đ¨;3*”r°ˇČÇ*eq¬ťŕĂ rŁśr ŽLr ĺS@_ä ±Č=śr‡;’ĐĄÓˇ ŔđTD13ŞśrSśsAĂTrŕĺXäc\sXä09Ç!°sAÇ,rsŮC•g™T7źR™śÇä`ˇĎdÍÔ* á—µ¦Ŕ·D‘Dd ĚŐ–q2>ŤGäp=":1㹢0¸-/ x6qĘ2N{* ˛™pĐ[ťČQĐŐ–Y˘˝`mľC3ĺ7),sw*d#–9 9¸ŽČ#*ĘÂ{N|Sa˛ćhřR莖dŽ"ť˛čꉎŕx*Ń#†H‘ČŹůEČŔČŕm~„Jţ28…Ŕž$Ţf fňń"qĚ9+)ĚS(X3Ę""C$(äqĘąS8äp""""""""""#čÉ$GF"8d‡†¨DDGXj(HđDDDGçbČą‘Ů4†ÄDHw8äG8ä V&äľýÍ»ďt,ˇ_ő—_߯ëďűz­¸Ňý®×ĺŃQß˙ xjE>˘DĽ ż^źří~«ßő«ýëô@đTň‡4wżý;tśGú˙ß{ţŐ˙ůß·{ú˙˘ˇř˙ßX*ŠŁ»×˙ˇý+˙­Úőż˙Ůł?÷_˙^„C˙Öżö@đ×uIöé˙č~ż_˙!8ÖaÎ=î«P˙÷„"&  Št÷ŢýúÂ%úŹ„GUŹőů?v(BŇŻ˙˘-Ͳ:_D¬§*g¦ź­ü'u»â™!/úřUŢń#¶Çß˙Vő÷µű÷şŻ\A; ŻűÝeĚŽ)K™Ë˛‡*9ţ™Űëý_Â* 6ľákúü~ţ.ţ˙˙\P]yÁ´q˙đDŤn?ăS)ęC©!˙Č Z¸/đKď]»8˙‚ ß!ŁO˙âp ±„ô ú ¨Azä1Ł˙ůÄ˝‚!†oŻôň OAŃ85Ň˙U%ĺqÎ9;[´ď »˙Ę&†„ŽŻ‚KýQĂ»őüDi“q öŽ?[TĐ_¬:‰Z˙ň R ţ;EFŹn@đjsŮ+Âţuţ"6D//áŃŻiW%˙ č0îU1~‚ ˙ÁłŹÂhIć®č?ŕÔ«mŢŞ@¤¤¨mŻý AŻńýҬ†@ŽaÎĺANF9ă˙~—ů €Tr‡ ˇĐA~Ó~Şţ# ż o}űĂZýżĄýČAÁü‚ŁîVť9äjD{ßö;>Ťś‹ yÁJ…X"?ÁÚT˙Ř_Żí[â1$ëů aÎű˙ôő>¤-¸@„%ří˙úBÁ"/}@đŘëţ_ýôä1«0†‚턥Ő{ ˙úKŇ‚CcOoŃP)żß˙»řPĂ)éń˙ţß˙Â8“*ű˙§Ü*ëß@Ă(ąNVŹůPf^żŻkľµ„]%Śkô˙˙´‡ż xÇŠż B*ňČÇßýš…ţč±× …˙˙ňMťchŽ‘‘×÷Řü öŻţŐypö"(züď<ʡH9÷×!­Ĺ;ú˙đ ´˙ĽxŤzy“Ozţ«<:NşPßú33óČr_O),2čÂ˙{đAĂŘAľżtÉ›}/ďëđťőý‰˘®:ßżţőUÇţ˙˙Ń8Ű×öqď!ĎÖŰ˙˙H;é˙˙_ý…^vőţ5÷ëyÁŠňëíĄŮW ŰTż˙ŻëDĚ_Ük»KÚČWM~•|ÁWűU6µ¶ —Ż˙‹÷§ÓUUđĘŤu ˘?kE?ÚjÚđÄi}­őâ5Mň躇ň đăNőţ÷yÁ¶˙YđĐ~5áá{ö¬á¦~Ö‘†läÁLrqĎ~aăä Ú÷Ü$"‡b˙Č-‚ˇČjĐ!íDßÁ*ZčE˛c•dAĚ:űi„Ô‚Ři9'ţŻu‚ZŞďĺT˙MuAßúÚYÁÇ(GÖ¦’r1Şi©ĂšëďĂ\â‚đJĹa8‡G—ďś7<ÜŘĚv©°××a®@ů¨®@ó˙;ÓkţtŻi{đČW q!ŕĆ«G !w…CëWţ¦ĘÚ˙¶aĘ#@ľ.4Ů7/ľ˝éö´«e…ţÄBéí¬ă}! ˘ëŢ—OŹ ŘŻé®×Ř5 xŹÇţ˙<‡ëĂ_ěÖ0eÖ.Nż˙ç@<3˙a°T@ńÖP˙Ă&äG1˙˙á…ţĚS xT˙„]b+˙˙ě8˙ä2E#ür?Ĺ:˙˙íŁ@"Cg_Źęˇ†ľG@ź˙Č ĺtë‘Äúë[Ç#˙ x«ö"Ż˙â c ˇĚ9NWˇ8lĂ” ˇČdžą°Ýg÷˘Fź«_˙şś2v Żű<4×ď÷ýµcÓţđîř}_űkŻő x6ŽSŞ˙ţ˙îNC$DNg˛:#‘/˙¬G|†@*í^˙îAHąČË”9 BC&/B""?˙â?Y˙ű$"8" šČ ËľEď! ăëäD‹ß|řhŮÂ˙UŃOžÍ'˙o×Xâý]ű‰ tí%T÷ţC$:$ľżŞ¶˙öżţC$XFˇ˙˙1ž_Ö˙Č`sa!Ďź˙a?˙â"sůÁ‘¤ĹĹ˙˙Mß˙â7<6ǧ őż“É:éĐő Ţä [B†ýv©¶©ú3)î@„˙ä‹˙­Ňęšč nżü ţ°PaďŻjëÂżúHQÓyĂ@áGűöÂVŮCĄTý˙čĐ;í+&°<?űÄmuő˙ÂżÚ xŽx‘xţת§˙ż÷„ŻÂq^˙»´×˙ţ’M˝|Ž3  ]Xar `­â " AÇď˙űAjŞş>řńׯý ÷ú˙µúÚ˙őtűl7.;p×°a_˙U ä (ţ ~”0ľT%kűëű‰Ŕđ(řű /űŻĂ^©Gďí¨0—ëý‡ÜŕŮK x0u0őY Ä8ç &G˙Ţۦ@đk´tň‚ŠwčD? x*Ž@đ×9NŻ˙­µ ţSášC˝?ż˙ČÁC”;{„0Ϣ@<2:‡˙č0żßč!<úI}‰$/]x`żŐţ"őáä ą×Źd —O˙_ń <˙Çţ´¶ë xeŽ ăď˙ľß<2¸˘2 â[ż˙îŇÄlÝýH‰?˙żÂÓŁö˝˙°aä4‘cřű˙ęŘKÁ/! Ł˙ý~íŞä2ę}5žeQü‚?˙ľ> !ü%Ú˙xYËň.ft2:o¸ NC Źî"ŞDňśˇč!WZýŹý`¨Dđ3Ń8fň®9˘5Ő˙ý'~=ŞżXIÂtŹ„3o <6ÜŮŹxA?úéA|LŽ”†Sż¸Aď´“mV‡ţ uýZTŘÁ:ë w˙ďöČ=(DďĆ{!’ß˙ŇţĐ"ëëý/ńH Ăű_ŻţľśgĂS@Â(÷î˙ößá”>”^@đÚŹÇč‚Ř,÷őWi)çˆWOßň a±Â˙sP÷íęßú˙ař“„Xa”;ßĂ˙ôÓţňpsz`Ĺ®ýűä IýS˙ľ"°ĂëĂ×ý$|Ă˙Ĺšµ†Ëü?ľ?¤ő  ůĂ>5aďß˙Ą ˙r:በ ż xqÍđĐl‡˙đ’đ¨Í?!§Bí<â»a‹˙őI˙Âz÷ĘţR+ţým˙¤ ßqőńúę—˙8*<5×Ç×÷ďú¤7Îř§ÚKłŘ†ë˙WűJÖşř?+ ď˙˙é0ziŢ.—_˙U˙˙H kşě"‡ Ó˙Ő?ý?‰>łÂ[?‚‚Ľ/˙_Żz  |ŕ\v,%şd/a 5˙˙ý]R¦ŰđÝbaa‚]{ú˙µTéjő„a4&`ŠpB뮿_˙§Şř‡…ÂTBŃÔ˙_őş_Ţâ<2ľ,"l˙Ů ŽA­˙ţúkZ)ęA™Ř)u·! r»Â ť˙˙ďôĽĐSŕěD\&? ľľť…Ą˙íŐűA$ÝDÖ?[_˙żż˙§©Ŕk.·‚~ě5é˙ x<:ŐÚ˙î#§řaĄ×ďvŞÉÓ(zX"ź§ČLŃA~›+_őaŐ"*ăőÄF`Źö_ľµ -­ČÇöň #˙@Ţ@ô?†Â ×ý†AÇ Řj’ýŇ NöSż ă¸l%®ľíˇ  q´ß Ü~§Ő¸˛‡ţżĂ ×ú‡Óď!(sâ#2âŰ;Ú±Vż˙±Mę˙‡®˝b#؆S©iá%_˙M}~á¨.ČÎHrCăŢ"„#<Žżű _üGâ )Íué˛:żţí7_ëÔÔ’a—2>Nkg’ Z˙ /ţ©/ýĎ!ú’±Ř™¤T?í/Đo_ţ@ńŽQřDQĘó÷Oł4™|Ź D~Úá‘ő„íWýÂdÂĐůŔŔţ"" ĂíĄá°ô·˙ „Wń\:#ŞááxH7j—ú§_ůŔŔţ ŮOáÚéĂm$ŻúžʉôűďaăńÂMŘK˙XBĚÄ }Ąîä+•f‚‡ü‚ýl0P’˙¤Đa»×Ź‚a`ęů5ôlUÝ}zjÁ? Ú˙Ý:żë xÖ˙ ô‚vM}{ëŻÚčĎ…ý;č6CďÓďţ»ŐéעruÂh}ÖÔzŻHQvAY˙A˙4đVePĐTȰS¨5ś‚¦E“žg9C 9Ç)Î9¦y•Ç4a5ýýűŔîÂ)Ĺz„Ođáe¬ˇ„DDXŹő°×­5ŹęźOĐMÚ¦®Âikű˙§ý>„_ý¬0L-ş˙é6?×[Kéa“â­iU˙ţ÷0„ŕ¦h‘oďbgŻo˛Č1h2o^żým?^ř0 /Ż!Dź¸"ť××Ţż× xaÚ˙Ąľq[÷˙oІGĎűŠě6ů~Âßú˙cúô¬•WßŕÂŃ˙[ý~6¬Ž‹˙*˘´ ®:űßý{ű^@đĘDGb( Xý˙Ż‹ ď{đÂ˙Óďńëa~ *˙ý{ /Á‚˙Čű}ăC^7úŻż˙ý~éÖ’˙ÉňsYND˙OżĄ xe<ś<(äŽV…pAţ„Dđeż˙Ţ˝ü˛řďÓ˙_˙űÂe8@ÖIĄ÷˙ľúúôëh:‰Ĺú˙Kýü†Púc.‰żČe#˙˙őÄÁĐn3­¶Xčŕ_á˙˙˙ÁŹFhľÔ\<ş^‚Żý˙üá”:đ„‚t ¬íí„ţ÷şŻŹ¬ ú뿥˙ĺŹukűMýzřA˙ă·á‘ĂA3­Ů~ÝZ÷á˙˙>"‡Şˇ^:ţ?/ćţc÷ů €]át˙„ńëýä ±í­˙YuđSŽLsŹ˙ż¦,cĂ—_űëâ"p2˙˙őőĂ éđ»(Nż×ézľ pľ›×ŰW˙ţëÖÄő}/LŁ˙ďŕ‹©p˝ľÍ˘4ňĆüG˙˙膫ţO ™đ·8ç^ĘŻo]/˙×ümubl`č!V0ľ˝÷˙ŽC)ëÝL8Q}Ă"!]Ľ+®˙÷ţÄŠäAÁ˙Lx"ëDx8ű ‡Ö/ČM G×˙ÂżŮpŘŁ˛†SE:8 -oé ű_üE{ÔH·ńá„$ČĆôżýG˙˝ëżČâ=ôSÁ˙\‚¸˙äqË‚ZŐ<פżýÓö^04˙™°$üW]éĹH8ŕËě¨ücŹÄk˙R uŹţ˘AÇuu!bÄXú­‘×Đ%†PĺPçîPĺYĚ9VFé“ňśšBť2†r‡,r‡3rśĂ… â§(iČŠRrn+ü=â /ŘKŤµýň,öaýkôĽbĽ\íeu˙3»Ő ŤőNü »ýĂ+T?_¤Śh+K¶Gţ_˙ę|Á› tÚIqř˙˙č-´›IuţČ09Dz(ä2‡Č#šK(r­ra”á¬3ŔĐíđUů ŃřŹ f Ä~%=†P a–éä)?Č^@¸űx0Î9Âľ’{^žř ňäNŚ+iRUúě­Ei­5ÇÇ!±Ę‚ˇŰJ«üH09‡0ä3# aľ˘'q¦á*Ýů ¤b"9´9nPrŇI;ř^„Dč†`Ô˙f!¬:˝uáŞa~äŽŐ_`–“ß ·TuÚaTmş %_‚ î›ő®ĽkWôÍU'ú(zu @ĺľé«đ—Ó¤Č|oŻ3·iS„?O|fÔAú]„‚6`˙ ęŻÝ±ÇIşK‡ö˙˙n‚ebIëŇ).@Đ4˙ű© ú±HTAśsaÜÓ‚śĺąÇ5iŽ[śrÇ"Ys(s9“są]öşd#éü8f…-C!Čě•”äܡĚ:2$|ů/‘Đ‹B,îh(sĚĄ`BŕÂ3B#ű˙ÖţaeŞIIĘ:e+;ˇ1B!hG‚#˘:Ý_˙ë¶H ˇ§ă»)Â~Čzţýý°Ë†ł@‰’r ŽrĺH( 2ŁÄî·öF0Gp–""$ ąěřSsq‡<ć ±cÖB9ĺą‚^x{úúĺ‡NÚADDDDDHAČ08úýŻßmŠB #ßďýsy†„K˙żďÄ Řb*ëö×˙°a„_ýĄá†;‚tl  żý°żřlP`‚Wő°ikűA0†§„sˇ˙öHżđĂ Ě6c˙±WţÁzŽĺ‚ď˝§ŻĂ Á42»řakřfdG! ?ü0żö Ä%˙!‚Ł_ĂA°păuř3^G ˙!h+!…üăŘ/ü†@f$m/Áł‘]/¦Ú_h.˙M´ż!Şža ČŕM^ţdŕĐżm „?üđlÉÂd‘ř’q˙´`€W:/Çţ©ÁĹ˙ĐtĂ ý˙®Á‚˙÷ü#@ě ?ő×ôšÎő˙˙@Đ$›÷mHĎ˙öëî+˙^ť*‚ A ţµŻďІ@t¶ý°O˙ţşö $týČ-‡ h N@˘Ź˙ĄţÁ‚HśżT&O˙˙Ů­ h˙ć€h!Auׯ IŐQlR0˙Am0C4Á Ł€‚„Áo˙ôPy ó ›ü†H6ńB0š (L($ ˙×sXś‚h $ţ… U5 @y!˙×  ĺöHAnPćˇĂ“¦ j¶@đ×Đ@‚¬}gQéâ""u@XA˙l0s¤`LáČć\ó„h.pCî Ażţ•ţC$ 8‹ŚŘehDCŃ n‚a¶@‚-˙żú¶žş÷÷Á"aëżů Ú‹&VkţüĂő˙AÁ\ _üŔŻÄ3X™H€5/í~ ˙˙ö H-˙Űů 1Č`‚€¦ő˙ř}˙ßřP/×Ăű#~Aľ_~µďŻúżőZ˙ţ=Źż÷áőŕŕď˙ü†@4Đđ{×ý|/ßęľŰ ˙÷Ż˙˛´˝ÖßüĐ_˙ď§÷ů eźp/Kúö°l0`ÁţęM˙ý˙ëPźµĹńÁ Č@a˙zv¶—…˙őT­ĄŻ† 0Á˛ Đ˝Żú÷>˙ap@ˇ¤Ă_đĂ 0aá_żµm}˙_AĎaXa/đ`Ă í;ż˙ë áDC@ů ß a ˘ §ĺ$µú¦ˇ4"Člń»!˙ŘL!Ĺ[ ŽA/×˙lDI `Vx2žH˙ {ŻÂ)ŔĚ Ô€¤4sŽaô~%ëé €näŽÓDD’á™Ř÷˙  Ó ŞióX5pÂđľä2AĄŃ95A˘CkŢ×µĂKÓ@Ńđy §.5AVS–9(»F`úG&¸`ü0¶×űAd4 Ë» xh ŞO6\¬!pN@Ú°Ň÷´ť4áĂ őOµ/˘říĄűŻ]µJőűČfjźěA~ :ućÓ{§éżČ5'ńd€PżoćÂś › l'ożŻůhmAĐ?†=5Óľß}uđuí6+Ô0˙ű Č,„˙Żň ´đŞ_a˙˙Ó|_ţţýHd‚äđ2QđÝŻ÷ű®—®ë6:h2…˙ ?ţľŰZżűńô«L&@ˇĘ˙põżţyáËvÖŐm,†~Şb>­Ú˙m¨ŤĄĄţAyóúţýĂ Wýá†mRa®A˙é#Ďű őw˙±L‘‘őa-°—§˙ŇOřa±Zţ–b)Ť&hzäČeŹ˙H&˙Ă^ş~íVĂ&O´˙ÖżŰa~ßá„ &1\đGŞ}ŻJ˙†í4´Őˇ!’H…­ŤĂ<ż /×ř`ņaa„( Ꟈlŕ/˙ě8Ť ÂTŞű¨ŹĄĂ´Đľ—ęÖ»đÁł˘L‘WßŰ &źëŰaša?˙†˙~ć8eŔĚŕAŕČ~•~:]xlE0OőçĂ1W˙´šdőř!ďČkŹř®C( í%˙ISţ–ÖUßü&ţAor‡SŤ®ĹXöşŻ‚Čeô»Ú î©-ř&@đk„ҦćŔż{ű­/Čd>OIŇ}Żě* ż!’ C4PNż|0ża‚J‚ü-˝wńdsű•eŹČdhĺWÂ˙ńŢ’Wđ„†ŔĹß_ţÁ5˙Á ú}_ň ň,q§ý׺]rˇOý†Ăé˝{Ý0O˙ů¬ á˙ë×ߤżÉJĂľÝW®źďů d¨0őđ«kŐ˙×ÉJ‡ş±íŻ<ŇýwŕŘa÷T“ %Ň ľżđpĂíZŕÁz§˙Ż [ ZiŠŇß×!¤?ŕˇěC Ň˙Ĺ|†H2ÔÉZţ»rCďä2AR·b‚úż×ü†H6V g^µÖšţ†„_íďĐ!H`4m/˝ä aţǵ_ŰńöF( ,P^»˙K( ř%ÝÚţC$Ć+I˙1‡ţC$ *ß˙m˙!’á…ý«ŕů†˝ö×ň aľb?í˙_űâ˙i7ţľřoýţŐŹ˙îź˙ŰP˙ţéţĂ ˙Ř0“˙ű ˙±_ţÂ˙đ×˙ ˙ČŔ˙ü6čAf„Čkń MHZä @¦˙¦Ax `¨Oű I_ő´Ó!‡´Óý{ýVÓµ_˙_Čdwś‹šŃé§§8Á#Ó!˙˙út"¨'ž:Ρ„ż˙˙ý´ťŇ}_˙˙˙§¦úú×ňŔV˙őŢźW÷˙żýkß÷§˙Wű$9‡#r w˛Ç?Ég0ć˙ő¦˙˙â"""""">t wň=>C ˙ő˙żý?‡˙Ţ˙ä ÜÚ˙Żß˙˙ů ómö˝üŕËß˙óc#‚äpĄĹ#äq‘ăŮvlyĐŕWéä'y nôk ü+C˙B"",!É,rNE‚,ËĂžĘrĘr¨żđ×·Ů ľ*˘¬Ô)!°ˇÎ<9 ׏ <4‡˙ţ""""""!ë˙ţ¤""""4Č6Gą S‚ ÎO˙ß˙ţ˙Đz„ż˙¶“˙ţ˙Ýýv˙­z˙˙^îűô˙ß6D Ő˙˙»Č ŠĎvĂ­|"s˙ůŻűő\Ôażî‚0ýŻ!žo˙˙ű46ţ°@ßűň_˙ęüy´ĂŢ7ý˙ăł ţ+ôďýaĂ߯˙Y˙˙ýżż„`˙˙ýŻň84˙˙mżü ßßďČČëŞĚ~˙o˙´`ëëżÓôí};RÝ5×ŰżüA‡ŻőŻiw}Ż÷űo˙I7ż˙öľęŢÓi'Ąkíţ·…a˙˙öě-…ö¶Ý˙«×˙÷Řţ)ŠŠŘ¦+ď˙«˙˙ö˝¦źwö˙ď××ď˙wi¦šk¶˙č삝ÍËß˙p NatßďŽô:÷ţ˘" Ž Ŕ‡Űż_×ëńnżż˙˙_ż˙÷˙ý˙nýęż_˙~›Żű˙˙ ­z­áż×˙ě~»˙ż˙ú˙Ű˙ŻďţČiéŻíţ÷˙˙‚˙vëë_˙ů Ŕ{˝m˙_ő˙.MŐ}‡˙Ő˙ţC@ýíŻßëůŇ?řiŢ˙ţV*÷Şm˙˙ř!ß! ăŢKűő˙ůN $ČiąH!f¤2\ä5hAćCV„5hAçŰŻë˙˙‚đL!aȡ0 ¸é„Âᆠ_~˙ţĂűTÝ4i¦ťŻ¶—˙˙ţ ÖŽTűítôÓżbő˙˙QŞ{­.Cc¬ôŃćç×MQćČăřký˙˙Áý&Ž„űŇN‚îpł„č:~ţ˙˙đÇőŇZŻM¤Ý>“jÚ]ű ý˙Č5Wűű~•==~ôűŹ˙˙ţ űMô˙kíáęť§ŻŻęźţ˙!®}ýiţżÇÚ«kî×ţż˙÷˙ďß»Ç˙˙żÁ˙˛ ˇĘző ˙ů”˙×ű˙˙á˙ýţşj«÷ţż˙ř˙w(ČoýżůĂ*+ż˙úüŹęÚZ'9+׾÷˙_DčŔ_˙÷údGČ/„4¤˙:frrµ®×ü…ĂÇĄäG `x™Ť˙˙ýičś@‚ ťä2Ő{+acő¶‡Á/!—°k˙˙÷ü.š ?ˇĹÖ˙˙ݎ˙ż˙˙ÚzOţ»˙_˙˙˙˙˙Ă˝/ý,?˙˙ż˙˙˙Ţô›đóyŚ"†o8—Q÷áüĹŔć7ß˙˙ß\âwŁŔOňí"±R§˙†üDYN'ý˙˙Ăżďł ' ąţ˙oŮ ×˙˙×é9 g_φ‹oš_˙˙6 ˙˙ý˙Î_Vţż˙ˇ÷ń˙ß˙˙§ű~żđeŃuZß˙˙ő˙ë˙Ő˙˙ÄXUtż˙ä2A±˙˙ű˙úż˙ý{|ŹOô»˙˙úęßäOý"7ôôď&䎿č7×˙ř¶ľCDZëý^®ľŞź˙ w˙˙řa~%ú{˙ŞÚV˝öšÚűţżo˙Ăřďô­KmmC85kÚÚ^ý×®·öj–ďöÚÝ~˝”vĘD]-´›_ ű˙züo ęk ;ß˙÷ň4Ç˙ x!˙ý|ý ‘@đw˙ýý˙ýűMŰý__ű×Nć u˙ľţ˙×ýŮ 7/ ˙ }}˙ îA˘>ż›¶‡†˙˙˙M˙č<0ýý˙˙8ĺAPPĺ9NźwţáÂj ?ß]ř˙˙Ý<0˙˙˙˙Ż˙çg ?×˙˙˙˙} o ˙˙Ż˙˙ü'Ă˙öţ˙÷Wż­> ˙˙äß_˙˙µü7˙˙×üŕe×ë^ţ÷ßń˙§˙ţ_Ű˙˙÷˙ë˙bŻ×˙˙˙˙˙ŢÂŕ—˙˙˙i?´V¸A˙úýŻâPeaVTá˙úýý†Č+čA·8ĺ?ř±„˙ß˙Á‚ü2 HňĚ9ě®)ü5 ż˙_ëŹőşČd†qÂAćA“fC?{X ż˙˙ö˝5OÓA¦!°pL üŕ^4YĂpK˙˙˙kßü‚¨öŞšh4Ó x?<7r ¸ ż˙ýo yĽ› ˛>ţŐi=;M|*®‚˙˙îý…őĐ·zjśŘeźúa˘:#¦Ź¦ź¦›äĂ˙˙Âi đaI}ę—7ŁĆái®ŃśĐ/˙ßÓ\/_ţ’~ť'§Ýęl˘ž_ęµţ¸ýt˙«}?NÓtúŞ[ń ý˙˙˙ŻR Gú»MV˙_ _űß]?é_őŻdÇß&=c¤˙×<2ÇŻý~ë˙çA?ó‹ÄĐ?"Ţ˙úń/˙˙őżý/‡éý˙‚˙˙żKôß(Č(„źo˙_ §~÷á/˙Ż÷˙oŃ 1ň!}˙őôi— uü _˙×úŰďšÂ?"'!°rt—!­ő_ Ź ń3EĎúá˙˙ţ˙Oä3WËÝ+Ăw´> qËđÂá˙˙ëŻöý‹ {ţúOŘ%‚_˙űľľż÷ż˙˙±čß˙ű˙O˙Oż˙~î× ˙zţ·őýśDy(G‘#łaČăI˙ë¬ŮҢřa5 ˙˙ý ë~lč Bş˙ ô3Pzᡯ˙˙˙ëů ňçő˙»ěĚ3üG˙ďé˙Ő}—˙ `w˙˙_×úŻĆĽ_ď_ý!’ŤňŁä09ÔwČ(“…-É9‚ď˙˙ýůĂ//˙˙ň XAaČ0Ź˘ ÜlŤZC¤"(ËP„N†Y ‡A x/98+uë˙öżČ‚?UÝí4˙UOOě&Şš ˛A˘I‡(ÉŔ‚ůŚŽ‹äpÁ©÷µ˙ţ$oŐ;R7!ż]U~˙˙˙Uý¸˛ B˙˘Ďýö¶ľ¶šşţé˙Jţ×Óľď~ëwţAÝ?ďýS k·­¬5ßi)ĆČ_óa•Í‚śqgđ"C)ĘîA•6˝ŢŻőMV×ý6Ů9ŰR Ç)ĘvWkkřÔ ä\‚ä˝>Ó‰§ţ»V×ü iE1B"ÇĆĹ/ Ľ'˙‰Â]aě¨(r”!®ĹEŢj¶_ת˙˙ţÄDD~ďű«´Ó ¦O˙¬ţ˙˙ţ¶¶«ńq hCMk˙PA˙˙ĽE ×¸ŽëýW˙˙üě$GG"<]čĆmä qČţş˙Ą˙Ż˙óÎlâ?˙k×˙˙_˙˙í˙˙˙Ú˙Oţďa˙˙ßűý˙†}?˙˙˙éýŠű˙˙˙˙×đ×i~˙˙˙˙ű ¦_˙˙˙˙üŕÎqŹý˙˙˙˙Qk˙˙˙˙˙ *˙ţżüŕł‚śů €^d3ą Mc5r†‚ĺcC˙ý˙ů‡ AÂDGá0M2"7ȉkV?˙ű˙¦žźé¦©ţaë˙˙ý¦©ű®«řM?u˙˙˝SďÔěth*Lä˙¦™W)ý_˙_ýnl4?şp ¦ĂAÂwüĚ3ŃđŘČ5$ü˙ëZz§˙¦ë§_át?˙˙˙§Ňo˙Ö’oýđ›Oß˙Çż¦˙˙§J˙ţžť?˙˙đí}?ř˝t˙˙čřl˙˙î-ëé˙żĐű˙ëď˙˙*?˙ţ˙×ďßčÔ/˙҉ń{˙ë¤˙˙ëţ“˙úÓ˙«k˙˙˙˙~żŮßůŰ_ě,˝˙˙˙ęÝa?Č0u oĺŤű l‡€«˙˙˙ůÎôF"8ţF\š8JČâčŚ]Ĺ1˙É ˙˙ŕ“Ţ@ş„'?`„F@‚$0U~C,·éÚm}W˙ȧ˙ ¸očGĹ„ˇżŻě&­}˙˙˙ÂOę˙v˙ö `ˇ‘Ž˙˙ô˙ęýý-˙ú˙~ţß˙GĐ/Č5h+Ž`¬ćňLć˙!¦çP]놿˙ő˙ĐCř5„ôA5K ţ,ÔľÂ˙ëë˙ëů@/ň:·ţh |ĺŽVˇŻ˙˙˙Ňýž úńďÁ˛†°ĺqČ®˙˙ď˙˙‡˙ßţ»LDG˙˙_ţż˙÷ż˙5ő˙ß˙˙˙˙úDŚâ/ż˙ý~ż˙ׯ˙ţxýţ˙ ¨˙®˙jMČlľ˙ôm˙˙˙ ®˙ä4B műUÖŐ˙§˙ď˙Ó˙˙_ű~í-÷_˙˙ÁČAÖV—ýšv†¬4»˙o˙˙ňčôAělÜ\VĹFµţ—ýř/§vÓ^µmt×˙˙˙˙…ýé§˙vťÚţő˙˙Č4ýĆ űh˙mo˙˙ňJÂ˙˙đu˙˙˙˙ü'M?ţ@đ–h8ţ˙˙˙˙×Ó¶żúÄ~×˙˙˙ú›Ž¸.\Ŕ¤pćŚŽź§łS^ďŰűż˙˙˙ţ"""$[ęuD{°q˙˙żŐú˙ŻżôN Ľ0‡˙˙˙˙ţ˙éůŕ1ÇŐ~ý˙˙˙˙ű„˙»ţ«_˙÷˙˙ţż˙űz¶—˙˙˙ýő˙˙úĐ˙˙<;˙˙ßőŰ˙˙ý*Ú˙¦˙˙˙˙ uőňĂ©pÚ‘n[_˙ë˙˙ż#ü!pÂÜ40—ţ˝˙˙őÔG¨Du˙MŠXŘ˙˙˙˙˙¶·Bý¦żđ ˙÷˙ż˙Ý­„×ţ©˙ë˙®×˙âM_ţżŹ˙׆˙ŕÁ ěő˙ß˙|r˙˙˙ď˙úţ9 ·4˙˙˙˙żŢ#ţż˙í˙ż_˙ű_ő˙×ďż˙˙˙ţ÷Ż˙˙˙˙˙˙<×˙˙˙˙˙}˙˙î˙˙˙®AT‚‡,sőÓ˙˙ő˙ţżčDZo˙˙˙© Ńż˙ö@Ś8ç­?ý˙ŻëŻ˙˙"/˙ýŻ˙˙÷Čd,~Çýq˙˙ý˙üE—˙˙ďďßZ˙ţí?űîő˙÷ë˙ľ5ß~ż÷ďű˙ő˙׿ú˙˙őé˙żýW˙˙ż˙_ű˙×ű˙˙˙ű„oŻ˙ďő qÄAʨű_×ýýk×đDýާ×˙˙ßżjL‚âDÖ]ć±ĘS„-ʬ­'D]˘:"##34a”":! ÁSG%Xĺá‡8÷ďëëŮă˙°aP´Âˇ"čďĂ ˙˙﹢ž:DtgśČčş<‚cNî/˙Ö""""U‚ĎöhŹ™A˝^×ţ˙ŘH Đ9‡ˇ]*HŽŠLŽ‹˘:;dm§Gň:.ŹF­hŁ>¦GŹťQçd/ý˝˙ :a8ÍšTŘh#âGEĐâ"%-DtE‘#Šp#˘89˙oú͆ą>‹Ätg×üSVžtAsad""#Đ˙˙ţ"""@đQé×á=;˙˙ü(äAç†zᮿŰ˙ë˙U0‚űFqÉÚ ň>\Í2ń 2‹‘ #†¦y‘ňčŔÍ@ÖC˛śä0¬3dffĚśÎâ™™#\!čŕ»˙˙w˙ôëÚč&xGDGĂa¶p6Ť†Ńđl8G" zĂTâ""Ab?Żý˙ţ!ŻA†ô~Bí;ÓôĂĐXojżĹ×˙Úű[I6ÚK˙ëŰ‚ ˝oţż˙˙śMHn)~BŽ[ťÎ9śăů Ü)×÷ GS{ý<‡Ţ˙÷ÇűZb*ˇ&Ú_‘Ü‚€'Ý´“îŻë˙˙á¨PŐ¤mĐ⊎-Ňmţżďţ˙ůĹvKd†«Ąéí¤ŚŰ~żŻ˙˙V:k¤f6ÚZČO†ôý??őŐ˙¶¨GXA˝.l ćŔżµ ß˙˙˙ţqϡĘs9C•ŽTĺaËu!…±ÉaC‘#Ă ˘’vÂ_uíŐ6Ć˙ýďżěDDDDDDDDDDEáˇé˝%~ËăÓĂzď˙˙˙ôAHr ʉ —I?^x¬!}7ý˙˙úŮ@4˙p–łá‡ý†ŇWű_h†H7˙úצô·@ëýŹě¤ňzĺ9 厥A<;‘\†l¦«˙ůćŕ3÷ţéř?$żk˙ż˙ş{^@ŢmŹŘ>;Á‚ČaňNAV:˙˙˙˙ ya ˇÇý%[ÁČ4E˙]ű˙×˙×Ý?úOOoôőď}.ţż˙˙˙ý}˙őA÷ëólĚ2l+÷ű˙Ż˙˙żĂý<#Mó0ió1ízO˙˙˙˙ﵩđÓ$đAŻ„ * ĽĘ ·Ż˙˙ő÷˙kîµ˝pKMR}P×µ˙˙ßýűŰUţÜ#¨ýĐţŇ_˝_ÝuňSý„ľşĐUě&ťé톽ۆ@6Çżď˙˙eŻ›M ”Řm‚Čhľhp6˘83a¤lÁ8Ú˛BKţż˙ú˙Đ@ţŘ­ëř+kţš«b§?űë˙˙˙§îŇKţÁ{˙űm%¨k%ď˙˙żh?°Â]ö±˙kkě4Ř^ź_˙ýűa¤±ÇÇÇŰ »ĄÁ/˙ýôx~Ů ő˙ţŘĄ˙ż·˙űëéö«˙ţĂ ţë˙˙˙Aúa‚Kä°đsçrUŻĂ Ż˙˙˙ý?l0‚ô"8ŹĂ ×˙˙˙˙ňNqöC–GżěWţ˙˙˙˙÷nŻb!~ţ]ţ×˙ţľ˙őţ Ľ5ţŘű_ýż˙â{IřŹ ˙ń˙ýáŞy5!`'ţCG~ő˙ţżűa$P ˝°‡Ř>ATr ĂUáš>Aˇńď˙˙é܆ł€Łë§¦ťU{ďµ˙˙˙˙t’ ˙˙§Ţ˝˙˙ëűÂ!›ôűLú˙Ţš˙}˙˙˙ţ‚ľ"=ŞyQë„N ű˙ţ÷ď 0(ŻpE¨Pd€Ó"€Ô( B‚…żŻ˙ď­BďőM;UOżď˙˙÷ëOň ®F?˙w˙˙˙÷˙Čf˙!”:„éöškkú˙!’˙Żü‚©†{\†rOp6͆Ńŕm<  › °X3aĄű˙˙˙˙PĂᮟíSL*Úw­˙˙˙ü‚Ŕ˙ńÁ–9ěˇÎ8%ßűřŻ˙ú˙­˙Ű­ţűő˙˙˙î˝ä 2r†»˙éęšµ˙˙ţţ˙k# 5ÍßQ÷˙˙ëő˙ŘmîPĎă˙˙˙ţ·˙ᨏŻ_˙˙żëYŹŘŻh~—äá‘˙˙÷ľ|6ľÖěÓMýű˙Ż ÷ŘBBąE÷˘ ˙˙˙÷żÎ©đa!á—_˝w˙ë˙ňśľ)ăúß˙ß˙űôß xÜđaĘĂÁS?•2ś«8 Ş…A+5šgA^R s«(rĽ¤ˇČ(r qDjFPŽ¨Ő‘Ń-F°Úüú˙×˙üŢôOś7Ńd3ć‹""""?ężďú˙ ČŔoČ*—+ŕoÂÓ%˙őżűôĂô.z§TŹżű˙˙˙ĆašÁĐ};őV·˙˙˙őđoôś‚aśŚr*e:›5ů°ÉNARČK!·d kÝß˙˙ď÷ŕĚ#čŽŃ xô""".rÍ˝Ł0^ŕ‰¨P]ßë˙˙żü ańő«ř0OŐ?˙˙˙˙׏A÷˙ÝÚÔ_˙ű^ż˙˙éä ŃÓŐ‘ő cŢćku×Ç˙ţ˝ň4Pü<¸x¶A˘âŞšňx ŘO˙ű˙˙kÁNZwx `˝˙˙ü_éîTŚ5 H9ű(wŢŞľż˙˙˙żůą´Ý4ę)=„˙˙˙˙÷ţƦ kĐaę¤Ç xŹţ×ß˙˙ü˛>a~ţ"˙˙˙˙×3Úxaţ -q˙]˙˙ü†ÓżßĂX{ă˙ë˙˙˙… ő×ő˙úČŻ×ß÷°¸ý˙ßűőúŻx÷ýő˙ýăß˙×˙˙˙˙˙˙˙ŁŹ~A¸Ź˙ď×_ý˘!±÷˙Şođ˙ë×»˙˙z˙˙ú|öx5~C./ ¬?Ěsn<‡âNk(r‡)Î9ě·* ⬟CŽ|(°é?˝żţşČ>á5ú~C?^y áĽK˙˙ŻŻý/Őč>źßôď˝=˙˙˙ďýuÇőý4ôő˙÷˙˙Ż×÷ä0Ź˙˙_ţý÷÷ďú[(A‡8ĺPćĂŽqĘ«=ťĘr,ĺaďŃđoëö˝YĎ˙ k˙˙ë˙kQ'Ăű„ŹâĽ&齯Á?ż˙˙ďmVţ«˙ż˙ …ő|5˙˙ěWýŻűý˙üíeD›#˘ůž]_đÁë˙őU3_¦ż Ú9źícéćť˙˙˙­}¦¦Ŕđ×˙<kö:Á› ˝y‹ţ˙˙÷ě!¦˙† ř Oýý˙˙˙Ź_s źAľÓ[˙˙˙˙˙˙üW„Æ ˙˙˙˙˙ň CýtţAUć/b;_ă˙˙˙ţA´'ßµéĎD˙Ç˙˙ý˙żu˙Ă^š ďűţż˙˙Tűű }Ý?×ő˙˙˙_˙ř0_˙˙ď˙w˙˙yÂ8Ö‡ě=˙_úŻűßôÓ˙ßŰßŐ˙˙˙˙˙˙~˙ͦ˙ő˙ý˙˙ýÖA´ţmŘ_ż˙˙ýŻ˙ţô˙ýľ ă‘G(ëď˙ő˙Žżk˙ß˙†LDon9K˙÷ďý˙˙Őí°đׂ<‚°˙änAU˙Ż˙ýŻČr˘ńýXgX.Ó[_ôďűÝW˙ĐŹ˙ FAF˝&žź˙˙_˙®˙÷řh{˙˙Ó˙÷Ö˙˙ú˙vľq4ss0ÖűP„ý˙űúűü/ü4A©×§§ÁüZ˙ę»×ţ×XúíŘä3u˙ţß˙˙w˙˙żß˙ú_›W˙˙ß˙˙đźÇ ňv ŕO˙ů Ń ˙˙úĽ&l4Ú˙×˙˙r Ł”9Ža˙ °?č WíW˙˙˙§˙˙ˇúUßÓ_˙˙űµ˙˙ß˙č4 ·˙˙×˙˙_˙µ§ńÄ~ëßý}˙˙ęë˙˙˙˙÷ü‚»ó`GČ4Žxň ˙î˙˙ý˙˙˙˙ä2µńýŻň‚““sŹý˙˙˙é®ţ˙ÇOüŕÚţż˙÷ű˙Ó˙í/ő˙ß˙˙˙×Ó˙Řaďµ˙÷˙żý?ţP'ý˙ďő×ďżćĆr˙äbżćŔŹ˙˙ű˙űŻîßţ!xˇÚ˙ßţź˙˙űáĄéoďéˇ8ČlŹëň #ţż_˙eVl3™Ę­ Ť39aťĘÖU®Á…˙˙ő°`°™?!ˇţűÓű˙˙řľ+˙˙ë&źţ·×˙˙Ţ×Ţľľ‚˝4˙ţżŻűűżf^¸kݦlýŢšöşő˙˙Ż#áĂ xk_˙ż8łŠá şů˙˙¸<ď ŘĄ˙˙ééô×µ·ľ˙˙ëW|Ż_ß÷őý†˙˙˙Żűý§˙őý}˙ŹëŻľżßđĐű˙üqŕÎ$µä3rű˙÷_˙Á‚ü†ĐëÚ˙í í}w˙ř˙·ę>™öjPBĽáś…`Âý5ţ_×˙˙˙äţ~ň ż±^kü/˙˙˙ö=â˝A…µăă˙˙˙ţřkQ˙˙˙˙WŇy˛4F3Ů6h/˙˙˙ý˙f°<6hDDD‡ oä  ˙÷÷«ľ uń˙_ýëő˙|6‚}őűűő˙ß˙ 0‚ü8˙ő˙ż˙ţřa żO xq˙ő˙Čd†Ç˙|0Áé őńëý}˙`Âü?˙ďď÷ż˙ ¤A”¨=÷˙˙˙˙\0aźÝäą PůGÔá¶9ţF9gýţżđŘAZü<C[ôÓô˙ßý{˙Řa˙1=4ßô×Ő˙˙ýpÁ‚#ĄżXaé§ ~©ý”÷˙ţőęľ ˇ űŘÁ§˝N/”"‚˙ţ·ű®Ř@ľň ä ůĎ9Óţ’ú˙˙ţ¸a„~d‡éëoţľ?˙ýë˙ĂúđżýzŇß˙˙˙ţ¸m˙ßkkCkíýů8fÂ}˙ßö _ěŢOŃtľ8ę úţż˙˙őŃĹÁ´·‹0 ťýëÖż˙˙˙߬[ᆠ˙M~ľŻő˙˙żú˝á†/Żö ÷´µÝ˙˙ő˙­=´˙^#Ž·ţ#˙˙ßú÷† Ľ‚öC2<ř×˙˙˙őK!´pO 4ľČÇ)Âýí%˙żú˙ÖÝR­oˇá†‚ř˙úÚ˙˙˙Đ‹I|0Ȩż˙ďiŻß˙˙×WđÚ˙ŰôŕÂý_ţżB•¬ŕ r<;“ĽŽ…˙†żŹë˙îţó‚ GeŃôfŚĂ‘Ä>Ś#ŽEqÂ20Č莍˘86}vN†Ż˙˙\á®?ăý‹""Dźˇ8ź~˙ţţ?ú×_<Ě"řa˙<6˙˙ú˙ďľ×A› đßŢ›äGß˙˙ý~`ŕ¨]‘Ă*=Sř0ň0†~Člz˙O˙˙÷ú× Qµ÷†0şůG-í_˙ďüĂŞ}˙d <ßţú˙˙ú_ř'ř`ôÓňźÓŘ@ţźď˙˙˙úĘGá‡ţX/ďř ˙˙ţÖCmČ‘űŮWŕĂç<çÓ_˙ď˙˙˙ÇM†ź|&ľ>žźď˙ý˙˙˙ýa˙˘ˇ×paľź{O˙˙˙˙É Ź˙Ú˙čé­CÇ6˙Áś /ýűŻ˙UoŻű†Öż˙˙u__ű˙ú˙!¨ú Ô=߯ű_Żţż˙űŮ»úôŐa‡´××˙ţ˙˙×˙_˙}Ľ0đÓ ţ |u÷˙˙ű÷˙Ü0ĽxŹţĹ~˙˙˙×ýáÇĂ!_ë_˙˙˙ű˙żÁ‡÷»µţ˙˙˙Żëäoá‡őę^˙˙˙˙W˙úpĂ˙Ü_˙˙˙ţá‚_ţÔëŻë˙Ż˙ě˙p`ţţ˙ý˙˙¦˝ţa‡˙Ńl+W˙ß˙˙đâżđň‡ˇđÁ˙µ„/˙˙˙úé…˙°v0„ŕ7üE˙ý˙ţČ+Ăëä&šhę XnAPr‡Č*Źßä ‚«®÷ß˙÷Đűř`đ°đĂČgä ôţxÍŤ××˙ý˙ῼ=źüŹëâ×U˙˙úřaęŰTű˙îüTG˙˙!Żd0ĺ˙†¬őPÁ÷φˇ 1ݞH?˙˙÷ďŕΡ—¦źŽtsÚţ±k˙˙×Ă˙ě7Í >›§ţ˙ż˙˙żú ? ˙żď×ţ˙ý[ýř`˙đĂîľl6—üÁž Ła?ăý÷oëŕĂţđańĹÓúí˙˙ß˙a‡˙†C zë÷é˙˙˙›AżíPaúÖÝűŻ˙˙˙¦ďÜpÁđa[Ă´Úľ˙!¬=/˙˙[uţ ě3î &?¶"/˙˙űkţÔxßÔGö˙_˙˙a‚#§ţé¬?ř}o˙˙ěE†÷đĹď˛@3˙˙˙Ľ>@’?ĂC†ᝯ˙˙íwÖ ,7ř7×ţC$6?ďÖ×đ|,0ő©¨?˙Ż´?ŢÇí˙˙˙ř÷ä5ÇŘs˙ýţ“ţ˙Ă÷˙ä‡0ĺßkeʇŘ˙ýiúţÂ˙˙Ă/Č1ú‚ú~$;˙˙ŃDý˙Żżń]ýß˙ţťßůÁĎO´˙Č+Â˙˙˙öťä4“üÁo™†·L‹4 ÁčřĎ˙×Ńý˙Í ů1pL.¨2šz~ xig˙_đD9µëČh ?Č<Ď“›Ő~Đ_řA<7{Čż˙ţ“ű}˝„?Ăôűż\ĐżéÜ>˙˙úżéűđĐ}. Ă^ŚĆÖ˙˙űý˙˙µëła·é›°0ţ/…6mĂ!˛>˙ß˙ďű”‡ţ8«ßéĹ?ţ†ŕđß˙˙˙ﯰh/é÷˙Uö˝-‡†P˙őý/o×!”ŁöšÇ˙_Ż÷‡†ů 4˙ľű)!JýüRĂA…˙éx˙†Ă†˙˙ŕÂÄm˙Mţ#_®˙÷ ŕΠ˙˙ëcŻü†Zż˙µŇ˙÷ <ýßő·ţC;ś ě§"=ű r ë°ÔŻýᩲ żô?‹O^)Đ…ţÚ¸`đct>ďŐ~Ĺ˙´ľď÷ţě-pĂ˙ď ËŐň {R ŹűWýX(¶ _őŽ˙Ô'űrc„˙a_řbÁÁüz×ű˙/ďL‚€˙7˙´˙˙ßß!”Oáú‹}Źě h4˙˙ßµi/ń§äŰű Şţ Ź‚„˙Ţýż!«§Ďţµň†ű[ńżő˙ë!µOßý6úżÇ^ţ˝ţ2_ÓO_¦˙Ż˙ďý÷żÂ|5Áü7ó8ůô‚Ĺ÷˙ýľżú°Oí®-?CÁ]Ë}˙Ćş˙Ꮿ„Lŕbż˙÷ß˙ßż¦d6ť4ü†HlŻë˙é‘ŇůŤóz z(F"ńtí·é˙˙˙Á ţĂč°T0ĎŠ>*ł˙˙ţ÷ň˙˙ű˙č7Ň×˙˙×˙őíż˙A>‡ ý˙˙m{˙˙Č+ď˙zîż˙ż~ý Iä4Üşîxżk˙˙Ţ˙_ď˙á…‚uă˙_˙1ż˙˙×!";o÷éŻ˙˙˙ű˙˙úhś5˙ţžźď$żýuĂ˙˙l‚‡ő»÷ýi;ý놰×aÚ˙öAµĐ™„ýż˙Λ  ţľź¶¶n×˙łŁ±‰šŁLö‡ëo×}^©˙öżćĄ†i•a,0ě/˙ő8·ý}7«ř˙±AŠŰ+_˙ü;˙®Óôőë˙°š!¤9ZXbż˙Úăßń˙˙˙ĂM!Âů°.\dp ŕČčÜc8GÄ/—Ď#Čé‘ŃÄfŤ˘čď—ýţßu˙§ü@ţ@öAv % B˙qB" ЉČk˙˙׫e}?Ů äoďÄEˇ˙é›?{˙üAýý˙éű˙«î?Ą˙ŻÝŻŇŻů •őz÷kżŮś†0ĺXäLČG(rÜăH,rc“UüDVAľa†żýň Ö@ź?űKţÖßâ"""""""4‘Ń=Ń 1Č.F/^ úiä{˙ľýŽżÔDźy ŃÉŽyž˙kďül†HeŹ˙˙ÓL'ü‚™áŽĘ$ü~ż­?˙˙hÂMëĹďűř‹@ľÖďţţlŤáżz{Á› żŕ͆—Ç_ü0Kűč/ýß Wß˙ţżŘŻţŹ?RĺÉäŰ*Á͆ŽäÇ2˙˙ż˙ăývó &>źŞa4˙ýŻďÎB˙Ąüřhä6{ʦťŰŤä2f?ŻőČ`g˙_ŹŹţCVf#_O˙˙Ó_˙ú˙çC˙O˙ŻôďţżżúAţ¶ż˙ţfTq˙^×ëz˙w˙ýé ť_ŻŻ×˙ŕČ衅Oă˙űŻ:×ţCcŮ˙˙Ź˙ä2C`˙ű˙_żŞk­˙ß˙ß§Ő˙úYÁrýzVżýÚëvż÷˙~ş}ý‘m[Żţí˙÷ő˙«\†śřăŞ×b*ňNAX!“ŽSś˙˙˙˙×˝¦¬r Žűý§ä2°»˙˙ýŞ\Řiý˙iţý­×đ˙ë˙dî˝î! ×®ŕÂ×üâYNPĺPä±?ţ˙řŞ˙ü¸ĺLGP qÝůĂt„Ő¦A­ËŹ˙˙űK˙řŹ>d€Ç •x"@j „> ˛D˙˙˙ U˙{č>5ôÂia˙˙ř0K˙×éýúiÓ¦ż˙ţ5˙˙ţA‘Óö˝î|4iÓŻ˙˙K˙ţ`6ÁzdGGÂ>`Í‚ˇ°ž tčĚż˙÷˙˙˙kuF¨?őđžü˙˙ţą q˙őűNź˙é÷ú˙­}-?ţýý+_÷Żéő§˙܆Ľ}w˙˙ZÂë÷űí˙ď¤f őě˙ŮĹ˙ţ¶ýţÁ” ŞA´(rśŻ;”9\S”đĚ9^PĺLÎ"_rśĺ9C•QÍY‡L„‚‡!áÇë Ţ9Üă¦Cjźô@đG˙éţşţű0äc”ë˙ÜDDDDDDDDDDDDDDDDDDúčDE„ý˙­¶˙ű[PÄDW˙Çׂ˙ßřkÚŘXVýuô˙˙űH˙|ÜŚrc…˛9Çj˙SaŹźŹ2:!ĽŠ˘ő°‘ń˙˙űřŻö"#b#ˇ›ŠĹ˙q"Y ; x/d5«%yuĹ ˙˙˙†żŘM ű[»´Ď’ŃA˙ďţÂXkü4AŻĹ±ýŇżűŘ0¸a}l¨ @šţż^Ňéýţ: ­x‰Á¤ż˙ďú׏ţCcÖĐŹhŹ˙ţl4}/˙ý}˘ó˙˙˙ü]/÷˙ü0@Ž O˙ ~†ˇr@˙˙ýţ˙˙µÄôĘÁHÍWý˙ţ–C(=|ą‘˙Á§OÁ đM0˙˙˙p‡úźú®Š7éú„w˙˙úZnż˙<˙óᡣ6GFtx3°źő˙ýi¶—˙í>“řkáŕ„Dť źČd†Çż˙×Fgz˙ü°Űôţ éIş7úo˙ţ¨ĎY A˙ţľżŻ§§]'˙˙˙Ič;C§˙Żé7ţµďOO˙ýűÇÓc˙˙űÓ˙÷˙_˙őý*_îă÷®?˙˙˙ý˙^ţł`†Â˙ď×÷˙mú_Ż_ňvR?ö˝żţ×[[Čgű˙ţ˝Pšôüz˙­™‹˙´Żµµë˙˙mSëÁě {÷ĹÚŘVËr¦_˙˙ëµ_ôďţ˙ě2Ü®+°ĘˇÎ9Ç;”ŕ¬DT?ű˙ŢNjl}˙é˙Xkýئ3¨ýŻ˙ëcŻýý?ü0_ě&š Wë˙îřkěV“˙Çü4Â]Đ&˙˙¨í[Ń ?˙ß xšÖ"-˙űŕĘ__˘€_Áx¤ďř‰Á­Ëł÷ú˙ţ7÷ÚÜđ:%˙U\”U}DGý˙˙×÷Z…‡ýôŐ˙˙˙Č4Ź˙˝~ßýŰ˙˙ß˙ů6˝`ˆßßűëďÔŕ´?˙˙řAÚţ7˙φ©˙ś5Ť äNC™‚†˙˙ß~`Ňď«LÇűBü‚»ařÁ=m|‚°äÓ ď˙ýué°Î8/÷ $żţOżÖ×Oď˙˙ţ|K ú(Ź˙í5ŻO_˙˙ôa±ŻÍ†Đ"‡ű^`Á˙ë˙í˙Ó ýŞúa°ÂO´ÂüżLăťňc¦M˙˙˙úÇýß˙ŰKëýzň1ź˙˙«ídí… _đÄ/Ý˙Ó˙ţűýqěx Âńö˝ˇ˙˙×˙ţwĚÂ7śEÄíţ·˙†Źá›Dt¶˛v™Yż˙üDD}äě„(r‡[ţ˙ńl5ä=ᇳ4˙ý‚éüDCŻż_˙ßđÂ˙đűaÁWűţĽ ˙ţ˙ß˙üá\ˇČ8ĺ9‡= »(ł§ţ˙ëGŕ×˙Ż!4˙˙ńĂ]Ý„o˙ţ͆ź˙˙Úű˙ôí0·ß˙!’úđ`ľżţ˙űO˙˙ăóŔ©˙á˙ńÓ˙ü†Łđżţš!Şä˙˙˙ý?ßüE5\H˙Ż˙˙ţ×ů Źö}? |9aśr ““ś}˙˙˙ńŻÓ®˙¨!dŐů `˙˙ýý÷¶ ÷şa>˙˙˙×ó0Ő[Ę#Đh1ź˙˙˙‚kLWţši˙˙˙˙úxazú< čřlhŃFź˙˙ż˙ţÂtDC˙˙ú˙ô ŕ6ú\ŔŇé6xA˙˙·˙ş}7¶ľžž˙˙K×˙ ú˙ü†ĐĺŹß˙ő˙˙ża?˙!¤ ˙˙ţ˙ŻĚű_ý„˙˙ý/ʤţ?Żß˙˙űýżý˙µmB˙˙˙˙ü'˙µ† µ˙˙˙˙Ż„żf‘Ń1‘ődÇ;Ą7 ˙˙˙˙˙b""6":xeyXPĺ˙˙˙ţ˙ý„§b"+˙˙ď˙˙Żh5áŻ˙˙Ż˙˙đh5í~?ż<4Ł˙żűńs ˙˙ ˙ő˙‘Źţ#˙˙Ůp[k˙ ¨˙ŇVµ˙˙íA*ý?ô×Č-YaŻ˙ţL/ţ·Č+ßü0› ť‚Dg˙ݶ ţş Çë˙I˙˙öżřh7űôh…Ń™oÚ˙ýü0ĐA˙Á‚Óľ8· ÓM5˙˙±P_˙ýßzř0‡˙˙ —˙ţ˙ßÇň Ü˙aýřaż ×ţź˙´Áż÷°Ń÷ňv€ż˙˙ě0˙ëţţż˙˙_0`솛˙˙Íí˙˙˙˙Ó Ţ×íŻ´×ČÁ˙˙ů† ë×ăűö#ŕź˙˙„a‡˙×űkţź˙˙Đlý˙ýŹ˙Či?˙˙Núţý§ż˙ţh5_÷ţ˙˙űüDj˙­wký_˙˙ ßżţ"A°~żţżAďdnAUŐÂ˙˙ ţ"#˙ţż˙żŃá?űëß˙˙ú7ů €'ü! AxÚ Ň?˙ţľ“ţňÂżż xr cf‚ŕ‚ź?˙żÓüŘ3G*ÓđM/M? Ďi¦Ce­Ë‚ ‘˙˙ôßÖ/®ťúĂ Úi§˙]˙˙ߣ@ÖčĐžCşř"€hzÚÚMŞ˙˙˙ţýřL/A3O˝kWí&×_ţ˙_őá˙đ›Óţţ›Aéęlż˙˙ú˙6ź˙OÇ˙ ÓÓ «˙˙öËŹ˙ ĂđÎH?˝ţ × ÷Żüţő˙đ߸ľ»k[ ÷úëw˙˙µK{ý»Ý˙†˙Č8˙˙Ş˙VĆżţĂ˙ÝXž»˙§ä˙˙˙ţĄŹřnżí]ýŻ˙OČx˙k˙ďx_öĂÜ~V‡Ç¶Ó_˙»˙˙đhzň¬ęgO_dň +î¬ ÖkýĄ˙˙X÷čDwű5ý¦L%j¶˙˙úţżkZŘŠb>ů8˙˙÷˙˙ě+ý¦­0¬Sß÷ţ@đb ă÷ěâ5"é8™ · »˙†Hh2D› ¨k_!’ Ç˙đ„_ľ,Ř4ßĹ4ű „ĐaCA¤ÂßÓ˙ňÇ^ľżîëń!Çb(C˙ţú®˙÷âÉţżÓ› 9 7üoň æ÷Ý´×ţţ–µßţAQ÷AŰů' ¬??U•…ChrĂ ÷÷Ń˙ő˝nßÓO „DNPšášU†Ho˙Żô“ő˙uţ˙˙4O˙˙ë˙˙˙˙ş´Đh7˙ż˙÷ß«(tý­żě§Aôš„˙ő˙ČX˙żâÂămţP`»GÁ˝†‡>a}˙˙«×ëý?¦Ôkđp×Ac¤$űÓ˙ţÓ˙˙˙Řöaoéá6A­D'öżţřß[ňVý5öţíuON´˙~˙öľ˙ü3a˘řkÁ›Ca7ţť?˙˙·˙úůŘřkú˙Ý?˙ëެ_˝ţÚ _˙ţŹw˙ý˙lO˙Ż˙ŐDi_Żţź_ý}vD5 ™÷˙ŽäŁ·ű[T›ż˙ö¦˙˙řw­ö]ď˙˙ö…4˙˙őA×ü3Žh“ŠG\0ż˙ý×˝żďßئ"·c˙˙{IoţżöţkÚţ˙ţ«ż˙ü?ý„ŐŻ˙˙!˘.=+˙ßţ~ľ á…ýŻiőţAL/˙†ż¶¤#ń˙ôĐ˙ ˙?řaG˙˙»×ţSŁ…˙ü7ݱ_őý[˙×_Đú‡ň íß÷a»KÇżţü5÷í˙öţżú˙¸_ ˙÷Ú˙˙˙[ţC%ç˙˙1>)/˙ô\~f Ż˙ö¶÷ţHW˙ /ŕź˙˙÷·µ_6ŕZď˙ú˙˙˙ě5!­ţ׏ţA^?˙ň!˘?őŘaGé˙Á§ě‹Ok˙˙­Šü'ä6úýN·ä#˙˙˙ß!¨?§ŕź˙Ş×˙~żá­?÷_˙˙ď˙˙ý Â˙×z˙á˙˙ďřŹöC@ţüfçíýľ@đ/Řűä2áőµă˙˙Ż˙ňp]÷A˙öC^ r(˙÷˙ţżü:Č/7Ó˙ü†Oú˙ëű˙ÓÂ:ü†@*ŔO˙ô˙˙ţ˙Ż÷ř?B|źý˙˙˙˙P´Ňá˙ő˙˙˙Ż˙ńżßőµŃ°#˙˙÷˙˙Ýn÷·˙˙˙˙ň*K×ŘÚ˙ň‡r ýý˙Đ9 ăä2‘]ľţĐ˙úwSŹ˙˙˙!„|h§ÁţAR=…ţJ*żë˙˙˙Ú{}Ă˙đaé˙˙ý˙˙đá¨bęn ńµő˙˙ęé˙Űöü1ú˙ý˙˙˙˙˙íŢđď>…żaŻÍ¤ŽĘ ˙ýö˙˙óźĂî]?°—§˙˙Uţ˙úA¶ađ×`߲˙ýőú˙델űŻâż˙żď˙˙ý¶ľÁPţć#ęC_˙˙ń˝˙Ň˝nצřaxh`ż˙˙˙ý_é‰ĺ÷Ô0_˙ő˙˙˙÷ű@ÖżŹ˝˙×_řűkŰC˝yŔÝýÚ˙˙ş˙­ö":˝ Çr‚ş/…˙_ű˙á…˙˙˙†Ż»˙ţżů¸˙˙˙Ç_ż×˙ń I˙˙_˙«˙˙˙D ¨ ­W˙ÚřůÁťü_űŻ˙!§ďţż˙ţ˙ď˙řA§˙öżé˙˙˙ţFd˙ý†—˙®˙˙őúé @˙ţĹ˙˙ţżűÚ>< ß˙żůĂj qSß_˙Ş˙ř@ÚżţÓ_čGű˙ţ×˙¤żüX_˙ű˙[Źţôß˙â˙ď˙ýé˙Ş×ż˙ţ˙ë˙Óţ˙ä-üŕÍ~IČ+?űţÝ˙űţľ@đËĎ˙î˙×ú_őö×O˙uő˙˙ë˙u]}5´Ę÷Ôă˙˙ę˙ý«żä oC˙Á`Š ˙ţżď{_úkkôşię˙˙ýű`ˇŻëßüx˙˙ü†H7˙öP2pŮýţźČ ő˙˙ë˙ńC˙µÁ8ůĂj|Ă=˘ —ţ˙éż×†żčVšôÂ~Đż˙ő˙°2ŹÔ÷˙˙˙ýkú_˝A‚ ®Fźő˙ëď˙˙Ý·˙ ű_^”ĺţ˝ú˙ü†ŘéţAĚ9ěänPćtČŁ“ă‘ ĂťĘĆúJüG˙ż˙ýÓFŤ÷d2zűŻ˙˙őő®Ź>˛®á?ý/÷ ˛?˙˙˙č'ý5˙ŻÓ˙˙żżé˙[˙ë˙k_ý˙÷ Đë˙0 Çžłgúíuüwëő_Ż!±GţÖ•5ýú˙˙˙˙˙˙ýz÷V–˙˙˙˙˙˙ýüi˙˙żŢ@ür1Ď…ůű_ţżëi|H˙ý˙Żř!°y ¨aŻ˙˙Řţí}˙ő˙˙ßĘÝ{őözý˙żú~ÄWú˙˙lŹ„+ú˙˙Ż˙íţ×ßB?˙˙˙˙6‘qLeâ:0ľ /ýőđE©·Če:˙˙˙׋®Ck˙ő˙Uý ˙˙˙ď÷h˙ţúý˙ë˙ú÷Çľű_ëýŐ˙˙kűëČ(‡Ďëoż ö˙żűü˙Ó2±ýř_Ă‹ţÁ?˙˙˙~5˙áĄ˙˙_˙ű˙˙}í~÷ë××˙˙˙ţ“K¶ż{ýő˙˙˙ţ§*D3ŹţŐx˙Ź˙˙÷˙ŇOK÷´?˙˙˙˙˙Ż÷ţC 3ľű˙˙˙úţż˙×˙˙˙˙ß˙±˙˙˙˙˙˙˙ëöż˙ôűż˙ä2Cc˙őď^˙˙«Z˙˙Óúű^˙Ź˙űß˙˙˙ż¬#úíŻ˙˙ţ˙˙˙÷§Ć¶ą G˙˙˙˙˙úýďi&'.żţAUú\ŤČ*żŻ˙˙˙ým5ß˙§ď­Ż˙ű÷˙ŢÓM5ů1˙˙ż×˙˙úż˙ ! ý?˙^ź˙˙˙_÷żŤ˙> űđD€Ő'.˙˙˙˙ë˙öźń„˙ß˙˙ţţżýzď˙˙˙ë˙ x`˙˙˙˙˙˙ďűÓď˙„A˛}óžAz˙úýţ·¦Cţż ‚˙fĂm˙ţ˙ţókĂO˙úŻýýţż_˙űűüÁ‡˙˙ú˙ű˙˙ţź·ýS˙˙˙˙˙Wú˙Űá†ţă˙ÚëÄ_˙÷˙˙ţ˙Ż˙˙˙ý~˙öů´˙żű˙×˙ţź˙đŰý}ůÁ]Ö×ß˙ţ× Ůu ˇB¸Ş7ÓŻóŁ˙ń?˙˙˙˘€řŰö˙Ú˙ë˙Lˇ˙ý˙ě¬)Jëö_Ň_úá˙ţţ"=ľŘďÄ%ď˙ľź˙Ź˙6!ŃF´ż^/ż˙˙ŻţťčDEľ_„·ýţ×ß˙yŔ¸ĺ Âçͽà ¬ ˝ľČh˛ ˙˙ţ˘$6˙ă„ý.Öź˙˙ţˆŽßč,‚Î>ßŢA rÎ9ŕ99 ±Î9' ˇÉŽCąż˙˙Ż|á‹đ‚ČAr‡ŰďÄDDDDDDF˙˙ż˙űÓđ‚Đ0Bp·čĐ5t×ő˙ţüś38 .>µú ®ź˝˙˙˙{ÂIč=ż__˙˙÷÷ĂŇ;‘Žöűű˙Żü†HlŹ×ďĐôűđhź˙˙˙ý˝‡˙3fĂohżŻ˙˙ř?~§Ű˙ż˙˙˙ýů‰ä5fhŹ‘âëÓßďţ˙ż˙ݶ¸o\DD‡ż űű^×ţë˙ď˙˝Ţ˙[·ăă˙˙˙˙~ńű^˙˙˙˙˙ŰxŻţíŻ˙˙˙˙î°Uýˇî˙˙ë˙˙÷ _hˇřöú_Ú˙˙ßň »n/˛ Óţß˙˙˙úݦEďĐAďţC1ú˙˙˙ßŐma~}m÷}˙˙ú˙~~ÚŰń˛v|!8¨(saC”ćâŕî~$ĺAx<Ŕä3ąc”çr¬ˇČAÎ9Ç&9P_) ·8ĺIÉŽ¤QÉĚĂ”9Ç(rC¦Hr Žl"AÝK˙˙˙[o`żAáťBĐ.ýČuňż˙˙á~?® !ü‚ ů!Ó˙˙˙ůÎßü†+Çoî“ý˙ý˙ZwŰôh}żMîż˙˙ú~:řAżżČmqŮÖˇ n Űů ą’ÂYë÷ýßş}Âî°`ŠTj Á©:k˙˙ţšýú§öűP©¦šiˇżýëý®˙Ąü}ëţš÷˙ű˙ßżöţý;Oű__ő˙Ż˙Ż˝l‡l6͆ŃŔÚ6gil·˙?ö+ß÷‚ˇé­©°T_˙˙{˙Úű˙˙××˙űŹOĂ ˙˙˙˙˙˙í=ŽŘ%ěĐ îŐmy˙˙˙|0Kđ×ßiZű˙˙üýâ#˙˙żúÖëď˙÷ţúä÷xiűOúő˙˙ |g«˙Ý˙ýđ@˙˙îý|†H7Uü&˝˙ř ýűO˙×ëŰţ˙˙ůń˙˙Ż˙˙®‚ Łź!¦˙ß˙˙˙ü'ďż˙ß˙ý˙Ţ˝Ľ† ¨äś‚¤Ű‚ ®AUČ*Ç×˙˙żé6żköšä6?˙÷˙ţµ˙Ódô×»µüé˙ý_˙˙˙ŰaÚ8ëýáďő˝ú˙Ş_˙LCÂ( 0d4ČH 2€Ô( B€Ô„z˙Öúö —żöĂ×»TŐ=>·żŻ˙fdż˙¦H7öżţŠ ;˙ű˙~4żţŕ<ţš®ľÂ4k˙˙˙†µúý Ţ Řmś Ł´p6Ť†Ř"XCk)Żëű˙ÚIő˙RPúvşŞ´á¶˙˙˙\@6/˙đDă{˝őDô˙×ţ+{ßŇ9 ż÷kAw˙˙űő_żĄ ńazn—˙˙ţżëý·Ž’ ·¤×˙˙ë×űJ|›÷HÍ˙7Ż˙ýߊAwü"ź{ČÇżď˙Ż}}ďĆn>±˙ŻýŻöߨ[ú˙˙ú_ďŇOúżX@˙j˙˙˙ţďéżďń˙ôŻďú×}Öż˙ú˙üűő¶™ä"šż˙ôŻ˙­?˛ `Ür ŁüG˙˙öW…Ě®(sąPg*?ďý˛PAQČ*ąW © Ůg^˙˙ţ""""-/ţżţÓ_µ ż˙×ţ—×Ţ:¶«˙ÚčähČů )¸ĆfG3‘ěľPĚ#˘5#i?ý˙ß÷ýü0é”<4hĆa®fěˇĐ<#5éÄDDDDDDGŻ˙ý'ëýpá°A„Â`! d4Ć=éß˙6 _ďöҦí?íkŇéţd†Ç˙ý%ň‚‡R ¶E{Ő‡˙ýmŻ˙ď˙˙ÄDDi¶–ŰM?´ővO˙O˙ô«y´ŕ¤٠(3a¶l6Ť‚ˇ€T0 ‰ŮˇĄ˙ý÷Jňý±[{OżŐ±Uőţ˙˙ú¦îIżëřN׿÷˙äGôľćĂ4Ždxř0`0Gm„­ý?őm%Ó˙Żů ¨ ˙üD0„ZěI±¦Ă úßďTĄ˙ű °‰´dKK˙˙ë׏˙˝± 7MŠ_˙˙z§×˙ě0I´0Kë˙˙çş˙ýl0“#ÄGˢt]ŃŚÚ$DtGĎF¤hŚDtGDpä„`‹çŃ‹ÇÄ_:˘:0‹Ĺň>GEň菑Ńq ó|Ú1žĚ3_#äp…ă™|Ć‚ ˇÎá4tĎ„qăŽË™tGâ‘Áůáć{.Dp<Ż˙˙Ő?O˙áŇb"""""""""""""""""""""""""""(…oO˙úúľż˙ SI˙˙ţż˙÷†?ţ˙˙__˙”9ĺAc‘Ă’DÇ•¬ş˙˙˙»˙˙$×4˙űýkŻ˙ď˙ţúU˙ý«˙úş×Ç˙Á‘졣4K˘ŚŽŽ#ŽŚ"s#ä0Ťh˘##HöwŠ˙˙ýŞ˙ţ"""""""""""C$6ś±ÉŽDˇÎ9Y˙ýqKŻţ"""?˙űÓ˙˙ężí:żţA¸˙ď÷°š˙˙öß˙˙ü&9ÜîPäÇ,s9!ĘîD‚(âżď˙äń¸Á[˙˙řúöCj‡ß˙˙µ„"˙˙ţô˙˙ćŔđ7#…ţ˝˙˙´/˙Sg˙ îAĄ˙˙ď´6?úa?ý˙ë˙ů©Ó˙˙˙ă˙ňÇ˙˙˙ţ˙˙ţż˙˙Ż˙ď˙˙ű˙őţCN?˙˙ţÇ˙y­ő˙˙ůŔË_ë˙­˝}?˙˙˙˙_˙ż˙ÓO˙˙ú˙ţ#˙ë˙˙˙˙ĂN˙˙˙˙ě%_˙˙Ú/Żě_÷˙ýż¬Wú˙ţżî˙ů ˘łjUś˙!‘Çkţ˙Č7Ů˙§ŁÄaŃ_ý…˙ ˙˙á?ö­Ň˙w˙î /űO˙ČCű×ţC*Ëżý5˙Ćű˙ńý_˙żż˙˙šó˙ţµĺB#2č».2>GË‚ľżţ?˙g˛ ˇĘň¨J…9NTącśr‡(rśă“˛ĘŤţëď ăä4‘ýSăüDDDDDDDDDDEú˙ Č4>CD˙˝żöö[ý‚x&ź˙˙ł/^Or`ĺW”9C“ॠW ä AQ˙Żü†Ô‡˝Ź"ýSß˙˙ÚŃ9żôń˙˙ŰĂ  Ă˙š˙˙ß -č7˙˙÷ŽA†˝ ˇţżýď Ăyŕ‡„ób_˙˙ďÂ0řA ýµżßäŹßÂ7˙·˙×˙ěxIżţí˙żüA˙áĂU˙}/ü ôÓIë˙ď„a˙÷ţä áwý­wÚkżţEÔO˙ü ŘaÚ˙Đ“'˙ßAţ#Ă_ú˙ŕ‚ ?¬0ż˙˙Ű ż|q˙˙ú Ö˛ŽEżď˙§ ĂÝń˙˙đ‚oĂ$0µ˙˙ţ P9NA#ţ°˙ţ¸Aëţ÷˙űÂĂż_÷˙őĐA‡˙ő‡˙ßÁ~C(Ź˙ýWH~Aąý_żÂgÎĂň˙÷ëď]˛NCTsş~˙·ß®˝Ů˘ţźýa”ůB˙×8ľšú˙V‘ĎŻ˝/ żżŃ¨˙ű¶˙ő׉ Yá&źĘöăúűŻó€c˙á±ţúČŹ˙ôú˙·˙5džpČčň#„#˘8…Ĺ0 ĄČŽ:Ţ«I÷˙m˙‰©ŻňŻŹ˙÷·ţß üW˙Ăý´˛ ˇ?áŻ&†)ő·ßD $ßü ů`-:í˙É ‘×ţ+TÓ˙ ˙‰ž×űú˙í˙ÖA\}ŻO˙aůÁßü}wަ ú¶şýě/Kţđß_u˙† á/ôí˝˙ţC6™‡ČÓëßö˙˙đF°j§Žżýáżţż?˙w˙o˙kő_ý­‡˙Ź÷ţűéţĘpźÚČmżŁ†ß˙×ýż˙ D˙ Íß˙ň1ů ażűíý˝˙릟ŢuýuO÷ţţďë7˙k«ďú˙×Ě9c–9c§˙5Wţôżű˙á«ÄDE˙Áżţ@đd¦sţµţ­Ş˙čżţźí/ýŘŻá»˙ŹżÓ V˙Úé}d ~ż˙ăężićÁl˙ ׿őýŞ_úży ˙˙Ú®˙ M!˙ľ˙öż†żřż×Ó˙íŻă˙Ť ţ?ď˙ď /˙Újú˙~¸~×í˙ä €´:˙$`üoÚ˙ýĐ0ţĽ‚ľW˙«˙"ŕźńżkű xeŽh˙Č §űţ6B~(sÁ‡#Š>BDr Z xg úáżż!´=|DDDDDF!űěć˙ôČa˙×˙jׯM§˙÷˙§˙ŁŕĂý}‘˙»ţlŤ‚<\ć`Âď¬Ý x8˙Ű÷ué0ëű|oďÖŰëü47Â/ÓWýx?é˙oßî4ýúŕßýüÚ~C8˙ęOa}‡˙ŻĂ|NÓüCűˇz˙úż˙ű|zŁé˙˙ëő˙ß_ü f†í[múîŻw 5˙ôšvŇŻŕŐ{ýXćÁ°Ź—¸§˘:53`xg]ëMa‘¸[ý˙ľ"""7űíqôň ˙­W®×˙űµ˙ýß»µ˙ä aë°ŐwÇ˙őâAďŻô˙ _˙ż×ă˙ďř˙ÉĘżý˙ăő°Áý~ü†Hnë_˙˙xd1żţµ!ď˙ď˙`Ă˙ď„úŻűĘq;˙Čg0îChż˙Úi}d1Ş×ú†:˙^@Řă¶š8żđb˙Ú÷řĂ ŞŕÁ˙ßŽŹ…}±żŕĆ˙µČ±řA˙żd4źü­×őá—?˙´Đkď Ôc~Żźú_˙°CőłQük !˙˙Ä~ňşŻă˙ů˙Áť_ü†Nű˝&C6˙ÚÁ‡żxúřňDs#˘9üĄ˙ WÄD~C$Ç J C˙ľţĹú%żxu×űďý4ýrá˙ě/˙×˙ {řk˙ĹfĎţ ;ţA—˙ţ«˙őńę§+éoţ>@đw˙úŻ˙űŻţźë˙őŰ˙˙ß˙ýěC˙Ú˙żú˙ßk×˙˙˙˙ ˙˙˙őŘ0\ż˙Ż˙ţ÷$Zd2‡˙÷˙˙ýŹÂw˙­ţ˙×× ć±Á>Ő˙˙ü5ÄDC¦Őż˙˙ďŘ]˙˙˙˙řk»† /úď˙ř0OÓ˙{˙˙8Ť†_¶«Ţç*ë˙â?´˙±_ä2C,ýgĂ(-ˇ˙˙ @äˇČeމÁ?ü!ÇöKĄŻ)hÂ'Dty´GČůžiňśň Gëý˛Ś˝â"""""?űOëö+Ő˙ěđNÉ@/_á§Ü?őăţ_ȑɎn!Ěĺ}Ő˙ů.?äľ"""@ť9;˙Ç™†+­ßţ¸˙őä €Yˇü«ý˙ßżB/ő˙›6'»˙_ďĂä §Ż÷˙k!ˇEżë˙Őx č4ż˙ţá˙˙éŕ~ż˙úŘKüŕďţöšĽÔť _÷˙Ă üĚ4l˙˙řŤ`ęď˙˙MÚ ˙˙ Q ţ˙˙űűµ˙Żţ»O®Á˙˙\ŕß˙˙á‘Á‚: ’ Ą†ň‚îú˙â#Äxaţź˙ţű˙ď˙ő&`äDz”?á˙{ hEŹä˙[ Ç)˙ú -_Čd‚ĚD?˙ţ úaď˙ ŇĺFČÄż xn3ň nś/úwÄqÂţŠx]©˙‚ţä}˝§á•~xXľżÁÝd@¸ĺAQř żÂ{{úÄ?B$ dżČ)˙ Řýů`r‚uácëď~ đóč.ż˙áżä5Âo °×żđČ řD¸?Şëű8A~ć¤Df]G3Ć]™ŚÚ/Ů|Ž pm¤š!…×\ŕ*ńa _ \DDDDDDDDDDŚ=˙^Á„đ¸ý§ţc ż…·ăµřl ża©Á”rC”9ç¨)Ę­Kr—+ü 4á†â""""$2TsAc” ŁÉHčş6â‘ŃGŃpĄŔđÚŻŕĂŻČ6é‹BJ…Cčńą˘=_öŇuÄŚăĎ "?đä3dŕ¶˝ †đëAýEż `׋–l—ú†ŕÍA^@đxm.dĽ8ĺYr‡0ĺŽP˙ŕ0˙űŘi^""""=ú0kŕΧŻ)Ňň ¤?ř đa˙ ÓëĐD §*/đcĽ5˙ń ‹ü秇˙ňŔ,Äż‡đÁŢ…ţą¶ýp™Ő—ŕ˙k˙„"?aţżý‚ü=ăřýú˙˙ý˙ř×^ţ@ä ]˙ß_„H±W˙˙Ăü†“˙˙&[Úý˙˙¦AD2ś××˙`ď»˙˙µżáß÷ďaf Ęđ.żě§4…Už ĐŤĘń‘\—aTR Ö8m,7őßâ"""""""#A`ÁţÍ@xuü6‚ŰýÇüá®; $ŕßólÔ…żä°@Ä%đoö¦ŕ3íŻ®đÍ@y|wÓk ţÁ˙﵂ţěÂ×ő!‘†ž‚żiIéżř4pA~. ?ýŇ ¦Ť$ż˙áGĚ8Żk!€˙ýl`đżÁ‡<?đ’0Âľđ߯úApD‡˙ţwŞ0Č菑ňďř@’xCę µlDDFC$źđ•ç_¸^µý(Mţ¤(Ź{ü „…p˙äeü/‡! ŁOđ’Źľ DGőA¸ Wţé~¤ÝU˙„ý _ú„˛·!–?ş‚ ˙ôa?V%8?ţ‚Đkü¸K°ľň ú aŻđ]űá-´ż‚˙]†A×řKmý˙!Č4żĄa°żÎŕŃý4ü%†!zµýČĹô ˇĘr7#˛śˇéŻ˙ ¶Ăü~„DDAě/˙ű˝˙˙®Ó˙ a¦?_<5%‡äđ˙O˙¤ę÷3Čçü ü450żÂAżČiŹżá¦AQ˙˙¦úţż¤ßżý˙h ˙˙Úř mŽ×ö[™ÎäsŽa˙† ü†ľ˘""#Čű' /ĹG˙řß x2U˙úvÖAßţ·ŃPe>Ö™<6’:ý˙ízz˙S4GG‘Żş %łxD3uűsÜŔ}rÓńđŠwżţőö ś2÷Ł0P˙˙Óü{Ň ż˙˙˙ M×˙Żőý˙ńßŢČ+Źúż˙ß~A!5š G"9+¦ýőŇő¨jó`®’oý÷˙Źú]Wßżőß˙·WíFÚz˙U˙˙˙đ_ţş_˙˙˙ż×đDuŻůŔćÂČAM˙đC˙ęźß¶źđO˙­ú˙ý˘Ł Šą(* ‚NAqČQ˙}őČd4Š99–9ŃČ`r rxqČŽw8äŕĂťČ9'(sŽS©Ý5űA7ĽDEŞČrä:‚śđAqĘ9T 㛊9 «*  ŽaČKýu¶Ô†@o„uŹĐZď§hXM°B,…PEęČP„đPĺYPT r(˙˙^ťúÂaĄżţľźiˇ ‡C„!ÂP9rYu«÷őO÷@ˇ®@đŃ9ܧ(rC»żOţşŞŮ ‡˝5Č;÷˙¬xnän Â1ÓµżŢ©ü7DůéíĄ06``ŕ1 x˛ ă09Ś!śr,˙Â|DDDDDA¦źţ"#ň#´·kq‡úk Ô9 §,r †g5żdQÉÚ{arN g?ďôÖ""#×l0–‡÷ü0Â÷áě4µżýí…áťďa„µ˙ýÇĂ -öCąÄcĚË˙ŕűý!t!ČmąaČ+AUČ*Ž@đ̉€˙Uń×[ uÚiöAU˙ýőýśT/×ÓMÖţ˝k ż˙ż˙öü†<Ö?`‹ h2‡ ś} 2Ł˙ýx0ż `…„,@i†CL€B˙˙ţ <˝=ýÓýűż˙Ż˙˙OČ5LJżúdtkѧÜ˙˙˛o÷đBÍ‚ˇ€T0fĂlŘm› łź˙˙7ýţżýz˙ő {ţżď˙˙ýr dÔ­5ű˙k®ţ˙^¶ßţ"""?„×˙^›×˙ő˙ű˙˙˙˙p/[×ţżż˙iý†Ż˙˙˙˙ű ˙˙˙› Żďń_˙ďúďţű˙˙ĐfÁn˙űý˙˙űľ˙ă[ Ż˙˙˙ţýŻüěr ĂČ‘˙˙ężPŕ×ýś!I NPeaÂr¸¬*f‚‡(ĺA´0ĺ9(sŽw<fĺ<̨Pţ˘?â?ńżď˙××ű˙żý}z˙oeA89Č|"Peq úžgÔĄHh§(çź˙ö×˙Źýţ-ţ˙©Ě:˙˙÷_˙úëď˙˙˙˙˙üâ J%˙żůĂ„˙˙~ú o˙˙ýstH4A;)ĎÄ(grĽ&™řÎT¶zćsą(0ĺńÜٰw>ćqĚĺAw ăr “ÍŤČ–aĘÂçá•ç‚M2ś°ĎäśĂ”9W©‡%dAĚć˛&9!Č ˙ţŮďä2@Ă!‘ÚŻ˙Âúk×ŇH7˙˙Ż˙ň1™tIł™KEŃ-Ĺ3lş JAqĘ↱÷ů'ç0ŕf łá”x2φYŕË<g(řeźĂ,řež łÁ–‰Î?˙l'˙¶îŰ»¸pá·mĂ˙˙ń˙۶Řm¶Ăm¶Űm¶Ü3Čyt=mŻűa¶î ;m¶Űm¶ß˙Źi/í¶Ű¶öŰm¶Ăm¶˙ë ý¶Ű 6Űa¶Űm¶Űo˙ý5ďŰm¶ŰmŰl6Ăm»aÓ˙ô9ŮŞ)HŽŽ.¶Ű¶Űm¶Ű¶Řmż˙ól(Źm¶l6Űm¶ŰnŰżëćĂkl ×ĂnÝ»ní»m¶Řo÷űâCéđĘŮÇ; Ę®<.ʱÍČ;ŮtĘxeهáśr,C4…ŽPňr.ŹfâD]eŰ* óŕ)đw ÝÎ?×ţ3ŚŽčĆGĚ2>GFĹ#ć38ŚËćc3EĹ?â"""""""""""""""""""""""# €ż˙đ„DDDDD3xoÓű˙ýý?öĽ(Ç(rC—Ĺgä2AˇĚ9‚Çł(P­ąMĹĘü|!řŃbNČ-†•TÁ!·ź˙…üá¤*WÓ»Mw˙ŻŞ˙á˙¤x6}×˙µü.‚×˙˙Č!îó™€ĺň8"˙×üűá˙˙^˝y˙ý>żëńű˙·żď˙ő˙üŻ÷˙ţŻ˙ýű˙ëü€<1˙ż˙^ú˙‡ßűţ˙ěŤŕ×˙˙˙Čiʆ˙ď˙˙]˙ë˙żÓ ¨ô@”ę?ď˙Żő±˙ČAÎ9 ?Î9!ÉZ§×˙^ĽDGű×ä ý˙˙˙±ďżý˙4§Č`Á ××ßD Ŕ°r #‚!‘äyâůtc8 ‘ÁLĂ/‘ĂAËÄ|Ž ŮL†mëßţ¶@Ět8Ăn‰ź r¨Pĺ9[Qq\U‘pˇÎ9} eEˇÁwýţľ""""""""/˙˙ůäG#Ĺ˙ü0_ü!fŔŽä3Kďů ßĘ‚ ąVS›Č#ť9ÂśŻ>zÂäĘ‚9Ç Ĺ‘Ž{ Ăšâ ÁXypÎ9VAđ¬!…•V@‹?9NSťÎäKłŽXĺůÜî@‡-ČW"şśrc•ď󋮿ˇ`„F…ˇ„!ˇś"hDY ˇ´,Śt""""""""""""?˙áśs|5#Ú™PV¤SźĘ®)Agr ĺ9r‡>76†č˙ÇM?»UÓ±żżúżýë˙Żé˙Wöl2ţAll ŮÎËçtoMSM4Đ2>`‹¤ sY ĺAIĎç™Cž@źŹëŁËÓř3~l Ŕż˙PD3o˙ß˙ýß˙˙˙Ňż˙ý}qáţ@đks(Gţżßa}ż˙ţř2 źďkđżűA†`úăř_k†ĽÜGă®A¶ż˙˙ň µs<Ž‹Łčą˙˙ü.śŘ B˙˙ČźŻČ/äŹ˙wÁ˙}0˙Őz˙ŕÓő÷ďţď˙ú˙\6ź˙Rׯ´ţőßÔ‚˛Śl† úiŻ9Űv«Ü ň`ĘîA¤Ťô›Ä>ôkÁ“Z¶Aďý>Ňa﫿řO|†ľťtßţގNĂß[˙Ń zě»$á« a{wÂôűĂ:ŕ×\0GÁo®>‚ ÷ŕŢ":°Ňţ˙ţÁ‚ţ‚ ú{˙@đŇą¬Ž ŽEéńđ\†Ç Ävúŕv|2»X\h>Z~•÷©zi öß_§Ç°Šđl…Ovţů°Ű‚pAh~!}ŕĐ0ą°m˙äĂIACů‘šřŹąh3ŹőäÁ \mö˙ČCLtţAl §2ľ ›Â Ç˙M˙Ł«#äh5ŚŘ(ŹB/˙÷á‘ _]˙˙őÂ3@ćŃ 4˘#Ó‚r-™ýo˙ţý$t †5 ˛\_˛Ň¸ˇĘr>Č*Cúż˙˙„'¬ĎhDDDJâA oíćŔŘ ^×Alţźh0żőí¤č" Ó5ťş/":>ŚfÑ̺>ş[ ˙˙µXD đ–!ĺĂ 3‘Áy Ď)Ďŕ?ŹőmtĘ€ÝâŃĘIP‡˙ý†čmźŻßµ˙đjéĐ9$0ë´O޶ľ˙`Á% A„Krč?WFhϯέ{ŻaťDZÜ=‡ţ ĂCýtĹuĘSř‘¸_P9OíţÂéĐź Î×ßń×ĂOÄú#Ľ0kţ˙đÂD ˇŻÂ\Ź8 1őčOţÚ§ŕÁz †˙Źý†’}$łćńD5H~ęűý† }ý»Ó˙ě @×ľá żăŐ˝°dM÷hµţ— BőÜ;V‡Ă^úD>ÚČmE~ äpW;iÁm¦™˙@Á~AťY>ö›¶żżÇÔqĐ”@k7›kŻďů 'táşvͧýdőýH*?D„î/ľßßO˙µ\¶·şëţâ@ô!ŰNýţmZ˙ü4Ř0í?˛‡^„Ž$oţaĘŹx<Ćď"Ž^K¦C.…PĺA€Ý ˙/DŔeeą@đTpW^ůâĚy'PKěŘ4ă×ćň`Ä,á™eUáůX+żCČd†Řř0q„ •â; żAßúů*0ä ţDóásPB é˙ۨ2>'4ň3 ô&“ČGAţÂkäDş´Ä•B=j» §Ôđlż<1ĹÍß5!ďh Ú˙°aŻšJń^ľź˙ čášk oÎ6 Č*ńÜ×ţ˙bŘ;ݦ±˛ä_ëýöFI¬×u dp_˙Ç}qÁiżkľ#˙˙b Á‘đkţ«ßWżäĂ( ˛03Ż[˙ýČ-Ar Z߼‚Đ˙đ×ü‚Ři!Ą4f#_ý>»;‘G ţAlF1$OľŞ˙ö"5ü ÖŻ®öľpdr#„ô˙!¬_˙ˇţÂü†“T|‚Ř) †ŐD6Çű]H*eÖţ /Óň `OäČ ÷_iëń˙]Č)Ó˙ôîţ˙ţGRŕÚżýýŻ3 —ţC@ţ/$[ Đ9Tżü†ż•3_k˙ń#X;W˙B/Ă Ň˙„A† —ńżdęż˙đv‚ţČ#µ|Ed0=˙˙=R iµ÷~Ó¦C(~N×˙ Âač 4HQCźď®źkÓŘĎ—Â@đ@šB!ř÷Xk´úţ`6ű¨o"<$_řá…ĹěŕE˙äŔ‹-ü†yŕh^"¸`´?ß[8F€^ěÂč‹™>đů §8ĺqű˙ŻB,]¤ Ĺś×ď˙ú#y-~–Ü7ď˙îüYNy˙{‡ ď„ —˙ÄxŹ pxŹoó€«˙šěč’ŠäÇŐ<Á Řë˙Člݵ!Nënţ™Ý>żůŽC) ŹÝŮĐ}˙˙ňCŽGŢß˙ŻňNAT}ŚuĹěŹţ=úŻŮßA‚jSő˙ý®Č`¦ä ü5ťC«˙˙öꇆ(‘˙ý/‡ěň:QP× í-üŕsbű ¶R} d§µ ^¨5˙Ă\1 Áľtř|áž•ż[ű Ă aĂcĂâË2˙ňy g_ r a9ĘN8ă˙¦˙›Mq"О:_d˙Ö˙đŘ\‚Ř6‰k}{µÓO˙a®AlŔ‚^—Ó_żü6‰ţ čl_ż™‘!ôźţa/ ¶ŕ_7ůěGíëâ&Al0qaŻÄč†?͆oý†‚A_úo×˙í„°‰pŰ_Ł˘îýaüČČŹĂ´I†´÷KŁA]áť5ëöźí\0Äś ŻđĘĂ0ľ˙żŘTŚ"§PĎ}cňCʧö]Ű_<2\4!tőăÚ ˙Kč‚ bľ=x3@!ýz~ä4TŇzřŹ˙>6F^ý× ^6ą'řE{d2Ş ÔOëôó¶ţ í˛ 2Ęu ˝‘Gőáíč&ö †Yr•á˘rţßgS ˙!¤ŕ‚ ‘_fĐdč_JA­ë‡´A˙Ó {@f‘Ş×˙Ń´ńWáśD€Ěľţ÷˙7áaÍ`Đë˙ö6 =ü džÄ202”ŕk÷_ î­ô?Â|‚ج†;Ż÷t}˙>Al3\ŞÁ†ďDä ä}űń_ ńdfţ@ńĚÇLĐ7Kß&˙Aň aŞ Ip­ä‡BôýVü0¨Hä  Üá>AlKŇP·Ţ˝újO˙Č-‚¨ç­ţS ´=Ąż|4í?÷Ä20÷‘'¶ˇţ´y V˙Ż —Ł{é!uůü༠'6•ß˝dÁe; ëi´ÁPý›I˙Ůa÷ Ě0—kúiéżňhe§<2ě]uţžžżA†Qµôôźď§ëţÁ€ßîvő˙˙ů0 Ýżh]Ç˙ßü.ő xgx!ňűú ¶ú8”ńµ¨˙˙ß_[”„‰ëí<˙ýČ-†X¨±‹<Ĺţ—_˙ň `܆`WŢţÓďđDt †hçÂô\Ă“˛r .ţ¶źÚ×á NČćUCKB"˙h0°Ő/퀸0 ~YUŢÚ¤á[úD0Ó)Á¤ŹŻëb6#˙AŰĐX\Ľ‚ű˛F! ż´2čľG„4@đÜwý¦š_¤,6±ői¦_ŇDQ˙xŹúL?ú{ţ~ż˙¤@ľ€Áů €Ő˙Żč”Ź˙÷HJ@n˙˙ę@f˙ü0 đá‹ţ»oČd¨ďúß˙%€Ŕ~@đŘ‚ WýđD0pmůÁ‚˙˙˙„NË Ă6ň‚$˙GKţahIÔa¤šd Ü…r ţ˘?ţĐlA»Áćôtń›ˇgŃ´hL©2ůôNŤŁ ˙»m;{A Bź˙ľ`ČqŘ~oď˙vč6!ďhkKk˙ÝĂ Źš$CŹŚá—28R8‡3lŤłyŻ0Ź":&‚ó x ĺw˙»PŮ ŚŘd‡DDH/b""JČjd !×űöĂ<6ž+ŹÓŞvŻű@źüűŽA¤t˙ON˙۲(ĂdtőČ;Ř_ŇGWűnÂă#ßýŻút¦ËţtŰeő°Čjżv? ťŇ~˙Ű»żş˙úú˙řvŻî=Wő˙űi¶‰¨ü‡Źëő˙ŘmŁ=·<(ä08_ß˙é˙ôáŃŰňčGWß˙ő×đŘjÝŢ5˙ë˙ú#íĽ=j˙˙˙˙ăeĐĄöG@şŇ˙×_ü‚ŘŻŹ»n$,˙ţţ˙ţţ˙ÎřŹ˙­Ż˙Đ|!&ä8˙ďýţżä4Ç Ş>ň菂řM żoý…Ři§j±l ×V„4ő]}ČdĐíŻk˙ŻÍ|ăČd ˙§×lW §*ź˙°c.ŞóTo˝ďýöÖÄS˙űY˙Â.{Žż°l-Żř3AÇ#pČ0jáyŔʨőţhCCüDG°ă ľťV"×ö#˙†_!.’Żżé˙â ¸$¶ůÁ°rś@íäü‚Ře;Ş]x!bĽ2·íäÁ Y¦ë<ôQśEŃďďüئ7G‘uČ-†™pŞ?ä ˇĘ¨CĄÄD~ /čDDD‹°m«k xl˙ă˙¸1×§hÖG˙ň `Ȣ«Ş xb»˙˙ň `ÄŻë xWD€Čż˙ţ2 z9 •ř!D ?˙÷Š[<† ‡«Üđě ß͆_˙ő†CHv7ő@şé˙űôDťżn»˙˙®$+Ö˝É"÷˙kÂ4`Áí+jCßk˙{ˤBd'aĂř±<żżýrÓ¶S„+ x%a®/ß_¸2\6ŚÁ,F‘Ă:r†ăŻż˙éŘ0ăŽĂ Ág{D îC,˙c!–#adŤ¸ôÂßŮ„í N N?µß˙ě Á“( ¦@đŐţđ×'Aţ÷ł e‡S`×đÂâ˙Y8, Ń >]˙Πxh†mC0<†@2BąĘÓľ·Ľ1A§GČd›‚'Ť7x˙x6ˇUčý{á`ĐApú÷ůômY ;đÖAl2†i‚Ýßř!Á2>F‘±ňä]ü†@oŻř’ ; Ľ4×ÁČ-†¸ĆĘ‹Čd ˙4E:ă< Á˙[ ˛ä3DxÁüGä2÷ä4ś‚ŁŕÁi Żţ 4ŻOÁa™Ç˙ x* Ja˙ď ¶ Ů !Ě×˙Č  `NkE’× —Č€ĚöůĂLeˇ~ż[çPkÝüÎ#ł†Ľ#PÂěĂ”çłyG)ëN †‚cźČeßó`‡µ aô ´÷‹Â0Ëd3†Pô­ôú K´˝ÚĽÚx2 xA˙÷°`Či $Ţ@đk{^Ó^ x H żü[!”]ëîľ#đŢ@đ( _ľ2 kV—ř?ä6@đ,O˙˙!†X2‡ Ô"›Çö´Ô0y €ß[żÚk˛‡'Ă-oŤív™Iđv?Älśt Ý+×gUâ!áA† ;ü203H€Ő]ë°]ࡆ?č2\3AŹY÷9sAĽ‚Čä6ź!đa ĽŕP!† ×ŕČ0Ě“\DjŞ6#ř"ś d ˙ ¶ ĚŤ­ÖŻČ l;ű ¶•śpd 52 #ᑾ+˙=f,á´\( Č˙@Äđ*3¸!ü&„pD`Ó_Či9QđÁË/…Čdú‚ä3ń–« xiďűO ¶ĹČf";ŐČ G† đš:đŤ`KWëäĂm80×Tôh úÁďÁ˙ů°dÔĂÍ·ů —­ăh/߲ `¦BÇiVNŹoňś€Ëű83ą°'NA˘·ú%´™ďä 4˙ÄG[Áí„G\áF€ÓćôÓůĂ\Gß°`ěÇŠpR͆ "źÇo˘‚ŞţČ5dd;Ö¤A„+Č ?żŕČ€%A8ŽŚ#`¶'ŃÂîC,|7ŞkIUuŮÁLb ‡ýÍ« ¶ S•€ý‘čzáxFAeüüŕNžďäĂXT=r8p1ťÚý< Çţ@Â|‚Ř(r–[Qˇ«^˙˛>¤ @H‚–żŕ‚Č-‚ű5Ý!Ëá“!Ń ?ÜN 2 aGB€˘8l&×ä2űaţ ‚ÂR ňă>v($á–źČdy¸9?Č2 Č-™AÖiÝ©ÂáYµřŕÁŕÁţ.@€ô}W÷ °8i˘ /ăôĂ~ŕ‚ŃÂ+˝ls÷†áş ţCX˘ů@Ž+˝®6S®]máëÁŕx>…Đř3Ž®,YN¸÷˝Ýúě" I\Dč×˙íuţ č†ĺąńv+o˙Â_Áw¦„J™¬ČjS× xIč °—˙čIhđ„?ľ@đk /Ř=¶äl6¸_é¶, _lÓ{“­Úř…żnŮ tÇýŇA~{m·D2TwüHQ9ńĐ_† †hچWi˙ …ř0xlQv7tH˙ü(_Ňp`ůĐH0×iŢ@ńG˙¨(_¦Ca"060@ČH.ö$Ç˙ č 0d¸e`¦húˇ˙ňda•a” Cć˙ţΠI ¶ ÂĚ i­?˙ůOó›Á’a”ńKf0§"ćë!˙ÄEäĂř2:.a&Dz˙é˙đÄ2 ŕ•[Z Ž˝d A¶9Ă8˙ŢAlÇ8čę  }Bt‡_ôî™˙Ą@€d \mk °?÷¦µ˙űBwĄ˙o˙k 'üŘ6ő›aP §!˛ŻĂîˇß­†Â_ďę`ĹłĐ˙qÇ^đÚL_˙©9H!”†‹ţň˙ö@a/˙ĺÔC `ÇhÓQVĘă(a1ĘcťĘ.JĎ~a Ú ţ¶í!‘×]´ ¨ Ad~"""""#Ű 6ýßnÁ˛ EĹďě±­PţÄ& ń!`Č0t˙×á„…ţÁ"d5§řabłDz0ŽôR^9ÔűM†( 2\ş{ ‚n\üŔ3Ă|DGµţŘlî°Íŕ^E°„4/ýt˙Á†dL?Ůă˙đAżŘ0mTQkÄ?˙tiŻĐ`Č0waÖC 5śÄÚ7Š˙!ÂA†óŇ}‡ NŹu„Í×ü i0˙L†ŰŕŰ ;w_BCdéÁ Ăü†AP0ö4â/ţ‚a ›_ü80ČX x5ĺßúA´oú} Č7¬âHpA©ku÷Ňto˙Úaâ9Í:ůĄőŘAá?ńáĂ ¬!}…Vżví4CŽ_ű ­LGŠ ˙zúŠb)Źí{# űHZ×Öß˙]Ä;đÂzÝţ×˙ŰÔ‡sĹŻOwř~ż˙›#ćţ WęĐzĹ˙÷˙HD†‹řaĘşßß ńŞřŻţÖöAŃXż…ţý¶Ű˘·˙˙ý˙@Ă0š}Š˙˙ď˙ůÓ†,ńůř%˙˙˙†«˘ ć A^kíż˙ţ#ô^E*_‚˙˙ú´B ű ă~ż˙˙®ĂAűHčŐ˙ţ@đŇ-÷ü‚Řs…YtČ ~0L/˙şţ†ŰŮ!ńüÁ‡Ő}|ŕ¸ůł~É2ť»Ü]a„÷üäŤwX™âČr:ĆťČ c•ÇŚsąO˙§ŚS榟ţńhDG˙ľq˘Ę»˙ý˙˙ ¶ž‡n˙˙ü†H3Źř>áXaśĆż˙řűÁ~˙Č×)ĘĂĚăś‚‡(¨đT„°¨3•ĺyC”ćâ°ăśsů#žłęTŠ>Í AX¦ˇřăźÎçÎaÎ9N_–9ÇRÜđ˝řd0<3L/ˇ˙řB""""""""""""4"""""""""!ľ¤4‡ě.‹ćúţťý'䔼ď˙kţ°E(|>˝ů'‘ň]"8(#ĹŔđl6 H ŁG$9PDł9=MşOżäÓ<ˆ[˙† _Â%Źłx0WČ-†6A¬ˇÎ8.ávt"ë˙ą^˙ý“rč‚Řiq[«Wá‚w!”?äô‰ ˙üDv$Teď±é§í-ŻľľAlpk%”ď°ľţÖőţĽ* I–řá®gFhÂţlO§˙ˇ$"ŕĽÄa…ÄDCú›MwŻőŔ~j«Ţ '˙­/˙ćÂŤ˘čşóŢ9C˙ŕĚFĂ/~žä ÂŹď˙Љ ^Š\DZŻÄW˙Rś‚°ä2Aµ×˙˙!änXçĂ9Ť˙ď±iT‚ AQČ*żw˙˙]AŕÍІ`Đ"‡˙ő˙M4×µ»˙ż  AŘďÇδᭇLăď˙˙ú˙ýä3*]ćČ<h~˛†‘oéÝÜ;(tʬá–úţ>¤Ă ôÉŮÓŻa7ôČŹň€Ő( B€Ô# `Ó †™…űŻ˙Ö¬ :¸Šż:Şµâ˝ŞhZß˙˙äďMŻŹľúë˙˙ď ©Żř˙ä2úéÝÁŻűż˙ Ę˙ţ?>glŘm  › ła¶ ż_őŞżďßýŞjď˙˙saN•'Dtx0qů2°§&ć”sw;•Ź~ýÚ˙܆He˛%ˇ'ßň ď< ^×˙˙Ň[˙}7ů7Ş.!#˛Aźô†qČqʲnBtż˙˙G(Ě  łá”f†Q:#s00| †QđË>!™Â"ŕËC[ň PĺŻ$9‡+2oű_}`rť?˙ü'˘@1AA?O „đŠqh§CH2B""&€ľüe>·Xż˙çOő„ő˙U×]4Ő=ĂMw_űkďîĘp”ôý~űÓÓ"W˙ţ­µű_¬w8ä[8äđ«°daQ ˙ä_Ż_¦¶˙ďxa%˙’G»Q =z: óË×8?4Şäô%ýűxí¬Ř·öu /ŢźëŐ|č ˘9Án¬đcűż°ÂTźěWkó{éßű đżXxgkëR T~Á‚kđ×a.°ý?˙ń_đdÇ ěbK;˙Â@_ěKü0¶t˙đ·~˙kÎŞĺ8Ź˘8KüXä~áŠČ7'˛!áY‡X޵í}öş˝­ C×Čg-ôřaËÓb+»…Ă Ř_ö]íaÂí®ż†řŕÂ×kÚ\ź#’÷Á’ú† ş/5y©uűŻ x2WţA_đÂü#¨%ŇŘŠútNŃCâ:k]†]4ĽČm‡d6ţ Ý­Ż'ωÁy *§Ëµnä‡=”ݎ$Eů°”?Ł@Ń 0°ÂňgUŞwŽžµá¬DHhĎ!z˙o!”9F?vl Äpׄ""ôNşúßţü, 3× @¶ATQ|K—üŕGł¨{^ÇŽţO×ü‚ dBĚ [Ů ˘xŤvűĐ`öG G_řb˙˙E fďCR&{?R×űz•#íd6Gřoßţ´ő ? ˘Ę Ńä6wuŢ„y '<>ů •ÝřoÇţDG÷˙B ý®×˙B"“Đżđ×< )ď˛Tç„/Ź.ýä3C#Ť;ýŇtżTŢúđţ@đV¬€×ü†PP´$óNޱ#®A@L†¦őűŇ…ęí~ÇÂäżř|†oÍđČ莿ôZ:‚g@Hj°|Č Ţżď´˙’˛.Ř·'0˛×8ä4Ľ‚wţźů_ýŻ˙ţCÔPç˝Á‹8 ýuÓ˙č†?ň ‹{__ţô"ů¬$łźEřký܆Ş{ń}„ô/‚Ä>žžÍŢ|X˙˙ęAQrçů (*ăhëÁ-kű^Ë‚€˝żßü.i‚!ž §?“ăhČe>C(źcţĺ ŽF˙ó‘żCâ?ýwů ·+ 8áPxB"" ň*zíqxB>mśżN˙˙˙ůĺôÓŐS×D„Gtő÷~‡Á,C•Ĺ9ßëü´5ÜŞ˙Č.7¤OOî/úďÚ÷ăČWé˙ˇuúćf˙ůÁśL§ Fn˙Ź˝^C`–@°űÂü ô ˙ aĘOÓö CůŻ› ĽŰ=W{ŹÂO˙TţŤHŽ>’~p0p1Ä3c˙ěAŢźű[µűá®˙óă9şýgé÷Ú÷ö˝ż_úńk·Â5"őűĐM˙Ń f? zż˙‹óź˙ń¬Ž…~ë˘@húţë ˙Âë˙˙ýSů K7}ô.µŕfĎßűJť‡˙_a%˙˙űŹÚmrsŻ÷Á?ůă“tČjŹl?ĂßůöC‚Këö¸wŻ×v"ß˙Z÷ý‰C˝şţÓ^"’÷·ŹÁżőŘđj–}/âŘ4µ˝´×k˙ß!¬>x&˝ë\úQ6 ˙ ßĘP~Á`ŹřÁv«Ć•¬8J!Ž­@¶ ľ rmjFVŻ˙„°Â…öí9ÁĐ^‡ÎGş·‚ăÁđeCb?!Ž@ň1ˇ«Wî˛ěQÂů4ôOziܧŃN,†•@ŢÄň.'\D5j?Xt?ľŘUÂkßZ}=/ EoĹP˛ #”?ţމŘ">5âř_˙Ă ¤Alő }ä2á‚r ĆŮCÁNUčśN ŢA­ý0żápÂČ,v,/ń‚ć7kDCŕňzxʵˇ[0KŃ 1 a&ř0żÔ ‘ô>Č9'%‹ţŐđY J~?řOőú!–ČuyäoÎ5­ţxÇ˙ü ˙˙  ź„ő í5éüC˙˙ŃÔ~C7‰gw˘\_§|OMzµ Ţ? sç ëŻ“‡í? %pOk˙Ň}î@‰ţ@ćdţýđDuöÂ˙łŔďë_śů Táéď ˙řOá˝r  h˝ kú_ µ…Ç ¶ö·ß ˘9rĺFżxY ˘÷Oâ?Ú^A¬r-/Y˘#»ď˙ Áfpě,MţĎŚuˇ§ÁxMżŰőĐÜGn»ýÚô‚őA?˙ uŃ:îřa~t×÷ß­?˙ µÁ4¤3G0ç‚ÜĐ‘ =ŹŮ¬KUł’~ •™ýOţ­„˛)G4ŕ„DC°‚úöî>©…ÄH0^AC“s$ĐD5ßďýşĹ‘˘Â -tF~ţß~Ţ@€Nż˙péh#ţö_ëŞiáőé?˙Á¨,†hĎG‚ář0_×úy …ýŻţ,,N˛Db  H2 ?KYťČfŮő*ď­ŽA¸Ě zä„tÄâ źp–’Á…˙ň ÂCOEţ ^şˇýŠżňĘłŽC`ú5e<Č6Sţ|4Pß˙íá‰1KDíč‘<‚¦={!ŁbÂ{Të΂쓞źřjż đyś}7ô…ž7ŽßĹčŇö˝d0[ŻN¿ЉVö„ Ţż§přŰ­=îČŚÂ~ˇŇ~ä“×ţzq}˙Ăë˙ ˇĎ2ś­2 +éřAôúČtúU×§˙ZýbÂ2i˙ŘO˙§Î‡aç™Ččżđűü2ń/—şř20 ßÄ_ď^ą?ŃČŢׄ"ŔÇţ×ű"ꤑá˝5÷˙ýŹw{ďű˙Áp_ Ă Ě”ĘrŻ!¤ÜŘÓ^<änő˙·6źţŁäżcY ĺáj}Sý†ţ×ß˙Đa˙ä2]xbµÂ_ßľ[Mcű_÷·˙Dk„Să{Úďü5ě”d“¨‹µĐ˙ş±˙‚ GQĄöá× ÇŐ=<_˙í_ü†űá…ÍŚđřKľ+´˙ö¶Ňţ‘`|Ě ˛> Ě?kµ˙˙Xđa_ý>l …Ž?ľ‰0ü„ě]5‘*ńk¶#‡˙ń!µúk }bĂăÓ˙“‚—ţCVЎŻßťľńĐ_áˇţÓ©Ă#˘ěşţÇß©N!Ň ňeü5ú§ŽBUšd$x/ůXöOÁÄŕ‰€Q!śł őŹB"Ě­Ú¬|8+ô‚\¤f¤`ăëä ÚđŢ‚ďŰżő‚r ˙„k »é˙r n<'Żý%dßĐ/öb˙ólŽ–šd®ŃĐ˙®>‚ČeąZź?ʆ»Đµ­‘5Ń@|Ř.x˙Ő˙˝µÝ.NşŞkŞ|7í?˙čÖ0˙`ô˙!B\WÚo„ׄ÷˙Ő4H ˙Ă#ţ‘&»Třž_§˙˙łş\Ě2ŢBx+ ˛¬ă”9Ců ¤ú˙:xkéW©đŮżő˙b+AP„DDEř7łaŁęŠ.C><˝iw˙˙ë[§ŕŢżĽ=i{TÍap×˙ý…9w˙!¨ý6`4źq˙ŢĂ {˙í5ţ„a? ŮŰăý|[ö íŕÂ\D…â×]ŻŃOö«Ăáşń˙Ĺä0oÚkÇ”"ćľÖľťÖ°č/ďőf őŰb?Öü0‡uĂÂ˙ü•–9C’rŻbżňm{żăײ¸'28˙ř!µÚľĂOä0^żëÄ_˙đaţKä‘˙|‚Čë˙ů ‰8kţCQËţţDcéîďďË׏×ü _őCî-~¤$ëÎ ŕ˙á+˙ž?ŰWµý?řAd09P~ü^·úý;í˙ĐJt˙§ä3ą_ŻíôA8‚ů˙ţEXJŻ‚ďé.šxßżű„˙˙µ˙·ż˙˙ßůĚÝë×ęőO ¤ţ˙˙ Źéí}Ú÷%jH~˙˙ŮôGÂäQČSřţAąĘ1Ńd4GřB'•ë_ßő@Ľ!íO#‰b@ľi…ż´6~ü4?î z{eŹÂűT˙KúÇü‚ő¬§ żb+ţÓ_" ”E.ćü'§í~˙ďű8čŕž<‚ĺy –U‘ŽV~áţ ć´ěçˇŐ­ń ˝ë§hD_únÖáÇ«е_ýý÷ţ‰¤0ŹBůâiř†«÷ßô˙ćaŢľ˝=ř§úŃ\Ú˙ô>wëţďů2ä6µ©Ŕ!Óá:PČëÝNg˙ô?Ř]?ţF;čů?ÓşŐ=¦»¸ ż˙Ó^? _Xkő˙ëA_˙Ă_§đ‘OżŹ{ű®8AUŻű˙Căë×ępS‚ü »_ý.îž›…Ż˙! ž ‚‡(r‡PlpżîĽÇ˙đ•ŻöëčDD^\E‡…±®Żiӿҵé¸AaŻđÂamo0Č៯˙űY ď-Żń0µ×OúüuÖ[ ˙xá˙ţšy'Á,†b?Ču§˙Ö˙ÖńÁ,Đ}Űá‘ďů ±ÜĐ?«Ľ$xţîE˙úä8Ďŵů89P沇)ş‘BgăśrW9H;ť[ú!—i ź!—…xĐž˙®ż´í%za„ÎS–ĺy‡*eqNS•Q\PĺAVP!H]Hb ĹŇ» ý˙ÖC+?!Ą®ľ’B"""""""""""""""""""""""""""""9ń‘ÁŘŕŕ6fA.32ŕĄňĚv— ň ˙ţÖ¸UO!˘f„ˇČÇ0ý$úsxKM8łµô8i%„u <˙˙Č.Y­|‹.űÖűđÂ®Š»Ú˙ń˙ŹOŇ~` Í9°'8瀠śŘr9d|ľ~#ŁöGdprčô0ŚG‘âC)Čg|qʲcśr1ňVB9‡Čâ-2T,rwŐ˙ęźä?żű˙Ő?揲ä\ň~ž…čGˇzčDN "/^„DC„/"ű_ý4˙Cúé˙ţą˘˙ö"8‘lçÖýúëÝ뮞ż˙˙˙ö¶D&VżľA¬r˙G‚µ÷˙˙ß˙ď˙˙űőZŐ`ŇĐżâĘŮr¨w)Ę:en'˘´ď żŘţż Ń®C5>A¦Ľ†X7!š9ulŽČëľôÖřf× ×^ďďő9oČhc×řŚGßúČf'÷ř,'…kÓ±aä4ôČiédőČii‰=l0żőý/ňÄšżí|Ť>ÖA¸„N B¨‚$B(„P ‰Á2€J(˘@$"€M~˙­ű«Y =~ śývUč-†ŠÁh:4č*F`ĹŃ 1@´˙_Ň˙PÂĹ…ŢŽ±°'0 'ŕ'c˙F%„k˙őitµÖ‚´´]o˙ńIŽęěÓXhHlŚ5ţŻ„˙ö$űŰíďľęö}ë÷űţ¤/‘„C Í‚Oďě/…ér@g}ݰ{˛&t aś}’-ě!‚d0ř5d€˙úúŻqr `a ~ľ˙$;čĐ2ŢĂG_!°vu `ö ={ YĐKaÆt=˙ża5Zá5.SŤwţ_\ }ý!±"PŁ ˇ^@ľ.ČřtC(töC,xy}ä đAä(ä :_U¨Ťţ´C>¸bżżOć ±źk×đžž„j»^@ą<‚‚xCČ('ˇčéĹß˙Ŕä˙{˛V_˙ü?KĂ_˙®żţş}ëŻo˙é‚ňQ6p? Î9 ű_× ‡Űöß / Ř^ű˙_ďűďő˙úôď‚ň€˙ţ˝\|G ŞůgČ+»W|†kaň ď†lY ÁČ1gˇý~÷M:˙O Ú?ďč˙˙qÇÇÄqů %˙^«˙ýx˙~^Ë˙Áż ¤?nç× \rĂČfه,|Xä‡ű Ň=ÖA |Xů‘ĘđVs^›˙ô·˙_ý7řKÄDĂ5Ťdđ„EĎ×˙Ř_˙˙Űýž˙ř0\Ŕ`Ř'ŕÜŘgó€GGŠĎAz< txó€CŃŔ#Î˙ń_˙ä ů/Ňň…ŮCsľ#őy¸+ý˙§Ň ˝éřAôđ›áú~č Ţ‚~ţúß˙htx8 4˙|ŹôtXŹ[úżý7Ón“í}=Óé7××Óď˙}Wř鮾ţźđW÷×˙ż˙Żôý~ýWżż˙˙á„×ů ŞűOż˙ţëęż˙˙÷zÝ~ß˙˙˙!Ş˙Óř47ů Š?˙ż˙š‚ň á3ßöŻ˙˙˙˙˙˙˙˙˙őńŻĐ>ż˙Á‘ň;<űýôÓńţČGKČGü„ČGöČQţČA˙!ňČQ˙ż!Gü…Ó˙üźOđź×ů 8ŻhAŻűÓ^ďĐ0_‹ű*ü'řOôäÇ_Óű §äHŻ ý‚ţ˙„/ü"€wőáŹÍ=„˙˙Ż˙ţ«˙˙˙ý˙ú_ż˙Č"Oűđµü ˙`ĺö ‚ű˙ʵ[M{‹´;Mo[ŽŞýÝ­¦·kq×ô˙“†·úú a~×÷ÄqŽÁˇČfYN85Íü†QÇ HpĐą‹˙ëôx6ßé7ýä3넾?˙üqÄqÇqÄqÇ˙ë˙˙Ą ×ë䜡ĎCBĽ†Î)>@Ü粇ČePćĐx*2 N[”çăä2ŕ“•eŹir¬ˇĘăä‡"ŹŇ™YhŽ 9O/łÁ>ČfqNO˛—˙˙_ßľAF:(‰ íd8ä-űů=5Bň`„DEä$Č(H¤ «Č('P“ ˇ&„GPOď˙őKöşŃ8jpÖ'ëŕŠ@1×_×O]=UO_˙ő0äű÷† ýđxAxęźµá˙ëŻţşëŻ_×˙»wřpż·°ř_÷÷áüŔifÂ‘Ć ›sís˘Z?‘ŃÄĎ#kýu˘ŚŹ‘ţŽD˙˙ĂuîC8ĺOü?ň9ŕ»/µ^˙Faˇţéô<Ŕ5fŻ"<Ź0 Y°jĚV`đżÚü=o† °š˝ä éĂđ„Eő6˙ú8O˙˙˙×ú˙˙˙đ÷­‚Ő7ď áőÝ/Żč7ú˙˙ţű˙˙Î9 ?ëřűŘŹ¦¤3ŹŢ$Oż˙ňÇĐO˙˙˙˙˙˙ŮO˙ú×ŇGßEFf!?Ă}żߢ( ˙Ţ˙˙˙˙˙ţ˙ü‚îU•ďţBőü2eh†Ź%Ý/^źż^˙˙ţż˙ý˙„".˙é'ýžAEX7í?ý˙ëţżú˙˙˙ţ‰ŃBţ˙Żţ©{őŕaýkv˝wď˙˙˙ý˙˙ýŘźďôë˙Ż!­®“x#¨ż] ďÓ°Ňý˙ţż˙˙_ýWç˙ţ˙ XI˝2ľöüN0Âýo×ďľ˙˙ţ˙_ďđ™Ă˙öÁ×ĐXKÂ~˙k Űa|\qÚÚǬqÇö˙uúŻ˙†\"€hÓ‚¶…i˙‚5\6—ţ8ţ?ű†ż÷ý˙ýŠ Ě#Iľ Â>it|˝y ‚:†¬—ÂôźWĐ[˙˙˙B"ůĐ6¸>? 7˙Á˙„ŹŢ‘űŇ?t=řHĎđ‚3ü$éfĽ$g˝$}t‚?zźµ˙ý˙řoÇĐ ü†`g}˙'č$ţéč ľ’~‚OÂA7¤‚~? /HO sŹ˙˙ţŢ@ą†u ®‰Ń{đÄ<{ŇßA?I~A? ťôá'č%ř%řA?IyW˙ý1„đd0kř?Â:r€Ďü†•XAk„żKş ~•ú_„źŇ§Đ_¤ţý/O˙˙ň ďµX`ü†PäQđß @üęţC@ç°ţÂ_¤ľ]h/Â_„µÂ_„Ú]č.´ľĐ]˙˙˙\SŰČ5‘Ĺä ý> řB/řĄx…đÂKv’ö®Â {A/i{śtľŇ^A|4—˙˙ďéĂ:ř?†˙× @§ÂUĄâÔP[KĹâ—KÄBZŠ]Š ±.AFź˙˙˙ä9!Ř={Ă_÷˙ú}´—.Ňě.©z^ô¤¸KÂ^Ľ"@ú˙ţA¸­`SúÇŰZ˙Č‹ţ^Őp’é-„–­Şvľí%ŐmWű˙ţC,'~»ăéA„µ˙Č(öyśrŹí0Xa0°ÓVMl*Ă ¶µ *ĂP¶Xj¶-˙˙ů ű_ÇöçUÁńÁ ;qGĂCbÂĂ „á„8a †â/˙˙ţ@A©Č=˙ěUĘŹ˙˙Ö48Ž8ăCđ˙ßáCVÖ#˙†´˙˙˙˙ýCý˙˙Đ-ŻňeaN{Ë­rś?ňu˙˙˙˙Řa˙˙˙úőČg!ďüP˙˙÷!Éý˙×ě?Ę‚OýăßřNÚ˙˙˙ż_˙ďň ę(}|‚á?ň]ü ńď Řů ±ňoU˙OČ*żů±ČqÔ‚‡8äQʇ±Î9ěˇÔůŕ«)Ď+–äÜă”: ŐYüĂ”9VAˆČ8˙ů ´ů)kÓٵČ@ÜćĂ/ú(˙r:! tCcĂČ7tAZ2 ŃVŚ‚«ä_ ©ARň ÇOř‘\Č@"žC.¬*Ďźđ´ú˙F`CkôD'˘„GËďLäÝ=S‘ŽťŮ äÁ'o,ň âA»AĐyńjAĽ' fˇĘ˛‡AăÇůĹ4Ü‚€zz^k_ú ţ±¬D_ĹńÄ^…čEč]ˇ|DD˙ţ͆· *_ţ‚ «ţ˙]˙˙ß˙ÎĆňč¨DĎ:#hëŕŰ0˙ĚćĂôűëÂoW˙Đ|˙˙Ż˙˙˙ćŔđ†Ŕđćđt$ŕá Y߲áżô| _ çú#k˙ëţl#‚ú뮺ëŻë• s26"ú÷üGZ| {Oţźd‡[˙ÝČ+Ý=0Y°jĚV`čŘ5ćŻ6 Y°kÍJeÁ®Ë_ë˙˙ĐAż˙ő‰Ô%‘ţ@MGjŘ[ímmml*¦Çď˙ü†^źý?˙î÷ßţúwăBŘŘăŽ8Ř˙˙ýţŹ¤ßżű#†]ő˙˛uşß´żţż˙˙ňĚÓ˙ů§żŻë䏯˙úßú˙˙ ˙éď˙]¤3$üÁoý´Ö‡ýş˙˙÷˙˙?˙˙żŕÜE}÷řx[űżß˙˙˙Ńđnţżë^u ˙ŕđ–A¬sćäČeÁNyä5ăä4ŕˇĘŠ ÚĺET ŐQň ä4‡ňŁťÍů ±Íçż˙˙řAń×űćÁVĘp’Ę ·öżö4˛ řO  . HË/Ë/ĘĘ/ˤ2„d Љź_˙ôärµď­oë ş~?ři,†€%Tđ´űÂxOOO<'„đź˙˙ý>HŔhŮ˙úýô˙×Ááaéë§„í==<'¦č5OO˙˙óż‚öżăţ«¸kG@%ţx0ÖjEÓÓÓÓÓÓÓŐSŃ®z<2ĺ_˙˙ľČA×OmR»ë¶ţgńńçGt} ý<ŕ1Ńŕ#hđ´póŔżG‡Îpđ„ý˙˙® 0¸G@áě»Őô ŻÁ˙÷AţťéřOĐ~đž¨: | ú?Aú˙˙džˇ.f;Kµ˘Oüę­˙ţ}wéýşIúú~ź¦şß}+˙ „9˙˙˙c  D2űp—kaÁî‰Fß˙}_˙ţ«ţ›˙÷ď߯˙wB/˙˙đőÂ}á  Ś `BĘʤů ± Ë+L†hĺkËŞ˛c2á3źżę˙&#kü‚ń˙ŹŻ˙©ýtš„Đzđž@şŚ‡„!ŕÓĐżţ˙ÂéúZ{Żo5‡Ę7ţűÁľžžť'A„ôxOOOOýßőďwĄ×ě=!)˙_)Ă_Ł1zzzzéë§§§Ż>OÜŹű˝W˙zÖź˙ň+} Çs€ÇG~Ź"8?ź yŕ_ĎďGٱîxŞ>z< t0G˙č?Ç˙®ő¬†!ďřA˙ďÁúiá¸BĐ Ţ‚h ü‡ĐAřAřOĐ|_˙ĐýţŐi.š˙_˙Fo§éú~ź§éľź¦ú ź¦ú|qĚäÇ(uŻţý˙bě5ď\Śr?˙˙}ČŔQßëű×éßúőúwŻßü‡'ô°˙Ú˙ăK[QŐ˙Ǣ.ľż˙˙Őď˙˙˙§ßď°˙Ćż¶ż\»"_jżţ ˙׿÷Ż×˙ëţµ˙ŕĂ˙! r˙˙i®‘ÄŢ!í«żä4AC”?ݶ˝ŻęßÚ÷÷î·ý˙đלĚ":ý»ü˙ÖávŇ×ôČŹ đgłiŰd08K†á…ŘkÁㄸkÁŻa…ŕÂđĘ/DĂ˙ü?ý;˙˙˙ŻúTű0ĎŽ˘>>>=ö+Źšż4G׊¶"ż˙ţú§˙˙÷†«ţŐ= @4v·Ý÷këcŘŹ}Ż×˙çéN˙é'ćŮÇĹ…˙ZŕŤaĄĂ iÚĂ[NÖĂá­­¬5ý˙ý˙á$˙ýŻűJpž@Šü°a`ÂĂ (aa…†Xa`Ád(ţď˙[O˙Użů篿ü†śoü$čč|hqÇr pä5ź Ő‡Gôżď_ýRu˙@ďŻß˙ďŇôN ž˙ühqý˙°żúţ> ˙řúúÓ{6ü†Ç Cäżűëä ¤ ?˙˙±_ú_ú~ż˙űúřú§©# ˇČî@‡Č‚ß aČg|‡ Dd A b1@‡Ó ÄjA‹á”ß˙‚˙m%ČK(rOú3?őíd:OŇęź ¦ţťé§§xM>ÓÓMBwŞzw§z§„ţ7˙ôýŞşÂ˙öš×ű˙˙_íU~đťŞŢ·iö·ŞzßŢ˙˙ _ńAWČhrçč&×üG_ßm%ďé˝'Ő˝oŻ_úJú˝oWé÷Ż˙/ö«ôÓúôżţżúý?MôßOÓ}7ÓôŢ“ôü&ôxŻ˙ żÚ§ ŔĺŐ?Jű_ß˙Ň˙Ň}'á?Aľ}ú ú~ź ý?O˙ţ‚˙Xµ¨_ß×܆–~ý­dü„÷ő­W˙ď§Ş~ż!Gň ˙×řŽ­Nú˙ő˙ű‚ëúD+ţB>ůďŃ ˙ŽýţB?ä+úD+ţBGéú˙°żÔ„ ’÷t—Úýv5˙í?T˙M{Oű^ďô˙]m˙×ß˙Ç˙F°Ű­7űń×}ýuXM4űMvÓűşý}UýnÓţţÓ^Đk˙˙Ţţu_ţŇřţŢ×Rża„]´÷a| Âě4 xh0Ľ4Ü4×´ŐŘh0˝„ †Pŕ\0“_˙×ďŇúŻ˙]Şßâ+řŹo !ěLb*¬!ń řŹb#Ĺß˙˙äkë˙í ×őżń÷ÚÚăăxŠţ=ö=­Ż˙˙ň ‘ŔĎV˙\GÂ˙ëěŁ ÚÚĂXaa­­­­¬4ěŁ ˙ü†˙@ň}é˙űř0 fŚ,33 Í­“Ë ŇN ĚÖ>Ł fŚ,3Ä Ŕ@ż˙ĐşüLsAC–=ą *Ç_í/˙ßÚńGÄ>#â9"ćC5Ăâ8Ź˙~·řB""ň Żëě5ýŻ˙ü±üH˙÷˙˙˙iWĂ ~?˙ä4P‡ ŢyČâ‡Č·ČeľC-Îůä ŽUä /˙`ú˙˙XA˙ +öż…ű_µ~Âľß÷ľß˝ŻĂ_†ż˙á‡ţźO÷ˇôűëűďŁ@a÷Ă ¬Ă]a•=c^_ Ľ0—ÇńľÇ˙ţ ?ôC×ůÄ´őżZ˙ďŘŻŹv?÷ŠřߏëßÚ˙ýŘčř7ř6ď˙Î…żţ={ vµí{^záŻkĂ Ú˙ýX~ú†D…ö˛ _Óűßýń (µab[A­¦—atÖá…ŐbÂÄ0ż˙ŘôűŻýᮿŇpab Ŕ$EÄPř ‹> ďň/ë÷Á…żŇ˙Ă î˙ţż|G˙ëô˙÷Ă_éá…×˙ů Pĺ>Ccťň 0§ČrÇüCţÁd F@Ľß˙ő˙´°z ˙ ß˙ţ׸‰ŕ/Bf (AčAä Ł ]9Č>@ąÇ†(†?˙˙ě.UŹŇ˙Ç˙Ű^>š€Š z5|Ôó h zŕßűkČ0ĺYĘ?˙Ňí|‚AC“r ›˙ü4»`ř;ľÁđôA”?)Á|Őřű᯿Ň˙Âk˙°`ľ@˝y Ş˛za‘€–K‚X<0{bÁě<†mKţľ˙a…‚\?Ňúô˙ň PS”9C솎%ě=‘5„ÍŻ Ó^A˘ĽMY Ú˛µä+Č4'Ů5ţűkřa* C‘ąoĄ¶żľţ@˝‚Á™ E|Ţů˝óŮ´ađö`ř|Äů‡ż˙_č†^şzřAîżá; Ńú#?@ß7Ěć óů†Öa˝—7ŕţ ˙ż×öCIŢżô¶^AFťŻ„ĘmoďďŕţŰđëoęďď˙úą şą€Y˙ĄŘ_‚łńđŁśsŹÉŽg8ćŤpžA¬s˝^»Żwß˙ׯţű÷ţ ˙űÎ9Ç3“ýHlQîČ÷ô»Jô‰Ţ#ř/gÓÁ/ě%ëá|%ŕľ çÓ°—˙ů»ŕúţ–ÇYóŕ_üV…Z¦ʞ´đK°^ÁtÂ\BâżëôßôőňB3EĂŃ Óá/@vC8ä2‡;şĐ#!±Á˘ .uÄd ŹpňO¸‚¸šD 8@˛Ć?÷ë˙Ł0`?Ľ!ˇ{ ĐS ľGD„ş|!zˇ:!Yă2ÄRZP# \fA@Ě! _ßţ˝č" ;zďđÂ\eWb"@‹!«oîšşÁ\č0Vh-ŔŚhpżkţ{ţčo˙ßĐ‹ÝÖź§ŕ¸O  ąĐ6g@Ů… ¸.Áp_˙đ8wő§˙eÂĚ,D~ş_ů m+Tv0[ g°/eٰY‡Ĺ}?ţżŻ˙ÄGýżż¤˙ÇqqÇýţ˙˙˙Ż˙}\"€ËŻ÷ţľ’ôß˙{ %‰Üx˙ń˙mh84,H˙ő˙d4‡Čjűýý˙ňp#„Č0‡˙˙ŕÁSzy·Č5ľCMňoÔ!¨>CL!¦;ŢżŻ˙_ÖĹz˙÷eät°ASúë§®žžžCN4Ő>˙˙÷ţđÖ©Żä“ŻţÄS„˙˙÷˙ýz˙ë®?řkIzČ(ź@żşD"ż˙ţż˙űýţÝ÷ŰúČe á NŮ ­J| ţßČeŽľ h%˙ëż˙ţ«˙×űŻMČié=nŻOőôňÎ95!–ź Ŕí˙÷˙˙˙ď˙űőŐű© =SŞOŮ„m˙]‡Ů Ađ„˙÷W×˙ţťďű˙_ţźý§„}żż!ŕ­5č~ż˙˙˙˙˙˙×´Ţżpľ–á…| oëđ‡Ż÷Ú˙×˙ý}k˙ţ#ţ˝ŞóŔÝé? źŇŰ_eÁ˙őý˙ţűß˙ýęC,~KToH7ë˙cŹŰĚĐĂâ?˙żß˙úőďţýżü|RŇO×é~î  ź˙ľ»˙˙ď˙˙˙ßč/i+¦ýý/ȵwđ˙ő÷˙ß˙˙×˙ýĐţëîżK˝Ü ţÖű uk}˙÷±Ç˙ë˙Đ~PžşWôş˙ôCüqÇ\hqĆÇţëß!˙đkűýú]ő×ĎwŻďŻ˙ýá€cýˇ˙őú_µä,Őíß˙×!—a_Ͱ¬˙_˙Č>Á…×űý/ÓĐţź˙Čˤ2„Y ˇĚ9Ç+ň®b2EđB!ä ţ˙×ň]Ź»_ý.­¤ż˙Aá=Iä2‹ŕ„<' ô˙ß]˙dąţéŢľľź˙o˙ÓÂxO< đžžş˙y Ş~PĐ5×}†ľľü‚üPĺF˙_äGČmľCmôôôőÓÓŐQ|ů?˙ý_®ř`˝˙ţĐŽ×ßú!ˇĐy Ńŕ_Ď<đ/çÁŠĚ·žß8tA˙˙á~ŠČe~pÁ”8%ëá.÷×!§A˛ßëňAÇ(rÇ,tô}5AťQaĐ@ú>ó€G@Š‚ }7˙őĄúBč9)±<–Úú ŻÓá¬0ŞÚţ„DEńńÓôßMôü'á?O˙O˙ţý»Ă°ŇőîČX űU Ü0ż˙ú˙őôú·Ó˙í˙ţ•}9ŕxĄĂ öMÉżá ß°¬5Ř0_űß˙§öŻúőú˙˙˙ďJţťďĚ×b˝żü‚áᆓa.t\‚çѰĹ˙ýj˙˙ďőí˙Ň˙ŕďUŻżŻ‚Ű ĂAaŠţl4ł§hEíxkÝ˙ßşöm{ ýič6ďĂWľÖA@ú 0‚ 0–_°śqᑎ˝…áĄp×´¸k°Âň#ň„fż˙é¬0Ýn^CAĘŽěp]´°`żâ=ŠŮ×ě—]†[”9AńĽ|{˙ýéśA‡űqČ^*š)ıMd35˙÷ÝŘřřö¶ś5†·˙kKř2J 7ň żÂ đ ,ü0ť…µ†ÚĂ[ a˙„tG+ěM ď a?˙ŢűUţľXk ma…† ŃeANPů Kű˙пà pĂ\¨"¬2´ľő×˙ăŽ.Aµň ]ăŽ"#޵˙ßě'Mň Ó˙Ô‚k#‚Šh?!šů ˇĎe_řâ7ä2Çľ˙×˙ x`Ęq§ ÷ű°X@Ëü&ČlŚś†cäą"PC[˛NU‘ţ¤`®˙ ˘„;Ö÷˙×ŕÁxb;=…˙ÂzŁđao ‚đőOMPzÂ~@Â| ˙DÇČ‚>ż˙ď Ä ‚ŻńđÖžŹ†ŽŻřO] 7§‚~›§znĐĽ#éęĐ} ôÓ˙˙ÄDÚ' ýßý>đa¤zD3GÂ'~^ůB/˝=5 \{ĐzŢ×î삨ú˙˙ű †Éóa™áőő“®Öa„ađŻ@hźĂŇoGŠŘóźGţúUŕőo+yă ˙˙˙,J i'Ňo˙txW˛8Ei„Ţ’čŕe~ÓđľĐ@ß3ĂnůÁ›ßÍżz ü6ú3Ź˝˙˙őoo˙˙ úiÔ&ŇÂúđŐ'˙ş}Óđ~•řUđ}?»ńµ˙˙Ł 6+ýý˙ţţ ÓüÄü…]űőÝöë}-ů?×˙˙˙˙d@5»˙˙˙µ í5CÖé°~žú˙ďř3 ýa÷×ĂČG˙}w˙ň ŽHr ÷řf¤G ÉpÍł@Q˙˙íÄGČl˝wň ú{Ă_ýC÷·űÚwéţ볎Ś#@}?ţ‡îC!Č(Ĺ˙íŻ­÷§ëÝŻ®Ţ˝¦® ű˙ä$ŰM~ÂS˙Ó˙Á•`DŰ˙˙ŞŃďüßţŘ&š—aĂ^C +ö˝/ař`¸÷ţ˙˙łĂ]Ż˙†«Ň˙A®Ă ÄjĹa®#rşqµĚËőÄż˙Ż­tE× .×˙úăţĐř0ľ@Ćm;[»J¸ńöČhŽí{^ż˙_‡÷ČeŮßd€]ü_^CP~ŃφNĽ4졵†Ö†ťŻ цP–Đa~×˙8ޤÓí.ÎŁ˙úwU d5ł`ÁCěBńÁ‚"fC5ÉţXff[JńĂ Ř$Ho˝ţ˝?żY (Ăżý: *˙Іâ8Ž8Ž8ŕÁăú˙˙ęÚ‚ ýaŻü4!”9U˙ţř˙ô˙×uţA€z†˙pđ…á„XhÄ˙ú˙˙ď˙v_˘0᎞AĄ˙ OĂC˙˙ď˙˙ß㣨kgÁż˙Aëâ˙˙÷˙˙˙ׯ' ş˙ Řk˙˙ţ˙˙˙uţ¦Á—NżţŚîAŚ @ź˙˙˙˙őßţ=?˙č ßú§˙ţ˙˙˙öżýż˙ôűä5Č0ď˙éżţŢŘ_ß†ą ‘˙ôţXú w! ]ű!”ůź˙÷ţżýqżŻ'ý„ÖB§í;OMÁ˙˙ë˙˙űKţÎ.ź˙‰qÓUTׇ~˙˙˙˙˙Ţ˙ŢĹk˙ä"wöXa{»˙˙˙˙˙ýŻü´fűţ»¶l%Ăoţ˙˙Ż˙ö ßĂ @“ý}=ˢ:6–ĂH0ŇěŻë˙ß˙˙ë /ż!ˇ?[˙ďĐ´;aać6÷˙˙˙ű˙÷‹˙Ź˙ţC¸MpĂA6—°Ăí˙˙˙ýţżäúü`˙í~ˇŠ Böüě‡˙ţČ4ޤAÎ9 ťĚ9c”á~ż|&«˘]DžkDb"8‹˘čŮt ˝Ă Ż =/˛Ç CžČÇ"Źf‚‡3–çTTÂ!˘ťYĎ#{/2;0f A»ä^ËĂŮH)Ę.0B‡(sčT:)ňř˛’ľ˙˙´äʱݠ׆˙'DtKçTGH„DDDDDDD_˙ëjđŤaď[ţ˙ěDDG˙äĂ’±˙ő!–ű ¦â: ? ż,Ŕż˙ŕ„D?_śźpůă#ćy|ĆGG‘Źˢ„l źČů¨dp0|Ď"9—ú~OŘkcÎÁLú9‘ÁĚ7ČćB">MŠČÍČŽŚŃFJFhäh! ŔŁ˙ëďôC`éýđB"""Š‚Aa‰ K„~hÍá†ćŕࡠŔ€°l4hŽ‹Ç`Hŕ(6`Ŕ,'˙ô˙ýú§Ń?ćwÂL0AýŹ˝ŞéŞl Âő˙ýŻ˙öć*¸D l†đdp„pÇ Ú0ú UW˙µţ˙˙ŃŻ˙„>†őGÁ‡řB ôi†˙˙˙˙ÝţÂ˙á®Í ˙‚çVöšč Ú70µO˙˙ü¨úŻĐKŞěÇŘ ÓŔ÷@ÁĐ7}+é: ń˙˙ďßÂ˙ źwâ'ß˝Hž Ě4}?a=˙˙˙˙_˙ÁżŘhh|ż†đßó‘Í/4Âk»˙˙őÖż˙/®š `Ájl7†×÷ řŽ@‹Ş˙˙ÝOúé}öApÇ áĽ˙˙EÉ×˙˙˙ţ˙…˙ŹáZl0ö˙¸k˙ż˙˙˙˙˙Üţ%pŰÄ'ţ-~Ăí˙˙˙_˙ű˙áţm†đż˙äŐű˙˙o˙ľĂ˙Ó Ł>ĐTĽ;ý?ä2´˙Č7Ă‘Ź§˙dGň ‘˙÷á‡ţ¨<é̆Ř|~Ü|† îČŔhÖC;”ä#–ůŕ z!‹!śžAtCĆAE”9ďä2Ç?9]Á<{+ĘF@‚˙ř0˙řiéËHU±Č{ú˛/údB°ű¡÷§ˇˇ žCefCA==˝ţ˝‡˙Ă}<-†/ŘÚýŻ0f°Q®őţż^ô#ÓŻľÝ˙żţ3»Â.AsD„]ţźĂ_˙[W{W˙ôőŇý­˙ŻČ`g˙6Ă~ęC=HGŻký…đ~÷çĚŘfHi‡Í†¤†fĽôN•űő͆Ľ†y¤˙á˙á†ý‡°Ť‡ťýiű /·ů’*x*¬5hŽA¤<†aŔjý® Ű˙˙đÉý·äiźűçĂh/_Âř@˝Q g_×őhĚ*ý_˙ 0ĽĆyĄ°ŤK8o ˙¤ţĂAy[č/ đ‚ú 7ëĐ XA_őű˙řcöŰśBNb{ä$Űľ5đŘA=•VAŽ0çŽ{=< lř _@~X żđAaN*żŰ× Ö˙ᅥü!$ l†˙_†)b B"#ôż _„ŘAaďzX XB˙÷Çűň WíńDُ<Ć×ę˝§Ô]p‚üUŕ‚ľ ˝|ta-?´µ˙ŻĽ0ŢjG¶*Űű_°˛+Č7u¨R-ű„«Á‚ ú°aIŽW/ýď˙áČfíđA a»3O†/µj ©‘ á`źBý0Š@Ăđ§±đK˙DJo0)Á?˙˙ó0$áľlÖ-‡†˙Dpź Ü ĐF°ĚZß÷÷<E 1ďÓúÝ˙˙˙ä€dě5ŞÁĂ C˙ 'č:Ad Ő÷´ďcűTźţÖ˙ýĂ‘G(s˙˘ś6űk{°ŮÇĂűŞ~Ź7ÎÄűX«#˛:0kÚˇßńĆ«˙]‰Ŕ1˙d¸k˝KIxb‰ŻŐoÁ ĂqÂ:ŰČiĎÄD||29—Kq˙˙÷×űČ8Ź 2©Ş AđëéPĽrŽSä ˇËˇň)Č8ĺřăŃîPĺA'8ék!•ĺÇ˙ý?!śG±U„Ă˙8ľo÷Č7­J|‚äň Đ! Č0Ż ŁB‡+Š! r‡0ć˛7ňn}l‚ęňä'˙ď˙ëě«ë i´CŽ84IţüÖ Ľ 4ôí4‚z„""ňO! žÂz˙˙űüÁ۶˝tByÁ˙^ú öCe~şżöť®žžžťz˙˙üáś?˙{@ÂđF“ćĹGX?â—á5ä 'őýă8şţť®ş˙óÁźŻú_×˙öŞ#hWĐań Ĺżţ/ä3SüĚ!sóbśÂ©±N ćG›G©Őßň1^lCb^`ľ ÷núúý8Ž ›ňBͰňc…÷ޱđDx žlú§é÷iýü3by°oćÁż›!űÝ­˙o˙„!=}o‘ á4ý„×ŢAG˙ßő´®˙˙éúú«˙]˙qő˙ű|„Č0ňpNĂN=Ať§á‘ĐC˙_úŰmo_ţ˙˙ţű[˙˙ş˙˙ע 5čC´ŢᇶC@zß„„Ď_˙÷׾¶×ţď˙˙ő˙ý˙ýµ˙óX*b íl‚‚=WM>Ľ}Go˙˙˙ÇׯČjŹęßř˙ü ł¨6„ř"> ·l0}N}í>ëű˙ő^˙˙×˙uőűü„„ý®˙˙ů°X†^„0mCd2Čőý{ďý?ů!Ńš˙Úşőţ›˙d8ĺ•C('!˘=˙Ż˙}á‡ÉE‡ú˙üŕÄAüGüDń˙rŁöS•Ďőţ"/Ź˙_˙˙Ă5]ô5ˇdG*řýZk}? `gÓ˙őý˙ż˙ß˙^˝¨3XfŰćLGĄw˙¬†Äžűµµ´Ó˝µÓőímSÖ˙é˙żO áíŻřAűXŽC*É9Câ8kß|GÁ¬y°ŮößđÓ^˝óőą˛ †SíW˙ú'Ź‹¨ö@ÁĘüú§őúÄ}˙Ă·n:†ÓŘM/˙xGÁ»˙IüGďő÷Ż˙ýČR?»ÁµätÎ8'ű˙Â˙ţżţź÷ţzn,´"?×FŽĐA˙ Ř?ŻţC.ďđÂţ»_˙ŕ®»sŘcŇľXϧü‚Aá=Č1Ƥ4AăţC8ä >™é˙­úĂúďá/¸p›J÷ëÓ˙ţ#řşŃ¦aEŃŁŃŐ5B?Ă^˙xDe_°\7†Á­ţ˙˙ő˙oŹřŹ˙a~×˝ű_ÄPžßc‘<Ă˙á”kýwż_˙ý|˙ŻŢú5Epßz ňí_ëőýä5ŻŻ˙\,Üń„˙ţÂúĚŹÍuóÁźüś\Ř7_ý®´×ÖřG@Őş¸Ă¤§˙ţÁŻ˙ţű=|Ŕ(®˙˙ö¤2é÷ů* HbĄAéű˙ěś˙ęż˙îźýíopżýĐN=oOőżĂżµöŐŢ×űű˙ë˝]/ü‡r )ôP Ř\>0ůá?˝~ţÁ~":ý­÷a^Ç ˙ţú_údG> Vx°iá˝'˙˙K†oăřŹY>`¦PĽEúţ—÷¨]…´ócŘ>źýÚň¤~×µěEWǵ˙˙éZiăżd8~ Ůź˙ńý…á…í_°°×ű˙éé'ţŮ !m‡±a˙đax0©Úü5Ů_˙µę‚˙á#ĺűŰ >Ă˙˙ËîS”9řůî>>?cŹzwş˙}A;ď¶ Ř0ýüżkˇţú˙Żý¬‚ ú_ţ“¦A¤}˝°`ű ő˙ëů ů ‚<†PĺANüĘ9YĐźýw\tżúď]ľĂ°ĂĂU˙éţđź‚˙!°&>űýŐR˙í*ďż v A…ţ@đĘr‡=”?ĚWôýč;é==úý?— Żţ»řaě0ě0a¨BůÁ€źľú~ź§öžź˙˙§˙Ă—öűl7„˙Čką÷ýkŁŔGçŹĎŁŕý?ţżŻ˙ż·Ř<0Ţźúá?˙éţúCF}A| ß˙˙ßţŇKí齇˙ý4gš":˙Óý?Óý¤ýí}>×ţ§đß»˝˙üoí{˙×őë˙_÷×!š9ď˙ &ľŰď±ŃĆq˙ý&˙úë÷ë˙˙Oíńű_}˝ż˙ްżßöż˙w˙ţ×˙űä(ĺ|(sÇá‘Áľm>sýýÓű /öďű_˙†żë˙˙ŕ„DHŔ1ű!ďpŢŕţ?˙gŹöN /áž sąTřdÜÎ öżĂ^u˙˙˙ZO]×műďü±‹řgTGKö"#ö"?ŹşŠŘŻ÷Ö—!¤?ýŢüá=°řov«ý[ü1ý{^Óöű_Ýďúż?Źl5·‹˙ßká‚ü0˝Żik -…˙ëŐőCCßď¸íăwűÚů şżuüŤ|O{ !–9łýwľ˙ű÷÷¶ßUôBŰ ăsąÇ xţ>>=c˙˙Ţľ˙Mk˙ŕö˙ö""+î˙˙˙÷Öź˙ëżđ—úţÝŻŞČ.ä3żŘä×ň A˙Ţýî˙đ\†í÷íyăťÎ_ôĐ~=H(rßň č?ßýh„˙ńű×]=ň©ü!˙~š~OőO űężżý˙ţű®˙ýc¸/é˙Ţýű§}_˙˙k˙˙áú]˙˙ŞÝôţ“úß­>o˙ú_˙ëü­ =îţŹ‚’­ ßÂoá?z·ď˙˙ďţâ7áß×ţ#čőý?Đá?_űýů«˙ę°‚ŞoŻŢż˘˙˙ţĽ…č„wţżß˙ňr‡Çáđ̧ż xbő«ż_ň?ČWűŞWű˙ő!–˙˙ˇ#`_ĄŤżţźŻ]ß˙ţ·×iŻŞ˙řý§álwá˙˙ő~šý„˙´ëý~Đ˙ô˙˙’B {§˙ëýřaá Á~Ó űh0ĽA…ţżµ˙ýż,!í˙äG5•íë±__a~â=Żď÷é˙ňpCß M'˙ů p˙Ăűő˙˙ţ×˙ż·ß˙ ű(Ś#Ž ZĂ(A{^ÓîÖB ˙úěőřW7«żý?b"H ›Á„ŕŃÁś ˝š5řfŚ,†Č˙ę˙ţAĽüAˇĐ.Ńu˙çÁ߇üGÄ|A› |G˙˙ZŻđ^Đi„ \!ďúţţ;˙ţýýá?†‚#ő˙Ň ů W,s÷˙˙˙×÷˙ů!x` ş]ôä14?Ź˙ú˙÷˙˙Ö× v‚(\v˙]§ű˙ű_˙ţ˝}č1ŕÚ&ĽýÖ˙˙˙˙˙÷˙řMa†A/˙˙ 7äśÖPćrŁ˙˙˙˙˙˙ç…†Á Dá=űýôţ@O˙˙˙˙u˙öpÁ ďëö´ß…˙˙˙˙˙˙ěG A ×űě-?˙˙˙ţż˙˙ĽD´OżżłŞ#’˙G"â µî˙żÔ†UťĘ9P™k?Żßô‰ h_úű_Ü!ňäAČ.9ą2¶RW"tr8ŽF>]Čč3ŽLsaíUJđBŽDŘSźŠ€Ť„BFŃ|ŹĆh‹‘#˘:#łŕËŁDDG˙˙ú|O‚Źűö˙ýDDDDDDDDDDDJÂ.&yŚDDDDDDDDDDDDE˝ţ˙ Ż˙öCżý±_ý%ýľĎYXGą ““2Ç?9S0糎V©– x –ĺŽMÎ9Ç˙»úůfP#‡#ätGÁł˙·ëC¤ńţ:űű;/‘Ń5Hčľc#äv\ͳțdtf‹˘>iťŚ ˙­ű ÚřA·_˙üDDDDDDŕNä(ĺŽTÎ9Ü›°Päë*ea:r‡0ĺ((r ˇĘhâ""?¤żď‘ •<Hüý]Żî"""""""""""?ßkŻĹá 7;Q‘d]~íW˙ýë˙ č ‚nlŤ9°ŘN†Ă7ý ×˙˙ţ˙á î÷@ýd4í† „µ÷ű˙›ŽĎF°A˙¦ßެEv+˙˙ţ- ô ˙Ł•í’?˙ëľ˙żAlŚŠô˙ݦä4‡"k×ë˙ýŕ‰Ä§_ţ$`€ĎČ0+ţíďţ— k«˙â>«úŻ˙˙„ß÷˙ężű˙Ź… Đ?Í›ďŻŢß˙˙żđŤA±ä5ŁĂ}÷˙üŔ`Ŕ=ű˙˙Ór (Č űí˙ďý˙˙˙á5Čeë’­}˝/ ˇ˙˙Ż˙×ëhtO°ŞĐ‘C}˝}!¤9ă˙»˙ű˙Ť„8Aa^Le?±kčé§ęé˙˙ýä,Ń8„ °ŤTËäÂěk„˙Đ~ţżý/Ö áa-Ä‚ íxAëŮH8w¨˙úďöAßTá@žd Ř^źńţďłDGGD_#Ä|DuU‚b’ä‹ä6Mě'˙ďżú˙ˇ?:k¤¬g8ő˙˙˙ď˙Â@Őj–:÷üÜG3â«ĹŻ˙˙zIőÁKß]úÇýůJ]'áŕ…ydKő˙˙˙Ąů€=Ö˝ĂÉä4 ~ď˙˙ţ«‚7§ˇ~‰ńŻ˙_ďŘiz†§% z}˙˙ű˝}d3GăWhč ­ŁË˙˙˙˙ľA>•T`‰Ýpú ű{µ˙˙ý˙§µNŚřpE”žlźM>ˇ‚˙˙˙˙đÔ%A8l$’ĐaďŐ?µý˙˙żĹ+…¸Tm‚ß˙Öżżőü†XĺLĺŢ#µn?† 'űűű˙×űţ Đ÷‹Š>9ń¶Çúű_ß˙ú˙żşJ»'D}˙ű_˙˙Ó˙ţ)ş[$˙Úׯ˙˙˙Ý-…Möň74xao˙ú˙ř/Ş h‚éÁľě& F +˙˙ yÖż‚ű ±!ÂaÎ仍еëű˙Ĺý˙UřX#Ż 7·Ź˙˙ő˝!˛ŻVC(†ŢŐ˙˙öA®ĎePĺŽw.4KQFFdË#Dz8’(űý_CâřčĐ6ű>Ôś*˙˙†[—‡*e…˙@÷ zŚ†Ă ›aâ4ß˙üDDD3ŽXĺYC‘|ˇÎćrNżÁWZŃ 0ţý˙ţ""""#ú@^ABřa,ţe„GÎáÎŃł0˙´đ¨)Ăe>D‰Śyď˙ó4P‹äp„pm6…Mł`x?ö}D EMŠÓßë˙ÂŻkűA0Âd}żÚt˙˙˙›Ďţ•ġ÷Ř_˙˙Oőő^Ţ:3 ź˙˙ďţČ.'ë"€˝Űô˙˙ţ˙şRkiŹAď˙űţżŞP±{ťAz˙ţżÚů ţ«‡Ř˙˙űż ů°C˙‚3}Č®A‹Ă„N˙ýWÓé­÷ _­íáHÇ˙˙˙ű0?ßă†UôÇú˙ý˙˙ýť&ŢD›Ä]ý˙ţż˙®@đÜ}‚ý«Ú˙˙˙˙×űă,}ůź si˙˙ßäżă˙ăůÉtą Ą6Ż˙÷_§í˝Źűä3Ôqů€e ^ď˙ýK˙˙qČŻř/˙˙Ű˙ýý<†exěŔeőľ˙żţ˙ýŹ Ő_‰ ?Oő˙k˙8˙ü† {ŻîżýWý?ű /y Ż\‡?˙˙îţ˝_đsżśľ«÷˙˙ß˙lGřů ÇU˙˙˙˙µ˙ő!”>9Óűöúű˙ţ +ţA­?äFčś#ßKűţ·ŻŘŻňŁ? ńärś¬­˙˙×ú×ňűşýâ/ţ˙˙˙µţC`ĎÉk˙_ß___ŕÂ˙ ÂĐ/Ý˙ţ÷ż°Â˙GPŐń^|Ř2Íu˙ţ´ëń˙Az:†ĄŔżĐŹ×˙˙˙ ‘˙~l ´řŹ˙ż˙źĎíř+˛ Ä(Çżűßč7ü‡ŕ´C-;˙ţţµűżPžůĹČihł36ř5˙˙˙ţ Ś „ů ýň;Ż_˙ ĘpËţA GŽC0r»R é‘#ü{ţşţĂü†ť[ä6kä2»˝Ż˙oßú˙Čk‘~CýţÇ˙˙N˙˙°Č„ü4ú˙˙{×˙ůk×&Ç˝ýw˙˙ăřF Ěµâ?ýőßÚ_˙č¸iG˙ú˙ü#P4Ţh ˝ýŰŐď˙@żőś_ßů qŰÝtPż…yČ˙ŞăŞ_ë ňCý˙p˙˙˙ţp6ţ+˙¦PĺYC§˙˙˝~D3Źű˙ń_˙˙ĐŻ˙˙˙úß÷úďľ×˙ýżöľ˙ä&d&š˙˙×˙˙ţJE@(Í.÷őýČ`żţ¸^@€Źţľä `P>˙¨__âC@ĚzŇ˙ţż_˝Ţ cRß˙˙˙­ymČ5ř_öÝőľ˙g×÷ `GÍ‚Ľ_ß]w˙ń!ďü ţ±ô˙˙˙˙đ@˙ `ý×ý˙÷ßOđň#!˙˙ß˙i}Q Ků ôőOőß×˙ô|6?Č`?ťSß˙ß˙˙@넾=˙˙Č`Cöô˙Í*AÇď˙_˙đźý7ż0 Pź_˙˙űŞôżř÷Í‘ßßý˙·ß˙čDő×˙TżŰ `~ż÷÷˙ç ă˙¶żöž?˙ëţőO˙k˙÷˙ţ˙ő˙üĐ˙§×˙úď÷ľ˙łS_đű˙×ß_ń×đĹÍď­o_×_Ř_űi_˙˙˙úú ě_{kď˙˙˙żîC.ŻŰč0×˙ß˙öžżÇ÷ö_ţźúýż˙MöĂ zű×z˙˙ţë±_׿_˙˙˙ᦷż˙w˙˙ň7ßa_˙!ý˙˙˙tyďµ˙˙×˙Ó”ŹŹő˙Żű˙˙5­ż{˙ý˙ú†ż×˙ďż˙˙sŻ˙˙˙˙˙ë#˙˙˙˙ţíšoý˙˙˙ţA˙˙˙˙˙˙q˙×ë˙˙˙_˙˙˙Č)ŽPĺaʡÎ:e9(.Č/ĺyPx9Ń©fÄ#…#†žżL Î9Ç(r¸‡ŠçîaÎ=“˛C™Ďeá8 @éŮpg#rc–8L±ěˇÎ9ܱ˙˙ü†°ćš¸!ůuě«* rx„B"""""""""""""""&ĽÂgFţ˙o&‚Đäh* l4w'äŕÎPäAÓ"9ĺ{?rwń$+×˙ L!= sWĚç‚Ç0çeâREé‘ ·7”ćsŽ{*…U› × Ř9 qČCXr9C”ŮËń.Śeă¦GF„mŃ)6H+qÎ99C”:eŽC,ş0ŮK…Ę‚1Î90Ú‹QČ;ťŻb"""""""""""""Eă4aDtGDr0eÄ<n^#˘B<Ź˘:,…,ĆyyÚ˘%ĐťÂ:#Čş0‰ĚŽŤ˘xŽĎg‘B&éŮôGGDp`¸d9ylÔŚ3ČŽĐ— Üŕ‹ŚDDDDDDI˝"9‘ňâ‘ŃŔ¬ş.d|ě)î"""H2qÉ6U Â(ĺw!¶9M~+B#śr‡ ¸â";‰; Đäܤş ˛$fˇG,ť Žz …BLs9ŕ›š‡S*Ď„%“d‚đˇĘDD{ x2w$â"""""""""""CmĘ”ÜlÎ]GÄDDHcšĘăń^VÉN8ŽŘţßţ˙űă˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙äĹř€ endstream endobj 1 0 obj << /Type /Pages /Kids [ 6 0 R ] /Count 1 >> endobj 2 0 obj << /ModDate (D:20060518142248+08'00') /CreationDate (D:20060518142210+08'00') /Creator (Acrobat 5.0 Scan Plug-in for Windows) /Producer (Acrobat 5.0 Scan Plug-in for Windows) >> endobj 3 0 obj << /Type /Metadata /Subtype /XML /Length 904 >> stream 2006-05-18T14:22:48+08:00 2006-05-18T14:22:10+08:00 Acrobat 5.0 Scan Plug-in for Windows Acrobat 5.0 Scan Plug-in for Windows 2006-05-18T14:22:48+08:00 2006-05-18T14:22:10+08:00 2006-05-18T14:22:48+08:00 endstream endobj xref 0 4 0000000000 65535 f 0000066696 00000 n 0000066760 00000 n 0000066955 00000 n trailer << /Size 4 /ID[<39a282b91eca3589d16ada50e93aecd8>] >> startxref 173 %%EOF gpsim-0.30.0/extras/graphic_lcd/doc/sed1520.pdf0000664000076400007640000050476013041763630015753 00000000000000%PDF-1.1 %âăĎÓ 1 0 obj [/CalRGB << /WhitePoint [0.9505 1 1.089] /Gamma [1.8 1.8 1.8] /Matrix [0.4497 0.2446 0.02518 0.3163 0.672 0.1412 0.1845 0.08334 0.9227] >> ] endobj 2 0 obj << /CreationDate (D:19960121173249) /Producer (Acrobat Distiller 2.1 for Power Macintosh) /Keywords () /Creator (Adobe PageMaker 6.0) /Title (SED1520 Technical Manual) /Subject () /Author (S-MOS Systems, Inc.) >> endobj 3 0 obj << /Filter [/ASCII85Decode /LZWDecode ] /Length 459 >> stream J,g]g+e/h_!_gCtO=0f)$P%cIi8Zdfc5&3j_8$7g.@L`YKUJNGBP\poR=_;Dl'P(T (7Boo^^S:71(MN]ZQX/+Cbu.lK"p74pe1T%s.DY%&\1TdJhr54.M9au6>79n6`Q:4 PbLSZTLEE(8E@'*1mg_*eTnN*;*'V3+gm-EEetX%;Bo$ur2ss*N`.-!.kG_q6GDD' dKoL!8Ka#EV,@V!\j8ZFbp6EE<9cn=N6j0nf;(&;QU6bUD')c@\ 9-d\DA=cZ0Q>gIM$$;cd2O@&a;X,Nn_aP(]I1aRc(K1^ue> gF/(+GaKo$qneLWDrQ#;5\S(\$q'LM9bYJX9N;hHO_e;>`Y"/'J:I~> endstream endobj 5 0 obj << /Filter /LZWDecode /Width 77 /Height 99 /BitsPerComponent 8 /ColorSpace [/Indexed /DeviceRGB 255 3 0 R] /Length 441 >> stream €5ŕP8$ „BaP¸RDbPhtN-Ś5â±ävŹHcŇ –/$“Jb‰T¶,—L`“ ”Ęi5—Mç©ÔîM=źH¨qCŁFi™=2cK§DŞ]RyV”ÔëÚÜ–µVXl(’Ȭ«ËP(µ–VŤZí2Ąe®ëc˛ŘnuŘíBÄ׿Ú/PL‚żŕ#”»\­kČC¬×lvNĎdŤ]qÖëµâ«¶Ým·k}ÖŮ€¶dtY›>?YVkł÷ËîŇ‹ÓX­ uo‡nŻúÍŁg+Řăî[ŤË›’Çé˛wNóŹ`Ä^¸[Ýď łąďîŞ[mŻ’•ćóú)ľ¨µŃîó|<ź-·Óiöľ~+żŞßň°˙*Đ©*0"ť)B“(Đb‰(0‚} 'p˘Žö=°Â' &°âm > stream € Dq  FB¸ćr2 Đs86Aˇ0¸l>#E`Äx°€Ó%AÍBYÜ@1D˛ěČ „‚h4j6 †łˇ°SŠ€Ńyg/ ŔŃĹ ‡UF´1ŔsB Ć6¤ö T9d Ń@ÄRT5SÔ8J,7@«Äd1zŚôZ0 !eC˝°¦-&“Ęb™d¦T"“JbÁ$śC[î$Z\î]8 ĆąěţCŐBčÔ‰hQ ľX5´ ßsCŮÉdŠžsľ †ô=ŢżqÉĺŃhňX¨Đkʆ pQź\p ÷ŃŕmN•rÂ]jc*Ô ě° «v× jă¤AÔd4@hZÁ fŔ…«ţşŹĂ‹a@†Č˛b Ţ:hÂ:CHđ ‚čě†AP2ŽAHş* KSĆ»đJň©â¤ŘÂĘ (Ë #pÉ ŁŇ3ŤÁŽ:Ť# Ë´Ž ®± {VÉ`fĺ(pJŞ(hĘ  endstream endobj 7 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 13 0 obj << /Length 286 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ž1Śä©&Uaś( J†«9A¶ÁgkśO'wN$A˝˛L-˘ $…Cľ¦-&“Ęb™d¦T"“JbÁ$śCb±ěC+ĽDC0Ôg żá4rˇ “«(Hä]©;aÖ$“ÉÄa0˛ !$â^čEłA°×‹Ś‡Ś.’q§ŃhŇ•v9A¶č endstream endobj 14 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 16 0 obj << /Length 1855 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;ĘcĚś@3ŃŠ’(Pä Á˘¤¨j™ĄiÄn.O˘uř0Čb9 óy´`.D ‡z™LZM'”Ä2ÉL¨E&”Ĺ‚I8†.«VłJ9Ť")$šQ‘K%Ń tt@7×ĺI-A˘•Ë`°:…;Ť…Ă}ŹK—Řěĺ©|Ćg[›ÎF#QtBĹĂâĘr)/Z0W.…±APR8Š "‘€ Ä)ŘŠ †QĽĚ !›ÍÇC/¬ć)چ= ¦E"pţB’éP”‚©)ŹąIHr-Š›Ňő˝ŁŁŢ« «xhžˇ ] Ŕˇ°nA+rŕč¦ë P¤ Až; Łě4ŚŁ»¬¦ŞârŮÁŞÂ›€k¨G‘ě}Č …!Č’,Ť#ÉL•"> pďăü…ˇ\‡+XZ¤¬đ@©­îĄDk@(ć1ŽCHŕ: /Sŕ†AQ%ĎĚő=Ď’Lš†’„¤˙ŠT©0Ä śČ¤˘Ś2Ś# ę9MO€d3ĽűMÓ”í=&KaŔeA?Żü¬ˇ ŇÚÁÇ „CE¸ł2öü?HĚ0ŤŁHŘ<„ŕ2ŚcHĚ4ŚtŚâ7=ďnÓTýťOɡ´ź(Ô˛ĄOURí[DLn˘’š„Ř7Śc\Đ4Ś#8ĺ\RÁŤ3gŢŤäÄKp8PP`m CĂöěĘ€ĂrÝ#,ć†Ömç…á–…CQ‡7ÍŻTŃŁ›0Uöô/Y HÜô=VĎIŘĎRn0ŚOÚěáąlű&†ř…ňߦĘčZŮ()Că+‡+”Á~ŐáBMă¸üÓ5Íł}ʦq‹‚¨¬”¦Ç1Ţ]«ë=ŰQ†*­«›¬AlŐ’ýů1c:87ŽńJö4ŚăpÂ6Y3¦Y¬ďu,a:íó}©®žŐFŠcČćö ·ę9°`ĺ[Śo §¸n[¤ć»»Ď5#R΄GŻJwۨ“\`†"MlPô #Ć:Ť#¦ß¸îvKCwó}Ě‘•óůšµš§2«Š¤ܱź*r´KŁÍ“tá“<Ýg]ŘvWČ5ÁęĆ›ŕ ® pú!›6­Ý|śĺęě´7̶Ë,ą˛ęŞĄd&ŠŻöqř *ąWĘ˙ÓÓ{o«Q)±6ĆűŇóńJÉq3…0ĘxĂĎcďD$¸ç y yWé4’?čĽÜę}+UŃ?%™ÂHdA« b2X&yÂ"‘ .)Ć97hĺ’ŰÄĐ}>9Đrŕ"„PÇRĄtÎC‘n0:őÎŻ`aWÄ:C0¤H°a Á‘ű˘—*e áĄĂ˘•,LO𩠭d®¶«L‰YF„'Ż4Q î^4ĂČýW¬l_$ ˛@ç˘xpŠ*đ)ĹPäě‚c<‘†1ĆPä“cD;Źíá?¬ČFčbň`¤6PÚÇÂd ŠR%˛ęă š“rpřś4Fľ!$ˇJġ€°XÁŁ#řI ŃĚË9Ś¤Äž—‚C ‰"ÓD2Śa˝Ş9Ź1—l?,íţ]4ÎzChmdÁP4«ÜČíE*D7Ésâ离y“ >mË™‡&|Rš1TĹ"ĂCŇuîĹK6ď3Ôśpu ˇ“B˘óH endstream endobj 17 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 19 0 obj << /Length 939 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ž1Śä©&Uaś( J†«9A¶ÁgkśO'wN$A˝˛L-˘ $…Cľ¦-&“Ęb™d¦T"“JbÁ$śCb±¨şI•ŢoˇóIĘ!« † †”¶()‘H›ÁŔR-ęŚĆŁAPR8Š "‘€ Ä)¨Š †QĽĚ !›ÍÇC/Ěć).• PZ Ňä†"süá«Ę”9 ”ć-Ť(PŢ AŠőŚc ä4ŚcŘř ä0ÂŁ,.9ŽĂîű«S ·! \¨­LąátmÇĚuÇ‘ě}Č … :î¨b;OĂô…°r!›ŔËdfŔąĐ|^Ä9Ťă`ęúhÂ< #hę6„ĂŤĂ;ď&†’<‡;ĎĚő=şápîI/Ëö*Q¤´’ ‡CŃéÄŁćΡD÷KÓÍ5H¨¤IT ç·«RŮ4Ť3ŤÄ4„M>¤Tµ7YÖ•¬uN†r@qPˇ\Á’›ŚăĆu%-µĚH2Í‚ę9ÍŁ(Â2âĽ/2 !¸Ě0ŤŁHŘ<̢€Ş..Ľ˙YV×mněAµu^ Rc*Š–,µ_Qť”úY¶}ŁiÚ¶»Ř$Ű6Řl˝[÷ ÇrÜ÷HZ†÷e݋Ӹ¨f×”$ĐÁŤ% R×ňŕ4Žc€Ř0ÜŹ‹ć9L5=Ă8şáe\âůÎ0ě28hëPLk¶-Ál»;řrŃĘđkĄB"mĚÚľqľ1˝–ؤ2ŚŃë¬] ÔRµ˛1j–ł±• ťm›l}>‡Čh׋F†ČΛ;;¤ăzcśB"`†"Q0¸íj”xĆů Ă,*4ľQ;´EZ" Ţî;L­µíÜîŮ>‡/ 9ş±Ű&Šŕó2eĄoÖă•. Čá CO‡ÇDĽŠ"4Ž@AÁp‚€ĂĆŤ›)Ó ¨ó8mQŻ=çĎ5€e†=&ďÓůIUÖsaB=řCÖ0ŚďfN6ľŁź 7ZÖąŻ ŰÓxńZ ¸šőćâއüťÔéÜ% đ"–b endstream endobj 20 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 22 0 obj << /Length 335 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;ĘcĚś@3ŃŠ’(Pä Á˘¨¤¨j™ĄiÄn.O˘uř0Čb9 óy´`.D ‡z™LZM'”Ä2ÉL¨E&”Ĺ‚I8†.«VłJ9Ť")$šQ‘K%Ń tt@7×ĺI-A˘•Ë`°:…;Ť…Ă}ŹK—Řěĺ­]Hh5Ůçƶ±¨Ď€8 x˘čČĘ śĚ+6şääe@†@şôaćAĂ·Ę)uHQIbA˘ÚO^ ěć k„@ilPO; FCaA”ä…ˇČP; #(R¸R.Š‚PĹ· j†·¦¬\!á›tä†)Ř`”9΀€€ endstream endobj 23 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 25 0 obj << /Length 286 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ž1Śä©&Uaś( J†«9A¶ÁgkśO'wN$A˝˛L-˘ $…Cľ¦-&“Ęb™d¦T"“JbÁ$śCb±ěC+ĽDC0Ôg żá4rˇ “«(Hä]©;aÖ$“ÉÄa0˛ !$â^čEłA°×‹Ś‡Ś.’q§ŃhŇ•v9A¶č endstream endobj 26 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 28 0 obj << /Length 3095 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;ĘcĚś@3ŃŠ’(Pä Á˘¸¤¨j™ĄiÄn.O˘uř0Čb9 óy´`.D ‡z™LZM'”Ä2ÉL¨E&”Ĺ‚I8†.«VłJ9Ť")$šQ‘K%Ń tt@7×ĺI-A˘•Ë`°:…;Ť…Ă}ŹK—Řěĺ©|Ćg[›ÎF#QtBĹĂâĘr),n¸ +—Bآ“. ĆP*Lb)هżZŕ ÎĆS—‚Î(;L˘‘ ÄPw—J„¨-&@ăżÎRR†Ëb¦ë˝SŘřŚŻÂ®¨j’’¦˘ ‰.p:Ŕô(ć1ŽCHŕ: #xÜÄ«)޸á-á˘z†"t]ÁŞĐç: "äş Đ2Żb(á»h8ć !Č7މÂ:D#Ŕ@&b$•˝c”¦)‰(8Ü: ŁpČ2Ś‘B ,"o ­á„j›Ç0ß- Hć8 ň ă0@1Ťä0Śsĺ#Ś3@3Đc€Đ4Śc\ÂIŁ<ÂöIđôP*N|Ű7N ś©+ ’ŔŇ7 áć4ŚăpÂ6HăÂ9Ě“ŕÜ CLš4ŤŁ -%NÓÄő%Iă 7N͡Ľ+c¨á<>C @3CxŰ$VáŔ[\Éłš&ŇCHZ٬8´5±2Áôä1f“ťkS„¤[´E`NóĚö2Xˇ¤ ‰¬D3¤ÁrąBń˦©Çҧ!HOsC„çLČő8Ü7ŽŇxŇőĎăHä1Ž·ÇUŐł4"¤¬đ,-O.Br…23ľR=ă$vhĺ K3ŘŘ7˘Y@ĺˇË÷ĺV8dQ5×cµˇ€ieŞrHî4ĚaTHěř8S%PĂxŘ:WĐő&+×CEëÖ–Ę0…ş˘ŢŠ%ČP:şćÁŢŘ–(Č» ä6×Yőî:Ö’Ö^O(Ű0Ž›ŇŔëE3Ťo9qtHÇ P3ö9Ź9Ď-#ŤüVEłÚ–´‘—Mc›6:1Ú§Ć ĂLźŔČéC82±„ŘVŞ÷Á@“[ÎsµŇnr ö^Ł|‘€DyĘ6Ow0Ü3Už AGČý`çĽŕů|Ó™w“APşłÚÁű2 †âf .1ň'ŔĚŹc>ďx0¬đؤŠ'?Gńw#“<ßť mRG¤7$2’cGę![Ş5ř°“Űb$A@(%ü Âîođ$"‚f ±]) äźôÖTÂŕ2#đŘšC’r[ÜB)¬56°§đ y+Tčx·°—“¨cIëy­ŻdŞ•8g ‰}&ÄOÉű9äĐĚaüMz)1Ą¤ě’“$L IźŞVGbúńm˛p@• gré}Áą¨VÍÓa P=ł¤—.ťC¨mެ=$ężV? IB(đĘzÖb-雹 %•:Ľ“ €7I™F–›~K*J"t€P2(ŕČš`oÂźaçŚÝÜ‚¨ŕTZ‹Îä×(ŕĚ`l ŠiL.­ ťX‚‹Ź3ŔŕFLT,'_Ň€6ĆĽÝÖ“µZň~,FŮOáo4â7¦¦f MLŔ¸”Gä ÂM‘>„«†T±AŃŕ“ (ń(ŁÄ'ĐÍ@á<%úD´}i ¤iM*«dP IŘ1A4R‘NŚČ:”tćYÓ:Á@FVi5m-Ŕ@B€UKĘ:pv°ńTőQB$ş)E§OĘ832šŹ$8-O‰ju‚ŘŰŚD˝sŐС©˝b ‡úĂôsO˘|ç¨Ŕ¶uNŔž—ĘŹŃR*fÎŮ3(q´ČíiL™Ŕe‘N`şÂlë,¨Ŕé3zęQ0\)]ń%Ąhťy´ě“ÓúÍ`j-Gťt§µ‰{>{Ę7Ü<µCm‚d†CÚ_k1p¶ÁŚÖżj„N¨CZĘőEZőśz/ŕ ĽŘ;Ćv« d ÎňŇ![©GACçl#Z¦¨uB(xPĘşB%ęîz`n wÇşDÁ}čąpČ._Yݍ)¦đîçSŰmDÂĄÔ¬÷b˘N‹ R)A˘Ę!J~´ę&|‡\psKÁŚ6TęŞ.Tj‘şľQ+Ş žRźĽ+˘Ŕ't Oab<“?BxNîá^¶i ćXOÁÁ…m6ąĘ2%Hâ.–s¦S7č1°+`~‚WÁ‡CáČŽtż(AýŁrŮŐ&Ýo¤ŠvóTÍů_x(üň—”˘™öĎB°qn€v†ň˝uźô8\:˰€şuăÄeÚĄ¤wÜ?XPPËÁz —2mҵ·óśÂ$€Ď*·±ÝCoůŠ­8`/˛˘-c cÝú‚0›OŢ!ÂÚ§ŢPZˇ:ϝϟŔ8§„Ű;Gi[đCß›ř#40âScÓĹb’prMs”m‡çT Ŕč!$Ď-ÖvŕޤŰçşbxoě˙ü`žˇO$90~I¸ý`P°ëDCŔđěßŘżŠP7 p2Oއ§vĂŤZK#Ŕ›âť­PéŇÎlG¨ôɨ+ŁÂę˘â~BJśŽŇľF*Î("'îZ…bÖP9ŔP BúNpřN¤,bÎüĂŠĆŕ€ôť(ÚC¬‡ť©ş˘/ĐooÔ đh€línŠ!ŽŽçcd%úé„éđŽę$fo (ĐĎ j+dEÂŃ P6ë,2Ă‚:<jŤŁě6*PĂâŔęxä¬.C ß ¬!îVčđx!âÍ poČř)łęt,±&îl8¤j4˘ă `A ®BŢF&°đäń0ľ+Ů NÜăPČ*îÓŽň›D\$ €äŻ`:"¸şŞđýÉŘťC‹ď.Ç›l^'PĂPp…pĘ!ĺAÉ­ pŚFq7†dřçz°+*ŁIŽ PLDŠŞBQhä`Q [ă$:Ŕmdb(„ ěě|ÁËçŃ.Y(„(ÂÎî˝ő ‚¶äb&ˇ°–śŃÖţQŰńă® =Ńę>ŃŤ1 Ń”ącBő˘â8ŁjNË‚LCv5OZ4#t$#l2Â'h5"\ęŕmĺ&’t2˛‡(˛j% 5âŁrŽ6ňž-xîH‚#ňr$R`-„Ü2– §%ÂâŚ$D‰,Šucy)˘&´‚*R`ob×CŻ'ŕZüâO(Ɔ5R­-ęź.L€ PĚMň¸;rs-bŚ7’»,’ë,ŕ1ňŤ1’Ă(R2#k3'-TŁi»(Ó5'SA-Pß,/[(’É+’b’•((PÍ%˛Ś4’x;rg,"`E/Qßîű6nŞé‘’í°pçs†;s‡!đŐ±3 Ż©9‘)cž'`r-MéŚ ĐÁęÎĺ"±n*qż9ńw8I<‘‚´‰–0`‘ń † Q%" endstream endobj 29 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R >> >> endobj 34 0 obj << /Length 4714 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ž1Śä©&Uaś( J†«9A¶ÁgkśO'wN$A˝˛L-˘ $…Cľ¦-&“Ęb™d¦T"“JbÁ$śCb±¨şI•ŢoˇóIĘ!ÂiĄ±Eö 'ťŚ§!H´b9Ť&QHŕPwꌆŁ!‡bú3—J„¨-ö!Ŕ÷pë‘¶z¬. 2^hşÔC`Ţ1Ťa4Ś#8ä0Ť­Đ"¬Č2$Š?!,“ A°p?Ájý? Zľ(ʍä2¬j»îÎ$’ ‹#Ň8ŃÁČbŁz*i0iFČ2PކˇŔr±GŤčrńĂÉB?#I dk&G1Ú¦–Çá”kˇńÓ}+Łśg-H2l‰(GҸ¤Mđd˝%˛L¦’Mŕe7Ę2T™!Éň<±5HRt‹?L3·!Đd¨§RÍĎČ\ݬă)Ii%"˘R”˛aLOtK}FOó$×QQtôĹGL´Šá «Ô5[Á pµRóŐ5ZVŐĹ?]R…_¬UdąWRv"[1NTĚÍ>§Op†O¬ůAÉcýj˲˛A\Îvěżo×÷ Ż(Yi‚ކ‹UĎ#¤Áf˘&ËŐß$^jXb˝J·‘uÝ·“Ł×eÝA]*FŹH÷Ľ}Ëč…ď,bâ!~ŕrÂńŕSŽbt,ď-ášA‡&„8Ša¸Eňeo.;rdj^M™Éľm“ĺËW@!ö¨\fóMMKŘÍËgc›*hZ%ÉcGŽotşř,ЇßmđlΤÚËý­ÝŞPrSÍĺ^©ě±®Đ±mTžŮ®Ú¬ę[±d×ćéŻçĎ˝ä˝&Y®J͇)Ŕn^ †„Ţ>¨ď Äg*Wá·µ¶ě_7¬=&Č„ăĹŇĽŢ‘ň!w'§°k—ç\7Ôők^ă&šŐÇ)|…âńĘxż Üĺýä—ßrˇÇ/i#ôd?’<ňaḓËô“ʎévzŽöÝ~‡ŘޱřgÓ?NÄÇęSĆ’w= ôŁóż)ZřÖ.!az^gťř}}¨K›ę~Nˇďľđ`řȢB30Ů×lo[zEQJ0“@óđµąpŕĺ_;fIĐô)pp±.ĂBhˇ vOµv„îġ¨ĺę.čc !d4, *5«Ä×PĐfФ&VgŐÚoe«ÎNG]2cü†ŕi0Ĺ´x§dčŤîXOčĹĺCgSĚÁň$vŰ>’C*ź­p¸7Uł‰„ŕKtą–sx›:`i4Ŕl;?ŔÎt´Ąő2vÓůÄ47ĘKiTÂ3…őć©ęRÁf|g•ÄÓŞhćĐä˘SŐ9†˘PóŞ ť©TiBTs|˘Pó:FôR§duX_‰Şu™“žIuVňoN•‰}–*˝JĐôQ–u’ŞW”´°—%}{Š˝îÔ ‘V«Ô®Ä"źéü­!Ca{ŤŤŰ¦ň— ěd˛{ŤʦăSćř€ąŰ˘řCŕ;¦G‘šégj Q¤đXĽÍĺ„éÔ%Ł/qZcjÉin$l¬Ľ©h >ŠÂńß3(“§´ôŹ5ń¸wĄętĽw/K×Ňy;îŢFöĄ¸ëˇČ6µ˛řz2Z[Ĺě×ÝĎÁú±ě®Ěé9Lľzú7Açh„ĄKęŇ6#ű"ŠÎÉ*ęßƤčó÷0Ům§ço›Ăőčű¦ľNŹĆúk$#ĆbO°pď‚uf†Ä…*C‰n¦ĎÄäϦ»Ż"GďBůOvÄÄŞŞ \ř0<¬ď\Ro`ňÇÇO’VŻ–ę8Ũ˘3ŹHú/ŻÉZ,PhđĚL)…7ŁxŢ2‡k©"BxˇľÉiĚR„Ź#GU#‚¤´ŕĆŚ"ű$)Nu.bĘŇ,”âŕ/‚HĘĂ2“ň^Î2J§c„h’k&0<„†‰%B ĚqĘŚiPd˘ &ň{({#ÂöŐiO# &P(jN7(ďl’.Ŕű˘:÷bŽť(b&Ť§˘«GT7ÇĘ7‚‰,q.3"Ő$˛ĐýrČlÎy˘=+ϰuBÔ“Łčúça-˘ ó#Ęúú"lę—±.‡cęyĄ¦J*äÍ-Ó 1’Ę<‚ “łüO„’ő+33/Íj#2µŇ`-'8źĹ$z"ÔNëbą PĽ˘y5‡M5Ĺ·â!$łd_mÎLŢNóL„4˘Â ŘĘ|¶Ďzć3p×-Lµ3„.ë–4EřH{9čŇF“l’‚«6 NíQ9sG5s@¶ÓĂ; ÜG#Ü„‰v$}R¶„&ĚŐčÍ=ÓÔpëĐ} šNłá>ä»&Nß*Ą?Ąk?ĺ^öJG3ü„&›Óň$KÚS8KłŇĹ 3´,âH´*¤‡k?ôCŤo@L/Tµ§ą?ě˛märť”3>É2źÓč†ÓâHňJUbřż Ú*QQ±„CLQGMG3Ćh&SÄu/öĽH~#“&'‡Vš$GÔšÉl~$E<ŞZG%ě™§UŹ7l @ü@Ă;`AŽg ÷ťth @^ úu$ů3yÚE¤€c¤ř†?Ěă§‘?‡ ™Ěí&&‡¨úBĄ‘@S¤@® Z™}$ çiÖJd$+KÎȤ<_6|$Ń*Vć%­–,€ $4ëJ‰MÂLß.Cúň€’Ľĺä÷:ţ'I2gg7°®‘®Żz’łObtR‡’}7˛qBŃq‚ŮqŐŽZY5ĐJR'ŘV‰v3·4ç€P Ä,2»XÂďťkC´Łí‡ ‰Ą;;Ąe!ŤĚ<§É4X¸9SµuŇ2‚µđ@0ٸMŹWO·…łŰwĄ¨ŕ_eőGŹ@¬#h Ŕh6€š÷ó”čŃŁîÔ-X1¤@¦é…¦űÖzĂ‘‚§¸y˝@ŹrŰÝ˝€mľ#:Ú"0ăXúmŔ7˘ ©˘ů/*–Çą4 Ľ`š7ś ŔřŘfĆ.ÎĂë¬[ş{»ŮO (7Š)ŹyŔ‚h{ĆAâĚ endstream endobj 35 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 38 0 obj << /Length 6865 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;ĘcĚś@3ŃŠ’(Pä Á˘Č¤¨j™ĄiÄn.O˘uř0Čb9 óy´`.D ‡z™LZM'”Ä2ÉL¨E&”Ĺ‚I8†.«VłJ9Ť")$šQ‘K%Ń tt@7×ĺI-A˘•Ë`°:…;Ť…Ă}ŹK—Řěĺ©|Ćg[›ÎF4™‹†.g¬ăZU2otq,@ŇnÍćă1¤Îu9N†žÜÜÂb6q0[xŇ{ Šr%Ś´Lm˛”RÁ¶ë…Çž©ŠŢ2Łč ĂÚő*ŕhdąĘj·†ďşn"5ˇüąŔĽ:ŤŁĘ9=ahb“ŔpDÉ:‘ Şř¶2!HZa c±°fÂŞ lČś4Á Âŕf AŐˇČnŞq´q*¤­ÇaĚz.Š‚R˛š«‰ĚLËr[¦˘¤0 b(†˛`Śő¨z~ž"m ŚÇ b¦/[â÷!’kÚ­‡ E6­«|4®.‘šň!†1°dÉaE.SA¬°!‰âj"Ô‚léCA°P&…✬Dá@¬ĚóD„ÚŐŃôQ-A´<ő#>Aë`P/ŐmďĽúż7V űÚŽI١ ×vńŃÄRX şÁ´$@*ďyîĚ<$řZ´á‚ŹđUͧ7úÄŕ€çőüÄtî˙Óë?0%ě˝ĺ&’ŃĺVXŰ cś&‹^ŔŘĚ÷,É -Ą ­ú,© SŹČáŻů°ąNÚîn¨ô"He«0ţBKV÷D˘dmń"í%Z°A°´íÎ$ýq'ŹbňJ ­P ňń6Ěp›gbZ© %DEŃJ,±>ľ°éo^ýĐíPżŻ|-QňĎ8!ńlבB€bŠSs*އQ 1vEń#ЇŹŐ °MŹßC,ňpĘ©Ă$’/rúd%±§ ńc жíńťďa0¢Ăf\0# 1´°iw±čűŚŘAďF\1“ 1—_P÷/şIj°ë/u ĆKݍGćFÜ0!Íą"*HŚűĎW1%ň -Z‹ŃŞ©>¦0d(i#"$Äë%Á2HÓń-#‘a&2<Ć©Ľňč˛Io6÷Hˇ±Š,˛~€R‚!ňvz˛.őŇ3Đőîg)$âĎ$*č(§D«+)Ź*­Ri)Ďňe)ďB­Cf42¨ąRÓP\7#‡ÎŇiĐ4ďSQ˲É&®fŁ*ÁĚÂ)t«ĘĂóŕ*"dj&Gě*”S¤SĂs ©łÂyqź 5a2,tÉp“1sĆŤp®I1¬ŠcŞ12Ě>ČZެ4Ró‘ˇ3˛ĘŔ“@ÖĚćâóR(LČű“~Í­]5\G,Ý8ÓdŃ“{6ł7 ’Ă)n%7m8ŃÍ8lĆÓ®{; ¨Ň“c0-Ňm2Ş“Á;3­9Ó=27/Óu8ídŐä0Ó=ë;>S€×­s;ó$Öí}?MbŘBU)0ďr5 RÄĘs¨łŤË0Ş$(M®Új1>ÂŽÜ"NŰĘ˙9mąB«áA4$łŃ70I@Ó¤±ô0ŕŠA®N(±>4Q'Ž?Ę8ßä+1SŹDÔ/So:/’Ô´ĺ}BB‘nR˘€ăäŁFNätŹ<“%GÔ?=”CÔˇG“ŽéŻH­B4ZčIč”»IŽ·î“Fóm3”uA.Ňeô1‚…M¨­;ĂL´/<´ë;tŞę•Gr™=tJ”0đĆYDôŕďO2°đtĽ."x¸Ő ďtźPuDU:s\óFőß0ő8ň´µQ/Dóô‘TŻITďO34Ó@•/JU-SS–ňoqQ@řeE5$÷ę'LO:÷•UV´Í9ňg/µcD“ŔúŻ˘-u>˘u”üuGT´P…Su¦E5NüOŻ&ŤDrV˝NęE/ä˛ÔYTŹă sëE v˙ÔőVoô˙ő|ţµËRµĂU±gP•“ĹY˘QPZ5ťĺERU÷v \uů“qJu_#3Yum`v)H•Ůă1Tö5µçäą^Ö#[ö!MUeY0­bµ˙e61TĄa*ťeőOe•ą)µď[¶G\Vc u™\őApÉe¶ ő«VpÖ­V‹eydVM¶mg%‚@Gę̢éšJ–˘Âv¦Ť˛Í ż –´É6ş-ćP-¨«ë×k¦«ĘíXsÓ,vźi¶ŻkpYlęínbán°/kŠîȢUl6ř­6ýmv޸ ęĚ3p¶™UŇůn7Őj ¶«_qI›r+mocč®ě4"!p2­77¶ě˝w-rvŃvXöIOöä ¤€žË™tuĚč7ajw0Ű+`€kQv÷4ëmm—H+â?p—Oquóa÷Yqéš4¨‚HwdŢ—˙÷<Ű lREzjďz¶ňˇ—­7Ły×uń/vťPUÂŇ–¤¬·‹yhź[±{Çb¶˘×}â wä —»~·Ű}VŰf·Íg7Ç6ăB$ÉÍy隀Bŕ(Wy{Š#öÍwë«syęÓ |7Ť|—W@wŽę‘7;6X@(ř 4+Jőé…ĺq7‹‚¸Hîř)Ő1u¸3‰Ąč߀ ą í‡xNŞ(«wv·sâĽ(¨ˇt×ű‡8x—űOŘ9WS|é–>WÁrz6CÝyŘN¶¸XŠŰ8Ľ“÷ą…řłŠ×ńŚŘˇGŃgZ,â’˘8Ón风.S…o´‘7狪ÍK¸gŽ«ŠĂŤtĎ:ÝyI˘6@aŠ÷ב"á‹Â®é ×8’*Ó’tŹŹéĄ‘xçx§€ŞđÉ—„8°I–ÉCŘV3ŮV'kM…×ű• ż•X1mÔA@µÁg$9‡u“µÍ—«…vŮ,AŔ`‹ë‡~„™™”¬9…—řg•‰=Xk‘ ’´ŮŽ™®BŮ”¦™ŚÄŁ˝‘xË–e›™o†™w†ŮCŠKzŚË‡™ŢÜ*9‚ ź–¸÷ąî™wçť9çž9ÓšVßJ6KšŇ˛jy€śúź9¢ü>ů+ˇ©­xL™†fRYű:—7‘Š3n`—âÂŮäÚęÁsąě`Â9•ĄŐ–Yť¤šE 9?ť—”Itňi÷‰Ö¬AÚpžů‰˘F‰ęĄz…™«;§Ş/š:g‘o „´¦žK -Y!¨ ‘¸MźZ®‡ú-Şz٦Z›XşkŠV˘©bĎlšw¬˘@©*hÜv˝l«É:Ýl™¬řÍ­B&řxź©zmŻšÉpđY®ŘéZ–ň,Łă­¶ű—Ú×°ćQ±7aŻ:ŃpÖč Ű“ÚĂš™×‘X«ĺ˛·gtşă±@=°k­›´c‘»=sBMr[!ŤZýG9Ű€W_x{_°{ją›LÜwr·›·—|Lšőx7k¶ű-¶x۬x{űŤv{™·włzŐ˙·űŁ{{›{$P˙űW—q·˙Ťéď};Ż}›Ĺş᳂׼×ë~/Ą»wőĽ[ÝŁ{»|ą«Ż¸;Ć+Ř şe%´ř#v ÷şŔŻ‚»÷ŔąŐ şű˛ěcîďµxF¶"!˝XX=Ű ż­Ć28[ÁC†"!ľ;cą;żłX|×"AÂ{‡[Ă ďX“´;ü48Zś9ĨßÄ —“ľŘ«‹{ň‘´é<)Śf_ČgcŚśkČ%ď¸wĹą ąXp8ěXŢśĄ<`ÜxóKĽ‡Ź˘×˝ŮŽ\qÉÚĹÄ{í“|—˛<­‘D‡Â™1Ŕ¸ţnąŁő7é‰W~=`U˙”W:ˇE^Kă®G•Ťśźăs9äŃWeQč‘AhUťńITţtG>yćÖŇ;ĺÓ?SqŽňÓ†€nË}YчOéä—ę>—Uť˝ă]›ć>Ť>h€~ąç˙Ô7čÎŻěugäë,ŻÇ]—©Ő7Ýéµ˙î Źé6ĽDö“\~ď¶?î3¶^3Aß"ľ?]’"Ţĺ%*+"űńußY?ŠŢ ¦žaíŐg$q;é?1äRR‰ GäŇUóő7ó{ąĎ>…dőÇ(ţ‘WUó†“F Tň‡ö6?őżKÔ+čµg*/54uw÷’Żń:/+_jÍ3+÷rżďý™ŢyÝSrď-Uü¸’ńě é.žň©Ňá.¶?ůđëôűéůf*тɭ?Ħ,Ç|ľˇ¶ĚŐ¦v‹OF(ĘH`Ç~©‚‘4'ţcí‘Xe Äęâ Ť†Âá€Ôd ŚĆâáÜh 1`pX<$f4‹‡(L d.°ˇ Ô\5`CXhŘf8“J%RČĆ.Ë#3I\h9‘ †rhÜv?AˇŃapŘ|F&s”AĄ˛čŔ@dśb‚á°Ţ ¬V#uń„ĘÇ6ÔÁ¤" 4^F– DC06±/ „Ůxć‹X˘P¦4Y„ i *Zëph †O&Ť Ŕ¤¨jĽ_ccĄ¨DÇäIŁ<®_2 * ´y!–śkÍjő¤ŃŽĂeŞÖd2C Ƨh(+mňŰě­”âîx$ŃyOłäků||y[MŐéuĆ˝Ö<ŚRďpJD^‡kżÂÜÖ%hH·Ű±I†báĽ0@6 %#KăÇ‚#Ö/KâüŻ0š2úľá»ň!ˇ¸pŔCĽ¬ˇ‚Y  ĚúęŃ „ĽmÜFDĐ„î˝ Fĺ5ÜD!;1“Ó†MʆŠÓkâ”ÁÂd•>ˇČbĹ-a@cH0a“üŻ**\Č\šÇ†!€a(«ËÚúż°!Ž2ÓXq ‹¬ś)˘:5¬îßEÍÜö‡3ÍPs˛Cňű»@F.4g@FÔ›Ó@:”|˙C¸”Ű@O´üő;TýPT´-QRá”KVOa”SXÔ´u/HT´“™NUÔµyTŐŃÓS4ľkĚĚľ rę;$%hpa07‚mo`ZUĄFŇVĂ%UŰbmO…ŻŕjŔěě>жłňŇ4őpÝÝ´ŐáuW×w˝Űj5/â<şC¬óAĎaµEzUˇ­Á„ĎiU—bľ;\…őJb·¶2#ˇ…ßjáŘFC;(4Hinâ“˝µ•?Ů=űŽGŮ>7Ld¶5F Ďg†ËĄÓdó9`‘^G{ŠÍËă­/Š?ş\%Ϩ`Nu§Á3UŹ#/‘ň“꯺ ¬ÂĐÂ6żŃŠAx®ŕP+ĽALň"îâ.ou`†&nâx¦!µü°č8†ŰńxH¤cś®j#čXĺç’QY>!Dâ|îYÎĺ<îÎÝuŻ3Íse-vÇ]uÝď=ˇý‡MÜNÁŹQŢŐÜ˝sWJ"u*Č Ô„…Şö˘±2í ˙ÉŘ<ĘŔJ~D~…)r'‰ruYëA@k2hj{čŢ»ű–?łćľ©rřˇ˛'Ír{b~(,śĽâ"ŁQăĺBÄť&%žIZŤ7!·źÄIC¸ *Ĺ`­ÂĘXů+ŔÜł¬bÔU4'HP…Ŕ\ŹIkU䄢@XY lˇL¶A’˛VĘé_,%¦Â2Ňá€6%Ţ’÷G}p¨Ś’~BaÄ:*ň Ăř= "h>q6vQâ¤N†ŕŤÄ˘Mâ´9‡e^ÁČCOś_„‘‰YźŔs•z …đ‚BŘü_ă|X-ĄĽ¸—2ę]ŇŁň@Ż-ü<â8ÖOň]‚Żš$ CÚŰQŹ„KU©›”2—bAE#k¸˙˘.V“Í1-UF źJ3R¶HżHňSX7!«ş˘BD N2ęW“‚dĐĚ·=$‘řKçćó"f&Iţ- š“™áą2šO2„dř(B ‚E Är‹pv;HC# kwä“×ČŁŕ>Ď4Ť‘Ż`Ô>žP~> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 41 0 obj << /Length 290 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EAIPŐg#H ÖŘ,â s‰ĺ®ă Ä€h7¶I…´A„¨wĹŤŇyL@S,”Ę„RiLX $“běn PT$uĹ ‹¸'lű$’y8‚L&D"aśKŢH¶h6ńqňEŇNLă@-R®Ç#(6Ü€€ endstream endobj 42 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 44 0 obj << /Length 308 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h b1• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨Ť»mÖŠ5đÇo ]9Ał™…r‹_śŚ¨Čj’2Č8×)EľĄQI†Ŕh¶M išů`0Wî₤Ü(ć1ŽCHŕ: #xÜö1Ŕj endstream endobj 45 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 47 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 48 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 50 0 obj << /Length 3260 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h b3• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇآM. ĆP)5`[j †ýk€@P4›„C)ĚĆr4ś†“y¸R]* ´‰+řćĄ!ČlĄ*®»Ěô=OcÜř>OŁě­*Nř\Ëp®+`Ż®ď" óŤă¸Ę9/ĂHÎ7 #`ćĆ+‰Şľâ®A˘z†"tdŃ3)Hjµş!@¸ç†±c„›, “F!‚¤. Ńb§éŕ@(ˇ´w.A„6©Ş˘ ‰!&’$aJśb”>šş2Ča6*‹’(”:a@†úŤĂ(Ć: Ł @: áVŠÁáÄapA;ŤŁkë?Đ"h *Ĺ$µ@rSĄĐńH8=!›Ičd˘ ˘a›Ž”Ę“6ĂR@¨ŞNÂYĆîTΉ†’EZąN‰PĹÂjÄI@Z“@P˛«ĆS‡"¶ÁڦIu·R¬µ,¨GaÍ^ĄË@¦)Ěs‚×uÔÉ) A¨pÜj¨`+0Ăń=O“őcČç> ¨ś"XŠÜ3#„X]f¦ň]ˇ Â^Řa–ÂŞ+ ÎË·QbŠÚguH¸j¨řŚ1,†qä:&ŽŁcćŤ(ě2Ť”5ŁśűH#ᛄ`†"tP¬7ćCÎ2Ňą2ÇeP̵YCŁá= #0Óźßă(Â1Ť.Ž yĆr4ŽzŇ; #&~1!äöílX*YZĆÓ0í9mŁ|H4ŤşŘČ0ŤŰH[} ٸĺ~„ AĆ~¶9 /›ëď{î¬ÎčĂÄŤšîż C(ÍĂ Ľ¨ĘôŚü¸ŕ8u3í"ě{(í¦šwc@t;đ`®°ď[Űwüü6磧eĘŚ9ôýGŰIÔĄnĘVE€¶ ­.Ëđ…q2üčxfš×ż0øĐ4ćˇÍëĂ`Ů˝Xˇh„ÁˇRíQM&ä8U]˘ Ĺ׿¤C\€d .x70t­Ë˝jL Ż­”śöČbĄ%­+%„—•şíFŠěÂŇ“ _x L !‹— d·ŘŇ>Jµt¦#`ň)uQhgŠ@8ZÉ%‰C˛°ĹS 5$đî&UDD";)ܢÔ"$'+ĘEPP¨‰¬Y]qn.˛¨uQ]k*C•DH#Q`‰1./Dč{˘fd J$óüŤ{čô“üŔ LôÆäř3cv!M"„Uă\* O¤Ł–ZŽQë‘IŚĆŕQXń€ÂP2T%ŞYÍ`Ş€Z ™†‡Ŕ°7:L4Ŕ°I»§´ŠL8/ îUž¨ śáj) ä5¦P»VĄąąňžŰ- ąĐĂ5(frçŞ_ói/ŕ›x!ąţ¶řń‹ˇ7C®,9<đŇ{Ăzúq!ÖK°’¸´ÉË ‰`µz!ł …Ë“€VEPę±0‚ \9Đü¦G’5?‹Í•Äâ\ĺÝ*ˇ$7 ˇŹLÖ›jn@§bBs3Ęu»$\¸dź¨D¤)ŠZr %2 ö¶ĐĹ%ch_sˇN§ćŰOM6zJ€ő´:¦Á¤$ŻSeŞD¶Řî ur ¦WŢŁĺ cÄWÍćNĘTŃV"XpŮbls™A'`íY@o*×Z|(Š7ý.PŃ_ŁéhŃ@mH‚E]•Ň…Ş’+ý,€©q«¤ëM+8 Ę(*NŔ¦B!ĆcáŤĚ<¶îĎž“† áş †”SRÔµM€”bU Ň››u»Ě7;[r_WřlD$­›3‹$ ézUdôÉz—?ŇČ8eĹVL¶”üŕ›eťňěÉÚý­G €ĄĚ˘GćŰ+5fěä._€ĚńRĘ7N¸"uĎ5á]>HÜʾݏhe».mΠě@Xß Rˇ!Ś:¸B#ĎSO­>ˇÓŕA{Řťš ł–©ČUYôwDŢva«íXi˝x_Ť¶˘§đňÖę ĽŇYŕWc‰.]ÁWŕěUQŕ»ć7ËÁ׌[jHDŘfúł› M$ľf"8$”ËěÝ6ńZ“˛ČÚáNÝ€Á@Lľy[?I]&´%M8Ł芏j 2^‡m”&hą°ŁIrޤlŕ˛ć>çćŢĘĘUŁ, ŇĄç‰Ŕ•P†üĂ~g ňíÜç’™Ëň í–¬†ęvţ΋9úĄ–:RŞĂÁ=7Ą § ßŻn& !’Ş:­%6:'E4:đµ9Ŕl9ĐCˇ3eřŰó>„cŔČ&1âjŘĎ›Dq‰úw¶CâćqĄě řŢ‹U,Đ(x’ňy´_ ĆÚH ×k‚ě µ% é.1âµ`g/@o=ĎŇϸ3 ËčwpÜa˶×1Ę,ĆŞ=ÓĽÖĽů*YZC,V5BżöSdÄÜăťALa±ŘÚáJއ¸ŞA(Gp›B•Ţ»‘»(5}m÷á2Šßé;ŕĂ:në`Uŕ8(śËó)ÓHVnŁ>0ÁH"`®§š~¤…č»,Äťg~éâłţĚ(sµ4¦ŕQ[^¦«LŐ¶ÖŤ€Š A„gęa ë3őSZ•€©ékÍ[D‚ A˘­NÜzţćY5ô& ĐřEIÁ{yIâ”J&·\ĂhąT‚*( OÔ!ń`×’wSk¦´ÝעLŐ/¶4ÚiäŕLS§”ź‘+°ů ü/SŁw…j.ţo×űgěř?µ“ßL¶]7îôHU÷ÚÓŕG0\ü϶Ž×¤|;MřßÇ.™Ćč«”h’Í)ŘţďľÚ$ ÝŞś€˘Ć $ę¨ěŽŹ âŽđ«eúQ@®Đ‰ÖÉŠÎtLBî/š ŽzMöߣ´i„ąË şB4ťÉŕđä:ć@ä懪s*¬OĢ0)rµëZá°0őŠdý€R¶Ŕp¤ாîţô«xő nł :p¤öd×ďâĚŹćm/ęĐ­8ÍďzôÍj˙ĐĄms ĆÄ €^ăŕOŽ>±†sݤą*ČŻ† čŤĐŻ z˛P ° Ąí— 3 Apgŕ@ đöjˇ ”˘‹0žýC¨őЦýĎŕŘ/äĚĎpÓ@a ŻŔ˙Pŕ˙Ą©mqBHŞQ3°ŕ'cŠÉÇćéL»M;‚·ËĆÎę¤ďîÎăéĎl¨v1´LŚqg‚č"ć.PŞęŔm­ě†ČŰŚşf­Ć,†v ŢžN˙é ‘ $|ÔGţ|h†@ \&¦ÍŔhgb`ŇLxź)8ú.Đ+gŇě„qî!ăyö¦%gć&ŐënŇ1jŽE¨aľÎĘ\xĚŞKË-â ęŢćáî:ŕć{N$Di<Ńp.Ľ…¬ŢBŞ ośă+š«($kK>n±´ťîZéQ®=#Ţ «˙BćY ¤  Ę’̸ʭ¶«@ë îs¬ŚnBu-ĂnĚpѸxěž ş®…_R®’ň˛zQĎńÔ †žÂe`™,cFĽĆÚîj¸hě"ÚČŇĐ=F„ßäQN6Q¸*äŘtĆĐăËä+¸Ü.nĺgôs§ ęłpRŞĐK(–N¬şé“.éÎzu.~D€ßŞon‘¬Aéüo¨ ÇS,ĺ¤éćŘpkîę…H„N%he˘&*çŢĂçĚ”DĚ]ď´dóŽM…„ěĐB ѦwDX1¤ ”!č¨$B):@c~şB’<B,$s=~Y@6‡ľ$M¦"`l{ă!Är—eW=%TJ q?sď$b:\Cp„Ţ9´5‚\FGľGt %TA@ö4B"DWł÷B#8´*<3ŇFEčëT=>âH)"> n×DŔk>ĂZäärýÓř@H^U´$UGŘŞ"DpbŞ3î—h_GTRÇ4 (´(SëFrpHâŚűT”)2$H(Dµ?’ň(tš5§;„¨)#.pKă|5˘ endstream endobj 51 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R >> >> endobj 54 0 obj << /Length 3842 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ř}IlP2@„I¸@D2śĚg#IŔči7›…"ŃČf3sĹĂ1It¨J‚Ń—(dP]ó  ĂaČŰD«=a°p¶1.p¸ä†˘0Rż@¤ö˝ěŠÔĘ-Ę"m…«čjľ-‚#Ä´Žbµ5 P!‚!„Ň3ŤĂŘÜ…âx@8:ˇp@!Ľ#pĘ1Ž(Č|nę„°Ţ37Ě$2/ě:ć1C Đ2„Ţ6ŤŻ@2;°Ę97¬{"É­«Ö-Rxi6Jq`Ó-ŽhQľoha@“ĹŁ(Ů»ďu> D'4ŔÄFMÓ€©4ˇ„Hİ3°†4;˛ËÂ: .«Ş3ÓŇăÂ9Ľl`r ˇ{^˘sĐlPďHAϢxę:Ý‚ݎ»ËHCPĺ'Nl¤íVŐčMeZ5°’7WŁĄ Ř6#CÎu7NËCuAQ Ő ć2ŚăhËqadđŚŻr•ŁsjWĎuÉ-l¬ž±”€g9T¤ *@ĐCÇ@¦"踆H#†áÍE_łT/b>ô”=94íHQĹ2ĐŘ:Ť®°¸\÷MÖ: Lż0Ôaß]ڱПgRdĚIň‹ýcÎPÜë*Ęá­&®Ż˘č¸„Ë Żšü“ ‰&ľĎÆů2a€hśë+Ň@ĺ… Ŕ¬mËPÂ7Hb˛AAĚCeÚ4Ý·= HAÄ<ÝŇh[މ‹)i (rĐġD´6ŚN¨ĂBşŇ\‰¦Ü2 Ĺ Ëűŕŕ6 < ¤ ˘ŰÉ&ŠP9V™,”[Ć#dĘČ«2 ‰"“ś’­¨‹¨®áš<ńW@9 «Ë cŻ‹ď©"{ @ó¨‰řĄmmJň4´:ÜSÝşs}§mF”t*s’Ü»—Ţ;ć˝g\iY)Š;MĚ73Ţ#ę Đö˘×HL a$®× ’çH˝˙%@P•ś¸ aʆĐÂŇ $‚A%Ý€×zKáĐ$€Ř‘ăüyž[Š(=ĆUĐ "D@‹‚4CŠ/-†0\ĽÁş3!ڧbpĹđ8lć’äö Ŕ2‹1ma’Ö˛RŁ Ţ@D~2“2űOĚk±´ŽĆřÄ~bŃŃŽ20Gt aŹ‘ŔG(č}¤$†$Ľ(€ŘŚ—âDJx¤@Ě”HˇdT$ńXőÇ波é'‹ňOĹÂĹăëŢeÖ6’——Ą\l2şN˝éK©?2Ţ@ÇYtź%d˝+˛ÔüËç0›(ĹWfĚ`sÖ~1^#ĄŔůăkë†f•«Â¸ÂČâ }…°NǶh#YĹgí ™´gâťá mU¬k–¸Č[ dC- 8¶Äˇ(hknĚŁ\)7,¬´Gí! `qk źÓďjĎř(Ě„śĄćwŚ ­©Š1<ŕ[˘ăśLS^Κ#,Ě·Xť‰÷ŞÖ§?ć# ó1ÂÍ#5iyttqOĐ&53űŠ^Ć®Ş%Şgڇ1JShô(<ăbن/ Ć;žBü‡˘Ůü`ć/9¦hdŐbÇ Í&“JH@őI`Ý©b ź!á#?ćÄ‚‡j5l¬ó˛ b·AŔpѢ°¦ä¦ ăč… ]+ĹwĽwRfŢŽ(˘ZÄ<ť÷K†¶›)'š~żV¬ ­ćß–gşDH˝!źBrÎ8çR°qJyM`¨ćÚ¦L!¤`/5‹’śüKA—)­â”HiËÉ„ć‰ĎD^qd¸/4ĺĽř±őĚů!JĺÝ6tŤ1Íş!-Ř„{§s^{Î)ź¨ÜvqútL!݆3ý‡Ą’ncŃůZoé]G”v?lząb<ĹÑ计ĎĺŹuí\›ąs®ÇÚů˙~îÝÇ©&ÎĹŕůżEđÝë˛vÎŤĘ»˙|ę]7´÷ÔŞgN4Ţ­ÍŘ…Ćj,’ë…çŻI’MăüŇ|ďžźĘü»ĺę ô3ŹŃ’ŤE:˝?‹í>«˛_uëĽĺ ¦žŠ‰{nAŕ“Ű÷˝Č˙_Ű:ĎłăźŇű‚aŢ}ßĘčť›ě| ě~´úžŢ”vß›ň}_ćó_?¬Q˙eCľ%8řÝ|ĆwHwóź®'WóĄ Ďđ#ďôˇbnĹÂD!čřŐÂÔôăřJ lÂË @nĄić?ÍjĐŁBęBDş ťÇŻę8˘ńΔ؂t8 ćݰ*Ś0. ¤6©°lâS Mđ@±9ŚLĘŚ¬2«>´MÜPL.06Ĺ(ŔOmÔ–ś«`C€. ‘g”ĺM k¦ľLČ^b«"QĐDJôâó)Ç•D˘/D˘8Í·ÎäçŚ Đn-LMcЬ0n”"nyg•ÂqNŠc):Ö0úĹĐéđpľb`ć#ŠÔ°Ţ˙k$Jŕ™É’ĐaäŁĐҶ0V<˘”ÁĐpá°8Şď m\”&*/L- 0öż×PCPQF90ÝĚŚMź@˙cA1qińSPÔćć8«¬M‘Iđą Üyѱ7oýQ±:4Më2,Ë6z°zÎâş$‰ćۨ^Ž ËZI«a B— Ś:0 ™Î¨` M&?ŃĚÜF+ Ʋ!đ‹MvÓńá +gb ˛FXPˇ0¦ŕ#!­-âH<É“r ĚÇ!#C!mą!°˘Űr# M=ŤZŐéĘÖO’3CäŽäŢCKH9fÎJ#”Ü­‚LƊئ®Jm’± ~Ů„šŮíDÚM¨LÂhś˘hăâ(/KWĹą”0 –ÜîŐ­ŘM˛XÚNpĂ ŁBŢͤ€‚ €+íśŃ †D. ޲2Záká­îâvâN(LÂĐM*l-b{Cô{nfkc0ĆO'@Mđ ŕšbF( @‡1Íeó& ¤8bf*Gs(Çú_G¨ł¤,žmÜdG^€ÖdĆPT§î^GřfÄŔ ě€ĆxWf|h4JĹâhf@hÍîĐg3')‚ö?S †Ŕ{FĆzŕ@Ŕ'·9Â@ |ŁmŔbm uFśnî&PFöoĄP‡pg 'ŢŞçhĺ(:-6×ë"Ő"rg*F'0txgSn“đ~ĄL§´ťŽI)fŘgHI8TŚ!‡>bę唨k€¦·Ôť9Óš?7KÓ’…¤2:M4Ą¸Y šr4"V°.ÔŽ.ÉVâéČmŤ%LfĹJśyK¤‰–9Ĺ.dŘUN…%Ż ŇÚXŁ(ŕôçH„Í8t´j”ň'+ôĐ4Ă9tÉPńPB: ZO §F…®äBĂC‡ËŇ„dÔ"oĹ<­Eć 㲠Ě}VÇ@GÜ]§j„›Fí{=“OČ1ł5Ó#3€š8p5Ŕ† Ó, fj}d‡ZÂI2ŔfĄ@2ü-ÄžNg†B;CłÜ€#śY…R&ŔjÜÄpčąYÓôßŬ<‚řUu¬Îrć/€Q[Ć6-'ŞNDßMÓH´íRôńC>˛MÇ=Ă(Ü´ú7ôž S{v$m ܆`söU#ĐVs/272íäC#ř^Ą¦ZŁĆ{öE_EŻ,&3aMĄN§°y(¶Ŕ`mU9LV1Sö4{Q¨!ö0Ĺ*vCťeĺ|C*î^ł/35Łe@lU+ż^cvU#AeÔDWő,jv?ÉWKéşO”Uf"şčK'5¨Gč “óF`‚f*WęiFŠrt1H.Lh5HhA?F$µLhZ…č€âç€"˘´†"䢦+ä5s"¤nâĆw÷/‰ś”"źSF(ŁÇrČ`ŘŤ*eč'¦îhŔ*`Z‹â@‡Â_r‡˛xh`‹÷a‚›w÷?i ä%ő3x4ş$×’3ëš*˘SvC?xBuz"—y׎#Ź &W¨ ··{ <^‡Ŕ!í” «A|‹Ř,b endstream endobj 55 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 57 0 obj << /Length 390 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h b5• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyÍ\]˛ń˘¸ĘAo©]Ąş°¸h)چC1ÜQ& “p€e9ÎF“ĐŇo7 KĄBP7®¨Ť»mÖŠ†oŘp°ŽC(ś¦ ⊯§!’€† P’’)üą%‚ Ş†k›ŔˇpfĐ"´«â#¦<ďKÖö˝ď(Ţ3Ň9 c¨Ň:Ř7ŚaHb…Xćů>ʞb€€ endstream endobj 58 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 60 0 obj << /Length 290 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EIPŐg#H ÖŘ,â s‰ĺ®ă Ä€h7¶I…´A„¨wĹŤŇyL@S,”Ę„RiLX $“běn PT$uĹ ‹¸'lű$’y8‚L&D"aśKŢH¶h6ńqňEŇNLă@-R®Ç#(6Ü€€ endstream endobj 61 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 63 0 obj << /Length 3865 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h b7• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽőzN^KIŃŘĄŘ,źIĐdĆ#apŢQ¦Ěč¶{]\¶_1™×¦ó‘Ô]˛ńxňśĘAo©]Ą±@Îć . ĆP.°ĚR-ŚíŁŽŻ\@D2śĚg#IŔči7›„ó0€†i9 FAŚę4Ž„6 ăRđ…X拢 ”‚© “ą‰HrÚ%Ę<ďKÖö˝ď‹ćúľă“ý@P Ç1Š“Ŕ$©¨¨"«Šć+ë»Ęh *°ăpč2ŽC0Â1ڱj†Á˛Ý)‘Ó¬¤G‚Ę6 ŁBů>’ ‡"Čă*n<ŽJ´®&Şűą‰ęŠÓl*Ź®PĘŕą"‘”t* ¦"Ž+¶żHKŇŁť9ÄthŇŚŹÄł-Ś#`@2 # Ă%zÔ&ń¤lđÔŽP1Q.ŔP" NÍ"âŕR}p9 #pć3H”Ý:0…ÉĽúOHËŽKä4ŇÂ8 #±ŠTkA2ŤŮ…PTP˝K— Ć ŘŕŰ\Xú=Vף%ŰO4…ťÉň#ö6ŤůŠ$ľWťˇ©OLuÎd 0Ń«n&çcŮ7u۶ ÔĘË Ă€ëŮŰŘĘ7ş–Ő[đé˘Ň;Ąť/ö´ĐçO”N˛Ć¦(8ÉBH¤6ŕhrµűjKX+ŽÁ8NNLŘ”4! p©.‚ä.ś>›kLRś”㇠(ZIž#`~‹těľű>´Úr Ť‰+_:%ÜęDČ’O4}Ŕ  ľ KH1H`oÁxW;ŕĐPPŮÎř7$Ş˝Xť˘­bF ĐÚ˝…BťLŁxe|ŞB5ü‹Iši8hÔ¤?BP‹ßr2JL×Ŕ6ĆuŁ;DŐ#žöăÜ(4ŮF4xrÉšŚMOx`„śÜ*0*H° Š\ŹÖ=ôy#č5äPţHΚ ±`< -îwS ˘Q:`ˇŠ0ř¶Î_±Ě†~ąB¬‡Ť2%5ÄfUd2g‰2‚›RŠS őޞL)Cľ ©ä đ‘Ć€Ť˘\<đúXŇL ŁśT’‘îT˝CZlK`5{„„”4ë4f™¬šó@3i&¤Ö)3vo›Ó< f(}Ä‘G‰Ň[Űâ7ŔČíyŐ'çlőśVkšĂ¶ü'ÜřŔ€N©ă9(86†Ř¶P cBŤäđź¦řŮťj:楢3ňyŕcCçµ ť@ťĎşJčˇ"oĐŠ‚$śK`7~Ö†OBv˙b|ąĐůd›é·JŃí.žbÍ9Ú fąm›4PişH'k…-‡Š”čA8ę¤íE©’YL§¸Ł/жV'Ćp 쬣ôÁ ÓB ćJ:1)śłńHf +I-©°Đ­ nŃL ąTM+Së!„ ô> 7Šbw,`Í §µŽźÔ w J%CłĆĂjŽvµő.ÁÓ L0R…&¤ËPXࣂ”ňHKµl®ÓwçĽ3/¶r§óŹRÎÂǦůec[6 É'ĹYdžÚsů8č´ &â~O IB¬‡B!Ĺx_hŕnítňFI@wĘ$“ÄUČyă ˇůµU(Đ`ę—ńE§‚€l S:vô`e !S˙Bç’Zťóśe-¬Ľ‡R®5¦Ę¨^ĺ2‘÷x¸e'pč-ÁŕZx‹IVÁÓ{PÂ䔨s Ý}Ü?/QsÜ‚OÍâALU°ř(ÄŘŚ`|CŠ!&¨ré|˛ˇŚĂ5XrF|5lŃąuÇ٠≉oA•„X‡%Â<\äžzťQ9QP’cfsѤÂI±Pę?@RGă<)·!Hsw‹!'‡ŮaúGB©wUPWɶᒤG›l=[‘čŢ,δú®łáµŕµ¬0Xîh( ®E["Ód|Ȣ$Šq€eިa¬41ârÎčRuĄ!ÖE˘nŇY­őv˝ś°M ¶Muü×ŘőT×’ŤŚ…ő\ƤŕËhk( (YBNtŠm’€v#w¤%k’%HKIkŘ”Bší ą»5vŕžwżmn]¤\©®ňŁÔŞBRÚ^H7!tކI´¨J)é.§äR Ě`pMfńkť ä˘ńGJM”¨„š˘ŚI(é%[RmĂm®Ď%ŮŠŹ”r©Ű¶Č)ä/ŕÖ¤)[Iˇ*ꤥĹI$u+©ŢÄ\¦4Ô™?{‚ r7¸Úŕ_‘c¤±€Žć;`¤t»ĎH‘"ÄF»béZq±ÄN W'çÜ; g¬…°mFÓŁŤµŻ"Ó*Ľ^ ‘ĆPâ]řcPÖ­ĺUG¤ăÄtGMP:pĘďÜbbqÎGĚ©ľ™”VÁęY‰<'ćűÜ;ËŃÎŰKi‡]çlĂ431 Ú¤ČsbH.„Ŕ¦të,[EĘz8|}™íJë9q‚<Î[˘¬R¬6wFp»Ň:}rL•zbçUWŞO7Đłź¤±Bń¸źYş-%DXRbn‘™3˛ÖśŐRÉĹý%cŮőĐHG’XěbĘ ¤ôN˘sçBXęôGžE¨đeâ ¦‚ćŔ„O pělY Îcň fži Č Ú  ňVÇ^d+o'žb@ĘrDDú,ÖÓÇľhŞk§úŽé: ŔĘ/ôr@Ǥ±ďĘvđ4Ĺ-ě´*§´:úFÔ^ĎŘWFčg*Hgüŕ@ Ř÷F0ýKt?0d)śÎŞˇ…Tý Âýŕîţ/:qŔîÉĄ!/ąO>- ńéN`BÖx®źä‚ó°yđŹdLP‡ŔËĐ2o$úú§H.m$UP^XđĄX¤ů ‚o1]ď1ěśĆLib(˛˘«/FQ ĘöĄ“p{ë1„ÄjŤ.WËŽţÇć-Ë,H‘_ hĺdŻpčĂŇé0¬˛ćěop Ĺ€KPZűĘ?@P ŔŢ@'4óŃLôXę)0čî’ ÚLF’@ ‚`†ncÎ knU€é m^pń»fž=ńÎUÄ`˛f°XĆňKöŃ„ŚěNęW…|Xoęřq(f QĹtóžqoćGç>>ŻŰqÄÄY/RĎ‚±|,iŔUQĎóDŕéÇ Ú>`Üy ¤˛woäXච෠jő%|€ä«ň>O8tG,÷ŕZ…’HGđĂţĹ2·m'Cý$˛NŁç´ęg î $ůŻH…:>ÜX u†âPO&ňg'c(Ę÷+’ Gţ`˛Ő&Ď;%Ű*Źe9ż¦rô`wĂśpđŢózgČ ‡c)ł&"ë% çvwD%Ín‘ pĘ8îÚĐŠšpóYÇź(ň’UŃÍĺ*S¤®_oj „fÎünŚ_2‘—kdTÇćřĄT]Ď>o-#ă'w4eŽQOürS[(ł`Kq{/#F~ŔĐQ# >&CPI 0…#ŇZK1–_ | Í2W±&ŤăžGS2ł.g˘"Ńqđ ±8me Y%Tu`îYëĹ!ëť «ęm€ë*ęě‡Ě8ŽnMä(’î{.Üpă¬"  @Ĺî îȉGαGÔíBŚř©Ľ-–8ęÄU@„Q3qCń\ů¦(&/ĺz˙†ŇnŹbłGo=í¨pďhöĎšQíügm,ď/Ż8WĄ÷5ŇŤ)·=âpń¶aG2.ľĹâüzZo,bş É?qsF@ Ôdtt `NJÓ?9ć YŁäV…·ŔAKg$ tĽw_JRÔX ‚R^0–ť&˛;’?qŇ>Ńţ¶ňD?ĺ“%gxRaÔĐ 4AMnŢňB«ZDj†0O¤WT&©ÄĹÎů 0GI¦úq”ÔřKś€“( .ôŻe2yĚcf:Pň2H†MFżőAÎl­”$¦ .Ź "‚bŞ; @<đóKĄđ@ YÄÄëîÂKôB±4MD¤ĺY˘Ž~4V ˝;†ňő˛ r^ŻÄţ ömĆ@K懏řLLŇSMV„đ˛ö* Ů[PÂGb^¦úů¦ `ž Ąc/mW`óŔë)ä‰/-'s‘ `pxR0Ć‹o˝–A0° iÝ §?RĄQG%dÔc“uaS dĎK@Ëhď…{eä^•4LR/&Ďĺ"˛\aKŽąFş‚TŮAŠw94xYu©0ő­_€A[6>ÓuŠÍ–R 4đů8‚ć™%TQÓ5d«_d>q–\őe?®ŔőŔĺf%˘>$†oö|,jő% ce”w–R%vłëď=¤U†ÝVtL@Ś„•8.bJpë ďÉhâ=4Éqż3ĹĐafňYĂÖ µ)T0°x ! ď 6gď†9E'*>Ŕ\ó@uóĽÎwňŃ9&scĆVÇ"Ç8gpĹUnN‘Lć%0/·`ŇőŚĎ,Ăę“öŮ3Łë2.t’żgn›"-–ş`ScŮ-ć0?N‹ŽÔę¶ BJ{­¨¦bRŘc| endstream endobj 64 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R >> >> endobj 66 0 obj << /Length 4144 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EŔ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; EłA˘QA„V´5 Îڑ}ÎČŁN],qˇ9lv\Ť«)nŠ †—(g‡ÇwčFCŤ>]ĹÓęEcIśëŮ ĹĂöG&¶< ŇHĚąˇrH٦ˇ’ ż°íH¶?H@" ŁĆ9 #€č4Ťăp@7ŚÁ†4ŽAHn c¨Ň:Ř7ŚaKĆ cR†!š:ÂrÔ.a’ýˇHş* H*ú@’Zš.ášęŃ1OŇ! ă`ę6ĂÂČ2;#ç,Łpč2Ĭ{şµ˛Ż3ČMŇzrHKó݆Ëcä* (@1Ë2Ü<0Ëó Ç@Lł8äĚc BŚQX@8L#(č: #Ř2ż¨pý‡3Ȩ"­#Ţ>,U3MĐ4ŚcC 4ŽĐ¬˙@Ë 0BŁťm¤ú Hć8 ňţŠUJ˘+ÄôĹ 0 B ,0ĚcĐ7ŽđđÓ>Źłđý?AŻ>ĐvŔËBâĽ13Ů–r‰P"XÖE• ÚÔu6ŤŁÜ2Vămmq·ýUŃTeëg˝îmőqÂă.Vaň‰…ÁŚ7Ńx6>7CŁ(ńcCcpĎ]Pµě?ZÍ,…›±N@‘†Řx…[c*‘€Ö2á6”EĂłŤĚă#{5SÁ”|´ő%LÎßSć\PyŚĹ[Ń9üÇqŚ(ŕ2ŕűDX3CxŰ`Ď´čAOÁP^¬Ň† Łä8 #<üěŚůdѧ˛ C˙6ÉŇkÄü†+ę@JS¶q¤ˇľĎÂËŔŽtSú´;Đ ˘<đ'H/śrď:¤f®TSÝ_1đŔÖ´m'Ěfćż`aÖ%űdăö­1ąSáŤB¶nďzÔÔ1VÍ·nŰ÷ r>ŻĽýtd:ÓaKrÝä˝ßFÓVomŘ.IÍlW1ř"h *Ř#}t1Śy•7 ¨–řßřfbfů<бŢ"Ä`+am8@p !C¶Đr Í YB1lĹĐ]ă Q‰%Š0Q#TSŚ Ţ7¸{×É-/ FµI€9Ź‘¦$G#ÖRˇŚŠ%`x¤Tb†’!‰I$”?’†v3µI¤kʇ@ÚÉřÖKe.”„BLĆC›%d…°–CAÚ2.Ĺ8đž°s-Ú˘.Ä´”Żpq/ŕŮp2& Ă™Tť%ĽtŚó2%ĚĺPI%Ä‘˛$¸Ů‘0eÔŰ1ždM)–A˘äÁ‘3bsMHË:–ŚŔ—32˨¬ ¦üó‘©˝; Ë2§p38¨ÓM:#-HSbpOG!ŕěŮś%Їźş#;hBB.Ň,Đi§Faů⣴JzJú,D)$Ť(&‚ťr—'ˇTV…„™ĺB» hĺ"Ł1UQČ=Nhĺ;'v,B dD#Ő<+©ćź¨he@9¦ŔŇ:ť%E.ôÂŁB*Cd,Ţ_ťňŢ\SÉ™.±‰Č#Ĺ đ3TF–€śAl–GĺUgb‚¸R Ťĺ"¦˘ú ¬CsqŔŐQ*@Q`ÎmxjV Đ©ňQcLPD!P Ů d,ťSöRżŘű ^ č7r(÷ŘËJ¨słÖˇ" §Á…®Tf($%–Ę­šjjS,)ú¬óěuÁ2ŽÄÜjýnÁE?°A{Äňe!Ńé©’Ęšɧ ŁÄłqĄę:I€f^ˇyMIF–­Óňúä(CŤ˝’ţÄE/ĺBĽ°öšUXŚŤetU®´Ę×/ĎabѧH¤ U¶Ž4’ŮűsěpIUČ7Ůrе}:GBÝXŕ¨_s.şe™Ôʤ‘JÍ`“P"=ŚI×)vć6 XŤŚX9¶ÉŚc*šÁ--Ĺń©Ëčä)|6ˇ%ąTRHŻű¤‚‡B=ł«=—Ú ňlŹ‘Ď'Jť|ĹvÝŮ1 _$ĘŰâG r>34$šŰ‹sŽS¦;‘©Ń+JËlx˛ÍŢźc,’KrtZĂ'źŻN¨×[ĘĹ,ó•[±“ĚG‰«JîĹěçô˘˛Ňů×čöKpqjfY:ľS“ďí‚xföm/_¦üŢOşŞ9•˙HEčĐc•QýY0ý>Ä\>,“‚©‰đµ¤ňŹKr‚oě˙ÂÄ-Î:qŻ N'L-/ ‰­ü0'š>ô]EćS„Ô-¬ĹLv nG">™‹ˇKJÍ0Żč1EÜPŚVÄ/ę"".#%–…@4.¸4ŞöőŠB˝)n CŢŻp .©t–â˘:Ëđׂô”‰‘ hé §• éŹ pŤ ŤŽ‘P‹ °Ş(0Ć_*8Ćîô)ČLyCC i„-BŞÓ0†!čLoĽčw PňâĐřÔq¤ ŕ‚a 0˘‘+ßĎ“ BFż® Ňý 1 ŕsLĎl¤Q ›2…éŚb@éŽ@ÉŠ‚/" ‡ oâ8бT–ń>ŽÉŇj@`ŻĂjQ@Ť‰âŐ‘LČi¤µQW«mBá‘eQh(V-QsJ(­ČEńŤÉ÷I©(‘â;Ń%q¤*«Şôb´‰Î'Ѝ˛bx†ńa‚P¤I%îµQÚď" Ʊ†¶Âj9©‘ =(ŤrQţţ‰H–l´$ Ż #óń×! ^ëÚç’*ßň0—䤔jžŃc#ęzçrD'’51j#č"i,'’V9ó$‚şč Ć‘RhťÉ¸?rg"’T#‰ś…{%î((ź'*© ?)¬ťŇ”™’S&…]#pëĂBĽé»Éx?QF? k+r’“‚Q+/.ŞÎ€öń|?2Î/‚@¤&rÂ=ńü‹Ö¦BŐ+Ré$Ä"÷(Ŕ/˛Đ÷S=2Ů0ÝĐ®µRÁ,MŚ2ňĺ1’®q/0Şű!S+ĹQ2“’ÉRô4ŇŇ: ý3ňę#’ŕŽŇ˙2¨Ů.ń«3Sž˛ű1ň÷0D}0“H¤$“S3h51Ó\ˇ]+ň»Ă©!p9‚Ă-ÄďéŞtň<‹łÉ҇Hju )s¤Ś±K'‰9ŠÄó9S‹b•$s®&Ëâ× k*Ď;-„ÍóĂ;«ă"SĹ;Ó2Rł=łŚ‘â˘"u:2‹9Ó†IsĽ„¨ćt9nw;rg?M˙<óAČôT27>łŇ.˛ˇ>M‚(ť<4%7˛yB4ĽJX1‚p‡"!It-JhîMÖňÂôŞI(§”3âŚňZ©#=TTďJ’»,xŁ‘u Íx¦Ó'HB?H”LŠÓ !đEn¦Ös˙IĐŮE‰jR¨ţ´pČp$DóKTdßâę÷4{ŠĽŠ}IŹ ˘ńKŽţôÖÖíłI´ĘędĄÂ;JććÎJ ´ÁG)ŢŁqŮFô‰fňGŃoOT ť5táH’HŞDQđ«NăßO4ęń‘^»3×QPŰíę9taKnâ/Ł›Kő P:–˛[S"gTË]MT4CKő("D)u;UĎŔ/ ­cBäO$yOM ¨ŤC(® ۤn" íY¦ň‹ P ÄoăÓZ­ĆÝä’ş„ şÂ´•2ż ŃŢ×u\r!˘Şă®>ŮâăX.°ňD…):ŕŞĹňÁçĆPŔ@WÄXÄ=TĐş¬ î°ČšŻÖ2…HAŕK`ÚcăłL,ľEöv& ‹fHä’<(ś-G“`k`¶2=aC÷dK3cßcKNj Xq¶1VI[dÔ±tnb=fKJě.ĆącÂ=%óĎ;fÖ€/¨j—ö‰Z6og ZÁ¶gY„qYŔmZµŻcő´ÜŚ=•´Ý68TĄ˘“­©iľş Ä ą«ł L˛6nItš˛ĚJz ‰mĹn6Ö´¬Ag T´Vňş 4łŚ@´++oë“ećlYÖÚłŕ|ö÷m$ónVŮl÷ ¶űr7 1Wnë‹s P Vër¶ás·9oW+i÷J·ć†k–ö^ëWuVŮ_ezÄ ÉoĐ tÖÝh—v,Im‹`¶WN˝ńývKJ· Ř·đvůď» Ż—ďŞÍjQ —žĽSŻy±n‚w  ¤tGÍü9¬˝ŻťzäĘ3z,…E7ĚĎ‚|’\üWş®B ç‹Ä@ŻşŞ”NĘOĆĽbŞ‚>”«ňZ,˝/˛üéú› ˝ O·€ôÍÄtŇwí|ŻÖ§ŐÖńŐÚň0őXK\Á3×KípČI~Áě"ÂiâGŞ1L4QL:Ă÷*ʋε‹smŚNĹ ĎdĄTÔż.ę›O‚ô®F)CŻAp®bʨ]ÂÎ8…ÜŻĚ•;Cô‰Ă>/{{du^ć,GB”Ç‚«KM]x«JĂ@#Ő±”&É›vVâŠä«ṟ̌"GŤ0ę6$pđŹ—·: †šĵ©fJH‘”9-Ěj™o03ůçqzŻĘŚâ˘Ť‘J)‘W’8öH7o#ČjHI.5ż/9B—N$÷ç‘Őń5y?)‚á•ö endstream endobj 67 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R /F11 68 0 R >> >> endobj 70 0 obj << /Length 4352 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h b9• S"4˘ 8‚ŤĹĐiôNĹUÄJ)RD- †ˇŢŞS“Iĺ1L˛S*IĄ1`€’N!‹«5˛,ĆAŽA†ăH„ŠI&”dâÉtC! Ć6)FZKIŃi%rŘ,źIĎä†#apßK#Óćv{YFr_1™×¦ó‘Ô]˛ńxňśĘAn©]AĄ±@Ě\6c(Xb1‹F#!ČČeŐąC)ĚĆr4ś†“y¸@o3f“¤hę4Ž„6 ăR†a@Ö9…"č¨% ŞB@äÂÎbR»Đě=cHć8 ňőŚ# Â BšĹ«‰Şľâ.!˘z†"tm Á¸pĄ5áĆ›®Á@7ŔŁ$SŚĂxä ‘I ă@9Ž’pĘ2 ď°č4DQd\/ŁHÜ1ڎľ2Ćıɸ® ’Ű"‰˘€Ş #t¸&b$ řĂ,ž1żűŽ4S4ĚĂ ËFĎĂ(Ü: ‘;ń S^ŃÎę¨Ę0ŚcCď5ŽL,•ú SMK>ŚňÜř9Ź38Đ9>Łxę9Ó4ĺ<¦HŁĽ4WĐ(Â2PŁç4ŚŁ0Ě2Śp+ë5 LŁÄŁË­*AjLĽł”踆ű¤ ătŇ1QoűmJVěˇ%ĚH´Â0ŽcŇ3ÝŇä˛űÝŐ„ 6„{śçÎwD…"*·•"Q‚L⦳xh&˘¦:žđ†nŻjŮ…ÓĚĺÁś# ´ě‡şY űÚY&M”eYf\îf9ś)q,a®2“á’Ű9Ρ…ÓĄ˛" ‡VŤăhŰ>Ë“5š:JÓ]o`m-ŽC,Jůľˇn7Şđ|Š9Ě…`2ޏËKO’…ë*Uq\Z‹ cxŘ:ŤŻµ–2m·í„čČ» gŚűU.űŽŁ áĐ»!Eź4×ř붨Ápf.6ú¶ŕ¦Ëż!n4 bč‘= +ő®Ť¶¸¨4Ťł0ÎŇÔt˛ţÜ śdá ±¬oÝzĐÔlç­ëŠ(ŻČş´ĂDTT ZÝĂ•+qşő®ůů#w—Í ßVŐŇ—aËÝČrŐ@n !±+?VşĽŐ‚ü !ŤV €ĆÝ(C ŽÁ25dŇŰrÔ@ˇЇ—.ťOˇ@/Í,đŮ’˛+ už0^lĎşO ĽíÁVŻ ÎÚP°}t‚č‘WÚĄ !•BĄŔĉŃ[ ŕ¶!7ภúXPÉń?%tJˇ]\ Á™Ő7%ŔÍ–!U}MŔűD÷ÚńO°mˇ°ůÄĆú•ĂĚR °Q;Df…]Âw€UÔđ˛?D+q*EđJĄ?J%‡HęMŞ4GO\‰˝řą IĐ]ÖAg !;‰%r%S>GĚš(m 80ź2•Ţyí^pđąPşĺwL)cŔŘßݢt6Ŕ…¶”ĺ řqrŃ>ŞŔŰ3"rĄfŞŮ˘ŃK ±1â-tĚ0v€aÎ&Čľ°Î82–é"8tNÂp/ á#ED¸ŃQóBE9á<§Ł\ ±x­łf˘ ęEkéůöPčŻ%űfmę•[J ćÖÄŮl҉3K9Îć ¬Ç^҉łÚ×Ó2VŞéZ%·dW¶C1č˛j “Š:Ďü2)ů5"™ű|˛6G˝7löNK٦ĥ$âs—SáL˛kľw›ĺ8 K=˛BŘŐŚ'M/˘™h #T}94‡ë+g„ꚓ撄yI’vĘár8QÚ7;«ú+˘a ÂĆwŢňP ­qŤ'Vr‚ŐKŁYQUüĄu˙Ąü­VMux0ŐF,ˤUěMţ5I¦¬w *»†Ú_žŁ»w$M Ô¸üdĚ€oŞľĚ‚od“Ě}(¦Ę˝!ŃĘ;©2LŁ"k' D·{ĄŽÂ>*©PÔ]“}qQ.Îĺh$ýĆ~FŔ6ćRZćŚ ˘b@€Ĺ `cĐB'Á(˛ý˛i˝˛ţ'żč¸ră\¬yO´ć©'ź¨a~ř YÖľĺ”Ńgvľ)Ęj‰‚IHn«™¨Ăň«x§……p»`°Öí}±¶kE'LXžĘŤ@Ď:‘X§ŞÂË Ó Éa vD1$…MD“5ŁĄwš{XgTJ­ŽK×!ĺℝŇĽ Á¤=+i ŐßÎVHkŻ Z” ItŞI(ŞéŔ—2Ҩ ?/¦»Q(IwˇâťĚ“«Ćq‚„ŢŚ*DÁJkYőÚ•­Sč,™‡9Ş6k;…#RX®ý ±’ţ*…‹ČJDeŘh¬ňŮŞ&qO®dĚÔałaîŁO€o “–ęcô­g`jKöţ»Q•˛̢×2š†L/˘µqłř0뮎äi“uKf zB'5şô 5-3ŐƆP𦚣ë ŰiŐ˛‰Űâľ ‘4±,⚱̲ Îȶ`ç„••ű˝ç0ĘA}mnRÁŤ°5bź‚$l Ś ;­ą]’1á Ł‹{uŠ4ś¸%Tď`@ĎvGmú^EŢ sŞ4’şHâĄsgZN„ <Ř>©Ín|•\*ŕ¶U¸$ž‘÷ç2úć$ýĚ©¶Ś) ÜOŕČ{ł[çk]Ę‘@’ťČµuMĄÚ*ˇ™])ß‹YiďĚę'ÄÁXË Jý¶nҢ:ädhÉŇŕ2d~Ý)Ëw;ř˙˝ńëĆÖń†Ş×.p%jD•/]ÉŔs›­šÎĆÚ¦đÝ˝BنŽCH°ÁŢŚg ĺŽjV 'ćý/Ĺý´GŮZxţtŠt¸:›T÷ü FĄý¶Ľź;ČóĚ<Á÷ŰTs^9TmźŘöĽÖ‚W‡yl3¦ĹôĽĆ•"A‘j@€‹pťBv(­Z»"Pt…BńÄŹ´´7>fWG•Dń/Bs:´M:đć6†ś+ÔY"˝*sÓ*ôFÔGŻ>’i8Tu)t5H#i'łŤt%t‹C„}%S• SˇF““o ôdł>Ń5S“9ÂX2”'BÄ‘ B•"-4™2łR5u 8±ADi@297˝?Gő7#•STŁRS3Q•RQH"OOAOôŻDr :ĂĚ%K$¨ý;”[0“ľ8´Ë1TĎ1µGP“s ˝UÝ ‡81@ŢBĹ2´’iU«WÄiUŁ[ŃńOđSµÍŃGTUđ%Gđ~đ/cÉŹ^ k‘q]4ŃY±®;ńYějS|âłô,Őăő=ôÓT”s@°µ–Q(ű`ŁG`ńCT5÷]sĺ[)b1ŚiUé`Őî5sűc™cT9Ő»b¶G2FK5’ËdsM!/-Ö8qÉf¶=g=ô—fóMeó+góB?öabÔ­:T°´´!”N9Ň$eŤ Lb¬Ő“?őődń%YŐK‚hö[l_fÓBÂwgBĹh‰%6ubĐkm6|:ÖŮYh“9l3+gse:2W”KiÓŻ°µm^Ö«EőŽöła5ŐkµŮ0koĺ!–ďn“C^Ö÷n-ov×47%]÷?OÓgYurä¦Ńőgtt;—WtpŘvöŐfSć]#Ź]ö,(ëánwh;pŚ"w)C“‘VřµAtÓmuS÷'sŚ(vB6wť —mx—r–×_vÉ\6Ít–ýDRD’űWâŚ*äě$¨ŢV¬(sÓ\łŮw‘Fö âŮ^—qlp“c¶-?´ÍkwOÖ˝aµlVo6's×h⣍vvŘâ¶ĺdXW›8‚¸swii6˙|5{KwČâŁh‡ÄeqŐqR§ke˛3c7•Yî+[6^1‚Ő¶avĘźtXIv߇¸wx§Q¸mhx‡9VŮ—Á(·ĹWŇâL-"˝„Ç~*Wq¶Mó€7č6×oVÇőgŚX4ř•SmŚ·»SÁ•Çt·ýy8őąuxh$fť{6ŘexŤ˘Xex~řű¸'ʏ÷X/Ž÷­xĺ…¶ąŽ¶7ůFW$¸-ůŹi’řů [g˘Í‡_.ö•pÇ ć”BŔo†f“Šň$:˛¨1“kY!‹”Yńc€‘a‚ąGw°k,6cm—U÷Š;uozW{—Ů•“WŤ4«”Ř;‰Ř?pWČčö÷{ŘN)s (óÄťRr;sĚŔÄ…<%Ŕi m°˘$…Ěe P ĄřĽŔąť$Ú.T|Ä9ônÂŞ çBłGažő\­›.*iâ« ™Ô+`[n‹.MémźŮ瞥 ˇÓÄ Ú)žĚiş Ú4\µťşśmĆNf[źÖ3Łş, h® şG˘$až:@}ÎÇFB endstream endobj 71 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 74 0 obj << /Length 4823 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E!€¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ř}IlP3@„C)ĚĆr4ś†“y¸@o3f“¤n(1ťM'AŘo1ŠFQA¬ć)Śo1§<\ŕfĆ€b…"č¨%2+S(·"sㆠPŚ&$Â9a@Ś4Śă¨ä2Ŕˇs  C(Ř0»nčć4;!Ä2ޏĘ2»Â Ň9ŽXňéĹ P ˘Âcá;pć #pČ# ÉŽc›«…Ôy6 Â9=‚`Ň7 ˇŇ K|«2®«BA›B‰"˛0Ť ˇ˛h ¸fŹ!„§! \H0e?…Ô –Ą45OHđpĐĄŞŚ÷>Ň´=1<ÓsőA,CśáD‡(дކNrĐŃu™Őˇ…^S´şÄ—¨¤ĺUˇf˘ EFÔ‰5…bXŐÍ>—†A­zţXôruhÚh…ť]ÔáŤR™ZsšµHĐôMpâ t:Čf×EÔŞ¨•ET-ĨëBč_WÍo~_đ–}#!6ő\ ŇG>¤ĘŠp Pm†ÂA”úŞáRHŻ4=lťbP–*d Ô5TăM…†ˇÂ•od¶'“ć9žX±ăą~>©AŞmšćëV… čyn=”ĘRň’b9¶MŁi´hj–gŤ2?ĺMa'Ue\ĐĄ Ĺ„µ^“ŤĹ;ŕÉ= rŃT¸\ý4)5ŮFÝëľĺş,[˝Ýx´4˙ŤíÔ•Í pAĎ ^8ą˘Ś/¸˝SxŻWNęŽrţGÄDÜU¸Đ/©E9yrýăNp<ďŽ^(ű;sň·RLu¶“CÎp|úS .ÜŁŁŮ#ťŰçŔq=Xh/¸ĄµŇl>FMmu=Î8ľDÁ®-ćv~Ąß‹z<ö9DÄÍ5«dŁź†’cL¸egü«ďĎŘwý/ÍńwňÇpŘBűhŃTe¬ěĐ9Ĺ,ĺK>Ĺęă•X0oŤY±Hú[›ësđ(âż,Ř`ˇ$~®­?—Ő ŞUŠČVpuą‘Öôúźd$đYŕB¨MÖŕ3s*Ů>Âţ°a›ž‚ đŞĂ"ű !c—‡ĘąÔČ™ !lŽ{‘–_겉rXÉOaLś“ŇB!J%)!Š$R`ʢ!#%ID•r’%Ęčß%#80(€Ů„ĘŇ.ĺě°‡˛č˙ËŮh˛¦$Ľrr Ş—‰w ĄdÎ?óBa9¤ ¦„Ç& iÄY3PŃWQŐkÎb¬#ŇÜcHm]M©×8ťĽĚšŔÝ ĆŁ=üöš«B|=d;§ěö‹3Z-°‚A9 02  âΙ›Bׄ~ˇJö†Kyż5¤$2‘oůň’‰F¤ü<Ł}vFşFi-Z ŻÉDµébÂn0˘uSůI‰…6”ňáhIf54iô5ˇÓZ Ó€eQiQ0B5QĹf˘W©x¤1™hTşĄ;޴˧„ÂbxkS–˝]ő šLÚÄčÝ‹—1…ŻQg¤XÖől‚T ‚ÍĆů>ë­rvńú¸Ę ÜýŠ á3±z°1Đ*›ě6×Ë_ÝY74«FśY#Łe*Kř&Jjq'Ň(\ĽĐPŽYň—4oRdL”5g gŤžµĄć×§«:DÁ… µ5S@uľŞÁʵVöšĐ±hŘíc•X®}Ěą+qn®3r,Śŕ«hçâC˘ąöžčÝ–crmsźv®ľâZ'Xčo%ł»ěqákËtoi“˝Oç<«·q^kÉ]7‚ë˝7ÜőŻ˝ćW×ý_7>üÉ%ďl8"ţ^¶y_ćş8@ž][ÂÇ Î/ _ŘĎ&!*©ÁK+BĽ;‰|CŽC÷=‰ŕäW48˛&Dśa cjĆçÇŇ„ń¤€Ç˛ bHli$˛=Ą‹Ű›ąňZĆĆňVYIěi)˛Lg–ŘÓ-ŕi‡01Nż#0e•ˇ7&ĹžĚWškÍ §5§2şĹ“ľsćba@qÖk¸Ď®z㬽A(ˇ“ĎK^ge°śH†sŽJűDçőˇJv¤ô“ÝlQNhý7ÎtëCT\ç§´uJŞ9†č-złˇ«>ˇ:§7”í±e}oš´‚Řýc­µ ŇsU6M;;šČëæ»UÓa]ýxŐ……ĽîştVVy|eaóy%Ű`ß[÷±6´Ż¨dż˝Z7ŻHăÚŔá|0öŔ·:ýÜËűtŞö Áőü Í%°ďÖÇ.ô5ŢexŽoťîĎ6Awßm‡€ËKŮ´Ěúî`WĂ„oýą¶YCo ×ĺç®uZHČ…ţŰ̡đP¦ˇ¸p"çČĽd±¶Â7g”c =u¸ oą]?*Ľ ž2–DŞ[·.cě…•­ÎhA™Ësçżť2†eĐąő¶ĺ,ˇ ö‡ÎQ7/éŤ s>•ÍZ«Oĺ˝EŹő–ŻŇU ek嫨'&>×›?`¶îśmř±ză(4-Bö®–ő‹‚¶)˝¸÷…\H:±éeňë\ľËÔĽ"Ťą~ą“ņRŁ{$L†;±ťjY—oČ+αr-ąRÂÄ}•)/E?­Ë4V¬µűŢí†öOL«děřŞ–S#‹an @¶Đ!?ŞC‘Áuňńł,c–@Ś0( „3†PąŞk4‡ý®*!Š )I*sIÎ*—ełřĄ‚ €‚MbF)iz˙oŕ1DÄLŹÎ8ÔX†ŔýĂN˙ŻćJcŞţĂ~r¬*ýďú`Ţ  Ú;°ý/î™äűř1@Ţ čTMo¦'uš!†: :[E/”$IJCŔA Çä˛0~ţŕ¨C€eă! 0–pś° K i pŞ€k ”K m –đÁ°ĆŚý× 0› ‘  ‰ PŮ đÝ đă Ý pë 0ż0Ý Pů p}đ‹ °×Ű 0Ë‘ P—Đ—q 0ýpÝ1- pĎ$ł°E„ł8‘ń K1Đő  nýE$T…^#(˙°¦úg÷pÇ `Zâë÷Dű0Ě `‘1Ń|"‘wQź‘ŁP»‰v/0ń‚˙±ŹqMâA±spÓ±ˇńĄLýdő1µ€cj?ń±QiQĘ1QÉńuůŃéĂ‹ű1˝Ň2qőŃAc wfš_b=P—@‘˛}r cM$E]2A1ó#Ń%$’=˛X·2@2@2@R@r@’@˛@ĐĆ"’ ńř?R$rRP˛%‡%rŹ%ŇŽM[Ň&’Ł&ŇŁ'Ł'RŁ'’˘Ä×D30`ĆbŽž‚ XbŕqQ€i+Q˛pJom€i+’޲ňâ€D i+Ďjčjkqg$±=!.qs#ń—Q\)e.ó €¦ Žňťr71Oű2ł/*ß#jŹ2“,“˛ľQ«B!ĺ{ ’J3Ş>^3E2K(QA$3(Ńů$Ó)So)“w˛˙0*J.ł81Rű M/*Ź6€Q.ł”§đ!4rů-ŇX’±.ó—6ré*Ń8’©;Rç:sś#°ĆaC"ă/s;2Ń“1÷:“Úómó=0ńů3Óu=˛S3Ó}>Ó-8ů4łN?B@PŹ€ @z!/Ôl¬)sX‚€†ýBô^#„BT3=nÓ13Ř1@ Ls,bBPđf Pj’íîec`ž"Óß3QíF´n"pÇFÂ-?AH Gô{?ŃůH” ´‰@‘OH“3Ht{4YH’eT(±FäHŔ›(”·Kó÷IôąIĄKô— ´łIÔ™K”ŁL”żJ’SK4Ż”€1”ĽQ4óHTŕQtóLÔűM4x ŞO4ßMµ NT“FęĄKŇQÓë °¦MĄşöF:Â†ŞŽ8§<×”/aSbđp†zŚ(ATG<#˘úˇ@[ĆD@TPć@.⢴âÔ15cU•h:gT¤őV<—‚čőAXçXC&îÚęEX+^$B—X¢łÎ^qµv?ěuZĄĚQ"¤l“[EUÄ5[% T%[Tc5YgŃUú1%˘fm]‰Ô´.˘.őävf0O•5\ë#Ź,—E`3˘â Őđ)VOĹjžÎfîŽÇK‚®ö±e a˘&î đ`+¤$±b&‹jd,Jbv88fů†xčęAÖ—Žöa•e6*RCdć?íacĘn%Ł“Cm`öĎm áZŘÁ6V˘¦#hDf%fvtz&lµ‚<>e&śĆv|Oö¦Ĺ(şs¶TU¶X‰v¶O䡑č,V]clugŞs”y üň܇¶ČP#'h®ö†F‚ÇFîĺć°4‚¤Ł€.Ăh@şĘd‡;k"Č,ÂĐú+ĺ=Efe,"†OP3ö4fCBCŻĆü˘ gBątw±Ót˛Y"O—C‘ß7:D“ëur7B·QRRu7ovŃýĆcu’—^.÷@śW}#‘ťw1ÍtŇSv·“wetwLwźu±ďyQ˙vő)Eé1aĹzxz¬lD›‡ŽSöĎfĽ.5o¦ü*"'|Eć˘ÝlC˘fŠű|vŔ. }·şSäţŇÖ},WäWĂbĹ~%Qµ…~¨ZO…ĘWÝ–ća·Ű€°†EZ‹«=‚8_Ă uĺt/;_ÓAxB#ďE_Ö „rrĚbŁ˘Ů8Ejd ‰n¸ hîŰWřSânRV“|ă‹€%3†Ń±‡¸:±kŃ€´ŇE€Ę ’5w‰$H €P  đÄŇMvx č"C—«ňµĂłćDÜ ¤pšnşrÝMŃ­ @qŰ«ű/Lę[ŰŚżyöd;Źs'íV;„*(Ň›ą¤ŰĄúŹC=IVB˘Ž](@źđU$;´€’;ŔčF—´Ŕ ¤z  Yłč;ŇD€ČGdz $~yĆ „ĆD„v¬=„Y p&ţ¤ĎµÔţúX!”Tńĺ^Řě2xK[ňGŕ‚D`ÂýC’DĆh8ęoT"{v÷îLT n+şącŹVUŻZyÂlu{­± 'O˛ÄN$8‡bÖk[EF Ţ €ę ŁĽJ0(JĽNőĺď¬{~O ,*.€Ś&ćżf"µĽ¨@µj^7?O!c‰ýĘíůĚ@O˘ř)\Ľ[…^BKĚb(ßśŰoÜąÍWŘ*˘ endstream endobj 75 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 77 0 obj << /Length 2626 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h d1• S"4˘ 8‚ŤĹĐiôNĹ«ŽDJ)RD- †ˇŢŞS“Iĺ1L˛S*IĄ1`€’N!‹«5˛,ĆAŽA†ăH„ŠI&”dâÉtC! Ć6)FZKIŃi%rŘ,źIĎä†#apßK#Óćv{YFr_1™×¦ó‘Ô]˛ńxňśĘAn©]AĄ±@Ě\6c(XcXŚFC‘Ë«r†S™Śäi8 &óp€ŢfÍ'!HĐ` c¨Ň:Ř7ŚaHb…X拢 ”±Ş’"H `Š„ \áhi@j) @†AĂĽ%ĘÖ& âjݏ‹Ś`† H¤>”JÖ˘)J¨Ś4Śă¬dŁCáp@& bH@1ľ Â4ŤŇŔÎű=ŁHŘ6 # Ţţ+P˘bŽĂę4\aŔpDńJPđ†©0c7“X ‹ŠH˘˘I,Ś#H(dłÎ©L× ¤45#©0p(©dZĚO]IŇ m.“Ó4ZjßF©šŐ «Š®˛!‘ň®,“°Ą‘ €Ţc>#®Ôńs}–«d©ÍŁi;µŽňŠž¦ âhoŽé‘.Âp H’Ë4DmAÁyç¨Í Ă;A¬äźjn~©fşťQ1¶k«śećQYlü3jzČÂŐ@čśłv§]DĽ÷’§Jş˛ŤŹ‚9šE͡jNŤ’č ěŚ:Ď<>vXAžŇ'}1çł*)P›ĽĚ|€áŚÍwĄ{ŕ‚¬1)éĄTć˘{5X¤—ťD¤ihgŻ"ž¶96MA‘AMŽAç–"MJĄi«§9ăÖćľCÁŁ.8´°ëĐń#ŮcÇkUÁéŐzZóÚMzĂÓ¶RCëu()ÚkY -[©c˛µĆ8yÉf]©Ř9Őé[ZŽu€´§ŹH= a 9sÍą‚@w'Jxeł´ą¤R UB“¨j¬˛É‚çN;ŢMÓh¶Ę̰a´„vŢn)ű9[ˇ(t Ş+•°Zmé­ádPUÓ1aŚÉŮ XŽÚ)Cäz÷)´vKëPzíu6ѶI{ď›ĘzEsĆđ+u˝{Qľ-3Fć†čÚA8ĆŽöĚ7ÄK%˝¸&ŤĚ®÷őŐ‚l˙^DńÝňxĂťôÖÖ ˘q]¦˘/%7× ڧŃqźvÝî¦ĚNËjî*ĂďZ}dk)ŢEj“.zeŽ«˘Aɲ*z=Ź”–µ¬Î$“1ho{y0b6ÖNV»É~Ř~¦Xĺ&«Ë+͉GĐđ”dŔŹa…ß17ĄÔľOnÜ{r(íňľ·C22!×V0ňDRđlχda%aĽ;°RVclIÁS}¤~hu``€4ĂÎym )}‚ň=Űą@vę|ł†đŽž«ŕÁ›€ňč ş° ÝݧwdÇÔy`a”6ôÎś–·Ŕw çŮÔÇŘ#bJ$9^tËŃ| AÔ3n«ş:ąUáŕ€7^Ăžý&*R»zëĎfâ yc˛ô–™N„%„ĚeĆkcž±üg¦k˝žT%žą?.FA$ăíýś«\Ăé,ˇŚ‘LtŘ‘©yę7ç2‹„±}(<ż?ë˘_ł,ţßÖ!ôÇď›ŕٞd¨GÉ»ăČwąL›bµ F?;uŮw@jŐ¦;ČăžX¦ #´;€=čÂLóĂŽ%$PŹ‚݆sďŚÔO’'˘ů‚ ´Ď¸!ďĽFL8٬üC¸c‡S«ÂyŻ®ŰďĘŤ$ĐͰ4.0F5b\üď{o€řO‰/Ú"p&sP,

    úÉç´eP2ű^%„H^O űĐŽXB‡°‚úoĚý >ýdđ„ŻŢ-cĆôŻĆ)HţŔZ‚LPâÖ˙˘č‹ŔŠŠ*ŕŚX'‘§4qGT-fzfi‘k*t ‚(ĘDŠ,cb‚e6ŘâDWüX‡Aj D‡Rź¤Zµ‘űĚÓ&\Řé€ýnrÄ|Gp°Gb® J*·ÉŔŽI$–§dśđcěŐmü>@ÜK`î@`ĐĘ@Üęd¦@ŕĆ hĘ endstream endobj 78 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 80 0 obj << /Length 1715 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E!¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v;!hµe-ŃApŇĺ âq„Ëě€l9hşApÇ)© X9¸ŕu: >¤Ü )u擝PĘv2›§3)»čd ⡰Ę1Ľ# Î&Š«|«čbč-‚#¦Ň‡ ;°ó(ä3 #¸6Ťă#¸0˝ŁĐ7Žď;̶ #ü庡p@# ă“» ÂđËĚ3Ŕâ T«Á€g 1C¸Ň: Îl06Ť#`ň@‚«qä~ °dµC# ŇřĘú<#Ň3ŤĂŘŽqĚv˘!Ŕr¶BnóŔüżo+ÎôŠqtaB´01Ć茇"Ś!lIC ™'MĐ|z©µ TŁ)ĽňĐd&KRä/»“ČţLóLÖö;®űÂý?.ŘA=JˇCč2Ň, °#Lă¬ĹE:˘ŕRޱđ@daËO4©ĽčĹ/hĘ< Łhŕ6 #0Ň2ż8Ć4 #„i^ Ĺ4$ŤŃĄîHR$ˇ…”ěA.¬*AÎŁ:ĐҡEa>MĆ7ŤĂs˙ żdîJ3 Ć2ĽŹ4\íŁ›qÖ®¨c Š"!¨d@X-]„Ś5ŰÍ!Ť3PŇ=[WWtui`ÇT`$ĚĽ6ڱp’3?Čç Ť·îO/eYcđ1I÷ŰŐ—Uń$,ŕeŢ^!h^Ś<&𫣠ž7?cf3ÂÁĹPácĄ€Č^‹cć×ðí;‚–Ű ănÂ7?ĂĚnîQ¤ĽcNXŚUőÄ •ôŚ2j÷Śčëˇ@¸ µöŢȲkc†˝$ŚÎ:$Š:k­:U°-…śz$Ć1ŽCM˝Ĺ<ă~€!Ť#R…ë!„Ě1….0P5ͰL¶¦v8´« ]–.‹˘ ”ȸ= ˘9]7ČϦ”Ps|0“®ĹoŢ9Đ`ŮÄńuŘýFB”]N9t.&h÷Řb290‰ľs4°Îsë:NÁ~ŻöŔŮj ?Ť˝ÇĽtαK4-e­ Öl–ÖX(mm;˘ŕ®vŐÚT L$·ĹĘY8n éů?DšýŇó‹PÉă$7*‚—šČG Äµ/•PĂ‚ó˛DC©”úźCŰđa Šl6‡äŚ r‡ R ŠwóN)Í|ŻĆBášBÔe’ý4&DNÚ&‡´85%›Y˘o…!Ít­¶ZŔřE,ĹŹ’ ‰5eŔĽ”Đ 4úź…ŘŞ–WA*ެ9:€j %™Š\Žm?€ÜĄAiˇ굉0"jvl0«ŕR h€4ö-6Äü4 {Ż}xŇů ©*¤Ô RŞXérOhl”đĚĆŘßÚH˝ŕ´2¨y•Ą3A~ş÷4ńiŮĆ,d:8Ć#ąLú™AújGé»]§.DŇzR o Ô6žy…XSí_áŐrÔ @C%xŚd&SJ> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 83 0 obj << /Length 6717 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h d3• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇŘ gcc(\b2‹{ă1°Ű­s†S™Śäi8 &óp€ŢfÍ'!HĐ` c¨Ň:Ř7ŚaHb…X拢 ”±Ę’"H `Š„ \ᮚ†ˇ‚ „hl'm@9 ­j`®&ŞűŠą‰ęŠCéCą´A”ŞĂHÎ:Ć 0\Ú„(đ0ŤŁ€Řö>ĎŔ!ŹSŢ; #pÎ ăě2ŚĂxä6±˘b ‹d”"I,Ś#@hâŘ1\tźÁČr-k(Ć‘AÂv˙(¬¬N¶¤)`ă‡*"Ř´¤ôc~(şČ@ŤÎë”óGˇ“äý@T!Đ´=$ň¶ˇ­ËŃóíVňŇŞ-/Lδěű=T´ô˙@ˇ•=SŐaŞÄUôu!bŘôł[LN”Üí¶[nÚjň®A°jšş*‚Ş+M.8n&«- -t®T™đs%ćîP"“Na™Tą®o©˝»ęšD ‘0k4ĽMěR¤!ÂÜ"hz+m¤Tş^šéúŚJäRZ°¦)Í0­Ńiŕ^QăU6 n%!ŁŻ^ů"?ÉßyN'×|UEw[5EăU†vţOĘŇ6ďKĺS‚#e®&_%뙤ű›†™Ę®”†kÄŻěú"´‘îúJ˝-›ä?¨ĽŤ¶Ź!ęúχ­ćhfĽµěwyßEÚ¶Ňăm› Q¶î;ž†űű_†*ZeôÍ?f†ţ_Ú Á§ę­ţ_ÇÔVÁiC,häłľJŁt)>\™5§“xÂy¸v*Ŕ\űcn=yBäĺc©cÍ‘.uüâëZî5Ž9‚R<)RPÝÖBĺrşˇ“]đ’EČ•Ś*UŃÖą¸`Ĺ•ěBt+ť·Xę!ÜVdđůŠD˘ă"˘c«©Â†GĽes+ö¸"›Ł(«ąCĎŃ =Yç®;Ŕőë·i®éBćRVxEmŁ7†”®ŰŰ}{Üď"' ÖÓ´z¤ ë±äLö–3¦‘Aý€ÖÚmŰycnPYóĘWúź{j~/Ü+?Idýšú–ďňZ?ůLQÓěi(ҰA‚, `äNîyŚG ś‚€[ńš$©)¤ąŁÜ‹Ë˛gB9 ĽťĘôY1ÝD‰Ä­¦Ě/™q˝ĐLř©5Ťşŕ‹ &xÂŮÓaŚ_ťłzw¨•i¦¬ţ6±n{ĹŘÝ>ˇŽ›đíĎ(učlöbSjÍÉ÷B§ěžtÓŽ€Ń¨ôÄ™[°&ŃţMHm ÉŰ:“ĘŔ‡‚Ýš;Ć O!§<·°Q\—zEn@;jO'› sE~–ĘIw)ź©|ł+>ŠŹ+ĺ‹ŕ—â[U)y.et˝m“Ě&ŕÉ™4R|Ńj gŔ  áÉC×2¦Ű‹˘ő˘křŻCËev ”NuWC ""‰.”:rËDśŐdŠšŔPµßë[$G1ַبA3kť-‡úÂQÖˇ ë}!ŹÄćž˝iÎ)K»jgˇ"Ţ%1o2AäÉ+6·ím.*˛aéŇZ|×äűbłv˛×=ęŹ)ßpPŐ2§U`T*Ëóş/â]\é_/  âHU|ĽPŽBk}˘µĘłŮŁČ«hâřĽóbľO‹y,mĄ«6$^ĄŤGěM⬷Â0ß"ŰgoU˙±˛_ş˙c‘FdîȨ#,­ú˝ř8±ÜĂďK$Â÷˛üŢë/ đFhőŢ»Úh]}ŁvlĆMš+NîmI5ÁpŕµČŞa#ž=´¦­@µŕ¸ęͩԙŔšŕTŚ1ĄFą×"ĄJ¸+j|´Ş2úWŐ\©-.®Whwb`{·1ťŢ"w‡LĚA…\C­×× Iú÷‡p.ł–Çđs'žv‰‘qÎg,Ď;°J…$Ř5Ih+ń3îŠZŽ nfpĚ*ŃÚBt^Ü㢦íÁ'nĘfĚw4=pĽxSFf”y5/V§Ĺö‘ÚK}i©ţ0Ô¨Ł©źkÁ¬Ą O“'@§ótĺ®ŔĘrĎ(]iiŤé“ÇO+đlĚ4~A·ąßÓ|ŤkIŮĺ-ÍžRäÍy"`QÚ;•6éî a,7.śŘ9DŞîm»FęË” ňťg*2|Ŭ$ sěĹކÂZbĚçTŢć4ö…gřsDDţ ť(ÉĎŁ|$˘ń-Ceł6‹źšŐę†HUćžĚłłh߉(č2äůż†Îş|pKqÂP‰­ľY¨°6sć tŇ "¤ąď çűŤi®xÓ9Bř6ŤO›ńŽIÎÜĆŤ\Ó©t.ťËń ;—ŃpňšqÓxÓ5Т–ŁKĎű-]čV‹Vâ·k¬Ä„!č“—Mq®˛kćş›+lGń°ęžäŢÂFěšił!Ƶ–éčä.ß'-;ٸGÚń,•v*NĽď[şćĺ­ă¸üWóűźľŐ=Ý–{öîŢeĎz›W{+÷0Ýů‘Ŕ`ďaéýey9ǡWľ´W8hžĹÁhĘ Í}wĄV®EĄţ?%çŠSŕt©óţ7»Íö˝v‚'÷~'-ŻÜëŢt !÷Ž6ť‰˝^ĆF|qב%늓˙Ĺý×Xt?˝ČŮÎQ®TţV9nŔäoô™ďřţ.č‡0˙°űú+(vÎęď¨KĐ úµr†ČÓďꏙ\ýŻ÷čJŮđEHç6ű0›Đ(Žb¨mđc0;TŁŻFŽg$˙ =É<ěćv§ čnp~Q&lˇĐť Ě0ü0ĄOÝ ¦pápÂęĎó } BÚĎQ × ĐŽżS F? ݰ˘ýĺ )˘ŔE“ +7 Ź× đ÷ )˘Ą°í Q1Ô‘ śŻ)Ł11ˇCh[éŔ°hs/úN§q,üŹöÄhT?ÍY#H6¨T$±BĎyq0§qRafăĄWá‘dXI?ń9ńq^ °e 0÷ÉŁp›Źíć$ ¢„â""ńéJ°ńUŠŇXę¨J®ÉíźBXéhmÉĐ O‹1”Tĺ0hPőĺO‰ŔR*PžřqDZ» × I­‘Ď­ €ÄÔq´›Ňç,˙’-€nçŃq"íeň ś˛5 1tž’Cr9#)±!Đ»Ş"něbEʲN˝ Ń é&ŇDš%i!2F-’zYŇUň#%˛Wňc#…]&’~‚>›q(C&ň>-’—'ÉŁ*ň…0O˛Ť(’+82˛™+1Ô ˛ŞG2Ď*&ˇ-rÇ,ň‡2Ă\*2Ŕč±ó#…dłr-Ź~YŇŮ/s/R.1G.bE%ЦýŇ8n2ËK-šP˛ˇ-3!+ Á32·1Ľt1ęí.Rń&,d„KSL)•Ó4sQ5Ňo6•ŃÇ4ók.¸üssQ©(ńç5k%!U7˙*i8ńĎ92*Ť9©í1}83w"zn3XžC8QN[s—;2A9Á#'; %%Ł:˛)4łŐ%î <ŃO(1q9ň1'Q×9“ëSoŇ=ł4Ą4s=“ŕšŇµ>sý)óż?r§sđG4#séB’S@S>™ĺ17ňď& BňÉ/”.˛×BtM?QODsDSu3ŇY.‘í4”AA%0”˛S6sýGt%?Ôq?«%H"Y:Q“+ŇéCÔi=ô/3”só-Aôˇ<´'IÔ…ô­H´5F3@łIbOńŰ5B LQË-fd†Óe6ń52ˇLÔÝ=4a)}4TżĂMłˇTŕ¨R˙M29Ôôy2˙Oµ C4ç:•LËPbŰ;uš3˝EµRroPµMő=;Nň‹FTíCóßPÓ˙µHÄqĎSsPRy@ŐQÓůKUOë@Ó§Q•_+4#O2yB´CV|n5AqÇT•‰VU=7µgSőxśYŤM‡ZPű-uIYăYHŃĺQ“CVÔŹV•r­2Y©­GÔ-QŐÍWńPµH”Yu•.µ“AIJŐČQ4ŁR‘'<µTŻ3Ë^ł'[R»V•»^t@;‘YN1‰a*!ZÖcÔ×fA7)±aQ6Ő‘TLéCµCIn PĆUAbő aäKdó‡!–-ó‰ô·N– cKăd±OS›fÉ­RŐ‹d6ybVCgYeµ3NV ŕ¶9[Ő·V–‰&hQiłóö&ž]jvśYÖˇT¶ŤfĂ^Ůk5P–tźŐjŇĄMöCXöIm5}`Sy=–˝`öĆłtÉl˛TSjVC[Yk6ů]öŹct˝k§ng%dvýeTWqI­]Öł]ÖÝ:Öá^Wť× ^ÖÖ˛Uó&öĚ2µ˙d4łs4±`6cQWľ"ŐLp±u4Ďb a'ŕkb6Iv0UYaVan6‘pv=u›eđvôýu×ie—^š7o·…Pö·w¶»tëűyuur›g÷gRS&;’›hW•{wIwWr©ůzSřP—ĄU±xéÁ} Ń{U[b·É@#=tA|}WW©W·‰Ií}ÉÁmBÓ)¶Ő~sÝ|7śŠwĄ[Í€RĎÔ·Ő\¸4_z IT`÷ĄH8·Ť)µÓÔoe70÷K[,ť×Ąs_w÷2X^®·ł…wż…2%w3=ň.$±nQ˛úi{ ˛ő*8y¸vĺHő€”Cm,X†G‘;‰/ŐQ?Šł(˙¸Ą0¸Ł‹™Cxo|X †É®ř~¨j ŘŃ0RŞcîgr/ŤŘ—„ö rw` O#w`dŘŮŹ¸÷'hKŹX‘Ź9c8ďŚ9ŚhJاŹ.'HwM8ÓŤą‹A’9‡7Fy9xâ5‹9”˛˘3 †ŮES¸ĹI6;“óvĎŹ™Y‹Rl™+–™qŽ9k[8éY‡5“Őo\âÁxÍŽ's¸Ű™yv†Ů‘Ť9ŹŤů7ą…~ĎÝ>Źą´‹S_ .~ °âśĆĚ*©Ś!)J$ĂBmŻ`*Ż:ďĎBąçîôŻDő ¦×-ŕ˦äŇ×q4w©ńâ‰-ş„âH•>*(ş~ ćŢ2¤ćŢ<ôKťŕ†n«J6‚ä(â@w¨p¸Gßţ"Öb×â‚Jž.Ş~săk¦‰’MÄႛ†GVäŤ&PMľÄ6Ęş‰±¬"[ř[qZa%“ëđ cYî›`ŹBŽ$Ţň žö˙§WďĆA®Ú`UpŠžĂüc§.›îż>ů žě%žÍÖčô°ş3ÜÂú[ç žđ¬öżCĄ8±ďůôę승J;{ŰőĄËő>őđ˙Möcj„¨Ťńʇ÷Gńůă+ěSř A÷ź#ňp‰÷ż%±óHó|e`ě-ľě$_K#+ô„7ż ö0źűµaŁH#ö鬟ĺťüąößÓđ_Čžźłř)˘žĄťţË _,ŠßëńßđžßůwÖ˘.Ťâ`4h9 †(Ô`4D`°x€Ô\9‡"(¤S”AĄ˛čŔ@dśAŁČŘ`5J&‘‘Ě&g91›A±qpŘkD"pAň †Đ¨‘ř=& †0*5&¤3ŞÓ±Ă{Ý %EŻŚĆ× ¸eZ$Ěő´iśÍiFŐ\ţ§'Ťę±[ ^iR¦ě†í®ď7˝ŔÔîřŃⵯľădRI4˘U,—b&3™¨ćn9ë'sŮŤÔ@3F/ÔVĹäĆÔ1C:ŢÁZöűň–«·ÝUŃÚmyüâú˝ďóčő°ščúŔČŰf­>ˇ“}ĽO‚§ Żtő†”-0ÓŃ 2Ś|A¶LCĐή,3-. +żÉ€\łłq‹đ¸±ł\üE1{fČBŃódÜÂĎTÇH“Ű#ÇňT[$2L»Ă!łaڦôĘ.ő80«Ă¤;’üL(;š’¤éJV–ĄîŞh™¦ÉÄŕî§ĎôŐĽŇÄđúĽěSŹ=jË@BoęÚëöąPč+Ź -0P+̧BÁ4ŔlÂsÄ˙NSŇý3 Ăt}+ ĂóűBřDuZ1Dő;E•ť[Ńď}ĂW!eAÄMkÁ`V’$_Ô1‹_Őź?ŮÍ• ŤŘµlŻBYM•°öĎŤäľ˝%Ń·jÚJüÇb\ÉĐçÍn”Ü™N›˛íήű?Ň*:?Z¨t'~ ˇlĐŐ0A௭„T5âŔűŕAş<őŇx ÁXľĘk-ÄőÓčŢ?Q08MSäď­U‘ŰŤĺŃ6`ŕ4µ¶Gš×­>"X{Lđ,µeałů%—šd Ý™•Zr^GŚYú~ś±ÖćqĄ4ş˝Üu»oäÚ‹Śäh;ż4%Í@;„kŁ6ş—‹­9;S˘xÜ. _{ĚľEŚĄŮ5nšaąş÷¦ď«J{âăĽkaK]iŇčMś<ßş;šuĽZ›Řsľô:ź'Á9śľßÍ^ÝçĎĄě€Ŕńď+frʇ ĚÝű—_şŢ»ŔiöĘ7‡âő;GWÂő˝ýĺŕńŹOă »Ŕqęy\łťć÷ÜGĎnÝY#~®ýňď~ÔĎćw»Źżč|>–t}/éäňżgą÷s|Jq~N1 ;WHäC"}OčľŐÜűÜăŠv'p¤1§']ą©qĎ®żČ˙ź‹|lőęAgŽBëµNňşçă‘H=b aD …N9Ř]—㎆kěö>hRĺÉq2m®±ď@řNęč1EŤ<ćôäÓ4Tp TŇľ—'Ś4\ŠIőÇEx†ŢâńŢ#j3"çTIT Ľ# b fĄĐ¬C¶]Č5;FŤÇCbcˇ<:`ÄÇ`ĆIA@0JŕĚ‚ÓRA@1.‚€j TH8‘ň`“pP ¤””42nLI©8 BčT D´ŇŞZŽĐT’:HJi'%A¸(’R˛LIůC$ĺ$Ľ•ÖMĚ%ĺt°ˇ86¨ŰŹ á{°9˙»Ĺ Ěp5*±©É¤ŘJxŽ›ćśŹ,çMpg6`ô-‚'už•˘ĘŢçLBĺŇzÎ4şöÉ,ěťĐîMŘ|~HĚD"HŐżCiÄŕhI¤`4€€ endstream endobj 84 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 86 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E! ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 87 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 89 0 obj << /Length 293 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h d5• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨Ť»mÖŠ5đÇo ]9Ał™…r‹_śŚ¨Čj’2Č8×)EľĄQ .xŔh¶‘ٵűąăůŞC7›M¦qćö1Ŕj endstream endobj 90 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 93 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E!°¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 94 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 96 0 obj << /Length 3713 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h d7• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyĚP\4žĂ8܉Lxg™ĄT®ŐRˇ„Äl2Ű,bဆo6›L&ă!Ď:žC'ţ‘ʶR0ÚĘ-ő^˙‡ĆdóéĂĚ÷l&â#č7Ś+δ¸é(@¸żđ Ş#ŁpĆ: #xÜó…Şö¨°`pµAĐ``+ę ¶!€R†Á¨f B$Vʇ@®)EjnŠŔZцQŕmČŕk"á„xHŚ‚"rlžJQŕc*‘Pş* Jâjݧ!hb…É,1$áşÖ*@Jb©D‰şď‹@b.1Xb"‘ŕŇ9Ž`Â<„xś‰â0ŚËrěöą†nLŘ‚¸îz¦Äń%5‡3´Hö…! aNĹSŘg…áMMĘôh)Ş™6Ňębî ¨ä7aÂ6 É?Đ4A X㕎3 Ě0Ňň Ł€Ëh Ă ŮB ă3ÎM $XtB B ,2 # Ăd ö¨Ë]×áçu¨ćĹ«ODś,Ş„Ę),Â’ůÎ-1;QĚ>PÔd¸ŠSa‡Şćb®ť3„…© m†QAę( ă˝ŢŽcígŚé ěŽăHč4^W Ň1ŘCŇ;;0´đaŇíüől˘ĹÓZ—‹DjüćNˇ”ń=O’P‰b\kőÔ9™gŔŐuR(e&¤”°©ŐAŽÔš ^¤V;5iµşU¸§i cHĚ4ڵíĘ‹ ›@1ŤăĺŔ޵†7eŁ ŢŁ…¤9 Ł}çmÁj@dc3n/§*Ľ(Üě΢ž&†Ĺ—akđ­Ă!¨\ĹĽěÓ5îú|ęęsŞ c.ş( #;˛ Ś'9ĽŰiHRPѵm›tU¸NĎlµ‡öĘ*Ëđ¨Á›V·Ź–—Ľ.Që[ůVE¶‹Ž~É©ß:úôüŢšPúSy/^®Šą0 $ě¬řóÍyęőņtţ{ł®ŐŰ»”Đ K«ÖRĄŐ¶'UTÚR LTÉŕžĐfÂÔÓßK®}Ű…ř“s;á°:†ĐÜcÎp*ő:ş×ěšž22¨˝â‡H ě`AqňA„ôk‡ ńQ ¶"Lałşsî…‰—DäUC `‚ Áx2†Ś%}5C‡GÓ (°µá… ËZŇé^Ě*06Ö¨sä3‘ \i#äL+’0˘Ic$_ę0Źç”33˛˘Řld¬±šČ ćÂUtqw̤BBűS‹*—ôô Š G)8•ÜĽorëĄ ˇpZçÁŠ5čGčŇ[’ÜsÎ"p‚zŮŹ8úC ë:‡@á9_ś AÜ0‡ ČÔĺK·CŽéo)9`élĚsŠrNiĐť\[<AĚ2ż‡h™ĚóMŽG†ˇÔJ‹LRoK´źZÚcŞśO@Ő×ĆBÍÉĆWH‰ÂE f9‘őY7ĺŕB ˛‘çĽdf¬U$Ě Î$ńĆĺ%[ş•ĘM‚Đäę Łâ} ěę Qú0HaEe«§idd’{`Řś„mSÍP]MČťŻ¶ĐßéIj¬ Ą±v2U%‚:u}™8…TAfG‚»Ö5ó4u R` 1/eÚäť…!Š0iýĆŚQayń:2Ŕš·Š‹,“¨7Ź…MH AčýQŞgÁV5@dÜ^§ŞČ˛®¤ś- cE€ÉŁŮŮ8‘x·čđ7)UŠDőtLQK® 0ŕÖ:Ő îr…ÍIííĘę{ÇmP`ü!:IľX>öťAĹIIOě!86“clŞÍJB….¦HˇSŠy˘ĄDÜUX(U7ĺV°ő`¬¨kěşV‚[ łč]qj !`ćHpuá…čÎjÓ—2iĆKń™2Ó±6‚äE8{ăLW ŠôűáÂĆ[( ź ­VrÎ×|ýśń: Xkg´w®s,ďN0ß9qÜéq3˛wPbĄspôŢ;Óó#Ďć»@- ™: \w€]đ(7‰â3fpÓŁÄ<‡˘aăÚ8ć‰b@4 lwŁbçŁÁăĘ<âfKă ˘ä9‚Ę9bQnc"ŕ.DĆc%n:Ł®;'¦ Ç ^ezöOŃz^Ŕʶbfi:ćâü ‰p2÷ J} n®P†éĽ `’rŚVWČ´  ÄYí*‡ĺ˛`0Ŕ¤ŕ®0ÄęF# Fç\rCΤ§ÚTë  $ Z® N°şk l, Ĺ~;‰|ć ŕqflY  đŘ@ę¤vÂ"L`r»DD4*ćÁ°ŕ ĐŐ Ż@ĄĄ ćşY0ć1X Ć”@Ć qĂn¤[°Ľę©đYźĹâB€Ú”…~éøčĺŢ ©Ô Ł ]qXý@Ćn Ü'Ś;ȶÄçćx¬hĂMPęl<(&<ńę4#*.Iq!RL-·)rB(Çq!ÂD€l QD6˛@5˛­)RO cq+®(Ău!ăBëâM$˛Ë-R%ŇÎ7š(ră,ÂĐhň©#˘P¶’H7ĂZ4 dCRÔ:.R·- -BĹ)r(+Ę,r˘™$É0b“2RÚ5Â$Îâ+";‚J3'ţD‚ç! Z-Ł3!'5˛""'3bu2pw02`"`j C0"M)b: BE7RÇsp5©“0Ób&˘E8˛8R1R7˛9Ň9“sóx"’-2ë:Zëň8ň;Ó—6ň‰Rg:ó|Uŕi<ňż5c9PvTró4g;¤GAÓB´{DôCT$ôBÔHs»CôOHôô”%Ĺ##rNúóĂDÓÚ)#%pg%ŁŃ&'÷&"†•±÷C˘N ĽOË&¸CäCâÖ÷,‚i«ˇ(Ö¦D~ÂŚý’Ś&+hěŮJÓůP“KTU@´Şb´L’—P˛ýJTQ3ĂR2ť=Ó»HµQT+SAźS3ĂSő;Kc‚&”˝&汨”zc*-P0Ľ$If^É ŻâĆ[ÄБ϶Ć)®›%ňMRLâM. äĆ% Q ŰVÂŰN"úîĆF TĄ…ółÍ,rŘ7«)sąJT±, $T§¬ăÓ*ÄÉ$ăŤd3F-ĘŕŮLVë>k+‘PŢß.¨ŚŞŢ6Ç BŞćÇ4;.ZŤ`Đ‹¦ ®që‚ůbkˇg'.€ Ć h‡h€ ÎciČČ}«ťh˘®-ĹomVŘz f(¸‚19l ^ŽË˛ÇÚ‘ë ĹQŢ]®N ®S +¦ć‘č&" endstream endobj 97 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 99 0 obj << /Length 4883 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E!Ŕ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ŕÝ ¸`0ĘjKb§8@ !›Í¦Ó ¸Čs‹FSP]. ĆP.¨ÔR]* ·Ř‡éšĂ‘¶‹ÔĽČ0@" #ŕ6 #Č@'‰Áxž#Íó"µ2‹r(‹’ Ă/¸‡đP* (@1»N㼠Ăxä1ŚŁ@0Ť`@2@°<|x:ŽCp@7ČQt†3 Íëż,Ëň˝ŻĐlµ9m+ ¶1!@¤Šđ’ĐÉ­‹pZęĽh0Zľ†ˇ“ú*ŠłśÓKk¦ †rĽKB#›!@®)UăHč4o:á˘čúHÉĂń.kźŤ@öW§ę:śgŰĘ9FCćîďşo{ߎIŃĺ’^Ľľą.TÚ˘.T˝ÇPPČ:ŽVUÚjCź‡;ŰĽ†9 ťŘ]Ź#pÂ6Ť#»t/ˇŽÁ6]ŽpińÁGe§ :‡şŚž1Ý í9Đş7JČ©°dŚ™”7ö~á’[~«Ž¤TĐ+ę A±Ą"€ŘChn®„9´ŕćĂoF݉#ĂŃ8h€A•%šCzQC&ťśśó(–RÚ]Ii}ÄÉziMo=7šsśÓ¨-Nŕĺ<§µŽź”-P@ÝB(e$¨ÔdRQĘH¨…8ĄŁTJqOF•AÔ"ĄYŠ˘"”EX«“B±~ŠáC«V°‰¸5 ö>¸°Q d‘(f" AŤRH€‚¦bř6’ѶJI¤äŇta¦EˇR t$&=&ĐP5RŃ qJc0ŘS‹®Jďä†Îésĺ@€1:#Á-rb‘Ŕą(Ĺ*Ia‰ŞŢKI2m äĽ}ZňnmM‰6ĺüZ1icĆZ¤zh[2ĺ+tĘ]AÍM–ÄXn@ŹĘÖ ±Ć’iP (Ô9ô đ7#‘ňyjÂ%®úݍ07ŠŠ…~‰JŞŹě¬ˇ«f$¨–eڤ*Z2äĹFcÍ źôÄ.őŹKč*jWŠećÉŞ)Ř|¶bHlűłS^Ń€N&Ž¶Ă®Ă+' ˝§O'j÷§¬¶flĹ1TÔg–Éç–PU˘XŠZ FMČ2´$zéť@fAA„Bč`˙j|Ç2-ćÍ `”ęŕe!Ô4‡diY=g­¤‰Wţ‹0M U†4`÷ś›y}í~†šWĺW٠޶ ‚_8A J˝†–¤Đ¦+' á™ŇŮ”wfŮ#¬~ Áů  E… Ô,p‘„Ć5!„ŁFŤQ~6)đ‰'Ő BqŐ¶*×áCZ´VŘ`«Ą°–ĹW‹HBů(AI7Ę„ą-Žcô„_łbŤ>h9źŇ@ýd’@UXÉ+DŘâ­V0N˛¤±?@Ď(•UÍ•R‘$Ů-%<şXäqRĘŮ‚ŞÂ–µrá?Í 7ćtp SĚŮČ ¨,ÁŹsb×(™—8äňĆzĺFeĘóřÓgý X‰z˙myëE“ =ťsކŇ(gLiS’^łÖŹ*µ_?éŕlN4&g(9HŠđ@E‰9ŔÔŹ*ÂIG‹€8*g¸'r@Ô‹Q"DSW•ĄŽut¦z:cQf‰˛sľĎΨsű¬ęÁ& clgÄ™µÜfJ>s«né˘ †§ťD™cĘ…«•76F+LŐ±•âa“7®MÄ€™e“>GrĂĚ3ďËofMţI×!üxćâ§@8FěáÜ ü•\ńťx†wÎś?†o­8ÎěĎŮhqÝGŁy'Ńš'Šmí%Ć9V–Ň|·siţaÄI†śăśWCę~AĚu'$äŮŁVP=‹¬H{÷CŰ[ČůS®Ěe×á—`”VeŃö?7Ú;#šqíĄŇyÂÇÔtŞín’RŠio[´o¦ÁŰ7/'=Ăxî‚Ć;1ÝÝßj3UXÚňÖKá˙0^ýŇŠź‚ź~#sw嫿:ľ°DÉ%MěňŃę ]”¸{źKÚ}Çŕ5OżÚH§Ĺ÷\z»ç_IŢ÷gÍ*j'„qj í>>wúţäőńď·ć=˙Ú8? ęć„§óżěü˙OáćŹKďľýţcˇęĽŹ}·‡›É„Ţue¬Ú®"mtŕ,Ŕ8 °ËĎ2pĚp"mÂᯊZăBâP#î<ăpb ěĐäp2ÎđA®\ĺBĺp ÍFŇâ§O7'MçPNç.ÇŽjç̵ÉýPcĎěfM\ô"Zâ”MNš×. ×¬´Ř^ŘObŘÍ—°>ną˝đx>pµB^ěĹ®öÎÔľŔpJ,Ľ?°Âď)Ő .ę"ä[ ŘďKě­Ľf®Äň6”ŁňŽţă&/âB'ëb´ôB&llę"‚pąÉWMf´n¨%âĘY¨ŠŁę§†(/ŤČ~j„ĄŁĚ"°…K¦ śę˘UJŞ8j¦źj8Ýçđ4cJ‘ę¸gŞľhV¸GRiJŘ˝Änł€@¶äOB˛gâ~hÝŞ¸ş§Ľ|äHiˤ„+’˛LeHP  Ú° ~ DT+ÄuÉô Ę 'ŚG€Ó'J±K‹„¤d ČR §J„¦O„dG«duÂl«‡Fç4zŃ€¶ńśn$dtJÄ­ Ţ{ŔŇfśE©‡±Ô¶Ml¬ŕÎ '¶E܆T ŢnK«"H€ŘAQú¶Ă d "J´ťĂĆĄ26|@ćG ŕtDt‘ěkşąú‚ ‚J1Jă ëĐpD‰#€Ý#Ćĺ$¨b†`Čľ îň˘&,Űj˛‡ÄâKD¸żČŠLcŠŻ 4Ŕś]éDŠLÁlOĺÖşĂČÂŚČČĂÉ&Se“ 4P‰9/ >ĂĚDމLŽĚM,¨ö„ÎČ)SÇF‘ŞI-.i@’ČĘ *’ED”)0“©¸“),“ó30*rUCšŽĺĐmc@yŇŃ2…(%#/s4É-/HĆ2ű5ĺ…6LDZě3\JcNyňş;(?¤–9˘(•g‚‡č’ËŔ®LF”Ó)o2Äč”Ĺ"–ĹhžW¨˘Ć3ľX“Ă1<¬D‚EqbN)iČbÔÄ‘ďG?Ń?; „ ŁbPďH›cÂ#˘(K@Š l”t\îoV/bEFlUKłÓ=“HżéĆ3)ÇD0Ö”F[eş[ä%?‚Ô•…Ö×MŞJ­&lb~‡\ŕóRಷgÄ=%ţ5L-Q˛;±î†FN`ó&±± çNR}‹µĂŠ`zMćv1KteEĽH$hHujp ŇH‡Ç çş©'Î[‘‡…%g”ÄĺŐSĂJőq–· ŕ[ËP ˛iŐD`•L=uR´$d „o|t Ć Ć•t_çđM©tá [9OI‘ÎiËHŻ’b° č7 ĐĆxĆŠ r ŞĘ¬«áCsLmlń;G˛ş4ăE€b‘0(MG`1@’|+r[džfÎ ŇdµKY+©:&•Ş]'^Ä­"†¬s¶ZFŕ䯧vkŕ\¤ˇbŐđ‰ŠîzJNsúÁHi5d§tdË~j¶adeAL D…C@Ť>¤,' D6@1JBS52–ĂśWu:M٦hg:pĹřLâ”4Ő&y•yg ô«–zj6€`ÜmÄ$™íĐ™ČňšGŁWă¦XB:‹–ž) PÄ\ćJhV­–c(öş˘¶żâô4Îl©^–6Đ2VÖ-VËmčJ öZ”dÎ:Ą'9•w^«f—g§gö¦2Á:‘óThăA„B8ŮŻl˛ŠJGNiQ}YDڵd’k©™hµ)[ ¦qČřLv›qâ˘aH‰Fˇj`4%q¶śŠÉ4z×ah‚!xjěɇóɉ ČdF@ŕ…FJtDjV¦„«#·ŕGwŤWUŻoR¸%őZ(/b3K@cŞ=W #ö.•ŔĄNôóm%U‚ŕd47<宫—ž}§fu\hub[ŃäDÇ8¸ Üt@ŇF€ŇQ·$ŔĐy*ćÄőč—óŁ_e@Î}DlHŃú Db©8$h6‡{7ęM7vň){÷Ů|WßâJ çË|ó±8tiŠ÷×|7ÝRŔĘ|Uš‰FČŤÎčőbĂöÜBźŽNy ďţňNg+0ĹŹLę% Ě ĎÇŹŤĹLÁ őMř˙ ą ‚§‘ =y BF(™.Ď fě´Y)“BA’Ć‚»ůí9DL™?“Bo“ŤÄ~ů[•B^ôQ“ůJ'YiŹůd$ń“yn)Ů{•-âč± c°ä$™\3˘@ő t•n˘×Ń$ő ­’y šą//ŽŇó/{YéŮl$‚L Ě˘BX,j [Đ'O2"Ú*ĄXí­híąË‘ăřŰŘâôNY—yźŹ ťQ^!ít΢ľ Çď–ą cAş!ŕoŻ*&Yö*8éźú,ÜСcŻ%Źő9śş:áú m†ô´/ŤfÍôîť™ĄĐÖ.Đśßy¦Öüáú#şB3ěé"Qú?cş~äšG‘:†3ús›şŽ!ú{‘+ť¨Ucşź¨ŞMQ©cťÚ§§…±žY“ú‘ZEŞşĹ«Ď:ąą%‘ú’®1¨ą#’ÚÍ”Ú×­/“ĆmŞ3"äá”:ńˇą_ŻúšđŮG“z۰şěăĎ-Ž)¨ü ŰŰÚ7¦ă>JúAŹo2˙ąŐ©`i˛Ú…{3źZżF" ś»G´/®»H'ZÜúoó“9űł»J#šńµ ő”îAłŰp÷;_•po¶[Y•Źť·ąf3®1łŮsµŰ5–yµy€#Űyąb ‚+¤ůŹF-™z[ nĄš8đö ‰¦Ů±˛»fó/•¸šĄ›űť˝/i˝$[©LŁľ:Ťľ離Dź{ď‘,zîpĺżďb«·N2­AL|$nöó+đ$ŔPA€@ő"m‚˘ÄçJ‰\_W~UTöZ°×ŁŞF‹öNe„–+h’ÉÂł$©hkÔŻ0đĹčđ%+ŞĽEĂ!ŤŰ…ŞŰP´ŐÎ,2pöí/8"|ă±BeÍń?/ďXîÜůŠZçă8÷‚–×q őŰż¦˘´> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R >> >> endobj 102 0 obj << /Length 4492 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h d9• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·n71…~î[ Ăapf2v†#H¶Ň1 {71€†o6›L&ă!ĚR]* ´‰+řćĄ!˸詋»Öî¸ä4Ž(@" #ŕ6 #Ě0Ž ®&ŞűŠą=(bŠŃ Bá”é.A€g.ʨ¨4B!Ćř>O @0Ť`Ţ;Žač4AÂh *ČCz#ÁˇT1A’Ţ3$1 +JZ¤-PŘ:«\b #pé%HppÉÂp¬«+„‚&…Áž7 ptÓ7Ă(<‚;ÉhÜCb U:‘„ =Ćă`ę6ŤŃŘČ2C(ç ĆŁë3ľC Ň1Çd-2Śt¨Ú2ĚĂ(Č CÍ C®KJo!Ü…H5@Â1 ”µo"ČňL—AĂhę6SÁhî7ŽU\­ Őę¬o3LٍŢ:Žu,‡*JËn«Á¸Ž¦°#¨ŻŞ@¤ŠđŰ„›,k´ɬ¶“މĽż®Šě!ĘŞ÷Pň†čřP+ŠO(p˘ nň˘i†Řpâ!®)bâ iŤc‚ gŹâŘe’b/$·b8đý&pëŘa´U{†·Č©}ßÎa~Ć.Ć\ŇÁ€Qنř††ÁČbab’ÁA⨠ľďʸá¬K"oűB†—YŞ®Ň‹8ŚŁ WBP¤,"J÷rixCń*z†D‘2 žĆ „Z-Đ4gĆď‹çUÔ1ü=ČŇDÎR»”ťVJ!§>K Ú{ąî…ö±çĐ0Ě9>ü«6nÝă9Ąc}AO ôŚ$2ŚcHĚ4ŐUd-ĐËRä}Q­ËQ´}#ąR”´ÇÇaŕ0ŚđwˇJŇó¬ď<őÖ‰CLĄĘŞV1NŮ2H<ČČĂQ}HR^Ť/?GtŰá Ső \–_!L*‡LŠ ©2¨AŞ­V‘5lŃŞşWŠůĘ,.ű‰ ÇY+EˇWÖ˛Ök˛Zjx7-e°¶ŰŁ$ŔÍ‚<„ZůźXAJŞ<6ˇh0ŤCpeUO4źTPŔeTHě3 Đäë”h-… {ĄŘ\úŢső{Ša ‡0ʨFY‰V+†Ň™†ŠČ8§P¸ŇÂŕ);§|FpÇVŮ[\ ’9‘C¸ ‰™EkńtUÖ»RĘďCÇIyŻXRę^L Ş0žÁËa )†0ć Ä™C!c ´±¶;&X‹#“’y“JĘĺ%hěŔ"3&ĽÍ[ă8gR|H¨"Ë©×ilQ„´¦ži.4`ÉŞ ŠB#YkmušŮbŘŹë€lÄ‹rPYÚEEú!;Ŕč&@CoLٰ˘ţç2;ć­s fňŃ’¸FČáę&PěCtriĚD'řî\ňT *\4†pÜ©Ó4K‰Żź›Ç.J¨bŠáŢ)ÖÝSsâvdYćżG¶ô•óʎE!ŇÂçPúâ°gˇ}J™ďÖ¸t l9§P’¤Cziđ€úż řćčc”ڱĐľЧ€(ś3ÍÇ#Ą@î’tá…J‚Ůí>&ú{Y’|PAJbTVĚMt JŇŞ ĄîyMÓ9ľ,aźˇ:»ĐÜÝsÜ.ˇ—r”t.GŤőżÜďĂ8uSţś%@’Ţśß d†Đß]ę;Rá”6«ŔóVbŃ@ĄV®!ż\Ł ÔĹF@]hT+…´5ĂÖb«MŐ-śI–Ľ?ćóÔśSxDLĂthĂBB !­KTHťm+"b@ɵđ‹W`ŞHP2Ţ9čŽű®íM¨Yń(JÄň\Cë ĎÉ$]uUĎŃŰ€ý˘´Uńß<ÉhźZeµV±J”k_@ls[ĺ&;cµ5ĘZç_Ë©v7¦ŔNW‘ČĚńź:v†]dmJ‘ě)0pZÂXĽ•¬<±&ËŮHD“ru’±ě`Če4b,ꞦX%^1•Ó6r’äÎYÜäŰ ­*\Đ`Ě Í–€dÎËhŇf"Ң&`rK$çůjZžńO! ťŁţ?ĆÇFĐp©$Öáią ľ…6ńˇ"ćnp,Ç*ÂŚťÍ`Í–u)âq‰čGDj[‚rń~›ÇĂ*- «€ÎR˛Y©¤`€k…‡ÖXĹ $&  đA€ňŤ*Ľ˛i“'«x¦ÉľF ěG€Ó¨¶O`¦¬€g a‹Îpěś6^}hÎ *úžč† ëö±hHŻ `“0rTC Ęr “ „˛ŃÇM"%Ěë¤/ 8ÂŇÍ zę 3Ä-4 đŠîK4ŕRN¤fAÓ23.‹ŕŘU– OU'ŢX›óĐź€¤n&ćvÜoˇ2˘ć”Ëg0ŔÄÔvFAŐŔI¦čĽd.O¶`>Ф«ˇ]s˛ Ĺ´&éä˛Ę¸"60«ä2BÍ4SÖ3^µî©µň>ÓkX‡R ČÁTµëfĂƤ}uěŻsŹM ů^ĹWg¶ÖSKň‰äŠ&ä¬'Ek µ4ż„R č±E"räöŁçî¸Ĺ>ą*¦H3_6+ŚU(.•4OvK[uş ŐľI–!_" vÓq…hÄ"°V+L ĚÓJú złtäuÄ|sG>»""H–ţźŠ4L¶)XdĆ *ľżgzwňye†s$vŔĄ*żh‚ † ŕYç3v¬+hHd W„Ę kş keŽ7‚Óč+ω>í%Hü²,ÂéĂQ«D@i@É$Äô).ĹńŮBÜ”$Ć4(d´,Ć40”Ť.f49l–‰D#m4H´M̦> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 105 0 obj << /Length 4775 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E1€¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v;!uąC8°Î¸9h±B­öFŐ”·_F[V‰V gšŚQěe7Aü'CA”@R2L‚iĽČi3Ds‘¤éć6űŚ» »ä1ŤăhÚţŚŽjŻ©şŘ먠r¶5!@Ţň Ł@ň?Ż;Ň2ďŁěóč0„#`2ކ7Ť¨Úđ# Č9 Łç@\AÄě)ŔoÄóŁĘ27¬{"É­ŽŠô’3.Ôv‡¦‰d/ŕkHH2-…¤ŔEP 7 ‘¸Z°`Ě®Ę .s‚ě†Hş* @hŠł*îŔd"H‚,Ś#@hâě/0S2˘/-2 i4ŕ˘% i9…ÁÍDťSk‹BUrÔŞŠ32#t}(”´4ťBŇĚÍ2H.ČjІ®B–ť!ŠŕíXB–ض=~‡†ęPaQŮ˝gOZ3¨±Ő¨3 N"(˝_XŇĄ.„ÖőĘ]†JěvÇÓ’µSWux†2Í©AĹž_)ú ~×őO^Ői…íx8BÄ1µmXQ×-%KÝ2ĄÖ“bW+Yâëž3sݢô¦GÁ¨lŹ$”ÖLĄá—‚ŕY‰EUgćAvh‚ćÁžq•Ęél·“ć:XâíYVů ŃJăTĆ9WixµkŚj&]˘e!š<äëy†Sx`«´˝gÖÉf»FqŻÎN…—婯ářŽ©Ši”ŽŻ‘k5Ö§‰Ü™˙§×A’뛵§PÔ{ęŻy·X®ŹłćöQAűź\#ÝóĄošµĎYÝZ–őÂcúoÖqWfxŕ Íë3^î p˘Yxű÷ö÷áÔýĘAˇvî'•Óď|/eŐä|_Źo·5mŔăxWy†8«ěÝÝ÷ŠRěěŘ& â|č7Ź‚ßëĺB±]ľýăůt:GŻŞđާ¸ëťCŇoĎůĵ˘`Á ±źGŚ!,CŠGÁĘžný÷X°Tđ4|Kl@´CŕÓ0t©AňF  di/EŘŔ7·^´…Żi¬Cş–Ôâ 4čµĺHŻTéfÉĹł'( ŹˇÚˇ‡Í ,ň:żWËôSä~Č”ţa[°{-9Ú@eÚtź  ËÖ0/‚¤úZú˙*/Ć–q ¬_L†8=´ęˇ{­qmL˛™t yÇşHv—ë>8Śů¸ŁĂ”@–ú1A@0†sĚŚQš5hś:ÔľJ -8ŔŇR#đPŠŃj/a#i9'H9"ŹŁŮLzRxN´÷źt ń÷EAä1†ŔĘsaB¨42Ň ¨uÁ@DEÁ´ůK„ “Š"¨92ĐÍŮLQ=H0„s%”ßDH’`Ěy°Ş¦ŰĽ‘Ó<Ĺ0Đd°s ‰ÉäŞÉ}G†žh`ŇHs<ˇśÔ ¦[Ľčúz€Š‚$žLŔá€7bý4po9Ş ‚™’¨Á´)eEb‚< %-)8Ĺ%ł’ ±ÄXĎÂ ŻšNé•+n@4čŻčDݱpç"–ĂĹFĘ‹Đ14Ö›Ó–TR Ť=¨Î™•TŞKNŤ&n5>Ö:[Kĺ*Á8Ě®Ş0Z¬ €8PôÖź·jË[+%®¬©3U*Î+JîŻË2›Vâ JaS°•îÁ3şĂ^Ř"B+Ä—X u•¤µVĂż*¤ţiőcAöa0Y«hśq8®ŽĘV‹.gX-.­´âĂŞLÎí +´vÂŐ–+On–—NuţApJůł‹BAÖŮ^­EÇ;7ĽŰ•FHč’ôµ¶X‡Ą´v îM…¶„=€©űźu}Ř»ě$·JćD‚Ř -WÎů_PfÇŻEň¨Ő.1Ý»‹~™89§·Šś7‹IŞůŔŘ –č¶ěޫݰ˛ Oڰmbů'ç áu¶Ká–€‘év+Őq‘84$› ŻüS1n‚çBA‘H'°­,jťhÁÉpP÷÷Tu‚™““›Ŕ–a7‘jćA]ř4“)\$wn)7ŕ$ŔZ‘ˇcŹĄ çĄ Q2ç"Śč‚ ĎŚ €0¦*pęŤŮ}EYÜ9†ô,e t3‚”C©ŕ s¸Č„ eV+:ÍEöă%’ůE `§q:H*l9ąµé Ń!ž§KďĄÓJĄ´ŕT %Ŧ¤LĎî‹ ’m N#×/ňťşÔ6‚ÔpŽ—ÉÉž—şÉ PšĂ!¸FÓ;Ѐݡuę•'„őI™\z<§űÂhTF"¤JŚĄhsČśóg\îyťâM2 dĚĄ™dNWnqHlÄ‚€¤‡u’ÔĄ¸»Ĺ‹@e®ĘAšhÓ”ČLh-¤ŔçQZM( áH‚×~ ć7ä¤PI˘ ą.Aä!~ „çË‚"}ă@ă™>WÍć2ć<ňhËf‰ŤOęRHçRx”âDĄ™ŇŮĹBBä§S¬ô`[×/[NťkݧNĂŮzĘ~P łLxVÉ[e¤ÂŮw"ÄK×2&ËĽ»¬ňMŢëš<3ÝÜÖ_߼)Ćđ8˝ĺ–<,T»ŹńěŔ»řĎvŞW‘ĹlóĚů_UV5îóT·ŃyćKÓ…ÍôjhÓwĎéÉ…**jÍŁĘgÜ|±Uh~SÚ*Féî<ůc]¤ăĂűZ!ë˝ĎŽ\8芕ĄqßJS*$—:·Jz¨kžaďTöőŠ™˝ź’Ş^óä”­ř|ÚĹhž›Ć’őŁßS1M-ĺ×ř{ ˇ˙ŠÄŇ>Güú `.ęŘ$ĹŠ…⯠Ä,Íáb ŇŤ&ŇBř/˘@em”ÎC1Jú-D4II:IΚĚĚÖÍ$ŞŐP+Š&‘ëJ™Ä"ÖMh@DĘÜ­Î ôF­Ä<ĂŢ`ŕ €Â>@ćD`äE- ĂĚF€Îˇ-Ś› Ů$~Kä„-P*Kě,Aí8>ŕä7 ´EÍ¸Ţ 4Ö ę Ш?„Řŕ’ŁĚŰ­ă ĽB­ŇÝc1+ÜpP1@î>ŔĐ ŕęE#ú>@Ę ŔĚ  ĆE Ţ@Ţ Đk1YŽ2–.§ Ž1Mˇ-ř!Ť,g áÄÂęăŕŕ®á-á‡x8®˘]±L⑬âî2ăn:ä®@äNHäĹ‚ĺ.†ćn`ćÎć‘Ţš.tĺŽpçÎvćn…NpëÎdé.Ôé‚ÓNžGÄtęD~/Ą¬™Î°ěŽą"ĚëŇ"ěNŇŇíŤ#”íp>Ő>ľOönÎZ‘ń¬A±JÓ€’ˇčÜÍQcdE QpB [miŕĺ ä ¤–7ÜB`@ CäBŤŹ–4ĄŚŮĂŃMÚp Pď(cäD‘VE ć Î ÍÎD á ŇId.Ü2ŚIÍÔKÍ^LN Ł^ 0 ""«F3ĺ¬/Đ(B*ú"` #ľˇ&¤-„V  Ä ňĹ0íˇîĚ­LÍŚŐRFdĐ Ť6B ¦DrZ e`>ł ŕŢĐ‘Z<0ć<…`ˇ1 Đř<@ě ŕ×€á0‘Š˛Ď 21@ç0H?1$ÚD– Ç4€ĆÎäi Íj ŔćEŔá%±fÜA@Â@Ř14©ĽÓ{3=8 ĺ8đ€ Łľ ŤćšCęÚíÄÖ“|?q‚ `Š´N®ŮĐę „Ű1j ‘osĐ@Řܱ`tˇÇŃfĽ … RL€¸hnJ_€p“+ Ŕ 6F`ŇÓH× `q‚I@Ď'Ó@’;m!Ůmťň<40;ä-Ŕčî“s§ ¤R Ăš8c28c@ú+äďK©˘Ł$ť$0C2@h¶PáH˘L©<@Ë<‰`/Jŕ”0 /‘Â*"@;”AÉD© P ŕç8ső&-ą Ę©+€Řqqn `ÖŐ(/®y!PěS)$Ŕ*qR<Ófňm7t5=[msJ©Ś=r‰50qT“K ĺ(ăłPŻRŐ;s;3ô2<Ń~ ŃB@čQ@ńÂżňU3M´ß+©Zˇ-ŔBĂßCRłs†SŠ>“d“,SˇŁżZĐ”ž.Í9C ‰[ŐŽĐł^ „F’Ô§#•x`¨˘*'JşnU4ł;’‚¶Ý“™Fw%¶4Pçţh lĘ™­{™˛ÍXŘZőH8ÂéHĂĐÚ€ä É`O„–Š–ęj,ÔDśMçH‚P$"šÂJ=Ăá}&+w8 C@ ÎLAě ó˘,Ś»Ľfů´"{ÂČm5—&_Äą’:Äś¤…[»˛ĺ»ä«Âx@ę~20ü6ÎpۤăęU[Ia‹ëäGx’˘©Q ö;Vµ *•‰5Ŕ Â!B!Ö~íĹź'iŞwkóvĽ¦đ‚ endstream endobj 106 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 108 0 obj << /Length 2905 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h˘Ž)*¦DiDq‹ Ó蝆 2ŽDJ)RD- †ˇŢŞS“Iĺ1L˛S*IĄ1`€’N!‹«˘,ĆAŽA†ăH„ŠI&”dâÉtC! Ć6FZKIŃi%rŘ,źIĎä†#apßK#Óćv{YFr_1™×fó‘Ô]˛qxňśĘAn©]AĄ±@ŇÄ4‹FC8řŰ«rfói´Ân2Ĺ%ҡ(Ť©A Ń( Â* Č‹¤q‡Xd”ˇ‚ „hb8Č€ä2µ¸»aÂ"µ„˛0Ťˇn°‡!š ’8Á°j$Apť¶ËRHť†˘Ô–DŃ@lµÍłjĹí`¶‡…ĐBĎÄhČ@Ť†ašÂ†A˛S$­»ţë(’\B˙µit‹#É)JH±IÁłhĘBQhâĘ l®ÚË!ł¸F˛ěż%3\Ű2ĚňD”ެ,¬3/?S„đĺ·Ó¬˛‡2ÄÝ>ÂT% :HÓD”†éܩϓAHRMě÷7Ě2d¨ßBň3 …Đě?H8á˘kÄó`sD†®°m(ĆlĽšÖ!ĘÄłpkôŰBu8V°h•Dµ%MKƲr—.4… Cő¤EŞ-“jĂčëô¶L°€g 2ĄKk$–ĹÁ†ˇ›®]6úŠß*Čp¸ŢńUšu"ą2vdC#5q5±qŕIrÁ÷ˇâóÎhp8AÎď:T´“:weĂm»ÚjüŻťEÓf˙ đűrR¶?[&±ëűî4‹™{žŹżwn?c­ŠFď†oSŤuż}߇ĺĚFď°űYľfîů8®ćÖđÄ6Żä4•"G’)úmmAő&˘L Á˘zĎ˝ť2ÄĹßěeĄÍüłŁţŰĐlx’˛ey IIh$éÁZżRJ\`Ëe:(4úa\&…ĘôλÖrs3gČj´(ŃPcHU°>$*RHóßńĚ$ÍąÂĂ·ČGK‰üG0©Ä€ !ÓiĐ­ôFHXN9ن ÍŃ®×čm\Zł~Q¶/AÂR\Ë”v„1?źčĺ˘2RŕäëĂBĎâkĹŠ äĹE±™ X}J*ř`ˇ AŰ$ °·Ĺt­›äo†Ńć²ß±š“ďQ…CřâŰâ‰RĚĚ)Ů!%µ2‹…š¦fZĎR҇nÉŽL„E#XC$‚,ť-&2JjćkU ˝í±IŽÇ—'(’c1f_ęj›MŃ'h±”Ůśĺqšą˝9Žd§‘Ěno˛ó”¸áű%M“µ?–…{<§Ér‘ĚÎr˛é®—LĚź˛,ă5ń@¦˘Š6¬®†Ě… D  ‡ ČP†řݦ\üź A/ÍÍ;ú˙I4‰Ňrĺ2čaÎWK(DŘń—cěakĹl°WłObîCOl—fläsß.)x9rj \ŇŔ®|§teém2`¤µ‰o¶´s=4b3“A5Âęo&¤^}ń»1)Tă ĚśN2'ÇË6ö&©Ţ°/ć,¬g'câNȦIż «8BLuóyb„ý5fĚ;“fhOsź0˝ě ŽňáÎÂYĎD匧ŤT±8ČmU⼗3–6Űçýč;ý¸çn?P“Ó'  š6Ę"ŮűS_獧˛ö–ŢřZJTä2¬XKyŚ!vb€¸ÝKhĄ%Ý·âCřZ„JZĂlń YŕČ“˛Ź}¸Qă­ˇj#ţfň˙ăüA¶´ľ0ZŹ˙-âi7“"8ŮĂNągvÍó„d ”§ ÔAŻČ Z Kn.JN—®äZŤ:QsST §©tmM_Fl  ĆVŤů[-Exś–fOHgf(Ę7đ$nJ‚őXĹ’3jHaŇeĘu˛@ÎÚ·p$@ "NëŮ—ďy‘é)3öÔEŠQU ŔÇş#´IçPTžHwP¨ Ľ3óŢąť‚˛|˙’˝Ő.â»ďšň]×I÷‚ÉŢí˝ŔOM* á˝?í µ"eđ‹TşŤ9ţşzjH=żX€mD˘®Ôżŕ‹¸S 6x’ÉÚ‹I´(*=´–ϰ €oá”9ćC°e Őú-^÷˛Ě4†pÜ ŘîŞ yÂȢŚo„ŘáâJyŹ"¦ Ü€`îŁŕ–ëÂWm^Ę ŠëµyĄvN낼l}Âćd¨˝PLj˝ĚB¬"yKčÝ(¦Ź%HŔ ÔéE S°fľÎ”H¬!Âě–SÍłŚ ÁŚ}I}«ąhlÂ-DŠHlŕ ˘yđ`ül4ɰ>.0NĆŔÄĐVt,RäĐĆČ _p6t,{ đĆLpäĐL%PR–,0 DĐđÉl‰đúF‚ 0|C› ĆŻĐ· í¨:Ęđ2DĐÖĚ » °CŚĹĐľNMpĐ˝Ź”ťQ%,ňÎ0Ü«¨:έË…K ©ĂŃY,ú?QE Nps10ĐĐçŤčňѤ%¨lŘ­+p´ŇDnÄ0Î׬ľŃšÔ±W-q QHŐMa qŠŐlr^Ń L-hŐ‘bÖq«diPĺQś~1 ±ŔÓ0_±á i*—ü8ë­QHßk» í¦C°KĺÝí± Ň‘mŮĐ´Ý|~˛1ܡíÁqtÝmą"†ÔER 1˝#-ç 1mćß‘é$¬ç±jX¬QŃ/ĂŽ9Ń40.NKR&ĺî,đ˛Šĺ WO‘%„$s"2‚[ň12x@R–´rn@QWŇdRi’E%˛U%Äbě¦&¶&®Č ¨přb',° Réűępbč.ŔPĎú¤-fÁ‚b endstream endobj 109 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 112 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E1¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 113 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 115 0 obj << /Length 316 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h f3• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨Ť»mÖŠ5đÇo ]9Ał™…r‹_śŚ¨Čj’2Č8×)EľĄQpĆŔh´h.ŽČ´‹M|‰R»UH¦Ă)Śč9 #Â6Đ0ŽC ü2ŔéŽoc  endstream endobj 116 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 118 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E1 ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 119 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 121 0 obj << /Length 2188 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h f5• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇŘŁŹ. ĆP.8ÄR-ă ­=k€@E6LgC‘¤Ća6f ČĂë2űNgOqĚR.Š‚R ¤$TćĄ!ČlĄ*®»Ěô=OcÜř>OŁěü?OŕĆ˙+JZ“4kX¨"A«Ě ŚCŢ6Ł Ę Łđ4ŤŁ¨Ú C ř7 đâ¶ŠÁ˘z†H&6©B>©.‹Ş(>ŁÚ2ĹĂ“ľ ¨P)Ź#hĹĘáČnŢ7 Ků3»íĽ˛ ŁtÔ˙Ŕ*âjݧ!kŽÍ„‚&±©-ŽŁ€ŕ6!íŽĎ‹@b..řb;A¨P+N!§éâI)HdA’Ř¦Ć «”ŚĺUĘrµ¤µDś;.ÚvÁVąr¸`†4Ý:…Ş8\5Dü¨éĽHą‚ľ»ş˘ť CŃ4XŮFŃá"R”´‘KÓjŔ[˝píZŐ-{_…ÖZ†ę=Ť@HüP“ĄlP”5EQ”u «\·XríSa‹ +e‰ŢÁ¸mb]!ç`JásbÓ—ŕ*M…«kĐbHÜ8E¸Eż…RŘ«}δúP¨5PŮe©k*j«VHµ'X¨×hA +éŤçK.u‘$†…˘ŐZF™XH)@ia©:Ó˘¦`—ŕ„޸ő}ˇµÚç’“‰źhĐN¨źć¦ep ą«hSa„Ż|]Ů.sQjŐ±§ăuH§UĂşNwĄě+fČ”$‰Eoµ;{bkŹŢ®ţĺ|î¶Cµ ďP&ľ…Ř6 ă¸Â1=)XŢ9żĎhŞá@ˇcę¨fuS‡;(ićôZ‰Żs»Ś4šź&¤N¨dńWZÔhŻcŮ2`kěO˝•.+šč›ŕ‚xŕüÇCLxEĂoî} uNđ2 ŁČr)Q*t´phe|Ş€Ţł™ké¦62!ŘT*Ť Ş« Żđ8+t™Ş„đAI06;D1A+„âˇa4&Ĺ`0‰*¬©±‘öWÖ›ňe‹d:óě¸_ë˙GP . AĚLőČłŘŮVj ~,­®°Îő|s¬µ¬ElRÚ,ch‡Mwť·*ĽÎ48+p¶śRLČË\?„°ÝV4îq €3‡Ě ˇŘ†wb3î`M ş°@¦ŠĂ!ůAťţWüţ çń)¦Đn_$ dĎ%ž…N\ťt{‹" ĆY0~cCJsR*Ë'˘tˇô*°Üö–¸B:%a”0†EËatRë,ŃĂH€$$9đńzȵ™beĄřőHR»IÔ •¨!€*S˘ poEÁĚNi¶qKEYĺŐRę”YvÇĹo8@ćŞ/ A„9†PČ8 qČ =ąş*łUAm}J¤"=6©::-H.ŤK0Pé Ć.Gh ‰+í$óń¨2M@"ČT Ľ3"·päŘ iť4¦°ÜHC©űˇ±Ýš$ĂüAŐÔč  áY‰Q&/D›$…4Q k=Y1&™ZhÔĘÝ,´]˘7“W;čꬕ”…QB×]©0 śÓFnP“#&Ä2žÓ˘X$‰¬Uh‘°s ¤,Âk ˇµŠ›V2™ »1W¬в†őŘ„°lÜ/–ŞÇŇp¬Mlś/)ŢŇĂ[j#Ü:µDžÖYö)hmÍ„źŇÖŰ{nëuž‘•š!RâNhV|§’eĚ«f“)ħ`€&0’HC ‰ H˝˙†ÚČCpt`á‘)0ŞC0 ©48¦Ş±YéđŞ„نPđĂ+Ŕ˘Ć«˘÷vŠ‘b.ĽÍŁx&Ă.TÝŻ0lXč§çł7ÖĄPZ)Tc nĺŢΨPŮCŕŔe ĎáŢ^$_|č}V éţ]°ćýĂđ 7Đ2ž“Ö{Oyń hXűĄPŇ~ĎîÁ„4˘Č˙y! ©SÉę…Y2ýóËŞ±Ä­–ž#»·~&Ţبn=a¦Äç}CH8t đ 6—w•SPyĄ…máŇ‘[®šĂ: —ÝŹzĂ·&3É”¸kaX¤$Đ{̢O vEá´7äůB‹ŕsÔŐ“;ŕî~o w§uIäJ†ˇŘI—ßśQÜśÍt†@—Ϩd0ɨźćM‡$Śů’xŽÔ0Ú”ÓEôÍą‹c%:®ńÎ;É{6eĐÇśsčkČŞ'6†pÓ¨˛črĂ8¬ö`‰QńF zipę—ő ŔiŽ*DĐ’TmÉ ą3*››ă[ÁA;{ü$ĚmÄNG%Ɔ,n&iř_ă&łŤ`jĆŤď7M?”pÇď#ä —ń>_ɢ'áO8ăónɨ)ćn ňî~Óîw:⮤ńŁ\l‰K"ĺ\.ł, §?†’’‚RI\ĺ/< r@ń)cgÜvŽÇuJIżX…‹‰öľŔHÍ'#ěťÄÖb$EŞ0ë\Ä1ş_kH(„ đC‘Äŕ­ endstream endobj 122 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R >> >> endobj 124 0 obj << /Length 6349 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E1°¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ř}IlQz¦Ă)Śčr4Ě&Á Đa9zĆ^ÁĚéŮ9ŠEłzO?Š).• P[ěC‡ő‡ÍaČŰD«Á€`Ę5/rH‚şďĽ/ĘóŚoKČ­L˘Üý3/Đh¤°pżá@¬ß©ĂüĚÄČxhľĂ°üB"‘$0†CA¨d®EÎ[IŔkd ¨H¬Ü ‘$SĎđh?Đô@ĺ… dśĂ)Ę:IŃ € dÓ C Ţ†±"Đ-lŞôľDë`Ĺ lLËLŇ·(‰171BęÉ­‹pZĐ#ó@Ćá€jµ “{ś(<Ú2ŽŹ#ÔÁn cČÚ1 ăcÔ”†T؆7ŤĂ ŇóŐPlą!@š4ŤĎS’‡@¨<޵5\‰Łđő-l ŁuVř>Kzâ†.–xkE+Šbü“ŕ8 ŽČÂ1:‘"úţ?ĎX\†‰Ĺ ¤ë Đ lf?AŤěý¸ń¤ęŤăm'TŚŁ$Hş†ńvÓSäE#I6‚C††!Ęë|F÷SFŇ´ËcN ršĺ'!p+‰®ĂăaPc©qr‰„47[ť.ËëÔËDNV>ijN™ŔmťKÁ†I2ľ/ť`4†„Ýq¸o± P­Âr:ĆĐîM‹±ÜÓăbž; Ţaë{Ó:ăÄąÂŘ6 㽿pçşDgiĆ{R††ń/etFażËń¸if>hÍ?×XQ}Śwíţ2`9`oiyŚßŚl”Ë †3F_¦Múöˇ¶pgÖÁ˘;Âp5-qÔőz%›Łć?GÍjQ'WL¸J_Ikř×=P}[4qt5×µ»n߸îc-l%!ŹRő{ß]\ćśí|5r(…T颢 U®ó‘÷Łlú{•Áë¬ců-Ŕ¬ –"6"€ ˘çdSB&ᑜ&śJęďNčĆĹÖé#óY›şöů\ao±«$RşZ  ĺř0ńB0cĚ9 $Âs áiËzÓśÖ˘ ë~ Ďö ŔŘţI˘†y®5G?Fŕý›Łú(żçzĘëw‡¨Xě$ €Ť @tĎĚaĹ^ć7·„äáĐ™h^T˘V ˘l ÉMCôľÓâ¤V€ę ˇć”ŤÓb|0($ÎiÔÁ”î+@ŕC  Ę„:Îőť$‘,˝ĆÖ¨d!+?ĚDĎB lĹQI  —V>´K±Ś @ÖW˛v„Ëѡ33Ćm+Ą‚PlL°»™m1XDČdđĽÔ @ Ë»¬l‰QöŽH%äÉ$Í9±·Ă)Ń+ I (™Ă4ŘÁ”cpĘmËvĚ•ˇ´ŕ.ÉBt:·.%"OspŔ@&ţY"$.;¸éŃ*QL¬…J®‰dźĄŞĎ™Ë>]Q9Z” !$N°%x®6„o‚P*:†>óß(h’bL2—1AÁˇť´}lLąë ´ßŁĚžr$ůĚŕ(|ęjě6Cz) §Ś0ž†A˛ź¤m,)Ű'z¤Ľ‚Ž —ş8ŞfE#Č2 cq’!–IÉPÝ%äĚ› ’vO®&HžKÂw’ţTT¨LÄ”*j1‹Öh`Bd´Ş“qzłů`¬#˝jµúUM Ž˘ěŚ<†úĹĎd5P¬Â!|´ffÉž†ęµD3˘šÉë¬˝Ş‡Vm±™ źF˲é-V…U«L¦ÁDÍ*™ůó žrŘź¬¶€W¦A^BčĐ5C˘Çť)bmŻň®Ŕ’–'ol3Q˘Á2ŚYÚ€H b »Ňú¤Ý«*¦¬»ˇžńαˉ7H} ľTVŃŰj5i–}¨†÷ě˙Ő»…cF¤†UqźŘńJ`Ž ŽiáB¦ÚaoéśŔ¦ôŘĐ©‚•80$ʶ«ĘĆOyŔ ŞĆ![Ş®Đt8€T]Ő¬*ö°ę"^a»BD!>Yß{H1AţZg)l›łŤn(˝Xé(cĚ}‰‹»}Ç9â5~YŰÝ$ˇfOiźGr«¦n×SyŤ”Ń śYÖ–\^‰Ło¬ó^lÇ ÍqoÍXÉ„™ŐÖ äüß /‘Ůô‚—Ć Żv˘ĚÜĺx .­ źŽ|Ź—:%ăLŹ:Č9ÔĄNŮŢ,xč6w׊ĐQ]e_u¦I/?~k‘¸R3ü7*ç<°ĐU¤qŁF@çiZńŽ±Ţ”-ťŹn/FĘਆŕ!ŕU&P>•a('Ki}Ă7™ěóB®0ďľÚďç”­Ĺ-ó¨ĐUżB v ÁA®ŕÉŐ׍ëC·˝K»|‡§;眡€O±1îŰnßmÚóť±%ž†řŁÉËŕUčĎÚ:ëśÇçZCľ”’š[LIŤ5\ôä\* ÓPź=Gw®q¶Ľw ÉŞřEŐß Xö›+­ľgo1]ǢeůÝTĆŘ0i ě^úzĽ#đZ¬ß/iüQźű3ó1řű^şR·ëňĽźk™˙5üź‡Ű¸ą$ľ¸ú,řĹ`sŁś ÍÜ/ŚPŢ->˘Dő˛NÉ€ń(rř‡NúkČŕ/BĽîÖIBřÖ/śÖ®ŮćÔě îOŻŠ´¦$¶ă.\8|ě@ćĘX#îHO‚óµ"“Č@eP4ő,f¬DäQ‘lâŞb€ň Ĺ$;3 S ł1ŔŇU§@uk©>1t$@KÍq;“jů/¬@IŠ/ď6dą8 ¸$HiŃçGÔW<’‹-†x©3ŢąÇ!ŤgIŠhB÷IŠ+>Sl˝`ë”—ĐZ›+Ł*¨˛Á9˘9@jtDůĹbhVÂPW#}e›ě9JOtěäqL‚î’~ný!GĐeJşäľŤB ŁM"ßę´.úSóôÓTíT3e@ôH'C@t WĹcARźAňůO3Š4ĄFS/xeM/gą t>iVEÓę—Ô4IJMIU‹Šd €PT˘Xř}‰<ŔÝ=Ä `Ë1hĘ=es´)LBđ…µ—3LţĆ Ç¬/dIĄu¶Kâ@” QűA3|dNč1dPfZu>u -Ć#qÉ QI&šşqÔu±RSk‡Ir˙ †Ł(pÝ 2iŔĂ1 ĆU` մTg¸oÄý\3]IFDřr'6cu3âîI„C#q#öofDŁg°‘%pY%Ôĺ&JĆ-RjNu'D÷Q϶9Äü4ÖSsäoÔŢ µ^4ó_R›j•g.ĆE*bŕot„ŕŇBĄ¦öbD&Ü­Í3dÜBTŞĚ€+®ľc.ňę çd¦ßGPÍ@â°÷]%GÖ­mtÄb3.Ťô›\î¤ţŹŐĹKŁL®ŮĎ 42>d"l—Ő8ÍlĽYčř"2ëőcqpďTX@4árc'Â>ÎfqŇĂ'č)l,Ť°_`¤u0f‚‘±HPĘPď@dĄ\—Źz$÷<ş-WW%FÂňІó 8^÷ł?î,Řfj@)ŃClÜ$—ÂÎ6řu€÷Q­8«†"(ęš}…íDô­fpzíP} r€ďĎu { soÚaɉt,€ŽÄCt¸ .׍?uŁcŠev7f"·lă‰ywhŰw±DÂd÷‚šÖŹxĄŃxäĺy6'3ßOjey÷˘Xô&Y°±sôÇ{!TM«{¬ż|U7ĆË7Íp.ř‹fp 8§Ĺ~łŠ1·é~7ď/k\ä=XV9Ĺöe(ÎRe@c€Á2”*b$@9)ĹUJSM}ŤĆN9Ń5j‚ů.QKVő˙8÷nViłź(U9ĂŇQĐꤦ:}€Š, (Ăôgâ+â ’‚Ä%í|&GBeäZâM“˘–Čé“"aRâ¦CŮA”ů<îd@*§Ď”cöń™BZ‚¦ŽÓ.*¤8'RĄÂrĎí–PS—O8ą?—ň}§±•ŮLCbq™yU™ťŮ*ŁA™ůŽ)˘8nŮ©bĆZfť›"uś…”ą`""'ŕ+E¦?fF)yn@d*eţABÇ“yÓťb¶C°?™y,?yţ$`Z„:*9e”1R+š*z äç9´)ă÷™—ˇčn§:'b O9y ‚Ć_9qšš¤z.,bËyEă}TkDŃT@žÉG®D‡/ŻVÂä ®Jč ´ž5˘BgÜŁ(Ťşc¦cϦş„ĆZrŤşyµťZ¤By ş _ ›YDkZł”Ú·Ą˘ŕ*bMšúÁ–Y¬ŞÇ]¤š8˘fI¤âˇlOyµ¬„m®YšŞĂ‰ Ö%#¤Ţ×ÖŁzé]ú,zľ˙ÚŐ¬›­Ůúášq˘bx4«Úŕ!éy°Fí˛ÂĄŻÂ ˛§]˘Bu±FM±…ň$z?ś{"TşÍ¤+>Ď» ÄWµÚî/f%Łz(îšĂł•Ć/y߯ZČWŰł…ň˝;l'›‰°˘_¸bQ­[oą{·kĐĘZĹ›nş[t…”Ę)[}ł$˝»[9«âů9[_TŶl™[Ć/±ĽÖoś;P Öǵb^Ĺçw[1tíą{e ;ůš‚«·b¦î„@ś{±Ŕfź”Ü˝—›\TYĄ͆#*)M˘aÜ,ś®č Ň ŽüŽôDĚgByęő§Ň^Ç/\K+/Ż`† ŕ›Äߪ‚Í—fK«şÇł"»«ĽRúł{CÇšłšR-2¸&3ňMµJ* ŔŢR ćV›… ˇ§J~6úeCz¦žW:Ž<3ŇŃúÂ" Ňr’dń~ ŕĚöúzbÎ@ÎĄ#€Ę` Y*Ŕ\ßLd&ęĘ‹Ĺ@ Ę´ 2ŕĐ<š}Ěŕć Čr€ÝÎę cżZú| ŕÇŕĺÎ@ÉZŔϦÚdF[5¶cz âűĎÇ›cH| Ľ»ËŕP]¶ę‚p‚gdăp´ž @‰J#p @^ ôž ŕĄJ<ĚU#»‘Ąš}ÇćĹťbsÖśĺ5CpŔ¤7šă_dŕČÚçÚX4ôý«ÚĺiÎ]u|‚‘ŕ}šo Úbô=]eÖ€AŰޤmŐݦ)]őÚÝgÝ˝mץŘ=†=‹Řý“Ů~Ůăq5]›Ü}Ę€ý¤¤$6~CśBqŕĄr[E¸[Çî"=ŇvéÝÝvh={âýú \Í\Ě“ Đ‘ŔŃĎťY§HqŔŇ şd –O[]R2Íçe „á|¶.DW^oÎ@ě;wÎtg1ěUčÇŃP÷ĚÉ4<„ ;`@<ñ¦^t-EÍĐźC@¦3…*]' ˘";ĺëóŚXĂ‚&ť˘r5? ł'Ľ–"fđ?Ă»>°r6ęľąG='Ó㱩C~#ÂşDgçxš2(‡¸Iä ÔŐąîŔÜ ŁŔ €ňŕ@Ţ1ó§ÄĹĚÝ7Ô÷ p×e[YĐúńئć˛d#’D ‡đ·-{ÂěQiZĹńJ>Šk­ć$^Ô/ľŮErXę Ýő‚Ůď¬ĘçčVd%ŠEôŹtÍŁ¶¬ń§ý™îß!ëfĺŇ:€@ ÄÇôÜĺîŔÚ '(Â)*˘Ń¨¸n8ŁpÔd *ŁpÄf1‰ÁĄ±@¨r.‹FĂAČ ¤e6N†“y¸ćh4ś#)Đîe2›„CA”@o9Í&É\¶^ 3ڧ¬ěĆyRŽFi”R]*°áŔŢ5  †C”P[ #EHŕ Ân2 P($n ^„Ěj7‡#°Ö$mŠ ×`hâ˝Ţň\F…Ăâqbŕ ç:Ť&s­0ç}‹ç†c+Üf\Č p]…’Yŕ±klr<*ŤcaĽśžp2Őe¦ă8€ěo6 &zWśeԛ̵f¶ żdőW‘§ź1ŕ±LP ¦SÇerWĎ €iôúđ~ččP.+¬Ä3í €Ň4ĘcT6I´®!ˇ˛ĆŔ·(z"‰˘ˇp`#oű„‡8®:Pí #›¨7 jî4§Đ  é:ޞ‚î·Â´8`Ň2®i˛pť'‰ň±ˇ\ü†Đ˛ČłC+L6I«xŢ:Ž„ŞJxĎŠb(Ž©bxšŮ@+@2Ś#Ń,ŤéČĺ,ËlđP+*¬NáXÇ/kÔŢ/ks+A­@$ŽLnR3G‹śXźNR‚ĺ9’Űžčşn«®¸şÍ˘ČᲱ7pË|=®>Ď,$öÂpA\m:7QC^9ŽŞĽ|<ÍTŘ2DĂ:(H†©ŤĂxčđ+•5P‡I” <KcŘ:Ů.p@&b$˛¸ĄS5&4ŽTŘ@1Ś#„Ő®1PçQ ˛<“ UHŁX¤I$F Ç1Ýâ1 Šč7„𢀍jĽHBř×âá dö0†:˙‚ů˛8Ŕ@ű†Ś==÷^"â€cŠ6Żřż$ŇS‡–±yJËdďş2°aÍlö±X‹$ř,t4áR{†ář‹]ŠHąľ2ócš6ΆHÚľď&†Ś0aÂŰĄV¶›‘`ÚĂ„áz®c«ć®¶ňżóµě;"Š’0e ˛ň@ĹA›*żńc`)«ˇ¬:ˇL¤ŻO4Är|Ż3#±ĘBÄsS Đşç}o,Ý;×ńČŹoÔČŘßYÔuܧ-ŰňW8č˝7Ťát|ÍgÄńŠęĘô†~Ź^†žŠ1čó¨gčw#ŕűśÚş÷~·ĹŃí~Ż»Ř7_CáŰ_7z<˙źšńyá5~F)蠟ţüťy endstream endobj 125 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R >> >> endobj 127 0 obj << /Length 4222 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h f7• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇŘŁŽ2‹t{OZć M†SĐäi1M‚ Âr0ůLľs™ÓĐs—J„ŞäÖľś¨ ę´Hl†ĘS¨A˲a¨P) Ł`Âű ăp@1 Ł î2ڰĐŢ9ŚcHŮ CĐĚ9 ŁëŚcË Ś#hĘ #pČ OËö‘¶Čb㨡p¤%<č…3ť'’AHɬ•¸¦"Ž0dŇ|‰)Lad©2Ľ2|˛ŔfÚÉ0D°.Éěr¤‚ Č’("ˇ$$°p± §t:Pí!\QQc[3RPM Ҧˇ•QÁ ,i­,—&ęl°"”$Uˇ˘Ľ¨«lé.Tę»…0Ň3ޱ`@ă†2xeb9+h&â"«_XŻ7J3„˘&µ’jč©•ä) 0Čć4 #„7Ăń@2ŹŁć7=AĆ6 ăÖ ’lĹ ¬łdVˇ­¶‘™jQVµOT‰Eµ, Lq¤m-K’ôÁ}¨·ě3aذ ÍŞÔˇ„ŔrŚäĚ­™™Č©¶"Yl’˛IżŁ”‹ŠńLŁ?˘ćŐ!ÄžDťłŇ@oĺiQ*’“*źäł’ÖEĹéV 2˙-qµ´)8 Q¦>-fý÷›r"Eŕp7‚NÍX.Fŕ3ˇw+-eYoä{gNr.MP—Č03€rĚ9:¤“3Ş^őRLĎńÄ Ż˝W‘9řCÜĺ5kq­tMŐâĐX(Üă6?P!)0č˛ćĎhB DQ‘đPĂóBá¤7p@xl„3ŁsáIQ¸o Ŕ€+;Cje”Q,0§CŇ’TP<•$Ć&ŽÂłŕf/°×§ŮýPߤ×#ŚŃ›,sŹ”ZŤ™Çh)Ćѧ¸Fi3駴פ͠ R%Í‘Bą¤ZË[;U(­ ZÎZ Í*§iĂ×Rx‚kş ™ÍěÚéA§Ď•RŇľU¨0 ĄÜ@ Hˇ%°¶RÇ€ifp˛vT‚€l T7łvŠl¤Ú‚d6Ͱ‰WwZ\z„gMd*7Ú|ĺÉ:viŐˇµBvÔ3l,Oý şka  8xˇYä#ňÓ+Kt¸5WpDćJ-i2š˛d‡lěMW¶$üťĂŔX–=*¶ëÜGgvĐŢA%ĄD(v . )}iěŘ3gä*‹ö&ÂZÜ$…A©É!Ž6Ęb‚§j Bë VÜ# °Ů,€ #dç±<ĂËĹ ;ŠđÔbŚDęU,Í%Ýf'ŘC ,(AfäóS¸|ŽÍ쀣AţfeŽĽ›üi9@n78ĺ)3L"”±üa¸—dlµŠ­®,Ž`7'ăl• .VÇ«Ę6–šŮń6ͬů‘lĹ"ó. Ěř;ś®YrĘ̌ą]ÜŚ±Đ ţŽ¸Ç™Ů´Úď­ây.ĺůG ćžg›6arŕj,ëđxˇ:¤Iëů†čţşúUËęG‚ke–e»~»?×wžö.Ě;.˙ęśĐ‚Ö¶qßSGÖE‹!<ý“7ׇ윳wź:"Ç·^]p¤ż<1o†ăýß©ęžűçVŻô~O0śăć}_Róľ/´ź#ě}(9ÓĘŻţŐ“yőa¬e‚˛ą›ě±ĘB_-~ÜÚ?HOö¤Żxă>´ŢkÖĄ4®–ýËQU Hć–ŕ?sżłďĽĐ8‘N»ŽrA`÷9ć×–ú®˘ţ NţM*ĐM.9ęĽÎOđTŹô«Ż ĚŹ4ć.ńOđţ…g0€­¤äŃŽ îĎtńO]oj` }p2ćâÄÜđ:č9ŽL8îQ/L9oűĎŢćO<í ,­ `Ö.˙0}p˙đuPzS˘čţđ0ôĐ—îÇ[đ(-Cjăhâ°­°˘ń/ă0’ÜK -xˇŻSŤ0Áüčđ™PÚQ°Ď °[ đ¨Đcą p› PóN}0Őí.6e0N"e)˙ 0¦âJ¬öŻímôŃ#p Đ1° 'p°="ę±7P,ĐéL˙P7 /±2ŰqOÇęŰü˙ŃGń4۰ ĐĹ;EŹX÷qz8đ ńkp‡ ‘_đ]Ń}ÂMQť QŻŃ±M­ ń/-QŠńaŻ?ĹŃČ€Íď7Pí‘”ΰÝ,ĐĺPĄeŽ‹±÷ qs w1ěĐqN7!±ą’Ć{­=":ö­Ě €Ť`-""©ć–ĎvęŞĺP~‰âÔvđ$)ŕ® Dmn-D ^˘sń¦ďMşŐ¤‹ŤbŇ©0(o)éqŃ‘cĐHńďdňHÚjP †˛ĆŠÂź%Xźă”źăŚVď„)**%r.Š2WĄ~ˇe†P„ž&o–'&žY‹†V‚ --X_ĺ†HËą˘ :Ex_",<^dÂfY†”)h¬Ë ďÝĆ:ßçpź¬~XäĐą…†™#6Ă“&Ż% ).ÄFĄ2“66Ă*×ó>Ż'ô$Ó:ĹÓ2&łO4C8ŚrĚ1¬ű1î#3@׳.ި+4Ó-4r‘sfčSlčŹ 7394r„6ł)5łSSd—shÔó‹Ń™9\ŹSŻ7ÓQ8s¦ÇďÎá;víĺI9ł5óˇ)3†ółŞń†‚ąs4z“˛ÂłV%3í9óc=ÓĄ8“ĆďF¤€d¬LĂ‘9STP“5@dž˝s@3ĺ4¤¬$“ďA3ABÓůŽ<,§BNŃ*Ă‚¬EW-Ë. Ď.B&9ĺ@E†2¦ĆľF¸Iĺ$ÄeD.FŘ|«"$ă˛4„"oÂçG˘:n‘HB(p´‚;HĐBC2v ŚĹjü*8ĽČG/ÂKäžýŞ(t˛ý+<ݤ€qkdŢĆ’šBNnŇîąiŽI„śdÄĐh/¦fHü+~dŇŢůÔUGĹ@ě"«O¬G´¨4ُľéŰEš[CŽrbÜ`”Ú®˛ÓL…D˝U 7†ˇ5‡8„‡(`‚řgĂPKNĺ`Ő9˘v€ô`‡VxěNÔOO@îB?Tâ®K¨ @˘ ¸9ŕbcŔ¦•‡Wu&ĽŁ}bÔsÁ@ ÝĆĎ3M{A­ęt35F t ?S“.l34UA˘¨đĎ•D¤€ę0qH‹S#(-e(ŞňÉM‹€flÖ4«üQ‚L‚5BĹI•+h†NM$R„–p•:X´¨űâJ|Ş> `†; –Ú‰ž÷&xÍlpŰî$`Cj-B ("Ä€iÝcBĆ„ AI–„Gwd”-dX€vScĄidĂYdV8XvceŤĄ?ł…bł‰cŞgOeKĽ-HChGf?h“‚Úöy>|ń‡qF¶…fHBŹfÖ“dóŰgrÉiÂ@âE—cv§eđ–kcÖeiliłiîĐ­f¶Kl‚Gn(Amq;óem“kmĚeÖ®B‘n–iní{o6·i–»m¶żgć‚¶=>Ç˙d(z@÷#9–•oSÝo“©oČÖä(ö¨$it7s7mwo·ń”DiĚi—Voô(ĄcćEnß_¦ Lj€nü÷GgÁIT~gÔŤH”x;T‡I»xÔ™G‡’«”"Îl‡oô¨ë¶pĆ9]*p¶n%†–rmSb«Qć–P•Kĺ@NË N˘·vUęej‘¦Đ(¦°WĐ:¤ztčĚ´˛ýXkŞ?‹ëv«ď^‚*ö>fÖŃn ä: ŚxĘxC*‡‹U‡a~”đżĆĐI °BHgGz|ǰ{@băh0ŘR{§ľűÓ {«W5ŚXő~€u…X•‡W‹ YOGóbnŁs–/u®Đ2¶’I6Wh<ŁŚ%-2Hć[0ÖîŤh— cµŃŠâ×\p…M«wg­¶2«Ź‰őĐS$hŁy„ ŤVN€v6nőĐf‹b%ä,xčĺS)ŹF*䬂ŢÖ[qîŽSFˇy ˝¨Đ%/.ĎČĹ@l»ąŠEe‘i‘·,‹ăŮ(PÓ&ÜXýciÚ%52Pä”v®PŘĎ“¶Ä#ĎLňnʍSYbž·5k–,Ęw<~âÚP4MŚÉ݌ƦA#G(Ř׏đHĺ5 Ëm–y~$™ž(ŇÔ Ă0ŠČRwg^Ĺk–$Ť|°dčä±1V" endstream endobj 128 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R /F9 36 0 R >> >> endobj 132 0 obj << /Length 4441 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E1Ŕ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ř}IlQz¦Ă)Śčr4Ě&Á Đa9zĆ^ÁĚéŮ9ŠEŁ Ěr4ç‹­EÁĘz‹†"’éP”‚ݍ‡ˇé @!łD´p`2ŤKâµ-HÚ4ŤĂ;şďĽ/ĘóŚoKÂ=apl-B ć1OĂô6ËĚ2Ťˇ„:Ža¤2Ś# ^+» ĘÜ„ŕPhĚ0Âă`ň ˘€Ş.-ó"µ2‹t ĚŔĎrôɲü“¤¬śALĚЇ âm… ­-ˇ0hAS ú9a@@ČŻ«LzBĘË@pµ˛®lµ01XP.A°aD­4bܢ$lÂŮImŔ­3ÄČb5´ ¬7Ϣ§9§2ârTő1±Sýű:°ALQrĘ9´…>ĹRł÷­ÂŮMŁôŞ1H KL2vz N.Hb(‰r+¬ĺąÂÁ& ˛äő°ŕ)Ź#hÄ7ŤŹPd†AŔP)Ť#8Üí˝OhmcxÜ2 />ő=ĐxP&ĂS€ľLŁČá‹1†&0ŹĺĚ Łvţ?Ň˝5?!¨p„-iĹnp‚2 Ę9Ç#Eđ28Ú2˝T}â™CţşŰ«˘âÎQję‰>L‚ĆÄvýĂS"vâî»Q÷&¨Ĺ!p!ŐúĘ”ľM*XmsĹw dąLKśý†[fRáŤüú_|b7;ÎFôżŻřZŻW Aج¤VŔîÁFośçqČçvŽŁ† hhjâZO·éěÎÎ418i\rÂľ°ßëÎĽ‘Ëđ;“\n[˘Ůʆ\.őľ;ő&ú†< ĂÁG”ń|j홣Ĵ°‚Řćßń”…ŚcČĆęsú‹ßÝ6SŐőZ}y†„ú!‹"gmÜn»üëűŕe 4ĎlĹp¤nDJĹE‚Ű›‚ {&QĘ‘DĹłtxëí}70kĎŘ-pĐ}œҙcŻ\j-ę=g(‹s Ç]|ŕCc›"!¤2@ĐůÉH…°†:µö}ÁË-N !Ŕ·j·ť»y' Ö$«ś}”ąëA ćAŘ4ŕ˘ńđypťÓ˝ôYŠ{/‹ ŔCśt ͇G:ů]7qŚyő4·S_p0QnŚĎ'ß»ZR(‡·8¦ ä)Ëw­Ôśăá›Ű}oď!ĺ<' #3ŽŤ+ęĆÇ%ADpŽ@źƀУČ9~>ş‚ěűK±ö«Ó¦@ŐâsüvĎńążâPrŚ•$ Ŕ ŕYJ%Ę,y')ŰĽž“/M¸ňŰ›Íyî)Ć?—€e*Ô…č5ˇQAâ nf<§Hb§Ť:\Ë0@Ý&’p12DÄň#«0XŞ©ůĄiöX3t…»™0ZÜĂk`Ěj*Řăi¨W* C`ŤCŹŐŕÝ·ÍcäöŚD¨pQ€Ľ‚€ráA›o Ĺ˝ĽşrŢç,Kđ ČFąŐ)çe0{<:‡Hn a„1>I`ĽC{–´>#اN]€O f?¶¶î*űSAt† Ĺ–ňă"ě"W€ –=[›đ7 D8˙? .ŠgµĘs÷T!«  "ž Đxfh!ˇ!‡c¶YٲŚč*7N^Ť ™´jŠXEZÚL…\iíř–Ćź”Í? Á_”sU}M3€ŔŮ %ŁŤš<‰ Q˘;GhŠX ˘SÓ&E]J%Ľ€.ÔpűÜÚF®ĺšWÉ4‚ŕĘ ŤÄ>Ha˛Ű$&eeJ†ő¸µČ¸ČďÉš‚€TđAm‹ –PT†Ă Ia°îK |AĂuOŽŚĂčϡĂ@ WŽz\ÜDÉnfőÓ„RÍZŠ2Qĺ)ą“Ł“±Ĺ$T㻢‰‰I59­Hźâ˛Ç‹TłŻ*d›•Ŕaޱ±/Ŭ¸ŹcŚ˘›/ĹE‹! gF~r6=°1ë%•\‘`]K)¤îŹe’§‹2q#ÉxđöĹ<ʼnJ©Ä+•=“˘žÉI?,x€­7⤠9$ŮŰ-Oő¤UqéSmň2’¦ sůcÉ <ĺ˝`tI/%$ăč<ôIÉö%Ń++LűĄ˛Ř4ÓÚH‘Ă٧ôi:Łą?iĚn&ŚĐ„sXgÝ7“)k¨=(ĄâóÉ$^%ôÎÎz;I:Îe®ëÝLëÓĚyqí,ŃŤő:`>ŰO7ăL«¶6đŐ…|cśű‹6Ě˙ÉY7äMż·NOŰ„óym|›™ťî&̶3ä·– Ć;&îĺíýŞ÷ĆóŁŰ÷\.n îI3¤áůČ—"Dö>[_˛®ćݱJáÄČ#-$?"Ç€çrň,Ó® ±×Ęp©«G_ ÓnĹf+ôl˘^UʶĚ"XŚ H)Ĺ8 otŞ$×&ÔEX@fHŹÖ°'TKŞ7›•Öń,Čôđu[” Wa,G°¸vj9ÚzŃ-§‹“·vâ¶ůż^ęîżµPŁ%HÍQčý%}膸_WßO3=DŽîËŢ»GY$ÄĽxţ­ä{ďc?=׾wsŘN<ç’íeóËv~áا›ňź\wţ‹ŕşGé~§,bă:źĄR«“µcÁٽߢ%ĄóĽ’DQç}B >]{ăü"  ďŔD˙8Š|RďôüÉ/őŢŤű•ᎵęÇ’vćý豋ńôĄđ¸y’ńęľ4˛úťcŕ/2p;ozü˙ßţżöîď´đŚűĎ éŠüOęOţ˘÷¬ŽÉPůήţ ”˙îÄ/‚<üĎŰűpđŹfü/öŔ@÷ůŠ8ý ŽňŻ/2/(ř/îůO¤÷Ź˘ôěÂn#Đ­ #5Žî_p· PÝŽţĆ­u/öP‰đŤ" \/–ęΰ`ď'#đďO+ P= ± ďdńPÔĆ(íŔp/Qëq:ňĐÉQ.ö‘nĆ)O€Ą„LëQ9ĐP/±)ńűń1 /nĎcßbďCÇ^>ŻŚô‘oP 0ЧHń‚˘ú.ô˘Qcń˘ýp«Ń• ŃUĐŽ&ĺÉË”ÚQ†2ŃÂůŤO.ý—°Ńqz&FřÄQ¬Mc5p q·0Eѡ1€­ńěň‚=BoO[‘ąń5"ń1$?1Ë"/ttŹťą0 ˛¬b×r)P$oŚV˛3’7±w@ ŻHíĎI"®,ýrkR[!±›#ďnbűJ$/±Ę1)(qíqűR=ěö)‘€//$Ćň.„'Ń“'qý'˛śŕrQ˛§âń(/ő,2)r;!Ňş&ň$řÂ}¦ý2ß'P?+q X>Ňľ_dŃ*…ů rçq+™-PŹ"Ď0.¶ýQĹ/’’,s#‘™.ň|ň‘i-Ňűę% ńŃ32Ď+S +“О„֞ЬJ\‘Ő2.Ńß/ă pěâÇ_"¤ď"ók.‘-43)+Ą*믍˛L>˛÷8S5ły5ó*Čäń* q,ĎÓ/qÓ7S -3EŮ,‘±¬(îë;“?.ł“2ÖŘň„Î0=2ďSŃ:“%ÓÉâůó· ­·;ňW22])łĺ/óĎÓ‡>óŮ@Ź-'9R»>rË0ß@OŤA“Ý?s 3ýň“€.ă?3‘:Ó{ďäř!Ŕs3”,Ň•4=AAC$QBâ D˛Crł1_s´·r SÖřÄ1ň5FÔGóB°”z°To43.49@Óá’b>Łó1´4ńĄH‰5t‡7toJPÖwrIPŢ>°ÁL”#'”? #M* c@‘EC"ůNSH”Ł&ÖÖłůPßD/™O”Ó5ÔŤ6& h«.`ţ˛K@´UH´ŔĎlł*óU$ÂŁ-°+RsŽ C -ŽĘŤdî÷„ŢĎnH§.­FTJ-NĺTdPMŽřA.×*Ş Ő>?DŢ%˘Üq<€cÚnQlb^ \(ôąMj"‡XJ")E-U ŽË%âęŔqW…VÂ9P¤8ÔÚ&â ęO°Që•TČ’,NŃ NőZŐÎĐ.˛M•@ Ő¬ęî¨A+¤4·^ĘTí˘4/‡_E•^˘”3°/#DfĐuě_Ŕ-ČŽë$Vg]⤰•Đě¨%Ą÷Y‚ňM†§D˘Ĺaěí]ÄL9"ĹVń?V‚Őa">{Lbĺ‚—–DËć,CÝ(޵\ĄŔĄ–me"oeuěŘvOQJAC:ëb‚–°Ň•áV8$Ś€VdREX–ěUnŠ Ę%J¦üëm\ÇqmXŐžlJycđ=¶mkMkѨý–‡Eâ—mÖľ\ßC‚˘şŐĂ’8/ ) EYÖě$BŐo5×nݦ&ĹRŻ6eĚL\Îłr%•6CrĂěf+)KcWl7$ě·)^$Ä4Ct±?WĚŹ^Ăßsqf×aow>ě·BČ÷RĺYtöh‚–=ﯥůâqJŹ®)Ehf4'ŐHúćĺ9öB[ëć"+x–´#”‚˘bŐzăĺx®Ą9¦_{¦Ţ”—™{Q]o× 8·¤%¤î(—ąxwż{6Ž)oˇcóq¶_6ĺŃfĐ× mχe5{nWóou¬,Ł"f„#Öý ř OîDŐ<«Óž~DČi$FŇŽXkŤ(X4ő_sšmĺÎj§dV"k&AN-]•č=Â=Täá!ĹWÔ=ÂáW¨–~§ď‚ĽVIůjX{z¸jT’Ç„v_Ł &őjwî~hšDxŤ‚Vc…Âó‡Ĺ€dSxˇäŐŠ`r. nL_ŚŁřŠ)xŽN¸ľë÷•lĄ*Ř•†O¸l¸qŠEúëđéc¦ç8N1JĹŽxW‰(o-ˇ\o‚ăxźŁ‹Ť„"ď&âń…×23¸ŕrĘ …Xę XZëčUXk¨8ŁÝ’¸o’řr$8vęäŃg“6ą•*Ć2»…îĎ'«\ô7GJlĂşµIŤ•ŔZ€P€ČDF Kň\®Xé–ü ž „ Q˘”lK™„Ś€Ŕ’6„¨J٤?‹™€ Ył›y»ťŔO…$HŔ¤ ‚™ÎDl<č%ř$%J_6c#…[M]•> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R /F9 36 0 R >> >> endobj 135 0 obj << /Length 4682 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h f9• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇŘŁŽ3ä E»AŔŕoÖąSa”Ćt9Lf`€†h0śŚ>s/¤ćtőĹ%ҡ* ¤$TćĄ!ČlĄ*®»ż/¸Ę6„ę9„Ę0Śx®ôŽ+$„ŕPhĚ0ŤŁHŘ<„h *‹K®&Şúr©+,p”‹¤ ą%P*Fk˛ČËb¤†ÁĘ‘ gˇ¨(„› A Šć+ë¸P±f. @: ík¦aÂl°8áĂ*† ‚"Ş.A°a8&“šrą2«"o= +HˇtކI!¤ťÁ@¦)ĘqĘ*ˇ‚-©2É3M8`+塢榪e>#´jâ6¬űÇ:çłňIŚá!@¦ţJŰŞ9Oń˙śŇęH dáâ6H ^KuyŤľ˝úÄ`›Öp‹Ă=¸4Č! #6>Cđĺh7 –±^C‰j é«©Pţ;TŻń>’jw]ŇLA<˛»Pj︹wzöâ Á:°"#‰ôćN9E,¶eřP0Ţ ‰gĐâĹ>÷:E µŽ~©@ŻŐśbk y’2d=*ĺ(u=!¸3‘ĐzAî ińb„UFňÁHyg`ÇIJín ÷9•Ýl­Ł%•LĄđÍ W2č=ˇĹż¦*Ł“´SWUh<7Îë©Ió¸7zěě{­±öÍĹ‚ű,ĺ›6ÄLîĆą¸ĄTş3¨ŹÁ›§_ŞťÇLë,ąŞ€Ň…%@o”‰ PA})¤"·ÇŐ(Çő€Heś—ńۤ,Pçî }ÎşÔ©Ü"™cň¦U4‚ŕĘ Ś54CÁł ˇ×É}ĂeůF7”­±RLN}ę.µ¸ geo€T¶`€ű]Đä8l=¶âú/©Gsťá=Ž9ńXşCž¸†ëś`@™‹}†8©CB Š Č7ÔčŽŮ a.Ďĺ_AÜŇfŚŃ˙?´{Ł´"LŇË?Jfuôv%F›ó+Ű)µYćśĚĚToŤiˇ$…#DD CHîĄ5¤Ů–ÖRubL×úŔ—%Ă"Z‹ĎD‘´‘lŤ.¬żŇ*|l ­Ö~ĐŃ 7LíM™·‰HŰ%m«˘w·¶¶ćŮű“S'í˛ö°4ÝÚ#mjfÉĄ÷¸ÔűŻhšŐ$«´FůŃŰ˙Fď]vDVRžE €É,BSµH‚ť) ’C‘˘Y­ŘË+…ŞÝîÖ49¸3 3@é=ýÇÝj8Ö¦çVľŽU±8ö$§cUňÍ5Í9†űY­FěvNů1.Ó:Ź(sŢmŃ5ťŤzç•ň=GÓ9†˛Ú_[*íGÔôá­\|Ém`dK[Ksý)?tq¨‰O<č&J5¬^Ťłµní|ë¶ňÓ»®ş3Ëý&,+ť0ל$ŠđÍÝ”ăfÇ{Q¦ćłňtă—Ťô€hH‘ "Ä`Ť7Bš ©Wć‰7‚‘/Ę4®w…¬–o'éŠ1¨]†sGďw\Zýť$¦±4´ťč}T†ő„{Ęďqđ}!ż€„™ˇosěý)r~^Ä“}ZjÎů â›b!č˝_ĽIq‹ďű/vKÉbW?óšŘv=Fť Ü‘/寧óöž¸ä{†UĹ–ÖäUĘ ÷a\üB€Nďňz¤îýŠppXäă±â ŤäŠ„ä$BŽÜĺźCj_Ää%‚†$ĂFND°TĎ`ýr)hG–ůŁX4‡ŞôEk"×0HÜŁ*.oap„ Ďëp-g®Žľŕ` ÇâŤ;Ąţ$€ŢńS@3ǵ ÂŽűîxWC,öŁjNÔ=ďh3Ăy ‚Ť2đ˝Ďjł/żC…—T0,Tö-’ŤT BpYĂlŤC~ňďóĐţ@ç“iĎNk4n.trőĄt˘Ö-B pLôĂzUp­<вi3˘Ü, G±ôzL*ŤröôŁGÓ‹%ŃĺHdšX“ČŰŠţQŇŠ6’­L´ť:â Jô~ăOúá ¸ŚT…#Äp—ó i3Ź/C¸˘;*ŇđeONĐ"ÔF®ş(ńOr nT†őGÝÔ6ô”Y’pńP4“Ł.($Ě S«. MíĺFŐ$ßFË ±Q&mT¤v;ÂÍS´=*˘Ç5UDĘH*B˘i"ÎLćn,ęŻĂGfŽ9cIuŠý&o+“éŔoWń Ç’ÖsNŤR'Żę]…‰/BŇz±xőµ˝%ÂAPł p%Ň% Ĺ×7âr(ďŐP’>Ŕđ<ŇŐĺYĄ±đLŇÎżXë2˙#Y^C‘^„ŚŔâYZíň=^mô×/Ť_B†řmä)ź\%‰\e[alí!®żZŇ€ĐńŹóB4Űc¶IX˘˘ÂNu…Ç8ő€ţł» âe4/#ck 6^˘bUł'bŃfŇ*$Čgb)B#+°f¦Ť 6“bj\pś2‘LńvhčńhăYZđ©7ÖŁk$}Č8peÇi±ÝÉąk§AUO)ż3d}a2€32$ŹuCĎó>Ó°ëä1)H¦ŞÚ˘>řvK<Ök=ńőZçB.‘Ź)ňą8Vř˙µRą2–ËHVťqqíqŇŔ·g,˘—í“,Ĺü$ËP(ÂÚŞÓhGŃuCKaöĆ÷ÜV>ŢH8Ž÷U*Ö5m¶˝v_t7ńßt”_2,.s…OCmeR7r⊗äę-µŐxŹżucFřbr&ąHep÷ĎH†bô.§\Ö™vJ „+mU2†‹y˘Ť %=!Ç=+V*¨l´Śůđ«2Ü€’~i/™=¤zu÷©ejv˝x $÷©fS0÷˙€íýjĐ­˛í5Vd6¤ GŚ((w+P¬${XV)‚“euónBŽ6±hIV#DĎ?0 üq7>VňIC°ź…vx&¸lŐŕ8şbwŔ-wÄu“‘[8DÂtR·Ö#ŹĽłBŐWÉ+‚IPPN䄪LůUŘG…=Rę.E˙ -q’Ť;¦[ŚB猓Ť ˛ŠX¸ÇfńÚńđzĐ*ˇi’UäxVlŞŞ,B‰„UVivŮqyzĂm)öä-I w¸č9 Ů¤ "1ŕčL«ą\˙/‡’ ł’bÓq8„&wĽ,Š´×úô0Ë3­o”śh8˘}ř© ‘;ńŕţ >Jz řĽ&/»)ř€ BSŞ ź]—>3Ň ŻđU‚8/‚Ű‚ ™˛ë …0Ńô–gX9±C›Öő‰xI`pĘ#ą˘:óUnFäţ-Ř€Ô3»Ä”Ů0;±›‡%BYťňű‚Ř_kyNŮR'9WöŁ)‚Řr%D…‰÷ŰŠE?~ 9ďĂm‹GFt¬ ·Â–wĆ-—ë7Â…Wúš7Ő–‘S˘‚S~ýv0öt(ĆŞgî´š¤GX_Đ ieÇ'Eť–gő˘ym¦˝?÷é‡%’†©t+zrfşFŢDvD†o\GµĄz‡–·ß§r!7Ő§“éŢHIs§AÚtô8ú;Ö˘9fͪ⫢ZµŠwŕ—ń2w±ď_in Š ¬„ ¬Ú u”ĐźĽR¦Ľl0Z*H% @@ŕA‹˘¶ C·µ{h@ @ü „ŔMűŠmłD ठ#F$g˛†®÷{0Ź€Ał{;łűW´[Ogj ‚›U#a;#&4ÜţPB"(p7‹ ceš¤ő'Ş˝m›7Őnřűźf÷ą•‰¬ąY¤{€‚Ů]{\JŠVĆ&—‚uG’J‡Áë@* PĹĚ·D> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R /F9 36 0 R >> >> endobj 138 0 obj << /Length 3421 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EA€¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ř}IlQz¦Ă)Śčr4Ě&Á Đa9zĆ^ÁĚéŮ9ŠEµŔäiĎ ţ"’éP•ľÄ8|Đ@!łD«Á€`Ę9Żä˝A¨f Ň9Ž`Â<»ŁxÜëŤîŕ¨4ŤŁHÜ3ľŹ˛ ˘‹’ŠŃKú®*nXP$ŤĂ€ę:-‘E1ěŠÔĘ-Ďó2˙p ˙@a@¨ß©ÄĚÉČ{M#‡2HĂ&HHcüĆ@A´ĺ°-HPˇ¸†M2: ék&-ÂÖĘŻKäž¶ŚP¸Ělz´Gëbܢa´äŔĎ!@†Ü ŇdŁ(Đ@şĘ’H¦)Ë Ě†ś†Źm+L“4Đ:°A8Ó”€Ž!‚Ą=†ÁŤQ@˛Ş jĘ´CеC'ADńlTE‘pr+«”“9ÂŔ0ŤŁ(čňA°;Ţ)Ź#hĹ˝A’nŇ3ŤÎŰÔTtT42 /<4őH°0P&ÄOS€ľICČá{$p€š0ʰfB¨ÝvÄŻ˝9­Ákĺe Ď\Z-Upç z$ęĂ+ą ĘŤ# č4\á¨d…¦·®(béÍ!˘ąŻÉ0P+‰‚™&X¶'3óă˙ś$ ­ŚKśÍámĽáDĎo[¸a«M“ë…U8`Ź…s<1Cmg±VÉ[D˝1č[…ŘŁC‰A̤ňŔéÁ@‘qŤ  ËŽăă®C‘Žů.Os†Pv[—®ş"Î"°edi9Đ®$gÚ‰™hvî/IcĚ­&–Ę14V¸š…rĄ†3–,ŇéŚF.jďkŞęő–Ą­kšĆľČŐVÉłműN×UíŻÖĐn,†ć˝nÁ%Nâ»Ţ›@ĐGv)ByĎhŢŘ& Çřü›3ÉŰÝ3;$Ž\÷Dáóé•ů4._Tř^ůÎx+u4µTÔAŤ=`äÓťůď ÇĄă°çJ”ŢŰm ńÔ»‡Äs‚1Ű;Źś2Ż`brZ«.}¬Ĺ÷łCH¨9/® g싟âDćĂ4˙ÝË}€mJ»Ĺ»W´ P8Á© ˘&‚Ä~ C2ůŢúawa)ČǸ „‡¨ű3î!ŹŔÎĂÂÎLPD‹Ýˇ4G #{¨„IÓŢŐÍ2^ĐĹp@eA1 ĆĽtâŘśiĹ846¤ţZ[amĘéę+ćÄÜĘP4‘/id ú˘Bz7FČá˘FóŢRšKEí# ĺ(Ś’Z=Qä1(ÂI-’˛™hIl )me ¦1&ŇŞJt>%FJ+üd[Đ>*J(°@ŁeŇ‘tô©I€Ś”ĽÂt mOLxh¨dĄTň^h–ç¤Ĺš˛|VR]Z(94ŮçÂĽ“Ę®;C•Ść*ač f¬ő˘´ß¨-‰ Ĺk­•¶đ7\ ‰r.fćşBë]ˇĄw°čÖ× nkŕ*/Ąř —ó`O­0‰&[#ň‰íEfőâě_BČb1‚ŘËáTi…‘­šFŘaS’LrŹŽÁĎĐb@ź*yžˇ€˘9·2D ]rˇ"„8eŕ˘ŕiĄË@“‹"$R(eň=UÉă%$´Ř§ čÉGŞĚ ´-.ŔŐýźÓNł@*/§¨®””lBkL2¸AŃŞ7‹Ń‚˘"FC‚ !”9ĚŘĹd €E‡o¬­¬ Aqę!f:I˝xĺőŞ1fiÔHTµHó[+eĂ|ŞłU 0ÂK]hl•¤´Ěť‘…;Ul“4• 79[zÜ­á6§łý´ŕT˛,ań8Ţ­;#Çl:Ý ďd“#QŻ˝3LŐ…­.•K)„{™™vv¤C̉ŕ¨Ď0TČN×-»4šA€%ľÓ†q}Ď%úI˙”°@ ÓBśt“"tŕz—‚I31«* ”¨ç•´ ¸2‚ăqu Ą“¸Ŕ‚ů†Ëëw’`E,ĘŘ•ŁŽŃŮłŤ'G&…ldqIUÉęĸ2M• ăµ)yd±ĺą—‰‚č+™ź2šVÝ6O+äĆ“ňÇ“ “µ*N™/¬őčH7%…Ź04Ľ€˛ţj*jßA’öµ 49:Ńú/A"^JIĆRŇ%8źe-ĄâťŇô“MEĄ4i˘šŹDj¦mŞ5ťYRŔq¬ăĆ© ÄJ±‘RµR:uˇ(•0ZX~Rż9ܢ´0@Eµs7Ę%4ťçLŻ”˛Ö«tŮ‹4ó˙·3nŃ~Zŕťmäűą6Ë6† S,nRx wfŖ̌űxiť©Ł÷^öÔď'o@b•sť ßú<¬˙˘Ú†~ďa‘«ˇa‡ Ń'ËEXôĆíAŰSŚéî-¬u?Úš›.Ôţ.KĺŻäDë”č›Éő¶äă|ł[ňî>Uwć˝Ůúü ćl ¸©}3¤‡MnH6Y/ŕ¤Sť€Ý'ĘÉ7Oá»ď&ó­ˇ°9!ĹăÝ cQCJTúI„(d|÷dŇ EÁ$ň$řÁ¤ĐG•Áję4Źxţ÷ ,ÜHĄ)ĆćH ||*ˑڗ PhI•á~ ¤`ĎęʬM)YXµz–'«QIJ8Ł× "Zş †ČĆ>‹Î– gćÖ'ř…Ř–µäHýŻ˝řŔŔů9e%ô˝Š,ßč Ăb˝Ó•!ńrřź+x~/L RhîýĂ˝ŘĚN>wëď%¨ŞČ`rhI’…./ÚÂu"ăî˘PĆęĘĚN$E"hÎŤď¨őüOŻľPřđ çđĐŹ¨)`o…‘̧đ24/ŹŹ|̢FE rNIEpÔ%#¤ĺ0nPeNČőÂŕúÎYbđ¨Ţüo°€]ď®lĚŇPLNŚ \8`¦ ÔAď(n°ŠËęĐ#đ řĺqŻč,mđҤ/˘D4.ćm˘HMlwí@óâFĆ%pR$ŠĘg.8«Äřâ<ĘÄŞáâR›d«Üŕ`@–­ °ŢáăÚ>&ÝŽ,Ő¦˙`q ‚=m@jú+ŁŤ&ÍĹ $$i0ď ‚» hNJBúXîäéĐ €±M&W &Ęí˘ Ä  ¦„[/ńB%đ ĎV1‘Ođ¨P˱Pä 2#±w°üE/ŕÔŃ›-břđ–YQ‘ŤCd«Q] bRM‰,ľlĐ–µ±˝/ę0˘aÎ"ďLżBđ-OŽ3Đ%¤řôĐ‹ ĺ"mŃů§„ bÜß ‹qťđÎĘOŽ)D"ń ä] úem!qÂZ-Ćj@¬Q!…•%ĽE ) 1+ B`E„‹‘ő rBú‘ń ˛J,RAć–ű‰Ë1ŽËčdí°_ I Ńů(% u’t@Ňxř1Ź#îť-ńpq±ŁF—eŽí°Fřâőđöá ČP°ę¦”Ë 'Č,ÂĐJĄV&†Sb:Şę`8§™&ę†$’eÉ„äî C.µ¦VčÂy"2°ăg‡:G¬”&Č)qŽ^/Ä Îćú¦Ť2Ć»lRĐOBP‹Zę(› Ňą4RŤ “JAÓO2í% ŁÚű‘q3°~öo3†Ý4‰ ]“,±¤ůłJO‘ń+¦ˇ,đ€rÓC.žÄó0Ë*ňÚÔ¨bEłxHĄAđFE/+ä,˘¦÷óšłź-FžÉDXPAäf ŘŻą2rĚ,EĐ:Ť:Ň˝>SĎÖEĄI-Ęa>“ĆëM¨/ňó‡:ď&‚E1ń>2T?g.Ě‚Ü,Ł#.Ib˘i×ĚbŤ©ËAŻ2†u0!0ł$1Ň ÂřE ݆ Yss‡^2č3 g.ěNíŽËđJ¤eD„›4O0´TŰMoŁä‘3B(ćG´kCtpAâ<ŚŇĆţ±GĺHIÇE/• †÷N€I(mIČ©FÂň˘ň!đ&ÔJÔ`qóhĹ „ńf&Ăă± tÂFGëL”5.ÔÓ=Lí‡FF| „Mäz F$ĘIńQ€I€¨DőQ5%R„Ćžc!Q†rǧIŁ!2"FńpŻ6sF#„ĽnŞÓ?sh,t,›%€ ¤Vsç."Ž0Č<-„ÄĹĆ«ňˇ"–Ŕ@BD(¨`@ d4CFGI_2Ě endstream endobj 139 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R /F9 36 0 R >> >> endobj 141 0 obj << /Length 342 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h h1• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨Ť»mÖŠ5đÇo ]9Ał™…r‹_śŚ¨Čj’2Č8×)EľĄQmFŔh·20µ‹išůŰr +÷qA4 *°ăpč2ŽC0Â1ŚŻbäŃľ*BÔšŠŹ°¶ @¤2ŚĐ R(Ý HR.Š‚PǨ endstream endobj 142 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 144 0 obj << /Length 290 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1E1IPŐg#H ÖŘ,â s‰ĺ®ă Ä€h7¶I…´A„¨wĹŤŇyL@S,”Ę„RiLX $“běn PT$uĹ ‹¸'lű$’y8‚L&D"aśKŢH¶h6ńqňEŇNLă@-R®Ç#(6Ü€€ endstream endobj 145 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 147 0 obj << /Length 5188 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h h3• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇŘŁj0‹t!ă­s Ą®Üt2śŚĆ”@\ڦaHÄh(ô™MŢŇŕ¤R.Š‚R ¤$TćĄ!ČlĄ*®»ÂńĽ˘KÎô˝okŢřľoËö2ż¬`Ç*H" ‰"‚*2Ar@ :P† B‚ˇf“(ŁĘÖ H"ä”"I,Ś#@hâŘ!”†'ÁpsÁk(Ć‘˘ä*(j!pf7¬Ż,„¨b“KíóZ(şČ@ŤČ딓%¬ł”ˇ&1.s#F…ÁÄŔĎr´ú˘Ĺ“EßÍ’$ß#ITŁ&IÓĽĄ*PŇÄ´,SM´şó kNKÔXPPíc@ÔŃ‚ĹMUJE5UŐHlˇÔłR]FÍÓ…#:R’xeI SŐkX#Ş@b·=ERSÉ`hLtÝ;SZv¬Ę'vŚ×6ČłŚťIOµ‡ Á9ĽďOÖŮÇwŮQa‹ó~L9ćH2Ł˘őäšöaĐ´«ČsV@rą[Í%´{}_˝úüĎ«Q|µ0Ĺ™aľńHdőnT2×Ó0‡¬îvß=ř]‚O|Ťo?Hęß[†}ĚA`©gäÓYJ;­MfARGÝZJx^7d˛­ ›Ă‚Ä•Ó&¨TŠ3ŕʦPd\é–e¬ DÂäpí dĐŐ3łF!Ě+…ŞŽ&sXNaSA…„@¤T \‡`â&%ňxZÉd:‡€Í ±s8ËbU6«M’Č‘S+d(ĺ®)CĆś "4Y†‘R4—#*š˘Jq¨µDxÁˇjÉ.fŤÇ2 GT´&±ČťĂU¨—M!E‹1˘AB ŁüzęᨒŰş8-°ćC&»˘ €“pÁ-Çĺ8qÖ¤L-îÉç>ŠŠşenLöIKtŞMX"h‹ ťŚKu-!d®zíUM—#nĎÓ4AjŚ“BČ€Ţć‰Dš`Äťż™.©ćY¤…Ó9É„­$ [‰tŞ5  ”âťi:wG¬ł cáö{9đ—“O)ěĎrP— 4íŔ±”T¸ "˘ śĺŽtĎš ąĘ˘V]‰~‹(Ε‹9”ź4%u–‰CgSgPE®ŚŇsIJ\ěüu@ÂŽO9ÚD(™ťLnz©'I'S‰–n%éÚÁÝŁOÔr‡é*fK« TôUTaz^Fô«J°‰F©,`Ăř+]¨sRłŇĆ[M"y­ŽF±”–¨ë(uÚiŐgVĘĄ{ión©’ZÄ ťr©•: Ş4µbÉE?OibŠ"·4GČ2T"”6 ¨ 0[(,ţ%B.ş[AA ąÇbńŚÚihâ„;”t2qEJq©4č˛ÖŢČŮ:7-±'·‚”AsjGču.¤QBŐ{Ydé –´´.™ŃȡgŁ…ą˛¶vŮk$ŹČ‹ÍdM!迊•+úNń13µ4«j•ík-}@ĆoŻ:{‰Éfö(¤ÂŤăŇZuKť˘ľŰęŇY+_O‘rÇßéߎäLŔq•oŕf¸ü/ÂyS őßŰÝS[š0'x ĽěypĘĆ.Ť xĎ/{]·Ūéöbl/Wü$v5¨*FŐ‹Ţţ>p·Óß|s~Q&Y ŞââGŚ1ě°ź^GŠLľ<‚NQAäA—1¤ Äů_#á¬w’śužÉÉš»<Őr&VĂ—E×Rbf{ö†ů…˛źČ†!ůUčfFrł ‘HVë6“»ÜĄś0¶rÇ ä«ć‚Š ÝV?P°n·ĄľL ák+ää±rŠYu* ;…çĘd» ‹YŃě v¤5§3’€¨ ¨I áH(ˇâsőŐŞ°ÚüŞ… ‡‹‰Č…HĐ“kŇo°@W [B;Uí¨X×V×١)í‚]Łť6űpťłő˛ Ň:9ł”lqÖDpn ś’9˝ôçf„}úMŻśô~¨śÓ,]Oč’fX˝ő3ÔGęVzž5I`«,%Ă®˛Đań܆9o.}šVXe§Űâ 5_Ň븉©w€c[Ç˝8#ÓzüČ;© myç>áüŮ­é,Ť˝Şö!ü+~±n—řFâe‹jrĆYérIWעŢB÷.¶Lq·í׳Žđ+{F‚dk¸5öŘŰHy+Ł>ßµ»@RÜś”ď>ŃÚýM'oniđś»A VđĽ;*s~˙Ęs˘ń> M>{ľč"rň©—Ëó\Ĺ‘|9đI;͸+Ýeâ’K$b*bŁi%@Q%˛_&#j$ÂRn 2s'rz ˛~GŁ`HŘ9h¨Đ"Ź2&×3ŇđńBÇ3‚XFk3ęL6ł5/+1"Ś‹“Dń˛ŕNräČÓ Éc5‚Žv˛÷5Se3SjOf 8sC0X«Ó]Pß5 K0s*ÎsvĚĹÔoŇđKča3†4›ł˛ňó•6Đź:rć৉5…%4S»8fĺ<3Ł6ó :“Í; !SÔu“˝>¤»=Ó>É7N S‡łą?9ó$ő˛ă2Ǧ`S|ßS”dčAó7A0i7śFę«8ô"j‡;;4=:űćQFÔ«=ÔŻ7ĘłKNJŤyG$YFË)KÓň(ËŰ=ÇQGtÓ:ż5t©As2}L´ÜaTÁHTçN «K´ÝN”¨,TÔx”ŮPS yŮg™s˙Ešł3”>Ş”l–sŠ6“©¦=Ő18u%LU Đ5>›ń5´ž_Ô˘OdÁSÉ@Ą¸8ó}RÔÔ`µcStďT"Ts—UsŃWBYTłĄTĺ…U'Q7ĚCő‹H[Htř(ÔÇKFĺXÔäŽSé6u¦¨OČňÄUr‰NĽŠIđ9ăjňiH[˘P9ę‰&şuşU‰zŚőŘXiśŰŐÁ\ăP ›\¤˝\ôµÖ$ëM^ClŰÉ1[v]Čv˘µę!ďÄ| ®†uÍa†‚•˙[…8¸ę+`¨1[ŠţtM×ajţŐ6‡IđŻëdv6´Ö:KÍ×cUŮFäśj) b'Pv‰‡d‚…‰,•6 fśADÔ')^9M_>|N(Ô» ¦×iN@(뎠Föc» jŠ]i¶„zéW-đIE?Ü(Łž,älmvÉUr‘,¦ś6KŔ.vÄśÇT]ÂĐĺ…@ťë(Š–ÍoCh´a‚Ňߡ‡Á/Ó\‰Şq Jُ&Ş'o¨¤°ă¶î40¨O«Ľşv¨÷7róZP38--Ym3M_óqbjĄłWtŁ–t·$¤çÁ\÷˘W3o)ip+$(ihóuЇdX©ŽS•E ÷†ŞĹ—l®$í§yN.9öâAk67—nqĺ"Ş“xŐrč swĂ‘x¦ůZ­é$Ĺ|Šę9 P9é`• bőÚZ—¨­âM~M‘y×µ|ősyÖ¨(^ŐC+xKž'*46ĂBv6b&¤©o°úu¤rK7q3›¸%pjާŠÝqĘŞ|$ÉrpúĄJkw"Ť„Kž¸—k„Ąe„w^ŻX<ą8[1éŮqł{3„ż‚ĘMPJť‚S€öń1âĹ‚*'+Ŕ"UXDoU"®łÄČU>˝ä˝32˙I”Cĺ.¨ś|ţ¸ő\Ŕ˝rŁ2ósĹ2‘lRęS+×r¸ą/b®8égoř”KŚ”2ż)~—·>óE‚ÓŽ/YBóă<¦Fe;3hKó‚ľY ´-řęĚÄ`€™ IsĘ«!©Jż”lIEY‘$Ń;9@PYTŮθŁOµ ’µ2T“ůIĄڵS“Ó}JąLPPąCŹůŠěu’9WM Ą•Ô±ą|Đ”Đ9QyY¤oV˛Ë9 -Y{Śtť•+ŃłmŘŮ|sX2ą˝Źń@÷ŃEŤ˛(&Łą\wź—‡#mjímÔěŤxÜ1˘ ŻÎÖĹdŃt3 Ř­ ĎŠîůěۤŕ®Ű‚ć$Ťľď ďq„Üâ Ú1ÝŤÝÎMX9´śą34RfĄ=?“9Ë$-*‘JZyÔĄN@;޵!NBďO˘ ’—ůYʇŻ1…âÄuG-¤®)¤ůÓYÉŮ*˙ ňÁˇDb$Ë.â*şLZ썫 ­›ˇč,s+ š¦äQ»Ł3ý–ŹaYb¤xŘĺ“Xy[—Ů›¦ëňôs”Ź8ž˛“®ÚH÷‘BŻDď„ÔTĆŽ´šŞ8ů@Pů„jť%¨ú¤ú€`úÄ@ZűšTűŐ6¤K_#yň+zţO!çZ ˘jFç(ŮqčţŹě˙ m˛±ó˛ďű łAcµ Kš_‹ŕą#K3%‡xӚǚ5™ĚÍ9‡lóď[’l”Źąů@™O¸şĺ¸ĺq§Zß´¦Đ;ťŻmCśŃďĄ SťJN2˘×©#Őąŕd%—ŃPF‹TÝ‘{˝‘“.×ĺ,›é”ÖČ&Kbת"Ž.­±· ·Fć2˘v*÷Ń·ńä.ŻË»` [ÇC‘ˇ| ®CÁ/ÁGp¸— hĆąÎC˛%ť-1öůZE\9p Á1ŞnrE@sĽíú-»:ü˛!¦şă@¦ŠÔw‹4^ßů ŤyÉŻ›ÁÂşS©† ¶rłÜ{ůâ+’˘,Ą¶4Hş"iđ:1\Jí¦ ‚©ĄâÜ.ăŞC˛„€P €Đ  ć=ŔĘČŮÎ@@ Ř`ßĎ`áĎxśţśâ/ŰŻ$űŹ Ăm´‚ Yr´>'BxOş;®cĚ´í 9äűŞ”-Í€)‚©±Ď§Ń\gŃŠע’ďĘ=+ˢËËĄ—#ůěüŁSV…­pťÍëJ¶:|×͢?Íýú=RúŻ®@]Ć˝Zçb&ÍeŇ„=Ö‚Öɢ+ݨ$CŞBďę<ŕ ÝÜ€ĎĎ`ÜŢ`Ç'@Ř =CúMŕßĎ@Ü ŕéŮ­o7׹ł­€Ú**:`P ÂĂÜČÁ&śŕ=ŔŢ č$ †  Č" ÓĐŢ/ Ú ć€@ CÜ = €Óă< €T:Bî Ŕç``0ÍśBŕ‹Ţ` Ţ2ŰD/ ŕ®?˝wr€"’Ü@b€"k(7ÎÔ^ščdÎ5|r)"DY~—ę¬h;`AëE››çëĂsb˝ę&OlB)Óc~ endstream endobj 148 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 152 0 obj << /Length 1752 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EA ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; EłA˘QA„V´5 ĆApĘAČľçdŃĘ3ڶ:˝[› ‰D"ŃĐ4ăHĆchd ű#É3&90ćp3Hsno®ta\;öľŔbŞ(Ż @ŤĽď|ö˘oKśů!Ź˘ /AŚ ˇ›úö$Á‹íĂń F±%đd=SŘĚÂOŚ) :®»ň‡†ĘT&“@ ÓđĎDZ\Ł0{ÍÂq¤->o«ď´ $~CÁpq*9R2ÇI1„$˙IĎ„0GĚ·"@RĽLś@“d˝7ĹĐpś!Ä,9“Ś ;…ÓĚ÷É,# Ldk3„ìHhx`Źďô€ěRĄ&ĄżŇ<_%Ěqť'Ń“LE5ŇKŐ+ ±<üU;/вUB”\o)S,ü˛OOüŐ*Wö =0ÔED÷T•ÚaGŇ!rľĐOý1hÚt ŤZSőĽ›QĚÖtOlVU`eażKÍ9Ał &Q6eĂ(ˇĘ•T1‹…Vť+Ĺz‡Ř\YvÖł•\Ů·Ąí-JŞĄK ˇ’•HÄ|÷~âxlE}Ą°ňű|¨ô'ŽâWřh®ŕY&3"/¸ĺë{ʶ[YĐ3 ˘<˝‘o^0­ç ¤Đ O»dݎaŚřnŹZ©l˘_]µ=éúL čŐž‘Th˛đĹ‚[·…—źBöpbhlřiMŰF­“한=b$çäŰ\ç·_ÖFëđbĂlěđp@óÖŻ2Ë€b°$hřl–qˇw@ŠVN¬\*?Ă„M °Ą«rĘČóŚ˘Üë;X癩ÄDűs'~´MPŠ"qî°Śß «ëńÎFŹ{L‡Ŕ`övÜ·pż±BxŕuöűÝŁFÓ¤ôt5żÜ… Ę1Ťă Ę9xĽç"9ŐßPáüŃ^b‹äW NeńűoîŻô•‘p ÍđfĆŐ›ţmëI/@§öŹ•šăJ‡­/3S w™Ëa~ •˛ŻC¬\x6(‰î$˘¤ü"@`ČĐ´ĺKS'(‹ěę  nÚâZ°*#Č { L5)páÍž•‚ŽNlD?ŇŔv”ÇŃŤ&Â!óřáÉN"€¸@txĄňçJÇîąebg"ŞD„qR)8 ˛UÄJ )Ć•$s¤%K Mś·- H‡ŞÁÖ—s«á‹ËDzDE6ľâ ‡†đĹ~µ9 •˘#ŹEkž>+ä…b TN¤>M8ŁŤ,^‰e Ć#úhUz„D‚Ę9 žá‰ŤĐiÇ%J%~? LÇ©9 łđµgÉ‚Ő0ä\††Đŕü/¨ÂţbLĎ[+VHÍ9´^Ąl/šť`HČšV‘ž/1JZĚ$NČbĘX•3~hĘähOÁ8?2Ň`΄ô¤&,m`Ž ‡„G^ęŔÝs6çóŤ ‘Žąĺ‰w˘ŽN‹˘ňA˘ \ďtśPĘ4¨{ÝdLJŤPwjQά@& I¬˘»Jäd7‹Ţ’şr\ ëÜ+´xžDuP^ěxŁ0°š6ş€é4ĄŐ>‰E'LY‹C©-Ž­á‡˘ž3±‚‰éÚĚR—O€( Ŕ.đ-xEL*C[kyʎPWzÜ ^|0ćĄđ ü 7Ż˝X Qbě }H"ŔPBŕ)˛긗ŐúH+­~Ż&BÇpĄe‚/ öfÍ™ :¤+Ąv±őţČ ¤B›Ŕ§2S([-C·5éő%h2ÎŰń±Đë &A!a3ta˛cľůz¸.[ó&í«łľŇń_÷y”­Ë‘îÄs»SÝ·şůĘÍ&˝ËmBKČăzeýŰ2óˇ…Ţô€QçsšľŚÓ–‚Ôę)DŠ(ÓKI–ŹăĐ †•ăšHg§iĐ©€Z ť[ ł\âBŽM_Ëą0&¤-‚‚”@M T܆ŕčůĂ0a a”Z€ĘK¬ś2†ěwfAMrčbč¸ BčT @5ő endstream endobj 153 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 155 0 obj << /Length 343 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h h5• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨ŐöÚ!­j3‹‡o]9Ał™…r‹_śŚ¨Čj’2Č8·)EľĄQX†Ŕh¶8J=ÜńŤ|‰° +÷rŘ !9/¨P4ŽĂ,.Š‚SÚ¤;¤-I¨¨ű…HÜ:ACŢ7 Ă(Ć: 0řćö1Ŕj endstream endobj 156 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 158 0 obj << /Length 290 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EA°¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇă>'#(6Ü€€ endstream endobj 159 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 161 0 obj << /Length 5855 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h h7• S"4˘ 8‚ŤĹĐiôNĹ G" ˝(- †ˇŢŞS“Iĺ1L˛S*IĄ1`€’N!‹«5˛,ĆAŽA†ăH„ŠI&”dâÉtC! Ć6)FZKIŃi%rŘ,źIĎä†#apßK#Óćv{YFr_1™×¦ó‘Ô]˛ńxňśĘ@TĄÍîűE`)ěĆ1N­Č@ &Č‚!ČŇv2ś°Ć㧤R9Íćăq”Ćt4üÎb’éP”‚© “ą‰Hr-ÎęđŽ-ö@ŐĄÖH¶Ł!÷¦%gâ“n-Ś,·î=ŚGáËj-x>nšÇę@s\enU—^Ů…óg敚D٧a”…ŘuÁwj:žhâEť‹f)ög|ŰŹ©äŮ k9*ăŹáífŹSëő^—±ă6ʉrG᥽_ďKÖ¶ěŔqcîJ’ŁďX_ŰőB\Ăih"‹Žň‰d°ăJëdQo(ĽđaÇ(ý%Î5iÎë|ZZfÉZôyć;ż\ý¦Ł\Şü7”Ű8ŰgĚŁüß)Ú6˛çŐxÍ^ĄÜ"w^ôľáůśźZß«‹\xŘ´…Ąbú(s† ZŻP;ks¨* đ`ěFN(Q>ďăý ¦he÷’ŻeÓËÓ˛í]Âs~ńíŕ(ËA.Őu‘p(É)|›“Ďé˙±ˇň–":]"ĘÁů?@pýźĆP–>H2˛j §}ą˛·5˛čňĆÎ/;°ë¸¤V0ŁD»'í“k»Žîýý¨ éJá©PŠ®Ś<'Ś!„đš†nv)š'Eżv5f:%} ş˙Ť[5…˛VĽ&óĘXN@ °‰j‘VŐGë«iNÍĆq÷?DÉÇiî}/$˱ ÝóÔ$Ť †ÔÝřvNĂfX™ă%ÜŤ«ŔÍ­>%9§ťśă0˝żÁxçÚ-Äâ\ Â7á• Ľ[ď ÉÂl˧ŢĆ×|qľú·S ¸ÄäçhiҦĎ9Ëżhç>cŹŮŇ" Ęaťâ@sąĘ-P’ŕ“R©Đ —B\Jß4s8ţ‚čA·*růŤ€gšŮžŞôšőL :śőK6[›^›ŘłC.]¬śíĂSAÇ=aýËíŽa•‡TyE ¶wޞNsn®ÍúÂţ>W&µ,™(Ą„PńŤĂpa “Ě6đĆÔY1૦D«wXÓçBŢje Ţ9Ţ78Íś‰ŤCqo8Â|÷¦đ±ŃŢ´˝şE)*ř督“RjO ©D“%Jd–0Ć P$1A§ŻwÜÓ5DMHú’űuŕD=â O ëăauPjZ_‡ż?Ţ•_Ą˛Đé­D‰¸ĘT>˘’EĘUŁ56ŤÉrž±ôíQ‚Jif8͢çŕnĐČ4jîâľ®§®đz˘]#j%Gžsg]ĆtH:-+2Ŕ¦¤gF.p8©äěĄ ©j-"â_âŃ"J—Ą˛žđ ¦uçścë\-ş“mĺL¨u+í¦¤{kěoÂ:ŇëW®PŚí†xUđ–7Ëě3 !đ]ejE+ Đ„Űđ‹âÖvÂĆzz"O °‚ď ľögşđ@éŇ,°. ÂÔ6‚ÔĂĺĆ*äIGŢŘĂÄŃÍ §ňĐ-&g‡¦Ăě^$‡Ž•±Ĺd|äĄügHk $דb`˘Ć$¦Š\L r? GÄMM #X\HĐć°ÓÉ}n§ íżŚ"!đw …Đ[¦ 0şš1.ĽB 0B¶%ž†đ6cg˘żËČä`jFbün#;L|É’Ŕ§hoĹ*-Q¶H…4$ç—ĚĂńĆE‘ÖŹRčńŇyd±nçe*K§q W‘łĆާqÜ$Îâçĺ'Ń‚$É6ď$DĘ‘ć4ň|ŃŘA˙ qłlĘjR"AĘ91Ł24Ŕ˘¨ĺ†xj¬˘äR°ěJP-R›Ń4ľĐéŁDŰćŕ ci¦Š6p„H…‚ľĂo'ŽđHŚ€(/L-MŻ"˛Š‰ŁX‘Ł^ĽCD‚Ž“„hŔbť*j0HŤ<2iĘmgq*˛şÎÉ pě`H„‘+С«-.ҡJë#:·˘+Ę|©ňPbĺ©#.ĘŚkíhB˝ĎhĆsK°jń––4ŠĂmP§ oCBălÖ¬}$wkĺX-b¨%ŐĘ,Î Uě®mÉyF˘ŞU;ł@€7 UđćMŁE§Ěo΋A—.E„ěÇ1Ç<Î…ż,¶¸ÓzöÜöôŇHsńB‚H-Ó–I„śJ6;ě,¦sžPlüŽż×bLŐ+wXH/âN)¸®7NäňL7r-7vůd˝wĚĘ8·—xb ţ7ZM…Ĺ÷”ű@@Tt¦·yNďŔâÂĽŤŞ::—Ä1@Z#ăŕB@@€Đ ćžcć>Łî? Ü0·čř`Č č @ ŕÍ~`Đřwž ŚMB¬lÄ ¬”V Qŕ@`Â Ż†Ć¸ 逸žK$Đ1Q U„®B×X÷Ř$ñ~P-/Bř @ę ŔĚ="~ăę  Čř`Ě ăÔ 82,l  ÚĐ«Ň ŔĎ~`î~8$8ř`ćŞăĐ<¦ ç… &%@Ň©$Ô§ÓNÄÝt.°*/ ‚Ö®U݆š„LăřáM«ŚxíŚĘv98Ô-xŘŔěáU.ŠéŤÄĹňÍ,e¨AŹĐ"xţŚpyDŚ…î`ŤY+0IĹ0´Ę,xÎ÷&ŠnŠVóŽçNăC‹•A•MúŽąB"úH9JŹYNä™_‘F®X#E—k3Eő–yGŹĂ·Ťypô.‘, ĽŻ@Tps‹ ¬ĺä–¶G E -e4™˛l°‡›e)`®úî"jSY¦áů±ŔEç¶U9!”™Źôdoš.- †Őž–ŤöÄ9ѬÖ`8˘ŁHí;-Oü§âHá·Kł˘ łĺ¨Ú®Ź´Y]EŁżÚťÚ^˘¸›Ľ`žÎŠť8}Ącížş–žqĄŰµÁ yçűsč^îqýÎL_ ôÇĐł Z8¤ŰJh¶„ÄOżüľ˝^PĘžTĂľX-Ť=(:Îż GnýäV6Z'”Łe˘LÝ&+kĆĚ˝^ő)Ńý7R¦䦔™?"źń2Ľj~$żuzýVÄý(U},ín§ŃÄŹˇÝkeJ©ŇLjĆýxů_!ő-.¸ŽąâŽI¤Ł©QuSUĐĂď ÎPÍ<ĽK:ô‚‚EÚăüşĘ• s›U/¨EŮGÍä  !˘ň0ä@1 ŔŃŔ¸p7A> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 164 0 obj << /Length 3173 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EAŔ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; EłA˘QA„V´5 ĆApĘAČľçdŃŽ0\1ڶ;.FŐ”·EĂK”3ĹäÎ „QśÓE‡ÔŠĆ“9×µ!ń‹¶R'`dÍň޸ˇ‹¤ľ OcÜż±B<ď*„dľąďjü“ą B›ř˙0 ®ĚĘęaÂ!Cpl¸ <¨şîx`čŞn٬ěÓ¸ł-úŘđ¨ŹC3 ?íf”Ć/“čű ŻÂô  h"†$CŃöţ†°ĽLČEp(A4Ĺ©$ź =áD- śŽ‚ŻI$—<ˇďpn"`¶'@&b @"CHě2ŽMČÜ:RHr cxÜ7 Łč4ÓCRęÁŠoBÁ€R.Š‚SĽµ˛łLUŻT,ĐĐA@TľÔnPp #p@: HćS4Ý;OÓMʼn*ڍč<„xÍaŤ¬E2LŐ]Z“©sRôĐĐpe\C‚|g4@•šěç UĽâ’ŽŁč R­žcŰ*Ś6=0Ţöµ±mDs,\wĂ.)QeĎ8ÝPd†M)%t1MěN†śr˘>Ó€mMč[_NA†Öµăę3 Ô‚cÓ(É*ŚĂ}"0ßÍě2ŤˇĐ0ŽĂHÜ3Řc¸ßjŇ#n…*Žcf™*‰‚’9·µe]ŞęłšĽ˘(x@‹#ŇaZ…Ő*!R塰rµ$Îr•ą=aşpç Ę®ő¸şŻXp©4ÉŇFŹGy kĂ©|J[ĹŐ!ŽIRäApµ*®Â<˙˛şëóI×-–†ű·Cц=/:óó/BäÜŢH“tę_Tvť˛Ä—żë×6Đ÷ŠPho €aá~&üyĽâĆ0ĎţDňęb–y2ok´ŢÔ˙éx=Ż›Đ‡ ě.–y^żłqű‹Ýsďá¸sŮřŢBuú9ż·BóŢ‹ż&h!wţüëözĚő>Xźâç~ŕŮôś×[ $ĎméăşZąŕ¤y-š3 ă–„Źˇ–¸sŢ ÂŁSQQð G[ÍŚł‚ú–ŕ›Üz9ý~GOX9'Í'– h Š 9Gq&%Ä×'tR ŔÚ!DcÔUQl$­ÁăĽÂxŕlďH—˘ŇpńÉ$|dčöˇ‚oŕábŚń=ô>¨.Kcqăq1Éř’ŇÝâŚSx˛ äČł"ŁTl ±r,Á8A©ˇwPÄ<ąŮ!-rÍěÎşđ˙e c Ƣ;„V0)N\"·neŚłueÁ šDöH8xR Kă,\%«Ä–ĄĆTË—jčfY(•!ÂbFßâDP… ČőfB_`cs4ÎÖnDéO.fp/„É®s›6g8ś˛Ž8÷jîÝJ©vSzN"çţRž[ě‘Ŕĺ‰ÁD0HâtöpđN|ĐäAL)!RΙ⨚©˘®Š^Gy쌗s=RgH˘„¶‰ÔfYEą˘ăËÔá§sĹ"K(€Ů !ZRß59”đĘ #JÝDňńŃ&©xhRŮĚoÄŢT2řśSš'„†5B‚ uYiyxŠŹË$â…HüKVHudý0‹Ś‰  $4«GŽ®BsÇ g‘ÍŽ'9TĤâAxSBíŇÓ¦ăOOůužNΫTSURX]K9µ5Y±9ą+bĺ”±öY9.¸G_!1 «ĹÝŢĆ·Bx¨$/ &*7ą<ŹR‡`5žBŕ‹§t,3ň°» ˇp„W‘4şßžĘoŇÝÇz†zS:jejÝ© V¬‘˛'ĺí§$ĘÚ[cŠ íÍ»Ąé6ź†č[L0†J&ľkR!Ób·…˘‚@D‚Ú#ě„»Ý0dFA&ç1ćĚ6[(Ý1"z ůٲ'ôUn˛°-×f®×úľ©•I"´U8âYO ¨ •ZěťRŽš,ă%+÷”D˘ŤUGFřf6..8ßEđxq®0=çbřâQŢCŇ;ęYUD  -Ś˘É1Ç%¤ čŕŰăŹĘ”őĽÉ’?Śó©˛ŮÍ"úÖRŮ!Η“ůǸ‚Hbs‘ÍΓ ¸ÄCśgłE€9¸ůŐkłĆžËSW )=čsűh«¸ę“¬‡Î3‘şOmĹDľĺ2ćϝƚ„őĆDGqÔ“íő@çDű;"93ýُPţ™Ęş{ÁĺÜ1ĽŁąî‹:żYyEőĂ™ţ˝ ¸ 0K…ĵvîŇýŰĚO:óűËwŇZ .ôěýÚĐů˙&J<Ż|íWWVÝt‘hřM;‚çWHÚâ;Ż*šĂS•}Â*·hדľ˙Â_Pĺď(ć+TX™NżŠ?˙5Ţ!YÝÖ9â-I%GëʱÇŰVß@›t€Ň›wÇéß'ÁuaÔçş¶ń$÷úŰăűçě\ťćË:`ó®Ôć*1‡ďây§>öÎęn/J— ň­fIÎüĺ/ÝďÚůo´> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 167 0 obj << /Length 358 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h h9• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨Ť»mÖŠ5đÇo ]9Ał™…r‹_śŚ¨Čj’2Č8×)EľĄQNĆŔh´g'Ťą”‹M|‰R»Kb‚ ¤fČŕ4ŚcŘcxÜ7 Łč4ÁCR.Š‚S`†(€Z¤-I¨¨űżc¸Ň: ! Şá@Ă ś*±Ŕj endstream endobj 168 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 171 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EQ€¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 172 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 174 0 obj << /Length 3751 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h j1• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;/ĚëÓyČÄj.Yx܉NLe ·Ô®ŔŇآv0‹F#!Ż?­s1A  ¨)îŠ'IŚÂlÍćăq”Ćt4üÎqIĐĐ ‚ @f /¨Ř‹˘ ”‚© •ą©Hr)J«®đŠŹ[Ú÷ľ/›ęűż#sö;żŻüŠHË«Jâjݏ«hžˇ ]¡°nC!@¶#Łcŕ2 㤄\6I°Ć4 #ÂűŚŁ@Ą/b™Č˘ Ú¨Š*"*˘ŕdʱ‘’l°.A«(† “@PH@č9‹łk© 2$Ѝ@ÉGiHl¬aj) "Pía\µŽC+Z ‹“¸­,Ś#@h€ao 9UJT˛ŚieH,a„0’,AŔjšÖMŕbHŔ]]&©bŇÚ×ö GŃm`eYŐ(‚I‡+]Ť_Xr®“†RŻd[* ކ‰®“ÁŤ ¬w-śí…×M¤'qőś¶Öµ˝éx¨¶5đŠC răŢÖ5 |­ůg`řXuޤaÖÖ`h˘ę#!7Sâ•UYŐĐ’XŞ(ôu~äÂE•^9k»Fa•ű”†4°`Ř!–qťYÁ†–h¤áË8»‹aUQÚ]śçs\"•fúľ‰c#¶b@«§n|0–f™b ˛f8Śăh2Ł8Ô&=SUíV† Y _“ćv€m[-š6Ŕ®\n´áwđixđŽîW¬ÜĽ†Ă`ąOÂi<›X1cXĺKU;Ý[žďčQŤîŘţó‘ožKŘĺžcËQĚŻ”öüU¦ńş…ˇŠřÍžąb˝×3Ű6˝ö‘tg{‡E»ô›ÖGľöu‚EŤÓÉB%ÖďM’u7U™ňľwҢýś¬^5ź„N_Žłůů?vwŰ}ÜŹÖĆ ŕz®ÁÓ7RYŔ+…­1(Â(YbŚä5ŕŰ9Ń •đB:m;J¤µ‚ŇL ą7NÁL"„CڬÂ2mq-Ń5>ťJ¬6fśMK“F&°ŕ"¸zĽX’q$°ŞÂ&Ą&RŕÍ CŞmËB6€ ¬ŐvŇ@6 Â. ÄSř[!&ö5Â’ĺŤëuωë»'Ęí’k~Ś@Ň„˛‹H,lě—:ČÚOcdo‘Ţ9>K[óć ÉÁ»†‘źc)`ďŞLÉ ‰ś 8€6)c˘€2UE%aJ˘ÖtA@C á56“4g(ŃŇ<9HŘ”+3VŰ AŃŔ #ÎTĘx,`¸@ęÉćĐĂH•˛XGîZ„dĂ. ŞĎN‰Ů5&ÄľMy9N)Í3•RJĂIőiř©Ă\ Ô*†| …±°vŁ•˘’Š,őÇ« @¦TŮŻ{Ş€*9őZ\@|I2‡QÉ«K^ŞV?Bňćq‹c/e‹‚ťÚ>J ©&9ëZ’śvZÚ]*i¦˛Ź) P]şô¦”š›Ć~ĄÎ}4i$ž Óę]PIbä(UŹ*J꣧#ł|Aj9ŁŹ2«SJ›TęĺP µ~­QšEG*LŞtišŇGĄ›Ív2F<5 VŤŇ‚I®?J˘Ĺ^ 08y{“µ€P¬µk&‘«ÂfÓ‰87ięüă‚U,;-EŠ-X3MÍśŠčą×ĹŤ]ÚFQv•·=&älńˇőĹž×7˛ŕ$GumśŐŐenĄ[˛Uv¨Łk„I«ż¸ÄŐJÜŠ®w ­Áą–ö±:YlŘĄr€°× łmnÝ$@Ň Ű»™V­đ Ľ•>Ž\yNéuí(w–Ö ŃXŻ]ć(×Ţ«Öű°»o»ŹlŘ)÷ż×&{Ýí^˘‰~¬yÇG—ŹÝ"Ř·oˇĆ,U— “»’śŻ¶Ş÷’żŐ¶XŻóٶ”KŃJęĆÉ„ ť2‘TĘrç*eZŞĄčŹĹR– (……Â6{ a<)˛Đa Q‹ÍbXmŞDHtDÚ\"RŘFq•XŤ‘IŮĆž%ĺhťŤČ4R«QU4ExĹ   6ڱz¦žXĹ  Ań¦CçŮ!đEÚŔW‰1”Ś8Ňđٸ6šö?Íü†ĎúNDÇUwńdvĹŘ4µ]LŁ'ú˛­XZÇę Ż'îöÓ5ÓŔe-`-!tfLĄ–UjóbHŁű2‹Y‹k¶[±ÖA94ňŽR,± ×Úç`JŁ‘hőĹ„m:ÎëM­5}©ÚÖµĐÚöéôľŞ¶Ř2ÜEK‘o.t~ÜŘBáÖ"‡§®fíŞűż]MçTµ&ösđ@ŕ­5€Ý1”8Îi™Q\2żÂď5¤ÁÜň![ČÖ>(ä™ ál/9C‰4~qĚÄL:¤”ě•r)2ÎzŤÔä[ŐĄ#‡1»÷UŰwÎć·=çÔۨÔjEŞĄő?8!Q Ť ™6‡©ˇ‹ý’ ˛–“ž[– rŽíď—Ĺ™…Ăć$Ć™–ei›3ć1š`ŘĂJ©®•R¸tK3rsÍţ­8NLL”MŢ«:¬‹&“Ľ6OË<ŃŠžĘ‰Ď•El•,ü(ĹĐ# NÓ Ģ„éíBČ• ňQ׳ĆE4Ë(\˝U„ÖeŻR•$ĺ´‡ůO^k.—ł(˛Ş‚Ł˙pŐ™a;…Ι’ĎrŇ=ÚäŠlďăűBŇP—Ć•ešüňyI. ĄL ŘÚÂźŚŽĽŮE6źwţäDŐÜlřĘ<±ţ|ĹúŻWě¶ľ´äDżŤ×ź¶ţÍż~n’Ćő ę"‚LWďŞ×on$C¶ĄO¸!đ˙pţ¤0gEr÷Ę’ŹP !ĺŇřŠY$×l@«K4~p?FŽú$ RĆökO®¦†z6Ę9ÎZ«ĆýŔpRĹ>­0jü@nˇj’VŚ4,Đ| °đqďođ Ću öĹ/Hd/LtđÓ€ryÔ"pnXjůP®,p˛-MÚF V‡€s k5¬n-i|±«&Š‚N[0ÄRđČ8Ƥ¤ë ë4ýŠ{EÔmÂŐ ! ®µÎŰďFŽeS gÉ «pVhýĹđSĺdĽ°‚Wë8ŞćzRŃ2…f­1=‘6a‘&üQ*Şë¬zq˙ďNjl_‰Đ© {fÜŁ°1 ćă*ĘO’ˇkĆÇŹÎ[§ű Ăŕ;lĂäu+Őч/řşďüy‘^ő,ŕNମ« Ĺ~$Ĺ*—±|f†Çě‚ČhDd,Xl”ă š†dRî„ltď@š ćî@äM¤tů&Ůę*¦rvV`d„G\‰VȆN̾㦤[˘Ě‚ęN°ȨžÍ(|ʲ<ŚDbŮ@§Ü†äĐ8ěę*c¨‹Ä‹ăĘĎ(ÎĎŽ`‘rtÁą±Ľ¬p ëV…0·±š·Q”“ńŔč˘r‚GĆ'íxŁ%–^‚Đl1$áŔ¨*¸čd⨦͒!ď&.^Ň®dĐ·Ěé&˝F_«{(’Ý/’Q’’€,ý,Ňw-1{-Š,˙Ą-N!ď•.ńµqińm((^0Ă qŻł^B' 0ěf¦V°Ń EśYjť ĚUFž9楓1…ś[b®+ÓS ¸hđő2M®‹S!łhۆă#cqg'ł'âŽq1IffüĎŨ÷‘91J´çÝ8±©8sšËž±VŐ3-sćě`črĆ‚‰’˘!ëBGjµ0Ď\¸.čA(I+ČPâč?î6MŞT*걳čTËClZ˘RůnDŚ2‹Ń|ĎS&îXŔÂ//2ΑRy-Hí/Ë8Ź“0S)C CM"”±Ćv1ĘFcžwÔ‡ÉÄ–¤M«†Ĺ' rŔ–)fž‰ď7ČB†)BŃŞ^±Ž_q-GłŞ[ŻČ¦1ë-ôŽ÷t€Äl0ü"I¨;S;“…3-Íf±çÝ 3^ů…m3“/3ĆĐ×sCJ"Ĺ4Ť€¸"ç5Ěe)5´Ë3-NsfRÓ&mµ24őí»7Ž]Brű;˛Ú˘3Ş\‘JĽp_J5*~0m:ő#Q1R÷:QT˙łJô+PČ)qĹnôÉ^Éň,i˙’Č@Ř ě ´.‚=@¬ĺi&rŚĚ÷A®]Bu-;GPTfý4 -44fkŃ[sč3ľMÄÄúJ("&h•ëŃÝ&3ţݏ<µlr@Ś$ š Äě€Ţ Łúî@Č™€’ ÂI@Ň?`ÜI @ ć  Č0Ăü서AH?V O`@ ö!uś+Žě'/(ĽŹś„ÖﮨĆd⯉ÚNđcÄ’c$ëŢ—j» âĽ-UŘ*©Šé’'e,ěé šFr0Ę8Jnŕ›Nč+dŔĆcxśVRďŽýdĎˤî\Ď ń·\ÂË\ĂBźă˘: śI ĘH˛¸#Ě=nČ ‚¸ž ÎĘ Ä@ `Ř ŕĆ `¸ @A Č  ČÓm`Ć>`č )ămÖú Ö.`Ć $Ś č ŕĺohA6IWn6*Ír× Č` ¶ IăĺDţ endstream endobj 175 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R /F9 36 0 R >> >> endobj 177 0 obj << /Length 4714 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EQ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1˝I3<t’Ź5D/ř}IlQp1A  ¨)Ć 'IŚÂlÍćăq”Ćt4řÎqIĐĐ &Č‚€¤d0|¦ÁH´bˇ€lç…Á€R.Š‚P"¬Č2$Š޵…ÍjŽ*Aݬę@˙4(@9 «®«CHŠ"ČÂ4Ž((\†Â/± dá!L‡!\ľÁj¨¸f'R…"HÁ˘úH ď ¤KPk)Ň r±&ňdËRŰŠ" lhľ†ńÜŁ)ĘłTŹŁł|»8 łśi/ČňL—0H2Ł#I \ţ–Ž`hŁ$”\#qŚs˘é731ő@UHĆQ¤mKGQâM˘”Ľ ÉC.$‰5SU‡(0m Fu„Ŕľ8µ¨A[Ă*ŠX‚וdŚŐög^Ő¶EsaŃ4]?T4¤n‰Ňő0AMQk+#/˛‹r<˙­LÍÇ?†!•4-A°c!Km –0Á@¦"íň ˘a”Š˝H7Ĺ_ˇđ_°3…¶hą@ˇ˛Ô*`aCâ"_OóJI‘Čq1AŽ2Ň×ŘlSŠ`Śn)˘ &OŻAś¶¶1.uŇěfN¬ AP`-ˇ*^ ©É:jŚŇĄ'Qˇ”ť1Çů•™#!•ź&ęV0j.µtŞÚZ‰ˇlZ6‘Pit®›lÚôÓ«kWp]ŻV(.«©ëkîč±%ô\‹ěúTé¦Ge3Y‹†´”jüG_VęU…0/ź#«Í\Ż˝rimSÇŮĽćľÚ(+ FSÜ %Áí\-K¶¤Ď»_@*%kşö[ÄČvójĄöťß{5wáżi÷Źü¬vuo‘áŁ7iőu[luü=6˘S´wUjđžÂGmmÁ‚<_Ň6%Ţ Ttî}§Öýłŕv“0owršî$‘ž3Ľ4)©űąŚÁşL€ŤuÚ’”ű`ű|ď¤Ŕä ŕ‰‚kýůżUöĘ+€EďUk*GĆěh7'9 ¦eúű ’]е ÂôŔůˇ‘ Vě1–(Tď!šż€íTµŘ <5‡¤µé-ŇĚZl\HήdfşşIaíQ«–>hŚ!†0&%{PŰÁF_K¬‘­uÖ‘ËąÄmz.;ČľrÁ@A+éqĹRąŇb;C$u-7xĽĽ‰0( €Ŕŕ1•ŕ˛ţHeM”H P Bŕ)_Lůî(ŘDŇa#áiĎ‘ŘĹ•żÔ*JI’•~(4¶śů-c‰°%¤¸—’˛Li• ±ÄŇL‚m$’˝;Ë`ˇSÚv—Ęd'Túˇ Q0”ÉBgʢÄéVôP-fV>®X˙ä "nf1_®ň>h#e_,-źhĹ^ŁŕzňŽ1ĆŕńÝłĘv/ˇÝ$'  ‰óĆUŻ ĺK*>JĂžÍáçĐW˘ôŢűiZóŃíDĺż6âšäZň»RęĚŕ¬]ŽćÓĆXÎc#LkK±´ĚĆňÔ’7Cr‘¨ő"¤Ţ Tpľ5d‘0é¤1R.F°°[#Í ’‚J…ŔP ¤Ě›,ŇuÔÂ9ĺDÜ3P ÍÍIRźÉ5\'R[§†d\ĚʬŔČśK¸’™ĺůx/S µLdećue®Ću:'Ęż4k§P‰úhÍž˘ŚÜ§4np0…`…_âî^˘ď*Í˝R2öTj‘$o„”ľ` _c QÚC$—)ĺ2ś•é ‹Ň][ t‚ďĂÝ"í—N4VËŽˇ-ýǵi1¤—äޕӱkŤáą7¶ŔY,=‰Ł1úťŘÔČŔ!RżIhͶl»´‰)5=éfzYšžŮM‘˘ę EVoúHt«TZg~Üv«|Ë:ÇeÝk—ôI]‡ZěęFśrY Ř@ˇ„ěm0ĎôîĚŢE3gO= ¶ëŰ ĎT‘É@¶¦üXm÷XQ{‡·Óř-Ë·™®Ĺ¶$–.čHФŠ0†Ö¨˝éwA †Âjú-Şá‘D*\šiD‹w˝!·S)"őÁ¤3‡TH ‚:‡@ňDÁzý7Üłô@c „9ÎC‘ëäAŽĹ" ]b ľkřu>IŐ¬ŰéëF(»•@ŇyO]NčÁ»¤-ľ—Ózxr"`Ű©őS+y››Dľ].uÎ˝ŠŠ"T›ŇWą©Ţž†Ýčťżˇ$´Đ˘HÄůç!ҧ˘!ű2Dh” Ů˘§Äž"µŔđÉÎH#›VM¤ŕ—ýN ÎeU§˙cęČšţK ÂäX˙p×_Ľ±ÜŞ6źîîD@©)Ę|’Ü Çą#ĐĚĐŻŇ=|Wz1„“ëI2AńĄ®IaVřĽD…ŔęSĚIČľ’D thÓó«ë–†˝™ü?ˇĆ)˘MgxĄďúq%v­¦fLc­v…OPknN$‹Ž)p´f>$ŹŤpd+°$őpLB ]âp@PđÜĹËMdĹkĚ4+ÄJ¤€jĘ÷ç-űtł]nďň_˘•@BnVđ& Ť¶ŘV q…ßv6gveü.%u”!x ŮpT4ź×WxČ?g—IIeO—ŠĂyŇ!qęV®4ŚĆ7­rô‹H cbAITkz7t5WUk–ůuëT×Őw–ÂÁ5.×eu¨xĘK—qRĆ­Sánl=SíxXTUëyUQ7Ö˛y‚ŚŽU{|X!,w-*Ě=Xöµr1XŐšCw˘˙5‚8CIö­WVRÁ…U}–`÷~¶Łspő†=%l#!&őmÂ9cwm†‚9d€dµ…‡=…7+ÇIp„'jW?‚bť‰×·¶š#ö“ŠiŠŞíŘ>íÝGśą‰”gcň;1ŮXMąŮ– µšXűUŃ'ŠŘf§ŃhÜÉÔ?˘]ůúąţz yúg•syk‘€j“4ě¨Ę|óYOxÝKó§L(Ý:óË;LŢBĆ„Î8ů–•·<Ę,b™ŁőôĄDc´ő`mˇŮ˘xCí‘lÍ\ŚŃ:µÓŁPŹ6Éѣ™¤ qŚąŞaă^şO¨:SLV[ţĐ`o¦Řaš#¦šZbş+§ă§Xé§’B)UÚ!ú’’רy©Źó‰^¨MŁ?¬k»ˇú/©şkOjśĄ_z©¦uýzł::sŽe§‡†°ß¨ÉŹzÍŹŮ!ůŠúÝ©sÚŤ‘bĺ´ödJŚd‚ Zl_¬mYCyE‘˛4¨¶|f…qbŁ´ŹQ1Dk1Ź:ÇdZoB@Ł’ţWĎZľ açxWÇ3·KÉr Î%»f4Ó¸Oó¸»j«›o|Ů騮[B'Q¨Ú°%o›”ş$â‡Úâń]„™QĘŃŔPăîBa°Ľ®@ÝÎFĹNL‹c†ĺC'aĆ/۲ćnjćâęÎvç®~.‚N† ć dH  ÜRŇ`ŕ €Â.† NÖí®”éŽśŽ ęF-ě-ĎtJC1®ŽýĂbŇđ>ěTöE`ŘěŕĘll endstream endobj 178 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F8 30 0 R /F9 36 0 R >> >> endobj 180 0 obj << /Length 372 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h j3• S"4˘ 8‚ŤĹĐiôNĹ G"Ą©"ŚĂPďU)‹I¤ň€¦Y)•¤Ň°@I'ĹŐšŮc ‰G Ăq¤BE$“J2‘ dş!‘ŽăŁ/%¤čô˛ąlO¤č2c°¸o¦‘ę3[M´Ł;®¨Ť»mÖ‹WáŽÚ¸ş r2g3 ĺż9P!.Í$d9q®R‹}J˘(Üń€ŃhĚ\6QE´‹M|‰ěą űąlP(!¨` !L1…!h cÎ…ˇČP2„ Ň6ŚŁpć4ŤđĐR.Š‚R »ä¤-I¨¨űżÂŕP) Ł0Ę9!Ä&7 c(¸ĂńǨ endstream endobj 181 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F7 10 0 R >> >> endobj 183 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EQ ¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 184 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 186 0 obj << /Length 9692 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@2Ä4@[.ŔڀѴl4AŁQ°Č\5GÄŔiLB*EäaśL@T3GyD ;Ęc¸€f1“ÍäP"ˇČ3Óćć0h˘‚)*¦DiDq‹ Ó蝆 2ŽDJ)RD- †ˇŢŞS“Iĺ1L˛S*IĄ1`€’N!‹«˘,ĆAŽA†ăH„ŠI&”dâÉtC! Ć6FZKIŃi%rŘ,źIĎä†#apßK#Óćv{YFr_1™×fó‘Ô]˛qxňśĘAn©]AĄ±@ćä)ŚFc‘ă«r ‘§xÂ) b‘ŘPkô <âßqź°1 ˘!¤Ú2ŤĂŇ7Ŕ!¸ C(Ě»Ă(ĺ c(¸…"č¨% ŞB@äĂNbR†ĘRŞë OÂ1ŤcÎýżŻüŔ°<3AĐ„% + k© 2$Ѝ@Č…Él4‰¨j) @†ŠL&°{X+kRĽś N°p Ák¬ëRk0nŻh\’­ŞX@¨…ä±`hZ“üž¤6khŞ­3| ö Ď Ă<Çh"ČÂ4Ž(,Ţí9b‘*M¨b1¤Ad°ËáÂŚ†ŤŞAPÍÁŁ)S¶Ś›W)arŹSi%UY­ <ŹSŐ5’Y)IµřdU!ĘŐa†UŞŇšŘő«śŐÔM˘ISZ.:@–TU cl5§nTauK`Wi`ćŠ.š2#t­7LSČśß\Ó4ýXăÍsZŁ­˝ETÜőÎYh+ťs4w@q„W•¬Ö_ő°lŢáX•§c¶ž/^Y5}ŽăýÉ‚[č}ÂądŔmE~4ć-Śeó}üŕ+WuÝ´•áJRČčg|ŢÔć‰P]—u'yRúëMß®‘)8Á¸qhε:‘jŤ®Ż•ZVŢTä·Ăe–Ʋ“łxV«Ż˝şÖŰžiYţ™ˇhš…:˛iíßxč7Ł“{ďhf¦:ËF±ą$8WílŐx°†ÎÍÉYś§,‡ítí™Çń{fw¤çÜç§pz6¤‘oÚ_ÔS\&Ź®hs|ŃÎqť¤§ŰŰ7 ˇ…ÁÍŹČ÷ÎŇăám\e‡ÚŁý<îť.Óď=—WŇoţž›ęő[çhÚ(†ăŃ{ë”×âlNŐS\¨˝ďŇýaŻŰÎí®×Áóü~Łěîüb÷\3¬n®™í´÷¬÷ťűZ.náň@’OßrłM-yöµw0ďË V~o*$·Äý­nνî5 #x€Đ}S(đZsů2°¸“ÇĹž*Q8ćÍô+8tZ 2‡ĐÖÂÔösÔ…pšÄGťLL…§áŽ’XÖátU†íťaŞçmaĂé‹Ä~ Äh˛Ĺ üq&Ĺ aCÚ…QąŮÂ㬙cL ?ÝáCŘşNĘ$‹ş@x6č˘ě|Ź/ę'B—ü@›ÔuŽ/őŘIN*Ň-^É“Ź&ŕŠĂ©4˘Gâ (ŕ|‡yňyQxÍâ|mńH7ؤ{E–ŤM]1y'eęť”2ťd¦™Lqf,Ş~ł_Âo%!,o–° éM—4š6.)öfµÉ´\Ä[‚çť±é8Á¬ĺL’qYÍůą;"<“„“^ILůçąłV˛ŽnT¨IŇ”Ç#¦ÔÎw‹@Ó,Ęťłî€Ä)ă=˘„ł›QţOz%M™´)FvMę5G&ł\G¶R8Ë(ËÁ¤ľFˉ+.¨ť-šÓâ2âšgí6VĎâ0ÎŇvĹč3éHé˝ůOÁMßĹ,žTFKBɧL¨µM—mp«Pq!TŞĐBž¬4×8* ł«éö…Uę·3h|ŐŞ4ÂzÖŞ™['̆8ńÜ–ÂłgĹ6Ô°ŐăŤ(ë-v®uˇčU ß$^˝K–UJ­ňâżeuu±ĚŘłŐŇŔNčÝ}˛ôŞŔŮ;!QĄ„ŽĄö"Ń \)ŞČ.Qö!5ËT -e–[ä™4Ć léÝ'‘×ÚĘ•iŁť±7\ÚI0’e9ą ¶Ľľ–WUěŇß8×BŁ-óH¨­†´÷8\KG%â9xó ¬[Äđf˛aÎŰN;ÖłmÔ«ĽŕćňF«µplem˘¶đTňŇúç ĽŘć«7„Í®Ž_¶vŤ«lC¬-Šż˘&á+‹Zťa”ç %ü °Ń«˝ŻŰ âýpí ·őşíáŠ)0ťÜ©ŕÉ&-©űŤ AÎĂ÷™ą`ś{Q±Ć6»8ZďÔém‹1Ž.eŔÁT¦Lo“}SŃ9möi[ęÚŘĺ3v™5·Ú“Xi YĄ©Ž_žŹ^V®iAyv,ᲹOf}CłH¦ZW»+;é]'…sĆĂ ÔJ<·6öWYş¶%E>Řö@ۧpęŚĹ°3 ±É:­®µbj®UŠ«mÍ{{râ « JM‘_¦ť˙Ŕ[CeV §}ďn°°ŽŮ¦›ckm©0â!Ţ÷WJÉ®q‡Q·ňEáe"ąľ Č¸ĺrŞăŤľž<ä7Ç Ň4ÎáiMSĽóęvÜk|¸ŢtóyŕOätQž;ĂćŤŔ:ń(Ľź°A.ĹĂß{÷ë\¶gq^'w{w5“nöľzí WZä=•ĺÁśáŮ9‚ť˘ wź Zz®đĎ^'kĹ8_ Ľ#\ńí;Ŕp(<¬>Ç>c¶E؉ݹ–żńµ?avűü "בŚě{˝t(}“}G_đ'ăŘ"·}O·â=Ćüř˝ßčÚ›• žŽGo‡ěĽ´…ě}ďŮžWÍŘüďĆŹÝřÎ-Ü>·¦—’hu¶¸Î$˙Ýůś T$ż—륤úöQ}Ď©Ôoć«ô˝Ę)ĚĎTqM¤ľů ÍTCÎčéD™/¨˙ řŽ ôO®ôŽ$ţ‹üťĚűÉü›püořťOţď‰OĐĐ íŻłލ÷đ›*©˝ŻöXj °RźÂˇ07tţ TĎŻć÷Şj_ŞTű®ŘŁĐwŞD“ďmT¤Đ6ŁđxýŹ«O´ĹíäęĘâ©L¨ęvő°źĘ~¨Ż3P˛ýn§Jpýđ °Ç ´\ČF¬đ€¬n˙‚ŔOŽţú0× :ń™ ĐË 0®Jđţđüňŕ4jţa°¶, Ι0ď pžńNm0řŠj®˛Źď«?ăFłŮ ±9Kś±ćo Phç q&żË{ eľlűI·0+kqW PnÂŹ±QuKŻ‹–»`şiKpŃg1°ˇ1ř¸ľe; QĄ Đ0[çÝ1a/m‘«Q°CđF㥊\vĆnÚ%Ě<¦U `cŘYŔ6‡*W‘ÎeQěĺ1ňXńŕc™)ńRpńú&ô牥±!Vr†T:ČúY‘ú˝r*aR!0ńÉ.§Ĺ}!¦Hcćą"1ÜqKRQ!ĄjW1ń$b;…mEzZňg%p=’CqĹ$Rpqvr­őrRrÎJ}2[&ebL˛c(,BŃů&R…)2w#Đő$ ”X’d(bxR‹)rĽx'‹,D‚8ëa)î ,í-EpƲÁ*ëE}'˛ą'†8Ć !EIŇó&˛•/˛Ţ`·-ÂŚ *rń3.M%˛ë+ro-bvjŇĂ0S2Ą‘"0(bÂdł-s>k3 (s5ň´ţQĂ.Ó&W¤‡s/!‚Ť5í13“d(íţYSJ"ŽK43\$Ók#˛ç2Rç3[6eřUŇů6ă”#ó9…jxS}6s˘qw93Q5l•8«8âŽDŹ‹(Ó]<ź"BŽ,%s:sĎ&łÔP˘‰;/y'ó"Ţ“ĽTH63Í>Ä—<˛ü٦­=Süb-+łôɓ㒠Ӈ ’îŕ­Ö;“ń?ŁŤBm?%R-BâÓ4´~ęS·;Sé&†:Ć=B%păOBłú,"?@]ô/T%S…1ň?DSŤD‡jL´P(ÔzŁtXWŽ|ÓŐH˘‰HâMGÔ>ţ0mGS»Gh`s—<αJ…‡,GŕôŽU$—Hô¦wŇ.“¸ŁĽî†/GŕgMQHt€,#ąHôá0´fŕ´Ů> >TĘź3ĽM ÁMTüOłřWtcÓŐPłINµVµI°kóă5”Hő P¬?Ü~7U(ČĽLµRôń'”CR3%Rr)9RO3Ż„ŁuSŃÓ:Ő:~cPőSTr±A3çGrşüÓMU|é’Ä•/=Uös˝X5qArłJę9Ň/ç[±Ú‚µ¤\’ú‚±öZu( q[eą[ĄŚaňŃ wRó'µˇ*’S•¦\Ą}µŰ&±Z˛',•ą"ň(mµ×*9Ő™WTöŰuĹ$†X`Uá˛U`ĺ©a5ĺ%ći`˛gbó]’uFôOUśŘ–%*˛‰]őł&r‡HUë^26˛ť\2)¦_ĄŤ)?cA5ULŐv]-ňľZeYd2Ç.6K˘†.2ŰeR»-’Óh“g5—G›f­/bR˙/vw^ÖŁM¶~ěs^ö[j˛J–·D“/veIŐŃT–mk“Od¨ĚÓ-a¶y!sAbł4vżh¶ÓluŢ6>Vo6sS§dÂŹoíÍaÓg76ë/xr·ŕłiSńÖői•uo˘Ź;ŐpS›9VŻ:’Éqł]:·A9miv3'¶‰·-=Ď‹Z—5<–ÝjG=–ĺqÓĐđ7Wv#˛lÖźD” ßW]hv7@7Fhbă?÷kE#1@×w QwW6ůj;xW ht'C×:ht5y&Cš(ׯQ×$÷ש]W­DÂUp7‰}— g…ËE÷Ćhtc|á|×yzv÷}TyIt…}ÎÇH7ăj”‘e&]jy8 WĄVśŐŘL7±g”®wׇ€t˝hřG7)ÔÉcv G„ÇM¸HO€·‚tă~¸]N;+´ď„S‰„—Uj3xR~3w»Q“Wë‡wMftź‚5ź‡UEs6R‰G…źSx‡Š‹‰·Ł„x•c•PĄX+j•[s†]{/śTX‡V¸‹VřmG8·„µ{%÷[{5•xÖX÷“Ž×ëŽxł†řÚ“ ;±YŹđ&ý ĚJi×LńĽŔ‘ÁŹ·ůr“ä-%˝9' JD,|0÷Y$Ăy]5K”lƬtőL”ąÇůRm‘[™HUđg\÷'tě”ËlŁ ylÉĐZË é÷p.l˛ú™r|ůcu9–™FÍpÓ¬—™Q­—ěß—ÖZd¬çLë™qI–WŃąjŃĎ)™ŤĐźšmšE¨Ńdż•¬üĐ‘—›Qť›–lÔ¤A—äŠŃÔCťśĹ¸ÓůóYëťąŤ‚DŇíf;yč׹v×YôĎĎň×otŐíi qřŐͦ“p Ů:1D.-Ł—mˇŻŁŁP’ô:yŕŇíÖŰşKŽ%ÄŰŮîÜfqyÜíÉZW¦ŁLxů k‚nqL-‚ÔňJn΄H˛ś?jŇr,B‹©‡Í!¶F–¨]©¶q ´šŹkĽ"z-zľ*´bRüĘ»I´ĆŞ®KZŐ^Z«¬šß©ć¬ĄU!ş‡©zĂŻ”-B©§Ů§Ę1P¦S/ńîňE­qĚr¨KiĚţwÂ\]¤°&d´8`Lrś,Ť,îč?P”iH+ÂD’ ŔČ  đQ‚bZŁk4‡*c˘I]ćµCd–8ÂŇ ĹąKbć(¤–)‘_„Üű\Ä-đ5bs˛`Ť˛˘żłĚ!›6"j1 ~SD@PKäň.O3c˛xĺP„‚O&g'»ÂnPb¬ň C˛+ŰĐ(ű˛P˛( Z` Ö …7dŔ+¨:´#gż`Q˝D,C !"QżŁż»Ż˝Cł¶ j*ŔbB¤.GBcŁÍş""/°Ió"&S«…S°â ĂÎYBćŲ:&żĹzVâŚesĂĹ{ ˙µ85šNU‰ü]{nú’a:¦äKâűÖ%"NŁčäBjLő(\;¦ëĐTÝŢßţSąäĹŮB«”LvéFjĄ›şŢ.Q^G"â(>EăśńµCZ"\€jcşMĺÂ!ű„Áθ§ţ®Ű¨kĘťP…ëĄë ŢçŢĹë¤Úx>Ŕ5˘ŁhBQę\Ăw˝+fžă˘–É–z+ďď›y!ueÓôďąCĐ>őo>ů™“îşđźď?ďyßđ^éńź#ńËîňžĺĄ?/óź |˙+ńßCň7ň_3ó;ôÓşmĺ ÓívăżX!íKFFĆm?eĘnXß\(Ą™ö-D×bX _qÎ3öF$(®:to؆sE±önSůߍeyů_÷€ř]Py‡y÷n¸w[÷–é?źüGüź§řüÓűµďçěë?ÚëŽŐůh}Rj}ż ěßóţg–Â. ĆBÄf.ŤÄŔiQ–ËŁqŚEĂhD-Ž †cY‚,c6ĆĆc‘pÔaÂab \"]0™ F‚á ć,‡Č<öA„PĆôX4" ‡N%ó|ŇĄÄâ±xĚn;”XärY<¦n4 ‡#9Ýbmµ[-ÔúE¦4ŽAĆ×iőâĺ{ßfuUÎŰoĂC˘(¤Z1‘ؤ" ,šÇhą …Ă1¶*kiÎg§w|<ôl4ÂO/úx‹Íçsű®2·ŹŻd¬7\®^Î •\ĄĂq΂iâńďÔ›Čâ5Łëyý5CoÄ…s0˝śms!_É﬑Ű6g…7ÂFP}·&7ë{F<ÜÄkuôŐ?ĘŞë®óŘ÷;ŞËľÝ2+<ň$O30ʸoĂ832ă Ł°łXç>)ęÚţ:ňé¶PĚ*ä(0B»|µśŃ|u•sël×&ÔSx`Ö#˝uÉ­zµÚéaÖńť5YÔUü”6&‹Řxž74‡rmťyůˇ‡źÝş^k«ô÷7…Ő†/ŐÂĂ%h?żćy)vóÜa[ďAď%˙˝¸řŢGîĂí­¤éđ?+ _YcÍ*őö?g|ŞÖKóuGĄŘ.ó:Ç_ GĚAÇdî f¤ŔTÖąSs‘ud[ W^}!˙vŽMâłG˘ě!SĆt‰/ö<ă_”N…A—. ˇÜ(‚kA÷8B‚{Rˇž0řůĂÇHöa»=„(‰#D´ AwEs“ĹeÄQ:$0Ĺ×|V‡ÎŘŔ7ăá‘]D$¶ĆĆ˙c,r$¤“Č×bŰt‹¨J ˝đ¸˘sĄŃ¨ g!ČtlŠq.+Ĺ:Č\„|@Č—@pAˇ7RĄÄöÉą:{KY0’hů»É<Äâ`2:áxĘÓ;.'* öËSď q2—d–>ĂhÝ#‚Z?@ÖT‘ŔräBĂ:ň2GBäř ád…ZLö”3'¦dΑńúK,¸˘pć$’ńÂsÎ7S9I\ënsĄtĎ9$Äâž3Úu;ů‹ 'ÜZťŹr)OÉŃ>§ť /ŇĐ ó;gĽôx4*sPŠ@¨ť ž´:ÉZ+D§}Ł4ZŹŃŠ#h˝¤4z|RšMHéE%ťÔ®PúALčŰŁ´¶™@ŠcÁg>2‚šD4 ĐÂ]iu’ÍPf}OňÔ“µ.ZSýPDBµ‡fşZĎĹW?äz+4b{2Ş4'˛j­.˘\ĐKěŤldńłŐč¬ILśV«uź:®ĽIy°Gq*¬±÷TŹKXUnl*­{­őřŘŕW§™ĘU“LęČ_ČcdCďM–ľyh¸8­v]ÚRKç•ĄŞ´©`jŢJ‰@%e© K @© DĘ(%ŞSË z ĘAƸ/ôůŰKlBĚ\‡Ę¦źTgZM­ą©đ‚HpjᓥÁ?ďL†]ÔćI/ ş`‚ęź3k^m”«“¦Ş´ÝŇăn‹ @_GéĽÜ™jAů%öÖäÖ”‘ÍLKąöÄů?ŇűZá ¬x)>![âOŘáYş$pjĐKÓş'°Ř`âŁ^--˝"¦“?„[!ś{Ő ö®ň‹Ţ,y©¬Ľ PgqQPĹĄ®#őoŹńd>.*U>=Ż™ÂÓęEˇ“µv~ÖNŘEL‘)%<žď÷ eŠ®ß.ÍF|Fz×XG 0ÍÚHÎĄg´é6‹ŃŮ„µ“¶˘2Á/É|ŽX ĚĄ/S@ U(#’ÝQŚů4‘¸×s’h­şłćŞ[¬ľú!TŽ Ëë !)#~ŻŁÍSŁŽŕŢŃî<«îP8!Ń/µĺ -Mű·c±5WSx9LMČ%ęR‚ińµÁÇw_ÄŕäŽ:›UîTÍ>şÔNlBQî5cr4ú–ćń}2‡2ÇݛߺňŞěeČ-ČQhd•ÖSl$BT•­˛dëłÍŽťŘ]?«ő*×W'ěňgđ2ăFŤ­¬-ÁíWDIÄE$)®ČŽl¶g#,ŃŢô‡“3qhÂ)›4ű¶ÇŤëĄţ«-ČСV|@ÓĆTb)ĚÄá˘ăĹ2 'yaj>,ך˛Ö´+_‡ĄţiëŘWQšĐ”˝hzRüLxw¨§˛çµDż÷]śľňýÂo P}ĂX¦Ë§=˛ď(źŚďř2ÇrCâ‡5¶vAP‚đŚP¨T«„¸’PZĐ’KB°ŕ€â›]Ĺ€k©-'×ě*°P9 ) ¨…@TA@ýâ¦.đŔ 3żĂý ŕµ?!~şé~Ť€Î3˛á2*·¤H„*3ůżńJ@X‚+í1 Ĺ, ˙­«®Š*/Ř’”ňÔ/ž‘˛Ą.čđ‡AnÁ*ý12®Zč‹Y—-+É  ‚­Ë S÷˘ĘAx¬ ’Sk°T¬š«ÂŇ5Sł¨3Ő¤iâ‰Ű%źó2¦`¦‹đ㽺ťĽKŐĄ€…2™ &űŮBëĂc˝¦‘Łb¤ŁÜľIźˇěĄKĆ;y-&€&ł·"*%3tAé…D+Á&?>43&3Ĺ%R´>k“ňQ rĹ YA:cU›)Žë|¦ËC#@ěE-Ä8•†%ĽQ«BR˛C˝ xµ‘ ÉŘBI«&",]­éĹôW.ř˛X¶Ä±Âśc*CĹl-Š8§“á”Ĭ$Xή#Ó Śk®0 F{ "BS)ˇ˘+V„p˘- h<{ćÄrQ”ŇODtVĄP„#B!pŔ1YĂé[ş0ľ9íC9®<ĚŚŃď1‚WĄs·ÇÜ`¦ Č '§ńtžđ¦+BoTK‰¸Ö ,Y&ÄN»ř…+”P¤;­<Ź7Ä’’Đ…;”U r[É2ꍊ˙1ÁZŁŕEĚš CÉ T•®Ęhă×IZĂĹ„i¤8;;„ĹBơďd¤ĆĂĎ ŞFčá;„„ĄŇŻG © ¸ü%Óź$ĐË4dYGÂúH©ľĄ,´Ćô€D„‰»H¦0*%řKYIËjS¸4ł&äG»K1\ŔĄ´¸H,H:H˘ŞIĽDĹ”-›ô/= ćŤÉź9RD|Ä˔Ƚ)Î3 Ě1¦kĎ羼¸»A®KZ¦Š4AĹşD&¬`Í”E<ŔľËíľčËđCŁőëň?ä 7ĚĐ–”ňPMűú?°ü@ř¦aËN“C`*$ž(Ŕ!vŔL?ĚŕŔˇ:l· ‘#ÚÔ3yŢš+@ŕ8Ŕř‹9ďÎ(  ˛Y /řQvĎ|çĎ”đΩYŞ4ęŚëÎČ50NčúÎřOšő+űňO2Ł ŤĘD˙ĄŚdOz*@ü»Ľ S°ě¶ŚâP6Řą˛E(ˇŻ2XÔć¦:éΖxć9c,"˛[ľĂí>ăďMűđť”ý ú´âÚšD*JNOsú´śË@eNŤĎ౞Dě?ôŃíŞ «c=M’% kĘ dŇÝ5L! ĺś¶ŇxűÓ¤›Ž›ËÓzíL6µ"'BÂŤH˘U żStu›W"1$HźÓµG HTCRTUCÓÝ@Íd,ÍtLŤM6+," d[JF’ AŽ=HŐ9ˇFÍ@ UOU-WU3Ě„¶‘ÝDŐąMÓűĹDÍU5_FQÓŕ„Ů·CrĚ|ÎŐ°ś–%PĂř ÔyáJŠ ŁUíWŠbBV€©Ö•gÖMYĂĂŐMpÄ­h IŰ<;Ś8ÁGé ¶řľT¨Ă×U\ÔÔÎMlŤT!×ŃWĺ`ŤpÔ×xű«CŃ׼ŤűŐ‘ŇÖ]|˘ó 5{ĹĺlލÖĹvX¸éXXž]‰WäW$°\źVHő$±‘ä!e‹ý&˝nŹŤ”Ř=†UĄf"ňeŐ‰Q µ—ÁĄ €őˇV%KYŃY­A(-Bů’Ežą#› RaÖˇ Ú»fTÉPÚĄYµqÓA5©),Äi »ÚÉ00}¶Zč©’Á*Ú]MÚt×+ń:"DŰÉ<Ú “í• AD˝¸”0¶Í…Úb„©Ńn”ĄdTISŐ卹QŘ͵\µšÜqM[ũʖéaŰ2Pť´’ _ž… ]EŁ•5Ń[­|Tä­kŮ×éoÝĄ˘Ů,ܽӖĺÖńj\í»)uéyUq†Ţ-•]9|ÝŮ]^eÍ…ăY•Ď=Ň{—y‡Ű1ŤUÓ˝ËíÜ"ůŠ^…ě]}ŐŞ/ +t^É›Űi–™}–ܢ3™ťßµő_-†ÝŠ/ˇ¤Ů9®šźß‰¨möŠžG ŽßÝŕÝ…»Č9·-té±Ú­ř›]®Z ߡ±ţ_5ś‘Ĺö9aĹŕ!®śŔá) a9ŠÖ.`ĺü`eśˇŃZ‘ĐźíîŰt^n‰5úa±ŃÜUá)QزĆĎf"á)Üťľ$Đ%Ü6"\…{ŕí‡ÉžµpSv+!^‘ębf/byĺbĆ)a…áź÷a©öŹ^.1őâdúáö5W=pŰ ‘[ %ÚźÉűŮqţőÜcö8ăÍĂ^¤<ś’_ –,äF6 Ł,aÚĄŽY’ nŮľ*$ĘÁY6,ˇ‘ăęß‚ ˘Ąă˘!ťűä˝üâŞ%!ő˝Őöˇţ$şÄt\ĄFŹ^5ćV"f ©ň CŞ+S5±_9 Br_ŞĽö,˝h¦¬Â›Xćp!bĆ› ަnc‰îd‰ľiĐë/fŁRf€‰MŰî=u"Ů;ßç24G &RŚŕŞňĘMř;żđ#H3¨9,áŕ€053çŘ"H6(74~…S endstream endobj 187 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R /F9 36 0 R >> >> endobj 190 0 obj << /Length 291 /Filter /LZWDecode >> stream € phÄ@i@‰P‘¨@4Ä4@[.ŔڀѠä\5 Ć!´5Á¤RC`4¦ ’DŁ‘éÜb7ŹÉdň™ Ţs-—Á  ĚĘ;9› …ĂyšQ*Ň©‚ 6&s‘´Bť<®Ő%ŔŇP/# âbˇ8ŹČ P+„ @2Ťg#1Śä©&UaźT1EQ°¤¨jł‘¤klqąÄň÷q„â@4Ű$ÂÚ ÂHT;âŠbŇi<¦ )–JeB)4¦,IÄ1v; 1ľÄ3<t@d0 Fr ţR(* :ňŽEÜ“¶ť˘I<śA& "0‚N%ď¤[4 x¸ČyBé'*qˇŤ)Wc‘”· endstream endobj 191 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F3 8 0 R /F5 9 0 R >> >> endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F3 /Encoding 192 0 R /BaseFont /Helvetica >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F5 /Encoding 192 0 R /BaseFont /Helvetica-Bold >> endobj 10 0 obj << /Type /Font /Subtype /Type1 /Name /F7 /Encoding 192 0 R /BaseFont /Times-BoldItalic >> endobj 30 0 obj << /Type /Font /Subtype /Type1 /Name /F8 /BaseFont /Symbol >> endobj 36 0 obj << /Type /Font /Subtype /Type1 /Name /F9 /Encoding /MacRomanEncoding /BaseFont /Helvetica >> endobj 68 0 obj << /Type /Font /Subtype /Type1 /Name /F11 /Encoding 193 0 R /BaseFont /ZapfDingbats >> endobj 192 0 obj << /Type /Encoding /Differences [ 39/quotesingle 96/grave 128/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis /Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla /eacute/egrave/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis /ntilde/oacute/ograve/ocircumflex/odieresis/otilde/uacute/ugrave /ucircumflex/udieresis/dagger/degree 164/section/bullet/paragraph/germandbls /registered/copyright/trademark/acute/dieresis/notequal/AE/Oslash /infinity/plusminus/lessequal/greaterequal/yen/mu/partialdiff/summation /product/pi/integral/ordfeminine/ordmasculine/Omega/ae/oslash /questiondown/exclamdown/logicalnot/radical/florin/approxequal/Delta/guillemotleft /guillemotright/ellipsis/blank/Agrave/Atilde/Otilde/OE/oe /endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide/lozenge /ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright/fi/fl /daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand/Acircumflex/Ecircumflex/Aacute /Edieresis/Egrave/Iacute/Icircumflex/Idieresis/Igrave/Oacute/Ocircumflex /apple/Ograve/Uacute/Ucircumflex/Ugrave 246/circumflex/tilde/macron /breve/dotaccent/ring/cedilla/hungarumlaut/ogonek/caron ] >> endobj 193 0 obj << /Type /Encoding /Differences [ 128/a89/a90/a93/a94/a91/a92/a205/a85 /a206/a86/a87/a88/a95/a96 ] >> endobj 4 0 obj << /Type /Page /Parent 11 0 R /Resources 7 0 R /Contents 6 0 R /Thumb 5 0 R >> endobj 12 0 obj << /Type /Page /Parent 11 0 R /Resources 14 0 R /Contents 13 0 R >> endobj 15 0 obj << /Type /Page /Parent 11 0 R /Resources 17 0 R /Contents 16 0 R >> endobj 18 0 obj << /Type /Page /Parent 11 0 R /Resources 20 0 R /Contents 19 0 R >> endobj 21 0 obj << /Type /Page /Parent 11 0 R /Resources 23 0 R /Contents 22 0 R >> endobj 24 0 obj << /Type /Page /Parent 11 0 R /Resources 26 0 R /Contents 25 0 R >> endobj 27 0 obj << /Type /Page /Parent 32 0 R /Resources 29 0 R /Contents 28 0 R >> endobj 33 0 obj << /Type /Page /Parent 32 0 R /Resources 35 0 R /Contents 34 0 R >> endobj 37 0 obj << /Type /Page /Parent 32 0 R /Resources 39 0 R /Contents 38 0 R >> endobj 40 0 obj << /Type /Page /Parent 32 0 R /Resources 42 0 R /Contents 41 0 R >> endobj 43 0 obj << /Type /Page /Parent 32 0 R /Resources 45 0 R /Contents 44 0 R >> endobj 46 0 obj << /Type /Page /Parent 32 0 R /Resources 48 0 R /Contents 47 0 R >> endobj 49 0 obj << /Type /Page /Parent 52 0 R /Resources 51 0 R /Contents 50 0 R >> endobj 53 0 obj << /Type /Page /Parent 52 0 R /Resources 55 0 R /Contents 54 0 R >> endobj 56 0 obj << /Type /Page /Parent 52 0 R /Resources 58 0 R /Contents 57 0 R >> endobj 59 0 obj << /Type /Page /Parent 52 0 R /Resources 61 0 R /Contents 60 0 R >> endobj 62 0 obj << /Type /Page /Parent 52 0 R /Resources 64 0 R /Contents 63 0 R >> endobj 65 0 obj << /Type /Page /Parent 52 0 R /Resources 67 0 R /Contents 66 0 R >> endobj 69 0 obj << /Type /Page /Parent 72 0 R /Resources 71 0 R /Contents 70 0 R >> endobj 73 0 obj << /Type /Page /Parent 72 0 R /Resources 75 0 R /Contents 74 0 R >> endobj 76 0 obj << /Type /Page /Parent 72 0 R /Resources 78 0 R /Contents 77 0 R >> endobj 79 0 obj << /Type /Page /Parent 72 0 R /Resources 81 0 R /Contents 80 0 R >> endobj 82 0 obj << /Type /Page /Parent 72 0 R /Resources 84 0 R /Contents 83 0 R >> endobj 85 0 obj << /Type /Page /Parent 72 0 R /Resources 87 0 R /Contents 86 0 R >> endobj 88 0 obj << /Type /Page /Parent 91 0 R /Resources 90 0 R /Contents 89 0 R >> endobj 92 0 obj << /Type /Page /Parent 91 0 R /Resources 94 0 R /Contents 93 0 R >> endobj 95 0 obj << /Type /Page /Parent 91 0 R /Resources 97 0 R /Contents 96 0 R >> endobj 98 0 obj << /Type /Page /Parent 91 0 R /Resources 100 0 R /Contents 99 0 R >> endobj 101 0 obj << /Type /Page /Parent 91 0 R /Resources 103 0 R /Contents 102 0 R >> endobj 104 0 obj << /Type /Page /Parent 91 0 R /Resources 106 0 R /Contents 105 0 R >> endobj 107 0 obj << /Type /Page /Parent 110 0 R /Resources 109 0 R /Contents 108 0 R >> endobj 111 0 obj << /Type /Page /Parent 110 0 R /Resources 113 0 R /Contents 112 0 R >> endobj 114 0 obj << /Type /Page /Parent 110 0 R /Resources 116 0 R /Contents 115 0 R >> endobj 117 0 obj << /Type /Page /Parent 110 0 R /Resources 119 0 R /Contents 118 0 R >> endobj 120 0 obj << /Type /Page /Parent 110 0 R /Resources 122 0 R /Contents 121 0 R >> endobj 123 0 obj << /Type /Page /Parent 110 0 R /Resources 125 0 R /Contents 124 0 R >> endobj 126 0 obj << /Type /Page /Parent 130 0 R /Resources 128 0 R /Contents 127 0 R >> endobj 131 0 obj << /Type /Page /Parent 130 0 R /Resources 133 0 R /Contents 132 0 R >> endobj 134 0 obj << /Type /Page /Parent 130 0 R /Resources 136 0 R /Contents 135 0 R >> endobj 137 0 obj << /Type /Page /Parent 130 0 R /Resources 139 0 R /Contents 138 0 R >> endobj 140 0 obj << /Type /Page /Parent 130 0 R /Resources 142 0 R /Contents 141 0 R >> endobj 143 0 obj << /Type /Page /Parent 130 0 R /Resources 145 0 R /Contents 144 0 R >> endobj 146 0 obj << /Type /Page /Parent 150 0 R /Resources 148 0 R /Contents 147 0 R >> endobj 151 0 obj << /Type /Page /Parent 150 0 R /Resources 153 0 R /Contents 152 0 R >> endobj 154 0 obj << /Type /Page /Parent 150 0 R /Resources 156 0 R /Contents 155 0 R >> endobj 157 0 obj << /Type /Page /Parent 150 0 R /Resources 159 0 R /Contents 158 0 R >> endobj 160 0 obj << /Type /Page /Parent 150 0 R /Resources 162 0 R /Contents 161 0 R >> endobj 163 0 obj << /Type /Page /Parent 150 0 R /Resources 165 0 R /Contents 164 0 R >> endobj 166 0 obj << /Type /Page /Parent 169 0 R /Resources 168 0 R /Contents 167 0 R >> endobj 170 0 obj << /Type /Page /Parent 169 0 R /Resources 172 0 R /Contents 171 0 R >> endobj 173 0 obj << /Type /Page /Parent 169 0 R /Resources 175 0 R /Contents 174 0 R >> endobj 176 0 obj << /Type /Page /Parent 169 0 R /Resources 178 0 R /Contents 177 0 R >> endobj 179 0 obj << /Type /Page /Parent 169 0 R /Resources 181 0 R /Contents 180 0 R >> endobj 182 0 obj << /Type /Page /Parent 169 0 R /Resources 184 0 R /Contents 183 0 R >> endobj 185 0 obj << /Type /Page /Parent 188 0 R /Resources 187 0 R /Contents 186 0 R >> endobj 189 0 obj << /Type /Page /Parent 188 0 R /Resources 191 0 R /Contents 190 0 R >> endobj 11 0 obj << /Type /Pages /Kids [4 0 R 12 0 R 15 0 R 18 0 R 21 0 R 24 0 R ] /Count 6 /Parent 31 0 R >> endobj 32 0 obj << /Type /Pages /Kids [27 0 R 33 0 R 37 0 R 40 0 R 43 0 R 46 0 R ] /Count 6 /Parent 31 0 R >> endobj 52 0 obj << /Type /Pages /Kids [49 0 R 53 0 R 56 0 R 59 0 R 62 0 R 65 0 R ] /Count 6 /Parent 31 0 R >> endobj 72 0 obj << /Type /Pages /Kids [69 0 R 73 0 R 76 0 R 79 0 R 82 0 R 85 0 R ] /Count 6 /Parent 31 0 R >> endobj 91 0 obj << /Type /Pages /Kids [88 0 R 92 0 R 95 0 R 98 0 R 101 0 R 104 0 R ] /Count 6 /Parent 31 0 R >> endobj 110 0 obj << /Type /Pages /Kids [107 0 R 111 0 R 114 0 R 117 0 R 120 0 R 123 0 R ] /Count 6 /Parent 31 0 R >> endobj 31 0 obj << /Type /Pages /Kids [11 0 R 32 0 R 52 0 R 72 0 R 91 0 R 110 0 R ] /Count 36 /Parent 129 0 R >> endobj 130 0 obj << /Type /Pages /Kids [126 0 R 131 0 R 134 0 R 137 0 R 140 0 R 143 0 R ] /Count 6 /Parent 149 0 R >> endobj 150 0 obj << /Type /Pages /Kids [146 0 R 151 0 R 154 0 R 157 0 R 160 0 R 163 0 R ] /Count 6 /Parent 149 0 R >> endobj 169 0 obj << /Type /Pages /Kids [166 0 R 170 0 R 173 0 R 176 0 R 179 0 R 182 0 R ] /Count 6 /Parent 149 0 R >> endobj 188 0 obj << /Type /Pages /Kids [185 0 R 189 0 R ] /Count 2 /Parent 149 0 R >> endobj 149 0 obj << /Type /Pages /Kids [130 0 R 150 0 R 169 0 R 188 0 R ] /Count 20 /Parent 129 0 R >> endobj 129 0 obj << /Type /Pages /Kids [31 0 R 149 0 R ] /Count 56 /MediaBox [0 0 612 792 ] >> endobj 194 0 obj << /Type /Catalog /Pages 129 0 R >> endobj xref 0 195 0000000000 65535 f 0000000016 00000 n 0000000172 00000 n 0000000400 00000 n 0000154718 00000 n 0000000947 00000 n 0000001543 00000 n 0000002034 00000 n 0000152796 00000 n 0000152894 00000 n 0000152997 00000 n 0000159543 00000 n 0000154812 00000 n 0000002154 00000 n 0000002511 00000 n 0000154896 00000 n 0000002621 00000 n 0000004548 00000 n 0000154980 00000 n 0000004658 00000 n 0000005668 00000 n 0000155064 00000 n 0000005778 00000 n 0000006184 00000 n 0000155148 00000 n 0000006305 00000 n 0000006662 00000 n 0000155232 00000 n 0000006772 00000 n 0000009939 00000 n 0000153103 00000 n 0000160211 00000 n 0000159652 00000 n 0000155316 00000 n 0000010060 00000 n 0000014846 00000 n 0000153181 00000 n 0000155400 00000 n 0000014967 00000 n 0000021904 00000 n 0000155484 00000 n 0000022025 00000 n 0000022386 00000 n 0000155568 00000 n 0000022496 00000 n 0000022875 00000 n 0000155652 00000 n 0000022996 00000 n 0000023358 00000 n 0000155736 00000 n 0000023468 00000 n 0000026800 00000 n 0000159762 00000 n 0000155820 00000 n 0000026921 00000 n 0000030835 00000 n 0000155904 00000 n 0000030956 00000 n 0000031417 00000 n 0000155988 00000 n 0000031538 00000 n 0000031899 00000 n 0000156072 00000 n 0000032009 00000 n 0000035946 00000 n 0000156156 00000 n 0000036067 00000 n 0000040283 00000 n 0000153290 00000 n 0000156240 00000 n 0000040416 00000 n 0000044840 00000 n 0000159872 00000 n 0000156324 00000 n 0000044961 00000 n 0000049856 00000 n 0000156408 00000 n 0000049977 00000 n 0000052675 00000 n 0000156492 00000 n 0000052796 00000 n 0000054583 00000 n 0000156576 00000 n 0000054693 00000 n 0000061482 00000 n 0000156660 00000 n 0000061603 00000 n 0000061965 00000 n 0000156744 00000 n 0000062075 00000 n 0000062439 00000 n 0000159982 00000 n 0000156828 00000 n 0000062560 00000 n 0000062922 00000 n 0000156912 00000 n 0000063032 00000 n 0000066817 00000 n 0000156996 00000 n 0000066927 00000 n 0000071882 00000 n 0000157081 00000 n 0000072004 00000 n 0000076569 00000 n 0000157168 00000 n 0000076680 00000 n 0000081528 00000 n 0000157255 00000 n 0000081650 00000 n 0000084628 00000 n 0000160094 00000 n 0000157343 00000 n 0000084750 00000 n 0000085113 00000 n 0000157431 00000 n 0000085224 00000 n 0000085612 00000 n 0000157519 00000 n 0000085734 00000 n 0000086097 00000 n 0000157607 00000 n 0000086208 00000 n 0000088469 00000 n 0000157695 00000 n 0000088591 00000 n 0000095013 00000 n 0000157783 00000 n 0000095135 00000 n 0000099430 00000 n 0000160867 00000 n 0000160324 00000 n 0000157871 00000 n 0000099563 00000 n 0000104077 00000 n 0000157959 00000 n 0000104210 00000 n 0000108965 00000 n 0000158047 00000 n 0000109098 00000 n 0000112592 00000 n 0000158135 00000 n 0000112725 00000 n 0000113139 00000 n 0000158223 00000 n 0000113261 00000 n 0000113623 00000 n 0000158311 00000 n 0000113734 00000 n 0000118995 00000 n 0000160764 00000 n 0000160442 00000 n 0000158399 00000 n 0000119117 00000 n 0000120942 00000 n 0000158487 00000 n 0000121064 00000 n 0000121479 00000 n 0000158575 00000 n 0000121601 00000 n 0000121963 00000 n 0000158663 00000 n 0000122074 00000 n 0000128002 00000 n 0000158751 00000 n 0000128124 00000 n 0000131370 00000 n 0000158839 00000 n 0000131492 00000 n 0000131922 00000 n 0000160560 00000 n 0000158927 00000 n 0000132044 00000 n 0000132407 00000 n 0000159015 00000 n 0000132518 00000 n 0000136342 00000 n 0000159103 00000 n 0000136475 00000 n 0000141262 00000 n 0000159191 00000 n 0000141395 00000 n 0000141839 00000 n 0000159279 00000 n 0000141961 00000 n 0000142324 00000 n 0000159367 00000 n 0000142435 00000 n 0000152200 00000 n 0000160678 00000 n 0000159455 00000 n 0000152322 00000 n 0000152685 00000 n 0000153393 00000 n 0000154598 00000 n 0000160962 00000 n trailer << /Size 195 /Root 194 0 R /Info 2 0 R /ID [<92e7af494ee3f7a38cf7abec5fcc196b><92e7af494ee3f7a38cf7abec5fcc196b>] >> startxref 161015 %%EOF 2 0 obj << /CreationDate (D:19960121173249) /Producer (Acrobat Distiller 2.1 for Power Macintosh) /Keywords () /Creator (Adobe PageMaker 6.0) /Title (SED1520 Technical Manual) /Subject () /Author (S-MOS Systems, Inc.) /ModDate (D:19960123135211) >> endobj 194 0 obj << /Type /Catalog /Pages 129 0 R /Outlines 195 0 R /PageMode /UseOutlines >> endobj 195 0 obj << /Count 2 /Type /Outlines /First 196 0 R /Last 199 0 R >> endobj 196 0 obj << /Title (Main Menu) /Parent 195 0 R /A 197 0 R /Next 199 0 R >> endobj 197 0 obj << /S /GoToR /F 198 0 R /D [ 0 /FitR 0 272 617 780 ] >> endobj 198 0 obj (../S0A_CVR/COVER.PDF) endobj 199 0 obj << /Title (SED1520) /Prev 196 0 R /Parent 195 0 R /A 200 0 R >> endobj 200 0 obj << /S /GoToR /F 201 0 R /D [ 0 /FitBH 725 ] >> endobj 201 0 obj (../S04_DRCT/DB611520.PDF) endobj xref 0 1 0000000000 65535 f 2 1 0000165074 00000 n 194 8 0000165344 00000 n 0000165452 00000 n 0000165543 00000 n 0000165639 00000 n 0000165724 00000 n 0000165767 00000 n 0000165861 00000 n 0000165937 00000 n trailer << /Size 202 /Info 2 0 R /Root 194 0 R /Prev 161015 /ID[<92e7af494ee3f7a38cf7abec5fcc196b>] >> startxref 165984 %%EOF gpsim-0.30.0/extras/graphic_lcd/Makefile.in0000664000076400007640000003260313117441635015467 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras/graphic_lcd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ examples/sed1520/18f452.lkr examples/sed1520/bitmaps.asm \ examples/sed1520/glcd_test.asm \ examples/sed1520/globalvars.inc \ examples/sed1520/lcd100X32.asm examples/sed1520/lcd100X32.inc \ examples/sed1520/Makefile \ examples/sed1520/portdef.inc examples/sed1520/processor.inc \ examples/sed1520/sed1520.asm examples/sed1520/sed1520.inc \ examples/ssd0323/bitmaps.asm examples/ssd0323/18f452.lkr \ examples/ssd0323/globalvars.inc examples/ssd0323/ssd0323.inc \ examples/ssd0323/osram128x64.asm examples/ssd0323/osram128x64.inc \ examples/ssd0323/Makefile examples/ssd0323/glcd_test.asm \ examples/ssd0323/portdef.inc examples/ssd0323/processor.inc \ examples/ssd0323/ssd0323.asm \ utils/custom.png utils/fontimage.png utils/gpsim1.png \ utils/konqueror16X16.png utils/konqueror3.png \ utils/konqueror.png utils/pngtopic.c utils/README \ doc/mgls10032a.pdf doc/sed1520.pdf \ src/glcd_100X32_sed1520.h src/osram.h src/ssd0323.h \ src/glcd.h src/sed1520.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/graphic_lcd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/graphic_lcd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/graphic_lcd/Makefile.am0000664000076400007640000000174213041763631015455 00000000000000 EXTRA_DIST = \ examples/sed1520/18f452.lkr examples/sed1520/bitmaps.asm \ examples/sed1520/glcd_test.asm \ examples/sed1520/globalvars.inc \ examples/sed1520/lcd100X32.asm examples/sed1520/lcd100X32.inc \ examples/sed1520/Makefile \ examples/sed1520/portdef.inc examples/sed1520/processor.inc \ examples/sed1520/sed1520.asm examples/sed1520/sed1520.inc \ examples/ssd0323/bitmaps.asm examples/ssd0323/18f452.lkr \ examples/ssd0323/globalvars.inc examples/ssd0323/ssd0323.inc \ examples/ssd0323/osram128x64.asm examples/ssd0323/osram128x64.inc \ examples/ssd0323/Makefile examples/ssd0323/glcd_test.asm \ examples/ssd0323/portdef.inc examples/ssd0323/processor.inc \ examples/ssd0323/ssd0323.asm \ utils/custom.png utils/fontimage.png utils/gpsim1.png \ utils/konqueror16X16.png utils/konqueror3.png \ utils/konqueror.png utils/pngtopic.c utils/README \ doc/mgls10032a.pdf doc/sed1520.pdf \ src/glcd_100X32_sed1520.h src/osram.h src/ssd0323.h \ src/glcd.h src/sed1520.h gpsim-0.30.0/extras/graphic_lcd/src/0000775000076400007640000000000013117466030014261 500000000000000gpsim-0.30.0/extras/graphic_lcd/src/glcd.h0000664000076400007640000000713613041763630015274 00000000000000/* Copyright (C) 2007 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(__GLCD_H__) #define __GLCD_H__ #include #include #include #include #define IN_BREADBOARD 0 class LCDColor { public: LCDColor() : r(0.0), g(0.0), b(0.0) {} double r, g, b; }; //======================================================================== // gLCD - graphic LCD // // gLCD implements the graphical component of the gpsim graphical LCD // modules. The I/O pins and various LCD controllers chips are implemented // elsehere. class gLCD { public: gLCD(unsigned int cols, unsigned int rows, unsigned int pixel_size_x, unsigned int pixel_size_y, unsigned int pixel_gap, unsigned int nColors=2 ); ~gLCD(); void clear(cairo_t *cr); void setPixel(cairo_t *cr, unsigned int col, unsigned int row); void setPixel(cairo_t *cr, unsigned int col, unsigned int row, unsigned int colorIdx); void setColor(unsigned int colorIdx, double r, double g, double b); protected: unsigned int m_nColumns; unsigned int m_nRows; unsigned int m_border; // pixel size Mapping between graphical pixmap and LCD. unsigned int m_xPixel; unsigned int m_yPixel; unsigned int m_pixelGap; // Colors LCDColor *m_Colors; unsigned int m_nColors; void setPixel(cairo_t *cr, unsigned int col, unsigned int row, double r, double g, double b); }; //======================================================================== class gLCD_Module; class gLCD_Interface : public Interface { private: gLCD_Module *plcd; public: //virtual void UpdateObject (gpointer xref,int new_value); //virtual void RemoveObject (gpointer xref); virtual void SimulationHasStopped (gpointer object); //virtual void NewProcessor (unsigned int processor_id); //virtual void NewModule (Module *module); //virtual void NodeConfigurationChanged (Stimulus_Node *node); //virtual void NewProgram (unsigned int processor_id); virtual void Update (gpointer object); gLCD_Interface(gLCD_Module *_gp); }; //======================================================================== // gLCD_Module - base class of graphic's LCD modules // class gLCD_Module : public Module { public: gLCD_Module(const char *new_name, const char *desc, unsigned int nCols, unsigned int nRows); virtual ~gLCD_Module(); virtual void Update(GtkWidget *pw =0); protected: GtkWidget *window; GtkWidget *darea; // Drawable containing the graphics gLCD *m_plcd; unsigned int m_nColumns; unsigned int m_nRows; unsigned int interface_seq_no; }; //------------------------------------------------------------------------ class ModuleTraceType; class LcdPortRegister : public PortRegister { public: LcdPortRegister(gLCD_Module *plcd, const char * _name, const char *_desc); virtual ~LcdPortRegister(); private: gLCD_Module *m_pLCD; ModuleTraceType *mMTT; }; #endif gpsim-0.30.0/extras/graphic_lcd/src/ssd0323.h0000664000076400007640000000574313041763630015466 00000000000000/* Copyright (C) 2007 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(__SSD0323_H__) #define __SSD0323_H__ class SSD0323 { enum { e8080Mode = 6, e6800Mode = 4, eSPIMode = 0, eInvalidMode = 0xff }; enum { // 8080 6800 SPI eCS = 1, // /CS /CS /CS eRES = 2, // /Reset /Reset /Reset eE_RD = 4, // /Rd Enable /Enable eRW = 8, // /Wr Rd /Wr /Wr eDC = 0x10 // D /C D /C D /C --- Data /Command }; public: SSD0323(); void setBS(unsigned int BSpin, bool newBS); void setCS(bool); void setRES(bool); void setDC(bool); void setE_RD(bool); void setRW(bool); void setData(unsigned int); void setSCLK(bool); void setSDIN(bool); void driveDataBus(unsigned int); bool dataBusDirection(); unsigned int getDataBus(); void storeData(); void executeCommand(); void randomizeRAM(); unsigned int getData(); unsigned int getStatus(); inline unsigned int &operator[] (unsigned int index) { return (index < 128*80/2) ? m_ram[index] : prBadRam(index); } void showState(); private: void advanceColumnAddress(); void advanceRowAddress(); // called if an illegal access is made to the RAM unsigned int &prBadRam(unsigned int); // Display state unsigned int m_controlState; unsigned int m_dataBus; // Communication - // The commMode selects one of three possible communication modes // The commState holds the communication state for that mode. unsigned int m_commMode; unsigned int m_commState; unsigned int m_SPIData; // Command processing unsigned int m_commandIndex; unsigned int m_expectedCommandWords; unsigned char cmdWords[20]; // Display ram + one for bad memory access unsigned int m_ram[(128*80/2) + 1]; // State information unsigned int m_colAddr; unsigned int m_rowAddr; // helper functions bool bEnabled() { return (m_controlState &(eCS|eRES)) == eRES; } bool bBitState(unsigned int b) { return (m_controlState&b)==b; } void abortCurrentTransaction(); // configuration data controlled by the SSD0323 commands unsigned int m_colStartAddr; unsigned int m_colEndAddr; unsigned int m_rowStartAddr; unsigned int m_rowEndAddr; unsigned int m_Remap; unsigned int m_ContrastControl; }; #endif // __SSD0323_H__ gpsim-0.30.0/extras/graphic_lcd/src/glcd.cc0000664000076400007640000001064613041763630015432 00000000000000/* Copyright (C) 2007 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_GUI #include "glcd.h" #include //------------------------------------------------------------------------ gLCD::gLCD(unsigned int cols, unsigned int rows, unsigned int pixel_size_x, unsigned int pixel_size_y, unsigned int pixel_gap, unsigned int nColors ) : m_nColumns(cols), m_nRows(rows), m_border(3), m_xPixel(pixel_size_x), m_yPixel(pixel_size_y), m_pixelGap(pixel_gap) { m_nColors = nColors < 2 ? 2 : nColors; m_Colors = new LCDColor[m_nColors]; setColor(0, double(0x78) / 255.0, double(0xa8) / 255.0, double(0x78) / 255.0); setColor(1, double(0x11) / 255.0, double(0x33) / 255.0, double(0x11) / 255.0); } gLCD::~gLCD() { delete [] m_Colors; } void gLCD::clear(cairo_t *cr) { double r = m_Colors[0].r; double g = m_Colors[0].g; double b = m_Colors[0].b; cairo_set_source_rgb(cr, r, g, b); cairo_rectangle(cr, 0.0, 0.0, m_xPixel * (m_nColumns + 2 * m_border), m_yPixel * (m_nRows + 2 * m_border)); cairo_fill(cr); } void gLCD::setPixel(cairo_t *cr, unsigned int col, unsigned int row, double r, double g, double b) { double x = (col + m_border) * m_xPixel; double y = (row + m_border) * m_yPixel; double px = m_xPixel - m_pixelGap; double py = m_yPixel - m_pixelGap; cairo_set_source_rgb(cr, r, g, b); cairo_set_line_width(cr, 0.5); cairo_rectangle(cr, x, y, px, py); cairo_fill(cr); } void gLCD::setPixel(cairo_t *cr, unsigned int col, unsigned int row) { if (col < m_nColumns && row < m_nRows) { double r = m_Colors[1].r; double g = m_Colors[1].g; double b = m_Colors[1].b; setPixel(cr, col, row, r, g, b); } } void gLCD::setPixel(cairo_t *cr, unsigned int col, unsigned int row, unsigned int colorIdx) { if (colorIdx < m_nColors) setPixel(cr, col, row, m_Colors[colorIdx].r, m_Colors[colorIdx].g, m_Colors[colorIdx].b); } void gLCD::setColor(unsigned int colorIdx, double r, double g, double b) { if (colorIdx < m_nColors) { m_Colors[colorIdx].r = r; m_Colors[colorIdx].g = g; m_Colors[colorIdx].b = b; } } //======================================================================== // // LCD interface to the simulator // gLCD_Interface::gLCD_Interface(gLCD_Module *_lcd) : Interface ( (gpointer *) _lcd), plcd(_lcd) { } //-------------------------------------------------- // SimulationHasStopped (gpointer) // // gpsim will call this function when the simulation // has halt (e.g. a break point was hit.) void gLCD_Interface::SimulationHasStopped (gpointer) { if(plcd) plcd->Update(); } void gLCD_Interface::Update (gpointer) { if(plcd) plcd->Update(); } //======================================================================== // // gLCD_Module::gLCD_Module(const char *new_name, const char *desc, unsigned int nCols, unsigned int nRows) : Module(new_name,desc), window(0),darea(0),m_plcd(0),m_nColumns(nCols), m_nRows(nRows) { interface_seq_no = get_interface().add_interface(new gLCD_Interface(this)); } gLCD_Module::~gLCD_Module() { get_interface().remove_interface(interface_seq_no); delete m_plcd; } void gLCD_Module::Update(GtkWidget *pw) { } //======================================================================== // LcdPortRegister::LcdPortRegister(gLCD_Module *plcd, const char * _name, const char *_desc) : PortRegister(plcd, _name,_desc,8, 0), m_pLCD(plcd) { mMTT = new ModuleTraceType(plcd,1," Graphic LCD"); trace.allocateTraceType(mMTT); RegisterValue rv(mMTT->type(), mMTT->type() + (1<<22)); set_write_trace(rv); rv = RegisterValue(mMTT->type()+(2<<22), mMTT->type() + (3<<22)); set_read_trace(rv); } LcdPortRegister::~LcdPortRegister() { delete mMTT; } #endif //HAVE_GUI gpsim-0.30.0/extras/graphic_lcd/src/glcd_100X32_sed1520.h0000664000076400007640000000313213041763630017304 00000000000000/* Copyright (C) 2005 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(__GLCD_100X32_SED1520_H__) #define __GLCD_100X32_SED1520_H__ #include #include "glcd.h" class SED1520; class gLCD_InputPin; class PortRegister; class Module; enum enPins { enA0, enE1, enE2, enRW }; class gLCD_100X32_SED1520 : public gLCD_Module { public: gLCD_100X32_SED1520(const char *new_name); ~gLCD_100X32_SED1520(); static Module *construct(const char *new_name); bool dataBusDirection(); void Update(GtkWidget *pw =0); void UpdatePinState(enPins, char); void create_iopin_map(); void create_widget(); private: PortRegister *m_dataBus; gLCD_InputPin *m_A0; gLCD_InputPin *m_E1; gLCD_InputPin *m_E2; gLCD_InputPin *m_RW; SED1520 *m_sed1; SED1520 *m_sed2; static gboolean lcd_expose_event(GtkWidget *widget, GdkEventExpose *event, gLCD_100X32_SED1520 *pLCD); }; #endif //__GLCD_100X32_SED1520_H__ gpsim-0.30.0/extras/graphic_lcd/src/osram.h0000664000076400007640000000344013041763630015476 00000000000000/* Copyright (C) 2007 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(__OSRAM_H__) #define __OSRAM_H__ #include #include "glcd.h" class SSD0323; class Module; class PortRegister; // gpsim graphics LCD modules for OSRAM Pictivia(tm) OLED Displays namespace OSRAM { class SSD0323_InputPin; class StateAttribute; class PK27_Series : public gLCD_Module { public: PK27_Series(const char *new_name); ~PK27_Series(); static Module *construct(const char *new_name); void Update(GtkWidget *pw =0); bool dataBusDirection(); /* void UpdatePinState(ePins, char); */ void create_iopin_map(); void create_widget(); private: PortRegister *m_dataBus; SSD0323_InputPin *m_CS; SSD0323_InputPin *m_RES; SSD0323_InputPin *m_DC; SSD0323_InputPin *m_E; SSD0323_InputPin *m_RW; SSD0323_InputPin *m_BS1; SSD0323_InputPin *m_BS2; IO_bi_directional *io_bus[8]; SSD0323 *m_pSSD0323; StateAttribute *m_state; static gboolean lcd_expose_event(GtkWidget *widget, GdkEventExpose *event, PK27_Series *pLCD); }; } // End of OSRAM namespace #endif gpsim-0.30.0/extras/graphic_lcd/src/glcd_100X32_sed1520.cc0000664000076400007640000002052113041763630017443 00000000000000/* Copyright (C) 2005 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #ifdef HAVE_GUI #include "glcd_100X32_sed1520.h" #include "glcd.h" #include "sed1520.h" #include #include #include //------------------------------------------------------------------------ // I/O pins for the graphic LCD //------------------------------------------------------------------------ // The gLCD_InputPin is the base class for the E1, E2, RW and A0 // pins. This class is derived from the IO_bi_directional class, // although the pins are never driven as outputs. The setDrivenState // method is overridden to capture when this pin is driven. class gLCD_InputPin : public IO_bi_directional { public: gLCD_InputPin (gLCD_100X32_SED1520 *, const char *pinName, enPins pin); // Capture when a node drives this pin. virtual void setDrivenState(bool new_dstate); char CurrentState() { return m_cDrivenState; } private: // The IO_bi_directional constructor will initialize the direction // to be an input. We'll override the update_direction method so that // this will never change. virtual void update_direction(unsigned int,bool refresh) { // Disallow pin direction changes. } gLCD_100X32_SED1520 *m_pLCD; enPins m_pin; char m_cDrivenState; }; //------------------------------------------------------------------------ // gLCD_InputPin::gLCD_InputPin (gLCD_100X32_SED1520 *pLCD , const char *pinName, enPins pin) : IO_bi_directional(pinName), m_pLCD(pLCD), m_pin(pin), m_cDrivenState('Z') { assert(m_pLCD); } void gLCD_InputPin::setDrivenState(bool new_dstate) { IO_bi_directional::setDrivenState(new_dstate); char cState = getBitChar(); if (m_cDrivenState != cState) { m_cDrivenState = cState; m_pLCD->UpdatePinState(m_pin, cState); } } //------------------------------------------------------------------------ // class gLCDSignalControl : public SignalControl { public: gLCDSignalControl(gLCD_100X32_SED1520 *pLCD) : m_pLCD(pLCD) { assert(m_pLCD); } virtual void release() { } virtual char getState() { // return the data bus direction (note the negative true logic. return m_pLCD->dataBusDirection() ? '0' : '1'; } private: gLCD_100X32_SED1520 *m_pLCD; }; //------------------------------------------------------------------------ bool gLCD_100X32_SED1520::dataBusDirection() { // FIXME, if both sed's are driving the data bus, then they'll be in // contention. return m_sed1->dataBusDirection() || m_sed2->dataBusDirection(); } //------------------------------------------------------------------------ Module *gLCD_100X32_SED1520::construct(const char *_new_name=0) { gLCD_100X32_SED1520 *gLCD = new gLCD_100X32_SED1520(_new_name); return gLCD; } //------------------------------------------------------------------------ gLCD_100X32_SED1520::gLCD_100X32_SED1520(const char *_new_name) : gLCD_Module(_new_name,"SED1520 100X32 Graphics LCD module",100,32) { m_dataBus = new LcdPortRegister(this,".data","LCD Data Port"); addSymbol(m_dataBus); m_dataBus->setEnableMask(0xff); m_A0 = new gLCD_InputPin(this, "a0", enA0); m_E1 = new gLCD_InputPin(this, "e1", enE1); m_E2 = new gLCD_InputPin(this, "e2", enE2); m_RW = new gLCD_InputPin(this, "rw", enRW); addSymbol(m_A0); addSymbol(m_E1); addSymbol(m_E2); addSymbol(m_RW); m_sed1 = new SED1520(); m_sed2 = new SED1520(); m_sed1->randomizeRAM(); m_sed2->randomizeRAM(); create_iopin_map(); create_widget(); } gLCD_100X32_SED1520::~gLCD_100X32_SED1520() { delete m_dataBus; removeSymbol(m_A0); removeSymbol(m_E1); removeSymbol(m_E2); removeSymbol(m_RW); delete m_sed1; delete m_sed2; gtk_widget_destroy(darea); } //------------------------------------------------------------------------ void gLCD_100X32_SED1520::create_iopin_map() { create_pkg(18); // Add the individual io pins to the data bus. assign_pin( 9, m_dataBus->addPin(new IO_bi_directional( "d0"), 0)); assign_pin(10, m_dataBus->addPin(new IO_bi_directional( "d1"), 1)); assign_pin(11, m_dataBus->addPin(new IO_bi_directional( "d2"), 2)); assign_pin(12, m_dataBus->addPin(new IO_bi_directional( "d3"), 3)); assign_pin(13, m_dataBus->addPin(new IO_bi_directional( "d4"), 4)); assign_pin(14, m_dataBus->addPin(new IO_bi_directional( "d5"), 5)); assign_pin(15, m_dataBus->addPin(new IO_bi_directional( "d6"), 6)); assign_pin(16, m_dataBus->addPin(new IO_bi_directional( "d7"), 7)); // Provide a SignalControl object that the dataBus port can query // to determine which direction to drive the data bus. // (See for more documentation on port behavior. // But in summary, when an I/O port updates its I/O pins, it will // query the pin drive direction via the SignalControl object. ) SignalControl *pPortDirectionControl = new gLCDSignalControl(this); for (int i=0; i<8; i++) (*m_dataBus)[i].setControl(pPortDirectionControl); assign_pin( 4, m_A0); assign_pin( 5, m_RW); assign_pin( 6, m_E1); assign_pin( 7, m_E2); } gboolean gLCD_100X32_SED1520::lcd_expose_event(GtkWidget *widget, GdkEventExpose *event, gLCD_100X32_SED1520 *pLCD) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); pLCD->m_plcd->clear(cr); for (unsigned int i = 0; i < pLCD->m_nColumns; ++i) { unsigned sedIndex = i < 50 ? i : (i - 50); SED1520 *sed = i < 50 ? pLCD->m_sed1 : pLCD->m_sed2; for (unsigned int j = 0; j < pLCD->m_nRows / 8; ++j) { unsigned int row = 8 * j; unsigned displayByte = (*sed)[sedIndex + ((j & 3) * 80)]; for (unsigned int b = 0; b < 8; b++ , displayByte >>= 1) if (displayByte & 1) pLCD->m_plcd->setPixel(cr, i, row + b); } } cairo_destroy(cr); return TRUE; } //------------------------------------------------------------------------ void gLCD_100X32_SED1520::Update(GtkWidget *widget) { gtk_widget_queue_draw(darea); } //------------------------------------------------------------------------ void gLCD_100X32_SED1520::create_widget() { window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_wmclass(GTK_WINDOW(window),"glcd","Gpsim"); gtk_window_set_title(GTK_WINDOW(window), "LCD"); GtkWidget *frame = gtk_frame_new("gLCD_100X32"); gtk_container_add(GTK_CONTAINER(window), frame); darea = gtk_drawing_area_new(); gtk_widget_set_size_request(darea, (m_nColumns+4)*3, (m_nRows+4)*3); gtk_container_add(GTK_CONTAINER(frame), darea); g_signal_connect(darea, "expose_event", G_CALLBACK(lcd_expose_event), this); gtk_widget_set_events(darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); gtk_widget_show_all(window); m_plcd = new gLCD(m_nColumns, m_nRows, 3, 3, 1); } //------------------------------------------------------------------------ void gLCD_100X32_SED1520::UpdatePinState(enPins pin, char cState) { // One of the control lines has changed states. So refresh the // sed's with the most current data bus value. if (!m_sed1->dataBusDirection()) m_sed1->driveDataBus(m_dataBus->get()); if (!m_sed2->dataBusDirection()) m_sed2->driveDataBus(m_dataBus->get()); bool bState = (cState =='1') || (cState =='W'); switch (pin) { case enA0: m_sed1->setA0(bState); m_sed2->setA0(bState); break; case enE1: m_sed1->setE(bState); break; case enE2: m_sed2->setE(bState); break; case enRW: m_sed1->setRW(bState); m_sed2->setRW(bState); break; } // If either one of the sed's is driving, then place that // data on to the data bus. if (m_sed1->dataBusDirection()) m_dataBus->put(m_sed1->getDataBus()); else if (m_sed2->dataBusDirection()) m_dataBus->put(m_sed2->getDataBus()); else m_dataBus->updatePort(); } #endif // HAVE_GUI gpsim-0.30.0/extras/graphic_lcd/src/ssd0323.cc0000664000076400007640000004235013041763630015617 00000000000000/* Copyright (C) 2007 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_GUI #define IN_MODULE #include #include #include "ssd0323.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FUNCTION__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif #define UNIT_TESTING 0 //======================================================================== // // SSD0323 Solomon Systech Display controller // // -- 128X80, 16 Gray Scale Dot Matrix // // // Questions // 1) The command sequence involves writing multiple bytes. Under what // conditions is the state of this sequence modified? // -- Assume that each command write automatically advances the state // -- Assume that it is okay for CS and DC to change states between writes // -- Assume that a low on RES clears the state. // -- Assume that a data write before the command completes aborts the command. //------------------------------------------------------------------------ //------------------------------------------------------------------------ #if UNIT_TESTING == 1 void unitTest(SSD0323 *pSSD0323); #endif SSD0323::SSD0323() : m_controlState(0), m_dataBus(0x100), m_commMode(SSD0323::eSPIMode), m_commState(0), m_SPIData(0), m_commandIndex(0), m_expectedCommandWords(0), m_colAddr(0), m_rowAddr(0), m_colStartAddr(0), m_colEndAddr(0x3f), m_rowStartAddr(0), m_rowEndAddr(0x4f), m_Remap(0), m_ContrastControl(0x40) { #if UNIT_TESTING == 1 unitTest(this); #endif } //------------------------------------------------------------------------ void SSD0323::abortCurrentTransaction() { m_commState = 0; m_commandIndex = 0; } //------------------------------------------------------------------------ // setBS -- selects the communication interface: // // BS Mode // 000 Serial // 100 6800 // 110 8080 void SSD0323::setBS(unsigned int BSpin, bool newBS) { //Dprintf(("pin:%d state:%d currentBS state:%d\n",BSpin, newBS,m_commMode)); if ( (((1<= 8) { // Place the contents of the SPI receiver onto the // internal data bus and then perform the write operation. m_dataBus = m_SPIData; if (bBitState(eDC)) storeData(); else executeCommand(); m_commState = 0; m_SPIData=0; } } } m_dataBus = d; } void SSD0323::setSCLK(bool bSCL) { setData((m_dataBus&~bSCLK) | (bSCL ? bSCLK : 0)); } void SSD0323::setSDIN(bool bSDA) { setData((m_dataBus&~bSDIN) | (bSDA ? bSDIN : 0)); } void SSD0323::driveDataBus(unsigned int d) { m_dataBus = d; } void SSD0323::advanceColumnAddress() { if (++m_colAddr <= m_colEndAddr) return; m_colAddr = m_colStartAddr; if (m_rowStartAddr != m_rowEndAddr) advanceRowAddress(); } void SSD0323::advanceRowAddress() { if (++m_rowAddr <= m_rowEndAddr) return; m_rowAddr = m_rowStartAddr; if (m_colStartAddr != m_colEndAddr) advanceColumnAddress(); } void SSD0323::storeData() { m_ram[m_rowAddr*64 + m_colAddr] = m_dataBus; Dprintf((" data:0x%02x row:%u col:%u\n",m_dataBus,m_rowAddr,m_colAddr )); const int incMode = 4; if (m_Remap & incMode) advanceRowAddress(); else advanceColumnAddress(); } unsigned int SSD0323::getData() { m_dataBus = m_ram[m_rowAddr*64 + m_colAddr]; return m_dataBus; } unsigned int SSD0323::getStatus() { return 0; } void SSD0323::executeCommand() { const int CmdSetColumnAddress = 0x15; const int CmdGraphicAccleration = 0x23; const int CmdDrawRectangle = 0x24; const int CmdCopy = 0x25; const int CmdHorizontalScroll = 0x26; const int CmdStopMoving = 0x2E; const int CmdStartMoving = 0x2F; const int CmdSetRowAddress = 0x75; const int CmdSetContrast = 0x81; const int CmdSetQuarterCurrent = 0x84; const int CmdSetHalfCurrent = 0x85; const int CmdSetFullCurrent = 0x86; const int CmdSetRemap = 0xA0; const int CmdSetDisplayStartLine = 0xA1; const int CmdSetDisplayOffset = 0xA2; const int CmdSetNormalDisplay = 0xA4; const int CmdSetAllOn = 0xA5; const int CmdSetAllOff = 0xA6; const int CmdSetInverse = 0xA7; const int CmdSetMultiplexRatio = 0xA8; const int CmdSetMasterCfg = 0xAD; const int CmdSetDisplayOff = 0xAE; const int CmdSetDisplayOn = 0xAF; const int CmdSetPreChargeCompensationEnable = 0xB0; const int CmdSetPhaseLength = 0xB1; const int CmdSetRowPeriod = 0xB2; const int CmdSetClockDivide = 0xB3; const int CmdSetPreChargeCompensationLevel = 0xB4; const int CmdSetGrayScaleTable = 0xB8; const int CmdSetPreChargeVoltage = 0xBC; const int CmdSetVCOMH = 0xBE; const int CmdSetVSL = 0xBF; const int CmdNop = 0xE3; cmdWords[m_commandIndex] = m_dataBus; m_commandIndex = (m_commandIndex+1)&0xf; if (m_commandIndex > sizeof (cmdWords)) { m_commandIndex = 0; printf("Warning: SSD0323::executeCommand() - command buffer overflow\n"); return; } printf("%s:data=0x%x\n", __FUNCTION__, m_dataBus); // decode the command if (m_commandIndex == 1) { switch (m_dataBus) { // 1-word commands case CmdStopMoving: case CmdStartMoving: case CmdSetQuarterCurrent: case CmdSetHalfCurrent: case CmdSetFullCurrent: case CmdSetNormalDisplay: case CmdSetAllOn: case CmdSetAllOff: case CmdSetInverse: case CmdSetDisplayOff: case CmdSetDisplayOn: case CmdNop: m_commandIndex = 0; return; break; // 2-word commands case CmdGraphicAccleration: case CmdSetContrast: case CmdSetRemap: case CmdSetDisplayStartLine: case CmdSetDisplayOffset: case CmdSetMultiplexRatio: case CmdSetMasterCfg: case CmdSetPreChargeCompensationEnable: case CmdSetRowPeriod: case CmdSetPreChargeCompensationLevel: case CmdSetPreChargeVoltage: case CmdSetVCOMH: case CmdSetVSL: case CmdSetPhaseLength: case CmdSetClockDivide: m_expectedCommandWords = 2; break; // 3-word commands case CmdSetColumnAddress: case CmdSetRowAddress: m_expectedCommandWords = 3; break; case CmdHorizontalScroll: m_expectedCommandWords = 4; break; case CmdDrawRectangle: m_expectedCommandWords = 6; break; case CmdCopy: m_expectedCommandWords = 7; break; case CmdSetGrayScaleTable: m_expectedCommandWords = 9; break; default: printf("Warning: SSD received bad command 0x%x\n", m_dataBus); } } if (m_commandIndex == m_expectedCommandWords) { unsigned int i = cmdWords[0]; printf("SSD0323 - executing command:0x%x\n", i); switch (cmdWords[0]) { // 1-word commands case CmdStopMoving: case CmdStartMoving: case CmdSetQuarterCurrent: case CmdSetHalfCurrent: case CmdSetFullCurrent: case CmdSetNormalDisplay: case CmdSetAllOn: case CmdSetAllOff: case CmdSetInverse: case CmdSetDisplayOff: case CmdSetDisplayOn: case CmdNop: break; case CmdSetContrast: m_ContrastControl = cmdWords[1] & 0x7f; break; case CmdSetRemap: m_Remap = cmdWords[1] & 0x7f; break; // 2-word commands case CmdGraphicAccleration: case CmdSetDisplayStartLine: case CmdSetDisplayOffset: case CmdSetMultiplexRatio: case CmdSetMasterCfg: case CmdSetPreChargeCompensationEnable: case CmdSetRowPeriod: case CmdSetPreChargeCompensationLevel: case CmdSetPreChargeVoltage: case CmdSetVCOMH: case CmdSetVSL: case CmdSetPhaseLength: case CmdSetClockDivide: m_expectedCommandWords = 2; break; // 3-word commands case CmdSetColumnAddress: m_colStartAddr = cmdWords[1] & 0x3f; m_colEndAddr = cmdWords[2] & 0x3f; m_colAddr = m_colStartAddr; break; case CmdSetRowAddress: m_rowStartAddr = cmdWords[1] & 0x7f; m_rowEndAddr = cmdWords[2] & 0x7f; m_rowAddr = m_rowStartAddr; break; case CmdHorizontalScroll: m_expectedCommandWords = 4; break; case CmdDrawRectangle: m_expectedCommandWords = 6; break; case CmdCopy: m_expectedCommandWords = 7; break; case CmdSetGrayScaleTable: m_expectedCommandWords = 16; break; default: printf("Warning: SSD received bad command 0x%x\n", m_dataBus); } m_commandIndex = 0; } } //------------------------------------------------------------------------ // dataBusDirection() // return true if the controller is driving the data bus bool SSD0323::dataBusDirection() { if (!bEnabled()) return false; if (m_commMode==e8080Mode && !bBitState(eE_RD)) return true; if (m_commMode==e6800Mode && bBitState(eRW)) return true; return false; } //------------------------------------------------------------------------ unsigned int SSD0323::getDataBus() { return m_dataBus; } //------------------------------------------------------------------------ void SSD0323::randomizeRAM() { for (unsigned int i=0; i < 128*80/2; i++) m_ram[i] = (rand()>>8) & 0xff; } //------------------------------------------------------------------------ // prBadRam - private function called when ever an illegal access is made // to the RAM unsigned int &SSD0323::prBadRam(unsigned int index) { printf("WARNING SSD0323 - illegal RAM access index=%u\n",index); return m_ram[(128*80/2)]; } //------------------------------------------------------------------------ //------------------------------------------------------------------------ void SSD0323::showState() { printf("SSD0323 internal state:\n"); switch (m_commMode) { case e8080Mode: printf(" 8080 mode\n"); break; case e6800Mode: printf(" 6800 mode\n"); break; case eSPIMode: printf(" SPI mode\n"); break; } printf("remap: 0x%02x\n",m_Remap); printf("column start:0x%02x end:0x%02x curr:0x%02x\n",m_colStartAddr,m_colEndAddr,m_colAddr); printf("row start:0x%02x end:0x%02x curr:0x%02x\n",m_rowStartAddr,m_rowEndAddr,m_rowAddr); } #if UNIT_TESTING == 1 //======================================================================== static SSD0323 *p_gSSD0323=0; void WriteCommand(unsigned int c) { if (p_gSSD0323) { p_gSSD0323->setData(c); p_gSSD0323->executeCommand(); } } void WriteData(unsigned int d) { if (p_gSSD0323) { p_gSSD0323->setData(d); p_gSSD0323->storeData(); } } void unitTest(SSD0323 *pSSD0323) { printf("Running SSD0323 unit test\n"); p_gSSD0323 = pSSD0323; // Column Address WriteCommand(0x15); /* Set Column Address */ WriteCommand(0x00); /* Start = 0 */ WriteCommand(0x3F); /* End = 127 */ // Row Address WriteCommand(0x75); /* Set Row Address */ WriteCommand(0x00); /* Start = 0 */ WriteCommand(0x3F); /* End = 63 */ // Contrast Control WriteCommand(0x81); /* Set Contrast Control */ WriteCommand(0x6D); /* 0 ~ 127 */ // Current Range WriteCommand(0x86); /* Set Current Range 84h:Quarter, 85h:Half, 86h:Full*/ // Re-map WriteCommand(0xA0); /* Set Re-map */ WriteCommand(0x41); /* [0]:MX, [1]:Nibble, [2]:H/V address [4]:MY, [6]:Com Split Odd/Even "1000010"*/ // Display Start Line WriteCommand(0xA1); /* Set Display Start Line */ WriteCommand(0x00); /* Start at row 0 */ // Display Offset WriteCommand(0xA2); /* Set Display Offset */ WriteCommand(0x44); /* Offset 68 rows */ // Display Mode WriteCommand(0xA4); /* Set DisplaMode,A4:Normal, A5:All ON, A6: All OFF, A7:Inverse */ // Multiplex Ratio WriteCommand(0xA8); /* Set Multiplex Ratio */ WriteCommand(0x3F); /* 64 mux*/ // Phase Length WriteCommand(0xB1); /* Set Phase Length */ WriteCommand(0x22); /* [3:0]:Phase 1 period of 1~16 clocks */ /* [7:4]:Phase 2 period of 1~16 clocks // POR = 0111 0100 */ // Set Pre-charge Compensation Enable WriteCommand(0xB0); /* Set Pre-charge Compensation Enable */ WriteCommand(0x28); /* Enable*/ // Set Pre-charge Compensation Level WriteCommand(0xB4); /* Set Pre-charge Compensation Level */ WriteCommand(0x07); /* Higher level */ // Row Period WriteCommand(0xB2); /* Set Row Period */ WriteCommand(0x46); /* [7:0]:18~255, K=P1+P2+GS15 (POR:4+7+29)*/ // Display Clock Divide WriteCommand(0xB3); /* Set Clock Divide (2) */ WriteCommand(0x91); /* [3:0]:1~16, [7:4]:0~16, 100Hz */ /* POR = 0000 0001 */ // VSL WriteCommand(0xBF); /* Set VSL */ WriteCommand(0x0D); /* [3:0]:VSL */ // VCOMH WriteCommand(0xBE); /* Set VCOMH (3) */ WriteCommand(0x02); /* [7:0]:VCOMH, (0.53 X Vref = 0.53 X 15 V = 7.95V)*/ // VP /* Set VP (4) */ WriteCommand(0xBC); WriteCommand(0x10); /* [7:0]:VP, (0.67 X Vref = 0.67 X 15 V = 10.05V) */ // Gamma WriteCommand(0xB8); /* Set Gamma with next 8 bytes */ WriteCommand(0x01); /* L1[2:1] */ WriteCommand(0x11); /* L3[6:4], L2[2:0] 0001 0001 */ WriteCommand(0x22); /* L5[6:4], L4[2:0] 0010 0010 */ WriteCommand(0x32); /* L7[6:4], L6[2:0] 0011 1011 */ WriteCommand(0x43); /* L9[6:4], L8[2:0] 0100 0100 */ WriteCommand(0x54); /* LB[6:4], LA[2:0] 0101 0101 */ WriteCommand(0x65); /* LD[6:4], LC[2:0] 0110 0110 */ WriteCommand(0x76); /* LF[6:4], LE[2:0] 1000 0111 */ // Set DC-DC WriteCommand(0xAD); /* Set DC-DC */ WriteCommand(0x02); /* 03=ON, 02=Off */ // Display ON/OFF WriteCommand(0xAF); /* AF=ON, AE=Sleep Mode */ //unsigned int i; //for(i=0; i<4; i++) WriteData(0xff); WriteData(0xff); } #endif // UNIT_TESTING #endif // HAVE_GUI gpsim-0.30.0/extras/graphic_lcd/src/sed1520.cc0000664000076400007640000000653413041763630015605 00000000000000/* Copyright (C) 2005 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_GUI #define IN_MODULE #include #include #include "sed1520.h" //------------------------------------------------------------------------ SED1520::SED1520() : m_bE(true), m_controlState(0), m_dataBus(0), m_page(0), m_columnAddress(0) { randomizeRAM(); } //------------------------------------------------------------------------ void SED1520::setA0(bool newA0) { m_controlState &= ~eA0; m_controlState |= (newA0 ? eA0 : 0); } void SED1520::setRW(bool newRW) { m_controlState &= ~eRW; m_controlState |= (newRW ? eRW : 0); } void SED1520::setE(bool newE) { if (m_bE != newE && newE) { switch (m_controlState) { case eDataRead: driveDataBus(getData()); advanceColumnAddress(); break; case eDataWrite: storeData(); advanceColumnAddress(); break; case eStatusRead: driveDataBus(getStatus()); break; case eCommandWrite: executeCommand(); break; } } m_bE = newE; } void SED1520::setData(unsigned int d) { m_dataBus = d; } void SED1520::driveDataBus(unsigned int d) { m_dataBus = d; } void SED1520::advanceColumnAddress() { m_columnAddress += (m_columnAddress < eNCOLUMNS_PER_PAGE) ? 1 : 0; } void SED1520::storeData() { m_ram[eNCOLUMNS_PER_PAGE*m_page + m_columnAddress] = m_dataBus; } unsigned int SED1520::getData() { m_dataBus = m_ram[eNCOLUMNS_PER_PAGE*m_page + m_columnAddress]; return m_dataBus; } unsigned int SED1520::getStatus() { return 0; } void SED1520::executeCommand() { // decode the command if ( (m_dataBus & 0x80) == 0) { // Set column address m_columnAddress = (m_dataBus & 0x7f) % eNCOLUMNS_PER_PAGE; } else { if ((m_dataBus & 0x7C) == 0x38) // set Page Address m_page = m_dataBus & 3; } } //------------------------------------------------------------------------ bool SED1520::dataBusDirection() { return (m_controlState & (eE | eRW)) == (eE | eRW); } //------------------------------------------------------------------------ unsigned int SED1520::getDataBus() { return m_dataBus; } //------------------------------------------------------------------------ void SED1520::randomizeRAM() { for (unsigned int i=0; i < eNCOLUMNS_PER_PAGE * eNPAGES; i++) m_ram[i] = (rand()>>8) & 0xff; } //------------------------------------------------------------------------ // prBadRam - private function called when ever an illegal access is made // to the RAM unsigned int &SED1520::prBadRam(unsigned int index) { static unsigned int si; printf("WARNING SED1520 - illegal RAM access index=%u\n",index); return si; } #endif // HAVE_GUI gpsim-0.30.0/extras/graphic_lcd/src/sed1520.h0000664000076400007640000000354413041763630015445 00000000000000/* Copyright (C) 2005 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined(__SED1520_H__) #define __SED1520_H__ class SED1520 { enum { eNPAGES = 4, eNCOLUMNS_PER_PAGE = 80 }; enum { eA0 = 1, eRW = 2, eE = 4, eDataRead = eA0 | eRW, eDataWrite = eA0, eStatusRead = eRW, eCommandWrite = 0 }; public: SED1520(); void setA0(bool); void setE(bool); void setRW(bool); void setData(unsigned int); void driveDataBus(unsigned int); bool dataBusDirection(); unsigned int getDataBus(); void advanceColumnAddress(); void storeData(); void executeCommand(); void randomizeRAM(); unsigned int getData(); unsigned int getStatus(); inline unsigned int &operator[] (unsigned int index) { return (index < eNCOLUMNS_PER_PAGE * eNPAGES) ? m_ram[index] : prBadRam(index); } private: // called if an illegal access is made to the RAM unsigned int &prBadRam(unsigned int); /// I/O pin interface bool m_bE; unsigned int m_controlState; unsigned int m_dataBus; // Display ram unsigned int m_ram[eNCOLUMNS_PER_PAGE * eNPAGES]; // State information unsigned int m_page; unsigned int m_columnAddress; }; #endif //__SED1520_H__ gpsim-0.30.0/extras/graphic_lcd/src/osram.cc0000664000076400007640000003323213041763630015636 00000000000000/* Copyright (C) 2007 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_GUI #include "osram.h" #include "glcd.h" #include "ssd0323.h" #include #include #include #include #include namespace OSRAM { //------------------------------------------------------------------------ // Debug Stuff //------------------------------------------------------------------------ class StateAttribute : public Integer { public: StateAttribute (SSD0323 *pSSD) : Integer("state",0,"Display the state of the SSD0323 graphics controller"), m_pSSD(pSSD) { assert(pSSD); } virtual string toString() { m_pSSD->showState(); return string(""); } private: SSD0323 *m_pSSD; }; //------------------------------------------------------------------------ // I/O pins for the SSD 0323 controller //------------------------------------------------------------------------ // The LCD_InputPin is the base class for the E1, E2, RW and A0 // pins. This class is derived from the IO_bi_directional class, // although the pins are never driven as outputs. The setDrivenState // method is overridden to capture when this pin is driven. // NOTE: an alternative implementation would be to instantiate // PinModule objects for each of the pins and supply them with // standard IO_bi_directional objects. Then SignalSinks could be // created to capture pin state changes. class SSD0323_InputPin : public IO_bi_directional { public: SSD0323_InputPin (SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName); // Capture when a node drives this pin. virtual void setDrivenState(bool new_dstate); virtual void UpdateControllerPin(bool bState) {} char CurrentState() { return m_cDrivenState; } protected: SSD0323 *m_pSSD0323; PortRegister *m_pDataBus; char m_cDrivenState; private: // The IO_bi_directional constructor will initialize the direction // to be an input. We'll override the update_direction method so that // this will never change. virtual void update_direction(unsigned int,bool refresh) { // Disallow pin direction changes. } }; SSD0323_InputPin::SSD0323_InputPin (SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName) : IO_bi_directional(pinName), m_pSSD0323(pSSD), m_pDataBus(pDataBus), m_cDrivenState('Z') { assert(m_pSSD0323); } void SSD0323_InputPin::setDrivenState(bool new_dstate) { IO_bi_directional::setDrivenState(new_dstate); if (!m_pSSD0323->dataBusDirection()) m_pSSD0323->driveDataBus(m_pDataBus->get()); char cState = getBitChar(); if (m_cDrivenState != cState) { m_cDrivenState = cState; //cout << "LCD pin:" << name() << "-->"<dataBusDirection()) m_pDataBus->put(m_pSSD0323->getDataBus()); } //------------------------------------------------------------------------ // SSD E Pin //------------------------------------------------------------------------ class SSD0323_EPin : public SSD0323_InputPin { public: SSD0323_EPin(SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName) : SSD0323_InputPin(pSSD,pDataBus,pinName) {} virtual void UpdateControllerPin(bool); }; void SSD0323_EPin::UpdateControllerPin(bool bState) { m_pSSD0323->setE_RD(bState); } //------------------------------------------------------------------------ // SSD CS Pin //------------------------------------------------------------------------ class SSD0323_CSPin : public SSD0323_InputPin { public: SSD0323_CSPin(SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName) : SSD0323_InputPin(pSSD,pDataBus,pinName) {} virtual void UpdateControllerPin(bool); }; void SSD0323_CSPin::UpdateControllerPin(bool bState) { m_pSSD0323->setCS(bState); } //------------------------------------------------------------------------ // SSD RES Pin //------------------------------------------------------------------------ class SSD0323_RESPin : public SSD0323_InputPin { public: SSD0323_RESPin(SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName) : SSD0323_InputPin(pSSD,pDataBus,pinName) {} virtual void UpdateControllerPin(bool); }; void SSD0323_RESPin::UpdateControllerPin(bool bState) { m_pSSD0323->setRES(bState); } //------------------------------------------------------------------------ // SSD CS Pin //------------------------------------------------------------------------ class SSD0323_DCPin : public SSD0323_InputPin { public: SSD0323_DCPin(SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName) : SSD0323_InputPin(pSSD,pDataBus,pinName) {} virtual void UpdateControllerPin(bool); }; void SSD0323_DCPin::UpdateControllerPin(bool bState) { m_pSSD0323->setDC(bState); } //------------------------------------------------------------------------ // SSD RW Pin //------------------------------------------------------------------------ class SSD0323_RWPin : public SSD0323_InputPin { public: SSD0323_RWPin(SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName) : SSD0323_InputPin(pSSD,pDataBus,pinName) {} virtual void UpdateControllerPin(bool); }; void SSD0323_RWPin::UpdateControllerPin(bool bState) { m_pSSD0323->setRW(bState); } //------------------------------------------------------------------------ // SSD BS1, BS2 Pin //------------------------------------------------------------------------ class SSD0323_BSPin : public SSD0323_InputPin { public: SSD0323_BSPin(SSD0323 *pSSD, PortRegister *pDataBus, const char *pinName, unsigned pin) : SSD0323_InputPin(pSSD,pDataBus,pinName), m_pin(pin) { assert(m_pin==1 || m_pin==2); } virtual void UpdateControllerPin(bool); private: unsigned int m_pin; }; void SSD0323_BSPin::UpdateControllerPin(bool bState) { m_pSSD0323->setBS(m_pin,bState); } //------------------------------------------------------------------------ // SSD BS1, BS2 Pin //------------------------------------------------------------------------ class SSD_SPISignalSink : public SignalSink { public: SSD_SPISignalSink(SSD0323 *pSSD, bool bClk_or_Data) : m_pSSD0323(pSSD), m_bClk(bClk_or_Data), m_cState(0) { assert(m_pSSD0323); } virtual void release() { } virtual void setSinkState(char c) { if (m_cState != c) { //cout << __FUNCTION__ << " new state: " << c << endl; if (m_bClk) m_pSSD0323->setSCLK(c=='1' || c=='W'); else m_pSSD0323->setSDIN(c=='1' || c=='W'); m_cState = c; } } private: SSD0323 *m_pSSD0323; bool m_bClk; char m_cState; }; //------------------------------------------------------------------------ // class LCDSignalControl : public SignalControl { public: LCDSignalControl(PK27_Series *pLCD) : m_pLCD(pLCD) { assert(m_pLCD); } virtual void release() { } virtual char getState() { // return the data bus direction (note the negative true logic. return m_pLCD->dataBusDirection() ? '0' : '1'; } private: PK27_Series *m_pLCD; }; //------------------------------------------------------------------------ // PK27_Series -- Module constructor. //------------------------------------------------------------------------ Module *PK27_Series::construct(const char *_new_name) { PK27_Series *pLCD = new PK27_Series(_new_name); pLCD->create_widget(); return pLCD; } //------------------------------------------------------------------------ // PK27_Series -- 128X64 - 4-bit gray scale. //------------------------------------------------------------------------ PK27_Series::PK27_Series(const char *_new_name) : gLCD_Module(_new_name,"OSRAM 128X64 Graphics OLED module",128,64) { m_pSSD0323 = new SSD0323(); m_pSSD0323->setBS(0, false); m_dataBus = new LcdPortRegister(this,".data","LCD Data Port"); addSymbol(m_dataBus); m_dataBus->setEnableMask(0xff); m_CS = new SSD0323_CSPin(m_pSSD0323, m_dataBus, "cs"); m_RES = new SSD0323_RESPin(m_pSSD0323, m_dataBus, "res"); m_DC = new SSD0323_DCPin(m_pSSD0323, m_dataBus, "dc"); m_E = new SSD0323_EPin(m_pSSD0323, m_dataBus, "e"); m_RW = new SSD0323_RWPin(m_pSSD0323, m_dataBus, "rw"); m_BS1 = new SSD0323_BSPin(m_pSSD0323, m_dataBus, "bs1",1); m_BS2 = new SSD0323_BSPin(m_pSSD0323, m_dataBus, "bs2",2); addSymbol(m_CS); addSymbol(m_RES); addSymbol(m_DC); addSymbol(m_E); addSymbol(m_RW); addSymbol(m_BS1); addSymbol(m_BS2); m_state = new StateAttribute(m_pSSD0323); addSymbol(m_state); /* m_sed1->randomizeRAM(); m_sed2->randomizeRAM(); */ create_iopin_map(); //create_widget(); } //------------------------------------------------------------------------ // ~PK27_Series //------------------------------------------------------------------------ PK27_Series::~PK27_Series() { removeSymbol(m_CS); removeSymbol(m_RES); removeSymbol(m_DC); removeSymbol(m_E); removeSymbol(m_RW); removeSymbol(m_BS1); removeSymbol(m_BS2); removeSymbol(m_state); gtk_widget_destroy(darea); delete m_pSSD0323; delete m_dataBus; delete m_state; } gboolean PK27_Series::lcd_expose_event(GtkWidget *widget, GdkEventExpose *event, PK27_Series *pLCD) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); pLCD->m_plcd->clear(cr); for (unsigned int row = 0; row < pLCD->m_nRows; ++row) { for (unsigned int i = 0; i < pLCD->m_nColumns / 2; ++i) { unsigned int displayByte = (*(pLCD->m_pSSD0323))[i + 64 * row]; for (unsigned int b = 0; b < 2; b++, displayByte <<= 4) pLCD->m_plcd->setPixel(cr, 2 * i + b, row, (displayByte >> 4) & 0xf); } } cairo_destroy(cr); return TRUE; } //------------------------------------------------------------------------ // PK27_Series::Update //------------------------------------------------------------------------ const int pixelScale = 2; void PK27_Series::Update(GtkWidget *widget) { gtk_widget_queue_draw(darea); } //------------------------------------------------------------------------ // PK27_Series::create_widget //------------------------------------------------------------------------ void PK27_Series::create_widget() { window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_wmclass(GTK_WINDOW(window),"glcd","Gpsim"); gtk_window_set_title(GTK_WINDOW(window), "LCD"); GtkWidget *frame = gtk_frame_new("OSRAM PK27_Series"); gtk_container_add(GTK_CONTAINER(window), frame); darea = gtk_drawing_area_new(); gtk_widget_set_size_request(darea, (m_nColumns+3)*pixelScale, (m_nRows+3)*pixelScale); gtk_container_add(GTK_CONTAINER(frame), darea); g_signal_connect(darea, "expose_event", G_CALLBACK(lcd_expose_event), this); gtk_widget_set_events(darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); gtk_widget_show_all(window); m_plcd = new gLCD(m_nColumns, m_nRows, pixelScale, pixelScale, 0, 16); for (int i = 0; i < 16; ++i) { double c = double(i) / 16.0; m_plcd->setColor(i, c, c, 0.0); } } //------------------------------------------------------------------------ // PK27_Series::create_widget //------------------------------------------------------------------------ void PK27_Series::create_iopin_map() { create_pkg(30); assign_pin(20,m_BS1); assign_pin(19,m_BS2); assign_pin(17,m_CS); assign_pin(16,m_RES); assign_pin(15,m_DC); assign_pin(14,m_RW); assign_pin(13,m_E); // Add the individual io pins to the data bus. char text[] = "d0"; for(int i = 0; i < 8; i++) { text[1] = '0' + i; io_bus[i] = new IO_bi_directional(text); addSymbol(io_bus[i]); assign_pin(12-i, m_dataBus->addPin(io_bus[i], i)); } m_dataBus->addSink(new SSD_SPISignalSink(m_pSSD0323, true),0); // SPI CLK m_dataBus->addSink(new SSD_SPISignalSink(m_pSSD0323, false),1); // SPI Data // Provide a SignalControl object that the dataBus port can query // to determine which direction to drive the data bus. // (See for more documentation on port behavior. // But in summary, when an I/O port updates its I/O pins, it will // query the pin drive direction via the SignalControl object. ) SignalControl *pPortDirectionControl = new LCDSignalControl(this); for (int i=0; i<8; i++) (*m_dataBus)[i].setControl(pPortDirectionControl); } bool PK27_Series::dataBusDirection() { return m_pSSD0323->dataBusDirection(); } } // end of namespace OSRAM #endif // HAVE_GUI gpsim-0.30.0/extras/graphic_lcd/ChangeLog0000664000076400007640000001172313041763630015172 000000000000002010-05-17 Roy Rankin * src/glcd.h src/osram.cc src/ssd0323.cc src/sed1520.cc src/gpsim_modules.cc src/glcd_100X32_sed1520.cc src/glcd.cc - Config now from gpsim root, so include paths change and may be built without GUI. 2007-10-20 Scott Dattalo * examples/ssd0323/glcd_test.asm: WDT was timing out 2007-07-29 Scott Dattalo * src/osram.cc, src/osram.h, - support all communication modes. - added most of the controller commands * examples/ssd0323/osram128x64.asm, examples/ssd0323/portdef.inc, * examples/ssd0323/ssd0323.inc, examples/ssd0323/18f452.lkr * examples/ssd0323/ssd0323.asm, examples/ssd0323/osram128x64.inc, * examples/ssd0323/glcd_test.asm, examples/ssd0323/ssd0323.inc - Tons of changes... * utils/xpmtopic.c: a utility for converting an XPM formatted file into a PIC include file. 2007-03-15 Borut Razem * src/makefile.mingw: updated with the latest Scott's chages 2007-03-05 Scott Dattalo * src/osram.cc, src/ssd0323.cc, src/ssd0323.h: - Added support for '6800' and SPI interfaces. Now all three interfaces of the SSD0323 are supported * examples/ssd0323/ssd0323.asm, examples/ssd0323/osram128x64.inc, examples/ssd0323/glcd_test.asm: - The SSD0323 example code now can interface to an OSRAM display in either the 8080, 6800, or SPI modes. 2007-03-02 Scott Dattalo * src/glcd.h, src/osram.cc, src/ssd0323.cc, src/osram.h, src/ssd0323.h, src/gpsim_modules.cc, src/glcd_100X32_sed1520.cc, src/glcd.cc: - First version of SSD0323 support. - Changed the graphic rendering from PixMaps to RGB maps. The latter allows for arbitrary color definitions. (Used by the 4-bit gray scale of the SSD0323). 2007-03-02 Scott Dattalo * examples/ssd0323, examples/ssd0323/18f452.lkr: * examples/ssd0323/Makefile, examples/ssd0323/bitmaps.asm: * examples/ssd0323/glcd_test.asm, examples/ssd0323/globalvars.inc, * examples/ssd0323/osram128x64.asm, * examples/ssd0323/osram128x64.inc, examples/ssd0323/portdef.inc, * examples/ssd0323/processor.inc, examples/ssd0323/ssd0323.asm, * examples/ssd0323/ssd0323.inc: - Created an example for the SSD0323. 2007-02-23 Scott Dattalo * examples/18f452.lkr, examples/sed1520/18f452.lkr: * examples/bitmaps.asm, examples/sed1520/bitmaps.asm: * examples/glcd_test.asm, examples/sed1520/glcd_test.asm: * examples/globalvars.inc, examples/sed1520/globalvars.inc: * examples/lcd100X32.asm, examples/sed1520/lcd100X32.asm: * examples/lcd100X32.inc, examples/sed1520/lcd100X32.inc: * examples/Makefile, examples/sed1520/Makefile: * examples/portdef.inc, examples/sed1520/portdef.inc: * examples/processor.inc, examples/sed1520/processor.inc: * examples/sed1520.asm, examples/sed1520/sed1520.asm: * examples/sed1520.inc, examples/sed1520/sed1520.inc: - moved the SED1520 examples from the examples/ directory to the examples/sed1520 directory. 2007-02-23 Scott Dattalo * src/glcd_100X32_sed1520.cc, src/glcd_100X32_sed1520.h: - Split out generic graphics LCD code into separate classes. * src/glcd.cc, src/glcd.h: New. generic graphics lcd code. * src/osram.cc, osram.h: New. Beginning of OSRAM OLED display support * src/ssd0323.cc, src/ssd0323.h: New. Beginning of SSD-0323 controller support. 2007-02-22 Scott Dattalo * src/glcd_100X32_sed1520.cc: API sync. 2007-01-17 Scott Dattalo * src/glcd_100X32_sed1520.h, src/glcd_100X32_sed1520.cc: Provided a compile time definition (IN_BREADBOARD) to select whether the graphic LCD is rendered in the breadboard or rendered in its own window. 2006-11-08 Scott Dattalo * src/glcd_100X32_sed1520.cc: Trace type API update * configure.ac: 0.3.0-RC2 release candidate 2 2006-10-23 Scott Dattalo * Makefile.am: doc/ directory is now part of the distribution. 2006-10-23 Scott Dattalo * doc/sed1520.pdf, doc/mgls10032a.pdf: Added manufacturer data sheets. * configure.ac: Release candidate 0.3.0-RC1 * README: Added more details about the LCD hardware. 2006-10-15 Scott Dattalo * src/glcd_100X32_sed1520.cc: Port writes are now traced in gpsim's trace buffer. * extras/graphic_lcd/examples/lcd100X32.asm: fixed typo * extras/graphic_lcd/examples/glcd_test.asm: Position the LCD screen in the breadboard. 2006-05-28 Borut Razem * src/gpsim_modules.cc, src/sed1520.cc: removed unneeded inclusion of config.h * src/makefile.mingw: added, thanks to Xiaofan Chen * INSTALL: CVS replaced with Subversion 2006-05-27 Scott Dattalo * examples/glcd_test.asm: Added config settings. 2006-05-25 Scott Dattalo * src/glcd_100X32_sed1520.cc: Fixed segv, maybe? 2006-05-25 Scott Dattalo * src/glcd_100X32_sed1520.cc: There is segv lurking... 2005-12-29 Scott Dattalo * commit'd code to CVS gpsim-0.30.0/extras/graphic_lcd/README0000664000076400007640000000431313041763631014276 00000000000000Graphic LCD modules for gpsim Directories: src/ -- source code for gpsim module examples/ -- PIC assembly code illustrating the module. utils/ -- Utility for converting PNG files into gpasm include files. doc/ -- Manufacturer data sheets The graphic LCD module is a gpsim module that simulates a Varitronix 100 X 32 pixel graphic LCD. The graphics controller is a Seiko SED1520. Data sheets for the module and controller can be found in the doc/ subdirectory. The real display can be purchased from Mouser. (BTW, the Varitronix "data sheet" leaves much to be desired. Fortunately (for you) I've taken the time to understand how the real module behaves and wrote the simulation to mimic the actual device. The only (major) thing not supported at the moment is the LCD contrast. If you're using a real display, you'll need a negative supply of -1.0 to -2.0 volts tied to the "V0" pin. A relatively simple way to generate this is with a diode/resistor/capacitor voltage inverter driven from an oscillating I/O pin: C1 D2 PIC I/O -------||---+---|<---+---------+ 0.01uF | | \ V D1 === C2 /<------ V0 contrast - | 0.01uF \ 100K pot | | / /// /// | /// None of the values are too critical. However, you may wish to add an addition resistor between D2 and the potentiometer just to protect the display against overdriving. This circuit is a classic negative voltage generator. When the PIC I/O is high, C1 charges through D1 to Vdd-0.7 volts. When the PIC I/O line drives low, D1 becomes reversed biased and C1 discharges though D2. The direction of the current is such that C2 becomes negatively charged. The potentiometer divides this negative voltage by a user selectable amount to created the LCD bias.) Installing: ---------- See INSTALL for directions on installing the graphic LCD module. Also, there are directions for running the example. BUGS: ----- Module Update - the graphic module doesn't automatically update itself. gtk-2.6 segv - the graphic module doesn't run in pre-gtk-2.8. gpsim-0.30.0/extras/graphic_lcd/INSTALL0000664000076400007640000000131513041763630014445 00000000000000This module has now been integrated into the gpsim source tree, so no seperate process is required to build or install the module. At this point, the Graphic LCD module has been compiled and installed as a shared library that can be loaded by gpsim. If you want to see if it works, then run the example: $ cd graphic_lcd-X.Y.Z/examples $ make $ gpsim -s glcd_test.cod This will assemble the PIC code that tests the LCD module.This code is fairly complete and can be used as an LCD driver for a real PIC/LCD board. When gpsim comes up, you should see the Graphic LCD display. A random number of pixels will be on. As you single step through the code, you can see some of the test patterns written to the display. gpsim-0.30.0/extras/graphic_lcd/examples/0000775000076400007640000000000013117466030015310 500000000000000gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/0000775000076400007640000000000013117466030016373 500000000000000gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/lcd100X32.inc0000664000076400007640000000077313041763631020300 00000000000000 ; Definitions for the 100X32 graphic LCD ; EXTERN LCD_ClearScreen EXTERN SED1520_Test EXTERN LCD_Line EXTERN LCD_putBitMap LCD_nROWS EQU 32 LCD_nCOLS EQU 100 ;------------------------------------------------------------------------ ; External RAM declarations EXTERN PixelX ;Current X & Y coordinates for graphic's operations. E.g. EXTERN PixelY ;starting point for lines, upper left hand corner of rectangles. EXTERN LCD_x2 ;End point for lines, EXTERN LCD_y2 ; gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/bitmaps.asm0000664000076400007640000002504513041763631020465 00000000000000;************************************************************************ ; ; Bitmap file ; ; this is designed to be included by lcd100X32.asm. ;------------------------------------------------------------------------ BitMapTable: dw World32X32BitMap dw World16X16BitMap dw gpsimGraphic ; pnmtopic - pnm to PIC include file ; Copyright 2005 - Scott Dattalo ; Automatically converted from t.png ; World16X16BitMap: ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from konqueror16X16.png ; ; ; [] [][] . ; [] [] [] [] . ; [] [][][][] [] [] . ; [] [][][][][] [][] []. ; [] [][][][][][][] []. ; [][][][][][][][] . ; [][][][][][] . ; [][] [][] . ; [] . ; [] . ; [][][] . ; [] [][][] []. ; [] [][][][] []. ; [] [][][][][] [] . ; [] [][][][] [] . ; [][] [] [][] . ; db 0x10,0x02 ;width in pixels and height in bytes db 0x18,0x04,0x22,0xf8,0xfd,0x7e,0xfc,0xfe db 0x70,0x3c,0x08,0x01,0x01,0x02,0x04,0x18 db 0x18,0x20,0x40,0x80,0x81,0x06,0x04,0x7c db 0xf8,0x78,0x70,0xa0,0x80,0x40,0x20,0x18 World32X32BitMap ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from konqueror.png ; ; ; [][][][][][][][] . ; [][][] [][][] . ; [] [] . ; [][] [][][][][][][] [][] . ; [] [][][][][][][] [][] [] . ; [] [][][][][][][] [][] [] . ; [] [][][][][][][][][][] [][][] [] . ; [] [][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][] []. ; [] [][][][][][][][][][][][][] []. ; [] [][][][][][][][][][][] []. ; [] [][][][][] [][] []. ; [] [][] []. ; [] [][] []. ; [] [] []. ; [] [][][] []. ; [] [][] [][][] [] . ; [] [][] [][][] [] . ; [] [][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [][] [][][][][] [][] . ; [] [][][][][] [] . ; [][][] [] [][][] . ; [][][][][][][][] . ; db 0x20,0x04 ;width in pixels and height in bytes db 0x00,0x00,0x00,0xc0,0x20,0x10,0xc8,0xc8 db 0xc4,0xf2,0xfa,0xfa,0xf9,0xf9,0xf9,0xf9 db 0x89,0x81,0xf1,0xf1,0xc2,0x02,0x02,0x04 db 0x08,0x08,0x10,0x20,0xc0,0x00,0x00,0x00 db 0xf0,0x0e,0x01,0x00,0x00,0x3e,0xff,0xff db 0xff,0xff,0xff,0x7f,0x7f,0x7f,0xff,0xff db 0x7f,0x3f,0x0f,0x0f,0x07,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x01,0x0e,0xf0 db 0x0f,0x70,0x80,0x00,0x00,0x00,0x00,0x00 db 0x00,0x03,0x07,0x08,0x08,0x08,0xf0,0xf0 db 0xc0,0xf0,0xf0,0xf0,0xc0,0x80,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x0f db 0x00,0x00,0x00,0x03,0x04,0x08,0x10,0x10 db 0x20,0x40,0x40,0x40,0x80,0x80,0x8f,0x8f db 0xbf,0xff,0xbf,0xbf,0x7f,0x4f,0x40,0x20 db 0x10,0x10,0x08,0x04,0x03,0x00,0x00,0x00 gpsimGraphic ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from gpsim1.png ; ; ; . ; [][][] [][][][] . ; [][][][] [][][][] [][] [][] [][][] [][][][] . ; [][] [][] [] [] [] [] [][][][] [] [][] [][][][][] . ; [][] [][] [] [][] [][] [][] [] [][] [] [] [][] . ; [] [] [] [] [] [][] [][][] [][] . ; [] [] [] [][] [][] [] [] [] [] . ; [] [] [][] [][] [][][][] [][] [] [] [][] . ; [] [][] [][][][] [][][] [] [] [] [] . ; [] [][][][] [] [][] [] [] [] [] . ; [][][][] [] [] [] [] [] [] [] . ; [] [] [] [] [] [] [] . ; [] [] [] [] [] [] [] . ; [] [][] [] [][] [] [] [] [] [] . ; [] [] [] [] [][] [] [][] [][] [] . ; [] [][] [][] [][][][][][] [] [] [] [][] . ; [] [][][] [][] [] [] [] [] . ; [][][][][] [] [] [] [] . ; . ; . ; . ; [][] [][][] [][][][] [] [] [] [][][][] [][][][] . ; [][][][] [] [][][][] [][][] [] [] [] [][] [] [] [][] [] [] [][] . ; [][] [] [] [] [] [][] [] [] [] [] [] [] [] [] [] [] . ; [] [] [] [][] [] [] [][] [] [] [] [] [] [] [] [][] . ; [] [] [][] [] [][] [] [] [][][][][] [] [][][][] [][][] [][][][] . ; [] [] [] [] [] [] [] [] [] [] [][] [] [] [] . ; [][] [][][] [] [] [] [] [] [] [] [] [] [][] [] [][] [][] . ; [] [] [] [][] [] [][] [] [][] [] [] [] [][] [] [] [] . ; [] [] [][] [] [][] [][][][] [] [][] [] [] [] [][] [][] [] [] . ; [][][][] [][][][][] [][][][] [][] [][][] [] [] [] [] [][][][][] [] [] . ; . ; db 0x40,0x04 ;width in pixels and height in bytes db 0x00,0x00,0x00,0xf0,0x18,0x0c,0x04,0x04 db 0x0c,0x18,0xf0,0x00,0x00,0xfc,0x84,0x04 db 0x04,0x82,0x82,0x46,0x74,0x18,0x00,0x70 db 0xdc,0x86,0x82,0x82,0x06,0x04,0x0c,0x00 db 0x00,0x00,0x00,0x00,0x0c,0x1c,0xdc,0x8c db 0x00,0x00,0x00,0x00,0x18,0xe0,0x30,0x18 db 0x08,0x30,0xe0,0x38,0x08,0x08,0x08,0x18 db 0x30,0xe0,0x80,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0xe0,0x00,0x07,0x04,0x04,0x06 db 0x82,0xe3,0x3f,0x00,0x00,0xff,0x81,0x01 db 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20 db 0x60,0x80,0x80,0x81,0x81,0x81,0xc2,0x7e db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff db 0x00,0x00,0x00,0x00,0x00,0xc0,0x7f,0x00 db 0x00,0x00,0xc7,0x78,0x00,0x00,0x00,0x00 db 0x00,0x80,0xff,0x00,0x00,0x00,0x00,0x00 db 0x00,0x80,0xc3,0x42,0x42,0xc2,0x03,0x01 db 0xc1,0x00,0x00,0x00,0x00,0x03,0xc1,0x40 db 0x40,0x40,0x00,0x00,0xe0,0x60,0xc0,0x80 db 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x20 db 0x60,0x80,0x00,0x00,0xe0,0x20,0x20,0x63 db 0xc0,0x00,0x00,0xe0,0x00,0x63,0x80,0x00 db 0x00,0xc0,0x61,0x00,0xe0,0x20,0x20,0x20 db 0x00,0xe3,0x20,0x20,0x60,0xc0,0x00,0x00 db 0x00,0x0f,0x78,0x40,0x48,0x78,0x08,0x00 db 0x63,0x7c,0x40,0x40,0x40,0x1e,0x73,0x40 db 0x40,0x60,0x20,0x00,0x79,0x67,0x20,0x33 db 0x1e,0x00,0x00,0x00,0x00,0x00,0x7f,0x40 db 0x60,0x31,0x1f,0x00,0x7f,0x02,0x02,0x0e db 0x73,0x00,0x00,0x7f,0x00,0x00,0x03,0x7e db 0x3e,0x03,0x00,0x60,0x7f,0x42,0x42,0x40 db 0x00,0x7f,0x0a,0x02,0x0f,0x79,0x00,0x00 gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/18f452.lkr0000664000076400007640000000146013041763631017662 00000000000000// $Id: 18f452.lkr 1410 2005-12-29 15:51:11Z sdattalo $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr START=0x80 END=0x5ff ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/globalvars.inc0000664000076400007640000000004213041763631021141 00000000000000 ; EXTERN's for global variables gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/lcd100X32.asm0000664000076400007640000003750113041763631020306 00000000000000; ; lcd100X32.asm - Driver for 100X32 pixel graphics LCD based on ; SED1520 controllers ; ; ; From a high level point of view, this driver supports basic graphing ; and text functions (that the SED1320 lacks). The graphing functions ; include points and lines, while the text function allows 5X7 fonts ; to be written to the display. ; ; The driver is relatively inefficient with regards to memory usage. The ; entire 100X32 LCD display is buffered in the PIC's memory. The purpose ; of this is to simplify the mapping of the logical coordinates of the LCD ; display to the RAM embedded in the SED1520's. ; ; !!! NOTE: The driver assumes all variables reside in Bank 0!. !!! include "processor.inc" include "sed1520.inc" ; GLOBAL DisplayBuffer EXTERN DisplayBuffer GLOBAL LCD_ClearScreen GLOBAL SED1520_Test GLOBAL LCD_Line GLOBAL LCD_putBitMap EXTERN temp0, temp1, temp2, temp3 UDATA_ACS LCD_WritePtrLo RES 1 LCD_WritePtrHi RES 1 PixelX RES 1 PixelY RES 1 TempX RES 1 TempY RES 1 global TempY, PixelX, PixelY ;---------------------------------------- ; Private RAM area for temporary variables. TempRam udata_ovr 0x78 LCD_Temporaries RES 6 TempRam udata_ovr 0x78 LCD_x2 RES 1 LCD_y2 RES 1 slope RES 1 dx RES 1 dy RES 1 dir RES 1 global LCD_x2, LCD_y2 ;------------------------------------------------------------------------ ; Display buffer ; ;GPR_ARRAYS UDATA 400 ;DisplayBuffer RES 100*4 ;------------------------------------------------------------------------ ; LCD_CODE CODE SED1520_Test: TestBitMap: MOVLW 20 MOVWF PixelX CLRF PixelY MOVLW 2 RCALL LCD_putBitMap CLRF PixelX CLRF PixelY MOVLW 93 MOVWF LCD_x2 CLRF LCD_y2 RCALL LCD_Line MOVLW 31 MOVWF LCD_x2 MOVWF LCD_y2 RCALL LCD_Line CLRF PixelX CLRF PixelY RCALL LCD_Line bra LCD_RefreshDisplay ;------------------------------------------------------------------------ ;LCD_ClearScreen LCD_ClearScreen: LFSR 0, DisplayBuffer ;Get a pointer to the display movlw 100 movwf temp0 movlw 4 cs1: CLRF POSTINC0 decfsz temp0,F bra cs1 decfsz WREG,F bra cs1 return ;------------------------------------------------------------------------ ; LCD_putBitMap ; ; Input: x1, y1 - Where the upper left hand corner of the bitmap will be placed ; WREG - Bitmap # (i.e. index into the BitMapTable array) ; Output ; MemUsed: temp0 - used as a counter ; PRODL,PRODH ; TBLPTRL,TBLPTRH ; ; Calls: LCD_putByte LCD_putBitMap: ; Point to BitMapTable entry that contains the pointer ; to the desired bitmap. RLNCF WREG,W ADDLW LOW(BitMapTable) MOVWF TBLPTRL MOVLW HIGH(BitMapTable) SKPNC ADDLW 1 MOVWF TBLPTRH ; Get the pointer to the bitmap TBLRD *+ MOVF TABLAT,W TBLRD *+ MOVWF TBLPTRL MOVF TABLAT,W MOVWF TBLPTRH ; The first byte of the bitmap is the width and the second is the height TBLRD *+ MOVF TABLAT,W MOVWF LCD_y2 TBLRD *+ MOVF TABLAT,W MOVWF LCD_x2 ; At this point, the TBLPTR points to the bitmap data. Now we need ; to fetch this data and copy it to the display. movf PixelX,W movwf temp1 rrncf PixelY,W rrncf WREG,W rrncf WREG,W RCALL LCD_MoveCursor pbm1: MOVF LCD_y2,W MOVWF temp0 pbm2: TBLRD *+ MOVF TABLAT,W RCALL LCD_PutByte DECFSZ temp0,F bra pbm2 MOVF LCD_y2,W SUBLW 100 ADDWF LCD_WritePtrLo,F CLRW ADDWFC LCD_WritePtrHi,F DECFSZ LCD_x2,F bra pbm1 aret: RETURN ;------------------------------------------------------------------------ ; LCD_putc ; ; Write a single character to the LCD display buffer. The input is the ASCII ; code of the character to write. This is used as an index into the LCD font ; table. The 5 7-bit bytes that comprise this character are then written to ; the LCD display buffer. In addition, a 6th byte containing 0 is written so ; that there will be a little space between characters. Note, the character ; will be written at the current location of the cursor. No attempt is made ; to prevent line wrapping. ; ; Input: WREG - ASCII value of character ; Output: None ; Mem used: temp0 - used as a counter ; LCD_putc: BTFSC WREG,7 ;The max character is 127 return ;leave if we're beyond this. ADDLW -' ' ;The first character in the table is a Space BNC aret ;leave if the ascii code is smaller than this MULLW 5 ;Each character is comprised of 5 bytes. ;The offset into the table is the product ;of the ASCII code and the size of each character CLRF TBLPTRU ;Get a pointer to the MOVF PRODL,W ;start of this character's font ADDLW LOW(ASCII_5X7Table) ; MOVWF TBLPTRL ; MOVLW HIGH(ASCII_5X7Table) ; ADDWFC PRODH,W MOVWF TBLPTRH ; ; MOVLW 5 ; Now loop through and get all 5 bytes MOVWF temp0 LCD_ASCII_L1 TBLRD *+ ;Get one byte MOVF TABLAT,W ; rcall LCD_PutByte ;Write the byte to the display buffer decfsz temp0,F bra LCD_ASCII_L1 MOVLW 0 ;; ;; !!!! Intentionally fall through to write a zero to the display ;; ;------------------------------------------------------------------------ ; LCD_PutByte - write a byte of data to the LCD display buffer ; ; Write the byte contained in W to the display buffer. The byte is written ; at the current cursor position. Also, the cursor position is incremented ; after the write. ; ; INPUT: WREG ; OUTPUT: ; Mem Used: temp1 ; LCD_WritePtrLo/Hi ; FSR0L/H LCD_PutByte: MOVWF temp1 ;Save the byte to write LFSR 0, DisplayBuffer ;Get a pointer to the display MOVF LCD_WritePtrLo,W ;Now point to the location ADDWF FSR0L,F ;of the cursor. MOVF LCD_WritePtrHi,W ADDWFC FSR0H,F MOVFF temp1, INDF0 ;Write the byte to the display INFSNZ LCD_WritePtrLo,F ;Increment the cursor position INCF LCD_WritePtrHi,F MOVLW LOW(400) ;The Display buffer is only 400 CPFSLT LCD_WritePtrLo ;bytes. If we didn't increment BTFSS LCD_WritePtrHi,0 ;beyond the end of the display return ;then we're okay. CLRF LCD_WritePtrHi ;oops - we've rolled over CLRF LCD_WritePtrLo return ;------------------------------------------------------------------------ ; LCD_MoveCursor - re-position the cursor. The cursor marks where the next ; byte will be written ; ; INPUT: WREG - row ; temp1 - column ; OUTPUT ; MemUsed: LCD_WritePtrLo/HI ; PRODL/H LCD_MoveCursor: ANDLW 3 MULLW 100 MOVF PRODL,W MOVWF LCD_WritePtrLo MOVF PRODH,W MOVWF LCD_WritePtrHi MOVF temp1,W ADDWF LCD_WritePtrLo,F CLRW ADDWFC LCD_WritePtrHi,F RETURN ;------------------------------------------------------------------------ ; LCD_GetPixelPtr - convert the current (PixelX,PixelY) coordinates into ; a pointer into the display buffer. This pointer is returned in FSR0 ; and the bit offset within the byte of the display buffer is returned ; is returned as bit mask in temp0. ; ; { ; temp0 = 1<<(PixelY & 7); ; ; int offset = (PixelY>>3) * nLCD_COLUMNS + PixelX ; FSR0 = &DisplayBuffer[offset]; ; return(temp0); ; } ; ; Input: PixelX = X location of the pixel ; PixelY = Y location of the pixel ; Output: FSR0L:FSR0H -- will point to the byte offset in the display buffer ; temp0 -- 2^n where n is the position within the byte. ; LCD_GetPixelPtr: RRCF PixelY,W ;Put the LSB of the current Y pixel into C. CLRF temp0 ; BSF temp0,0 ; 1<<0 -- assumes Y is even SKPNC ; RLNCF temp0,F ; 1<<1 -- Y is actually odd RRCF WREG,W ;Put bit 1 of the current Y pixel into C BNC pp1 ; RLNCF temp0,F ; bit 1 is set, so we need to shift the RLNCF temp0,F ; mask two positions pp1: RRCF WREG,W ;Put bit 2 of the current Y pixel into C SKPNC ;If it is set SWAPF temp0,F ; then shift the mask left 4 positions. ANDLW 3 ;The lower two bits of W are the 3rd and 4th ;bit of the current Y pixel. MULLW 100 ;Multiply by 100 (number of columns in a row) ;to obtain the byte offset into the buffer. LFSR 0, DisplayBuffer ;Get a pointer to the display MOVF PRODL,W ADDWF FSR0L,F MOVF PRODH,W ADDWFC FSR0H,F MOVF PixelX,W ADDWF FSR0L,F MOVLW 0 ADDWFC FSR0H,F ret1: return ;------------------------------------------------------------------------ ; LCD_Line - Draw a line ; ; Inputs: PixelX, PixelY - start coordinates ; LCD_x2, LCD_y2 - end coordinates ; ; int dx = abs(x2-x1); ; int dy = abs(y2-y1); ; ; int bRight = 1; ; int bUp = 1; ; ; if (dx<0) { ; bRight = 0; ; dx = -dx; ; } ; if (dy<0) { ; bUp = 0 ; ; dy = -dY; ; } ; ; int slope = dx - dy; ; ; do { ; ; SetPixel(x,y); ; ; if ( slope < 0) { ; y++; ; slope += dx; ; } else { ; x++; ; slope -= dy; ; } ; } while (x!=x2 && y!=y2); ; ; ; MEM Used: ; dx ; dy ; slope ; temp1 ; Calls: ; LCD_SetPixel ; LCD_Line: MOVF PixelX,W ;x1 SUBWF LCD_x2,W ;W=x2-x1 MOVWF dx ;dx=x2-x1 RLCF dir,F ;Pick up carry BTFSS dir,0 ;if x2 ; The defines in portdef.inc allow the LCD port definitions to be customized. #include "portdef.inc" #include "lcd100X32.inc" ; Functions: GLOBAL SED1520_Init GLOBAL SED1520_WriteCmd GLOBAL LCD_RefreshDisplay EXTERN temp0, temp1, temp2, temp3 EXTERN DisplayBuffer ;======================================================================== ; ; SED1520 Driver ; ; ; RAM Definitions UDATA_ACS ;-------------------- ; Mode ;-------------------- SED1520_Mode RES 1 GLOBAL SED1520_Mode ; xxxx_xxCM ; |+--- Mode 0=Command 1=Data ; +---- Chip 0=1st chip on Display, 1=2nd chip bSED1520_MODE_CHIP EQU 1<<1 ;------------------------------------------------------------------------ ; Macros ; SetMode ; Selects between Command and Data mode mSED1520_SetMode macro BCF LATA, RA1 BTFSC SED1520_Mode,bSED1520_MODE_CMD BSF LATA, RA1 endm mSED1520_SelectChip macro BTFSS SED1520_Mode,bSED1520_MODE_CHIP BCF LATE, RE0 ; BTFSC SED1520_Mode,bSED1520_MODE_CHIP ; BCF LATE, RE1 endm mSED1520_deSelectChip macro BTFSS SED1520_Mode,bSED1520_MODE_CHIP BSF LATE, RE0 BTFSC SED1520_Mode,bSED1520_MODE_CHIP BSF LATE, RE1 endm SETA0 macro BSF LCDA0_LAT,LCDA0_BIT endm CLRA0 macro BCF LCDA0_LAT,LCDA0_BIT endm ;------------------------------------------------------------------------ ; SED1520 commands ; ; The SED1520 Commands are written to address 1 of the chip. ; The data written for the command includes the command type and optional ; parameters. The data bus is only 8-bits wide. The upper bits in general ; describe the command while the lower are for data SED1520_DisplayOn EQU 0xaf SED1520_DisplayOff EQU 0xae SED1520_DisplayStartLine EQU 0xc0 SED1520_SETPAGEADDRESS EQU 0xb8 SED1520_SetColumnAddress EQU 0x00 SED1520_SetDuty EQU 0xa8 ;------------------------------------------------------------------------ ; SED1520_CODE CODE SED1520_Init: BCF TRISA, RA1 CLRF SED1520_TRIS if LCDE1_TRIS == LCDE2_TRIS && LCDE1_TRIS == LCDRW_TRIS CLRF TRISE else BCF LCDE1_TRIS, LCDE1_BIT BCF LCDE2_TRIS, LCDE2_BIT BCF LCDRW_TRIS, LCDRW_BIT endif ; Select the first chip and set the mode to command CLRF SED1520_Mode RCALL LSED1520_Init BSF SED1520_Mode, bSED1520_MODE_CHIP ; Fall through to initialize the second chip LSED1520_Init: MOVLW SED1520_DisplayStartLine rcall SED1520_WriteCmd MOVLW SED1520_SETPAGEADDRESS rcall SED1520_WriteCmd MOVLW SED1520_SetColumnAddress rcall SED1520_WriteCmd MOVLW SED1520_SetDuty|1 rcall SED1520_WriteCmd MOVLW SED1520_DisplayOn bra SED1520_WriteCmd ;------------------------------------------------------------ ; Write either a command or data to the SED1520 ; ; Inputs: WREG - byte to be written ; Outputs: ; Mem used: W ; SED1520_WriteCmd ;<--- Entry point to write a command. BCF LATA, RA1 SED1520_Write: ;<--- Entry point to write data. BCF LATE, RE2 ;SED1520 R/W' = write rcall d2 MOVWF SED1520_LAT rcall d2 BTFSS SED1520_Mode,bSED1520_MODE_CHIP BSF LATE, RE0 BTFSC SED1520_Mode,bSED1520_MODE_CHIP BSF LATE, RE1 rcall d2 BCF LATE, RE0 BCF LATE, RE1 BSF LATA, RA1 return d2 rcall d3 d3 return ;------------------------------------------------------------------------ ;LCD_RefreshDisplay - copy the RAM buffered display to the physical display ; ; Inputs: None ; Outputs: None ; MemUsed: temp0 LCD_RefreshDisplay: LFSR 0, DisplayBuffer RCALL SED1520_Init CLRF SED1520_Mode MOVLW LCD_nROWS/8 MOVWF temp0 SED_ref1: BCF SED1520_Mode,bSED1520_MODE_CHIP RCALL SED_ref2 BSF SED1520_Mode,bSED1520_MODE_CHIP RCALL SED_ref2 DECFSZ temp0,F bra SED_ref1 return SED_ref2: MOVLW SED1520_SetColumnAddress rcall SED1520_WriteCmd MOVF temp0,W SUBLW LCD_nROWS/8 ANDLW 3 IORLW SED1520_SETPAGEADDRESS rcall SED1520_WriteCmd MOVLW 50 MOVWF temp1 SED_ref3: MOVF POSTINC0,W rcall SED1520_Write DECFSZ temp1,F bra SED_ref3 return ;------------------------------------------------------------ end gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/glcd_test.asm0000664000076400007640000001001213041763631020762 00000000000000 ;; Node test ;; ;; The purpose of this program is to verify that nodes ;; can interconnect I/O pins. include "processor.inc" include ; Grab some useful macros CONFIG OSC = HSPLL, OSCS = ON, WDT = ON, LVP = OFF CONFIG CP0 = ON, CP1 = ON, CPB = ON include "sed1520.inc" include "lcd100X32.inc" include "portdef.inc" ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ; Variable declarations ;---------------------------------------------------------------------- GPR_DATA UDATA_ACS temp RES 1 temp0 RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 GLOBAL temp0, temp1, temp2, temp3 Tx RES 1 Ty RES 1 DISPLAY_DATA UDATA 400 DisplayBuffer RES 100*4 GLOBAL DisplayBuffer ;------------------------------------------------------------------------ ; Code labels GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;---------------------------------------------------------------------- ; ******************* INTERRUPT VECTOR LOCATION ****************** ;---------------------------------------------------------------------- INT_VECTOR CODE 0x008 ; interrupt vector location RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;; ;; Define the simulation environment. ;; .sim "module library libgpsim_extras" .sim "module library libgpsim_modules" .sim "module load LCD100X32 LCD" .sim "module load pullup R1" .sim "module load pullup R2" .sim "node nE1" .sim "node nE2" .sim "node nRW" .sim "node nA0" .sim "attach nE1 porte0 LCD.e1 R1.pin" .sim "attach nE2 porte1 LCD.e2 R2.pin" .sim "attach nRW porte2 LCD.rw" .sim "attach nA0 porta1 LCD.a0" .sim "node nd0 nd1 nd2 nd3 nd4 nd5 nd6 nd7" .sim "attach nd0 portb0 LCD.d0" .sim "attach nd1 portb1 LCD.d1" .sim "attach nd2 portb2 LCD.d2" .sim "attach nd3 portb3 LCD.d3" .sim "attach nd4 portb4 LCD.d4" .sim "attach nd5 portb5 LCD.d5" .sim "attach nd6 portb6 LCD.d6" .sim "attach nd7 portb7 LCD.d7" ;; Now position the modules in the BreadBoard viewer .sim "LCD.xpos=192.0" .sim "LCD.ypos=24.0" .sim "R1.xpos=216.0" .sim "R1.ypos=264.0" .sim "R2.xpos=312.0" .sim "R2.ypos=264.0" ;; Initialize the SED1520 LCD graphics controller. RCALL SED1520_Init loop: CLRWDT ; Clear Screen Test RCALL LCD_ClearScreen RCALL LCD_RefreshDisplay ; Line Test movlw 31 movwf Ty movlw 99 movwf Tx LL clrwdt movf Tx,W MOVWF LCD_x2 movf Ty,W MOVWF LCD_y2 MOVLW 0 MOVWF PixelX MOVLW 1 MOVWF PixelY RCALL LCD_Line ; RCALL LCD_RefreshDisplay decf Tx,F BNN LL RCALL LCD_RefreshDisplay MOVLW 0 MOVWF PixelX MOVWF PixelY MOVLW 99 MOVWF LCD_x2 MOVLW 15 MOVWF LCD_y2 RCALL LCD_Line RCALL LCD_RefreshDisplay MOVLW 20 MOVWF PixelX CLRF PixelY .assert "\"Press run for next test\"" nop RCALL LCD_ClearScreen MOVLW 1 RCALL LCD_putBitMap RCALL LCD_RefreshDisplay .assert "\"Press run for next test\"" nop RCALL LCD_ClearScreen CLRF PixelX MOVLW 0 RCALL LCD_putBitMap RCALL LCD_RefreshDisplay MOVLW 32 MOVWF PixelX MOVLW 2 RCALL LCD_putBitMap RCALL LCD_RefreshDisplay .assert "\"Press run to repeat test\"" nop bra loop nop done: .assert "\"*** PASSED LCD test\"" goto $ FAILED: .assert "\"*** FAILED LCD test\"" goto $ end gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/portdef.inc0000664000076400007640000000131513041763631020454 00000000000000 ;------------------------------------------------------------------------ ; ; I/O Port definitions for the SED1520 based graphic LCD ; ; ; The user of the graphic LCD module should configure this ; file according to their specific application. ; LCDA0_PORT EQU PORTA LCDA0_TRIS EQU TRISA LCDA0_LAT EQU LATA LCDA0_BIT EQU RA1 LCDE1_PORT EQU PORTE LCDE1_TRIS EQU TRISE LCDE1_LAT EQU LATE LCDE1_BIT EQU RE0 LCDE2_PORT EQU PORTE LCDE2_TRIS EQU TRISE LCDE2_LAT EQU LATE LCDE2_BIT EQU RE1 LCDRW_PORT EQU PORTE LCDRW_TRIS EQU TRISE LCDRW_LAT EQU LATE LCDRW_BIT EQU RE2 SED1520_PORT EQU PORTB SED1520_TRIS EQU TRISB SED1520_LAT EQU LATB gpsim-0.30.0/extras/graphic_lcd/examples/sed1520/processor.inc0000664000076400007640000000040313041763631021025 00000000000000; ; Processor include file. ; ; All .asm files in the project include this file. If the processor ; type needs to change, then those changes only need to be made ; here list p=18f452,t=ON,c=132,n=80 radix dec #include gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/0000775000076400007640000000000013117466030016411 500000000000000gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/bitmaps.asm0000664000076400007640000002504513041763631020503 00000000000000;************************************************************************ ; ; Bitmap file ; ; this is designed to be included by lcd100X32.asm. ;------------------------------------------------------------------------ BitMapTable: dw World32X32BitMap dw World16X16BitMap dw gpsimGraphic ; pnmtopic - pnm to PIC include file ; Copyright 2005 - Scott Dattalo ; Automatically converted from t.png ; World16X16BitMap: ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from konqueror16X16.png ; ; ; [] [][] . ; [] [] [] [] . ; [] [][][][] [] [] . ; [] [][][][][] [][] []. ; [] [][][][][][][] []. ; [][][][][][][][] . ; [][][][][][] . ; [][] [][] . ; [] . ; [] . ; [][][] . ; [] [][][] []. ; [] [][][][] []. ; [] [][][][][] [] . ; [] [][][][] [] . ; [][] [] [][] . ; db 0x10,0x02 ;width in pixels and height in bytes db 0x18,0x04,0x22,0xf8,0xfd,0x7e,0xfc,0xfe db 0x70,0x3c,0x08,0x01,0x01,0x02,0x04,0x18 db 0x18,0x20,0x40,0x80,0x81,0x06,0x04,0x7c db 0xf8,0x78,0x70,0xa0,0x80,0x40,0x20,0x18 World32X32BitMap ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from konqueror.png ; ; ; [][][][][][][][] . ; [][][] [][][] . ; [] [] . ; [][] [][][][][][][] [][] . ; [] [][][][][][][] [][] [] . ; [] [][][][][][][] [][] [] . ; [] [][][][][][][][][][] [][][] [] . ; [] [][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][][][] [] . ; [] [][][][][][][][][][][][][] []. ; [] [][][][][][][][][][][][][] []. ; [] [][][][][][][][][][][] []. ; [] [][][][][] [][] []. ; [] [][] []. ; [] [][] []. ; [] [] []. ; [] [][][] []. ; [] [][] [][][] [] . ; [] [][] [][][] [] . ; [] [][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [] [][][][][][][][] [] . ; [][] [][][][][] [][] . ; [] [][][][][] [] . ; [][][] [] [][][] . ; [][][][][][][][] . ; db 0x20,0x04 ;width in pixels and height in bytes db 0x00,0x00,0x00,0xc0,0x20,0x10,0xc8,0xc8 db 0xc4,0xf2,0xfa,0xfa,0xf9,0xf9,0xf9,0xf9 db 0x89,0x81,0xf1,0xf1,0xc2,0x02,0x02,0x04 db 0x08,0x08,0x10,0x20,0xc0,0x00,0x00,0x00 db 0xf0,0x0e,0x01,0x00,0x00,0x3e,0xff,0xff db 0xff,0xff,0xff,0x7f,0x7f,0x7f,0xff,0xff db 0x7f,0x3f,0x0f,0x0f,0x07,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x01,0x0e,0xf0 db 0x0f,0x70,0x80,0x00,0x00,0x00,0x00,0x00 db 0x00,0x03,0x07,0x08,0x08,0x08,0xf0,0xf0 db 0xc0,0xf0,0xf0,0xf0,0xc0,0x80,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x80,0x70,0x0f db 0x00,0x00,0x00,0x03,0x04,0x08,0x10,0x10 db 0x20,0x40,0x40,0x40,0x80,0x80,0x8f,0x8f db 0xbf,0xff,0xbf,0xbf,0x7f,0x4f,0x40,0x20 db 0x10,0x10,0x08,0x04,0x03,0x00,0x00,0x00 gpsimGraphic ; pngtopic - png to gpasm PIC include file ; for use with gpsim's graphic's LCD driver ; Copyright 2005 - Scott Dattalo ; Automatically converted from gpsim1.png ; ; ; . ; [][][] [][][][] . ; [][][][] [][][][] [][] [][] [][][] [][][][] . ; [][] [][] [] [] [] [] [][][][] [] [][] [][][][][] . ; [][] [][] [] [][] [][] [][] [] [][] [] [] [][] . ; [] [] [] [] [] [][] [][][] [][] . ; [] [] [] [][] [][] [] [] [] [] . ; [] [] [][] [][] [][][][] [][] [] [] [][] . ; [] [][] [][][][] [][][] [] [] [] [] . ; [] [][][][] [] [][] [] [] [] [] . ; [][][][] [] [] [] [] [] [] [] . ; [] [] [] [] [] [] [] . ; [] [] [] [] [] [] [] . ; [] [][] [] [][] [] [] [] [] [] . ; [] [] [] [] [][] [] [][] [][] [] . ; [] [][] [][] [][][][][][] [] [] [] [][] . ; [] [][][] [][] [] [] [] [] . ; [][][][][] [] [] [] [] . ; . ; . ; . ; [][] [][][] [][][][] [] [] [] [][][][] [][][][] . ; [][][][] [] [][][][] [][][] [] [] [] [][] [] [] [][] [] [] [][] . ; [][] [] [] [] [] [][] [] [] [] [] [] [] [] [] [] [] . ; [] [] [] [][] [] [] [][] [] [] [] [] [] [] [] [][] . ; [] [] [][] [] [][] [] [] [][][][][] [] [][][][] [][][] [][][][] . ; [] [] [] [] [] [] [] [] [] [] [][] [] [] [] . ; [][] [][][] [] [] [] [] [] [] [] [] [] [][] [] [][] [][] . ; [] [] [] [][] [] [][] [] [][] [] [] [] [][] [] [] [] . ; [] [] [][] [] [][] [][][][] [] [][] [] [] [] [][] [][] [] [] . ; [][][][] [][][][][] [][][][] [][] [][][] [] [] [] [] [][][][][] [] [] . ; . ; db 0x40,0x04 ;width in pixels and height in bytes db 0x00,0x00,0x00,0xf0,0x18,0x0c,0x04,0x04 db 0x0c,0x18,0xf0,0x00,0x00,0xfc,0x84,0x04 db 0x04,0x82,0x82,0x46,0x74,0x18,0x00,0x70 db 0xdc,0x86,0x82,0x82,0x06,0x04,0x0c,0x00 db 0x00,0x00,0x00,0x00,0x0c,0x1c,0xdc,0x8c db 0x00,0x00,0x00,0x00,0x18,0xe0,0x30,0x18 db 0x08,0x30,0xe0,0x38,0x08,0x08,0x08,0x18 db 0x30,0xe0,0x80,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0xe0,0x00,0x07,0x04,0x04,0x06 db 0x82,0xe3,0x3f,0x00,0x00,0xff,0x81,0x01 db 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20 db 0x60,0x80,0x80,0x81,0x81,0x81,0xc2,0x7e db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff db 0x00,0x00,0x00,0x00,0x00,0xc0,0x7f,0x00 db 0x00,0x00,0xc7,0x78,0x00,0x00,0x00,0x00 db 0x00,0x80,0xff,0x00,0x00,0x00,0x00,0x00 db 0x00,0x80,0xc3,0x42,0x42,0xc2,0x03,0x01 db 0xc1,0x00,0x00,0x00,0x00,0x03,0xc1,0x40 db 0x40,0x40,0x00,0x00,0xe0,0x60,0xc0,0x80 db 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x20 db 0x60,0x80,0x00,0x00,0xe0,0x20,0x20,0x63 db 0xc0,0x00,0x00,0xe0,0x00,0x63,0x80,0x00 db 0x00,0xc0,0x61,0x00,0xe0,0x20,0x20,0x20 db 0x00,0xe3,0x20,0x20,0x60,0xc0,0x00,0x00 db 0x00,0x0f,0x78,0x40,0x48,0x78,0x08,0x00 db 0x63,0x7c,0x40,0x40,0x40,0x1e,0x73,0x40 db 0x40,0x60,0x20,0x00,0x79,0x67,0x20,0x33 db 0x1e,0x00,0x00,0x00,0x00,0x00,0x7f,0x40 db 0x60,0x31,0x1f,0x00,0x7f,0x02,0x02,0x0e db 0x73,0x00,0x00,0x7f,0x00,0x00,0x03,0x7e db 0x3e,0x03,0x00,0x60,0x7f,0x42,0x42,0x40 db 0x00,0x7f,0x0a,0x02,0x0f,0x79,0x00,0x00 gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/18f452.lkr0000664000076400007640000000164613041763631017706 00000000000000// $Id: 18f452.lkr 1410 2005-12-29 15:51:11Z sdattalo $ // File: 18f452.lkr // Sample linker script for the PIC18F452 processor LIBPATH . CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=main START=0x2A END=0x2FFF CODEPAGE NAME=LCD_TABLES START=0x3000 END=0x33FF CODEPAGE NAME=bitmaps START=0x3400 END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED ACCESSBANK NAME=accessram START=0x0 END=0x7F DATABANK NAME=gpr START=0x80 END=0x5ff ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED SECTION NAME=CONFIG ROM=config gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/globalvars.inc0000664000076400007640000000004213041763631021157 00000000000000 ; EXTERN's for global variables gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/ssd0323.inc0000664000076400007640000000047013041763631020131 00000000000000 ; ;SSD0323 driver for 16bit-core PICs ; Scott Dattalo ; EXTERN SSD0323_Init EXTERN LCD_RefreshDisplay EXTERN LCD_RefreshEntireDisplay EXTERN SSD_SetColumnRange EXTERN SSD_SetRowRange EXTERN CommandLoop EXTERN SSD0323_Write EXTERN SSD0323_WriteCmd EXTERN CommandWaitForSPI gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/osram128x64.asm0000664000076400007640000003450313041763631020761 00000000000000; ; osram128x64.asm - Driver for 128x64 pixel graphics LCD based on ; SSD0323 controllers ; ; ; From a high level point of view, this driver supports basic graphing ; and text functions (that the SED1320 lacks). The graphing functions ; include points and lines, while the text function allows 5X7 fonts ; to be written to the display. ; ; !!! NOTE: The driver assumes all variables reside in Bank 0!. !!! include "processor.inc" include "ssd0323.inc" ; GLOBAL DisplayBuffer EXTERN DisplayBuffer GLOBAL LCD_ClearScreen GLOBAL SSD0323_Test GLOBAL LCD_Line GLOBAL LCD_putBitMap GLOBAL LCD_ResetCursor GLOBAL LCD_MoveCursor EXTERN temp0, temp1, temp2, temp3 UDATA_ACS LCD_WritePtrLo RES 1 LCD_WritePtrHi RES 1 PixelX RES 1 PixelY RES 1 TempX RES 1 TempY RES 1 global TempY, PixelX, PixelY ; The virtual display (rendered in the PIC's ram) size is defined here: DisplaySizeX RES 1 DisplaySizeY RES 1 global DisplaySizeX,DisplaySizeY ;---------------------------------------- ; Private RAM area for temporary variables. TempRam udata_ovr 0x78 LCD_Temporaries RES 6 TempRam udata_ovr 0x78 LCD_x2 RES 1 LCD_y2 RES 1 slope RES 1 dx RES 1 dy RES 1 dir RES 1 global LCD_x2, LCD_y2 ;------------------------------------------------------------------------ ; Display buffer ; ;GPR_ARRAYS UDATA 400 ;DisplayBuffer RES 100*4 ;------------------------------------------------------------------------ ; LCD_CODE CODE SSD0323_Test: MOVLW 20 MOVWF PixelX CLRF PixelY MOVLW 2 RCALL LCD_putBitMap CLRF PixelX CLRF PixelY MOVLW 93 MOVWF LCD_x2 CLRF LCD_y2 RCALL LCD_Line MOVLW 31 MOVWF LCD_x2 MOVWF LCD_y2 RCALL LCD_Line CLRF PixelX CLRF PixelY RCALL LCD_Line bra LCD_RefreshDisplay ;------------------------------------------------------------------------ ;LCD_ClearScreen LCD_ClearScreen: LFSR 0, DisplayBuffer ;Get a pointer to the display SWAPF DisplaySizeY,W ;Y/16 RLNCF WREG,W ;Y/8 ANDLW 0x1f MULWF DisplaySizeX MOVFF PRODL,temp0 MOVF PRODH,W cs1 CLRF POSTINC0 decfsz temp0,F bra cs1 andlw 0xff BZ LCS1 decfsz WREG,F bra cs1 LCS1: return ;------------------------------------------------------------------------ ; LCD_putBitMap ; ; Input: x1, y1 - Where the upper left hand corner of the bitmap will be placed ; WREG - Bitmap # (i.e. index into the BitMapTable array) ; Output ; MemUsed: temp0 - used as a counter ; PRODL,PRODH ; TBLPTRL,TBLPTRH ; ; Calls: LCD_putByte LCD_putBitMap: ; Point to BitMapTable entry that contains the pointer ; to the desired bitmap. RLNCF WREG,W ADDLW LOW(BitMapTable) MOVWF TBLPTRL MOVLW HIGH(BitMapTable) SKPNC ADDLW 1 MOVWF TBLPTRH ; Get the pointer to the bitmap TBLRD *+ MOVF TABLAT,W TBLRD *+ MOVWF TBLPTRL MOVF TABLAT,W MOVWF TBLPTRH ; The first byte of the bitmap is the width and the second is the height TBLRD *+ MOVF TABLAT,W MOVWF LCD_y2 TBLRD *+ MOVF TABLAT,W MOVWF LCD_x2 ; At this point, the TBLPTR points to the bitmap data. Now we need ; to fetch this data and copy it to the display. movf PixelX,W movwf temp1 rrncf PixelY,W rrncf WREG,W rrncf WREG,W RCALL LCD_MoveCursor pbm1: MOVF LCD_y2,W MOVWF temp0 pbm2: TBLRD *+ MOVF TABLAT,W RCALL LCD_PutByte DECFSZ temp0,F bra pbm2 MOVF LCD_y2,W SUBLW 128 ADDWF LCD_WritePtrLo,F CLRW ADDWFC LCD_WritePtrHi,F DECFSZ LCD_x2,F bra pbm1 aret: RETURN ;------------------------------------------------------------------------ ; LCD_putc ; ; Write a single character to the LCD display buffer. The input is the ASCII ; code of the character to write. This is used as an index into the LCD font ; table. The 5 7-bit bytes that comprise this character are then written to ; the LCD display buffer. In addition, a 6th byte containing 0 is written so ; that there will be a little space between characters. Note, the character ; will be written at the current location of the cursor. No attempt is made ; to prevent line wrapping. ; ; Input: WREG - ASCII value of character ; Output: None ; Mem used: temp0 - used as a counter ; LCD_putc: global LCD_putc BTFSC WREG,7 ;The max character is 127 return ;leave if we're beyond this. ADDLW -' ' ;The first character in the table is a Space BNC aret ;leave if the ascii code is smaller than this MULLW 5 ;Each character is comprised of 5 bytes. ;The offset into the table is the product ;of the ASCII code and the size of each character CLRF TBLPTRU ;Get a pointer to the MOVF PRODL,W ;start of this character's font ADDLW LOW(ASCII_5X7Table) ; MOVWF TBLPTRL ; MOVLW HIGH(ASCII_5X7Table) ; ADDWFC PRODH,W MOVWF TBLPTRH ; ; MOVLW 5 ; Now loop through and get all 5 bytes MOVWF temp0 LCD_ASCII_L1 TBLRD *+ ;Get one byte MOVF TABLAT,W ; rcall LCD_PutByte ;Write the byte to the display buffer decfsz temp0,F bra LCD_ASCII_L1 MOVLW 0 ;; ;; !!!! Intentionally fall through to write a zero to the display ;; ;------------------------------------------------------------------------ ; LCD_PutByte - write a byte of data to the LCD display buffer ; ; Write the byte contained in W to the display buffer. The byte is written ; at the current cursor position. Also, the cursor position is incremented ; after the write. ; ; INPUT: WREG ; OUTPUT: ; Mem Used: temp1 ; LCD_WritePtrLo/Hi ; FSR0L/H LCD_PutByte: MOVWF temp1 ;Save the byte to write LFSR 0, DisplayBuffer ;Get a pointer to the display MOVF LCD_WritePtrLo,W ;Now point to the location ADDWF FSR0L,F ;of the cursor. MOVF LCD_WritePtrHi,W ADDWFC FSR0H,F MOVFF temp1, INDF0 ;Write the byte to the display INFSNZ LCD_WritePtrLo,F ;Increment the cursor position INCF LCD_WritePtrHi,F MOVLW HIGH(128*64/8) ;The Display buffer is only 400 CPFSGT LCD_WritePtrHi ;bytes. If we didn't increment return ;then we're okay. ;;; Fall Through... LCD_ResetCursor: CLRF LCD_WritePtrHi ;oops - we've rolled over CLRF LCD_WritePtrLo return ;------------------------------------------------------------------------ ; LCD_MoveCursor - re-position the cursor. The cursor marks where the next ; byte will be written ; ; INPUT: WREG - row ; temp1 - column ; OUTPUT ; MemUsed: LCD_WritePtrLo/HI ; PRODL/H LCD_MoveCursor: ANDLW 7 MULLW 128 MOVF PRODL,W MOVWF LCD_WritePtrLo MOVF PRODH,W MOVWF LCD_WritePtrHi MOVF temp1,W ADDWF LCD_WritePtrLo,F CLRW ADDWFC LCD_WritePtrHi,F RETURN ;------------------------------------------------------------------------ ; LCD_GetPixelPtr - convert the current (PixelX,PixelY) coordinates into ; a pointer into the display buffer. This pointer is returned in FSR0 ; and the bit offset within the byte of the display buffer is returned ; is returned as bit mask in temp0. ; ; { ; temp0 = 1<<(PixelY & 7); ; ; int offset = (PixelY>>3) * nLCD_COLUMNS + PixelX ; FSR0 = &DisplayBuffer[offset]; ; return(temp0); ; } ; ; Input: PixelX = X location of the pixel ; PixelY = Y location of the pixel ; Output: FSR0L:FSR0H -- will point to the byte offset in the display buffer ; temp0 -- 2^n where n is the position within the byte. ; LCD_GetPixelPtr: RRCF PixelY,W ;Put the LSB of the current Y pixel into C. CLRF temp0 ; BSF temp0,0 ; 1<<0 -- assumes Y is even SKPNC ; RLNCF temp0,F ; 1<<1 -- Y is actually odd RRCF WREG,W ;Put bit 1 of the current Y pixel into C BNC pp1 ; RLNCF temp0,F ; bit 1 is set, so we need to shift the RLNCF temp0,F ; mask two positions pp1: RRCF WREG,W ;Put bit 2 of the current Y pixel into C SKPNC ;If it is set SWAPF temp0,F ; then shift the mask left 4 positions. ANDLW 7 ;The lower two bits of W are the 3rd and 4th ;bit of the current Y pixel. MULLW 128 ;Multiply by number of columns in a row ;to obtain the byte offset into the buffer. LFSR 0, DisplayBuffer ;Get a pointer to the display MOVF PRODL,W ADDWF FSR0L,F MOVF PRODH,W ADDWFC FSR0H,F MOVF PixelX,W ADDWF FSR0L,F MOVLW 0 ADDWFC FSR0H,F ret1: return ;------------------------------------------------------------------------ ; LCD_Line - Draw a line ; ; Inputs: PixelX, PixelY - start coordinates ; LCD_x2, LCD_y2 - end coordinates ; ; Outputs: PixelX and PixelY will equal LCD_x2 and LCD_y2 ; ; Algorithm: ; ; int dx = abs(x2-x1); ; int dy = abs(y2-y1); ; ; int bRight = 1; ; int bUp = 1; ; ; if (dx<0) { ; bRight = 0; ; dx = -dx; ; } ; if (dy<0) { ; bUp = 0 ; ; dy = -dY; ; } ; ; int slope = dx - dy; ; ; do { ; ; SetPixel(x,y); ; ; if ( slope < 0) { ; y++; ; slope += dx; ; } else { ; x++; ; slope -= dy; ; } ; } while (x!=x2 && y!=y2); ; ; ; MEM Used: ; dx ; dy ; slope ; temp1 ; Calls: ; LCD_SetPixel ; LCD_Line: MOVF PixelX,W ;x1 SUBWF LCD_x2,W ;W=x2-x1 MOVWF dx ;dx=x2-x1 RLCF dir,F ;Pick up carry BTFSS dir,0 ;if x2 ; Grab some useful macros CONFIG OSC = HSPLL, OSCS = ON, WDT = ON, LVP = OFF CONFIG CP0 = ON, CP1 = ON, CPB = ON include "ssd0323.inc" include "osram128x64.inc" include "portdef.inc" ;------------------------------------------------------------------------ ; gpsim command .command macro x .direct "C", x endm ;---------------------------------------------------------------------- ; Variable declarations ;---------------------------------------------------------------------- GPR_DATA UDATA_ACS temp RES 1 temp0 RES 1 temp1 RES 1 temp2 RES 1 temp3 RES 1 GLOBAL temp0, temp1, temp2, temp3 Tx RES 1 Ty RES 1 DISPLAY_DATA UDATA 400 DisplayBuffer RES LCD_nROWS*LCD_nCOLS/8 GLOBAL DisplayBuffer ;------------------------------------------------------------------------ ; Code labels GLOBAL done ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector bra start ; go to beginning of program ;---------------------------------------------------------------------- ; ******************* INTERRUPT VECTOR LOCATION ****************** ;---------------------------------------------------------------------- INT_VECTOR CODE 0x008 ; interrupt vector location RETFIE 1 ;---------------------------------------------------------------------- ; ******************* MAIN CODE START LOCATION ****************** ;---------------------------------------------------------------------- MAIN CODE start ;; ;; Define the simulation environment. ;; .sim "module library libgpsim_extras" .sim "module library libgpsim_modules" .sim "module load OSRAM128X64 LCD" .sim "module load pullup R1" .sim "module load pullup R2" if InterfaceMode == Mode8080 .sim "module load pullup RBS1" .sim "module load pullup RBS2" endif if InterfaceMode == Mode6800 .sim "module load pulldown RBS1" .sim "module load pullup RBS2" endif if InterfaceMode == ModeSPI .sim "module load pulldown RBS1" .sim "module load pulldown RBS2" endif .sim "node nBS1" .sim "node nBS2" .sim "attach nBS2 RBS2.pin LCD.bs2" .sim "attach nBS1 RBS1.pin LCD.bs1" if InterfaceMode == Mode6800 || InterfaceMode == Mode8080 .sim "node nE" .sim "node nRW" .sim "attach nE porte0 LCD.e" .sim "attach nRW porte1 LCD.rw" .sim "node nd0 nd1 nd2 nd3 nd4 nd5 nd6 nd7" .sim "attach nd0 portb0 LCD.d0" .sim "attach nd1 portb1 LCD.d1" .sim "attach nd2 portb2 LCD.d2" .sim "attach nd3 portb3 LCD.d3" .sim "attach nd4 portb4 LCD.d4" .sim "attach nd5 portb5 LCD.d5" .sim "attach nd6 portb6 LCD.d6" .sim "attach nd7 portb7 LCD.d7" else .sim "module load pulldown Rgnd" .sim "node nGnd" .sim "attach nGnd Rgnd.pin LCD.d7 LCD.d6 LCD.d5 LCD.d4 LCD.d3 LCD.d2 LCD.e LCD.rw" .sim "node nSDA nSCL" .sim "attach nSDA portc5 LCD.d1" .sim "attach nSCL portc3 LCD.d0" endif .sim "node nCS" .sim "node nRES" .sim "node nDC" .sim "attach nDC porte2 LCD.dc" .sim "attach nCS portd0 LCD.cs R2.pin" .sim "attach nRES portd1 LCD.res" ;; Now position the modules in the BreadBoard viewer .sim "LCD.xpos=220.0" .sim "LCD.ypos=24.0" .sim "R1.xpos=216.0" .sim "R1.ypos=264.0" .sim "R2.xpos=312.0" .sim "R2.ypos=264.0" ; .sim "R3.xpos=376.0" ; .sim "R3.ypos=264.0" if InterfaceMode == ModeSPI ;; Initialize the SPI port: ;CKP == 1 ;CKE == 0 BCF TRISC, RC5 BCF TRISC, RC3 CLRF SSPSTAT SPIClk_FOSC_64 EQU (1< gpsim-0.30.0/extras/graphic_lcd/examples/ssd0323/ssd0323.asm0000664000076400007640000002477113041763631020152 00000000000000; ; SSD0323 Driver for the PIC 18F family. ; ; Copyright (C) 2007 T. Scott Dattalo ; ; This driver is designed to test gpsim. However, it is also usable ; as a stand alone driver. You're free to use this driver as you ; wish as long as the copyright is retained. ; ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; The SSD0323 driver supports graphic LCD displays that are based on the ; Solomon Systech SSD0323 OLED graphics controller. The SSD0323 is an ; 128X80, 4-bit gray scale dot matrix controller. ; ; ; ; !!! NOTE: The driver assumes all variables reside in Bank 0!. !!! ; list p=18f452,t=ON,c=132,n=80 radix dec #include ; The defines in portdef.inc allow the LCD port definitions to be customized. #include "portdef.inc" #include "osram128x64.inc" ; Functions: GLOBAL SSD0323_Init GLOBAL SSD0323_WriteCmd GLOBAL SSD0323_Write GLOBAL LCD_RefreshDisplay GLOBAL LCD_RefreshEntireDisplay GLOBAL CommandLoop GLOBAL CommandWaitForSPI EXTERN temp0, temp1, temp2, temp3 EXTERN DisplayBuffer ;======================================================================== ; ; SSD0323 Driver ; ; ; RAM Definitions UDATA_ACS ;-------------------- ; Mode ;-------------------- SSD0323_Mode RES 1 GLOBAL SSD0323_Mode ; xxxx_xxxM ; +--- Mode 0=Command 1=Data ;------------------------------------------------------------------------ ; Macros ; SetMode ; Selects between Command and Data mode mSSD0323_SetMode macro BCF LATA, RA1 BTFSC SSD0323_Mode,bSSD0323_MODE_CMD BSF LATA, RA1 endm SETA0 macro BSF LCDA0_LAT,LCDA0_BIT endm CLRA0 macro BCF LCDA0_LAT,LCDA0_BIT endm ;------------------------------------------------------------------------ ; SSD0323 commands ; ; The SSD0323 Commands are written to address 1 of the chip. ; The data written for the command includes the command type and optional ; parameters. The data bus is only 8-bits wide. The upper bits in general ; describe the command while the lower are for data SSD0323_DisplayOn EQU 0xaf SSD0323_DisplayOff EQU 0xae SSD0323_DisplayStartLine EQU 0xc0 SSD0323_SETPAGEADDRESS EQU 0xb8 SSD0323_SetColumnAddress EQU 0x00 SSD0323_SetDuty EQU 0xa8 ;------------------------------------------------------------------------ ; SSD0323_CODE CODE SSD0323_Init: mInitLCD_PINS ; de-select the chip mSetLCDCS ; Bring the chip out of reset: RCALL delay mSetLCDRES RCALL delay ; Select the chip mClrLCDCS CmdSetColumnAddress EQU 0x15 CmdGraphicAccleration EQU 0x23 CmdDrawRectangle EQU 0x24 CmdCopy EQU 0x25 CmdHorizontalScroll EQU 0x26 CmdStopMoving EQU 0x2E CmdStartMoving EQU 0x2F CmdSetRowAddress EQU 0x75 CmdSetContrast EQU 0x81 CmdSetQuarterCurrent EQU 0x84 CmdSetHalfCurrent EQU 0x85 CmdSetFullCurrent EQU 0x86 CmdSetRemap EQU 0xA0 CmdSetDisplayStartLine EQU 0xA1 CmdSetDisplayOffset EQU 0xA2 CmdSetNormalDisplay EQU 0xA4 CmdSetAllOn EQU 0xA5 CmdSetAllOff EQU 0xA6 CmdSetInverse EQU 0xA7 CmdSetMultiplexRatio EQU 0xA8 CmdSetMasterCfg EQU 0xAD CmdSetDisplayOff EQU 0xAE CmdSetDisplayOn EQU 0xAF CmdSetPreChargeCompensationEnable EQU 0xB0 CmdSetPhaseLength EQU 0xB1 CmdSetRowPeriod EQU 0xB2 CmdSetClockDivide EQU 0xB3 CmdSetPreChargeCompensationLevel EQU 0xB4 CmdSetGrayScaleTable EQU 0xB8 CmdSetPreChargeVoltage EQU 0xBC CmdSetVCOMH EQU 0xBE CmdSetVSL EQU 0xBF CmdNop EQU 0xE3 MOVLW LOW(CommandTable) MOVWF TBLPTRL MOVLW HIGH(CommandTable) MOVWF TBLPTRH MOVLW CommandTableEnd-CommandTable MOVWF temp0 CommandLoop: TBLRD *+ MOVF TABLAT,W rcall SSD0323_WriteCmd decfsz temp0,F bra CommandLoop if InterfaceMode == ModeSPI ; In SPI mode, we need to wait for the command completes ; before returning. The reason is that we may send data ; just after this command. Sending data changes the DC ; bit which in turn will screw up the command transfer. CommandWaitForSPI: MOVF SSPBUF,W CommandSPIBusy: BTFSS SSPSTAT,BF bra CommandSPIBusy endif return CommandTable: db CmdSetColumnAddress, 0x00, 0x3f, CmdSetRowAddress, 0x00, 0x3f db CmdSetContrast, 0x6d db CmdSetFullCurrent, CmdSetRemap, 0x41, CmdSetDisplayStartLine db 0x00, CmdSetDisplayOffset, 0x44, CmdSetNormalDisplay db CmdSetMultiplexRatio, 0x3f db CmdSetPhaseLength, 0x28 db CmdSetPreChargeCompensationLevel, 0x07 db CmdSetRowPeriod, 0x46 db CmdSetClockDivide, 0x91 db CmdSetVSL, 0x0d db CmdSetVCOMH, 0x02 db CmdSetPreChargeVoltage, 0x10 db CmdSetGrayScaleTable, 0x01,0x11,0x22, 0x32, 0x43,0x54,0x65 db 0x76, CmdSetMasterCfg, 02, CmdSetDisplayOn CommandTableEnd: CommandSetCursorPosition: db CmdSetColumnAddress, 0x00, 0x3f, CmdSetRowAddress, 0x00, 0x3f CommandSetCursorPositionEnd: ;------------------------------------------------------------ ; Write either a command or data to the SSD0323 ; ; Inputs: WREG - byte to be written ; Outputs: ; Mem used: W ; if InterfaceMode == Mode8080 SSD0323_WriteCmd ;<--- Entry point to write a command. BCF LCDDC_LAT, LCDDC_BIT SSD0323_Write: ;<--- Entry point to write data. BCF LCDRW_LAT, LCDRW_BIT ;SSD0323 WR# MOVWF SSD0323_LAT BSF LCDRW_LAT, LCDRW_BIT ;Rising edge writes the data BSF LCDDC_LAT, LCDDC_BIT return endif if InterfaceMode == Mode6800 SSD0323_WriteCmd ;<--- Entry point to write a command. BCF LCDDC_LAT, LCDDC_BIT SSD0323_Write: ;<--- Entry point to write data. BCF LCDRW_LAT, LCDRW_BIT ;SSD0323 R/W line is low for writes MOVWF SSD0323_LAT BCF LCDE_LAT, LCDE_BIT ;Falling edge of E latches the data. BRA $+2 BSF LCDE_LAT, LCDE_BIT ;Turn off the enable BSF LCDDC_LAT, LCDDC_BIT return endif if InterfaceMode == ModeSPI SSD0323_WriteCmd ;<--- Entry point to write a command. BCF LCDDC_LAT, LCDDC_BIT BRA SSD0323_WriteSPI SSD0323_Write: ;<--- Entry point to write data. BSF LCDDC_LAT, LCDDC_BIT SSD0323_WriteSPI: MOVWF SSPBUF btfss SSPCON1, WCOL return BCF SSPCON1, WCOL bra SSD0323_WriteSPI return endif d2 rcall d3 d3 return delay: bra $+2 bra $+2 bra $+2 decfsz WREG,F bra delay return ;------------------------------------------------------------------------ ;SSD_SetColumnRange - set the start and columns in the SSD0323 ; In addition, the width of the virtual display (in the PIC's ram) ; is also initialized. ; ; Inputs: W - start column ; temp0 - end column ; Outputs: DisplaySizeX ; MemUsed: None ; SSD_SetColumnRange: GLOBAL SSD_SetColumnRange MOVWF temp1 SUBWF temp0,W ADDLW 1 MOVWF DisplaySizeX CLRC RRCF temp0,F CLRC RRCF temp1,F MOVLW CmdSetColumnAddress SSD_SetRowCol: RCALL SSD0323_WriteCmd MOVF temp1,W RCALL SSD0323_WriteCmd MOVF temp0,W bra SSD0323_WriteCmd SSD_SetRowRange: GLOBAL SSD_SetRowRange MOVWF temp1 SUBWF temp0,W ADDLW 1 MOVWF DisplaySizeY MOVLW CmdSetRowAddress bra SSD_SetRowCol ;------------------------------------------------------------------------ ;LCD_RefreshDisplay - copy the RAM buffered display to the physical display ; ; Inputs: None ; Outputs: None ; MemUsed: temp0 ; ; The display buffer is organized differently than the physical display ; Here is a graphical mapping: ; ; columns ; 0 1 2 3 4 5 6 7 8 ; ----------------------------------- ; 0 | a0 b0 c0 d0 e0 f0 g0 h0 i0 ; 1 | a1 b1 c1 d1 e1 f1 g1 h1 i1 ; 2 | a2 b2 c2 d2 e2 f2 g2 h2 i2 ; R 3 | a3 b3 c3 d3 e3 f3 g3 h3 i3 ; O 4 | a4 b4 c4 d4 e4 f4 g4 h4 i4 ; W 5 | a5 b5 c5 d5 e5 f5 g5 h5 i5 ; S 6 | a6 b6 c6 d6 e6 f6 g6 h6 i6 ; 7 | a7 b7 c7 d7 e7 f7 g7 h7 i7 ; 8 | A0 B0 C0 D0 E0 F0 G0 H0 I0 ; 9 | A1 B1 C1 D1 E1 F1 G1 H1 I1 ; ; The sequence of bytes in the PIC memory is: ; a, b, c, and so on for the first 8 rows of pixels. The next 8 rows ; begin with the A, B, C and so on bytes. ; ; LCD_RefreshEntireDisplay: MOVLW LOW(CommandSetCursorPosition) MOVWF TBLPTRL MOVLW HIGH(CommandSetCursorPosition) MOVWF TBLPTRH MOVLW CommandSetCursorPositionEnd-CommandSetCursorPosition MOVWF temp0 call CommandLoop LCD_RefreshDisplay: LFSR 0, DisplayBuffer MOVLW 0 ; row counter MOVWF temp0 MOVLW 1 MOVWF temp2 ; bit mask SSD_ref1: ;row counter * number of columns MOVF temp0,W MULWF DisplaySizeX ; MULLW LCD_nCOLS LFSR 0, DisplayBuffer ;Get a pointer to the display MOVF PRODL,W ADDWF FSR0L,F MOVF PRODH,W ADDWFC FSR0H,F ;MOVLW LCD_nCOLS/2 ; # of columns - 1 byte covers 2 columns RRCF DisplaySizeX,W ANDLW 0x7f MOVWF temp1 SSD_ref2: movf temp2,W ; Check a single pixel in the display andwf POSTINC0,W ; buffer movlw 0 ;Assume that the pixel is off skpz ; movlw 0xf0 ;Pixel was on- assign it the maximum color movwf temp3 ;We now have the low order pixel. movf temp2,W ;Check the pixel in the next column andwf POSTINC0,W movlw 0 ;Again, assume it's zero skpz ; movlw 0x0f ;Pixel is on iorwf temp3,W ;We now have the high order pixel rcall SSD0323_Write ;Write both pixels DECFSZ temp1,F ;Have we gone through all of the columns? bra SSD_ref2 ;... nope ; next row rlncf temp2,F ;Rotate the pixel mask btfss temp2,0 ;Did we wrap around? bra SSD_ref1 ;Nope, incf temp0,F ;Display buffer row counter. SWAPF temp0,W RRNCF WREG,W ADDLW 1 CPFSLT DisplaySizeY bra SSD_ref1 return ;------------------------------------------------------------ end gpsim-0.30.0/extras/graphic_lcd/NEWS0000664000076400007640000000000013041763631014102 00000000000000gpsim-0.30.0/extras/graphic_lcd/COPYING0000664000076400007640000000000013041763631014436 00000000000000gpsim-0.30.0/extras/makefile.mingw0000664000076400007640000000325513117107673014005 00000000000000## Makefile for building the dht11 with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw BASE = .. TOP = $(BASE)/.. ifndef GPSIM_DEF_PATH GPSIM_DEF_PATH = $(BASE)/plat/win32 endif include $(GPSIM_DEF_PATH)/make.mingw ################################################################ # Nothing much configurable below LIBS = -L $(GLIB_PATH)/lib -l glib-2.0 -l gobject-2.0 \ -L $(GTK_PATH)/lib -l gdk-win32-2.0 -l gtk-win32-2.0 \ -L $(PANGO_PATH)/lib -l pango-1.0 \ -L $(CAIRO_PATH)/lib -l cairo \ -L $(GDK_PIXBUF_PATH)/lib -l gdk_pixbuf-2.0 \ $(BASE)/src/libgpsim.a INCLUDES = -I $(BASE) -I $(BASE)/include \ -I $(GLIB_PATH)/include/glib-2.0 -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GTK_PATH)/include/gtk-2.0 -I $(GTK_PATH)/lib/gtk-2.0/include \ -I $(PANGO_PATH)/include/pango-1.0 -I $(ATK_PATH)/include/atk-1.0 \ -I $(CAIRO_PATH)/include/cairo \ -I dht11/ -I ds1820/ -I solar/ -I lcd/ -Igraphic_lcd/src -I ds1307 \ -I $(GDK_PIXBUF_PATH)/include/gdk-pixbuf-2.0 DEFINES += -DHAVE_GUI all: \ libgpsim_extras.dll libgpsim_extras_OBJECTS = \ dht11/dht11.o ds1820/ds1820.o ds1820/rom1w.o ds1820/bit1w.o \ solar/solar.o lcd/lcd.o lcd/lcdgui.o lcd/hd44780.o lcd/raw_lcd.o \ graphic_lcd/src/glcd_100X32_sed1520.o graphic_lcd/src/glcd.o \ graphic_lcd/src/osram.o graphic_lcd/src/sed1520.o \ graphic_lcd/src/ssd0323.o \ ds1307/ds1307.o \ module_manager.o ################ The modules DLL libgpsim_extras.dll : $(libgpsim_extras_OBJECTS) $(CXX) $(CFLAGS) $(CLDFLAGS) -shared -o libgpsim_extras.dll $(GPSIM_DEF_PATH)/modules.def $(libgpsim_extras_OBJECTS) $(LIBS) gpsim-0.30.0/extras/ds1820/0000775000076400007640000000000013117466030012154 500000000000000gpsim-0.30.0/extras/ds1820/ds1820.cc0000664000076400007640000002103213041763633013327 00000000000000/* Copyright (C) 2012 Eduard Timotei Budulea Copyright (C) 2013 Roy R. Rankin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include "ds1820.h" class TemperatureAttribute : public Float { public: TemperatureAttribute() : Float("temperature",25.0,"Current temperature") { } void set(int r) { Float::set((double)r); }; }; class PoweredAttribute : public Boolean { public: PoweredAttribute() : Boolean ("powered", true, "Externally Powered") {} }; class Alarm_Th_Attribute : public Integer { public: Alarm_Th_Attribute() : Integer ("alarm_th", 30, "Temp high or user data1 in EEPROM") {} virtual void get(char *buffer, int buf_size) { if(buffer) { int i; i = getVal();; snprintf(buffer,buf_size,"%d",i); } } }; class Alarm_Tl_Attribute : public Integer { public: Alarm_Tl_Attribute() : Integer ("alarm_tl", -5, "Temp low or user data2 in EEPROM") {} virtual void get(char *buffer, int buf_size) { if(buffer) { int i; i = getVal();; snprintf(buffer,buf_size,"%d",i); } } }; class Config_Attribute : public Integer { public: Config_Attribute() : Integer ("config_register", 0x7f, "EEPROM value of 18B20 Configuration Register") { } virtual void set(gint64 v) { Integer::set(v); } virtual void get(char *buffer, int buf_size) { if(buffer) { guint8 i; i = getVal();; snprintf(buffer,buf_size,"0x%0x",i); } } }; namespace DS1820_Modules { void DS1820::doneBits() { if(verbose) cout << name() << " Setting dsState\n"; (this->*dsState)(); } void DS1820::resetEngine() { if(verbose) cout << name() << " Ready for readCommand" << endl; dsState = &DS1820::readCommand; bitRemaining = 8; isReading = true; } bool DS1820::isAlarm() { char Th = scratchpad[2]; char Tl = scratchpad[3]; char temp = scratchpad[0]>>1; if(scratchpad[1]) temp |= 0x80; return temp < Tl || temp > Th; } void DS1820::readCommand() { short temp; guchar mode; int count; double frac_part, int_part; if(verbose) cout << name() << " Got readCommand! " << hex << (unsigned int)octetBuffer[0] << endl; // load scratch from EEPROM here first time through to capture changes // from .sim commands in the program if (!ds1820_eeprom_loaded) { ds1820_eeprom_loaded = true; loadEEPROM(); } switch(octetBuffer[0]) { case 0x44: // Convert Temperature mode = (scratchpad[4]>>5) & 3; frac_part = modf(attr_Temp->getVal() + 0.25, &int_part); temp = (int)((attr_Temp->getVal() + 0.25) * 2.); // Note count can be > 16 for negative temperatures count = mode?(16 - 16 * frac_part):0; if ( temp > 250 || temp < -110) cout << name() << " Warning temperature " << attr_Temp->getVal() << " outside operating range -55 to 125\n"; scratchpad[0] = temp & 0xFF; scratchpad[1] = temp >> 8; scratchpad[6] = count; scratchpad[8] = calculateCRC8(scratchpad, 8); if (attr_powered->getVal()) // Can return status if powered { double time_conversion = 0.750; // 750 ms switch(mode) { case 0: // 9 bit resolution // Max time for conversion 93.75 ms time_conversion /= 8.; break; case 1: // 10 bit resolution // Max time for conversion 187.5 ms time_conversion /= 4.; break; case 2: // 11 bit resolution // Max time for conversion 375 ms time_conversion /= 2.; break; case 3: // 12 bit resolution // Max time for conversion 750 ms break; } set_status_poll(get_cycles().get(time_conversion)); return; } break; case 0x48: //Copy scratchpad to EEPROM attr_thigh->set(scratchpad[2]); attr_tlow->set(scratchpad[3]); if(is_ds18b20) attr_config->set(scratchpad[4]); if (attr_powered->getVal()) { // Can return status if powered // Max time to complete 10ms set_status_poll(get_cycles().get(0.010000)); return; } break; case 0x4E: //Write scratchpad (master to Th, Tl isReading = true; bitRemaining = is_ds18b20?24:16; dsState = &DS1820::writeScratchpad; return; case 0xB4: //Read Power supply isReading = false; if (attr_powered->getVal()) { if(verbose) printf("%s is powered\n", name().c_str()); bitRemaining = 0; return; } if(verbose) printf("%s on parasite power\n", name().c_str()); octetBuffer[0] = 0; bitRemaining = 8; dsState = &DS1820::readPower; return; case 0xB8: // Recall EE (Th, Tl from EEPROM to scratchpad) loadEEPROM(); break; case 0xBE: // Read scratchpad if(verbose) printf("%s scratchpad contents\n", name().c_str()); for (int i = 0; i < 9; ++i) { octetBuffer[i] = scratchpad[8 - i]; if(verbose) printf("%d %0x\n", i, scratchpad[i]); } isReading = false; bitRemaining = 72; dsState = &DS1820::done; return; default: cout << name() << " " << __FUNCTION__ << " Unexpected command " << hex << (unsigned int)octetBuffer[0] << endl; } isReading = false; octetBuffer[0] = 0x32; dsState = &DS1820::done; bitRemaining = 8; } void DS1820::writeScratchpad() { if(verbose) cout << "GOT writeScratchpad!" << hex << (unsigned int)octetBuffer[0] << ',' << (unsigned int) octetBuffer[1] << endl; if(is_ds18b20) { scratchpad[2] = octetBuffer[2]; scratchpad[3] = octetBuffer[1]; scratchpad[4] = (octetBuffer[0] & 0x60) | 0x1f; } else { scratchpad[2] = octetBuffer[1]; scratchpad[3] = octetBuffer[0]; } scratchpad[8] = calculateCRC8(scratchpad, 8); return; } void DS1820::readPower() { if(verbose) cout << "Got readPower!" << endl; bitRemaining = 8; return; } void DS1820::done() { return; } void DS1820::loadEEPROM() { scratchpad[2] = (char)attr_thigh->getVal(); scratchpad[3] = (char)attr_tlow->getVal(); if(is_ds18b20) scratchpad[4] = (char)((attr_config->getVal() & 0x60) | 0x1f); scratchpad[8] = calculateCRC8(scratchpad, 8); } DS1820::DS1820(const char *name, bool ds18B20): Rom1W(name, "DS1820 - 1Wire thermomether."), ds1820_eeprom_loaded(false), dsState(&DS1820::done) { is_ds18b20 = ds18B20; scratchpad[0] = 0xAA; scratchpad[1] = 0; scratchpad[4] = 0xFF; scratchpad[5] = 0xFF; scratchpad[6] = 0x0C; scratchpad[7] = 0x10; attr_Temp = new TemperatureAttribute(); attr_thigh = new Alarm_Th_Attribute(); attr_tlow = new Alarm_Tl_Attribute(); attr_powered = new PoweredAttribute(); addSymbol(attr_Temp); addSymbol(attr_thigh); addSymbol(attr_tlow); addSymbol(attr_powered); if(is_ds18b20) { attr_config = new Config_Attribute(); addSymbol(attr_config); cout << "===created a ds18b20 with name " << (name ?: "unnamed!") << endl; } else cout << "===created a ds1820 with name " << (name ?: "unnamed!") << endl; } DS1820::~DS1820() { removeSymbol(attr_Temp); removeSymbol(attr_thigh); removeSymbol(attr_tlow); removeSymbol(attr_powered); delete attr_Temp; delete attr_thigh; delete attr_tlow; delete attr_powered; if(is_ds18b20) { removeSymbol(attr_config); delete attr_config; } } Module* DS1820::construct(const char *name) { return new DS1820(name, false); } Module* DS1820::constructB(const char *name) { return new DS1820(name, true); } } //end of namespace gpsim-0.30.0/extras/ds1820/Makefile.in0000664000076400007640000004537713117441635014165 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile for the DS1820 module # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras/ds1820 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = ds1820.h bit1w.h rom1w.h examples/README \ examples/ds1820.asm examples/ds18b20.asm examples/Makefile SUBDIRS = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/ds1820/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/ds1820/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/ds1820/Makefile.am0000664000076400007640000000026113041763633014134 00000000000000# Makefile for the DS1820 module # EXTRA_DIST = ds1820.h bit1w.h rom1w.h examples/README \ examples/ds1820.asm examples/ds18b20.asm examples/Makefile SUBDIRS = gpsim-0.30.0/extras/ds1820/rom1w.cc0000664000076400007640000002224513041763633013462 00000000000000/* Copyright (C) 2012 Eduard Timotei Budulea Copyright (C) 2013 Roy R. Rankin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include "rom1w.h" class ROMCodeAttribute : public Integer { public: ROMCodeAttribute() : Integer("ROMCode",0x06050403020110LL,"Device ROM code") { // Add CRC gint64 v = getVal(); set(v); } void set(gint64 i) { gint64 id = (i & 0xffffffffffff00LL) | 0x10; gint64 crc; crc = Rom1W::calculateCRC8((const unsigned char *)&id, 7); id |= crc << 56; Integer::set(id); } virtual void get(char *buffer, int buf_size) { if(buffer) { gint64 i; i = getVal();; snprintf(buffer,buf_size,"0x%" PRINTF_GINT64_MODIFIER "x",i); } } virtual string toString() { return Integer::toString("0x%" PRINTF_INT64_MODIFIER "x"); } }; void Rom1W::gotReset() { if(verbose) cout << name() << " got rom reset" << endl; romState = &Rom1W::readRomCommand; bitRemaining = 8; isReading = true; } static bool getBit(int bitIndex, unsigned char * buffer) { return 0 != (buffer[bitIndex / 8] & (1 << (7 - bitIndex % 8))); } Rom1W::NextAction Rom1W::gotBitStart() { if(verbose)cout << name() << " gotBitStart" << endl; if (--bitRemaining < 0) return (this->*romState)(); if (isReading) return READ; bool write1 = getBit(bitRemaining, octetBuffer); if(verbose) cout << name() << " writing bit = " << write1 << " remaining " << bitRemaining <> ((7 - i) * 8); } Rom1W::NextAction Rom1W::readRomCommand() { if(verbose) cout << name() << " "<<__FUNCTION__ << " got " << hex << (int)octetBuffer[0] << endl; gint64 intaddr; switch (octetBuffer[0]) { case 0x33: // Skip ROM isSelected = false; romState = &Rom1W::readRom; intaddr = attr_ROMCode->getVal(); int64ToBuff(intaddr, octetBuffer); bitRemaining = 64; isReading = false; return IDLE; case 0x55: // Match ROM isSelected = false; romState = &Rom1W::matchRom; bitRemaining = 64; isReading = true; return READ; case 0xEC: // Alarm Search // Fall through to Search ROM case 0xF0: // Search ROM isSelected = (octetBuffer[0]==0xF0 || isAlarm())?true:false; romState = &Rom1W::searchRom; intaddr = attr_ROMCode->getVal(); int64ToBuff(intaddr, octetBuffer + 1); if (octetBuffer[8] & 1) octetBuffer[0] = 0x40; else octetBuffer[0] = 0x80; octetBuffer[9] = 63; bitRemaining = 2; isReading = false; return IDLE; case 0xCC: // Skip ROM isSelected = false; if(verbose) cout << name() << " Skip rom function command\n"; break; case 0xA5: if (isSelected) break; default: return RESET; } return readRom(); } Rom1W::NextAction Rom1W::readRom() { if(verbose) cout << name() << " called " << __FUNCTION__ << endl; resetEngine(); romState = &Rom1W::deviceData; return IDLE; } Rom1W::NextAction Rom1W::matchRom() { if(verbose) cout << name() << " called " << __FUNCTION__ << endl; unsigned char myaddr[8]; gint64 intaddr; intaddr = attr_ROMCode->getVal(); int64ToBuff(intaddr, myaddr); if (memcmp(myaddr, octetBuffer, 8)) { if(verbose) { cout << name() << " " << hex << intaddr << " no match\n got "; for(int i=0; i < 8; i++) printf("%x", octetBuffer[i]); cout < get_cycles().get()) { if (poll_break) get_cycles().clear_break(poll_break); get_cycles().set_break(delay, this); if(verbose) printf("%s to poll busy for %.3f mS\n", name().c_str(), (delay - get_cycles().get())*4./(20. * 1000.)); poll_break = delay; } } // Rom1W::callback catches breaks from both Bit1W and Rom1W // and uses last break setting (bit_break-Bit1W and poll_break-Rom1W) // to determine what action to take void Rom1W::callback() { guint64 now = get_cycles().get(); if (now == poll_break) { isReady = true; octetBuffer[0] = 0xff; poll_break = 0; } if(now == bit_break) LowLevel1W::callback(); } Rom1W::Rom1W(const char *_name, const char *desc): LowLevel1W(_name, desc), isSelected(false), bitRemaining(0), isReading(false), romState(&Rom1W::deviceData) { poll_break = 0; attr_ROMCode = new ROMCodeAttribute(); addSymbol(attr_ROMCode); } Rom1W::~Rom1W() { removeSymbol(attr_ROMCode); delete attr_ROMCode; } static const guint8 crc8Table[256] = {0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53}; guint8 Rom1W::calculateCRC8(const unsigned char *buffer, int bufferLen) { guint8 crc = 0; for (int i = 0; i < bufferLen; ++i) crc = crc8Table[crc ^ buffer[i]]; return crc; } gpsim-0.30.0/extras/ds1820/bit1w.h0000664000076400007640000000511113041763633013276 00000000000000/* Copyright (C) 2012 Eduard Timotei Budulea Copyright (C) 2013 Roy R. Rankin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef BIT1W_H #define BIT1W_H #ifndef IN_MODULE #define IN_MODULE #endif #include #include #include #include #include #include using namespace std; class LowLevel1W : public Module, public TriggerObject { protected: enum NextAction {WRITE1, WRITE0, READ, RESET, IDLE}; private: guint64 cicluReper; bool lastValue; bool lastTimeout; class Pin1W : public IO_bi_directional { LowLevel1W &to; public: Pin1W(char const *name, LowLevel1W &to): IO_bi_directional(name), to(to) {} virtual void setDrivenState(bool new_dstate) { IO_bi_directional::setDrivenState(new_dstate); to.change(true); } virtual void setDrivenState(char new_state) { IO_bi_directional::setDrivenState(new_state); to.change(true); } }; Pin1W *pin; virtual void gotReset() = 0; virtual NextAction gotBitStart() = 0; virtual void readBit(bool value) = 0; virtual int bit_remaining() = 0; virtual bool is_reading() = 0; void change(bool pinChange); void (LowLevel1W::*state)(bool input, bool isTimeout); bool ignoreCallback; void idle(bool input, bool isTimeout); void inResetPulse(bool input, bool isTimeout); void endResetPulse(bool input, bool isTimeout); void inPresencePulse(bool input, bool isTimeout); void endPresencePulse(bool input, bool isTimeout); void waitIdle(bool input, bool isTimeout); void inWritting0(bool input, bool isTimeout); void inWritting1(bool input, bool isTimeout); void inReading(bool input, bool isTimeout); void finalizeBit(bool input, bool isTimeout); public: guint64 bit_break; LowLevel1W(const char *name, const char *desc); ~LowLevel1W(); virtual void callback(); }; #endif gpsim-0.30.0/extras/ds1820/ds1820.h0000664000076400007640000000331613041763633013176 00000000000000/* Copyright (C) 2012 Eduard Timotei Budulea Copyright (C) 2013 Roy R. Rankin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DS1820_H #define DS1820_H #ifndef IN_MODULE #define IN_MODULE #endif #include "rom1w.h" class TemperatureAttribute; class PoweredAttribute; class Alarm_Th_Attribute; class Alarm_Tl_Attribute; class Config_Attribute; namespace DS1820_Modules { class DS1820 : public Rom1W { virtual void doneBits(); virtual void resetEngine(); virtual bool isAlarm(); TemperatureAttribute *attr_Temp; PoweredAttribute *attr_powered; Alarm_Th_Attribute *attr_thigh; Alarm_Tl_Attribute *attr_tlow; Config_Attribute *attr_config; bool ds1820_eeprom_loaded; unsigned char scratchpad[9]; bool is_ds18b20; void (DS1820::* dsState)(); void readCommand(); void writeScratchpad(); void readPower(); void done(); void loadEEPROM(); public: DS1820(const char *name, bool isDS18B20); ~DS1820(); static Module* construct(const char *name = 0); static Module* constructB(const char *name = 0); }; } // end of namespace #endif gpsim-0.30.0/extras/ds1820/rom1w.h0000664000076400007640000000361013041763633013317 00000000000000/* Copyright (C) 2012 Eduard Timotei Budulea Copyright (C) 2013 Roy R. Rankin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ROM1W_H #define ROM1W_H #ifndef IN_MODULE #define IN_MODULE #endif #include "bit1w.h" #include "src/value.h" class ROMCodeAttribute; class Rom1W : public LowLevel1W { private: virtual void gotReset(); virtual NextAction gotBitStart(); virtual void readBit(bool value); virtual int bit_remaining() { return bitRemaining;} virtual bool is_reading() { return isReading;} bool isSelected; bool isReady; ROMCodeAttribute *attr_ROMCode; virtual void doneBits() = 0; virtual void resetEngine() = 0; virtual bool isAlarm() { return false;} protected: int bitRemaining; bool isReading; guint64 poll_break; unsigned char octetBuffer[64]; private: NextAction (Rom1W::*romState)(); NextAction readRomCommand(); NextAction readRom(); NextAction matchRom(); NextAction searchRom(); NextAction deviceData(); NextAction ignoreData(); NextAction statusPoll(); virtual void callback(); public: Rom1W(const char *name, const char *desc); ~Rom1W(); static unsigned char calculateCRC8(const unsigned char *buffer, int bufferLen); void set_status_poll(guint64 delay); }; #endif gpsim-0.30.0/extras/ds1820/examples/0000775000076400007640000000000013117466030013772 500000000000000gpsim-0.30.0/extras/ds1820/examples/ds1820.asm0000664000076400007640000002545513041763633015355 00000000000000; ; Test operation of the 1-wire tmemperaure sensor ds1820 and ; is part of gpsim. ; ; Copyright (c) 2013 Roy Rankin ; ; This program is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version 2 ; of the License, or (at your option) any later version. ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, see ; http://www.gnu.org/licenses/gpl-2.0.html ; ; MACROS and some code included the following ;************************************************************************ ;* Microchip Technology Inc. 2006 ;* 02/15/06 ;* Designed to run at 20MHz ;************************************************************************ ; gpsim command .command macro x .direct "C", x endm list p=16F1823 #include p16f1823.inc include __CONFIG _CONFIG1, _CP_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _PWRTE_ON & _WDTE_OFF & _FOSC_HS errorlevel -302 radix dec #define NO_PARASITE 1 #define ID1_ADDRESS 0x20 #define ID2_ADDRESS 0x30 #define DS_PORT PORTC #define DS_PIN 0 #define DS_TRIS TRISC UDATA 0x20 ID1 RES 8 scratch RES 8 ID2 RES 8 Tlsb RES 1 Tmsb RES 1 Th RES 1 Tl RES 1 reserve RES 2 count_rem RES 1 count_per_c RES 1 crc RES 1 variables UDATA 0x70 d1l RES 1 ; delay counter d1h RES 1 ; delay counter d2 RES 1 ; long period counter temp1 RES 1 temp2 RES 1 status_temp RES 1 w_temp RES 1 bit_cnt RES 1 ; bit count for byte I/O dup_devices RES 1 ; found more than 1 device dev_select RES 1 ; select device to save GLOBAL Tlsb, Tmsb,Th,Tl, count_rem ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location .assert "\"***FAILED p16f1823 unexpected interrupt\"" nop exit_int: retfie ; MAIN CODE start .sim "module lib libgpsim_modules" .sim "module lib libgpsim_extras" .sim "module load ds1820 temp1" .sim "module load ds1820 temp2" .sim "module load pu pu1" .sim "node n1" .sim "attach n1 pu1.pin portc0 temp1.pin " ;.sim "attach n1 pu1.pin portc0 temp1.pin temp2.pin" .sim "pu1.xpos = 240" .sim "pu1.ypos = 188" .sim "pu1.resistance = 4700" .sim "temp1.xpos = 240" .sim "temp1.ypos = 50" .sim "temp1.powered = false" .sim "temp2.xpos = 240" .sim "temp2.ypos = 110" .sim "temp2.ROMCode = 0x06050403020200" .sim "temp2.temperature = -25.4" .sim "p16f1823.xpos = 36" .sim "p16f1823.ypos = 36" .sim "scope.ch0=\"portc0\"" call ProgInit ; Get everything running step-by-step ;goto two clrf dev_select call searchRom call read_rom call check_power .assert "W==0x00,\"DS1820 temp1 parasite power\"" nop call power_on_val call read_temp .assert "Tlsb==0x32,\"Temperature Reading lsb 0x32 (25C)\"" nop .assert "Tmsb==0x00,\"Temperature Reading msb 0x00 (25C)\"" nop call write_ThTl call eeprom2scratch two .command "attach n1 temp2.pin" nop incf dev_select,F ; search for second ds1820 call searchRom call check_power .assert "W==0x80,\"DS1820 temp2 external power\"" nop call power_on_val call read_temp .assert "Tlsb==0xce,\"Temperature Reading lsb 0xce (-25.4C)\"" nop .assert "Tmsb==0xff, \"Temperature Reading msb 0xFF (-25.4C)\"" nop call write_ThTl call eeprom2scratch .assert "\"*** PASSED p16f1823 DS1820 test\"" nop goto $ ; ; Read Power-on scratchpad 0,1 power_on_val call match_device movlw 0xbe ;Transmit out temperature call send_byte call get_byte .assert "W==0xAA,\"Power-on reading scratchpad[0]\"" nop call get_byte .assert "W==0x00,\"Power-on reading scratchpad[1]\"" nop return ; ; Do Temperature conversion, and read temperature read_temp call ds1820init movlw 0xcc ;Send skip rom command call send_byte movlw 0x44 ;Issue convert T command call send_byte ;; It is not known what a real devices would do on the following ;; status reads if at least one is on parasite power. ;; However this code would fail on real devices using parasite power ;; as a hard pullup is required during the conversion #ifdef NO_PARASITE call get_byte ; status read call get_byte ; status read loop btfss temp1,0 goto $-2 #else banksel DS_PORT bsf DS_PORT,DS_PIN ; we want strong pullup, so output banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay750mS ; Tconv delay #endif call read_scratch call get_byte ; temp lsb movwf Tlsb call get_byte ; temp lsb movwf Tmsb return ; ; Write Th & Tl to scratchpad write_ThTl call match_device movlw 0x4e ; write Th & Tl to scratchpad call send_byte movlw 0xa0 call send_byte movlw 0x00 call send_byte call read_scratch call get_byte ; temp lsb call get_byte ; temp msb call get_byte ; Th .assert "W==0xa0,\"Th 0xa0\"" nop call get_byte ; Tl .assert "W==0, \"Tl 0x00\"" nop return ; ; Transfer EEPROM to scratchpad eeprom2scratch call match_device movlw 0xb8 ; Recall EE call send_byte call read_scratch call get_byte ; temp lsb movwf Tlsb call get_byte ; temp msb movwf Tmsb call get_byte ; Th movwf Th call get_byte ; Tl movwf Tl call get_byte movwf reserve call get_byte movwf reserve+1 call get_byte movwf count_rem call get_byte movwf count_per_c call get_byte movwf crc .assert "Th==30,\"Th 30\"" nop .assert "Tl==0xfb, \"Tl -5\"" nop return read_rom call ds1820init movlw 0x33 ;read rom command call send_byte movlw ID2_ADDRESS ; address of scratch + 8 movwf FSR0 movlw 8 movwf temp2 call get_byte movwi --FSR0 decfsz temp2,F goto $-3 return read_scratch call match_device movlw 0xbe ;Transmit out temperature call send_byte return ; Match_device does a skip ROM command if one device present ; Otherwise it does a match ROM on ID1 or ID2 depending on dev_select match_device call ds1820init btfsc dup_devices,0 goto $+4 movlw 0xcc ; just 1 device do skip ROM call send_byte return movlw 0x55 call send_byte movlw ID1_ADDRESS+8 ; address of ID1+8 btfsc dev_select,0 movlw ID2_ADDRESS+8 ;address of ID2+8 movwf FSR0 movlw 8 movwf temp2 moviw --FSR0 call send_byte decfsz temp2,F goto $-3 return check_power: call match_device movlw 0xb4 ;Check power call send_byte call get_1bit return searchRom: call ds1820init movlw 0xf0 ;Search ROM call send_byte movlw .64 movwf temp2 searchloop call get_2bits call process_bits decfsz temp2,F goto searchloop return process_bits btfsc temp1,6 goto b1x btfsc temp1,7 goto b01 ; 00 got 00 some devices sent 0 some 1 , do 0 first incf dup_devices,F ; indicate duplicate btfss dev_select,0 goto b10 b01 bcf temp1,0 ; got 01 all devices sent 0 bcf STATUS,C goto bits_ack b1x btfsc temp1,7 goto b11 b10 bsf temp1,0 ; got 10 all devices sent 1 bsf STATUS,C goto bits_ack b11 .assert "\"no devices present\"" nop bits_ack btfsc dev_select,0 goto bits_ack2 bits_ack1 banksel ID1 rrf ID1,F rrf ID1+1,F rrf ID1+2,F rrf ID1+3,F rrf ID1+4,F rrf ID1+5,F rrf ID1+6,F rrf ID1+7,F call send_1bit return bits_ack2 banksel ID2 rrf ID2,F rrf ID2+1,F rrf ID2+2,F rrf ID2+3,F rrf ID2+4,F rrf ID2+5,F rrf ID2+6,F rrf ID2+7,F call send_1bit return ;****************** Initialize Registers and Variables ***************** ;************************************************************************ ProgInit banksel DS_PORT movlw 0xff movwf DS_PORT ; Set all bits high on Port banksel DS_TRIS clrf DS_TRIS banksel ANSELC clrf ANSELC return ds1820init: ; DS1820 init sequence banksel DS_PORT bsf DS_PORT,DS_PIN ; Pin high banksel DS_TRIS bcf DS_TRIS,DS_PIN ; Pin as output banksel DS_PORT bcf DS_PORT,DS_PIN ; Pin low call Delay500us banksel DS_TRIS bsf DS_TRIS,DS_PIN ; Pin as input (pullup to high) banksel DS_PORT call Delay70us movf DS_PORT,W .assert "(W & 1)==0,\"DS1820, no presents pulse\"" nop call Delay500us return ; send 1 bit from temp1 send_1bit movlw 1 goto send_bits ; send the byte in W send_byte movwf temp1 movlw 8 send_bits movwf bit_cnt banksel DS_PORT ; we want bit low, high is by pullup bcf DS_PORT,DS_PIN send_loop rrf temp1,F ; rotate lSB into carry btfss STATUS,C ; is bit 0 or 1 goto send_0 goto send_1 send_chk decfsz bit_cnt,F ; have we send all bits goto send_loop ; NO banksel DS_PORT return ; YES send_0 banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay70us bsf DS_TRIS,DS_PIN goto send_chk send_1 banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay10us bsf DS_TRIS,DS_PIN call Delay70us goto send_chk ; read 1 bit of data get_1bit movlw 1 goto get_bits ; read 2 bits of data get_2bits movlw 2 goto get_bits ; read a data byte and return it in W get_byte movlw 8 ; input bit counter get_bits movwf bit_cnt clrf temp1 banksel DS_PORT bcf DS_PORT,DS_PIN get_loop banksel DS_TRIS bcf DS_TRIS,DS_PIN ; init read timeslot by pulling line low nop ; delay for at least 1 usec nop nop nop nop bsf DS_TRIS,DS_PIN ; release line call Delay10us banksel DS_PORT bsf STATUS,C ; set carry incase of 1 btfss DS_PORT,DS_PIN ; read port data bcf STATUS,C ; its 0, so clear carry rrf temp1,f ; roll data into data word call Delay70us ; this could be 45us btfss DS_PORT,DS_PIN ; check port pin goto $-1 ; loop until high decfsz bit_cnt,F goto get_loop movf temp1,W return Delay750mS movlw .75 movwf d2 loop750ms call Delay10mS decfsz d2,F goto loop750ms return Delay10mS movlw 0x50 movwf d1l movlw 0x28 movwf d1h goto Delay_0 Delay500us movlw 0x02 movwf d1h movlw 0xfe movwf d1l goto Delay_0 Delay70us movlw 0x01 movwf d1h movlw 0x44 movwf d1l goto Delay_0 Delay10us movlw 0x01 movwf d1h movlw 0x08 movwf d1l goto Delay_0 Delay_0 decfsz d1l, f goto $+2 decfsz d1h, f goto Delay_0 ;2 cycles goto $+1 return end gpsim-0.30.0/extras/ds1820/examples/Makefile0000664000076400007640000000067613041763633015370 00000000000000EXTRA_DIST = ds1820.asm ds18b20.asm 16f1823_g.lkr README MOSTLYCLEANFILES = *.o *.hex *.cod *.lst *.map *~ CLEANFILES = *.o *.hex *.cod *.lst *.map *~ DISTCLEANFILES = *.o *.hex *.cod *.lst *.map *~ MAINTAINERCLEANFILES = *.o *.hex *.cod *.lst *.map *~ .SUFFIXES: .o .asm .cod all: ds1820.cod ds18b20.cod ds1820.cod: ds1820.o ds18b20.cod: ds18b20.o %.cod: %.o gplink --map -o $@ $< %.o: %.asm gpasm -c $< clean: rm -f ${CLEANFILES} gpsim-0.30.0/extras/ds1820/examples/README0000664000076400007640000000060213041763633014575 00000000000000This directory contains programs to test the ds1820 and ds18b20 1-wire temperature sensing devices. Note that this code is written for a 16f1823 processor which may not be supported in your version of gpsim. Also this code may not run on real devices using parasite power. Enter make to compile the programs and then run them gpsim ds1820.cod or gpsim ds18b20.cod Roy Rankin gpsim-0.30.0/extras/ds1820/examples/ds18b20.asm0000664000076400007640000002745713041763633015523 00000000000000; ; Test operation of the 1-wire tmemperaure sensor ds18b20. ; This program is part of gpsim. ; ; Copyright (c) 2013 Roy Rankin ; ; This program is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version 2 ; of the License, or (at your option) any later version. ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, see ; http://www.gnu.org/licenses/gpl-2.0.html ; ; MACROS and some code included the following ;************************************************************************ ;* Microchip Technology Inc. 2006 ;* 02/15/06 ;* Designed to run at 20MHz ;************************************************************************ ; gpsim command .command macro x .direct "C", x endm list p=16F1823 #include p16f1823.inc include __CONFIG _CONFIG1, _CP_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _PWRTE_ON & _WDTE_OFF & _FOSC_HS errorlevel -302 radix dec #define NO_PARASITE 1 #define ID1_ADDRESS 0x20 #define ID2_ADDRESS 0x30 #define DS_PORT PORTC #define DS_PIN 0 #define DS_TRIS TRISC UDATA 0x20 ID1 RES 8 scratch RES 8 ID2 RES 8 Tlsb RES 1 Tmsb RES 1 Th RES 1 Tl RES 1 config_reg RES 1 reserve RES 1 count_rem RES 1 count_per_c RES 1 crc RES 1 variables UDATA 0x70 d1l RES 1 ; delay counter d1h RES 1 ; delay counter d2 RES 1 ; long period counter temp1 RES 1 temp2 RES 1 status_temp RES 1 w_temp RES 1 bit_cnt RES 1 ; bit count for byte I/O dup_devices RES 1 ; found more than 1 device dev_select RES 1 ; select device to save GLOBAL Tlsb, Tmsb,Th,Tl, count_rem, config_reg ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location .assert "\"***FAILED p16f1823 unexpected interrupt\"" nop exit_int: retfie ; MAIN CODE start .sim "module lib libgpsim_modules" .sim "module lib libgpsim_extras" .sim "module load ds18b20 temp1" .sim "module load ds18b20 temp2" .sim "module load pu pu1" .sim "node n1" .sim "attach n1 pu1.pin portc0 temp1.pin " ;.sim "attach n1 pu1.pin portc0 temp1.pin temp2.pin" .sim "pu1.xpos = 240" .sim "pu1.ypos = 188" .sim "pu1.resistance = 4700" .sim "temp1.xpos = 240" .sim "temp1.ypos = 50" .sim "temp1.powered = false" .sim "temp2.xpos = 240" .sim "temp2.ypos = 110" .sim "temp2.ROMCode = 0x06050403020200" .sim "temp2.temperature = -25.4" .sim "temp2.config_register = 0x3f" .sim "p16f1823.xpos = 36" .sim "p16f1823.ypos = 36" .sim "scope.ch0=\"portc0\"" call ProgInit ; Get everything running step-by-step ;goto two clrf dev_select call searchRom call read_rom call check_power .assert "W==0x00,\"DS18B20 temp1 parasite power\"" nop call power_on_val call read_temp .assert "Tlsb==0x32,\"Temperature Reading lsb 0x32 (25C)\"" nop .assert "Tmsb==0x00,\"Temperature Reading msb 0x00 (25C)\"" nop call write_ThTl call eeprom2scratch two .command "attach n1 temp2.pin" nop incf dev_select,F ; search for second ds18b20 call searchRom call check_power .assert "W==0x80,\"DS18B20 temp2 external power\"" nop call power_on_val call read_temp .assert "Tlsb==0xce,\"Temperature Reading lsb 0xce (-25.4C)\"" nop .assert "Tmsb==0xff, \"Temperature Reading msb 0xFF (-25.4C)\"" nop call alarmSearch call write_ThTl call eeprom2scratch call scratch2eeprom .assert "\"*** PASSED p16f1823 DS18B20 test\"" nop goto $ ; ; Read Power-on scratchpad 0,1 power_on_val call match_device movlw 0xbe ;Transmit out temperature call send_byte call get_byte .assert "W==0xAA,\"Power-on reading scratchpad[0]\"" nop call get_byte .assert "W==0x00,\"Power-on reading scratchpad[1]\"" nop return ; ; Do Temperature conversion, and read temperature read_temp call ds1820init movlw 0xcc ;Send skip rom command call send_byte movlw 0x44 ;Issue convert T command call send_byte ;; It is not known what a real devices would do on the following ;; status reads if at least one is on parasite power. ;; However this code would fail on real devices using parasite power ;; as a hard pullup is required during the conversion #ifdef NO_PARASITE call get_byte ; status read call get_byte ; status read loop btfss temp1,0 goto $-2 #else banksel DS_PORT bsf DS_PORT,DS_PIN ; we want strong pullup, so output banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay750mS ; Tconv delay #endif call read_scratch call get_byte ; temp lsb movwf Tlsb call get_byte ; temp lsb movwf Tmsb return ; ; Write Th & Tl to scratchpad write_ThTl call match_device movlw 0x4e ; write Th & Tl to scratchpad call send_byte movlw 0xa0 call send_byte ; send Th movlw 0x00 call send_byte ; send Tl movlw 0x20 call send_byte ; send configuration resgister call read_scratch call get_byte ; temp lsb call get_byte ; temp msb call get_byte ; Th .assert "W==0xa0,\"Th 0xa0\"" nop call get_byte ; Tl .assert "W==0, \"Tl 0x00\"" nop call get_byte ; configuration register .assert "W==0x3f, \"config_reg 0x3f\"" nop return ; transfer Th, Tl and config to EEPROM ; scratch2eeprom call match_device movlw 0x48 call send_byte ;; It is not known what a real devices would do on the following ;; status reads if at least one is on parasite power. ;; However this code would fail on real devices using parasite power ;; as a hard pullup is required during the conversion #ifdef NO_PARASITE nop call get_byte ; status read loop btfss temp1,0 goto $-2 #else banksel DS_PORT bsf DS_PORT,DS_PIN ; we want strong pullup, so output banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay10mS ; Tconv delay #endif return ; ; Transfer EEPROM to scratchpad eeprom2scratch call match_device movlw 0xb8 ; Recall EE call send_byte call read_scratch call get_byte ; temp lsb movwf Tlsb call get_byte ; temp msb movwf Tmsb call get_byte ; Th movwf Th call get_byte ; Tl movwf Tl call get_byte movwf config_reg call get_byte movwf reserve call get_byte movwf count_rem call get_byte movwf count_per_c call get_byte movwf crc .assert "Th==30,\"Th 30\"" nop .assert "Tl==0xfb, \"Tl -5\"" nop return read_rom call ds1820init movlw 0x33 ;read rom command call send_byte movlw ID2_ADDRESS ; address of scratch + 8 movwf FSR0 movlw 8 movwf temp2 call get_byte movwi --FSR0 decfsz temp2,F goto $-3 return read_scratch call match_device movlw 0xbe ;Transmit out temperature call send_byte return ; Match_device does a skip ROM command if one device present ; Otherwise it does a match ROM on ID1 or ID2 depending on dev_select match_device call ds1820init btfsc dup_devices,0 goto $+4 movlw 0xcc ; just 1 device do skip ROM call send_byte return movlw 0x55 call send_byte movlw ID1_ADDRESS+8 ; address of ID1+8 btfsc dev_select,0 movlw ID2_ADDRESS+8 ;address of ID2+8 movwf FSR0 movlw 8 movwf temp2 moviw --FSR0 call send_byte decfsz temp2,F goto $-3 return check_power: call match_device movlw 0xb4 ;Check power call send_byte call get_1bit return alarmSearch: call ds1820init movlw 0xec ;Alarm Search ROM call send_byte movlw .64 movwf temp2 goto searchloop searchRom: call ds1820init movlw 0xf0 ;Search ROM call send_byte movlw .64 movwf temp2 searchloop call get_2bits call process_bits decfsz temp2,F goto searchloop return process_bits btfsc temp1,6 goto b1x btfsc temp1,7 goto b01 ; 00 got 00 some devices sent 0 some 1 , do 0 first incf dup_devices,F ; indicate duplicate btfss dev_select,0 goto b10 b01 bcf temp1,0 ; got 01 all devices sent 0 bcf STATUS,C goto bits_ack b1x btfsc temp1,7 goto b11 b10 bsf temp1,0 ; got 10 all devices sent 1 bsf STATUS,C goto bits_ack b11 .assert "\"no devices present\"" nop bits_ack btfsc dev_select,0 goto bits_ack2 bits_ack1 banksel ID1 rrf ID1,F rrf ID1+1,F rrf ID1+2,F rrf ID1+3,F rrf ID1+4,F rrf ID1+5,F rrf ID1+6,F rrf ID1+7,F call send_1bit return bits_ack2 banksel ID2 rrf ID2,F rrf ID2+1,F rrf ID2+2,F rrf ID2+3,F rrf ID2+4,F rrf ID2+5,F rrf ID2+6,F rrf ID2+7,F call send_1bit return ;****************** Initialize Registers and Variables ***************** ;************************************************************************ ProgInit banksel DS_PORT movlw 0xff movwf DS_PORT ; Set all bits high on Port banksel DS_TRIS clrf DS_TRIS banksel ANSELC clrf ANSELC return ds1820init: ; DS1820 init sequence banksel DS_PORT bsf DS_PORT,DS_PIN ; Pin high banksel DS_TRIS bcf DS_TRIS,DS_PIN ; Pin as output banksel DS_PORT bcf DS_PORT,DS_PIN ; Pin low call Delay500us banksel DS_TRIS bsf DS_TRIS,DS_PIN ; Pin as input (pullup to high) banksel DS_PORT call Delay70us movf DS_PORT,W .assert "(W & 1)==0,\"DS18B20, no presents pulse\"" nop call Delay500us return ; send 1 bit from temp1 send_1bit movlw 1 goto send_bits ; send the byte in W send_byte movwf temp1 movlw 8 send_bits movwf bit_cnt banksel DS_PORT ; we want bit low, high is by pullup bcf DS_PORT,DS_PIN send_loop rrf temp1,F ; rotate lSB into carry btfss STATUS,C ; is bit 0 or 1 goto send_0 goto send_1 send_chk decfsz bit_cnt,F ; have we send all bits goto send_loop ; NO banksel DS_PORT return ; YES send_0 banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay70us bsf DS_TRIS,DS_PIN goto send_chk send_1 banksel DS_TRIS bcf DS_TRIS,DS_PIN call Delay10us bsf DS_TRIS,DS_PIN call Delay70us goto send_chk ; read 1 bit of data get_1bit movlw 1 goto get_bits ; read 2 bits of data get_2bits movlw 2 goto get_bits ; read a data byte and return it in W get_byte movlw 8 ; input bit counter get_bits movwf bit_cnt clrf temp1 banksel DS_PORT bcf DS_PORT,DS_PIN get_loop banksel DS_TRIS bcf DS_TRIS,DS_PIN ; init read timeslot by pulling line low nop ; delay for at least 1 usec nop nop nop nop bsf DS_TRIS,DS_PIN ; release line call Delay10us banksel DS_PORT bsf STATUS,C ; set carry incase of 1 btfss DS_PORT,DS_PIN ; read port data bcf STATUS,C ; its 0, so clear carry rrf temp1,f ; roll data into data word call Delay70us ; this could be 45us btfss DS_PORT,DS_PIN ; check port pin goto $-1 ; loop until high decfsz bit_cnt,F goto get_loop movf temp1,W return Delay750mS movlw .75 movwf d2 loop750ms call Delay10mS decfsz d2,F goto loop750ms return Delay10mS movlw 0x50 movwf d1l movlw 0x28 movwf d1h goto Delay_0 Delay500us movlw 0x02 movwf d1h movlw 0xfe movwf d1l goto Delay_0 Delay70us movlw 0x01 movwf d1h movlw 0x44 movwf d1l goto Delay_0 Delay10us movlw 0x01 movwf d1h movlw 0x08 movwf d1l goto Delay_0 Delay_0 decfsz d1l, f goto $+2 decfsz d1h, f goto Delay_0 ;2 cycles goto $+1 return end gpsim-0.30.0/extras/ds1820/bit1w.cc0000664000076400007640000001526013041763633013442 00000000000000/* Copyright (C) 2012 Eduard Timotei Budulea Copyright (C) 2013 Roy R. Rankin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include "bit1w.h" bool debug = false; LowLevel1W::LowLevel1W(const char *name, const char *desc): Module(name, desc), cicluReper(0), lastValue(true), lastTimeout(false), state(&LowLevel1W::idle), ignoreCallback(false), bit_break(0) { pin = new Pin1W("pin", *this); addSymbol(pin); create_pkg(1); assign_pin(1, pin); pin->putState(false); pin->update_direction(IOPIN::DIR_INPUT, true); change(true); } LowLevel1W::~LowLevel1W() { removeSymbol(pin); } void LowLevel1W::callback() { change(false); } void LowLevel1W::change(bool pinChange) { if (ignoreCallback) return; guint64 ciclu = get_cycles().get(); bool bitValue = false; switch(pin->getBitChar()) { case 'Z': case '1': case 'x': case 'W': bitValue = true; } bool isTimeout = ciclu >= cicluReper; if ((lastValue != bitValue || lastTimeout != isTimeout) && debug) { cout << name() <<" +++change state: line = " << bitValue << ", timeout = " << isTimeout << "; time = " << hex << ciclu << ", reper = " << cicluReper << endl; } lastValue = bitValue; lastTimeout = isTimeout; ignoreCallback = true; (this->*state)(bitValue, isTimeout); ignoreCallback = false; if (cicluReper > ciclu) { if (!pinChange && bit_break >= ciclu) { get_cycles().clear_break(bit_break); } if(cicluReper != bit_break) get_cycles().set_break(cicluReper, this); if(debug) printf("%s now %" PRINTF_GINT64_MODIFIER "x next break %" PRINTF_GINT64_MODIFIER "x last break %" PRINTF_GINT64_MODIFIER "x delta(usec) %.1f\n", name().c_str(), ciclu, cicluReper, bit_break, (cicluReper-ciclu)*4./20.); bit_break = cicluReper; } } void LowLevel1W::idle(bool input, bool isTimeout) { if(debug && !isTimeout) cout <update_direction(IOPIN::DIR_OUTPUT, true); return; case READ: if(verbose) cout << name() << " ===read" << endl; state = &LowLevel1W::inReading; cicluReper = get_cycles().get(0.000030); return; case RESET: if(verbose) cout << name() <<" ===expect reset" << endl; state = &LowLevel1W::inResetPulse; cicluReper = get_cycles().get(0.000440); return; case IDLE: state = &LowLevel1W::idle; return; } } void LowLevel1W::inResetPulse(bool input, bool isTimeout) { if(debug) cout < <...>\n" " -o --output Output file (default=%s)\n" " -b --baud Baud rate (default=%d)\n" " -f --frequency Pic frequency (default=%d)\n" " -n --name Stimulus name (default=%s)\n" " -d --data Data to be sent and when\n" " -c --char Data restricted to printable characters\n" " -h, --help This help\n\n" "Examples:\n" " rs232-gen -b 115200 -d 100:0xFF,0x00 -d +100:0xFF,0x01\n" " rs232-gen -b 9600 -f 4000000 -c 100:Test\\ String\n\n", DEF_FILE, DEF_BAUD, DEF_FREQ, DEF_NAME); return 0; } /* usage() */ static void parse_defaults(void) { int i; for (i = 0; i < MAX_DATA; i++) data[i].size = -1; strcpy(out_file, DEF_FILE); strcpy(name, DEF_NAME); baud = DEF_BAUD; frequency = DEF_FREQ; return; } /* parse_defaults() */ static int parse_data(char *str, int type) { int64_t offset = 0; unsigned int val; int i = 0, j = 0; char *ptr; while ((data[i].size != -1) && (i < MAX_DATA)) i++; if (i == MAX_DATA) { fprintf(stderr, "Error: Too many data segments (>%d)\n", MAX_DATA); return 1; } if ((ptr = strchr(str, ':')) == NULL) { fprintf(stderr, "Error: No ':' in provided data\n"); return 1; } /* Extract the cycle count */ ptr[0] = '\0'; if ((str[0] == '+') && (i > 0)) offset = data[i-1].cycle; data[i].cycle = offset + strtoll(str,0,10); /* Extract the actual data * * To make life easier data can be entered in two ways. * * 1) As binary hex data seperated by commas * e.g. -d 1000:0x01,0x02,0x03,0x04,0x05... * * 2) As printable characters strung together in a string * e.g. -c 1000:This-is-a-test-string */ if (type == DATA_FLAG) { do { ptr = ptr + 1; sscanf(ptr, "0x%X", &val); data[i].data[j] = val & 0xFF; j++; } while ((ptr = strchr(ptr, ',')) != NULL); data[i].size = j; } else { if (type == CHAR_FLAG) { ptr = ptr + 1; strcpy((char *)data[i].data, ptr); data[i].size = strlen((char *)data[i].data); } else { fprintf(stderr, "Error: Unknown data type %d\n", type); return 1; } } return 0; } /* parse_data() */ static int parse_args(int argc, char *argv[]) { int rc, c, longindex; opterr = 0; while ((c = getopt_long(argc, argv, OPT_STR, longopts, &longindex)) != -1) { switch (c) { case 'o': strcpy(out_file, optarg); break; case 'b': baud = atoi(optarg); break; case 'f': frequency = atoi(optarg); break; case 'n': strcpy(name, optarg); break; case 'd': if ((rc = parse_data(optarg, DATA_FLAG)) != 0) return rc; break; case 'c': if ((rc = parse_data(optarg, CHAR_FLAG)) != 0) return rc; break; case 'h': default: return !usage(); } } return 0; } /* parse_args() */ static int output_file(void) { int bit, mask, i = 0, j; long long val, pad; FILE *fp; if ((fp = fopen(out_file, "w")) == 0) { fprintf(stderr, "Error: [%d] %s\n", errno, strerror(errno)); return 1; } /* Determine the length of each bit. This is simply the chip * frequency divided by the baud rate and divided by the clock cycles * per instruction. */ pad = (frequency / (DEF_CPI * baud)); fprintf(fp, "# rs232 Stimulus generated by rs232-gen\n\n"); fprintf(fp, "stimulus asynchronous_stimulus\n"); fprintf(fp, "initial_state 1\n"); fprintf(fp, "start_cycle 0\n\n"); fprintf(fp, "{\n"); while ((data[i].size != -1) && (i < MAX_DATA)) { fprintf(fp, "# Chunk: %d\n", i); val = data[i].cycle; for (j = 0; j < data[i].size; j++) { fprintf(fp, "# Character: 0x%02X", data[i].data[j]); if (isprint(data[i].data[j])) fprintf(fp, " (%c)\n", data[i].data[j]); else fprintf(fp, "\n"); fprintf(fp, "%lld, 0,\n", val); val += pad; for (mask = 0x01; mask < 0xFF; mask = mask << 1) { bit = ((data[i].data[j] & (mask & 0xFF)) ? 1 : 0); fprintf(fp, "%lld, %d,\n", val, bit); val += pad; } fprintf(fp, "%lld, 1,\n\n", val); val += pad; } i++; } fprintf(fp, "# dummy ending\n"); fprintf(fp, "%lld, 0\n", val); fprintf(fp, "}\n\n"); fprintf(fp, "name %s\n", name); fprintf(fp, "end\n"); if (fclose(fp) != 0) { fprintf(stderr, "Error: [%d] %s\n", errno, strerror(errno)); return 1; } return 0; } /* output_file() */ int main(int argc, char *argv[]) { int rc; parse_defaults(); if ((rc = parse_args(argc, argv)) != 0) return rc; if (data[0].size == -1) { fprintf(stderr, "Error: No data provided\n"); return 1; } if ((rc = output_file()) != 0) return rc; return 0; } /* main() */ gpsim-0.30.0/extras/rs232-gen/Makefile0000664000076400007640000000013713041763633014243 00000000000000all: rs232-gen rs232-gen: rs232-gen.c gcc -o rs232-gen rs232-gen.c clean: rm -f rs232-gen gpsim-0.30.0/extras/rs232-gen/README0000664000076400007640000000100213041763633013453 00000000000000/* * Simple RS232 generator for gpsim. * - At most 32 discrete messages * - At most 256 bytes per message * * Brian Behlendorf */ Examples: rs232-gen -b 115200 -d 100:0xFF,0x00 -d +100:0xFF,0x01 rs232-gen -b 9600 -f 4000000 -c 100:Test\ String Example stc file: # example.stc load s example.cod frequency 4000000 # must match the freq. used by rs232-gen node uart_test load c uart_stim.txt # the output from rs232-gen attach uart_test rs232_stimulus portc7 # portb1 for 62x gpsim-0.30.0/extras/rs232-gen/example/0000775000076400007640000000000013117466030014310 500000000000000gpsim-0.30.0/extras/rs232-gen/example/Makefile0000664000076400007640000000035513041763633015700 00000000000000all: uart_stim.txt example.cod uart_stim.txt: ../rs232-gen -b 115200 -o uart_stim.txt -f 1843200 -c 3000:rs232-test example.cod: example.asm gpasm -i -w 1 example.asm clean: rm -f example.cod example.hex example.lst uart_stim.txt gpsim-0.30.0/extras/rs232-gen/example/README0000664000076400007640000000015113041763633015112 00000000000000 Run make. This will assemble the example and create the uart_stim.txt. Then run: gpsim -c example.stc gpsim-0.30.0/extras/rs232-gen/example/example.stc0000664000076400007640000000035113041763633016402 00000000000000# example.stc load s example.cod frequency 1843200 # must match the freq. used by rs232-gen node uart_test load c uart_stim.txt # the output from rs232-gen attach uart_test rs232_stimulus portc7 # portb1 for 62x gpsim-0.30.0/extras/rs232-gen/example/example.asm0000664000076400007640000000255713041763633016403 00000000000000 ;; The purpose of this program is to test gpsim's ability to simulate ;; USART in the 14bit core. list p=16f877 __config _wdt_off include "p16f877.inc" #define RX_BUF_SIZE 0x10 cblock 0x20 temp1 temp2 w_temp status_temp fsr_temp tx_ptr rx_ptr rx_buffer : RX_BUF_SIZE endc org 0 goto start org 4 ;; Interrupt ;; movwf w_temp swapf status,w movwf status_temp bcf status,rp0 btfsc intcon,peie btfss pir1,rcif goto int_done ;;; movf fsr,w movwf fsr_temp incf rx_ptr,w andlw 0x0f movwf rx_ptr addlw rx_buffer movwf fsr movf rcreg,w movwf indf movf fsr_temp,w movwf fsr int_done: swapf status_temp,w movwf status swapf w_temp,f swapf w_temp,w retfie ;; ---------------------------------------------------- ;; ;; start ;; start ;; USART Initialization ;; ;; Turn on the high baud rate (BRGH), disable the transmitter, ;; disable synchronous mode. ;; clrf status bsf status,rp0 movlw (1< #endif class I2C_EE; class PromAddress; class I2C_RTC; class SQW_PIN; namespace DS1307_Modules { class ds1307 : public Module, public TriggerObject { public: ds1307(const char *_name); ~ds1307(); static Module *construct_ds1307(const char *new_name); virtual void create_iopin_map(); virtual void setEnable(bool bNewState, unsigned int m_bit){}; virtual void callback(); void secWritten(unsigned int sec); void controlWritten(unsigned int cntl); enum control { RS0 = 1 << 0, RS1 = 1 << 1, SQWE = 1 << 4, OUT = 1 << 7 }; enum second { CH = 1 << 7 }; protected: void incrementRTC(); I2C_RTC *m_eeprom; SQW_PIN *m_sqw; unsigned int chip_select; // Write Protect and A0 - A2 state PromAddress *att_eeprom; guint64 next_clock_tick; // increment RTC here guint64 next_sqw_edge; // change sqw edge here guint64 sqw_interval; // cycles between edges bool out; // Output state }; } // end of namespace DS1307_Modules class I2C_RTC : public I2C_EE { public: I2C_RTC(Processor *pCpu, unsigned int _rom_size, unsigned int _write_page_size = 1, unsigned int _addr_bytes = 1, unsigned int _CSmask = 0, unsigned int _BSmask = 0, unsigned int _BSshift = 0 ); virtual ~I2C_RTC(){} protected: virtual bool match_address(); DS1307_Modules::ds1307 *pEE; }; #endif // __DS1307_H__ gpsim-0.30.0/extras/ds1307/Makefile.in0000664000076400007640000004542713117441635014161 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile for the DS1307 module # make in .. directory # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = extras/ds1307 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in ChangeLog DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = ds1307.h ChangeLog examples/README \ examples/ds1307.asm examples/i2c_low.inc examples/Makefile SUBDIRS = all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu extras/ds1307/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu extras/ds1307/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/extras/ds1307/Makefile.am0000664000076400007640000000030113041763631014125 00000000000000# Makefile for the DS1307 module # make in .. directory # EXTRA_DIST = ds1307.h ChangeLog examples/README \ examples/ds1307.asm examples/i2c_low.inc examples/Makefile SUBDIRS = gpsim-0.30.0/extras/ds1307/ChangeLog0000664000076400007640000000012313041763631013645 000000000000002010-05-17 Roy Rankin - Create DS1307 Realtime Clock module gpsim-0.30.0/extras/ds1307/examples/0000775000076400007640000000000013117466030013772 500000000000000gpsim-0.30.0/extras/ds1307/examples/ds1307.asm0000664000076400007640000003426513041763631015352 00000000000000; ; Test reading, writing, dump and load for external i2c EEPROM module ; ; Copyright (c) 2007 Roy Rankin ; MACROS and some code included the following ;************************************************************************ ;* Microchip Technology Inc. 2006 ;* 02/15/06 ;* Designed to run at 20MHz ;************************************************************************ ; gpsim command .command macro x .direct "C", x endm list p=16F876A #include p16f876a.inc include __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _PWRTE_ON & _BODEN_ON & _WDT_OFF & _HS_OSC errorlevel -302 radix dec variables UDATA 0x30 time RES 16 temp1 RES 1 temp2 RES 1 status_temp RES 1 w_temp RES 1 global time ;---------------------------------------------------------------------- ; ********************* RESET VECTOR LOCATION ******************** ;---------------------------------------------------------------------- RESET_VECTOR CODE 0x000 ; processor reset vector movlw high start ; load upper byte of 'start' label movwf PCLATH ; initialize PCLATH goto start ; go to beginning of program ;------------------------------------------------------------------------ ; ; Interrupt Vector ; ;------------------------------------------------------------------------ INT_VECTOR CODE 0x004 ; interrupt vector location movwf w_temp swapf STATUS,W movwf status_temp btfsc INTCON,RBIF goto rb_int .assert "\"***FAILED ds1307 unexpected interrupt\"" nop rb_int nop bcf INTCON,RBIF exit_int: swapf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ; MAIN CODE start .sim "module lib libgpsim_modules" .sim "module lib libgpsim_extras" .sim "module lib libgpsim_ds1307" .sim "module load ds1307 ee" .sim "module load pu pu1" .sim "module load pu pu2" .sim "module load pu pu3" .sim "node n1" .sim "attach n1 portc4 pu1.pin portb4 ee.SDA" ; SDA .sim "node n2" .sim "attach n2 portc3 pu2.pin portb1 ee.SCL" ; SCL .sim "node n3" .sim "attach n3 pu3.pin portb0 ee.SQW" .sim "pu1.xpos = 240." .sim "pu1.ypos = 336." .sim "pu2.xpos = 216." .sim "pu2.ypos = 24." .sim "ee.xpos = 48." .sim "ee.ypos = 180." .sim "p16f876a.xpos = 240." .sim "p16f876a.ypos = 84." call ProgInit ; Get everything running step-by-step BANKSEL PORTA movlw 0x2F movwf time+2 movwf time+5 movlw 0x20 movwf time+8 movlw 0x3A movwf time+0xb movwf time+0xe nop call is_ready call read_ds1307 ; Current date and time startting in ram location 30 ; sleep nop call I2CSendResult call write_eeprom call is_ready call read_ds1307 ; 02/05/10 19:59:12 starting in ram location 30 .assert "time == 0x30, \"*** FAILED ds1307 day 10's\"" nop BANKSEL time movf time+1,W .assert "W == 0x33, \"*** FAILED ds1307 day 1's\"" nop movf time+3,W .assert "W == 0x30, \"*** FAILED ds1307 month 10's\"" nop movf time+4,W .assert "W == 0x35, \"*** FAILED ds1307 month 1's\"" nop movf time+6,W .assert "W == 0x31, \"*** FAILED ds1307 year 10's\"" nop movf time+7,W .assert "W == 0x30, \"*** FAILED ds1307 year 1's\"" nop movf time+9,W .assert "W == 0x31, \"*** FAILED ds1307 hour 10's\"" nop movf time+10,W .assert "W == 0x39, \"*** FAILED ds1307 hour 1's\"" nop movf time+12,W .assert "W == 0x35, \"*** FAILED ds1307 min 10's\"" nop movf time+13,W .assert "W == 0x39, \"*** FAILED ds1307 min 1's\"" nop movf time+15,W .assert "W == 0x31, \"*** FAILED ds1307 sec 10's\"" nop movf time+16,W .assert "W == 0x32, \"*** FAILED ds1307 sec 1's\"" nop sleep nop .command "dump e ee dump.hex" nop call is_ready call read_ds1307 BANKSEL time movf time+16,W .assert "W == 0x33, \"*** FAILED ds1307 sec 1's after 1 sec\"" nop .assert "\"*** PASSED p16f876a I2C test\"" goto $ ;****************************** SUBROUTINES **************************** ;************************************************************************ START_I2C MACRO banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 banksel PORTA ENDM RSTART_I2C MACRO banksel SSPCON2 ; Generate I2C repeat start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 banksel PORTA ENDM STOP_I2C MACRO banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PORTA ENDM IDLE_WAIT_I2C MACRO banksel SSPCON2 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_W goto $-1 banksel PORTA ENDM ;****************** Initialize Registers and Variables ***************** ;************************************************************************ ProgInit banksel PORTA clrf PORTA ; Set all bits to zero on Port A banksel TRISA clrf TRISA banksel SSPADD movlw 0x0C ; Set I2C baud rate to 385 kHz movwf SSPADD bcf OPTION_REG,INTEDG banksel SSPCON movlw 0x08 ; Set for I2C master mode movwf SSPCON movlw 0x28 ; Enable I2C movwf SSPCON bsf INTCON,INTE return ;************************************************************************ I2CSendResult banksel SSPCON2 ; Generate I2C start, bus collision bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 bsf SSPCON2,SEN bcf TRISB,1 IDLE_WAIT_I2C .assert "(pir2 & 0x08) == 0x08, \"FAILED BCLIF for start\"" nop banksel TRISB bsf TRISB,1 banksel PIR2 bcf PIR2,BCLIF banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN IDLE_WAIT_I2C .assert "(portc & 0x18) == 0, \"FAILED Start SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Start SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Start BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED Start S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x18) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,ACKDT bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 .assert "(portc & 0x18) == 0x10, \"FAILED ACKEN SCL low, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED ACKEN SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED ACKEN BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED ACKEN S bit set\"" nop bcf SSPCON2,ACKDT bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C restart bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 .assert "(portc & 0x18) == 0, \"FAILED RStart SCL, SDL low\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED RStart SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RStart BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x08, \"FAILED RStart S bit set\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 .assert "(portc & 0x18) == 0x18, \"FAILED Stop SCL, SDL high\"" nop .assert "(pir1 & 0x08) == 0x08, \"FAILED Stop SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED Stop BCLIF clear\"" nop .assert "(sspstat & 0x3f) == 0x10, \"FAILED Stop P bit set\"" nop return ; ; repeatedly send command to eeprom until an ACK ; is received back ; ; The call of delay is not required for operation of the code, ; but it speeds up the simulation with the GUI running. -- RRR ; is_ready banksel SSPCON movlw 0x04 movwf temp2 clrf temp1 call delay banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xd0 ; write command to eeprom call I2C_send_w call I2C_stop banksel SSPCON2 ; Generate I2C start btfsc SSPCON2,ACKSTAT goto is_ready banksel PIR2 bcf PIR2,BCLIF return write_eeprom_address banksel SSPCON2 ; Generate I2C start bsf SSPCON2,SEN btfsc SSPCON2,SEN goto $-1 movlw 0xd0 ; write command to eeprom call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write command to eeprom ACK\"" nop .assert "(sspstat & 0x01) == 0x00, \"FAILED write to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write eeprom address call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write address to eeprom ACK\"" nop return write_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSPIF movlw 0x12 ; write seconds 12 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x59 ; write minutes 59 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x19|0x40 ; write hours 19 and 24 hour format call I2C_send_w nop banksel PIR1 bcf PIR1,SSPIF movlw 0x01 ; write Day of week (1-7) call I2C_send_w nop banksel PIR1 bcf PIR1,SSPIF movlw 0x03 ; write Day of month call I2C_send_w nop banksel PIR1 bcf PIR1,SSPIF movlw 0x05 ; write month call I2C_send_w nop banksel PIR1 bcf PIR1,SSPIF movlw 0x10 ; write year call I2C_send_w nop banksel PIR1 bcf PIR1,SSPIF movlw 0x10 ; control out=1 SQWE off call I2C_send_w nop call I2C_stop return clr_eeprom call write_eeprom_address banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write data1 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data1 to eeprom ACK\"" nop banksel PIR1 bcf PIR1,SSPIF movlw 0x00 ; write data2 call I2C_send_w .assert "(sspcon2 & 0x40) == 0x00, \"FAILED write data2 to eeprom ACK\"" nop nop call I2C_stop return read_ds1307 call write_eeprom_address banksel SSPCON2 ; Generate I2C repeated start bsf SSPCON2,RSEN btfsc SSPCON2,RSEN goto $-1 movlw 0xd1 ; Send address/read to eeprom banksel SSPBUF movwf SSPBUF banksel SSPCON2 ; wait for idle (ACKEN,RCEN,PEN,RSEN,SEN) == 0 movlw 0x1f andwf SSPCON2,W BNZ $-3 btfsc SSPSTAT,R_W ; also R_W == 0 goto $-1 .assert "(sspstat & 0x01) == 0x00, \"FAILED address/read to eeprom BF clear\"" nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read seconds from RTC btfsc SSPCON2,RCEN goto $-1 .assert "(pir1 & 0x08) == 0x08, \"FAILED RCEN SSPIF set\"" nop .assert "(pir2 & 0x08) == 0x00, \"FAILED RCEN BCLIF clear\"" nop .assert "(sspstat & 0x01) == 0x01, \"FAILED RCEN BF set\"" nop banksel SSPBUF movf SSPBUF,W banksel PORTA movwf time+0x10 movwf time+0xf movlw 0x0f andwf time+0x10,f movlw 0x30 addwf time+0x10,f movlw 0x70 andwf time+0xf,f RRF time+0xf,f RRF time+0xf,f RRF time+0xf,f RRF time+0xf,f movlw 0x30 addwf time+0xf,f nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read minutes from RTC btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W banksel PORTA movwf time+0xd movwf time+0xc movlw 0x0f andwf time+0xd,f movlw 0x30 addwf time+0xd,f movlw 0xf0 andwf time+0xc,f RRF time+0xc,f RRF time+0xc,f RRF time+0xc,f RRF time+0xc,f movlw 0x30 addwf time+0xc,f nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read Hours from RTC btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W banksel PORTA movwf time+0xa movwf time+0x9 movlw 0x0f andwf time+0xa,f movlw 0x30 addwf time+0xa,f movlw 0x30 andwf time+0x9,f RRF time+0x9,f RRF time+0x9,f RRF time+0x9,f RRF time+0x9,f movlw 0x30 addwf time+0x9,f nop banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read day of week btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read Day of month btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W banksel PORTA movwf time+0x1 movwf time+0x0 movlw 0x0f andwf time+0x1,f movlw 0x30 addwf time+0x1,f movlw 0x30 andwf time+0x0,f RRF time+0x0,f RRF time+0x0,f RRF time+0x0,f RRF time+0x0,f movlw 0x30 addwf time+0x0,f nop banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read month btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W banksel PORTA movwf time+0x4 movwf time+0x3 movlw 0x0f andwf time+0x4,f movlw 0x30 addwf time+0x4,f movlw 0x30 andwf time+0x3,f RRF time+0x3,f RRF time+0x3,f RRF time+0x3,f RRF time+0x3,f movlw 0x30 addwf time+0x3,f nop banksel SSPCON2 bcf SSPCON2,ACKDT ; send ACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,RCEN ; read Year btfsc SSPCON2,RCEN goto $-1 banksel SSPBUF movf SSPBUF,W banksel PORTA movwf time+0x7 movwf time+0x6 movlw 0x0f andwf time+0x7,f movlw 0x30 addwf time+0x7,f movlw 0xf0 andwf time+0x6,f RRF time+0x6,f RRF time+0x6,f RRF time+0x6,f RRF time+0x6,f movlw 0x30 addwf time+0x6,f nop banksel PIR1 bcf PIR1,SSPIF banksel SSPCON2 bsf SSPCON2,ACKDT ; send NACK bsf SSPCON2,ACKEN btfsc SSPCON2,ACKEN goto $-1 return I2C_stop banksel SSPCON2 ; Generate I2C stop bsf SSPCON2,PEN btfsc SSPCON2,PEN goto $-1 return delay decfsz temp1,f goto $+2 decfsz temp2,f goto delay return ;********************** Output byte in W via I2C bus ******************** ;************************************************************************ I2C_send_w banksel SSPBUF ; Second byte of data (middle) movwf SSPBUF banksel SSPSTAT btfsc SSPSTAT,R_W goto $-1 return end gpsim-0.30.0/extras/ds1307/examples/i2c_low.inc0000664000076400007640000003227213041763631015754 00000000000000;**************************************************************************** ; ; Low Level I2C Routines ; ; Single Master Transmitter & Single Master Receiver Routines ; These routines can very easily be converted to Multi-Master System ; when PIC16C6X with on chip I2C Slave Hardware, Start & Stop Bit ; detection is available. ; ; The generic high level routines are given in I2C_HIGH.ASM ; ; ; Program: I2C_LOW.ASM ; Revision Date: ; 1-16-97 Compatibility with MPASMWIN 1.40 ; ;*************************************************************************** ;************************************************************************** ; I2C Bus Initialization ; ;************************************************************************** InitI2CBus_Master: bcf STATUS,RP0 movlw ~(1< //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif #include "config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #endif #include "src/i2c-ee.h" #include "ds1307.h" #include "src/gpsim_time.h" #include "src/stimuli.h" #include "src/ioports.h" #include "src/symbol.h" #include "src/value.h" #include "src/packages.h" #include "src/gpsim_interface.h" class Processor; I2C_RTC::I2C_RTC(Processor *pCpu, unsigned int _rom_size, unsigned int _write_page_size, unsigned int _addr_bytes, unsigned int _CSmask, unsigned int _BSmask, unsigned int _BSshift) : I2C_EE(pCpu, _rom_size, _write_page_size, _addr_bytes, _CSmask, _BSmask, _BSshift) { pEE = (DS1307_Modules::ds1307 *)pCpu; i2c_slave_address = 0xd0; } bool I2C_RTC::match_address() { Dprintf(("match_address I2C got address=0x%x (w=%d) want 0x%x\n", (xfr_data & 0xfe), (xfr_data & 0x01), i2c_slave_address)); return((xfr_data & 0xfe) == i2c_slave_address); } class SQW_PIN : public IO_open_collector { public: SQW_PIN (const char *_name) : IO_open_collector(_name) { bDrivingState = true; bDrivenState = true; // Make the pin an output. update_direction(IO_bi_directional::DIR_OUTPUT,true); }; void setDrivingState(bool new_state) { bDrivingState = new_state; bDrivenState = new_state; if(snode) snode->update(); } }; namespace DS1307_Modules { ds1307::ds1307(const char *_name) : Module(_name, "BS1307") { chip_select = 0; next_sqw_edge = 0; next_clock_tick = 0; sqw_interval = 0; out = false; } ds1307::~ds1307() { removeSymbol(m_sqw); removeSymbol((IOPIN *)(m_eeprom->sda)); removeSymbol((IOPIN *)(m_eeprom->scl)); m_eeprom->sda = 0; m_eeprom->scl = 0; delete att_eeprom; delete m_eeprom; } Module *ds1307::construct_ds1307(const char *_new_name) { string att_name = _new_name; ds1307 *pEE = new ds1307(_new_name); // I2C_EE size in bytes prom size in bits (pEE->m_eeprom) = new I2C_RTC((Processor *)pEE,64, 16, 1, 0xe, 0, 0); pEE->create_iopin_map(); att_name += ".ds1307"; pEE->att_eeprom = new PromAddress(pEE->m_eeprom, "eeprom", "Address I2C_RTC"); pEE->addSymbol(pEE->att_eeprom); #ifdef LOCAL_TIME struct tm *tm; time_t t = time(NULL); int val; tm = localtime(&t); val = tm->tm_sec; (pEE->m_eeprom->get_register(0))->put((val % 10) + ((val / 10)<<4)); val = tm->tm_min; (pEE->m_eeprom->get_register(1))->put((val % 10) + ((val / 10)<<4)); val = tm->tm_hour; (pEE->m_eeprom->get_register(2))->put((val % 10) + ((val / 10)<<4) + 0x40); (pEE->m_eeprom->get_register(3))->put(tm->tm_wday+1); val = tm->tm_mday; (pEE->m_eeprom->get_register(4))->put((val % 10) + ((val / 10)<<4)); val = tm->tm_mon + 1; (pEE->m_eeprom->get_register(5))->put((val % 10) + ((val / 10)<<4)); val = tm->tm_year % 100; (pEE->m_eeprom->get_register(6))->put((val % 10) + ((val / 10)<<4)); (pEE->m_eeprom->get_register(7))->put(0x10); pEE->controlWritten(0x10); #else // factory defaults (pEE->m_eeprom->get_register(0))->put(0x80); (pEE->m_eeprom->get_register(1))->put(0x00); (pEE->m_eeprom->get_register(2))->put(0x00); (pEE->m_eeprom->get_register(3))->put(0x01); (pEE->m_eeprom->get_register(4))->put(0x01); (pEE->m_eeprom->get_register(5))->put(0x01); (pEE->m_eeprom->get_register(6))->put(0x00); (pEE->m_eeprom->get_register(7))->put(0x00); #endif return(pEE); } void ds1307::create_iopin_map() { m_sqw = new SQW_PIN("SQW"); addSymbol(m_sqw); addSymbol((IOPIN *)(m_eeprom->sda)); addSymbol((IOPIN *)(m_eeprom->scl)); package = new Package(8); package->assign_pin( 1, 0); package->assign_pin( 2, 0); package->assign_pin( 3, 0); package->assign_pin( 5, (IOPIN *)(m_eeprom->sda)); package->assign_pin( 6, (IOPIN *)(m_eeprom->scl)); package->assign_pin( 7, m_sqw); m_sqw->update_direction(1,true); } void ds1307::controlWritten(unsigned int cntl) { unsigned int new_sqw_interval = 0; if ( cntl & SQWE ) { switch(cntl & (RS1|RS0)) { case 0: new_sqw_interval = 0.5 / (get_cycles().seconds_per_cycle()); break; case 1: new_sqw_interval = 0.5 / (4096. * get_cycles().seconds_per_cycle()); break; case 2: new_sqw_interval = 0.5 / (8192. * get_cycles().seconds_per_cycle()); break; case 3: new_sqw_interval = 0.5 / (32768. * get_cycles().seconds_per_cycle()); break; } if (!new_sqw_interval) { fprintf(stderr, "DS1307 SQW faster than can be simulated\n"); new_sqw_interval = 1; } int sec = (m_eeprom->get_register(0))->get(); if (!(sec & CH)) { if (next_sqw_edge ) { if (new_sqw_interval != sqw_interval) { get_cycles().clear_break(next_sqw_edge); next_sqw_edge = new_sqw_interval - sqw_interval; get_cycles().set_break(next_sqw_edge, this); } } else { out = false; m_sqw->setDrivingState(out); next_sqw_edge = get_cycles().get() + new_sqw_interval; get_cycles().set_break(next_sqw_edge, this); } if (!next_clock_tick) { next_clock_tick = get_cycles().get() + get_cycles().instruction_cps(); get_cycles().set_break(next_clock_tick, this); } } sqw_interval = new_sqw_interval; } else { sqw_interval = 0; if (next_sqw_edge) // stop the SQW output { get_cycles().clear_break(next_sqw_edge); next_sqw_edge = 0; } m_sqw->setDrivingState((cntl & OUT) == OUT); } } void ds1307::secWritten(unsigned int sec) { if (sec & CH) // Turn off clock functions { Dprintf(("DS1307 Turn off clock\n")); if (next_sqw_edge) // stop the SQW output { get_cycles().clear_break(next_sqw_edge); next_sqw_edge = 0; } if (next_clock_tick) // stop the SQW output { get_cycles().clear_break(next_clock_tick); next_clock_tick = 0; } } else // Clock functions on { Dprintf(("Clock functions on\n")); if (next_clock_tick) // resync ticks get_cycles().clear_break(next_clock_tick); next_clock_tick = get_cycles().get() + get_cycles().instruction_cps(); get_cycles().set_break(next_clock_tick, this); if (next_sqw_edge) get_cycles().clear_break(next_sqw_edge); if (sqw_interval) { next_sqw_edge = get_cycles().get() + sqw_interval; get_cycles().set_break(next_sqw_edge, this); } } } void ds1307::incrementRTC() { int i; int value; bool is12h; unsigned char dom; unsigned char month; unsigned int year; unsigned char dim[12] = { 31, 28, 31, 30,31, 30, 31, 31, 30, 31, 30, 31}; value = (m_eeprom->get_register(0))->get(); if (value & 0x80) // return if clock halt set return; i = (value >> 4) * 10 + (value & 0xf) + 1; if ( i < 60 ) { value = i % 10; value = (i >= 10) ? value | ((i / 10) << 4) : value; (m_eeprom->get_register(0))->put(value); return; } (m_eeprom->get_register(0))->put(0); value = (m_eeprom->get_register(1))->get(); // Get minutes i = (value >> 4) * 10 + (value & 0xf) + 1; if ( i < 60 ) { value = i % 10; value = (i >= 10) ? value | ((i / 10) << 4) : value; (m_eeprom->get_register(1))->put(value); return; } (m_eeprom->get_register(1))->put(0); value = (m_eeprom->get_register(2))->get(); // Get Hours is12h = ( value & 0x40) == 0x40; if (is12h) { bool isPM; isPM = ( value & 0x20) == 0x20; i = ((value & 1) >> 4) * 10 + (value & 0xf) + 1; if ( i == 12 && ! isPM) { isPM = true; i = 0; } if (i < 12) { value = i % 10; value = (i >= 10) ? value | ((i / 10) << 4) : value; value |= isPM ? 0x60 : 0x40; (m_eeprom->get_register(2))->put(value); return; } value = 0x40; (m_eeprom->get_register(2))->put(value); } else { i = (value >> 4) * 10 + (value & 0xf) + 1; if (i < 24) { value = i % 10; value = (i >= 10) ? value | ((i / 10) << 4) : value; (m_eeprom->get_register(2))->put(value); return; } (m_eeprom->get_register(2))->put(0); } value = (m_eeprom->get_register(3))->get(); // Get DOW value = ( value + 1 ) % 7; (m_eeprom->get_register(3))->put(value); value = (m_eeprom->get_register(4))->get(); // Get DOM dom = (value >> 4) * 10 + (value & 0xf) + 1; value = (m_eeprom->get_register(5))->get(); // Get month month = (value >> 4) * 10 + (value & 0xf); value = (m_eeprom->get_register(6))->get(); // Get year year = (value >> 4) * 10 + (value & 0xf) + 2000; if ((year % 400) == 0 || ((year % 4) == 0 && (year % 100) != 0)) dim[1] = 29; if (dom <= dim[month-1]) { value = dom % 10; value = (dom >= 10) ? value | ((dom / 10) << 4) : value; (m_eeprom->get_register(4))->put(value); return; } (m_eeprom->get_register(4))->put(1); if (++month <= 12) { value = month % 10; value = (month >= 10) ? value | ((month / 10) << 4) : value; (m_eeprom->get_register(5))->put(value); return; } (m_eeprom->get_register(5))->put(1); i = ++year % 100; value = i % 10; value = (i >= 10) ? value | ((i / 10) << 4) : value; (m_eeprom->get_register(6))->put(value); return; } void ds1307::callback() { guint64 now = get_cycles().get(); Dprintf(("ds1307 now=%ld tick= %ld sqw= %ld\n", (long)now, (long)next_clock_tick, (long)next_sqw_edge)); if (now == next_clock_tick) { incrementRTC(); next_clock_tick = get_cycles().get() + get_cycles().instruction_cps(); get_cycles().set_break(next_clock_tick, this); } if (now == next_sqw_edge) { long diff; out = !out; next_sqw_edge = get_cycles().get() + sqw_interval; // syncronize with clock ticks diff = labs((long)(next_sqw_edge - next_clock_tick)); if (diff < (long)sqw_interval / 2) { if (!out) fprintf(stderr, "DS1307 SQW phase issue\n"); next_sqw_edge = next_clock_tick; } m_sqw->setDrivingState(out); get_cycles().set_break(next_sqw_edge, this); } } } // end of namespace DS1307_Modules gpsim-0.30.0/NEWS0000664000076400007640000000004113041763636010347 00000000000000 gpsim News See the Readme filesgpsim-0.30.0/ltmain.sh0000644000076400007640000117077113026757070011507 00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.6 package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname (GNU libtool) 2.4.6 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: gpsim-0.30.0/configure.ac0000664000076400007640000002013513117441545012140 00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) AC_INIT([gpsim], [0.30.0], []) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE([subdir-objects]) AM_MAINTAINER_MODE AC_CONFIG_MACRO_DIR([m4]) # Determine the host and build type. The target is always a PIC. AC_CANONICAL_BUILD AC_CANONICAL_HOST dnl --enable-leak-sanitize : Turn on memory leak detection dnl The default is off dnl X86-64 Linux GCC 4.8+ CLang only AC_ARG_ENABLE(leak-sanitize, [ --enable-leak-sanitize Enable memory leak debugging], [case "${enableval}" in yes) use_leak_sanitize=yes ;; no) use_leak_sanitize=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-leak-sanitize) ;; esac],[use_leak_sanitize=no]) if test "$use_leak_sanitize" = "yes"; then echo enabling memory leak debugging LD_SANITIZE="-fsanitize=leak" else LD_SANITIZE="" fi dnl --enable-address-sanitize : Turn on memory error detection dnl The default is off dnl X86-64 Linux GCC 4.8+ CLang only AC_ARG_ENABLE(address-sanitize, [ --enable-address-sanitize Enable memory error debugging], [case "${enableval}" in yes) use_address_sanitize=yes ;; no) use_address_sanitize=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-address-sanitize) ;; esac],[use_address_sanitize=no]) if test "$use_address_sanitize" = "yes"; then echo enabling memory address debugging LD_ADDRESS="-fsanitize=address" else LD_ADDRESS="" fi dnl --enable-undefined-sanitize : Turn on undefined behavior detection dnl The default is off dnl X86-64 Linux GCC 4.8+ CLang only AC_ARG_ENABLE(undefined-sanitize, [ --enable-undefined-sanitize Enable undefined behavior detection], [case "${enableval}" in yes) use_undefined_sanitize=yes ;; no) use_undefined_sanitize=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-undefined-sanitize) ;; esac],[use_undefined_sanitize=no]) if test "$use_undefined_sanitize" = "yes"; then echo enabling undefined behavior detection LD_UNDEFINED="-fsanitize=undefined" else LD_UNDEFINED="" fi dnl --disable-gui : turn off gui support (cli only) dnl The default is to have the gui. AC_ARG_ENABLE(gui, [ --disable-gui Only use the cli and not the gui], [case "${enableval}" in yes) use_gui=yes ;; no) use_gui=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --disable-gui) ;; esac],[use_gui=yes]) if test "$use_gui" = "no"; then echo disabling gui support else echo enabling gui support [ use_gui=yes ] AC_DEFINE([HAVE_GUI],[],[True if GUI is being used]) fi dnl --enable-sockets : allows gpsim to be controlled from a socket interface dnl The default is to not use sockets. AC_ARG_ENABLE(sockets, [ --enable-sockets Allows gpsim to be controlled via a socket interface], [case "${enableval}" in yes) use_sockets=yes ;; no) use_sockets=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-sockets) ;; esac],[use_sockets=no]) if test "$use_sockets" = "no"; then echo disabling gpsim socket interface else echo enabling gpsim socket interface [ use_sockets=yes ] AC_DEFINE([HAVE_SOCKETS],[],[True if gpsim socket interface is being used]) fi dnl check if popt is installed AC_CHECK_HEADER(popt.h, , AC_MSG_ERROR(popt not installed: cannot find popt.h)) GTK= GDK= GLIB= PKG_PROG_PKG_CONFIG() if test "$use_gui" = "no"; then dnl glib2 checks PKG_CHECK_MODULES(P_GLIB, [glib-2.0 >= 2.26 gthread-2.0 gmodule-2.0]) X_LDFLAGS=$P_GLIB_LIBS X_CFLAGS=$P_GLIB_CFLAGS Y_LDFLAGS= Y_CFLAGS= else dnl gtk2 checks # PKG_CHECK_MODULES(GTKEXTRAMOD, gtkextra-2.0, , # [PKG_CHECK_MODULES(GTKEXTRAMOD, gtkextra-3.0, , # [AC_MSG_ERROR(Cannot find gtkextra-2.0 or gtkextra-3.0 package)])]) PKG_CHECK_MODULES(P_GTK, [gtk+-2.0 >= 2.24 glib-2.0 >= 2.26 gthread-2.0]) X_LDFLAGS=$P_GTK_LIBS X_CFLAGS=$P_GTK_CFLAGS # Y_LDFLAGS=$GTKEXTRAMOD_LIBS # Y_CFLAGS=$GTKEXTRAMOD_CFLAGS GTK_VERSION_T=`$PKG_CONFIG --modversion gtk+-2.0` echo linking with gtk-$GTK_VERSION_T AC_DEFINE_UNQUOTED([GTK_VERSION],"$GTK_VERSION_T",[gtk version]) fi wi_LIB_READLINE if test "$wi_cv_lib_readline" != yes; then AC_MSG_ERROR(Cannot find readline library) fi # Checks for programs. AC_PROG_CXX AC_PROG_CXXCPP AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_YACC AM_PROG_LEX AM_PROG_LIBTOOL # Checks for libraries. AC_LANG([C++]) #AC_CHECK_LIB([gpsim], [main]) AC_CHECK_LIB([popt], [main]) #AC_CHECK_LIB([pthread], [main]) AC_CHECK_LIB([dl], [dlopen], [LIBDL="-ldl"]) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/file.h sys/ioctl.h sys/socket.h sys/time.h termios.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_HEADER_TIME AC_TYPE_SIGNAL # Checks for library functions. AC_FUNC_ALLOCA AC_PROG_GCC_TRADITIONAL #AC_FUNC_MALLOC #AC_FUNC_REALLOC AC_FUNC_SELECT_ARGTYPES AC_FUNC_STRTOD AC_CHECK_FUNCS([floor gethostbyname gethostname gettimeofday memset pow select socket sqrt strcasecmp strchr strdup strerror strncasecmp strndup strpbrk strrchr strstr strtoul]) # printf modifier define for long long as "ll" # config_win32.h.in defines this for Visual Studio stdclib as "I64" AC_DEFINE([PRINTF_INT64_MODIFIER],["ll"],[printf modifier define for long long]) # define printf modifier for GINT64 (guint64 and gint64) as "ll" on 32 bit machines and as "l" on 64 bit machines # config_win32.h.in defines this for Visual Studio stdclib as "I64" AC_CHECK_SIZEOF(long) if test "$ac_cv_sizeof_long" -ge 8; then gpsim_cv_printf_gint64_modifier=l else gpsim_cv_printf_gint64_modifier=ll fi AC_DEFINE_UNQUOTED([PRINTF_GINT64_MODIFIER],"$gpsim_cv_printf_gint64_modifier",[printf modifier define for GINT64]) AM_CFLAGS= AM_CXXFLAGS= AM_LDFLAGS= # Options for the system on which the package will run case "${host}" in *linux* ) if test "x$GCC" = "xyes"; then AM_CFLAGS="-Wall" AM_CXXFLAGS="-Wall" AM_LDFLAGS="-Wl,-warn-common -Wl,-warn-once" fi ;; *mingw* ) ;; esac CFLAGS="${CFLAGS} ${AM_CFLAGS} ${LD_SANITIZE} ${LD_ADDRESS} ${LD_UNDEFINED}" CXXFLAGS="${CXXFLAGS} ${AM_CXXFLAGS} ${LD_SANITIZE} ${LD_ADDRESS} ${LD_UNDEFINED}" LDFLAGS="${LDFLAGS} ${AM_LDFLAGS} ${LD_SANITIZE} ${LD_ADDRESS} ${LD_UNDEFINED}" # Host filesystem options case "${host}" in *mingw* | *-pc-os2_emx | *-pc-os2-emx | *djgpp* ) AC_DEFINE(HAVE_DOS_BASED_FILE_SYSTEM, 1, [Define if your host uses a DOS based file system. ]) ;; esac AC_SUBST(Y_CFLAGS) AC_SUBST(Y_LDFLAGS) AC_SUBST(X_CFLAGS) AC_SUBST(X_LDFLAGS) AC_SUBST(GTK) AC_SUBST(GDK) AC_SUBST(GLIB) AC_SUBST(LIBREADLINE) AC_SUBST(LIBDL) AC_CONFIG_FILES([Makefile cli/Makefile doc/Makefile examples/Makefile examples/modules/Makefile examples/projects/Makefile examples/12bit/Makefile examples/14bit/Makefile examples/16bit/Makefile eXdbm/Makefile gpsim/Makefile gui/Makefile modules/Makefile extras/Makefile extras/lcd/Makefile extras/dht11/Makefile extras/ds1820/Makefile extras/ds1307/Makefile extras/solar/Makefile extras/graphic_lcd/Makefile regression/Makefile src/Makefile src/dspic/Makefile xpms/Makefile gpsim.spec]) AC_OUTPUT AC_MSG_RESULT([ gpsim-$PACKAGE_VERSION is now configured for $canonical_host_type Build: $build Host: $host Source directory: $srcdir Installation prefix: $prefix C compiler: $CC $CPPFLAGS $CFLAGS C++ compiler: $CXX $CPPFLAGS $CXXFLAGS gui: $use_gui Socket interface: $use_sockets ]) gpsim-0.30.0/COPYING0000664000076400007640000004325413041763636010720 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. gpsim-0.30.0/README.EXAMPLES0000664000076400007640000000113413041763636011751 00000000000000Write me 23OCT06 - removed the contents of this because it was completely out of date. This document needs to discuss the examples/ and regression/ subdirectories. Point out how the examples subdirectory illustrates some basic module features. Point out how the regression directory while designed to preserve gpsim's integrity also illustrates a wide variety of features. In addition, users may experiment with particular regression tests to see how the simulator is supporting a particular module. Perhaps this will make it easier for users to find new bugs! (and submit patches that fix them!). gpsim-0.30.0/modules/0000775000076400007640000000000013117465765011413 500000000000000gpsim-0.30.0/modules/usart.h0000664000076400007640000000425713041763636012644 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __USART_MODULE_H__ #define __USART_MODULE_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../config.h" #ifdef HAVE_GUI #include #endif #include #include "../src/modules.h" class TXREG; class RCREG; class RxBaudRateAttribute; class TxBaudRateAttribute; class TxBuffer; class RxBuffer; class Boolean; class USART_TXPIN; class USART_RXPIN; class USART_IO; class USARTModule : public Module { public: #ifdef HAVE_GUI GtkWidget *window, *text; #endif // HAVE_GUI void CreateGraphics(void); virtual void show_tx(unsigned int data); virtual void SendByte(unsigned tx_byte); // Inheritances from the Package class virtual void create_iopin_map(); USARTModule(const char *new_name); ~USARTModule(); static Module *USART_construct(const char *new_name=NULL); virtual void new_rx_edge(unsigned int); virtual bool mGetTxByte(unsigned int &); virtual void newRxByte(unsigned int); virtual void get(char *, int len); private: RxBaudRateAttribute *m_RxBaud; TxBaudRateAttribute *m_TxBaud; Boolean *m_CRLF; Boolean *m_loop; Boolean *m_console; Boolean *m_ShowHex; TxBuffer *m_TxBuffer; RxBuffer *m_RxBuffer; RCREG *m_rcreg; TXREG *m_txreg; USART_TXPIN *txpin; USART_RXPIN *rxpin; USART_IO *cts; USART_IO *rts; unsigned char * m_TxFIFO; int m_FifoLen; int m_FifoHead; int m_FifoTail; }; #endif // __USART_MODULE_H__ gpsim-0.30.0/modules/ttl.h0000664000076400007640000000614313041763636012305 00000000000000/* Copyright (C) 2006 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __ttl_H__ #define __ttl_H__ #include "../src/modules.h" #include "../src/trigger.h" class IOPIN; class IO_bi_directional; namespace TTL { //------------------------------------------------------------------------ // // TTL devices // class TTLbase : public Module { public: TTLbase(const char *_name, const char *desc); ~TTLbase(); virtual void setClock(bool) {} virtual void setStrobe(bool) {} virtual void setEnable(bool) {} virtual void setReset(bool) {} //virtual void create_iopin_map(); virtual void update_state()=0; //GtkWidget *create_pixmap(char **pixmap_data); protected: double m_dVdd; bool m_bClock; bool m_bEnable; }; class Clock; class Strobe; class Enable; class Reset; class TTL377 : public TTLbase { public: TTL377(const char *_name); ~TTL377(); static Module *construct(const char *new_name=NULL); virtual void create_iopin_map(); virtual void setClock(bool); virtual void setEnable(bool); virtual void update_state(); protected: Clock *m_clock; Enable *m_enable; IOPIN **m_D; IO_bi_directional **m_Q; }; class TTL595 : public TTLbase, public TriggerObject { public: TTL595(const char *_name); ~TTL595(); static Module *construct(const char *new_name=NULL); virtual void create_iopin_map(); virtual void setClock(bool); virtual void setStrobe(bool); virtual void setEnable(bool); virtual void setReset(bool); virtual void update_state(); virtual void callback(); virtual void callback_print(); protected: bool m_bStrobe; Clock *m_clock; Strobe *m_strobe; Reset *m_reset; Enable *m_enable; IOPIN *m_Ds; IOPIN *m_Qs; IO_bi_directional **m_Q; unsigned short sreg; }; class TTL165 : public TTLbase { public: TTL165(const char *_name); ~TTL165(); static Module *construct(const char *new_name=NULL); virtual void create_iopin_map(); virtual void setClock(bool); virtual void setStrobe(bool); virtual void setEnable(bool); virtual void update_state(); protected: bool m_bStrobe; Clock *m_clock; Strobe *m_strobe; Enable *m_enable; IOPIN *m_Ds; IOPIN *m_Q; IOPIN *m_Qbar; IOPIN **m_D; unsigned short sreg; }; } // end of namespace TTL #endif // __ttl_H__ gpsim-0.30.0/modules/m_stimuli.cc0000664000076400007640000006045313041763636013646 00000000000000/* Copyright (C) 2006 Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* stimuli.cc This module provides extended stimuli for gpsim. pulsegen - This a stimulus designed to synthesize square waves. It has the following attributes: .set .clear .delete .period The set and clear attributes generate the edge states. For example if the module is instantiated as PG, then gpsim> PG.set = 0x1000 gpsim> PG.clear = 0x2000 generate a rising edge at cycle 0x1000 and a falling edge at cycle 0x2000. Any number of edges can be specified and they may be in any order. The delete attribute removes an edge: gpsim> PG.delete = 0x2000 # remove the edge at cycle 0x2000 The period attribute tells how many cycles there are in a rollover. If period is 0, then the pulsegen is not periodic. If there are edges beyond the period time, then those will be ignored. To be added: .start - specify a cycle to start .vhi - voltage for high drive .vlo - voltage for low drive .rth - output resitance .cth - output capacitance. pwlgen - piecewise linear generator. FileStimulus - time and values are taken from a file. .file - Name of input file. FileRecorder - time and values are written to a file. .file - name of file or pipe to write data to .in_digital - is the signal digital (true) or analog (false) */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include #include #include "../config.h" #include "../src/gpsim_time.h" #include "m_stimuli.h" #include "../src/pic-ioports.h" #include "../src/symbol.h" #include "../src/trace.h" #include "../src/processor.h" #include "../src/packages.h" namespace ExtendedStimuli { //---------------------------------------------------------------------- // Attributes // class PulseAttribute : public Integer { public: PulseAttribute(PulseGen *pParent, const char *_name, const char * desc, double voltage); virtual void set(gint64); private: PulseGen *m_pParent; double m_voltage; }; class PulsePeriodAttribute : public Integer { public: PulsePeriodAttribute(PulseGen *pParent, const char *_name, const char * desc); virtual void set(gint64); private: PulseGen *m_pParent; }; class PulseInitial : public Float { public: PulseInitial(PulseGen *pParent, const char *_name, const char * desc, double voltage); virtual void set(double); private: PulseGen *m_pParent; double m_voltage; }; //---------------------------------------------------------------------- //---------------------------------------------------------------------- PulseAttribute::PulseAttribute(PulseGen *pParent, const char *_name, const char * desc, double voltage) : Integer(_name,0,desc), m_pParent(pParent), m_voltage(voltage) { } void PulseAttribute::set(gint64 i) { Integer::set(i); ValueStimulusData vsd; vsd.time = i; vsd.v = new Float(m_voltage); m_pParent->put_data(vsd); } //---------------------------------------------------------------------- PulsePeriodAttribute::PulsePeriodAttribute(PulseGen *pParent, const char *_name, const char * desc) : Integer(_name,0,desc), m_pParent(pParent) { } void PulsePeriodAttribute::set(gint64 i) { Integer::set(i); m_pParent->update_period(); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- PulseInitial::PulseInitial(PulseGen *pParent, const char *_name, const char * desc, double voltage) : Float(_name,0,desc), m_pParent(pParent), m_voltage(voltage) { } void PulseInitial::set(double d) { Float::set(d); m_pParent->update(); } //---------------------------------------------------------------------- // StimulusBase //---------------------------------------------------------------------- StimulusBase::StimulusBase(const char *_name, const char *_desc) : Module(_name,_desc) { // The I/O pin m_pin = new IO_bi_directional("pin"); m_pin->set_is_analog(true); m_pin->set_Zth(0.01); m_pin->update_direction(IOPIN::DIR_OUTPUT, true); addSymbol(m_pin); } StimulusBase::~StimulusBase() { removeSymbol(m_pin); } void StimulusBase::putState(double new_Vth) { m_pin->putState(new_Vth); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- void StimulusBase::callback_print() { printf("ExtendedStimulus:%s CallBack ID %d\n",name().c_str(),CallBackID); } void StimulusBase::create_iopin_map() { create_pkg(1); assign_pin(1, m_pin); } //---------------------------------------------------------------------- // FileGen Module //---------------------------------------------------------------------- //FileGen::FileGen //---------------------------------------------------------------------- // PulseGen Module //---------------------------------------------------------------------- Module *PulseGen::construct(const char *new_name) { PulseGen *pPulseGen = new PulseGen(new_name); return pPulseGen; } //---------------------------------------------------------------------- //---------------------------------------------------------------------- PulseGen::PulseGen(const char *_name) : StimulusBase(_name, "\ Pulse Generator\n\ Attributes:\n\ .set - time when the pulse will drive high\n\ .clear - time when the pulse will drive low\n\ .period - time the pulse stream is repeated\n\ .initial - initial pin voltage\n\ "), m_future_cycle(0), m_start_cycle(0) { // Attributes for the pulse generator. m_set = new PulseAttribute(this, "set","r/w cycle time when ouput will be driven high", 5.0); m_clear = new PulseAttribute(this, "clear","r/w cycle time when ouput will be driven low",0.0); m_period = new PulsePeriodAttribute(this, "period","r/w cycle time to specify pulse stream repeat rate"); m_init = new PulseInitial(this, "initial","initial I/O pin voltage", 5.0); addSymbol(m_set); addSymbol(m_clear); addSymbol(m_period); addSymbol(m_init); sample_iterator = samples.end(); create_iopin_map(); } PulseGen::~PulseGen() { removeSymbol(m_set); removeSymbol(m_clear); removeSymbol(m_period); removeSymbol(m_init); delete m_set; delete m_clear; delete m_period; delete m_init; } //---------------------------------------------------------------------- //---------------------------------------------------------------------- void PulseGen::callback() { //guint64 currCycle = get_cycles().get(); if (sample_iterator != samples.end()) { m_future_cycle = 0; double d; (*sample_iterator).v->get(d); m_pin->putState(d > 2.5); ++sample_iterator; // If we reached the end of a non-periodic waveform // then we're done. if (sample_iterator == samples.end() && m_period->getVal() == 0) return; // If this is a periodic pulse stream and either // a) we reached the end of the sequence // b) we have more data but it exceeds the period // then // start the stream over. if (m_period->getVal() && ((sample_iterator == samples.end() || (*sample_iterator).time > m_period->getVal()))) { sample_iterator = samples.begin(); m_start_cycle += m_period->getVal(); } m_future_cycle = m_start_cycle + (*sample_iterator).time; get_cycles().set_break(m_future_cycle, this); } } //------------------------------------------------------------ // Set a callback break point at the cycle specified // Point the sample_iterator to the appropiate sample void PulseGen::setBreak(guint64 next_cycle,list::iterator si) { if (m_future_cycle) { get_cycles().clear_break(this); m_future_cycle = 0; sample_iterator = samples.end(); } if (next_cycle > get_cycles().get()) { get_cycles().set_break(next_cycle, this); m_future_cycle = next_cycle; sample_iterator = si; } } //------------------------------------------------------------ // cycleIsInFuture - find_if helper predicate. // // The stl find_if() algorithm takes a pointer to a function whose // job is to compare a list element to a reference value. Stroustrop // calls this function a predicate. static gint64 current_cycle=0; static bool cycleIsInFuture(ValueStimulusData &data_point) { return data_point.time > current_cycle; } void PulseGen::update_period() { // If the period is 0 then force the start to 0. if (m_period->getVal() == 0) m_start_cycle = 0; // Find the next sample that will generate an edge. list::iterator si; current_cycle = get_cycles().get() - m_start_cycle; si = find_if(samples.begin(), samples.end(), cycleIsInFuture); if (si == samples.end() && m_period->getVal()) setBreak(m_start_cycle + m_period->getVal(), samples.begin()); } void PulseGen::update() { if (samples.empty()) { double d; m_init->get(d); m_pin->putState(d > 2.5); return; // There are no samples } current_cycle = get_cycles().get(); list::iterator si; if (current_cycle == 0) { // The simulation hasn't started yet. // Point to the second sample si = samples.begin(); ++si; // If the next sample *is* the second one then we've been here before // (and that means we've already handled the first sample) if (sample_iterator == si) return; if (si == samples.end()) { si = samples.begin(); sample_iterator = si; double d; (*si).v->get(d); m_pin->putState(d > 2.5); } sample_iterator = si; --si; double d; (*si).v->get(d); m_pin->putState(d > 2.5); setBreak((*sample_iterator).time, sample_iterator); return; } current_cycle -= m_start_cycle; si = find_if(samples.begin(), samples.end(), cycleIsInFuture); if (si == sample_iterator) return; setBreak(m_start_cycle + (*si).time, si); } static bool compare_data_point(const ValueStimulusData &data_point1, const ValueStimulusData &data_point2) { return (data_point1.time < data_point2.time); } void PulseGen::put_data(ValueStimulusData &data_point) { list::iterator si; si = find(samples.begin(), samples.end(), data_point); if (si == samples.end()) { samples.push_back(data_point); samples.sort(compare_data_point); } else { delete (*si).v; (*si).v = data_point.v; } update(); } string PulseGen::toString() { ostringstream sOut; sOut << "pulsegen toString method" << hex; list::iterator si; if (m_period->getVal()) sOut << endl <<"period 0x" << m_period->getVal(); if (m_start_cycle) sOut << endl << "start 0x" << m_start_cycle; si = samples.begin(); while (si != samples.end()) { sOut << endl; double d; (*si).v->get(d); sOut << " {0x" << (*si).time << ',' << d << '}'; if (si == sample_iterator) sOut << " <-- Next at cycle 0x" << (m_start_cycle + (*si).time); ++si; } sOut << ends; return sOut.str(); } //---------------------------------------------------------------------- // File Stimulus and Recorder use this attribute //---------------------------------------------------------------------- template FileNameAttribute::FileNameAttribute(T *parent) : String("file", "", "Name of a file or pipe"), m_Parent(parent) { parent->addSymbol(this); } template void FileNameAttribute::update() { m_Parent->newFile(); } //---------------------------------------------------------------------- // File Stimulus //---------------------------------------------------------------------- Module *FileStimulus::construct(const char *new_name) { FileStimulus *pFileStimulus = new FileStimulus(new_name); return pFileStimulus; } FileStimulus::FileStimulus(const char *_name) : StimulusBase(_name, "\ File Stimulus\n\ Attributes:\n\ .file - name of file or pipe supplying data\n\ "), m_future_cycle(0), m_fp(NULL) { // Attributes for the pulse generator. m_filename = new FileNameAttribute(this); create_iopin_map(); if (verbose) cout << description() << endl; } void FileStimulus::newFile() { if (m_future_cycle) { get_cycles().clear_break(this); m_future_cycle = 0; } if (m_fp) delete m_fp; m_fp = NULL; char fname[20] = ""; m_filename->get(fname, 20); if (fname[0]) { m_fp = new ifstream(fname); if (m_fp->fail()) { printf( "Warning can't open Stimulus file %s\n", fname); delete m_fp; m_fp = NULL; return; } } // Set the first breakpoint parseLine(true); } void FileStimulus::parseLine(bool first) { if (!m_fp || m_fp->eof()) return; m_fp->precision(16); *m_fp >> dec >> m_future_cycle >> m_future_value; if (m_fp->eof()) return; if (verbose) { cout << this->name() << " read " << dec << m_future_value << " @ 0x" << hex << m_future_cycle << endl; } if (m_future_cycle > get_cycles().get()) get_cycles().set_break(m_future_cycle, this); else if (first) { // Always set the reset value putState(m_future_value); // Set the next breakpoint parseLine(); } else { if (verbose) cout << this->name() << " WARNING: Ignoring past stimulus " << dec << m_future_value << " @ 0x" << hex << m_future_cycle << endl; // Do not set this value, it could have a good or a bad side effect. // Set the next breakpoint parseLine(); } } void FileStimulus::callback() { // Remove this breakpoint get_cycles().clear_break(this); m_future_cycle = 0; // Set the new value putState(m_future_value); // Set the next breakpoint parseLine(); } //---------------------------------------------------------------------- // File Recorder //---------------------------------------------------------------------- class Recorder_Input : public IOPIN { public: Recorder_Input(const char *n, FileRecorder *pParent); virtual void setDrivenState(bool); virtual void set_nodeVoltage(double); private: bool is_digital(); FileRecorder *m_pParent; BooleanAttribute *m_digitalattribute; }; Recorder_Input::Recorder_Input(const char *n, FileRecorder *pParent) : IOPIN(n), m_pParent(pParent) { m_digitalattribute = new BooleanAttribute("digital", false, "Is the signal digital (true) or analog (false)"); pParent->addSymbol(m_digitalattribute); } void Recorder_Input::setDrivenState(bool new_dstate) { IOPIN::setDrivenState(new_dstate); if (is_digital()) m_pParent->record(new_dstate); } void Recorder_Input::set_nodeVoltage(double v) { IOPIN::set_nodeVoltage(v); if (is_digital()) m_pParent->record(v); } bool Recorder_Input::is_digital() { bool value; m_digitalattribute->get(value); return value; } //------------------------------------------------------------------------ Module *FileRecorder::construct(const char *new_name) { FileRecorder *pFileRecorder = new FileRecorder(new_name); return pFileRecorder; } FileRecorder::FileRecorder(const char *_name) : Module(_name, "\ File Recorder\n\ Attributes:\n\ .file - name of file or pipe to write data to\n\ .digital - is the signal digital (true) or analog (false)\n\ "), m_fp(NULL), m_lastval(99.0) { create_pkg(1); // Position pin on left side of package package->set_pin_position(1,0.5); m_pin = new Recorder_Input("pin", this); assign_pin(1, m_pin); addSymbol(m_pin); // Attribute for the recorder. m_filename = new FileNameAttribute(this); if (verbose) cout << description() << endl; } FileRecorder::~FileRecorder() { removeSymbol(m_pin); if (m_fp) delete m_fp; } // Invoked when the FileNameAttribute is updated. void FileRecorder::newFile() { if (m_fp) delete m_fp; m_fp = NULL; char fname[20] = ""; m_filename->get(fname, 20); if (fname[0]) m_fp = new ofstream(fname); } void FileRecorder::record(bool NewVal) { unsigned newvalue = (NewVal? 1: 0); if (newvalue == m_lastval) return; if (m_fp) { gint64 current_cycle = get_cycles().get(); *m_fp << dec << current_cycle << ' ' << newvalue << endl; if (verbose) { cout << this->name() << " recording " << newvalue << " @ 0x" << hex << current_cycle << endl; } m_lastval = newvalue; } } void FileRecorder::record(double NewVal) { if (NewVal == m_lastval) return; if (m_fp) { gint64 current_cycle = get_cycles().get(); m_fp->precision(16); *m_fp << dec << current_cycle << ' ' << NewVal << endl; if (verbose) { cout << this->name() << " recording " << NewVal << " @ 0x" << hex << current_cycle << endl; } m_lastval = NewVal; } } //---------------------------------------------------------------------- //---------------------------------------------------------------------- class RegisterAddressAttribute : public Integer { public: RegisterAddressAttribute(Register *pReg, const char *_name, const char * desc); virtual void set(gint64); private: Register *m_replaced; const unsigned int InvalidAddress; }; RegisterAddressAttribute::RegisterAddressAttribute(Register *pReg,const char *_name, const char * desc) : Integer(_name,0xffffffff,desc), m_replaced(pReg), InvalidAddress(0xffffffff) { m_replaced->address = InvalidAddress; } void RegisterAddressAttribute::set(gint64 i) { Processor *pcpu = get_active_cpu(); if (pcpu && m_replaced) { if (m_replaced->address != InvalidAddress) pcpu->rma.removeRegister(m_replaced->address,m_replaced); m_replaced->set_cpu(pcpu); m_replaced->address = i & 0xffffffff; if (!pcpu->rma.insertRegister(m_replaced->address,m_replaced)) m_replaced->address = InvalidAddress; gint64 insertAddress = m_replaced->address; Integer::set(insertAddress); } } //---------------------------------------------------------------------- //---------------------------------------------------------------------- static void buildTraceType(Register *pReg, unsigned int baseType) { RegisterValue rv; rv = RegisterValue(baseType + (0<<8), baseType + (1<<8)); pReg->set_write_trace(rv); rv = RegisterValue(baseType + (2<<8), baseType + (3<<8)); pReg->set_read_trace(rv); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- class PortPullupRegister : public sfr_register { public: PortPullupRegister(Module *mod, const char *_name, PicPortRegister *_port, unsigned int enableMask); ~PortPullupRegister() {} virtual void put(unsigned int new_value); private: PicPortRegister *m_port; unsigned int m_EnableMask; }; PortPullupRegister::PortPullupRegister(Module *mod, const char *_name, PicPortRegister *_port, unsigned int enableMask) : sfr_register(mod ,_name,"Port Pullup"),m_port(_port),m_EnableMask(enableMask) { new_name(_name); value = RegisterValue(0,~enableMask); } void PortPullupRegister::put(unsigned int new_value) { get_trace().raw(write_trace.get() | value.data); unsigned int diff = (value.data ^ new_value) & m_EnableMask; value.data = new_value; if (diff && m_port) { for (unsigned int i=1,j=0; diff && i; i<<=1, j++) if (diff & i) m_port->getPin(j)->update_pullup(((value.data & i) !=0) ? '1':'0',true); m_port->updatePort(); } } //---------------------------------------------------------------------- //---------------------------------------------------------------------- Module *PortStimulus::construct8(const char *new_name) { return new PortStimulus(new_name,8); } Module *PortStimulus::construct16(const char *new_name) { return new PortStimulus(new_name,16); } Module *PortStimulus::construct32(const char *new_name) { return new PortStimulus(new_name,32); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- PortStimulus::PortStimulus(const char *_name, int nPins) : Module(_name, "\ Port Stimulus\n\ Attributes:\n\ .port - port name\n\ .tris - tris name\n\ .lat - latch name\n\ .pullup - pullup name\n\ "), m_nPins(nPins) { mPort = new PicPortRegister((Processor *)this,"port","",m_nPins,(1<type()); buildTraceType(mTris, mMTT->type() + (4<<16)); buildTraceType(mLatch, mMTT->type() + (8<<16)); buildTraceType(mPullup, mMTT->type() + (12<<16)); create_iopin_map(); } PortStimulus::~PortStimulus() { printf("~PortStimulus\n"); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- void PortStimulus::callback_print() { printf("PortStimulus:%s CallBack ID %d\n",name().c_str(),CallBackID); } void PortStimulus::create_iopin_map() { create_pkg(m_nPins); char pinNumber[3]; for (int i=0; iupdate_direction(IOPIN::DIR_OUTPUT,true); assign_pin(i+1, mPort->addPin(this, ppin,i)); } } } // end of namespace ExtendedStimuli gpsim-0.30.0/modules/usart.cc0000664000076400007640000006546413115240023012767 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* usart.cc This is gpsim's universal synchronous/asynchronous receiver/transceiver. Features: 8 or 9 bit receiver and transmitter 0 or 1 start bits 0 or 1 stop bits 0 or 1 parity bits and even/odd selectable variable sized transmit and receive buffers */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #define DEFAULT_BAUD 9600 #include #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #endif #include "usart.h" #include #include "../src/value.h" #include "../src/modules.h" #include "../src/stimuli.h" #include "../src/uart.h" //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("module-%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif #define HAVE_TXFIFO static bool bIsLow(char state) { return state=='0' || state=='w'; } static bool bIsHigh(char state) { return state=='1' || state=='W'; } /********************************************************************************** gpsim's USART module The USART module is a general purpose universal synchronous/asynchronous serial receiver and transmitter. In other words, it's a serial port. It's purpose is to provide a tool to assist in the debugging of serial interfaces. Users can load this module and tie it to their receive and transmit pins of their simulated PIC's. Then experiments can be conducted on things like baud rate variation, transmit inundation, protocol development, etc. The design of this dynamically loadable module mimics the USART peripheral found in PIC microcontrollers. In fact, the USARTModule class is derived from the USART_MODULE class that is instantiated by simulated PIC's. There are some notable differences, however. For example, the registers from which the usart is constructed behave differently. Most notably, the spbrg (serial port baud rate generator) is not confined to the limited number of discrete baud rates. **********************************************************************************/ //-------------------------------------------------------------- // // class USART_RXPIN : public IO_bi_directional_pu { public: USARTModule *usart; USART_RXPIN (USARTModule *_usart, const char *opt_name=NULL) : IO_bi_directional_pu(opt_name) { usart = _usart; // Let the pin think it's in the high state. If this is wrong, // then the I/O pin driving it will correct it. (Starting off // low prevents the start bit from being captured.) // Note, may want to add a flag that indicates if the pin // has ever been driven at all. This way, we can capture the // first edge. Or we could add another parameter to the constructor. bDrivenState = true; update_direction(0,true); // Make the RX pin an input. bPullUp = true; Zpullup = 10e3; }; void setDrivenState(bool new_dstate) { bool diff = new_dstate ^ bDrivenState; Dprintf((" usart module rxpin new state=%d\n",new_dstate)); if( usart && diff ) { bDrivenState = new_dstate; IOPIN::setDrivenState(new_dstate); usart->new_rx_edge(bDrivenState); } } }; //-------------------------------------------------------------- // // class USART_TXPIN : public IO_bi_directional { public: USARTModule *usart; USART_TXPIN (USARTModule *_usart, const char *opt_name=NULL) : IO_bi_directional(opt_name) { usart = _usart; bDrivingState = true; update_direction(1,true); // Make the TX pin an output. }; }; //================================================================= // // TXREG // // Create a transmit register based upon the transmit register // defined in the main gpsim code. // class TXREG : public TriggerObject { private: bool empty_flag; double baud; guint64 time_per_bit; guint64 last_time; guint64 start_time; guint64 future_time; guint64 start_bit_time; unsigned int start_bit_index; bool last_bit; int bits_per_byte; double stop_bits; guint64 time_per_packet; unsigned int txr; // Transmit register int bit_count; // used while transmitting. unsigned int tx_byte; enum TX_STATES { TX_TRANSMITTING } transmit_state; bool use_parity; bool parity; // 0 = even, 1 = odd public: USART_TXPIN *txpin; USARTModule *usart; virtual bool is_empty() { return empty_flag;}; virtual void empty() {empty_flag = 1;}; virtual void full() {empty_flag = 0;}; virtual void assign_pir_set(PIR_SET *new_pir_set){}; TXREG(void) { txpin = 0; usart = 0; bits_per_byte = 8; stop_bits = 1; use_parity = 0; set_baud_rate(DEFAULT_BAUD); tx_byte = '0'; update_packet_time(); empty(); } void update_packet_time(void) { if(baud <= 0.0) baud = 9600; //arbitrary // Calculate the total time to send a "packet", i.e. start bit, data, parity, and stop // The stop bit time is included in the total packet time if(get_active_cpu()) { time_per_packet = (guint64)( get_cycles().instruction_cps() * ( (1.0 + // start bit bits_per_byte + // data bits stop_bits + // stop bit(s) use_parity) // /baud)); time_per_bit = (guint64)(get_cycles().instruction_cps() / baud); } else time_per_packet = time_per_bit = 0; //cout << "update_packet_time ==> 0x" << hex<< time_per_packet << "\n"; } void set_bits_per_byte(int num_bits) { bits_per_byte = num_bits; update_packet_time(); } void set_baud_rate(double new_baud) { baud = new_baud; update_packet_time(); }; void set_stop_bits(double new_stop_bits) { stop_bits = new_stop_bits; } void set_noparity(void) { use_parity = 0; } void set_parity(bool new_parity) { use_parity = 1; parity = new_parity; } virtual void callback(void) { Dprintf((" usart module TXREG time:0x%" PRINTF_GINT64_MODIFIER "x=%" PRINTF_GINT64_MODIFIER "d txr=0x%x bit_count=%d\n", get_cycles().get(), get_cycles().get(), txr, bit_count)); last_time = get_cycles().get(); start_time = last_time; if(txpin) { txpin->putState((txr & 1) ? true : false); } if(bit_count) { txr >>= 1; bit_count--; update_packet_time(); future_time = last_time + time_per_bit; get_cycles().set_break(future_time, this); } else { // We've sent the whole byte. /* output data from buffer if configured */ #ifdef HAVE_TXFIFO if(usart && usart->mGetTxByte(tx_byte)) mSendByte(tx_byte); else #endif empty(); } } void mSendByte(unsigned _tx_byte) { if(0) { cout << "\n\n"; cout << "TXREG::" << __FUNCTION__ << "\n"; cout << "\n\n"; } mBuildTXpacket(_tx_byte); last_time = get_cycles().get(); update_packet_time(); future_time = last_time + time_per_bit; get_cycles().set_break(future_time, this); full(); } private: void mBuildTXpacket(unsigned int tb) { tx_byte = tb & ((1< 0x" << hex<< time_per_packet << "\n"; } void set_baud_rate(double new_baud) { baud = new_baud; update_packet_time(); }; void set_stop_bits(double new_stop_bits) { stop_bits = new_stop_bits; } void set_noparity(void) { use_parity = 0; } void set_parity(bool new_parity) { use_parity = 1; parity = new_parity; } virtual void callback(); void start(); void new_rx_edge(bool bit); private: USARTModule *m_usart; char m_cLastRXState; unsigned int start_bit_event; guint32 error_flag; guint64 time_per_bit; guint64 start_time; guint64 future_time; // Configuration information int bits_per_byte; double stop_bits; bool use_parity; bool parity; // 0 = even, 1 = odd double baud; unsigned int rx_byte; int rx_count; guint64 time_per_packet; bool autobaud; IOPIN *rcpin; unsigned int *fifo; }; //------------------------------------------------------------------------ RCREG::RCREG(USARTModule *pUsart) : m_usart(pUsart), m_cLastRXState('?'), start_bit_event(0), rcpin(0) { assert(m_usart); receive_state = RS_WAITING_FOR_START; autobaud = false; baud = DEFAULT_BAUD; set_stop_bits(0.9); set_noparity(); set_bits_per_byte(8); } //------------------------------------------------------------------------ void RCREG::callback() { Dprintf((" usart module RCREG time:0x%" PRINTF_GINT64_MODIFIER "x=%" PRINTF_GINT64_MODIFIER "d state=0x%x\n", get_cycles().get(), get_cycles().get(), receive_state)); switch(receive_state) { case RS_WAITING_FOR_START: Dprintf(("waiting for start\n")); break; case RS_START_BIT: // should now be in middle of start bit if (bIsLow(m_cLastRXState)) { receive_state = RS_RECEIVING; rx_count = bits_per_byte + use_parity; rx_byte = 0; future_time = get_cycles().get() + time_per_bit; if(!autobaud) get_cycles().set_break(future_time, this); } else // Not valid start bit { receive_state = RS_WAITING_FOR_START; } break; case RS_RECEIVING: if (rx_count--) { rx_byte = (rx_byte >> 1) | (bIsHigh(m_cLastRXState) ? 1<<(bits_per_byte-1) : 0); future_time = get_cycles().get() + time_per_bit; if(!autobaud) get_cycles().set_break(future_time, this); } else if (bIsHigh(m_cLastRXState)) // on stop bit { m_usart->newRxByte(rx_byte); m_usart->show_tx(rx_byte); receive_state = RS_WAITING_FOR_START; } else { cout << "USART module RX overrun error\n"; receive_state = RS_WAITING_FOR_START; } break; case RS_STOPPED: receive_state = RS_WAITING_FOR_START; cout << "received a stop bit\n"; break; default: break; } }; //------------------------------------------------------------------------ void RCREG::start() { receive_state = RS_START_BIT; update_packet_time(); future_time = get_cycles().get() + time_per_bit/2; if(!autobaud) { get_cycles().set_break(future_time, this); } Dprintf((" usart module RCREG current cycle=0x%" PRINTF_GINT64_MODIFIER "x future_cycle=0x%" PRINTF_GINT64_MODIFIER "x\n", get_cycles().get(),future_time)); } //------------------------------------------------------------------------ // new_rx_edge(bool bit) // // This routine get's called when there's a change on the // RX line. The time the edge occurred is stored into an // event buffer. No effort is made here to decode a byte; // instead, decoding will take place in callback(). void RCREG::new_rx_edge(bool bit) { // Save the event state char currentRXState = rxpin->getBitChar(); if (currentRXState != m_cLastRXState) { m_cLastRXState = currentRXState; switch(receive_state) { case RS_WAITING_FOR_START: if(bIsLow(currentRXState)) { start(); Dprintf(("Start bit at t=0x%" PRINTF_GINT64_MODIFIER "x\n",get_cycles().get())); } break; case RS_RECEIVING: break; case RS_OVERRUN: break; default: break; } /**/ } } //------------------------------------------------------------------------ class USART_IO : public IO_bi_directional_pu { public: USARTModule *usart; USART_IO(void) { cout << "USART_IO constructor - do nothing\n"; } USART_IO ( USARTModule *_usart, unsigned int b, const char *opt_name ) : IO_bi_directional_pu(opt_name) { usart = _usart; bDrivenState = true; update_direction(0,true); // Make the RX pin an input. bPullUp = true; Zpullup = 10e3; } void setDrivenState(bool new_dstate) { bool diff = new_dstate ^ bDrivenState; // Dprintf((" usart module %s new state=%d\n",name(),new_dstate)); if( usart && diff ) { bDrivenState = new_dstate; IOPIN::setDrivenState(new_dstate); } } }; // // USART attributes // // Provide attributes that allow the user to dynamically // configure the USART module // // Attribute Default // Name Value // ------------------- // txbaud 9600 // rxbaud 9600 // txreg -- // rxreg -- // parity 0 // start_bits 1 // stop_bits 1 // class RxBaudRateAttribute : public Integer { public: RCREG *rcreg; RxBaudRateAttribute(RCREG *prcreg) : Integer("rxbaud",DEFAULT_BAUD,"USART Module Receiver baud rate"), rcreg(prcreg) { assert(rcreg); } void set(Value *v) { Integer::set(v); gint64 b; get(b); rcreg->set_baud_rate(b); cout << "Setting Rx baud rate attribute to " << dec << b << "\n"; }; virtual string toString() { return Integer::toString("%" PRINTF_INT64_MODIFIER "d"); } }; class TxBaudRateAttribute : public Integer { public: TXREG *txreg; TxBaudRateAttribute(TXREG *ptxreg) : Integer("txbaud",DEFAULT_BAUD,"USART Module Transmitter baud rate"), txreg(ptxreg) { assert(txreg); } void set(Value *v) { Integer::set(v); gint64 b; get(b); txreg->set_baud_rate(b); cout << "Setting Tx baud rate attribute to " << dec << b << "\n"; } virtual string toString() { return Integer::toString("%" PRINTF_INT64_MODIFIER "d"); } }; class TxBuffer : public Integer { USARTModule *usart; public: TxBuffer(USARTModule *_usart) : Integer("tx",0,"UART Transmit Register"),usart(_usart) { } virtual void set(gint64 i) { i &= 0xff; //cout << name() << " sending byte 0x" << hex << i << endl; if(usart) usart->SendByte(i); Integer::set(i); } virtual string toString() { return Integer::toString("%" PRINTF_INT64_MODIFIER "d"); } }; class RxBuffer : public Integer { RCREG *rcreg; public: RxBuffer(RCREG *_rcreg) : Integer("rx",0,"UART Receive Register"),rcreg(_rcreg) { } virtual void set(gint64 i) { cout << "Receive buffer is read only\n"; } virtual string toString() { return Integer::toString("%" PRINTF_INT64_MODIFIER "d"); } void newByte(gint64 b) { Dprintf((" RxBuffer received a byte: 0x%02x=%d=%c",(int)b, (int)b, (int)b)); Integer::set(b); } }; //-------------------------------------------------------------- void USARTModule::new_rx_edge(unsigned int bit) { if(m_rcreg) m_rcreg->new_rx_edge(bit ? true : false); } //-------------------------------------------------------------- void USARTModule::newRxByte(unsigned int aByte) { m_RxBuffer->newByte(aByte); if(m_loop->getVal()) { SendByte(aByte); } } //-------------------------------------------------------------- #ifndef HAVE_TXFIFO static unsigned int _tx_index=0; static unsigned char Test_Hello[] = { 0x1b,0xff, 0x87,0x05, 'H', 'E', 'L', 'L', 'O', 0x17, 0x55 }; bool USARTModule::mGetTxByte(unsigned int &aByte) { if (_tx_index > sizeof(Test_Hello)) return false; aByte = Test_Hello[_tx_index++]; return true; } #else bool USARTModule::mGetTxByte(unsigned int &aByte) { if ( m_FifoHead == m_FifoTail ) return false; aByte = m_TxFIFO[m_FifoTail]; if ( m_FifoTail < m_FifoLen-1 ) m_FifoTail++; else m_FifoTail = 0; return true; } #endif //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. #define USART_PKG_TXPIN 1 #define USART_PKG_RXPIN 2 #define USART_PKG_CTSPIN 3 #define USART_PKG_RTXPIN 4 void USARTModule::create_iopin_map(void) { // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // // USART I/O pins: // // 1 - Tx - Transmit // 2 - Rx - Receive // 3 - CTS - Clear To Send // 4 - RTS - Request To Send create_pkg(4); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created.The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. txpin = new USART_TXPIN(this, "TXPIN"); rxpin = new USART_RXPIN(this, "RXPIN"); cts = new USART_IO(this, 2, "CTS"); rts = new USART_IO(this, 3, "RTS"); addSymbol(rxpin); addSymbol(txpin); addSymbol(cts); addSymbol(rts); assign_pin(1, txpin); assign_pin(2, rxpin); assign_pin(3, cts); assign_pin(4, rts); // Complete the usart initialization m_txreg->txpin = txpin; m_txreg->usart = this; // Point back to the module m_rcreg->rxpin = rxpin; } //-------------------------------------------------------------- void USARTModule::get(char *cP, int len) { cout << "USARTModule::get(char *cP, int len)\n"; } //-------------------------------------------------------------- Module * USARTModule::USART_construct(const char *_new_name) { Dprintf(("USART construct\n")); USARTModule *um = new USARTModule( (_new_name ?_new_name:"USART")); um->create_iopin_map(); return um; } USARTModule::USARTModule(const char *_name) : Module(_name, "USART") { #ifdef HAVE_TXFIFO m_TxFIFO = new unsigned char[64]; m_FifoLen = 64; m_FifoHead = m_FifoTail = 0; #endif txpin = 0; rxpin = 0; cts = 0; rts = 0; m_rcreg = new RCREG(this); m_txreg = new TXREG; m_RxBaud = new RxBaudRateAttribute(m_rcreg); addSymbol(m_RxBaud); m_TxBaud = new TxBaudRateAttribute(m_txreg); addSymbol(m_TxBaud); m_RxBuffer = new RxBuffer(m_rcreg); addSymbol(m_RxBuffer); m_TxBuffer = new TxBuffer(this); addSymbol(m_TxBuffer); m_CRLF = new Boolean("crlf", true, "if true, carriage return and linefeeds generate new lines in the terminal"); addSymbol(m_CRLF); m_ShowHex = new Boolean("hex", false, "if true, display received data in hex - i.e. assume binary"); addSymbol(m_ShowHex); m_loop = new Boolean("loop", false, "if true, received characters looped back to transmit"); addSymbol(m_loop); m_console = new Boolean("console", false, "if true, display received character to the terminal window"); addSymbol(m_console); CreateGraphics(); assert(m_rcreg); assert(m_txreg); assert(m_RxBaud); assert(m_TxBaud); assert(m_RxBuffer); assert(m_TxBuffer); } USARTModule::~USARTModule() { #ifdef HAVE_GUI if(window) gtk_widget_destroy(window); #endif #ifdef HAVE_TXFIFO delete [] m_TxFIFO; #endif removeSymbol(m_RxBaud); removeSymbol(m_TxBaud); removeSymbol(m_RxBuffer); removeSymbol(m_TxBuffer); removeSymbol(m_CRLF); removeSymbol(m_ShowHex); removeSymbol(m_loop); removeSymbol(m_console); removeSymbol(txpin); removeSymbol(rxpin); removeSymbol(cts); removeSymbol(rts); delete m_rcreg; delete m_txreg; delete m_RxBaud; delete m_TxBaud; delete m_RxBuffer; delete m_TxBuffer; delete m_CRLF; delete m_ShowHex; delete m_loop; delete m_console; /* delete txpin; delete rxpin; delete cts; delete rts; */ } //-------------------------------------------------------------- void USARTModule::SendByte(unsigned tx_byte) { #ifdef HAVE_TXFIFO Dprintf (( "SendByte <%02X> : head=%d, tail=%d, txreg=%p\n", tx_byte, m_FifoHead, m_FifoTail, m_txreg )) if ( m_FifoHead != m_FifoTail || !m_txreg || !m_txreg->is_empty() ) { int newHead; m_TxFIFO[m_FifoHead] = tx_byte; newHead = m_FifoHead+1; if ( newHead >= m_FifoLen ) newHead = 0; if ( newHead == m_FifoTail ) { int newLen = m_FifoLen + 32; unsigned char * newFIFO; newFIFO = new unsigned char[newLen]; int oldTail = m_FifoTail; int dIdx = 0; int sIdx; for ( sIdx = oldTail; sIdx < m_FifoLen; ) newFIFO[dIdx++] = m_TxFIFO[sIdx++]; for ( sIdx = 0; sIdx < newHead; ) newFIFO[dIdx++] = m_TxFIFO[sIdx++]; unsigned char * oldFIFO = m_TxFIFO; m_TxFIFO = newFIFO; m_FifoTail -= oldTail; m_FifoHead = dIdx; m_FifoLen = newLen; delete oldFIFO; } else m_FifoHead = newHead; //cout << "Byte added to queue\n"; } else #endif if (m_txreg) m_txreg->mSendByte(tx_byte); }; #ifdef HAVE_GUI static bool ctl = false; // true when ctrl key is down static gint key_press(GtkWidget *widget, GdkEventKey *key, gpointer data) { unsigned int c = key->keyval; g_signal_stop_emission_by_name (widget, "key_press_event"); if(c == 0xffe3 || c == 0xffe4) // key is left or right ctrl { ctl = true; return(1); } if (ctl && c < 0xff00) // build control character { Dprintf(("CTL 0x%02x\n", c)); c &= 0x1f; } if ( c < 0xff20) // send character to usart { c &= 0xff; ((USARTModule *)data)->USARTModule::SendByte(c); Dprintf(("Send %c 0x%x\n", c,c)); } else { Dprintf(( "0x%02x\n", c)); } return(1); } static gint key_release(GtkWidget *widget, GdkEventKey *key, gpointer data) { unsigned int c = key->keyval; if(c == 0xffe3 || c == 0xffe4) // Capture release of ctrl key { ctl = false; } return(1); } #endif //HAVE_GUI // Display character from usart on GUI text window void USARTModule::show_tx(unsigned int data) { data &= 0xff; bool IsAscii = true; if ( m_ShowHex->getVal() ) IsAscii = false; else if ( (isascii(data) && isprint(data)) ) IsAscii = true; else if (m_CRLF->getVal() && ('\n' == data || '\r' == data)) IsAscii = true; else IsAscii = false; if(m_console->getVal()) { if ( IsAscii ) putchar(data); else printf("<%02X>", data); } #ifdef HAVE_GUI if(get_interface().bUsingGUI()) { GtkTextBuffer *buff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); GtkTextIter iter; GtkTextMark *insert_mark; gtk_text_buffer_get_end_iter(buff, &iter); if (IsAscii) { char ch = data; gtk_text_buffer_insert(buff, &iter, &ch, 1); } else { char hex[5]; sprintf (hex, "<%02X>", data); gtk_text_buffer_insert(buff, &iter, hex, 4); } /* get end iter again */ gtk_text_buffer_get_end_iter (buff, &iter); /* get the current ( cursor )mark name */ insert_mark = gtk_text_buffer_get_insert (buff); /* move mark and selection bound to the end */ gtk_text_buffer_place_cursor(buff, &iter); /* scroll to the end view */ gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (text), insert_mark, 0.0, TRUE, 0.0, 1.0); } #endif //HAVE_GUI } // Create a GUI text window void USARTModule::CreateGraphics() { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) { window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "USART"); gtk_window_set_default_size (GTK_WINDOW (window), 300, 100); GtkWidget *pSW = gtk_scrolled_window_new (0,0); gtk_container_add (GTK_CONTAINER (window), pSW); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pSW), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); text = gtk_text_view_new (); gtk_text_view_set_editable (GTK_TEXT_VIEW (text), TRUE); gtk_container_add (GTK_CONTAINER (pSW), text); /* Change default font throughout the widget */ PangoFontDescription *font_desc; font_desc = pango_font_description_from_string ("Courier 10"); gtk_widget_modify_font (text, font_desc); pango_font_description_free (font_desc); gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK); g_signal_connect(text, "key_press_event", G_CALLBACK(key_press), this); g_signal_connect(text, "key_release_event", G_CALLBACK(key_release), this); g_signal_connect (window, "destroy", G_CALLBACK(gtk_widget_destroy), window); gtk_widget_show_all(window); } else { window = 0; text = 0; } #endif // HAVE_GUI } gpsim-0.30.0/modules/i2c-eeprom.cc0000664000076400007640000001047213041763636013602 00000000000000/* Copyright (C) 2006 T. Scott Dattalo Copyright (C) 2006 Roy R Rankin This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #endif class Processor; #include "../src/i2c-ee.h" #include "i2c-eeprom.h" #include "../src/stimuli.h" #include "../src/packages.h" #include namespace I2C_EEPROM_Modules { class I2C_ENABLE : public IOPIN { public: I2C_ENABLE(const char *name, unsigned int bit, I2C_EE_Module *pParent); virtual void setDrivenState(bool); private: I2C_EE_Module *m_pParent; unsigned int m_bit; }; I2C_ENABLE::I2C_ENABLE(const char *name, unsigned int bit, I2C_EE_Module *pParent) : IOPIN(name), m_pParent(pParent), m_bit(bit) { } void I2C_ENABLE::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_pParent) m_pParent->setEnable(bNewState, m_bit); } I2C_EE_Module::I2C_EE_Module(const char *_name) : Module(_name, "EEProm") { //initializeAttributes(); chip_select = 0; } I2C_EE_Module::~I2C_EE_Module() { removeSymbol(m_wp); removeSymbol(m_A[0]); removeSymbol(m_A[1]); removeSymbol(m_A[2]); removeSymbol((IOPIN *)(m_eeprom->sda)); removeSymbol((IOPIN *)(m_eeprom->scl)); m_eeprom->sda = 0; m_eeprom->scl = 0; delete att_eeprom; delete m_eeprom; } Module *I2C_EE_Module::construct_2k(const char *_new_name) { string att_name = _new_name; I2C_EE_Module *pEE = new I2C_EE_Module(_new_name); // I2C_EE size in bytes prom size in bits (pEE->m_eeprom) = new I2C_EE((Processor *)pEE,256, 16, 1, 0xe, 0, 0); pEE->create_iopin_map(); att_name += ".eeprom"; pEE->att_eeprom = new PromAddress(pEE->m_eeprom, "eeprom", "Address I2C_EE"); pEE->addSymbol(pEE->att_eeprom); return(pEE); } Module *I2C_EE_Module::construct_16k(const char *_new_name) { string att_name = _new_name; I2C_EE_Module *pEE = new I2C_EE_Module(_new_name); // I2C_EE size in bytes prom size in bits (pEE->m_eeprom) = new I2C_EE((Processor *)pEE,2048, 16, 1, 0, 0xe, 1); pEE->create_iopin_map(); att_name += ".eeprom"; pEE->att_eeprom = new PromAddress(pEE->m_eeprom, att_name.c_str(), "Address I2C_EE"); pEE->addSymbol(pEE->att_eeprom); return(pEE); } Module *I2C_EE_Module::construct_256k(const char *_new_name) { string att_name = _new_name; I2C_EE_Module *pEE = new I2C_EE_Module(_new_name); // I2C_EE size in bytes prom size in bits (pEE->m_eeprom) = new I2C_EE((Processor *)pEE,32768, 64, 2, 0xe, 0, 0); pEE->create_iopin_map(); att_name += ".eeprom"; pEE->att_eeprom = new PromAddress(pEE->m_eeprom, att_name.c_str(), "Address I2C_EE"); pEE->addSymbol(pEE->att_eeprom); return(pEE); } void I2C_EE_Module::create_iopin_map() { m_wp = new I2C_ENABLE("WP", 0, this); addSymbol(m_wp); m_A[0] = new I2C_ENABLE("A0", 1, this); addSymbol(m_A[0]); m_A[1] = new I2C_ENABLE("A1", 2, this); addSymbol(m_A[1]); m_A[2] = new I2C_ENABLE("A2", 3, this); addSymbol(m_A[2]); addSymbol((IOPIN *)(m_eeprom->sda)); addSymbol((IOPIN *)(m_eeprom->scl)); package = new Package(8); package->assign_pin( 1, m_A[0]); package->assign_pin( 2, m_A[1]); package->assign_pin( 3, m_A[2]); package->assign_pin( 5, (IOPIN *)(m_eeprom->sda)); package->assign_pin( 6, (IOPIN *)(m_eeprom->scl)); package->assign_pin( 7, m_wp); } // WP or A0-A2 has changed void I2C_EE_Module::setEnable(bool NewState, unsigned int bit) { if (NewState) chip_select |= 1 << bit; else chip_select &= ~(1 << bit); m_eeprom->set_chipselect(chip_select); } } // end of namespace I2C_EEEPROM_Modules gpsim-0.30.0/modules/video.cc0000664000076400007640000002416413041763636012751 00000000000000/* Copyright (C) 2003 Ralf Forsberg This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* A PAL video module. It makes use of two digital inputs to generate PAL signal sync lume result 0 0 sync 0 1 not valid 1 0 black 1 1 white */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #include "../src/gpsim_interface.h" #include "../src/processor.h" #include "video.h" //-------------------------------------------------------------- // // Create an "interface" to gpsim // class Video_Interface : public Interface { private: Video *video; public: //virtual void UpdateObject (gpointer xref,int new_value); //virtual void RemoveObject (gpointer xref); virtual void SimulationHasStopped (gpointer object) { if(video) video->refresh(); } virtual void NewProcessor (Processor *new_cpu) { if(video) video->cpu = new_cpu; } //virtual void NewModule (Module *module); //virtual void NodeConfigurationChanged (Stimulus_Node *node); //virtual void NewProgram (unsigned int processor_id); virtual void GuiUpdate (gpointer object) { if(video) video->refresh(); } Video_Interface(Video *_video) : Interface((gpointer *) _video) { video = _video; } }; //-------------------------------------------------------------- // This class is a minor extension of a normal IO_input. I may // remove it later, but for now it does serve a simple purpose. // Specifically, this derivation will intercept when a stimulus // is being changed. void IOPIN_Monitor::setDrivenState( bool new_state) { bool current_state = getDrivenState(); IOPIN::setDrivenState(new_state); if(current_state != getDrivenState()) { if(video) video->update_state(); } } static void expose(GtkWidget *widget, GdkEventExpose *event, Video *video) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface(cr, video->image, 0.0, 0.0); cairo_paint(cr); cairo_destroy(cr); } /************************************************************* * * Video class */ Video::Video(const char *_name) : Module(_name), sync_time(0), scanline(0), line_nr(0), last_line_nr(0) { sync_pin = new IOPIN_Monitor(this,"sync"); lume_pin = new IOPIN_Monitor(this,"lume"); addSymbol(sync_pin); addSymbol(lume_pin); //cout << "Video base class constructor\n"; memset(line, 0x80, XRES); memset(shadow, 0x42, XRES * YRES); // initalize shadow to invalid values // cpu = get_processor(1); cpu = get_active_cpu(); //FIXME interface = new Video_Interface(this); get_interface().add_interface(interface); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(window), XRES,YRES); gtk_window_set_title(GTK_WINDOW(window), "Video"); da = gtk_drawing_area_new(); g_signal_connect(da, "expose_event", G_CALLBACK(expose), this); gtk_container_add(GTK_CONTAINER(window), da); gtk_widget_show_all(window); image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, XRES, YRES); } Video::~Video() { cairo_surface_destroy(image); gtk_widget_destroy(window); removeSymbol(sync_pin); removeSymbol(lume_pin); } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void Video::create_iopin_map() { // Create an I/O port to which the I/O pins can interface // The module I/O pins are treated in a similar manner to // the pic I/O pins. Each pin has a unique pin number that // describes it's position on the physical package. This // pin can then be logically grouped with other pins to define // an I/O port. // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // create_pkg(2); // Define the I/O pins (already done) and assign them to the package. //FIX comment // There are two things happening here. First, there is // a new I/O pin that is being created. For the binary // indicator, both pins are inputs. The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. assign_pin(1, sync_pin); //package->set_pin_position(1,(float)0.0); assign_pin(2, lume_pin); //package->set_pin_position(2,(float)0.9999); } //-------------------------------------------------------------- // construct Module * Video::construct(const char *_new_name) { //cout << " Video construct\n"; Video *video = new Video(_new_name) ; video->create_iopin_map(); //cout << "Video should be constructed\n"; return video; } static int screen_y_from_line(int line) { int y; if (line < 313) y = line * 2; else y = (line - 313) * 2 + 1; return y; } void Video::copy_scanline_to_pixmap() { int i, y; int last=line[0]; cairo_t *cr = cairo_create(image); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Clear any skipped lines. if(last_line_nr>line_nr) last_line_nr=0; // new frame if(last_line_nr= 4) { *p = 0x00ffffff; } else if (line[i] > 2) { *p = 0x007f7f7f; } else { *p = 0x00000000; } } cairo_surface_mark_dirty(image); cairo_destroy(cr); } guint64 Video::cycles_to_us(guint64 cycles) { double ret = 0;; if(cpu) ret = cycles*4000000.0/cpu->get_frequency(); return (guint64) ret; } guint64 Video::us_to_cycles(guint64 us) { double ret = 0; if(cpu) ret = us*cpu->get_frequency()/4000000.0; return (guint64) ret; } void Video::refresh() { gdk_window_invalidate_rect(gtk_widget_get_window(da), NULL, FALSE); } void Video::update_state() { guint64 cycletime; guint64 index; static int last_port_value=0; //int val=(int)(lume_pin->get_Vth()); // needs more work to make this work int val=(lume_pin->getDrivenState())?4:0; // 4 to get it above the 2 threshold for visibility maybe use Vth?? static int shortsync_counter, last_shortsync_counter; // get the current simulation cycle time from gpsim. cycletime = get_cycles().get(); if(sync_time>cycletime) { // Cycle counter rolled over. sync_time+=us_to_cycles(64); // 64 us = 1 line assert(sync_time<=cycletime); } // Index into line buffer. Calculated from sync_time. index=cycles_to_us((cycletime-sync_time)*(XRES/64)); if(cycletime-sync_time>us_to_cycles(70)) { // Long time with no sync pulses // Shouldn't happen? // If there was a long time since last sync, we jump over a line. sync_time+=us_to_cycles(64); // 64 us = 1 line memset(line,0x80,XRES); // clear line buffer } if(last_port_value==1 && (sync_pin->getDrivenState()?1:0)==0) // Start of sync { // Every 32 or 64us there should be a sync. sync_time=cycletime; // Start measure on negative flank, when we have lots in buffer. if(index>XRES-XRES/5) { // Have a full line if(shortsync_counter>0) { // We are on first line in the frame. if(shortsync_counter > last_shortsync_counter) { line_nr=6; // Draw the last full image refresh(); } else if(shortsync_counter < last_shortsync_counter) { line_nr=318; } else { puts("VSYNC error"); printf("%d, %d\n",shortsync_counter, last_shortsync_counter); //bp.halt(); useful for debug } last_shortsync_counter=shortsync_counter; shortsync_counter=0; } copy_scanline_to_pixmap(); // display last line line_nr++; if(line_nr>=YRES) line_nr=0; memset(line,0x80,XRES); index=0; } else if(index>XRES/3 && indexgetDrivenState()?1:0)!=0) // End of sync { guint64 us_time; // Should be 4 us (0.000004*12000000 us_time = cycles_to_us(cycletime-sync_time); /* if(us_time > 2 && us_time < 6) { // Valid HSYNC }*/ if(us_time > 25 && us_time < 35) { // vertical sync (FIXME, how should this be?) shortsync_counter=0; } } if(index>=XRES) index=XRES-1; line[index]=val; last_port_value=(sync_pin->getDrivenState()?1:0); } #endif // HAVE_GUI gpsim-0.30.0/modules/Makefile.in0000664000076400007640000005547013117441635013401 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgpsim_modules_la_DEPENDENCIES = ../eXdbm/libgpsim_eXdbm.la \ ../src/libgpsim.la am_libgpsim_modules_la_OBJECTS = gpsim_modules.lo resistor.lo usart.lo \ switch.lo logic.lo led.lo push_button.lo encoder.lo \ i2c-eeprom.lo m_stimuli.lo ttl.lo video.lo i2c.lo i2c2par.lo libgpsim_modules_la_OBJECTS = $(am_libgpsim_modules_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgpsim_modules_la_SOURCES) DIST_SOURCES = $(libgpsim_modules_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDK = @GDK@ GLIB = @GLIB@ GREP = @GREP@ GTK = @GTK@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBDL = @LIBDL@ LIBOBJS = @LIBOBJS@ LIBREADLINE = @LIBREADLINE@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ P_GLIB_CFLAGS = @P_GLIB_CFLAGS@ P_GLIB_LIBS = @P_GLIB_LIBS@ P_GTK_CFLAGS = @P_GTK_CFLAGS@ P_GTK_LIBS = @P_GTK_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ X_CFLAGS = @X_CFLAGS@ X_LDFLAGS = @X_LDFLAGS@ YACC = @YACC@ YFLAGS = @YFLAGS@ Y_CFLAGS = @Y_CFLAGS@ Y_LDFLAGS = @Y_LDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim_modules.la libgpsim_modules_la_SOURCES = \ gpsim_modules.cc \ module_attribute.h \ resistor.cc resistor.h \ usart.cc usart.h \ switch.cc switch.h \ logic.cc logic.h \ led.cc led.h \ push_button.cc push_button.h \ encoder.cc encoder.h \ i2c-eeprom.cc i2c-eeprom.h \ m_stimuli.h m_stimuli.cc \ ttl.cc ttl.h \ video.cc video.h \ i2c.cc i2c.h \ i2c2par.cc i2c2par.h libgpsim_modules_la_LIBADD = ../eXdbm/libgpsim_eXdbm.la -lstdc++ -lpopt \ @X_LDFLAGS@ @Y_LDFLAGS@ @LIBREADLINE@ ../src/libgpsim.la EXTRA_DIST = makefile.mingw all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu modules/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgpsim_modules.la: $(libgpsim_modules_la_OBJECTS) $(libgpsim_modules_la_DEPENDENCIES) $(EXTRA_libgpsim_modules_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(libgpsim_modules_la_OBJECTS) $(libgpsim_modules_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsim_modules.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i2c-eeprom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i2c.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i2c2par.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/led.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m_stimuli.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/push_button.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resistor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/switch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usart.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video.Plo@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile # TSD - removed 17APR06 #PGS added back # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gpsim-0.30.0/modules/m_stimuli.h0000664000076400007640000001125013041763636013477 00000000000000/* Copyright (C) 2006 Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __MOD_STIMULI_H__ #define __MOD_STIMULI_H__ #ifdef HAVE_GUI #include #endif #include #include "../src/stimuli.h" #include "../src/modules.h" #include "module_attribute.h" #include #include #include class PicPortRegister; class PicTrisRegister; class PicLatchRegister; namespace ExtendedStimuli { class PulseAttribute; class PulseInitial; class PulsePeriodAttribute; class ValueStimulusData { public: gint64 time; Value *v; inline bool operator < (ValueStimulusData &rValue) { return time < rValue.time; } inline bool operator == (ValueStimulusData rValue) { return time == rValue.time; } }; class StimulusBase : public Module, public TriggerObject { public: StimulusBase(const char *_name, const char *_desc); ~StimulusBase(); virtual void callback_print(); void create_iopin_map(); void putState(double new_Vth); protected: IO_bi_directional *m_pin; }; //---------------------------------------------------------------------- class PulseGen : public StimulusBase { public: static Module *construct(const char *new_name); PulseGen(const char *_name=0); ~PulseGen(); virtual void callback(); virtual void put_data(ValueStimulusData &data_point); virtual string toString(); void update(); void update_period(); private: PulseAttribute *m_set; PulseAttribute *m_clear; PulseInitial *m_init; PulsePeriodAttribute *m_period; guint64 m_future_cycle; guint64 m_start_cycle; list samples; list::iterator sample_iterator; void setBreak(guint64 next_cycle, list::iterator ); }; //---------------------------------------------------------------------- // File Stimulus and Recorder use this attribute //---------------------------------------------------------------------- template class FileNameAttribute : public String { public: FileNameAttribute(T *parent); virtual void update(); private: T *m_Parent; }; //---------------------------------------------------------------------- class FileStimulus : public StimulusBase { public: static Module *construct(const char *new_name); FileStimulus(const char *_name); void newFile(); void parseLine(bool first = false); virtual void callback(); private: FileNameAttribute *m_filename; guint64 m_future_cycle; ifstream *m_fp; double m_future_value; }; //---------------------------------------------------------------------- class Recorder_Input; class FileRecorder : public Module { public: static Module *construct(const char *new_name); FileRecorder(const char *_name); ~FileRecorder(); void newFile(); virtual void record(bool NewVal); virtual void record(double NewVal); private: FileNameAttribute *m_filename; Recorder_Input *m_pin; ofstream *m_fp; double m_lastval; }; //---------------------------------------------------------------------- class RegisterAddressAttribute; // used for mapping registers into a processor memory class PortPullupRegister; class PortStimulus : public Module, public TriggerObject { public: static Module *construct8(const char *new_name); static Module *construct16(const char *new_name); static Module *construct32(const char *new_name); PortStimulus(const char *_name, int nPins); ~PortStimulus(); virtual void callback_print(); void create_iopin_map(); protected: int m_nPins; PicPortRegister *mPort; PicTrisRegister *mTris; PicLatchRegister *mLatch; PortPullupRegister *mPullup; RegisterAddressAttribute *mPortAddress; RegisterAddressAttribute *mTrisAddress; RegisterAddressAttribute *mLatchAddress; RegisterAddressAttribute *mPullupAddress; }; } #endif // __MOD_STIMULI_H__ gpsim-0.30.0/modules/Makefile.am0000664000076400007640000000135313041763636013363 00000000000000## Process this file with automake to produce Makefile.in AM_CPPFLAGS = @X_CFLAGS@ lib_LTLIBRARIES = libgpsim_modules.la libgpsim_modules_la_SOURCES = \ gpsim_modules.cc \ module_attribute.h \ resistor.cc resistor.h \ usart.cc usart.h \ switch.cc switch.h \ logic.cc logic.h \ led.cc led.h \ push_button.cc push_button.h \ encoder.cc encoder.h \ i2c-eeprom.cc i2c-eeprom.h \ m_stimuli.h m_stimuli.cc \ ttl.cc ttl.h \ video.cc video.h \ i2c.cc i2c.h \ i2c2par.cc i2c2par.h # TSD - removed 17APR06 #PGS added back ## paraface.cc paraface.h \ # TSD - removed 16APR06 libgpsim_modules_la_LIBADD = ../eXdbm/libgpsim_eXdbm.la -lstdc++ -lpopt \ @X_LDFLAGS@ @Y_LDFLAGS@ @LIBREADLINE@ ../src/libgpsim.la EXTRA_DIST = makefile.mingw gpsim-0.30.0/modules/switch.cc0000664000076400007640000004223613041763636013144 00000000000000/* Copyright (C) 2002 Ralf Forsberg This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* switch.cc This is a module that displays a togglebutton on the screen and puts the togglebutton state on its output pin. */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include #include #include #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #endif #include "../src/packages.h" #include "../src/stimuli.h" #include "../src/gpsim_interface.h" #include "switch.h" namespace Switches { //------------------------------------------------------------------------ // SwitchPin class SwitchPin : public IOPIN { public: SwitchPin(SwitchBase *parent, const char *_name); virtual void getThevenin(double &v, double &z, double &c); virtual void sumThevenin(double ¤t, double &conductance, double &Cth); virtual void Build_List(stimulus * st); virtual void set_Refreshing() { bRefreshing = true; } double get_Zopen() { return m_pParent->getZopen(); } double get_Zclosed() { return m_pParent->getZclosed(); } bool switch_closed() { return m_pParent->switch_closed(); } SwitchPin * other_pin(SwitchPin *pin) { return m_pParent->other_pin(pin);} private: SwitchBase *m_pParent; bool bRefreshing; stimulus **st_list; // List of stimuli int st_cnt; // Size of list SwitchPin **sp_list; // List of Switch pins we have seen int sp_cnt; // size of list }; SwitchPin::SwitchPin(SwitchBase *parent, const char *_name) : IOPIN(_name), m_pParent(parent), bRefreshing(false) { assert(m_pParent); sp_cnt = 5; sp_list = (SwitchPin **)calloc(sp_cnt, sizeof(SwitchPin *)); st_cnt = 10; st_list = (stimulus **)calloc(st_cnt, sizeof(stimulus *)); } /* ** If the switch is closed, look through switch to get values */ void SwitchPin::getThevenin(double &v, double &z, double &c) { if (switch_closed()) { SwitchPin * op = other_pin(this); double current = 0.; double conductance = 0.; double Cth = 0.; op->sumThevenin(current, conductance, Cth); z = 1./conductance; v = current * z; z += (get_Zclosed() ? get_Zclosed() : 0.0); c = Cth; if (!bRefreshing && op->snode) // Not called from other pin { op->set_Refreshing(); op->snode->update(); // update other pin node } bRefreshing = false; } else { v = 0.; z = get_Zopen(); c = 0; } set_Vth(v); set_Zth(z); set_Cth(c); if (verbose) cout << "SwitchPin::getThevenin :" << name() << " v=" << v << " z=" << z << " Cth=" << c << endl; } /* Build_list, given the first stimuli from a node with a connected switch, builds a list of all the stimuli of the node except for the switch itself. If it encounters other switches on the node, it will do one of two things. If the switch is open, the switch stimuli will be ignored. However, if the switch is closed and the switch pin has not already been seen (to stop recursion), Build_List will look through the switch and add all the stimuli connected to it's other pin. Stimuli may be encountered more than once, but will only be added to the list the first time. The resulting stimulus list is used by sumThevenin. */ void SwitchPin::Build_List(stimulus *st) { for(; st; st = st->next) { if (name() != st->name()) { if (typeid(*st) == typeid(*this)) // This is a SwitchPin stimulus { SwitchPin *sp_ptr = (SwitchPin *)st; bool state = sp_ptr->switch_closed(); if (verbose) cout << "SwitchPin::Build_List " << this->name() << " found " << st->name() << "switch state=" << (state?"closed":"open") << endl; if (state) // Switch is closed { int i; SwitchPin **sp_pt = sp_list; // Scan list, stop on match or end of list for(i = 0; (i < sp_cnt) && *sp_pt && (*sp_pt != sp_ptr); i++, sp_pt++) {} if (i+1 >= st_cnt) // need to grow list { if (verbose) cout << "\tIncrease size of SwitchPin list\n"; sp_cnt += 5; sp_list = (SwitchPin **)realloc(sp_list, sp_cnt * sizeof(SwitchPin *)); sp_pt = sp_list + i; } // have not seen this switch pin, add to end of list // add stimuli on other pin of switch if (*sp_pt != sp_ptr) { *sp_pt++ = sp_ptr; *sp_pt = NULL; if (verbose) cout << "\t" << sp_ptr->name() << " other=" << sp_ptr->other_pin(sp_ptr)->name() << endl; // Add stimuli on other pin of closed swich if (sp_ptr->other_pin(sp_ptr)->snode) Build_List(sp_ptr->other_pin(sp_ptr)->snode->stimuli); } } } else // other type of stimulus { int i; stimulus **st_pt = st_list; // Scan list, stop on match or end of list for(i = 0; (i < st_cnt) && *st_pt && (*st_pt != st); i++, st_pt++) {} if (i+1 >= st_cnt) // need to grow list { if (verbose) cout << "\tIncrease size of stimlui list\n"; st_cnt += 5; st_list = (stimulus **)realloc(st_list, st_cnt * sizeof(stimulus *)); st_pt = st_list + i; } if (*st_pt != st) // Add stimulus to list { if (verbose) cout << "Build_List adding " << st->name() << endl; *st_pt++ = st; *st_pt = NULL; } } } } } /* sumThevenin ** Sum the Thevenin parameters for all stimuli connected to pin except for the ** pin stimulus itself. This is a helper function for getThevenin and do_voltage(). ** ** +---------------+ node +----------------+ ** Switch | +---Zth--+--|-------+------|--+----Z1---+ | First Stimulus ** Pin | Vth Cth | --> | --> | C1 V1 | connected to ** | | | | I | I1 | | | | the switch. ** | /// /// | | | /// /// | ** +---------------+ : +----------------+ ** : ** | +----------------+ ** +------|--+----Zn---+ | Last Stimulus ** --> | Cn Vn | connected to ** In | | | | the switch. ** | /// /// | ** +----------------+ ** */ void SwitchPin::sumThevenin(double ¤t, double &conductance, double &Cth) { stimulus **sptr; if (!snode) return; *sp_list = NULL; *st_list = NULL; if (verbose) cout << "SwitchPin::sumThevenin " << name() << endl; Build_List(snode->stimuli); for(sptr = st_list; *sptr ; sptr++) { double V1,Z1,C1; // Get the thevenin parameters of the stimulus connected to the switch pin (*sptr)->getThevenin(V1,Z1,C1); if (verbose) cout << " N: " <<(*sptr)->name() << " V=" << V1 << " Z=" << Z1 << " C=" << C1 << endl; double Cs = 1 / Z1; // The Thevenin current is the Thevenin voltage divided by // the Thevenin resistance: current += V1 * Cs; conductance += Cs; Cth += C1; } } //======================================================================== //---------------------------------------- class ResistanceAttribute : public Float { public: SwitchBase *m_sw; ResistanceAttribute(SwitchBase *psw, double resistance, const char *_name, const char *_desc) : Float(_name,resistance,_desc), m_sw(psw) { } virtual void set(int r) { double dr = r; set(dr); } virtual void set(double r) { Float::set(r); if(m_sw) m_sw->update(); } }; //---------------------------------------- class SwitchAttribute : public Boolean { public: SwitchAttribute(SwitchBase *_parent) : Boolean("state",false,"Query or Change the switch"), m_pParent(_parent) { assert(m_pParent); } virtual void set(bool b); virtual void set(Value *v); virtual void set(const char *buffer, int buf_size = 0); virtual void get(char *return_str, int len); virtual bool Parse(const char *pValue, bool &bValue); void setFromButton(bool b); private: SwitchBase *m_pParent; }; bool SwitchAttribute::Parse(const char *pValue, bool &bValue) { if(strncmp("true", pValue, sizeof("true")) == 0 || strncmp("closed", pValue, sizeof("closed")) == 0) { bValue = true; return true; } else if(strncmp("false", pValue, sizeof("false")) == 0 || strncmp("open", pValue, sizeof("open")) == 0) { bValue = false; return true; } return false; } void SwitchAttribute::set(Value *v) { if (typeid(*v) == typeid(Boolean)) { bool d; v->get(d); set(d); } else if ( typeid(*v) == typeid(String)) { char buff[20]; v->get((char *)buff, sizeof(buff)); set(buff); } else throw new TypeMismatch(string("set "), "SwitchAttribute", v->showType()); } void SwitchAttribute::set(const char *buffer, int buf_size) { if(buffer) { bool bValue; if(Parse(buffer, bValue)) { set(bValue); } } } void SwitchAttribute::set(bool b) { Boolean::set(b); m_pParent->setState(b); } void SwitchAttribute::setFromButton(bool b) { Boolean::set(b); } void SwitchAttribute::get(char *return_str, int len) { if(return_str) { bool b; Boolean::get(b); snprintf(return_str,len,"%s",(b ? "closed" : "open")); } } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void SwitchBase::create_iopin_map(void) { // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // create_pkg(2); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created. For the binary // indicator, both pins are inputs. The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. m_pinA = new SwitchPin(this,"A"); addSymbol(m_pinA); m_pinB = new SwitchPin(this,"B"); addSymbol(m_pinB); assign_pin(1, m_pinA); assign_pin(2, m_pinB); package->set_pin_position(1,2.5); package->set_pin_position(2,0.5); } //------------------------------------------------------------------------ // void SwitchBase::setState(bool bNewState) { if ( switch_closed() != bNewState) { m_bCurrentState = bNewState; update(); } } //------------------------------------------------------------------------ /* If the switch is closed, we send an update to one side only as SwitchPin::getThevenin will send it to the other pin. If the switch is open, then update both sides */ void SwitchBase::update() { if (switch_closed()) // equalise voltage if capacitance involved do_voltage(); if (m_pinA->snode) m_pinA->snode->update(); if (!switch_closed() && m_pinB->snode) m_pinB->snode->update(); } //------------------------------------------------------------------------ double SwitchBase::getZopen() { return m_Zopen ? m_Zopen->getVal() : 1e8; } double SwitchBase::getZclosed() { return m_Zclosed ? m_Zclosed->getVal() : 10; } SwitchPin * SwitchBase::other_pin(SwitchPin *pin) { return( (pin == m_pinA)? m_pinB: m_pinA); } //------------------------------------------------------------------------ SwitchBase::SwitchBase(const char *_new_name, const char *_desc) : Module(_new_name,_desc), m_pinA(0), m_pinB(0), m_bCurrentState(false), m_aState(0) { // Default module attributes. //initializeAttributes(); m_Zopen = new ResistanceAttribute(this, 1e8, "Ropen", "Resistance of opened switch"); m_Zclosed = new ResistanceAttribute(this, 10, "Rclosed", "Resistance of closed switch"); m_aState = new SwitchAttribute(this); addSymbol(m_aState); addSymbol(m_Zopen); addSymbol(m_Zclosed); } SwitchBase::~SwitchBase(void) { removeSymbol(m_aState); removeSymbol(m_Zopen); removeSymbol(m_Zclosed); removeSymbol(m_pinA); removeSymbol(m_pinB); delete m_Zclosed; delete m_Zopen; delete m_aState; /* delete m_pinA; delete m_pinB; */ } /* ** do_voltage computes the initial switch voltage when the switch is closed ** and capacitance is present. It is assumed that when the switch closes, ** charge will instantaneously be exchanged between the capacitors until ** they have the same voltage. */ void SwitchBase::do_voltage() { double conductance=0.0; // Thevenin conductance. double Cth=0; // Thevenin capacitance double current=0.0; // current flowing through the switch double C1, C2; double V1, V2; double Vth; V1 = m_pinA->get_nodeVoltage(); m_pinA->sumThevenin(current, conductance, Cth); C1 = Cth; V2 = m_pinB->get_nodeVoltage(); m_pinB->sumThevenin(current, conductance, Cth); C2 = Cth - C1; if (verbose) cout << "\nSwitch::do_voltage " << name() << " V.A=" << V1 << " V.B=" << V2 << endl; if (Cth) { Vth = (V1*C1 + V2*C2)/Cth; if (verbose) cout << "Switch::do_voltage " << name() << " equilise voltage to " << Vth << endl << " V1=" << V1 << " V2=" << V2 << " C1=" << C1 << " C2=" << C2 << endl; if (m_pinA->snode) m_pinA->snode->set_nodeVoltage(Vth); if (m_pinB->snode) m_pinB->snode->set_nodeVoltage(Vth); } } //======================================================================== Switch::Switch(const char *_new_name) : SwitchBase(_new_name, "\ Two port switch\n\ Attributes:\n\ .state - true if switch is pressed\n\ "), m_button(0) { } Switch::~Switch() { } //-------------------------------------------------------------- // construct Module * Switch::construct(const char *_new_name=0) { Switch *switchP = new Switch(_new_name); //switchP->new_name(_new_name); switchP->create_iopin_map(); if(get_interface().bUsingGUI()) switchP->create_widget(switchP); return switchP; } //-------------------------------------------------------------- // GUI #ifdef HAVE_GUI static void toggle_cb (GtkToggleButton *button, Switch *sw) { if (sw) sw->buttonToggled(); } void Switch::buttonToggled () { bool b = gtk_toggle_button_get_active(m_button) ? true : false; if (! m_pinA->snode || ! m_pinB->snode) { cout << "\n WARNING both pins of " << name() << " must be connected to nodes\n"; return; } m_aState->set(b); } #endif //------------------------------------------------------------------------ // void Switch::setState(bool bNewState) { #ifdef HAVE_GUI if (m_button) gtk_toggle_button_set_active(m_button, bNewState ? TRUE : FALSE); #endif SwitchBase::setState(bNewState); } //------------------------------------------------------------------------ void Switch::create_widget(Switch *sw) { #ifdef HAVE_GUI GtkWidget *box1; box1 = gtk_vbox_new (FALSE, 0); m_button = GTK_TOGGLE_BUTTON(gtk_toggle_button_new_with_label ((char*)sw->name().c_str())); gtk_container_set_border_width (GTK_CONTAINER (m_button), 1); g_signal_connect (m_button, "toggled", G_CALLBACK(toggle_cb), (gpointer)sw); gtk_widget_show(GTK_WIDGET(m_button)); gtk_box_pack_start (GTK_BOX (box1), GTK_WIDGET(m_button), FALSE, FALSE, 0); gtk_widget_show_all (box1); // Tell gpsim which widget to use in breadboard. sw->set_widget(box1); #endif } } gpsim-0.30.0/modules/i2c2par.h0000664000076400007640000000321213041763636012736 00000000000000/* Copyright (C) 2015 Roy R Rankin This file is part of gpsim. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __I2C2PAR_H__ #define __I2C2PAR_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "src/modules.h" #include "src/ioports.h" #include "src/stimuli.h" #include "src/trigger.h" #include "src/i2c-ee.h" class IOPort; class AddAttribute; namespace I2C2PAR_Modules { class i2c2par : public i2c_slave, public Module, public TriggerObject { public: i2c2par(const char *_name); ~i2c2par(); static Module *construct(const char *new_name); virtual void create_iopin_map(); virtual void setEnable(bool bNewState, unsigned int m_bit){}; virtual bool match_address(); virtual void put_data(unsigned int data); virtual unsigned int get_data(); virtual void slave_transmit(bool yes); IOPort *io_port; protected: AddAttribute *Addattr; IO_bi_directional_pu **pins; }; } // end of namespace I2C2PAR_Modules #endif // __I2C2PAR_H__ gpsim-0.30.0/modules/logic.h0000664000076400007640000001066313041763636012601 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __LOGIC_H__ #define __LOGIC_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../src/stimuli.h" #include "../src/modules.h" #ifdef HAVE_GUI #include #endif class LogicGate; /********************************************************* * * Create a class derived from the IO_input class that * will allow us to intercept when the I/O input is being * driven. (This isn't done for PIC I/O pins because the * logic for handling I/O pin changes resides in the IOPORT * class.) */ class Logic_Input : public IOPIN { private: LogicGate *LGParent; unsigned int m_iobit; public: virtual void setDrivenState( bool new_state); //RRR virtual void get(char *return_str, int len); Logic_Input (LogicGate *parent, unsigned int b, const char *opt_name=0) : IOPIN(opt_name), LGParent(parent), m_iobit(b) { } }; class Logic_Output : public IO_bi_directional { private: LogicGate *LGParent; unsigned int m_iobit; public: //RRR virtual void get(char *return_str, int len); Logic_Output (LogicGate *parent, unsigned int b,const char *opt_name=0) : IO_bi_directional(opt_name), LGParent(parent), m_iobit(b) { } }; /************************************************************* * * LogicGate class. * * Here's the definition for the LogicGate class and all of its * children * * Module * | * -------- * | * |-LogicGate * | * |- ANDGate * | | * | |- AND2Gate * |- ORGate * | * |- OR2Gate */ class LogicGate : public Module { public: int number_of_pins; unsigned int input_bit_mask; unsigned int input_state; IOPIN **pInputPins; Logic_Output *pOutputPin; #ifdef HAVE_GUI GdkPixbuf *pixbuf; #endif LogicGate(const char *name, const char * desc); ~LogicGate(); // Inheritances from the Package class virtual void create_iopin_map(); virtual void update_state()=0; void update_input_pin(unsigned int pin, bool bValue); virtual int get_num_of_pins() {return number_of_pins;}; void set_number_of_pins(int npins){number_of_pins=npins;}; #ifdef HAVE_GUI GtkWidget *create_pixmap(const gchar **pixmap_data); #endif }; // 2 input and gate class ANDGate: public LogicGate { public: virtual void update_state(); ANDGate(const char *name, const char * desc); ~ANDGate(); }; class AND2Gate: public ANDGate { public: static Module *construct(const char *new_name); const virtual char *type() { return ("and2"); }; // virtual void update_state(void); AND2Gate(const char *); ~AND2Gate(); }; class ORGate: public LogicGate { public: ORGate(const char *name, const char * desc); ~ORGate(); virtual void update_state(); }; // 2 input or gate class OR2Gate: public ORGate { public: //virtual void update_state(void); static Module *construct(const char *new_name); const virtual char *type() { return ("or2"); }; OR2Gate(const char *name); ~OR2Gate(); }; class XORGate: public LogicGate { public: XORGate(const char *name, const char * desc); ~XORGate(); virtual void update_state(); }; // 2 input or gate class XOR2Gate: public XORGate { public: //virtual void update_state(void); static Module *construct(const char *new_name); const virtual char *type() { return ("xor2"); }; XOR2Gate(const char *name); ~XOR2Gate(); }; class NOTGate: public LogicGate { public: //virtual void update_state(void); static Module *construct(const char *new_name); const virtual char *type() { return ("not"); }; virtual void update_state(); NOTGate(const char *name); ~NOTGate(); }; #endif // __LOGIC_H__ gpsim-0.30.0/modules/ttl.cc0000664000076400007640000002721713115240061012430 00000000000000/* Copyright (C) 2006T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* ttl.cc - gpsim's TTL library */ #include "../config.h" #ifdef HAVE_GUI #include #endif #include "ttl.h" #include "../src/stimuli.h" #include "../src/packages.h" #include "../src/gpsim_time.h" #include #include //#define DEBUG #if defined(DEBUG) #include "../config.h" #define Dprintf(arg) {printf("%s:%d %s ",__FILE__,__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif namespace TTL { //------------------------------------------------------------------------ // TTL base class TTLbase::TTLbase(const char *_name, const char *desc) : Module(_name,desc), m_dVdd(0),m_bClock(false), m_bEnable(false) { } TTLbase::~TTLbase() { } //------------------------------------------------------------------------ // Some edge-sensitive pins // // //------------------------------------------------------------ // Clock // class Clock : public IOPIN { public: Clock(const char *n, TTLbase *pParent); virtual void setDrivenState(bool); private: TTLbase *m_pParent; }; Clock::Clock(const char *n, TTLbase *pParent) : IOPIN(n), m_pParent(pParent) { } void Clock::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_pParent) m_pParent->setClock(bNewState); } //------------------------------------------------------------ // Strobe // class Strobe : public IOPIN { public: Strobe(const char *n, TTLbase *pParent); virtual void setDrivenState(bool); private: TTLbase *m_pParent; }; Strobe::Strobe(const char *n, TTLbase *pParent) : IOPIN(n), m_pParent(pParent) { } void Strobe::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_pParent) m_pParent->setStrobe(bNewState); } //------------------------------------------------------------ // Enable // class Enable : public IOPIN { public: Enable(const char *n, TTLbase *pParent); virtual void setDrivenState(bool); private: TTLbase *m_pParent; }; Enable::Enable(const char *n, TTLbase *pParent) : IOPIN(n), m_pParent(pParent) { } void Enable::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_pParent) m_pParent->setEnable(bNewState); } //------------------------------------------------------------ // Reset // class Reset : public IOPIN { public: Reset(const char *n, TTLbase *pParent); virtual void setDrivenState(bool); private: TTLbase *m_pParent; }; Reset::Reset(const char *n, TTLbase *pParent) : IOPIN(n), m_pParent(pParent) { } void Reset::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); if (m_pParent) m_pParent->setReset(bNewState); } //------------------------------------------------------------------------ // TTL377 - Octal Latch // // Module *TTL377::construct(const char *_new_name) { TTL377 *pTTL377 = new TTL377(_new_name); pTTL377->new_name(_new_name); pTTL377->create_iopin_map(); return pTTL377; } TTL377::TTL377(const char *_name) : TTLbase(_name, "TTL377 - Octal Latch") { m_D = new IOPIN *[8]; m_Q = new IO_bi_directional *[8]; char pName[4]; pName[2] = 0; int i; for (i=0; i<8; i++) { pName[0] = 'D'; pName[1] = '0' + i; m_D[i] = new IOPIN(pName); addSymbol(m_D[i]); pName[0] = 'Q'; m_Q[i] = new IO_bi_directional(pName); addSymbol(m_Q[i]); m_Q[i]->setDriving(true); } m_enable = new Enable("E",this); addSymbol(m_enable); m_clock = new Clock("CP",this); addSymbol(m_clock); } TTL377::~TTL377() { for (int i = 0; i < 8; i++) { removeSymbol(m_D[i]); removeSymbol(m_Q[i]); } delete [] m_D; delete [] m_Q; removeSymbol(m_enable); removeSymbol(m_clock); } void TTL377::setClock(bool bNewClock) { if (bNewClock && !m_bClock && !m_bEnable) { update_state(); } m_bClock = bNewClock; } void TTL377::setEnable(bool bNewEnable) { m_bEnable = bNewEnable; } void TTL377::update_state() { int i; bool state[8]; // Copy the inputs to the outputs through an intermediary to simulate // the simultaneous action of the real part. for (i=0; i<8; i++) state[i]=m_D[i]->getDrivenState(); for (i=0; i<8; i++) m_Q[i]->putState(state[i]); } void TTL377::create_iopin_map() { package = new Package(20); package->assign_pin( 1, m_enable); package->assign_pin( 2, m_Q[0]); package->assign_pin( 3, m_D[0]); package->assign_pin( 4, m_D[1]); package->assign_pin( 5, m_Q[1]); package->assign_pin( 6, m_Q[2]); package->assign_pin( 7, m_D[2]); package->assign_pin( 8, m_D[3]); package->assign_pin( 9, m_Q[3]); package->assign_pin(11, m_clock); package->assign_pin(12, m_Q[4]); package->assign_pin(13, m_D[4]); package->assign_pin(14, m_D[5]); package->assign_pin(15, m_Q[5]); package->assign_pin(16, m_Q[6]); package->assign_pin(17, m_D[6]); package->assign_pin(18, m_D[7]); package->assign_pin(19, m_Q[7]); } //------------------------------------------------------------------------ // TTL595 - Octal shift register // // Module *TTL595::construct(const char *_new_name) { TTL595 *pTTL595 = new TTL595(_new_name); pTTL595->new_name(_new_name); pTTL595->create_iopin_map(); return pTTL595; } TTL595::TTL595(const char *_name) : TTLbase(_name, "TTL595 - Octal Shift Register"), m_bStrobe(false), sreg(0) { m_Q = new IO_bi_directional *[8]; char pName[4] = "Q0"; int i; for (i=0; i<8; i++) { pName[1] = '0' + i; m_Q[i] = new IO_bi_directional(pName); addSymbol(m_Q[i]); m_Q[i]->setDriving(true); } m_Ds = new IOPIN("Ds"); addSymbol(m_Ds); m_Qs = new IO_bi_directional("Qs"); addSymbol(m_Qs); m_Qs->setDriving(true); m_enable = new Enable("OE",this); addSymbol(m_enable); m_clock = new Clock("SCK",this); addSymbol(m_clock); m_strobe = new Strobe("RCK",this); addSymbol(m_strobe); m_reset = new Reset("MR",this); addSymbol(m_reset); } TTL595::~TTL595() { for(int i = 0; i < 8; i++) { removeSymbol(m_Q[i]); } delete [] m_Q; removeSymbol(m_Ds); removeSymbol(m_Qs); removeSymbol(m_enable); removeSymbol(m_clock); removeSymbol(m_strobe); removeSymbol(m_reset); } void TTL595::setClock(bool bNewClock) { // Clock shifts the shift register on rising edge, if MR pin is high Dprintf(("bNewClock %d m_bClock %d reset %d Ds %d\n", bNewClock, m_bClock, m_reset->getDrivenState(), m_Ds->getDrivenState())); if (bNewClock && !m_bClock && m_reset->getDrivenState()) { // Move the shift register left and out. sreg <<= 1; if ( m_Ds->getDrivenState() ) sreg |= 0x01; Dprintf(("%s sreg=%x now=0x%lx bNewClock %d m_bClock %d\n", name().c_str(), sreg, get_cycles().get(), bNewClock,m_bClock)); get_cycles().set_break(get_cycles().get() + 1, this); } m_bClock = bNewClock; } void TTL595::setEnable(bool bNewEnable) { // This is the output enable pin on this device for (int i=0; i<8; i++) m_Q[i]->update_direction(!bNewEnable,true); } void TTL595::setReset(bool bNewReset) { if (!bNewReset) sreg = 0; } void TTL595::setStrobe(bool bNewStrobe) { Dprintf(("bNewStrobe %d m_bStrobe %d\n", bNewStrobe, m_bStrobe)); // Strobe copies the contents of the shift register into the outputs if (bNewStrobe && !m_bStrobe) { update_state(); } m_bStrobe = bNewStrobe; } void TTL595::update_state() { for (int i=0, ss=sreg; i<8; i++,ss>>=1) m_Q[i]->putState((bool) (ss&1)); Dprintf(("sreg=0x%x\n", sreg)); } void TTL595::callback_print() { cout << "TTL595 " << name() << " CallBack ID 0x" << hex << CallBackID << '\n'; } void TTL595::callback() { Dprintf(("%s %s now=0x%lx\n", __FUNCTION__, name().c_str(), get_cycles().get())); m_Qs->putState ( (sreg & 0x80)!=0 ); } void TTL595::create_iopin_map() { package = new Package(16); package->assign_pin( 1, m_Q[1]); package->assign_pin( 2, m_Q[2]); package->assign_pin( 3, m_Q[3]); package->assign_pin( 4, m_Q[4]); package->assign_pin( 5, m_Q[5]); package->assign_pin( 6, m_Q[6]); package->assign_pin( 7, m_Q[7]); package->assign_pin( 9, m_Qs); package->assign_pin(10, m_reset); package->assign_pin(11, m_clock); package->assign_pin(12, m_strobe); package->assign_pin(13, m_enable); package->assign_pin(14, m_Ds); package->assign_pin(15, m_Q[0]); } //------------------------------------------------------------------------ // TTL165 - 8-bit parallel to serial shift register // // Module *TTL165::construct(const char *_new_name) { TTL165 *pTTL165 = new TTL165(_new_name); pTTL165->new_name(_new_name); pTTL165->create_iopin_map(); return pTTL165; } TTL165::TTL165(const char *_name) : TTLbase(_name, "TTL165 - PISO Shift Register"), m_bStrobe(false), sreg(0) { m_D = new IOPIN *[8]; char pName[4] = "D0"; int i; for (i=0; i<8; i++) { pName[1] = '0' + i; m_D[i] = new IOPIN(pName); addSymbol(m_D[i]); } m_Ds = new IOPIN("Ds"); addSymbol(m_Ds); m_Q = new IO_bi_directional("Q7"); addSymbol(m_Q); m_Q->setDriving(true); m_Qbar = new IO_bi_directional("nQ7"); addSymbol(m_Qbar); m_Qbar->setDriving(true); m_enable = new Enable("CE", this); addSymbol(m_enable); m_clock = new Clock("CP",this); addSymbol(m_clock); m_strobe = new Strobe("PL",this); addSymbol(m_strobe); } TTL165::~TTL165() { for(int i = 0; i < 8; i++) { removeSymbol(m_D[i]); } delete [] m_D; removeSymbol(m_Ds); removeSymbol(m_Q); removeSymbol(m_Qbar); removeSymbol(m_enable); removeSymbol(m_clock); removeSymbol(m_strobe); } void TTL165::setClock(bool bNewClock) { // Clock shifts the shift register on rising edge, if CE pin is low and PL is high if ( bNewClock && !m_bClock && !m_enable->getDrivenState() && m_strobe->getDrivenState() ) { // Move the shift register left and out. sreg <<= 1; if ( m_Ds->getDrivenState() ) sreg |= 0x01; m_Q->putState ( (sreg & 0x80)!=0 ); m_Qbar->putState ( (sreg & 0x80)==0 ); } m_bClock = bNewClock; } void TTL165::setEnable(bool bNewEnable) { // This is the clock enable pin on this device. No explicit action needed on change. } void TTL165::setStrobe(bool bNewStrobe) { // Strobe copies the contents of the parallel inputs into the shift register if (bNewStrobe && !m_bStrobe) { update_state(); } if ( !bNewStrobe ) { m_Q->putState ( m_D[7]->getDrivenState() ); m_Qbar->putState ( !m_D[7]->getDrivenState() ); } m_bStrobe = bNewStrobe; } void TTL165::update_state() { unsigned short ss = 0; for (int i=0; i<8; i++) { if ( m_D[i]->getDrivenState() ) ss |= 1<assign_pin( 1, m_strobe); package->assign_pin( 2, m_clock); package->assign_pin( 3, m_D[4]); package->assign_pin( 4, m_D[5]); package->assign_pin( 5, m_D[6]); package->assign_pin( 6, m_D[7]); package->assign_pin( 7, m_Qbar); package->assign_pin( 9, m_Q); package->assign_pin(10, m_Ds); package->assign_pin(11, m_D[0]); package->assign_pin(12, m_D[1]); package->assign_pin(13, m_D[2]); package->assign_pin(14, m_D[3]); package->assign_pin(15, m_enable); } } gpsim-0.30.0/modules/switch.h0000664000076400007640000000455013041763636013003 00000000000000/* Copyright (C) 2002 Ralf Forsberg This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __SWITCH_H__ #define __SWITCH_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../src/modules.h" #ifdef HAVE_GUI #include #else struct GtkToggleButton; #endif namespace Switches { class SwitchPin; // defined and implemented in switch.cc class SwitchAttribute; // " " class SwitchBase : public Module, public TriggerObject { public: SwitchBase(const char *_name, const char *_desc); ~SwitchBase(); void update(); virtual void setState(bool); // Inheritances from the Package class virtual void create_iopin_map(); // Inheritance from Module class const virtual char *type() { return ("switch"); }; virtual void do_voltage(); virtual bool switch_closed() { return m_bCurrentState; } virtual SwitchPin * other_pin(SwitchPin *pin); // Attributes call back into the switch through here: double getZopen(); double getZclosed(); protected: SwitchPin *m_pinA; SwitchPin *m_pinB; // State of the switch bool m_bCurrentState; SwitchAttribute *m_aState; // Switch resistance. Float *m_Zopen; Float *m_Zclosed; }; class Switch : public SwitchBase { public: Switch(const char *_name=0); ~Switch(); virtual void setState(bool); void buttonToggled(); static Module *construct(const char *new_name); protected: // The switch's graphical representation. GtkToggleButton *m_button; private: void create_widget(Switch *sw); static void cb_buttonToggle(GtkToggleButton *button, SwitchBase *This); }; } #endif // __SWITCH_H__ gpsim-0.30.0/modules/encoder.cc0000664000076400007640000001140513041763636013254 00000000000000/* Copyright (C) 2004 Chris Emerson (Based on the push_button Copyright (C) 2002 Carlos Ghirardelli) This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* encoder.cc */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #include "../src/gpsim_time.h" #include "../src/packages.h" #include "../src/stimuli.h" #include "encoder.h" #define PIN_A (0x01) #define PIN_B (0x02) //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void Encoder::create_iopin_map(void) { // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // create_pkg(2); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created. For the binary // indicator, both pins are inputs. The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. a_pin = new IO_bi_directional("a"); addSymbol(a_pin); assign_pin(1, a_pin); package->set_pin_position(1,(float)0.0); b_pin = new IO_bi_directional("b"); addSymbol(b_pin); assign_pin(2, b_pin); package->set_pin_position(2,(float)0.9999); } //-------------------------------------------------------------- // GUI static void cw_cb (GtkButton *button, Encoder *enc) { enc->send_cw(); } static void ccw_cb (GtkButton *button, Encoder *enc) { enc->send_ccw(); } void Encoder::create_widget(Encoder *enc) { GtkWidget *box1; GtkWidget *buttonl, *buttonr; box1 = gtk_hbox_new (FALSE, 0); buttonl = gtk_button_new_with_label ("ccw"); buttonr = gtk_button_new_with_label (" cw"); gtk_container_set_border_width (GTK_CONTAINER (buttonl), 5); gtk_container_set_border_width (GTK_CONTAINER (buttonr), 5); g_signal_connect (buttonl, "pressed", G_CALLBACK(ccw_cb), (gpointer)enc); g_signal_connect (buttonr, "pressed", G_CALLBACK(cw_cb), (gpointer)enc); gtk_widget_show(buttonl); gtk_widget_show(buttonr); gtk_box_pack_start (GTK_BOX (box1), buttonl, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (box1), buttonr, FALSE, FALSE, 0); // Tell gpsim which widget to use in breadboard. enc->set_widget(box1); } //-------------------------------------------------------------- // construct Module * Encoder::construct(const char *_new_name=NULL) { Encoder *enc_p = new Encoder(_new_name); enc_p->create_widget(enc_p); return enc_p; } Encoder::Encoder(const char * _name) : Module(_name, "Encoder"), rs(rot_detent) { create_iopin_map(); } Encoder::~Encoder(void) { /* done elsewhere RRR delete a_pin; delete b_pin; */ } void Encoder::send_cw(void) { switch (rs) { case rot_detent: rs = rot_moving_cw; toggle_a(); /* A toggles before B going clockwise */ schedule_tick(); break; default: // XXX: ought to do something here as well break; } } void Encoder::send_ccw(void) { switch (rs) { case rot_detent: rs = rot_moving_ccw; toggle_b(); schedule_tick(); break; default: // XXX: ought to do something here as well break; } } void Encoder::toggle_a() { a_pin->toggle(); } void Encoder::toggle_b() { b_pin->toggle(); } void Encoder::schedule_tick() { /* XXX: make the time delay configurable */ if (!get_cycles().set_break_delta(100, this)) { std::cerr << "Encoder: error setting breakpoint." << std::endl; } } void Encoder::callback() { switch (rs) { case rot_detent: assert(false); break; case rot_moving_cw: toggle_b(); rs = rot_detent; break; case rot_moving_ccw: toggle_a(); rs = rot_detent; break; } } #endif // HAVE_GUI gpsim-0.30.0/modules/logic.cc0000664000076400007640000003430313041763636012734 00000000000000/* Copyright (C) 2000 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* Logic.cc This is an example module library for interfacing with gpsim. In here you'll find some simple logic devices: AND2Gate - A 2-input AND gate OR2Gate - A 2-input OR gate */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../config.h" // get the definition for HAVE_GUI #include #ifdef HAVE_GUI #include /* XPM */ static const gchar * and2_pixmap[] = { "32 32 3 1", " c black", ". c None", "X c white", " ............", " ........", " XXXXXXXXXXXXXXXXXX ........", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXXXX ....", " XXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXX XXX XXX X XXXXXXX .", " XXXXX X XX XX XX XX XXXXXX .", " XXXX XXX X XX XX XX XXXXXXX ", " XXXX XXX X X X XX XX XXXXXXX ", " XXXX XXX X X X XX XX XXXXXXX ", " XXXX X XX XX XX XXXXXXX ", " XXXX XXX X XX XX XX XXXXXXX ", " XXXX XXX X XXX XX XX XXXXXXX ", " XXXX XXX X XXX X XXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXX ....", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXX ........", " ........", " ............"}; /* XPM */ static const gchar * or2_pixmap[] = { "32 32 3 1", " c black", ". c None", "X c white", " ............", " ........", " XXXXXXXXXXXXXXXXXX ........", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", ". XXXXXXXXXXXXXXXXXXXXXXX ....", ". XXXXXXXXXXXXXXXXXXXXXXX ...", ". XXXXXXXXXXXXXXXXXXXXXXXX ...", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXX XX XXXXXXXXX .", "... XXXXX XXX X XXX XXXXXXXX .", "... XXXXX XXX X XXX XXXXXXXXX ", "... XXXXX XXX X XXX XXXXXXXXX ", "... XXXXX XXX X XXXXXXXXXX ", "... XXXXX XXX X X XXXXXXXXXXX ", "... XXXXX XXX X XX XXXXXXXXXX ", "... XXXXX XXX X XXX XXXXXXXXX ", "... XXXXXX XX XXX XXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ". XXXXXXXXXXXXXXXXXXXXXXXX ...", ". XXXXXXXXXXXXXXXXXXXXXXX ...", ". XXXXXXXXXXXXXXXXXXXXXXX ....", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXX ........", " ........", " ............"}; static const gchar * xor2_pixmap[] = { "40 32 3 1", " c None", ". c black", "X c white", " .................... ", " .. .................... ", " .... ........................ ", " ... ..XXXXXXXXXXXXXXXXXX.... ", " ... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXX... ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXX.XXX.XX...XX....XXXXX.. ", " .. ..XXX.XXX.X.XXX.X.XXX.XXXX.. ", " .. ..XXXX.X.XX.XXX.X.XXX.XXXXX..", " .. ..XXXX.X.XX.XXX.X.XXX.XXXXX..", " ... ..XXXXX.XXX.XXX.X....XXXXXX..", " ... ..XXXX.X.XX.XXX.X.X.XXXXXXX..", " ... ..XXXX.X.XX.XXX.X.XX.XXXXXX..", " ... ..XXX.XXX.X.XXX.X.XXX.XXXXX..", " ... ..XXX.XXX.XX...XX.XXX.XXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " .. ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXX... ", " ... ..XXXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " ..... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXX.... ", " .. ........................ "}; static const gchar * not_pixmap[] = { "32 32 3 1", " c black", ". c None", "X c white", " ...............................", " .............................", " ...........................", " X ..........................", " XXX ........................", " XXXX ......................", " XXXXXX ....................", " XXXXXXXX ...................", " XXXXXXXXXX .................", " XXXXXXXXXXX ...............", " XXXXXXXXXXXXX ..............", " XXXXXXXXXXXXXXX ............", " XXXXXXXXXXXXXXXX ..... ..", " XXXXXXXXXXXXXXXXXX .. XXX .", " XXXXXXXXXXXXXXXXXXXX XXXXX ", " XXXXXXXXXXXXXXXXXXXXXX XXXXX ", " XXXXXXXXXXXXXXXXXXXX XXXXX ", " XXXXXXXXXXXXXXXXXXX .. XXX .", " XXXXXXXXXXXXXXXXX ..... ..", " XXXXXXXXXXXXXXX ...........", " XXXXXXXXXXXXXX .............", " XXXXXXXXXXXX ...............", " XXXXXXXXXXX ................", " XXXXXXXXX ..................", " XXXXXXX ...................", " XXXXXX .....................", " XXXX .......................", " XXX ........................", " X ..........................", " ...........................", " .............................", " ..............................."}; #endif #include #include #include "logic.h" #include "../src/packages.h" #include "../src/gpsim_interface.h" //-------------------------------------------------------------- // Led_Input // This class is a minor extension of a normal IO_input. I may // remove it later, but for now it does serve a simple purpose. // Specifically, this derivation will intercept when a stimulus // is being changed. void Logic_Input::setDrivenState( bool new_state) { if(verbose) std::cout << name()<< " setDrivenState= " << (new_state ? "high" : "low") << std::endl; if(new_state != getDrivenState()) { bDrivingState = new_state; bDrivenState = new_state; if(LGParent) { LGParent->update_input_pin(m_iobit, new_state); LGParent->update_state(); } } } #ifdef RRR void Logic_Input::get(char *return_str, int len) { if (return_str) strncpy(return_str, IOPIN::getState()?"1": "0", len); } void Logic_Output::get(char *return_str, int len) { if (return_str) strncpy(return_str, IOPIN::getDrivingState()?"1": "0", len); } #endif ANDGate::ANDGate(const char *name, const char *desc) : LogicGate(name, desc) { } ANDGate::~ANDGate() { } ORGate::ORGate(const char *name, const char *desc) : LogicGate(name, desc) { } ORGate::~ORGate() { } XORGate::XORGate(const char *name, const char *desc) : LogicGate(name, desc) { } XORGate::~XORGate() { } /************************************************************* * * LogicGate class */ LogicGate::LogicGate(const char *name, const char *desc) : Module(name, desc), number_of_pins(0), input_bit_mask(0), input_state(0), pInputPins(0), pOutputPin(0) { #ifdef HAVE_GUI pixbuf = NULL; #endif } LogicGate::~LogicGate() { #ifdef HAVE_GUI if (pixbuf) g_object_unref(pixbuf); #endif } //-------------------------------------------------------------- void LogicGate::update_input_pin(unsigned int pin, bool bValue) { unsigned int mask = 1<update_direction(1,true); // make the bidirectional an output // Position pin on middle right side of package package->set_pin_position(1,2.5); assign_pin(OUTPUT_BITPOSITION + 1, pOutputPin); Logic_Input *LIP; int j; pInputPins = (IOPIN **) new char[sizeof (IOPIN *) * (number_of_pins-1)]; string inname; for(i=j=INPUT_FIRST_BITPOSITION; iset_pin_position(i+1, 0.5); // Left side of package else package->set_pin_position(i+1, (float)((i-INPUT_FIRST_BITPOSITION)*0.9999)); // Left side of package addSymbol(LIP); assign_pin(i+1, LIP ); // Pin numbers begin at 1 } // Form the logic gate bit masks input_bit_mask = (1<< (number_of_pins-1)) - 1; //initializeAttributes(); } #ifdef HAVE_GUI static gboolean expose(GtkWidget *widget, GdkEventExpose *event, LogicGate *lg) { if (!lg->pixbuf) { puts("LogicGate has no pixmap"); return 0; } cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); gdk_cairo_set_source_pixbuf(cr, lg->pixbuf, 0.0, 0.0); cairo_paint(cr); cairo_destroy(cr); return 0; } GtkWidget *LogicGate::create_pixmap(const gchar **pixmap_data) { pixbuf = gdk_pixbuf_new_from_xpm_data(pixmap_data); int width = gdk_pixbuf_get_width(pixbuf); int height = gdk_pixbuf_get_height(pixbuf); GtkWidget *da = gtk_drawing_area_new(); gtk_widget_set_size_request(da, width, height); g_signal_connect(da, "expose_event", G_CALLBACK(expose), this); return da; } #endif //-------------------------------------------------------------- // construct Module * AND2Gate::construct(const char *_new_name) { AND2Gate *a2gP = new AND2Gate(_new_name) ; a2gP->set_number_of_pins(3); a2gP->create_iopin_map(); return a2gP; } AND2Gate::AND2Gate(const char *name) : ANDGate(name, "And2Gate") { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(and2_pixmap)); #endif } AND2Gate::~AND2Gate() { } void ANDGate::update_state() { pOutputPin->putState((input_state & input_bit_mask) == input_bit_mask); if (pOutputPin->snode) pOutputPin->snode->update(); } //-------------------------------------------------------------- // construct OR2Gate::OR2Gate(const char *name) : ORGate(name, "OR2Gate") { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(or2_pixmap)); #endif } OR2Gate::~OR2Gate() { } Module * OR2Gate::construct(const char *_new_name) { OR2Gate *o2gP = new OR2Gate(_new_name) ; o2gP->set_number_of_pins(3); o2gP->create_iopin_map(); return o2gP; } void ORGate::update_state() { pOutputPin->putState((input_state & input_bit_mask) != 0); } //-------------------------------------------------------------- // construct NOT Module * NOTGate::construct(const char *_new_name) { NOTGate *a2gP = new NOTGate(_new_name) ; a2gP->set_number_of_pins(2); a2gP->create_iopin_map(); a2gP->update_state(); return a2gP; } NOTGate::NOTGate(const char *name) : LogicGate(name, "NOTGate") { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(not_pixmap)); #endif } NOTGate::~NOTGate() { } void NOTGate::update_state() { if (verbose) std::cout << name() << " update_state\n"; pOutputPin->putState((input_state & input_bit_mask) == 0); } //-------------------------------------------------------------- // construct XOR2Gate::XOR2Gate(const char *name) : XORGate(name, "XOR2Gate") { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(xor2_pixmap)); #endif } XOR2Gate::~XOR2Gate() { } Module * XOR2Gate::construct(const char *_new_name) { XOR2Gate *o2gP = new XOR2Gate(_new_name); o2gP->set_number_of_pins(3); o2gP->create_iopin_map(); return o2gP; } void XORGate::update_state() { bool bNewOutputState=false; unsigned int mask=input_bit_mask; while(mask) { unsigned int lsb = (~mask + 1) & mask; mask ^= lsb; bNewOutputState ^= (lsb & input_state) ? true : false; } pOutputPin->putState(bNewOutputState); } gpsim-0.30.0/modules/i2c.h0000664000076400007640000001620413041763636012156 00000000000000/* Copyright (C) 2006 Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__I2C_H__) #define __I2C_H__ namespace I2C_Module { //------------------------------------------------------------------------ // I2C Attributes class I2C_TxBuffer; class I2C_TxReady; class I2C_RxBuffer; class I2C_RxSequence; class I2C_LogFile; class I2C_Send7BitAddress; class I2C_Stop; class I2C_Address; class I2C_Debug; class I2C_SCL_PIN; class I2C_SDA_PIN; class I2CMasterModule; //------------------------------------------------------------------------ // I2C interface // // The pure virtual I2C interface class is used by the I2CMaster // class to establish low-level communications. class I2CInterface { public: virtual ~I2CInterface() { } static void *master_interface(void *); virtual void run_tests()=0; }; //------------------------------------------------------------------------ // I2CMaster // // The I2CMaster can either a) simulate a master interface or b) provide support // for some external code that wishes to serve as a master. class I2CMaster : public TriggerObject, public Module { public: I2CMaster(const char *_name); virtual ~I2CMaster(); static Module *construct(const char *new_name); virtual void create_iopin_map(); void reset(RESET_TYPE); enum eI2CResult { eI2CResAck, // Slave acknowledged last transfer eI2CResNack, // Slave did not acknowledge last transfer eI2CResSuccess, // Last action succeeded eI2CResFailed, // Last action failed. eI2CResCollision, // }; /// There are only three things the I2CMaster hardware knows how /// to do: send start bits, send stop bits, transfer 8 data bits. /// Note that a read operation is performed when the byte '0xff' /// is written. eI2CResult sendStart(); eI2CResult sendStop(); eI2CResult send8BitData(unsigned int data); void send7BitAddress(unsigned addr); /// rising and falling SCL and SDA edges are captured: void new_scl_edge ( bool direction ); void new_sda_edge ( bool direction ); /// Breakpoint stuff virtual void callback(); virtual void callback_print(); virtual char const * bpName() { return "i2cmaster"; } /// When the start, stop or transfer state machines then these /// functions are called. (Classes derived from this one can /// capture this). virtual void startCompleted(); virtual void stopCompleted(); virtual void transferCompleted(); void debug(); /// I/O pins for the I2C bus IO_open_collector *m_pSCL; IO_open_collector *m_pSDA; protected: void wait_uSec(unsigned int uSec); void startIdle(); bool checkSDA_SCL(bool bSDA, bool bSCL); unsigned int m_bitCount; // Current bit number for either Tx or Rx unsigned int m_command; // Most recent command received from I2C host unsigned int m_xfr_data; // Transmit and receive shift register. unsigned int m_TxData; // Next data byte to transmit bool m_nextBit; // Next bit to be sent guint64 future_cycle; I2CMasterModule *m_pI2CModule; private: enum eI2CMicroState { eI2CIdle=0, // Micro states for Start eI2CStartA, // Trying to drive SDA low to begin start eI2CStartB, // Holding Start state (SDA=0, SCL=1) eI2CStartC, // Holding Start state (SDA=0, SCL=0) eI2CListenToAddress, // Some other master initiated a start. eI2CBusy, // Some other Master has control of the bus. // Micro states for Transfer eI2CTransferA, // Transfer- drove SCL low, waiting for it to fall eI2CTransferB, // Transfer- caught SCL low, waiting to update SDA eI2CTransferC, // Transfer- update SDA, wait to drive SCL high eI2CTransferD, // Transfer- drive SCL high, waiting for it to rise eI2CTransferE, // Transfer- caught SCL high, wait before driving low // Micro states for Stop eI2CStopA, // Stop - Waiting to drive SDA high. eI2CStopB, // Stop - drove SDA high Waiting for it to go high. } m_uState; enum eI2CMacroState { //eI2CStart, // In the process of sending a start bit. eI2CStop, // In the process of sending a stop bit eI2CTransfer, // In the prcoess of transferring a byte eI2CMaster, // Bus is idle but we're in control. eI2CSlave, // Bus is idle but we're not in control eI2CIdleBus // Bus is idle and no one owns it } m_mState; const unsigned int m_MSBmask; // MSB of transfer mask. Used in data transfers bool readBit(); void setNextMicroState(eI2CMicroState nextState, unsigned int waitTime); void setNextMacroState(eI2CMacroState nextState); // Define propogation delays. // tClkToData = time between when the I2C clock goes // low and when the I2C module will update it's data // output line. unsigned int tClkToData; // tClkToSample - time between when the I2C clock goes // low and when the I2C module will sample the data // line. unsigned int tClkToSample; /// token - the I2C master interfaces to the I2C client. The /// client runs in a different thread. token synchronizes the /// two threads. // gpsim::Token token; not implemented... /// debug stuff const char *microStateName(eI2CMicroState); const char *macroStateName(eI2CMacroState); /// I2C attribute for the Transmit buffer. Writing a byte to /// this attribute initiates an I2C transmit. I2C_TxBuffer *mTxByte; /// I2C attribute for transmit ready status. 'true' means the module /// is ready to transmit. I2C_TxReady *mTxReady; /// I2C Receive buffer. This holds the last byte received. I2C_RxBuffer *mRxByte; /// I2C Receive Sequence number. This increments everytime a byte is /// received. I2C_RxSequence *mRxSequence; /// I2C 7-bit Address: Writing to here initiates an I2C transaction I2C_Send7BitAddress *mSend7BitAddress; /// I2C 10-bit Address: Writing to here initiates an I2C transaction //I2C_Send10BitAddress *mSend10BitAddress; /// I2C Stop. Complete current transfer then issue a STOP bit I2C_Stop *mStop; /// I2C Module's address I2C_Address *mAddress; /// I2C debug I2C_Debug *mDebug; }; } // end of namespace #endif //!defined(__I2C_H__) gpsim-0.30.0/modules/i2c-eeprom.h0000664000076400007640000000317613041763636013447 00000000000000/* Copyright (C) 2006 T. Scott Dattalo Copyright (C) 2006 Roy R Rankin This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __I2C_EEPROM_H__ #define __I2C_EEPROM_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../src/modules.h" class I2C_EE; class PromAddress; namespace I2C_EEPROM_Modules { class I2C_ENABLE; class I2C_EE_Module : public Module { public: I2C_EE_Module(const char *_name); ~I2C_EE_Module(); static Module *construct_2k(const char *new_name); static Module *construct_16k(const char *new_name); static Module *construct_256k(const char *new_name); virtual void create_iopin_map(); virtual void setEnable(bool bNewState, unsigned int m_bit); protected: I2C_EE *m_eeprom; I2C_ENABLE *m_A[3]; I2C_ENABLE *m_wp; unsigned int chip_select; // Write Protect and A0 - A2 state PromAddress *att_eeprom; }; } // end of namespace I2C_EEEPROM_Modules #endif // __I2C_EEPROM_H__ gpsim-0.30.0/modules/README0000664000076400007640000000031513041763636012204 00000000000000gpsim modules This directory contains modules dynamically loaded by gpsim, but are not part of gpsim proper. Additional modules may be found on gpsim's web page: http://gpsim.sourceforge.net/gpsim.html gpsim-0.30.0/modules/led.h0000664000076400007640000000771713041763636012256 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __LED_H__ #define __LED_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include "../src/modules.h" namespace Leds { class LED_Interface; // Defined in led.cc class Led_Input; enum ActiveStates { HIGH, LOW }; enum Colors { RED = 0, ORANGE, GREEN, YELLOW, BLUE // Must be last }; //------------------------------------------------------------------------ // LED base class class Led_base { public: virtual ~Led_base() {} virtual void build_window() = 0; virtual void update() = 0; unsigned int interface_seq_no; }; //------------------------------------------------------------------------ // 7-segment leds // define a point typedef struct { double x; double y; } XfPoint; #define MAX_PTS 6 /* max # of pts per segment polygon */ #define NUM_SEGS 7 /* number of segments in a digit */ /* * These constants give the bit positions for the segmask[] * digit masks. */ #define TOP 0 #define TOP_RIGHT 1 #define BOT_RIGHT 2 #define BOTTOM 3 #define BOT_LEFT 4 #define TOP_LEFT 5 #define MIDDLE 6 //#define DECIMAL_POINT 7 typedef XfPoint segment_pts[NUM_SEGS][MAX_PTS]; class Led_7Segments : public Module, public Led_base { public: guint w_width; guint w_height; segment_pts seg_pts; GtkWidget *darea; Led_7Segments(const char *); ~Led_7Segments(); void build_segments( int w, int h); virtual void build_window(); virtual void update(); unsigned int getPinState(); // Inheritances from the Package class virtual void create_iopin_map(); // Inheritance from Module class const virtual char *type() { return ("led_7segments"); }; static Module *construct(const char *new_name); private: static gboolean led7_expose_event(GtkWidget *widget, GdkEvent *event, gpointer user_data); //unsigned int m_segmentStates; Led_Input *m_pins[8]; int m_nPins; }; //------------------------------------------------------------------------ // Simple LED // class ColorAttribute; class ActiveStateAttribute; class Led: public Module, public Led_base { public: GtkWidget *darea; GdkColor led_on_color[BLUE+1]; GdkColor led_segment_off_color; int w_width, w_height; Led(const char *); ~Led(); virtual void build_window(); virtual void update(); // Inheritances from the Package class virtual void create_iopin_map(); // Inheritance from Module class const virtual char *type() { return ("led"); }; static Module *construct(const char *new_name); Colors get_on_color() { return on_color; } void set_on_color(Colors color); ActiveStates get_the_activestate() { return the_activestate; } void set_the_activestate(ActiveStates activestate); private: static gboolean led_expose_event(GtkWidget *widget, GdkEvent *event, gpointer user_data); Led_Input *m_pin; Colors on_color; ColorAttribute *m_colorAttribute; ActiveStates the_activestate; ActiveStateAttribute *m_activestateAttribute; }; } // end of namespace Led #endif // __LED_H__ gpsim-0.30.0/modules/video.h0000664000076400007640000000456413041763636012615 00000000000000/* Copyright (C) 2003 Ralf Forsberg This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __VIDEO_H__ #define __VIDEO_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../src/stimuli.h" #include "../src/modules.h" #include class Video; class Video_Interface; class Processor; /********************************************************* * * Create a class derived from the IOPIN class that * will allow us to intercept when the I/O input is being * driven. (This isn't done for PIC I/O pins because the * logic for handling I/O pin changes resides in the ??? * class.) */ class IOPIN_Monitor : public IOPIN { private: Video *video; public: virtual void setDrivenState( bool new_state); IOPIN_Monitor (Video *v, const char *opt_name) : IOPIN(opt_name) , video(v) { } }; #define XRES 640 #define YRES 625 class Video : public Module { public: IOPIN * sync_pin; IOPIN * lume_pin; guint64 sync_time; // gpsim cycle counter at last H-sync int scanline; unsigned char line[XRES]; // buffer for one line unsigned char shadow[XRES][YRES]; // pixmap mirror Processor *cpu; GtkWidget *window; GtkWidget *da; cairo_surface_t *image; int line_nr; int last_line_nr; Video(const char *); ~Video(); // Inheritances from the Package class virtual void create_iopin_map(); virtual void update_state(); virtual int get_num_of_pins() {return 2;}; void copy_scanline_to_pixmap(); int check_for_vrt1(); int check_for_vrt2(); guint64 cycles_to_us(guint64 cycles); guint64 us_to_cycles(guint64 cycles); void refresh(); static Module *construct(const char *new_name); private: Video_Interface *interface; }; #endif // __VIDEO_H__ gpsim-0.30.0/modules/resistor.cc0000664000076400007640000001354013065573230013504 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* resistor.cc This is gpsim's resistor component. resistor pullup pulldown */ /* IN_MODULE should be defined for modules */ //#define IN_MODULE #include #include #include "../config.h" #ifdef HAVE_GUI #include #endif #include "resistor.h" #include "../src/stimuli.h" #include "../src/value.h" #include "../src/gpsim_interface.h" //---------------------------------------- class ResistanceAttribute : public Float { public: PullupResistor *pur; ResistanceAttribute(PullupResistor *ppur) : Float("resistance",0.0,"resistance value of the pullup"), pur(ppur) { if(pur) Float::set((pur->res)->get_Zth()); } virtual void set(double r) { Float::set(r); if(pur) { pur->res->set_Zpullup(r); pur->res->updateNode(); } }; void set(int r) { Float::set((double)r); }; }; //---------------------------------------- class CapacitanceAttribute : public Float { public: PullupResistor *pur; CapacitanceAttribute(PullupResistor *ppur) : Float("capacitance",0.0,"pin capacitance of pullup resistor"), pur(ppur) { if(pur) Float::set(pur->res->get_Cth()); } void set(double r) { Float::set(r); if(pur) { pur->res->set_Cth(r); pur->res->updateNode(); } }; void set(int r) { set(double(r)); }; }; //---------------------------------------- class VoltageAttribute : public Float { public: PullupResistor *pur; VoltageAttribute(PullupResistor *ppur) : Float("voltage",0.0,"Voltage of pullup resistor"), pur(ppur) { if(pur) Float::set(pur->res->get_Vpullup()); } void set(double r) { Float::set(r); if(pur) { pur->res->set_Vpullup(r); pur->res->updateNode(); } }; void set(int r) { set(double(r)); }; }; //-------------------------------------------------------------- // PullupResistor::create_iopin_map // void PullupResistor::create_iopin_map(void) { // The PullupResistor has only one pin. create_pkg(1); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created.The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. assign_pin(1, res); } //-------------------------------------------------------------- Module * PullupResistor::pu_construct(const char *_new_name) { PullupResistor *pur = new PullupResistor(_new_name, "Pullup Resistor"); pur->res->set_Vth(5.0); pur->res->set_Vpullup(5.0); return pur; } //-------------------------------------------------------------- Module * PullupResistor::pd_construct(const char *_new_name) { PullupResistor *pur = new PullupResistor(_new_name, "PullDown resistor", 0.0); pur->res->set_Vth(0); pur->res->set_Vpullup(0.0); return pur; } //-------------------------------------------------------------- PullupResistor::PullupResistor(const char *init_name, const char * desc, float vinit) : Module(init_name, desc) { string s; s = init_name; // set the module name if(init_name) { new_name(init_name); s.append(".pin"); } //rRRres = new IO_bi_directional_pu(s.c_str()); res = new IO_bi_directional_pu("pin"); res->set_Vpullup(vinit); create_iopin_map(); // Default module attributes. //initializeAttributes(); set_description("\ pullup resistor or generic voltage source\n\ Attributes:\n\ .resistance - pullup resistance\n\ .voltage - pullup or drive voltage\n\ .capacitance - pin capacitance\n\ "); if(verbose)cout << description() << endl; // Note ResistanceAttribute is designed to give access // to res.Zth with a symbol name of "modulename + '.resistance'". attr = new ResistanceAttribute(this); cattr = new CapacitanceAttribute(this); vattr = new VoltageAttribute(this); addSymbol(res); addSymbol(attr); addSymbol(cattr); addSymbol(vattr); attr->set(10e3); cattr->set(0.); res->setDriving(false); res->update_pullup('1',true); vattr->set(res->get_Vpullup()); #ifdef MANAGING_GUI pu_window = 0; if(get_interface().bUsingGUI()) build_window(); #endif } PullupResistor::~PullupResistor() { removeSymbol(attr); removeSymbol(cattr); removeSymbol(vattr); delete attr; delete cattr; delete vattr; } #ifdef MANAGING_GUI static void pu_cb(GtkWidget *button, gpointer pur_class) { PullupResistor *pur = (PullupResistor *)pur_class; } void PullupResistor::build_window(void) { GtkWidget *buttonbox; GtkWidget *button; pu_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); buttonbox = gtk_hbox_new(FALSE,0); gtk_container_add (GTK_CONTAINER (pu_window), buttonbox); gtk_container_set_border_width (GTK_CONTAINER (buttonbox), 1); button = gtk_button_new_with_label (name().c_str()); g_signal_connect(button, "clicked", G_CALLBACK(pu_cb), (gpointer)this); gtk_box_pack_start (GTK_BOX (buttonbox), button, TRUE, TRUE, 0); gtk_widget_show_all (pu_window); set_widget(pu_window); } #endif gpsim-0.30.0/modules/makefile.mingw0000664000076400007640000000273313041763636014152 00000000000000## Makefile for building the gpsim with gcc for mingw. The build ## uses tools running on cygwin, however. ## Use: make -f makefile.mingw TOP = ../.. include ../plat/win32/make.mingw ################################################################ # Nothing much configurable below LIBS = -L $(POPT_PATH)/lib -l popt \ -L $(PANGO_PATH)/lib -l pango-1.0 \ -L $(CAIRO_PATH)/lib -l cairo \ -L $(GDK_PIXBUF_PATH)/lib -l gdk_pixbuf-2.0 \ -L $(GTK_PATH)/lib -l gdk-win32-2.0 -l gtk-win32-2.0 \ -L $(GLIB_PATH)/lib -l glib-2.0 -l gobject-2.0 \ ../src/libgpsim.a INCLUDES = -I .. -I ../plat/win32 \ -I $(GLIB_PATH)/include/glib-2.0 -I $(GLIB_PATH)/lib/glib-2.0/include \ -I $(GTK_PATH)/include/gtk-2.0 -I $(GTK_PATH)/lib/gtk-2.0/include \ -I $(ATK_PATH)/include/atk-1.0 \ -I $(PANGO_PATH)/include/pango-1.0 \ -I $(CAIRO_PATH)/include/cairo \ -I $(GDK_PIXBUF_PATH)/include/gdk-pixbuf-2.0 DEFINES += -DHAVE_GUI all : \ ../config.h \ libgpsim_modules.dll modules_OBJECTS = \ gpsim_modules.o \ encoder.o \ i2c.o \ i2c2par.o \ i2c-eeprom.o \ led.o \ logic.o \ push_button.o \ resistor.o \ m_stimuli.o \ switch.o \ ttl.o \ usart.o \ video.o ../config.h : ../config_win32.h.in (cd .. ; $(AWK) -f plat/win32/configure_win32.awk config_win32.h.in > config.h) ################ The modules DLL libgpsim_modules.dll : $(modules_OBJECTS) $(CXX) $(CFLAGS) $(CLDFLAGS) -shared -o libgpsim_modules.dll ../plat/win32/modules.def $(modules_OBJECTS) $(LIBS) gpsim-0.30.0/modules/module_attribute.h0000664000076400007640000000260513041763636015051 00000000000000/* Copyright (C) 2014 Martin Habets This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #if !defined(__MODULE_ATTRIBUTES_H__) #define __MODULE_ATTRIBUTES_H__ #include "../src/value.h" /* The classes below are wrappers for simple values that must show up in * the breadboard settings. Without "Attribute" in the class name they won't. */ class BooleanAttribute : public Boolean { public: BooleanAttribute(const char *_name, bool newValue = false, const char *desc=0) : Boolean(_name, newValue, desc) { } }; class IntegerAttribute : public Integer { public: IntegerAttribute(const char *_name, gint64 newValue = 0, const char *desc=0) : Integer(_name, newValue, desc) { } }; #endif //if !defined(__MODULE_ATTRIBUTES_H__) gpsim-0.30.0/modules/led.cc0000664000076400007640000005072013041763636012404 00000000000000/* Copyright (C) 2000 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* led.cc This is an example module illustrating how gpsim modules may be created. Additional examples may also be found with the gpsim. This particular example creates a 7-segment, common cathode LED display. Pin Numbering of LED: -------------------- a --- f | g | b --- e | | c --- d cc = common cathode Electrical: ---------- a ---|>|---+ b ---|>|---+ c ---|>|---+ d ---|>|---+ e ---|>|---+ f ---|>|---+ g ---|>|---+ | cc How It Works: ------------ Once the Led module has been built (and optionally installed), you can include it in your .stc file. See the examples subdirectory. */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include #include #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #include #include "../src/stimuli.h" #include "../src/value.h" #include "../src/gpsim_interface.h" #include "led.h" #include "../src/packages.h" namespace Leds { //-------------------------------------------------------------- // // Create an "interface" to gpsim // class LED_Interface : public Interface { private: Led_base *led; public: virtual void SimulationHasStopped(gpointer object) { Update(object); } virtual void Update(gpointer object) { if(led) led->update(); } LED_Interface(Led_base *_led) : Interface((gpointer *) _led), led(_led) { } }; class Led_Input : public IOPIN { public: Led_Input(const std::string &n, Led_base *pParent); virtual void setDrivenState(bool); virtual void get(char *return_str, int len); private: Led_base *m_pParent; }; //------------------------------------------------------------------------ // Led_Input::Led_Input(const std::string &n, Led_base *pParent) : IOPIN(n.c_str()), m_pParent(pParent) { } void Led_Input::setDrivenState(bool bNewState) { IOPIN::setDrivenState(bNewState); } void Led_Input::get(char *return_str, int len) { if (return_str) strncpy(return_str, IOPIN::getState()?"1": "0", len); } //------------------------------------------------------------------------ void Led_7Segments::update() { if(get_interface().bUsingGUI()) gtk_widget_queue_draw(darea); } gboolean Led_7Segments::led7_expose_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { Led_7Segments *led = static_cast(user_data); g_return_val_if_fail (widget != NULL, TRUE); g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); guint max_width = allocation.width; guint max_height = allocation.height; // not a very O-O way of doing it... but here we go directly // to the I/O port and get the values of the segments int segment_states = led->getPinState(); cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, 0.0, 0.0, max_width, max_height); cairo_fill(cr); for (int i = 0; i < 7; ++i) { // common cathode, cathode must be low to turn //digits on. if ((segment_states & 1) == 0 && segment_states & (2 << i)) { cairo_set_source_rgb(cr, 0.75, 0.0, 0.0); } else { cairo_set_source_rgb(cr, 0.25, 0.0, 0.0); } XfPoint *pts = &(led->seg_pts[i][0]); cairo_move_to(cr, pts[0].x, pts[0].y); for (int j = 1; j < MAX_PTS; ++j) { cairo_line_to(cr, pts[j].x, pts[j].y); } cairo_line_to(cr, pts[0].x, pts[0].y); cairo_fill(cr); } cairo_destroy(cr); return TRUE; } //------------------------------------------------------------------- // build_segments // // from Dclock.c (v.2.0) -- a digital clock widget. // Copyright (c) 1988 Dan Heller // Modifications 2/93 by Tim Edwards // And further modifications by Scott Dattalo // // Each segment on the LED is comprised of a 6 point polygon. // This routine will calculate what those points should be and // store them an arrary. void Led_7Segments::build_segments( int w, int h) { XfPoint *pts; float spacer, hskip, fslope, bslope, midpt, seg_width, segxw; float invcosphi, invsinphi, invcospsi, invsinpsi, slope; float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy5, dy6; float xfactor, temp_xpts[4]; w_width = w; w_height = h; // Hard code the display parameters... float space_factor = 0.13; float width_factor = 0.13; float sxw = 0.13; float angle = 6; /* define various useful constants */ segxw = sxw * w; slope = angle; seg_width = width_factor * w; spacer = w * space_factor; hskip = seg_width * 0.125; fslope = 1 / (segxw/seg_width + 1/slope); bslope = -1 / (segxw/seg_width - 1/slope); midpt = h / 2; /* define some trigonometric values */ /* phi is the forward angle separating two segments; psi is the reverse angle separating two segments. */ invsinphi = sqrt(1 + fslope * fslope) / fslope; invcosphi = sqrt(1 + 1/(fslope * fslope)) * fslope; invsinpsi = sqrt(1 + bslope * bslope) / -bslope; invcospsi = sqrt(1 + 1/(bslope * bslope)) * bslope; /* define offsets from easily-calculated points for 6 situations */ dx1 = hskip * invsinphi / (slope/fslope - 1); dy1 = hskip * invcosphi / (1 - fslope/slope); dx2 = hskip * invsinpsi / (1 - slope/bslope); dy2 = hskip * invcospsi / (bslope/slope - 1); dx3 = hskip * invsinphi; dx4 = hskip * invsinpsi; dx5 = hskip * invsinpsi / (1 - fslope/bslope); dy5 = hskip * invcospsi / (bslope/fslope - 1); dx6 = dy5; dy6 = dx5; /* calculate some simple reference points */ temp_xpts[0] = spacer + (h - seg_width)/slope; temp_xpts[1] = spacer + (h - seg_width/2)/slope + segxw/2; temp_xpts[2] = spacer + h/slope + segxw; temp_xpts[3] = temp_xpts[0] + segxw; xfactor = w - 2 * spacer - h / slope - segxw; // calculate the digit positions pts = seg_pts[TOP]; pts[0].y = pts[1].y = 0; pts[0].x = temp_xpts[2] - dx3; pts[1].x = w - spacer - segxw + dx4; pts[2].y = pts[5].y = (seg_width / 2) - dy5 - dy6; pts[5].x = temp_xpts[1] + dx5 - dx6; pts[2].x = pts[5].x + xfactor; pts[3].y = pts[4].y = seg_width; pts[4].x = temp_xpts[3] + dx4; pts[3].x = temp_xpts[0] + xfactor - dx3; pts = &(seg_pts[MIDDLE][0]); pts[0].y = pts[1].y = midpt - seg_width/2; pts[0].x = spacer + (h - pts[0].y)/slope + segxw; pts[1].x = pts[0].x - segxw + xfactor; pts[2].y = pts[5].y = midpt; pts[3].y = pts[4].y = midpt + seg_width/2; pts[5].x = spacer + (h - pts[5].y)/slope + segxw/2; pts[2].x = pts[5].x + xfactor; pts[4].x = pts[0].x - seg_width/slope; pts[3].x = spacer + (h - pts[3].y)/slope + xfactor; pts = &(seg_pts[BOTTOM][0]); pts[3].y = pts[4].y = (float)h; pts[2].y = pts[5].y = h - (seg_width / 2) + dy5 + dy6; pts[0].y = pts[1].y = h - seg_width; pts[0].x = spacer + segxw + seg_width/slope + dx3; pts[1].x = spacer + (h - pts[1].y)/slope + xfactor - dx4; pts[4].x = spacer + segxw - dx4; pts[5].x = spacer + segxw/2 + (h - pts[5].y)/slope + dx6 - dx5; pts[2].x = pts[5].x + xfactor; pts[3].x = spacer + xfactor + dx3; pts = &(seg_pts[TOP_LEFT][0]); pts[0].y = seg_width / 2 - dy6 + dy5; pts[1].y = seg_width + dy2; pts[2].y = seg_pts[MIDDLE][0].y - 2 * dy1; pts[3].y = seg_pts[MIDDLE][5].y - 2 * dy6; pts[4].y = seg_pts[MIDDLE][0].y; pts[5].y = seg_width - dy1; pts[0].x = temp_xpts[1] - dx5 - dx6; pts[1].x = temp_xpts[3] - dx2; pts[2].x = seg_pts[MIDDLE][0].x + 2 * dx1; pts[3].x = seg_pts[MIDDLE][5].x - 2 * dx6; pts[4].x = spacer + (h - pts[4].y)/slope; pts[5].x = temp_xpts[0] + dx1; pts = &(seg_pts[BOT_LEFT][0]); pts[0].y = seg_pts[MIDDLE][5].y + 2 * dy5; pts[1].y = seg_pts[MIDDLE][4].y + 2 * dy2; pts[2].y = seg_pts[BOTTOM][0].y - dy1; pts[3].y = seg_pts[BOTTOM][5].y - 2 * dy6; pts[4].y = h - seg_width + dy2; pts[5].y = midpt + seg_width/2; pts[0].x = seg_pts[MIDDLE][5].x - 2 * dx5; pts[1].x = seg_pts[MIDDLE][4].x - 2 * dx2; pts[2].x = seg_pts[BOTTOM][0].x - dx3 + dx1; pts[3].x = seg_pts[BOTTOM][5].x - 2 * dx6; pts[4].x = spacer + seg_width / slope - dx2; pts[5].x = spacer + (midpt - seg_width/2) / slope; pts = &(seg_pts[TOP_RIGHT][0]); pts[0].y = seg_width/2 - dy5 + dy6; pts[1].y = seg_width - dy2; pts[2].y = midpt - seg_width/2; pts[3].y = midpt - 2 * dy5; pts[4].y = pts[2].y - 2 * dy2; pts[5].y = seg_width + dy1; pts[0].x = temp_xpts[1] + xfactor + dx5 + dx6; pts[1].x = temp_xpts[3] + xfactor + dx1; pts[2].x = seg_pts[MIDDLE][0].x + xfactor; pts[3].x = seg_pts[MIDDLE][5].x + xfactor + dx5 * 2; pts[4].x = seg_pts[TOP_LEFT][4].x + xfactor + dx2 * 2; pts[5].x = temp_xpts[0] + xfactor - dx1; pts = &(seg_pts[BOT_RIGHT][0]); pts[0].y = seg_pts[MIDDLE][2].y + 2 * dy6; pts[1].y = midpt + seg_width / 2; pts[2].y = h - seg_width + dy1; pts[3].y = h - (seg_width / 2) + dy6 - dy5; pts[4].y = h - seg_width - dy2; pts[5].y = seg_pts[MIDDLE][3].y + 2 * dy1; pts[0].x = seg_pts[MIDDLE][2].x + 2 * dx6; pts[1].x = seg_pts[MIDDLE][3].x + segxw; pts[2].x = seg_pts[BOTTOM][1].x + dx4 + segxw - dx1; pts[3].x = seg_pts[BOTTOM][2].x + 2 * dx5; pts[4].x = seg_pts[BOTTOM][1].x + dx4 + dx2; pts[5].x = seg_pts[MIDDLE][3].x - 2 * dx1; } void Led_7Segments::build_window() { darea = gtk_drawing_area_new(); gtk_widget_set_size_request(darea, 100, 110); g_signal_connect(darea, "expose_event", G_CALLBACK(led7_expose_event), this); gtk_widget_set_events(darea, GDK_EXPOSURE_MASK); gtk_widget_show(darea); set_widget(darea); } //-------------------------------------------------------------- Led_7Segments::Led_7Segments(const char *name) : Module(name, "7 Segment LED") { if(get_interface().bUsingGUI()) { build_segments(100, 110); build_window(); } interface_seq_no = get_interface().add_interface(new LED_Interface(this)); create_iopin_map(); } Led_7Segments::~Led_7Segments() { for(int i = 0; i < 8; i++) removeSymbol(m_pins[i]); get_interface().remove_interface(interface_seq_no); //RRRgtk_widget_destroy(darea); } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void Led_7Segments::create_iopin_map() { // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // // The 7-segment LED has 8 pins create_pkg(8); float ypos = 6.0; for (int i = 1; i <= 8; i++) { package->setPinGeometry(i, 0.0, ypos, 0, false); ypos += 12.; } // Here, we create and name the I/O pins. In gpsim, we will reference // the bit positions as LED.seg0, LED.seg1, ..., where LED is the // user-assigned name of the 7-segment LED m_pins[0] = new Led_Input("cc", this); addSymbol(m_pins[0]); assign_pin(1, m_pins[0]); int i; char ch; for (ch = '0', i = 1; i < 8; i++, ch++) { m_pins[i] = new Led_Input((string)"seg" + ch, this); addSymbol(m_pins[i]); assign_pin(i+1, m_pins[i]); } } //-------------------------------------------------------------- unsigned int Led_7Segments::getPinState() { unsigned int s = 0; for (int i = 1; i < 8; i++) { double delta_v = m_pins[i]->get_nodeVoltage() - m_pins[0]->get_nodeVoltage(); s = (s >> 1) | (delta_v > 1.5 ? 0x80 : 0); } return s; } //-------------------------------------------------------------- // construct Module * Led_7Segments::construct(const char *_new_name=0) { return new Led_7Segments(_new_name); } class ColorAttribute : public Value { public: ColorAttribute(Led *_led) : Value("color", "On color of LED"), m_led(_led) { } virtual void get(char *return_str, int len); virtual void set(const char *buffer, int buf_size = 0); virtual void set(Value *v); virtual bool Parse(const char *pValue, Colors &bValue); private: Led *m_led; }; void ColorAttribute::set(Value *v) { if ( typeid(*v) == typeid(String)) { char buff[20]; v->get(buff, sizeof(buff)); set(buff); } else throw new TypeMismatch(string("set "), "ColorAttribute", v->showType()); } void ColorAttribute::set(const char *buffer, int len) { if(buffer) { Colors color; if(Parse(buffer, color)) { m_led->set_on_color(color); } else { cout << "ColorAttribute::set " << buffer << " unknown color\n"; } } } void ColorAttribute::get(char *return_str, int len) { if(return_str) { switch(m_led->get_on_color()) { case RED: g_strlcpy(return_str, "red", len); break; case ORANGE: g_strlcpy(return_str, "orange", len); break; case GREEN: g_strlcpy(return_str, "green", len); break; case YELLOW: g_strlcpy(return_str, "yellow", len); break; case BLUE: g_strlcpy(return_str, "blue", len); break; } } } bool ColorAttribute::Parse(const char *pValue, Colors &bValue) { std::string s(pValue); if (s == "red") { bValue = RED; return true; } else if (s == "orange") { bValue = ORANGE; return true; } else if (s == "green") { bValue = GREEN; return true; } else if (s == "yellow") { bValue = YELLOW; return true; } else if (s == "blue") { bValue = BLUE; return true; } return false; } class ActiveStateAttribute : public Value { public: ActiveStateAttribute(Led *_led) : Value("ActiveState", "high or low"), m_led(_led) { } virtual void get(char *return_str, int len); virtual void set(const char *buffer, int buf_size = 0); virtual void set(Value *v); virtual bool Parse(const char *pValue, ActiveStates &bValue); private: Led *m_led; }; void ActiveStateAttribute::set(Value *v) { if ( typeid(*v) == typeid(String)) { char buff[20]; v->get(buff, sizeof(buff)); set(buff); } else throw new TypeMismatch(string("set "), "ActiveStateAttribute", v->showType()); } void ActiveStateAttribute::set(const char *buffer, int len) { if(buffer) { ActiveStates activestate; if(Parse(buffer, activestate)) { m_led->set_the_activestate(activestate); } else { cout << "ActiveStateAttribute::set " << buffer << " unknown active state\n"; } } } void ActiveStateAttribute::get(char *return_str, int len) { if(return_str) { switch(m_led->get_the_activestate()) { case HIGH: g_strlcpy(return_str, "high", len); break; case LOW: g_strlcpy(return_str, "low", len); break; } } } bool ActiveStateAttribute::Parse(const char *pValue, ActiveStates &bValue) { if(strncmp("high", pValue, sizeof("high")) == 0) { bValue = HIGH; return true; } else if (strncmp("low", pValue, sizeof("low")) == 0) { bValue = LOW; return true; } return false; } //------------------------------------------------------------- // Led (simple) //------------------------------------------------------------- void Led::update() { if (get_interface().bUsingGUI()) gtk_widget_queue_draw(darea); } void Led::set_on_color(Colors color) { if (color != on_color) { on_color = color; if (get_interface().bUsingGUI()) { update(); } } } void Led::set_the_activestate(ActiveStates activestate) { if (activestate != the_activestate) { if (activestate == HIGH) m_pin->set_Vth(0.); else m_pin->set_Vth(3.5); // includes LED voltage drop the_activestate = activestate; if (get_interface().bUsingGUI() ) { update(); } } } gboolean Led::led_expose_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { Led *led = static_cast(user_data); g_return_val_if_fail (widget != NULL, TRUE); g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); guint max_width = allocation.width; guint max_height = allocation.height; GdkWindow *gdk_win = gtk_widget_get_window(widget); cairo_t *cr = gdk_cairo_create(gdk_win); // Led is on when DrivenState=TRUE in current HIGH active state OR // when DrivenState=FALSE in current LOW active state. double delta_v ; if (led->get_the_activestate() == HIGH) delta_v = led->m_pin->get_nodeVoltage() - led->m_pin->get_Vth(); else delta_v = led->m_pin->get_Vth() - led->m_pin->get_nodeVoltage(); if (delta_v > 1.5) { gdk_cairo_set_source_color(cr, &led->led_on_color[led->on_color]); } else { gdk_cairo_set_source_color(cr, &led->led_segment_off_color); } cairo_arc(cr, max_width / 2, max_height / 2, max_width / 2, 0.0, 2 * G_PI); cairo_fill(cr); cairo_destroy(cr); return FALSE; } void Led::build_window() { darea = gtk_drawing_area_new (); w_height=20; w_width=20; gtk_widget_set_size_request(darea, w_height, w_width); g_signal_connect (darea, "expose_event", G_CALLBACK(led_expose_event), this); gtk_widget_set_events (darea, GDK_EXPOSURE_MASK); gtk_widget_show (darea); set_widget(darea); // The default 'on' color is bright red gdk_color_parse("red3", &led_on_color[RED]); gdk_color_parse("orange", &led_on_color[ORANGE]); gdk_color_parse("green", &led_on_color[GREEN]); gdk_color_parse("yellow", &led_on_color[YELLOW]); gdk_color_parse("blue", &led_on_color[BLUE]); // The `off' color is dark red led_segment_off_color.red = 0x4000; led_segment_off_color.green = 0x0000; led_segment_off_color.blue = 0x0000; } //-------------------------------------------------------------- Led::Led(const char *name) : Module(name, "Simple LED"), on_color(RED), the_activestate(HIGH) { create_iopin_map(); // the following will load the driver of the input as would a real // LED m_pin->set_Zth(150.); m_pin->set_Vth(0.); if (get_interface().bUsingGUI()) build_window(); m_colorAttribute = new ColorAttribute(this); addSymbol(m_colorAttribute); m_activestateAttribute = new ActiveStateAttribute(this); addSymbol(m_activestateAttribute); interface_seq_no = get_interface().add_interface(new LED_Interface(this)); } Led::~Led() { removeSymbol(m_pin); removeSymbol(m_colorAttribute); removeSymbol(m_activestateAttribute); get_interface().remove_interface(interface_seq_no); /* if (darea) gtk_widget_destroy(darea); darea = 0; */ delete m_activestateAttribute; delete m_colorAttribute; } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void Led::create_iopin_map() { create_pkg(1); // Position pin on left side of package package->set_pin_position(1,0.5); // Define the LED Cathode. (The anode is implicitly tied to VCC) m_pin = new Led_Input("in", this); addSymbol(m_pin); assign_pin(1, m_pin); } //-------------------------------------------------------------- // construct Module * Led::construct(const char *_new_name=0) { return new Led(_new_name); } } #endif //HAVE_GUI gpsim-0.30.0/modules/resistor.h0000664000076400007640000000334113041763636013351 00000000000000/* Copyright (C) 1998,1999,2000,2001 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __RESISTOR_H__ #define __RESISTOR_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #ifdef HAVE_GUI #include #else struct GtkToggleButton; #endif #include #include "../src/modules.h" #include "../src/stimuli.h" class ResistanceAttribute; class CapacitanceAttribute; class VoltageAttribute; class PullupResistor : public Module , public TriggerObject { public: IO_bi_directional_pu *res; #ifdef MANAGING_GUI GtkWidget *pu_window; #endif PullupResistor(const char *init_name=NULL, const char *desc=NULL, float vinit=5.0); ~PullupResistor(); // Inheritances from the Package class virtual void create_iopin_map(void); static Module *pu_construct(const char *new_name=NULL); static Module *pd_construct(const char *new_name=NULL); #ifdef MANAGING_GUI void build_window(void); #endif private: ResistanceAttribute *attr; CapacitanceAttribute *cattr; VoltageAttribute *vattr; }; #endif // __RESISTOR_H__ gpsim-0.30.0/modules/gpsim_modules.cc0000664000076400007640000001414413041763636014507 00000000000000/* Copyright (C) 1998,1999,2000 T. Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* gpsim_modules.cc gpsim supports modules, or thingies, that are not part of gpsim proper. This is to say, that the modules are not compiled and linked with the core gpsim software. Instead, they are compiled and linked separately and then dynamically loaded by gpsim. This approach provides a flexibility to the user to create customized objects for simulation purposes. The big benefit of course, is that the user doesn't have to get bogged down in to the nitty-gritty details of the way gpsim is designed. The templates provided here can serve as a relatively simple example of how one may go about creating customized modules. Please see the README.MODULES for more details on how modules are intended to be used. Here are a list of functions that a gpsim compliant module library should support: void mod_list(void) - Prints a list of the modules in a library Module_Types * get_mod_list(void) - Obtain pointer to the list of modules */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include #include #include #include "../config.h" // get the definition for HAVE_GUI #include "../src/modules.h" #include "resistor.h" #include "usart.h" #ifndef _WIN32 //#include "paraface.h" #endif #include "switch.h" #include "logic.h" #ifdef HAVE_GUI #include "led.h" #include "push_button.h" #include "video.h" #include "encoder.h" #endif #include "m_stimuli.h" #include "ttl.h" #include "i2c-eeprom.h" #include "i2c.h" #include "i2c2par.h" Module_Types available_modules[] = { #ifndef _WIN32 // Parallel port interface /* TSD - removed 16APR06 - The parallel port interface uses the deprecated IOPORT class. { {"parallel_interface", "paraface"}, Paraface::construct}, */ #endif // Switch { {"switch", "sw"}, Switches::Switch::construct}, // Logic { {"and2", "and2"}, AND2Gate::construct}, { {"or2", "or2"}, OR2Gate::construct}, { {"xor2", "xor2"}, XOR2Gate::construct}, { {"not", "not"}, NOTGate::construct}, #ifdef HAVE_GUI // Leds { {"led_7segments", "led7s"}, Leds::Led_7Segments::construct}, { {"led", "led"}, Leds::Led::construct}, { {"push_button", "pb"}, PushButton::construct }, #endif { {"PortStimulus", "ps"}, ExtendedStimuli::PortStimulus::construct8 }, { {"PortStimulus16", "ps"}, ExtendedStimuli::PortStimulus::construct16 }, { {"PortStimulus32", "ps"}, ExtendedStimuli::PortStimulus::construct32 }, { {"pullup", "pu"}, PullupResistor::pu_construct }, { {"pulldown", "pd"}, PullupResistor::pd_construct }, { {"pulsegen", "pg"}, ExtendedStimuli::PulseGen::construct }, { {"FileRecorder", "fr"}, ExtendedStimuli::FileRecorder::construct }, { {"FileStimulus", "fs"}, ExtendedStimuli::FileStimulus::construct }, #ifdef HAVE_GUI // PGS added back 23MAY10 // TSD Removed 17APR06 // Video { {"PAL_video", "video"}, Video::construct}, // Encoder { {"Encoder", "encoder"}, Encoder::construct}, #endif // USART { {"usart", "usart"}, USARTModule::USART_construct}, // TTL devices { {"TTL165", "ttl165"}, TTL::TTL165::construct}, { {"TTL377", "ttl377"}, TTL::TTL377::construct}, { {"TTL595", "ttl595"}, TTL::TTL595::construct}, // I2c EEPROM { {"I2C-EEPROM2k", "e24xx024"}, I2C_EEPROM_Modules::I2C_EE_Module::construct_2k}, { {"I2C-EEPROM16k", "e24xx16b"}, I2C_EEPROM_Modules::I2C_EE_Module::construct_16k}, { {"I2C-EEPROM256k", "e24xx256"}, I2C_EEPROM_Modules::I2C_EE_Module::construct_256k}, { {"i2cmaster", "I2CMaster"}, I2C_Module::I2CMaster::construct }, { {"i2c2par", "I2C2PAR"}, I2C2PAR_Modules::i2c2par::construct }, // No more modules { {0,0},0} }; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /******************************************************************************** * mod_list - Display all of the modules in this library. * * This is a required function for gpsim compliant libraries. */ Module_Types * get_mod_list(void) { return available_modules; } /******************************************************************************** * mod_list - Display all of the modules in this library. * * This is a required function for gpsim compliant libraries. */ void mod_list(void) { unsigned int number_of = sizeof(available_modules) / sizeof(Module_Types); unsigned int i,j,l; unsigned int k,longest; for(i=0,longest=0; ilongest) longest = k; } k=0; do { for(i=0; (i<4) && (k. */ #ifndef __ENC_H__ #define __ENC_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../src/ioports.h" #include "../src/symbol.h" #include "../src/trace.h" #include "../src/modules.h" #include class Encoder : public Module, private TriggerObject { void create_widget(Encoder *enc); public: IOPIN *a_pin; IOPIN *b_pin; Encoder(const char *); ~Encoder(void); void test(void); void update(void); /* Send clockwise pulses */ void send_cw(void); /* Send anticlockwise pulses */ void send_ccw(void); // Inheritances from the Package class virtual void create_iopin_map(void); // Inheritance from Module class const virtual char *type(void) { return ("encoder"); }; static Module *construct(const char *new_name); private: enum rotate_state { rot_detent, rot_moving_cw, rot_moving_ccw }; rotate_state rs; void toggle_a(); void toggle_b(); void schedule_tick(); void callback(); }; #endif // __ENC_H__ gpsim-0.30.0/modules/i2c.cc0000664000076400007640000010067113045306453012310 00000000000000/* Copyright (C) 2006 Scott Dattalo This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* i2c.cc I2C Module for gpsim OVERVIEW: The I2C Module is a plugin module for gpsim (the gnupic simulator) that implements the I2C protocol. BACKGROUND: Application Layer ----------------- The application layer is responsible for interpreting and generating packets. Physical Layer: -------------- The physical layer consists of two wires that model the I2C bus SCL - Open Collector SDA - Open Collector Changes on these lines due to external stimuli will be propogated up to the Datalink Layer. Similarly, the Datalink layer will relay changes in the application layer to the I/O pins Implementation Details ---------------------- The I2C module is designed to be a dynamic library that is loaded by gpsim. A typical scenario would be to start gpsim, load a processor, load the I2C module and connect the I2C module to the processor. The I2C module communicates to the simulator through 3 different mechanisms. First, the I/O pins of the I2C module are manipulated; e.g. the SCL and SDA lines swing low and high. This is a low level physical-type interface. Second, gpsim has a callback mechanism tied into it's real-time timer. The I2C module will set 'callback breakpoints' to occur at specific instances of time. Finally, the last method of communication is through simulator attributes. *** FIXME *** gpsim is a single-threaded software application. This makes it somewhat difficult to implement the state machines in the I2C module. So to get around this problem, the I2C module will spawn a thread for the application layer. In essence, this thread will allow a set of functions to be written that can send and receive byte streams. pThread mutexs will ensure that this thread safely communicates with the I2C state machines that run in the context of the simulator thread. */ //------------------------------------------------------------------------ // I2C State Machines // // The I2C state machines are responible for the physical layer of the I2CMaster. // Here is the general timing of an I2C transaction: // // ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ __ // SDA \__/___X___X___X___X___X___X___\_________/___X___X___X___X___X___X___X___/ \__/ // S A7 A6 A5 A4 A3 A2 A1 R/W ACK D7 D6 D5 D4 D3 D2 D1 D0 /ACK P // ____ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ____ // SCL \__/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\_/9\___/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\_/9\_/ // // S = Start // P = Stop // Ai - Address bits // Di - Data bits // R/W - Read or Write. A low means write, i.e. transmission from master to slave // ACK - Acknowledge. The slave holds SDA low to acknowledge the previous transfer // // The gpsim I2C controller breaks the transaction down into smaller // pieces and utilizes state machines for each piece. At the lowest // level, there are three state machines: Start-bit, Stop-bit, and // Data-bit. At the next higher level, is the byte transfer state // machine. And finally, at the highest level is the stream transfer // state machine. // // The start, stop, and data bit state machines use combinations of // timing events and I/O events as inputs for state transitions. For // example, a start bit begins with the bus idle (SDA and SCL both // high) and then with the master driving SDA low. There could be a // delay between SDA being driven low and it actually falling low // (e.g. excessive bus capacitamce or bus hardware error). So the // state machine doesn't make a transition into the start state until // SDA is actually falls low. Similarly, when a bit is being // transmitted, the I2C specification requires certain setup and hlod // times between SDA and SCL. A gpsim cycle callback ensures these // timings are met and the state machine transitions only after the // callback triggers. // // // Start bit State Machine: // ____________________ // SDA \_____________ // __________________________________ // SCL // idle | sendingStart | Start // // The host controller is notified 1uS after SDA goes low. // // // Data bit transfer State Machine: // _____________________________________ __________________________ // bus SDA_____________________________________X__________________________ // ____________________ ________ // bus SCL \__________________________________/ // ________________________________ _______________________________ // SDA________________________________X_______________________________ // __________ ____________________ // SCL \________________________________/ // // TransferE TransferA TransferB TransferC TransferD TransferE // // There are 5 states in the bit-transmit state machine: // // TransferA -- SCL has been driven low and we're waiting for it to fall // TransferB -- SCL has fallen low. We're now waiting t_HD;DAT before driving SDA // TransferC -- SDA has been driven with new data. Now wait t_SU;DAT to release SCL // TransferD -- SCL has been released and we're waiting for it to rise // TransferE -- SCL has risen high. The bit has been transferred. // // // Stop bit State Machine // ---------------------- // // __________ __________ _________ // bus SDA__________X__________\_______________/ // _______________________________________________ // bus SCL__________X__________/ // _____________________ _________________ // SDA__________X__________\_______/ // __________ ____________________________________ // SCL__________X__________/ // // any state Transfer StopA StopB Idle // SDA = 0 // // any state - The stop bit can be initiated at any point. When the // request to send a stop bit is made, the state machine is forced // into the "transfer a bit state". The bit transferred is a // '0'. Once this transition completes, the state machine enters the // Stop bit state machine. // // StopA - SCL is High SDA is Low. Waiting t_HD;DAT before driving SDA high // StopB - SDA has been released and we're waiting for it to rise. // Idle - SDA has been risen high. The master is notified // #include #include #include #include #include "../src/stimuli.h" #include "../src/modules.h" #include "../src/gpsim_time.h" #include "../src/ui.h" #include "i2c.h" //using namespace gpsim; //using namespace I2C_Module namespace I2C_Module { //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%5d:%s ",__LINE__,__FUNCTION__); printf arg; } #else #define Dprintf(arg) {} #endif //static int verbose =1; #define Vprintf(arg) { if (verbose) {printf("%s:%d ",__FILE__,__LINE__); printf arg;} } #ifndef PRINTF_INT64_MODIFIER #ifndef WIN32 #define PRINTF_INT64_MODIFIER "ll" #endif #endif FILE *g_TraceOut = stdout; // A pointer to the simulator's global defined cycle counter class: // (there's an issue with DLL's directly accessing globally declared // objects, so we'll use an accessor function to get a pointer to them // [or in this case, it]) Cycle_Counter *gcycles = 0; //---------------------------------------- #if 0 // defined but not used static double get_time() { double t = (double) gcycles->get(); t /= 2.0; double r = floor(t/1e6); t -= r*1e6; return t; } #endif //------------------------------------------------------------------------ #define isSCLlow() (m_pSCL->getDrivenState() == false) #define isSCLhigh() (m_pSCL->getDrivenState() == true) #define isSDAlow() (m_pSDA->getDrivenState() == false) #define isSDAhigh() (m_pSDA->getDrivenState() == true) //------------------------------------------------------------------------ // I2CPin // // An I2C I/O pin is a bidirectional I/O pin that has a strong driver // for a low state, but a weak driver for the high state. There are // several ways to model that behavior in gpsim. The way chosen here // is to derive from the IO_open_collector class and to modify the // high and low drive output impedances. // // class I2C_PIN : public IO_open_collector { public: I2C_PIN(I2CMaster *pMaster, const char *_name) : IO_open_collector(_name), m_pI2Cmaster(pMaster) { bDrivingState = true; bDrivenState = true; update_direction(IO_bi_directional::DIR_OUTPUT,true); // Set the pullup resistance to 10k ohms: set_Zpullup(10e3); update_pullup('1', // Turn on the pullup resistor. false); // Don't update the node. (none is attached). } void debug() { cout << name() << " digital_state=" << (getDrivingState() ? "high" : "low") << " Vth=" << get_Vth() << " Zth=" << get_Zth() << " driving=" << (getDriving() ? "true" : "false") << endl; } bool isLow() { return bDrivingState == false && bDrivenState == false; } bool isHigh() { return bDrivingState == true && bDrivenState == true; } void setDrivingState(bool new_state) { bDrivingState = new_state; //bDrivenState = new_state; if(snode) snode->update(); } protected: // Parent module I2CMaster *m_pI2Cmaster; }; //------------------------------------------------------------------------ class I2C_SDA_PIN : public I2C_PIN { public: I2C_SDA_PIN (I2CMaster *pMaster, const char *_name) : I2C_PIN (pMaster,_name) { } virtual void setDrivenState(bool new_dstate) { bool diff = new_dstate ^ bDrivenState; Dprintf(("I2C SDA setDrivenState %d diff %d\n", new_dstate,diff)); if( m_pI2Cmaster && diff ) { bDrivenState = new_dstate; m_pI2Cmaster->new_sda_edge(new_dstate); } } }; //------------------------------------------------------------------------ class I2C_SCL_PIN : public I2C_PIN { public: I2C_SCL_PIN (I2CMaster *pMaster, const char *_name) : I2C_PIN (pMaster,_name) { } virtual void setDrivenState(bool new_state) { bool diff = new_state ^ bDrivenState; Dprintf(("I2C SCL setDrivenState %d\n", new_state)); if( m_pI2Cmaster && diff ) { bDrivenState = new_state; m_pI2Cmaster->new_scl_edge(bDrivenState); } } }; //------------------------------------------------------------------------ // I2C attributes // // The I2C attributes expose an interface to the I2C module. Each attribute // can be treated as a variable that a user (or a script) can access. // There are two C++ methods used for assigning new values. The first // is the 'set()' method defined in the Value base class. This is the one // used whenever the user assigns values. The other method is setFromMaster(). // This used whenever the value is changed by the I2C state machine. // //------------------------------------------------------------------------ // I2C_TxBuffer // Data written to this attribute will get transmitted to the client (TouchPad) // class I2C_TxBuffer : public Integer { I2CMaster *i2c; public: I2C_TxBuffer(I2CMaster *); virtual void set(gint64); void setFromMaster(gint64); }; // I2C_TxReady // This read-only attribute let's the user know if the TxBuffer is ready // to accept another byte. class I2C_TxReady : public Boolean { I2CMaster *i2c; public: I2C_TxReady(I2CMaster *); virtual void set(bool); void setFromMaster(bool); }; // I2C_RxBuffer // Holds the last byte received from the client. class I2C_RxBuffer : public Integer { I2CMaster *i2c; public: I2C_RxBuffer(I2CMaster *); virtual void set(gint64); void setFromMaster(gint64); }; // I2C_RxSequence // gpsim attaches a sequence number to every received byte. This // attribute allows the user to query that number. class I2C_RxSequence : public Integer { I2CMaster *i2c; public: I2C_RxSequence(I2CMaster *); virtual void set(gint64); void setFromMaster(gint64); }; // I2C_Send7BitAddress class I2C_Send7BitAddress : public Integer { I2CMaster *i2c; public: I2C_Send7BitAddress(I2CMaster *); virtual void set(gint64); void setFromMaster(gint64); }; // I2C_Stop class I2C_Stop : public Boolean { I2CMaster *i2c; public: I2C_Stop(I2CMaster *); virtual void set(bool); void setFromMaster(bool); }; // I2C_Address class I2C_Address : public Integer { I2CMaster *i2c; public: I2C_Address(I2CMaster *); virtual void set(gint64); // void setFromMaster(gint64); }; // I2C_Address class I2C_Debug : public Integer { I2CMaster *i2c; public: I2C_Debug(I2CMaster *); virtual void set(gint64); // void setFromMaster(gint64); }; //------------------------------------------------------------------------ // I2CMaster::I2CMaster(const char *_name) : TriggerObject(), Module (_name), m_bitCount(0), m_command(0), m_xfr_data(0), future_cycle(0), m_uState(eI2CIdle), m_mState(eI2CIdleBus), m_MSBmask(1<<8) { // Transmit and Receive propogation delays // The units are simulation cycles. tClkToData = 10; tClkToSample = 10; m_pSCL = new I2C_SCL_PIN(this, "scl"); addSymbol(m_pSCL); m_pSDA = new I2C_SDA_PIN(this, "sda"); addSymbol(m_pSDA); mTxByte = new I2C_TxBuffer(this); mTxReady = new I2C_TxReady(this); mRxByte = new I2C_RxBuffer(this); mRxSequence = new I2C_RxSequence(this); mSend7BitAddress = new I2C_Send7BitAddress(this); mStop = new I2C_Stop(this); mAddress = new I2C_Address(this); mDebug = new I2C_Debug(this); //initializeAttributes(); addSymbol(mTxByte); addSymbol(mTxReady); addSymbol(mRxByte); addSymbol(mRxSequence); addSymbol(mSend7BitAddress); addSymbol(mStop); addSymbol(mAddress); addSymbol(mDebug); // We may also want a logging function... } I2CMaster::~I2CMaster() { removeSymbol(mTxByte); removeSymbol(mTxReady); removeSymbol(mRxByte); removeSymbol(mRxSequence); removeSymbol(mSend7BitAddress); removeSymbol(mStop); removeSymbol(mAddress); removeSymbol(mDebug); removeSymbol(m_pSCL); removeSymbol(m_pSDA); delete mTxByte; delete mTxReady; delete mRxByte; delete mRxSequence; delete mSend7BitAddress; delete mStop; delete mAddress; delete mDebug; } void I2CMaster::startIdle() { m_pSDA->setDrivingState(true); m_pSCL->setDrivingState(true); m_uState = eI2CIdle; setNextMacroState(eI2CIdleBus); } bool I2CMaster::checkSDA_SCL(bool bSDA, bool bSCL) { Dprintf((" SDA %d--%d SCL %d--%d\n", m_pSDA->getDrivenState(),bSDA, m_pSCL->getDrivenState(),bSCL)); if (m_pSCL->getDrivenState() == bSCL && m_pSDA->getDrivenState() == bSDA) { Dprintf((" Match\n")); return true; } startIdle(); return false; } //------------------------------------------------------------------------ // callback() - timer callbacks // // The I2C state machines insert wait states and set timeouts. When // these trigger, control is sent here. // void I2CMaster::callback() { Dprintf(("\n")); debug(); // We get here because at some point in the past // we made the request to receive control at this point // in time. So find out what it was: future_cycle=0; switch (m_uState) { case eI2CStartB: if (checkSDA_SCL(false, true)) { setNextMicroState(eI2CStartC, 1000); m_pSCL->setDrivingState(false); return; } break; case eI2CTransferB: // First half of bit transfer where we're driving the clock // If SCL high, then there's something clamping it high (that's a // bus error). // If SCL is low then we'll drive out the new data bit and wait // a few uSec before driving SCL high again if (isSCLlow()) { setNextMicroState(eI2CTransferC, 5); m_pSDA->setDrivingState(m_nextBit); return; } case eI2CTransferC: // Second half of bit transfer. We've just placed the new data bit // onto SDA. SCL should still be low. If it isn't, then there's // something clamping it high (and that's a bus error). // If SCL is low, then we'll drive it high and set a 1mSec time // out. When SCL rises, we'll capture the edge and advance the // state machine. if (isSCLlow()) { setNextMicroState(eI2CTransferD, 1000); m_pSCL->setDrivingState(true); return; } case eI2CTransferE: if (isSCLhigh()) { setNextMicroState(eI2CTransferA, 1000); m_pSCL->setDrivingState(false); return; } case eI2CStopA: if (checkSDA_SCL(false, true)) { setNextMicroState(eI2CStopB, 1000); m_pSDA->setDrivingState(true); } default: // Disable the bus ; } // We reach here if either there was a timeout or // an error in the state machine. startIdle(); } void I2CMaster::callback_print() { cout << "I2CMaster " << CallBackID << '\n'; } //------------------------------------------------------------------------ // readBit() // // Should only be called when SCL is caught rising high. // // readBit() shifts the TransferData register left 1 position and // copies the state of SDA to the LSB position. The MSB shifted out // becomes the nextBit that will be transmitted (that bit is written // to SDA later on). // bool I2CMaster::readBit() { if (m_bitCount) { m_xfr_data <<= 1; m_xfr_data |= m_pSDA->getDrivenState() ? 1 : 0; m_bitCount--; m_nextBit = (m_xfr_data & m_MSBmask) == m_MSBmask; Dprintf(("I2CMaster SCL : Rising edge, data in=%u, nextOut=%d bit_count=%u\n", m_xfr_data & 1, m_nextBit, m_bitCount)); return true; } return false; } const char *I2CMaster::microStateName(eI2CMicroState state) { switch (state) { case eI2CIdle: return "eI2CIdle"; case eI2CStartA: return "eI2CStartA"; case eI2CStartB: return "eI2CStartB"; case eI2CStartC: return "eI2CStartC"; case eI2CBusy: return "eI2CBusy"; case eI2CTransferA: return "eI2CTransferA"; case eI2CTransferB: return "eI2CTransferB"; case eI2CTransferC: return "eI2CTransferC"; case eI2CTransferD: return "eI2CTransferD"; case eI2CTransferE: return "eI2CTransferE"; case eI2CStopA: return "eI2CStopA"; case eI2CStopB: return "eI2CStopB"; default: ; } return "eI2Cunknown"; } const char *I2CMaster::macroStateName(eI2CMacroState state) { switch (state) { case eI2CStop: return "eI2CStop"; case eI2CTransfer: return "eI2CTransfer"; case eI2CMaster: return "eI2CMaster"; case eI2CSlave: return "eI2CSlave"; case eI2CIdleBus: return "eI2CIdleBus"; default: ; } return "eI2Cunknown"; } void I2CMaster::debug() { #if defined(DEBUG) cout << " SDA:" << m_pSDA->getDrivenState() << " SCL:" << m_pSCL->getDrivenState() << " microstate:" << microStateName(m_uState) << " macrostate:" << macroStateName(m_mState) << endl; cout << " xfr_data:" << hex << m_xfr_data << " bits:" << m_bitCount << " next bit:" << m_nextBit << " fc: 0x" << future_cycle << endl; #endif } //------------------------------------------------------------------------ // new_scl_edge ( bool direction ) // // Handle SCL transitions // void I2CMaster::new_scl_edge(bool direction) { int curBusState = m_uState; if (verbose) { Vprintf(("I2CMaster::new_scl_edge: %d\n",direction)); debug(); } if ( direction ) { // Rising edge switch (m_uState) { case eI2CTransferD: if (readBit()) setNextMicroState(eI2CTransferE, 5); else if (m_mState == eI2CTransfer) transferCompleted(); else if (m_mState == eI2CStop) setNextMicroState(eI2CStopA, 5); break; case eI2CStopB: // Stop is complete. if (m_mState == eI2CStop) { setNextMacroState(eI2CIdleBus); stopCompleted(); } default: ; } } else { // Falling edge Dprintf(("I2CMaster SCL : Falling edge,data=%d\n ",m_nextBit)); debug(); switch ( m_uState ) { case eI2CIdle : m_pSDA->setDrivingState(true); break; case eI2CStartC: case eI2CStartB: setNextMicroState(eI2CTransferC, 1000); // If the clock went low because of someone else, still clamp. m_pSCL->setDrivingState(false); // Start bit has been sent. SDA and SCL are both low. // hold the start state for a short moment startCompleted(); break; case eI2CTransferA: // We're driving the clock and have just managed to pull it // low. Now set up to drive the next data bit (if we're reading // then the next data bit is a '1'). if (m_bitCount) setNextMicroState(eI2CTransferB, 5); else transferCompleted(); break; default : m_pSDA->setDrivingState(true); // Release the bus break; } } if ((bool)verbose && m_uState != curBusState) { Vprintf(("I2C_EE::new_scl_edge() new bus state = %d\n",m_uState)); debug(); } } //------------------------------------------------------------------------ // new_sda_edge ( bool direction ) // // Handle SDA transitions // void I2CMaster::new_sda_edge ( bool direction ) { Dprintf(("I2CMaster::new_sda_edge: direction:%d\n",direction)); debug(); if ( m_pSCL->getDrivenState() ) { // SCL is high. // If SDA just went low, then we caught a start // If SDA just went high, then we caught a stop. if ( direction ) { // stop bit Dprintf(("I2CMaster SDA : Rising edge in SCL high => stop bit\n")); m_uState = eI2CIdle; } else { // start bit Dprintf(("I2CMaster SDA : Falling edge in SCL high => start bit\n")); if ( m_uState != eI2CStartA ) { Dprintf((" Another Master has started a transaction\n")); // Release SDA and listen to the address m_pSDA->setDrivingState(true); m_uState = eI2CListenToAddress; } else { // Wait 1us before notifying the module. setNextMicroState(eI2CStartB, 5); m_bitCount = 0; m_xfr_data = 0; } } } else { // SCL is low - SDA changed states. We need to make sure the SDA // state matches the SDA state we're driving. If they're different // then that means some other I2C device changed the SDA // state. We need to wait until SCL changes states before // declaring some other master has control. //if (direction != m_nextBit) // cout << "Warning SDA unexpectedly changed to: " << direction << endl; // Another thing we can do is record the time when SDA changed. // This could be useful for recording slave response times. // For now, we do nothing: ; } } void I2CMaster::reset(RESET_TYPE r) { if(future_cycle) { gcycles->clear_break(this); future_cycle = 0; } startIdle(); #if defined(DEBUG) cout << "I2CMaster reset\n"; debug(); #endif } //------------------------------------------------------------------------ // sendStart // If the bus is idle, send a start bit. // I2CMaster::eI2CResult I2CMaster::sendStart() { if ( m_uState == eI2CIdle) { // Drive SDA low and set a 1mS timeout setNextMicroState(eI2CStartA, 1000); m_pSDA->setDrivingState ( false ); return eI2CResSuccess; } return eI2CResFailed; } //------------------------------------------------------------------------ // sendStop() - unconditionally initiate the 'stop' state machine // // Depending on the current state of the I2C bus, the stop state // machine will transition the I2C bus so that a stop bit can be // sent. In all cases, the bus needs to be in the state where SCL is // high and SDA is low. The stop bit occurs when SDA is then driven // high. // // There are 4 possibilities: // SCL=0 SDA=0 - need to drive SCL high // SCL=0 SDA=1 - drive SDA low followed by SCL high // SCL=1 SDA=0 - drive SDA high ==> this will be the stop bit // SCL=1 SDA=1 - drive SCL low followed by SDA low then SCL high. // I2CMaster::eI2CResult I2CMaster::sendStop() { // Can't send a stop if we're a slave. if (m_mState == eI2CStop || m_mState == eI2CSlave) return eI2CResFailed; setNextMacroState(eI2CStop); if (isSCLhigh()) { // && m_pSCL->getDrivingState()) { if (isSDAhigh()) { // SCL is high, SDA high. m_bitCount = 0; m_xfr_data = 0; m_nextBit = false; setNextMicroState(eI2CTransferA, 5); m_pSCL->setDrivingState(false); } else { // SCL is high, SDA low -- perfect. // Now we only need to drive SDA high and we're done. setNextMicroState(eI2CStopA, 5); } } else { if (isSDAhigh()) { // SCL low, SDA high // We need to drive SDA low followed by SCL high. setNextMicroState(eI2CTransferC, 5); m_pSDA->setDrivingState(false); } else { // SCL low, SDA low // We need to drive SCL high. setNextMicroState(eI2CTransferD, 5); m_pSCL->setDrivingState(true); } } return eI2CResSuccess; } //------------------------------------------------------------------------ // send8BitData(unsigned int data) // // The 'Transfer' state machine is initialized here. A transfer can // only commence if we've seen a start (or have just completed a // transfer earlier). SCL should be sitting low. I2CMaster::eI2CResult I2CMaster::send8BitData(unsigned int data) { Dprintf((" send8BitData:0x%x\n",data)); if (isSCLlow()) { mStop->setFromMaster(false); setNextMacroState(eI2CTransfer); m_bitCount = 9; // There are 8 data bits and 1 ACK bit m_xfr_data = (data<<1) | 1; // LSB = 1 ==> we'll release SDA // during ACK m_nextBit = (data & m_MSBmask) == m_MSBmask; // We could also remember how long it's been since SCL has gone // low and possibly wait a shorter amount of time. setNextMicroState(eI2CTransferB, 5); } return eI2CResFailed; } //------------------------------------------------------------------------ // wait_uSec - suspends the I2C state machine. // void I2CMaster::wait_uSec(unsigned int uSec) { guint64 fc = gcycles->get() + (uSec * 2); if(future_cycle) gcycles->reassign_break(future_cycle, fc, this); else gcycles->set_break(fc, this); future_cycle = fc; } //------------------------------------------------------------------------ // void I2CMaster::setNextMicroState(eI2CMicroState nextState, unsigned int waitTime) { Dprintf((" curr:%s next:%s\n",microStateName(m_uState), microStateName(nextState))); m_uState = nextState; wait_uSec(waitTime); } //------------------------------------------------------------------------ // void I2CMaster::setNextMacroState(eI2CMacroState nextState) { Dprintf((" curr:%s next:%s\n",macroStateName(m_mState), macroStateName(nextState))); m_mState = nextState; mStop->setFromMaster(m_mState == eI2CStop); } Module *I2CMaster::construct(const char *new_name) { gcycles = &get_cycles(); I2CMaster *pI2CMaster = new I2CMaster(new_name); pI2CMaster->create_iopin_map(); return pI2CMaster; } //------------------------------------------------------------------------ void I2CMaster::send7BitAddress(unsigned int addr) { Dprintf(("\n")); if (eI2CResSuccess == sendStart()) mTxByte->setFromMaster(addr<<1); } //------------------------------------------------------------------------ void I2CMaster::startCompleted() { Dprintf(("\n")); send8BitData(mTxByte->getVal()); } //------------------------------------------------------------------------ void I2CMaster::stopCompleted() { Dprintf(("\n")); mStop->setFromMaster(true); } //------------------------------------------------------------------------ void I2CMaster::transferCompleted() { Dprintf(("\n")); } //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the I2C Master's package is defined. // Specifically, the I/O pins of the module are created. void I2CMaster::create_iopin_map(void) { // Define the physical package. It has two pins create_pkg(2); assign_pin(1, m_pSCL); assign_pin(2, m_pSDA); } //======================================================================== // I2C Attributes I2C_TxBuffer::I2C_TxBuffer(I2CMaster *_i2c) : Integer("tx",0,"I2C Transmit Register - byte currently transmitting"),i2c(_i2c) { } void I2C_TxBuffer::set(gint64 i) { i &= 0xff; if(i2c) i2c->send8BitData((int)i); Integer::set(i); } void I2C_TxBuffer::setFromMaster(gint64 i) { Integer::set(i); } //######################################## // TxREady - reflects the bus state - if the I2C bus is not owned by another // master, then TxReady is true I2C_TxReady::I2C_TxReady(I2CMaster *_i2c) : Boolean("tx_ready",false, "I2C Transmit Ready - a read-only register that is false only\n" "when some other master controls the I2C bus."), i2c(_i2c) { } void I2C_TxReady::set(bool b) { } void I2C_TxReady::setFromMaster(bool b) { Boolean::set(b); } //######################################## I2C_RxBuffer::I2C_RxBuffer(I2CMaster *_i2c) : Integer("rx",0,"I2C Receive Register - most recently received byte"),i2c(_i2c) { } void I2C_RxBuffer::set(gint64 i) { } void I2C_RxBuffer::setFromMaster(gint64 i) { Integer::set(i); } //######################################## I2C_RxSequence::I2C_RxSequence(I2CMaster *_i2c) : Integer("rx_sequence",0,"I2C Receive Sequence number - increments on each recieved byte"), i2c(_i2c) { } void I2C_RxSequence::set(gint64 i) { } void I2C_RxSequence::setFromMaster(gint64 i) { Integer::set(i); } //######################################## I2C_Send7BitAddress::I2C_Send7BitAddress(I2CMaster *_i2c) : Integer("slaveaddr",0,"I2C slave address - a write to this will send a slave address"), i2c(_i2c) { } void I2C_Send7BitAddress::set(gint64 i) { Dprintf(("setting addr to 0x%lx\n",i)); Integer::set(i); int addr = (int) (i & 0xff); i2c->send7BitAddress(addr); } void I2C_Send7BitAddress::setFromMaster(gint64 i) { Integer::set(i); } //######################################## I2C_Stop::I2C_Stop(I2CMaster *_i2c) : Boolean("stop",0,"I2C stop - transmit a stop bit now"), i2c(_i2c) { } void I2C_Stop::set(bool b) { if (b) { Boolean::set(b); i2c->sendStop(); } } void I2C_Stop::setFromMaster(bool b) { Boolean::set(b); } //######################################## I2C_Address::I2C_Address(I2CMaster *_i2c) : Integer("addr",0,"I2C master address - a write to this sets the master address"), i2c(_i2c) { } void I2C_Address::set(gint64 i) { } //######################################## I2C_Debug::I2C_Debug(I2CMaster *_i2c) : Integer("debug",0,"I2C debug - a write sets debug verbosity"), i2c(_i2c) { } void I2C_Debug::set(gint64 i) { i2c->debug(); } } // end of namespace I2C_Module gpsim-0.30.0/modules/push_button.h0000664000076400007640000000257213041763636014056 00000000000000/* Copyright (C) 2004 Carlos Ghirardelli This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef __PSHB_H__ #define __PSHB_H__ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../src/modules.h" #include class IOPIN; class PushButton : public Module { void create_widget(PushButton *pb); public: IOPIN *pshb_pin; PushButton(const char *); ~PushButton(void); void test(void); void update(void); // Inheritances from the Package class virtual void create_iopin_map(void); // Inheritance from Module class const virtual char *type(void) { return ("push_button"); }; static Module *construct(const char *new_name); }; #endif // __PSHB_H__ gpsim-0.30.0/modules/push_button.cc0000664000076400007640000001020013041763636014177 00000000000000/* Copyright (C) 2002 Carlos Ghirardelli This file is part of the libgpsim_modules library of gpsim This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ /* push_button.cc */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #include "../src/stimuli.h" #include "../src/packages.h" #include "push_button.h" //-------------------------------------------------------------- // create_iopin_map // // This is where the information for the Module's package is defined. // Specifically, the I/O pins of the module are created. void PushButton::create_iopin_map(void) { // Create an I/O port to which the I/O pins can interface // The module I/O pins are treated in a similar manner to // the pic I/O pins. Each pin has a unique pin number that // describes it's position on the physical package. This // pin can then be logically grouped with other pins to define // an I/O port. //pshb_port = new IOPORT(1); //pshb_port->value.put(0); // Here, we name the port `pin'. So in gpsim, we will reference // the bit positions as U1.pin0, U1.pin1, ..., where U1 is the // name of the logic gate (which is assigned by the user and // obtained with the name() member function call). //char *pin_name = (char*)name().c_str(); // Get the name of this switch //if(pin_name) { // pshb_port->new_name(pin_name); //} // Define the physical package. // The Package class, which is a parent of all of the modules, // is responsible for allocating memory for the I/O pins. // create_pkg(1); // Define the I/O pins and assign them to the package. // There are two things happening here. First, there is // a new I/O pin that is being created. For the binary // indicator, both pins are inputs. The second thing is // that the pins are "assigned" to the package. If we // need to reference these newly created I/O pins (like // below) then we can call the member function 'get_pin'. pshb_pin = new IO_bi_directional("out"); addSymbol(pshb_pin); assign_pin(1, pshb_pin); package->set_pin_position(1,2.5); // Position pin on middle right side of package if(pshb_pin) pshb_pin->update_direction(1,true); } //-------------------------------------------------------------- // GUI static void press_cb (GtkButton *button, PushButton *pb) { if (pb && pb->pshb_pin) pb->pshb_pin->toggle(); } static void released_cb (GtkButton *button, PushButton *pb) { } void PushButton::create_widget(PushButton *pb) { GtkWidget *box1; GtkWidget *button; box1 = gtk_vbox_new (FALSE, 0); button = gtk_button_new_with_label ((char*)pb->name().c_str()); gtk_container_set_border_width (GTK_CONTAINER (button), 5); g_signal_connect (button, "pressed", G_CALLBACK(press_cb), (gpointer)pb); g_signal_connect (button, "released", G_CALLBACK(released_cb), (gpointer)pb); gtk_widget_show(button); gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0); // Tell gpsim which widget to use in breadboard. pb->set_widget(box1); } //-------------------------------------------------------------- // construct Module * PushButton::construct(const char *_new_name=0) { PushButton *pshbP = new PushButton(_new_name) ; pshbP->create_widget(pshbP); return pshbP; } PushButton::PushButton(const char * _name) : Module(_name, "PushButton") { create_iopin_map(); } PushButton::~PushButton(void) { removeSymbol(pshb_pin); } #endif // HAVE_GUI gpsim-0.30.0/modules/i2c2par.cc0000664000076400007640000001146013041763636013100 00000000000000/* Copyright (C) 2015 Roy R Rankin This file is part of gpsim. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* This module simulates a 7 bit address slave I2C device with an 8 bit I/O bus. The direction of the 8 bit bus is controlled by the R/W bit sent from the master. This module allows multi-pin devices such as LCD displays to be connected to the processor via the 2 pin I2C bus. */ #include //#define DEBUG #if defined(DEBUG) #define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; } #else #define Dprintf(arg) {} #endif #include "config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI #include #endif #include "src/gpsim_time.h" #include "src/stimuli.h" #include "src/ioports.h" #include "src/symbol.h" #include "src/value.h" #include "src/packages.h" #include "src/gpsim_interface.h" #include "i2c2par.h" class AddAttribute : public Integer { public: I2C2PAR_Modules::i2c2par *i2cpt; AddAttribute(I2C2PAR_Modules::i2c2par *_i2cpt) : Integer("Slave_Address", 0x27, "I2C Slave Address"), i2cpt(_i2cpt) { } virtual void set(int v) { Integer::set(v); if (i2cpt) i2cpt->i2c_slave_address = (v<<1); } }; class IOPort : public PortModule //class IOPort : public PortRegister { public: unsigned int direction; // virtual void put(unsigned int new_value); IOPort (unsigned int _num_iopins=8); void update_pin_directions(unsigned int ); void put(unsigned int); unsigned int get(); }; //IOPort::IOPort(unsigned int _num_iopins) : PortRegister(_num_iopins, "P", "") IOPort::IOPort(unsigned int _num_iopins) : PortModule(_num_iopins), direction(0) {} void IOPort::put(unsigned int value) { IOPIN *m_pin; for(int i = 0; i<8; i++) { unsigned int bit = 1<putState((value & bit) == bit); } } unsigned int IOPort::get() { IOPIN *m_pin; unsigned int value = 0; for(int i = 0; i<8; i++) { unsigned int bit = 1<getState()) value |= bit; } } return(value); } void IOPort::update_pin_directions(unsigned int new_direction) { IOPIN *m_pin; if((new_direction ^ direction) & 1) { direction = new_direction & 1; for(int i=0; i<8; i++) { if ((m_pin = getPin(i))) { m_pin->update_direction(direction,true); if (m_pin->snode) m_pin->snode->update(); } } } } namespace I2C2PAR_Modules { i2c2par::i2c2par(const char *_name) : i2c_slave(), Module(_name, "i2c2par") { io_port = new IOPort(8); Addattr = new AddAttribute(this); addSymbol(Addattr); Addattr->set(0x27); } i2c2par::~i2c2par() { delete io_port; delete Addattr; for(int i = 0; i<8; i++) { removeSymbol(pins[i]); } delete [] pins; removeSymbol((IOPIN *)scl); removeSymbol((IOPIN *)sda); // set sda, scl to zero as package deletes them, // thus stopping ~i2c_slave from trying to delete them also sda = 0; scl = 0; } void i2c2par::put_data(unsigned int data) { io_port->put(data); } unsigned int i2c2par::get_data() { return(io_port->get()); } void i2c2par::slave_transmit(bool yes) { if (yes) io_port->update_pin_directions(IOPIN::DIR_INPUT); else io_port->update_pin_directions(IOPIN::DIR_OUTPUT); } bool i2c2par::match_address() { return((xfr_data & 0xfe) == i2c_slave_address); } Module *i2c2par::construct(const char *_new_name) { string att_name = _new_name; i2c2par *pEE = new i2c2par(_new_name); pEE->create_iopin_map(); return(pEE); } void i2c2par::create_iopin_map() { pins = new IO_bi_directional_pu *[8]; char pin_name[] = "p0"; addSymbol((IOPIN *)sda); addSymbol((IOPIN *)scl); package = new Package(10); for (int i = 0; i < 8; i++) { pin_name[1] = '0' + i; pins[i] = new IO_bi_directional_pu(pin_name); package->assign_pin( i<4 ? i+1 : i+3, io_port->addPin(pins[i], i)); addSymbol(pins[i]); } package->assign_pin( 5, (IOPIN *)(sda)); package->assign_pin( 6, (IOPIN *)(scl)); } } // end of namespace I2C2PAR_Modules